From 1e39bd944b615aa9d577f97cd84e05af1a611207 Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Wed, 7 Oct 2009 01:45:02 +0000 Subject: Mangle anonymous structs/unions correctly. Fixes PR5139. llvm-svn: 83448 --- clang/lib/CodeGen/Mangle.cpp | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) (limited to 'clang/lib/CodeGen/Mangle.cpp') diff --git a/clang/lib/CodeGen/Mangle.cpp b/clang/lib/CodeGen/Mangle.cpp index 269c1130f79..aa017c92077 100644 --- a/clang/lib/CodeGen/Mangle.cpp +++ b/clang/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) { // ::= DeclarationName Name = ND->getDeclName(); switch (Name.getNameKind()) { - case DeclarationName::Identifier: - if (const NamespaceDecl *NS = dyn_cast(ND)) + case DeclarationName::Identifier: { + if (const NamespaceDecl *NS = dyn_cast(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(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] $_ + // 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: -- cgit v1.2.3