//===-- 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_
