//===- RecordName.cpp ----------------------------------------- *- 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/CodeView/RecordName.h"

#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
#include "llvm/DebugInfo/CodeView/SymbolRecordMapping.h"
#include "llvm/DebugInfo/CodeView/TypeCollection.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
#include "llvm/Support/FormatVariadic.h"

using namespace llvm;
using namespace llvm::codeview;

namespace {
class TypeNameComputer : public TypeVisitorCallbacks {
  /// The type collection.  Used to calculate names of nested types.
  TypeCollection &Types;
  TypeIndex CurrentTypeIndex = TypeIndex::None();

  /// Name of the current type. Only valid before visitTypeEnd.
  SmallString<256> Name;

public:
  explicit TypeNameComputer(TypeCollection &Types) : Types(Types) {}

  StringRef name() const { return Name; }

  /// Paired begin/end actions for all types. Receives all record data,
  /// including the fixed-length record prefix.
  Error visitTypeBegin(CVType &Record) override;
  Error visitTypeBegin(CVType &Record, TypeIndex Index) override;
  Error visitTypeEnd(CVType &Record) override;

#define TYPE_RECORD(EnumName, EnumVal, Name)                                   \
  Error visitKnownRecord(CVType &CVR, Name##Record &Record) override;
#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
#define MEMBER_RECORD(EnumName, EnumVal, Name)
#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
};
} // namespace

Error TypeNameComputer::visitTypeBegin(CVType &Record) {
  llvm_unreachable("Must call visitTypeBegin with a TypeIndex!");
  return Error::success();
}

Error TypeNameComputer::visitTypeBegin(CVType &Record, TypeIndex Index) {
  // Reset Name to the empty string. If the visitor sets it, we know it.
  Name = "";
  CurrentTypeIndex = Index;
  return Error::success();
}

Error TypeNameComputer::visitTypeEnd(CVType &CVR) { return Error::success(); }

Error TypeNameComputer::visitKnownRecord(CVType &CVR,
                                         FieldListRecord &FieldList) {
  Name = "<field list>";
  return Error::success();
}

Error TypeNameComputer::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
                                         StringIdRecord &String) {
  Name = String.getString();
  return Error::success();
}

Error TypeNameComputer::visitKnownRecord(CVType &CVR, ArgListRecord &Args) {
  auto Indices = Args.getIndices();
  uint32_t Size = Indices.size();
  Name = "(";
  for (uint32_t I = 0; I < Size; ++I) {
    if (Indices[I] < CurrentTypeIndex)
      Name.append(Types.getTypeName(Indices[I]));
    else
      Name.append("<unknown 0x" + utohexstr(Indices[I].getIndex()) + ">");
    if (I + 1 != Size)
      Name.append(", ");
  }
  Name.push_back(')');
  return Error::success();
}

Error TypeNameComputer::visitKnownRecord(CVType &CVR,
                                         StringListRecord &Strings) {
  auto Indices = Strings.getIndices();
  uint32_t Size = Indices.size();
  Name = "\"";
  for (uint32_t I = 0; I < Size; ++I) {
    Name.append(Types.getTypeName(Indices[I]));
    if (I + 1 != Size)
      Name.append("\" \"");
  }
  Name.push_back('\"');
  return Error::success();
}

Error TypeNameComputer::visitKnownRecord(CVType &CVR, ClassRecord &Class) {
  Name = Class.getName();
  return Error::success();
}

Error TypeNameComputer::visitKnownRecord(CVType &CVR, UnionRecord &Union) {
  Name = Union.getName();
  return Error::success();
}

Error TypeNameComputer::visitKnownRecord(CVType &CVR, EnumRecord &Enum) {
  Name = Enum.getName();
  return Error::success();
}

Error TypeNameComputer::visitKnownRecord(CVType &CVR, ArrayRecord &AT) {
  Name = AT.getName();
  return Error::success();
}

Error TypeNameComputer::visitKnownRecord(CVType &CVR, VFTableRecord &VFT) {
  Name = VFT.getName();
  return Error::success();
}

Error TypeNameComputer::visitKnownRecord(CVType &CVR, MemberFuncIdRecord &Id) {
  Name = Id.getName();
  return Error::success();
}

Error TypeNameComputer::visitKnownRecord(CVType &CVR, ProcedureRecord &Proc) {
  StringRef Ret = Types.getTypeName(Proc.getReturnType());
  StringRef Params = Types.getTypeName(Proc.getArgumentList());
  Name = formatv("{0} {1}", Ret, Params).sstr<256>();
  return Error::success();
}

Error TypeNameComputer::visitKnownRecord(CVType &CVR,
                                         MemberFunctionRecord &MF) {
  StringRef Ret = Types.getTypeName(MF.getReturnType());
  StringRef Class = Types.getTypeName(MF.getClassType());
  StringRef Params = Types.getTypeName(MF.getArgumentList());
  Name = formatv("{0} {1}::{2}", Ret, Class, Params).sstr<256>();
  return Error::success();
}

Error TypeNameComputer::visitKnownRecord(CVType &CVR, FuncIdRecord &Func) {
  Name = Func.getName();
  return Error::success();
}

Error TypeNameComputer::visitKnownRecord(CVType &CVR, TypeServer2Record &TS) {
  Name = TS.getName();
  return Error::success();
}

Error TypeNameComputer::visitKnownRecord(CVType &CVR, PointerRecord &Ptr) {

  if (Ptr.isPointerToMember()) {
    const MemberPointerInfo &MI = Ptr.getMemberInfo();

    StringRef Pointee = Types.getTypeName(Ptr.getReferentType());
    StringRef Class = Types.getTypeName(MI.getContainingType());
    Name = formatv("{0} {1}::*", Pointee, Class);
  } else {
    Name.append(Types.getTypeName(Ptr.getReferentType()));

    if (Ptr.getMode() == PointerMode::LValueReference)
      Name.append("&");
    else if (Ptr.getMode() == PointerMode::RValueReference)
      Name.append("&&");
    else if (Ptr.getMode() == PointerMode::Pointer)
      Name.append("*");

    // Qualifiers in pointer records apply to the pointer, not the pointee, so
    // they go on the right.
    if (Ptr.isConst())
      Name.append(" const");
    if (Ptr.isVolatile())
      Name.append(" volatile");
    if (Ptr.isUnaligned())
      Name.append(" __unaligned");
    if (Ptr.isRestrict())
      Name.append(" __restrict");
  }
  return Error::success();
}

Error TypeNameComputer::visitKnownRecord(CVType &CVR, ModifierRecord &Mod) {
  uint16_t Mods = static_cast<uint16_t>(Mod.getModifiers());

  if (Mods & uint16_t(ModifierOptions::Const))
    Name.append("const ");
  if (Mods & uint16_t(ModifierOptions::Volatile))
    Name.append("volatile ");
  if (Mods & uint16_t(ModifierOptions::Unaligned))
    Name.append("__unaligned ");
  Name.append(Types.getTypeName(Mod.getModifiedType()));
  return Error::success();
}

Error TypeNameComputer::visitKnownRecord(CVType &CVR,
                                         VFTableShapeRecord &Shape) {
  Name = formatv("<vftable {0} methods>", Shape.getEntryCount());
  return Error::success();
}

Error TypeNameComputer::visitKnownRecord(
    CVType &CVR, UdtModSourceLineRecord &ModSourceLine) {
  return Error::success();
}

Error TypeNameComputer::visitKnownRecord(CVType &CVR,
                                         UdtSourceLineRecord &SourceLine) {
  return Error::success();
}

Error TypeNameComputer::visitKnownRecord(CVType &CVR, BitFieldRecord &BF) {
  return Error::success();
}

Error TypeNameComputer::visitKnownRecord(CVType &CVR,
                                         MethodOverloadListRecord &Overloads) {
  return Error::success();
}

Error TypeNameComputer::visitKnownRecord(CVType &CVR, BuildInfoRecord &BI) {
  return Error::success();
}

Error TypeNameComputer::visitKnownRecord(CVType &CVR, LabelRecord &R) {
  return Error::success();
}

Error TypeNameComputer::visitKnownRecord(CVType &CVR,
                                         PrecompRecord &Precomp) {
  return Error::success();
}

Error TypeNameComputer::visitKnownRecord(CVType &CVR,
                                         EndPrecompRecord &EndPrecomp) {
  return Error::success();
}

std::string llvm::codeview::computeTypeName(TypeCollection &Types,
                                            TypeIndex Index) {
  TypeNameComputer Computer(Types);
  CVType Record = Types.getType(Index);
  if (auto EC = visitTypeRecord(Record, Index, Computer)) {
    consumeError(std::move(EC));
    return "<unknown UDT>";
  }
  return std::string(Computer.name());
}

static int getSymbolNameOffset(CVSymbol Sym) {
  switch (Sym.kind()) {
  // See ProcSym
  case SymbolKind::S_GPROC32:
  case SymbolKind::S_LPROC32:
  case SymbolKind::S_GPROC32_ID:
  case SymbolKind::S_LPROC32_ID:
  case SymbolKind::S_LPROC32_DPC:
  case SymbolKind::S_LPROC32_DPC_ID:
    return 35;
  // See Thunk32Sym
  case SymbolKind::S_THUNK32:
    return 21;
  // See SectionSym
  case SymbolKind::S_SECTION:
    return 16;
  // See CoffGroupSym, RegRelativeIndirSym
  case SymbolKind::S_COFFGROUP:
  case SymbolKind::S_REGREL32_INDIR:
    return 14;
  // See PublicSym32, FileStaticSym, RegRelativeSym, DataSym, ThreadLocalDataSym
  case SymbolKind::S_PUB32:
  case SymbolKind::S_FILESTATIC:
  case SymbolKind::S_REGREL32:
  case SymbolKind::S_GDATA32:
  case SymbolKind::S_LDATA32:
  case SymbolKind::S_LMANDATA:
  case SymbolKind::S_GMANDATA:
  case SymbolKind::S_LTHREAD32:
  case SymbolKind::S_GTHREAD32:
  case SymbolKind::S_PROCREF:
  case SymbolKind::S_LPROCREF:
    return 10;
  // See RegisterSym and LocalSym
  case SymbolKind::S_REGISTER:
  case SymbolKind::S_LOCAL:
    return 6;
  // See BlockSym
  case SymbolKind::S_BLOCK32:
    return 18;
  // See LabelSym
  case SymbolKind::S_LABEL32:
    return 7;
  // See ObjNameSym, ExportSym, and UDTSym
  case SymbolKind::S_OBJNAME:
  case SymbolKind::S_EXPORT:
  case SymbolKind::S_UDT:
    return 4;
  // See BPRelativeSym
  case SymbolKind::S_BPREL32:
    return 8;
  // See UsingNamespaceSym
  case SymbolKind::S_UNAMESPACE:
    return 0;
  default:
    return -1;
  }
}

StringRef llvm::codeview::getSymbolName(CVSymbol Sym) {
  if (Sym.kind() == SymbolKind::S_CONSTANT) {
    // S_CONSTANT is preceded by an APSInt, which has a variable length.  So we
    // have to do a full deserialization.
    BinaryStreamReader Reader(Sym.content(), llvm::endianness::little);
    // The container doesn't matter for single records.
    SymbolRecordMapping Mapping(Reader, CodeViewContainer::ObjectFile);
    ConstantSym Const(SymbolKind::S_CONSTANT);
    cantFail(Mapping.visitSymbolBegin(Sym));
    cantFail(Mapping.visitKnownRecord(Sym, Const));
    cantFail(Mapping.visitSymbolEnd(Sym));
    return Const.Name;
  }

  int Offset = getSymbolNameOffset(Sym);
  if (Offset == -1)
    return StringRef();

  StringRef StringData = toStringRef(Sym.content()).drop_front(Offset);
  return StringData.split('\0').first;
}
