This revision was automatically updated to reflect the committed changes. Closed by commit rC332338: [ASTImporter] Extend lookup logic in class templates (authored by a.sidorin, committed by ).
Changed prior to commit: https://reviews.llvm.org/D46353?vs=146765&id=146780#toc Repository: rC Clang https://reviews.llvm.org/D46353 Files: lib/AST/ASTImporter.cpp unittests/AST/ASTImporterTest.cpp Index: lib/AST/ASTImporter.cpp =================================================================== --- lib/AST/ASTImporter.cpp +++ lib/AST/ASTImporter.cpp @@ -4108,8 +4108,14 @@ if (auto *FoundTemplate = dyn_cast<ClassTemplateDecl>(Found)) { if (IsStructuralMatch(D, FoundTemplate)) { // The class templates structurally match; call it the same template. - // FIXME: We may be filling in a forward declaration here. Handle - // this case! + + // We found a forward declaration but the class to be imported has a + // definition. + // FIXME Add this forward declaration to the redeclaration chain. + if (D->isThisDeclarationADefinition() && + !FoundTemplate->isThisDeclarationADefinition()) + continue; + Importer.Imported(D->getTemplatedDecl(), FoundTemplate->getTemplatedDecl()); return Importer.Imported(D, FoundTemplate); Index: unittests/AST/ASTImporterTest.cpp =================================================================== --- unittests/AST/ASTImporterTest.cpp +++ unittests/AST/ASTImporterTest.cpp @@ -1431,6 +1431,39 @@ MatchVerifier<Decl>{}.match(To->getTranslationUnitDecl(), Pattern)); } +TEST_P(ASTImporterTestBase, ImportDefinitionOfClassTemplateAfterFwdDecl) { + { + Decl *FromTU = getTuDecl( + R"( + template <typename T> + struct B; + )", + Lang_CXX, "input0.cc"); + auto *FromD = FirstDeclMatcher<ClassTemplateDecl>().match( + FromTU, classTemplateDecl(hasName("B"))); + + Import(FromD, Lang_CXX); + } + + { + Decl *FromTU = getTuDecl( + R"( + template <typename T> + struct B { + void f(); + }; + )", + Lang_CXX, "input1.cc"); + FunctionDecl *FromD = FirstDeclMatcher<FunctionDecl>().match( + FromTU, functionDecl(hasName("f"))); + Import(FromD, Lang_CXX); + auto *FromCTD = FirstDeclMatcher<ClassTemplateDecl>().match( + FromTU, classTemplateDecl(hasName("B"))); + auto *ToCTD = cast<ClassTemplateDecl>(Import(FromCTD, Lang_CXX)); + EXPECT_TRUE(ToCTD->isThisDeclarationADefinition()); + } +} + INSTANTIATE_TEST_CASE_P( ParameterizedTests, ASTImporterTestBase, ::testing::Values(ArgVector(), ArgVector{"-fdelayed-template-parsing"}),);
Index: lib/AST/ASTImporter.cpp =================================================================== --- lib/AST/ASTImporter.cpp +++ lib/AST/ASTImporter.cpp @@ -4108,8 +4108,14 @@ if (auto *FoundTemplate = dyn_cast<ClassTemplateDecl>(Found)) { if (IsStructuralMatch(D, FoundTemplate)) { // The class templates structurally match; call it the same template. - // FIXME: We may be filling in a forward declaration here. Handle - // this case! + + // We found a forward declaration but the class to be imported has a + // definition. + // FIXME Add this forward declaration to the redeclaration chain. + if (D->isThisDeclarationADefinition() && + !FoundTemplate->isThisDeclarationADefinition()) + continue; + Importer.Imported(D->getTemplatedDecl(), FoundTemplate->getTemplatedDecl()); return Importer.Imported(D, FoundTemplate); Index: unittests/AST/ASTImporterTest.cpp =================================================================== --- unittests/AST/ASTImporterTest.cpp +++ unittests/AST/ASTImporterTest.cpp @@ -1431,6 +1431,39 @@ MatchVerifier<Decl>{}.match(To->getTranslationUnitDecl(), Pattern)); } +TEST_P(ASTImporterTestBase, ImportDefinitionOfClassTemplateAfterFwdDecl) { + { + Decl *FromTU = getTuDecl( + R"( + template <typename T> + struct B; + )", + Lang_CXX, "input0.cc"); + auto *FromD = FirstDeclMatcher<ClassTemplateDecl>().match( + FromTU, classTemplateDecl(hasName("B"))); + + Import(FromD, Lang_CXX); + } + + { + Decl *FromTU = getTuDecl( + R"( + template <typename T> + struct B { + void f(); + }; + )", + Lang_CXX, "input1.cc"); + FunctionDecl *FromD = FirstDeclMatcher<FunctionDecl>().match( + FromTU, functionDecl(hasName("f"))); + Import(FromD, Lang_CXX); + auto *FromCTD = FirstDeclMatcher<ClassTemplateDecl>().match( + FromTU, classTemplateDecl(hasName("B"))); + auto *ToCTD = cast<ClassTemplateDecl>(Import(FromCTD, Lang_CXX)); + EXPECT_TRUE(ToCTD->isThisDeclarationADefinition()); + } +} + INSTANTIATE_TEST_CASE_P( ParameterizedTests, ASTImporterTestBase, ::testing::Values(ArgVector(), ArgVector{"-fdelayed-template-parsing"}),);
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits