diff options
Diffstat (limited to 'clang/lib/CodeGen/CodeGenModule.cpp')
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 078edebb965..fd884db6ca2 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -513,6 +513,12 @@ void CodeGenModule::EmitCtorList(const CtorList &Fns, const char *GlobalName) { llvm::GlobalValue::LinkageTypes CodeGenModule::getFunctionLinkage(GlobalDecl GD) { const FunctionDecl *D = cast<FunctionDecl>(GD.getDecl()); + + if (isa<CXXDestructorDecl>(D) && + getCXXABI().useThunkForDtorVariant(cast<CXXDestructorDecl>(D), + GD.getDtorType())) + return llvm::Function::LinkOnceODRLinkage; + GVALinkage Linkage = getContext().GetGVALinkageForFunction(D); if (Linkage == GVA_Internal) @@ -1348,6 +1354,14 @@ CodeGenModule::GetOrCreateLLVMFunction(StringRef MangledName, return llvm::ConstantExpr::getBitCast(Entry, Ty->getPointerTo()); } + // All MSVC dtors other than the base dtor are linkonce_odr and delegate to + // each other bottoming out with the base dtor. Therefore we emit non-base + // dtors on usage, even if there is no dtor definition in the TU. + if (D && isa<CXXDestructorDecl>(D) && + getCXXABI().useThunkForDtorVariant(cast<CXXDestructorDecl>(D), + GD.getDtorType())) + DeferredDeclsToEmit.push_back(GD); + // This function doesn't have a complete type (for example, the return // type is an incomplete struct). Use a fake type instead, and make // sure not to try to set attributes. @@ -2869,7 +2883,7 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { case Decl::CXXDestructor: if (cast<FunctionDecl>(D)->isLateTemplateParsed()) return; - EmitCXXDestructors(cast<CXXDestructorDecl>(D)); + getCXXABI().EmitCXXDestructors(cast<CXXDestructorDecl>(D)); break; case Decl::StaticAssert: |