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@PR20047@@@PR20047@@YAXXZ" } + +namespace UnnamedType { +struct A { + struct {} *TD; +}; + +void f(decltype(*A::TD)) {} +// CHECK-DAG: @"\01?f@UnnamedType@@YAXAAU<unnamed-type-TD>@A@1@@Z" + +template <typename T> +struct B { + enum { + } *e; +}; + +void f(decltype(B<int>::e)) {} +// CHECK-DAG: @"\01?f@UnnamedType@@YAXPAW4<unnamed-type-e>@?$B@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@UnnamedType@@YAXQAPAU<unnamed-type-T1>@S@1@@Z" +// CHECK-DAG: @"\01?f@UnnamedType@@YAXUT2@S@1@@Z" +// CHECK-DAG: @"\01?f@UnnamedType@@YAXPAUT4@S@1@@Z" +// CHECK-DAG: @"\01?f@UnnamedType@@YAXUT4@S@1@@Z" +// CHECK-DAG: @"\01?f@UnnamedType@@YAXUT5@S@1@@Z" +// CHECK-DAG: @"\01?f@UnnamedType@@YAXPAU<unnamed-type-T6>@S@1@@Z" + +// X64-DAG: @"\01?f@UnnamedType@@YAXQEAPEAU<unnamed-type-T1>@S@1@@Z" +// X64-DAG: @"\01?f@UnnamedType@@YAXUT2@S@1@@Z" +// X64-DAG: @"\01?f@UnnamedType@@YAXPEAUT4@S@1@@Z"(%"struct.UnnamedType::S::T4" +// X64-DAG: @"\01?f@UnnamedType@@YAXUT4@S@1@@Z" +// X64-DAG: @"\01?f@UnnamedType@@YAXUT5@S@1@@Z" +// X64-DAG: @"\01?f@UnnamedType@@YAXPEAU<unnamed-type-T6>@S@1@@Z" +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits