diff options
author | David Majnemer <david.majnemer@gmail.com> | 2013-09-17 22:21:27 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2013-09-17 22:21:27 +0000 |
commit | 1ebb145bdff0b3dc85a972922b9c706d298fc462 (patch) | |
tree | c6580c88b57f6ccfb0565553d7d13e9a6b02ee19 /clang/lib | |
parent | 870b662779107b429a3ebc10340b039c48229806 (diff) | |
download | bcm5719-llvm-1ebb145bdff0b3dc85a972922b9c706d298fc462.tar.gz bcm5719-llvm-1ebb145bdff0b3dc85a972922b9c706d298fc462.zip |
[-cxx-abi microsoft] Mangle local TagDecls appropriately
Summary:
When selecting a mangling for an anonymous tag type:
- We should first try it's typedef'd name.
- If that doesn't work, we should mangle in the name of the declarator
that specified it as a declaration specifier.
- If that doesn't work, fall back to a static mangling of
<unnamed-type>.
This should make our anonymous type mangling compatible.
This partially fixes PR16994; we would need to have an implementation of
scope numbering to get it right (a separate issue).
Reviewers: rnk, rsmith, rjmccall, cdavis5x
CC: cfe-commits
Differential Revision: http://llvm-reviews.chandlerc.com/D1540
llvm-svn: 190892
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/Decl.cpp | 8 | ||||
-rw-r--r-- | clang/lib/AST/MicrosoftMangle.cpp | 12 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 12 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 13 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriterDecl.cpp | 4 |
6 files changed, 41 insertions, 12 deletions
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 0fa1b980f31..dbbf4753dcc 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/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/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp index 8506c4c8dde..119bc86be29 100644 --- a/clang/lib/AST/MicrosoftMangle.cpp +++ b/clang/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 '<unnamed-tag>@'. - Out << "<unnamed-tag>@"; + if (TD->hasDeclaratorForAnonDecl()) + // Anonymous types with no tag or typedef get the name of their + // declarator mangled in. + Out << "<unnamed-type-" << TD->getDeclaratorForAnonDecl()->getName() + << ">@"; + else + // Anonymous types with no tag, no typedef, or declarator get + // '<unnamed-tag>@'. + Out << "<unnamed-tag>@"; break; } diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index a2e05e0094f..beffe414f56 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/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<DeclaratorDecl>(D)) + if (!FirstDeclaratorInGroup) + FirstDeclaratorInGroup = DD; Decls.push_back(D); + } if (DeclSpec::isDeclRep(DS.getTypeSpecType())) { - if (const TagDecl *Tag = dyn_cast_or_null<TagDecl>(DS.getRepAsDecl())) + if (TagDecl *Tag = dyn_cast_or_null<TagDecl>(DS.getRepAsDecl())) { HandleTagNumbering(*this, Tag); + if (!Tag->hasNameForLinkage() && !Tag->hasDeclaratorForAnonDecl()) + Tag->setDeclaratorForAnonDecl(FirstDeclaratorInGroup); + } } return BuildDeclaratorGroup(Decls, DS.containsPlaceholderType()); diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index cc9cb6317a1..8cd37258b6a 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/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<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); if (NewVar->hasAttrs()) diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 791f3c9f8ca..a9225fc81be 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/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<TypedefNameDecl>(Record, Idx)); + TD->NamedDeclOrQualifier = ReadDeclAs<NamedDecl>(Record, Idx); mergeRedeclarable(TD, Redecl); return Redecl; diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index dc2ed465758..a9d8a03f717 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -229,8 +229,10 @@ void ASTDeclWriter::VisitTagDecl(TagDecl *D) { Record.push_back(D->hasExtInfo()); if (D->hasExtInfo()) Writer.AddQualifierInfo(*D->getExtInfo(), Record); - else + else if (D->getTypedefNameForAnonDecl()) Writer.AddDeclRef(D->getTypedefNameForAnonDecl(), Record); + else if (D->hasDeclaratorForAnonDecl()) + Writer.AddDeclRef(D->getDeclaratorForAnonDecl(), Record); } void ASTDeclWriter::VisitEnumDecl(EnumDecl *D) { |