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 &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 DiscriminatorKeyTy; - llvm::DenseMap Discriminator; + llvm::DenseMap Discriminators; llvm::DenseMap 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(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(ND)) { + if (Tag->getName().empty() && !Tag->getTypedefNameForAnonDecl()) + return false; + } + + if (const VarDecl *VD = dyn_cast(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(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(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(GD.getDecl()); + CGM.getCXXABI().getMangleContext().processNewFunction(*FD); // Check if we should generate debug info for this function. if (FD->hasAttr()) 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 {