http://reviews.llvm.org/D6295
Files:
include/clang/AST/Mangle.h
lib/AST/ItaniumMangle.cpp
lib/CodeGen/CodeGenFunction.cpp
test/CodeGenCXX/mangle-local-anonymous-unions.cpp
test/CodeGenCXX/mangle.cpp
Index: include/clang/AST/Mangle.h
===================================================================
--- include/clang/AST/Mangle.h
+++ include/clang/AST/Mangle.h
@@ -71,7 +71,8 @@
DiagnosticsEngine &getDiags() const { return Diags; }
virtual void startNewFunction() { LocalBlockIds.clear(); }
-
+ virtual void processNewFunction(const FunctionDecl &FD) {}
+
unsigned getBlockId(const BlockDecl *BD, bool Local) {
llvm::DenseMap<const BlockDecl *, unsigned> &BlockIds
= Local? LocalBlockIds : GlobalBlockIds;
Index: lib/AST/ItaniumMangle.cpp
===================================================================
--- lib/AST/ItaniumMangle.cpp
+++ lib/AST/ItaniumMangle.cpp
@@ -115,9 +115,11 @@
class ItaniumMangleContextImpl : public ItaniumMangleContext {
typedef std::pair<const DeclContext*, IdentifierInfo*> DiscriminatorKeyTy;
- llvm::DenseMap<DiscriminatorKeyTy, unsigned> Discriminator;
+ llvm::DenseMap<DiscriminatorKeyTy, unsigned> Discriminators;
llvm::DenseMap<const NamedDecl*, unsigned> Uniquifier;
-
+private:
+ unsigned uniquifyNamedDecl(const NamedDecl *ND);
+
public:
explicit ItaniumMangleContextImpl(ASTContext &Context,
DiagnosticsEngine &Diags)
@@ -162,37 +164,8 @@
void mangleStringLiteral(const StringLiteral *, raw_ostream &) override;
- bool getNextDiscriminator(const NamedDecl *ND, unsigned &disc) {
- // Lambda closure types are already numbered.
- if (isLambda(ND))
- return false;
-
- // Anonymous tags are already numbered.
- if (const TagDecl *Tag = dyn_cast<TagDecl>(ND)) {
- if (Tag->getName().empty() && !Tag->getTypedefNameForAnonDecl())
- return false;
- }
-
- // Use the canonical number for externally visible decls.
- if (ND->isExternallyVisible()) {
- unsigned discriminator = getASTContext().getManglingNumber(ND);
- if (discriminator == 1)
- return false;
- disc = discriminator - 2;
- return true;
- }
-
- // Make up a reasonable number for internal decls.
- unsigned &discriminator = Uniquifier[ND];
- if (!discriminator) {
- const DeclContext *DC = getEffectiveDeclContext(ND);
- discriminator = ++Discriminator[std::make_pair(DC, ND->getIdentifier())];
- }
- if (discriminator == 1)
- return false;
- disc = discriminator-2;
- return true;
- }
+ bool getNextDiscriminator(const NamedDecl *ND, unsigned &disc);
+ void processNewFunction(const FunctionDecl &FD) override;
/// @}
};
@@ -3733,7 +3706,7 @@
"Mangling declaration");
CXXNameMangler Mangler(*this, Out, D);
- return Mangler.mangle(D);
+ Mangler.mangle(D);
}
void ItaniumMangleContextImpl::mangleCXXCtor(const CXXConstructorDecl *D,
@@ -3922,3 +3895,62 @@
ItaniumMangleContext::create(ASTContext &Context, DiagnosticsEngine &Diags) {
return new ItaniumMangleContextImpl(Context, Diags);
}
+
+static bool isDiscriminatorNeeded(const NamedDecl *ND) {
+ // Lambda closure types are already numbered.
+ if (isLambda(ND))
+ return false;
+
+ // Anonymous tags are already numbered.
+ if (const TagDecl *Tag = dyn_cast<TagDecl>(ND)) {
+ if (Tag->getName().empty() && !Tag->getTypedefNameForAnonDecl())
+ return false;
+ }
+
+ if (const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
+ return VD->isStaticLocal() || VD->isExternallyVisible();
+ }
+
+ return true;
+}
+
+unsigned ItaniumMangleContextImpl::uniquifyNamedDecl(const NamedDecl *ND) {
+ if (IdentifierInfo *Identifier = ND->getIdentifier()) {
+ const NamedDecl *D = ND;
+ if (const IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(ND)) {
+ D = IFD->getVarDecl();
+ }
+ unsigned &Discriminator = Uniquifier[D];
+ if (!Discriminator) {
+ const DeclContext *DC = getEffectiveDeclContext(D);
+ Discriminator = ++Discriminators[std::make_pair(DC, Identifier)];
+ }
+ return Discriminator;
+ } else
+ return 0;
+}
+
+void ItaniumMangleContextImpl::processNewFunction(const FunctionDecl &FD) {
+ for (auto D: FD.decls()) {
+ if (const NamedDecl * ND = dyn_cast<NamedDecl>(D)) {
+ if (isDiscriminatorNeeded(ND))
+ uniquifyNamedDecl(ND);
+ }
+ }
+}
+
+bool ItaniumMangleContextImpl::getNextDiscriminator(const NamedDecl *ND,
+ unsigned &disc) {
+ if (!isDiscriminatorNeeded(ND))
+ return false;
+
+ unsigned Discriminator = Uniquifier[ND];
+ if (!Discriminator) {
+ Discriminator = uniquifyNamedDecl(ND);
+ }
+ if (Discriminator <= 1)
+ return false;
+ disc = Discriminator-2;
+ return true;
+}
+
Index: lib/CodeGen/CodeGenFunction.cpp
===================================================================
--- lib/CodeGen/CodeGenFunction.cpp
+++ lib/CodeGen/CodeGenFunction.cpp
@@ -809,6 +809,7 @@
void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn,
const CGFunctionInfo &FnInfo) {
const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl());
+ CGM.getCXXABI().getMangleContext().processNewFunction(*FD);
// Check if we should generate debug info for this function.
if (FD->hasAttr<NoDebugAttr>())
Index: test/CodeGenCXX/mangle-local-anonymous-unions.cpp
===================================================================
--- test/CodeGenCXX/mangle-local-anonymous-unions.cpp
+++ test/CodeGenCXX/mangle-local-anonymous-unions.cpp
@@ -0,0 +1,63 @@
+// RUN: %clang_cc1 %s -emit-llvm -triple %itanium_abi_triple -o - | FileCheck %s
+
+// CHECK-DAG: @_ZZ2f0vE1a
+// CHECK-DAG: @_ZZ2f0vE1c
+// CHECK-DAG: @_ZZ2f0vE1e_0
+inline int f0() {
+ static union {
+ int a;
+ long int b;
+ };
+
+ static union {
+ int c;
+ double d;
+ };
+
+ if (0) {
+ static union {
+ int e;
+ int f;
+ };
+ }
+ static union {
+ int e;
+ int f;
+ };
+
+ return a+c;
+}
+
+// CHECK-DAG: @_ZZ2f1vE1a
+// CHECK-DAG: @_ZZ2f1vE1c
+// CHECK-DAG: @_ZZ2f1vE1c_0
+// CHECK-DAG: @_ZZ2f1vE1c_1
+// CHECK-DAG: @_ZZ2f1vE1e_0
+int f1 () {
+ static union {
+ int a;
+ long int b;
+ };
+
+ static union {
+ int c;
+ double d;
+ };
+
+ { static int c; }
+ { static int c; }
+
+ if (0) {
+ static union {
+ int e;
+ int f;
+ };
+ }
+ static union {
+ int e;
+ int f;
+ };
+
+ return a+c+f0();
+}
+
Index: test/CodeGenCXX/mangle.cpp
===================================================================
--- test/CodeGenCXX/mangle.cpp
+++ test/CodeGenCXX/mangle.cpp
@@ -899,7 +899,7 @@
}
namespace test40 {
- // CHECK: i32* {{.*}} @_ZZN6test401fEvE1a_0
+ // CHECK-DAG: i32* {{.*}} @_ZZN6test401fEvE1a_0
void h(int&);
inline void f() {
if (0) {
@@ -908,7 +908,15 @@
static int a;
h(a);
};
- void g() { f(); }
+ // CHECK-DAG: i32* {{.*}} @_ZZN6test402ffEvE1a_0
+ void ff() {
+ if (0) {
+ static int a;
+ }
+ static int a;
+ h(a);
+ }
+ void g() { f(); ff(); }
}
namespace test41 {
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits