@@ -41,6 +41,14 @@ using namespace clang;
4141
4242namespace {
4343
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+
4452static bool isLocalContainerContext (const DeclContext *DC) {
4553 return isa<FunctionDecl>(DC) || isa<ObjCMethodDecl>(DC) || isa<BlockDecl>(DC);
4654}
@@ -134,6 +142,11 @@ class ItaniumMangleContextImpl : public ItaniumMangleContext {
134142
135143 void mangleModuleInitializer (const Module *Module, raw_ostream &) override ;
136144
145+ void mangleForRISCVZicfilpFuncSigLabel (const FunctionType &,
146+ const bool IsCXXInstanceMethod,
147+ const bool IsCXXVirtualMethod,
148+ raw_ostream &) override ;
149+
137150 bool getNextDiscriminator (const NamedDecl *ND, unsigned &disc) {
138151 // Lambda closure types are already numbered.
139152 if (isLambda (ND))
@@ -386,8 +399,10 @@ class CXXNameMangler {
386399 llvm::DenseMap<uintptr_t , unsigned > Substitutions;
387400 llvm::DenseMap<StringRef, unsigned > ModuleSubstitutions;
388401
402+ protected:
389403 ASTContext &getASTContext () const { return Context.getASTContext (); }
390404
405+ private:
391406 bool isCompatibleWith (LangOptions::ClangABI Ver) {
392407 return Context.getASTContext ().getLangOpts ().getClangABICompat () <= Ver;
393408 }
@@ -434,6 +449,8 @@ class CXXNameMangler {
434449 NullOut = true ;
435450 }
436451
452+ virtual ~CXXNameMangler () = default ;
453+
437454 struct WithTemplateDepthOffset { unsigned Offset; };
438455 CXXNameMangler (ItaniumMangleContextImpl &C, raw_ostream &Out,
439456 WithTemplateDepthOffset Offset)
@@ -552,9 +569,12 @@ class CXXNameMangler {
552569 StringRef Prefix = " " );
553570 void mangleOperatorName (DeclarationName Name, unsigned Arity);
554571 void mangleOperatorName (OverloadedOperatorKind OO, unsigned Arity);
572+
573+ protected:
555574 void mangleQualifiers (Qualifiers Quals, const DependentAddressSpaceType *DAST = nullptr );
556575 void mangleRefQualifier (RefQualifierKind RefQualifier);
557576
577+ private:
558578 void mangleObjCMethodName (const ObjCMethodDecl *MD);
559579
560580 // Declare manglers for every type class.
@@ -565,12 +585,25 @@ class CXXNameMangler {
565585
566586 void mangleType (const TagType*);
567587 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:
568597 static StringRef getCallingConvQualifierName (CallingConv CC);
569598 void mangleExtParameterInfo (FunctionProtoType::ExtParameterInfo info);
570599 void mangleExtFunctionInfo (const FunctionType *T);
571600 void mangleSMEAttrs (unsigned SMEAttrs);
601+
602+ protected:
572603 void mangleBareFunctionType (const FunctionProtoType *T, bool MangleReturnType,
573604 const FunctionDecl *FD = nullptr );
605+
606+ private:
574607 void mangleNeonVectorType (const VectorType *T);
575608 void mangleNeonVectorType (const DependentVectorType *T);
576609 void mangleAArch64NeonVectorType (const VectorType *T);
@@ -3111,7 +3144,9 @@ void CXXNameMangler::mangleCXXRecordDecl(const CXXRecordDecl *Record) {
31113144 addSubstitution (Record);
31123145}
31133146
3114- void CXXNameMangler::mangleType (const BuiltinType *T) {
3147+ void CXXNameMangler::mangleType (const BuiltinType *T) { mangleTypeImpl (T); }
3148+
3149+ void CXXNameMangler::mangleTypeImpl (const BuiltinType *T) {
31153150 // <type> ::= <builtin-type>
31163151 // <builtin-type> ::= v # void
31173152 // ::= w # wchar_t
@@ -3694,10 +3729,14 @@ CXXNameMangler::mangleExtParameterInfo(FunctionProtoType::ExtParameterInfo PI) {
36943729 mangleVendorQualifier (" noescape" );
36953730}
36963731
3732+ void CXXNameMangler::mangleType (const FunctionProtoType *T) {
3733+ return mangleTypeImpl (T);
3734+ }
3735+
36973736// <type> ::= <function-type>
36983737// <function-type> ::= [<CV-qualifiers>] F [Y]
36993738// <bare-function-type> [<ref-qualifier>] E
3700- void CXXNameMangler::mangleType (const FunctionProtoType *T) {
3739+ void CXXNameMangler::mangleTypeImpl (const FunctionProtoType *T) {
37013740 unsigned SMEAttrs = T->getAArch64SMEAttributes ();
37023741
37033742 if (SMEAttrs)
@@ -3742,6 +3781,10 @@ void CXXNameMangler::mangleType(const FunctionProtoType *T) {
37423781}
37433782
37443783void CXXNameMangler::mangleType (const FunctionNoProtoType *T) {
3784+ return mangleTypeImpl (T);
3785+ }
3786+
3787+ void CXXNameMangler::mangleTypeImpl (const FunctionNoProtoType *T) {
37453788 // Function types without prototypes can arise when mangling a function type
37463789 // within an overloadable function in C. We mangle these as the absence of any
37473790 // parameter types (not even an empty parameter list).
@@ -7233,6 +7276,86 @@ bool CXXNameMangler::shouldHaveAbiTags(ItaniumMangleContextImpl &C,
72337276 return TrackAbiTags.AbiTagsRoot .getUsedAbiTags ().size ();
72347277}
72357278
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+
72367359//
72377360
72387361// / Mangles the name of the declaration D and emits that name to the given
@@ -7571,6 +7694,17 @@ void ItaniumMangleContextImpl::mangleModuleInitializer(const Module *M,
75717694 }
75727695}
75737696
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+
75747708ItaniumMangleContext *ItaniumMangleContext::create (ASTContext &Context,
75757709 DiagnosticsEngine &Diags,
75767710 bool IsAux) {
0 commit comments