//===- DWARFLinkerCompileUnit.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_LIB_DWARFLINKER_PARALLEL_DWARFLINKERCOMPILEUNIT_H
#define LLVM_LIB_DWARFLINKER_PARALLEL_DWARFLINKERCOMPILEUNIT_H

#include "DWARFLinkerUnit.h"
#include "llvm/DWARFLinker/DWARFFile.h"
#include <limits>
#include <optional>

namespace llvm {
namespace dwarf_linker {
namespace parallel {

using OffsetToUnitTy = function_ref<CompileUnit *(uint64_t Offset)>;

struct AttributesInfo;
class SyntheticTypeNameBuilder;
class DIEGenerator;
class TypeUnit;
class DependencyTracker;

class CompileUnit;

/// This is a helper structure which keeps a debug info entry
/// with it's containing compilation unit.
struct UnitEntryPairTy {
  UnitEntryPairTy() = default;
  UnitEntryPairTy(CompileUnit *CU, const DWARFDebugInfoEntry *DieEntry)
      : CU(CU), DieEntry(DieEntry) {}

  CompileUnit *CU = nullptr;
  const DWARFDebugInfoEntry *DieEntry = nullptr;

  UnitEntryPairTy getNamespaceOrigin();
  std::optional<UnitEntryPairTy> getParent();
};

enum ResolveInterCUReferencesMode : bool {
  Resolve = true,
  AvoidResolving = false,
};

/// Stores all information related to a compile unit, be it in its original
/// instance of the object file or its brand new cloned and generated DIE tree.
/// NOTE: we need alignment of at least 8 bytes as we use
///       PointerIntPair<CompileUnit *, 3> in the DependencyTracker.h
class alignas(8) CompileUnit : public DwarfUnit {
public:
  /// The stages of new compile unit processing.
  enum class Stage : uint8_t {
    /// Created, linked with input DWARF file.
    CreatedNotLoaded = 0,

    /// Input DWARF is loaded.
    Loaded,

    /// Input DWARF is analysed(DIEs pointing to the real code section are
    /// discovered, type names are assigned if ODR is requested).
    LivenessAnalysisDone,

    /// Check if dependencies have incompatible placement.
    /// If that is the case modify placement to be compatible.
    UpdateDependenciesCompleteness,

    /// Type names assigned to DIEs.
    TypeNamesAssigned,

    /// Output DWARF is generated.
    Cloned,

    /// Offsets inside patch records are updated.
    PatchesUpdated,

    /// Resources(Input DWARF, Output DWARF tree) are released.
    Cleaned,

    /// Compile Unit should be skipped
    Skipped
  };

  CompileUnit(LinkingGlobalData &GlobalData, unsigned ID,
              StringRef ClangModuleName, DWARFFile &File,
              OffsetToUnitTy UnitFromOffset, dwarf::FormParams Format,
              llvm::endianness Endianess);

  CompileUnit(LinkingGlobalData &GlobalData, DWARFUnit &OrigUnit, unsigned ID,
              StringRef ClangModuleName, DWARFFile &File,
              OffsetToUnitTy UnitFromOffset, dwarf::FormParams Format,
              llvm::endianness Endianess);

  /// Returns stage of overall processing.
  Stage getStage() const { return Stage; }

  /// Set stage of overall processing.
  void setStage(Stage Stage) { this->Stage = Stage; }

  /// Loads unit line table.
  void loadLineTable();

  /// Returns name of the file for the \p FileIdx
  /// from the unit`s line table.
  StringEntry *getFileName(unsigned FileIdx, StringPool &GlobalStrings);

  /// Returns DWARFFile containing this compile unit.
  const DWARFFile &getContaingFile() const { return File; }

  /// Set deterministic priority for type DIE allocation ordering.
  /// Lower priority values win when multiple CUs race to define the same type.
  llvm::Error setPriority(uint64_t ObjFileIdx, uint64_t LocalIdx);

  uint64_t getPriority() const { return Priority; }

  /// Load DIEs of input compilation unit. \returns true if input DIEs
  /// successfully loaded.
  bool loadInputDIEs();

  /// Reset compile units data(results of liveness analysis, clonning)
  /// if current stage greater than Stage::Loaded. We need to reset data
  /// as we are going to repeat stages.
  void maybeResetToLoadedStage();

  /// Collect references to parseable Swift interfaces in imported
  /// DW_TAG_module blocks. The entries are staged on the CompileUnit and
  /// merged into the shared map after the parallel analysis phase.
  void analyzeImportedModule(const DWARFDebugInfoEntry *DieEntry);

  /// Merge the Swift interface entries collected by analyzeImportedModule
  /// into \p Map, emitting a warning for each conflicting path. Must be
  /// called serially after analysis has completed.
  void mergeSwiftInterfaces(DWARFLinkerBase::SwiftInterfacesMapTy &Map);

  /// Navigate DWARF tree and set die properties.
  void analyzeDWARFStructure() {
    analyzeDWARFStructureRec(getUnitDIE().getDebugInfoEntry(), false);
  }

  /// Cleanup unneeded resources after compile unit is cloned.
  void cleanupDataAfterClonning();

  /// After cloning stage the output DIEs offsets are deallocated.
  /// This method copies output offsets for referenced DIEs into DIEs patches.
  void updateDieRefPatchesWithClonedOffsets();

  /// Search for subprograms and variables referencing live code and discover
  /// dependend DIEs. Mark live DIEs, set placement for DIEs.
  bool resolveDependenciesAndMarkLiveness(
      bool InterCUProcessingStarted,
      std::atomic<bool> &HasNewInterconnectedCUs);

  /// Check dependend DIEs for incompatible placement.
  /// Make placement to be consistent.
  bool updateDependenciesCompleteness();

  /// Check DIEs to have a consistent marking(keep marking, placement marking).
  void verifyDependencies();

  /// Search for type entries and assign names.
  Error assignTypeNames(TypePool &TypePoolRef);

  /// Kinds of placement for the output die.
  enum DieOutputPlacement : uint8_t {
    NotSet = 0,

    /// Corresponding DIE goes to the type table only.
    TypeTable = 1,

    /// Corresponding DIE goes to the plain dwarf only.
    PlainDwarf = 2,

    /// Corresponding DIE goes to type table and to plain dwarf.
    Both = 3,
  };

  /// Information gathered about source DIEs.
  struct DIEInfo {
    DIEInfo() = default;
    DIEInfo(const DIEInfo &Other) { Flags = Other.Flags.load(); }
    DIEInfo &operator=(const DIEInfo &Other) {
      Flags = Other.Flags.load();
      return *this;
    }

    /// Data member keeping various flags.
    std::atomic<uint16_t> Flags = {0};

    /// \returns Placement kind for the corresponding die.
    DieOutputPlacement getPlacement() const {
      return DieOutputPlacement(Flags & 0x7);
    }

    /// Sets Placement kind for the corresponding die.
    void setPlacement(DieOutputPlacement Placement) {
      auto InputData = Flags.load();
      while (!Flags.compare_exchange_weak(InputData,
                                          ((InputData & ~0x7) | Placement))) {
      }
    }

    /// Unsets Placement kind for the corresponding die.
    void unsetPlacement() {
      auto InputData = Flags.load();
      while (!Flags.compare_exchange_weak(InputData, (InputData & ~0x7))) {
      }
    }

    /// Sets Placement kind for the corresponding die.
    bool setPlacementIfUnset(DieOutputPlacement Placement) {
      auto InputData = Flags.load();
      if ((InputData & 0x7) == NotSet)
        if (Flags.compare_exchange_strong(InputData, (InputData | Placement)))
          return true;

      return false;
    }

#define SINGLE_FLAG_METHODS_SET(Name, Value)                                   \
  bool get##Name() const { return Flags & Value; }                             \
  void set##Name() {                                                           \
    auto InputData = Flags.load();                                             \
    while (!Flags.compare_exchange_weak(InputData, InputData | Value)) {       \
    }                                                                          \
  }                                                                            \
  void unset##Name() {                                                         \
    auto InputData = Flags.load();                                             \
    while (!Flags.compare_exchange_weak(InputData, InputData & ~Value)) {      \
    }                                                                          \
  }

    /// DIE is a part of the linked output.
    SINGLE_FLAG_METHODS_SET(Keep, 0x08)

    /// DIE has children which are part of the linked output.
    SINGLE_FLAG_METHODS_SET(KeepPlainChildren, 0x10)

    /// DIE has children which are part of the type table.
    SINGLE_FLAG_METHODS_SET(KeepTypeChildren, 0x20)

    /// DIE is in module scope.
    SINGLE_FLAG_METHODS_SET(IsInMouduleScope, 0x40)

    /// DIE is in function scope.
    SINGLE_FLAG_METHODS_SET(IsInFunctionScope, 0x80)

    /// DIE is in anonymous namespace scope.
    SINGLE_FLAG_METHODS_SET(IsInAnonNamespaceScope, 0x100)

    /// DIE is available for ODR type deduplication.
    SINGLE_FLAG_METHODS_SET(ODRAvailable, 0x200)

    /// Track liveness for the DIE.
    SINGLE_FLAG_METHODS_SET(TrackLiveness, 0x400)

    /// Track liveness for the DIE.
    SINGLE_FLAG_METHODS_SET(HasAnAddress, 0x800)

    void unsetFlagsWhichSetDuringLiveAnalysis() {
      auto InputData = Flags.load();
      while (!Flags.compare_exchange_weak(
          InputData, InputData & ~(0x7 | 0x8 | 0x10 | 0x20))) {
      }
    }

    /// Erase all flags.
    void eraseData() { Flags = 0; }

#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
    LLVM_DUMP_METHOD void dump();
#endif

    bool needToPlaceInTypeTable() const {
      return (getKeep() && (getPlacement() == CompileUnit::TypeTable ||
                            getPlacement() == CompileUnit::Both)) ||
             getKeepTypeChildren();
    }

    bool needToKeepInPlainDwarf() const {
      return (getKeep() && (getPlacement() == CompileUnit::PlainDwarf ||
                            getPlacement() == CompileUnit::Both)) ||
             getKeepPlainChildren();
    }
  };

  /// \defgroup Group of functions returning DIE info.
  ///
  /// @{

  /// \p Idx index of the DIE.
  /// \returns DieInfo descriptor.
  DIEInfo &getDIEInfo(unsigned Idx) { return DieInfoArray[Idx]; }

  /// \p Idx index of the DIE.
  /// \returns DieInfo descriptor.
  const DIEInfo &getDIEInfo(unsigned Idx) const { return DieInfoArray[Idx]; }

  /// \p Idx index of the DIE.
  /// \returns DieInfo descriptor.
  DIEInfo &getDIEInfo(const DWARFDebugInfoEntry *Entry) {
    return DieInfoArray[getOrigUnit().getDIEIndex(Entry)];
  }

  /// \p Idx index of the DIE.
  /// \returns DieInfo descriptor.
  const DIEInfo &getDIEInfo(const DWARFDebugInfoEntry *Entry) const {
    return DieInfoArray[getOrigUnit().getDIEIndex(Entry)];
  }

  /// \p Die
  /// \returns PlainDieInfo descriptor.
  DIEInfo &getDIEInfo(const DWARFDie &Die) {
    return DieInfoArray[getOrigUnit().getDIEIndex(Die)];
  }

  /// \p Die
  /// \returns PlainDieInfo descriptor.
  const DIEInfo &getDIEInfo(const DWARFDie &Die) const {
    return DieInfoArray[getOrigUnit().getDIEIndex(Die)];
  }

  /// \p Idx index of the DIE.
  /// \returns DieInfo descriptor.
  uint64_t getDieOutOffset(uint32_t Idx) {
    return reinterpret_cast<std::atomic<uint64_t> *>(&OutDieOffsetArray[Idx])
        ->load();
  }

  /// \p Idx index of the DIE.
  /// \returns type entry.
  TypeEntry *getDieTypeEntry(uint32_t Idx) {
    return reinterpret_cast<std::atomic<TypeEntry *> *>(&TypeEntries[Idx])
        ->load();
  }

  /// \p InputDieEntry debug info entry.
  /// \returns DieInfo descriptor.
  uint64_t getDieOutOffset(const DWARFDebugInfoEntry *InputDieEntry) {
    return reinterpret_cast<std::atomic<uint64_t> *>(
               &OutDieOffsetArray[getOrigUnit().getDIEIndex(InputDieEntry)])
        ->load();
  }

  /// \p InputDieEntry debug info entry.
  /// \returns type entry.
  TypeEntry *getDieTypeEntry(const DWARFDebugInfoEntry *InputDieEntry) {
    return reinterpret_cast<std::atomic<TypeEntry *> *>(
               &TypeEntries[getOrigUnit().getDIEIndex(InputDieEntry)])
        ->load();
  }

  /// \p Idx index of the DIE.
  /// \returns DieInfo descriptor.
  void rememberDieOutOffset(uint32_t Idx, uint64_t Offset) {
    reinterpret_cast<std::atomic<uint64_t> *>(&OutDieOffsetArray[Idx])
        ->store(Offset);
  }

  /// \p Idx index of the DIE.
  /// \p Type entry.
  void setDieTypeEntry(uint32_t Idx, TypeEntry *Entry) {
    reinterpret_cast<std::atomic<TypeEntry *> *>(&TypeEntries[Idx])
        ->store(Entry);
  }

  /// \p InputDieEntry debug info entry.
  /// \p Type entry.
  void setDieTypeEntry(const DWARFDebugInfoEntry *InputDieEntry,
                       TypeEntry *Entry) {
    reinterpret_cast<std::atomic<TypeEntry *> *>(
        &TypeEntries[getOrigUnit().getDIEIndex(InputDieEntry)])
        ->store(Entry);
  }

  /// @}

  /// Returns value of DW_AT_low_pc attribute.
  std::optional<uint64_t> getLowPc() const { return LowPc; }

  /// Returns value of DW_AT_high_pc attribute.
  uint64_t getHighPc() const { return HighPc; }

  /// Returns true if there is a label corresponding to the specified \p Addr.
  bool hasLabelAt(uint64_t Addr) const { return Labels.count(Addr); }

  /// Add the low_pc of a label that is relocated by applying
  /// offset \p PCOffset.
  void addLabelLowPc(uint64_t LabelLowPc, int64_t PcOffset);

  /// Resolve the DIE attribute reference that has been extracted in \p
  /// RefValue. The resulting DIE might be in another CompileUnit.
  /// \returns referenced die and corresponding compilation unit.
  ///          compilation unit is null if reference could not be resolved.
  std::optional<UnitEntryPairTy>
  resolveDIEReference(const DWARFFormValue &RefValue,
                      ResolveInterCUReferencesMode CanResolveInterCUReferences);

  std::optional<UnitEntryPairTy>
  resolveDIEReference(const DWARFDebugInfoEntry *DieEntry,
                      dwarf::Attribute Attr,
                      ResolveInterCUReferencesMode CanResolveInterCUReferences);

  /// @}

  /// Add a function range [\p LowPC, \p HighPC) that is relocated by applying
  /// offset \p PCOffset.
  void addFunctionRange(uint64_t LowPC, uint64_t HighPC, int64_t PCOffset);

  /// Returns function ranges of this unit.
  const RangesTy &getFunctionRanges() const { return Ranges; }

  /// Record that a DW_AT_LLVM_stmt_sequence attribute on this unit
  /// references the input line-table sequence whose header sits at
  /// \p InputStmtSeqOffset. Resolution of that offset to an input
  /// first-row index (via parser results plus a manual boundary-based
  /// fallback) happens in a post-cloning pass, before \p V is rewritten
  /// to the byte offset of the matching output sequence. Keying on row
  /// index rather than address avoids collisions when two input
  /// sequences would relocate to the same output address (e.g. ICF).
  void noteStmtSeqListAttribute(DIEValue *V, uint64_t InputStmtSeqOffset) {
    StmtSeqListAttributes.push_back({V, InputStmtSeqOffset});
  }

  /// Clone and emit this compilation unit.
  Error
  cloneAndEmit(std::optional<std::reference_wrapper<const Triple>> TargetTriple,
               TypeUnit *ArtificialTypeUnit);

  /// Clone and emit debug locations(.debug_loc/.debug_loclists).
  Error cloneAndEmitDebugLocations();

  /// Clone and emit ranges.
  Error cloneAndEmitRanges();

  /// Clone and emit debug macros(.debug_macinfo/.debug_macro).
  Error cloneAndEmitDebugMacro();

  // Clone input DIE entry. \p SiblingOrdinal is this DIE's position in its
  // parent's child list, or UINT32_MAX for the unit DIE.
  std::pair<DIE *, TypeEntry *>
  cloneDIE(const DWARFDebugInfoEntry *InputDieEntry,
           TypeEntry *ClonedParentTypeDIE, uint64_t OutOffset,
           std::optional<int64_t> FuncAddressAdjustment,
           std::optional<int64_t> VarAddressAdjustment,
           BumpPtrAllocator &Allocator, TypeUnit *ArtificialTypeUnit,
           uint32_t SiblingOrdinal = std::numeric_limits<uint32_t>::max());

  // Clone and emit line table.
  Error cloneAndEmitLineTable(const Triple &TargetTriple);

  /// Clone attribute location axpression.
  void cloneDieAttrExpression(const DWARFExpression &InputExpression,
                              SmallVectorImpl<uint8_t> &OutputExpression,
                              SectionDescriptor &Section,
                              std::optional<int64_t> VarAddressAdjustment,
                              OffsetsPtrVector &PatchesOffsets);

  /// Returns index(inside .debug_addr) of an address.
  uint64_t getDebugAddrIndex(uint64_t Addr) {
    return DebugAddrIndexMap.getValueIndex(Addr);
  }

  /// Returns directory and file from the line table by index.
  std::optional<std::pair<StringRef, StringRef>>
  getDirAndFilenameFromLineTable(const DWARFFormValue &FileIdxValue);

  /// Returns directory and file from the line table by index.
  std::optional<std::pair<StringRef, StringRef>>
  getDirAndFilenameFromLineTable(uint64_t FileIdx);

  /// \defgroup Helper methods to access OrigUnit.
  ///
  /// @{

  /// Returns paired compile unit from input DWARF.
  DWARFUnit &getOrigUnit() const {
    assert(OrigUnit != nullptr);
    return *OrigUnit;
  }

  const DWARFDebugInfoEntry *
  getFirstChildEntry(const DWARFDebugInfoEntry *Die) const {
    assert(OrigUnit != nullptr);
    return OrigUnit->getFirstChildEntry(Die);
  }

  const DWARFDebugInfoEntry *
  getSiblingEntry(const DWARFDebugInfoEntry *Die) const {
    assert(OrigUnit != nullptr);
    return OrigUnit->getSiblingEntry(Die);
  }

  DWARFDie getParent(const DWARFDebugInfoEntry *Die) {
    assert(OrigUnit != nullptr);
    return OrigUnit->getParent(Die);
  }

  DWARFDie getDIEAtIndex(unsigned Index) {
    assert(OrigUnit != nullptr);
    return OrigUnit->getDIEAtIndex(Index);
  }

  const DWARFDebugInfoEntry *getDebugInfoEntry(unsigned Index) const {
    assert(OrigUnit != nullptr);
    return OrigUnit->getDebugInfoEntry(Index);
  }

  DWARFDie getUnitDIE(bool ExtractUnitDIEOnly = true) {
    assert(OrigUnit != nullptr);
    return OrigUnit->getUnitDIE(ExtractUnitDIEOnly);
  }

  DWARFDie getDIE(const DWARFDebugInfoEntry *Die) {
    assert(OrigUnit != nullptr);
    return DWARFDie(OrigUnit, Die);
  }

  uint32_t getDIEIndex(const DWARFDebugInfoEntry *Die) const {
    assert(OrigUnit != nullptr);
    return OrigUnit->getDIEIndex(Die);
  }

  uint32_t getDIEIndex(const DWARFDie &Die) const {
    assert(OrigUnit != nullptr);
    return OrigUnit->getDIEIndex(Die);
  }

  std::optional<DWARFFormValue> find(uint32_t DieIdx,
                                     ArrayRef<dwarf::Attribute> Attrs) const {
    assert(OrigUnit != nullptr);
    return find(OrigUnit->getDebugInfoEntry(DieIdx), Attrs);
  }

  std::optional<DWARFFormValue> find(const DWARFDebugInfoEntry *Die,
                                     ArrayRef<dwarf::Attribute> Attrs) const {
    if (!Die)
      return std::nullopt;
    auto AbbrevDecl = Die->getAbbreviationDeclarationPtr();
    if (AbbrevDecl) {
      for (auto Attr : Attrs) {
        if (auto Value = AbbrevDecl->getAttributeValue(Die->getOffset(), Attr,
                                                       *OrigUnit))
          return Value;
      }
    }
    return std::nullopt;
  }

  std::optional<uint32_t> getDIEIndexForOffset(uint64_t Offset) {
    return OrigUnit->getDIEIndexForOffset(Offset);
  }

  /// @}

  /// \defgroup Methods used for reporting warnings and errors:
  ///
  /// @{

  void warn(const Twine &Warning, const DWARFDie *DIE = nullptr) {
    GlobalData.warn(Warning, getUnitName(), DIE);
  }

  void warn(Error Warning, const DWARFDie *DIE = nullptr) {
    handleAllErrors(std::move(Warning), [&](ErrorInfoBase &Info) {
      GlobalData.warn(Info.message(), getUnitName(), DIE);
    });
  }

  void warn(const Twine &Warning, const DWARFDebugInfoEntry *DieEntry) {
    if (DieEntry != nullptr) {
      DWARFDie DIE(&getOrigUnit(), DieEntry);
      GlobalData.warn(Warning, getUnitName(), &DIE);
      return;
    }

    GlobalData.warn(Warning, getUnitName());
  }

  void error(const Twine &Err, const DWARFDie *DIE = nullptr) {
    GlobalData.warn(Err, getUnitName(), DIE);
  }

  void error(Error Err, const DWARFDie *DIE = nullptr) {
    handleAllErrors(std::move(Err), [&](ErrorInfoBase &Info) {
      GlobalData.error(Info.message(), getUnitName(), DIE);
    });
  }

  /// @}

  /// Save specified accelerator info \p Info.
  void saveAcceleratorInfo(const DwarfUnit::AccelInfo &Info) {
    AcceleratorRecords.add(Info);
  }

  /// Enumerates all units accelerator records.
  void
  forEachAcceleratorRecord(function_ref<void(AccelInfo &)> Handler) override {
    AcceleratorRecords.forEach(Handler);
  }

  /// Output unit selector.
  class OutputUnitVariantPtr {
  public:
    OutputUnitVariantPtr(CompileUnit *U);
    OutputUnitVariantPtr(TypeUnit *U);

    /// Accessor for common functionality.
    DwarfUnit *operator->();

    bool isCompileUnit();

    bool isTypeUnit();

    /// Returns CompileUnit if applicable.
    CompileUnit *getAsCompileUnit();

    /// Returns TypeUnit if applicable.
    TypeUnit *getAsTypeUnit();

  protected:
    PointerUnion<CompileUnit *, TypeUnit *> Ptr;
  };

private:
  /// Navigate DWARF tree recursively and set die properties.
  void analyzeDWARFStructureRec(const DWARFDebugInfoEntry *DieEntry,
                                bool IsODRUnavailableFunctionScope);

  struct LinkedLocationExpressionsWithOffsetPatches {
    DWARFLocationExpression Expression;
    OffsetsPtrVector Patches;
  };
  using LinkedLocationExpressionsVector =
      SmallVector<LinkedLocationExpressionsWithOffsetPatches>;

  /// Emit debug locations.
  void emitLocations(DebugSectionKind LocationSectionKind);

  /// Emit location list header.
  uint64_t emitLocListHeader(SectionDescriptor &OutLocationSection);

  /// Emit location list fragment.
  uint64_t emitLocListFragment(
      const LinkedLocationExpressionsVector &LinkedLocationExpression,
      SectionDescriptor &OutLocationSection);

  /// Emit the .debug_addr section fragment for current unit.
  Error emitDebugAddrSection();

  /// Emit .debug_aranges.
  void emitAranges(AddressRanges &LinkedFunctionRanges);

  /// Clone and emit .debug_ranges/.debug_rnglists.
  void cloneAndEmitRangeList(DebugSectionKind RngSectionKind,
                             AddressRanges &LinkedFunctionRanges);

  /// Emit range list header.
  uint64_t emitRangeListHeader(SectionDescriptor &OutRangeSection);

  /// Emit range list fragment.
  void emitRangeListFragment(const AddressRanges &LinkedRanges,
                             SectionDescriptor &OutRangeSection);

  /// Insert the new line info sequence \p Seq into the current
  /// set of already linked line info \p Rows. \p SeqIndices carries the
  /// input Row index that each entry in \p Seq originated from (or the
  /// invalid-row-index sentinel for manufactured end-of-range rows), and
  /// is kept in lockstep with \p RowIndices.
  void insertLineSequence(std::vector<DWARFDebugLine::Row> &Seq,
                          SmallVectorImpl<uint64_t> &SeqIndices,
                          std::vector<DWARFDebugLine::Row> &Rows,
                          SmallVectorImpl<uint64_t> &RowIndices);

  /// Filter \p InputLineTable's rows to those covered by this unit's
  /// function ranges, relocating addresses in the process, and store the
  /// result in \p NewRows. \p NewRowIndices is populated in lockstep with
  /// \p NewRows and carries, for each output row, the index of the input
  /// row it originated from — or InvalidRowIndex for manufactured
  /// end-of-range rows.
  void filterLineTableRows(const DWARFDebugLine::LineTable &InputLineTable,
                           std::vector<DWARFDebugLine::Row> &NewRows,
                           SmallVectorImpl<uint64_t> &NewRowIndices);

  /// Rewrite every DW_AT_LLVM_stmt_sequence DIEValue recorded on this
  /// unit with the local .debug_line offset of the output sequence
  /// containing the corresponding input first row.
  /// \p SeqOffsetToFirstRowIndex maps an input stmt-sequence offset to
  /// its first-row index (built by buildStmtSeqOffsetToFirstRowIndex so
  /// that sequences missed by the DWARF parser are recovered from row
  /// boundaries). \p RowIndexToSeqStartOffset maps an input first-row
  /// index to the byte offset of the output DW_LNE_set_address that
  /// opens the matching output sequence.
  void patchStmtSeqAttributes(
      const DenseMap<uint64_t, uint64_t> &SeqOffsetToFirstRowIndex,
      const DenseMap<uint64_t, uint64_t> &RowIndexToSeqStartOffset);

  /// Build a map from input stmt-sequence offset to the first-row index
  /// of the corresponding sequence in \p InputLineTable. Seeds the map
  /// from \p InputLineTable.Sequences (the DWARF parser's results), then
  /// augments it by manually walking row boundaries and realigning them
  /// against the recorded DW_AT_LLVM_stmt_sequence values so that
  /// sequences missed by the parser still resolve. Mirrors the
  /// classic DWARFLinker's constructSeqOffsettoOrigRowMapping.
  DenseMap<uint64_t, uint64_t> buildStmtSeqOffsetToFirstRowIndex(
      const DWARFDebugLine::LineTable &InputLineTable) const;

  /// Emits body for both macro sections.
  void emitMacroTableImpl(const DWARFDebugMacro *MacroTable,
                          uint64_t OffsetToMacroTable, bool hasDWARFv5Header);

  /// Creates DIE which would be placed into the "Plain" compile unit.
  DIE *createPlainDIEandCloneAttributes(
      const DWARFDebugInfoEntry *InputDieEntry, DIEGenerator &PlainDIEGenerator,
      uint64_t &OutOffset, std::optional<int64_t> &FuncAddressAdjustment,
      std::optional<int64_t> &VarAddressAdjustment);

  /// Creates DIE which would be placed into the "Type" compile unit.
  /// \p SiblingOrdinal is the input DIE's position in its parent's child list.
  TypeEntry *createTypeDIEandCloneAttributes(
      const DWARFDebugInfoEntry *InputDieEntry, DIEGenerator &TypeDIEGenerator,
      TypeEntry *ClonedParentTypeDIE, TypeUnit *ArtificialTypeUnit,
      uint32_t SiblingOrdinal);

  /// Create output DIE inside specified \p TypeDescriptor.
  DIE *allocateTypeDie(TypeEntryBody *TypeDescriptor,
                       DIEGenerator &TypeDIEGenerator, dwarf::Tag DieTag,
                       bool IsDeclaration, bool IsParentDeclaration);

  /// Enumerate \p DieEntry children and assign names for them.
  Error assignTypeNamesRec(const DWARFDebugInfoEntry *DieEntry,
                           SyntheticTypeNameBuilder &NameBuilder);

  /// DWARFFile containing this compile unit.
  DWARFFile &File;

  /// Pointer to the paired compile unit from the input DWARF.
  DWARFUnit *OrigUnit = nullptr;

  /// Raw DW_AT_language from the input (not ODR-filtered).
  std::optional<uint16_t> Language;

  /// Parseable Swift interface entries staged during the parallel analysis
  /// phase. Merged serially afterwards.
  struct PendingSwiftInterface {
    PendingSwiftInterface(StringRef ModuleName, StringRef ResolvedPath)
        : ModuleName(ModuleName), ResolvedPath(ResolvedPath) {}
    std::string ModuleName;
    std::string ResolvedPath;
  };
  SmallVector<PendingSwiftInterface> PendingSwiftInterfaces;

  /// Line table for this unit.
  const DWARFDebugLine::LineTable *LineTablePtr = nullptr;

  /// Cached resolved paths from the line table.
  /// The key is <UniqueUnitID, FileIdx>.
  using ResolvedPathsMap = DenseMap<unsigned, StringEntry *>;
  ResolvedPathsMap ResolvedFullPaths;
  StringMap<StringEntry *> ResolvedParentPaths;

  /// Maps an address into the index inside .debug_addr section.
  IndexedValuesMap<uint64_t> DebugAddrIndexMap;

  std::unique_ptr<DependencyTracker> Dependencies;

  /// \defgroup Data Members accessed asynchronously.
  ///
  /// @{
  OffsetToUnitTy getUnitFromOffset;

  std::optional<uint64_t> LowPc;
  uint64_t HighPc = 0;

  /// Flag indicating whether type de-duplication is forbidden.
  bool NoODR = true;

  /// Deterministic priority for type DIE allocation (lower wins).
  uint64_t Priority = std::numeric_limits<uint64_t>::max();

  /// The ranges in that map are the PC ranges for functions in this unit,
  /// associated with the PC offset to apply to the addresses to get
  /// the linked address.
  RangesTy Ranges;
  std::mutex RangesMutex;

  /// The DW_AT_low_pc of each DW_TAG_label.
  using LabelMapTy = SmallDenseMap<uint64_t, uint64_t, 1>;
  LabelMapTy Labels;

  /// Recorded DW_AT_LLVM_stmt_sequence attributes for this unit. Each
  /// entry pairs the DIEValue holding the attribute with the input-side
  /// byte offset of the referenced line-table sequence. The value is
  /// rewritten with the matching output offset after the line table has
  /// been emitted; resolution from input offset to input first-row
  /// index (including the parser-miss fallback) happens at patch time.
  struct StmtSeqPatch {
    DIEValue *Value = nullptr;
    uint64_t InputStmtSeqOffset = 0;
  };
  SmallVector<StmtSeqPatch, 4> StmtSeqListAttributes;
  std::mutex LabelsMutex;

  /// This field keeps current stage of overall compile unit processing.
  std::atomic<Stage> Stage;

  /// DIE info indexed by DIE index.
  SmallVector<DIEInfo> DieInfoArray;
  SmallVector<uint64_t> OutDieOffsetArray;
  SmallVector<TypeEntry *> TypeEntries;

  /// The list of accelerator records for this unit.
  ArrayList<AccelInfo> AcceleratorRecords;
  /// @}
};

/// \returns list of attributes referencing type DIEs which might be
/// deduplicated.
/// Note: it does not include DW_AT_containing_type attribute to avoid
/// infinite recursion.
ArrayRef<dwarf::Attribute> getODRAttributes();

} // end of namespace parallel
} // end of namespace dwarf_linker
} // end of namespace llvm

#endif // LLVM_LIB_DWARFLINKER_PARALLEL_DWARFLINKERCOMPILEUNIT_H
