diff -Nuar llvm-3.8.0.src.orig/tools/clang/lib/AST/ItaniumMangle.cpp llvm-3.8.0.src/tools/clang/lib/AST/ItaniumMangle.cpp --- llvm-3.8.0.src.orig/tools/clang/lib/AST/ItaniumMangle.cpp 2016-01-09 13:53:17.000000000 +0100 +++ llvm-3.8.0.src/tools/clang/lib/AST/ItaniumMangle.cpp 2016-07-10 23:59:08.412719561 +0200 @@ -212,6 +212,12 @@ class CXXNameMangler { ItaniumMangleContextImpl &Context; raw_ostream &Out; + bool NullOut = false; + /// In the "DisableDerivedAbiTags" mode derived ABI tags are not calculated. + /// This mode is used when mangler creates another mangler recursively to + /// calculate ABI tags for the function return value or the variable type. + /// Also it is required to avoid infinite recursion in some cases. + bool DisableDerivedAbiTags = false; /// The "structor" is the top-level declaration being mangled, if /// that's not a template specialization; otherwise it's the pattern @@ -261,15 +267,131 @@ } FunctionTypeDepth; + // abi_tag is a gcc attribute, taking one or more strings called "tags". + // The goal is to annotate against which version of a library an object was + // built and to be able to provide backwards compatibility ("dual abi"). + // For more information see docs/ItaniumMangleAbiTags.rst. + typedef SmallVector AbiTagList; + typedef llvm::SmallSetVector AbiTagSet; + + // State to gather all implicit and explicit tags used in a mangled name. + // Must always have an instance of this while emitting any name to keep + // track. + class AbiTagState final { + //! All abi tags used implicitly or explicitly + AbiTagSet UsedAbiTags; + //! All explicit abi tags (i.e. not from namespace) + AbiTagSet EmittedAbiTags; + + AbiTagState *&LinkHead; + AbiTagState *Parent = nullptr; + + bool LinkActive = false; + + public: + explicit AbiTagState(AbiTagState *&Head) : LinkHead(Head) { + Parent = LinkHead; + LinkHead = this; + LinkActive = true; + } + + // no copy, no move + AbiTagState(const AbiTagState &) = delete; + AbiTagState &operator=(const AbiTagState &) = delete; + + ~AbiTagState() { pop(); } + + void pop() { + if (!LinkActive) + return; + + assert(LinkHead == this && + "abi tag link head must point to us on destruction"); + LinkActive = false; + if (Parent) { + Parent->UsedAbiTags.insert(UsedAbiTags.begin(), UsedAbiTags.end()); + Parent->EmittedAbiTags.insert(EmittedAbiTags.begin(), + EmittedAbiTags.end()); + } + LinkHead = Parent; + } + + void write(raw_ostream &Out, const NamedDecl *ND, + const AbiTagList *AdditionalAbiTags) { + ND = cast(ND->getCanonicalDecl()); + + if (!isa(ND) && !isa(ND)) { + assert( + !AdditionalAbiTags && + "only function and variables need a list of additional abi tags"); + if (const auto *NS = dyn_cast(ND)) { + if (const auto *AbiTag = NS->getAttr()) { + for (const auto &Tag : AbiTag->tags()) { + UsedAbiTags.insert(Tag); + } + } + // Don't emit abi tags for namespaces. + return; + } + } + + AbiTagList TagList; + if (const auto *AbiTag = ND->getAttr()) { + for (const auto &Tag : AbiTag->tags()) { + UsedAbiTags.insert(Tag); + // AbiTag->tags() is sorted and has no duplicates + TagList.push_back(Tag); + } + } + + if (AdditionalAbiTags) { + for (const auto &Tag : *AdditionalAbiTags) { + UsedAbiTags.insert(Tag); + if (std::find(TagList.begin(), TagList.end(), Tag) == TagList.end()) { + // don't insert duplicates + TagList.push_back(Tag); + } + } + // AbiTag->tags() are already sorted; only add if we had additional tags + std::sort(TagList.begin(), TagList.end()); + } + + writeSortedUniqueAbiTags(Out, TagList); + } + + const AbiTagSet &getUsedAbiTags() const { return UsedAbiTags; } + void setUsedAbiTags(const AbiTagSet &AbiTags) { + UsedAbiTags = AbiTags; + } + + const AbiTagSet &getEmittedAbiTags() const { + return EmittedAbiTags; + } + + private: + template + void writeSortedUniqueAbiTags(raw_ostream &Out, TagList const &AbiTags) { + for (const auto &Tag : AbiTags) { + EmittedAbiTags.insert(Tag); + Out << "B"; + Out << Tag.size(); + Out << Tag; + } + } + }; + + AbiTagState *AbiTags = nullptr; + AbiTagState AbiTagsRoot; + llvm::DenseMap Substitutions; ASTContext &getASTContext() const { return Context.getASTContext(); } public: CXXNameMangler(ItaniumMangleContextImpl &C, raw_ostream &Out_, - const NamedDecl *D = nullptr) - : Context(C), Out(Out_), Structor(getStructor(D)), StructorType(0), - SeqID(0) { + const NamedDecl *D = nullptr, bool NullOut_ = false) + : Context(C), Out(Out_), NullOut(NullOut_), Structor(getStructor(D)), + StructorType(0), SeqID(0), AbiTagsRoot(AbiTags) { // These can't be mangled without a ctor type or dtor type. assert(!D || (!isa(D) && !isa(D))); @@ -277,11 +399,16 @@ CXXNameMangler(ItaniumMangleContextImpl &C, raw_ostream &Out_, const CXXConstructorDecl *D, CXXCtorType Type) : Context(C), Out(Out_), Structor(getStructor(D)), StructorType(Type), - SeqID(0) { } + SeqID(0), AbiTagsRoot(AbiTags) { } CXXNameMangler(ItaniumMangleContextImpl &C, raw_ostream &Out_, const CXXDestructorDecl *D, CXXDtorType Type) : Context(C), Out(Out_), Structor(getStructor(D)), StructorType(Type), - SeqID(0) { } + SeqID(0), AbiTagsRoot(AbiTags) { } + + CXXNameMangler(CXXNameMangler &Outer, llvm::raw_null_ostream &Out_) + : Context(Outer.Context), Out(Out_), NullOut(true), + Structor(Outer.Structor), StructorType(Outer.StructorType), + SeqID(Outer.SeqID), AbiTagsRoot(AbiTags) {} #if MANGLE_CHECKER ~CXXNameMangler() { @@ -296,14 +423,18 @@ #endif raw_ostream &getStream() { return Out; } + void disableDerivedAbiTags() { DisableDerivedAbiTags = true; } + static bool shouldHaveAbiTags(ItaniumMangleContextImpl &C, const VarDecl *VD); + void mangle(const NamedDecl *D); 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(const FunctionDecl *FD, + bool ExcludeUnqualifiedName = false); void mangleSeqID(unsigned SeqID); - void mangleName(const NamedDecl *ND); + void mangleName(const NamedDecl *ND, bool ExcludeUnqualifiedName = false); void mangleType(QualType T); void mangleNameOrStandardSubstitution(const NamedDecl *ND); @@ -334,31 +465,53 @@ DeclarationName name, unsigned KnownArity = UnknownArity); - void mangleName(const TemplateDecl *TD, - const TemplateArgument *TemplateArgs, - unsigned NumTemplateArgs); - void mangleUnqualifiedName(const NamedDecl *ND) { - mangleUnqualifiedName(ND, ND->getDeclName(), UnknownArity); + void mangleFunctionEncodingBareType(const FunctionDecl *FD); + + void mangleNameWithAbiTags(const NamedDecl *ND, + const AbiTagList *AdditionalAbiTags, + bool ExcludeUnqualifiedName); + void mangleTemplateName(const TemplateDecl *TD, + const AbiTagList *AdditionalAbiTags, + bool ExcludeUnqualifiedName, + const TemplateArgument *TemplateArgs, + unsigned NumTemplateArgs); + void mangleUnqualifiedName(const NamedDecl *ND, + const AbiTagList *AdditionalAbiTags) { + mangleUnqualifiedName(ND, ND->getDeclName(), UnknownArity, + AdditionalAbiTags); } void mangleUnqualifiedName(const NamedDecl *ND, DeclarationName Name, - unsigned KnownArity); - void mangleUnscopedName(const NamedDecl *ND); - void mangleUnscopedTemplateName(const TemplateDecl *ND); - void mangleUnscopedTemplateName(TemplateName); + unsigned KnownArity, + const AbiTagList *AdditionalAbiTags); + void mangleUnscopedName(const NamedDecl *ND, + const AbiTagList *AdditionalAbiTags); + void mangleUnscopedTemplateName(const TemplateDecl *ND, + const AbiTagList *AdditionalAbiTags); + void mangleUnscopedTemplateName(TemplateName, + const AbiTagList *AdditionalAbiTags); void mangleSourceName(const IdentifierInfo *II); - void mangleLocalName(const Decl *D); + void mangleLocalName(const Decl *D, + const AbiTagList *AdditionalAbiTags, + bool ExcludeUnqualifiedName); void mangleBlockForPrefix(const BlockDecl *Block); void mangleUnqualifiedBlock(const BlockDecl *Block); void mangleLambda(const CXXRecordDecl *Lambda); void mangleNestedName(const NamedDecl *ND, const DeclContext *DC, - bool NoFunction=false); + const AbiTagList *AdditionalAbiTags, + bool NoFunction, + bool ExcludeUnqualifiedName); void mangleNestedName(const TemplateDecl *TD, + const AbiTagList *AdditionalAbiTags, + bool ExcludeUnqualifiedName, const TemplateArgument *TemplateArgs, unsigned NumTemplateArgs); 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(const TemplateDecl *ND, + const AbiTagList *AdditionalAbiTags, + bool NoFunction = false, + bool ExcludeUnqualifiedName = false); void mangleTemplatePrefix(TemplateName Template); bool mangleUnresolvedTypeOrSimpleId(QualType DestroyedType, StringRef Prefix = ""); @@ -405,6 +558,13 @@ void mangleTemplateParameter(unsigned Index); void mangleFunctionParam(const ParmVarDecl *parm); + + void writeAbiTags(const NamedDecl *ND, + const AbiTagList *AdditionalAbiTags = nullptr); + + AbiTagSet getTagsFromPrefixAndTemplateArguments(const NamedDecl *ND); + AbiTagList makeAdditionalTagsForFunction(const FunctionDecl *FD); + AbiTagList makeAdditionalTagsForVariable(const VarDecl *VD); }; } @@ -448,6 +608,7 @@ while (!DC->isNamespace() && !DC->isTranslationUnit()) DC = getEffectiveParentContext(DC); if (DC->isTranslationUnit() && D->getFormalLinkage() != InternalLinkage && + !CXXNameMangler::shouldHaveAbiTags(*this, VD) && !isa(D)) return false; } @@ -455,6 +616,12 @@ return true; } +void CXXNameMangler::writeAbiTags(const NamedDecl *ND, + const AbiTagList *AdditionalAbiTags) { + assert(AbiTags && "require AbiTagState"); + AbiTags->write(Out, ND, DisableDerivedAbiTags ? nullptr : AdditionalAbiTags); +} + void CXXNameMangler::mangle(const NamedDecl *D) { // ::= _Z // ::= @@ -470,14 +637,31 @@ mangleName(cast(D)); } -void CXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) { - // ::= - mangleName(FD); - +void CXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD, + bool ExcludeUnqualifiedName) { // Don't mangle in the type if this isn't a decl we should typically mangle. - if (!Context.shouldMangleDeclName(FD)) + if (!Context.shouldMangleDeclName(FD)) { + mangleNameWithAbiTags(FD, /* AdditionalAbiTags */ nullptr, + ExcludeUnqualifiedName); return; + } + + // ::= + + if (ExcludeUnqualifiedName) { + // running makeAdditionalTagsForFunction would loop, don't need it here + // anyway + mangleNameWithAbiTags(FD, /* AdditionalAbiTags */ nullptr, + ExcludeUnqualifiedName); + } else { + AbiTagList AdditionalAbiTags = makeAdditionalTagsForFunction(FD); + mangleNameWithAbiTags(FD, &AdditionalAbiTags, ExcludeUnqualifiedName); + } + mangleFunctionEncodingBareType(FD); +} + +void CXXNameMangler::mangleFunctionEncodingBareType(const FunctionDecl *FD) { if (FD->hasAttr()) { FunctionTypeDepthState Saved = FunctionTypeDepth.push(); Out << "Ua9enable_ifI"; @@ -581,7 +765,24 @@ return nullptr; } -void CXXNameMangler::mangleName(const NamedDecl *ND) { +// Must not be run from mangleLocalName for the as it would loop +// otherwise. +void CXXNameMangler::mangleName(const NamedDecl *ND, + bool ExcludeUnqualifiedName) { + if (!ExcludeUnqualifiedName) { + if (const auto *VD = dyn_cast(ND)) { + AbiTagList VariableAdditionalAbiTags = makeAdditionalTagsForVariable(VD); + mangleNameWithAbiTags(VD, &VariableAdditionalAbiTags, + ExcludeUnqualifiedName); + return; + } + } + mangleNameWithAbiTags(ND, nullptr, ExcludeUnqualifiedName); +} + +void CXXNameMangler::mangleNameWithAbiTags(const NamedDecl *ND, + const AbiTagList *AdditionalAbiTags, + bool ExcludeUnqualifiedName) { // ::= // ::= // ::= @@ -597,7 +798,7 @@ while (!DC->isNamespace() && !DC->isTranslationUnit()) DC = getEffectiveParentContext(DC); else if (GetLocalClassDecl(ND)) { - mangleLocalName(ND); + mangleLocalName(ND, AdditionalAbiTags, ExcludeUnqualifiedName); return; } @@ -607,76 +808,93 @@ // Check if we have a template. const TemplateArgumentList *TemplateArgs = nullptr; if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) { - mangleUnscopedTemplateName(TD); + if (!ExcludeUnqualifiedName) + mangleUnscopedTemplateName(TD, AdditionalAbiTags); mangleTemplateArgs(*TemplateArgs); return; } - mangleUnscopedName(ND); + if (!ExcludeUnqualifiedName) + mangleUnscopedName(ND, AdditionalAbiTags); return; } if (isLocalContainerContext(DC)) { - mangleLocalName(ND); + mangleLocalName(ND, AdditionalAbiTags, ExcludeUnqualifiedName); return; } - mangleNestedName(ND, DC); + mangleNestedName(ND, DC, AdditionalAbiTags, /* NoFunction */ false, + ExcludeUnqualifiedName); } -void CXXNameMangler::mangleName(const TemplateDecl *TD, - const TemplateArgument *TemplateArgs, - unsigned NumTemplateArgs) { + +void CXXNameMangler::mangleTemplateName(const TemplateDecl *TD, + const AbiTagList *AdditionalAbiTags, + bool ExcludeUnqualifiedName, + const TemplateArgument *TemplateArgs, + unsigned NumTemplateArgs) { const DeclContext *DC = IgnoreLinkageSpecDecls(getEffectiveDeclContext(TD)); if (DC->isTranslationUnit() || isStdNamespace(DC)) { - mangleUnscopedTemplateName(TD); + if (!ExcludeUnqualifiedName) + mangleUnscopedTemplateName(TD, AdditionalAbiTags); mangleTemplateArgs(TemplateArgs, NumTemplateArgs); } else { - mangleNestedName(TD, TemplateArgs, NumTemplateArgs); + mangleNestedName(TD, AdditionalAbiTags, ExcludeUnqualifiedName, + TemplateArgs, NumTemplateArgs); } } -void CXXNameMangler::mangleUnscopedName(const NamedDecl *ND) { +void CXXNameMangler::mangleUnscopedName(const NamedDecl *ND, + const AbiTagList *AdditionalAbiTags) { // ::= // ::= St # ::std:: if (isStdNamespace(IgnoreLinkageSpecDecls(getEffectiveDeclContext(ND)))) Out << "St"; - mangleUnqualifiedName(ND); + mangleUnqualifiedName(ND, AdditionalAbiTags); } -void CXXNameMangler::mangleUnscopedTemplateName(const TemplateDecl *ND) { +void CXXNameMangler::mangleUnscopedTemplateName( + const TemplateDecl *ND, const AbiTagList *AdditionalAbiTags) { // ::= // ::= if (mangleSubstitution(ND)) return; // ::= - if (const auto *TTP = dyn_cast(ND)) + if (const auto *TTP = dyn_cast(ND)) { + assert(!AdditionalAbiTags && + "template template param cannot have abi tags"); mangleTemplateParameter(TTP->getIndex()); - else - mangleUnscopedName(ND->getTemplatedDecl()); + } else { + mangleUnscopedName(ND->getTemplatedDecl(), AdditionalAbiTags); + } addSubstitution(ND); } -void CXXNameMangler::mangleUnscopedTemplateName(TemplateName Template) { +void CXXNameMangler::mangleUnscopedTemplateName( + TemplateName Template, const AbiTagList *AdditionalAbiTags) { // ::= // ::= if (TemplateDecl *TD = Template.getAsTemplateDecl()) - return mangleUnscopedTemplateName(TD); + return mangleUnscopedTemplateName(TD, AdditionalAbiTags); if (mangleSubstitution(Template)) return; + assert(!AdditionalAbiTags && + "dependent template name cannot have abi tags"); + DependentTemplateName *Dependent = Template.getAsDependentTemplateName(); assert(Dependent && "Not a dependent template name?"); if (const IdentifierInfo *Id = Dependent->getIdentifier()) mangleSourceName(Id); else mangleOperatorName(Dependent->getOperator(), UnknownArity); - + addSubstitution(Template); } @@ -835,6 +1053,7 @@ else Out << "sr"; mangleSourceName(qualifier->getAsNamespace()->getIdentifier()); + writeAbiTags(qualifier->getAsNamespace()); break; case NestedNameSpecifier::NamespaceAlias: if (qualifier->getPrefix()) @@ -843,6 +1062,7 @@ else Out << "sr"; mangleSourceName(qualifier->getAsNamespaceAlias()->getIdentifier()); + writeAbiTags(qualifier->getAsNamespaceAlias()); break; case NestedNameSpecifier::TypeSpec: @@ -877,6 +1097,7 @@ Out << "sr"; mangleSourceName(qualifier->getAsIdentifier()); + // an Identifier has no type information, so we can't emit abi tags for it break; } @@ -922,7 +1143,8 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, DeclarationName Name, - unsigned KnownArity) { + unsigned KnownArity, + const AbiTagList *AdditionalAbiTags) { unsigned Arity = KnownArity; // ::= // ::= @@ -941,6 +1163,7 @@ Out << 'L'; mangleSourceName(II); + writeAbiTags(ND, AdditionalAbiTags); break; } @@ -980,6 +1203,7 @@ assert(FD->getIdentifier() && "Data member name isn't an identifier!"); mangleSourceName(FD->getIdentifier()); + // Not emitting abi tags: internal name anyway break; } @@ -1000,6 +1224,10 @@ assert(D->getDeclName().getAsIdentifierInfo() && "Typedef was not named!"); mangleSourceName(D->getDeclName().getAsIdentifierInfo()); + assert(!AdditionalAbiTags && "Type cannot have additional abi tags"); + // explicit abi tags are still possible; take from underlying type, not + // from typedef. + writeAbiTags(TD, nullptr); break; } @@ -1009,6 +1237,8 @@ // ::= + # Parameter types or 'v' for 'void'. if (const CXXRecordDecl *Record = dyn_cast(TD)) { if (Record->isLambda() && Record->getLambdaManglingNumber()) { + assert(!AdditionalAbiTags && + "Lambda type cannot have additional abi tags"); mangleLambda(Record); break; } @@ -1020,11 +1250,13 @@ if (UnnamedMangle > 1) Out << UnnamedMangle - 2; Out << '_'; + writeAbiTags(TD, AdditionalAbiTags); break; } - // Get a unique id for the anonymous struct. - unsigned AnonStructId = Context.getAnonymousStructId(TD); + // Get a unique id for the anonymous struct. If it is not a real output + // ID doesn't matter so use fake one. + unsigned AnonStructId = NullOut ? 0 : Context.getAnonymousStructId(TD); // Mangle it as a source name in the form // [n] $_ @@ -1052,6 +1284,7 @@ // Otherwise, use the complete constructor name. This is relevant if a // class with a constructor is declared within a constructor. mangleCXXCtorType(Ctor_Complete); + writeAbiTags(ND, AdditionalAbiTags); break; case DeclarationName::CXXDestructorName: @@ -1063,6 +1296,7 @@ // Otherwise, use the complete destructor name. This is relevant if a // class with a destructor is declared within a destructor. mangleCXXDtorType(Dtor_Complete); + writeAbiTags(ND, AdditionalAbiTags); break; case DeclarationName::CXXOperatorName: @@ -1078,6 +1312,7 @@ case DeclarationName::CXXConversionFunctionName: case DeclarationName::CXXLiteralOperatorName: mangleOperatorName(Name, Arity); + writeAbiTags(ND, AdditionalAbiTags); break; case DeclarationName::CXXUsingDirective: @@ -1094,7 +1329,9 @@ void CXXNameMangler::mangleNestedName(const NamedDecl *ND, const DeclContext *DC, - bool NoFunction) { + const AbiTagList *AdditionalAbiTags, + bool NoFunction, + bool ExcludeUnqualifiedName) { // // ::= N [] [] E // ::= N [] [] @@ -1114,30 +1351,36 @@ // Check if we have a template. const TemplateArgumentList *TemplateArgs = nullptr; if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) { - mangleTemplatePrefix(TD, NoFunction); + mangleTemplatePrefix(TD, AdditionalAbiTags, NoFunction, + ExcludeUnqualifiedName); mangleTemplateArgs(*TemplateArgs); } else { manglePrefix(DC, NoFunction); - mangleUnqualifiedName(ND); + if (!ExcludeUnqualifiedName) + mangleUnqualifiedName(ND, AdditionalAbiTags); } Out << 'E'; } void CXXNameMangler::mangleNestedName(const TemplateDecl *TD, + const AbiTagList *AdditionalAbiTags, + bool ExcludeUnqualifiedName, const TemplateArgument *TemplateArgs, unsigned NumTemplateArgs) { // ::= N [] E Out << 'N'; - mangleTemplatePrefix(TD); + mangleTemplatePrefix(TD, AdditionalAbiTags, ExcludeUnqualifiedName); mangleTemplateArgs(TemplateArgs, NumTemplateArgs); Out << 'E'; } -void CXXNameMangler::mangleLocalName(const Decl *D) { +void CXXNameMangler::mangleLocalName(const Decl *D, + const AbiTagList *AdditionalAbiTags, + bool ExcludeUnqualifiedName) { // := Z E [] // := Z E s [] // := Z E d [ ] @@ -1149,15 +1392,26 @@ Out << 'Z'; - if (const ObjCMethodDecl *MD = dyn_cast(DC)) - mangleObjCMethodName(MD); - else if (const BlockDecl *BD = dyn_cast(DC)) - mangleBlockForPrefix(BD); - else - mangleFunctionEncoding(cast(DC)); + { + AbiTagState LocalAbiTags(AbiTags); + + if (const ObjCMethodDecl *MD = dyn_cast(DC)) + mangleObjCMethodName(MD); + else if (const BlockDecl *BD = dyn_cast(DC)) + mangleBlockForPrefix(BD); + else + mangleFunctionEncoding(cast(DC)); + + // Implicit ABI tags (from namespace) are not available in the following + // entity; reset to actually emitted tags, which are available. + LocalAbiTags.setUsedAbiTags(LocalAbiTags.getEmittedAbiTags()); + } Out << 'E'; + // GCC 5.3.0 doesn't emit derived ABI tags for local names but that seems to + // be a bug that is fixed in trunk. + if (RD) { // The parameter number is omitted for the last parameter, 0 for the // second-to-last parameter, 1 for the third-to-last parameter, etc. The @@ -1182,13 +1436,17 @@ // Mangle the name relative to the closest enclosing function. // equality ok because RD derived from ND above if (D == RD) { - mangleUnqualifiedName(RD); + if (!ExcludeUnqualifiedName) + mangleUnqualifiedName(RD, AdditionalAbiTags); } else if (const BlockDecl *BD = dyn_cast(D)) { manglePrefix(getEffectiveDeclContext(BD), true /*NoFunction*/); - mangleUnqualifiedBlock(BD); + assert(!AdditionalAbiTags && "Block cannot have additional abi tags"); + if (!ExcludeUnqualifiedName) + mangleUnqualifiedBlock(BD); } else { const NamedDecl *ND = cast(D); - mangleNestedName(ND, getEffectiveDeclContext(ND), true /*NoFunction*/); + mangleNestedName(ND, getEffectiveDeclContext(ND), AdditionalAbiTags, + true /*NoFunction*/, ExcludeUnqualifiedName); } } else if (const BlockDecl *BD = dyn_cast(D)) { // Mangle a block in a default parameter; see above explanation for @@ -1205,30 +1463,37 @@ } } - mangleUnqualifiedBlock(BD); + assert(!AdditionalAbiTags && "Block cannot have additional abi tags"); + if (!ExcludeUnqualifiedName) + mangleUnqualifiedBlock(BD); } else { - mangleUnqualifiedName(cast(D)); + if (!ExcludeUnqualifiedName) + mangleUnqualifiedName(cast(D), AdditionalAbiTags); } - if (const NamedDecl *ND = dyn_cast(RD ? RD : D)) { - unsigned disc; - if (Context.getNextDiscriminator(ND, disc)) { - if (disc < 10) - Out << '_' << disc; - else - Out << "__" << disc << '_'; + if (!ExcludeUnqualifiedName) { + if (const NamedDecl *ND = dyn_cast(RD ? RD : D)) { + unsigned disc; + if (Context.getNextDiscriminator(ND, disc)) { + if (disc < 10) + Out << '_' << disc; + else + Out << "__" << disc << '_'; + } } } } void CXXNameMangler::mangleBlockForPrefix(const BlockDecl *Block) { if (GetLocalClassDecl(Block)) { - mangleLocalName(Block); + mangleLocalName(Block, /* AdditionalAbiTags */ nullptr, + /* ExcludeUnqualifiedName */ false); return; } const DeclContext *DC = getEffectiveDeclContext(Block); if (isLocalContainerContext(DC)) { - mangleLocalName(Block); + mangleLocalName(Block, /* AdditionalAbiTags */ nullptr, + /* ExcludeUnqualifiedName */ false); return; } manglePrefix(getEffectiveDeclContext(Block)); @@ -1239,10 +1504,11 @@ if (Decl *Context = Block->getBlockManglingContextDecl()) { if ((isa(Context) || isa(Context)) && Context->getDeclContext()->isRecord()) { - if (const IdentifierInfo *Name - = cast(Context)->getIdentifier()) { + const auto *ND = cast(Context); + if (const IdentifierInfo *Name = ND->getIdentifier()) { mangleSourceName(Name); - Out << 'M'; + writeAbiTags(ND, /* AdditionalAbiTags */ nullptr); + Out << 'M'; } } } @@ -1275,7 +1541,7 @@ if (const IdentifierInfo *Name = cast(Context)->getIdentifier()) { mangleSourceName(Name); - Out << 'M'; + Out << 'M'; } } } @@ -1358,11 +1624,11 @@ // Check if we have a template. const TemplateArgumentList *TemplateArgs = nullptr; if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) { - mangleTemplatePrefix(TD); + mangleTemplatePrefix(TD, /* AdditionalAbiTags */ nullptr); mangleTemplateArgs(*TemplateArgs); } else { manglePrefix(getEffectiveDeclContext(ND), NoFunction); - mangleUnqualifiedName(ND); + mangleUnqualifiedName(ND, /* AdditionalAbiTags */ nullptr); } addSubstitution(ND); @@ -1373,27 +1639,30 @@ // ::= // ::= if (TemplateDecl *TD = Template.getAsTemplateDecl()) - return mangleTemplatePrefix(TD); + return mangleTemplatePrefix(TD, /* AdditionalAbiTags */ nullptr); if (QualifiedTemplateName *Qualified = Template.getAsQualifiedTemplateName()) manglePrefix(Qualified->getQualifier()); - + if (OverloadedTemplateStorage *Overloaded = Template.getAsOverloadedTemplate()) { mangleUnqualifiedName(nullptr, (*Overloaded->begin())->getDeclName(), - UnknownArity); + UnknownArity, + /* AdditionalAbiTags */ nullptr); return; } - + DependentTemplateName *Dependent = Template.getAsDependentTemplateName(); assert(Dependent && "Unknown template name kind?"); if (NestedNameSpecifier *Qualifier = Dependent->getQualifier()) manglePrefix(Qualifier); - mangleUnscopedTemplateName(Template); + mangleUnscopedTemplateName(Template, /* AdditionalAbiTags */ nullptr); } void CXXNameMangler::mangleTemplatePrefix(const TemplateDecl *ND, - bool NoFunction) { + const AbiTagList *AdditionalAbiTags, + bool NoFunction, + bool ExcludeUnqualifiedName) { // ::=