//===- NativeTypeEnum.cpp - info about enum type ----------------*- 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
//
//===----------------------------------------------------------------------===//

#include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h"

#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h"
#include "llvm/DebugInfo/PDB/Native/NativeSymbolEnumerator.h"
#include "llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h"
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
#include "llvm/DebugInfo/PDB/Native/SymbolCache.h"
#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"

#include "llvm/Support/FormatVariadic.h"

#include <cassert>

using namespace llvm;
using namespace llvm::codeview;
using namespace llvm::pdb;

namespace {
// Yea, this is a pretty terrible class name.  But if we have an enum:
//
// enum Foo {
//  A,
//  B
// };
//
// then A and B are the "enumerators" of the "enum" Foo.  And we need
// to enumerate them.
class NativeEnumEnumEnumerators : public IPDBEnumSymbols, TypeVisitorCallbacks {
public:
  NativeEnumEnumEnumerators(NativeSession &Session,
                            const NativeTypeEnum &ClassParent);

  uint32_t getChildCount() const override;
  std::unique_ptr<PDBSymbol> getChildAtIndex(uint32_t Index) const override;
  std::unique_ptr<PDBSymbol> getNext() override;
  void reset() override;

private:
  Error visitKnownMember(CVMemberRecord &CVM,
                         EnumeratorRecord &Record) override;
  Error visitKnownMember(CVMemberRecord &CVM,
                         ListContinuationRecord &Record) override;

  NativeSession &Session;
  const NativeTypeEnum &ClassParent;
  std::vector<EnumeratorRecord> Enumerators;
  Optional<TypeIndex> ContinuationIndex;
  uint32_t Index = 0;
};
} // namespace

NativeEnumEnumEnumerators::NativeEnumEnumEnumerators(
    NativeSession &Session, const NativeTypeEnum &ClassParent)
    : Session(Session), ClassParent(ClassParent) {
  TpiStream &Tpi = cantFail(Session.getPDBFile().getPDBTpiStream());
  LazyRandomTypeCollection &Types = Tpi.typeCollection();

  ContinuationIndex = ClassParent.getEnumRecord().FieldList;
  while (ContinuationIndex) {
    CVType FieldList = Types.getType(*ContinuationIndex);
    assert(FieldList.kind() == LF_FIELDLIST);
    ContinuationIndex.reset();
    cantFail(visitMemberRecordStream(FieldList.data(), *this));
  }
}

Error NativeEnumEnumEnumerators::visitKnownMember(CVMemberRecord &CVM,
                                                  EnumeratorRecord &Record) {
  Enumerators.push_back(Record);
  return Error::success();
}

Error NativeEnumEnumEnumerators::visitKnownMember(
    CVMemberRecord &CVM, ListContinuationRecord &Record) {
  ContinuationIndex = Record.ContinuationIndex;
  return Error::success();
}

uint32_t NativeEnumEnumEnumerators::getChildCount() const {
  return Enumerators.size();
}

std::unique_ptr<PDBSymbol>
NativeEnumEnumEnumerators::getChildAtIndex(uint32_t Index) const {
  if (Index >= getChildCount())
    return nullptr;

  SymIndexId Id = Session.getSymbolCache()
                      .getOrCreateFieldListMember<NativeSymbolEnumerator>(
                          ClassParent.getEnumRecord().FieldList, Index,
                          ClassParent, Enumerators[Index]);
  return Session.getSymbolCache().getSymbolById(Id);
}

std::unique_ptr<PDBSymbol> NativeEnumEnumEnumerators::getNext() {
  if (Index >= getChildCount())
    return nullptr;

  return getChildAtIndex(Index++);
}

void NativeEnumEnumEnumerators::reset() { Index = 0; }

NativeTypeEnum::NativeTypeEnum(NativeSession &Session, SymIndexId Id,
                               TypeIndex Index, EnumRecord Record)
    : NativeRawSymbol(Session, PDB_SymType::Enum, Id), Index(Index),
      Record(std::move(Record)) {}

NativeTypeEnum::NativeTypeEnum(NativeSession &Session, SymIndexId Id,
                               NativeTypeEnum &UnmodifiedType,
                               codeview::ModifierRecord Modifier)
    : NativeRawSymbol(Session, PDB_SymType::Enum, Id),
      UnmodifiedType(&UnmodifiedType), Modifiers(std::move(Modifier)) {}

NativeTypeEnum::~NativeTypeEnum() {}

void NativeTypeEnum::dump(raw_ostream &OS, int Indent,
                          PdbSymbolIdField ShowIdFields,
                          PdbSymbolIdField RecurseIdFields) const {
  NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);

  dumpSymbolField(OS, "baseType", static_cast<uint32_t>(getBuiltinType()),
                  Indent);
  dumpSymbolIdField(OS, "lexicalParentId", 0, Indent, Session,
                    PdbSymbolIdField::LexicalParent, ShowIdFields,
                    RecurseIdFields);
  dumpSymbolField(OS, "name", getName(), Indent);
  dumpSymbolIdField(OS, "typeId", getTypeId(), Indent, Session,
                    PdbSymbolIdField::Type, ShowIdFields, RecurseIdFields);
  if (Modifiers.hasValue())
    dumpSymbolIdField(OS, "unmodifiedTypeId", getUnmodifiedTypeId(), Indent,
                      Session, PdbSymbolIdField::UnmodifiedType, ShowIdFields,
                      RecurseIdFields);
  dumpSymbolField(OS, "length", getLength(), Indent);
  dumpSymbolField(OS, "constructor", hasConstructor(), Indent);
  dumpSymbolField(OS, "constType", isConstType(), Indent);
  dumpSymbolField(OS, "hasAssignmentOperator", hasAssignmentOperator(), Indent);
  dumpSymbolField(OS, "hasCastOperator", hasCastOperator(), Indent);
  dumpSymbolField(OS, "hasNestedTypes", hasNestedTypes(), Indent);
  dumpSymbolField(OS, "overloadedOperator", hasOverloadedOperator(), Indent);
  dumpSymbolField(OS, "isInterfaceUdt", isInterfaceUdt(), Indent);
  dumpSymbolField(OS, "intrinsic", isIntrinsic(), Indent);
  dumpSymbolField(OS, "nested", isNested(), Indent);
  dumpSymbolField(OS, "packed", isPacked(), Indent);
  dumpSymbolField(OS, "isRefUdt", isRefUdt(), Indent);
  dumpSymbolField(OS, "scoped", isScoped(), Indent);
  dumpSymbolField(OS, "unalignedType", isUnalignedType(), Indent);
  dumpSymbolField(OS, "isValueUdt", isValueUdt(), Indent);
  dumpSymbolField(OS, "volatileType", isVolatileType(), Indent);
}

std::unique_ptr<IPDBEnumSymbols>
NativeTypeEnum::findChildren(PDB_SymType Type) const {
  if (Type != PDB_SymType::Data)
    return std::make_unique<NullEnumerator<PDBSymbol>>();

  const NativeTypeEnum *ClassParent = nullptr;
  if (!Modifiers)
    ClassParent = this;
  else
    ClassParent = UnmodifiedType;
  return std::make_unique<NativeEnumEnumEnumerators>(Session, *ClassParent);
}

PDB_SymType NativeTypeEnum::getSymTag() const { return PDB_SymType::Enum; }

PDB_BuiltinType NativeTypeEnum::getBuiltinType() const {
  if (UnmodifiedType)
    return UnmodifiedType->getBuiltinType();

  Session.getSymbolCache().findSymbolByTypeIndex(Record->getUnderlyingType());

  codeview::TypeIndex Underlying = Record->getUnderlyingType();

  // This indicates a corrupt record.
  if (!Underlying.isSimple() ||
      Underlying.getSimpleMode() != SimpleTypeMode::Direct) {
    return PDB_BuiltinType::None;
  }

  switch (Underlying.getSimpleKind()) {
  case SimpleTypeKind::Boolean128:
  case SimpleTypeKind::Boolean64:
  case SimpleTypeKind::Boolean32:
  case SimpleTypeKind::Boolean16:
  case SimpleTypeKind::Boolean8:
    return PDB_BuiltinType::Bool;
  case SimpleTypeKind::NarrowCharacter:
  case SimpleTypeKind::UnsignedCharacter:
  case SimpleTypeKind::SignedCharacter:
    return PDB_BuiltinType::Char;
  case SimpleTypeKind::WideCharacter:
    return PDB_BuiltinType::WCharT;
  case SimpleTypeKind::Character16:
    return PDB_BuiltinType::Char16;
  case SimpleTypeKind::Character32:
    return PDB_BuiltinType::Char32;
  case SimpleTypeKind::Int128:
  case SimpleTypeKind::Int128Oct:
  case SimpleTypeKind::Int16:
  case SimpleTypeKind::Int16Short:
  case SimpleTypeKind::Int32:
  case SimpleTypeKind::Int32Long:
  case SimpleTypeKind::Int64:
  case SimpleTypeKind::Int64Quad:
    return PDB_BuiltinType::Int;
  case SimpleTypeKind::UInt128:
  case SimpleTypeKind::UInt128Oct:
  case SimpleTypeKind::UInt16:
  case SimpleTypeKind::UInt16Short:
  case SimpleTypeKind::UInt32:
  case SimpleTypeKind::UInt32Long:
  case SimpleTypeKind::UInt64:
  case SimpleTypeKind::UInt64Quad:
    return PDB_BuiltinType::UInt;
  case SimpleTypeKind::HResult:
    return PDB_BuiltinType::HResult;
  case SimpleTypeKind::Complex16:
  case SimpleTypeKind::Complex32:
  case SimpleTypeKind::Complex32PartialPrecision:
  case SimpleTypeKind::Complex64:
  case SimpleTypeKind::Complex80:
  case SimpleTypeKind::Complex128:
    return PDB_BuiltinType::Complex;
  case SimpleTypeKind::Float16:
  case SimpleTypeKind::Float32:
  case SimpleTypeKind::Float32PartialPrecision:
  case SimpleTypeKind::Float48:
  case SimpleTypeKind::Float64:
  case SimpleTypeKind::Float80:
  case SimpleTypeKind::Float128:
    return PDB_BuiltinType::Float;
  default:
    return PDB_BuiltinType::None;
  }
  llvm_unreachable("Unreachable");
}

SymIndexId NativeTypeEnum::getUnmodifiedTypeId() const {
  return UnmodifiedType ? UnmodifiedType->getSymIndexId() : 0;
}

bool NativeTypeEnum::hasConstructor() const {
  if (UnmodifiedType)
    return UnmodifiedType->hasConstructor();

  return bool(Record->getOptions() &
              codeview::ClassOptions::HasConstructorOrDestructor);
}

bool NativeTypeEnum::hasAssignmentOperator() const {
  if (UnmodifiedType)
    return UnmodifiedType->hasAssignmentOperator();

  return bool(Record->getOptions() &
              codeview::ClassOptions::HasOverloadedAssignmentOperator);
}

bool NativeTypeEnum::hasNestedTypes() const {
  if (UnmodifiedType)
    return UnmodifiedType->hasNestedTypes();

  return bool(Record->getOptions() &
              codeview::ClassOptions::ContainsNestedClass);
}

bool NativeTypeEnum::isIntrinsic() const {
  if (UnmodifiedType)
    return UnmodifiedType->isIntrinsic();

  return bool(Record->getOptions() & codeview::ClassOptions::Intrinsic);
}

bool NativeTypeEnum::hasCastOperator() const {
  if (UnmodifiedType)
    return UnmodifiedType->hasCastOperator();

  return bool(Record->getOptions() &
              codeview::ClassOptions::HasConversionOperator);
}

uint64_t NativeTypeEnum::getLength() const {
  if (UnmodifiedType)
    return UnmodifiedType->getLength();

  const auto Id = Session.getSymbolCache().findSymbolByTypeIndex(
      Record->getUnderlyingType());
  const auto UnderlyingType =
      Session.getConcreteSymbolById<PDBSymbolTypeBuiltin>(Id);
  return UnderlyingType ? UnderlyingType->getLength() : 0;
}

std::string NativeTypeEnum::getName() const {
  if (UnmodifiedType)
    return UnmodifiedType->getName();

  return std::string(Record->getName());
}

bool NativeTypeEnum::isNested() const {
  if (UnmodifiedType)
    return UnmodifiedType->isNested();

  return bool(Record->getOptions() & codeview::ClassOptions::Nested);
}

bool NativeTypeEnum::hasOverloadedOperator() const {
  if (UnmodifiedType)
    return UnmodifiedType->hasOverloadedOperator();

  return bool(Record->getOptions() &
              codeview::ClassOptions::HasOverloadedOperator);
}

bool NativeTypeEnum::isPacked() const {
  if (UnmodifiedType)
    return UnmodifiedType->isPacked();

  return bool(Record->getOptions() & codeview::ClassOptions::Packed);
}

bool NativeTypeEnum::isScoped() const {
  if (UnmodifiedType)
    return UnmodifiedType->isScoped();

  return bool(Record->getOptions() & codeview::ClassOptions::Scoped);
}

SymIndexId NativeTypeEnum::getTypeId() const {
  if (UnmodifiedType)
    return UnmodifiedType->getTypeId();

  return Session.getSymbolCache().findSymbolByTypeIndex(
      Record->getUnderlyingType());
}

bool NativeTypeEnum::isRefUdt() const { return false; }

bool NativeTypeEnum::isValueUdt() const { return false; }

bool NativeTypeEnum::isInterfaceUdt() const { return false; }

bool NativeTypeEnum::isConstType() const {
  if (!Modifiers)
    return false;
  return ((Modifiers->getModifiers() & ModifierOptions::Const) !=
          ModifierOptions::None);
}

bool NativeTypeEnum::isVolatileType() const {
  if (!Modifiers)
    return false;
  return ((Modifiers->getModifiers() & ModifierOptions::Volatile) !=
          ModifierOptions::None);
}

bool NativeTypeEnum::isUnalignedType() const {
  if (!Modifiers)
    return false;
  return ((Modifiers->getModifiers() & ModifierOptions::Unaligned) !=
          ModifierOptions::None);
}

const NativeTypeBuiltin &NativeTypeEnum::getUnderlyingBuiltinType() const {
  if (UnmodifiedType)
    return UnmodifiedType->getUnderlyingBuiltinType();

  return Session.getSymbolCache().getNativeSymbolById<NativeTypeBuiltin>(
      getTypeId());
}
