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 @@ -548,6 +548,7 @@ ExpectedDecl VisitUsingDecl(UsingDecl *D); ExpectedDecl VisitUsingShadowDecl(UsingShadowDecl *D); ExpectedDecl VisitUsingDirectiveDecl(UsingDirectiveDecl *D); + ExpectedDecl VisitUsingPackDecl(UsingPackDecl *D); ExpectedDecl ImportUsingShadowDecls(BaseUsingDecl *D, BaseUsingDecl *ToSI); ExpectedDecl VisitUsingEnumDecl(UsingEnumDecl *D); ExpectedDecl VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D); @@ -4832,6 +4833,36 @@ return ToUsingDir; } +ExpectedDecl ASTNodeImporter::VisitUsingPackDecl(UsingPackDecl *D) { + DeclContext *DC, *LexicalDC; + DeclarationName Name; + SourceLocation Loc; + NamedDecl *ToD = nullptr; + if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc)) + return std::move(Err); + if (ToD) + return ToD; + + auto ToInstantiatedFromUsingOrErr = + Importer.Import(D->getInstantiatedFromUsingDecl()); + if (!ToInstantiatedFromUsingOrErr) + return ToInstantiatedFromUsingOrErr.takeError(); + SmallVector Expansions(D->expansions().size()); + if (Error Err = ImportArrayChecked(D->expansions(), Expansions.begin())) + return std::move(Err); + + UsingPackDecl *ToUsingPack; + if (GetImportedOrCreateDecl(ToUsingPack, D, Importer.getToContext(), DC, + cast(*ToInstantiatedFromUsingOrErr), + Expansions)) + return ToUsingPack; + + ToUsingPack->setLexicalDeclContext(LexicalDC); + LexicalDC->addDeclInternal(ToUsingPack); + + return ToUsingPack; +} + ExpectedDecl ASTNodeImporter::VisitUnresolvedUsingValueDecl( UnresolvedUsingValueDecl *D) { DeclContext *DC, *LexicalDC; 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 @@ -910,6 +910,20 @@ functionDecl(hasDescendant(usingEnumDecl(hasName("bar"))))); } +const internal::VariadicDynCastAllOfMatcher usingPackDecl; + +TEST_P(ImportDecl, ImportUsingPackDecl) { + MatchVerifier Verifier; + testImport( + "struct A { int operator()() { return 1; } };" + "struct B { int operator()() { return 2; } };" + "template struct C : T... { using T::operator()...; };" + "C declToImport;", + Lang_CXX20, "", Lang_CXX20, Verifier, + varDecl(hasType(templateSpecializationType(hasDeclaration( + classTemplateSpecializationDecl(hasDescendant(usingPackDecl()))))))); +} + /// \brief Matches shadow declarations introduced into a scope by a /// (resolved) using declaration. ///