Index: lib/CodeGen/CodeGenModule.cpp =================================================================== --- lib/CodeGen/CodeGenModule.cpp +++ lib/CodeGen/CodeGenModule.cpp @@ -1609,7 +1609,11 @@ !VD->hasDefinition() && (VD->hasAttr() || VD->hasAttr()); - if (!MustEmitForCuda && + bool MustEmitVarInst = isa(VD) && + !VD->isStaticDataMember() && + !VD->hasDefinition() && + !VD->hasAttr(); + if (!(MustEmitForCuda || MustEmitVarInst) && VD->isThisDeclarationADefinition() != VarDecl::Definition && !Context.isMSStaticDataMemberInlineDefinition(VD)) { // If this declaration may have caused an inline variable definition to Index: test/CodeGenCXX/dllexport.cpp =================================================================== --- test/CodeGenCXX/dllexport.cpp +++ test/CodeGenCXX/dllexport.cpp @@ -108,8 +108,8 @@ template __declspec(dllexport) int VarTmplDef; INSTVAR(VarTmplDef) -// MSC-DAG: @"\01??$VarTmplImplicitDef@UImplicitInst_Exported@@@@3HA" = external dllexport global -// GNU-DAG: @_Z18VarTmplImplicitDefI21ImplicitInst_ExportedE = external dllexport global +// MSC-DAG: @"\01??$VarTmplImplicitDef@UImplicitInst_Exported@@@@3HA" = weak_odr dllexport global +// GNU-DAG: @_Z18VarTmplImplicitDefI21ImplicitInst_ExportedE = weak_odr dllexport global template __declspec(dllexport) int VarTmplImplicitDef; USEVAR(VarTmplImplicitDef) Index: test/CodeGenCXX/variable-templates.cpp =================================================================== --- /dev/null +++ test/CodeGenCXX/variable-templates.cpp @@ -0,0 +1,50 @@ +// RUN: %clang_cc1 -std=c++14 %s -triple=x86_64-linux -emit-llvm -o - | FileCheck %s + +// Unused template +// CHECK-NOT: _Z6var_00ILi0EE +template int var_00; + +// Definition without initializer +// CHECK: @_Z6var_01ILi0EE = linkonce_odr global i32 0, comdat +template int var_01; +int use_01a() { + return var_01<0>; +} +int use_01b() { + return var_01<0>; +} + +// Definitions without initializer combined with extern declaration + +// CHECK: @_Z6var_02ILi0EE = linkonce_odr global i32 0, comdat +template extern int var_02; +template int var_02; +int use_02() { + return var_02<0>; +} + +// CHECK: @_Z6var_03ILi0EE = linkonce_odr global i32 0, comdat +template int var_03; +template extern int var_03; +int use_03() { + return var_03<0>; +} + +// CHECK: @_Z6var_04ILi0EE = linkonce_odr global i32 0, comdat +template extern int var_04; +int use_04() { + return var_04<0>; +} +template int var_04; + +// CHECK: @_Z6var_05ILi0EE = linkonce_odr global i32 0, comdat +template int var_05; +int use_05() { + return var_05<0>; +} +template extern int var_05; + + +int main(int argc, char *argv[]) { + return 0; +}