diff options
author | Chuanqi Xu <yedeng.yd@linux.alibaba.com> | 2024-07-02 11:29:17 +0800 |
---|---|---|
committer | Chuanqi Xu <yedeng.yd@linux.alibaba.com> | 2024-07-02 11:43:26 +0800 |
commit | 18f3bcbb13ca83d33223b00761d8cddf463e9ffb (patch) | |
tree | 10281b75a5ee808e16cf621073de62053560a6ad /clang/lib | |
parent | c72cb2766cec0ac519a051780ae5aed42485e012 (diff) | |
download | llvm-18f3bcbb13ca83d33223b00761d8cddf463e9ffb.zip llvm-18f3bcbb13ca83d33223b00761d8cddf463e9ffb.tar.gz llvm-18f3bcbb13ca83d33223b00761d8cddf463e9ffb.tar.bz2 |
[C++20] [Modules] Correct the linkage for template instantiations in
named modules
Close https://github.com/llvm/llvm-project/issues/97313
In the previous patch (https://github.com/llvm/llvm-project/pull/75912),
I made an oversight that I ignored the templates in named module when
calculating the linkage for the vtables. In this patch, I tried to
correct the behavior by merging the logics to calculate the linkage with
key functions with named modules.
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/CodeGen/CGVTables.cpp | 43 |
1 files changed, 24 insertions, 19 deletions
diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp index 3e88cd7..10d972e 100644 --- a/clang/lib/CodeGen/CGVTables.cpp +++ b/clang/lib/CodeGen/CGVTables.cpp @@ -1079,33 +1079,38 @@ CodeGenModule::getVTableLinkage(const CXXRecordDecl *RD) { if (!RD->isExternallyVisible()) return llvm::GlobalVariable::InternalLinkage; - // V-tables for non-template classes with an owning module are always - // uniquely emitted in that module. - if (RD->isInNamedModule()) - return llvm::GlobalVariable::ExternalLinkage; - - // We're at the end of the translation unit, so the current key - // function is fully correct. - const CXXMethodDecl *keyFunction = Context.getCurrentKeyFunction(RD); - if (keyFunction && !RD->hasAttr<DLLImportAttr>()) { + bool IsInNamedModule = RD->isInNamedModule(); + // If the CXXRecordDecl are not in a module unit, we need to get + // its key function. We're at the end of the translation unit, so the current + // key function is fully correct. + const CXXMethodDecl *keyFunction = + IsInNamedModule ? nullptr : Context.getCurrentKeyFunction(RD); + if (IsInNamedModule || (keyFunction && !RD->hasAttr<DLLImportAttr>())) { // If this class has a key function, use that to determine the // linkage of the vtable. const FunctionDecl *def = nullptr; - if (keyFunction->hasBody(def)) + if (keyFunction && keyFunction->hasBody(def)) keyFunction = cast<CXXMethodDecl>(def); - switch (keyFunction->getTemplateSpecializationKind()) { - case TSK_Undeclared: - case TSK_ExplicitSpecialization: + bool IsExternalDefinition = + IsInNamedModule ? RD->shouldEmitInExternalSource() : !def; + + TemplateSpecializationKind Kind = + IsInNamedModule ? RD->getTemplateSpecializationKind() + : keyFunction->getTemplateSpecializationKind(); + + switch (Kind) { + case TSK_Undeclared: + case TSK_ExplicitSpecialization: assert( - (def || CodeGenOpts.OptimizationLevel > 0 || + (IsInNamedModule || def || CodeGenOpts.OptimizationLevel > 0 || CodeGenOpts.getDebugInfo() != llvm::codegenoptions::NoDebugInfo) && - "Shouldn't query vtable linkage without key function, " - "optimizations, or debug info"); - if (!def && CodeGenOpts.OptimizationLevel > 0) + "Shouldn't query vtable linkage without the class in module units, " + "key function, optimizations, or debug info"); + if (IsExternalDefinition && CodeGenOpts.OptimizationLevel > 0) return llvm::GlobalVariable::AvailableExternallyLinkage; - if (keyFunction->isInlined()) + if (keyFunction && keyFunction->isInlined()) return !Context.getLangOpts().AppleKext ? llvm::GlobalVariable::LinkOnceODRLinkage : llvm::Function::InternalLinkage; @@ -1124,7 +1129,7 @@ CodeGenModule::getVTableLinkage(const CXXRecordDecl *RD) { case TSK_ExplicitInstantiationDeclaration: llvm_unreachable("Should not have been asked to emit this"); - } + } } // -fapple-kext mode does not support weak linkage, so we must use |