From 63814be4fa23ef9b36cf2d14388c7f6ba591d3b6 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Tue, 19 Apr 2022 14:40:52 -0700 Subject: [PATCH] [modules] Merge variable template specializations. --- clang/lib/Serialization/ASTReaderDecl.cpp | 12 ++++++++---- .../Inputs/merge-template-specializations/a.h | 2 ++ .../Inputs/merge-template-specializations/b.h | 2 ++ .../Inputs/merge-template-specializations/c.h | 3 +++ .../test/Modules/merge-template-specializations.cpp | 4 ++++ 5 files changed, 19 insertions(+), 4 deletions(-) diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 43aacdeda998..9e0c3d558323 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -2382,13 +2382,17 @@ ASTDeclReader::VisitVarTemplateSpecializationDeclImpl( if (writtenAsCanonicalDecl) { auto *CanonPattern = readDeclAs(); if (D->isCanonicalDecl()) { // It's kept in the folding set. - // FIXME: If it's already present, merge it. + VarTemplateSpecializationDecl *CanonSpec; if (auto *Partial = dyn_cast(D)) { - CanonPattern->getCommonPtr()->PartialSpecializations - .GetOrInsertNode(Partial); + CanonSpec = CanonPattern->getCommonPtr() + ->PartialSpecializations.GetOrInsertNode(Partial); } else { - CanonPattern->getCommonPtr()->Specializations.GetOrInsertNode(D); + CanonSpec = + CanonPattern->getCommonPtr()->Specializations.GetOrInsertNode(D); } + // If we already have a matching specialization, merge it. + if (CanonSpec != D) + mergeRedeclarable(D, CanonSpec, Redecl); } } diff --git a/clang/test/Modules/Inputs/merge-template-specializations/a.h b/clang/test/Modules/Inputs/merge-template-specializations/a.h index fb05647c0aa9..00426af2b1d5 100644 --- a/clang/test/Modules/Inputs/merge-template-specializations/a.h +++ b/clang/test/Modules/Inputs/merge-template-specializations/a.h @@ -1 +1,3 @@ template class SmallString {}; + +template int var_template = 0; diff --git a/clang/test/Modules/Inputs/merge-template-specializations/b.h b/clang/test/Modules/Inputs/merge-template-specializations/b.h index 96ce2bb1d8d6..89d0e36d6c96 100644 --- a/clang/test/Modules/Inputs/merge-template-specializations/b.h +++ b/clang/test/Modules/Inputs/merge-template-specializations/b.h @@ -1,2 +1,4 @@ #include "a.h" void f(SmallString<256>&); + +template void use_var_template(decltype(T() + var_template<0>)) {} diff --git a/clang/test/Modules/Inputs/merge-template-specializations/c.h b/clang/test/Modules/Inputs/merge-template-specializations/c.h index 100463a2f7f2..44fe4925d7c2 100644 --- a/clang/test/Modules/Inputs/merge-template-specializations/c.h +++ b/clang/test/Modules/Inputs/merge-template-specializations/c.h @@ -1,3 +1,6 @@ #include "a.h" struct X { SmallString<256> ss; }; + +template void use_var_template(decltype(T() + var_template<0>)); + #include "b.h" diff --git a/clang/test/Modules/merge-template-specializations.cpp b/clang/test/Modules/merge-template-specializations.cpp index 25db93fbbb20..1f8e68a2e925 100644 --- a/clang/test/Modules/merge-template-specializations.cpp +++ b/clang/test/Modules/merge-template-specializations.cpp @@ -3,3 +3,7 @@ // expected-no-diagnostics #include "c.h" X x; + +void test_var_template() { + use_var_template(0); +}