diff options
author | Anders Carlsson <andersca@mac.com> | 2009-10-07 01:45:02 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2009-10-07 01:45:02 +0000 |
commit | c4355b6883382b85cda3b7337587784dabf3450b (patch) | |
tree | c7259415334f343cfd10c9c7fe1fbaabd8844b4b /lib/CodeGen/Mangle.cpp | |
parent | 44da821078a5f09127a01f9aa01dd9dd9af9de86 (diff) |
Mangle anonymous structs/unions correctly. Fixes PR5139.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@83448 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/Mangle.cpp')
-rw-r--r-- | lib/CodeGen/Mangle.cpp | 37 |
1 files changed, 34 insertions, 3 deletions
diff --git a/lib/CodeGen/Mangle.cpp b/lib/CodeGen/Mangle.cpp index 269c1130f7..aa017c9207 100644 --- a/lib/CodeGen/Mangle.cpp +++ b/lib/CodeGen/Mangle.cpp @@ -22,6 +22,7 @@ #include "clang/AST/DeclTemplate.h" #include "clang/AST/ExprCXX.h" #include "clang/Basic/SourceManager.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/ErrorHandling.h" @@ -404,8 +405,8 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND) { // ::= <source-name> DeclarationName Name = ND->getDeclName(); switch (Name.getNameKind()) { - case DeclarationName::Identifier: - if (const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(ND)) + case DeclarationName::Identifier: { + if (const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(ND)) { if (NS->isAnonymousNamespace()) { // This is how gcc mangles these names. It's apparently // always '1', no matter how many different anonymous @@ -413,8 +414,38 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND) { Out << "12_GLOBAL__N_1"; break; } - mangleSourceName(Name.getAsIdentifierInfo()); + } + + if (const IdentifierInfo *II = Name.getAsIdentifierInfo()) { + mangleSourceName(II); + break; + } + + // We must have an anonymous struct. + const TagDecl *TD = cast<TagDecl>(ND); + if (const TypedefDecl *D = TD->getTypedefForAnonDecl()) { + assert(TD->getDeclContext() == D->getDeclContext() && + "Typedef should not be in another decl context!"); + assert(D->getDeclName().getAsIdentifierInfo() && + "Typedef was not named!"); + mangleSourceName(D->getDeclName().getAsIdentifierInfo()); + break; + } + + // Get a unique id for the anonymous struct. + uint64_t AnonStructId = Context.getAnonymousStructId(TD); + + // Mangle it as a source name in the form + // [n] $_<id> + // where n is the length of the string. + llvm::SmallString<8> Str; + Str += "$_"; + Str += llvm::utostr(AnonStructId); + + Out << Str.size(); + Out << Str.str(); break; + } case DeclarationName::ObjCZeroArgSelector: case DeclarationName::ObjCOneArgSelector: |