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 @@ -383,6 +383,8 @@ ExpectedType VisitTemplateTypeParmType(const TemplateTypeParmType *T); ExpectedType VisitSubstTemplateTypeParmType( const SubstTemplateTypeParmType *T); + ExpectedType + VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType *T); ExpectedType VisitTemplateSpecializationType( const TemplateSpecializationType *T); ExpectedType VisitElaboratedType(const ElaboratedType *T); @@ -1486,6 +1488,22 @@ Replaced, (*ToReplacementTypeOrErr).getCanonicalType()); } +ExpectedType ASTNodeImporter::VisitSubstTemplateTypeParmPackType( + const SubstTemplateTypeParmPackType *T) { + ExpectedType ReplacedOrErr = import(QualType(T->getReplacedParameter(), 0)); + if (!ReplacedOrErr) + return ReplacedOrErr.takeError(); + const TemplateTypeParmType *Replaced = + cast(ReplacedOrErr->getTypePtr()); + + Expected ToArgumentPack = import(T->getArgumentPack()); + if (!ToArgumentPack) + return ToArgumentPack.takeError(); + + return Importer.getToContext().getSubstTemplateTypeParmPackType( + Replaced, *ToArgumentPack); +} + ExpectedType ASTNodeImporter::VisitTemplateSpecializationType( const TemplateSpecializationType *T) { auto ToTemplateOrErr = import(T->getTemplateName()); 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 @@ -4693,6 +4693,57 @@ ToD2->getDeclContext(), ToD2->getTemplateParameters()->getParam(0))); } +const AstTypeMatcher + substTemplateTypeParmPackType; + +TEST_P(ASTImporterOptionSpecificTestBase, ImportSubstTemplateTypeParmPackType) { + constexpr auto Code = R"( + template struct D { + template using B = int(int (*...p)(T, U)); + template D(B*); + }; + int f(int(int, int), int(int, int)); + + using asd = D::B; + )"; + Decl *FromTU = getTuDecl(Code, Lang_CXX11, "input.cpp"); + auto *FromClass = FirstDeclMatcher().match( + FromTU, classTemplateSpecializationDecl()); + + { + ASTContext &FromCtx = FromTU->getASTContext(); + const auto *FromSubstPack = selectFirst( + "pack", match(substTemplateTypeParmPackType().bind("pack"), FromCtx)); + + ASSERT_TRUE(FromSubstPack); + ASSERT_EQ(FromSubstPack->getIdentifier()->getName(), "T"); + ArrayRef FromArgPack = + FromSubstPack->getArgumentPack().pack_elements(); + ASSERT_EQ(FromArgPack.size(), 3u); + ASSERT_EQ(FromArgPack[0].getAsType(), FromCtx.FloatTy); + ASSERT_EQ(FromArgPack[1].getAsType(), FromCtx.DoubleTy); + ASSERT_EQ(FromArgPack[2].getAsType(), FromCtx.FloatTy); + } + { + // Let's do the import. + ClassTemplateSpecializationDecl *ToClass = Import(FromClass, Lang_CXX11); + ASTContext &ToCtx = ToClass->getASTContext(); + + const auto *ToSubstPack = selectFirst( + "pack", match(substTemplateTypeParmPackType().bind("pack"), ToCtx)); + + // Check if it meets the requirements. + ASSERT_TRUE(ToSubstPack); + ASSERT_EQ(ToSubstPack->getIdentifier()->getName(), "T"); + ArrayRef ToArgPack = + ToSubstPack->getArgumentPack().pack_elements(); + ASSERT_EQ(ToArgPack.size(), 3u); + ASSERT_EQ(ToArgPack[0].getAsType(), ToCtx.FloatTy); + ASSERT_EQ(ToArgPack[1].getAsType(), ToCtx.DoubleTy); + ASSERT_EQ(ToArgPack[2].getAsType(), ToCtx.FloatTy); + } +} + struct ASTImporterLookupTableTest : ASTImporterOptionSpecificTestBase {}; TEST_P(ASTImporterLookupTableTest, OneDecl) {