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