diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -556,42 +556,51 @@ 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 --- 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 @@ # 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 @@ b1: .quad 0xbaadf00d +c1: + .long 42474247 .section .debug_abbrev,"",@progbits .byte 1 # Abbreviation Code @@ -118,6 +127,17 @@ .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 @@ .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,"",@progbits .Lcu_begin0: @@ -222,7 +251,6 @@ .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 @@ .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: