1 //===-- DWARFDIE.h ----------------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDIE_H 10 #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDIE_H 11 12 #include "DWARFBaseDIE.h" 13 #include "llvm/ADT/SmallSet.h" 14 #include "llvm/ADT/iterator_range.h" 15 #include "llvm/DebugInfo/DWARF/DWARFAddressRange.h" 16 17 namespace lldb_private::plugin { 18 namespace dwarf { 19 class DWARFDIE : public DWARFBaseDIE { 20 public: 21 class child_iterator; 22 using DWARFBaseDIE::DWARFBaseDIE; 23 24 // Tests 25 bool IsStructUnionOrClass() const; 26 27 bool IsMethod() const; 28 29 // Accessors 30 31 // Accessing information about a DIE 32 const char *GetMangledName(bool substitute_name_allowed = true) const; 33 34 const char *GetPubname() const; 35 36 using DWARFBaseDIE::GetName; 37 void GetName(Stream &s) const; 38 39 void AppendTypeName(Stream &s) const; 40 41 Type *ResolveType() const; 42 43 // Resolve a type by UID using this DIE's DWARF file 44 Type *ResolveTypeUID(const DWARFDIE &die) const; 45 46 // Functions for obtaining DIE relations and references 47 48 DWARFDIE 49 GetParent() const; 50 51 DWARFDIE 52 GetFirstChild() const; 53 54 DWARFDIE 55 GetSibling() const; 56 57 DWARFDIE 58 GetReferencedDIE(const dw_attr_t attr) const; 59 60 // Get a another DIE from the same DWARF file as this DIE. This will 61 // check the current DIE's compile unit first to see if "die_offset" is 62 // in the same compile unit, and fall back to checking the DWARF file. 63 DWARFDIE 64 GetDIE(dw_offset_t die_offset) const; 65 using DWARFBaseDIE::GetDIE; 66 67 DWARFDIE 68 LookupDeepestBlock(lldb::addr_t file_addr) const; 69 70 DWARFDIE 71 GetParentDeclContextDIE() const; 72 73 /// Return this DIE's decl context as it is needed to look up types 74 /// in Clang modules. This context will include any modules or functions that 75 /// the type is declared in so an exact module match can be efficiently made. 76 /// 77 /// \param[in] derive_template_names 78 /// If true, augments the returned names with template arguments derived 79 /// from the child DIEs, if the names don't contained template arguments 80 /// already. If false, the returned context will contain the names exactly 81 /// as they are spelled in the debug info, regardless of whether that 82 /// includes template arguments or not. 83 std::vector<CompilerContext> 84 GetDeclContext(bool derive_template_names = false) const; 85 86 /// Get a context to a type so it can be looked up. 87 /// 88 /// This function uses the current DIE to fill in a CompilerContext array 89 /// that is suitable for type lookup for comparison to a TypeQuery's compiler 90 /// context (TypeQuery::GetContextRef()). If this DIE represents a named type, 91 /// it should fill out the compiler context with the type itself as the last 92 /// entry. The declaration context should be above the type and stop at an 93 /// appropriate time, like either the translation unit or at a function 94 /// context. This is designed to allow users to efficiently look for types 95 /// using a full or partial CompilerContext array. 96 /// 97 /// \param[in] derive_template_names 98 /// If true, augments the returned names with template arguments derived 99 /// from the child DIEs, if the names don't contained template arguments 100 /// already. If false, the returned context will contain the names exactly 101 /// as they are spelled in the debug info, regardless of whether that 102 /// includes template arguments or not. 103 std::vector<CompilerContext> 104 GetTypeLookupContext(bool derive_template_names = false) const; 105 106 DWARFDeclContext GetDWARFDeclContext() const; 107 108 // Getting attribute values from the DIE. 109 // 110 // GetAttributeValueAsXXX() functions should only be used if you are 111 // looking for one or two attributes on a DIE. If you are trying to 112 // parse all attributes, use GetAttributes (...) instead 113 DWARFDIE 114 GetAttributeValueAsReferenceDIE(const dw_attr_t attr) const; 115 116 bool GetDIENamesAndRanges( 117 const char *&name, const char *&mangled, 118 llvm::DWARFAddressRangesVector &ranges, std::optional<int> &decl_file, 119 std::optional<int> &decl_line, std::optional<int> &decl_column, 120 std::optional<int> &call_file, std::optional<int> &call_line, 121 std::optional<int> &call_column, DWARFExpressionList *frame_base) const; 122 123 // The following methods use LLVM naming convension in order to be are used by 124 // LLVM libraries. 125 std::optional<uint64_t> getLanguage() const; 126 127 DWARFDIE getParent() const { return GetParent(); } 128 129 DWARFDIE resolveReferencedType(dw_attr_t attr) const; 130 131 DWARFDIE resolveReferencedType(DWARFFormValue v) const; 132 133 DWARFDIE resolveTypeUnitReference() const; 134 135 std::optional<DWARFFormValue> find(const dw_attr_t attr) const; 136 137 /// The range of all the children of this DIE. 138 llvm::iterator_range<child_iterator> children() const; 139 140 child_iterator begin() const; 141 child_iterator end() const; 142 }; 143 144 class DWARFDIE::child_iterator 145 : public llvm::iterator_facade_base<DWARFDIE::child_iterator, 146 std::forward_iterator_tag, DWARFDIE> { 147 /// The current child or an invalid DWARFDie. 148 DWARFDIE m_die; 149 150 public: 151 child_iterator() = default; 152 child_iterator(const DWARFDIE &parent) : m_die(parent.GetFirstChild()) {} 153 bool operator==(const child_iterator &it) const { 154 // DWARFDIE's operator== differentiates between an invalid DWARFDIE that 155 // has a CU but no DIE and one that has neither CU nor DIE. The 'end' 156 // iterator could be default constructed, so explicitly allow 157 // (CU, (DIE)nullptr) == (nullptr, nullptr) -> true 158 if (!m_die.IsValid() && !it.m_die.IsValid()) 159 return true; 160 return m_die == it.m_die; 161 } 162 const DWARFDIE &operator*() const { 163 assert(m_die.IsValid() && "Derefencing invalid iterator?"); 164 return m_die; 165 } 166 DWARFDIE &operator*() { 167 assert(m_die.IsValid() && "Derefencing invalid iterator?"); 168 return m_die; 169 } 170 child_iterator &operator++() { 171 assert(m_die.IsValid() && "Incrementing invalid iterator?"); 172 m_die = m_die.GetSibling(); 173 return *this; 174 } 175 }; 176 } // namespace dwarf 177 } // namespace lldb_private::plugin 178 179 #endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDIE_H 180