Mangle anonymous structs/unions correctly. Fixes PR5139.

llvm-svn: 83448
This commit is contained in:
Anders Carlsson 2009-10-07 01:45:02 +00:00
parent db9fca7735
commit 1e39bd944b
3 changed files with 59 additions and 3 deletions

View File

@ -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:

View File

@ -20,6 +20,7 @@
#include "CGCXX.h"
#include "clang/AST/Type.h"
#include "llvm/ADT/DenseMap.h"
namespace llvm {
class raw_ostream;
@ -35,11 +36,21 @@ namespace clang {
class MangleContext {
ASTContext &Context;
llvm::DenseMap<const TagDecl *, uint64_t> AnonStructIds;
public:
explicit MangleContext(ASTContext &Context)
: Context(Context) { }
ASTContext &getASTContext() const { return Context; }
uint64_t getAnonymousStructId(const TagDecl *TD) {
std::pair<llvm::DenseMap<const TagDecl *,
uint64_t>::iterator, bool> Result =
AnonStructIds.insert(std::make_pair(TD, AnonStructIds.size()));
return Result.first->second;
}
};
bool mangleName(MangleContext &Context, const NamedDecl *D,

View File

@ -207,3 +207,17 @@ void extern_f(void);
// CHECK: @extern_f
void extern_f(void) { }
struct S7 {
struct S { S(); };
struct {
S s;
} a;
};
// PR5139
// CHECK: @_ZN2S7C1Ev
// CHECK: @_ZN2S7C2Ev
// CHECK: @"_ZN2S73$_0C1Ev"
S7::S7() {}