diff options
author | Chuanqi Xu <yedeng.yd@linux.alibaba.com> | 2025-06-12 14:40:38 +0800 |
---|---|---|
committer | Chuanqi Xu <yedeng.yd@linux.alibaba.com> | 2025-06-12 14:42:04 +0800 |
commit | 3f0cf742ac4eb3437450f8f263081ea951248851 (patch) | |
tree | cb6c1116ee190040191565d0b6af36dfb38a2488 /clang/lib/Serialization/ASTWriterDecl.cpp | |
parent | 9d491bc602c2d9730cb42fe25f0753471a3af389 (diff) | |
download | llvm-3f0cf742ac4eb3437450f8f263081ea951248851.zip llvm-3f0cf742ac4eb3437450f8f263081ea951248851.tar.gz llvm-3f0cf742ac4eb3437450f8f263081ea951248851.tar.bz2 |
[C++20] [Modules] [Reduced BMI] Don't write specializations with local args
Close https://github.com/llvm/llvm-project/issues/119947
As discussed in the above thread, we shouldn't write specializations
with local args in reduced BMI. Since users can't find such
specializations any way.
Diffstat (limited to 'clang/lib/Serialization/ASTWriterDecl.cpp')
-rw-r--r-- | clang/lib/Serialization/ASTWriterDecl.cpp | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index 8f82324..052cb5a 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -221,6 +221,48 @@ namespace clang { Record.AddDeclRef(F.second); } + template <typename T> bool shouldSkipWritingSpecializations(T *Spec) { + // Now we will only avoid writing specializations if we're generating + // reduced BMI. + if (!GeneratingReducedBMI) + return false; + + assert((isa<FunctionDecl, ClassTemplateSpecializationDecl, + VarTemplateSpecializationDecl>(Spec))); + + ArrayRef<TemplateArgument> Args; + if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(Spec)) + Args = CTSD->getTemplateArgs().asArray(); + else if (auto *VTSD = dyn_cast<VarTemplateSpecializationDecl>(Spec)) + Args = VTSD->getTemplateArgs().asArray(); + else + Args = cast<FunctionDecl>(Spec) + ->getTemplateSpecializationArgs() + ->asArray(); + + // If there is any template argument is TULocal, we can avoid writing the + // specialization since the consumers of reduced BMI won't get the + // specialization anyway. + for (const TemplateArgument &TA : Args) { + switch (TA.getKind()) { + case TemplateArgument::Type: { + Linkage L = TA.getAsType()->getLinkage(); + if (!isExternallyVisible(L)) + return true; + break; + } + case TemplateArgument::Declaration: + if (!TA.getAsDecl()->isExternallyVisible()) + return true; + break; + default: + break; + } + } + + return false; + } + /// Add to the record the first template specialization from each module /// file that provides a declaration of D. We store the DeclId and an /// ODRHash of the template arguments of D which should provide enough @@ -235,6 +277,9 @@ namespace clang { CollectFirstDeclFromEachModule(D, /*IncludeLocal*/ true, Firsts); for (const auto &F : Firsts) { + if (shouldSkipWritingSpecializations(F.second)) + continue; + if (isa<ClassTemplatePartialSpecializationDecl, VarTemplatePartialSpecializationDecl>(F.second)) PartialSpecsInMap.push_back(F.second); |