@@ -43,6 +43,14 @@ using namespace clang;
43
43
44
44
namespace {
45
45
46
+ static bool mayBeCovariant (const Type &Ty) {
47
+ if (auto *const PT = Ty.getAs <PointerType>())
48
+ return PT->getPointeeType ()->isStructureOrClassType ();
49
+ if (auto *const RT = Ty.getAs <ReferenceType>())
50
+ return RT->getPointeeType ()->isStructureOrClassType ();
51
+ return false ;
52
+ }
53
+
46
54
static bool isLocalContainerContext (const DeclContext *DC) {
47
55
return isa<FunctionDecl>(DC) || isa<ObjCMethodDecl>(DC) || isa<BlockDecl>(DC);
48
56
}
@@ -136,6 +144,11 @@ class ItaniumMangleContextImpl : public ItaniumMangleContext {
136
144
137
145
void mangleModuleInitializer (const Module *Module, raw_ostream &) override ;
138
146
147
+ void mangleForRISCVZicfilpFuncSigLabel (const FunctionType &,
148
+ const bool IsCXXInstanceMethod,
149
+ const bool IsCXXVirtualMethod,
150
+ raw_ostream &) override ;
151
+
139
152
bool getNextDiscriminator (const NamedDecl *ND, unsigned &disc) {
140
153
// Lambda closure types are already numbered.
141
154
if (isLambda (ND))
@@ -395,8 +408,10 @@ class CXXNameMangler {
395
408
llvm::DenseMap<uintptr_t , unsigned > Substitutions;
396
409
llvm::DenseMap<StringRef, unsigned > ModuleSubstitutions;
397
410
411
+ protected:
398
412
ASTContext &getASTContext () const { return Context.getASTContext (); }
399
413
414
+ private:
400
415
bool isCompatibleWith (LangOptions::ClangABI Ver) {
401
416
return Context.getASTContext ().getLangOpts ().getClangABICompat () <= Ver;
402
417
}
@@ -443,6 +458,8 @@ class CXXNameMangler {
443
458
NullOut = true ;
444
459
}
445
460
461
+ virtual ~CXXNameMangler () = default ;
462
+
446
463
struct WithTemplateDepthOffset { unsigned Offset; };
447
464
CXXNameMangler (ItaniumMangleContextImpl &C, raw_ostream &Out,
448
465
WithTemplateDepthOffset Offset)
@@ -559,9 +576,12 @@ class CXXNameMangler {
559
576
StringRef Prefix = " " );
560
577
void mangleOperatorName (DeclarationName Name, unsigned Arity);
561
578
void mangleOperatorName (OverloadedOperatorKind OO, unsigned Arity);
579
+
580
+ protected:
562
581
void mangleQualifiers (Qualifiers Quals, const DependentAddressSpaceType *DAST = nullptr );
563
582
void mangleRefQualifier (RefQualifierKind RefQualifier);
564
583
584
+ private:
565
585
void mangleObjCMethodName (const ObjCMethodDecl *MD);
566
586
567
587
// Declare manglers for every type class.
@@ -572,11 +592,24 @@ class CXXNameMangler {
572
592
573
593
void mangleType (const TagType*);
574
594
void mangleType (TemplateName);
595
+
596
+ protected:
597
+ // Use the `Impl` scheme instead of directly virtualizing `mangleType`s since
598
+ // `mangleType`s are declared by tables
599
+ virtual void mangleTypeImpl (const BuiltinType *T);
600
+ virtual void mangleTypeImpl (const FunctionProtoType *T);
601
+ virtual void mangleTypeImpl (const FunctionNoProtoType *T);
602
+
603
+ private:
575
604
static StringRef getCallingConvQualifierName (CallingConv CC);
576
605
void mangleExtParameterInfo (FunctionProtoType::ExtParameterInfo info);
577
606
void mangleExtFunctionInfo (const FunctionType *T);
607
+
608
+ protected:
578
609
void mangleBareFunctionType (const FunctionProtoType *T, bool MangleReturnType,
579
610
const FunctionDecl *FD = nullptr );
611
+
612
+ private:
580
613
void mangleNeonVectorType (const VectorType *T);
581
614
void mangleNeonVectorType (const DependentVectorType *T);
582
615
void mangleAArch64NeonVectorType (const VectorType *T);
@@ -3058,7 +3091,9 @@ void CXXNameMangler::mangleCXXRecordDecl(const CXXRecordDecl *Record) {
3058
3091
addSubstitution (Record);
3059
3092
}
3060
3093
3061
- void CXXNameMangler::mangleType (const BuiltinType *T) {
3094
+ void CXXNameMangler::mangleType (const BuiltinType *T) { mangleTypeImpl (T); }
3095
+
3096
+ void CXXNameMangler::mangleTypeImpl (const BuiltinType *T) {
3062
3097
// <type> ::= <builtin-type>
3063
3098
// <builtin-type> ::= v # void
3064
3099
// ::= w # wchar_t
@@ -3563,10 +3598,14 @@ CXXNameMangler::mangleExtParameterInfo(FunctionProtoType::ExtParameterInfo PI) {
3563
3598
mangleVendorQualifier (" noescape" );
3564
3599
}
3565
3600
3601
+ void CXXNameMangler::mangleType (const FunctionProtoType *T) {
3602
+ return mangleTypeImpl (T);
3603
+ }
3604
+
3566
3605
// <type> ::= <function-type>
3567
3606
// <function-type> ::= [<CV-qualifiers>] F [Y]
3568
3607
// <bare-function-type> [<ref-qualifier>] E
3569
- void CXXNameMangler::mangleType (const FunctionProtoType *T) {
3608
+ void CXXNameMangler::mangleTypeImpl (const FunctionProtoType *T) {
3570
3609
mangleExtFunctionInfo (T);
3571
3610
3572
3611
// Mangle CV-qualifiers, if present. These are 'this' qualifiers,
@@ -3604,6 +3643,10 @@ void CXXNameMangler::mangleType(const FunctionProtoType *T) {
3604
3643
}
3605
3644
3606
3645
void CXXNameMangler::mangleType (const FunctionNoProtoType *T) {
3646
+ return mangleTypeImpl (T);
3647
+ }
3648
+
3649
+ void CXXNameMangler::mangleTypeImpl (const FunctionNoProtoType *T) {
3607
3650
// Function types without prototypes can arise when mangling a function type
3608
3651
// within an overloadable function in C. We mangle these as the absence of any
3609
3652
// parameter types (not even an empty parameter list).
@@ -7074,6 +7117,85 @@ bool CXXNameMangler::shouldHaveAbiTags(ItaniumMangleContextImpl &C,
7074
7117
return TrackAbiTags.AbiTagsRoot .getUsedAbiTags ().size ();
7075
7118
}
7076
7119
7120
+ namespace {
7121
+
7122
+ class RISCVZicfilpFuncSigLabelMangler : public CXXNameMangler {
7123
+ bool IsTopLevelAndCXXVirtualMethod;
7124
+
7125
+ public:
7126
+ RISCVZicfilpFuncSigLabelMangler (ItaniumMangleContextImpl &C, raw_ostream &Out,
7127
+ const bool IsCXXVirtualMethod)
7128
+ : CXXNameMangler(C, Out),
7129
+ IsTopLevelAndCXXVirtualMethod (/* IsTopLevel=*/ true &&
7130
+ IsCXXVirtualMethod) {}
7131
+
7132
+ void mangleTypeImpl (const BuiltinType *T) override {
7133
+ if (T->getKind () == BuiltinType::WChar_S ||
7134
+ T->getKind () == BuiltinType::WChar_U) {
7135
+ const Type *const OverrideT =
7136
+ getASTContext ().getWCharTypeInC ().getTypePtr ();
7137
+ assert (isa<BuiltinType>(OverrideT) &&
7138
+ " `wchar_t' in C is expected to be defined to a built-in type" );
7139
+ T = static_cast <const BuiltinType *>(OverrideT);
7140
+ }
7141
+ return CXXNameMangler::mangleTypeImpl (T);
7142
+ }
7143
+
7144
+ // This <function-type> is the RISC-V psABI modified version
7145
+ // <function-type> ::= [<CV-qualifiers>] [Dx] F <bare-function-type>
7146
+ // [<ref-qualifier>] E
7147
+ void mangleTypeImpl (const FunctionProtoType *T) override {
7148
+ // Mangle CV-qualifiers, if present. These are 'this' qualifiers,
7149
+ // e.g. "const" in "int (A::*)() const".
7150
+ mangleQualifiers (T->getMethodQuals ());
7151
+
7152
+ getStream () << ' F' ;
7153
+
7154
+ bool MangleReturnType = true ;
7155
+ if (const Type &RetT = *T->getReturnType ().getTypePtr ();
7156
+ IsTopLevelAndCXXVirtualMethod && mayBeCovariant (RetT)) {
7157
+ // Possible covariant types mangle dummy cv-unqualified `class v` as its
7158
+ // class type
7159
+ if (RetT.isPointerType ())
7160
+ getStream () << " P1v" ;
7161
+ else if (RetT.isLValueReferenceType ())
7162
+ getStream () << " R1v" ;
7163
+ else {
7164
+ assert (RetT.isRValueReferenceType () &&
7165
+ " Expect an r-value ref for covariant return type that is not a "
7166
+ " pointer or an l-value ref" );
7167
+ getStream () << " O1v" ;
7168
+ }
7169
+
7170
+ IsTopLevelAndCXXVirtualMethod = false ; // Not top-level anymore
7171
+ MangleReturnType = false ;
7172
+ }
7173
+ mangleBareFunctionType (T, MangleReturnType);
7174
+
7175
+ // Mangle the ref-qualifier, if present.
7176
+ mangleRefQualifier (T->getRefQualifier ());
7177
+
7178
+ getStream () << ' E' ;
7179
+ }
7180
+
7181
+ void mangleTypeImpl (const FunctionNoProtoType *T) override {
7182
+ return CXXNameMangler::mangleTypeImpl (toFunctionProtoType (T));
7183
+ }
7184
+
7185
+ private:
7186
+ const FunctionProtoType *
7187
+ toFunctionProtoType (const FunctionNoProtoType *const T) {
7188
+ FunctionProtoType::ExtProtoInfo EPI;
7189
+ EPI.ExtInfo = T->getExtInfo ();
7190
+ const Type *const NewT = getASTContext ()
7191
+ .getFunctionType (T->getReturnType (), {}, EPI)
7192
+ .getTypePtr ();
7193
+ return static_cast <const FunctionProtoType *>(NewT);
7194
+ }
7195
+ }; // class RISCVZicfilpFuncSigLabelMangler
7196
+
7197
+ } // anonymous namespace
7198
+
7077
7199
//
7078
7200
7079
7201
// / Mangles the name of the declaration D and emits that name to the given
@@ -7412,6 +7534,17 @@ void ItaniumMangleContextImpl::mangleModuleInitializer(const Module *M,
7412
7534
}
7413
7535
}
7414
7536
7537
+ void ItaniumMangleContextImpl::mangleForRISCVZicfilpFuncSigLabel (
7538
+ const FunctionType &FT, const bool IsCXXInstanceMethod,
7539
+ const bool IsCXXVirtualMethod, raw_ostream &Out) {
7540
+ if (IsCXXInstanceMethod)
7541
+ // member methods uses a dummy class named `v` in place of real classes
7542
+ Out << " M1v" ;
7543
+
7544
+ RISCVZicfilpFuncSigLabelMangler Mangler (*this , Out, IsCXXVirtualMethod);
7545
+ Mangler.mangleType (QualType (&FT, 0 ));
7546
+ }
7547
+
7415
7548
ItaniumMangleContext *ItaniumMangleContext::create (ASTContext &Context,
7416
7549
DiagnosticsEngine &Diags,
7417
7550
bool IsAux) {
0 commit comments