Index: clang/include/clang/AST/GlobalDecl.h =================================================================== --- clang/include/clang/AST/GlobalDecl.h +++ clang/include/clang/AST/GlobalDecl.h @@ -55,6 +55,7 @@ : MultiVersionIndex(MVIndex) { Init(D); } + GlobalDecl(const NamedDecl *D) { Init(D); } GlobalDecl(const BlockDecl *D) { Init(D); } GlobalDecl(const CapturedDecl *D) { Init(D); } GlobalDecl(const ObjCMethodDecl *D) { Init(D); } @@ -108,6 +109,8 @@ void *getAsOpaquePtr() const { return Value.getOpaqueValue(); } + explicit operator bool() const { return getAsOpaquePtr(); } + static GlobalDecl getFromOpaquePtr(void *P) { GlobalDecl GD; GD.Value.setFromOpaqueValue(P); Index: clang/include/clang/AST/Mangle.h =================================================================== --- clang/include/clang/AST/Mangle.h +++ clang/include/clang/AST/Mangle.h @@ -14,6 +14,7 @@ #define LLVM_CLANG_AST_MANGLE_H #include "clang/AST/Decl.h" +#include "clang/AST/GlobalDecl.h" #include "clang/AST/Type.h" #include "clang/Basic/ABI.h" #include "llvm/ADT/DenseMap.h" @@ -96,8 +97,8 @@ virtual bool shouldMangleStringLiteral(const StringLiteral *SL) = 0; // FIXME: consider replacing raw_ostream & with something like SmallString &. - void mangleName(const NamedDecl *D, raw_ostream &); - virtual void mangleCXXName(const NamedDecl *D, raw_ostream &) = 0; + void mangleName(GlobalDecl GD, raw_ostream &); + virtual void mangleCXXName(GlobalDecl GD, raw_ostream &) = 0; virtual void mangleThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk, raw_ostream &) = 0; Index: clang/lib/AST/ItaniumMangle.cpp =================================================================== --- clang/lib/AST/ItaniumMangle.cpp +++ clang/lib/AST/ItaniumMangle.cpp @@ -135,7 +135,7 @@ bool shouldMangleStringLiteral(const StringLiteral *) override { return false; } - void mangleCXXName(const NamedDecl *D, raw_ostream &) override; + void mangleCXXName(GlobalDecl GD, raw_ostream &) override; void mangleThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk, raw_ostream &) override; void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type, @@ -417,14 +417,14 @@ void disableDerivedAbiTags() { DisableDerivedAbiTags = true; } static bool shouldHaveAbiTags(ItaniumMangleContextImpl &C, const VarDecl *VD); - void mangle(const NamedDecl *D); + void mangle(GlobalDecl GD); void mangleCallOffset(int64_t NonVirtual, int64_t Virtual); void mangleNumber(const llvm::APSInt &I); void mangleNumber(int64_t Number); void mangleFloat(const llvm::APFloat &F); - void mangleFunctionEncoding(const FunctionDecl *FD); + void mangleFunctionEncoding(GlobalDecl GD); void mangleSeqID(unsigned SeqID); - void mangleName(const NamedDecl *ND); + void mangleName(GlobalDecl GD); void mangleType(QualType T); void mangleNameOrStandardSubstitution(const NamedDecl *ND); void mangleLambdaSig(const CXXRecordDecl *Lambda); @@ -461,38 +461,39 @@ void mangleFunctionEncodingBareType(const FunctionDecl *FD); - void mangleNameWithAbiTags(const NamedDecl *ND, + void mangleNameWithAbiTags(GlobalDecl GD, const AbiTagList *AdditionalAbiTags); void mangleModuleName(const Module *M); void mangleModuleNamePrefix(StringRef Name); void mangleTemplateName(const TemplateDecl *TD, const TemplateArgument *TemplateArgs, unsigned NumTemplateArgs); - void mangleUnqualifiedName(const NamedDecl *ND, + void mangleUnqualifiedName(GlobalDecl GD, const AbiTagList *AdditionalAbiTags) { - mangleUnqualifiedName(ND, ND->getDeclName(), UnknownArity, + mangleUnqualifiedName(GD, cast(GD.getDecl())->getDeclName(), UnknownArity, AdditionalAbiTags); } - void mangleUnqualifiedName(const NamedDecl *ND, DeclarationName Name, + void mangleUnqualifiedName(GlobalDecl GD, DeclarationName Name, unsigned KnownArity, const AbiTagList *AdditionalAbiTags); - void mangleUnscopedName(const NamedDecl *ND, + void mangleUnscopedName(GlobalDecl GD, const AbiTagList *AdditionalAbiTags); - void mangleUnscopedTemplateName(const TemplateDecl *ND, + void mangleUnscopedTemplateName(GlobalDecl GD, const AbiTagList *AdditionalAbiTags); void mangleUnscopedTemplateName(TemplateName, const AbiTagList *AdditionalAbiTags); void mangleSourceName(const IdentifierInfo *II); void mangleRegCallName(const IdentifierInfo *II); + void mangleDeviceStubName(const IdentifierInfo *II); void mangleSourceNameWithAbiTags( const NamedDecl *ND, const AbiTagList *AdditionalAbiTags = nullptr); - void mangleLocalName(const Decl *D, + void mangleLocalName(GlobalDecl GD, const AbiTagList *AdditionalAbiTags); void mangleBlockForPrefix(const BlockDecl *Block); void mangleUnqualifiedBlock(const BlockDecl *Block); void mangleTemplateParamDecl(const NamedDecl *Decl); void mangleLambda(const CXXRecordDecl *Lambda); - void mangleNestedName(const NamedDecl *ND, const DeclContext *DC, + void mangleNestedName(GlobalDecl GD, const DeclContext *DC, const AbiTagList *AdditionalAbiTags, bool NoFunction=false); void mangleNestedName(const TemplateDecl *TD, @@ -501,7 +502,7 @@ void manglePrefix(NestedNameSpecifier *qualifier); void manglePrefix(const DeclContext *DC, bool NoFunction=false); void manglePrefix(QualType type); - void mangleTemplatePrefix(const TemplateDecl *ND, bool NoFunction=false); + void mangleTemplatePrefix(GlobalDecl GD, bool NoFunction=false); void mangleTemplatePrefix(TemplateName Template); bool mangleUnresolvedTypeOrSimpleId(QualType DestroyedType, StringRef Prefix = ""); @@ -640,34 +641,36 @@ writeAbiTags(ND, AdditionalAbiTags); } -void CXXNameMangler::mangle(const NamedDecl *D) { +void CXXNameMangler::mangle(GlobalDecl GD) { // ::= _Z // ::= // ::= Out << "_Z"; - if (const FunctionDecl *FD = dyn_cast(D)) - mangleFunctionEncoding(FD); - else if (const VarDecl *VD = dyn_cast(D)) + if (const FunctionDecl *FD = dyn_cast(GD.getDecl())) + mangleFunctionEncoding(GD); + else if (const VarDecl *VD = dyn_cast(GD.getDecl())) mangleName(VD); - else if (const IndirectFieldDecl *IFD = dyn_cast(D)) + else if (const IndirectFieldDecl *IFD = + dyn_cast(GD.getDecl())) mangleName(IFD->getAnonField()); else - mangleName(cast(D)); + mangleName(cast(GD.getDecl())); } -void CXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) { +void CXXNameMangler::mangleFunctionEncoding(GlobalDecl GD) { + const FunctionDecl *FD = cast(GD.getDecl()); // ::= // Don't mangle in the type if this isn't a decl we should typically mangle. if (!Context.shouldMangleDeclName(FD)) { - mangleName(FD); + mangleName(GD); return; } AbiTagList ReturnTypeAbiTags = makeFunctionReturnTypeTags(FD); if (ReturnTypeAbiTags.empty()) { // There are no tags for return type, the simplest case. - mangleName(FD); + mangleName(GD); mangleFunctionEncodingBareType(FD); return; } @@ -787,13 +790,14 @@ return isStd(cast(DC)); } -static const TemplateDecl * -isTemplate(const NamedDecl *ND, const TemplateArgumentList *&TemplateArgs) { +static const GlobalDecl +isTemplate(GlobalDecl GD, const TemplateArgumentList *&TemplateArgs) { + const NamedDecl *ND = cast(GD.getDecl()); // Check if we have a function template. if (const FunctionDecl *FD = dyn_cast(ND)) { if (const TemplateDecl *TD = FD->getPrimaryTemplate()) { TemplateArgs = FD->getTemplateSpecializationArgs(); - return TD; + return GD.getWithDecl(TD); } } @@ -801,20 +805,21 @@ if (const ClassTemplateSpecializationDecl *Spec = dyn_cast(ND)) { TemplateArgs = &Spec->getTemplateArgs(); - return Spec->getSpecializedTemplate(); + return GD.getWithDecl(Spec->getSpecializedTemplate()); } // Check if we have a variable template. if (const VarTemplateSpecializationDecl *Spec = dyn_cast(ND)) { TemplateArgs = &Spec->getTemplateArgs(); - return Spec->getSpecializedTemplate(); + return GD.getWithDecl(Spec->getSpecializedTemplate()); } - return nullptr; + return GlobalDecl(); } -void CXXNameMangler::mangleName(const NamedDecl *ND) { +void CXXNameMangler::mangleName(GlobalDecl GD) { + const NamedDecl *ND = cast(GD.getDecl()); if (const VarDecl *VD = dyn_cast(ND)) { // Variables should have implicit tags from its type. AbiTagList VariableTypeAbiTags = makeVariableTypeTags(VD); @@ -843,12 +848,13 @@ // Output name with implicit tags. mangleNameWithAbiTags(VD, &AdditionalAbiTags); } else { - mangleNameWithAbiTags(ND, nullptr); + mangleNameWithAbiTags(GD, nullptr); } } -void CXXNameMangler::mangleNameWithAbiTags(const NamedDecl *ND, +void CXXNameMangler::mangleNameWithAbiTags(GlobalDecl GD, const AbiTagList *AdditionalAbiTags) { + const NamedDecl *ND = cast(GD.getDecl()); // ::= [] // ::= [] // ::= [] @@ -864,14 +870,14 @@ while (!DC->isNamespace() && !DC->isTranslationUnit()) DC = getEffectiveParentContext(DC); else if (GetLocalClassDecl(ND)) { - mangleLocalName(ND, AdditionalAbiTags); + mangleLocalName(GD, AdditionalAbiTags); return; } DC = IgnoreLinkageSpecDecls(DC); if (isLocalContainerContext(DC)) { - mangleLocalName(ND, AdditionalAbiTags); + mangleLocalName(GD, AdditionalAbiTags); return; } @@ -886,17 +892,17 @@ if (DC->isTranslationUnit() || isStdNamespace(DC)) { // Check if we have a template. const TemplateArgumentList *TemplateArgs = nullptr; - if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) { + if (GlobalDecl TD = isTemplate(GD, TemplateArgs)) { mangleUnscopedTemplateName(TD, AdditionalAbiTags); mangleTemplateArgs(*TemplateArgs); return; } - mangleUnscopedName(ND, AdditionalAbiTags); + mangleUnscopedName(GD, AdditionalAbiTags); return; } - mangleNestedName(ND, DC, AdditionalAbiTags); + mangleNestedName(GD, DC, AdditionalAbiTags); } void CXXNameMangler::mangleModuleName(const Module *M) { @@ -947,19 +953,21 @@ } } -void CXXNameMangler::mangleUnscopedName(const NamedDecl *ND, +void CXXNameMangler::mangleUnscopedName(GlobalDecl GD, const AbiTagList *AdditionalAbiTags) { + const NamedDecl *ND = cast(GD.getDecl()); // ::= // ::= St # ::std:: if (isStdNamespace(IgnoreLinkageSpecDecls(getEffectiveDeclContext(ND)))) Out << "St"; - mangleUnqualifiedName(ND, AdditionalAbiTags); + mangleUnqualifiedName(GD, AdditionalAbiTags); } void CXXNameMangler::mangleUnscopedTemplateName( - const TemplateDecl *ND, const AbiTagList *AdditionalAbiTags) { + GlobalDecl GD, const AbiTagList *AdditionalAbiTags) { + const TemplateDecl *ND = cast(GD.getDecl()); // ::= // ::= if (mangleSubstitution(ND)) @@ -971,9 +979,9 @@ "template template param cannot have abi tags"); mangleTemplateParameter(TTP->getDepth(), TTP->getIndex()); } else if (isa(ND) || isa(ND)) { - mangleUnscopedName(ND, AdditionalAbiTags); + mangleUnscopedName(GD, AdditionalAbiTags); } else { - mangleUnscopedName(ND->getTemplatedDecl(), AdditionalAbiTags); + mangleUnscopedName(GD.getWithDecl(ND->getTemplatedDecl()), AdditionalAbiTags); } addSubstitution(ND); @@ -1250,10 +1258,11 @@ mangleTemplateArgs(TemplateArgs, NumTemplateArgs); } -void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, +void CXXNameMangler::mangleUnqualifiedName(GlobalDecl GD, DeclarationName Name, unsigned KnownArity, const AbiTagList *AdditionalAbiTags) { + const NamedDecl *ND = cast_or_null(GD.getDecl()); unsigned Arity = KnownArity; // ::= // ::= @@ -1499,10 +1508,11 @@ Out << II->getLength() << II->getName(); } -void CXXNameMangler::mangleNestedName(const NamedDecl *ND, +void CXXNameMangler::mangleNestedName(GlobalDecl GD, const DeclContext *DC, const AbiTagList *AdditionalAbiTags, bool NoFunction) { + const NamedDecl *ND = cast(GD.getDecl()); // // ::= N [] [] E // ::= N [] [] @@ -1520,13 +1530,13 @@ // Check if we have a template. const TemplateArgumentList *TemplateArgs = nullptr; - if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) { + if (GlobalDecl TD = isTemplate(GD, TemplateArgs)) { mangleTemplatePrefix(TD, NoFunction); mangleTemplateArgs(*TemplateArgs); } else { manglePrefix(DC, NoFunction); - mangleUnqualifiedName(ND, AdditionalAbiTags); + mangleUnqualifiedName(GD, AdditionalAbiTags); } Out << 'E'; @@ -1544,8 +1554,24 @@ Out << 'E'; } -void CXXNameMangler::mangleLocalName(const Decl *D, +static GlobalDecl getParentOfLocalEntity(const DeclContext *DC) { + GlobalDecl GD; + // The Itanium spec says: + // For entities in constructors and destructors, the mangling of the + // complete object constructor or destructor is used as the base function + // name, i.e. the C1 or D1 version. + if (auto *CD = dyn_cast(DC)) + GD = GlobalDecl(CD, Ctor_Complete); + else if (auto *DD = dyn_cast(DC)) + GD = GlobalDecl(DD, Dtor_Complete); + else + GD = GlobalDecl(dyn_cast(DC)); + return GD; +} + +void CXXNameMangler::mangleLocalName(GlobalDecl GD, const AbiTagList *AdditionalAbiTags) { + const Decl *D = GD.getDecl(); // := Z E [] // := Z E s [] // := Z E d [ ] @@ -1565,7 +1591,7 @@ else if (const BlockDecl *BD = dyn_cast(DC)) mangleBlockForPrefix(BD); else - mangleFunctionEncoding(cast(DC)); + mangleFunctionEncoding(getParentOfLocalEntity(DC)); // Implicit ABI tags (from namespace) are not available in the following // entity; reset to actually emitted tags, which are available. @@ -1608,7 +1634,7 @@ mangleUnqualifiedBlock(BD); } else { const NamedDecl *ND = cast(D); - mangleNestedName(ND, getEffectiveDeclContext(ND), AdditionalAbiTags, + mangleNestedName(GD, getEffectiveDeclContext(ND), AdditionalAbiTags, true /*NoFunction*/); } } else if (const BlockDecl *BD = dyn_cast(D)) { @@ -1629,7 +1655,7 @@ assert(!AdditionalAbiTags && "Block cannot have additional abi tags"); mangleUnqualifiedBlock(BD); } else { - mangleUnqualifiedName(cast(D), AdditionalAbiTags); + mangleUnqualifiedName(GD, AdditionalAbiTags); } if (const NamedDecl *ND = dyn_cast(RD ? RD : D)) { @@ -1840,7 +1866,7 @@ // Check if we have a template. const TemplateArgumentList *TemplateArgs = nullptr; - if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) { + if (GlobalDecl TD = isTemplate(ND, TemplateArgs)) { mangleTemplatePrefix(TD); mangleTemplateArgs(*TemplateArgs); } else { @@ -1863,7 +1889,7 @@ if (OverloadedTemplateStorage *Overloaded = Template.getAsOverloadedTemplate()) { - mangleUnqualifiedName(nullptr, (*Overloaded->begin())->getDeclName(), + mangleUnqualifiedName(GlobalDecl(), (*Overloaded->begin())->getDeclName(), UnknownArity, nullptr); return; } @@ -1875,8 +1901,9 @@ mangleUnscopedTemplateName(Template, /* AdditionalAbiTags */ nullptr); } -void CXXNameMangler::mangleTemplatePrefix(const TemplateDecl *ND, +void CXXNameMangler::mangleTemplatePrefix(GlobalDecl GD, bool NoFunction) { + const TemplateDecl *ND = cast(GD.getDecl()); // ::=