aboutsummaryrefslogtreecommitdiff
path: root/clang/lib
diff options
context:
space:
mode:
authorChuanqi Xu <yedeng.yd@linux.alibaba.com>2024-07-02 11:29:17 +0800
committerChuanqi Xu <yedeng.yd@linux.alibaba.com>2024-07-02 11:43:26 +0800
commit18f3bcbb13ca83d33223b00761d8cddf463e9ffb (patch)
tree10281b75a5ee808e16cf621073de62053560a6ad /clang/lib
parentc72cb2766cec0ac519a051780ae5aed42485e012 (diff)
downloadllvm-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.cpp43
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