[clang][AST] Add support for DecompositionDecl to ASTImporter.

BindingDecl was added recently but the related DecompositionDecl is needed
to make C++17 structured bindings importable.
Import of BindingDecl was changed to avoid infinite import loop.

Reviewed By: martong

Differential Revision: https://reviews.llvm.org/D105354
This commit is contained in:
Balázs Kéri 2021-07-22 11:43:13 +02:00
parent aa245ddd46
commit 41adc09b22
2 changed files with 50 additions and 12 deletions

View File

@ -2302,6 +2302,11 @@ ExpectedDecl ASTNodeImporter::VisitBindingDecl(BindingDecl *D) {
if (ToND)
return ToND;
BindingDecl *ToD;
if (GetImportedOrCreateDecl(ToD, D, Importer.getToContext(), DC, Loc,
Name.getAsIdentifierInfo()))
return ToD;
Error Err = Error::success();
QualType ToType = importChecked(Err, D->getType());
Expr *ToBinding = importChecked(Err, D->getBinding());
@ -2309,11 +2314,6 @@ ExpectedDecl ASTNodeImporter::VisitBindingDecl(BindingDecl *D) {
if (Err)
return std::move(Err);
BindingDecl *ToD;
if (GetImportedOrCreateDecl(ToD, D, Importer.getToContext(), DC, Loc,
Name.getAsIdentifierInfo()))
return ToD;
ToD->setBinding(ToType, ToBinding);
ToD->setDecomposedDecl(ToDecomposedDecl);
addDeclToContexts(D, ToD);
@ -4098,14 +4098,26 @@ ExpectedDecl ASTNodeImporter::VisitVarDecl(VarDecl *D) {
if (Err)
return std::move(Err);
// Create the imported variable.
VarDecl *ToVar;
if (GetImportedOrCreateDecl(ToVar, D, Importer.getToContext(), DC,
ToInnerLocStart, Loc,
Name.getAsIdentifierInfo(),
ToType, ToTypeSourceInfo,
D->getStorageClass()))
return ToVar;
if (auto *FromDecomp = dyn_cast<DecompositionDecl>(D)) {
SmallVector<BindingDecl *> Bindings(FromDecomp->bindings().size());
if (Error Err =
ImportArrayChecked(FromDecomp->bindings(), Bindings.begin()))
return std::move(Err);
DecompositionDecl *ToDecomp;
if (GetImportedOrCreateDecl(
ToDecomp, FromDecomp, Importer.getToContext(), DC, ToInnerLocStart,
Loc, ToType, ToTypeSourceInfo, D->getStorageClass(), Bindings))
return ToDecomp;
ToVar = ToDecomp;
} else {
// Create the imported variable.
if (GetImportedOrCreateDecl(ToVar, D, Importer.getToContext(), DC,
ToInnerLocStart, Loc,
Name.getAsIdentifierInfo(), ToType,
ToTypeSourceInfo, D->getStorageClass()))
return ToVar;
}
ToVar->setTSCSpec(D->getTSCSpec());
ToVar->setQualifierInfo(ToQualifierLoc);

View File

@ -3725,6 +3725,32 @@ TEST_P(ImportVariables, ImportBindingDecl) {
VerifyImport("y3");
}
TEST_P(ImportVariables, ImportDecompositionDeclArray) {
Decl *From, *To;
std::tie(From, To) = getImportedDecl(
R"(
void declToImport() {
int a[2] = {1,2};
auto [x1,y1] = a;
};
)",
Lang_CXX17, "", Lang_CXX17);
TranslationUnitDecl *FromTU = From->getTranslationUnitDecl();
auto *FromDecomp =
FirstDeclMatcher<DecompositionDecl>().match(FromTU, decompositionDecl());
auto *ToDecomp = Import(FromDecomp, Lang_CXX17);
EXPECT_TRUE(ToDecomp);
ArrayRef<BindingDecl *> FromB = FromDecomp->bindings();
ArrayRef<BindingDecl *> ToB = ToDecomp->bindings();
EXPECT_EQ(FromB.size(), ToB.size());
for (unsigned int I = 0; I < FromB.size(); ++I) {
auto *ToBI = Import(FromB[I], Lang_CXX17);
EXPECT_EQ(ToBI, ToB[I]);
}
}
struct ImportClasses : ASTImporterOptionSpecificTestBase {};
TEST_P(ImportClasses, ImportDefinitionWhenProtoIsInNestedToContext) {