From 275efb9e5020d60178251611373d636da6def0ca Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 28 May 2014 01:52:23 +0000 Subject: [PATCH] Don't dllimport/export destructor variants implemented by thunks. MSVC doesn't export these functions, so trying to import them doesnt' work. Also, don't let any dll attributes on the CXXDestructorDecl influence the thunk's linkage -- they should always be linkonce_odr. This takes care of the FIXME's for this in Nico's tests. Differential Revision: http://reviews.llvm.org/D3930 llvm-svn: 209706 --- clang/lib/CodeGen/CodeGenModule.cpp | 31 +++++++++++---------- clang/lib/CodeGen/CodeGenModule.h | 3 +- clang/test/CodeGenCXX/dllimport-members.cpp | 23 +++++++-------- 3 files changed, 28 insertions(+), 29 deletions(-) diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 9e8401da3a84..c55e2310d8c2 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -561,13 +561,16 @@ CodeGenModule::getFunctionLinkage(GlobalDecl GD) { GVALinkage Linkage = getContext().GetGVALinkageForFunction(D); - bool UseThunkForDtorVariant = - isa(D) && + if (isa(D) && getCXXABI().useThunkForDtorVariant(cast(D), - GD.getDtorType()); + GD.getDtorType())) { + // Destructor variants in the Microsoft C++ ABI are always internal or + // linkonce_odr thunks emitted on an as-needed basis. + return Linkage == GVA_Internal ? llvm::GlobalValue::InternalLinkage + : llvm::GlobalValue::LinkOnceODRLinkage; + } - return getLLVMLinkageForDeclarator(D, Linkage, /*isConstantVariable=*/false, - UseThunkForDtorVariant); + return getLLVMLinkageForDeclarator(D, Linkage, /*isConstantVariable=*/false); } void CodeGenModule::setFunctionDefinitionAttributes(const FunctionDecl *D, @@ -780,6 +783,13 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, 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()); @@ -1914,8 +1924,7 @@ static bool isVarDeclStrongDefinition(const VarDecl *D, bool NoCommon) { } llvm::GlobalValue::LinkageTypes CodeGenModule::getLLVMLinkageForDeclarator( - const DeclaratorDecl *D, GVALinkage Linkage, bool IsConstantVariable, - bool UseThunkForDtorVariant) { + const DeclaratorDecl *D, GVALinkage Linkage, bool IsConstantVariable) { if (Linkage == GVA_Internal) return llvm::Function::InternalLinkage; @@ -1954,11 +1963,6 @@ llvm::GlobalValue::LinkageTypes CodeGenModule::getLLVMLinkageForDeclarator( return !Context.getLangOpts().AppleKext ? llvm::Function::WeakODRLinkage : llvm::Function::ExternalLinkage; - // Destructor variants in the Microsoft C++ ABI are always linkonce_odr thunks - // emitted on an as-needed basis. - if (UseThunkForDtorVariant) - return llvm::GlobalValue::LinkOnceODRLinkage; - // If required by the ABI, give definitions of static data members with inline // initializers at least linkonce_odr linkage. if (getCXXABI().isInlineInitializedStaticDataMemberLinkOnce() && @@ -1987,8 +1991,7 @@ llvm::GlobalValue::LinkageTypes CodeGenModule::getLLVMLinkageForDeclarator( llvm::GlobalValue::LinkageTypes CodeGenModule::getLLVMLinkageVarDefinition( const VarDecl *VD, bool IsConstant) { GVALinkage Linkage = getContext().GetGVALinkageForVariable(VD); - return getLLVMLinkageForDeclarator(VD, Linkage, IsConstant, - /*UseThunkForDtorVariant=*/false); + return getLLVMLinkageForDeclarator(VD, Linkage, IsConstant); } /// Replace the uses of a function that was declared with a non-proto type. diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index 9e5835132aee..c54f6dea521f 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -975,8 +975,7 @@ public: /// Returns LLVM linkage for a declarator. llvm::GlobalValue::LinkageTypes getLLVMLinkageForDeclarator(const DeclaratorDecl *D, GVALinkage Linkage, - bool IsConstantVariable, - bool UseThunkForDtorVariant); + bool IsConstantVariable); /// Returns LLVM linkage for a declarator. llvm::GlobalValue::LinkageTypes diff --git a/clang/test/CodeGenCXX/dllimport-members.cpp b/clang/test/CodeGenCXX/dllimport-members.cpp index 63ce9893338c..7fe48a7a8719 100644 --- a/clang/test/CodeGenCXX/dllimport-members.cpp +++ b/clang/test/CodeGenCXX/dllimport-members.cpp @@ -422,9 +422,8 @@ struct ImportSpecials { // G64-DAG: declare dllimport void @_ZN14ImportSpecialsC1Ev(%struct.ImportSpecials*) __declspec(dllimport) ImportSpecials(); - // FIXME: MSVC emits ??1ImportSpecials@@{{QAE|QEAA}}@XZ here. - // M32-DAG: declare dllimport x86_thiscallcc void @"\01??_DImportSpecials@@QAE@XZ"(%struct.ImportSpecials*) - // M64-DAG: declare dllimport void @"\01??_DImportSpecials@@QEAA@XZ"(%struct.ImportSpecials*) + // M32-DAG: declare dllimport x86_thiscallcc void @"\01??1ImportSpecials@@QAE@XZ"(%struct.ImportSpecials*) + // M64-DAG: declare dllimport void @"\01??1ImportSpecials@@QEAA@XZ"(%struct.ImportSpecials*) // G32-DAG: declare dllimport x86_thiscallcc void @_ZN14ImportSpecialsD1Ev(%struct.ImportSpecials*) // G64-DAG: declare dllimport void @_ZN14ImportSpecialsD1Ev(%struct.ImportSpecials*) __declspec(dllimport) ~ImportSpecials() {} @@ -466,12 +465,11 @@ struct ImportInlineSpecials { // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN20ImportInlineSpecialsC1Ev( __declspec(dllimport) ImportInlineSpecials() {} - // FIXME: MSVC emits ??1ImportInlineSpecials@@{{QAE|QEAA}}@XZ here. - // M32-DAG: declare dllimport x86_thiscallcc void @"\01??_DImportInlineSpecials@@QAE@XZ"(%struct.ImportInlineSpecials*) - // M64-DAG: declare dllimport void @"\01??_DImportInlineSpecials@@QEAA@XZ"(%struct.ImportInlineSpecials*) + // M32-DAG: declare dllimport x86_thiscallcc void @"\01??1ImportInlineSpecials@@QAE@XZ"(%struct.ImportInlineSpecials*) + // M64-DAG: declare dllimport void @"\01??1ImportInlineSpecials@@QEAA@XZ"(%struct.ImportInlineSpecials*) // G32-DAG: declare dllimport x86_thiscallcc void @_ZN20ImportInlineSpecialsD1Ev(%struct.ImportInlineSpecials*) // G64-DAG: declare dllimport void @_ZN20ImportInlineSpecialsD1Ev(%struct.ImportInlineSpecials*) - // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01??_DImportInlineSpecials@@QAE@XZ"( + // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01??1ImportInlineSpecials@@QAE@XZ"( // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN20ImportInlineSpecialsD1Ev( __declspec(dllimport) ~ImportInlineSpecials() {} @@ -522,11 +520,11 @@ struct ImportDefaulted { // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN15ImportDefaultedC1Ev(%struct.ImportDefaulted* %this) __declspec(dllimport) ImportDefaulted() = default; - // M32-DAG: declare dllimport x86_thiscallcc void @"\01??_DImportDefaulted@@QAE@XZ"(%struct.ImportDefaulted*) - // M64-DAG: declare dllimport void @"\01??_DImportDefaulted@@QEAA@XZ"(%struct.ImportDefaulted*) + // M32-DAG: declare dllimport x86_thiscallcc void @"\01??1ImportDefaulted@@QAE@XZ"(%struct.ImportDefaulted*) + // M64-DAG: declare dllimport void @"\01??1ImportDefaulted@@QEAA@XZ"(%struct.ImportDefaulted*) // G32-DAG: declare dllimport x86_thiscallcc void @_ZN15ImportDefaultedD1Ev(%struct.ImportDefaulted*) // G64-DAG: declare dllimport void @_ZN15ImportDefaultedD1Ev(%struct.ImportDefaulted*) - // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01??_DImportDefaulted@@QAE@XZ"(%struct.ImportDefaulted* %this) + // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01??1ImportDefaulted@@QAE@XZ"(%struct.ImportDefaulted* %this) // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN15ImportDefaultedD1Ev(%struct.ImportDefaulted* %this) __declspec(dllimport) ~ImportDefaulted() = default; @@ -585,9 +583,8 @@ struct ImportDefaultedDefs { // G64-DAG: declare dllimport void @_ZN19ImportDefaultedDefsC1Ev(%struct.ImportDefaultedDefs*) __declspec(dllimport) ImportDefaultedDefs::ImportDefaultedDefs() = default; -// FIXME: MSVC emits ??1ImportDefaultedDefs@@{{QAE|QEAA}}@XZ here. -// M32-DAG: declare dllimport x86_thiscallcc void @"\01??_DImportDefaultedDefs@@QAE@XZ"(%struct.ImportDefaultedDefs*) -// M64-DAG: declare dllimport void @"\01??_DImportDefaultedDefs@@QEAA@XZ"(%struct.ImportDefaultedDefs*) +// M32-DAG: declare dllimport x86_thiscallcc void @"\01??1ImportDefaultedDefs@@QAE@XZ"(%struct.ImportDefaultedDefs*) +// M64-DAG: declare dllimport void @"\01??1ImportDefaultedDefs@@QEAA@XZ"(%struct.ImportDefaultedDefs*) // G32-DAG: declare dllimport x86_thiscallcc void @_ZN19ImportDefaultedDefsD1Ev(%struct.ImportDefaultedDefs*) // G64-DAG: declare dllimport void @_ZN19ImportDefaultedDefsD1Ev(%struct.ImportDefaultedDefs*) __declspec(dllimport) ImportDefaultedDefs::~ImportDefaultedDefs() = default;