aboutsummaryrefslogtreecommitdiff
path: root/include/lldb/Symbol/Block.h
blob: 4a305e3cbbec282812f368b9b316f0ec0ea85e38 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
//===-- Block.h -------------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef liblldb_Block_h_
#define liblldb_Block_h_

#include "lldb/lldb-private.h"
#include "lldb/Core/AddressRange.h"
#include "lldb/Core/RangeMap.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/UserID.h"
#include "lldb/Symbol/LineEntry.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/ClangASTType.h"

namespace lldb_private {

//----------------------------------------------------------------------
/// @class Block Block.h "lldb/Symbol/Block.h"
/// @brief A class that describes a single lexical block.
///
/// A Function object owns a BlockList object which owns one or more
/// Block objects. The BlockList object contains a section offset
/// address range, and Block objects contain one or more ranges
/// which are offsets into that range. Blocks are can have discontiguous
/// ranges within the BlockList adress range, and each block can
/// contain child blocks each with their own sets of ranges.
///
/// Each block has a variable list that represents local, argument, and
/// static variables that are scoped to the block.
///
/// Inlined functions are representated by attaching a
/// InlineFunctionInfo shared pointer object to a block. Inlined
/// functions are represented as named blocks.
//----------------------------------------------------------------------
class Block :
    public UserID,
    public SymbolContextScope
{
public:
    typedef RangeArray<uint32_t, uint32_t, 1> RangeList;
    typedef RangeList::Entry Range;

    //------------------------------------------------------------------
    /// Construct with a User ID \a uid, \a depth.
    ///
    /// Initialize this block with the specified UID \a uid. The
    /// \a depth in the \a block_list is used to represent the parent,
    /// sibling, and child block information and also allows for partial
    /// parsing at the block level.
    ///
    /// @param[in] uid
    ///     The UID for a given block. This value is given by the
    ///     SymbolFile plug-in and can be any value that helps the
    ///     SymbolFile plug-in to match this block back to the debug
    ///     information data that it parses for further or more in
    ///     depth parsing. Common values would be the index into a
    ///     table, or an offset into the debug information.
    ///
    /// @param[in] depth
    ///     The integer depth of this block in the block list hierarchy.
    ///
    /// @param[in] block_list
    ///     The block list that this object belongs to.
    ///
    /// @see BlockList
    //------------------------------------------------------------------
    Block (lldb::user_id_t uid);

    //------------------------------------------------------------------
    /// Destructor.
    //------------------------------------------------------------------
    virtual ~Block ();

    //------------------------------------------------------------------
    /// Add a child to this object.
    ///
    /// @param[in] child_block_sp
    ///     A shared pointer to a child block that will get added to
    ///     this block.
    //------------------------------------------------------------------
    void
    AddChild (const lldb::BlockSP &child_block_sp);

    //------------------------------------------------------------------
    /// Add a new offset range to this block.
    ///
    /// @param[in] start_offset
    ///     An offset into this Function's address range that
    ///     describes the start address of a range for this block.
    ///
    /// @param[in] end_offset
    ///     An offset into this Function's address range that
    ///     describes the end address of a range for this block.
    //------------------------------------------------------------------
    void
    AddRange (const Range& range);

    void
    FinalizeRanges ();

    //------------------------------------------------------------------
    /// @copydoc SymbolContextScope::CalculateSymbolContext(SymbolContext*)
    ///
    /// @see SymbolContextScope
    //------------------------------------------------------------------
    virtual void
    CalculateSymbolContext(SymbolContext* sc);

    virtual lldb::ModuleSP
    CalculateSymbolContextModule ();

    virtual CompileUnit *
    CalculateSymbolContextCompileUnit ();

    virtual Function *
    CalculateSymbolContextFunction ();

    virtual Block *
    CalculateSymbolContextBlock ();

    //------------------------------------------------------------------
    /// Check if an offset is in one of the block offset ranges.
    ///
    /// @param[in] range_offset
    ///     An offset into the Function's address range.
    ///
    /// @return
    ///     Returns \b true if \a range_offset falls in one of this
    ///     block's ranges, \b false otherwise.
    //------------------------------------------------------------------
    bool
    Contains (lldb::addr_t range_offset) const;

    //------------------------------------------------------------------
    /// Check if a offset range is in one of the block offset ranges.
    ///
    /// @param[in] range
    ///     An offset range into the Function's address range.
    ///
    /// @return
    ///     Returns \b true if \a range falls in one of this
    ///     block's ranges, \b false otherwise.
    //------------------------------------------------------------------
    bool
    Contains (const Range& range) const;

    //------------------------------------------------------------------
    /// Check if this object contains "block" as a child block at any
    /// depth.
    ///
    /// @param[in] block
    ///     A potential child block.
    ///
    /// @return
    ///     Returns \b true if \a block is a child of this block, \b 
    ///     false otherwise.
    //------------------------------------------------------------------
    bool
    Contains (const Block *block) const;

    //------------------------------------------------------------------
    /// Dump the block contents.
    ///
    /// @param[in] s
    ///     The stream to which to dump the object descripton.
    ///
    /// @param[in] base_addr
    ///     The resolved start address of the Function's address
    ///     range. This should be resolved as the file or load address
    ///     prior to passing the value into this function for dumping.
    ///
    /// @param[in] depth
    ///     Limit the number of levels deep that this function should
    ///     print as this block can contain child blocks. Specify
    ///     INT_MAX to dump all child blocks.
    ///
    /// @param[in] show_context
    ///     If \b true, variables will dump their context information.
    //------------------------------------------------------------------
    void
    Dump (Stream *s, lldb::addr_t base_addr, int32_t depth, bool show_context) const;

    //------------------------------------------------------------------
    /// @copydoc SymbolContextScope::DumpSymbolContext(Stream*)
    ///
    /// @see SymbolContextScope
    //------------------------------------------------------------------
    virtual void
    DumpSymbolContext(Stream *s);

    void
    DumpAddressRanges (Stream *s,
                       lldb::addr_t base_addr);
                      
    void
    GetDescription (Stream *s, 
                    Function *function, 
                    lldb::DescriptionLevel level, 
                    Target *target) const;
    
    //------------------------------------------------------------------
    /// Get the parent block.
    ///
    /// @return
    ///     The parent block pointer, or NULL if this block has no 
    ///     parent.
    //------------------------------------------------------------------
    Block *
    GetParent () const;
    
    
    //------------------------------------------------------------------
    /// Get the inlined block that contains this block.
    ///
    /// @return
    ///     If this block contains inlined function info, it will return
    ///     this block, else parent blocks will be searched to see if
    ///     any contain this block. NULL will be returned if this block
    ///     nor any parent blocks are inlined function blocks.
    //------------------------------------------------------------------
    Block *
    GetContainingInlinedBlock ();

    //------------------------------------------------------------------
    /// Get the inlined parent block for this block.
    ///
    /// @return
    ///     The parent block pointer, or NULL if this block has no 
    ///     parent.
    //------------------------------------------------------------------
    Block *
    GetInlinedParent ();

    //------------------------------------------------------------------
    /// Get the sibling block for this block.
    ///
    /// @return
    ///     The sibling block pointer, or NULL if this block has no 
    ///     sibling.
    //------------------------------------------------------------------
    Block *
    GetSibling () const;

    //------------------------------------------------------------------
    /// Get the first child block.
    ///
    /// @return
    ///     The first child block pointer, or NULL if this block has no 
    ///     children.
    //------------------------------------------------------------------
    Block *
    GetFirstChild () const
    {
        if (m_children.empty())
            return NULL;
        return m_children.front().get();
    }

    //------------------------------------------------------------------
    /// Get the variable list for this block only.
    ///
    /// @param[in] can_create
    ///     If \b true, the variables can be parsed if they already
    ///     haven't been, else the current state of the block will be
    ///     returned. 
    ///
    /// @return
    ///     A variable list shared pointer that contains all variables
    ///     for this block.
    //------------------------------------------------------------------
    lldb::VariableListSP
    GetBlockVariableList (bool can_create);


    //------------------------------------------------------------------
    /// Get the variable list for this block and optionally all child
    /// blocks if \a get_child_variables is \b true.
    ///
    /// @param[in] get_child_variables
    ///     If \b true, all variables from all child blocks will be
    ///     added to the variable list.
    ///
    /// @param[in] can_create
    ///     If \b true, the variables can be parsed if they already
    ///     haven't been, else the current state of the block will be
    ///     returned. Passing \b true for this parameter can be used
    ///     to see the current state of what has been parsed up to this
    ///     point.
    ///
    /// @param[in] add_inline_child_block_variables
    ///     If this is \b false, no child variables of child blocks
    ///     that are inlined functions will be gotten. If \b true then
    ///     all child variables will be added regardless of whether they
    ///     come from inlined functions or not.
    ///
    /// @return
    ///     A variable list shared pointer that contains all variables
    ///     for this block.
    //------------------------------------------------------------------
    uint32_t
    AppendBlockVariables (bool can_create,
                          bool get_child_block_variables,
                          bool stop_if_child_block_is_inlined_function,
                          VariableList *variable_list);
                          
    //------------------------------------------------------------------
    /// Appends the variables from this block, and optionally from all
    /// parent blocks, to \a variable_list.
    ///
    /// @param[in] can_create
    ///     If \b true, the variables can be parsed if they already
    ///     haven't been, else the current state of the block will be
    ///     returned. Passing \b true for this parameter can be used
    ///     to see the current state of what has been parsed up to this
    ///     point.
    ///
    /// @param[in] get_parent_variables
    ///     If \b true, all variables from all parent blocks will be
    ///     added to the variable list.
    ///
    /// @param[in] stop_if_block_is_inlined_function
    ///     If \b true, all variables from all parent blocks will be
    ///     added to the variable list until there are no parent blocks
    ///     or the parent block has inlined function info.
    ///
    /// @param[in/out] variable_list
    ///     All variables in this block, and optionally all parent
    ///     blocks will be added to this list.
    ///
    /// @return
    ///     The number of variable that were appended to \a
    ///     variable_list.
    //------------------------------------------------------------------
    uint32_t
    AppendVariables (bool can_create, 
                     bool get_parent_variables, 
                     bool stop_if_block_is_inlined_function,
                     VariableList *variable_list);

    //------------------------------------------------------------------
    /// Get const accessor for any inlined function information.
    ///
    /// @return
    ///     A comst pointer to any inlined function information, or NULL
    ///     if this is a regular block.
    //------------------------------------------------------------------
    const InlineFunctionInfo*
    GetInlinedFunctionInfo () const
    {
        return m_inlineInfoSP.get();
    }
    
    clang::DeclContext *
    GetClangDeclContext();

    //------------------------------------------------------------------
    /// Get the memory cost of this object.
    ///
    /// Returns the cost of this object plus any owned objects from the
    /// ranges, variables, and inline function information.
    ///
    /// @return
    ///     The number of bytes that this object occupies in memory.
    //------------------------------------------------------------------
    size_t
    MemorySize() const;

    //------------------------------------------------------------------
    /// Set accessor for any inlined function information.
    ///
    /// @param[in] name
    ///     The method name for the inlined function. This value should
    ///     not be NULL.
    ///
    /// @param[in] mangled
    ///     The mangled method name for the inlined function. This can
    ///     be NULL if there is no mangled name for an inlined function
    ///     or if the name is the same as \a name.
    ///
    /// @param[in] decl_ptr
    ///     A optional pointer to declaration information for the
    ///     inlined function information. This value can be NULL to
    ///     indicate that no declaration information is available.
    ///
    /// @param[in] call_decl_ptr
    ///     Optional calling location declaration information that
    ///     describes from where this inlined function was called.
    //------------------------------------------------------------------
    void
    SetInlinedFunctionInfo (const char *name,
                            const char *mangled,
                            const Declaration *decl_ptr,
                            const Declaration *call_decl_ptr);


    void
    SetParentScope (SymbolContextScope *parent_scope)
    {
        m_parent_scope = parent_scope;
    }

    //------------------------------------------------------------------
    /// Set accessor for the variable list.
    ///
    /// Called by the SymbolFile plug-ins after they have parsed the
    /// variable lists and are ready to hand ownership of the list over
    /// to this object.
    ///
    /// @param[in] variable_list_sp
    ///     A shared pointer to a VariableList.
    //------------------------------------------------------------------
    void
    SetVariableList (lldb::VariableListSP& variable_list_sp)
    {
        m_variable_list_sp = variable_list_sp;
    }



    bool
    BlockInfoHasBeenParsed() const
    {
        return m_parsed_block_info;
    }
    
    void
    SetBlockInfoHasBeenParsed (bool b, bool set_children);

    Block *
    FindBlockByID (lldb::user_id_t block_id);

    size_t
    GetNumRanges () const
    {
        return m_ranges.GetSize();
    }

    bool
    GetRangeContainingOffset (const lldb::addr_t offset, Range &range);

    bool
    GetRangeContainingAddress (const Address& addr, AddressRange &range);
    
    bool
    GetRangeContainingLoadAddress (lldb::addr_t load_addr, Target &target, AddressRange &range);

    uint32_t
    GetRangeIndexContainingAddress (const Address& addr);

    //------------------------------------------------------------------
    // Since blocks might have multiple discontiguous addresss ranges,
    // we need to be able to get at any of the address ranges in a block.
    //------------------------------------------------------------------
    bool
    GetRangeAtIndex (uint32_t range_idx, 
                     AddressRange &range);

    bool
    GetStartAddress (Address &addr);
    
    void
    SetDidParseVariables (bool b, bool set_children);

protected:
    typedef std::vector<lldb::BlockSP> collection;
    //------------------------------------------------------------------
    // Member variables.
    //------------------------------------------------------------------
    SymbolContextScope *m_parent_scope;
    collection m_children;
    RangeList m_ranges;
    lldb::InlineFunctionInfoSP m_inlineInfoSP; ///< Inlined function information.
    lldb::VariableListSP m_variable_list_sp; ///< The variable list for all local, static and paramter variables scoped to this block.
    bool m_parsed_block_info:1,         ///< Set to true if this block and it's children have all been parsed
         m_parsed_block_variables:1,
         m_parsed_child_blocks:1;

    // A parent of child blocks can be asked to find a sibling block given
    // one of its child blocks
    Block *
    GetSiblingForChild (const Block *child_block) const;

private:
    DISALLOW_COPY_AND_ASSIGN (Block);
};


} // namespace lldb_private

#endif  // liblldb_Block_h_