//===- NativeInlineSiteSymbol.cpp - info about inline sites -----*- 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/NativeInlineSiteSymbol.h"

#include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"
#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
#include "llvm/DebugInfo/PDB/Native/NativeEnumLineNumbers.h"
#include "llvm/DebugInfo/PDB/Native/TpiStream.h"

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

NativeInlineSiteSymbol::NativeInlineSiteSymbol(
    NativeSession &Session, SymIndexId Id, const codeview::InlineSiteSym &Sym,
    uint64_t ParentAddr)
    : NativeRawSymbol(Session, PDB_SymType::InlineSite, Id), Sym(Sym),
      ParentAddr(ParentAddr) {}

NativeInlineSiteSymbol::~NativeInlineSiteSymbol() {}

void NativeInlineSiteSymbol::dump(raw_ostream &OS, int Indent,
                                  PdbSymbolIdField ShowIdFields,
                                  PdbSymbolIdField RecurseIdFields) const {
  NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
  dumpSymbolField(OS, "name", getName(), Indent);
}

static Optional<InlineeSourceLine>
findInlineeByTypeIndex(TypeIndex Id, ModuleDebugStreamRef &ModS) {
  for (const auto &SS : ModS.getSubsectionsArray()) {
    if (SS.kind() != DebugSubsectionKind::InlineeLines)
      continue;

    DebugInlineeLinesSubsectionRef InlineeLines;
    BinaryStreamReader Reader(SS.getRecordData());
    if (auto EC = InlineeLines.initialize(Reader)) {
      consumeError(std::move(EC));
      continue;
    }

    for (const InlineeSourceLine &Line : InlineeLines)
      if (Line.Header->Inlinee == Id)
        return Line;
  }
  return None;
}

std::string NativeInlineSiteSymbol::getName() const {
  auto Tpi = Session.getPDBFile().getPDBTpiStream();
  if (!Tpi) {
    consumeError(Tpi.takeError());
    return "";
  }
  auto Ipi = Session.getPDBFile().getPDBIpiStream();
  if (!Ipi) {
    consumeError(Ipi.takeError());
    return "";
  }

  LazyRandomTypeCollection &Types = Tpi->typeCollection();
  LazyRandomTypeCollection &Ids = Ipi->typeCollection();
  CVType InlineeType = Ids.getType(Sym.Inlinee);
  std::string QualifiedName;
  if (InlineeType.kind() == LF_MFUNC_ID) {
    MemberFuncIdRecord MFRecord;
    cantFail(TypeDeserializer::deserializeAs<MemberFuncIdRecord>(InlineeType,
                                                                 MFRecord));
    TypeIndex ClassTy = MFRecord.getClassType();
    QualifiedName.append(std::string(Types.getTypeName(ClassTy)));
    QualifiedName.append("::");
  } else if (InlineeType.kind() == LF_FUNC_ID) {
    FuncIdRecord FRecord;
    cantFail(
        TypeDeserializer::deserializeAs<FuncIdRecord>(InlineeType, FRecord));
    TypeIndex ParentScope = FRecord.getParentScope();
    if (!ParentScope.isNoneType()) {
      QualifiedName.append(std::string(Ids.getTypeName(ParentScope)));
      QualifiedName.append("::");
    }
  }

  QualifiedName.append(std::string(Ids.getTypeName(Sym.Inlinee)));
  return QualifiedName;
}

void NativeInlineSiteSymbol::getLineOffset(uint32_t OffsetInFunc,
                                           uint32_t &LineOffset,
                                           uint32_t &FileOffset) const {
  LineOffset = 0;
  FileOffset = 0;
  uint32_t CodeOffset = 0;
  for (const auto &Annot : Sym.annotations()) {
    switch (Annot.OpCode) {
    case BinaryAnnotationsOpCode::CodeOffset:
    case BinaryAnnotationsOpCode::ChangeCodeOffset:
    case BinaryAnnotationsOpCode::ChangeCodeLength:
      CodeOffset += Annot.U1;
      break;
    case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset:
      CodeOffset += Annot.U2;
      break;
    case BinaryAnnotationsOpCode::ChangeLineOffset:
    case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset:
      CodeOffset += Annot.U1;
      LineOffset += Annot.S1;
      break;
    case BinaryAnnotationsOpCode::ChangeFile:
      FileOffset = Annot.U1;
      break;
    default:
      break;
    }

    if (CodeOffset >= OffsetInFunc)
      return;
  }
}

std::unique_ptr<IPDBEnumLineNumbers>
NativeInlineSiteSymbol::findInlineeLinesByVA(uint64_t VA,
                                             uint32_t Length) const {
  uint16_t Modi;
  if (!Session.moduleIndexForVA(VA, Modi))
    return nullptr;

  Expected<ModuleDebugStreamRef> ModS = Session.getModuleDebugStream(Modi);
  if (!ModS) {
    consumeError(ModS.takeError());
    return nullptr;
  }

  Expected<DebugChecksumsSubsectionRef> Checksums =
      ModS->findChecksumsSubsection();
  if (!Checksums) {
    consumeError(Checksums.takeError());
    return nullptr;
  }

  // Get the line number offset and source file offset.
  uint32_t SrcLineOffset;
  uint32_t SrcFileOffset;
  getLineOffset(VA - ParentAddr, SrcLineOffset, SrcFileOffset);

  // Get line info from inlinee line table.
  Optional<InlineeSourceLine> Inlinee =
      findInlineeByTypeIndex(Sym.Inlinee, ModS.get());

  if (!Inlinee)
    return nullptr;

  uint32_t SrcLine = Inlinee->Header->SourceLineNum + SrcLineOffset;
  uint32_t SrcCol = 0; // Inline sites don't seem to have column info.
  uint32_t FileChecksumOffset =
      (SrcFileOffset == 0) ? Inlinee->Header->FileID : SrcFileOffset;

  auto ChecksumIter = Checksums->getArray().at(FileChecksumOffset);
  uint32_t SrcFileId =
      Session.getSymbolCache().getOrCreateSourceFile(*ChecksumIter);

  uint32_t LineSect, LineOff;
  Session.addressForVA(VA, LineSect, LineOff);
  NativeLineNumber LineNum(Session, SrcLine, SrcCol, LineSect, LineOff, Length,
                           SrcFileId, Modi);
  auto SrcFile = Session.getSymbolCache().getSourceFileById(SrcFileId);
  std::vector<NativeLineNumber> Lines{LineNum};

  return std::make_unique<NativeEnumLineNumbers>(std::move(Lines));
}
