[Lldb-commits] [PATCH] D103172: [lldb][NFC] Allow range-based for loops over DWARFDIE's children
wallace added a comment. I found the issue: https://reviews.llvm.org/D107434 Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D103172/new/ https://reviews.llvm.org/D103172 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D103172: [lldb][NFC] Allow range-based for loops over DWARFDIE's children
wallace added subscribers: clayborg, wallace. wallace added a comment. This breaks debugging in many cases :( Many of my users started reporting crashes in LLDB when setting source line breakpoints. For example, a simple command like `(lldb) b TransAttr.cpp:758` causes a crash and has the following stack trace thread #1, name = 'lldb', stop reason = signal SIGSEGV: invalid address (fault address: 0x10) * frame #0: 0x7f1c2b642caa liblldb.so.14`DWARFUnit::GetSymbolFileDWARF(this=0x) const at DWARFUnit.h:194:56 frame #1: 0x7f1c2bd46ce4 liblldb.so.14`SymbolFileDWARF::GetTypeSystem(unit=0x) at SymbolFileDWARF.cpp:3880:15 frame #2: 0x7f1c2bd3b29b liblldb.so.14`SymbolFileDWARF::GetDWARFParser(unit=0x) at SymbolFileDWARF.cpp:3884:29 frame #3: 0x7f1c2bd8cb87 liblldb.so.14`DWARFASTParserClang::CopyUniqueClassMethodTypes(this=0x01eaa920, src_class_die=0x7ffe9ff0ff38, dst_class_die=0x7ffe9ff0fe48, class_type=0x01d42c10, failures=size=0) at DWARFASTParserClang.cpp:3572:11 frame #4: 0x7f1c2bd891fd liblldb.so.14`DWARFASTParserClang::ParseSubroutine(this=0x01eaa920, die=0x7ffe9ff10778, attrs=0x7ffe9ff101b0) at DWARFASTParserClang.cpp:1025:15 frame #5: 0x7f1c2bd85080 liblldb.so.14`DWARFASTParserClang::ParseTypeFromDWARF(this=0x01eaa920, sc=0x7ffe9ff105d0, die=0x7ffe9ff10778, type_is_new_ptr=0x) at DWARFASTParserClang.cpp:522:15 frame #6: 0x7f1c2bd401fb liblldb.so.14`SymbolFileDWARF::ParseType(this=0x004610a0, sc=0x7ffe9ff105d0, die=0x7ffe9ff10778, type_is_new_ptr=0x) at SymbolFileDWARF.cpp:2946:31 frame #7: 0x7f1c2bd3b70f liblldb.so.14`SymbolFileDWARF::GetTypeForDIE(this=0x004610a0, die=0x7ffe9ff10778, resolve_function_context=false) at SymbolFileDWARF.cpp:2560:17 frame #8: 0x7f1c2bd3a4bd liblldb.so.14`SymbolFileDWARF::ResolveType(this=0x004610a0, die=0x7ffe9ff10778, assert_not_being_parsed=true, resolve_function_context=false) at SymbolFileDWARF.cpp:1568:18 frame #9: 0x7f1c2bd17500 liblldb.so.14`DWARFDIE::ResolveType(this=0x7ffe9ff10778) const at DWARFDIE.cpp:350:24 frame #10: 0x7f1c2bd3a365 liblldb.so.14`SymbolFileDWARF::ResolveTypeUID(this=0x004610a0, type_uid=57283337) at SymbolFileDWARF.cpp:1437:21 frame #11: 0x7f1c2b73037e liblldb.so.14`lldb_private::Function::GetType(this=0x01cd5ed0) at Function.cpp:515:24 frame #12: 0x7f1c2b73017a liblldb.so.14`lldb_private::Function::GetStartLineSourceInfo(this=0x01cd5ed0, source_file=0x7ffe9ff109e0, line_no=0x7ffe9ff109dc) at Function.cpp:252:3 frame #13: 0x7f1c2b515a5e liblldb.so.14`lldb_private::BreakpointResolverFileLine::FilterContexts(this=0x01f61c00, sc_list=0x7ffe9ff10d00, is_relative=true) at BreakpointResolverFileLine.cpp:162:20 frame #14: 0x7f1c2b5163d3 liblldb.so.14`lldb_private::BreakpointResolverFileLine::SearchCallback(this=0x01f61c00, filter=0x01fab770, context=0x7ffe9ff10d68, addr=0x) at BreakpointResolverFileLine.cpp:254:3 frame #15: 0x7f1c2b5cae2a liblldb.so.14`lldb_private::SearchFilter::DoModuleIteration(this=0x01fab770, context=0x7ffe9ff10f28, searcher=0x01f61c00) at SearchFilter.cpp:271:20 frame #16: 0x7f1c2b5cabb9 liblldb.so.14`lldb_private::SearchFilter::Search(this=0x01fab770, searcher=0x01f61c00) at SearchFilter.cpp:216:3 frame #17: 0x7f1c2b50c24e liblldb.so.14`lldb_private::BreakpointResolver::ResolveBreakpoint(this=0x01f61c00, filter=0x01fab770) at BreakpointResolver.cpp:177:10 frame #18: 0x7f1c2b4e93e6 liblldb.so.14`lldb_private::Breakpoint::ResolveBreakpoint(this=0x003c76d0) at Breakpoint.cpp:443:20 frame #19: 0x7f1c2b851596 liblldb.so.14`lldb_private::Target::AddBreakpoint(this=0x0044dad0, bp_sp=std::__shared_ptr::element_type @ 0x003c76d0, internal=false) at Target.cpp:662:10 frame #20: 0x7f1c2b852f64 liblldb.so.14`lldb_private::Target::CreateBreakpoint(this=0x0044dad0, filter_sp=std::__shared_ptr::element_type @ 0x01fab770, resolver_sp=std::__shared_ptr::element_type @ 0x01f61c00, internal=false, request_hardware=false, resolve_indirect_symbols=true) at Target.cpp:641:5 frame #21: 0x7f1c2b85342f liblldb.so.14`lldb_private::Target::CreateBreakpoint(this=0x0044dad0, containingModules=0x00348b80, file=0x7ffe9ff11768, line_no=758, column=0, offset=0, check_inlines=eLazyBoolYes, skip_prologue=eLazyBoolYes, internal=false, hardware=false, move_to_nearest_code=eLazyBoolYes) at Target.cpp:384:10 frame #22: 0x7f1c2d6895f0 liblldb.so.14`CommandObjectBreakpointSet::DoExecute(this=0x00348750,
[Lldb-commits] [PATCH] D103172: [lldb][NFC] Allow range-based for loops over DWARFDIE's children
dblaikie added inline comments. Comment at: lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h:97-105 + template + llvm::iterator_range children() const { +return llvm::make_range(T(*this), T()); + } +}; + +class DWARFDIE::child_iterator rather than a temeplate, what if it were code something like this: https://godbolt.org/z/3abeK3EPx ? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D103172/new/ https://reviews.llvm.org/D103172 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D103172: [lldb][NFC] Allow range-based for loops over DWARFDIE's children
This revision was landed with ongoing or failed builds. This revision was automatically updated to reflect the committed changes. Closed by commit rG77440d644b3b: [lldb][NFC] Allow range-based for loops over DWARFDIEs children (authored by teemperor). Herald added a subscriber: lldb-commits. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D103172/new/ https://reviews.llvm.org/D103172 Files: lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp lldb/unittests/SymbolFile/DWARF/CMakeLists.txt lldb/unittests/SymbolFile/DWARF/DWARFDIETest.cpp Index: lldb/unittests/SymbolFile/DWARF/DWARFDIETest.cpp === --- /dev/null +++ lldb/unittests/SymbolFile/DWARF/DWARFDIETest.cpp @@ -0,0 +1,105 @@ +//===-- DWARFDIETest.cpp --=---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "Plugins/SymbolFile/DWARF/DWARFDIE.h" +#include "TestingSupport/Symbol/YAMLModuleTester.h" +#include "llvm/ADT/STLExtras.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +using namespace lldb; +using namespace lldb_private; + +TEST(DWARFDIETest, ChildIteration) { + // Tests DWARFDIE::child_iterator. + + const char *yamldata = R"( +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data:ELFDATA2LSB + Type:ET_EXEC + Machine: EM_386 +DWARF: + debug_abbrev: +- Table: +- Code:0x0001 + Tag: DW_TAG_compile_unit + Children:DW_CHILDREN_yes + Attributes: +- Attribute: DW_AT_language + Form:DW_FORM_data2 +- Code:0x0002 + Tag: DW_TAG_base_type + Children:DW_CHILDREN_no + Attributes: +- Attribute: DW_AT_encoding + Form:DW_FORM_data1 +- Attribute: DW_AT_byte_size + Form:DW_FORM_data1 + debug_info: +- Version: 4 + AddrSize:8 + Entries: +- AbbrCode:0x0001 + Values: +- Value: 0x000C +- AbbrCode:0x0002 + Values: +- Value: 0x0007 # DW_ATE_unsigned +- Value: 0x0004 +- AbbrCode:0x0002 + Values: +- Value: 0x0007 # DW_ATE_unsigned +- Value: 0x0008 +- AbbrCode:0x0002 + Values: +- Value: 0x0005 # DW_ATE_signed +- Value: 0x0008 +- AbbrCode:0x +)"; + + YAMLModuleTester t(yamldata); + ASSERT_TRUE((bool)t.GetDwarfUnit()); + + DWARFUnit *unit = t.GetDwarfUnit(); + const DWARFDebugInfoEntry *die_first = unit->DIE().GetDIE(); + + // Create a DWARFDIE that has three DW_TAG_base_type children. + DWARFDIE top_die(unit, die_first); + + // Create the iterator range that has the three tags as elements. + llvm::iterator_range children = top_die.children(); + + // Compare begin() to the first child DIE. + DWARFDIE::child_iterator child_iter = children.begin(); + ASSERT_NE(child_iter, children.end()); + const DWARFDebugInfoEntry *die_child0 = die_first->GetFirstChild(); + EXPECT_EQ((*child_iter).GetDIE(), die_child0); + + // Step to the second child DIE. + ++child_iter; + ASSERT_NE(child_iter, children.end()); + const DWARFDebugInfoEntry *die_child1 = die_child0->GetSibling(); + EXPECT_EQ((*child_iter).GetDIE(), die_child1); + + // Step to the third child DIE. + ++child_iter; + ASSERT_NE(child_iter, children.end()); + const DWARFDebugInfoEntry *die_child2 = die_child1->GetSibling(); + EXPECT_EQ((*child_iter).GetDIE(), die_child2); + + // Step to the end of the range. + ++child_iter; + EXPECT_EQ(child_iter, children.end()); + + // Take one of the DW_TAG_base_type DIEs (which has no children) and make + // sure the children range is now empty. + DWARFDIE no_children_die(unit, die_child0); + EXPECT_TRUE(no_children_die.children().empty()); +} Index: lldb/unittests/SymbolFile/DWARF/CMakeLists.txt === --- lldb/unittests/SymbolFile/DWARF/CMakeLists.txt +++ lldb/unittests/SymbolFile/DWARF/CMakeLists.txt @@ -1,5 +1,6 @@ add_lldb_unittest(SymbolFileDWARFTests DWARFASTParserClangTests.cpp + DWARFDIETest.cpp DWARFUnitTest.cpp
[Lldb-commits] [PATCH] D103172: [lldb][NFC] Allow range-based for loops over DWARFDIE's children
JDevlieghere accepted this revision. JDevlieghere added a comment. LGTM CHANGES SINCE LAST ACTION https://reviews.llvm.org/D103172/new/ https://reviews.llvm.org/D103172 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D103172: [lldb][NFC] Allow range-based for loops over DWARFDIE's children
teemperor added a comment. ping. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D103172/new/ https://reviews.llvm.org/D103172 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D103172: [lldb][NFC] Allow range-based for loops over DWARFDIE's children
teemperor added inline comments. Comment at: lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h:117 +// (CU, (DIE)nullptr) == (nullptr, nullptr) -> true +if (!m_die.IsValid() && !it.m_die.IsValid()) + return true; shafik wrote: > I think: > > ``` > bool operator==(const DWARFBaseDIE , const DWARFBaseDIE ) { > return lhs.GetDIE() == rhs.GetDIE() && lhs.GetCU() == rhs.GetCU(); > } > ``` > > will do the same thing but maybe I am confused. > > Maybe we should have a unit test? That's the `DWARFDIE::operator==` implementation called below and this special case is because of the comment one line above (we need to match the end iterator if it's default constructed when `GetSibling()` returns a DWARFDIE that has a valid CU but a `null` DIE). CHANGES SINCE LAST ACTION https://reviews.llvm.org/D103172/new/ https://reviews.llvm.org/D103172 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D103172: [lldb][NFC] Allow range-based for loops over DWARFDIE's children
teemperor updated this revision to Diff 352666. teemperor added a comment. Herald added a subscriber: mgorny. - Added a unit test (thanks Shafik!) CHANGES SINCE LAST ACTION https://reviews.llvm.org/D103172/new/ https://reviews.llvm.org/D103172 Files: lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp lldb/unittests/SymbolFile/DWARF/CMakeLists.txt lldb/unittests/SymbolFile/DWARF/DWARFDIETest.cpp Index: lldb/unittests/SymbolFile/DWARF/DWARFDIETest.cpp === --- /dev/null +++ lldb/unittests/SymbolFile/DWARF/DWARFDIETest.cpp @@ -0,0 +1,105 @@ +//===-- DWARFDIETest.cpp --=---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "Plugins/SymbolFile/DWARF/DWARFDIE.h" +#include "TestingSupport/Symbol/YAMLModuleTester.h" +#include "llvm/ADT/STLExtras.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +using namespace lldb; +using namespace lldb_private; + +TEST(DWARFDIETest, ChildIteration) { + // Tests DWARFDIE::child_iterator. + + const char *yamldata = R"( +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data:ELFDATA2LSB + Type:ET_EXEC + Machine: EM_386 +DWARF: + debug_abbrev: +- Table: +- Code:0x0001 + Tag: DW_TAG_compile_unit + Children:DW_CHILDREN_yes + Attributes: +- Attribute: DW_AT_language + Form:DW_FORM_data2 +- Code:0x0002 + Tag: DW_TAG_base_type + Children:DW_CHILDREN_no + Attributes: +- Attribute: DW_AT_encoding + Form:DW_FORM_data1 +- Attribute: DW_AT_byte_size + Form:DW_FORM_data1 + debug_info: +- Version: 4 + AddrSize:8 + Entries: +- AbbrCode:0x0001 + Values: +- Value: 0x000C +- AbbrCode:0x0002 + Values: +- Value: 0x0007 # DW_ATE_unsigned +- Value: 0x0004 +- AbbrCode:0x0002 + Values: +- Value: 0x0007 # DW_ATE_unsigned +- Value: 0x0008 +- AbbrCode:0x0002 + Values: +- Value: 0x0005 # DW_ATE_signed +- Value: 0x0008 +- AbbrCode:0x +)"; + + YAMLModuleTester t(yamldata); + ASSERT_TRUE((bool)t.GetDwarfUnit()); + + DWARFUnit *unit = t.GetDwarfUnit(); + const DWARFDebugInfoEntry *die_first = unit->DIE().GetDIE(); + + // Create a DWARFDIE that has three DW_TAG_base_type children. + DWARFDIE top_die(unit, die_first); + + // Create the iterator range that has the three tags as elements. + llvm::iterator_range children = top_die.children(); + + // Compare begin() to the first child DIE. + DWARFDIE::child_iterator child_iter = children.begin(); + ASSERT_NE(child_iter, children.end()); + const DWARFDebugInfoEntry *die_child0 = die_first->GetFirstChild(); + EXPECT_EQ((*child_iter).GetDIE(), die_child0); + + // Step to the second child DIE. + ++child_iter; + ASSERT_NE(child_iter, children.end()); + const DWARFDebugInfoEntry *die_child1 = die_child0->GetSibling(); + EXPECT_EQ((*child_iter).GetDIE(), die_child1); + + // Step to the third child DIE. + ++child_iter; + ASSERT_NE(child_iter, children.end()); + const DWARFDebugInfoEntry *die_child2 = die_child1->GetSibling(); + EXPECT_EQ((*child_iter).GetDIE(), die_child2); + + // Step to the end of the range. + ++child_iter; + EXPECT_EQ(child_iter, children.end()); + + // Take one of the DW_TAG_base_type DIEs (which has no children) and make + // sure the children range is now empty. + DWARFDIE no_children_die(unit, die_child0); + EXPECT_TRUE(no_children_die.children().empty()); +} Index: lldb/unittests/SymbolFile/DWARF/CMakeLists.txt === --- lldb/unittests/SymbolFile/DWARF/CMakeLists.txt +++ lldb/unittests/SymbolFile/DWARF/CMakeLists.txt @@ -1,5 +1,6 @@ add_lldb_unittest(SymbolFileDWARFTests DWARFASTParserClangTests.cpp + DWARFDIETest.cpp DWARFUnitTest.cpp SymbolFileDWARFTests.cpp XcodeSDKModuleTests.cpp Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp ===
[Lldb-commits] [PATCH] D103172: [lldb][NFC] Allow range-based for loops over DWARFDIE's children
shafik added inline comments. Comment at: lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h:117 +// (CU, (DIE)nullptr) == (nullptr, nullptr) -> true +if (!m_die.IsValid() && !it.m_die.IsValid()) + return true; I think: ``` bool operator==(const DWARFBaseDIE , const DWARFBaseDIE ) { return lhs.GetDIE() == rhs.GetDIE() && lhs.GetCU() == rhs.GetCU(); } ``` will do the same thing but maybe I am confused. Maybe we should have a unit test? CHANGES SINCE LAST ACTION https://reviews.llvm.org/D103172/new/ https://reviews.llvm.org/D103172 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D103172: [lldb][NFC] Allow range-based for loops over DWARFDIE's children
teemperor created this revision. teemperor added a reviewer: LLDB. teemperor added a project: LLDB. Herald added a subscriber: JDevlieghere. Herald added a reviewer: shafik. teemperor requested review of this revision. This patch adds the ability to get a DWARFDIE's children as an LLVM range. This way we can use for range loops to iterate over them and we can use LLVM's algorithms like `llvm::all_of` to query all children. The implementation has to do some small shenanigans as the iterator needs to store a DWARFDIE, but a DWARFDIE container is also a DWARFDIE so it can't return the iterator by value. I just made the `children` getter a templated function to avoid the cyclic dependency. https://reviews.llvm.org/D103172 Files: lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h 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 @@ -360,8 +360,7 @@ } } -for (DWARFDIE child_die = die.GetFirstChild(); child_die.IsValid(); - child_die = child_die.GetSibling()) { +for (DWARFDIE child_die : die.children()) { GetTypes(child_die, min_die_offset, max_die_offset, type_mask, type_set); } } @@ -985,8 +984,7 @@ if (!die) return false; - for (DWARFDIE child_die = die.GetFirstChild(); child_die; - child_die = child_die.GetSibling()) { + for (DWARFDIE child_die : die.children()) { if (child_die.Tag() != DW_TAG_imported_declaration) continue; @@ -1245,8 +1243,7 @@ bool SymbolFileDWARF::ClassOrStructIsVirtual(const DWARFDIE _die) { if (parent_die) { -for (DWARFDIE die = parent_die.GetFirstChild(); die; - die = die.GetSibling()) { +for (DWARFDIE die : parent_die.children()) { dw_tag_t tag = die.Tag(); bool check_virtuality = false; switch (tag) { @@ -3419,8 +3416,7 @@ // Give the concrete function die specified by "func_die_offset", find the // concrete block whose DW_AT_specification or DW_AT_abstract_origin points // to "spec_block_die_offset" -for (DWARFDIE child_die = die.GetFirstChild(); child_die; - child_die = child_die.GetSibling()) { +for (DWARFDIE child_die : die.children()) { DWARFDIE result_die = FindBlockContainingSpecification(child_die, spec_block_die_offset); if (result_die) @@ -3549,8 +3545,7 @@ static CallSiteParameterArray CollectCallSiteParameters(ModuleSP module, DWARFDIE call_site_die) { CallSiteParameterArray parameters; - for (DWARFDIE child = call_site_die.GetFirstChild(); child.IsValid(); - child = child.GetSibling()) { + for (DWARFDIE child : call_site_die.children()) { if (child.Tag() != DW_TAG_call_site_parameter && child.Tag() != DW_TAG_GNU_call_site_parameter) continue; @@ -3615,8 +3610,7 @@ // For now, assume that all entries are nested directly under the subprogram // (this is the kind of DWARF LLVM produces) and parse them eagerly. std::vector> call_edges; - for (DWARFDIE child = function_die.GetFirstChild(); child.IsValid(); - child = child.GetSibling()) { + for (DWARFDIE child : function_die.children()) { if (child.Tag() != DW_TAG_call_site && child.Tag() != DW_TAG_GNU_call_site) continue; Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h === --- lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h @@ -11,9 +11,11 @@ #include "DWARFBaseDIE.h" #include "llvm/ADT/SmallSet.h" +#include "llvm/ADT/iterator_range.h" class DWARFDIE : public DWARFBaseDIE { public: + class child_iterator; using DWARFBaseDIE::DWARFBaseDIE; // Tests @@ -88,6 +90,47 @@ int _line, int _column, int _file, int _line, int _column, lldb_private::DWARFExpression *frame_base) const; + /// The range of all the children of this DIE. + /// + /// This is a template just because child_iterator is not completely defined + /// at this point. + template + llvm::iterator_range children() const { +return llvm::make_range(T(*this), T()); + } +}; + +class DWARFDIE::child_iterator +: public llvm::iterator_facade_base { + /// The current child or an invalid DWARFDie. + DWARFDIE m_die; + +public: + child_iterator() = default; + child_iterator(const DWARFDIE ) : m_die(parent.GetFirstChild()) {} + bool operator==(const child_iterator ) const { +// DWARFDIE's operator== differentiates between an invalid DWARFDIE that +// has a CU but no DIE and one that has neither CU nor DIE. The 'end' +