diff options
author | Anders Carlsson <andersca@mac.com> | 2010-06-08 14:49:03 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2010-06-08 14:49:03 +0000 |
commit | 6f7e2f4019860cad19883db44f4d0bfa36d2f552 (patch) | |
tree | f34dce4a4b27312225149201bf167a643c0a489e /lib/CodeGen/Mangle.cpp | |
parent | 1c573cb0e06bac4e557123703069da7dd45d3dc0 (diff) |
Correctly mangle static variables of anonymous struct/union type.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@105606 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/Mangle.cpp')
-rw-r--r-- | lib/CodeGen/Mangle.cpp | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/lib/CodeGen/Mangle.cpp b/lib/CodeGen/Mangle.cpp index c246bb50c6..faa9a9e453 100644 --- a/lib/CodeGen/Mangle.cpp +++ b/lib/CodeGen/Mangle.cpp @@ -598,6 +598,28 @@ void CXXNameMangler::mangleUnresolvedName(NestedNameSpecifier *Qualifier, mangleUnqualifiedName(0, Name, KnownArity); } +static const FieldDecl *FindFirstNamedDataMember(const RecordDecl *RD) { + assert(RD->isAnonymousStructOrUnion() && + "Expected anonymous struct or union!"); + + for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end(); + I != E; ++I) { + const FieldDecl *FD = *I; + + if (FD->getIdentifier()) + return FD; + + if (const RecordType *RT = FD->getType()->getAs<RecordType>()) { + if (const FieldDecl *NamedDataMember = + FindFirstNamedDataMember(RT->getDecl())) + return NamedDataMember; + } + } + + // We didn't find a named data member. + return 0; +} + void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, DeclarationName Name, unsigned KnownArity) { @@ -630,6 +652,28 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, } } + if (const VarDecl *VD = dyn_cast<VarDecl>(ND)) { + // We must have an anonymous union or struct declaration. + const RecordDecl *RD = + cast<RecordDecl>(VD->getType()->getAs<RecordType>()->getDecl()); + + // Itanium C++ ABI 5.1.2: + // + // For the purposes of mangling, the name of an anonymous union is + // considered to be the name of the first named data member found by a + // pre-order, depth-first, declaration-order walk of the data members of + // the anonymous union. If there is no such data member (i.e., if all of + // the data members in the union are unnamed), then there is no way for + // a program to refer to the anonymous union, and there is therefore no + // need to mangle its name. + const FieldDecl *FD = FindFirstNamedDataMember(RD); + assert(FD && "Didn't find a named data member!"); + assert(FD->getIdentifier() && "Data member name isn't an identifier!"); + + mangleSourceName(FD->getIdentifier()); + break; + } + // We must have an anonymous struct. const TagDecl *TD = cast<TagDecl>(ND); if (const TypedefDecl *D = TD->getTypedefForAnonDecl()) { |