aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-03-13 18:23:07 +0000
committerDouglas Gregor <dgregor@apple.com>2010-03-13 18:23:07 +0000
commit8f51a4f2d00b0abda3cde7f3828fb2e2b9beafb5 (patch)
treef094edbfc92c77e38ed8992e41961d673cc552d3 /lib/CodeGen
parent961b167bcea8fe37465b2770c90bf9bf6b349470 (diff)
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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@98441 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/CodeGenModule.cpp23
-rw-r--r--lib/CodeGen/CodeGenModule.h3
2 files changed, 18 insertions, 8 deletions
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index c67948d27f..f41db14f1a 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/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() &&
diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h
index 40dc563889..9077adedd0 100644
--- a/lib/CodeGen/CodeGenModule.h
+++ b/lib/CodeGen/CodeGenModule.h
@@ -437,7 +437,8 @@ public:
GVA_C99Inline,
GVA_CXXInline,
GVA_StrongExternal,
- GVA_TemplateInstantiation
+ GVA_TemplateInstantiation,
+ GVA_ExplicitTemplateInstantiation
};
llvm::GlobalVariable::LinkageTypes