<div dir="ltr"><span style="font-size:12.800000190734863px">Hi Dmitry,</span><div style="font-size:12.800000190734863px"><br></div><div style="font-size:12.800000190734863px">I think that this commit has caused a regression that's tracked by PR 30440. I'll try working on a fix for it.</div><div><br></div><div>Alex</div><span class="gmail-HOEnZb" style="font-size:12.800000190734863px"><font color="#888888"></font></span></div><div class="gmail_extra"><br><div class="gmail_quote">On 30 June 2016 at 02:40, Dmitry Polukhin via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: dpolukhin<br>
Date: Thu Jun 30 04:40:38 2016<br>
New Revision: 274222<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=274222&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=274222&view=rev</a><br>
Log:<br>
[GCC] PR23529 Mangler part of attrbute abi_tag support<br>
<br>
Original patch by Stefan Bühler <a href="http://reviews.llvm.org/D12834" rel="noreferrer" target="_blank">http://reviews.llvm.org/D12834</a><br>
<br>
Difference between original and this one:<br>
- fixed all failing tests<br>
- fixed mangling for global variable outside namespace<br>
- emit ABI tags for guards and local names<br>
- clang-format + other stylistic changes<br>
- significantly reworked patch according to Richard's suggestions<br>
<br>
Sema part, committed before <a href="http://reviews.llvm.org/D17567" rel="noreferrer" target="_blank">http://reviews.llvm.org/D17567</a><br>
<br>
Differential revision: <a href="http://reviews.llvm.org/D18035" rel="noreferrer" target="_blank">http://reviews.llvm.org/D18035</a><br>
<br>
Added:<br>
cfe/trunk/test/CodeGenCXX/<wbr>mangle-abi-tag.cpp (with props)<br>
Modified:<br>
cfe/trunk/lib/AST/<wbr>ItaniumMangle.cpp<br>
cfe/trunk/lib/Sema/<wbr>SemaDeclAttr.cpp<br>
cfe/trunk/test/PCH/attrs.c<br>
cfe/trunk/test/SemaCXX/attr-<wbr>abi-tag-syntax.cpp<br>
<br>
Modified: cfe/trunk/lib/AST/<wbr>ItaniumMangle.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=274222&r1=274221&r2=274222&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/AST/<wbr>ItaniumMangle.cpp?rev=274222&<wbr>r1=274221&r2=274222&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/AST/<wbr>ItaniumMangle.cpp (original)<br>
+++ cfe/trunk/lib/AST/<wbr>ItaniumMangle.cpp Thu Jun 30 04:40:38 2016<br>
@@ -214,6 +214,12 @@ public:<br>
class CXXNameMangler {<br>
ItaniumMangleContextImpl &Context;<br>
raw_ostream &Out;<br>
+ bool NullOut = false;<br>
+ /// In the "DisableDerivedAbiTags" mode derived ABI tags are not calculated.<br>
+ /// This mode is used when mangler creates another mangler recursively to<br>
+ /// calculate ABI tags for the function return value or the variable type.<br>
+ /// Also it is required to avoid infinite recursion in some cases.<br>
+ bool DisableDerivedAbiTags = false;<br>
<br>
/// The "structor" is the top-level declaration being mangled, if<br>
/// that's not a template specialization; otherwise it's the pattern<br>
@@ -263,15 +269,126 @@ class CXXNameMangler {<br>
<br>
} FunctionTypeDepth;<br>
<br>
+ // abi_tag is a gcc attribute, taking one or more strings called "tags".<br>
+ // The goal is to annotate against which version of a library an object was<br>
+ // built and to be able to provide backwards compatibility ("dual abi").<br>
+ // For more information see docs/ItaniumMangleAbiTags.rst.<br>
+ typedef SmallVector<StringRef, 4> AbiTagList;<br>
+<br>
+ // State to gather all implicit and explicit tags used in a mangled name.<br>
+ // Must always have an instance of this while emitting any name to keep<br>
+ // track.<br>
+ class AbiTagState final {<br>
+ public:<br>
+ explicit AbiTagState(AbiTagState *&Head) : LinkHead(Head) {<br>
+ Parent = LinkHead;<br>
+ LinkHead = this;<br>
+ }<br>
+<br>
+ // No copy, no move.<br>
+ AbiTagState(const AbiTagState &) = delete;<br>
+ AbiTagState &operator=(const AbiTagState &) = delete;<br>
+<br>
+ ~AbiTagState() { pop(); }<br>
+<br>
+ void write(raw_ostream &Out, const NamedDecl *ND,<br>
+ const AbiTagList *AdditionalAbiTags) {<br>
+ ND = cast<NamedDecl>(ND-><wbr>getCanonicalDecl());<br>
+ if (!isa<FunctionDecl>(ND) && !isa<VarDecl>(ND)) {<br>
+ assert(<br>
+ !AdditionalAbiTags &&<br>
+ "only function and variables need a list of additional abi tags");<br>
+ if (const auto *NS = dyn_cast<NamespaceDecl>(ND)) {<br>
+ if (const auto *AbiTag = NS->getAttr<AbiTagAttr>()) {<br>
+ UsedAbiTags.insert(<wbr>UsedAbiTags.end(), AbiTag->tags().begin(),<br>
+ AbiTag->tags().end());<br>
+ }<br>
+ // Don't emit abi tags for namespaces.<br>
+ return;<br>
+ }<br>
+ }<br>
+<br>
+ AbiTagList TagList;<br>
+ if (const auto *AbiTag = ND->getAttr<AbiTagAttr>()) {<br>
+ UsedAbiTags.insert(<wbr>UsedAbiTags.end(), AbiTag->tags().begin(),<br>
+ AbiTag->tags().end());<br>
+ TagList.insert(TagList.end(), AbiTag->tags().begin(),<br>
+ AbiTag->tags().end());<br>
+ }<br>
+<br>
+ if (AdditionalAbiTags) {<br>
+ UsedAbiTags.insert(<wbr>UsedAbiTags.end(), AdditionalAbiTags->begin(),<br>
+ AdditionalAbiTags->end());<br>
+ TagList.insert(TagList.end(), AdditionalAbiTags->begin(),<br>
+ AdditionalAbiTags->end());<br>
+ }<br>
+<br>
+ std::sort(TagList.begin(), TagList.end());<br>
+ TagList.erase(std::unique(<wbr>TagList.begin(), TagList.end()), TagList.end());<br>
+<br>
+ writeSortedUniqueAbiTags(Out, TagList);<br>
+ }<br>
+<br>
+ const AbiTagList &getUsedAbiTags() const { return UsedAbiTags; }<br>
+ void setUsedAbiTags(const AbiTagList &AbiTags) {<br>
+ UsedAbiTags = AbiTags;<br>
+ }<br>
+<br>
+ const AbiTagList &getEmittedAbiTags() const {<br>
+ return EmittedAbiTags;<br>
+ }<br>
+<br>
+ const AbiTagList &getSortedUniqueUsedAbiTags() {<br>
+ std::sort(UsedAbiTags.begin(), UsedAbiTags.end());<br>
+ UsedAbiTags.erase(std::unique(<wbr>UsedAbiTags.begin(), UsedAbiTags.end()),<br>
+ UsedAbiTags.end());<br>
+ return UsedAbiTags;<br>
+ }<br>
+<br>
+ private:<br>
+ //! All abi tags used implicitly or explicitly.<br>
+ AbiTagList UsedAbiTags;<br>
+ //! All explicit abi tags (i.e. not from namespace).<br>
+ AbiTagList EmittedAbiTags;<br>
+<br>
+ AbiTagState *&LinkHead;<br>
+ AbiTagState *Parent = nullptr;<br>
+<br>
+ void pop() {<br>
+ assert(LinkHead == this &&<br>
+ "abi tag link head must point to us on destruction");<br>
+ if (Parent) {<br>
+ Parent->UsedAbiTags.insert(<wbr>Parent->UsedAbiTags.end(),<br>
+ UsedAbiTags.begin(), UsedAbiTags.end());<br>
+ Parent->EmittedAbiTags.insert(<wbr>Parent->EmittedAbiTags.end(),<br>
+ EmittedAbiTags.begin(),<br>
+ EmittedAbiTags.end());<br>
+ }<br>
+ LinkHead = Parent;<br>
+ }<br>
+<br>
+ void writeSortedUniqueAbiTags(raw_<wbr>ostream &Out, const AbiTagList &AbiTags) {<br>
+ for (const auto &Tag : AbiTags) {<br>
+ EmittedAbiTags.push_back(Tag);<br>
+ Out << "B";<br>
+ Out << Tag.size();<br>
+ Out << Tag;<br>
+ }<br>
+ }<br>
+ };<br>
+<br>
+ AbiTagState *AbiTags = nullptr;<br>
+ AbiTagState AbiTagsRoot;<br>
+<br>
llvm::DenseMap<uintptr_t, unsigned> Substitutions;<br>
<br>
ASTContext &getASTContext() const { return Context.getASTContext(); }<br>
<br>
public:<br>
CXXNameMangler(<wbr>ItaniumMangleContextImpl &C, raw_ostream &Out_,<br>
- const NamedDecl *D = nullptr)<br>
- : Context(C), Out(Out_), Structor(getStructor(D)), StructorType(0),<br>
- SeqID(0) {<br>
+ const NamedDecl *D = nullptr, bool NullOut_ = false)<br>
+ : Context(C), Out(Out_), NullOut(NullOut_), Structor(getStructor(D)),<br>
+ StructorType(0), SeqID(0), AbiTagsRoot(AbiTags) {<br>
// These can't be mangled without a ctor type or dtor type.<br>
assert(!D || (!isa<CXXDestructorDecl>(D) &&<br>
!isa<CXXConstructorDecl>(D)));<br>
@@ -279,11 +396,21 @@ public:<br>
CXXNameMangler(<wbr>ItaniumMangleContextImpl &C, raw_ostream &Out_,<br>
const CXXConstructorDecl *D, CXXCtorType Type)<br>
: Context(C), Out(Out_), Structor(getStructor(D)), StructorType(Type),<br>
- SeqID(0) { }<br>
+ SeqID(0), AbiTagsRoot(AbiTags) { }<br>
CXXNameMangler(<wbr>ItaniumMangleContextImpl &C, raw_ostream &Out_,<br>
const CXXDestructorDecl *D, CXXDtorType Type)<br>
: Context(C), Out(Out_), Structor(getStructor(D)), StructorType(Type),<br>
- SeqID(0) { }<br>
+ SeqID(0), AbiTagsRoot(AbiTags) { }<br>
+<br>
+ CXXNameMangler(CXXNameMangler &Outer, raw_ostream &Out_)<br>
+ : Context(Outer.Context), Out(Out_), NullOut(false),<br>
+ Structor(Outer.Structor), StructorType(Outer.<wbr>StructorType),<br>
+ SeqID(Outer.SeqID), AbiTagsRoot(AbiTags) {}<br>
+<br>
+ CXXNameMangler(CXXNameMangler &Outer, llvm::raw_null_ostream &Out_)<br>
+ : Context(Outer.Context), Out(Out_), NullOut(true),<br>
+ Structor(Outer.Structor), StructorType(Outer.<wbr>StructorType),<br>
+ SeqID(Outer.SeqID), AbiTagsRoot(AbiTags) {}<br>
<br>
#if MANGLE_CHECKER<br>
~CXXNameMangler() {<br>
@@ -298,6 +425,9 @@ public:<br>
#endif<br>
raw_ostream &getStream() { return Out; }<br>
<br>
+ void disableDerivedAbiTags() { DisableDerivedAbiTags = true; }<br>
+ static bool shouldHaveAbiTags(<wbr>ItaniumMangleContextImpl &C, const VarDecl *VD);<br>
+<br>
void mangle(const NamedDecl *D);<br>
void mangleCallOffset(int64_t NonVirtual, int64_t Virtual);<br>
void mangleNumber(const llvm::APSInt &I);<br>
@@ -335,23 +465,37 @@ private:<br>
DeclarationName name,<br>
unsigned KnownArity = UnknownArity);<br>
<br>
- void mangleName(const TemplateDecl *TD,<br>
- const TemplateArgument *TemplateArgs,<br>
- unsigned NumTemplateArgs);<br>
- void mangleUnqualifiedName(const NamedDecl *ND) {<br>
- mangleUnqualifiedName(ND, ND->getDeclName(), UnknownArity);<br>
+ void mangleFunctionEncodingBareType<wbr>(const FunctionDecl *FD);<br>
+<br>
+ void mangleNameWithAbiTags(const NamedDecl *ND,<br>
+ const AbiTagList *AdditionalAbiTags);<br>
+ void mangleTemplateName(const TemplateDecl *TD,<br>
+ const TemplateArgument *TemplateArgs,<br>
+ unsigned NumTemplateArgs);<br>
+ void mangleUnqualifiedName(const NamedDecl *ND,<br>
+ const AbiTagList *AdditionalAbiTags) {<br>
+ mangleUnqualifiedName(ND, ND->getDeclName(), UnknownArity,<br>
+ AdditionalAbiTags);<br>
}<br>
void mangleUnqualifiedName(const NamedDecl *ND, DeclarationName Name,<br>
- unsigned KnownArity);<br>
- void mangleUnscopedName(const NamedDecl *ND);<br>
- void mangleUnscopedTemplateName(<wbr>const TemplateDecl *ND);<br>
- void mangleUnscopedTemplateName(<wbr>TemplateName);<br>
+ unsigned KnownArity,<br>
+ const AbiTagList *AdditionalAbiTags);<br>
+ void mangleUnscopedName(const NamedDecl *ND,<br>
+ const AbiTagList *AdditionalAbiTags);<br>
+ void mangleUnscopedTemplateName(<wbr>const TemplateDecl *ND,<br>
+ const AbiTagList *AdditionalAbiTags);<br>
+ void mangleUnscopedTemplateName(<wbr>TemplateName,<br>
+ const AbiTagList *AdditionalAbiTags);<br>
void mangleSourceName(const IdentifierInfo *II);<br>
- void mangleLocalName(const Decl *D);<br>
+ void mangleSourceNameWithAbiTags(<br>
+ const NamedDecl *ND, const AbiTagList *AdditionalAbiTags = nullptr);<br>
+ void mangleLocalName(const Decl *D,<br>
+ const AbiTagList *AdditionalAbiTags);<br>
void mangleBlockForPrefix(const BlockDecl *Block);<br>
void mangleUnqualifiedBlock(const BlockDecl *Block);<br>
void mangleLambda(const CXXRecordDecl *Lambda);<br>
void mangleNestedName(const NamedDecl *ND, const DeclContext *DC,<br>
+ const AbiTagList *AdditionalAbiTags,<br>
bool NoFunction=false);<br>
void mangleNestedName(const TemplateDecl *TD,<br>
const TemplateArgument *TemplateArgs,<br>
@@ -410,6 +554,14 @@ private:<br>
void mangleTemplateParameter(<wbr>unsigned Index);<br>
<br>
void mangleFunctionParam(const ParmVarDecl *parm);<br>
+<br>
+ void writeAbiTags(const NamedDecl *ND,<br>
+ const AbiTagList *AdditionalAbiTags);<br>
+<br>
+ // Returns sorted unique list of ABI tags.<br>
+ AbiTagList makeFunctionReturnTypeTags(<wbr>const FunctionDecl *FD);<br>
+ // Returns sorted unique list of ABI tags.<br>
+ AbiTagList makeVariableTypeTags(const VarDecl *VD);<br>
};<br>
<br>
}<br>
@@ -453,6 +605,7 @@ bool ItaniumMangleContextImpl::<wbr>shouldMan<br>
while (!DC->isNamespace() && !DC->isTranslationUnit())<br>
DC = getEffectiveParentContext(DC);<br>
if (DC->isTranslationUnit() && D->getFormalLinkage() != InternalLinkage &&<br>
+ !CXXNameMangler::<wbr>shouldHaveAbiTags(*this, VD) &&<br>
!isa<<wbr>VarTemplateSpecializationDecl><wbr>(D))<br>
return false;<br>
}<br>
@@ -460,6 +613,18 @@ bool ItaniumMangleContextImpl::<wbr>shouldMan<br>
return true;<br>
}<br>
<br>
+void CXXNameMangler::writeAbiTags(<wbr>const NamedDecl *ND,<br>
+ const AbiTagList *AdditionalAbiTags) {<br>
+ assert(AbiTags && "require AbiTagState");<br>
+ AbiTags->write(Out, ND, DisableDerivedAbiTags ? nullptr : AdditionalAbiTags);<br>
+}<br>
+<br>
+void CXXNameMangler::<wbr>mangleSourceNameWithAbiTags(<br>
+ const NamedDecl *ND, const AbiTagList *AdditionalAbiTags) {<br>
+ mangleSourceName(ND-><wbr>getIdentifier());<br>
+ writeAbiTags(ND, AdditionalAbiTags);<br>
+}<br>
+<br>
void CXXNameMangler::mangle(const NamedDecl *D) {<br>
// <mangled-name> ::= _Z <encoding><br>
// ::= <data name><br>
@@ -477,12 +642,52 @@ void CXXNameMangler::mangle(const NamedD<br>
<br>
void CXXNameMangler::<wbr>mangleFunctionEncoding(const FunctionDecl *FD) {<br>
// <encoding> ::= <function name> <bare-function-type><br>
- mangleName(FD);<br>
<br>
// Don't mangle in the type if this isn't a decl we should typically mangle.<br>
- if (!Context.<wbr>shouldMangleDeclName(FD))<br>
+ if (!Context.<wbr>shouldMangleDeclName(FD)) {<br>
+ mangleName(FD);<br>
+ return;<br>
+ }<br>
+<br>
+ AbiTagList ReturnTypeAbiTags = makeFunctionReturnTypeTags(FD)<wbr>;<br>
+ if (ReturnTypeAbiTags.empty()) {<br>
+ // There are no tags for return type, the simplest case.<br>
+ mangleName(FD);<br>
+ mangleFunctionEncodingBareType<wbr>(FD);<br>
return;<br>
+ }<br>
+<br>
+ // Mangle function name and encoding to temporary buffer.<br>
+ // We have to output name and encoding to the same mangler to get the same<br>
+ // substitution as it will be in final mangling.<br>
+ SmallString<256> FunctionEncodingBuf;<br>
+ llvm::raw_svector_ostream FunctionEncodingStream(<wbr>FunctionEncodingBuf);<br>
+ CXXNameMangler FunctionEncodingMangler(*this, FunctionEncodingStream);<br>
+ // Output name of the function.<br>
+ FunctionEncodingMangler.<wbr>disableDerivedAbiTags();<br>
+ FunctionEncodingMangler.<wbr>mangleNameWithAbiTags(FD, nullptr);<br>
+<br>
+ // Remember length of the function name in the buffer.<br>
+ size_t EncodingPositionStart = FunctionEncodingStream.str().<wbr>size();<br>
+ FunctionEncodingMangler.<wbr>mangleFunctionEncodingBareType<wbr>(FD);<br>
+<br>
+ // Get tags from return type that are not present in function name or<br>
+ // encoding.<br>
+ const AbiTagList &UsedAbiTags =<br>
+ FunctionEncodingMangler.<wbr>AbiTagsRoot.<wbr>getSortedUniqueUsedAbiTags();<br>
+ AbiTagList AdditionalAbiTags(<wbr>ReturnTypeAbiTags.size());<br>
+ AdditionalAbiTags.erase(<br>
+ std::set_difference(<wbr>ReturnTypeAbiTags.begin(), ReturnTypeAbiTags.end(),<br>
+ UsedAbiTags.begin(), UsedAbiTags.end(),<br>
+ AdditionalAbiTags.begin()),<br>
+ AdditionalAbiTags.end());<br>
+<br>
+ // Output name with implicit tags and function encoding from temporary buffer.<br>
+ mangleNameWithAbiTags(FD, &AdditionalAbiTags);<br>
+ Out << FunctionEncodingStream.str().<wbr>substr(EncodingPositionStart);<br>
+}<br>
<br>
+void CXXNameMangler::<wbr>mangleFunctionEncodingBareType<wbr>(const FunctionDecl *FD) {<br>
if (FD->hasAttr<EnableIfAttr>()) {<br>
FunctionTypeDepthState Saved = FunctionTypeDepth.push();<br>
Out << "Ua9enable_ifI";<br>
@@ -593,6 +798,40 @@ isTemplate(const NamedDecl *ND, const Te<br>
}<br>
<br>
void CXXNameMangler::mangleName(<wbr>const NamedDecl *ND) {<br>
+ if (const VarDecl *VD = dyn_cast<VarDecl>(ND)) {<br>
+ // Variables should have implicit tags from its type.<br>
+ AbiTagList VariableTypeAbiTags = makeVariableTypeTags(VD);<br>
+ if (VariableTypeAbiTags.empty()) {<br>
+ // Simple case no variable type tags.<br>
+ mangleNameWithAbiTags(VD, nullptr);<br>
+ return;<br>
+ }<br>
+<br>
+ // Mangle variable name to null stream to collect tags.<br>
+ llvm::raw_null_ostream NullOutStream;<br>
+ CXXNameMangler VariableNameMangler(*this, NullOutStream);<br>
+ VariableNameMangler.<wbr>disableDerivedAbiTags();<br>
+ VariableNameMangler.<wbr>mangleNameWithAbiTags(VD, nullptr);<br>
+<br>
+ // Get tags from variable type that are not present in its name.<br>
+ const AbiTagList &UsedAbiTags =<br>
+ VariableNameMangler.<wbr>AbiTagsRoot.<wbr>getSortedUniqueUsedAbiTags();<br>
+ AbiTagList AdditionalAbiTags(<wbr>VariableTypeAbiTags.size());<br>
+ AdditionalAbiTags.erase(<br>
+ std::set_difference(<wbr>VariableTypeAbiTags.begin(),<br>
+ VariableTypeAbiTags.end(), UsedAbiTags.begin(),<br>
+ UsedAbiTags.end(), AdditionalAbiTags.begin()),<br>
+ AdditionalAbiTags.end());<br>
+<br>
+ // Output name with implicit tags.<br>
+ mangleNameWithAbiTags(VD, &AdditionalAbiTags);<br>
+ } else {<br>
+ mangleNameWithAbiTags(ND, nullptr);<br>
+ }<br>
+}<br>
+<br>
+void CXXNameMangler::<wbr>mangleNameWithAbiTags(const NamedDecl *ND,<br>
+ const AbiTagList *AdditionalAbiTags) {<br>
// <name> ::= <nested-name><br>
// ::= <unscoped-name><br>
// ::= <unscoped-template-name> <template-args><br>
@@ -608,7 +847,7 @@ void CXXNameMangler::mangleName(<wbr>const Na<br>
while (!DC->isNamespace() && !DC->isTranslationUnit())<br>
DC = getEffectiveParentContext(DC);<br>
else if (GetLocalClassDecl(ND)) {<br>
- mangleLocalName(ND);<br>
+ mangleLocalName(ND, AdditionalAbiTags);<br>
return;<br>
}<br>
<br>
@@ -618,76 +857,86 @@ void CXXNameMangler::mangleName(<wbr>const Na<br>
// Check if we have a template.<br>
const TemplateArgumentList *TemplateArgs = nullptr;<br>
if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) {<br>
- mangleUnscopedTemplateName(TD)<wbr>;<br>
+ mangleUnscopedTemplateName(TD, AdditionalAbiTags);<br>
mangleTemplateArgs(*<wbr>TemplateArgs);<br>
return;<br>
}<br>
<br>
- mangleUnscopedName(ND);<br>
+ mangleUnscopedName(ND, AdditionalAbiTags);<br>
return;<br>
}<br>
<br>
if (isLocalContainerContext(DC)) {<br>
- mangleLocalName(ND);<br>
+ mangleLocalName(ND, AdditionalAbiTags);<br>
return;<br>
}<br>
<br>
- mangleNestedName(ND, DC);<br>
+ mangleNestedName(ND, DC, AdditionalAbiTags);<br>
}<br>
-void CXXNameMangler::mangleName(<wbr>const TemplateDecl *TD,<br>
- const TemplateArgument *TemplateArgs,<br>
- unsigned NumTemplateArgs) {<br>
+<br>
+void CXXNameMangler::<wbr>mangleTemplateName(const TemplateDecl *TD,<br>
+ const TemplateArgument *TemplateArgs,<br>
+ unsigned NumTemplateArgs) {<br>
const DeclContext *DC = IgnoreLinkageSpecDecls(<wbr>getEffectiveDeclContext(TD));<br>
<br>
if (DC->isTranslationUnit() || isStdNamespace(DC)) {<br>
- mangleUnscopedTemplateName(TD)<wbr>;<br>
+ mangleUnscopedTemplateName(TD, nullptr);<br>
mangleTemplateArgs(<wbr>TemplateArgs, NumTemplateArgs);<br>
} else {<br>
mangleNestedName(TD, TemplateArgs, NumTemplateArgs);<br>
}<br>
}<br>
<br>
-void CXXNameMangler::<wbr>mangleUnscopedName(const NamedDecl *ND) {<br>
+void CXXNameMangler::<wbr>mangleUnscopedName(const NamedDecl *ND,<br>
+ const AbiTagList *AdditionalAbiTags) {<br>
// <unscoped-name> ::= <unqualified-name><br>
// ::= St <unqualified-name> # ::std::<br>
<br>
if (isStdNamespace(<wbr>IgnoreLinkageSpecDecls(<wbr>getEffectiveDeclContext(ND))))<br>
Out << "St";<br>
<br>
- mangleUnqualifiedName(ND);<br>
+ mangleUnqualifiedName(ND, AdditionalAbiTags);<br>
}<br>
<br>
-void CXXNameMangler::<wbr>mangleUnscopedTemplateName(<wbr>const TemplateDecl *ND) {<br>
+void CXXNameMangler::<wbr>mangleUnscopedTemplateName(<br>
+ const TemplateDecl *ND, const AbiTagList *AdditionalAbiTags) {<br>
// <unscoped-template-name> ::= <unscoped-name><br>
// ::= <substitution><br>
if (mangleSubstitution(ND))<br>
return;<br>
<br>
// <template-template-param> ::= <template-param><br>
- if (const auto *TTP = dyn_cast<<wbr>TemplateTemplateParmDecl>(ND))<br>
+ if (const auto *TTP = dyn_cast<<wbr>TemplateTemplateParmDecl>(ND)) {<br>
+ assert(!AdditionalAbiTags &&<br>
+ "template template param cannot have abi tags");<br>
mangleTemplateParameter(TTP-><wbr>getIndex());<br>
- else<br>
- mangleUnscopedName(ND-><wbr>getTemplatedDecl());<br>
+ } else {<br>
+ mangleUnscopedName(ND-><wbr>getTemplatedDecl(), AdditionalAbiTags);<br>
+ }<br>
<br>
addSubstitution(ND);<br>
}<br>
<br>
-void CXXNameMangler::<wbr>mangleUnscopedTemplateName(<wbr>TemplateName Template) {<br>
+void CXXNameMangler::<wbr>mangleUnscopedTemplateName(<br>
+ TemplateName Template, const AbiTagList *AdditionalAbiTags) {<br>
// <unscoped-template-name> ::= <unscoped-name><br>
// ::= <substitution><br>
if (TemplateDecl *TD = Template.getAsTemplateDecl())<br>
- return mangleUnscopedTemplateName(TD)<wbr>;<br>
+ return mangleUnscopedTemplateName(TD, AdditionalAbiTags);<br>
<br>
if (mangleSubstitution(Template))<br>
return;<br>
<br>
+ assert(!AdditionalAbiTags &&<br>
+ "dependent template name cannot have abi tags");<br>
+<br>
DependentTemplateName *Dependent = Template.<wbr>getAsDependentTemplateName();<br>
assert(Dependent && "Not a dependent template name?");<br>
if (const IdentifierInfo *Id = Dependent->getIdentifier())<br>
mangleSourceName(Id);<br>
else<br>
mangleOperatorName(Dependent-><wbr>getOperator(), UnknownArity);<br>
-<br>
+<br>
addSubstitution(Template);<br>
}<br>
<br>
@@ -845,7 +1094,7 @@ void CXXNameMangler::<wbr>mangleUnresolvedPre<br>
/*recursive*/ true);<br>
else<br>
Out << "sr";<br>
- mangleSourceName(qualifier-><wbr>getAsNamespace()-><wbr>getIdentifier());<br>
+ mangleSourceNameWithAbiTags(<wbr>qualifier->getAsNamespace());<br>
break;<br>
case NestedNameSpecifier::<wbr>NamespaceAlias:<br>
if (qualifier->getPrefix())<br>
@@ -853,7 +1102,7 @@ void CXXNameMangler::<wbr>mangleUnresolvedPre<br>
/*recursive*/ true);<br>
else<br>
Out << "sr";<br>
- mangleSourceName(qualifier-><wbr>getAsNamespaceAlias()-><wbr>getIdentifier());<br>
+ mangleSourceNameWithAbiTags(<wbr>qualifier-><wbr>getAsNamespaceAlias());<br>
break;<br>
<br>
case NestedNameSpecifier::TypeSpec:<br>
@@ -888,6 +1137,7 @@ void CXXNameMangler::<wbr>mangleUnresolvedPre<br>
Out << "sr";<br>
<br>
mangleSourceName(qualifier-><wbr>getAsIdentifier());<br>
+ // An Identifier has no type information, so we can't emit abi tags for it.<br>
break;<br>
}<br>
<br>
@@ -933,7 +1183,8 @@ void CXXNameMangler::<wbr>mangleUnresolvedNam<br>
<br>
void CXXNameMangler::<wbr>mangleUnqualifiedName(const NamedDecl *ND,<br>
DeclarationName Name,<br>
- unsigned KnownArity) {<br>
+ unsigned KnownArity,<br>
+ const AbiTagList *AdditionalAbiTags) {<br>
unsigned Arity = KnownArity;<br>
// <unqualified-name> ::= <operator-name><br>
// ::= <ctor-dtor-name><br>
@@ -952,6 +1203,7 @@ void CXXNameMangler::<wbr>mangleUnqualifiedNa<br>
Out << 'L';<br>
<br>
mangleSourceName(II);<br>
+ writeAbiTags(ND, AdditionalAbiTags);<br>
break;<br>
}<br>
<br>
@@ -991,6 +1243,7 @@ void CXXNameMangler::<wbr>mangleUnqualifiedNa<br>
assert(FD->getIdentifier() && "Data member name isn't an identifier!");<br>
<br>
mangleSourceName(FD-><wbr>getIdentifier());<br>
+ // Not emitting abi tags: internal name anyway.<br>
break;<br>
}<br>
<br>
@@ -1011,6 +1264,10 @@ void CXXNameMangler::<wbr>mangleUnqualifiedNa<br>
assert(D->getDeclName().<wbr>getAsIdentifierInfo() &&<br>
"Typedef was not named!");<br>
mangleSourceName(D-><wbr>getDeclName().<wbr>getAsIdentifierInfo());<br>
+ assert(!AdditionalAbiTags && "Type cannot have additional abi tags");<br>
+ // Explicit abi tags are still possible; take from underlying type, not<br>
+ // from typedef.<br>
+ writeAbiTags(TD, nullptr);<br>
break;<br>
}<br>
<br>
@@ -1020,6 +1277,8 @@ void CXXNameMangler::<wbr>mangleUnqualifiedNa<br>
// <lambda-sig> ::= <parameter-type>+ # Parameter types or 'v' for 'void'.<br>
if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(TD)) {<br>
if (Record->isLambda() && Record-><wbr>getLambdaManglingNumber()) {<br>
+ assert(!AdditionalAbiTags &&<br>
+ "Lambda type cannot have additional abi tags");<br>
mangleLambda(Record);<br>
break;<br>
}<br>
@@ -1031,11 +1290,13 @@ void CXXNameMangler::<wbr>mangleUnqualifiedNa<br>
if (UnnamedMangle > 1)<br>
Out << UnnamedMangle - 2;<br>
Out << '_';<br>
+ writeAbiTags(TD, AdditionalAbiTags);<br>
break;<br>
}<br>
<br>
- // Get a unique id for the anonymous struct.<br>
- unsigned AnonStructId = Context.getAnonymousStructId(<wbr>TD);<br>
+ // Get a unique id for the anonymous struct. If it is not a real output<br>
+ // ID doesn't matter so use fake one.<br>
+ unsigned AnonStructId = NullOut ? 0 : Context.getAnonymousStructId(<wbr>TD);<br>
<br>
// Mangle it as a source name in the form<br>
// [n] $_<id><br>
@@ -1077,6 +1338,8 @@ void CXXNameMangler::<wbr>mangleUnqualifiedNa<br>
// nested-name, but it's more convenient to mangle them here.<br>
if (InheritedTemplateArgs)<br>
mangleTemplateArgs(*<wbr>InheritedTemplateArgs);<br>
+<br>
+ writeAbiTags(ND, AdditionalAbiTags);<br>
break;<br>
}<br>
<br>
@@ -1089,6 +1352,7 @@ void CXXNameMangler::<wbr>mangleUnqualifiedNa<br>
// Otherwise, use the complete destructor name. This is relevant if a<br>
// class with a destructor is declared within a destructor.<br>
mangleCXXDtorType(Dtor_<wbr>Complete);<br>
+ writeAbiTags(ND, AdditionalAbiTags);<br>
break;<br>
<br>
case DeclarationName::<wbr>CXXOperatorName:<br>
@@ -1104,6 +1368,7 @@ void CXXNameMangler::<wbr>mangleUnqualifiedNa<br>
case DeclarationName::<wbr>CXXConversionFunctionName:<br>
case DeclarationName::<wbr>CXXLiteralOperatorName:<br>
mangleOperatorName(Name, Arity);<br>
+ writeAbiTags(ND, AdditionalAbiTags);<br>
break;<br>
<br>
case DeclarationName::<wbr>CXXUsingDirective:<br>
@@ -1120,6 +1385,7 @@ void CXXNameMangler::<wbr>mangleSourceName(co<br>
<br>
void CXXNameMangler::<wbr>mangleNestedName(const NamedDecl *ND,<br>
const DeclContext *DC,<br>
+ const AbiTagList *AdditionalAbiTags,<br>
bool NoFunction) {<br>
// <nested-name><br>
// ::= N [<CV-qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E<br>
@@ -1145,7 +1411,7 @@ void CXXNameMangler::<wbr>mangleNestedName(co<br>
}<br>
else {<br>
manglePrefix(DC, NoFunction);<br>
- mangleUnqualifiedName(ND);<br>
+ mangleUnqualifiedName(ND, AdditionalAbiTags);<br>
}<br>
<br>
Out << 'E';<br>
@@ -1163,7 +1429,8 @@ void CXXNameMangler::<wbr>mangleNestedName(co<br>
Out << 'E';<br>
}<br>
<br>
-void CXXNameMangler::<wbr>mangleLocalName(const Decl *D) {<br>
+void CXXNameMangler::<wbr>mangleLocalName(const Decl *D,<br>
+ const AbiTagList *AdditionalAbiTags) {<br>
// <local-name> := Z <function encoding> E <entity name> [<discriminator>]<br>
// := Z <function encoding> E s [<discriminator>]<br>
// <local-name> := Z <function encoding> E d [ <parameter number> ]<br>
@@ -1175,15 +1442,26 @@ void CXXNameMangler::<wbr>mangleLocalName(con<br>
<br>
Out << 'Z';<br>
<br>
- if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(DC))<br>
- mangleObjCMethodName(MD);<br>
- else if (const BlockDecl *BD = dyn_cast<BlockDecl>(DC))<br>
- mangleBlockForPrefix(BD);<br>
- else<br>
- mangleFunctionEncoding(cast<<wbr>FunctionDecl>(DC));<br>
+ {<br>
+ AbiTagState LocalAbiTags(AbiTags);<br>
+<br>
+ if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(DC))<br>
+ mangleObjCMethodName(MD);<br>
+ else if (const BlockDecl *BD = dyn_cast<BlockDecl>(DC))<br>
+ mangleBlockForPrefix(BD);<br>
+ else<br>
+ mangleFunctionEncoding(cast<<wbr>FunctionDecl>(DC));<br>
+<br>
+ // Implicit ABI tags (from namespace) are not available in the following<br>
+ // entity; reset to actually emitted tags, which are available.<br>
+ LocalAbiTags.setUsedAbiTags(<wbr>LocalAbiTags.<wbr>getEmittedAbiTags());<br>
+ }<br>
<br>
Out << 'E';<br>
<br>
+ // GCC 5.3.0 doesn't emit derived ABI tags for local names but that seems to<br>
+ // be a bug that is fixed in trunk.<br>
+<br>
if (RD) {<br>
// The parameter number is omitted for the last parameter, 0 for the<br>
// second-to-last parameter, 1 for the third-to-last parameter, etc. The<br>
@@ -1208,13 +1486,15 @@ void CXXNameMangler::<wbr>mangleLocalName(con<br>
// Mangle the name relative to the closest enclosing function.<br>
// equality ok because RD derived from ND above<br>
if (D == RD) {<br>
- mangleUnqualifiedName(RD);<br>
+ mangleUnqualifiedName(RD, AdditionalAbiTags);<br>
} else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) {<br>
manglePrefix(<wbr>getEffectiveDeclContext(BD), true /*NoFunction*/);<br>
+ assert(!AdditionalAbiTags && "Block cannot have additional abi tags");<br>
mangleUnqualifiedBlock(BD);<br>
} else {<br>
const NamedDecl *ND = cast<NamedDecl>(D);<br>
- mangleNestedName(ND, getEffectiveDeclContext(ND), true /*NoFunction*/);<br>
+ mangleNestedName(ND, getEffectiveDeclContext(ND), AdditionalAbiTags,<br>
+ true /*NoFunction*/);<br>
}<br>
} else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) {<br>
// Mangle a block in a default parameter; see above explanation for<br>
@@ -1231,9 +1511,10 @@ void CXXNameMangler::<wbr>mangleLocalName(con<br>
}<br>
}<br>
<br>
+ assert(!AdditionalAbiTags && "Block cannot have additional abi tags");<br>
mangleUnqualifiedBlock(BD);<br>
} else {<br>
- mangleUnqualifiedName(cast<<wbr>NamedDecl>(D));<br>
+ mangleUnqualifiedName(cast<<wbr>NamedDecl>(D), AdditionalAbiTags);<br>
}<br>
<br>
if (const NamedDecl *ND = dyn_cast<NamedDecl>(RD ? RD : D)) {<br>
@@ -1249,12 +1530,12 @@ void CXXNameMangler::<wbr>mangleLocalName(con<br>
<br>
void CXXNameMangler::<wbr>mangleBlockForPrefix(const BlockDecl *Block) {<br>
if (GetLocalClassDecl(Block)) {<br>
- mangleLocalName(Block);<br>
+ mangleLocalName(Block, /* AdditionalAbiTags */ nullptr);<br>
return;<br>
}<br>
const DeclContext *DC = getEffectiveDeclContext(Block)<wbr>;<br>
if (isLocalContainerContext(DC)) {<br>
- mangleLocalName(Block);<br>
+ mangleLocalName(Block, /* AdditionalAbiTags */ nullptr);<br>
return;<br>
}<br>
manglePrefix(<wbr>getEffectiveDeclContext(Block)<wbr>);<br>
@@ -1265,10 +1546,10 @@ void CXXNameMangler::<wbr>mangleUnqualifiedBl<br>
if (Decl *Context = Block-><wbr>getBlockManglingContextDecl()) {<br>
if ((isa<VarDecl>(Context) || isa<FieldDecl>(Context)) &&<br>
Context->getDeclContext()-><wbr>isRecord()) {<br>
- if (const IdentifierInfo *Name<br>
- = cast<NamedDecl>(Context)-><wbr>getIdentifier()) {<br>
- mangleSourceName(Name);<br>
- Out << 'M';<br>
+ const auto *ND = cast<NamedDecl>(Context);<br>
+ if (ND->getIdentifier()) {<br>
+ mangleSourceNameWithAbiTags(<wbr>ND);<br>
+ Out << 'M';<br>
}<br>
}<br>
}<br>
@@ -1301,7 +1582,7 @@ void CXXNameMangler::mangleLambda(<wbr>const<br>
if (const IdentifierInfo *Name<br>
= cast<NamedDecl>(Context)-><wbr>getIdentifier()) {<br>
mangleSourceName(Name);<br>
- Out << 'M';<br>
+ Out << 'M';<br>
}<br>
}<br>
}<br>
@@ -1388,7 +1669,7 @@ void CXXNameMangler::manglePrefix(<wbr>const<br>
mangleTemplateArgs(*<wbr>TemplateArgs);<br>
} else {<br>
manglePrefix(<wbr>getEffectiveDeclContext(ND), NoFunction);<br>
- mangleUnqualifiedName(ND);<br>
+ mangleUnqualifiedName(ND, nullptr);<br>
}<br>
<br>
addSubstitution(ND);<br>
@@ -1403,19 +1684,19 @@ void CXXNameMangler::<wbr>mangleTemplatePrefi<br>
<br>
if (QualifiedTemplateName *Qualified = Template.<wbr>getAsQualifiedTemplateName())<br>
manglePrefix(Qualified-><wbr>getQualifier());<br>
-<br>
+<br>
if (OverloadedTemplateStorage *Overloaded<br>
= Template.<wbr>getAsOverloadedTemplate()) {<br>
mangleUnqualifiedName(nullptr, (*Overloaded->begin())-><wbr>getDeclName(),<br>
- UnknownArity);<br>
+ UnknownArity, nullptr);<br>
return;<br>
}<br>
-<br>
+<br>
DependentTemplateName *Dependent = Template.<wbr>getAsDependentTemplateName();<br>
assert(Dependent && "Unknown template name kind?");<br>
if (NestedNameSpecifier *Qualifier = Dependent->getQualifier())<br>
manglePrefix(Qualifier);<br>
- mangleUnscopedTemplateName(<wbr>Template);<br>
+ mangleUnscopedTemplateName(<wbr>Template, /* AdditionalAbiTags */ nullptr);<br>
}<br>
<br>
void CXXNameMangler::<wbr>mangleTemplatePrefix(const TemplateDecl *ND,<br>
@@ -1434,7 +1715,7 @@ void CXXNameMangler::<wbr>mangleTemplatePrefi<br>
mangleTemplateParameter(TTP-><wbr>getIndex());<br>
} else {<br>
manglePrefix(<wbr>getEffectiveDeclContext(ND), NoFunction);<br>
- mangleUnqualifiedName(ND-><wbr>getTemplatedDecl());<br>
+ mangleUnqualifiedName(ND-><wbr>getTemplatedDecl(), nullptr);<br>
}<br>
<br>
addSubstitution(ND);<br>
@@ -1569,17 +1850,17 @@ bool CXXNameMangler::<wbr>mangleUnresolvedTyp<br>
return true;<br>
<br>
case Type::Typedef:<br>
- mangleSourceName(cast<<wbr>TypedefType>(Ty)->getDecl()-><wbr>getIdentifier());<br>
+ mangleSourceNameWithAbiTags(<wbr>cast<TypedefType>(Ty)-><wbr>getDecl());<br>
break;<br>
<br>
case Type::UnresolvedUsing:<br>
- mangleSourceName(<br>
- cast<UnresolvedUsingType>(Ty)-<wbr>>getDecl()->getIdentifier());<br>
+ mangleSourceNameWithAbiTags(<br>
+ cast<UnresolvedUsingType>(Ty)-<wbr>>getDecl());<br>
break;<br>
<br>
case Type::Enum:<br>
case Type::Record:<br>
- mangleSourceName(cast<TagType><wbr>(Ty)->getDecl()-><wbr>getIdentifier());<br>
+ mangleSourceNameWithAbiTags(<wbr>cast<TagType>(Ty)->getDecl());<br>
break;<br>
<br>
case Type::TemplateSpecialization: {<br>
@@ -1597,7 +1878,7 @@ bool CXXNameMangler::<wbr>mangleUnresolvedTyp<br>
if (isa<TemplateTemplateParmDecl><wbr>(TD))<br>
goto unresolvedType;<br>
<br>
- mangleSourceName(TD-><wbr>getIdentifier());<br>
+ mangleSourceNameWithAbiTags(<wbr>TD);<br>
break;<br>
}<br>
<br>
@@ -1627,8 +1908,8 @@ bool CXXNameMangler::<wbr>mangleUnresolvedTyp<br>
}<br>
<br>
case Type::InjectedClassName:<br>
- mangleSourceName(<br>
- cast<InjectedClassNameType>(<wbr>Ty)->getDecl()->getIdentifier(<wbr>));<br>
+ mangleSourceNameWithAbiTags(<br>
+ cast<InjectedClassNameType>(<wbr>Ty)->getDecl());<br>
break;<br>
<br>
case Type::DependentName:<br>
@@ -1679,8 +1960,6 @@ void CXXNameMangler::<wbr>mangleOperatorName(<br>
}<br>
}<br>
<br>
-<br>
-<br>
void<br>
CXXNameMangler::<wbr>mangleOperatorName(<wbr>OverloadedOperatorKind OO, unsigned Arity) {<br>
switch (OO) {<br>
@@ -2108,7 +2387,9 @@ void CXXNameMangler::mangleType(<wbr>const Bu<br>
case BuiltinType::Id:<br>
#include "clang/AST/BuiltinTypes.def"<br>
case BuiltinType::Dependent:<br>
- llvm_unreachable("mangling a placeholder type");<br>
+ if (!NullOut)<br>
+ llvm_unreachable("mangling a placeholder type");<br>
+ break;<br>
case BuiltinType::ObjCId:<br>
Out << "11objc_object";<br>
break;<br>
@@ -2640,7 +2921,7 @@ void CXXNameMangler::mangleType(<wbr>const In<br>
<br>
void CXXNameMangler::mangleType(<wbr>const TemplateSpecializationType *T) {<br>
if (TemplateDecl *TD = T->getTemplateName().<wbr>getAsTemplateDecl()) {<br>
- mangleName(TD, T->getArgs(), T->getNumArgs());<br>
+ mangleTemplateName(TD, T->getArgs(), T->getNumArgs());<br>
} else {<br>
if (mangleSubstitution(QualType(<wbr>T, 0)))<br>
return;<br>
@@ -2967,12 +3248,14 @@ recurse:<br>
case Expr::PseudoObjectExprClass:<br>
case Expr::AtomicExprClass:<br>
{<br>
- // As bad as this diagnostic is, it's better than crashing.<br>
- DiagnosticsEngine &Diags = Context.getDiags();<br>
- unsigned DiagID = Diags.getCustomDiagID(<wbr>DiagnosticsEngine::Error,<br>
- "cannot yet mangle expression type %0");<br>
- Diags.Report(E->getExprLoc(), DiagID)<br>
- << E->getStmtClassName() << E->getSourceRange();<br>
+ if (!NullOut) {<br>
+ // As bad as this diagnostic is, it's better than crashing.<br>
+ DiagnosticsEngine &Diags = Context.getDiags();<br>
+ unsigned DiagID = Diags.getCustomDiagID(<wbr>DiagnosticsEngine::Error,<br>
+ "cannot yet mangle expression type %0");<br>
+ Diags.Report(E->getExprLoc(), DiagID)<br>
+ << E->getStmtClassName() << E->getSourceRange();<br>
+ }<br>
break;<br>
}<br>
<br>
@@ -4117,6 +4400,48 @@ void CXXNameMangler::<wbr>addSubstitution(uin<br>
Substitutions[Ptr] = SeqID++;<br>
}<br>
<br>
+CXXNameMangler::AbiTagList<br>
+CXXNameMangler::<wbr>makeFunctionReturnTypeTags(<wbr>const FunctionDecl *FD) {<br>
+ // When derived abi tags are disabled there is no need to make any list.<br>
+ if (DisableDerivedAbiTags)<br>
+ return AbiTagList();<br>
+<br>
+ llvm::raw_null_ostream NullOutStream;<br>
+ CXXNameMangler TrackReturnTypeTags(*this, NullOutStream);<br>
+ TrackReturnTypeTags.<wbr>disableDerivedAbiTags();<br>
+<br>
+ const FunctionProtoType *Proto =<br>
+ cast<FunctionProtoType>(FD-><wbr>getType()->getAs<FunctionType><wbr>());<br>
+ TrackReturnTypeTags.<wbr>FunctionTypeDepth.<wbr>enterResultType();<br>
+ TrackReturnTypeTags.<wbr>mangleType(Proto-><wbr>getReturnType());<br>
+ TrackReturnTypeTags.<wbr>FunctionTypeDepth.<wbr>leaveResultType();<br>
+<br>
+ return TrackReturnTypeTags.<wbr>AbiTagsRoot.<wbr>getSortedUniqueUsedAbiTags();<br>
+}<br>
+<br>
+CXXNameMangler::AbiTagList<br>
+CXXNameMangler::<wbr>makeVariableTypeTags(const VarDecl *VD) {<br>
+ // When derived abi tags are disabled there is no need to make any list.<br>
+ if (DisableDerivedAbiTags)<br>
+ return AbiTagList();<br>
+<br>
+ llvm::raw_null_ostream NullOutStream;<br>
+ CXXNameMangler TrackVariableType(*this, NullOutStream);<br>
+ TrackVariableType.<wbr>disableDerivedAbiTags();<br>
+<br>
+ TrackVariableType.mangleType(<wbr>VD->getType());<br>
+<br>
+ return TrackVariableType.AbiTagsRoot.<wbr>getSortedUniqueUsedAbiTags();<br>
+}<br>
+<br>
+bool CXXNameMangler::<wbr>shouldHaveAbiTags(<wbr>ItaniumMangleContextImpl &C,<br>
+ const VarDecl *VD) {<br>
+ llvm::raw_null_ostream NullOutStream;<br>
+ CXXNameMangler TrackAbiTags(C, NullOutStream, nullptr, true);<br>
+ TrackAbiTags.mangle(VD);<br>
+ return TrackAbiTags.AbiTagsRoot.<wbr>getUsedAbiTags().size();<br>
+}<br>
+<br>
//<br>
<br>
/// Mangles the name of the declaration D and emits that name to the given<br>
@@ -4218,6 +4543,8 @@ void ItaniumMangleContextImpl::<wbr>mangleSta<br>
// <special-name> ::= GV <object name> # Guard variable for one-time<br>
// # initialization<br>
CXXNameMangler Mangler(*this, Out);<br>
+ // GCC 5.3.0 doesn't emit derived ABI tags for local names but that seems to<br>
+ // be a bug that is fixed in trunk.<br>
Mangler.getStream() << "_ZGV";<br>
Mangler.mangleName(D);<br>
}<br>
<br>
Modified: cfe/trunk/lib/Sema/<wbr>SemaDeclAttr.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=274222&r1=274221&r2=274222&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Sema/<wbr>SemaDeclAttr.cpp?rev=274222&<wbr>r1=274221&r2=274222&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Sema/<wbr>SemaDeclAttr.cpp (original)<br>
+++ cfe/trunk/lib/Sema/<wbr>SemaDeclAttr.cpp Thu Jun 30 04:40:38 2016<br>
@@ -4713,10 +4713,6 @@ static void handleAbiTagAttr(Sema &S, De<br>
D->addAttr(::new (S.Context)<br>
AbiTagAttr(Attr.getRange(), S.Context, Tags.data(), Tags.size(),<br>
Attr.<wbr>getAttributeSpellingListIndex(<wbr>)));<br>
-<br>
- // FIXME: remove this warning as soon as mangled part is ready.<br>
- S.Diag(Attr.getRange().<wbr>getBegin(), diag::warn_attribute_ignored)<br>
- << Attr.getName();<br>
}<br>
<br>
static void handleARMInterruptAttr(Sema &S, Decl *D,<br>
<br>
Added: cfe/trunk/test/CodeGenCXX/<wbr>mangle-abi-tag.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-abi-tag.cpp?rev=274222&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/<wbr>CodeGenCXX/mangle-abi-tag.cpp?<wbr>rev=274222&view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/CodeGenCXX/<wbr>mangle-abi-tag.cpp (added)<br>
+++ cfe/trunk/test/CodeGenCXX/<wbr>mangle-abi-tag.cpp Thu Jun 30 04:40:38 2016<br>
@@ -0,0 +1,204 @@<br>
+// RUN: %clang_cc1 %s -emit-llvm -triple %itanium_abi_triple -std=c++11 -o - | FileCheck %s<br>
+// RUN: %clang_cc1 %s -emit-llvm -triple i686-linux-gnu -std=c++11 -o - | FileCheck %s<br>
+// RUN: %clang_cc1 %s -emit-llvm -triple x86_64-linux-gnu -std=c++11 -o - | FileCheck %s<br>
+<br>
+struct __attribute__((abi_tag("A", "B"))) A { };<br>
+<br>
+struct B: A { };<br>
+<br>
+template<class T><br>
+<br>
+struct C {<br>
+};<br>
+<br>
+struct D { A* p; };<br>
+<br>
+template<class T><br>
+struct __attribute__((abi_tag("C", "D"))) E {<br>
+};<br>
+<br>
+struct __attribute__((abi_tag("A", "B"))) F { };<br>
+<br>
+A a1;<br>
+// CHECK-DAG: @_Z2a1B1AB1B =<br>
+<br>
+__attribute__((abi_tag("C", "D")))<br>
+A a2;<br>
+// CHECK-DAG: @_Z2a2B1AB1BB1CB1D =<br>
+<br>
+B a3;<br>
+// CHECK-DAG: @a3 =<br>
+<br>
+C<A> a4;<br>
+// CHECK-DAG: @_Z2a4B1AB1B =<br>
+<br>
+D a5;<br>
+// CHECK-DAG: @a5 =<br>
+<br>
+E<int> a6;<br>
+// CHECK-DAG: @_Z2a6B1CB1D =<br>
+<br>
+E<A> a7;<br>
+// CHECK-DAG: @_Z2a7B1AB1BB1CB1D =<br>
+<br>
+template<><br>
+struct E<float> {<br>
+ static float a8;<br>
+};<br>
+float E<float>::a8;<br>
+// CHECK-DAG: @_ZN1EB1CB1DIfE2a8E =<br>
+<br>
+template<><br>
+struct E<F> {<br>
+ static bool a9;<br>
+};<br>
+bool E<F>::a9;<br>
+// CHECK-DAG: @_ZN1EB1CB1DI1FB1AB1BE2a9E =<br>
+<br>
+struct __attribute__((abi_tag("A", "B"))) A10 {<br>
+ virtual ~A10() {}<br>
+} a10;<br>
+// vtable<br>
+// CHECK-DAG: @_ZTV3A10B1AB1B =<br>
+// typeinfo<br>
+// CHECK-DAG: @_ZTI3A10B1AB1B =<br>
+<br>
+struct __attribute__((abi_tag("A"))) B11 {<br>
+ static A10 b;<br>
+};<br>
+A10 B11::b;<br>
+// B11[abi:A]::b[abi:B]<br>
+// CHECK-DAG: @_ZN3B11B1A1bB1BE =<br>
+<br>
+__attribute__ ((abi_tag("C", "D")))<br>
+void* f1() {<br>
+ return 0;<br>
+}<br>
+// CHECK-DAG: define {{.*}} @_Z2f1B1CB1Dv(<br>
+<br>
+__attribute__ ((abi_tag("C", "D")))<br>
+A* f2() {<br>
+ return 0;<br>
+}<br>
+// CHECK-DAG: define {{.*}} @_Z2f2B1AB1BB1CB1Dv(<br>
+<br>
+B* f3() {<br>
+ return 0;<br>
+}<br>
+// CHECK-DAG: define {{.*}} @_Z2f3v(<br>
+<br>
+C<A>* f4() {<br>
+ return 0;<br>
+}<br>
+// CHECK-DAG: define {{.*}} @_Z2f4B1AB1Bv(<br>
+<br>
+D* f5() {<br>
+ return 0;<br>
+}<br>
+// CHECK-DAG: define {{.*}} @_Z2f5v(<br>
+<br>
+E<char>* f6() {<br>
+ return 0;<br>
+}<br>
+// CHECK-DAG: define {{.*}} @_Z2f6B1CB1Dv(<br>
+<br>
+E<A>* f7() {<br>
+ return 0;<br>
+}<br>
+// CHECK-DAG: define {{.*}} @_Z2f7B1AB1BB1CB1Dv(<br>
+<br>
+void f8(E<A>*) {<br>
+}<br>
+// CHECK-DAG: define {{.*}} @_Z2f8P1EB1CB1DI1AB1AB1BE(<br>
+<br>
+inline namespace Names1 __attribute__((__abi_tag__)) {<br>
+ class C1 {};<br>
+}<br>
+C1 f9() { return C1(); }<br>
+// CHECK-DAG: @_Z2f9B6Names1v(<br>
+<br>
+inline namespace Names2 __attribute__((__abi_tag__("<wbr>Tag1", "Tag2"))) {<br>
+ class C2 {};<br>
+}<br>
+C2 f10() { return C2(); }<br>
+// CHECK-DAG: @_Z3f10B4Tag1B4Tag2v(<br>
+<br>
+void __attribute__((abi_tag("A"))) f11(A) {}<br>
+// f11[abi:A](A[abi:A][abi:B])<br>
+// CHECK-DAG: define {{.*}} @_Z3f11B1A1AB1AB1B(<br>
+<br>
+A f12(A) { return A(); }<br>
+// f12(A[abi:A][abi:B])<br>
+// CHECK-DAG: define {{.*}} @_Z3f121AB1AB1B(<br>
+<br>
+inline void f13() {<br>
+ struct L {<br>
+ static E<int>* foo() {<br>
+ static A10 a;<br>
+ return 0;<br>
+ }<br>
+ };<br>
+ L::foo();<br>
+}<br>
+void f13_test() {<br>
+ f13();<br>
+}<br>
+// f13()::L::foo[abi:C][abi:D]()<br>
+// CHECK-DAG: define linkonce_odr %struct.E* @_ZZ3f13vEN1L3fooB1CB1DEv(<br>
+<br>
+// f13()::L::foo[abi:C][abi:D]():<wbr>:a[abi:A][abi:B]<br>
+// CHECK-DAG: @_<wbr>ZZZ3f13vEN1L3fooB1CB1DEvE1aB1A<wbr>B1B =<br>
+<br>
+// guard variable for f13()::L::foo[abi:C][abi:D]():<wbr>:a[abi:A][abi:B]<br>
+// CHECK-DAG: @_<wbr>ZGVZZ3f13vEN1L3fooB1CB1DEvE1aB<wbr>1AB1B =<br>
+<br>
+struct __attribute__((abi_tag("TAG"))<wbr>) A14 {<br>
+ A14 f14();<br>
+};<br>
+A14 A14::f14() {<br>
+ return A14();<br>
+}<br>
+// A14[abi:TAG]::f14()<br>
+// CHECK-DAG: define void @_ZN3A14B3TAG3f14Ev(<br>
+<br>
+template<class T><br>
+T f15() {<br>
+ return T();<br>
+}<br>
+void f15_test() {<br>
+ f15<A14>();<br>
+}<br>
+// A14[abi:TAG] f15<A14[abi:TAG]>()<br>
+// CHECK-DAG: define linkonce_odr void @_Z3f15I3A14B3TAGET_v(<br>
+<br>
+template<class T><br>
+A14 f16() {<br>
+ return A14();<br>
+}<br>
+void f16_test() {<br>
+ f16<int>();<br>
+}<br>
+// A14[abi:TAG] f16<int>()<br>
+// CHECK-DAG: define linkonce_odr void @_Z3f16IiE3A14B3TAGv(<br>
+<br>
+template<class T><br>
+struct __attribute__((abi_tag("TAG"))<wbr>) A17 {<br>
+ A17 operator+(const A17& a) {<br>
+ return a;<br>
+ }<br>
+};<br>
+void f17_test() {<br>
+ A17<int> a, b;<br>
+ a + b;<br>
+}<br>
+// A17[abi:TAG]<int>::operator+(<wbr>A17[abi:TAG]<int> const&)<br>
+// CHECK-DAG: define linkonce_odr void @_ZN3A17B3TAGIiEplERKS0_(<br>
+<br>
+struct A18 {<br>
+ operator A() { return A(); }<br>
+};<br>
+void f18_test() {<br>
+ A a = A18();<br>
+}<br>
+// A18::operator A[abi:A][abi:B]() but GCC adds the same tags twice!<br>
+// CHECK-DAG: define linkonce_odr void @_ZN3A18cv1AB1AB1BEv(<br>
<br>
Propchange: cfe/trunk/test/CodeGenCXX/<wbr>mangle-abi-tag.cpp<br>
------------------------------<wbr>------------------------------<wbr>------------------<br>
svn:eol-style = native<br>
<br>
Propchange: cfe/trunk/test/CodeGenCXX/<wbr>mangle-abi-tag.cpp<br>
------------------------------<wbr>------------------------------<wbr>------------------<br>
svn:keywords = "Author Date Id Rev URL"<br>
<br>
Propchange: cfe/trunk/test/CodeGenCXX/<wbr>mangle-abi-tag.cpp<br>
------------------------------<wbr>------------------------------<wbr>------------------<br>
svn:mime-type = text/plain<br>
<br>
Modified: cfe/trunk/test/PCH/attrs.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/attrs.c?rev=274222&r1=274221&r2=274222&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/PCH/<wbr>attrs.c?rev=274222&r1=274221&<wbr>r2=274222&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/PCH/attrs.c (original)<br>
+++ cfe/trunk/test/PCH/attrs.c Thu Jun 30 04:40:38 2016<br>
@@ -9,7 +9,7 @@<br>
#define HEADER<br>
<br>
int f(int) __attribute__((visibility("<wbr>default"), overloadable));<br>
-int g(int) __attribute__((abi_tag("foo", "bar", "baz"), no_sanitize("address", "memory"))); // expected-warning {{ignored}}<br>
+int g(int) __attribute__((abi_tag("foo", "bar", "baz"), no_sanitize("address", "memory")));<br>
<br>
#else<br>
<br>
<br>
Modified: cfe/trunk/test/SemaCXX/attr-<wbr>abi-tag-syntax.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-abi-tag-syntax.cpp?rev=274222&r1=274221&r2=274222&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/<wbr>SemaCXX/attr-abi-tag-syntax.<wbr>cpp?rev=274222&r1=274221&r2=<wbr>274222&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/SemaCXX/attr-<wbr>abi-tag-syntax.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/attr-<wbr>abi-tag-syntax.cpp Thu Jun 30 04:40:38 2016<br>
@@ -16,28 +16,18 @@ inline namespace __attribute__((__abi_ta<br>
// expected-warning@-1 {{'abi_tag' attribute on anonymous namespace ignored}}<br>
<br>
inline namespace N __attribute__((__abi_tag__)) {}<br>
-// FIXME: remove this warning as soon as attribute fully supported.<br>
-// expected-warning@-2 {{'__abi_tag__' attribute ignored}}<br>
<br>
} // namespcace N2<br>
<br>
__attribute__((abi_tag("B", "A"))) extern int a1;<br>
-// FIXME: remove this warning as soon as attribute fully supported.<br>
-// expected-warning@-2 {{'abi_tag' attribute ignored}}<br>
<br>
__attribute__((abi_tag("A", "B"))) extern int a1;<br>
// expected-note@-1 {{previous declaration is here}}<br>
-// FIXME: remove this warning as soon as attribute fully supported.<br>
-// expected-warning@-3 {{'abi_tag' attribute ignored}}<br>
<br>
__attribute__((abi_tag("A", "C"))) extern int a1;<br>
// expected-error@-1 {{'abi_tag' C missing in original declaration}}<br>
-// FIXME: remove this warning as soon as attribute fully supported.<br>
-// expected-warning@-3 {{'abi_tag' attribute ignored}}<br>
<br>
extern int a2;<br>
// expected-note@-1 {{previous declaration is here}}<br>
__attribute__((abi_tag("A")))<wbr>extern int a2;<br>
// expected-error@-1 {{cannot add 'abi_tag' attribute in a redeclaration}}<br>
-// FIXME: remove this warning as soon as attribute fully supported.<br>
-// expected-warning@-3 {{'abi_tag' attribute ignored}}<br>
<br>
<br>
______________________________<wbr>_________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>