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 | |