diff options
Diffstat (limited to 'clang/lib/CodeGen/CGVTables.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGVTables.cpp | 42 |
1 files changed, 30 insertions, 12 deletions
diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp index 7321dbf..c6d7e06 100644 --- a/clang/lib/CodeGen/CGVTables.cpp +++ b/clang/lib/CodeGen/CGVTables.cpp @@ -679,6 +679,12 @@ CodeGenVTables::GenerateConstructionVTable(const CXXRecordDecl *RD, return VTable; } +static bool shouldEmitAvailableExternallyVTable(const CodeGenModule &CGM, + const CXXRecordDecl *RD) { + return CGM.getCodeGenOpts().OptimizationLevel > 0 && + CGM.getCXXABI().canEmitAvailableExternallyVTable(RD); +} + /// Compute the required linkage of the v-table for the given class. /// /// Note that we only call this at the end of the translation unit. @@ -700,7 +706,12 @@ CodeGenModule::getVTableLinkage(const CXXRecordDecl *RD) { switch (keyFunction->getTemplateSpecializationKind()) { case TSK_Undeclared: case TSK_ExplicitSpecialization: - assert(def && "Should not have been asked to emit this"); + assert((def || CodeGenOpts.OptimizationLevel > 0) && + "Shouldn't query vtable linkage without key function or " + "optimizations"); + if (!def && CodeGenOpts.OptimizationLevel > 0) + return llvm::GlobalVariable::AvailableExternallyLinkage; + if (keyFunction->isInlined()) return !Context.getLangOpts().AppleKext ? llvm::GlobalVariable::LinkOnceODRLinkage : @@ -742,16 +753,18 @@ CodeGenModule::getVTableLinkage(const CXXRecordDecl *RD) { } switch (RD->getTemplateSpecializationKind()) { - case TSK_Undeclared: - case TSK_ExplicitSpecialization: - case TSK_ImplicitInstantiation: - return DiscardableODRLinkage; - - case TSK_ExplicitInstantiationDeclaration: - return llvm::GlobalVariable::ExternalLinkage; - - case TSK_ExplicitInstantiationDefinition: - return NonDiscardableODRLinkage; + case TSK_Undeclared: + case TSK_ExplicitSpecialization: + case TSK_ImplicitInstantiation: + return DiscardableODRLinkage; + + case TSK_ExplicitInstantiationDeclaration: + return shouldEmitAvailableExternallyVTable(*this, RD) + ? llvm::GlobalVariable::AvailableExternallyLinkage + : llvm::GlobalVariable::ExternalLinkage; + + case TSK_ExplicitInstantiationDefinition: + return NonDiscardableODRLinkage; } llvm_unreachable("Invalid TemplateSpecializationKind!"); @@ -819,7 +832,12 @@ bool CodeGenVTables::isVTableExternal(const CXXRecordDecl *RD) { /// we define that v-table? static bool shouldEmitVTableAtEndOfTranslationUnit(CodeGenModule &CGM, const CXXRecordDecl *RD) { - return !CGM.getVTables().isVTableExternal(RD); + // If vtable is internal then it has to be done + if (!CGM.getVTables().isVTableExternal(RD)) + return true; + + // If it's external then maybe we will need it as available_externally + return shouldEmitAvailableExternallyVTable(CGM, RD); } /// Given that at some point we emitted a reference to one or more |