//===-- 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 LLDB_SYMBOL_BLOCK_H
#define LLDB_SYMBOL_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 RangeVector<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);

  Block *FindInnermostBlockByOffset(const lldb::addr_t offset);

  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:
  Block(const Block &) = delete;
  const Block &operator=(const Block &) = delete;
};

} // namespace lldb_private

#endif // LLDB_SYMBOL_BLOCK_H
