Index: clang/lib/AST/ASTImporter.cpp =================================================================== --- clang/lib/AST/ASTImporter.cpp +++ clang/lib/AST/ASTImporter.cpp @@ -1683,7 +1683,34 @@ Error ChildErrors = Error::success(); for (auto *From : FromDC->decls()) { ExpectedDecl ImportedOrErr = import(From); - if (!ImportedOrErr) { + + // If we are in the process of ImportDefinition(...) for a RecordDecl we + // want to make sure that we are also completing each FieldDecl. There + // are currently cases where this does not happen and this is correctness + // fix since operations such as code generation will expect this to be so. + if (ImportedOrErr) { + FieldDecl *FieldFrom = dyn_cast_or_null(From); + Decl *ImportedDecl = (Decl*)*ImportedOrErr; + FieldDecl *FieldTo = dyn_cast_or_null(ImportedDecl); + if (FieldFrom && FieldTo) { + const RecordType *RecordFrom = FieldFrom->getType()->getAs(); + const RecordType *RecordTo = FieldTo->getType()->getAs(); + if (RecordFrom && RecordTo) { + RecordDecl *FromRecordDecl = RecordFrom->getDecl(); + RecordDecl *ToRecordDecl = RecordTo->getDecl(); + + if (FromRecordDecl->isCompleteDefinition() && + !ToRecordDecl->isCompleteDefinition()) { + Error Err = ImportDefinition(FromRecordDecl, ToRecordDecl); + + if (Err && AccumulateChildErrors) + ChildErrors = joinErrors(std::move(ChildErrors), std::move(Err)); + else + consumeError(std::move(Err)); + } + } + } + } else { if (AccumulateChildErrors) ChildErrors = joinErrors(std::move(ChildErrors), ImportedOrErr.takeError()); Index: lldb/packages/Python/lldbsuite/test/commands/expression/codegen-crash-typedefdecl-not-in_declcontext/TestCodegenCrashTypedefDeclNotInDeclContext.py =================================================================== --- /dev/null +++ lldb/packages/Python/lldbsuite/test/commands/expression/codegen-crash-typedefdecl-not-in_declcontext/TestCodegenCrashTypedefDeclNotInDeclContext.py @@ -0,0 +1,4 @@ +from lldbsuite.test import lldbinline +from lldbsuite.test import decorators + +lldbinline.MakeInlineTest(__file__, globals(), []) Index: lldb/packages/Python/lldbsuite/test/commands/expression/codegen-crash-typedefdecl-not-in_declcontext/main.cpp =================================================================== --- /dev/null +++ lldb/packages/Python/lldbsuite/test/commands/expression/codegen-crash-typedefdecl-not-in_declcontext/main.cpp @@ -0,0 +1,39 @@ +// This is a reproducer for a crash in codegen. It happens when we have a +// RecordDecl used in an expression and one of the FieldDecl are not complete. +// This case happens when: +// - A RecordDecl (E) has a FieldDecl which is a reference member variable +// - The underlying type of the FieldDec is a TypedefDecl +// - The typedef refers to a ClassTemplateSpecialization (DWrapper) +// - The typedef is not present in the DeclContext of B +// - The typedef shows up as a return value of a member function of E (f()) +template struct DWrapper {}; + +struct D {}; + +namespace NS { +typedef DWrapper DW; +} + +struct B { + NS::DW spd; + int a = 0; +}; + +struct E { + E(B &b) : b_ref(b) {} + NS::DW f() { return {}; }; + void g() { + return; //%self.expect("p b_ref", substrs=['(B) $0 =', '(spd = NS::DW', 'a = 0)']) + } + + B &b_ref; +}; + +int main() { + B b; + E e(b); + + e.g(); + + return 0; +} Index: lldb/packages/Python/lldbsuite/test/commands/expression/completion-crash-incomplete-record/TestCompletionCrashIncompleteRecord.py =================================================================== --- lldb/packages/Python/lldbsuite/test/commands/expression/completion-crash-incomplete-record/TestCompletionCrashIncompleteRecord.py +++ lldb/packages/Python/lldbsuite/test/commands/expression/completion-crash-incomplete-record/TestCompletionCrashIncompleteRecord.py @@ -1,4 +1,4 @@ from lldbsuite.test import lldbinline from lldbsuite.test import decorators -lldbinline.MakeInlineTest(__file__, globals(), [decorators.skipIf(bugnumber="rdar://53756116")]) +lldbinline.MakeInlineTest(__file__, globals(), [])