krisb created this revision. krisb added reviewers: jingham, aprantl, JDevlieghere. Herald added a subscriber: pengfei. krisb requested review of this revision. Herald added a project: LLDB. Herald added a subscriber: lldb-commits.
D113741 <https://reviews.llvm.org/D113741> and D113743 <https://reviews.llvm.org/D113743> makes types defined in a lexical (bracketed) block correctly scoped within this block, which reveals a lack of support of such a case in lldb. Consider the following example: * thread #1, name = 'a.out', stop reason = step over frame #0: 0x000000000040111d a.out`foo(a=1) at test_lldb.cpp:5:12 1 int foo(int a) { 2 { 3 typedef int Int; 4 Int local = a; -> 5 return local; 6 } 7 } 8 (lldb) p local error: expression failed to parse: error: <lldb wrapper prefix>:45:31: no member named 'local' in namespace '$__lldb_local_vars' using $__lldb_local_vars::local; ~~~~~~~~~~~~~~~~~~~~^ error: <user expression 0>:1:1: use of undeclared identifier 'local' local ^ lldb failed to find 'local' variable typed with a lexical block defined type (typedef Int). The immediate cause of this issue is that clang failed to import this typedef: lldb (x86_64) a.out: DWARFASTParserClang::ParseTypeFromDWARF (die = 0x00000070, decl_ctx = 0x2509cb0 (die 0x00000055)) DW_TAG_typedef name = 'Int') lldb (x86_64) a.out: SymbolFileDWARF::ResolveTypeUID (die = 0x00000070) DW_TAG_typedef 'Int' lldb (x86_64) a.out: SymbolFileDWARF::ResolveTypeUID (die = 0x00000096) DW_TAG_base_type 'int' lldb Compiler diagnostic: lldb Couldn't import type: UnsupportedConstruct lldb Couldn't copy a variable's type into the parser's AST context The importing wasn't success because clang wasn't able to import typedef's context, which is actually a BlockDecl (import for BlockDecl isn't implemented, but this is still a question to me why DW_TAG_lexical_block is associated with a BlockDecl). This workaround makes everything behaves as it was before D113741 <https://reviews.llvm.org/D113741> / D113743 <https://reviews.llvm.org/D113743>. While looking for a context for a type-like entity scoped within a lexical block, GetDeclContextDIEContainingDIE() will return a DeclContext of a parent subprogram, instead of a BlockDecl. Despite the patch doesn't fix the issue properly, looks like a step forward to me as lldb at least may now properly display variables of such types, which may appear in the DWARF generated by other compilers (gcc as an example). Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D115277 Files: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -2616,9 +2616,27 @@ case DW_TAG_structure_type: case DW_TAG_union_type: case DW_TAG_class_type: - case DW_TAG_lexical_block: case DW_TAG_subprogram: return die; + case DW_TAG_lexical_block: { + if (orig_die.Tag() != DW_TAG_structure_type && + orig_die.Tag() != DW_TAG_union_type && + orig_die.Tag() != DW_TAG_class_type && + orig_die.Tag() != DW_TAG_enumeration_type && + orig_die.Tag() != DW_TAG_typedef) + return die; + // Make local type's context to be a subprogram. + // FIXME: DWARFASTParserClang doesn't properly support type-like + // entities scoped within a lexical block. This workaround makes + // it possible to correctly display variables that have such a type, + // but lldb still isn't able to handle properly handle more than one + // local type with the same name. + while (true) { + die = die.GetParent(); + if (die.Tag() == DW_TAG_subprogram) + return die; + } + } case DW_TAG_inlined_subroutine: { DWARFDIE abs_die = die.GetReferencedDIE(DW_AT_abstract_origin); if (abs_die) {
Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -2616,9 +2616,27 @@ case DW_TAG_structure_type: case DW_TAG_union_type: case DW_TAG_class_type: - case DW_TAG_lexical_block: case DW_TAG_subprogram: return die; + case DW_TAG_lexical_block: { + if (orig_die.Tag() != DW_TAG_structure_type && + orig_die.Tag() != DW_TAG_union_type && + orig_die.Tag() != DW_TAG_class_type && + orig_die.Tag() != DW_TAG_enumeration_type && + orig_die.Tag() != DW_TAG_typedef) + return die; + // Make local type's context to be a subprogram. + // FIXME: DWARFASTParserClang doesn't properly support type-like + // entities scoped within a lexical block. This workaround makes + // it possible to correctly display variables that have such a type, + // but lldb still isn't able to handle properly handle more than one + // local type with the same name. + while (true) { + die = die.GetParent(); + if (die.Tag() == DW_TAG_subprogram) + return die; + } + } case DW_TAG_inlined_subroutine: { DWARFDIE abs_die = die.GetReferencedDIE(DW_AT_abstract_origin); if (abs_die) {
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits