Index: lib/AST/ASTImporter.cpp =================================================================== --- lib/AST/ASTImporter.cpp +++ lib/AST/ASTImporter.cpp @@ -2305,9 +2305,16 @@ if (!FoundDecl->isInIdentifierNamespace(IDNS)) continue; if (auto *FoundTypedef = dyn_cast(FoundDecl)) { - if (Importer.IsStructurallyEquivalent( - D->getUnderlyingType(), FoundTypedef->getUnderlyingType())) + QualType FromUT = D->getUnderlyingType(); + QualType FoundUT = FoundTypedef->getUnderlyingType(); + if (Importer.IsStructurallyEquivalent(FromUT, FoundUT)) { + // If the "From" context has a complete underlying type but we + // already have a complete underlying type then return with that. + if (!FromUT->isIncompleteType() && !FoundUT->isIncompleteType()) return Importer.MapImported(D, FoundTypedef); + } + // FIXME Handle redecl chain. + break; } ConflictingDecls.push_back(FoundDecl); Index: unittests/AST/ASTImporterTest.cpp =================================================================== --- unittests/AST/ASTImporterTest.cpp +++ unittests/AST/ASTImporterTest.cpp @@ -3726,6 +3726,38 @@ EXPECT_EQ(To1->getPreviousDecl(), To0); } +TEST_P(ASTImporterTestBase, ImportingTypedefShouldImportTheCompleteType) { + // We already have an incomplete underlying type in the "To" context. + auto Code = + R"( + template + struct S { + void foo(); + }; + using U = S; + )"; + Decl *ToTU = getToTuDecl(Code, Lang_CXX11); + auto *ToD = FirstDeclMatcher().match(ToTU, + typedefNameDecl(hasName("U"))); + ASSERT_TRUE(ToD->getUnderlyingType()->isIncompleteType()); + + // The "From" context has the same typedef, but the underlying type is + // complete this time. + Decl *FromTU = getTuDecl(std::string(Code) + + R"( + void foo(U* u) { + u->foo(); + } + )", Lang_CXX11); + auto *FromD = FirstDeclMatcher().match(FromTU, + typedefNameDecl(hasName("U"))); + ASSERT_FALSE(FromD->getUnderlyingType()->isIncompleteType()); + + // The imported type should be complete. + auto *ImportedD = cast(Import(FromD, Lang_CXX11)); + EXPECT_FALSE(ImportedD->getUnderlyingType()->isIncompleteType()); +} + INSTANTIATE_TEST_CASE_P(ParameterizedTests, DeclContextTest, ::testing::Values(ArgVector()), );