[clang] d351344 - [C++20] [Modules] Make the linkage consistent for class template and its

Chuanqi Xu via cfe-commits cfe-commits at lists.llvm.org
Mon Jul 25 02:57:52 PDT 2022


Author: Chuanqi Xu
Date: 2022-07-25T17:57:02+08:00
New Revision: d35134485a6cd1b0e25b5dccd330678b9e57919d

URL: https://github.com/llvm/llvm-project/commit/d35134485a6cd1b0e25b5dccd330678b9e57919d
DIFF: https://github.com/llvm/llvm-project/commit/d35134485a6cd1b0e25b5dccd330678b9e57919d.diff

LOG: [C++20] [Modules] Make the linkage consistent for class template and its
specialization

Previously in D120397, we've handled the linkage for function template
and its specialization. But we forgot to handle it for class templates
and their specialization. So we make it in the patch with the similar
approach.

Added: 
    

Modified: 
    clang/lib/AST/Decl.cpp
    clang/unittests/AST/DeclTest.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index f88a2e3fa2681..aaba4345587b2 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -394,7 +394,6 @@ void LinkageComputer::mergeTemplateLV(
     shouldConsiderTemplateVisibility(fn, specInfo);
 
   FunctionTemplateDecl *temp = specInfo->getTemplate();
-
   // Merge information from the template declaration.
   LinkageInfo tempLV = getLVForDecl(temp, computation);
   // The linkage of the specialization should be consistent with the
@@ -468,11 +467,16 @@ void LinkageComputer::mergeTemplateLV(
 
   // Merge information from the template parameters, but ignore
   // visibility if we're only considering template arguments.
-
   ClassTemplateDecl *temp = spec->getSpecializedTemplate();
-  LinkageInfo tempLV =
+  // Merge information from the template declaration.
+  LinkageInfo tempLV = getLVForDecl(temp, computation);
+  // The linkage of the specialization should be consistent with the
+  // template declaration.
+  LV.setLinkage(tempLV.getLinkage());
+
+  LinkageInfo paramsLV =
     getLVForTemplateParameterList(temp->getTemplateParameters(), computation);
-  LV.mergeMaybeWithVisibility(tempLV,
+  LV.mergeMaybeWithVisibility(paramsLV,
            considerVisibility && !hasExplicitVisibilityAlready(computation));
 
   // Merge information from the template arguments.  We ignore
@@ -520,7 +524,6 @@ void LinkageComputer::mergeTemplateLV(LinkageInfo &LV,
 
   // Merge information from the template parameters, but ignore
   // visibility if we're only considering template arguments.
-
   VarTemplateDecl *temp = spec->getSpecializedTemplate();
   LinkageInfo tempLV =
     getLVForTemplateParameterList(temp->getTemplateParameters(), computation);
@@ -1077,7 +1080,6 @@ LinkageComputer::getLVForClassMember(const NamedDecl *D,
 
   // Finally, merge in information from the class.
   LV.mergeMaybeWithVisibility(classLV, considerClassVisibility);
-
   return LV;
 }
 

diff  --git a/clang/unittests/AST/DeclTest.cpp b/clang/unittests/AST/DeclTest.cpp
index 560c6b3ddf434..71835a0508fda 100644
--- a/clang/unittests/AST/DeclTest.cpp
+++ b/clang/unittests/AST/DeclTest.cpp
@@ -179,7 +179,14 @@ TEST(Decl, InConsistLinkageForTemplates) {
     void f() {}
 
     template <>
-    void f<int>() {})");
+    void f<int>() {}
+
+    export template <class T>
+    class C {};
+
+    template<>
+    class C<int> {};
+    )");
 
   auto AST =
       tooling::buildASTFromCodeWithArgs(Code.code(), /*Args=*/{"-std=c++20"});
@@ -193,6 +200,18 @@ TEST(Decl, InConsistLinkageForTemplates) {
   const FunctionDecl *SpecializedF = Funcs[1].getNodeAs<FunctionDecl>("f");
   EXPECT_EQ(TemplateF->getLinkageInternal(),
             SpecializedF->getLinkageInternal());
+
+  llvm::SmallVector<ast_matchers::BoundNodes, 1> ClassTemplates =
+      match(classTemplateDecl().bind("C"), Ctx);
+  llvm::SmallVector<ast_matchers::BoundNodes, 1> ClassSpecializations =
+      match(classTemplateSpecializationDecl().bind("C"), Ctx);
+
+  EXPECT_EQ(ClassTemplates.size(), 1U);
+  EXPECT_EQ(ClassSpecializations.size(), 1U);
+  const NamedDecl *TemplatedC = ClassTemplates[0].getNodeAs<NamedDecl>("C");
+  const NamedDecl *SpecializedC = ClassSpecializations[0].getNodeAs<NamedDecl>("C");
+  EXPECT_EQ(TemplatedC->getLinkageInternal(),
+            SpecializedC->getLinkageInternal());
 }
 
 TEST(Decl, ModuleAndInternalLinkage) {


        


More information about the cfe-commits mailing list