balazske updated this revision to Diff 314604. balazske added a comment. Found a better solution. And the decl chain looks more normal if this change is used.
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D94067/new/ https://reviews.llvm.org/D94067 Files: clang/lib/AST/ASTImporter.cpp clang/unittests/AST/ASTImporterTest.cpp Index: clang/unittests/AST/ASTImporterTest.cpp =================================================================== --- clang/unittests/AST/ASTImporterTest.cpp +++ clang/unittests/AST/ASTImporterTest.cpp @@ -6141,6 +6141,41 @@ EXPECT_EQ(ToAttr->getAnnotation(), "A"); } +TEST_P(ASTImporterOptionSpecificTestBase, + ImportOfTemplatedDeclWhenPreviousDeclHasNoDescribedTemplateSet) { + Decl *FromTU = getTuDecl( + R"( + + namespace std { + template<typename T> + class basic_stringbuf; + } + namespace std { + class char_traits; + template<typename T = char_traits> + class basic_stringbuf; + } + namespace std { + template<typename T> + class basic_stringbuf {}; + } + + )", + Lang_CXX11); + + auto *From1 = FirstDeclMatcher<ClassTemplateDecl>().match( + FromTU, + classTemplateDecl(hasName("basic_stringbuf"), unless(isImplicit()))); + auto *To1 = cast_or_null<ClassTemplateDecl>(Import(From1, Lang_CXX11)); + EXPECT_TRUE(To1); + + auto *From2 = LastDeclMatcher<ClassTemplateDecl>().match( + FromTU, + classTemplateDecl(hasName("basic_stringbuf"), unless(isImplicit()))); + auto *To2 = cast_or_null<ClassTemplateDecl>(Import(From2, Lang_CXX11)); + EXPECT_TRUE(To2); +} + INSTANTIATE_TEST_CASE_P(ParameterizedTests, ASTImporterLookupTableTest, DefaultTestValuesForRunOptions, ); Index: clang/lib/AST/ASTImporter.cpp =================================================================== --- clang/lib/AST/ASTImporter.cpp +++ clang/lib/AST/ASTImporter.cpp @@ -2897,6 +2897,9 @@ getCanonicalForwardRedeclChain(D2CXX); for (auto *R : Redecls) { auto *RI = cast<CXXRecordDecl>(R); + // Skip the declaration if injected type is already set. + if (isa<InjectedClassNameType>(RI->getTypeForDecl())) + continue; RI->setTypeForDecl(nullptr); // Below we create a new injected type and assign that to the // canonical decl, subsequent declarations in the chain will reuse @@ -5393,16 +5396,16 @@ CXXRecordDecl *FromTemplated = D->getTemplatedDecl(); + auto TemplateParamsOrErr = import(D->getTemplateParameters()); + if (!TemplateParamsOrErr) + return TemplateParamsOrErr.takeError(); + // Create the declaration that is being templated. CXXRecordDecl *ToTemplated; if (Error Err = importInto(ToTemplated, FromTemplated)) return std::move(Err); // Create the class template declaration itself. - auto TemplateParamsOrErr = import(D->getTemplateParameters()); - if (!TemplateParamsOrErr) - return TemplateParamsOrErr.takeError(); - ClassTemplateDecl *D2; if (GetImportedOrCreateDecl(D2, D, Importer.getToContext(), DC, Loc, Name, *TemplateParamsOrErr, ToTemplated))
Index: clang/unittests/AST/ASTImporterTest.cpp =================================================================== --- clang/unittests/AST/ASTImporterTest.cpp +++ clang/unittests/AST/ASTImporterTest.cpp @@ -6141,6 +6141,41 @@ EXPECT_EQ(ToAttr->getAnnotation(), "A"); } +TEST_P(ASTImporterOptionSpecificTestBase, + ImportOfTemplatedDeclWhenPreviousDeclHasNoDescribedTemplateSet) { + Decl *FromTU = getTuDecl( + R"( + + namespace std { + template<typename T> + class basic_stringbuf; + } + namespace std { + class char_traits; + template<typename T = char_traits> + class basic_stringbuf; + } + namespace std { + template<typename T> + class basic_stringbuf {}; + } + + )", + Lang_CXX11); + + auto *From1 = FirstDeclMatcher<ClassTemplateDecl>().match( + FromTU, + classTemplateDecl(hasName("basic_stringbuf"), unless(isImplicit()))); + auto *To1 = cast_or_null<ClassTemplateDecl>(Import(From1, Lang_CXX11)); + EXPECT_TRUE(To1); + + auto *From2 = LastDeclMatcher<ClassTemplateDecl>().match( + FromTU, + classTemplateDecl(hasName("basic_stringbuf"), unless(isImplicit()))); + auto *To2 = cast_or_null<ClassTemplateDecl>(Import(From2, Lang_CXX11)); + EXPECT_TRUE(To2); +} + INSTANTIATE_TEST_CASE_P(ParameterizedTests, ASTImporterLookupTableTest, DefaultTestValuesForRunOptions, ); Index: clang/lib/AST/ASTImporter.cpp =================================================================== --- clang/lib/AST/ASTImporter.cpp +++ clang/lib/AST/ASTImporter.cpp @@ -2897,6 +2897,9 @@ getCanonicalForwardRedeclChain(D2CXX); for (auto *R : Redecls) { auto *RI = cast<CXXRecordDecl>(R); + // Skip the declaration if injected type is already set. + if (isa<InjectedClassNameType>(RI->getTypeForDecl())) + continue; RI->setTypeForDecl(nullptr); // Below we create a new injected type and assign that to the // canonical decl, subsequent declarations in the chain will reuse @@ -5393,16 +5396,16 @@ CXXRecordDecl *FromTemplated = D->getTemplatedDecl(); + auto TemplateParamsOrErr = import(D->getTemplateParameters()); + if (!TemplateParamsOrErr) + return TemplateParamsOrErr.takeError(); + // Create the declaration that is being templated. CXXRecordDecl *ToTemplated; if (Error Err = importInto(ToTemplated, FromTemplated)) return std::move(Err); // Create the class template declaration itself. - auto TemplateParamsOrErr = import(D->getTemplateParameters()); - if (!TemplateParamsOrErr) - return TemplateParamsOrErr.takeError(); - ClassTemplateDecl *D2; if (GetImportedOrCreateDecl(D2, D, Importer.getToContext(), DC, Loc, Name, *TemplateParamsOrErr, ToTemplated))
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits