balazske created this revision. Herald added subscribers: cfe-commits, martong. Herald added a reviewer: a.sidorin.
When a CXXRecordDecl under ClassTemplateDecl is imported, check the templated record decl for similarity instead of the template. Repository: rC Clang https://reviews.llvm.org/D47313 Files: lib/AST/ASTImporter.cpp unittests/AST/ASTImporterTest.cpp Index: unittests/AST/ASTImporterTest.cpp =================================================================== --- unittests/AST/ASTImporterTest.cpp +++ unittests/AST/ASTImporterTest.cpp @@ -1139,6 +1139,50 @@ has(fieldDecl(hasType(dependentSizedArrayType()))))))); } +TEST_P(ASTImporterTestBase, ImportOfTemplatedDeclOfClassTemplateDecl) { + Decl *FromTU = getTuDecl("template<class X> struct S{};", Lang_CXX); + auto From = + FirstDeclMatcher<ClassTemplateDecl>().match(FromTU, classTemplateDecl()); + ASSERT_TRUE(From); + auto To = cast<ClassTemplateDecl>(Import(From, Lang_CXX)); + ASSERT_TRUE(To); + Decl *ToTemplated = To->getTemplatedDecl(); + Decl *ToTemplated1 = Import(From->getTemplatedDecl(), Lang_CXX); + EXPECT_TRUE(ToTemplated1); + EXPECT_EQ(ToTemplated1, ToTemplated); +} + +TEST_P(ASTImporterTestBase, ImportCorrectTemplatedDecl) { + auto Code = + R"( + namespace x { + template<class X> struct S1{}; + template<class X> struct S2{}; + template<class X> struct S3{}; + } + )"; + Decl *FromTU = getTuDecl(Code, Lang_CXX); + auto FromNs = + FirstDeclMatcher<NamespaceDecl>().match(FromTU, namespaceDecl()); + auto ToNs = cast<NamespaceDecl>(Import(FromNs, Lang_CXX)); + ASSERT_TRUE(ToNs); + auto From = + FirstDeclMatcher<ClassTemplateDecl>().match(FromTU, + classTemplateDecl( + hasName("S2"))); + auto To = + FirstDeclMatcher<ClassTemplateDecl>().match(ToNs, + classTemplateDecl( + hasName("S2"))); + ASSERT_TRUE(From); + ASSERT_TRUE(To); + auto ToTemplated = To->getTemplatedDecl(); + auto ToTemplated1 = + cast<CXXRecordDecl>(Import(From->getTemplatedDecl(), Lang_CXX)); + EXPECT_TRUE(ToTemplated1); + ASSERT_EQ(ToTemplated1, ToTemplated); +} + TEST_P(ASTImporterTestBase, DISABLED_ImportFunctionWithBackReferringParameter) { Decl *From, *To; std::tie(From, To) = getImportedDecl( Index: lib/AST/ASTImporter.cpp =================================================================== --- lib/AST/ASTImporter.cpp +++ lib/AST/ASTImporter.cpp @@ -2009,7 +2009,14 @@ if (const auto *Tag = Typedef->getUnderlyingType()->getAs<TagType>()) Found = Tag->getDecl(); } - + + if (D->getDescribedTemplate()) { + if (auto *Template = dyn_cast<ClassTemplateDecl>(Found)) + Found = Template->getTemplatedDecl(); + else + continue; + } + if (auto *FoundRecord = dyn_cast<RecordDecl>(Found)) { if (!SearchName) { // If both unnamed structs/unions are in a record context, make sure
Index: unittests/AST/ASTImporterTest.cpp =================================================================== --- unittests/AST/ASTImporterTest.cpp +++ unittests/AST/ASTImporterTest.cpp @@ -1139,6 +1139,50 @@ has(fieldDecl(hasType(dependentSizedArrayType()))))))); } +TEST_P(ASTImporterTestBase, ImportOfTemplatedDeclOfClassTemplateDecl) { + Decl *FromTU = getTuDecl("template<class X> struct S{};", Lang_CXX); + auto From = + FirstDeclMatcher<ClassTemplateDecl>().match(FromTU, classTemplateDecl()); + ASSERT_TRUE(From); + auto To = cast<ClassTemplateDecl>(Import(From, Lang_CXX)); + ASSERT_TRUE(To); + Decl *ToTemplated = To->getTemplatedDecl(); + Decl *ToTemplated1 = Import(From->getTemplatedDecl(), Lang_CXX); + EXPECT_TRUE(ToTemplated1); + EXPECT_EQ(ToTemplated1, ToTemplated); +} + +TEST_P(ASTImporterTestBase, ImportCorrectTemplatedDecl) { + auto Code = + R"( + namespace x { + template<class X> struct S1{}; + template<class X> struct S2{}; + template<class X> struct S3{}; + } + )"; + Decl *FromTU = getTuDecl(Code, Lang_CXX); + auto FromNs = + FirstDeclMatcher<NamespaceDecl>().match(FromTU, namespaceDecl()); + auto ToNs = cast<NamespaceDecl>(Import(FromNs, Lang_CXX)); + ASSERT_TRUE(ToNs); + auto From = + FirstDeclMatcher<ClassTemplateDecl>().match(FromTU, + classTemplateDecl( + hasName("S2"))); + auto To = + FirstDeclMatcher<ClassTemplateDecl>().match(ToNs, + classTemplateDecl( + hasName("S2"))); + ASSERT_TRUE(From); + ASSERT_TRUE(To); + auto ToTemplated = To->getTemplatedDecl(); + auto ToTemplated1 = + cast<CXXRecordDecl>(Import(From->getTemplatedDecl(), Lang_CXX)); + EXPECT_TRUE(ToTemplated1); + ASSERT_EQ(ToTemplated1, ToTemplated); +} + TEST_P(ASTImporterTestBase, DISABLED_ImportFunctionWithBackReferringParameter) { Decl *From, *To; std::tie(From, To) = getImportedDecl( Index: lib/AST/ASTImporter.cpp =================================================================== --- lib/AST/ASTImporter.cpp +++ lib/AST/ASTImporter.cpp @@ -2009,7 +2009,14 @@ if (const auto *Tag = Typedef->getUnderlyingType()->getAs<TagType>()) Found = Tag->getDecl(); } - + + if (D->getDescribedTemplate()) { + if (auto *Template = dyn_cast<ClassTemplateDecl>(Found)) + Found = Template->getTemplatedDecl(); + else + continue; + } + if (auto *FoundRecord = dyn_cast<RecordDecl>(Found)) { if (!SearchName) { // If both unnamed structs/unions are in a record context, make sure
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits