1254721Semaste//===-- Block.h -------------------------------------------------*- C++ -*-===//
2254721Semaste//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6254721Semaste//
7254721Semaste//===----------------------------------------------------------------------===//
8254721Semaste
9254721Semaste#ifndef liblldb_Block_h_
10254721Semaste#define liblldb_Block_h_
11254721Semaste
12254721Semaste#include "lldb/Core/AddressRange.h"
13314564Sdim#include "lldb/Symbol/CompilerType.h"
14254721Semaste#include "lldb/Symbol/LineEntry.h"
15254721Semaste#include "lldb/Symbol/SymbolContext.h"
16321369Sdim#include "lldb/Symbol/SymbolContextScope.h"
17353358Sdim#include "lldb/Utility/RangeMap.h"
18321369Sdim#include "lldb/Utility/Stream.h"
19321369Sdim#include "lldb/Utility/UserID.h"
20314564Sdim#include "lldb/lldb-private.h"
21353358Sdim#include <vector>
22254721Semaste
23254721Semastenamespace lldb_private {
24254721Semaste
25353358Sdim/// \class Block Block.h "lldb/Symbol/Block.h"
26341825Sdim/// A class that describes a single lexical block.
27254721Semaste///
28254721Semaste/// A Function object owns a BlockList object which owns one or more
29341825Sdim/// Block objects. The BlockList object contains a section offset address
30341825Sdim/// range, and Block objects contain one or more ranges which are offsets into
31341825Sdim/// that range. Blocks are can have discontiguous ranges within the BlockList
32341825Sdim/// address range, and each block can contain child blocks each with their own
33341825Sdim/// sets of ranges.
34254721Semaste///
35341825Sdim/// Each block has a variable list that represents local, argument, and static
36341825Sdim/// variables that are scoped to the block.
37254721Semaste///
38341825Sdim/// Inlined functions are represented by attaching a InlineFunctionInfo shared
39341825Sdim/// pointer object to a block. Inlined functions are represented as named
40341825Sdim/// blocks.
41314564Sdimclass Block : public UserID, public SymbolContextScope {
42254721Semastepublic:
43314564Sdim  typedef RangeArray<uint32_t, uint32_t, 1> RangeList;
44314564Sdim  typedef RangeList::Entry Range;
45254721Semaste
46314564Sdim  /// Construct with a User ID \a uid, \a depth.
47314564Sdim  ///
48341825Sdim  /// Initialize this block with the specified UID \a uid. The \a depth in the
49341825Sdim  /// \a block_list is used to represent the parent, sibling, and child block
50341825Sdim  /// information and also allows for partial parsing at the block level.
51314564Sdim  ///
52353358Sdim  /// \param[in] uid
53314564Sdim  ///     The UID for a given block. This value is given by the
54314564Sdim  ///     SymbolFile plug-in and can be any value that helps the
55314564Sdim  ///     SymbolFile plug-in to match this block back to the debug
56314564Sdim  ///     information data that it parses for further or more in
57314564Sdim  ///     depth parsing. Common values would be the index into a
58314564Sdim  ///     table, or an offset into the debug information.
59314564Sdim  ///
60353358Sdim  /// \see BlockList
61314564Sdim  Block(lldb::user_id_t uid);
62254721Semaste
63314564Sdim  /// Destructor.
64314564Sdim  ~Block() override;
65254721Semaste
66314564Sdim  /// Add a child to this object.
67314564Sdim  ///
68353358Sdim  /// \param[in] child_block_sp
69314564Sdim  ///     A shared pointer to a child block that will get added to
70314564Sdim  ///     this block.
71314564Sdim  void AddChild(const lldb::BlockSP &child_block_sp);
72254721Semaste
73314564Sdim  /// Add a new offset range to this block.
74314564Sdim  void AddRange(const Range &range);
75254721Semaste
76314564Sdim  void FinalizeRanges();
77254721Semaste
78353358Sdim  /// \copydoc SymbolContextScope::CalculateSymbolContext(SymbolContext*)
79314564Sdim  ///
80353358Sdim  /// \see SymbolContextScope
81314564Sdim  void CalculateSymbolContext(SymbolContext *sc) override;
82254721Semaste
83314564Sdim  lldb::ModuleSP CalculateSymbolContextModule() override;
84254721Semaste
85314564Sdim  CompileUnit *CalculateSymbolContextCompileUnit() override;
86254721Semaste
87314564Sdim  Function *CalculateSymbolContextFunction() override;
88254721Semaste
89314564Sdim  Block *CalculateSymbolContextBlock() override;
90254721Semaste
91314564Sdim  /// Check if an offset is in one of the block offset ranges.
92314564Sdim  ///
93353358Sdim  /// \param[in] range_offset
94314564Sdim  ///     An offset into the Function's address range.
95314564Sdim  ///
96353358Sdim  /// \return
97314564Sdim  ///     Returns \b true if \a range_offset falls in one of this
98314564Sdim  ///     block's ranges, \b false otherwise.
99314564Sdim  bool Contains(lldb::addr_t range_offset) const;
100254721Semaste
101314564Sdim  /// Check if a offset range is in one of the block offset ranges.
102314564Sdim  ///
103353358Sdim  /// \param[in] range
104314564Sdim  ///     An offset range into the Function's address range.
105314564Sdim  ///
106353358Sdim  /// \return
107314564Sdim  ///     Returns \b true if \a range falls in one of this
108314564Sdim  ///     block's ranges, \b false otherwise.
109314564Sdim  bool Contains(const Range &range) const;
110254721Semaste
111341825Sdim  /// Check if this object contains "block" as a child block at any depth.
112314564Sdim  ///
113353358Sdim  /// \param[in] block
114314564Sdim  ///     A potential child block.
115314564Sdim  ///
116353358Sdim  /// \return
117314564Sdim  ///     Returns \b true if \a block is a child of this block, \b
118314564Sdim  ///     false otherwise.
119314564Sdim  bool Contains(const Block *block) const;
120254721Semaste
121314564Sdim  /// Dump the block contents.
122314564Sdim  ///
123353358Sdim  /// \param[in] s
124314564Sdim  ///     The stream to which to dump the object description.
125314564Sdim  ///
126353358Sdim  /// \param[in] base_addr
127314564Sdim  ///     The resolved start address of the Function's address
128314564Sdim  ///     range. This should be resolved as the file or load address
129314564Sdim  ///     prior to passing the value into this function for dumping.
130314564Sdim  ///
131353358Sdim  /// \param[in] depth
132314564Sdim  ///     Limit the number of levels deep that this function should
133314564Sdim  ///     print as this block can contain child blocks. Specify
134314564Sdim  ///     INT_MAX to dump all child blocks.
135314564Sdim  ///
136353358Sdim  /// \param[in] show_context
137314564Sdim  ///     If \b true, variables will dump their context information.
138314564Sdim  void Dump(Stream *s, lldb::addr_t base_addr, int32_t depth,
139314564Sdim            bool show_context) const;
140254721Semaste
141353358Sdim  /// \copydoc SymbolContextScope::DumpSymbolContext(Stream*)
142314564Sdim  ///
143353358Sdim  /// \see SymbolContextScope
144314564Sdim  void DumpSymbolContext(Stream *s) override;
145254721Semaste
146314564Sdim  void DumpAddressRanges(Stream *s, lldb::addr_t base_addr);
147254721Semaste
148314564Sdim  void GetDescription(Stream *s, Function *function,
149314564Sdim                      lldb::DescriptionLevel level, Target *target) const;
150254721Semaste
151314564Sdim  /// Get the parent block.
152314564Sdim  ///
153353358Sdim  /// \return
154314564Sdim  ///     The parent block pointer, or nullptr if this block has no
155314564Sdim  ///     parent.
156314564Sdim  Block *GetParent() const;
157254721Semaste
158314564Sdim  /// Get the inlined block that contains this block.
159314564Sdim  ///
160353358Sdim  /// \return
161314564Sdim  ///     If this block contains inlined function info, it will return
162314564Sdim  ///     this block, else parent blocks will be searched to see if
163314564Sdim  ///     any contain this block. nullptr will be returned if this block
164314564Sdim  ///     nor any parent blocks are inlined function blocks.
165314564Sdim  Block *GetContainingInlinedBlock();
166254721Semaste
167314564Sdim  /// Get the inlined parent block for this block.
168314564Sdim  ///
169353358Sdim  /// \return
170314564Sdim  ///     The parent block pointer, or nullptr if this block has no
171314564Sdim  ///     parent.
172314564Sdim  Block *GetInlinedParent();
173254721Semaste
174314564Sdim  //------------------------------------------------------------------
175353358Sdim  /// Get the inlined block at the given call site that contains this block.
176353358Sdim  ///
177353358Sdim  /// @param[in] find_call_site
178353358Sdim  ///     a declaration with the file and line of the call site to find.
179353358Sdim  ///
180353358Sdim  /// @return
181353358Sdim  ///     If this block contains inlined function info and is at the call
182353358Sdim  ///     site given by the file and line at the given \b declaration, then
183353358Sdim  ///     it will return this block, otherwise the parent blocks will be
184353358Sdim  ///     searched to see if any is at the call site. nullptr will be returned
185353358Sdim  ///     if no block is found at the call site.
186353358Sdim  //------------------------------------------------------------------
187353358Sdim  Block *
188353358Sdim  GetContainingInlinedBlockWithCallSite(const Declaration &find_call_site);
189353358Sdim
190314564Sdim  /// Get the sibling block for this block.
191314564Sdim  ///
192353358Sdim  /// \return
193314564Sdim  ///     The sibling block pointer, or nullptr if this block has no
194314564Sdim  ///     sibling.
195314564Sdim  Block *GetSibling() const;
196309124Sdim
197314564Sdim  /// Get the first child block.
198314564Sdim  ///
199353358Sdim  /// \return
200314564Sdim  ///     The first child block pointer, or nullptr if this block has no
201314564Sdim  ///     children.
202314564Sdim  Block *GetFirstChild() const {
203314564Sdim    return (m_children.empty() ? nullptr : m_children.front().get());
204314564Sdim  }
205254721Semaste
206314564Sdim  /// Get the variable list for this block only.
207314564Sdim  ///
208353358Sdim  /// \param[in] can_create
209314564Sdim  ///     If \b true, the variables can be parsed if they already
210314564Sdim  ///     haven't been, else the current state of the block will be
211314564Sdim  ///     returned.
212314564Sdim  ///
213353358Sdim  /// \return
214314564Sdim  ///     A variable list shared pointer that contains all variables
215314564Sdim  ///     for this block.
216314564Sdim  lldb::VariableListSP GetBlockVariableList(bool can_create);
217254721Semaste
218341825Sdim  /// Get the variable list for this block and optionally all child blocks if
219341825Sdim  /// \a get_child_variables is \b true.
220314564Sdim  ///
221353358Sdim  /// \param[in] can_create
222314564Sdim  ///     If \b true, the variables can be parsed if they already
223314564Sdim  ///     haven't been, else the current state of the block will be
224314564Sdim  ///     returned. Passing \b true for this parameter can be used
225314564Sdim  ///     to see the current state of what has been parsed up to this
226314564Sdim  ///     point.
227314564Sdim  ///
228360784Sdim  /// \param[in] get_child_block_variables
229360784Sdim  ///     If \b true, all variables from all child blocks will be
230360784Sdim  ///     added to the variable list.
231314564Sdim  ///
232353358Sdim  /// \return
233314564Sdim  ///     A variable list shared pointer that contains all variables
234314564Sdim  ///     for this block.
235314564Sdim  uint32_t AppendBlockVariables(bool can_create, bool get_child_block_variables,
236314564Sdim                                bool stop_if_child_block_is_inlined_function,
237314564Sdim                                const std::function<bool(Variable *)> &filter,
238314564Sdim                                VariableList *variable_list);
239254721Semaste
240341825Sdim  /// Appends the variables from this block, and optionally from all parent
241341825Sdim  /// blocks, to \a variable_list.
242314564Sdim  ///
243353358Sdim  /// \param[in] can_create
244314564Sdim  ///     If \b true, the variables can be parsed if they already
245314564Sdim  ///     haven't been, else the current state of the block will be
246314564Sdim  ///     returned. Passing \b true for this parameter can be used
247314564Sdim  ///     to see the current state of what has been parsed up to this
248314564Sdim  ///     point.
249314564Sdim  ///
250353358Sdim  /// \param[in] get_parent_variables
251314564Sdim  ///     If \b true, all variables from all parent blocks will be
252314564Sdim  ///     added to the variable list.
253314564Sdim  ///
254353358Sdim  /// \param[in] stop_if_block_is_inlined_function
255314564Sdim  ///     If \b true, all variables from all parent blocks will be
256314564Sdim  ///     added to the variable list until there are no parent blocks
257314564Sdim  ///     or the parent block has inlined function info.
258314564Sdim  ///
259353358Sdim  /// \param[in,out] variable_list
260314564Sdim  ///     All variables in this block, and optionally all parent
261314564Sdim  ///     blocks will be added to this list.
262314564Sdim  ///
263353358Sdim  /// \return
264314564Sdim  ///     The number of variable that were appended to \a
265314564Sdim  ///     variable_list.
266314564Sdim  uint32_t AppendVariables(bool can_create, bool get_parent_variables,
267314564Sdim                           bool stop_if_block_is_inlined_function,
268314564Sdim                           const std::function<bool(Variable *)> &filter,
269314564Sdim                           VariableList *variable_list);
270254721Semaste
271314564Sdim  /// Get const accessor for any inlined function information.
272314564Sdim  ///
273353358Sdim  /// \return
274314564Sdim  ///     A const pointer to any inlined function information, or nullptr
275314564Sdim  ///     if this is a regular block.
276314564Sdim  const InlineFunctionInfo *GetInlinedFunctionInfo() const {
277314564Sdim    return m_inlineInfoSP.get();
278314564Sdim  }
279254721Semaste
280344779Sdim  /// Get the symbol file which contains debug info for this block's
281344779Sdim  /// symbol context module.
282344779Sdim  ///
283353358Sdim  /// \return A pointer to the symbol file or nullptr.
284344779Sdim  SymbolFile *GetSymbolFile();
285344779Sdim
286314564Sdim  CompilerDeclContext GetDeclContext();
287254721Semaste
288314564Sdim  /// Get the memory cost of this object.
289314564Sdim  ///
290341825Sdim  /// Returns the cost of this object plus any owned objects from the ranges,
291341825Sdim  /// variables, and inline function information.
292314564Sdim  ///
293353358Sdim  /// \return
294314564Sdim  ///     The number of bytes that this object occupies in memory.
295314564Sdim  size_t MemorySize() const;
296254721Semaste
297314564Sdim  /// Set accessor for any inlined function information.
298314564Sdim  ///
299353358Sdim  /// \param[in] name
300314564Sdim  ///     The method name for the inlined function. This value should
301314564Sdim  ///     not be nullptr.
302314564Sdim  ///
303353358Sdim  /// \param[in] mangled
304314564Sdim  ///     The mangled method name for the inlined function. This can
305314564Sdim  ///     be nullptr if there is no mangled name for an inlined function
306314564Sdim  ///     or if the name is the same as \a name.
307314564Sdim  ///
308353358Sdim  /// \param[in] decl_ptr
309314564Sdim  ///     A optional pointer to declaration information for the
310314564Sdim  ///     inlined function information. This value can be nullptr to
311314564Sdim  ///     indicate that no declaration information is available.
312314564Sdim  ///
313353358Sdim  /// \param[in] call_decl_ptr
314314564Sdim  ///     Optional calling location declaration information that
315314564Sdim  ///     describes from where this inlined function was called.
316314564Sdim  void SetInlinedFunctionInfo(const char *name, const char *mangled,
317314564Sdim                              const Declaration *decl_ptr,
318314564Sdim                              const Declaration *call_decl_ptr);
319254721Semaste
320314564Sdim  void SetParentScope(SymbolContextScope *parent_scope) {
321314564Sdim    m_parent_scope = parent_scope;
322314564Sdim  }
323254721Semaste
324314564Sdim  /// Set accessor for the variable list.
325314564Sdim  ///
326341825Sdim  /// Called by the SymbolFile plug-ins after they have parsed the variable
327341825Sdim  /// lists and are ready to hand ownership of the list over to this object.
328314564Sdim  ///
329353358Sdim  /// \param[in] variable_list_sp
330314564Sdim  ///     A shared pointer to a VariableList.
331314564Sdim  void SetVariableList(lldb::VariableListSP &variable_list_sp) {
332314564Sdim    m_variable_list_sp = variable_list_sp;
333314564Sdim  }
334254721Semaste
335314564Sdim  bool BlockInfoHasBeenParsed() const { return m_parsed_block_info; }
336254721Semaste
337314564Sdim  void SetBlockInfoHasBeenParsed(bool b, bool set_children);
338254721Semaste
339314564Sdim  Block *FindBlockByID(lldb::user_id_t block_id);
340254721Semaste
341314564Sdim  size_t GetNumRanges() const { return m_ranges.GetSize(); }
342254721Semaste
343314564Sdim  bool GetRangeContainingOffset(const lldb::addr_t offset, Range &range);
344314564Sdim
345314564Sdim  bool GetRangeContainingAddress(const Address &addr, AddressRange &range);
346314564Sdim
347314564Sdim  bool GetRangeContainingLoadAddress(lldb::addr_t load_addr, Target &target,
348314564Sdim                                     AddressRange &range);
349314564Sdim
350314564Sdim  uint32_t GetRangeIndexContainingAddress(const Address &addr);
351314564Sdim
352341825Sdim  // Since blocks might have multiple discontiguous address ranges, we need to
353341825Sdim  // be able to get at any of the address ranges in a block.
354314564Sdim  bool GetRangeAtIndex(uint32_t range_idx, AddressRange &range);
355314564Sdim
356314564Sdim  bool GetStartAddress(Address &addr);
357314564Sdim
358314564Sdim  void SetDidParseVariables(bool b, bool set_children);
359314564Sdim
360254721Semasteprotected:
361314564Sdim  typedef std::vector<lldb::BlockSP> collection;
362314564Sdim  // Member variables.
363314564Sdim  SymbolContextScope *m_parent_scope;
364314564Sdim  collection m_children;
365314564Sdim  RangeList m_ranges;
366314564Sdim  lldb::InlineFunctionInfoSP m_inlineInfoSP; ///< Inlined function information.
367314564Sdim  lldb::VariableListSP m_variable_list_sp; ///< The variable list for all local,
368314564Sdim                                           ///static and parameter variables
369314564Sdim                                           ///scoped to this block.
370314564Sdim  bool m_parsed_block_info : 1, ///< Set to true if this block and it's children
371314564Sdim                                ///have all been parsed
372314564Sdim      m_parsed_block_variables : 1, m_parsed_child_blocks : 1;
373254721Semaste
374314564Sdim  // A parent of child blocks can be asked to find a sibling block given
375314564Sdim  // one of its child blocks
376314564Sdim  Block *GetSiblingForChild(const Block *child_block) const;
377254721Semaste
378254721Semasteprivate:
379314564Sdim  DISALLOW_COPY_AND_ASSIGN(Block);
380254721Semaste};
381254721Semaste
382254721Semaste} // namespace lldb_private
383254721Semaste
384296417Sdim#endif // liblldb_Block_h_
385