[Lldb-commits] [lldb] 9109311 - [lldb] Forcefully complete a type when adding typedefs
Pavel Labath via lldb-commits
lldb-commits at lists.llvm.org
Thu Aug 20 06:24:15 PDT 2020
Author: Pavel Labath
Date: 2020-08-20T15:19:10+02:00
New Revision: 9109311356cc9e74818dd7450020d9b85d2f8125
URL: https://github.com/llvm/llvm-project/commit/9109311356cc9e74818dd7450020d9b85d2f8125
DIFF: https://github.com/llvm/llvm-project/commit/9109311356cc9e74818dd7450020d9b85d2f8125.diff
LOG: [lldb] Forcefully complete a type when adding typedefs
This is very similar to D85968, only more elusive to since we were not
adding the typedef type to the relevant DeclContext until D86140, which
meant that the DeclContext was populated (and the relevant assertion
hit) only after importing the type into the expression ast in a
particular way.
I haven't checked whether this situation can be hit in the gmodules
case, but my money is on "yes".
Differential Revision: https://reviews.llvm.org/D86216
Added:
Modified:
lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
lldb/test/Shell/SymbolFile/DWARF/DW_AT_declaration-with-children.s
Removed:
################################################################################
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 486945ccbb8b..2fee87d98da8 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -556,42 +556,51 @@ DWARFASTParserClang::ParseTypeModifier(const SymbolContext &sc,
TypeSP type_sp;
CompilerType clang_type;
- if (tag == DW_TAG_typedef && attrs.type.IsValid()) {
- // Try to parse a typedef from the (DWARF embedded in the) Clang
- // module file first as modules can contain typedef'ed
- // structures that have no names like:
- //
- // typedef struct { int a; } Foo;
- //
- // In this case we will have a structure with no name and a
- // typedef named "Foo" that points to this unnamed
- // structure. The name in the typedef is the only identifier for
- // the struct, so always try to get typedefs from Clang modules
- // if possible.
- //
- // The type_sp returned will be empty if the typedef doesn't
- // exist in a module file, so it is cheap to call this function
- // just to check.
- //
- // If we don't do this we end up creating a TypeSP that says
- // this is a typedef to type 0x123 (the DW_AT_type value would
- // be 0x123 in the DW_TAG_typedef), and this is the unnamed
- // structure type. We will have a hard time tracking down an
- // unnammed structure type in the module debug info, so we make
- // sure we don't get into this situation by always resolving
- // typedefs from the module.
- const DWARFDIE encoding_die = attrs.type.Reference();
-
- // First make sure that the die that this is typedef'ed to _is_
- // just a declaration (DW_AT_declaration == 1), not a full
- // definition since template types can't be represented in
- // modules since only concrete instances of templates are ever
- // emitted and modules won't contain those
- if (encoding_die &&
- encoding_die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) == 1) {
- type_sp = ParseTypeFromClangModule(sc, die, log);
- if (type_sp)
- return type_sp;
+ if (tag == DW_TAG_typedef) {
+ // DeclContext will be populated when the clang type is materialized in
+ // Type::ResolveCompilerType.
+ PrepareContextToReceiveMembers(
+ m_ast, GetClangASTImporter(),
+ GetClangDeclContextContainingDIE(die, nullptr), die,
+ attrs.name.GetCString());
+
+ if (attrs.type.IsValid()) {
+ // Try to parse a typedef from the (DWARF embedded in the) Clang
+ // module file first as modules can contain typedef'ed
+ // structures that have no names like:
+ //
+ // typedef struct { int a; } Foo;
+ //
+ // In this case we will have a structure with no name and a
+ // typedef named "Foo" that points to this unnamed
+ // structure. The name in the typedef is the only identifier for
+ // the struct, so always try to get typedefs from Clang modules
+ // if possible.
+ //
+ // The type_sp returned will be empty if the typedef doesn't
+ // exist in a module file, so it is cheap to call this function
+ // just to check.
+ //
+ // If we don't do this we end up creating a TypeSP that says
+ // this is a typedef to type 0x123 (the DW_AT_type value would
+ // be 0x123 in the DW_TAG_typedef), and this is the unnamed
+ // structure type. We will have a hard time tracking down an
+ // unnammed structure type in the module debug info, so we make
+ // sure we don't get into this situation by always resolving
+ // typedefs from the module.
+ const DWARFDIE encoding_die = attrs.type.Reference();
+
+ // First make sure that the die that this is typedef'ed to _is_
+ // just a declaration (DW_AT_declaration == 1), not a full
+ // definition since template types can't be represented in
+ // modules since only concrete instances of templates are ever
+ // emitted and modules won't contain those
+ if (encoding_die &&
+ encoding_die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) == 1) {
+ type_sp = ParseTypeFromClangModule(sc, die, log);
+ if (type_sp)
+ return type_sp;
+ }
}
}
diff --git a/lldb/test/Shell/SymbolFile/DWARF/DW_AT_declaration-with-children.s b/lldb/test/Shell/SymbolFile/DWARF/DW_AT_declaration-with-children.s
index f17902918e38..9365dd966ed8 100644
--- a/lldb/test/Shell/SymbolFile/DWARF/DW_AT_declaration-with-children.s
+++ b/lldb/test/Shell/SymbolFile/DWARF/DW_AT_declaration-with-children.s
@@ -28,6 +28,13 @@ expr b1
# CHECK-LABEL: expr b1
# CHECK: (B::B1) $0 = (ptr = 0x00000000baadf00d)
+target var c1
+# CHECK-LABEL: target var c1
+# CHECK: (C::C1) c1 = 424742
+
+expr c1
+# CHECK-LABEL: expr c1
+# CHECK: (C::C1) $1 = 424742
#--- asm
.text
_ZN1AC2Ev:
@@ -42,6 +49,8 @@ a:
b1:
.quad 0xbaadf00d
+c1:
+ .long 42474247
.section .debug_abbrev,"", at progbits
.byte 1 # Abbreviation Code
@@ -118,6 +127,17 @@ b1:
.byte 19 # DW_FORM_ref4
.byte 0 # EOM(1)
.byte 0 # EOM(2)
+ .byte 9 # Abbreviation Code
+ .byte 36 # DW_TAG_base_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 8 # DW_FORM_string
+ .byte 62 # DW_AT_encoding
+ .byte 11 # DW_FORM_data1
+ .byte 11 # DW_AT_byte_size
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
.byte 10 # Abbreviation Code
.byte 46 # DW_TAG_subprogram
.byte 1 # DW_CHILDREN_yes
@@ -146,6 +166,15 @@ b1:
.byte 25 # DW_FORM_flag_present
.byte 0 # EOM(1)
.byte 0 # EOM(2)
+ .byte 12 # Abbreviation Code
+ .byte 22 # DW_TAG_typedef
+ .byte 0 # DW_CHILDREN_no
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 3 # DW_AT_name
+ .byte 8 # DW_FORM_string
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
.byte 0 # EOM(3)
.section .debug_info,"", at progbits
.Lcu_begin0:
@@ -222,7 +251,6 @@ b1:
.LB1:
.byte 6 # Abbrev [6] DW_TAG_class_type
.asciz "B1" # DW_AT_name
- # DW_AT_declaration
.byte 7 # Abbrev [5] 0x58:0xc DW_TAG_member
.asciz "ptr" # DW_AT_name
.long .LAptr # DW_AT_type
@@ -237,5 +265,33 @@ b1:
.byte 3
.quad b1
+# Case 3: A typedef in DW_AT_declaration struct.
+# C++ equivalent:
+# struct C {
+# virtual ~C(); // not defined here
+# typedef int C1;
+# };
+# C::C1 c1;
+.Lint:
+ .byte 9 # Abbrev [9] DW_TAG_base_type
+ .asciz "int" # DW_AT_name
+ .byte 5 # DW_AT_encoding
+ .byte 4 # DW_AT_byte_size
+ .byte 3 # Abbrev [3] DW_TAG_structure_type
+ .asciz "C" # DW_AT_name
+ # DW_AT_declaration
+.LC1:
+ .byte 12 # Abbrev [12] DW_TAG_typedef
+ .long .Lint-.Lcu_begin0 # DW_AT_type
+ .asciz "C1" # DW_AT_name
+ .byte 0 # End Of Children Mark
+
+ .byte 2 # Abbrev [2] DW_TAG_variable
+ .asciz "c1" # DW_AT_name
+ .long .LC1-.Lcu_begin0 # DW_AT_type
+ .byte 9 # DW_AT_location
+ .byte 3
+ .quad c1
+
.byte 0 # End Of Children Mark
.Ldebug_info_end0:
More information about the lldb-commits
mailing list