diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-03-13 18:23:07 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-03-13 18:23:07 +0000 |
commit | b14d1237740b76d3f9f9b116f1dab4564c4744ca (patch) | |
tree | 37f5000052e2162a19bb503fb402203e97fdbe71 /clang/lib/CodeGen/CodeGenModule.cpp | |
parent | 13327bbe5535da30a203cd8b00d4037085e6d557 (diff) | |
download | bcm5719-llvm-b14d1237740b76d3f9f9b116f1dab4564c4744ca.tar.gz bcm5719-llvm-b14d1237740b76d3f9f9b116f1dab4564c4744ca.zip |
Give explicit template instantiations weak ODR linkage. Former
iterations of this patch gave explicit template instantiation
link-once ODR linkage, which permitted the back end to eliminate
unused symbols. Weak ODR linkage still requires the symbols to be
generated.
llvm-svn: 98441
Diffstat (limited to 'clang/lib/CodeGen/CodeGenModule.cpp')
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index c67948d27f0..f41db14f1a6 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -285,8 +285,7 @@ GetLinkageForFunction(ASTContext &Context, const FunctionDecl *FD, break; case TSK_ExplicitInstantiationDefinition: - // FIXME: explicit instantiation definitions should use weak linkage - return CodeGenModule::GVA_StrongExternal; + return CodeGenModule::GVA_ExplicitTemplateInstantiation; case TSK_ExplicitInstantiationDeclaration: case TSK_ImplicitInstantiation: @@ -343,6 +342,12 @@ CodeGenModule::getFunctionLinkage(const FunctionDecl *D) { // merged with other definitions. c) C++ has the ODR, so we know the // definition is dependable. return llvm::Function::LinkOnceODRLinkage; + } else if (Linkage == GVA_ExplicitTemplateInstantiation) { + // An explicit instantiation of a template has weak linkage, since + // explicit instantiations can occur in multiple translation units + // and must all be equivalent. However, we are not allowed to + // throw away these explicit instantiations. + return llvm::Function::WeakODRLinkage; } else { assert(Linkage == GVA_StrongExternal); // Otherwise, we have strong external linkage. @@ -589,6 +594,7 @@ bool CodeGenModule::MayDeferGeneration(const ValueDecl *Global) { // static, static inline, always_inline, and extern inline functions can // always be deferred. Normal inline functions can be deferred in C99/C++. + // Implicit template instantiations can also be deferred in C++. if (Linkage == GVA_Internal || Linkage == GVA_C99Inline || Linkage == GVA_CXXInline || Linkage == GVA_TemplateInstantiation) return true; @@ -1043,15 +1049,15 @@ GetLinkageForVariable(ASTContext &Context, const VarDecl *VD) { switch (TSK) { case TSK_Undeclared: case TSK_ExplicitSpecialization: - - // FIXME: ExplicitInstantiationDefinition should be weak! - case TSK_ExplicitInstantiationDefinition: return CodeGenModule::GVA_StrongExternal; - + case TSK_ExplicitInstantiationDeclaration: llvm_unreachable("Variable should not be instantiated"); // Fall through to treat this like any other instantiation. + case TSK_ExplicitInstantiationDefinition: + return CodeGenModule::GVA_ExplicitTemplateInstantiation; + case TSK_ImplicitInstantiation: return CodeGenModule::GVA_TemplateInstantiation; } @@ -1171,7 +1177,10 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) { GV->setLinkage(llvm::GlobalVariable::WeakODRLinkage); else GV->setLinkage(llvm::GlobalVariable::WeakAnyLinkage); - } else if (Linkage == GVA_TemplateInstantiation) + } else if (Linkage == GVA_TemplateInstantiation || + Linkage == GVA_ExplicitTemplateInstantiation) + // FIXME: It seems like we can provide more specific linkage here + // (LinkOnceODR, WeakODR). GV->setLinkage(llvm::GlobalVariable::WeakAnyLinkage); else if (!getLangOptions().CPlusPlus && !CodeGenOpts.NoCommon && !D->hasExternalStorage() && !D->getInit() && |