Mangle anonymous structs/unions correctly. Fixes PR5139.
llvm-svn: 83448
This commit is contained in:
parent
db9fca7735
commit
1e39bd944b
|
@ -22,6 +22,7 @@
|
||||||
#include "clang/AST/DeclTemplate.h"
|
#include "clang/AST/DeclTemplate.h"
|
||||||
#include "clang/AST/ExprCXX.h"
|
#include "clang/AST/ExprCXX.h"
|
||||||
#include "clang/Basic/SourceManager.h"
|
#include "clang/Basic/SourceManager.h"
|
||||||
|
#include "llvm/ADT/StringExtras.h"
|
||||||
#include "llvm/Support/Compiler.h"
|
#include "llvm/Support/Compiler.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
#include "llvm/Support/ErrorHandling.h"
|
#include "llvm/Support/ErrorHandling.h"
|
||||||
|
@ -404,8 +405,8 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND) {
|
||||||
// ::= <source-name>
|
// ::= <source-name>
|
||||||
DeclarationName Name = ND->getDeclName();
|
DeclarationName Name = ND->getDeclName();
|
||||||
switch (Name.getNameKind()) {
|
switch (Name.getNameKind()) {
|
||||||
case DeclarationName::Identifier:
|
case DeclarationName::Identifier: {
|
||||||
if (const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(ND))
|
if (const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(ND)) {
|
||||||
if (NS->isAnonymousNamespace()) {
|
if (NS->isAnonymousNamespace()) {
|
||||||
// This is how gcc mangles these names. It's apparently
|
// This is how gcc mangles these names. It's apparently
|
||||||
// always '1', no matter how many different anonymous
|
// always '1', no matter how many different anonymous
|
||||||
|
@ -413,8 +414,38 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND) {
|
||||||
Out << "12_GLOBAL__N_1";
|
Out << "12_GLOBAL__N_1";
|
||||||
break;
|
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;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case DeclarationName::ObjCZeroArgSelector:
|
case DeclarationName::ObjCZeroArgSelector:
|
||||||
case DeclarationName::ObjCOneArgSelector:
|
case DeclarationName::ObjCOneArgSelector:
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
#include "CGCXX.h"
|
#include "CGCXX.h"
|
||||||
#include "clang/AST/Type.h"
|
#include "clang/AST/Type.h"
|
||||||
|
#include "llvm/ADT/DenseMap.h"
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
class raw_ostream;
|
class raw_ostream;
|
||||||
|
@ -35,11 +36,21 @@ namespace clang {
|
||||||
|
|
||||||
class MangleContext {
|
class MangleContext {
|
||||||
ASTContext &Context;
|
ASTContext &Context;
|
||||||
|
|
||||||
|
llvm::DenseMap<const TagDecl *, uint64_t> AnonStructIds;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit MangleContext(ASTContext &Context)
|
explicit MangleContext(ASTContext &Context)
|
||||||
: Context(Context) { }
|
: Context(Context) { }
|
||||||
|
|
||||||
ASTContext &getASTContext() const { return 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,
|
bool mangleName(MangleContext &Context, const NamedDecl *D,
|
||||||
|
|
|
@ -207,3 +207,17 @@ void extern_f(void);
|
||||||
// CHECK: @extern_f
|
// CHECK: @extern_f
|
||||||
void extern_f(void) { }
|
void extern_f(void) { }
|
||||||
|
|
||||||
|
struct S7 {
|
||||||
|
struct S { S(); };
|
||||||
|
|
||||||
|
struct {
|
||||||
|
S s;
|
||||||
|
} a;
|
||||||
|
};
|
||||||
|
|
||||||
|
// PR5139
|
||||||
|
// CHECK: @_ZN2S7C1Ev
|
||||||
|
// CHECK: @_ZN2S7C2Ev
|
||||||
|
// CHECK: @"_ZN2S73$_0C1Ev"
|
||||||
|
S7::S7() {}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue