/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/include/lldb/Symbol/Block.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- Block.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_SYMBOL_BLOCK_H |
10 | | #define LLDB_SYMBOL_BLOCK_H |
11 | | |
12 | | #include "lldb/Core/AddressRange.h" |
13 | | #include "lldb/Symbol/CompilerType.h" |
14 | | #include "lldb/Symbol/LineEntry.h" |
15 | | #include "lldb/Symbol/SymbolContext.h" |
16 | | #include "lldb/Symbol/SymbolContextScope.h" |
17 | | #include "lldb/Utility/RangeMap.h" |
18 | | #include "lldb/Utility/Stream.h" |
19 | | #include "lldb/Utility/UserID.h" |
20 | | #include "lldb/lldb-private.h" |
21 | | #include <vector> |
22 | | |
23 | | namespace lldb_private { |
24 | | |
25 | | /// \class Block Block.h "lldb/Symbol/Block.h" |
26 | | /// A class that describes a single lexical block. |
27 | | /// |
28 | | /// A Function object owns a BlockList object which owns one or more |
29 | | /// Block objects. The BlockList object contains a section offset address |
30 | | /// range, and Block objects contain one or more ranges which are offsets into |
31 | | /// that range. Blocks are can have discontiguous ranges within the BlockList |
32 | | /// address range, and each block can contain child blocks each with their own |
33 | | /// sets of ranges. |
34 | | /// |
35 | | /// Each block has a variable list that represents local, argument, and static |
36 | | /// variables that are scoped to the block. |
37 | | /// |
38 | | /// Inlined functions are represented by attaching a InlineFunctionInfo shared |
39 | | /// pointer object to a block. Inlined functions are represented as named |
40 | | /// blocks. |
41 | | class Block : public UserID, public SymbolContextScope { |
42 | | public: |
43 | | typedef RangeVector<uint32_t, uint32_t, 1> RangeList; |
44 | | typedef RangeList::Entry Range; |
45 | | |
46 | | /// Construct with a User ID \a uid, \a depth. |
47 | | /// |
48 | | /// Initialize this block with the specified UID \a uid. The \a depth in the |
49 | | /// \a block_list is used to represent the parent, sibling, and child block |
50 | | /// information and also allows for partial parsing at the block level. |
51 | | /// |
52 | | /// \param[in] uid |
53 | | /// The UID for a given block. This value is given by the |
54 | | /// SymbolFile plug-in and can be any value that helps the |
55 | | /// SymbolFile plug-in to match this block back to the debug |
56 | | /// information data that it parses for further or more in |
57 | | /// depth parsing. Common values would be the index into a |
58 | | /// table, or an offset into the debug information. |
59 | | /// |
60 | | /// \see BlockList |
61 | | Block(lldb::user_id_t uid); |
62 | | |
63 | | /// Destructor. |
64 | | ~Block() override; |
65 | | |
66 | | /// Add a child to this object. |
67 | | /// |
68 | | /// \param[in] child_block_sp |
69 | | /// A shared pointer to a child block that will get added to |
70 | | /// this block. |
71 | | void AddChild(const lldb::BlockSP &child_block_sp); |
72 | | |
73 | | /// Add a new offset range to this block. |
74 | | void AddRange(const Range &range); |
75 | | |
76 | | void FinalizeRanges(); |
77 | | |
78 | | /// \copydoc SymbolContextScope::CalculateSymbolContext(SymbolContext*) |
79 | | /// |
80 | | /// \see SymbolContextScope |
81 | | void CalculateSymbolContext(SymbolContext *sc) override; |
82 | | |
83 | | lldb::ModuleSP CalculateSymbolContextModule() override; |
84 | | |
85 | | CompileUnit *CalculateSymbolContextCompileUnit() override; |
86 | | |
87 | | Function *CalculateSymbolContextFunction() override; |
88 | | |
89 | | Block *CalculateSymbolContextBlock() override; |
90 | | |
91 | | /// Check if an offset is in one of the block offset ranges. |
92 | | /// |
93 | | /// \param[in] range_offset |
94 | | /// An offset into the Function's address range. |
95 | | /// |
96 | | /// \return |
97 | | /// Returns \b true if \a range_offset falls in one of this |
98 | | /// block's ranges, \b false otherwise. |
99 | | bool Contains(lldb::addr_t range_offset) const; |
100 | | |
101 | | /// Check if a offset range is in one of the block offset ranges. |
102 | | /// |
103 | | /// \param[in] range |
104 | | /// An offset range into the Function's address range. |
105 | | /// |
106 | | /// \return |
107 | | /// Returns \b true if \a range falls in one of this |
108 | | /// block's ranges, \b false otherwise. |
109 | | bool Contains(const Range &range) const; |
110 | | |
111 | | /// Check if this object contains "block" as a child block at any depth. |
112 | | /// |
113 | | /// \param[in] block |
114 | | /// A potential child block. |
115 | | /// |
116 | | /// \return |
117 | | /// Returns \b true if \a block is a child of this block, \b |
118 | | /// false otherwise. |
119 | | bool Contains(const Block *block) const; |
120 | | |
121 | | /// Dump the block contents. |
122 | | /// |
123 | | /// \param[in] s |
124 | | /// The stream to which to dump the object description. |
125 | | /// |
126 | | /// \param[in] base_addr |
127 | | /// The resolved start address of the Function's address |
128 | | /// range. This should be resolved as the file or load address |
129 | | /// prior to passing the value into this function for dumping. |
130 | | /// |
131 | | /// \param[in] depth |
132 | | /// Limit the number of levels deep that this function should |
133 | | /// print as this block can contain child blocks. Specify |
134 | | /// INT_MAX to dump all child blocks. |
135 | | /// |
136 | | /// \param[in] show_context |
137 | | /// If \b true, variables will dump their context information. |
138 | | void Dump(Stream *s, lldb::addr_t base_addr, int32_t depth, |
139 | | bool show_context) const; |
140 | | |
141 | | /// \copydoc SymbolContextScope::DumpSymbolContext(Stream*) |
142 | | /// |
143 | | /// \see SymbolContextScope |
144 | | void DumpSymbolContext(Stream *s) override; |
145 | | |
146 | | void DumpAddressRanges(Stream *s, lldb::addr_t base_addr); |
147 | | |
148 | | void GetDescription(Stream *s, Function *function, |
149 | | lldb::DescriptionLevel level, Target *target) const; |
150 | | |
151 | | /// Get the parent block. |
152 | | /// |
153 | | /// \return |
154 | | /// The parent block pointer, or nullptr if this block has no |
155 | | /// parent. |
156 | | Block *GetParent() const; |
157 | | |
158 | | /// Get the inlined block that contains this block. |
159 | | /// |
160 | | /// \return |
161 | | /// If this block contains inlined function info, it will return |
162 | | /// this block, else parent blocks will be searched to see if |
163 | | /// any contain this block. nullptr will be returned if this block |
164 | | /// nor any parent blocks are inlined function blocks. |
165 | | Block *GetContainingInlinedBlock(); |
166 | | |
167 | | /// Get the inlined parent block for this block. |
168 | | /// |
169 | | /// \return |
170 | | /// The parent block pointer, or nullptr if this block has no |
171 | | /// parent. |
172 | | Block *GetInlinedParent(); |
173 | | |
174 | | //------------------------------------------------------------------ |
175 | | /// Get the inlined block at the given call site that contains this block. |
176 | | /// |
177 | | /// @param[in] find_call_site |
178 | | /// a declaration with the file and line of the call site to find. |
179 | | /// |
180 | | /// @return |
181 | | /// If this block contains inlined function info and is at the call |
182 | | /// site given by the file and line at the given \b declaration, then |
183 | | /// it will return this block, otherwise the parent blocks will be |
184 | | /// searched to see if any is at the call site. nullptr will be returned |
185 | | /// if no block is found at the call site. |
186 | | //------------------------------------------------------------------ |
187 | | Block * |
188 | | GetContainingInlinedBlockWithCallSite(const Declaration &find_call_site); |
189 | | |
190 | | /// Get the sibling block for this block. |
191 | | /// |
192 | | /// \return |
193 | | /// The sibling block pointer, or nullptr if this block has no |
194 | | /// sibling. |
195 | | Block *GetSibling() const; |
196 | | |
197 | | /// Get the first child block. |
198 | | /// |
199 | | /// \return |
200 | | /// The first child block pointer, or nullptr if this block has no |
201 | | /// children. |
202 | 0 | Block *GetFirstChild() const { |
203 | 0 | return (m_children.empty() ? nullptr : m_children.front().get()); |
204 | 0 | } |
205 | | |
206 | | /// Get the variable list for this block only. |
207 | | /// |
208 | | /// \param[in] can_create |
209 | | /// If \b true, the variables can be parsed if they already |
210 | | /// haven't been, else the current state of the block will be |
211 | | /// returned. |
212 | | /// |
213 | | /// \return |
214 | | /// A variable list shared pointer that contains all variables |
215 | | /// for this block. |
216 | | lldb::VariableListSP GetBlockVariableList(bool can_create); |
217 | | |
218 | | /// Get the variable list for this block and optionally all child blocks if |
219 | | /// \a get_child_variables is \b true. |
220 | | /// |
221 | | /// \param[in] can_create |
222 | | /// If \b true, the variables can be parsed if they already |
223 | | /// haven't been, else the current state of the block will be |
224 | | /// returned. Passing \b true for this parameter can be used |
225 | | /// to see the current state of what has been parsed up to this |
226 | | /// point. |
227 | | /// |
228 | | /// \param[in] get_child_block_variables |
229 | | /// If \b true, all variables from all child blocks will be |
230 | | /// added to the variable list. |
231 | | /// |
232 | | /// \return |
233 | | /// A variable list shared pointer that contains all variables |
234 | | /// for this block. |
235 | | uint32_t AppendBlockVariables(bool can_create, bool get_child_block_variables, |
236 | | bool stop_if_child_block_is_inlined_function, |
237 | | const std::function<bool(Variable *)> &filter, |
238 | | VariableList *variable_list); |
239 | | |
240 | | /// Appends the variables from this block, and optionally from all parent |
241 | | /// blocks, to \a variable_list. |
242 | | /// |
243 | | /// \param[in] can_create |
244 | | /// If \b true, the variables can be parsed if they already |
245 | | /// haven't been, else the current state of the block will be |
246 | | /// returned. Passing \b true for this parameter can be used |
247 | | /// to see the current state of what has been parsed up to this |
248 | | /// point. |
249 | | /// |
250 | | /// \param[in] get_parent_variables |
251 | | /// If \b true, all variables from all parent blocks will be |
252 | | /// added to the variable list. |
253 | | /// |
254 | | /// \param[in] stop_if_block_is_inlined_function |
255 | | /// If \b true, all variables from all parent blocks will be |
256 | | /// added to the variable list until there are no parent blocks |
257 | | /// or the parent block has inlined function info. |
258 | | /// |
259 | | /// \param[in,out] variable_list |
260 | | /// All variables in this block, and optionally all parent |
261 | | /// blocks will be added to this list. |
262 | | /// |
263 | | /// \return |
264 | | /// The number of variable that were appended to \a |
265 | | /// variable_list. |
266 | | uint32_t AppendVariables(bool can_create, bool get_parent_variables, |
267 | | bool stop_if_block_is_inlined_function, |
268 | | const std::function<bool(Variable *)> &filter, |
269 | | VariableList *variable_list); |
270 | | |
271 | | /// Get const accessor for any inlined function information. |
272 | | /// |
273 | | /// \return |
274 | | /// A const pointer to any inlined function information, or nullptr |
275 | | /// if this is a regular block. |
276 | 289k | const InlineFunctionInfo *GetInlinedFunctionInfo() const { |
277 | 289k | return m_inlineInfoSP.get(); |
278 | 289k | } |
279 | | |
280 | | /// Get the symbol file which contains debug info for this block's |
281 | | /// symbol context module. |
282 | | /// |
283 | | /// \return A pointer to the symbol file or nullptr. |
284 | | SymbolFile *GetSymbolFile(); |
285 | | |
286 | | CompilerDeclContext GetDeclContext(); |
287 | | |
288 | | /// Get the memory cost of this object. |
289 | | /// |
290 | | /// Returns the cost of this object plus any owned objects from the ranges, |
291 | | /// variables, and inline function information. |
292 | | /// |
293 | | /// \return |
294 | | /// The number of bytes that this object occupies in memory. |
295 | | size_t MemorySize() const; |
296 | | |
297 | | /// Set accessor for any inlined function information. |
298 | | /// |
299 | | /// \param[in] name |
300 | | /// The method name for the inlined function. This value should |
301 | | /// not be nullptr. |
302 | | /// |
303 | | /// \param[in] mangled |
304 | | /// The mangled method name for the inlined function. This can |
305 | | /// be nullptr if there is no mangled name for an inlined function |
306 | | /// or if the name is the same as \a name. |
307 | | /// |
308 | | /// \param[in] decl_ptr |
309 | | /// A optional pointer to declaration information for the |
310 | | /// inlined function information. This value can be nullptr to |
311 | | /// indicate that no declaration information is available. |
312 | | /// |
313 | | /// \param[in] call_decl_ptr |
314 | | /// Optional calling location declaration information that |
315 | | /// describes from where this inlined function was called. |
316 | | void SetInlinedFunctionInfo(const char *name, const char *mangled, |
317 | | const Declaration *decl_ptr, |
318 | | const Declaration *call_decl_ptr); |
319 | | |
320 | 7.23k | void SetParentScope(SymbolContextScope *parent_scope) { |
321 | 7.23k | m_parent_scope = parent_scope; |
322 | 7.23k | } |
323 | | |
324 | | /// Set accessor for the variable list. |
325 | | /// |
326 | | /// Called by the SymbolFile plug-ins after they have parsed the variable |
327 | | /// lists and are ready to hand ownership of the list over to this object. |
328 | | /// |
329 | | /// \param[in] variable_list_sp |
330 | | /// A shared pointer to a VariableList. |
331 | 2.85k | void SetVariableList(lldb::VariableListSP &variable_list_sp) { |
332 | 2.85k | m_variable_list_sp = variable_list_sp; |
333 | 2.85k | } |
334 | | |
335 | 262k | bool BlockInfoHasBeenParsed() const { return m_parsed_block_info; } |
336 | | |
337 | | void SetBlockInfoHasBeenParsed(bool b, bool set_children); |
338 | | |
339 | | Block *FindBlockByID(lldb::user_id_t block_id); |
340 | | |
341 | | Block *FindInnermostBlockByOffset(const lldb::addr_t offset); |
342 | | |
343 | 10 | size_t GetNumRanges() const { return m_ranges.GetSize(); } |
344 | | |
345 | | bool GetRangeContainingOffset(const lldb::addr_t offset, Range &range); |
346 | | |
347 | | bool GetRangeContainingAddress(const Address &addr, AddressRange &range); |
348 | | |
349 | | bool GetRangeContainingLoadAddress(lldb::addr_t load_addr, Target &target, |
350 | | AddressRange &range); |
351 | | |
352 | | uint32_t GetRangeIndexContainingAddress(const Address &addr); |
353 | | |
354 | | // Since blocks might have multiple discontiguous address ranges, we need to |
355 | | // be able to get at any of the address ranges in a block. |
356 | | bool GetRangeAtIndex(uint32_t range_idx, AddressRange &range); |
357 | | |
358 | | bool GetStartAddress(Address &addr); |
359 | | |
360 | | void SetDidParseVariables(bool b, bool set_children); |
361 | | |
362 | | protected: |
363 | | typedef std::vector<lldb::BlockSP> collection; |
364 | | // Member variables. |
365 | | SymbolContextScope *m_parent_scope; |
366 | | collection m_children; |
367 | | RangeList m_ranges; |
368 | | lldb::InlineFunctionInfoSP m_inlineInfoSP; ///< Inlined function information. |
369 | | lldb::VariableListSP m_variable_list_sp; ///< The variable list for all local, |
370 | | ///static and parameter variables |
371 | | ///scoped to this block. |
372 | | bool m_parsed_block_info : 1, ///< Set to true if this block and it's children |
373 | | ///have all been parsed |
374 | | m_parsed_block_variables : 1, m_parsed_child_blocks : 1; |
375 | | |
376 | | // A parent of child blocks can be asked to find a sibling block given |
377 | | // one of its child blocks |
378 | | Block *GetSiblingForChild(const Block *child_block) const; |
379 | | |
380 | | private: |
381 | | Block(const Block &) = delete; |
382 | | const Block &operator=(const Block &) = delete; |
383 | | }; |
384 | | |
385 | | } // namespace lldb_private |
386 | | |
387 | | #endif // LLDB_SYMBOL_BLOCK_H |