//===-- 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.
  ///
  /// \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.
  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] 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_child_block_variables
  ///     If \b true, all variables from all child blocks will be
  ///     added to the variable list.
  ///
  /// \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_
