diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index e4774a587707a..4327eeb92bfbf 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -4554,9 +4554,12 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction( Entry->setLinkage(llvm::Function::ExternalLinkage); } - // Handle dropped DLL attributes. - if (D && !D->hasAttr() && !D->hasAttr() && - !shouldMapVisibilityToDLLExport(cast_or_null(D))) { + // Handle dropped dllimport. + if (D && + (Entry->getDLLStorageClass() == + llvm::GlobalVariable::DLLImportStorageClass) && + !D->hasAttr() && + !shouldMapVisibilityToDLLExport(cast(D))) { Entry->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass); setDSOLocal(Entry); } @@ -4849,9 +4852,11 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName, llvm::Type *Ty, Entry->setLinkage(llvm::Function::ExternalLinkage); } - // Handle dropped DLL attributes. - if (D && !D->hasAttr() && !D->hasAttr() && - !shouldMapVisibilityToDLLExport(D)) + // Handle dropped dllimport. + if (D && + (Entry->getDLLStorageClass() == + llvm::GlobalVariable::DLLImportStorageClass) && + !D->hasAttr() && !shouldMapVisibilityToDLLExport(D)) Entry->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass); if (LangOpts.OpenMP && !LangOpts.OpenMPSimd && D) diff --git a/clang/test/CodeGenCXX/windows-instantiate-dllexport-template-specialization.cpp b/clang/test/CodeGenCXX/windows-instantiate-dllexport-template-specialization.cpp new file mode 100644 index 0000000000000..97f341ba1f909 --- /dev/null +++ b/clang/test/CodeGenCXX/windows-instantiate-dllexport-template-specialization.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -triple i686-windows -fdeclspec -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-MS +// RUN: %clang_cc1 -triple i686-windows-itanium -fdeclspec -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-scei-ps4 -fdeclspec -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-sie-ps5 -fdeclspec -emit-llvm %s -o - | FileCheck %s + +struct s { + template static bool f(); +}; + +template bool template_using_f(T) { return s::f(); } + +bool use_template_using_f() { return template_using_f(0); } + +template<> +bool __declspec(dllexport) s::f() { return true; } + +// CHECK-MS: dllexport {{.*}} @"??$f@$00@s@@SA_NXZ" +// CHECK: dllexport {{.*}} @_ZN1s1fILb1EEEbv