//===-- SymbolFile.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_SYMBOLFILE_H
#define LLDB_SYMBOL_SYMBOLFILE_H

#include "lldb/Core/ModuleList.h"
#include "lldb/Core/PluginInterface.h"
#include "lldb/Core/SourceLocationSpec.h"
#include "lldb/Symbol/CompilerDecl.h"
#include "lldb/Symbol/CompilerDeclContext.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/SourceModule.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Symbol/TypeList.h"
#include "lldb/Symbol/TypeSystem.h"
#include "lldb/Target/Statistics.h"
#include "lldb/Utility/XcodeSDK.h"
#include "lldb/lldb-private.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/Support/Errc.h"

#include <mutex>

#if defined(LLDB_CONFIGURATION_DEBUG)
#define ASSERT_MODULE_LOCK(expr) (expr->AssertModuleLock())
#else
#define ASSERT_MODULE_LOCK(expr) ((void)0)
#endif

namespace lldb_private {

/// Provides public interface for all SymbolFiles. Any protected
/// virtual members should go into SymbolFileCommon; most SymbolFile
/// implementations should inherit from SymbolFileCommon to override
/// the behaviors except SymbolFileOnDemand which inherits
/// public interfaces from SymbolFile and forward to underlying concrete
/// SymbolFile implementation.
class SymbolFile : public PluginInterface {
  /// LLVM RTTI support.
  static char ID;

public:
  /// LLVM RTTI support.
  /// \{
  virtual bool isA(const void *ClassID) const { return ClassID == &ID; }
  static bool classof(const SymbolFile *obj) { return obj->isA(&ID); }
  /// \}

  // Symbol file ability bits.
  //
  // Each symbol file can claim to support one or more symbol file abilities.
  // These get returned from SymbolFile::GetAbilities(). These help us to
  // determine which plug-in will be best to load the debug information found
  // in files.
  enum Abilities {
    CompileUnits = (1u << 0),
    LineTables = (1u << 1),
    Functions = (1u << 2),
    Blocks = (1u << 3),
    GlobalVariables = (1u << 4),
    LocalVariables = (1u << 5),
    VariableTypes = (1u << 6),
    kAllAbilities = ((1u << 7) - 1u)
  };

  static SymbolFile *FindPlugin(lldb::ObjectFileSP objfile_sp);

  // Constructors and Destructors
  SymbolFile() = default;

  ~SymbolFile() override = default;

  /// SymbolFileOnDemand class overrides this to return the underlying
  /// backing SymbolFile implementation that loads on-demand.
  virtual SymbolFile *GetBackingSymbolFile() { return this; }

  /// Get a mask of what this symbol file supports for the object file
  /// that it was constructed with.
  ///
  /// Each symbol file gets to respond with a mask of abilities that
  /// it supports for each object file. This happens when we are
  /// trying to figure out which symbol file plug-in will get used
  /// for a given object file. The plug-in that responds with the
  /// best mix of "SymbolFile::Abilities" bits set, will get chosen to
  /// be the symbol file parser. This allows each plug-in to check for
  /// sections that contain data a symbol file plug-in would need. For
  /// example the DWARF plug-in requires DWARF sections in a file that
  /// contain debug information. If the DWARF plug-in doesn't find
  /// these sections, it won't respond with many ability bits set, and
  /// we will probably fall back to the symbol table SymbolFile plug-in
  /// which uses any information in the symbol table. Also, plug-ins
  /// might check for some specific symbols in a symbol table in the
  /// case where the symbol table contains debug information (STABS
  /// and COFF). Not a lot of work should happen in these functions
  /// as the plug-in might not get selected due to another plug-in
  /// having more abilities. Any initialization work should be saved
  /// for "void SymbolFile::InitializeObject()" which will get called
  /// on the SymbolFile object with the best set of abilities.
  ///
  /// \return
  ///     A uint32_t mask containing bits from the SymbolFile::Abilities
  ///     enumeration. Any bits that are set represent an ability that
  ///     this symbol plug-in can parse from the object file.
  virtual uint32_t GetAbilities() = 0;
  virtual uint32_t CalculateAbilities() = 0;

  /// Symbols file subclasses should override this to return the Module that
  /// owns the TypeSystem that this symbol file modifies type information in.
  virtual std::recursive_mutex &GetModuleMutex() const;

  /// Initialize the SymbolFile object.
  ///
  /// The SymbolFile object with the best set of abilities (detected
  /// in "uint32_t SymbolFile::GetAbilities()) will have this function
  /// called if it is chosen to parse an object file. More complete
  /// initialization can happen in this function which will get called
  /// prior to any other functions in the SymbolFile protocol.
  virtual void InitializeObject() {}

  /// Whether debug info will be loaded or not.
  ///
  /// It will be true for most implementations except SymbolFileOnDemand.
  virtual bool GetLoadDebugInfoEnabled() { return true; }

  /// Specify debug info should be loaded.
  ///
  /// It will be no-op for most implementations except SymbolFileOnDemand.
  virtual void SetLoadDebugInfoEnabled() { return; }

  // Compile Unit function calls
  // Approach 1 - iterator
  virtual uint32_t GetNumCompileUnits() = 0;
  virtual lldb::CompUnitSP GetCompileUnitAtIndex(uint32_t idx) = 0;

  virtual Symtab *GetSymtab() = 0;

  virtual lldb::LanguageType ParseLanguage(CompileUnit &comp_unit) = 0;
  /// Return the Xcode SDK comp_unit was compiled against.
  virtual XcodeSDK ParseXcodeSDK(CompileUnit &comp_unit) { return {}; }
  virtual size_t ParseFunctions(CompileUnit &comp_unit) = 0;
  virtual bool ParseLineTable(CompileUnit &comp_unit) = 0;
  virtual bool ParseDebugMacros(CompileUnit &comp_unit) = 0;

  /// Apply a lambda to each external lldb::Module referenced by this
  /// \p comp_unit. Recursively also descends into the referenced external
  /// modules of any encountered compilation unit.
  ///
  /// This function can be used to traverse Clang -gmodules debug
  /// information, which is stored in DWARF files separate from the
  /// object files.
  ///
  /// \param comp_unit
  ///     When this SymbolFile consists of multiple auxilliary
  ///     SymbolFiles, for example, a Darwin debug map that references
  ///     multiple .o files, comp_unit helps choose the auxilliary
  ///     file. In most other cases comp_unit's symbol file is
  ///     identical with *this.
  ///
  /// \param[in] lambda
  ///     The lambda that should be applied to every function. The lambda can
  ///     return true if the iteration should be aborted earlier.
  ///
  /// \param visited_symbol_files
  ///     A set of SymbolFiles that were already visited to avoid
  ///     visiting one file more than once.
  ///
  /// \return
  ///     If the lambda early-exited, this function returns true to
  ///     propagate the early exit.
  virtual bool ForEachExternalModule(
      lldb_private::CompileUnit &comp_unit,
      llvm::DenseSet<lldb_private::SymbolFile *> &visited_symbol_files,
      llvm::function_ref<bool(Module &)> lambda) {
    return false;
  }
  virtual bool ParseSupportFiles(CompileUnit &comp_unit,
                                 FileSpecList &support_files) = 0;
  virtual size_t ParseTypes(CompileUnit &comp_unit) = 0;
  virtual bool ParseIsOptimized(CompileUnit &comp_unit) { return false; }

  virtual bool
  ParseImportedModules(const SymbolContext &sc,
                       std::vector<SourceModule> &imported_modules) = 0;
  virtual size_t ParseBlocksRecursive(Function &func) = 0;
  virtual size_t ParseVariablesForContext(const SymbolContext &sc) = 0;
  virtual Type *ResolveTypeUID(lldb::user_id_t type_uid) = 0;

  /// The characteristics of an array type.
  struct ArrayInfo {
    int64_t first_index = 0;
    llvm::SmallVector<uint64_t, 1> element_orders;
    uint32_t byte_stride = 0;
    uint32_t bit_stride = 0;
  };
  /// If \c type_uid points to an array type, return its characteristics.
  /// To support variable-length array types, this function takes an
  /// optional \p ExecutionContext. If \c exe_ctx is non-null, the
  /// dynamic characteristics for that context are returned.
  virtual llvm::Optional<ArrayInfo>
  GetDynamicArrayInfoForUID(lldb::user_id_t type_uid,
                            const lldb_private::ExecutionContext *exe_ctx) = 0;

  virtual bool CompleteType(CompilerType &compiler_type) = 0;
  virtual void ParseDeclsForContext(CompilerDeclContext decl_ctx) {}
  virtual CompilerDecl GetDeclForUID(lldb::user_id_t uid) {
    return CompilerDecl();
  }
  virtual CompilerDeclContext GetDeclContextForUID(lldb::user_id_t uid) {
    return CompilerDeclContext();
  }
  virtual CompilerDeclContext GetDeclContextContainingUID(lldb::user_id_t uid) {
    return CompilerDeclContext();
  }
  virtual uint32_t ResolveSymbolContext(const Address &so_addr,
                                        lldb::SymbolContextItem resolve_scope,
                                        SymbolContext &sc) = 0;
  virtual uint32_t
  ResolveSymbolContext(const SourceLocationSpec &src_location_spec,
                       lldb::SymbolContextItem resolve_scope,
                       SymbolContextList &sc_list);

  virtual void DumpClangAST(Stream &s) {}
  virtual void FindGlobalVariables(ConstString name,
                                   const CompilerDeclContext &parent_decl_ctx,
                                   uint32_t max_matches,
                                   VariableList &variables);
  virtual void FindGlobalVariables(const RegularExpression &regex,
                                   uint32_t max_matches,
                                   VariableList &variables);
  virtual void FindFunctions(ConstString name,
                             const CompilerDeclContext &parent_decl_ctx,
                             lldb::FunctionNameType name_type_mask,
                             bool include_inlines, SymbolContextList &sc_list);
  virtual void FindFunctions(const RegularExpression &regex,
                             bool include_inlines, SymbolContextList &sc_list);
  virtual void
  FindTypes(ConstString name, const CompilerDeclContext &parent_decl_ctx,
            uint32_t max_matches,
            llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
            TypeMap &types);

  /// Find types specified by a CompilerContextPattern.
  /// \param languages
  ///     Only return results in these languages.
  /// \param searched_symbol_files
  ///     Prevents one file from being visited multiple times.
  virtual void
  FindTypes(llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages,
            llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
            TypeMap &types);

  virtual void
  GetMangledNamesForFunction(const std::string &scope_qualified_name,
                             std::vector<ConstString> &mangled_names);

  virtual void GetTypes(lldb_private::SymbolContextScope *sc_scope,
                        lldb::TypeClass type_mask,
                        lldb_private::TypeList &type_list) = 0;

  virtual void PreloadSymbols();

  virtual llvm::Expected<lldb_private::TypeSystem &>
  GetTypeSystemForLanguage(lldb::LanguageType language) = 0;

  virtual CompilerDeclContext
  FindNamespace(ConstString name, const CompilerDeclContext &parent_decl_ctx) {
    return CompilerDeclContext();
  }

  virtual ObjectFile *GetObjectFile() = 0;
  virtual const ObjectFile *GetObjectFile() const = 0;
  virtual ObjectFile *GetMainObjectFile() = 0;

  virtual std::vector<std::unique_ptr<CallEdge>>
  ParseCallEdgesInFunction(UserID func_id) {
    return {};
  }

  virtual void AddSymbols(Symtab &symtab) {}

  /// Notify the SymbolFile that the file addresses in the Sections
  /// for this module have been changed.
  virtual void SectionFileAddressesChanged() = 0;

  struct RegisterInfoResolver {
    virtual ~RegisterInfoResolver(); // anchor

    virtual const RegisterInfo *ResolveName(llvm::StringRef name) const = 0;
    virtual const RegisterInfo *ResolveNumber(lldb::RegisterKind kind,
                                              uint32_t number) const = 0;
  };
  virtual lldb::UnwindPlanSP
  GetUnwindPlan(const Address &address, const RegisterInfoResolver &resolver) {
    return nullptr;
  }

  /// Return the number of stack bytes taken up by the parameters to this
  /// function.
  virtual llvm::Expected<lldb::addr_t> GetParameterStackSize(Symbol &symbol) {
    return llvm::createStringError(make_error_code(llvm::errc::not_supported),
                                   "Operation not supported.");
  }

  virtual void Dump(Stream &s) = 0;

  /// Metrics gathering functions

  /// Return the size in bytes of all debug information in the symbol file.
  ///
  /// If the debug information is contained in sections of an ObjectFile, then
  /// this call should add the size of all sections that contain debug
  /// information. Symbols the symbol tables are not considered debug
  /// information for this call to make it easy and quick for this number to be
  /// calculated. If the symbol file is all debug information, the size of the
  /// entire file should be returned. The default implementation of this
  /// function will iterate over all sections in a module and add up their
  /// debug info only section byte sizes.
  virtual uint64_t GetDebugInfoSize() = 0;

  /// Return the time taken to parse the debug information.
  ///
  /// \returns 0.0 if no information has been parsed or if there is
  /// no computational cost to parsing the debug information.
  virtual StatsDuration::Duration GetDebugInfoParseTime() { return {}; }

  /// Return the time it took to index the debug information in the object
  /// file.
  ///
  /// \returns 0.0 if the file doesn't need to be indexed or if it
  /// hasn't been indexed yet, or a valid duration if it has.
  virtual StatsDuration::Duration GetDebugInfoIndexTime() { return {}; }

  /// Get the additional modules that this symbol file uses to parse debug info.
  ///
  /// Some debug info is stored in stand alone object files that are represented
  /// by unique modules that will show up in the statistics module list. Return
  /// a list of modules that are not in the target module list that this symbol
  /// file is currently using so that they can be tracked and assoicated with
  /// the module in the statistics.
  virtual ModuleList GetDebugInfoModules() { return ModuleList(); }

  /// Accessors for the bool that indicates if the debug info index was loaded
  /// from, or saved to the module index cache.
  ///
  /// In statistics it is handy to know if a module's debug info was loaded from
  /// or saved to the cache. When the debug info index is loaded from the cache
  /// startup times can be faster. When the cache is enabled and the debug info
  /// index is saved to the cache, debug sessions can be slower. These accessors
  /// can be accessed by the statistics and emitted to help track these costs.
  /// \{
  virtual bool GetDebugInfoIndexWasLoadedFromCache() const = 0;
  virtual void SetDebugInfoIndexWasLoadedFromCache() = 0;
  virtual bool GetDebugInfoIndexWasSavedToCache() const = 0;
  virtual void SetDebugInfoIndexWasSavedToCache() = 0;
  /// \}

protected:
  void AssertModuleLock();

private:
  SymbolFile(const SymbolFile &) = delete;
  const SymbolFile &operator=(const SymbolFile &) = delete;
};

/// Containing protected virtual methods for child classes to override.
/// Most actual SymbolFile implementations should inherit from this class.
class SymbolFileCommon : public SymbolFile {
  /// LLVM RTTI support.
  static char ID;

public:
  /// LLVM RTTI support.
  /// \{
  bool isA(const void *ClassID) const override {
    return ClassID == &ID || SymbolFile::isA(ClassID);
  }
  static bool classof(const SymbolFileCommon *obj) { return obj->isA(&ID); }
  /// \}

  // Constructors and Destructors
  SymbolFileCommon(lldb::ObjectFileSP objfile_sp)
      : m_objfile_sp(std::move(objfile_sp)) {}

  ~SymbolFileCommon() override = default;

  uint32_t GetAbilities() override {
    if (!m_calculated_abilities) {
      m_abilities = CalculateAbilities();
      m_calculated_abilities = true;
    }
    return m_abilities;
  }

  Symtab *GetSymtab() override;

  ObjectFile *GetObjectFile() override { return m_objfile_sp.get(); }
  const ObjectFile *GetObjectFile() const override {
    return m_objfile_sp.get();
  }
  ObjectFile *GetMainObjectFile() override;

  /// Notify the SymbolFile that the file addresses in the Sections
  /// for this module have been changed.
  void SectionFileAddressesChanged() override;

  // Compile Unit function calls
  // Approach 1 - iterator
  uint32_t GetNumCompileUnits() override;
  lldb::CompUnitSP GetCompileUnitAtIndex(uint32_t idx) override;

  llvm::Expected<lldb_private::TypeSystem &>
  GetTypeSystemForLanguage(lldb::LanguageType language) override;

  void Dump(Stream &s) override;

  uint64_t GetDebugInfoSize() override;

  bool GetDebugInfoIndexWasLoadedFromCache() const override {
    return m_index_was_loaded_from_cache;
  }
  void SetDebugInfoIndexWasLoadedFromCache() override {
    m_index_was_loaded_from_cache = true;
  }
  bool GetDebugInfoIndexWasSavedToCache() const override {
    return m_index_was_saved_to_cache;
  }
  void SetDebugInfoIndexWasSavedToCache() override {
    m_index_was_saved_to_cache = true;
  }

protected:
  virtual uint32_t CalculateNumCompileUnits() = 0;
  virtual lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t idx) = 0;
  virtual TypeList &GetTypeList() { return m_type_list; }
  void SetCompileUnitAtIndex(uint32_t idx, const lldb::CompUnitSP &cu_sp);

  lldb::ObjectFileSP m_objfile_sp; // Keep a reference to the object file in
                                   // case it isn't the same as the module
                                   // object file (debug symbols in a separate
                                   // file)
  llvm::Optional<std::vector<lldb::CompUnitSP>> m_compile_units;
  TypeList m_type_list;
  Symtab *m_symtab = nullptr;
  uint32_t m_abilities = 0;
  bool m_calculated_abilities = false;
  bool m_index_was_loaded_from_cache = false;
  bool m_index_was_saved_to_cache = false;

private:
  SymbolFileCommon(const SymbolFileCommon &) = delete;
  const SymbolFileCommon &operator=(const SymbolFileCommon &) = delete;
};

} // namespace lldb_private

#endif // LLDB_SYMBOL_SYMBOLFILE_H
