| //===-- Block.h -------------------------------------------------*- C++ -*-===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef liblldb_Block_h_ |
| #define liblldb_Block_h_ |
| |
| #include "lldb/Core/AddressRange.h" |
| #include "lldb/Symbol/CompilerType.h" |
| #include "lldb/Symbol/LineEntry.h" |
| #include "lldb/Symbol/SymbolContext.h" |
| #include "lldb/Symbol/SymbolContextScope.h" |
| #include "lldb/Utility/RangeMap.h" |
| #include "lldb/Utility/Stream.h" |
| #include "lldb/Utility/UserID.h" |
| #include "lldb/lldb-private.h" |
| #include <vector> |
| |
| namespace lldb_private { |
| |
| /// \class Block Block.h "lldb/Symbol/Block.h" |
| /// 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 |
| /// address 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 represented 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. |
| ~Block() override; |
| |
| /// 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 |
| void CalculateSymbolContext(SymbolContext *sc) override; |
| |
| lldb::ModuleSP CalculateSymbolContextModule() override; |
| |
| CompileUnit *CalculateSymbolContextCompileUnit() override; |
| |
| Function *CalculateSymbolContextFunction() override; |
| |
| Block *CalculateSymbolContextBlock() override; |
| |
| /// 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 description. |
| /// |
| /// \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 |
| void DumpSymbolContext(Stream *s) override; |
| |
| 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 nullptr 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. nullptr 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 nullptr if this block has no |
| /// parent. |
| Block *GetInlinedParent(); |
| |
| //------------------------------------------------------------------ |
| /// Get the inlined block at the given call site that contains this block. |
| /// |
| /// @param[in] find_call_site |
| /// a declaration with the file and line of the call site to find. |
| /// |
| /// @return |
| /// If this block contains inlined function info and is at the call |
| /// site given by the file and line at the given \b declaration, then |
| /// it will return this block, otherwise the parent blocks will be |
| /// searched to see if any is at the call site. nullptr will be returned |
| /// if no block is found at the call site. |
| //------------------------------------------------------------------ |
| Block * |
| GetContainingInlinedBlockWithCallSite(const Declaration &find_call_site); |
| |
| /// Get the sibling block for this block. |
| /// |
| /// \return |
| /// The sibling block pointer, or nullptr if this block has no |
| /// sibling. |
| Block *GetSibling() const; |
| |
| /// Get the first child block. |
| /// |
| /// \return |
| /// The first child block pointer, or nullptr if this block has no |
| /// children. |
| Block *GetFirstChild() const { |
| return (m_children.empty() ? nullptr : 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, |
| const std::function<bool(Variable *)> &filter, |
| 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, |
| const std::function<bool(Variable *)> &filter, |
| VariableList *variable_list); |
| |
| /// Get const accessor for any inlined function information. |
| /// |
| /// \return |
| /// A const pointer to any inlined function information, or nullptr |
| /// if this is a regular block. |
| const InlineFunctionInfo *GetInlinedFunctionInfo() const { |
| return m_inlineInfoSP.get(); |
| } |
| |
| /// Get the symbol file which contains debug info for this block's |
| /// symbol context module. |
| /// |
| /// \return A pointer to the symbol file or nullptr. |
| SymbolFile *GetSymbolFile(); |
| |
| CompilerDeclContext GetDeclContext(); |
| |
| /// 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 nullptr. |
| /// |
| /// \param[in] mangled |
| /// The mangled method name for the inlined function. This can |
| /// be nullptr 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 nullptr 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 address 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 parameter 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_ |