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 @@ -5250,15 +5250,22 @@ if (!TemplateParamsOrErr) return TemplateParamsOrErr.takeError(); - // FIXME: Import default argument. - TemplateTemplateParmDecl *ToD = nullptr; - (void)GetImportedOrCreateDecl( - ToD, D, Importer.getToContext(), - Importer.getToContext().getTranslationUnitDecl(), *LocationOrErr, - D->getDepth(), D->getPosition(), D->isParameterPack(), - (*NameOrErr).getAsIdentifierInfo(), - *TemplateParamsOrErr); + if (GetImportedOrCreateDecl( + ToD, D, Importer.getToContext(), + Importer.getToContext().getTranslationUnitDecl(), *LocationOrErr, + D->getDepth(), D->getPosition(), D->isParameterPack(), + (*NameOrErr).getAsIdentifierInfo(), *TemplateParamsOrErr)) + return ToD; + + if (D->hasDefaultArgument()) { + Expected ToDefaultArgOrErr = + import(D->getDefaultArgument()); + if (!ToDefaultArgOrErr) + return ToDefaultArgOrErr.takeError(); + ToD->setDefaultArgument(Importer.getToContext(), *ToDefaultArgOrErr); + } + return ToD; } 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 @@ -901,6 +901,39 @@ .isValid()); } +TEST_P(ASTImporterOptionSpecificTestBase, + TemplateTemplateParmDeclNoDefaultArg) { + Decl *FromTU = getTuDecl(R"( + template typename TT> struct Y {}; + )", + Lang_CXX17); + auto From = FirstDeclMatcher().match( + FromTU, templateTemplateParmDecl(hasName("TT"))); + TemplateTemplateParmDecl *To = Import(From, Lang_CXX17); + ASSERT_FALSE(To->hasDefaultArgument()); +} + +TEST_P(ASTImporterOptionSpecificTestBase, TemplateTemplateParmDeclDefaultArg) { + Decl *FromTU = getTuDecl(R"( + template struct X {}; + template typename TT = X> struct Y {}; + )", + Lang_CXX17); + auto From = FirstDeclMatcher().match( + FromTU, templateTemplateParmDecl(hasName("TT"))); + TemplateTemplateParmDecl *To = Import(From, Lang_CXX17); + ASSERT_TRUE(To->hasDefaultArgument()); + const TemplateArgument &ToDefaultArg = To->getDefaultArgument().getArgument(); + ASSERT_TRUE(To->isTemplateDecl()); + TemplateDecl *ToTemplate = ToDefaultArg.getAsTemplate().getAsTemplateDecl(); + + // Find the default argument template 'X' in the AST and compare it against + // the default argument we got. + auto ToExpectedDecl = FirstDeclMatcher().match( + To->getTranslationUnitDecl(), classTemplateDecl(hasName("X"))); + ASSERT_EQ(ToTemplate, ToExpectedDecl); +} + TEST_P(ASTImporterOptionSpecificTestBase, ImportOfTemplatedDeclOfClassTemplateDecl) { Decl *FromTU = getTuDecl("template struct S{};", Lang_CXX03);