//===-- Function.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_Function_h_
#define liblldb_Function_h_

#include "lldb/Core/AddressRange.h"
#include "lldb/Core/Mangled.h"
#include "lldb/Expression/DWARFExpression.h"
#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/Declaration.h"
#include "lldb/Utility/UserID.h"
#include "llvm/ADT/ArrayRef.h"

namespace lldb_private {

class ExecutionContext;

/// \class FunctionInfo Function.h "lldb/Symbol/Function.h"
/// A class that contains generic function information.
///
/// This provides generic function information that gets reused between inline
/// functions and function types.
class FunctionInfo {
public:
  /// Construct with the function method name and optional declaration
  /// information.
  ///
  /// \param[in] name
  ///     A C string name for the method name for this function. This
  ///     value should not be the mangled named, but the simple method
  ///     name.
  ///
  /// \param[in] decl_ptr
  ///     Optional declaration information that describes where the
  ///     function was declared. This can be NULL.
  FunctionInfo(const char *name, const Declaration *decl_ptr);

  /// Construct with the function method name and optional declaration
  /// information.
  ///
  /// \param[in] name
  ///     A name for the method name for this function. This value
  ///     should not be the mangled named, but the simple method name.
  ///
  /// \param[in] decl_ptr
  ///     Optional declaration information that describes where the
  ///     function was declared. This can be NULL.
  FunctionInfo(ConstString name, const Declaration *decl_ptr);

  /// Destructor.
  ///
  /// The destructor is virtual since classes inherit from this class.
  virtual ~FunctionInfo();

  /// Compare two function information objects.
  ///
  /// First compares the method names, and if equal, then compares the
  /// declaration information.
  ///
  /// \param[in] lhs
  ///     The Left Hand Side const FunctionInfo object reference.
  ///
  /// \param[in] rhs
  ///     The Right Hand Side const FunctionInfo object reference.
  ///
  /// \return
  ///     -1 if lhs < rhs
  ///     0 if lhs == rhs
  ///     1 if lhs > rhs
  static int Compare(const FunctionInfo &lhs, const FunctionInfo &rhs);

  /// 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, bool show_fullpaths) const;

  /// Get accessor for the declaration information.
  ///
  /// \return
  ///     A reference to the declaration object.
  Declaration &GetDeclaration();

  /// Get const accessor for the declaration information.
  ///
  /// \return
  ///     A const reference to the declaration object.
  const Declaration &GetDeclaration() const;

  /// Get accessor for the method name.
  ///
  /// \return
  ///     A const reference to the method name object.
  ConstString GetName() const;

  /// Get the memory cost of this object.
  ///
  /// \return
  ///     The number of bytes that this object occupies in memory.
  ///     The returned value does not include the bytes for any
  ///     shared string values.
  ///
  /// \see ConstString::StaticMemorySize ()
  virtual size_t MemorySize() const;

protected:
  // Member variables.
  ConstString m_name;        ///< Function method name (not a mangled name).
  Declaration m_declaration; ///< Information describing where this function
                             ///information was defined.
};

/// \class InlineFunctionInfo Function.h "lldb/Symbol/Function.h"
/// A class that describes information for an inlined function.
class InlineFunctionInfo : public FunctionInfo {
public:
  /// Construct with the function method name, mangled name, and optional
  /// declaration information.
  ///
  /// \param[in] name
  ///     A C string name for the method name for this function. This
  ///     value should not be the mangled named, but the simple method
  ///     name.
  ///
  /// \param[in] mangled
  ///     A C string name for the mangled name for this function. This
  ///     value can be NULL if there is no mangled information.
  ///
  /// \param[in] decl_ptr
  ///     Optional declaration information that describes where the
  ///     function was declared. This can be NULL.
  ///
  /// \param[in] call_decl_ptr
  ///     Optional calling location declaration information that
  ///     describes from where this inlined function was called.
  InlineFunctionInfo(const char *name, llvm::StringRef mangled,
                     const Declaration *decl_ptr,
                     const Declaration *call_decl_ptr);

  /// Construct with the function method name, mangled name, and optional
  /// declaration information.
  ///
  /// \param[in] name
  ///     A name for the method name for this function. This value
  ///     should not be the mangled named, but the simple method name.
  ///
  /// \param[in] mangled
  ///     A name for the mangled name for this function. This value
  ///     can be empty if there is no mangled information.
  ///
  /// \param[in] decl_ptr
  ///     Optional declaration information that describes where the
  ///     function was declared. This can be NULL.
  ///
  /// \param[in] call_decl_ptr
  ///     Optional calling location declaration information that
  ///     describes from where this inlined function was called.
  InlineFunctionInfo(ConstString name, const Mangled &mangled,
                     const Declaration *decl_ptr,
                     const Declaration *call_decl_ptr);

  /// Destructor.
  ~InlineFunctionInfo() override;

  /// Compare two inlined function information objects.
  ///
  /// First compares the FunctionInfo objects, and if equal, compares the
  /// mangled names.
  ///
  /// \param[in] lhs
  ///     The Left Hand Side const InlineFunctionInfo object
  ///     reference.
  ///
  /// \param[in] rhs
  ///     The Right Hand Side const InlineFunctionInfo object
  ///     reference.
  ///
  /// \return
  ///     -1 if lhs < rhs
  ///     0 if lhs == rhs
  ///     1 if lhs > rhs
  int Compare(const InlineFunctionInfo &lhs, const InlineFunctionInfo &rhs);

  /// 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, bool show_fullpaths) const;

  void DumpStopContext(Stream *s) const;

  ConstString GetName() const;

  ConstString GetDisplayName() const;

  /// Get accessor for the call site declaration information.
  ///
  /// \return
  ///     A reference to the declaration object.
  Declaration &GetCallSite();

  /// Get const accessor for the call site declaration information.
  ///
  /// \return
  ///     A const reference to the declaration object.
  const Declaration &GetCallSite() const;

  /// Get accessor for the mangled name object.
  ///
  /// \return
  ///     A reference to the mangled name object.
  Mangled &GetMangled();

  /// Get const accessor for the mangled name object.
  ///
  /// \return
  ///     A const reference to the mangled name object.
  const Mangled &GetMangled() const;

  /// Get the memory cost of this object.
  ///
  /// \return
  ///     The number of bytes that this object occupies in memory.
  ///     The returned value does not include the bytes for any
  ///     shared string values.
  ///
  /// \see ConstString::StaticMemorySize ()
  size_t MemorySize() const override;

private:
  // Member variables.
  Mangled m_mangled; ///< Mangled inlined function name (can be empty if there
                     ///is no mangled information).
  Declaration m_call_decl;
};

class Function;

/// \class CallSiteParameter Function.h "lldb/Symbol/Function.h"
///
/// Represent the locations of a parameter at a call site, both in the caller
/// and in the callee.
struct CallSiteParameter {
  DWARFExpression LocationInCallee;
  DWARFExpression LocationInCaller;
};

/// A vector of \c CallSiteParameter.
using CallSiteParameterArray = llvm::SmallVector<CallSiteParameter, 0>;

/// \class CallEdge Function.h "lldb/Symbol/Function.h"
///
/// Represent a call made within a Function. This can be used to find a path
/// in the call graph between two functions, or to evaluate DW_OP_entry_value.
class CallEdge {
public:
  virtual ~CallEdge() {}

  /// Get the callee's definition.
  ///
  /// Note that this might lazily invoke the DWARF parser. A register context
  /// from the caller's activation is needed to find indirect call targets.
  virtual Function *GetCallee(ModuleList &images,
                              ExecutionContext &exe_ctx) = 0;

  /// Get the load PC address of the instruction which executes after the call
  /// returns. Returns LLDB_INVALID_ADDRESS iff this is a tail call. \p caller
  /// is the Function containing this call, and \p target is the Target which
  /// made the call.
  lldb::addr_t GetReturnPCAddress(Function &caller, Target &target) const;

  /// Like \ref GetReturnPCAddress, but returns an unresolved file address.
  lldb::addr_t GetUnresolvedReturnPCAddress() const { return return_pc; }

  /// Get the call site parameters available at this call edge.
  llvm::ArrayRef<CallSiteParameter> GetCallSiteParameters() const {
    return parameters;
  }

protected:
  CallEdge(lldb::addr_t return_pc, CallSiteParameterArray &&parameters)
      : return_pc(return_pc), parameters(std::move(parameters)) {}

  /// An invalid address if this is a tail call. Otherwise, the return PC for
  /// the call. Note that this is a file address which must be resolved.
  lldb::addr_t return_pc;

  CallSiteParameterArray parameters;
};

/// A direct call site. Used to represent call sites where the address of the
/// callee is fixed (e.g. a function call in C in which the call target is not
/// a function pointer).
class DirectCallEdge : public CallEdge {
public:
  /// Construct a call edge using a symbol name to identify the callee, and a
  /// return PC within the calling function to identify a specific call site.
  DirectCallEdge(const char *symbol_name, lldb::addr_t return_pc,
                 CallSiteParameterArray &&parameters)
      : CallEdge(return_pc, std::move(parameters)) {
    lazy_callee.symbol_name = symbol_name;
  }

  Function *GetCallee(ModuleList &images, ExecutionContext &exe_ctx) override;

private:
  void ParseSymbolFileAndResolve(ModuleList &images);

  // Used to describe a direct call.
  //
  // Either the callee's mangled name or its definition, discriminated by
  // \ref resolved.
  union {
    const char *symbol_name;
    Function *def;
  } lazy_callee;

  /// Whether or not an attempt was made to find the callee's definition.
  bool resolved = false;
};

/// An indirect call site. Used to represent call sites where the address of
/// the callee is not fixed, e.g. a call to a C++ virtual function (where the
/// address is loaded out of a vtable), or a call to a function pointer in C.
class IndirectCallEdge : public CallEdge {
public:
  /// Construct a call edge using a DWARFExpression to identify the callee, and
  /// a return PC within the calling function to identify a specific call site.
  IndirectCallEdge(DWARFExpression call_target, lldb::addr_t return_pc,
                   CallSiteParameterArray &&parameters)
      : CallEdge(return_pc, std::move(parameters)),
        call_target(std::move(call_target)) {}

  Function *GetCallee(ModuleList &images, ExecutionContext &exe_ctx) override;

private:
  // Used to describe an indirect call.
  //
  // Specifies the location of the callee address in the calling frame.
  DWARFExpression call_target;
};

/// \class Function Function.h "lldb/Symbol/Function.h"
/// A class that describes a function.
///
/// Functions belong to CompileUnit objects (Function::m_comp_unit), have
/// unique user IDs (Function::UserID), know how to reconstruct their symbol
/// context (Function::SymbolContextScope), have a specific function type
/// (Function::m_type_uid), have a simple method name (FunctionInfo::m_name),
/// be declared at a specific location (FunctionInfo::m_declaration), possibly
/// have mangled names (Function::m_mangled), an optional return type
/// (Function::m_type), and contains lexical blocks (Function::m_blocks).
///
/// The function information is split into a few pieces:
///     \li The concrete instance information
///     \li The abstract information
///
/// The abstract information is found in the function type (Type) that
/// describes a function information, return type and parameter types.
///
/// The concrete information is the address range information and specific
/// locations for an instance of this function.
class Function : public UserID, public SymbolContextScope {
public:
  /// Construct with a compile unit, function UID, function type UID, optional
  /// mangled name, function type, and a section offset based address range.
  ///
  /// \param[in] comp_unit
  ///     The compile unit to which this function belongs.
  ///
  /// \param[in] func_uid
  ///     The UID for this function. This value is provided by the
  ///     SymbolFile plug-in and can be any value that allows
  ///     the plug-in to quickly find and parse more detailed
  ///     information when and if more information is needed.
  ///
  /// \param[in] func_type_uid
  ///     The type UID for the function Type to allow for lazy type
  ///     parsing from the debug information.
  ///
  /// \param[in] mangled
  ///     The optional mangled name for this function. If empty, there
  ///     is no mangled information.
  ///
  /// \param[in] func_type
  ///     The optional function type. If NULL, the function type will
  ///     be parsed on demand when accessed using the
  ///     Function::GetType() function by asking the SymbolFile
  ///     plug-in to get the type for \a func_type_uid.
  ///
  /// \param[in] range
  ///     The section offset based address for this function.
  Function(CompileUnit *comp_unit, lldb::user_id_t func_uid,
           lldb::user_id_t func_type_uid, const Mangled &mangled,
           Type *func_type, const AddressRange &range);

  /// Destructor.
  ~Function() override;

  /// \copydoc SymbolContextScope::CalculateSymbolContext(SymbolContext*)
  ///
  /// \see SymbolContextScope
  void CalculateSymbolContext(SymbolContext *sc) override;

  lldb::ModuleSP CalculateSymbolContextModule() override;

  CompileUnit *CalculateSymbolContextCompileUnit() override;

  Function *CalculateSymbolContextFunction() override;

  const AddressRange &GetAddressRange() { return m_range; }

  lldb::LanguageType GetLanguage() const;
  /// Find the file and line number of the source location of the start of the
  /// function.  This will use the declaration if present and fall back on the
  /// line table if that fails.  So there may NOT be a line table entry for
  /// this source file/line combo.
  ///
  /// \param[out] source_file
  ///     The source file.
  ///
  /// \param[out] line_no
  ///     The line number.
  void GetStartLineSourceInfo(FileSpec &source_file, uint32_t &line_no);

  /// Find the file and line number of the source location of the end of the
  /// function.
  ///
  ///
  /// \param[out] source_file
  ///     The source file.
  ///
  /// \param[out] line_no
  ///     The line number.
  void GetEndLineSourceInfo(FileSpec &source_file, uint32_t &line_no);

  /// Get the outgoing call edges from this function, sorted by their return
  /// PC addresses (in increasing order).
  llvm::ArrayRef<std::unique_ptr<CallEdge>> GetCallEdges();

  /// Get the outgoing tail-calling edges from this function. If none exist,
  /// return None.
  llvm::ArrayRef<std::unique_ptr<CallEdge>> GetTailCallingEdges();

  /// Get the outgoing call edge from this function which has the given return
  /// address \p return_pc, or return nullptr. Note that this will not return a
  /// tail-calling edge.
  CallEdge *GetCallEdgeForReturnAddress(lldb::addr_t return_pc, Target &target);

  /// Get accessor for the block list.
  ///
  /// \return
  ///     The block list object that describes all lexical blocks
  ///     in the function.
  ///
  /// \see BlockList
  Block &GetBlock(bool can_create);

  /// Get accessor for the compile unit that owns this function.
  ///
  /// \return
  ///     A compile unit object pointer.
  CompileUnit *GetCompileUnit();

  /// Get const accessor for the compile unit that owns this function.
  ///
  /// \return
  ///     A const compile unit object pointer.
  const CompileUnit *GetCompileUnit() const;

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

  /// Get accessor for the frame base location.
  ///
  /// \return
  ///     A location expression that describes the function frame
  ///     base.
  DWARFExpression &GetFrameBaseExpression() { return m_frame_base; }

  /// Get const accessor for the frame base location.
  ///
  /// \return
  ///     A const compile unit object pointer.
  const DWARFExpression &GetFrameBaseExpression() const { return m_frame_base; }

  ConstString GetName() const;

  ConstString GetNameNoArguments() const;

  ConstString GetDisplayName() const;

  const Mangled &GetMangled() const { return m_mangled; }

  /// Get the DeclContext for this function, if available.
  ///
  /// \return
  ///     The DeclContext, or NULL if none exists.
  CompilerDeclContext GetDeclContext();

  /// Get accessor for the type that describes the function return value type,
  /// and parameter types.
  ///
  /// \return
  ///     A type object pointer.
  Type *GetType();

  /// Get const accessor for the type that describes the function return value
  /// type, and parameter types.
  ///
  /// \return
  ///     A const type object pointer.
  const Type *GetType() const;

  CompilerType GetCompilerType();

  /// Get the size of the prologue instructions for this function.  The
  /// "prologue" instructions include any instructions given line number 0
  /// immediately following the prologue end.
  ///
  /// \return
  ///     The size of the prologue.
  uint32_t GetPrologueByteSize();

  /// 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.
  ///
  /// \param[in] show_context
  ///     If \b true, variables will dump their symbol context
  ///     information.
  void Dump(Stream *s, bool show_context) const;

  /// \copydoc SymbolContextScope::DumpSymbolContext(Stream*)
  ///
  /// \see SymbolContextScope
  void DumpSymbolContext(Stream *s) override;

  /// Get the memory cost of this object.
  ///
  /// \return
  ///     The number of bytes that this object occupies in memory.
  ///     The returned value does not include the bytes for any
  ///     shared string values.
  ///
  /// \see ConstString::StaticMemorySize ()
  size_t MemorySize() const;

  /// Get whether compiler optimizations were enabled for this function
  ///
  /// The debug information may provide information about whether this
  /// function was compiled with optimization or not.  In this case,
  /// "optimized" means that the debug experience may be difficult for the
  /// user to understand.  Variables may not be available when the developer
  /// would expect them, stepping through the source lines in the function may
  /// appear strange, etc.
  ///
  /// \return
  ///     Returns 'true' if this function was compiled with
  ///     optimization.  'false' indicates that either the optimization
  ///     is unknown, or this function was built without optimization.
  bool GetIsOptimized();

  /// Get whether this function represents a 'top-level' function
  ///
  /// The concept of a top-level function is language-specific, mostly meant
  /// to represent the notion of scripting-style code that has global
  /// visibility of the variables/symbols/functions/... defined within the
  /// containing file/module
  ///
  /// If stopped in a top-level function, LLDB will expose global variables
  /// as-if locals in the 'frame variable' command
  ///
  /// \return
  ///     Returns 'true' if this function is a top-level function,
  ///     'false' otherwise.
  bool IsTopLevelFunction();

  lldb::DisassemblerSP GetInstructions(const ExecutionContext &exe_ctx,
                                       const char *flavor,
                                       bool prefer_file_cache);

  bool GetDisassembly(const ExecutionContext &exe_ctx, const char *flavor,
                      bool prefer_file_cache, Stream &strm);

protected:
  enum {
    flagsCalculatedPrologueSize =
        (1 << 0) ///< Have we already tried to calculate the prologue size?
  };

  // Member variables.
  CompileUnit *m_comp_unit; ///< The compile unit that owns this function.
  lldb::user_id_t
      m_type_uid; ///< The user ID of for the prototype Type for this function.
  Type *m_type; ///< The function prototype type for this function that include
                ///the function info (FunctionInfo), return type and parameters.
  Mangled m_mangled; ///< The mangled function name if any, if empty, there is
                     ///no mangled information.
  Block m_block;     ///< All lexical blocks contained in this function.
  AddressRange m_range; ///< The function address range that covers the widest
                        ///range needed to contain all blocks
  DWARFExpression m_frame_base; ///< The frame base expression for variables
                                ///that are relative to the frame pointer.
  Flags m_flags;
  uint32_t
      m_prologue_byte_size; ///< Compute the prologue size once and cache it

  bool m_call_edges_resolved = false; ///< Whether call site info has been
                                      ///  parsed.
  std::vector<std::unique_ptr<CallEdge>> m_call_edges; ///< Outgoing call edges.
private:
  DISALLOW_COPY_AND_ASSIGN(Function);
};

} // namespace lldb_private

#endif // liblldb_Function_h_
