Coverage Report

Created: 2023-09-30 09:22

/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