[clang][ASTImporter] Add support for import of UsingPackDecl.

Reviewed By: martong

Differential Revision: https://reviews.llvm.org/D125986
This commit is contained in:
Balázs Kéri 2022-06-01 09:10:18 +02:00
parent ae8ae45e2a
commit d597a461e0
2 changed files with 69 additions and 0 deletions

View File

@ -548,6 +548,7 @@ namespace clang {
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,35 @@ ExpectedDecl ASTNodeImporter::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
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<NamedDecl *, 4> 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<NamedDecl>(*ToInstantiatedFromUsingOrErr),
Expansions))
return ToUsingPack;
addDeclToContexts(D, ToUsingPack);
return ToUsingPack;
}
ExpectedDecl ASTNodeImporter::VisitUnresolvedUsingValueDecl(
UnresolvedUsingValueDecl *D) {
DeclContext *DC, *LexicalDC;

View File

@ -910,6 +910,20 @@ TEST_P(ImportDecl, ImportUsingEnumDecl) {
functionDecl(hasDescendant(usingEnumDecl(hasName("bar")))));
}
const internal::VariadicDynCastAllOfMatcher<Decl, UsingPackDecl> usingPackDecl;
TEST_P(ImportDecl, ImportUsingPackDecl) {
MatchVerifier<Decl> Verifier;
testImport(
"struct A { int operator()() { return 1; } };"
"struct B { int operator()() { return 2; } };"
"template<typename ...T> struct C : T... { using T::operator()...; };"
"C<A, B> 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.
///
@ -1022,6 +1036,31 @@ TEST_P(ImportExpr, DependentSizedArrayType) {
has(fieldDecl(hasType(dependentSizedArrayType())))))));
}
TEST_P(ASTImporterOptionSpecificTestBase, ImportUsingPackDecl) {
Decl *FromTU = getTuDecl(
"struct A { int operator()() { return 1; } };"
"struct B { int operator()() { return 2; } };"
"template<typename ...T> struct C : T... { using T::operator()...; };"
"C<A, B> Var;",
Lang_CXX20);
auto From = FirstDeclMatcher<UsingPackDecl>().match(FromTU, usingPackDecl());
ASSERT_TRUE(From);
auto To = cast<UsingPackDecl>(Import(From, Lang_CXX20));
ASSERT_TRUE(To);
ArrayRef<NamedDecl *> FromExpansions = From->expansions();
ArrayRef<NamedDecl *> ToExpansions = To->expansions();
ASSERT_EQ(FromExpansions.size(), ToExpansions.size());
for (unsigned int I = 0; I < FromExpansions.size(); ++I) {
auto ImportedExpansion = Import(FromExpansions[I], Lang_CXX20);
EXPECT_EQ(ImportedExpansion, ToExpansions[I]);
}
auto ImportedDC = cast<Decl>(Import(From->getDeclContext(), Lang_CXX20));
EXPECT_EQ(ImportedDC, cast<Decl>(To->getDeclContext()));
}
TEST_P(ASTImporterOptionSpecificTestBase, TemplateTypeParmDeclNoDefaultArg) {
Decl *FromTU = getTuDecl("template<typename T> struct X {};", Lang_CXX03);
auto From = FirstDeclMatcher<TemplateTypeParmDecl>().match(