Index: lib/AST/ASTImporter.cpp =================================================================== --- lib/AST/ASTImporter.cpp +++ lib/AST/ASTImporter.cpp @@ -927,6 +927,28 @@ EllipsisLoc); } +template +bool ASTNodeImporter::hasSameVisibilityContext(T *Found, T *From) { + if (From->hasExternalFormalLinkage()) + return Found->hasExternalFormalLinkage(); + else if (Importer.GetFromTU(Found) == From->getTranslationUnitDecl()) { + if (From->isInAnonymousNamespace()) + return Found->isInAnonymousNamespace(); + else + return !Found->isInAnonymousNamespace() && + !Found->hasExternalFormalLinkage(); + } + return false; +} + +template <> +bool ASTNodeImporter::hasSameVisibilityContext(TypedefNameDecl *Found, + TypedefNameDecl *From) { + if (From->isInAnonymousNamespace() && Found->isInAnonymousNamespace()) + return Importer.GetFromTU(Found) == From->getTranslationUnitDecl(); + return From->isInAnonymousNamespace() == Found->isInAnonymousNamespace(); +} + } // namespace clang //---------------------------------------------------------------------------- @@ -2278,6 +2300,9 @@ if (!FoundDecl->isInIdentifierNamespace(IDNS)) continue; if (auto *FoundTypedef = dyn_cast(FoundDecl)) { + if (!hasSameVisibilityContext(FoundTypedef, D)) + continue; + QualType FromUT = D->getUnderlyingType(); QualType FoundUT = FoundTypedef->getUnderlyingType(); if (Importer.IsStructurallyEquivalent(FromUT, FoundUT)) { @@ -2945,19 +2970,6 @@ return Error::success(); } -template -bool ASTNodeImporter::hasSameVisibilityContext(T *Found, T *From) { - if (From->hasExternalFormalLinkage()) - return Found->hasExternalFormalLinkage(); - if (Importer.GetFromTU(Found) != From->getTranslationUnitDecl()) - return false; - if (From->isInAnonymousNamespace()) - return Found->isInAnonymousNamespace(); - else - return !Found->isInAnonymousNamespace() && - !Found->hasExternalFormalLinkage(); -} - ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) { SmallVector Redecls = getCanonicalForwardRedeclChain(D); Index: unittests/AST/ASTImporterVisibilityTest.cpp =================================================================== --- unittests/AST/ASTImporterVisibilityTest.cpp +++ unittests/AST/ASTImporterVisibilityTest.cpp @@ -39,6 +39,14 @@ using DeclTy = EnumDecl; BindableMatcher operator()() { return enumDecl(hasName("E")); } }; +struct GetTypedefPattern { + using DeclTy = TypedefDecl; + BindableMatcher operator()() { return typedefDecl(hasName("T")); } +}; +struct GetTypeAliasPattern { + using DeclTy = TypeAliasDecl; + BindableMatcher operator()() { return typeAliasDecl(hasName("T")); } +}; // Values for the value-parameterized test fixtures. // FunctionDecl: @@ -55,6 +63,11 @@ // EnumDecl: const auto *ExternE = "enum E {};"; const auto *AnonE = "namespace { enum E {}; }"; +// TypedefNameDecl: +auto *ExternTypedef = "typedef int T;"; +auto *AnonTypedef = "namespace { typedef int T; }"; +auto *ExternUsing = "using T = int;"; +auto *AnonUsing = "namespace { using T = int; }"; // First value in tuple: Compile options. // Second value in tuple: Source code to be used in the test. @@ -237,6 +250,8 @@ using ImportVariablesVisibility = ImportVisibility; using ImportClassesVisibility = ImportVisibility; using ImportEnumsVisibility = ImportVisibility; +using ImportTypedefVisibility = ImportVisibility; +using ImportTypeAliasVisibility = ImportVisibility; // FunctionDecl. TEST_P(ImportFunctionsVisibility, ImportAfter) { @@ -266,6 +281,19 @@ TEST_P(ImportEnumsVisibility, ImportAfterImport) { TypedTest_ImportAfterImportWithMerge(); } +// TypedefNameDecl. +TEST_P(ImportTypedefVisibility, ImportAfter) { + TypedTest_ImportAfterWithMerge(); +} +TEST_P(ImportTypedefVisibility, ImportAfterImport) { + TypedTest_ImportAfterImportWithMerge(); +} +TEST_P(ImportTypeAliasVisibility, ImportAfter) { + TypedTest_ImportAfterWithMerge(); +} +TEST_P(ImportTypeAliasVisibility, ImportAfterImport) { + TypedTest_ImportAfterImportWithMerge(); +} const bool ExpectLink = true; const bool ExpectNotLink = false; @@ -312,6 +340,24 @@ std::make_tuple(ExternE, AnonE, ExpectNotLink), std::make_tuple(AnonE, ExternE, ExpectNotLink), std::make_tuple(AnonE, AnonE, ExpectNotLink))), ); +INSTANTIATE_TEST_CASE_P( + ParameterizedTests, ImportTypedefVisibility, + ::testing::Combine( + DefaultTestValuesForRunOptions, + ::testing::Values( + std::make_tuple(ExternTypedef, ExternTypedef, ExpectLink), + std::make_tuple(ExternTypedef, AnonTypedef, ExpectNotLink), + std::make_tuple(AnonTypedef, ExternTypedef, ExpectNotLink), + std::make_tuple(AnonTypedef, AnonTypedef, ExpectNotLink))), ); +INSTANTIATE_TEST_CASE_P( + ParameterizedTests, ImportTypeAliasVisibility, + ::testing::Combine( + DefaultTestValuesForRunOptions, + ::testing::Values( + std::make_tuple(ExternUsing, ExternUsing, ExpectLink), + std::make_tuple(ExternUsing, AnonUsing, ExpectNotLink), + std::make_tuple(AnonUsing, ExternUsing, ExpectNotLink), + std::make_tuple(AnonUsing, AnonUsing, ExpectNotLink))), ); } // end namespace ast_matchers } // end namespace clang