Index: lib/AST/ASTImporter.cpp =================================================================== --- lib/AST/ASTImporter.cpp +++ lib/AST/ASTImporter.cpp @@ -2559,6 +2559,9 @@ if (!IsStructuralMatch(D, FoundRecord, false)) continue; + if (!hasSameVisibilityContext(FoundRecord, D)) + continue; + if (IsStructuralMatch(D, FoundRecord)) { RecordDecl *FoundDef = FoundRecord->getDefinition(); if (D->isThisDeclarationADefinition() && FoundDef) { Index: unittests/AST/ASTImporterVisibilityTest.cpp =================================================================== --- unittests/AST/ASTImporterVisibilityTest.cpp +++ unittests/AST/ASTImporterVisibilityTest.cpp @@ -31,6 +31,10 @@ using DeclTy = VarDecl; BindableMatcher operator()() { return varDecl(hasName("v")); } }; +struct GetClassPattern { + using DeclTy = CXXRecordDecl; + BindableMatcher operator()() { return cxxRecordDecl(hasName("X")); } +}; // Values for the value-parameterized test fixtures. // FunctionDecl: @@ -41,6 +45,9 @@ const auto *ExternV = "extern int v;"; const auto *StaticV = "static int v;"; const auto *AnonV = "namespace { extern int v; }"; +// CXXRecordDecl: +auto *ExternC = "class X;"; +auto *AnonC = "namespace { class X; }"; // First value in tuple: Compile options. // Second value in tuple: Source code to be used in the test. @@ -84,14 +91,19 @@ // Manual instantiation of the fixture with each type. using ImportFunctionsVisibilityChain = ImportVisibilityChain; using ImportVariablesVisibilityChain = ImportVisibilityChain; -// Value-parameterized test for the first type. +using ImportClassesVisibilityChain = ImportVisibilityChain; +// Value-parameterized test for functions. TEST_P(ImportFunctionsVisibilityChain, ImportChain) { TypedTest_ImportChain(); } -// Value-parameterized test for the second type. +// Value-parameterized test for variables. TEST_P(ImportVariablesVisibilityChain, ImportChain) { TypedTest_ImportChain(); } +// Value-parameterized test for classes. +TEST_P(ImportClassesVisibilityChain, ImportChain) { + TypedTest_ImportChain(); +} // Automatic instantiation of the value-parameterized tests. INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportFunctionsVisibilityChain, @@ -110,6 +122,11 @@ // provided but they must have the same linkage. See also the test // ImportVariableChainInC which test for this special C Lang case. ::testing::Values(ExternV, AnonV)), ); +INSTANTIATE_TEST_CASE_P( + ParameterizedTests, ImportClassesVisibilityChain, + ::testing::Combine( + DefaultTestValuesForRunOptions, + ::testing::Values(ExternC, AnonC)), ); // First value in tuple: Compile options. // Second value in tuple: Tuple with informations for the test. @@ -169,6 +186,7 @@ }; using ImportFunctionsVisibility = ImportVisibility; using ImportVariablesVisibility = ImportVisibility; +using ImportClassesVisibility = ImportVisibility; // FunctionDecl. TEST_P(ImportFunctionsVisibility, ImportAfter) { @@ -184,6 +202,13 @@ TEST_P(ImportVariablesVisibility, ImportAfterImport) { TypedTest_ImportAfterImport(); } +// CXXRecordDecl. +TEST_P(ImportClassesVisibility, ImportAfter) { + TypedTest_ImportAfter(); +} +TEST_P(ImportClassesVisibility, ImportAfterImport) { + TypedTest_ImportAfterImport(); +} const bool ExpectLink = true; const bool ExpectNotLink = false; @@ -214,6 +239,14 @@ std::make_tuple(AnonV, ExternV, ExpectNotLink), std::make_tuple(AnonV, StaticV, ExpectNotLink), std::make_tuple(AnonV, AnonV, ExpectNotLink))), ); +INSTANTIATE_TEST_CASE_P( + ParameterizedTests, ImportClassesVisibility, + ::testing::Combine( + DefaultTestValuesForRunOptions, + ::testing::Values(std::make_tuple(ExternC, ExternC, ExpectLink), + std::make_tuple(ExternC, AnonC, ExpectNotLink), + std::make_tuple(AnonC, ExternC, ExpectNotLink), + std::make_tuple(AnonC, AnonC, ExpectNotLink))), ); } // end namespace ast_matchers } // end namespace clang