<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>