r246469 - [MS ABI] Correctly mangle classes without names for linkage purposes

David Majnemer via cfe-commits cfe-commits at lists.llvm.org
Mon Aug 31 11:48:39 PDT 2015


Author: majnemer
Date: Mon Aug 31 13:48:39 2015
New Revision: 246469

URL: http://llvm.org/viewvc/llvm-project?rev=246469&view=rev
Log:
[MS ABI] Correctly mangle classes without names for linkage purposes

A class without a name for linkage purposes gets a name along the lines
of <unnamed-type-foo> where foo is either the name of a declarator which
defined it (like a variable or field) or a
typedef-name (like a typedef or alias-declaration).

We handled the declarator case correctly but it would fall down during
template instantiation if the declarator didn't share the tag's type.
We failed to handle the typedef-name case at all.

Instead, keep track of the association between the two and keep it up to
date in the face of template instantiation.

Modified:
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/include/clang/AST/Decl.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/AST/CXXABI.h
    cfe/trunk/lib/AST/Decl.cpp
    cfe/trunk/lib/AST/ItaniumCXXABI.cpp
    cfe/trunk/lib/AST/MicrosoftCXXABI.cpp
    cfe/trunk/lib/AST/MicrosoftMangle.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
    cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
    cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
    cfe/trunk/test/CodeGenCXX/mangle-ms-cxx11.cpp
    cfe/trunk/test/CodeGenCXX/mangle-ms.cpp

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=246469&r1=246468&r2=246469&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Mon Aug 31 13:48:39 2015
@@ -2311,6 +2311,14 @@ public:
   Expr *getDefaultArgExprForConstructor(const CXXConstructorDecl *CD,
                                         unsigned ParmIdx);
 
+  void addTypedefNameForUnnamedTagDecl(TagDecl *TD, TypedefNameDecl *TND);
+
+  TypedefNameDecl *getTypedefNameForUnnamedTagDecl(const TagDecl *TD);
+
+  void addDeclaratorForUnnamedTagDecl(TagDecl *TD, DeclaratorDecl *DD);
+
+  DeclaratorDecl *getDeclaratorForUnnamedTagDecl(const TagDecl *TD);
+
   void setManglingNumber(const NamedDecl *ND, unsigned Number);
   unsigned getManglingNumber(const NamedDecl *ND) const;
 

Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=246469&r1=246468&r2=246469&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Mon Aug 31 13:48:39 2015
@@ -2778,12 +2778,12 @@ private:
   /// declaration specifier for variables, it points to the first VarDecl (used
   /// for mangling);
   /// otherwise, it is a null (TypedefNameDecl) pointer.
-  llvm::PointerUnion<NamedDecl *, ExtInfo *> NamedDeclOrQualifier;
+  llvm::PointerUnion<TypedefNameDecl *, ExtInfo *> TypedefNameDeclOrQualifier;
 
-  bool hasExtInfo() const { return NamedDeclOrQualifier.is<ExtInfo *>(); }
-  ExtInfo *getExtInfo() { return NamedDeclOrQualifier.get<ExtInfo *>(); }
+  bool hasExtInfo() const { return TypedefNameDeclOrQualifier.is<ExtInfo *>(); }
+  ExtInfo *getExtInfo() { return TypedefNameDeclOrQualifier.get<ExtInfo *>(); }
   const ExtInfo *getExtInfo() const {
-    return NamedDeclOrQualifier.get<ExtInfo *>();
+    return TypedefNameDeclOrQualifier.get<ExtInfo *>();
   }
 
 protected:
@@ -2794,7 +2794,7 @@ protected:
         TagDeclKind(TK), IsCompleteDefinition(false), IsBeingDefined(false),
         IsEmbeddedInDeclarator(false), IsFreeStanding(false),
         IsCompleteDefinitionRequired(false),
-        NamedDeclOrQualifier((NamedDecl *)nullptr) {
+        TypedefNameDeclOrQualifier((TypedefNameDecl *)nullptr) {
     assert((DK != Enum || TK == TTK_Enum) &&
            "EnumDecl not matched with TTK_Enum");
     setPreviousDecl(PrevDecl);
@@ -2941,22 +2941,11 @@ public:
     return (getDeclName() || getTypedefNameForAnonDecl());
   }
 
-  bool hasDeclaratorForAnonDecl() const {
-    return dyn_cast_or_null<DeclaratorDecl>(
-        NamedDeclOrQualifier.get<NamedDecl *>());
-  }
-  DeclaratorDecl *getDeclaratorForAnonDecl() const {
-    return hasExtInfo() ? nullptr : dyn_cast_or_null<DeclaratorDecl>(
-                                  NamedDeclOrQualifier.get<NamedDecl *>());
-  }
-
   TypedefNameDecl *getTypedefNameForAnonDecl() const {
-    return hasExtInfo() ? nullptr : dyn_cast_or_null<TypedefNameDecl>(
-                                  NamedDeclOrQualifier.get<NamedDecl *>());
+    return hasExtInfo() ? nullptr
+                        : TypedefNameDeclOrQualifier.get<TypedefNameDecl *>();
   }
 
-  void setDeclaratorForAnonDecl(DeclaratorDecl *DD) { NamedDeclOrQualifier = DD; }
-
   void setTypedefNameForAnonDecl(TypedefNameDecl *TDD);
 
   /// \brief Retrieve the nested-name-specifier that qualifies the name of this

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=246469&r1=246468&r2=246469&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Mon Aug 31 13:48:39 2015
@@ -8549,6 +8549,25 @@ Expr *ASTContext::getDefaultArgExprForCo
       cast<CXXConstructorDecl>(CD->getFirstDecl()), ParmIdx);
 }
 
+void ASTContext::addTypedefNameForUnnamedTagDecl(TagDecl *TD,
+                                                 TypedefNameDecl *DD) {
+  return ABI->addTypedefNameForUnnamedTagDecl(TD, DD);
+}
+
+TypedefNameDecl *
+ASTContext::getTypedefNameForUnnamedTagDecl(const TagDecl *TD) {
+  return ABI->getTypedefNameForUnnamedTagDecl(TD);
+}
+
+void ASTContext::addDeclaratorForUnnamedTagDecl(TagDecl *TD,
+                                                DeclaratorDecl *DD) {
+  return ABI->addDeclaratorForUnnamedTagDecl(TD, DD);
+}
+
+DeclaratorDecl *ASTContext::getDeclaratorForUnnamedTagDecl(const TagDecl *TD) {
+  return ABI->getDeclaratorForUnnamedTagDecl(TD);
+}
+
 void ASTContext::setParameterIndex(const ParmVarDecl *D, unsigned int index) {
   ParamIndices[D] = index;
 }

Modified: cfe/trunk/lib/AST/CXXABI.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/CXXABI.h?rev=246469&r1=246468&r2=246469&view=diff
==============================================================================
--- cfe/trunk/lib/AST/CXXABI.h (original)
+++ cfe/trunk/lib/AST/CXXABI.h Mon Aug 31 13:48:39 2015
@@ -21,6 +21,7 @@ namespace clang {
 
 class ASTContext;
 class CXXConstructorDecl;
+class DeclaratorDecl;
 class Expr;
 class MemberPointerType;
 class MangleNumberingContext;
@@ -57,6 +58,17 @@ public:
 
   virtual Expr *getDefaultArgExprForConstructor(const CXXConstructorDecl *CD,
                                                 unsigned ParmIdx) = 0;
+
+  virtual void addTypedefNameForUnnamedTagDecl(TagDecl *TD,
+                                               TypedefNameDecl *DD) = 0;
+
+  virtual TypedefNameDecl *
+  getTypedefNameForUnnamedTagDecl(const TagDecl *TD) = 0;
+
+  virtual void addDeclaratorForUnnamedTagDecl(TagDecl *TD,
+                                              DeclaratorDecl *DD) = 0;
+
+  virtual DeclaratorDecl *getDeclaratorForUnnamedTagDecl(const TagDecl *TD) = 0;
 };
 
 /// Creates an instance of a C++ ABI class.

Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=246469&r1=246468&r2=246469&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Mon Aug 31 13:48:39 2015
@@ -3403,7 +3403,7 @@ SourceRange TagDecl::getSourceRange() co
 TagDecl *TagDecl::getCanonicalDecl() { return getFirstDecl(); }
 
 void TagDecl::setTypedefNameForAnonDecl(TypedefNameDecl *TDD) {
-  NamedDeclOrQualifier = TDD;
+  TypedefNameDeclOrQualifier = TDD;
   if (const Type *T = getTypeForDecl()) {
     (void)T;
     assert(T->isLinkageValid());
@@ -3461,7 +3461,7 @@ void TagDecl::setQualifierInfo(NestedNam
   if (QualifierLoc) {
     // Make sure the extended qualifier info is allocated.
     if (!hasExtInfo())
-      NamedDeclOrQualifier = new (getASTContext()) ExtInfo;
+      TypedefNameDeclOrQualifier = new (getASTContext()) ExtInfo;
     // Set qualifier info.
     getExtInfo()->QualifierLoc = QualifierLoc;
   } else {
@@ -3469,7 +3469,7 @@ void TagDecl::setQualifierInfo(NestedNam
     if (hasExtInfo()) {
       if (getExtInfo()->NumTemplParamLists == 0) {
         getASTContext().Deallocate(getExtInfo());
-        NamedDeclOrQualifier = (TypedefNameDecl*)nullptr;
+        TypedefNameDeclOrQualifier = (TypedefNameDecl *)nullptr;
       }
       else
         getExtInfo()->QualifierLoc = QualifierLoc;
@@ -3483,7 +3483,7 @@ void TagDecl::setTemplateParameterListsI
   // Make sure the extended decl info is allocated.
   if (!hasExtInfo())
     // Allocate external info struct.
-    NamedDeclOrQualifier = new (getASTContext()) ExtInfo;
+    TypedefNameDeclOrQualifier = new (getASTContext()) ExtInfo;
   // Set the template parameter lists info.
   getExtInfo()->setTemplateParameterListsInfo(Context, TPLists);
 }

Modified: cfe/trunk/lib/AST/ItaniumCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumCXXABI.cpp?rev=246469&r1=246468&r2=246469&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ItaniumCXXABI.cpp (original)
+++ cfe/trunk/lib/AST/ItaniumCXXABI.cpp Mon Aug 31 13:48:39 2015
@@ -149,6 +149,20 @@ public:
     return nullptr;
   }
 
+  void addTypedefNameForUnnamedTagDecl(TagDecl *TD,
+                                       TypedefNameDecl *DD) override {}
+
+  TypedefNameDecl *getTypedefNameForUnnamedTagDecl(const TagDecl *TD) override {
+    return nullptr;
+  }
+
+  void addDeclaratorForUnnamedTagDecl(TagDecl *TD,
+                                      DeclaratorDecl *DD) override {}
+
+  DeclaratorDecl *getDeclaratorForUnnamedTagDecl(const TagDecl *TD) override {
+    return nullptr;
+  }
+
   MangleNumberingContext *createMangleNumberingContext() const override {
     return new ItaniumNumberingContext();
   }

Modified: cfe/trunk/lib/AST/MicrosoftCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/MicrosoftCXXABI.cpp?rev=246469&r1=246468&r2=246469&view=diff
==============================================================================
--- cfe/trunk/lib/AST/MicrosoftCXXABI.cpp (original)
+++ cfe/trunk/lib/AST/MicrosoftCXXABI.cpp Mon Aug 31 13:48:39 2015
@@ -70,6 +70,11 @@ class MicrosoftCXXABI : public CXXABI {
   llvm::SmallDenseMap<std::pair<const CXXConstructorDecl *, unsigned>, Expr *>
       CtorToDefaultArgExpr;
 
+  llvm::SmallDenseMap<TagDecl *, DeclaratorDecl *>
+      UnnamedTagDeclToDeclaratorDecl;
+  llvm::SmallDenseMap<TagDecl *, TypedefNameDecl *>
+      UnnamedTagDeclToTypedefNameDecl;
+
 public:
   MicrosoftCXXABI(ASTContext &Ctx) : Context(Ctx) { }
 
@@ -120,6 +125,34 @@ public:
     RecordToCopyCtor[RD] = CD;
   }
 
+  void addTypedefNameForUnnamedTagDecl(TagDecl *TD,
+                                       TypedefNameDecl *DD) override {
+    TD = TD->getCanonicalDecl();
+    DD = cast<TypedefNameDecl>(DD->getCanonicalDecl());
+    TypedefNameDecl *&I = UnnamedTagDeclToTypedefNameDecl[TD];
+    if (!I)
+      I = DD;
+  }
+
+  TypedefNameDecl *getTypedefNameForUnnamedTagDecl(const TagDecl *TD) override {
+    return UnnamedTagDeclToTypedefNameDecl[const_cast<TagDecl *>(
+        TD->getCanonicalDecl())];
+  }
+
+  void addDeclaratorForUnnamedTagDecl(TagDecl *TD,
+                                      DeclaratorDecl *DD) override {
+    TD = TD->getCanonicalDecl();
+    DD = cast<DeclaratorDecl>(DD->getCanonicalDecl());
+    DeclaratorDecl *&I = UnnamedTagDeclToDeclaratorDecl[TD];
+    if (!I)
+      I = DD;
+  }
+
+  DeclaratorDecl *getDeclaratorForUnnamedTagDecl(const TagDecl *TD) override {
+    return UnnamedTagDeclToDeclaratorDecl[const_cast<TagDecl *>(
+        TD->getCanonicalDecl())];
+  }
+
   MangleNumberingContext *createMangleNumberingContext() const override {
     return new MicrosoftNumberingContext();
   }

Modified: cfe/trunk/lib/AST/MicrosoftMangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/MicrosoftMangle.cpp?rev=246469&r1=246468&r2=246469&view=diff
==============================================================================
--- cfe/trunk/lib/AST/MicrosoftMangle.cpp (original)
+++ cfe/trunk/lib/AST/MicrosoftMangle.cpp Mon Aug 31 13:48:39 2015
@@ -786,10 +786,17 @@ void MicrosoftCXXNameMangler::mangleUnqu
       }
 
       llvm::SmallString<64> Name("<unnamed-type-");
-      if (TD->hasDeclaratorForAnonDecl()) {
-        // Anonymous types with no tag or typedef get the name of their
+      if (DeclaratorDecl *DD =
+              Context.getASTContext().getDeclaratorForUnnamedTagDecl(TD)) {
+        // Anonymous types without a name for linkage purposes have their
         // declarator mangled in if they have one.
-        Name += TD->getDeclaratorForAnonDecl()->getName();
+        Name += DD->getName();
+      } else if (TypedefNameDecl *TND =
+                     Context.getASTContext().getTypedefNameForUnnamedTagDecl(
+                         TD)) {
+        // Anonymous types without a name for linkage purposes have their
+        // associate typedef mangled in if they have one.
+        Name += TND->getName();
       } else {
         // Otherwise, number the types using a $S prefix.
         Name += "$S";

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=246469&r1=246468&r2=246469&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Aug 31 13:48:39 2015
@@ -3560,11 +3560,8 @@ void Sema::handleTagNumbering(const TagD
 
 void Sema::setTagNameForLinkagePurposes(TagDecl *TagFromDeclSpec,
                                         TypedefNameDecl *NewTD) {
-  // Do nothing if the tag is not anonymous or already has an
-  // associated typedef (from an earlier typedef in this decl group).
-  if (TagFromDeclSpec->getIdentifier())
-    return;
-  if (TagFromDeclSpec->getTypedefNameForAnonDecl())
+  // Do nothing if the tag already has a name for linkage purposes.
+  if (TagFromDeclSpec->hasNameForLinkage())
     return;
 
   // A well-formed anonymous tag must always be a TUK_Definition.
@@ -3572,8 +3569,11 @@ void Sema::setTagNameForLinkagePurposes(
 
   // The type must match the tag exactly;  no qualifiers allowed.
   if (!Context.hasSameType(NewTD->getUnderlyingType(),
-                           Context.getTagDeclType(TagFromDeclSpec)))
+                           Context.getTagDeclType(TagFromDeclSpec))) {
+    if (getLangOpts().CPlusPlus)
+      Context.addTypedefNameForUnnamedTagDecl(TagFromDeclSpec, NewTD);
     return;
+  }
 
   // If we've already computed linkage for the anonymous tag, then
   // adding a typedef name for the anonymous decl can change that
@@ -10050,8 +10050,9 @@ Sema::DeclGroupPtrTy Sema::FinalizeDecla
   if (DeclSpec::isDeclRep(DS.getTypeSpecType())) {
     if (TagDecl *Tag = dyn_cast_or_null<TagDecl>(DS.getRepAsDecl())) {
       handleTagNumbering(Tag, S);
-      if (!Tag->hasNameForLinkage() && !Tag->hasDeclaratorForAnonDecl())
-        Tag->setDeclaratorForAnonDecl(FirstDeclaratorInGroup);
+      if (FirstDeclaratorInGroup && !Tag->hasNameForLinkage() &&
+          getLangOpts().CPlusPlus)
+        Context.addDeclaratorForUnnamedTagDecl(Tag, FirstDeclaratorInGroup);
     }
   }
 

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=246469&r1=246468&r2=246469&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Mon Aug 31 13:48:39 2015
@@ -813,6 +813,14 @@ Decl *TemplateDeclInstantiator::VisitEnu
   Enum->setAccess(D->getAccess());
   // Forward the mangling number from the template to the instantiated decl.
   SemaRef.Context.setManglingNumber(Enum, SemaRef.Context.getManglingNumber(D));
+  // See if the old tag was defined along with a declarator.
+  // If it did, mark the new tag as being associated with that declarator.
+  if (DeclaratorDecl *DD = SemaRef.Context.getDeclaratorForUnnamedTagDecl(D))
+    SemaRef.Context.addDeclaratorForUnnamedTagDecl(Enum, DD);
+  // See if the old tag was defined along with a typedef.
+  // If it did, mark the new tag as being associated with that typedef.
+  if (TypedefNameDecl *TND = SemaRef.Context.getTypedefNameForUnnamedTagDecl(D))
+    SemaRef.Context.addTypedefNameForUnnamedTagDecl(Enum, TND);
   if (SubstQualifier(D, Enum)) return nullptr;
   Owner->addDecl(Enum);
 
@@ -1298,6 +1306,16 @@ Decl *TemplateDeclInstantiator::VisitCXX
   SemaRef.Context.setManglingNumber(Record,
                                     SemaRef.Context.getManglingNumber(D));
 
+  // See if the old tag was defined along with a declarator.
+  // If it did, mark the new tag as being associated with that declarator.
+  if (DeclaratorDecl *DD = SemaRef.Context.getDeclaratorForUnnamedTagDecl(D))
+    SemaRef.Context.addDeclaratorForUnnamedTagDecl(Record, DD);
+
+  // See if the old tag was defined along with a typedef.
+  // If it did, mark the new tag as being associated with that typedef.
+  if (TypedefNameDecl *TND = SemaRef.Context.getTypedefNameForUnnamedTagDecl(D))
+    SemaRef.Context.addTypedefNameForUnnamedTagDecl(Record, TND);
+
   Owner->addDecl(Record);
 
   // DR1484 clarifies that the members of a local class are instantiated as part
@@ -3615,19 +3633,6 @@ void Sema::BuildVariableInstantiation(
     NewVar->setReferenced(OldVar->isReferenced());
   }
 
-  // See if the old variable had a type-specifier that defined an anonymous tag.
-  // If it did, mark the new variable as being the declarator for the new
-  // anonymous tag.
-  if (const TagType *OldTagType = OldVar->getType()->getAs<TagType>()) {
-    TagDecl *OldTag = OldTagType->getDecl();
-    if (OldTag->getDeclaratorForAnonDecl() == OldVar) {
-      TagDecl *NewTag = NewVar->getType()->castAs<TagType>()->getDecl();
-      assert(!NewTag->hasNameForLinkage() &&
-             !NewTag->hasDeclaratorForAnonDecl());
-      NewTag->setDeclaratorForAnonDecl(NewVar);
-    }
-  }
-
   InstantiateAttrs(TemplateArgs, OldVar, NewVar, LateAttrs, StartingScope);
 
   LookupResult Previous(

Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=246469&r1=246468&r2=246469&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Mon Aug 31 13:48:39 2015
@@ -441,8 +441,8 @@ void ASTDeclReader::Visit(Decl *D) {
     // If this is a tag declaration with a typedef name for linkage, it's safe
     // to load that typedef now.
     if (NamedDeclForTagDecl)
-      cast<TagDecl>(D)->NamedDeclOrQualifier =
-          cast<NamedDecl>(Reader.GetDecl(NamedDeclForTagDecl));
+      cast<TagDecl>(D)->TypedefNameDeclOrQualifier =
+          cast<TypedefNameDecl>(Reader.GetDecl(NamedDeclForTagDecl));
   } else if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) {
     // if we have a fully initialized TypeDecl, we can safely read its type now.
     ID->TypeForDecl = Reader.GetType(TypeIDForTypeDecl).getTypePtrOrNull();
@@ -595,16 +595,13 @@ ASTDeclReader::RedeclarableResult ASTDec
   case 1: { // ExtInfo
     TagDecl::ExtInfo *Info = new (Reader.getContext()) TagDecl::ExtInfo();
     ReadQualifierInfo(*Info, Record, Idx);
-    TD->NamedDeclOrQualifier = Info;
+    TD->TypedefNameDeclOrQualifier = Info;
     break;
   }
   case 2: // TypedefNameForAnonDecl
     NamedDeclForTagDecl = ReadDeclID(Record, Idx);
     TypedefNameForLinkage = Reader.GetIdentifierInfo(F, Record, Idx);
     break;
-  case 3: // DeclaratorForAnonDecl
-    NamedDeclForTagDecl = ReadDeclID(Record, Idx);
-    break;
   default:
     llvm_unreachable("unexpected tag info kind");
   }

Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=246469&r1=246468&r2=246469&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Mon Aug 31 13:48:39 2015
@@ -378,9 +378,6 @@ void ASTDeclWriter::VisitTagDecl(TagDecl
     Record.push_back(2);
     Writer.AddDeclRef(TD, Record);
     Writer.AddIdentifierRef(TD->getDeclName().getAsIdentifierInfo(), Record);
-  } else if (auto *DD = D->getDeclaratorForAnonDecl()) {
-    Record.push_back(3);
-    Writer.AddDeclRef(DD, Record);
   } else {
     Record.push_back(0);
   }
@@ -410,7 +407,6 @@ void ASTDeclWriter::VisitEnumDecl(EnumDe
       !D->isUsed(false) &&
       !D->hasExtInfo() &&
       !D->getTypedefNameForAnonDecl() &&
-      !D->getDeclaratorForAnonDecl() &&
       D->getFirstDecl() == D->getMostRecentDecl() &&
       !D->isInvalidDecl() &&
       !D->isReferenced() &&
@@ -439,7 +435,6 @@ void ASTDeclWriter::VisitRecordDecl(Reco
       !D->isUsed(false) &&
       !D->hasExtInfo() &&
       !D->getTypedefNameForAnonDecl() &&
-      !D->getDeclaratorForAnonDecl() &&
       D->getFirstDecl() == D->getMostRecentDecl() &&
       !D->isInvalidDecl() &&
       !D->isReferenced() &&

Modified: cfe/trunk/test/CodeGenCXX/mangle-ms-cxx11.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-ms-cxx11.cpp?rev=246469&r1=246468&r2=246469&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-ms-cxx11.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/mangle-ms-cxx11.cpp Mon Aug 31 13:48:39 2015
@@ -243,3 +243,21 @@ void f() {}
 template void f<AliasA>();
 // CHECK-DAG: @"\01??$f@$$YAliasA at PR20047@@@PR20047@@YAXXZ"
 }
+
+namespace UnnamedType {
+struct A {
+  struct {} *TD;
+};
+
+void f(decltype(*A::TD)) {}
+// CHECK-DAG: @"\01?f at UnnamedType@@YAXAAU<unnamed-type-TD>@A at 1@@Z"
+
+template <typename T>
+struct B {
+  enum {
+  } *e;
+};
+
+void f(decltype(B<int>::e)) {}
+// CHECK-DAG: @"\01?f at UnnamedType@@YAXPAW4<unnamed-type-e>@?$B at H@1@@Z
+}

Modified: cfe/trunk/test/CodeGenCXX/mangle-ms.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-ms.cpp?rev=246469&r1=246468&r2=246469&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-ms.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/mangle-ms.cpp Mon Aug 31 13:48:39 2015
@@ -389,3 +389,32 @@ template void fn_tmpl<extern_c_func>();
 
 extern "C" void __attribute__((overloadable)) overloaded_fn() {}
 // CHECK-DAG: @"\01?overloaded_fn@@$$J0YAXXZ"
+
+namespace UnnamedType {
+struct S {
+  typedef struct {} *T1[1];
+  typedef struct {} T2;
+  typedef struct {} *T3, T4;
+  using T5 = struct {};
+  using T6 = struct {} *;
+};
+void f(S::T1) {}
+void f(S::T2) {}
+void f(S::T3) {}
+void f(S::T4) {}
+void f(S::T5) {}
+void f(S::T6) {}
+// CHECK-DAG: @"\01?f at UnnamedType@@YAXQAPAU<unnamed-type-T1>@S at 1@@Z"
+// CHECK-DAG: @"\01?f at UnnamedType@@YAXUT2 at S@1@@Z"
+// CHECK-DAG: @"\01?f at UnnamedType@@YAXPAUT4 at S@1@@Z"
+// CHECK-DAG: @"\01?f at UnnamedType@@YAXUT4 at S@1@@Z"
+// CHECK-DAG: @"\01?f at UnnamedType@@YAXUT5 at S@1@@Z"
+// CHECK-DAG: @"\01?f at UnnamedType@@YAXPAU<unnamed-type-T6>@S at 1@@Z"
+
+// X64-DAG: @"\01?f at UnnamedType@@YAXQEAPEAU<unnamed-type-T1>@S at 1@@Z"
+// X64-DAG: @"\01?f at UnnamedType@@YAXUT2 at S@1@@Z"
+// X64-DAG: @"\01?f at UnnamedType@@YAXPEAUT4 at S@1@@Z"(%"struct.UnnamedType::S::T4"
+// X64-DAG: @"\01?f at UnnamedType@@YAXUT4 at S@1@@Z"
+// X64-DAG: @"\01?f at UnnamedType@@YAXUT5 at S@1@@Z"
+// X64-DAG: @"\01?f at UnnamedType@@YAXPEAU<unnamed-type-T6>@S at 1@@Z"
+}




More information about the cfe-commits mailing list