diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -2897,6 +2897,9 @@ getCanonicalForwardRedeclChain(D2CXX); for (auto *R : Redecls) { auto *RI = cast(R); + // Skip the declaration if injected type is already set. + if (isa(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)) diff --git a/clang/unittests/AST/ASTImporterTest.cpp b/clang/unittests/AST/ASTImporterTest.cpp --- a/clang/unittests/AST/ASTImporterTest.cpp +++ b/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 + class basic_stringbuf; + } + namespace std { + class char_traits; + template + class basic_stringbuf; + } + namespace std { + template + class basic_stringbuf {}; + } + + )", + Lang_CXX11); + + auto *From1 = FirstDeclMatcher().match( + FromTU, + classTemplateDecl(hasName("basic_stringbuf"), unless(isImplicit()))); + auto *To1 = cast_or_null(Import(From1, Lang_CXX11)); + EXPECT_TRUE(To1); + + auto *From2 = LastDeclMatcher().match( + FromTU, + classTemplateDecl(hasName("basic_stringbuf"), unless(isImplicit()))); + auto *To2 = cast_or_null(Import(From2, Lang_CXX11)); + EXPECT_TRUE(To2); +} + INSTANTIATE_TEST_CASE_P(ParameterizedTests, ASTImporterLookupTableTest, DefaultTestValuesForRunOptions, );