@@ -41,6 +41,14 @@ using namespace clang;
41
41
42
42
namespace {
43
43
44
+ static bool mayBeCovariant (const Type &Ty) {
45
+ if (auto *const PT = Ty.getAs <PointerType>())
46
+ return PT->getPointeeType ()->isStructureOrClassType ();
47
+ if (auto *const RT = Ty.getAs <ReferenceType>())
48
+ return RT->getPointeeType ()->isStructureOrClassType ();
49
+ return false ;
50
+ }
51
+
44
52
static bool isLocalContainerContext (const DeclContext *DC) {
45
53
return isa<FunctionDecl>(DC) || isa<ObjCMethodDecl>(DC) || isa<BlockDecl>(DC);
46
54
}
@@ -134,6 +142,11 @@ class ItaniumMangleContextImpl : public ItaniumMangleContext {
134
142
135
143
void mangleModuleInitializer (const Module *Module, raw_ostream &) override ;
136
144
145
+ void mangleForRISCVZicfilpFuncSigLabel (const FunctionType &,
146
+ const bool IsCXXInstanceMethod,
147
+ const bool IsCXXVirtualMethod,
148
+ raw_ostream &) override ;
149
+
137
150
bool getNextDiscriminator (const NamedDecl *ND, unsigned &disc) {
138
151
// Lambda closure types are already numbered.
139
152
if (isLambda (ND))
@@ -386,8 +399,10 @@ class CXXNameMangler {
386
399
llvm::DenseMap<uintptr_t , unsigned > Substitutions;
387
400
llvm::DenseMap<StringRef, unsigned > ModuleSubstitutions;
388
401
402
+ protected:
389
403
ASTContext &getASTContext () const { return Context.getASTContext (); }
390
404
405
+ private:
391
406
bool isCompatibleWith (LangOptions::ClangABI Ver) {
392
407
return Context.getASTContext ().getLangOpts ().getClangABICompat () <= Ver;
393
408
}
@@ -434,6 +449,8 @@ class CXXNameMangler {
434
449
NullOut = true ;
435
450
}
436
451
452
+ virtual ~CXXNameMangler () = default ;
453
+
437
454
struct WithTemplateDepthOffset { unsigned Offset; };
438
455
CXXNameMangler (ItaniumMangleContextImpl &C, raw_ostream &Out,
439
456
WithTemplateDepthOffset Offset)
@@ -552,9 +569,12 @@ class CXXNameMangler {
552
569
StringRef Prefix = " " );
553
570
void mangleOperatorName (DeclarationName Name, unsigned Arity);
554
571
void mangleOperatorName (OverloadedOperatorKind OO, unsigned Arity);
572
+
573
+ protected:
555
574
void mangleQualifiers (Qualifiers Quals, const DependentAddressSpaceType *DAST = nullptr );
556
575
void mangleRefQualifier (RefQualifierKind RefQualifier);
557
576
577
+ private:
558
578
void mangleObjCMethodName (const ObjCMethodDecl *MD);
559
579
560
580
// Declare manglers for every type class.
@@ -565,12 +585,25 @@ class CXXNameMangler {
565
585
566
586
void mangleType (const TagType*);
567
587
void mangleType (TemplateName);
588
+
589
+ protected:
590
+ // Use the `Impl` scheme instead of directly virtualizing `mangleType`s since
591
+ // `mangleType`s are declared by tables
592
+ virtual void mangleTypeImpl (const BuiltinType *T);
593
+ virtual void mangleTypeImpl (const FunctionProtoType *T);
594
+ virtual void mangleTypeImpl (const FunctionNoProtoType *T);
595
+
596
+ private:
568
597
static StringRef getCallingConvQualifierName (CallingConv CC);
569
598
void mangleExtParameterInfo (FunctionProtoType::ExtParameterInfo info);
570
599
void mangleExtFunctionInfo (const FunctionType *T);
571
600
void mangleSMEAttrs (unsigned SMEAttrs);
601
+
602
+ protected:
572
603
void mangleBareFunctionType (const FunctionProtoType *T, bool MangleReturnType,
573
604
const FunctionDecl *FD = nullptr );
605
+
606
+ private:
574
607
void mangleNeonVectorType (const VectorType *T);
575
608
void mangleNeonVectorType (const DependentVectorType *T);
576
609
void mangleAArch64NeonVectorType (const VectorType *T);
@@ -3111,7 +3144,9 @@ void CXXNameMangler::mangleCXXRecordDecl(const CXXRecordDecl *Record) {
3111
3144
addSubstitution (Record);
3112
3145
}
3113
3146
3114
- void CXXNameMangler::mangleType (const BuiltinType *T) {
3147
+ void CXXNameMangler::mangleType (const BuiltinType *T) { mangleTypeImpl (T); }
3148
+
3149
+ void CXXNameMangler::mangleTypeImpl (const BuiltinType *T) {
3115
3150
// <type> ::= <builtin-type>
3116
3151
// <builtin-type> ::= v # void
3117
3152
// ::= w # wchar_t
@@ -3694,10 +3729,14 @@ CXXNameMangler::mangleExtParameterInfo(FunctionProtoType::ExtParameterInfo PI) {
3694
3729
mangleVendorQualifier (" noescape" );
3695
3730
}
3696
3731
3732
+ void CXXNameMangler::mangleType (const FunctionProtoType *T) {
3733
+ return mangleTypeImpl (T);
3734
+ }
3735
+
3697
3736
// <type> ::= <function-type>
3698
3737
// <function-type> ::= [<CV-qualifiers>] F [Y]
3699
3738
// <bare-function-type> [<ref-qualifier>] E
3700
- void CXXNameMangler::mangleType (const FunctionProtoType *T) {
3739
+ void CXXNameMangler::mangleTypeImpl (const FunctionProtoType *T) {
3701
3740
unsigned SMEAttrs = T->getAArch64SMEAttributes ();
3702
3741
3703
3742
if (SMEAttrs)
@@ -3742,6 +3781,10 @@ void CXXNameMangler::mangleType(const FunctionProtoType *T) {
3742
3781
}
3743
3782
3744
3783
void CXXNameMangler::mangleType (const FunctionNoProtoType *T) {
3784
+ return mangleTypeImpl (T);
3785
+ }
3786
+
3787
+ void CXXNameMangler::mangleTypeImpl (const FunctionNoProtoType *T) {
3745
3788
// Function types without prototypes can arise when mangling a function type
3746
3789
// within an overloadable function in C. We mangle these as the absence of any
3747
3790
// parameter types (not even an empty parameter list).
@@ -7233,6 +7276,86 @@ bool CXXNameMangler::shouldHaveAbiTags(ItaniumMangleContextImpl &C,
7233
7276
return TrackAbiTags.AbiTagsRoot .getUsedAbiTags ().size ();
7234
7277
}
7235
7278
7279
+ namespace {
7280
+
7281
+ class RISCVZicfilpFuncSigLabelMangler : public CXXNameMangler {
7282
+ bool IsTopLevelAndCXXVirtualMethod;
7283
+
7284
+ public:
7285
+ RISCVZicfilpFuncSigLabelMangler (ItaniumMangleContextImpl &C, raw_ostream &Out,
7286
+ const bool IsCXXVirtualMethod)
7287
+ : CXXNameMangler(C, Out),
7288
+ IsTopLevelAndCXXVirtualMethod (/* IsTopLevel=*/ true &&
7289
+ IsCXXVirtualMethod) {}
7290
+
7291
+ void mangleTypeImpl (const BuiltinType *T) override {
7292
+ if (T->getKind () == BuiltinType::WChar_S ||
7293
+ T->getKind () == BuiltinType::WChar_U) {
7294
+ const Type *const OverrideT =
7295
+ getASTContext ().getWCharTypeInC ().getTypePtr ();
7296
+ assert (isa<BuiltinType>(OverrideT) &&
7297
+ " `wchar_t' in C is expected to be defined to a built-in type" );
7298
+ T = static_cast <const BuiltinType *>(OverrideT);
7299
+ }
7300
+ return CXXNameMangler::mangleTypeImpl (T);
7301
+ }
7302
+
7303
+ // This <function-type> is the RISC-V psABI modified version
7304
+ // <function-type> ::= [<CV-qualifiers>] [Dx] F <bare-function-type>
7305
+ // [<ref-qualifier>] E
7306
+ void mangleTypeImpl (const FunctionProtoType *T) override {
7307
+ const bool WasTopLevelAndCXXVirtualMethod = IsTopLevelAndCXXVirtualMethod;
7308
+ IsTopLevelAndCXXVirtualMethod = false ; // Not top-level anymore
7309
+
7310
+ // Mangle CV-qualifiers, if present. These are 'this' qualifiers,
7311
+ // e.g. "const" in "int (A::*)() const".
7312
+ mangleQualifiers (T->getMethodQuals ());
7313
+
7314
+ getStream () << ' F' ;
7315
+
7316
+ bool MangleReturnType = true ;
7317
+ if (const Type &RetT = *T->getReturnType ().getTypePtr ();
7318
+ WasTopLevelAndCXXVirtualMethod && mayBeCovariant (RetT)) {
7319
+ // Possible covariant types mangle dummy cv-unqualified `class v` as its
7320
+ // class type
7321
+ if (RetT.isPointerType ())
7322
+ getStream () << " P1v" ;
7323
+ else if (RetT.isLValueReferenceType ())
7324
+ getStream () << " R1v" ;
7325
+ else {
7326
+ assert (RetT.isRValueReferenceType () &&
7327
+ " Expect an r-value ref for covariant return type that is not a "
7328
+ " pointer or an l-value ref" );
7329
+ getStream () << " O1v" ;
7330
+ }
7331
+ MangleReturnType = false ;
7332
+ }
7333
+ mangleBareFunctionType (T, MangleReturnType);
7334
+
7335
+ // Mangle the ref-qualifier, if present.
7336
+ mangleRefQualifier (T->getRefQualifier ());
7337
+
7338
+ getStream () << ' E' ;
7339
+ }
7340
+
7341
+ void mangleTypeImpl (const FunctionNoProtoType *T) override {
7342
+ return CXXNameMangler::mangleTypeImpl (toFunctionProtoType (T));
7343
+ }
7344
+
7345
+ private:
7346
+ const FunctionProtoType *
7347
+ toFunctionProtoType (const FunctionNoProtoType *const T) {
7348
+ FunctionProtoType::ExtProtoInfo EPI;
7349
+ EPI.ExtInfo = T->getExtInfo ();
7350
+ const Type *const NewT = getASTContext ()
7351
+ .getFunctionType (T->getReturnType (), {}, EPI)
7352
+ .getTypePtr ();
7353
+ return static_cast <const FunctionProtoType *>(NewT);
7354
+ }
7355
+ }; // class RISCVZicfilpFuncSigLabelMangler
7356
+
7357
+ } // anonymous namespace
7358
+
7236
7359
//
7237
7360
7238
7361
// / Mangles the name of the declaration D and emits that name to the given
@@ -7571,6 +7694,17 @@ void ItaniumMangleContextImpl::mangleModuleInitializer(const Module *M,
7571
7694
}
7572
7695
}
7573
7696
7697
+ void ItaniumMangleContextImpl::mangleForRISCVZicfilpFuncSigLabel (
7698
+ const FunctionType &FT, const bool IsCXXInstanceMethod,
7699
+ const bool IsCXXVirtualMethod, raw_ostream &Out) {
7700
+ if (IsCXXInstanceMethod)
7701
+ // member methods uses a dummy class named `v` in place of real classes
7702
+ Out << " M1v" ;
7703
+
7704
+ RISCVZicfilpFuncSigLabelMangler Mangler (*this , Out, IsCXXVirtualMethod);
7705
+ Mangler.mangleType (QualType (&FT, 0 ));
7706
+ }
7707
+
7574
7708
ItaniumMangleContext *ItaniumMangleContext::create (ASTContext &Context,
7575
7709
DiagnosticsEngine &Diags,
7576
7710
bool IsAux) {
0 commit comments