//===-- SymbolContext.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_SymbolContext_h_
#define liblldb_SymbolContext_h_

#include <memory>
#include <string>
#include <vector>

#include "lldb/Core/Address.h"
#include "lldb/Core/Mangled.h"
#include "lldb/Symbol/LineEntry.h"
#include "lldb/Utility/Iterable.h"
#include "lldb/lldb-private.h"

namespace lldb_private {

class SymbolContextScope;

/// \class SymbolContext SymbolContext.h "lldb/Symbol/SymbolContext.h" Defines
/// a symbol context baton that can be handed other debug core functions.
///
/// Many debugger functions require a context when doing lookups. This class
/// provides a common structure that can be used as the result of a query that
/// can contain a single result. Examples of such queries include
///     \li Looking up a load address.
class SymbolContext {
public:
  /// Default constructor.
  ///
  /// Initialize all pointer members to nullptr and all struct members to
  /// their default state.
  SymbolContext();

  /// Construct with an object that knows how to reconstruct its symbol
  /// context.
  ///
  /// \param[in] sc_scope
  ///     A symbol context scope object that knows how to reconstruct
  ///     it's context.
  explicit SymbolContext(SymbolContextScope *sc_scope);

  /// Construct with module, and optional compile unit, function, block, line
  /// table, line entry and symbol.
  ///
  /// Initialize all pointer to the specified values.
  ///
  /// \param[in] module
  ///     A Module pointer to the module for this context.
  ///
  /// \param[in] comp_unit
  ///     A CompileUnit pointer to the compile unit for this context.
  ///
  /// \param[in] function
  ///     A Function pointer to the function for this context.
  ///
  /// \param[in] block
  ///     A Block pointer to the deepest block for this context.
  ///
  /// \param[in] line_entry
  ///     A LineEntry pointer to the line entry for this context.
  ///
  /// \param[in] symbol
  ///     A Symbol pointer to the symbol for this context.
  explicit SymbolContext(const lldb::TargetSP &target_sp,
                         const lldb::ModuleSP &module_sp,
                         CompileUnit *comp_unit = nullptr,
                         Function *function = nullptr, Block *block = nullptr,
                         LineEntry *line_entry = nullptr,
                         Symbol *symbol = nullptr);

  // This version sets the target to a NULL TargetSP if you don't know it.
  explicit SymbolContext(const lldb::ModuleSP &module_sp,
                         CompileUnit *comp_unit = nullptr,
                         Function *function = nullptr, Block *block = nullptr,
                         LineEntry *line_entry = nullptr,
                         Symbol *symbol = nullptr);

  ~SymbolContext();

  /// Assignment operator.
  ///
  /// Copies the address value from another SymbolContext object \a rhs into
  /// \a this object.
  ///
  /// \param[in] rhs
  ///     A const SymbolContext object reference to copy.
  ///
  /// \return
  ///     A const SymbolContext object reference to \a this.
  const SymbolContext &operator=(const SymbolContext &rhs);

  /// Clear the object's state.
  ///
  /// Resets all pointer members to nullptr, and clears any class objects to
  /// their default state.
  void Clear(bool clear_target);

  /// Dump a description of this object to a Stream.
  ///
  /// Dump a description of the contents of this object to the supplied stream
  /// \a s.
  ///
  /// \param[in] s
  ///     The stream to which to dump the object description.
  void Dump(Stream *s, Target *target) const;

  /// Dump the stop context in this object to a Stream.
  ///
  /// Dump the best description of this object to the stream. The information
  /// displayed depends on the amount and quality of the information in this
  /// context. If a module, function, file and line number are available, they
  /// will be dumped. If only a module and function or symbol name with offset
  /// is available, that will be output. Else just the address at which the
  /// target was stopped will be displayed.
  ///
  /// \param[in] s
  ///     The stream to which to dump the object description.
  ///
  /// \param[in] so_addr
  ///     The resolved section offset address.
  ///
  /// \param[in] show_fullpaths
  ///     When printing file paths (with the Module), whether the
  ///     base name of the Module should be printed or the full path.
  ///
  /// \param[in] show_module
  ///     Whether the module name should be printed followed by a
  ///     grave accent "`" character.
  ///
  /// \param[in] show_inlined_frames
  ///     If a given pc is in inlined function(s), whether the inlined
  ///     functions should be printed on separate lines in addition to
  ///     the concrete function containing the pc.
  ///
  /// \param[in] show_function_arguments
  ///     If false, this method will try to elide the function argument
  ///     types when printing the function name.  This may be ambiguous
  ///     for languages that have function overloading - but it may
  ///     make the "function name" too long to include all the argument
  ///     types.
  ///
  /// \param[in] show_function_name
  ///     Normally this should be true - the function/symbol name should
  ///     be printed.  In disassembly formatting, where we want a format
  ///     like "<*+36>", this should be false and "*" will be printed
  ///     instead.
  bool DumpStopContext(Stream *s, ExecutionContextScope *exe_scope,
                       const Address &so_addr, bool show_fullpaths,
                       bool show_module, bool show_inlined_frames,
                       bool show_function_arguments,
                       bool show_function_name) const;

  /// Get the address range contained within a symbol context.
  ///
  /// Address range priority is as follows:
  ///     - line_entry address range if line_entry is valid and
  ///     eSymbolContextLineEntry is set in \a scope
  ///     - block address range if block is not nullptr and eSymbolContextBlock
  ///     is set in \a scope
  ///     - function address range if function is not nullptr and
  ///     eSymbolContextFunction is set in \a scope
  ///     - symbol address range if symbol is not nullptr and
  ///     eSymbolContextSymbol is set in \a scope
  ///
  /// \param[in] scope
  ///     A mask of symbol context bits telling this function which
  ///     address ranges it can use when trying to extract one from
  ///     the valid (non-nullptr) symbol context classes.
  ///
  /// \param[in] range_idx
  ///     The address range index to grab. Since many functions and
  ///     blocks are not always contiguous, they may have more than
  ///     one address range.
  ///
  /// \param[in] use_inline_block_range
  ///     If \a scope has the eSymbolContextBlock bit set, and there
  ///     is a valid block in the symbol context, return the block
  ///     address range for the containing inline function block, not
  ///     the deepest most block. This allows us to extract information
  ///     for the address range of the inlined function block, not
  ///     the deepest lexical block.
  ///
  /// \param[out] range
  ///     An address range object that will be filled in if \b true
  ///     is returned.
  ///
  /// \return
  ///     \b True if this symbol context contains items that describe
  ///     an address range, \b false otherwise.
  bool GetAddressRange(uint32_t scope, uint32_t range_idx,
                       bool use_inline_block_range, AddressRange &range) const;

  bool GetAddressRangeFromHereToEndLine(uint32_t end_line, AddressRange &range,
                                        Status &error);

  /// Find the best global data symbol visible from this context.
  ///
  /// Symbol priority is:
  ///     - extern symbol in the current module if there is one
  ///     - non-extern symbol in the current module if there is one
  ///     - extern symbol in the target
  ///     - non-extern symbol in the target
  /// It is an error if the highest-priority result is ambiguous.
  ///
  /// \param[in] name
  ///     The name of the symbol to search for.
  ///
  /// \param[out] error
  ///     An error that will be populated with a message if there was an
  ///     ambiguous result.  The error will not be populated if no result
  ///     was found.
  ///
  /// \return
  ///     The symbol that was found, or \b nullptr if none was found.
  const Symbol *FindBestGlobalDataSymbol(ConstString name, Status &error);

  void GetDescription(Stream *s, lldb::DescriptionLevel level,
                      Target *target) const;

  uint32_t GetResolvedMask() const;

  lldb::LanguageType GetLanguage() const;

  /// Find a block that defines the function represented by this symbol
  /// context.
  ///
  /// If this symbol context points to a block that is an inlined function, or
  /// is contained within an inlined function, the block that defines the
  /// inlined function is returned.
  ///
  /// If this symbol context has no block in it, or the block is not itself an
  /// inlined function block or contained within one, we return the top level
  /// function block.
  ///
  /// This is a handy function to call when you want to get the block whose
  /// variable list will include the arguments for the function that is
  /// represented by this symbol context (whether the function is an inline
  /// function or not).
  ///
  /// \return
  ///     The block object pointer that defines the function that is
  ///     represented by this symbol context object, nullptr otherwise.
  Block *GetFunctionBlock();

  /// If this symbol context represents a function that is a method, return
  /// true and provide information about the method.
  ///
  /// \param[out] language
  ///     If \b true is returned, the language for the method.
  ///
  /// \param[out] is_instance_method
  ///     If \b true is returned, \b true if this is a instance method,
  ///     \b false if this is a static/class function.
  ///
  /// \param[out] language_object_name
  ///     If \b true is returned, the name of the artificial variable
  ///     for the language ("this" for C++, "self" for ObjC).
  ///
  /// \return
  ///     \b True if this symbol context represents a function that
  ///     is a method of a class, \b false otherwise.
  bool GetFunctionMethodInfo(lldb::LanguageType &language,
                             bool &is_instance_method,
                             ConstString &language_object_name);

  /// Sorts the types in TypeMap according to SymbolContext to TypeList
  ///
  void SortTypeList(TypeMap &type_map, TypeList &type_list) const;

  /// Find a name of the innermost function for the symbol context.
  ///
  /// For instance, if the symbol context contains an inlined block, it will
  /// return the inlined function name.
  ///
  /// \param[in] prefer_mangled
  ///    if \btrue, then the mangled name will be returned if there
  ///    is one.  Otherwise the unmangled name will be returned if it
  ///    is available.
  ///
  /// \return
  ///     The name of the function represented by this symbol context.
  ConstString GetFunctionName(
      Mangled::NamePreference preference = Mangled::ePreferDemangled) const;

  /// Get the line entry that corresponds to the function.
  ///
  /// If the symbol context contains an inlined block, the line entry for the
  /// start address of the inlined function will be returned, otherwise the
  /// line entry for the start address of the function will be returned. This
  /// can be used after doing a Module::FindFunctions(...) or
  /// ModuleList::FindFunctions(...) call in order to get the correct line
  /// table information for the symbol context. it will return the inlined
  /// function name.
  ///
  /// \param[in] prefer_mangled
  ///    if \btrue, then the mangled name will be returned if there
  ///    is one.  Otherwise the unmangled name will be returned if it
  ///    is available.
  ///
  /// \return
  ///     The name of the function represented by this symbol context.
  LineEntry GetFunctionStartLineEntry() const;

  /// Find the block containing the inlined block that contains this block.
  ///
  /// For instance, if the symbol context contains an inlined block, it will
  /// return the inlined function name.
  ///
  /// \param[in] curr_frame_pc
  ///    The address within the block of this object.
  ///
  /// \param[out] next_frame_sc
  ///     A new symbol context that does what the title says it does.
  ///
  /// \param[out] next_frame_addr
  ///     This is what you should report as the PC in \a next_frame_sc.
  ///
  /// \return
  ///     \b true if this SymbolContext specifies a block contained in an
  ///     inlined block.  If this returns \b true, \a next_frame_sc and
  ///     \a next_frame_addr will be filled in correctly.
  bool GetParentOfInlinedScope(const Address &curr_frame_pc,
                               SymbolContext &next_frame_sc,
                               Address &inlined_frame_addr) const;

  // Member variables
  lldb::TargetSP target_sp; ///< The Target for a given query
  lldb::ModuleSP module_sp; ///< The Module for a given query
  CompileUnit *comp_unit;   ///< The CompileUnit for a given query
  Function *function;       ///< The Function for a given query
  Block *block;             ///< The Block for a given query
  LineEntry line_entry;     ///< The LineEntry for a given query
  Symbol *symbol;           ///< The Symbol for a given query
  Variable *variable;       ///< The global variable matching the given query
};

class SymbolContextSpecifier {
public:
  enum SpecificationType {
    eNothingSpecified = 0,
    eModuleSpecified = 1 << 0,
    eFileSpecified = 1 << 1,
    eLineStartSpecified = 1 << 2,
    eLineEndSpecified = 1 << 3,
    eFunctionSpecified = 1 << 4,
    eClassOrNamespaceSpecified = 1 << 5,
    eAddressRangeSpecified = 1 << 6
  };

  // This one produces a specifier that matches everything...
  SymbolContextSpecifier(const lldb::TargetSP &target_sp);

  ~SymbolContextSpecifier();

  bool AddSpecification(const char *spec_string, SpecificationType type);

  bool AddLineSpecification(uint32_t line_no, SpecificationType type);

  void Clear();

  bool SymbolContextMatches(SymbolContext &sc);

  bool AddressMatches(lldb::addr_t addr);

  void GetDescription(Stream *s, lldb::DescriptionLevel level) const;

private:
  lldb::TargetSP m_target_sp;
  std::string m_module_spec;
  lldb::ModuleSP m_module_sp;
  std::unique_ptr<FileSpec> m_file_spec_up;
  size_t m_start_line;
  size_t m_end_line;
  std::string m_function_spec;
  std::string m_class_name;
  std::unique_ptr<AddressRange> m_address_range_up;
  uint32_t m_type; // Or'ed bits from SpecificationType
};

/// \class SymbolContextList SymbolContext.h "lldb/Symbol/SymbolContext.h"
/// Defines a list of symbol context objects.
///
/// This class provides a common structure that can be used to contain the
/// result of a query that can contain a multiple results. Examples of such
/// queries include:
///     \li Looking up a function by name.
///     \li Finding all addresses for a specified file and line number.
class SymbolContextList {
public:
  /// Default constructor.
  ///
  /// Initialize with an empty list.
  SymbolContextList();

  /// Destructor.
  ~SymbolContextList();

  /// Append a new symbol context to the list.
  ///
  /// \param[in] sc
  ///     A symbol context to append to the list.
  void Append(const SymbolContext &sc);

  void Append(const SymbolContextList &sc_list);

  bool AppendIfUnique(const SymbolContext &sc, bool merge_symbol_into_function);

  uint32_t AppendIfUnique(const SymbolContextList &sc_list,
                          bool merge_symbol_into_function);

  /// Clear the object's state.
  ///
  /// Clears the symbol context list.
  void Clear();

  /// Dump a description of this object to a Stream.
  ///
  /// Dump a description of the contents of each symbol context in the list to
  /// the supplied stream \a s.
  ///
  /// \param[in] s
  ///     The stream to which to dump the object description.
  void Dump(Stream *s, Target *target) const;

  /// Get accessor for a symbol context at index \a idx.
  ///
  /// Dump a description of the contents of each symbol context in the list to
  /// the supplied stream \a s.
  ///
  /// \param[in] idx
  ///     The zero based index into the symbol context list.
  ///
  /// \param[out] sc
  ///     A reference to the symbol context to fill in.
  ///
  /// \return
  ///     Returns \b true if \a idx was a valid index into this
  ///     symbol context list and \a sc was filled in, \b false
  ///     otherwise.
  bool GetContextAtIndex(size_t idx, SymbolContext &sc) const;

  /// Direct reference accessor for a symbol context at index \a idx.
  ///
  /// The index \a idx must be a valid index, no error checking will be done
  /// to ensure that it is valid.
  ///
  /// \param[in] idx
  ///     The zero based index into the symbol context list.
  ///
  /// \return
  ///     A const reference to the symbol context to fill in.
  SymbolContext &operator[](size_t idx) { return m_symbol_contexts[idx]; }

  const SymbolContext &operator[](size_t idx) const {
    return m_symbol_contexts[idx];
  }

  bool RemoveContextAtIndex(size_t idx);

  /// Get accessor for a symbol context list size.
  ///
  /// \return
  ///     Returns the number of symbol context objects in the list.
  uint32_t GetSize() const;

  uint32_t NumLineEntriesWithLine(uint32_t line) const;

  void GetDescription(Stream *s, lldb::DescriptionLevel level,
                      Target *target) const;

protected:
  typedef std::vector<SymbolContext>
      collection; ///< The collection type for the list.

  // Member variables.
  collection m_symbol_contexts; ///< The list of symbol contexts.

public:
  typedef AdaptedIterable<collection, SymbolContext, vector_adapter>
      SymbolContextIterable;
  SymbolContextIterable SymbolContexts() {
    return SymbolContextIterable(m_symbol_contexts);
  }
};

bool operator==(const SymbolContext &lhs, const SymbolContext &rhs);
bool operator!=(const SymbolContext &lhs, const SymbolContext &rhs);

bool operator==(const SymbolContextList &lhs, const SymbolContextList &rhs);
bool operator!=(const SymbolContextList &lhs, const SymbolContextList &rhs);

} // namespace lldb_private

#endif // liblldb_SymbolContext_h_
