//===- TypeIndex.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 LLVM_DEBUGINFO_CODEVIEW_TYPEINDEX_H
#define LLVM_DEBUGINFO_CODEVIEW_TYPEINDEX_H

#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/Support/Endian.h"
#include <cassert>
#include <cinttypes>
#include <functional>

namespace llvm {

class ScopedPrinter;

namespace codeview {

class TypeCollection;

enum class SimpleTypeKind : uint32_t {
  None = 0x0000,          // uncharacterized type (no type)
  Void = 0x0003,          // void
  NotTranslated = 0x0007, // type not translated by cvpack
  HResult = 0x0008,       // OLE/COM HRESULT

  SignedCharacter = 0x0010,   // 8 bit signed
  UnsignedCharacter = 0x0020, // 8 bit unsigned
  NarrowCharacter = 0x0070,   // really a char
  WideCharacter = 0x0071,     // wide char
  Character16 = 0x007a,       // char16_t
  Character32 = 0x007b,       // char32_t

  SByte = 0x0068,       // 8 bit signed int
  Byte = 0x0069,        // 8 bit unsigned int
  Int16Short = 0x0011,  // 16 bit signed
  UInt16Short = 0x0021, // 16 bit unsigned
  Int16 = 0x0072,       // 16 bit signed int
  UInt16 = 0x0073,      // 16 bit unsigned int
  Int32Long = 0x0012,   // 32 bit signed
  UInt32Long = 0x0022,  // 32 bit unsigned
  Int32 = 0x0074,       // 32 bit signed int
  UInt32 = 0x0075,      // 32 bit unsigned int
  Int64Quad = 0x0013,   // 64 bit signed
  UInt64Quad = 0x0023,  // 64 bit unsigned
  Int64 = 0x0076,       // 64 bit signed int
  UInt64 = 0x0077,      // 64 bit unsigned int
  Int128Oct = 0x0014,   // 128 bit signed int
  UInt128Oct = 0x0024,  // 128 bit unsigned int
  Int128 = 0x0078,      // 128 bit signed int
  UInt128 = 0x0079,     // 128 bit unsigned int

  Float16 = 0x0046,                 // 16 bit real
  Float32 = 0x0040,                 // 32 bit real
  Float32PartialPrecision = 0x0045, // 32 bit PP real
  Float48 = 0x0044,                 // 48 bit real
  Float64 = 0x0041,                 // 64 bit real
  Float80 = 0x0042,                 // 80 bit real
  Float128 = 0x0043,                // 128 bit real

  Complex16 = 0x0056,                 // 16 bit complex
  Complex32 = 0x0050,                 // 32 bit complex
  Complex32PartialPrecision = 0x0055, // 32 bit PP complex
  Complex48 = 0x0054,                 // 48 bit complex
  Complex64 = 0x0051,                 // 64 bit complex
  Complex80 = 0x0052,                 // 80 bit complex
  Complex128 = 0x0053,                // 128 bit complex

  Boolean8 = 0x0030,   // 8 bit boolean
  Boolean16 = 0x0031,  // 16 bit boolean
  Boolean32 = 0x0032,  // 32 bit boolean
  Boolean64 = 0x0033,  // 64 bit boolean
  Boolean128 = 0x0034, // 128 bit boolean
};

enum class SimpleTypeMode : uint32_t {
  Direct = 0x00000000,        // Not a pointer
  NearPointer = 0x00000100,   // Near pointer
  FarPointer = 0x00000200,    // Far pointer
  HugePointer = 0x00000300,   // Huge pointer
  NearPointer32 = 0x00000400, // 32 bit near pointer
  FarPointer32 = 0x00000500,  // 32 bit far pointer
  NearPointer64 = 0x00000600, // 64 bit near pointer
  NearPointer128 = 0x00000700 // 128 bit near pointer
};

/// A 32-bit type reference. Types are indexed by their order of appearance in
/// .debug$T plus 0x1000. Type indices less than 0x1000 are "simple" types,
/// composed of a SimpleTypeMode byte followed by a SimpleTypeKind byte.
class TypeIndex {
public:
  static const uint32_t FirstNonSimpleIndex = 0x1000;
  static const uint32_t SimpleKindMask = 0x000000ff;
  static const uint32_t SimpleModeMask = 0x00000700;
  static const uint32_t DecoratedItemIdMask = 0x80000000;

public:
  TypeIndex() : Index(static_cast<uint32_t>(SimpleTypeKind::None)) {}
  explicit TypeIndex(uint32_t Index) : Index(Index) {}
  explicit TypeIndex(SimpleTypeKind Kind)
      : Index(static_cast<uint32_t>(Kind)) {}
  TypeIndex(SimpleTypeKind Kind, SimpleTypeMode Mode)
      : Index(static_cast<uint32_t>(Kind) | static_cast<uint32_t>(Mode)) {}

  uint32_t getIndex() const { return Index; }
  void setIndex(uint32_t I) { Index = I; }
  bool isSimple() const { return Index < FirstNonSimpleIndex; }
  bool isDecoratedItemId() const { return !!(Index & DecoratedItemIdMask); }

  bool isNoneType() const { return *this == None(); }

  uint32_t toArrayIndex() const {
    assert(!isSimple());
    return (getIndex() & ~DecoratedItemIdMask) - FirstNonSimpleIndex;
  }

  static TypeIndex fromArrayIndex(uint32_t Index) {
    return TypeIndex(Index + FirstNonSimpleIndex);
  }

  static TypeIndex fromDecoratedArrayIndex(bool IsItem, uint32_t Index) {
    return TypeIndex((Index + FirstNonSimpleIndex) |
                     (IsItem ? DecoratedItemIdMask : 0));
  }

  TypeIndex removeDecoration() {
    return TypeIndex(Index & ~DecoratedItemIdMask);
  }

  SimpleTypeKind getSimpleKind() const {
    assert(isSimple());
    return static_cast<SimpleTypeKind>(Index & SimpleKindMask);
  }

  SimpleTypeMode getSimpleMode() const {
    assert(isSimple());
    return static_cast<SimpleTypeMode>(Index & SimpleModeMask);
  }

  TypeIndex makeDirect() const { return TypeIndex{getSimpleKind()}; }

  static TypeIndex None() { return TypeIndex(SimpleTypeKind::None); }
  static TypeIndex Void() { return TypeIndex(SimpleTypeKind::Void); }
  static TypeIndex VoidPointer32() {
    return TypeIndex(SimpleTypeKind::Void, SimpleTypeMode::NearPointer32);
  }
  static TypeIndex VoidPointer64() {
    return TypeIndex(SimpleTypeKind::Void, SimpleTypeMode::NearPointer64);
  }

  static TypeIndex NullptrT() {
    // std::nullptr_t uses the pointer mode that doesn't indicate bit-width,
    // presumably because std::nullptr_t is intended to be compatible with any
    // pointer type.
    return TypeIndex(SimpleTypeKind::Void, SimpleTypeMode::NearPointer);
  }

  static TypeIndex SignedCharacter() {
    return TypeIndex(SimpleTypeKind::SignedCharacter);
  }
  static TypeIndex UnsignedCharacter() {
    return TypeIndex(SimpleTypeKind::UnsignedCharacter);
  }
  static TypeIndex NarrowCharacter() {
    return TypeIndex(SimpleTypeKind::NarrowCharacter);
  }
  static TypeIndex WideCharacter() {
    return TypeIndex(SimpleTypeKind::WideCharacter);
  }
  static TypeIndex Int16Short() {
    return TypeIndex(SimpleTypeKind::Int16Short);
  }
  static TypeIndex UInt16Short() {
    return TypeIndex(SimpleTypeKind::UInt16Short);
  }
  static TypeIndex Int32() { return TypeIndex(SimpleTypeKind::Int32); }
  static TypeIndex UInt32() { return TypeIndex(SimpleTypeKind::UInt32); }
  static TypeIndex Int32Long() { return TypeIndex(SimpleTypeKind::Int32Long); }
  static TypeIndex UInt32Long() {
    return TypeIndex(SimpleTypeKind::UInt32Long);
  }
  static TypeIndex Int64() { return TypeIndex(SimpleTypeKind::Int64); }
  static TypeIndex UInt64() { return TypeIndex(SimpleTypeKind::UInt64); }
  static TypeIndex Int64Quad() { return TypeIndex(SimpleTypeKind::Int64Quad); }
  static TypeIndex UInt64Quad() {
    return TypeIndex(SimpleTypeKind::UInt64Quad);
  }

  static TypeIndex Float32() { return TypeIndex(SimpleTypeKind::Float32); }
  static TypeIndex Float64() { return TypeIndex(SimpleTypeKind::Float64); }

  TypeIndex &operator+=(unsigned N) {
    Index += N;
    return *this;
  }

  TypeIndex &operator++() {
    Index += 1;
    return *this;
  }

  TypeIndex operator++(int) {
    TypeIndex Copy = *this;
    operator++();
    return Copy;
  }

  TypeIndex &operator-=(unsigned N) {
    assert(Index >= N);
    Index -= N;
    return *this;
  }

  TypeIndex &operator--() {
    Index -= 1;
    return *this;
  }

  TypeIndex operator--(int) {
    TypeIndex Copy = *this;
    operator--();
    return Copy;
  }

  friend inline bool operator==(const TypeIndex &A, const TypeIndex &B) {
    return A.getIndex() == B.getIndex();
  }

  friend inline bool operator!=(const TypeIndex &A, const TypeIndex &B) {
    return A.getIndex() != B.getIndex();
  }

  friend inline bool operator<(const TypeIndex &A, const TypeIndex &B) {
    return A.getIndex() < B.getIndex();
  }

  friend inline bool operator<=(const TypeIndex &A, const TypeIndex &B) {
    return A.getIndex() <= B.getIndex();
  }

  friend inline bool operator>(const TypeIndex &A, const TypeIndex &B) {
    return A.getIndex() > B.getIndex();
  }

  friend inline bool operator>=(const TypeIndex &A, const TypeIndex &B) {
    return A.getIndex() >= B.getIndex();
  }

  friend inline TypeIndex operator+(const TypeIndex &A, uint32_t N) {
    TypeIndex Result(A);
    Result += N;
    return Result;
  }

  friend inline TypeIndex operator-(const TypeIndex &A, uint32_t N) {
    assert(A.getIndex() >= N);
    TypeIndex Result(A);
    Result -= N;
    return Result;
  }

  friend inline uint32_t operator-(const TypeIndex &A, const TypeIndex &B) {
    assert(A >= B);
    return A.toArrayIndex() - B.toArrayIndex();
  }

  static StringRef simpleTypeName(TypeIndex TI);

private:
  support::ulittle32_t Index;
};

// Used for pseudo-indexing an array of type records.  An array of such records
// sorted by TypeIndex can allow log(N) lookups even though such a type record
// stream does not provide random access.
struct TypeIndexOffset {
  TypeIndex Type;
  support::ulittle32_t Offset;
};

void printTypeIndex(ScopedPrinter &Printer, StringRef FieldName, TypeIndex TI,
                    TypeCollection &Types);
}

template <> struct DenseMapInfo<codeview::TypeIndex> {
  static inline codeview::TypeIndex getEmptyKey() {
    return codeview::TypeIndex{DenseMapInfo<uint32_t>::getEmptyKey()};
  }
  static inline codeview::TypeIndex getTombstoneKey() {
    return codeview::TypeIndex{DenseMapInfo<uint32_t>::getTombstoneKey()};
  }
  static unsigned getHashValue(const codeview::TypeIndex &TI) {
    return DenseMapInfo<uint32_t>::getHashValue(TI.getIndex());
  }
  static bool isEqual(const codeview::TypeIndex &LHS,
                      const codeview::TypeIndex &RHS) {
    return LHS == RHS;
  }
};

} // namespace llvm

#endif
