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