aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Serialization/ASTWriterDecl.cpp
diff options
context:
space:
mode:
authorChuanqi Xu <yedeng.yd@linux.alibaba.com>2025-06-12 14:40:38 +0800
committerChuanqi Xu <yedeng.yd@linux.alibaba.com>2025-06-12 14:42:04 +0800
commit3f0cf742ac4eb3437450f8f263081ea951248851 (patch)
treecb6c1116ee190040191565d0b6af36dfb38a2488 /clang/lib/Serialization/ASTWriterDecl.cpp
parent9d491bc602c2d9730cb42fe25f0753471a3af389 (diff)
downloadllvm-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.cpp45
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);