From: David Majnemer Date: Tue, 17 Sep 2013 23:57:10 +0000 (+0000) Subject: Revert "Revert "[-cxx-abi microsoft] Mangle local TagDecls appropriately"" X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=aa82461f696ced36b0cd817dfa492b6c93d15447;p=clang Revert "Revert "[-cxx-abi microsoft] Mangle local TagDecls appropriately"" This reverts commit r190895 which reverted r190892. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@190904 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 7cd61fcc22..95812d2542 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -2507,17 +2507,20 @@ private: // to be used for the (uncommon) case of out-of-line declarations. typedef QualifierInfo ExtInfo; - /// TypedefNameDeclOrQualifier - If the (out-of-line) tag declaration name + /// \brief If the (out-of-line) tag declaration name /// is qualified, it points to the qualifier info (nns and range); /// otherwise, if the tag declaration is anonymous and it is part of /// a typedef or alias, it points to the TypedefNameDecl (used for mangling); + /// otherwise, if the tag declaration is anonymous and it is used as a + /// declaration specifier for variables, it points to the first VarDecl (used + /// for mangling); /// otherwise, it is a null (TypedefNameDecl) pointer. - llvm::PointerUnion TypedefNameDeclOrQualifier; + llvm::PointerUnion NamedDeclOrQualifier; - bool hasExtInfo() const { return TypedefNameDeclOrQualifier.is(); } - ExtInfo *getExtInfo() { return TypedefNameDeclOrQualifier.get(); } + bool hasExtInfo() const { return NamedDeclOrQualifier.is(); } + ExtInfo *getExtInfo() { return NamedDeclOrQualifier.get(); } const ExtInfo *getExtInfo() const { - return TypedefNameDeclOrQualifier.get(); + return NamedDeclOrQualifier.get(); } protected: @@ -2527,7 +2530,7 @@ protected: IsCompleteDefinition(false), IsBeingDefined(false), IsEmbeddedInDeclarator(false), IsFreeStanding(false), IsCompleteDefinitionRequired(false), - TypedefNameDeclOrQualifier((TypedefNameDecl *)0) { + NamedDeclOrQualifier((NamedDecl *)0) { assert((DK != Enum || TK == TTK_Enum) && "EnumDecl not matched with TTK_Enum"); setPreviousDeclaration(PrevDecl); @@ -2670,11 +2673,22 @@ public: return (getDeclName() || getTypedefNameForAnonDecl()); } + bool hasDeclaratorForAnonDecl() const { + return dyn_cast_or_null( + NamedDeclOrQualifier.get()); + } + DeclaratorDecl *getDeclaratorForAnonDecl() const { + return hasExtInfo() ? 0 : dyn_cast_or_null( + NamedDeclOrQualifier.get()); + } + TypedefNameDecl *getTypedefNameForAnonDecl() const { - return hasExtInfo() ? 0 : - TypedefNameDeclOrQualifier.get(); + return hasExtInfo() ? 0 : dyn_cast_or_null( + NamedDeclOrQualifier.get()); } + void setDeclaratorForAnonDecl(DeclaratorDecl *DD) { NamedDeclOrQualifier = DD; } + void setTypedefNameForAnonDecl(TypedefNameDecl *TDD); /// \brief Retrieve the nested-name-specifier that qualifies the name of this diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 0fa1b980f3..dbbf4753dc 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -3084,7 +3084,7 @@ TagDecl* TagDecl::getCanonicalDecl() { } void TagDecl::setTypedefNameForAnonDecl(TypedefNameDecl *TDD) { - TypedefNameDeclOrQualifier = TDD; + NamedDeclOrQualifier = TDD; if (TypeForDecl) assert(TypeForDecl->isLinkageValid()); assert(isLinkageValid()); @@ -3141,7 +3141,7 @@ void TagDecl::setQualifierInfo(NestedNameSpecifierLoc QualifierLoc) { if (QualifierLoc) { // Make sure the extended qualifier info is allocated. if (!hasExtInfo()) - TypedefNameDeclOrQualifier = new (getASTContext()) ExtInfo; + NamedDeclOrQualifier = new (getASTContext()) ExtInfo; // Set qualifier info. getExtInfo()->QualifierLoc = QualifierLoc; } else { @@ -3149,7 +3149,7 @@ void TagDecl::setQualifierInfo(NestedNameSpecifierLoc QualifierLoc) { if (hasExtInfo()) { if (getExtInfo()->NumTemplParamLists == 0) { getASTContext().Deallocate(getExtInfo()); - TypedefNameDeclOrQualifier = (TypedefNameDecl*) 0; + NamedDeclOrQualifier = (TypedefNameDecl*) 0; } else getExtInfo()->QualifierLoc = QualifierLoc; @@ -3164,7 +3164,7 @@ void TagDecl::setTemplateParameterListsInfo(ASTContext &Context, // Make sure the extended decl info is allocated. if (!hasExtInfo()) // Allocate external info struct. - TypedefNameDeclOrQualifier = new (getASTContext()) ExtInfo; + NamedDeclOrQualifier = new (getASTContext()) ExtInfo; // Set the template parameter lists info. getExtInfo()->setTemplateParameterListsInfo(Context, NumTPLists, TPLists); } diff --git a/lib/AST/MicrosoftMangle.cpp b/lib/AST/MicrosoftMangle.cpp index 8506c4c8dd..119bc86be2 100644 --- a/lib/AST/MicrosoftMangle.cpp +++ b/lib/AST/MicrosoftMangle.cpp @@ -563,9 +563,15 @@ MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, break; } - // When VC encounters an anonymous type with no tag and no typedef, - // it literally emits '@'. - Out << "@"; + if (TD->hasDeclaratorForAnonDecl()) + // Anonymous types with no tag or typedef get the name of their + // declarator mangled in. + Out << "getDeclaratorForAnonDecl()->getName() + << ">@"; + else + // Anonymous types with no tag, no typedef, or declarator get + // '@'. + Out << "@"; break; } diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index a2e05e0094..beffe414f5 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -8814,13 +8814,21 @@ Sema::DeclGroupPtrTy Sema::FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS, if (DS.isTypeSpecOwned()) Decls.push_back(DS.getRepAsDecl()); + DeclaratorDecl *FirstDeclaratorInGroup = 0; for (unsigned i = 0, e = Group.size(); i != e; ++i) - if (Decl *D = Group[i]) + if (Decl *D = Group[i]) { + if (DeclaratorDecl *DD = dyn_cast(D)) + if (!FirstDeclaratorInGroup) + FirstDeclaratorInGroup = DD; Decls.push_back(D); + } if (DeclSpec::isDeclRep(DS.getTypeSpecType())) { - if (const TagDecl *Tag = dyn_cast_or_null(DS.getRepAsDecl())) + if (TagDecl *Tag = dyn_cast_or_null(DS.getRepAsDecl())) { HandleTagNumbering(*this, Tag); + if (!Tag->hasNameForLinkage() && !Tag->hasDeclaratorForAnonDecl()) + Tag->setDeclaratorForAnonDecl(FirstDeclaratorInGroup); + } } return BuildDeclaratorGroup(Decls, DS.containsPlaceholderType()); diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index cc9cb6317a..8cd37258b6 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -3356,6 +3356,19 @@ 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()) { + TagDecl *OldTag = OldTagType->getDecl(); + if (OldTag->getDeclaratorForAnonDecl() == OldVar) { + TagDecl *NewTag = NewVar->getType()->castAs()->getDecl(); + assert(!NewTag->hasNameForLinkage() && + !NewTag->hasDeclaratorForAnonDecl()); + NewTag->setDeclaratorForAnonDecl(NewVar); + } + } + InstantiateAttrs(TemplateArgs, OldVar, NewVar, LateAttrs, StartingScope); if (NewVar->hasAttrs()) diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index 791f3c9f8c..a9225fc81b 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -464,9 +464,9 @@ ASTDeclReader::RedeclarableResult ASTDeclReader::VisitTagDecl(TagDecl *TD) { if (Record[Idx++]) { // hasExtInfo TagDecl::ExtInfo *Info = new (Reader.getContext()) TagDecl::ExtInfo(); ReadQualifierInfo(*Info, Record, Idx); - TD->TypedefNameDeclOrQualifier = Info; + TD->NamedDeclOrQualifier = Info; } else - TD->setTypedefNameForAnonDecl(ReadDeclAs(Record, Idx)); + TD->NamedDeclOrQualifier = ReadDeclAs(Record, Idx); mergeRedeclarable(TD, Redecl); return Redecl; diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp index dc2ed46575..252569b2ca 100644 --- a/lib/Serialization/ASTWriterDecl.cpp +++ b/lib/Serialization/ASTWriterDecl.cpp @@ -229,6 +229,8 @@ void ASTDeclWriter::VisitTagDecl(TagDecl *D) { Record.push_back(D->hasExtInfo()); if (D->hasExtInfo()) Writer.AddQualifierInfo(*D->getExtInfo(), Record); + else if (D->hasDeclaratorForAnonDecl()) + Writer.AddDeclRef(D->getDeclaratorForAnonDecl(), Record); else Writer.AddDeclRef(D->getTypedefNameForAnonDecl(), Record); } diff --git a/test/CodeGenCXX/mangle-ms.cpp b/test/CodeGenCXX/mangle-ms.cpp index 8b7aa4223d..fd7c605c99 100644 --- a/test/CodeGenCXX/mangle-ms.cpp +++ b/test/CodeGenCXX/mangle-ms.cpp @@ -275,3 +275,32 @@ int wWinMain() { return 0; } int DllMain() { return 0; } // CHECK-DAG: @DllMain // X64-DAG: @DllMain + +inline int inline_function_with_local_type() { + static struct { + int a_field; + } static_variable_in_inline_function = { 20 }, second_static = { 40 }; + // CHECK: @"\01?static_variable_in_inline_function@?1??inline_function_with_local_type@@YAHXZ@4U@?1??1@YAHXZ@A" + + return static_variable_in_inline_function.a_field + second_static.a_field; +} + +int call_inline_function_with_local_type() { + return inline_function_with_local_type(); +} + +template +inline int templated_inline_function_with_local_type() { + static struct { + int a_field; + } static_variable_in_templated_inline_function = { 20 }, + second_static = { 40 }; + // CHECK: @"\01?static_variable_in_templated_inline_function@?1???$templated_inline_function_with_local_type@H@@YAHXZ@4U@?1???$templated_inline_function_with_local_type@H@@YAHXZ@A" + + return static_variable_in_templated_inline_function.a_field + + second_static.a_field; +} + +int call_templated_inline_function_with_local_type() { + return templated_inline_function_with_local_type(); +}