}
To->startDefinition();
+ // Set the definition to complete even if it is really not complete during
+ // import. Some AST constructs (expressions) require the record layout
+ // to be calculated (see 'clang::computeDependence') at the time they are
+ // constructed. Import of such AST node is possible during import of the
+ // same record, there is no way to have a completely defined record (all
+ // fields imported) at that time without multiple AST import passes.
+ if (!Importer.isMinimalImport())
+ To->setCompleteDefinition(true);
// Complete the definition even if error is returned.
// The RecordDecl may be already part of the AST so it is better to
// have it in complete state even if something is wrong with it.
ToCXX->setBases(Bases.data(), Bases.size());
}
- if (shouldForceImportDeclContext(Kind))
+ if (shouldForceImportDeclContext(Kind)) {
if (Error Err = ImportDeclContext(From, /*ForceImport=*/true))
return Err;
+ }
return Error::success();
}
bool MinimalImport,
const std::shared_ptr<ASTImporterSharedState> &SharedState) {
return new ASTImporter(ToContext, ToFileManager, FromContext,
- FromFileManager, MinimalImport,
+ // Use minimal import for these tests.
+ FromFileManager, /*MinimalImport=*/true,
// We use the regular lookup.
/*SharedState=*/nullptr);
};
ToDGOther);
}
+TEST_P(ASTImporterOptionSpecificTestBase,
+ ImportRecordWithLayoutRequestingExpr) {
+ TranslationUnitDecl *FromTU = getTuDecl(
+ R"(
+ struct A {
+ int idx;
+ static void foo(A x) {
+ (void)&"text"[x.idx];
+ }
+ };
+ )",
+ Lang_CXX11);
+
+ auto *FromA = FirstDeclMatcher<CXXRecordDecl>().match(
+ FromTU, cxxRecordDecl(hasName("A")));
+
+ // Test that during import of 'foo' the record layout can be obtained without
+ // crash.
+ auto *ToA = Import(FromA, Lang_CXX11);
+ EXPECT_TRUE(ToA);
+ EXPECT_TRUE(ToA->isCompleteDefinition());
+}
+
+TEST_P(ASTImporterOptionSpecificTestBase,
+ ImportRecordWithLayoutRequestingExprDifferentRecord) {
+ TranslationUnitDecl *FromTU = getTuDecl(
+ R"(
+ struct B;
+ struct A {
+ int idx;
+ B *b;
+ };
+ struct B {
+ static void foo(A x) {
+ (void)&"text"[x.idx];
+ }
+ };
+ )",
+ Lang_CXX11);
+
+ auto *FromA = FirstDeclMatcher<CXXRecordDecl>().match(
+ FromTU, cxxRecordDecl(hasName("A")));
+
+ // Test that during import of 'foo' the record layout (of 'A') can be obtained
+ // without crash. It is not possible to have all of the fields of 'A' imported
+ // at that time (without big code changes).
+ auto *ToA = Import(FromA, Lang_CXX11);
+ EXPECT_TRUE(ToA);
+ EXPECT_TRUE(ToA->isCompleteDefinition());
+}
+
INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ASTImporterLookupTableTest,
DefaultTestValuesForRunOptions);