diff options
Diffstat (limited to 'clang/lib/CIR/CodeGen/CIRGenVTables.cpp')
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenVTables.cpp | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/clang/lib/CIR/CodeGen/CIRGenVTables.cpp b/clang/lib/CIR/CodeGen/CIRGenVTables.cpp index 94d856b..84f5977 100644 --- a/clang/lib/CIR/CodeGen/CIRGenVTables.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenVTables.cpp @@ -327,9 +327,40 @@ cir::GlobalLinkageKind CIRGenModule::getVTableLinkage(const CXXRecordDecl *rd) { llvm_unreachable("Should not have been asked to emit this"); } } + // -fapple-kext mode does not support weak linkage, so we must use + // internal linkage. + if (astContext.getLangOpts().AppleKext) + return cir::GlobalLinkageKind::InternalLinkage; + + auto discardableODRLinkage = cir::GlobalLinkageKind::LinkOnceODRLinkage; + auto nonDiscardableODRLinkage = cir::GlobalLinkageKind::WeakODRLinkage; + if (rd->hasAttr<DLLExportAttr>()) { + // Cannot discard exported vtables. + discardableODRLinkage = nonDiscardableODRLinkage; + } else if (rd->hasAttr<DLLImportAttr>()) { + // Imported vtables are available externally. + discardableODRLinkage = cir::GlobalLinkageKind::AvailableExternallyLinkage; + nonDiscardableODRLinkage = + cir::GlobalLinkageKind::AvailableExternallyLinkage; + } + + switch (rd->getTemplateSpecializationKind()) { + case TSK_Undeclared: + case TSK_ExplicitSpecialization: + case TSK_ImplicitInstantiation: + return discardableODRLinkage; + + case TSK_ExplicitInstantiationDeclaration: { + errorNYI(rd->getSourceRange(), + "getVTableLinkage: explicit instantiation declaration"); + return cir::GlobalLinkageKind::ExternalLinkage; + } + + case TSK_ExplicitInstantiationDefinition: + return nonDiscardableODRLinkage; + } - errorNYI(rd->getSourceRange(), "getVTableLinkage: no key function"); - return cir::GlobalLinkageKind::ExternalLinkage; + llvm_unreachable("Invalid TemplateSpecializationKind!"); } cir::GlobalOp CIRGenVTables::getAddrOfVTT(const CXXRecordDecl *rd) { |