//===-- Type.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_Type_h_
#define liblldb_Type_h_

#include "lldb/Core/ClangForward.h"
#include "lldb/Symbol/CompilerDecl.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Symbol/Declaration.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/UserID.h"
#include "lldb/lldb-private.h"

#include "llvm/ADT/APSInt.h"

#include <set>

namespace lldb_private {
//----------------------------------------------------------------------
// CompilerContext allows an array of these items to be passed to perform
// detailed lookups in SymbolVendor and SymbolFile functions.
//----------------------------------------------------------------------
struct CompilerContext {
  CompilerContext(CompilerContextKind t, const ConstString &n)
      : type(t), name(n) {}

  bool operator==(const CompilerContext &rhs) const {
    return type == rhs.type && name == rhs.name;
  }

  void Dump() const;

  CompilerContextKind type;
  ConstString name;
};

class SymbolFileType : public std::enable_shared_from_this<SymbolFileType>,
                       public UserID {
public:
  SymbolFileType(SymbolFile &symbol_file, lldb::user_id_t uid)
      : UserID(uid), m_symbol_file(symbol_file) {}

  SymbolFileType(SymbolFile &symbol_file, const lldb::TypeSP &type_sp);

  ~SymbolFileType() {}

  Type *operator->() { return GetType(); }

  Type *GetType();

protected:
  SymbolFile &m_symbol_file;
  lldb::TypeSP m_type_sp;
};

class Type : public std::enable_shared_from_this<Type>, public UserID {
public:
  typedef enum EncodingDataTypeTag {
    eEncodingInvalid,
    eEncodingIsUID,      ///< This type is the type whose UID is m_encoding_uid
    eEncodingIsConstUID, ///< This type is the type whose UID is m_encoding_uid
                         ///with the const qualifier added
    eEncodingIsRestrictUID, ///< This type is the type whose UID is
                            ///m_encoding_uid with the restrict qualifier added
    eEncodingIsVolatileUID, ///< This type is the type whose UID is
                            ///m_encoding_uid with the volatile qualifier added
    eEncodingIsTypedefUID,  ///< This type is pointer to a type whose UID is
                            ///m_encoding_uid
    eEncodingIsPointerUID,  ///< This type is pointer to a type whose UID is
                            ///m_encoding_uid
    eEncodingIsLValueReferenceUID, ///< This type is L value reference to a type
                                   ///whose UID is m_encoding_uid
    eEncodingIsRValueReferenceUID, ///< This type is R value reference to a type
                                   ///whose UID is m_encoding_uid
    eEncodingIsSyntheticUID
  } EncodingDataType;

  // We must force the underlying type of the enum to be unsigned here.  Not
  // all compilers behave the same with regards to the default underlying type
  // of an enum, but because this enum is used in an enum bitfield and integer
  // comparisons are done with the value we need to guarantee that it's always
  // unsigned so that, for example, eResolveStateFull doesn't compare less than
  // eResolveStateUnresolved when used in a 2-bit bitfield.
  typedef enum ResolveStateTag : unsigned {
    eResolveStateUnresolved = 0,
    eResolveStateForward = 1,
    eResolveStateLayout = 2,
    eResolveStateFull = 3
  } ResolveState;

  Type(lldb::user_id_t uid, SymbolFile *symbol_file, const ConstString &name,
       llvm::Optional<uint64_t> byte_size, SymbolContextScope *context,
       lldb::user_id_t encoding_uid, EncodingDataType encoding_uid_type,
       const Declaration &decl, const CompilerType &compiler_qual_type,
       ResolveState compiler_type_resolve_state);

  // This makes an invalid type.  Used for functions that return a Type when
  // they get an error.
  Type();

  Type(const Type &rhs);

  const Type &operator=(const Type &rhs);

  void Dump(Stream *s, bool show_context);

  void DumpTypeName(Stream *s);

  // Since Type instances only keep a "SymbolFile *" internally, other classes
  // like TypeImpl need make sure the module is still around before playing
  // with
  // Type instances. They can store a weak pointer to the Module;
  lldb::ModuleSP GetModule();

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

  SymbolFile *GetSymbolFile() { return m_symbol_file; }
  const SymbolFile *GetSymbolFile() const { return m_symbol_file; }

  TypeList *GetTypeList();

  const ConstString &GetName();

  llvm::Optional<uint64_t> GetByteSize();

  uint32_t GetNumChildren(bool omit_empty_base_classes);

  bool IsAggregateType();

  bool IsValidType() { return m_encoding_uid_type != eEncodingInvalid; }

  bool IsTypedef() { return m_encoding_uid_type == eEncodingIsTypedefUID; }

  lldb::TypeSP GetTypedefType();

  const ConstString &GetName() const { return m_name; }

  ConstString GetQualifiedName();

  void DumpValue(ExecutionContext *exe_ctx, Stream *s,
                 const DataExtractor &data, uint32_t data_offset,
                 bool show_type, bool show_summary, bool verbose,
                 lldb::Format format = lldb::eFormatDefault);

  bool DumpValueInMemory(ExecutionContext *exe_ctx, Stream *s,
                         lldb::addr_t address, AddressType address_type,
                         bool show_types, bool show_summary, bool verbose);

  bool ReadFromMemory(ExecutionContext *exe_ctx, lldb::addr_t address,
                      AddressType address_type, DataExtractor &data);

  bool WriteToMemory(ExecutionContext *exe_ctx, lldb::addr_t address,
                     AddressType address_type, DataExtractor &data);

  bool GetIsDeclaration() const;

  void SetIsDeclaration(bool b);

  bool GetIsExternal() const;

  void SetIsExternal(bool b);

  lldb::Format GetFormat();

  lldb::Encoding GetEncoding(uint64_t &count);

  SymbolContextScope *GetSymbolContextScope() { return m_context; }
  const SymbolContextScope *GetSymbolContextScope() const { return m_context; }
  void SetSymbolContextScope(SymbolContextScope *context) {
    m_context = context;
  }

  const lldb_private::Declaration &GetDeclaration() const;

  // Get the clang type, and resolve definitions for any
  // class/struct/union/enum types completely.
  CompilerType GetFullCompilerType();

  // Get the clang type, and resolve definitions enough so that the type could
  // have layout performed. This allows ptrs and refs to
  // class/struct/union/enum types remain forward declarations.
  CompilerType GetLayoutCompilerType();

  // Get the clang type and leave class/struct/union/enum types as forward
  // declarations if they haven't already been fully defined.
  CompilerType GetForwardCompilerType();

  static int Compare(const Type &a, const Type &b);

  // From a fully qualified typename, split the type into the type basename and
  // the remaining type scope (namespaces/classes).
  static bool GetTypeScopeAndBasename(const llvm::StringRef& name,
                                      llvm::StringRef &scope,
                                      llvm::StringRef &basename,
                                      lldb::TypeClass &type_class);
  void SetEncodingType(Type *encoding_type) { m_encoding_type = encoding_type; }

  uint32_t GetEncodingMask();

  bool IsCompleteObjCClass() { return m_flags.is_complete_objc_class; }

  void SetIsCompleteObjCClass(bool is_complete_objc_class) {
    m_flags.is_complete_objc_class = is_complete_objc_class;
  }

protected:
  ConstString m_name;
  SymbolFile *m_symbol_file;
  SymbolContextScope
      *m_context; // The symbol context in which this type is defined
  Type *m_encoding_type;
  lldb::user_id_t m_encoding_uid;
  EncodingDataType m_encoding_uid_type;
  uint64_t m_byte_size : 63;
  uint64_t m_byte_size_has_value : 1;
  Declaration m_decl;
  CompilerType m_compiler_type;

  struct Flags {
#ifdef __GNUC__
    // using unsigned type here to work around a very noisy gcc warning
    unsigned compiler_type_resolve_state : 2;
#else
    ResolveState compiler_type_resolve_state : 2;
#endif
    bool is_complete_objc_class : 1;
  } m_flags;

  Type *GetEncodingType();

  bool ResolveClangType(ResolveState compiler_type_resolve_state);
};

// these classes are used to back the SBType* objects

class TypePair {
public:
  TypePair() : compiler_type(), type_sp() {}

  TypePair(CompilerType type) : compiler_type(type), type_sp() {}

  TypePair(lldb::TypeSP type) : compiler_type(), type_sp(type) {
    compiler_type = type_sp->GetForwardCompilerType();
  }

  bool IsValid() const {
    return compiler_type.IsValid() || (type_sp.get() != nullptr);
  }

  explicit operator bool() const { return IsValid(); }

  bool operator==(const TypePair &rhs) const {
    return compiler_type == rhs.compiler_type &&
           type_sp.get() == rhs.type_sp.get();
  }

  bool operator!=(const TypePair &rhs) const {
    return compiler_type != rhs.compiler_type ||
           type_sp.get() != rhs.type_sp.get();
  }

  void Clear() {
    compiler_type.Clear();
    type_sp.reset();
  }

  ConstString GetName() const {
    if (type_sp)
      return type_sp->GetName();
    if (compiler_type)
      return compiler_type.GetTypeName();
    return ConstString();
  }

  ConstString GetDisplayTypeName() const {
    if (type_sp)
      return type_sp->GetForwardCompilerType().GetDisplayTypeName();
    if (compiler_type)
      return compiler_type.GetDisplayTypeName();
    return ConstString();
  }

  void SetType(CompilerType type) {
    type_sp.reset();
    compiler_type = type;
  }

  void SetType(lldb::TypeSP type) {
    type_sp = type;
    if (type_sp)
      compiler_type = type_sp->GetForwardCompilerType();
    else
      compiler_type.Clear();
  }

  lldb::TypeSP GetTypeSP() const { return type_sp; }

  CompilerType GetCompilerType() const { return compiler_type; }

  CompilerType GetPointerType() const {
    if (type_sp)
      return type_sp->GetForwardCompilerType().GetPointerType();
    return compiler_type.GetPointerType();
  }

  CompilerType GetPointeeType() const {
    if (type_sp)
      return type_sp->GetForwardCompilerType().GetPointeeType();
    return compiler_type.GetPointeeType();
  }

  CompilerType GetReferenceType() const {
    if (type_sp)
      return type_sp->GetForwardCompilerType().GetLValueReferenceType();
    else
      return compiler_type.GetLValueReferenceType();
  }

  CompilerType GetTypedefedType() const {
    if (type_sp)
      return type_sp->GetForwardCompilerType().GetTypedefedType();
    else
      return compiler_type.GetTypedefedType();
  }

  CompilerType GetDereferencedType() const {
    if (type_sp)
      return type_sp->GetForwardCompilerType().GetNonReferenceType();
    else
      return compiler_type.GetNonReferenceType();
  }

  CompilerType GetUnqualifiedType() const {
    if (type_sp)
      return type_sp->GetForwardCompilerType().GetFullyUnqualifiedType();
    else
      return compiler_type.GetFullyUnqualifiedType();
  }

  CompilerType GetCanonicalType() const {
    if (type_sp)
      return type_sp->GetForwardCompilerType().GetCanonicalType();
    return compiler_type.GetCanonicalType();
  }

  TypeSystem *GetTypeSystem() const { return compiler_type.GetTypeSystem(); }

  lldb::ModuleSP GetModule() const {
    if (type_sp)
      return type_sp->GetModule();
    return lldb::ModuleSP();
  }

protected:
  CompilerType compiler_type;
  lldb::TypeSP type_sp;
};

// the two classes here are used by the public API as a backend to the SBType
// and SBTypeList classes

class TypeImpl {
public:
  TypeImpl();

  ~TypeImpl() {}

  TypeImpl(const TypeImpl &rhs);

  TypeImpl(const lldb::TypeSP &type_sp);

  TypeImpl(const CompilerType &compiler_type);

  TypeImpl(const lldb::TypeSP &type_sp, const CompilerType &dynamic);

  TypeImpl(const CompilerType &compiler_type, const CompilerType &dynamic);

  TypeImpl(const TypePair &pair, const CompilerType &dynamic);

  void SetType(const lldb::TypeSP &type_sp);

  void SetType(const CompilerType &compiler_type);

  void SetType(const lldb::TypeSP &type_sp, const CompilerType &dynamic);

  void SetType(const CompilerType &compiler_type, const CompilerType &dynamic);

  void SetType(const TypePair &pair, const CompilerType &dynamic);

  TypeImpl &operator=(const TypeImpl &rhs);

  bool operator==(const TypeImpl &rhs) const;

  bool operator!=(const TypeImpl &rhs) const;

  bool IsValid() const;

  explicit operator bool() const;

  void Clear();

  ConstString GetName() const;

  ConstString GetDisplayTypeName() const;

  TypeImpl GetPointerType() const;

  TypeImpl GetPointeeType() const;

  TypeImpl GetReferenceType() const;

  TypeImpl GetTypedefedType() const;

  TypeImpl GetDereferencedType() const;

  TypeImpl GetUnqualifiedType() const;

  TypeImpl GetCanonicalType() const;

  CompilerType GetCompilerType(bool prefer_dynamic);

  TypeSystem *GetTypeSystem(bool prefer_dynamic);

  bool GetDescription(lldb_private::Stream &strm,
                      lldb::DescriptionLevel description_level);

private:
  bool CheckModule(lldb::ModuleSP &module_sp) const;

  lldb::ModuleWP m_module_wp;
  TypePair m_static_type;
  CompilerType m_dynamic_type;
};

class TypeListImpl {
public:
  TypeListImpl() : m_content() {}

  void Append(const lldb::TypeImplSP &type) { m_content.push_back(type); }

  class AppendVisitor {
  public:
    AppendVisitor(TypeListImpl &type_list) : m_type_list(type_list) {}

    void operator()(const lldb::TypeImplSP &type) { m_type_list.Append(type); }

  private:
    TypeListImpl &m_type_list;
  };

  void Append(const lldb_private::TypeList &type_list);

  lldb::TypeImplSP GetTypeAtIndex(size_t idx) {
    lldb::TypeImplSP type_sp;
    if (idx < GetSize())
      type_sp = m_content[idx];
    return type_sp;
  }

  size_t GetSize() { return m_content.size(); }

private:
  std::vector<lldb::TypeImplSP> m_content;
};

class TypeMemberImpl {
public:
  TypeMemberImpl()
      : m_type_impl_sp(), m_bit_offset(0), m_name(), m_bitfield_bit_size(0),
        m_is_bitfield(false)

  {}

  TypeMemberImpl(const lldb::TypeImplSP &type_impl_sp, uint64_t bit_offset,
                 const ConstString &name, uint32_t bitfield_bit_size = 0,
                 bool is_bitfield = false)
      : m_type_impl_sp(type_impl_sp), m_bit_offset(bit_offset), m_name(name),
        m_bitfield_bit_size(bitfield_bit_size), m_is_bitfield(is_bitfield) {}

  TypeMemberImpl(const lldb::TypeImplSP &type_impl_sp, uint64_t bit_offset)
      : m_type_impl_sp(type_impl_sp), m_bit_offset(bit_offset), m_name(),
        m_bitfield_bit_size(0), m_is_bitfield(false) {
    if (m_type_impl_sp)
      m_name = m_type_impl_sp->GetName();
  }

  const lldb::TypeImplSP &GetTypeImpl() { return m_type_impl_sp; }

  const ConstString &GetName() const { return m_name; }

  uint64_t GetBitOffset() const { return m_bit_offset; }

  uint32_t GetBitfieldBitSize() const { return m_bitfield_bit_size; }

  void SetBitfieldBitSize(uint32_t bitfield_bit_size) {
    m_bitfield_bit_size = bitfield_bit_size;
  }

  bool GetIsBitfield() const { return m_is_bitfield; }

  void SetIsBitfield(bool is_bitfield) { m_is_bitfield = is_bitfield; }

protected:
  lldb::TypeImplSP m_type_impl_sp;
  uint64_t m_bit_offset;
  ConstString m_name;
  uint32_t m_bitfield_bit_size; // Bit size for bitfield members only
  bool m_is_bitfield;
};

///
/// Sometimes you can find the name of the type corresponding to an object, but
/// we don't have debug
/// information for it.  If that is the case, you can return one of these
/// objects, and then if it
/// has a full type, you can use that, but if not at least you can print the
/// name for informational
/// purposes.
///

class TypeAndOrName {
public:
  TypeAndOrName();
  TypeAndOrName(lldb::TypeSP &type_sp);
  TypeAndOrName(const CompilerType &compiler_type);
  TypeAndOrName(const char *type_str);
  TypeAndOrName(const TypeAndOrName &rhs);
  TypeAndOrName(ConstString &type_const_string);

  TypeAndOrName &operator=(const TypeAndOrName &rhs);

  bool operator==(const TypeAndOrName &other) const;

  bool operator!=(const TypeAndOrName &other) const;

  ConstString GetName() const;

  lldb::TypeSP GetTypeSP() const { return m_type_pair.GetTypeSP(); }

  CompilerType GetCompilerType() const { return m_type_pair.GetCompilerType(); }

  void SetName(const ConstString &type_name);

  void SetName(const char *type_name_cstr);

  void SetTypeSP(lldb::TypeSP type_sp);

  void SetCompilerType(CompilerType compiler_type);

  bool IsEmpty() const;

  bool HasName() const;

  bool HasTypeSP() const;

  bool HasCompilerType() const;

  bool HasType() const { return HasTypeSP() || HasCompilerType(); }

  void Clear();

  explicit operator bool() { return !IsEmpty(); }

private:
  TypePair m_type_pair;
  ConstString m_type_name;
};

class TypeMemberFunctionImpl {
public:
  TypeMemberFunctionImpl()
      : m_type(), m_decl(), m_name(), m_kind(lldb::eMemberFunctionKindUnknown) {
  }

  TypeMemberFunctionImpl(const CompilerType &type, const CompilerDecl &decl,
                         const std::string &name,
                         const lldb::MemberFunctionKind &kind)
      : m_type(type), m_decl(decl), m_name(name), m_kind(kind) {}

  bool IsValid();

  ConstString GetName() const;

  ConstString GetMangledName() const;

  CompilerType GetType() const;

  CompilerType GetReturnType() const;

  size_t GetNumArguments() const;

  CompilerType GetArgumentAtIndex(size_t idx) const;

  lldb::MemberFunctionKind GetKind() const;

  bool GetDescription(Stream &stream);

protected:
  std::string GetPrintableTypeName();

private:
  CompilerType m_type;
  CompilerDecl m_decl;
  ConstString m_name;
  lldb::MemberFunctionKind m_kind;
};

class TypeEnumMemberImpl {
public:
  TypeEnumMemberImpl()
      : m_integer_type_sp(), m_name("<invalid>"), m_value(), m_valid(false) {}

  TypeEnumMemberImpl(const lldb::TypeImplSP &integer_type_sp,
                     const ConstString &name, const llvm::APSInt &value);

  TypeEnumMemberImpl(const TypeEnumMemberImpl &rhs)
      : m_integer_type_sp(rhs.m_integer_type_sp), m_name(rhs.m_name),
        m_value(rhs.m_value), m_valid(rhs.m_valid) {}

  TypeEnumMemberImpl &operator=(const TypeEnumMemberImpl &rhs);

  bool IsValid() { return m_valid; }

  const ConstString &GetName() const { return m_name; }

  const lldb::TypeImplSP &GetIntegerType() const { return m_integer_type_sp; }

  uint64_t GetValueAsUnsigned() const { return m_value.getZExtValue(); }

  int64_t GetValueAsSigned() const { return m_value.getSExtValue(); }

protected:
  lldb::TypeImplSP m_integer_type_sp;
  ConstString m_name;
  llvm::APSInt m_value;
  bool m_valid;
};

class TypeEnumMemberListImpl {
public:
  TypeEnumMemberListImpl() : m_content() {}

  void Append(const lldb::TypeEnumMemberImplSP &type) {
    m_content.push_back(type);
  }

  void Append(const lldb_private::TypeEnumMemberListImpl &type_list);

  lldb::TypeEnumMemberImplSP GetTypeEnumMemberAtIndex(size_t idx) {
    lldb::TypeEnumMemberImplSP enum_member;
    if (idx < GetSize())
      enum_member = m_content[idx];
    return enum_member;
  }

  size_t GetSize() { return m_content.size(); }

private:
  std::vector<lldb::TypeEnumMemberImplSP> m_content;
};

} // namespace lldb_private

#endif // liblldb_Type_h_
