summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2013-09-17 22:21:27 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2013-09-17 22:21:27 +0000
commit1ebb145bdff0b3dc85a972922b9c706d298fc462 (patch)
treec6580c88b57f6ccfb0565553d7d13e9a6b02ee19 /clang/lib
parent870b662779107b429a3ebc10340b039c48229806 (diff)
downloadbcm5719-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.cpp8
-rw-r--r--clang/lib/AST/MicrosoftMangle.cpp12
-rw-r--r--clang/lib/Sema/SemaDecl.cpp12
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiateDecl.cpp13
-rw-r--r--clang/lib/Serialization/ASTReaderDecl.cpp4
-rw-r--r--clang/lib/Serialization/ASTWriterDecl.cpp4
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) {
OpenPOWER on IntegriCloud