From: Hans Wennborg Date: Thu, 28 May 2015 17:44:56 +0000 (+0000) Subject: Get the dll storage class right for structors of classes exported/imported via explic... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a386316d89408297df095c0fa23ef2f0dcb3e2d3;p=clang Get the dll storage class right for structors of classes exported/imported via explicit instantiation (PR23667) This is a follow-up to r238266. It turned out structors are codegened through a different path, and didn't get the storage class set in EmitGlobalFunctionDefinition. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@238443 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp index 29a199d697..7d7ed784b1 100644 --- a/lib/CodeGen/CGCXX.cpp +++ b/lib/CodeGen/CGCXX.cpp @@ -218,6 +218,8 @@ llvm::Function *CodeGenModule::codegenCXXStructor(const CXXMethodDecl *MD, } setFunctionLinkage(GD, Fn); + setFunctionDLLStorageClass(GD, Fn); + CodeGenFunction(*this).GenerateCode(GD, Fn, FnInfo); setFunctionDefinitionAttributes(MD, Fn); SetLLVMFunctionAttributesForDefinition(MD, Fn); diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 400506129e..e275466ce1 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -676,6 +676,25 @@ CodeGenModule::getFunctionLinkage(GlobalDecl GD) { return getLLVMLinkageForDeclarator(D, Linkage, /*isConstantVariable=*/false); } +void CodeGenModule::setFunctionDLLStorageClass(GlobalDecl GD, llvm::Function *F) { + const auto *FD = cast(GD.getDecl()); + + if (const auto *Dtor = dyn_cast_or_null(FD)) { + if (getCXXABI().useThunkForDtorVariant(Dtor, GD.getDtorType())) { + // Don't dllexport/import destructor thunks. + F->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass); + return; + } + } + + if (FD->hasAttr()) + F->setDLLStorageClass(llvm::GlobalVariable::DLLImportStorageClass); + else if (FD->hasAttr()) + F->setDLLStorageClass(llvm::GlobalVariable::DLLExportStorageClass); + else + F->setDLLStorageClass(llvm::GlobalVariable::DefaultStorageClass); +} + void CodeGenModule::setFunctionDefinitionAttributes(const FunctionDecl *D, llvm::Function *F) { setNonAliasAttributes(D, F); @@ -889,13 +908,6 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, llvm::Function *F, setLinkageAndVisibilityForGV(F, FD); - if (const auto *Dtor = dyn_cast_or_null(FD)) { - if (getCXXABI().useThunkForDtorVariant(Dtor, GD.getDtorType())) { - // Don't dllexport/import destructor thunks. - F->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass); - } - } - if (const SectionAttr *SA = FD->getAttr()) F->setSection(SA->getName()); @@ -2455,12 +2467,7 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD, // declarations). auto *Fn = cast(GV); setFunctionLinkage(GD, Fn); - if (D->hasAttr()) - GV->setDLLStorageClass(llvm::GlobalVariable::DLLImportStorageClass); - else if (D->hasAttr()) - GV->setDLLStorageClass(llvm::GlobalVariable::DLLExportStorageClass); - else - GV->setDLLStorageClass(llvm::GlobalVariable::DefaultStorageClass); + setFunctionDLLStorageClass(GD, Fn); // FIXME: this is redundant with part of setFunctionDefinitionAttributes setGlobalVisibility(Fn, D); diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index feef6c2583..35000964b2 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -1018,6 +1018,9 @@ public: F->setLinkage(getFunctionLinkage(GD)); } + /// Set the DLL storage class on F. + void setFunctionDLLStorageClass(GlobalDecl GD, llvm::Function *F); + /// Return the appropriate linkage for the vtable, VTT, and type information /// of the given class. llvm::GlobalVariable::LinkageTypes getVTableLinkage(const CXXRecordDecl *RD); diff --git a/test/CodeGenCXX/dllexport.cpp b/test/CodeGenCXX/dllexport.cpp index 3a1a3ffd87..916e695005 100644 --- a/test/CodeGenCXX/dllexport.cpp +++ b/test/CodeGenCXX/dllexport.cpp @@ -691,10 +691,11 @@ extern template struct ExplicitInstantiationDeclExportedTemplate; USEMEMFUNC(ExplicitInstantiationDeclExportedTemplate, f); // M32-DAG: {{declare|define available_externally}} x86_thiscallcc void @"\01?f@?$ExplicitInstantiationDeclExportedTemplate@H@@QAEXXZ" -template struct ExplicitInstantiationDeclExportedDefTemplate { void f() {} }; +template struct ExplicitInstantiationDeclExportedDefTemplate { void f() {} ExplicitInstantiationDeclExportedDefTemplate() {} }; extern template struct ExplicitInstantiationDeclExportedDefTemplate; template struct __declspec(dllexport) ExplicitInstantiationDeclExportedDefTemplate; // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?f@?$ExplicitInstantiationDeclExportedDefTemplate@H@@QAEXXZ" +// M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExplicitInstantiationDeclExportedDefTemplate* @"\01??0?$ExplicitInstantiationDeclExportedDefTemplate@H@@QAE@XZ" namespace { struct InternalLinkageType {}; } struct __declspec(dllexport) PR23308 { diff --git a/test/CodeGenCXX/dllimport.cpp b/test/CodeGenCXX/dllimport.cpp index 6de856017b..0867fdd3f0 100644 --- a/test/CodeGenCXX/dllimport.cpp +++ b/test/CodeGenCXX/dllimport.cpp @@ -724,17 +724,21 @@ template struct __declspec(dllimport) ExplicitlyInstantiatedWithDifferentAttr, f); // M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?f@?$ExplicitlyInstantiatedWithDifferentAttr@H@@QAEXXZ" -template struct ExplicitInstantiationDeclImportedDefTemplate { void f() {} }; +template struct ExplicitInstantiationDeclImportedDefTemplate { void f() {} ExplicitInstantiationDeclImportedDefTemplate() {}}; extern template struct ExplicitInstantiationDeclImportedDefTemplate; template struct __declspec(dllimport) ExplicitInstantiationDeclImportedDefTemplate; +USECLASS(ExplicitInstantiationDeclImportedDefTemplate); USEMEMFUNC(ExplicitInstantiationDeclImportedDefTemplate, f); // M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?f@?$ExplicitInstantiationDeclImportedDefTemplate@H@@QAEXXZ" +// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc %struct.ExplicitInstantiationDeclImportedDefTemplate* @"\01??0?$ExplicitInstantiationDeclImportedDefTemplate@H@@QAE@XZ" -template struct __declspec(dllimport) ExplicitInstantiationDeclExportedDefImportedTemplate { void f() {} }; +template struct __declspec(dllimport) ExplicitInstantiationDeclExportedDefImportedTemplate { void f() {} ExplicitInstantiationDeclExportedDefImportedTemplate() {} }; extern template struct __declspec(dllimport) ExplicitInstantiationDeclExportedDefImportedTemplate ; template struct __declspec(dllexport) ExplicitInstantiationDeclExportedDefImportedTemplate; +USECLASS(ExplicitInstantiationDeclExportedDefImportedTemplate); USEMEMFUNC(ExplicitInstantiationDeclExportedDefImportedTemplate, f); // M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?f@?$ExplicitInstantiationDeclExportedDefImportedTemplate@H@@QAEXXZ" +// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc %struct.ExplicitInstantiationDeclExportedDefImportedTemplate* @"\01??0?$ExplicitInstantiationDeclExportedDefImportedTemplate@H@@QAE@XZ" //===----------------------------------------------------------------------===//