diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -5075,6 +5075,8 @@ Decl *Found = FoundDecl; auto *FoundTemplate = dyn_cast(Found); if (FoundTemplate) { + if (!hasSameVisibilityContext(FoundTemplate, D)) + continue; if (IsStructuralMatch(D, FoundTemplate)) { ClassTemplateDecl *TemplateWithDef = diff --git a/clang/unittests/AST/ASTImporterVisibilityTest.cpp b/clang/unittests/AST/ASTImporterVisibilityTest.cpp --- a/clang/unittests/AST/ASTImporterVisibilityTest.cpp +++ b/clang/unittests/AST/ASTImporterVisibilityTest.cpp @@ -49,6 +49,10 @@ return functionTemplateDecl(hasName("f")); } }; +struct GetClassTemplPattern { + using DeclTy = ClassTemplateDecl; + BindableMatcher operator()() { return classTemplateDecl(hasName("X")); } +}; // Values for the value-parameterized test fixtures. // FunctionDecl: @@ -74,6 +78,9 @@ const auto *ExternFT = "template void f();"; const auto *StaticFT = "template static void f();"; const auto *AnonFT = "namespace { template void f(); }"; +// ClassTemplateDecl: +const auto *ExternCT = "template class X;"; +const auto *AnonCT = "namespace { template class X; }"; // First value in tuple: Compile options. // Second value in tuple: Source code to be used in the test. @@ -120,6 +127,8 @@ using ImportClassesVisibilityChain = ImportVisibilityChain; using ImportFunctionTemplatesVisibilityChain = ImportVisibilityChain; +using ImportClassTemplatesVisibilityChain = + ImportVisibilityChain; // Value-parameterized test for functions. TEST_P(ImportFunctionsVisibilityChain, ImportChain) { @@ -137,6 +146,10 @@ TEST_P(ImportFunctionTemplatesVisibilityChain, ImportChain) { TypedTest_ImportChain(); } +// Value-parameterized test for class templates. +TEST_P(ImportClassTemplatesVisibilityChain, ImportChain) { + TypedTest_ImportChain(); +} // Automatic instantiation of the value-parameterized tests. INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportFunctionsVisibilityChain, @@ -165,6 +178,10 @@ ::testing::Combine(DefaultTestValuesForRunOptions, ::testing::Values(ExternFT, StaticFT, AnonFT)), ); +INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportClassTemplatesVisibilityChain, + ::testing::Combine(DefaultTestValuesForRunOptions, + ::testing::Values(ExternCT, + AnonCT)), ); // First value in tuple: Compile options. // Second value in tuple: Tuple with informations for the test. @@ -276,6 +293,7 @@ using ImportEnumsVisibility = ImportVisibility; using ImportTypedefNameVisibility = ImportVisibility; using ImportFunctionTemplatesVisibility = ImportVisibility; +using ImportClassTemplatesVisibility = ImportVisibility; // FunctionDecl. TEST_P(ImportFunctionsVisibility, ImportAfter) { @@ -319,6 +337,11 @@ TEST_P(ImportFunctionTemplatesVisibility, ImportAfterImport) { TypedTest_ImportAfterImport(); } +// ClassTemplateDecl. +TEST_P(ImportClassTemplatesVisibility, ImportAfter) { TypedTest_ImportAfter(); } +TEST_P(ImportClassTemplatesVisibility, ImportAfterImport) { + TypedTest_ImportAfterImport(); +} const bool ExpectLinkedDeclChain = true; const bool ExpectUnlinkedDeclChain = false; @@ -411,6 +434,13 @@ std::make_tuple(AnonFT, ExternFT, ExpectUnlinkedDeclChain), std::make_tuple(AnonFT, StaticFT, ExpectUnlinkedDeclChain), std::make_tuple(AnonFT, AnonFT, ExpectUnlinkedDeclChain))), ); - +INSTANTIATE_TEST_CASE_P( + ParameterizedTests, ImportClassTemplatesVisibility, + ::testing::Combine( + DefaultTestValuesForRunOptions, + ::testing::Values(std::make_tuple(ExternCT, ExternCT, ExpectLinkedDeclChain), + std::make_tuple(ExternCT, AnonCT, ExpectUnlinkedDeclChain), + std::make_tuple(AnonCT, ExternCT, ExpectUnlinkedDeclChain), + std::make_tuple(AnonCT, AnonCT, ExpectUnlinkedDeclChain))), ); } // end namespace ast_matchers } // end namespace clang