From: Pavel Labath Date: Mon, 6 Jul 2020 08:09:13 +0000 (+0200) Subject: [lldb/DWARF] Look for complete array element definitions in other modules X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=b65d4b23f6dd4da4277acbf2bb912becce4f8a57;p=android-x86%2Fexternal-llvm-project.git [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. --- diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 0bb69eb9136..0bd2d0c05c1 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -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 diff --git a/lldb/test/API/functionalities/limit-debug-info/TestLimitDebugInfo.py b/lldb/test/API/functionalities/limit-debug-info/TestLimitDebugInfo.py index 396861f5eb7..9408ad6eee1 100644 --- a/lldb/test/API/functionalities/limit-debug-info/TestLimitDebugInfo.py +++ b/lldb/test/API/functionalities/limit-debug-info/TestLimitDebugInfo.py @@ -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'"]) diff --git a/lldb/test/API/functionalities/limit-debug-info/main.cpp b/lldb/test/API/functionalities/limit-debug-info/main.cpp index 886b3feec43..0a25de13d9f 100644 --- a/lldb/test/API/functionalities/limit-debug-info/main.cpp +++ b/lldb/test/API/functionalities/limit-debug-info/main.cpp @@ -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; } diff --git a/lldb/test/API/functionalities/limit-debug-info/one.cpp b/lldb/test/API/functionalities/limit-debug-info/one.cpp index ee275e3321e..c1eb6310dd6 100644 --- a/lldb/test/API/functionalities/limit-debug-info/one.cpp +++ b/lldb/test/API/functionalities/limit-debug-info/one.cpp @@ -2,3 +2,4 @@ One::~One() = default; member::One::~One() = default; +array::One::~One() = default; diff --git a/lldb/test/API/functionalities/limit-debug-info/onetwo.h b/lldb/test/API/functionalities/limit-debug-info/onetwo.h index 6822d84803f..67609dd7ff6 100644 --- a/lldb/test/API/functionalities/limit-debug-info/onetwo.h +++ b/lldb/test/API/functionalities/limit-debug-info/onetwo.h @@ -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 diff --git a/lldb/test/API/functionalities/limit-debug-info/two.cpp b/lldb/test/API/functionalities/limit-debug-info/two.cpp index db98c5e8d3d..04683da6e9c 100644 --- a/lldb/test/API/functionalities/limit-debug-info/two.cpp +++ b/lldb/test/API/functionalities/limit-debug-info/two.cpp @@ -2,3 +2,4 @@ Two::~Two() = default; member::Two::~Two() = default; +array::Two::~Two() = default;