@@ -43,6 +43,14 @@ using namespace clang;
4343
4444namespace {
4545
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+
4654static bool isLocalContainerContext (const DeclContext *DC) {
4755 return isa<FunctionDecl>(DC) || isa<ObjCMethodDecl>(DC) || isa<BlockDecl>(DC);
4856}
@@ -136,6 +144,11 @@ class ItaniumMangleContextImpl : public ItaniumMangleContext {
136144
137145 void mangleModuleInitializer (const Module *Module, raw_ostream &) override ;
138146
147+ void mangleForRISCVZicfilpFuncSigLabel (const FunctionType &,
148+ const bool IsCXXInstanceMethod,
149+ const bool IsCXXVirtualMethod,
150+ raw_ostream &) override ;
151+
139152 bool getNextDiscriminator (const NamedDecl *ND, unsigned &disc) {
140153 // Lambda closure types are already numbered.
141154 if (isLambda (ND))
@@ -395,8 +408,10 @@ class CXXNameMangler {
395408 llvm::DenseMap<uintptr_t , unsigned > Substitutions;
396409 llvm::DenseMap<StringRef, unsigned > ModuleSubstitutions;
397410
411+ protected:
398412 ASTContext &getASTContext () const { return Context.getASTContext (); }
399413
414+ private:
400415 bool isCompatibleWith (LangOptions::ClangABI Ver) {
401416 return Context.getASTContext ().getLangOpts ().getClangABICompat () <= Ver;
402417 }
@@ -443,6 +458,8 @@ class CXXNameMangler {
443458 NullOut = true ;
444459 }
445460
461+ virtual ~CXXNameMangler () = default ;
462+
446463 struct WithTemplateDepthOffset { unsigned Offset; };
447464 CXXNameMangler (ItaniumMangleContextImpl &C, raw_ostream &Out,
448465 WithTemplateDepthOffset Offset)
@@ -559,9 +576,12 @@ class CXXNameMangler {
559576 StringRef Prefix = " " );
560577 void mangleOperatorName (DeclarationName Name, unsigned Arity);
561578 void mangleOperatorName (OverloadedOperatorKind OO, unsigned Arity);
579+
580+ protected:
562581 void mangleQualifiers (Qualifiers Quals, const DependentAddressSpaceType *DAST = nullptr );
563582 void mangleRefQualifier (RefQualifierKind RefQualifier);
564583
584+ private:
565585 void mangleObjCMethodName (const ObjCMethodDecl *MD);
566586
567587 // Declare manglers for every type class.
@@ -572,11 +592,24 @@ class CXXNameMangler {
572592
573593 void mangleType (const TagType*);
574594 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:
575604 static StringRef getCallingConvQualifierName (CallingConv CC);
576605 void mangleExtParameterInfo (FunctionProtoType::ExtParameterInfo info);
577606 void mangleExtFunctionInfo (const FunctionType *T);
607+
608+ protected:
578609 void mangleBareFunctionType (const FunctionProtoType *T, bool MangleReturnType,
579610 const FunctionDecl *FD = nullptr );
611+
612+ private:
580613 void mangleNeonVectorType (const VectorType *T);
581614 void mangleNeonVectorType (const DependentVectorType *T);
582615 void mangleAArch64NeonVectorType (const VectorType *T);
@@ -3058,7 +3091,9 @@ void CXXNameMangler::mangleCXXRecordDecl(const CXXRecordDecl *Record) {
30583091 addSubstitution (Record);
30593092}
30603093
3061- void CXXNameMangler::mangleType (const BuiltinType *T) {
3094+ void CXXNameMangler::mangleType (const BuiltinType *T) { mangleTypeImpl (T); }
3095+
3096+ void CXXNameMangler::mangleTypeImpl (const BuiltinType *T) {
30623097 // <type> ::= <builtin-type>
30633098 // <builtin-type> ::= v # void
30643099 // ::= w # wchar_t
@@ -3563,10 +3598,14 @@ CXXNameMangler::mangleExtParameterInfo(FunctionProtoType::ExtParameterInfo PI) {
35633598 mangleVendorQualifier (" noescape" );
35643599}
35653600
3601+ void CXXNameMangler::mangleType (const FunctionProtoType *T) {
3602+ return mangleTypeImpl (T);
3603+ }
3604+
35663605// <type> ::= <function-type>
35673606// <function-type> ::= [<CV-qualifiers>] F [Y]
35683607// <bare-function-type> [<ref-qualifier>] E
3569- void CXXNameMangler::mangleType (const FunctionProtoType *T) {
3608+ void CXXNameMangler::mangleTypeImpl (const FunctionProtoType *T) {
35703609 mangleExtFunctionInfo (T);
35713610
35723611 // Mangle CV-qualifiers, if present. These are 'this' qualifiers,
@@ -3604,6 +3643,10 @@ void CXXNameMangler::mangleType(const FunctionProtoType *T) {
36043643}
36053644
36063645void CXXNameMangler::mangleType (const FunctionNoProtoType *T) {
3646+ return mangleTypeImpl (T);
3647+ }
3648+
3649+ void CXXNameMangler::mangleTypeImpl (const FunctionNoProtoType *T) {
36073650 // Function types without prototypes can arise when mangling a function type
36083651 // within an overloadable function in C. We mangle these as the absence of any
36093652 // parameter types (not even an empty parameter list).
@@ -7074,6 +7117,85 @@ bool CXXNameMangler::shouldHaveAbiTags(ItaniumMangleContextImpl &C,
70747117 return TrackAbiTags.AbiTagsRoot .getUsedAbiTags ().size ();
70757118}
70767119
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+
70777199//
70787200
70797201// / Mangles the name of the declaration D and emits that name to the given
@@ -7412,6 +7534,17 @@ void ItaniumMangleContextImpl::mangleModuleInitializer(const Module *M,
74127534 }
74137535}
74147536
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+
74157548ItaniumMangleContext *ItaniumMangleContext::create (ASTContext &Context,
74167549 DiagnosticsEngine &Diags,
74177550 bool IsAux) {
0 commit comments