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