//===- DWARFLinkerCompileUnit.cpp -----------------------------------------===//
//
// 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/DWARFLinker/DWARFLinkerCompileUnit.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/DWARFLinker/DWARFLinkerDeclContext.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
#include "llvm/Support/FormatVariadic.h"

namespace llvm {

#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void CompileUnit::DIEInfo::dump() {
  llvm::errs() << "{\n";
  llvm::errs() << "  AddrAdjust: " << AddrAdjust << '\n';
  llvm::errs() << "  Ctxt: " << formatv("{0:x}", Ctxt) << '\n';
  llvm::errs() << "  Clone: " << formatv("{0:x}", Clone) << '\n';
  llvm::errs() << "  ParentIdx: " << ParentIdx << '\n';
  llvm::errs() << "  Keep: " << Keep << '\n';
  llvm::errs() << "  InDebugMap: " << InDebugMap << '\n';
  llvm::errs() << "  Prune: " << Prune << '\n';
  llvm::errs() << "  Incomplete: " << Incomplete << '\n';
  llvm::errs() << "  InModuleScope: " << InModuleScope << '\n';
  llvm::errs() << "  ODRMarkingDone: " << ODRMarkingDone << '\n';
  llvm::errs() << "  UnclonedReference: " << UnclonedReference << '\n';
  llvm::errs() << "}\n";
}
#endif // if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)

/// Check if the DIE at \p Idx is in the scope of a function.
static bool inFunctionScope(CompileUnit &U, unsigned Idx) {
  while (Idx) {
    if (U.getOrigUnit().getDIEAtIndex(Idx).getTag() == dwarf::DW_TAG_subprogram)
      return true;
    Idx = U.getInfo(Idx).ParentIdx;
  }
  return false;
}

uint16_t CompileUnit::getLanguage() {
  if (!Language) {
    DWARFDie CU = getOrigUnit().getUnitDIE();
    Language = dwarf::toUnsigned(CU.find(dwarf::DW_AT_language), 0);
  }
  return Language;
}

StringRef CompileUnit::getSysRoot() {
  if (SysRoot.empty()) {
    DWARFDie CU = getOrigUnit().getUnitDIE();
    SysRoot = dwarf::toStringRef(CU.find(dwarf::DW_AT_LLVM_sysroot)).str();
  }
  return SysRoot;
}

void CompileUnit::markEverythingAsKept() {
  unsigned Idx = 0;

  for (auto &I : Info) {
    // Mark everything that wasn't explicit marked for pruning.
    I.Keep = !I.Prune;
    auto DIE = OrigUnit.getDIEAtIndex(Idx++);
    DWARFUnit *U = DIE.getDwarfUnit();

    // Try to guess which DIEs must go to the accelerator tables. We do that
    // just for variables, because functions will be handled depending on
    // whether they carry a DW_AT_low_pc attribute or not.
    if (DIE.getTag() != dwarf::DW_TAG_variable &&
        DIE.getTag() != dwarf::DW_TAG_constant)
      continue;

    std::optional<DWARFFormValue> Value;
    if (!(Value = DIE.find(dwarf::DW_AT_location))) {
      if ((Value = DIE.find(dwarf::DW_AT_const_value)) &&
          !inFunctionScope(*this, I.ParentIdx))
        I.InDebugMap = true;
      continue;
    }

    if (auto ExprLockBlock = Value->getAsBlock()) {
      // Parse 'exprloc' expression.
      DataExtractor Data(toStringRef(*ExprLockBlock),
                         U->getContext().isLittleEndian(),
                         U->getAddressByteSize());
      DWARFExpression Expression(Data, U->getAddressByteSize(),
                                 U->getFormParams().Format);

      for (DWARFExpression::iterator It = Expression.begin();
           (It != Expression.end()) && !I.InDebugMap; ++It) {
        DWARFExpression::iterator NextIt = It;
        ++NextIt;

        switch (It->getCode()) {
        case dwarf::DW_OP_const4u:
        case dwarf::DW_OP_const8u:
        case dwarf::DW_OP_const4s:
        case dwarf::DW_OP_const8s:
          if (NextIt == Expression.end() ||
              NextIt->getCode() != dwarf::DW_OP_form_tls_address)
            break;
          [[fallthrough]];
        case dwarf::DW_OP_constx:
        case dwarf::DW_OP_addr:
        case dwarf::DW_OP_addrx:
          I.InDebugMap = true;
          break;
        default:
          // Nothing to do.
          break;
        }
      }
    }
  }
}

uint64_t CompileUnit::computeNextUnitOffset(uint16_t DwarfVersion) {
  NextUnitOffset = StartOffset;
  if (NewUnit) {
    NextUnitOffset += (DwarfVersion >= 5) ? 12 : 11; // Header size
    NextUnitOffset += NewUnit->getUnitDie().getSize();
  }
  return NextUnitOffset;
}

/// Keep track of a forward cross-cu reference from this unit
/// to \p Die that lives in \p RefUnit.
void CompileUnit::noteForwardReference(DIE *Die, const CompileUnit *RefUnit,
                                       DeclContext *Ctxt, PatchLocation Attr) {
  ForwardDIEReferences.emplace_back(Die, RefUnit, Ctxt, Attr);
}

void CompileUnit::fixupForwardReferences() {
  for (const auto &Ref : ForwardDIEReferences) {
    DIE *RefDie;
    const CompileUnit *RefUnit;
    PatchLocation Attr;
    DeclContext *Ctxt;
    std::tie(RefDie, RefUnit, Ctxt, Attr) = Ref;
    if (Ctxt && Ctxt->hasCanonicalDIE()) {
      assert(Ctxt->getCanonicalDIEOffset() &&
             "Canonical die offset is not set");
      Attr.set(Ctxt->getCanonicalDIEOffset());
    } else {
      assert(RefDie->getOffset() && "Referenced die offset is not set");
      Attr.set(RefDie->getOffset() + RefUnit->getStartOffset());
    }
  }
}

void CompileUnit::addLabelLowPc(uint64_t LabelLowPc, int64_t PcOffset) {
  Labels.insert({LabelLowPc, PcOffset});
}

void CompileUnit::addFunctionRange(uint64_t FuncLowPc, uint64_t FuncHighPc,
                                   int64_t PcOffset) {
  Ranges.insert({FuncLowPc, FuncHighPc}, PcOffset);
  if (LowPc)
    LowPc = std::min(*LowPc, FuncLowPc + PcOffset);
  else
    LowPc = FuncLowPc + PcOffset;
  this->HighPc = std::max(HighPc, FuncHighPc + PcOffset);
}

void CompileUnit::noteRangeAttribute(const DIE &Die, PatchLocation Attr) {
  if (Die.getTag() == dwarf::DW_TAG_compile_unit) {
    UnitRangeAttribute = Attr;
    return;
  }

  RangeAttributes.emplace_back(Attr);
}

void CompileUnit::noteLocationAttribute(PatchLocation Attr) {
  LocationAttributes.emplace_back(Attr);
}

void CompileUnit::addNamespaceAccelerator(const DIE *Die,
                                          DwarfStringPoolEntryRef Name) {
  Namespaces.emplace_back(Name, Die);
}

void CompileUnit::addObjCAccelerator(const DIE *Die,
                                     DwarfStringPoolEntryRef Name,
                                     bool SkipPubSection) {
  ObjC.emplace_back(Name, Die, SkipPubSection);
}

void CompileUnit::addNameAccelerator(const DIE *Die,
                                     DwarfStringPoolEntryRef Name,
                                     bool SkipPubSection) {
  Pubnames.emplace_back(Name, Die, SkipPubSection);
}

void CompileUnit::addTypeAccelerator(const DIE *Die,
                                     DwarfStringPoolEntryRef Name,
                                     bool ObjcClassImplementation,
                                     uint32_t QualifiedNameHash) {
  Pubtypes.emplace_back(Name, Die, QualifiedNameHash, ObjcClassImplementation);
}

} // namespace llvm
