[Lldb-commits] [lldb] b3b9528 - [lldb/DWARF] Look for complete member definitions in other modules
Pavel Labath via lldb-commits
lldb-commits at lists.llvm.org
Fri Jul 3 07:54:26 PDT 2020
Author: Pavel Labath
Date: 2020-07-03T16:50:49+02:00
New Revision: b3b952873f3705e6877644013461be7923c6caad
URL: https://github.com/llvm/llvm-project/commit/b3b952873f3705e6877644013461be7923c6caad
DIFF: https://github.com/llvm/llvm-project/commit/b3b952873f3705e6877644013461be7923c6caad.diff
LOG: [lldb/DWARF] Look for complete member definitions in other modules
With -flimit-debug-info, we can have a definition of a class, but no
definition for some of its members. This extends the same logic we were
using for incomplete base classes to cover incomplete members too.
Test forward-declarations.s is removed as it is no longer applicable --
we don't warn anymore when encountering incomplete members as they could
be completed elsewhere. New checks added to TestLimitDebugInfo cover the
handling of incomplete members more thoroughly.
Added:
Modified:
lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
lldb/test/API/functionalities/limit-debug-info/TestLimitDebugInfo.py
lldb/test/API/functionalities/limit-debug-info/main.cpp
lldb/test/API/functionalities/limit-debug-info/one.cpp
lldb/test/API/functionalities/limit-debug-info/onetwo.h
lldb/test/API/functionalities/limit-debug-info/two.cpp
Removed:
lldb/test/Shell/SymbolFile/DWARF/forward-declarations.s
################################################################################
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 4bf5796ed59d..0bb69eb91362 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -2741,31 +2741,21 @@ void DWARFASTParserClang::ParseSingleMember(
if (TypeSystemClang::IsCXXClassType(member_clang_type) &&
!member_clang_type.GetCompleteType()) {
- if (die.GetCU()->GetProducer() == eProducerClang)
- module_sp->ReportError(
- "DWARF DIE at 0x%8.8x (class %s) has a member variable "
- "0x%8.8x (%s) whose type is a forward declaration, not a "
- "complete definition.\nTry compiling the source file "
- "with -fstandalone-debug",
- parent_die.GetOffset(), parent_die.GetName(), die.GetOffset(),
- name);
- else
- module_sp->ReportError(
- "DWARF DIE at 0x%8.8x (class %s) has a member variable "
- "0x%8.8x (%s) whose type is a forward declaration, not a "
- "complete definition.\nPlease file a bug against the "
- "compiler and include the preprocessed output for %s",
- parent_die.GetOffset(), parent_die.GetName(), die.GetOffset(),
- name, GetUnitName(parent_die).c_str());
- // We have no choice other than to pretend that the member
- // class 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, ut we make a note of the fact that
+ // this class is not _really_ complete so we can later search for a
+ // definition in a
diff erent 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(
member_clang_type)) {
TypeSystemClang::CompleteTagDeclarationDefinition(
member_clang_type);
+ const auto *td = TypeSystemClang::GetQualType(
+ member_clang_type.GetOpaqueQualType())
+ .getTypePtr()
+ ->getAsTagDecl();
+ m_ast.GetMetadata(td)->SetIsForcefullyCompleted();
} else {
module_sp->ReportError(
"DWARF DIE at 0x%8.8x (class %s) has a member variable "
diff --git a/lldb/test/API/functionalities/limit-debug-info/TestLimitDebugInfo.py b/lldb/test/API/functionalities/limit-debug-info/TestLimitDebugInfo.py
index d22aeaace7bf..396861f5eb76 100644
--- a/lldb/test/API/functionalities/limit-debug-info/TestLimitDebugInfo.py
+++ b/lldb/test/API/functionalities/limit-debug-info/TestLimitDebugInfo.py
@@ -44,11 +44,16 @@ def test_one_and_two_debug(self):
# all members.
self.expect_expr("inherits_from_one.member", result_value="47")
self.expect_expr("inherits_from_one.one", result_value="142")
-
self.expect_expr("inherits_from_two.member", result_value="47")
self.expect_expr("inherits_from_two.one", result_value="142")
self.expect_expr("inherits_from_two.two", result_value="242")
+ self.expect_expr("one_as_member.member", result_value="47")
+ self.expect_expr("one_as_member.one.member", result_value="147")
+ self.expect_expr("two_as_member.member", result_value="47")
+ self.expect_expr("two_as_member.two.one.member", result_value="147")
+ self.expect_expr("two_as_member.two.member", result_value="247")
+
@skipIf(bugnumber="pr46284", debug_info="gmodules")
@skipIfWindows # Clang emits type info even with -flimit-debug-info
def test_two_debug(self):
@@ -63,12 +68,19 @@ def test_two_debug(self):
self.expect_expr("inherits_from_one.member", result_value="47")
self.expect("expr inherits_from_one.one", error=True,
substrs=["no member named 'one' in 'InheritsFromOne'"])
-
self.expect_expr("inherits_from_two.member", result_value="47")
self.expect("expr inherits_from_two.one", error=True,
substrs=["no member named 'one' in 'InheritsFromTwo'"])
self.expect_expr("inherits_from_two.two", result_value="242")
+ self.expect_expr("one_as_member.member", result_value="47")
+ self.expect("expr one_as_member.one.member", error=True,
+ substrs=["no member named 'member' in 'member::One'"])
+ self.expect_expr("two_as_member.member", result_value="47")
+ self.expect("expr two_as_member.two.one.member", error=True,
+ substrs=["no member named 'member' in 'member::One'"])
+ self.expect_expr("two_as_member.two.member", result_value="247")
+
@skipIf(bugnumber="pr46284", debug_info="gmodules")
@skipIfWindows # Clang emits type info even with -flimit-debug-info
def test_one_debug(self):
@@ -85,9 +97,16 @@ def test_one_debug(self):
# "One".
self.expect_expr("inherits_from_one.member", result_value="47")
self.expect_expr("inherits_from_one.one", result_value="142")
-
self.expect_expr("inherits_from_two.member", result_value="47")
self.expect("expr inherits_from_two.one", error=True,
substrs=["no member named 'one' in 'InheritsFromTwo'"])
self.expect("expr inherits_from_two.two", error=True,
substrs=["no member named 'two' in 'InheritsFromTwo'"])
+
+ self.expect_expr("one_as_member.member", result_value="47")
+ self.expect_expr("one_as_member.one.member", result_value="147")
+ self.expect_expr("two_as_member.member", result_value="47")
+ self.expect("expr two_as_member.two.one.member", error=True,
+ 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'"])
diff --git a/lldb/test/API/functionalities/limit-debug-info/main.cpp b/lldb/test/API/functionalities/limit-debug-info/main.cpp
index e3049ed74489..886b3feec434 100644
--- a/lldb/test/API/functionalities/limit-debug-info/main.cpp
+++ b/lldb/test/API/functionalities/limit-debug-info/main.cpp
@@ -10,4 +10,16 @@ struct InheritsFromTwo : Two {
int member = 47;
} inherits_from_two;
+struct OneAsMember {
+ constexpr OneAsMember() = default;
+ member::One one;
+ int member = 47;
+} one_as_member;
+
+struct TwoAsMember {
+ constexpr TwoAsMember() = default;
+ member::Two two;
+ int member = 47;
+} two_as_member;
+
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 728875dd9e55..ee275e3321e4 100644
--- a/lldb/test/API/functionalities/limit-debug-info/one.cpp
+++ b/lldb/test/API/functionalities/limit-debug-info/one.cpp
@@ -1,3 +1,4 @@
#include "onetwo.h"
One::~One() = default;
+member::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 82df76c64b58..6822d84803fe 100644
--- a/lldb/test/API/functionalities/limit-debug-info/onetwo.h
+++ b/lldb/test/API/functionalities/limit-debug-info/onetwo.h
@@ -9,3 +9,18 @@ struct Two : One {
constexpr Two() = default;
~Two() override;
};
+
+namespace member {
+struct One {
+ int member = 147;
+ constexpr One() = default;
+ virtual ~One();
+};
+
+struct Two {
+ One one;
+ int member = 247;
+ constexpr Two() = default;
+ virtual ~Two();
+};
+} // namespace member
diff --git a/lldb/test/API/functionalities/limit-debug-info/two.cpp b/lldb/test/API/functionalities/limit-debug-info/two.cpp
index 928b091728c3..db98c5e8d3dc 100644
--- a/lldb/test/API/functionalities/limit-debug-info/two.cpp
+++ b/lldb/test/API/functionalities/limit-debug-info/two.cpp
@@ -1,3 +1,4 @@
#include "onetwo.h"
Two::~Two() = default;
+member::Two::~Two() = default;
diff --git a/lldb/test/Shell/SymbolFile/DWARF/forward-declarations.s b/lldb/test/Shell/SymbolFile/DWARF/forward-declarations.s
deleted file mode 100644
index 952c4ee7f87e..000000000000
--- a/lldb/test/Shell/SymbolFile/DWARF/forward-declarations.s
+++ /dev/null
@@ -1,111 +0,0 @@
-# Test handling of the situation (including the error message) where a structure
-# has a incomplete member.
-
-# REQUIRES: x86
-
-# RUN: llvm-mc -triple x86_64-pc-linux -filetype=obj %s -o %t
-# RUN: %lldb %t -o "target var b" -b 2>&1 | FileCheck %s
-
-# CHECK: error: {{.*}} DWARF DIE at 0x0000002b (class B) has a member variable 0x00000030 (a) whose type is a forward declaration, not a complete definition.
-# CHECK-NEXT: Please file a bug against the compiler and include the preprocessed output for /tmp/a.cc
-
-# CHECK: b = (a = A @ 0x0000000000000001)
-
- .type b, at object # @b
- .comm b,1,1
- .section .debug_str,"MS", at progbits,1
-.Linfo_string0:
- .asciz "Hand-written DWARF"
-.Lcu_name:
- .asciz "/tmp/a.cc"
-.Lcu_compdir:
- .asciz "/foo/bar"
-.Lb:
- .asciz "b"
-.La:
- .asciz "a"
-.LA:
- .asciz "A"
-.LB:
- .asciz "B"
-
- .section .debug_abbrev,"", at progbits
- .byte 1 # Abbreviation Code
- .byte 17 # DW_TAG_compile_unit
- .byte 1 # DW_CHILDREN_yes
- .byte 37 # DW_AT_producer
- .byte 14 # DW_FORM_strp
- .byte 3 # DW_AT_name
- .byte 14 # DW_FORM_strp
- .byte 27 # DW_AT_comp_dir
- .byte 14 # DW_FORM_strp
- .byte 0 # EOM(1)
- .byte 0 # EOM(2)
- .byte 2 # Abbreviation Code
- .byte 52 # DW_TAG_variable
- .byte 0 # DW_CHILDREN_no
- .byte 3 # DW_AT_name
- .byte 14 # DW_FORM_strp
- .byte 73 # DW_AT_type
- .byte 19 # DW_FORM_ref4
- .byte 2 # DW_AT_location
- .byte 24 # DW_FORM_exprloc
- .byte 0 # EOM(1)
- .byte 0 # EOM(2)
- .byte 3 # Abbreviation Code
- .byte 19 # DW_TAG_structure_type
- .byte 1 # DW_CHILDREN_yes
- .byte 3 # DW_AT_name
- .byte 14 # DW_FORM_strp
- .byte 0 # EOM(1)
- .byte 0 # EOM(2)
- .byte 4 # Abbreviation Code
- .byte 13 # DW_TAG_member
- .byte 0 # DW_CHILDREN_no
- .byte 3 # DW_AT_name
- .byte 14 # DW_FORM_strp
- .byte 73 # DW_AT_type
- .byte 19 # DW_FORM_ref4
- .byte 0 # EOM(1)
- .byte 0 # EOM(2)
- .byte 5 # Abbreviation Code
- .byte 19 # DW_TAG_structure_type
- .byte 0 # DW_CHILDREN_no
- .byte 60 # DW_AT_declaration
- .byte 25 # DW_FORM_flag_present
- .byte 3 # DW_AT_name
- .byte 14 # DW_FORM_strp
- .byte 0 # EOM(1)
- .byte 0 # EOM(2)
- .byte 0 # EOM(3)
-
- .section .debug_info,"", at progbits
-.Lcu_begin0:
- .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
-.Ldebug_info_start0:
- .short 4 # DWARF version number
- .long .debug_abbrev # Offset Into Abbrev. Section
- .byte 8 # Address Size (in bytes)
- .byte 1 # Abbrev [1] 0xb:0x46 DW_TAG_compile_unit
- .long .Linfo_string0 # DW_AT_producer
- .long .Lcu_name # DW_AT_name
- .long .Lcu_compdir # DW_AT_comp_dir
- .byte 2 # Abbrev [2] 0x1e:0x15 DW_TAG_variable
- .long .Lb # DW_AT_name
- .long .LB_die-.Lcu_begin0 # DW_AT_type
- .byte 9 # DW_AT_location
- .byte 3
- .quad b
-.LB_die:
- .byte 3 # Abbrev [3] 0x33:0x15 DW_TAG_structure_type
- .long .LB # DW_AT_name
- .byte 4 # Abbrev [4] 0x3b:0xc DW_TAG_member
- .long .La # DW_AT_name
- .long .LA_die-.Lcu_begin0 # DW_AT_type
- .byte 0 # End Of Children Mark
-.LA_die:
- .byte 5 # Abbrev [5] 0x48:0x8 DW_TAG_structure_type
- # DW_AT_declaration
- .long .LA # DW_AT_name
- .byte 0 # End Of Children Mark
-.Ldebug_info_end0:
More information about the lldb-commits
mailing list