From: Eli Friedman Date: Mon, 1 Jul 2013 20:53:07 +0000 (+0000) Subject: Simplify linkage code for static local vars. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7a36a5913f045bfaf6d26ed874e39a3e7c1ad9ae;p=clang Simplify linkage code for static local vars. The key insight here is that weak linkage for a static local variable should always mean linkonce_odr, because every file that needs it will generate a definition. We don't actually care about the precise linkage of the parent context. I feel a bit silly that I didn't realize this before. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@185381 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp index 62cd7442ec..49364e6b56 100644 --- a/lib/CodeGen/CGDecl.cpp +++ b/lib/CodeGen/CGDecl.cpp @@ -124,60 +124,14 @@ void CodeGenFunction::EmitVarDecl(const VarDecl &D) { llvm::GlobalValue::LinkageTypes Linkage = llvm::GlobalValue::InternalLinkage; - // If the function definition has some sort of weak linkage, its - // static variables should also be weak so that they get properly - // uniqued. + // If the variable is externally visible, it must have weak linkage so it + // can be uniqued. if (D.isExternallyVisible()) { - const Decl *D = CurCodeDecl; - while (true) { - if (const BlockDecl *BD = dyn_cast(D)) { - if (!BD->getBlockManglingNumber()) - break; - - // This block has the linkage/visibility of its contained variables - // determined by its owner. - const DeclContext *DC = D->getDeclContext()->getRedeclContext(); - if (Decl *ContextDecl = BD->getBlockManglingContextDecl()) { - if (isa(ContextDecl)) { - DC = ContextDecl->getDeclContext()->getRedeclContext(); - } else { - D = ContextDecl; - continue; - } - } - - if (const NamedDecl *ND = dyn_cast(DC)) { - D = ND; - continue; - } - - break; - } else if (isa(D)) { - D = cast(cast(D)->getParent()); - } else { - break; - } - } - llvm::GlobalValue::LinkageTypes ParentLinkage; - if (isa(D)) { - ParentLinkage = CGM.getFunctionLinkage(cast(D)); - } else if (isa(D)) { - // FIXME: I'm pretty sure this is wrong... - ParentLinkage = CGM.GetLLVMLinkageVarDefinition(cast(D), - /*constant*/false); - } else { - assert(isa(D) && "Expect function, variable, or field"); - // FIXME: Is this right? - ParentLinkage = llvm::GlobalValue::LinkOnceODRLinkage; - } - - if (llvm::GlobalValue::isWeakForLinker(ParentLinkage)) - Linkage = ParentLinkage; + Linkage = llvm::GlobalValue::LinkOnceODRLinkage; // FIXME: We need to force the emission/use of a guard variable for // some variables even if we can constant-evaluate them because // we can't guarantee every translation unit will constant-evaluate them. - // Also, we might need to fix up the linkage. } return EmitStaticVarDecl(D, Linkage); diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index cfb9e78368..250442caae 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -515,11 +515,7 @@ void CodeGenModule::EmitCtorList(const CtorList &Fns, const char *GlobalName) { llvm::GlobalValue::LinkageTypes CodeGenModule::getFunctionLinkage(GlobalDecl GD) { - return getFunctionLinkage(cast(GD.getDecl())); -} - -llvm::GlobalValue::LinkageTypes -CodeGenModule::getFunctionLinkage(const FunctionDecl *D) { + const FunctionDecl *D = cast(GD.getDecl()); GVALinkage Linkage = getContext().GetGVALinkageForFunction(D); if (Linkage == GVA_Internal) diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index a5fca36a93..b4e234f4a7 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -925,7 +925,6 @@ public: void AddDependentLib(StringRef Lib); llvm::GlobalVariable::LinkageTypes getFunctionLinkage(GlobalDecl GD); - llvm::GlobalVariable::LinkageTypes getFunctionLinkage(const FunctionDecl *D); void setFunctionLinkage(GlobalDecl GD, llvm::GlobalValue *V) { V->setLinkage(getFunctionLinkage(GD)); diff --git a/test/CodeGenCXX/linkage.cpp b/test/CodeGenCXX/linkage.cpp index c7feaefeb8..4aba1b3282 100644 --- a/test/CodeGenCXX/linkage.cpp +++ b/test/CodeGenCXX/linkage.cpp @@ -211,7 +211,7 @@ namespace test16 { } namespace test17 { - // CHECK-DAG: @_ZZN6test173fooILi42EEEPivE3bar = weak_odr + // CHECK-DAG: @_ZZN6test173fooILi42EEEPivE3bar = linkonce_odr // CHECK-DAG: define weak_odr i32* @_ZN6test173fooILi42EEEPiv( template int *foo() {