15ffd83dbSDimitry Andric //===-- DWARFDIE.cpp ------------------------------------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "DWARFDIE.h" 100b57cec5SDimitry Andric 110b57cec5SDimitry Andric #include "DWARFASTParser.h" 120b57cec5SDimitry Andric #include "DWARFDebugInfo.h" 130b57cec5SDimitry Andric #include "DWARFDebugInfoEntry.h" 140b57cec5SDimitry Andric #include "DWARFDeclContext.h" 150b57cec5SDimitry Andric #include "DWARFUnit.h" 160b57cec5SDimitry Andric 170b57cec5SDimitry Andric using namespace lldb_private; 180b57cec5SDimitry Andric 190b57cec5SDimitry Andric namespace { 200b57cec5SDimitry Andric 210b57cec5SDimitry Andric /// Iterate through all DIEs elaborating (i.e. reachable by a chain of 220b57cec5SDimitry Andric /// DW_AT_specification and DW_AT_abstract_origin attributes) a given DIE. For 230b57cec5SDimitry Andric /// convenience, the starting die is included in the sequence as the first 240b57cec5SDimitry Andric /// item. 250b57cec5SDimitry Andric class ElaboratingDIEIterator 260b57cec5SDimitry Andric : public std::iterator<std::input_iterator_tag, DWARFDIE> { 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric // The operating invariant is: top of m_worklist contains the "current" item 290b57cec5SDimitry Andric // and the rest of the list are items yet to be visited. An empty worklist 300b57cec5SDimitry Andric // means we've reached the end. 310b57cec5SDimitry Andric // Infinite recursion is prevented by maintaining a list of seen DIEs. 320b57cec5SDimitry Andric // Container sizes are optimized for the case of following DW_AT_specification 330b57cec5SDimitry Andric // and DW_AT_abstract_origin just once. 340b57cec5SDimitry Andric llvm::SmallVector<DWARFDIE, 2> m_worklist; 355ffd83dbSDimitry Andric llvm::SmallSet<DWARFDebugInfoEntry *, 3> m_seen; 360b57cec5SDimitry Andric 370b57cec5SDimitry Andric void Next() { 380b57cec5SDimitry Andric assert(!m_worklist.empty() && "Incrementing end iterator?"); 390b57cec5SDimitry Andric 400b57cec5SDimitry Andric // Pop the current item from the list. 410b57cec5SDimitry Andric DWARFDIE die = m_worklist.back(); 420b57cec5SDimitry Andric m_worklist.pop_back(); 430b57cec5SDimitry Andric 440b57cec5SDimitry Andric // And add back any items that elaborate it. 450b57cec5SDimitry Andric for (dw_attr_t attr : {DW_AT_specification, DW_AT_abstract_origin}) { 460b57cec5SDimitry Andric if (DWARFDIE d = die.GetReferencedDIE(attr)) 475ffd83dbSDimitry Andric if (m_seen.insert(die.GetDIE()).second) 480b57cec5SDimitry Andric m_worklist.push_back(d); 490b57cec5SDimitry Andric } 500b57cec5SDimitry Andric } 510b57cec5SDimitry Andric 520b57cec5SDimitry Andric public: 530b57cec5SDimitry Andric /// An iterator starting at die d. 540b57cec5SDimitry Andric explicit ElaboratingDIEIterator(DWARFDIE d) : m_worklist(1, d) {} 550b57cec5SDimitry Andric 560b57cec5SDimitry Andric /// End marker 570b57cec5SDimitry Andric ElaboratingDIEIterator() {} 580b57cec5SDimitry Andric 590b57cec5SDimitry Andric const DWARFDIE &operator*() const { return m_worklist.back(); } 600b57cec5SDimitry Andric ElaboratingDIEIterator &operator++() { 610b57cec5SDimitry Andric Next(); 620b57cec5SDimitry Andric return *this; 630b57cec5SDimitry Andric } 640b57cec5SDimitry Andric ElaboratingDIEIterator operator++(int) { 650b57cec5SDimitry Andric ElaboratingDIEIterator I = *this; 660b57cec5SDimitry Andric Next(); 670b57cec5SDimitry Andric return I; 680b57cec5SDimitry Andric } 690b57cec5SDimitry Andric 700b57cec5SDimitry Andric friend bool operator==(const ElaboratingDIEIterator &a, 710b57cec5SDimitry Andric const ElaboratingDIEIterator &b) { 720b57cec5SDimitry Andric if (a.m_worklist.empty() || b.m_worklist.empty()) 730b57cec5SDimitry Andric return a.m_worklist.empty() == b.m_worklist.empty(); 740b57cec5SDimitry Andric return a.m_worklist.back() == b.m_worklist.back(); 750b57cec5SDimitry Andric } 760b57cec5SDimitry Andric friend bool operator!=(const ElaboratingDIEIterator &a, 770b57cec5SDimitry Andric const ElaboratingDIEIterator &b) { 780b57cec5SDimitry Andric return !(a == b); 790b57cec5SDimitry Andric } 800b57cec5SDimitry Andric }; 810b57cec5SDimitry Andric 820b57cec5SDimitry Andric llvm::iterator_range<ElaboratingDIEIterator> 830b57cec5SDimitry Andric elaborating_dies(const DWARFDIE &die) { 840b57cec5SDimitry Andric return llvm::make_range(ElaboratingDIEIterator(die), 850b57cec5SDimitry Andric ElaboratingDIEIterator()); 860b57cec5SDimitry Andric } 870b57cec5SDimitry Andric } // namespace 880b57cec5SDimitry Andric 890b57cec5SDimitry Andric DWARFDIE 900b57cec5SDimitry Andric DWARFDIE::GetParent() const { 910b57cec5SDimitry Andric if (IsValid()) 920b57cec5SDimitry Andric return DWARFDIE(m_cu, m_die->GetParent()); 930b57cec5SDimitry Andric else 940b57cec5SDimitry Andric return DWARFDIE(); 950b57cec5SDimitry Andric } 960b57cec5SDimitry Andric 970b57cec5SDimitry Andric DWARFDIE 980b57cec5SDimitry Andric DWARFDIE::GetFirstChild() const { 990b57cec5SDimitry Andric if (IsValid()) 1000b57cec5SDimitry Andric return DWARFDIE(m_cu, m_die->GetFirstChild()); 1010b57cec5SDimitry Andric else 1020b57cec5SDimitry Andric return DWARFDIE(); 1030b57cec5SDimitry Andric } 1040b57cec5SDimitry Andric 1050b57cec5SDimitry Andric DWARFDIE 1060b57cec5SDimitry Andric DWARFDIE::GetSibling() const { 1070b57cec5SDimitry Andric if (IsValid()) 1080b57cec5SDimitry Andric return DWARFDIE(m_cu, m_die->GetSibling()); 1090b57cec5SDimitry Andric else 1100b57cec5SDimitry Andric return DWARFDIE(); 1110b57cec5SDimitry Andric } 1120b57cec5SDimitry Andric 1130b57cec5SDimitry Andric DWARFDIE 1140b57cec5SDimitry Andric DWARFDIE::GetReferencedDIE(const dw_attr_t attr) const { 1150b57cec5SDimitry Andric if (IsValid()) 1160b57cec5SDimitry Andric return m_die->GetAttributeValueAsReference(GetCU(), attr); 1170b57cec5SDimitry Andric else 1180b57cec5SDimitry Andric return {}; 1190b57cec5SDimitry Andric } 1200b57cec5SDimitry Andric 1210b57cec5SDimitry Andric DWARFDIE 1220b57cec5SDimitry Andric DWARFDIE::GetDIE(dw_offset_t die_offset) const { 1230b57cec5SDimitry Andric if (IsValid()) 1240b57cec5SDimitry Andric return m_cu->GetDIE(die_offset); 1250b57cec5SDimitry Andric else 1260b57cec5SDimitry Andric return DWARFDIE(); 1270b57cec5SDimitry Andric } 1280b57cec5SDimitry Andric 1290b57cec5SDimitry Andric DWARFDIE 1300b57cec5SDimitry Andric DWARFDIE::GetAttributeValueAsReferenceDIE(const dw_attr_t attr) const { 1310b57cec5SDimitry Andric if (IsValid()) { 1320b57cec5SDimitry Andric DWARFUnit *cu = GetCU(); 1330b57cec5SDimitry Andric const bool check_specification_or_abstract_origin = true; 1340b57cec5SDimitry Andric DWARFFormValue form_value; 1350b57cec5SDimitry Andric if (m_die->GetAttributeValue(cu, attr, form_value, nullptr, 1360b57cec5SDimitry Andric check_specification_or_abstract_origin)) 1370b57cec5SDimitry Andric return form_value.Reference(); 1380b57cec5SDimitry Andric } 1390b57cec5SDimitry Andric return DWARFDIE(); 1400b57cec5SDimitry Andric } 1410b57cec5SDimitry Andric 1420b57cec5SDimitry Andric DWARFDIE 1435ffd83dbSDimitry Andric DWARFDIE::LookupDeepestBlock(lldb::addr_t address) const { 1445ffd83dbSDimitry Andric if (!IsValid()) 1450b57cec5SDimitry Andric return DWARFDIE(); 1465ffd83dbSDimitry Andric 1475ffd83dbSDimitry Andric DWARFDIE result; 1485ffd83dbSDimitry Andric bool check_children = false; 1495ffd83dbSDimitry Andric bool match_addr_range = false; 1505ffd83dbSDimitry Andric switch (Tag()) { 1515ffd83dbSDimitry Andric case DW_TAG_class_type: 1525ffd83dbSDimitry Andric case DW_TAG_namespace: 1535ffd83dbSDimitry Andric case DW_TAG_structure_type: 1545ffd83dbSDimitry Andric case DW_TAG_common_block: 1555ffd83dbSDimitry Andric check_children = true; 1565ffd83dbSDimitry Andric break; 1575ffd83dbSDimitry Andric case DW_TAG_compile_unit: 1585ffd83dbSDimitry Andric case DW_TAG_module: 1595ffd83dbSDimitry Andric case DW_TAG_catch_block: 1605ffd83dbSDimitry Andric case DW_TAG_subprogram: 1615ffd83dbSDimitry Andric case DW_TAG_try_block: 1625ffd83dbSDimitry Andric case DW_TAG_partial_unit: 1635ffd83dbSDimitry Andric match_addr_range = true; 1645ffd83dbSDimitry Andric break; 1655ffd83dbSDimitry Andric case DW_TAG_lexical_block: 1665ffd83dbSDimitry Andric case DW_TAG_inlined_subroutine: 1675ffd83dbSDimitry Andric check_children = true; 1685ffd83dbSDimitry Andric match_addr_range = true; 1695ffd83dbSDimitry Andric break; 1705ffd83dbSDimitry Andric default: 1715ffd83dbSDimitry Andric break; 1725ffd83dbSDimitry Andric } 1735ffd83dbSDimitry Andric 1745ffd83dbSDimitry Andric if (match_addr_range) { 1755ffd83dbSDimitry Andric DWARFRangeList ranges; 1765ffd83dbSDimitry Andric if (m_die->GetAttributeAddressRanges(m_cu, ranges, 1775ffd83dbSDimitry Andric /*check_hi_lo_pc=*/true) && 1785ffd83dbSDimitry Andric ranges.FindEntryThatContains(address)) { 1795ffd83dbSDimitry Andric check_children = true; 1805ffd83dbSDimitry Andric switch (Tag()) { 1815ffd83dbSDimitry Andric default: 1825ffd83dbSDimitry Andric break; 1835ffd83dbSDimitry Andric 1845ffd83dbSDimitry Andric case DW_TAG_inlined_subroutine: // Inlined Function 1855ffd83dbSDimitry Andric case DW_TAG_lexical_block: // Block { } in code 1865ffd83dbSDimitry Andric result = *this; 1875ffd83dbSDimitry Andric break; 1885ffd83dbSDimitry Andric } 1895ffd83dbSDimitry Andric } else { 1905ffd83dbSDimitry Andric check_children = false; 1915ffd83dbSDimitry Andric } 1925ffd83dbSDimitry Andric } 1935ffd83dbSDimitry Andric 1945ffd83dbSDimitry Andric if (check_children) { 1955ffd83dbSDimitry Andric for (DWARFDIE child = GetFirstChild(); child; child = child.GetSibling()) { 1965ffd83dbSDimitry Andric if (DWARFDIE child_result = child.LookupDeepestBlock(address)) 1975ffd83dbSDimitry Andric return child_result; 1985ffd83dbSDimitry Andric } 1995ffd83dbSDimitry Andric } 2005ffd83dbSDimitry Andric return result; 2010b57cec5SDimitry Andric } 2020b57cec5SDimitry Andric 2030b57cec5SDimitry Andric const char *DWARFDIE::GetMangledName() const { 2040b57cec5SDimitry Andric if (IsValid()) 2050b57cec5SDimitry Andric return m_die->GetMangledName(m_cu); 2060b57cec5SDimitry Andric else 2070b57cec5SDimitry Andric return nullptr; 2080b57cec5SDimitry Andric } 2090b57cec5SDimitry Andric 2100b57cec5SDimitry Andric const char *DWARFDIE::GetPubname() const { 2110b57cec5SDimitry Andric if (IsValid()) 2120b57cec5SDimitry Andric return m_die->GetPubname(m_cu); 2130b57cec5SDimitry Andric else 2140b57cec5SDimitry Andric return nullptr; 2150b57cec5SDimitry Andric } 2160b57cec5SDimitry Andric 2170b57cec5SDimitry Andric const char *DWARFDIE::GetQualifiedName(std::string &storage) const { 2180b57cec5SDimitry Andric if (IsValid()) 2190b57cec5SDimitry Andric return m_die->GetQualifiedName(m_cu, storage); 2200b57cec5SDimitry Andric else 2210b57cec5SDimitry Andric return nullptr; 2220b57cec5SDimitry Andric } 2230b57cec5SDimitry Andric 2240b57cec5SDimitry Andric // GetName 2250b57cec5SDimitry Andric // 2260b57cec5SDimitry Andric // Get value of the DW_AT_name attribute and place that value into the supplied 2270b57cec5SDimitry Andric // stream object. If the DIE is a NULL object "NULL" is placed into the stream, 2280b57cec5SDimitry Andric // and if no DW_AT_name attribute exists for the DIE then nothing is printed. 2290b57cec5SDimitry Andric void DWARFDIE::GetName(Stream &s) const { 2300b57cec5SDimitry Andric if (!IsValid()) 2310b57cec5SDimitry Andric return; 2320b57cec5SDimitry Andric if (GetDIE()->IsNULL()) { 2330b57cec5SDimitry Andric s.PutCString("NULL"); 2340b57cec5SDimitry Andric return; 2350b57cec5SDimitry Andric } 2360b57cec5SDimitry Andric const char *name = GetDIE()->GetAttributeValueAsString(GetCU(), DW_AT_name, nullptr, true); 2370b57cec5SDimitry Andric if (!name) 2380b57cec5SDimitry Andric return; 2390b57cec5SDimitry Andric s.PutCString(name); 2400b57cec5SDimitry Andric } 2410b57cec5SDimitry Andric 2420b57cec5SDimitry Andric // AppendTypeName 2430b57cec5SDimitry Andric // 2440b57cec5SDimitry Andric // Follows the type name definition down through all needed tags to end up with 2450b57cec5SDimitry Andric // a fully qualified type name and dump the results to the supplied stream. 2460b57cec5SDimitry Andric // This is used to show the name of types given a type identifier. 2470b57cec5SDimitry Andric void DWARFDIE::AppendTypeName(Stream &s) const { 2480b57cec5SDimitry Andric if (!IsValid()) 2490b57cec5SDimitry Andric return; 2500b57cec5SDimitry Andric if (GetDIE()->IsNULL()) { 2510b57cec5SDimitry Andric s.PutCString("NULL"); 2520b57cec5SDimitry Andric return; 2530b57cec5SDimitry Andric } 2540b57cec5SDimitry Andric if (const char *name = GetPubname()) { 2550b57cec5SDimitry Andric s.PutCString(name); 2560b57cec5SDimitry Andric return; 2570b57cec5SDimitry Andric } 2580b57cec5SDimitry Andric switch (Tag()) { 2590b57cec5SDimitry Andric case DW_TAG_array_type: 2600b57cec5SDimitry Andric break; // print out a "[]" after printing the full type of the element 2610b57cec5SDimitry Andric // below 2620b57cec5SDimitry Andric case DW_TAG_base_type: 2630b57cec5SDimitry Andric s.PutCString("base "); 2640b57cec5SDimitry Andric break; 2650b57cec5SDimitry Andric case DW_TAG_class_type: 2660b57cec5SDimitry Andric s.PutCString("class "); 2670b57cec5SDimitry Andric break; 2680b57cec5SDimitry Andric case DW_TAG_const_type: 2690b57cec5SDimitry Andric s.PutCString("const "); 2700b57cec5SDimitry Andric break; 2710b57cec5SDimitry Andric case DW_TAG_enumeration_type: 2720b57cec5SDimitry Andric s.PutCString("enum "); 2730b57cec5SDimitry Andric break; 2740b57cec5SDimitry Andric case DW_TAG_file_type: 2750b57cec5SDimitry Andric s.PutCString("file "); 2760b57cec5SDimitry Andric break; 2770b57cec5SDimitry Andric case DW_TAG_interface_type: 2780b57cec5SDimitry Andric s.PutCString("interface "); 2790b57cec5SDimitry Andric break; 2800b57cec5SDimitry Andric case DW_TAG_packed_type: 2810b57cec5SDimitry Andric s.PutCString("packed "); 2820b57cec5SDimitry Andric break; 2830b57cec5SDimitry Andric case DW_TAG_pointer_type: 2840b57cec5SDimitry Andric break; // print out a '*' after printing the full type below 2850b57cec5SDimitry Andric case DW_TAG_ptr_to_member_type: 2860b57cec5SDimitry Andric break; // print out a '*' after printing the full type below 2870b57cec5SDimitry Andric case DW_TAG_reference_type: 2880b57cec5SDimitry Andric break; // print out a '&' after printing the full type below 2890b57cec5SDimitry Andric case DW_TAG_restrict_type: 2900b57cec5SDimitry Andric s.PutCString("restrict "); 2910b57cec5SDimitry Andric break; 2920b57cec5SDimitry Andric case DW_TAG_set_type: 2930b57cec5SDimitry Andric s.PutCString("set "); 2940b57cec5SDimitry Andric break; 2950b57cec5SDimitry Andric case DW_TAG_shared_type: 2960b57cec5SDimitry Andric s.PutCString("shared "); 2970b57cec5SDimitry Andric break; 2980b57cec5SDimitry Andric case DW_TAG_string_type: 2990b57cec5SDimitry Andric s.PutCString("string "); 3000b57cec5SDimitry Andric break; 3010b57cec5SDimitry Andric case DW_TAG_structure_type: 3020b57cec5SDimitry Andric s.PutCString("struct "); 3030b57cec5SDimitry Andric break; 3040b57cec5SDimitry Andric case DW_TAG_subrange_type: 3050b57cec5SDimitry Andric s.PutCString("subrange "); 3060b57cec5SDimitry Andric break; 3070b57cec5SDimitry Andric case DW_TAG_subroutine_type: 3080b57cec5SDimitry Andric s.PutCString("function "); 3090b57cec5SDimitry Andric break; 3100b57cec5SDimitry Andric case DW_TAG_thrown_type: 3110b57cec5SDimitry Andric s.PutCString("thrown "); 3120b57cec5SDimitry Andric break; 3130b57cec5SDimitry Andric case DW_TAG_union_type: 3140b57cec5SDimitry Andric s.PutCString("union "); 3150b57cec5SDimitry Andric break; 3160b57cec5SDimitry Andric case DW_TAG_unspecified_type: 3170b57cec5SDimitry Andric s.PutCString("unspecified "); 3180b57cec5SDimitry Andric break; 3190b57cec5SDimitry Andric case DW_TAG_volatile_type: 3200b57cec5SDimitry Andric s.PutCString("volatile "); 3210b57cec5SDimitry Andric break; 3220b57cec5SDimitry Andric default: 3230b57cec5SDimitry Andric return; 3240b57cec5SDimitry Andric } 3250b57cec5SDimitry Andric 3260b57cec5SDimitry Andric // Follow the DW_AT_type if possible 3270b57cec5SDimitry Andric if (DWARFDIE next_die = GetAttributeValueAsReferenceDIE(DW_AT_type)) 3280b57cec5SDimitry Andric next_die.AppendTypeName(s); 3290b57cec5SDimitry Andric 3300b57cec5SDimitry Andric switch (Tag()) { 3310b57cec5SDimitry Andric case DW_TAG_array_type: 3320b57cec5SDimitry Andric s.PutCString("[]"); 3330b57cec5SDimitry Andric break; 3340b57cec5SDimitry Andric case DW_TAG_pointer_type: 3350b57cec5SDimitry Andric s.PutChar('*'); 3360b57cec5SDimitry Andric break; 3370b57cec5SDimitry Andric case DW_TAG_ptr_to_member_type: 3380b57cec5SDimitry Andric s.PutChar('*'); 3390b57cec5SDimitry Andric break; 3400b57cec5SDimitry Andric case DW_TAG_reference_type: 3410b57cec5SDimitry Andric s.PutChar('&'); 3420b57cec5SDimitry Andric break; 3430b57cec5SDimitry Andric default: 3440b57cec5SDimitry Andric break; 3450b57cec5SDimitry Andric } 3460b57cec5SDimitry Andric } 3470b57cec5SDimitry Andric 3480b57cec5SDimitry Andric lldb_private::Type *DWARFDIE::ResolveType() const { 3490b57cec5SDimitry Andric if (IsValid()) 3500b57cec5SDimitry Andric return GetDWARF()->ResolveType(*this, true); 3510b57cec5SDimitry Andric else 3520b57cec5SDimitry Andric return nullptr; 3530b57cec5SDimitry Andric } 3540b57cec5SDimitry Andric 3550b57cec5SDimitry Andric lldb_private::Type *DWARFDIE::ResolveTypeUID(const DWARFDIE &die) const { 3560b57cec5SDimitry Andric if (SymbolFileDWARF *dwarf = GetDWARF()) 3570b57cec5SDimitry Andric return dwarf->ResolveTypeUID(die, true); 3580b57cec5SDimitry Andric return nullptr; 3590b57cec5SDimitry Andric } 3600b57cec5SDimitry Andric 3610b57cec5SDimitry Andric std::vector<DWARFDIE> DWARFDIE::GetDeclContextDIEs() const { 3620b57cec5SDimitry Andric if (!IsValid()) 3630b57cec5SDimitry Andric return {}; 3640b57cec5SDimitry Andric 3650b57cec5SDimitry Andric std::vector<DWARFDIE> result; 3660b57cec5SDimitry Andric DWARFDIE parent = GetParentDeclContextDIE(); 3670b57cec5SDimitry Andric while (parent.IsValid() && parent.GetDIE() != GetDIE()) { 3680b57cec5SDimitry Andric result.push_back(std::move(parent)); 3690b57cec5SDimitry Andric parent = parent.GetParentDeclContextDIE(); 3700b57cec5SDimitry Andric } 3710b57cec5SDimitry Andric 3720b57cec5SDimitry Andric return result; 3730b57cec5SDimitry Andric } 3740b57cec5SDimitry Andric 3759dba64beSDimitry Andric void DWARFDIE::GetDeclContext( 3769dba64beSDimitry Andric llvm::SmallVectorImpl<lldb_private::CompilerContext> &context) const { 3770b57cec5SDimitry Andric const dw_tag_t tag = Tag(); 3780b57cec5SDimitry Andric if (tag == DW_TAG_compile_unit || tag == DW_TAG_partial_unit) 3790b57cec5SDimitry Andric return; 3800b57cec5SDimitry Andric DWARFDIE parent = GetParent(); 3810b57cec5SDimitry Andric if (parent) 3820b57cec5SDimitry Andric parent.GetDeclContext(context); 3830b57cec5SDimitry Andric switch (tag) { 3840b57cec5SDimitry Andric case DW_TAG_module: 3859dba64beSDimitry Andric context.push_back({CompilerContextKind::Module, ConstString(GetName())}); 3860b57cec5SDimitry Andric break; 3870b57cec5SDimitry Andric case DW_TAG_namespace: 3889dba64beSDimitry Andric context.push_back({CompilerContextKind::Namespace, ConstString(GetName())}); 3890b57cec5SDimitry Andric break; 3900b57cec5SDimitry Andric case DW_TAG_structure_type: 3919dba64beSDimitry Andric context.push_back({CompilerContextKind::Struct, ConstString(GetName())}); 3920b57cec5SDimitry Andric break; 3930b57cec5SDimitry Andric case DW_TAG_union_type: 3949dba64beSDimitry Andric context.push_back({CompilerContextKind::Union, ConstString(GetName())}); 3950b57cec5SDimitry Andric break; 3960b57cec5SDimitry Andric case DW_TAG_class_type: 3979dba64beSDimitry Andric context.push_back({CompilerContextKind::Class, ConstString(GetName())}); 3980b57cec5SDimitry Andric break; 3990b57cec5SDimitry Andric case DW_TAG_enumeration_type: 4009dba64beSDimitry Andric context.push_back({CompilerContextKind::Enum, ConstString(GetName())}); 4010b57cec5SDimitry Andric break; 4020b57cec5SDimitry Andric case DW_TAG_subprogram: 4039dba64beSDimitry Andric context.push_back( 4049dba64beSDimitry Andric {CompilerContextKind::Function, ConstString(GetPubname())}); 4050b57cec5SDimitry Andric break; 4060b57cec5SDimitry Andric case DW_TAG_variable: 4079dba64beSDimitry Andric context.push_back( 4089dba64beSDimitry Andric {CompilerContextKind::Variable, ConstString(GetPubname())}); 4090b57cec5SDimitry Andric break; 4100b57cec5SDimitry Andric case DW_TAG_typedef: 4119dba64beSDimitry Andric context.push_back({CompilerContextKind::Typedef, ConstString(GetName())}); 4120b57cec5SDimitry Andric break; 4130b57cec5SDimitry Andric default: 4140b57cec5SDimitry Andric break; 4150b57cec5SDimitry Andric } 4160b57cec5SDimitry Andric } 4170b57cec5SDimitry Andric 4180b57cec5SDimitry Andric DWARFDIE 4190b57cec5SDimitry Andric DWARFDIE::GetParentDeclContextDIE() const { 4200b57cec5SDimitry Andric if (IsValid()) 4210b57cec5SDimitry Andric return m_die->GetParentDeclContextDIE(m_cu); 4220b57cec5SDimitry Andric else 4230b57cec5SDimitry Andric return DWARFDIE(); 4240b57cec5SDimitry Andric } 4250b57cec5SDimitry Andric 4260b57cec5SDimitry Andric bool DWARFDIE::IsStructUnionOrClass() const { 4270b57cec5SDimitry Andric const dw_tag_t tag = Tag(); 4280b57cec5SDimitry Andric return tag == DW_TAG_class_type || tag == DW_TAG_structure_type || 4290b57cec5SDimitry Andric tag == DW_TAG_union_type; 4300b57cec5SDimitry Andric } 4310b57cec5SDimitry Andric 4320b57cec5SDimitry Andric bool DWARFDIE::IsMethod() const { 4330b57cec5SDimitry Andric for (DWARFDIE d : elaborating_dies(*this)) 4340b57cec5SDimitry Andric if (d.GetParent().IsStructUnionOrClass()) 4350b57cec5SDimitry Andric return true; 4360b57cec5SDimitry Andric return false; 4370b57cec5SDimitry Andric } 4380b57cec5SDimitry Andric 4390b57cec5SDimitry Andric bool DWARFDIE::GetDIENamesAndRanges( 4400b57cec5SDimitry Andric const char *&name, const char *&mangled, DWARFRangeList &ranges, 4410b57cec5SDimitry Andric int &decl_file, int &decl_line, int &decl_column, int &call_file, 4420b57cec5SDimitry Andric int &call_line, int &call_column, 4430b57cec5SDimitry Andric lldb_private::DWARFExpression *frame_base) const { 4440b57cec5SDimitry Andric if (IsValid()) { 4450b57cec5SDimitry Andric return m_die->GetDIENamesAndRanges( 4460b57cec5SDimitry Andric GetCU(), name, mangled, ranges, decl_file, decl_line, decl_column, 4470b57cec5SDimitry Andric call_file, call_line, call_column, frame_base); 4480b57cec5SDimitry Andric } else 4490b57cec5SDimitry Andric return false; 4500b57cec5SDimitry Andric } 451