Block.h revision 360784
176259Sgreen//===-- Block.h -------------------------------------------------*- C++ -*-===//
276259Sgreen//
376259Sgreen// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
476259Sgreen// See https://llvm.org/LICENSE.txt for license information.
576259Sgreen// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
676259Sgreen//
776259Sgreen//===----------------------------------------------------------------------===//
876259Sgreen
976259Sgreen#ifndef liblldb_Block_h_
1076259Sgreen#define liblldb_Block_h_
1176259Sgreen
1276259Sgreen#include "lldb/Core/AddressRange.h"
1376259Sgreen#include "lldb/Symbol/CompilerType.h"
1476259Sgreen#include "lldb/Symbol/LineEntry.h"
1576259Sgreen#include "lldb/Symbol/SymbolContext.h"
1676259Sgreen#include "lldb/Symbol/SymbolContextScope.h"
1776259Sgreen#include "lldb/Utility/RangeMap.h"
1876259Sgreen#include "lldb/Utility/Stream.h"
1976259Sgreen#include "lldb/Utility/UserID.h"
2076259Sgreen#include "lldb/lldb-private.h"
2176259Sgreen#include <vector>
2276259Sgreen
2376259Sgreennamespace lldb_private {
2476259Sgreen
2576259Sgreen/// \class Block Block.h "lldb/Symbol/Block.h"
26113908Sdes/// A class that describes a single lexical block.
2776259Sgreen///
2876259Sgreen/// A Function object owns a BlockList object which owns one or more
2976259Sgreen/// Block objects. The BlockList object contains a section offset address
3076259Sgreen/// range, and Block objects contain one or more ranges which are offsets into
3176259Sgreen/// that range. Blocks are can have discontiguous ranges within the BlockList
3292555Sdes/// address range, and each block can contain child blocks each with their own
3376259Sgreen/// sets of ranges.
3476259Sgreen///
3576259Sgreen/// Each block has a variable list that represents local, argument, and static
3676259Sgreen/// variables that are scoped to the block.
3776259Sgreen///
3892555Sdes/// Inlined functions are represented by attaching a InlineFunctionInfo shared
3976259Sgreen/// pointer object to a block. Inlined functions are represented as named
4076259Sgreen/// blocks.
4176259Sgreenclass Block : public UserID, public SymbolContextScope {
4276259Sgreenpublic:
4376259Sgreen  typedef RangeArray<uint32_t, uint32_t, 1> RangeList;
4476259Sgreen  typedef RangeList::Entry Range;
4576259Sgreen
4676259Sgreen  /// Construct with a User ID \a uid, \a depth.
4776259Sgreen  ///
4892555Sdes  /// Initialize this block with the specified UID \a uid. The \a depth in the
4976259Sgreen  /// \a block_list is used to represent the parent, sibling, and child block
5076259Sgreen  /// information and also allows for partial parsing at the block level.
5176259Sgreen  ///
5276259Sgreen  /// \param[in] uid
5392555Sdes  ///     The UID for a given block. This value is given by the
5476259Sgreen  ///     SymbolFile plug-in and can be any value that helps the
5576259Sgreen  ///     SymbolFile plug-in to match this block back to the debug
5676259Sgreen  ///     information data that it parses for further or more in
5776259Sgreen  ///     depth parsing. Common values would be the index into a
5876259Sgreen  ///     table, or an offset into the debug information.
5976259Sgreen  ///
6092555Sdes  /// \see BlockList
6176259Sgreen  Block(lldb::user_id_t uid);
6276259Sgreen
6376259Sgreen  /// Destructor.
6476259Sgreen  ~Block() override;
6576259Sgreen
6692555Sdes  /// Add a child to this object.
6792555Sdes  ///
6876259Sgreen  /// \param[in] child_block_sp
6976259Sgreen  ///     A shared pointer to a child block that will get added to
7092555Sdes  ///     this block.
7192555Sdes  void AddChild(const lldb::BlockSP &child_block_sp);
7292555Sdes
7392555Sdes  /// Add a new offset range to this block.
7492555Sdes  void AddRange(const Range &range);
7592555Sdes
7692555Sdes  void FinalizeRanges();
7792555Sdes
7892555Sdes  /// \copydoc SymbolContextScope::CalculateSymbolContext(SymbolContext*)
7992555Sdes  ///
8092555Sdes  /// \see SymbolContextScope
8192555Sdes  void CalculateSymbolContext(SymbolContext *sc) override;
8292555Sdes
8392555Sdes  lldb::ModuleSP CalculateSymbolContextModule() override;
8492555Sdes
8592555Sdes  CompileUnit *CalculateSymbolContextCompileUnit() override;
8692555Sdes
8792555Sdes  Function *CalculateSymbolContextFunction() override;
8892555Sdes
8992555Sdes  Block *CalculateSymbolContextBlock() override;
9092555Sdes
9192555Sdes  /// Check if an offset is in one of the block offset ranges.
9292555Sdes  ///
9392555Sdes  /// \param[in] range_offset
9492555Sdes  ///     An offset into the Function's address range.
9592555Sdes  ///
9692555Sdes  /// \return
9792555Sdes  ///     Returns \b true if \a range_offset falls in one of this
9892555Sdes  ///     block's ranges, \b false otherwise.
9992555Sdes  bool Contains(lldb::addr_t range_offset) const;
10092555Sdes
10192555Sdes  /// Check if a offset range is in one of the block offset ranges.
10292555Sdes  ///
10392555Sdes  /// \param[in] range
10492555Sdes  ///     An offset range into the Function's address range.
10592555Sdes  ///
10692555Sdes  /// \return
10792555Sdes  ///     Returns \b true if \a range falls in one of this
108113908Sdes  ///     block's ranges, \b false otherwise.
10992555Sdes  bool Contains(const Range &range) const;
11092555Sdes
11192555Sdes  /// Check if this object contains "block" as a child block at any depth.
11292555Sdes  ///
11376259Sgreen  /// \param[in] block
11476259Sgreen  ///     A potential child block.
11576259Sgreen  ///
11692555Sdes  /// \return
11776259Sgreen  ///     Returns \b true if \a block is a child of this block, \b
11876259Sgreen  ///     false otherwise.
11976259Sgreen  bool Contains(const Block *block) const;
12076259Sgreen
12176259Sgreen  /// Dump the block contents.
12276259Sgreen  ///
12376259Sgreen  /// \param[in] s
12476259Sgreen  ///     The stream to which to dump the object description.
12576259Sgreen  ///
12676259Sgreen  /// \param[in] base_addr
12776259Sgreen  ///     The resolved start address of the Function's address
12876259Sgreen  ///     range. This should be resolved as the file or load address
12976259Sgreen  ///     prior to passing the value into this function for dumping.
13076259Sgreen  ///
13176259Sgreen  /// \param[in] depth
13276259Sgreen  ///     Limit the number of levels deep that this function should
13376259Sgreen  ///     print as this block can contain child blocks. Specify
13476259Sgreen  ///     INT_MAX to dump all child blocks.
13576259Sgreen  ///
13676259Sgreen  /// \param[in] show_context
13776259Sgreen  ///     If \b true, variables will dump their context information.
13876259Sgreen  void Dump(Stream *s, lldb::addr_t base_addr, int32_t depth,
13976259Sgreen            bool show_context) const;
14076259Sgreen
14176259Sgreen  /// \copydoc SymbolContextScope::DumpSymbolContext(Stream*)
14276259Sgreen  ///
14376259Sgreen  /// \see SymbolContextScope
14476259Sgreen  void DumpSymbolContext(Stream *s) override;
14576259Sgreen
14676259Sgreen  void DumpAddressRanges(Stream *s, lldb::addr_t base_addr);
14776259Sgreen
14876259Sgreen  void GetDescription(Stream *s, Function *function,
14976259Sgreen                      lldb::DescriptionLevel level, Target *target) const;
15076259Sgreen
15176259Sgreen  /// Get the parent block.
15276259Sgreen  ///
15376259Sgreen  /// \return
15476259Sgreen  ///     The parent block pointer, or nullptr if this block has no
15598937Sdes  ///     parent.
15692555Sdes  Block *GetParent() const;
15798937Sdes
15898937Sdes  /// Get the inlined block that contains this block.
15992555Sdes  ///
16098937Sdes  /// \return
16198937Sdes  ///     If this block contains inlined function info, it will return
16276259Sgreen  ///     this block, else parent blocks will be searched to see if
16398937Sdes  ///     any contain this block. nullptr will be returned if this block
16476259Sgreen  ///     nor any parent blocks are inlined function blocks.
16576259Sgreen  Block *GetContainingInlinedBlock();
16676259Sgreen
16776259Sgreen  /// Get the inlined parent block for this block.
16876259Sgreen  ///
16992555Sdes  /// \return
17092555Sdes  ///     The parent block pointer, or nullptr if this block has no
17192555Sdes  ///     parent.
17292555Sdes  Block *GetInlinedParent();
17392555Sdes
17492555Sdes  //------------------------------------------------------------------
17592555Sdes  /// Get the inlined block at the given call site that contains this block.
17676259Sgreen  ///
17776259Sgreen  /// @param[in] find_call_site
17876259Sgreen  ///     a declaration with the file and line of the call site to find.
17976259Sgreen  ///
18076259Sgreen  /// @return
18176259Sgreen  ///     If this block contains inlined function info and is at the call
18276259Sgreen  ///     site given by the file and line at the given \b declaration, then
18376259Sgreen  ///     it will return this block, otherwise the parent blocks will be
18476259Sgreen  ///     searched to see if any is at the call site. nullptr will be returned
18576259Sgreen  ///     if no block is found at the call site.
18676259Sgreen  //------------------------------------------------------------------
18776259Sgreen  Block *
18876259Sgreen  GetContainingInlinedBlockWithCallSite(const Declaration &find_call_site);
18992555Sdes
19092555Sdes  /// Get the sibling block for this block.
19192555Sdes  ///
19292555Sdes  /// \return
19392555Sdes  ///     The sibling block pointer, or nullptr if this block has no
19492555Sdes  ///     sibling.
19592555Sdes  Block *GetSibling() const;
19692555Sdes
19792555Sdes  /// Get the first child block.
19892555Sdes  ///
19992555Sdes  /// \return
20092555Sdes  ///     The first child block pointer, or nullptr if this block has no
20192555Sdes  ///     children.
20292555Sdes  Block *GetFirstChild() const {
20392555Sdes    return (m_children.empty() ? nullptr : m_children.front().get());
20492555Sdes  }
20592555Sdes
20692555Sdes  /// Get the variable list for this block only.
20792555Sdes  ///
20892555Sdes  /// \param[in] can_create
20992555Sdes  ///     If \b true, the variables can be parsed if they already
21092555Sdes  ///     haven't been, else the current state of the block will be
21192555Sdes  ///     returned.
21292555Sdes  ///
21392555Sdes  /// \return
21492555Sdes  ///     A variable list shared pointer that contains all variables
21592555Sdes  ///     for this block.
21692555Sdes  lldb::VariableListSP GetBlockVariableList(bool can_create);
21792555Sdes
21892555Sdes  /// Get the variable list for this block and optionally all child blocks if
21992555Sdes  /// \a get_child_variables is \b true.
22092555Sdes  ///
22192555Sdes  /// \param[in] can_create
22292555Sdes  ///     If \b true, the variables can be parsed if they already
22392555Sdes  ///     haven't been, else the current state of the block will be
22492555Sdes  ///     returned. Passing \b true for this parameter can be used
22592555Sdes  ///     to see the current state of what has been parsed up to this
22692555Sdes  ///     point.
22792555Sdes  ///
22892555Sdes  /// \param[in] get_child_block_variables
22992555Sdes  ///     If \b true, all variables from all child blocks will be
23092555Sdes  ///     added to the variable list.
23192555Sdes  ///
23292555Sdes  /// \return
23392555Sdes  ///     A variable list shared pointer that contains all variables
23492555Sdes  ///     for this block.
23592555Sdes  uint32_t AppendBlockVariables(bool can_create, bool get_child_block_variables,
23692555Sdes                                bool stop_if_child_block_is_inlined_function,
23792555Sdes                                const std::function<bool(Variable *)> &filter,
23892555Sdes                                VariableList *variable_list);
23992555Sdes
24092555Sdes  /// Appends the variables from this block, and optionally from all parent
24192555Sdes  /// blocks, to \a variable_list.
24292555Sdes  ///
24392555Sdes  /// \param[in] can_create
24492555Sdes  ///     If \b true, the variables can be parsed if they already
24592555Sdes  ///     haven't been, else the current state of the block will be
24692555Sdes  ///     returned. Passing \b true for this parameter can be used
24792555Sdes  ///     to see the current state of what has been parsed up to this
24892555Sdes  ///     point.
24992555Sdes  ///
25092555Sdes  /// \param[in] get_parent_variables
25192555Sdes  ///     If \b true, all variables from all parent blocks will be
25292555Sdes  ///     added to the variable list.
25392555Sdes  ///
25492555Sdes  /// \param[in] stop_if_block_is_inlined_function
25592555Sdes  ///     If \b true, all variables from all parent blocks will be
25692555Sdes  ///     added to the variable list until there are no parent blocks
25792555Sdes  ///     or the parent block has inlined function info.
25892555Sdes  ///
25992555Sdes  /// \param[in,out] variable_list
26092555Sdes  ///     All variables in this block, and optionally all parent
26192555Sdes  ///     blocks will be added to this list.
26292555Sdes  ///
26392555Sdes  /// \return
26492555Sdes  ///     The number of variable that were appended to \a
26592555Sdes  ///     variable_list.
26692555Sdes  uint32_t AppendVariables(bool can_create, bool get_parent_variables,
26792555Sdes                           bool stop_if_block_is_inlined_function,
26892555Sdes                           const std::function<bool(Variable *)> &filter,
26992555Sdes                           VariableList *variable_list);
27092555Sdes
27192555Sdes  /// Get const accessor for any inlined function information.
27292555Sdes  ///
27392555Sdes  /// \return
27492555Sdes  ///     A const pointer to any inlined function information, or nullptr
27592555Sdes  ///     if this is a regular block.
27692555Sdes  const InlineFunctionInfo *GetInlinedFunctionInfo() const {
27792555Sdes    return m_inlineInfoSP.get();
27892555Sdes  }
27992555Sdes
28092555Sdes  /// Get the symbol file which contains debug info for this block's
28192555Sdes  /// symbol context module.
28292555Sdes  ///
28392555Sdes  /// \return A pointer to the symbol file or nullptr.
28492555Sdes  SymbolFile *GetSymbolFile();
28592555Sdes
28692555Sdes  CompilerDeclContext GetDeclContext();
28792555Sdes
28892555Sdes  /// Get the memory cost of this object.
28992555Sdes  ///
29092555Sdes  /// Returns the cost of this object plus any owned objects from the ranges,
29192555Sdes  /// variables, and inline function information.
29292555Sdes  ///
29392555Sdes  /// \return
29492555Sdes  ///     The number of bytes that this object occupies in memory.
29592555Sdes  size_t MemorySize() const;
29692555Sdes
29792555Sdes  /// Set accessor for any inlined function information.
29892555Sdes  ///
29992555Sdes  /// \param[in] name
30092555Sdes  ///     The method name for the inlined function. This value should
30192555Sdes  ///     not be nullptr.
30292555Sdes  ///
30392555Sdes  /// \param[in] mangled
30492555Sdes  ///     The mangled method name for the inlined function. This can
30592555Sdes  ///     be nullptr if there is no mangled name for an inlined function
30692555Sdes  ///     or if the name is the same as \a name.
30792555Sdes  ///
30892555Sdes  /// \param[in] decl_ptr
30992555Sdes  ///     A optional pointer to declaration information for the
31092555Sdes  ///     inlined function information. This value can be nullptr to
31192555Sdes  ///     indicate that no declaration information is available.
31292555Sdes  ///
31392555Sdes  /// \param[in] call_decl_ptr
31492555Sdes  ///     Optional calling location declaration information that
31592555Sdes  ///     describes from where this inlined function was called.
31692555Sdes  void SetInlinedFunctionInfo(const char *name, const char *mangled,
31792555Sdes                              const Declaration *decl_ptr,
31892555Sdes                              const Declaration *call_decl_ptr);
31992555Sdes
32092555Sdes  void SetParentScope(SymbolContextScope *parent_scope) {
32192555Sdes    m_parent_scope = parent_scope;
32292555Sdes  }
32392555Sdes
32492555Sdes  /// Set accessor for the variable list.
32592555Sdes  ///
32698937Sdes  /// Called by the SymbolFile plug-ins after they have parsed the variable
32798937Sdes  /// lists and are ready to hand ownership of the list over to this object.
32898937Sdes  ///
32998937Sdes  /// \param[in] variable_list_sp
33098937Sdes  ///     A shared pointer to a VariableList.
33198937Sdes  void SetVariableList(lldb::VariableListSP &variable_list_sp) {
33298937Sdes    m_variable_list_sp = variable_list_sp;
33398937Sdes  }
33498937Sdes
33598937Sdes  bool BlockInfoHasBeenParsed() const { return m_parsed_block_info; }
33698937Sdes
33798937Sdes  void SetBlockInfoHasBeenParsed(bool b, bool set_children);
33898937Sdes
33998937Sdes  Block *FindBlockByID(lldb::user_id_t block_id);
34098937Sdes
34198937Sdes  size_t GetNumRanges() const { return m_ranges.GetSize(); }
34298937Sdes
34398937Sdes  bool GetRangeContainingOffset(const lldb::addr_t offset, Range &range);
34498937Sdes
34598937Sdes  bool GetRangeContainingAddress(const Address &addr, AddressRange &range);
34698937Sdes
34798937Sdes  bool GetRangeContainingLoadAddress(lldb::addr_t load_addr, Target &target,
34898937Sdes                                     AddressRange &range);
34998937Sdes
35098937Sdes  uint32_t GetRangeIndexContainingAddress(const Address &addr);
35198937Sdes
352  // Since blocks might have multiple discontiguous address ranges, we need to
353  // be able to get at any of the address ranges in a block.
354  bool GetRangeAtIndex(uint32_t range_idx, AddressRange &range);
355
356  bool GetStartAddress(Address &addr);
357
358  void SetDidParseVariables(bool b, bool set_children);
359
360protected:
361  typedef std::vector<lldb::BlockSP> collection;
362  // Member variables.
363  SymbolContextScope *m_parent_scope;
364  collection m_children;
365  RangeList m_ranges;
366  lldb::InlineFunctionInfoSP m_inlineInfoSP; ///< Inlined function information.
367  lldb::VariableListSP m_variable_list_sp; ///< The variable list for all local,
368                                           ///static and parameter variables
369                                           ///scoped to this block.
370  bool m_parsed_block_info : 1, ///< Set to true if this block and it's children
371                                ///have all been parsed
372      m_parsed_block_variables : 1, m_parsed_child_blocks : 1;
373
374  // A parent of child blocks can be asked to find a sibling block given
375  // one of its child blocks
376  Block *GetSiblingForChild(const Block *child_block) const;
377
378private:
379  DISALLOW_COPY_AND_ASSIGN(Block);
380};
381
382} // namespace lldb_private
383
384#endif // liblldb_Block_h_
385