diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-03-12 04:49:06 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-03-12 04:49:06 +0000 |
commit | e5e0c9deb1b4cfa081152cda548d31368facbc57 (patch) | |
tree | 9d56492d9869cdedcaaff27f5978ef3bdee8fa53 /lib/CodeGen | |
parent | 187ab37a05b8f7015b9f39cc8cd9129a0c6d0b48 (diff) |
Give explicit template instantiations weak linkage (but don't defer
them). Fixes PR6578.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@98328 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/CodeGenModule.cpp | 18 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.h | 3 |
2 files changed, 12 insertions, 9 deletions
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index c67948d27f..7314dae813 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: @@ -335,7 +334,8 @@ CodeGenModule::getFunctionLinkage(const FunctionDecl *D) { // In C99 mode, 'inline' functions are guaranteed to have a strong // definition somewhere else, so we can use available_externally linkage. return llvm::Function::AvailableExternallyLinkage; - } else if (Linkage == GVA_CXXInline || Linkage == GVA_TemplateInstantiation) { + } else if (Linkage == GVA_CXXInline || Linkage == GVA_TemplateInstantiation || + Linkage == GVA_ExplicitTemplateInstantiation) { // In C++, the compiler has to emit a definition in every translation unit // that references the function. We should use linkonce_odr because // a) if all references in this translation unit are optimized away, we @@ -589,6 +589,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 +1044,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 +1172,8 @@ 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) 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 |