[lldb/DWARF] Look for complete array element definitions in other modules
This applies the same logic we have for incomplete class bases and members to array element types.
This commit is contained in:
parent
8849831d55
commit
b65d4b23f6
|
|
@ -1267,32 +1267,20 @@ TypeSP DWARFASTParserClang::ParseArrayType(const DWARFDIE &die,
|
|||
if (TypeSystemClang::IsCXXClassType(array_element_type) &&
|
||||
!array_element_type.GetCompleteType()) {
|
||||
ModuleSP module_sp = die.GetModule();
|
||||
if (module_sp) {
|
||||
if (die.GetCU()->GetProducer() == eProducerClang)
|
||||
module_sp->ReportError(
|
||||
"DWARF DW_TAG_array_type DIE at 0x%8.8x has a "
|
||||
"class/union/struct element type DIE 0x%8.8x that is a "
|
||||
"forward declaration, not a complete definition.\nTry "
|
||||
"compiling the source file with -fstandalone-debug or "
|
||||
"disable -gmodules",
|
||||
die.GetOffset(), type_die.GetOffset());
|
||||
else
|
||||
module_sp->ReportError(
|
||||
"DWARF DW_TAG_array_type DIE at 0x%8.8x has a "
|
||||
"class/union/struct element type DIE 0x%8.8x that is a "
|
||||
"forward declaration, not a complete definition.\nPlease "
|
||||
"file a bug against the compiler and include the "
|
||||
"preprocessed output for %s",
|
||||
die.GetOffset(), type_die.GetOffset(), GetUnitName(die).c_str());
|
||||
}
|
||||
|
||||
// We have no choice other than to pretend that the element class
|
||||
// type is complete. If we don't do this, clang will crash when
|
||||
// trying to layout the class. Since we provide layout
|
||||
// assistance, all ivars in this class and other classes will be
|
||||
// fine, this is the best we can do short of crashing.
|
||||
// Mark the class as complete, but we make a note of the fact that
|
||||
// this class is not _really_ complete so we can later search for a
|
||||
// definition in a different module.
|
||||
// Since we provide layout assistance, all ivars in this class and other
|
||||
// classes will be fine even if we are not able to find the definition
|
||||
// elsewhere.
|
||||
if (TypeSystemClang::StartTagDeclarationDefinition(array_element_type)) {
|
||||
TypeSystemClang::CompleteTagDeclarationDefinition(array_element_type);
|
||||
const auto *td =
|
||||
TypeSystemClang::GetQualType(array_element_type.GetOpaqueQualType())
|
||||
.getTypePtr()
|
||||
->getAsTagDecl();
|
||||
m_ast.GetMetadata(td)->SetIsForcefullyCompleted();
|
||||
} else {
|
||||
module_sp->ReportError("DWARF DIE at 0x%8.8x was not able to "
|
||||
"start its definition.\nPlease file a "
|
||||
|
|
@ -2741,7 +2729,7 @@ void DWARFASTParserClang::ParseSingleMember(
|
|||
|
||||
if (TypeSystemClang::IsCXXClassType(member_clang_type) &&
|
||||
!member_clang_type.GetCompleteType()) {
|
||||
// Mark the class as complete, ut we make a note of the fact that
|
||||
// Mark the class as complete, but we make a note of the fact that
|
||||
// this class is not _really_ complete so we can later search for a
|
||||
// definition in a different module.
|
||||
// Since we provide layout assistance, all ivars in this class and
|
||||
|
|
|
|||
|
|
@ -54,6 +54,10 @@ class LimitDebugInfoTestCase(TestBase):
|
|||
self.expect_expr("two_as_member.two.one.member", result_value="147")
|
||||
self.expect_expr("two_as_member.two.member", result_value="247")
|
||||
|
||||
self.expect_expr("array_of_one[2].member", result_value="174")
|
||||
self.expect_expr("array_of_two[2].one[2].member", result_value="174")
|
||||
self.expect_expr("array_of_two[2].member", result_value="274")
|
||||
|
||||
@skipIf(bugnumber="pr46284", debug_info="gmodules")
|
||||
@skipIfWindows # Clang emits type info even with -flimit-debug-info
|
||||
def test_two_debug(self):
|
||||
|
|
@ -81,6 +85,12 @@ class LimitDebugInfoTestCase(TestBase):
|
|||
substrs=["no member named 'member' in 'member::One'"])
|
||||
self.expect_expr("two_as_member.two.member", result_value="247")
|
||||
|
||||
self.expect("expr array_of_one[2].member", error=True,
|
||||
substrs=["no member named 'member' in 'array::One'"])
|
||||
self.expect("expr array_of_two[2].one[2].member", error=True,
|
||||
substrs=["no member named 'member' in 'array::One'"])
|
||||
self.expect_expr("array_of_two[2].member", result_value="274")
|
||||
|
||||
@skipIf(bugnumber="pr46284", debug_info="gmodules")
|
||||
@skipIfWindows # Clang emits type info even with -flimit-debug-info
|
||||
def test_one_debug(self):
|
||||
|
|
@ -110,3 +120,9 @@ class LimitDebugInfoTestCase(TestBase):
|
|||
substrs=["no member named 'one' in 'member::Two'"])
|
||||
self.expect("expr two_as_member.two.member", error=True,
|
||||
substrs=["no member named 'member' in 'member::Two'"])
|
||||
|
||||
self.expect_expr("array_of_one[2].member", result_value="174")
|
||||
self.expect("expr array_of_two[2].one[2].member", error=True,
|
||||
substrs=["no member named 'one' in 'array::Two'"])
|
||||
self.expect("expr array_of_two[2].member", error=True,
|
||||
substrs=["no member named 'member' in 'array::Two'"])
|
||||
|
|
|
|||
|
|
@ -22,4 +22,7 @@ struct TwoAsMember {
|
|||
int member = 47;
|
||||
} two_as_member;
|
||||
|
||||
array::One array_of_one[3];
|
||||
array::Two array_of_two[3];
|
||||
|
||||
int main() { return 0; }
|
||||
|
|
|
|||
|
|
@ -2,3 +2,4 @@
|
|||
|
||||
One::~One() = default;
|
||||
member::One::~One() = default;
|
||||
array::One::~One() = default;
|
||||
|
|
|
|||
|
|
@ -24,3 +24,18 @@ struct Two {
|
|||
virtual ~Two();
|
||||
};
|
||||
} // namespace member
|
||||
|
||||
namespace array {
|
||||
struct One {
|
||||
int member = 174;
|
||||
constexpr One() = default;
|
||||
virtual ~One();
|
||||
};
|
||||
|
||||
struct Two {
|
||||
One one[3];
|
||||
int member = 274;
|
||||
constexpr Two() = default;
|
||||
virtual ~Two();
|
||||
};
|
||||
} // namespace array
|
||||
|
|
|
|||
|
|
@ -2,3 +2,4 @@
|
|||
|
||||
Two::~Two() = default;
|
||||
member::Two::~Two() = default;
|
||||
array::Two::~Two() = default;
|
||||
|
|
|
|||
Loading…
Reference in New Issue