brintos

brintos / llvm-project-archived public Read only

0
0
Text · 24.1 KiB · 90c007e Raw
740 lines · c
1//===- DWARFLinkerCompileUnit.h ---------------------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLVM_LIB_DWARFLINKER_PARALLEL_DWARFLINKERCOMPILEUNIT_H10#define LLVM_LIB_DWARFLINKER_PARALLEL_DWARFLINKERCOMPILEUNIT_H11 12#include "DWARFLinkerUnit.h"13#include "llvm/DWARFLinker/DWARFFile.h"14#include <optional>15 16namespace llvm {17namespace dwarf_linker {18namespace parallel {19 20using OffsetToUnitTy = function_ref<CompileUnit *(uint64_t Offset)>;21 22struct AttributesInfo;23class SyntheticTypeNameBuilder;24class DIEGenerator;25class TypeUnit;26class DependencyTracker;27 28class CompileUnit;29 30/// This is a helper structure which keeps a debug info entry31/// with it's containing compilation unit.32struct UnitEntryPairTy {33  UnitEntryPairTy() = default;34  UnitEntryPairTy(CompileUnit *CU, const DWARFDebugInfoEntry *DieEntry)35      : CU(CU), DieEntry(DieEntry) {}36 37  CompileUnit *CU = nullptr;38  const DWARFDebugInfoEntry *DieEntry = nullptr;39 40  UnitEntryPairTy getNamespaceOrigin();41  std::optional<UnitEntryPairTy> getParent();42};43 44enum ResolveInterCUReferencesMode : bool {45  Resolve = true,46  AvoidResolving = false,47};48 49/// Stores all information related to a compile unit, be it in its original50/// instance of the object file or its brand new cloned and generated DIE tree.51/// NOTE: we need alignment of at least 8 bytes as we use52///       PointerIntPair<CompileUnit *, 3> in the DependencyTracker.h53class alignas(8) CompileUnit : public DwarfUnit {54public:55  /// The stages of new compile unit processing.56  enum class Stage : uint8_t {57    /// Created, linked with input DWARF file.58    CreatedNotLoaded = 0,59 60    /// Input DWARF is loaded.61    Loaded,62 63    /// Input DWARF is analysed(DIEs pointing to the real code section are64    /// discovered, type names are assigned if ODR is requested).65    LivenessAnalysisDone,66 67    /// Check if dependencies have incompatible placement.68    /// If that is the case modify placement to be compatible.69    UpdateDependenciesCompleteness,70 71    /// Type names assigned to DIEs.72    TypeNamesAssigned,73 74    /// Output DWARF is generated.75    Cloned,76 77    /// Offsets inside patch records are updated.78    PatchesUpdated,79 80    /// Resources(Input DWARF, Output DWARF tree) are released.81    Cleaned,82 83    /// Compile Unit should be skipped84    Skipped85  };86 87  CompileUnit(LinkingGlobalData &GlobalData, unsigned ID,88              StringRef ClangModuleName, DWARFFile &File,89              OffsetToUnitTy UnitFromOffset, dwarf::FormParams Format,90              llvm::endianness Endianess);91 92  CompileUnit(LinkingGlobalData &GlobalData, DWARFUnit &OrigUnit, unsigned ID,93              StringRef ClangModuleName, DWARFFile &File,94              OffsetToUnitTy UnitFromOffset, dwarf::FormParams Format,95              llvm::endianness Endianess);96 97  /// Returns stage of overall processing.98  Stage getStage() const { return Stage; }99 100  /// Set stage of overall processing.101  void setStage(Stage Stage) { this->Stage = Stage; }102 103  /// Loads unit line table.104  void loadLineTable();105 106  /// Returns name of the file for the \p FileIdx107  /// from the unit`s line table.108  StringEntry *getFileName(unsigned FileIdx, StringPool &GlobalStrings);109 110  /// Returns DWARFFile containing this compile unit.111  const DWARFFile &getContaingFile() const { return File; }112 113  /// Load DIEs of input compilation unit. \returns true if input DIEs114  /// successfully loaded.115  bool loadInputDIEs();116 117  /// Reset compile units data(results of liveness analysis, clonning)118  /// if current stage greater than Stage::Loaded. We need to reset data119  /// as we are going to repeat stages.120  void maybeResetToLoadedStage();121 122  /// Collect references to parseable Swift interfaces in imported123  /// DW_TAG_module blocks.124  void analyzeImportedModule(const DWARFDebugInfoEntry *DieEntry);125 126  /// Navigate DWARF tree and set die properties.127  void analyzeDWARFStructure() {128    analyzeDWARFStructureRec(getUnitDIE().getDebugInfoEntry(), false);129  }130 131  /// Cleanup unneeded resources after compile unit is cloned.132  void cleanupDataAfterClonning();133 134  /// After cloning stage the output DIEs offsets are deallocated.135  /// This method copies output offsets for referenced DIEs into DIEs patches.136  void updateDieRefPatchesWithClonedOffsets();137 138  /// Search for subprograms and variables referencing live code and discover139  /// dependend DIEs. Mark live DIEs, set placement for DIEs.140  bool resolveDependenciesAndMarkLiveness(141      bool InterCUProcessingStarted,142      std::atomic<bool> &HasNewInterconnectedCUs);143 144  /// Check dependend DIEs for incompatible placement.145  /// Make placement to be consistent.146  bool updateDependenciesCompleteness();147 148  /// Check DIEs to have a consistent marking(keep marking, placement marking).149  void verifyDependencies();150 151  /// Search for type entries and assign names.152  Error assignTypeNames(TypePool &TypePoolRef);153 154  /// Kinds of placement for the output die.155  enum DieOutputPlacement : uint8_t {156    NotSet = 0,157 158    /// Corresponding DIE goes to the type table only.159    TypeTable = 1,160 161    /// Corresponding DIE goes to the plain dwarf only.162    PlainDwarf = 2,163 164    /// Corresponding DIE goes to type table and to plain dwarf.165    Both = 3,166  };167 168  /// Information gathered about source DIEs.169  struct DIEInfo {170    DIEInfo() = default;171    DIEInfo(const DIEInfo &Other) { Flags = Other.Flags.load(); }172    DIEInfo &operator=(const DIEInfo &Other) {173      Flags = Other.Flags.load();174      return *this;175    }176 177    /// Data member keeping various flags.178    std::atomic<uint16_t> Flags = {0};179 180    /// \returns Placement kind for the corresponding die.181    DieOutputPlacement getPlacement() const {182      return DieOutputPlacement(Flags & 0x7);183    }184 185    /// Sets Placement kind for the corresponding die.186    void setPlacement(DieOutputPlacement Placement) {187      auto InputData = Flags.load();188      while (!Flags.compare_exchange_weak(InputData,189                                          ((InputData & ~0x7) | Placement))) {190      }191    }192 193    /// Unsets Placement kind for the corresponding die.194    void unsetPlacement() {195      auto InputData = Flags.load();196      while (!Flags.compare_exchange_weak(InputData, (InputData & ~0x7))) {197      }198    }199 200    /// Sets Placement kind for the corresponding die.201    bool setPlacementIfUnset(DieOutputPlacement Placement) {202      auto InputData = Flags.load();203      if ((InputData & 0x7) == NotSet)204        if (Flags.compare_exchange_strong(InputData, (InputData | Placement)))205          return true;206 207      return false;208    }209 210#define SINGLE_FLAG_METHODS_SET(Name, Value)                                   \211  bool get##Name() const { return Flags & Value; }                             \212  void set##Name() {                                                           \213    auto InputData = Flags.load();                                             \214    while (!Flags.compare_exchange_weak(InputData, InputData | Value)) {       \215    }                                                                          \216  }                                                                            \217  void unset##Name() {                                                         \218    auto InputData = Flags.load();                                             \219    while (!Flags.compare_exchange_weak(InputData, InputData & ~Value)) {      \220    }                                                                          \221  }222 223    /// DIE is a part of the linked output.224    SINGLE_FLAG_METHODS_SET(Keep, 0x08)225 226    /// DIE has children which are part of the linked output.227    SINGLE_FLAG_METHODS_SET(KeepPlainChildren, 0x10)228 229    /// DIE has children which are part of the type table.230    SINGLE_FLAG_METHODS_SET(KeepTypeChildren, 0x20)231 232    /// DIE is in module scope.233    SINGLE_FLAG_METHODS_SET(IsInMouduleScope, 0x40)234 235    /// DIE is in function scope.236    SINGLE_FLAG_METHODS_SET(IsInFunctionScope, 0x80)237 238    /// DIE is in anonymous namespace scope.239    SINGLE_FLAG_METHODS_SET(IsInAnonNamespaceScope, 0x100)240 241    /// DIE is available for ODR type deduplication.242    SINGLE_FLAG_METHODS_SET(ODRAvailable, 0x200)243 244    /// Track liveness for the DIE.245    SINGLE_FLAG_METHODS_SET(TrackLiveness, 0x400)246 247    /// Track liveness for the DIE.248    SINGLE_FLAG_METHODS_SET(HasAnAddress, 0x800)249 250    void unsetFlagsWhichSetDuringLiveAnalysis() {251      auto InputData = Flags.load();252      while (!Flags.compare_exchange_weak(253          InputData, InputData & ~(0x7 | 0x8 | 0x10 | 0x20))) {254      }255    }256 257    /// Erase all flags.258    void eraseData() { Flags = 0; }259 260#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)261    LLVM_DUMP_METHOD void dump();262#endif263 264    bool needToPlaceInTypeTable() const {265      return (getKeep() && (getPlacement() == CompileUnit::TypeTable ||266                            getPlacement() == CompileUnit::Both)) ||267             getKeepTypeChildren();268    }269 270    bool needToKeepInPlainDwarf() const {271      return (getKeep() && (getPlacement() == CompileUnit::PlainDwarf ||272                            getPlacement() == CompileUnit::Both)) ||273             getKeepPlainChildren();274    }275  };276 277  /// \defgroup Group of functions returning DIE info.278  ///279  /// @{280 281  /// \p Idx index of the DIE.282  /// \returns DieInfo descriptor.283  DIEInfo &getDIEInfo(unsigned Idx) { return DieInfoArray[Idx]; }284 285  /// \p Idx index of the DIE.286  /// \returns DieInfo descriptor.287  const DIEInfo &getDIEInfo(unsigned Idx) const { return DieInfoArray[Idx]; }288 289  /// \p Idx index of the DIE.290  /// \returns DieInfo descriptor.291  DIEInfo &getDIEInfo(const DWARFDebugInfoEntry *Entry) {292    return DieInfoArray[getOrigUnit().getDIEIndex(Entry)];293  }294 295  /// \p Idx index of the DIE.296  /// \returns DieInfo descriptor.297  const DIEInfo &getDIEInfo(const DWARFDebugInfoEntry *Entry) const {298    return DieInfoArray[getOrigUnit().getDIEIndex(Entry)];299  }300 301  /// \p Die302  /// \returns PlainDieInfo descriptor.303  DIEInfo &getDIEInfo(const DWARFDie &Die) {304    return DieInfoArray[getOrigUnit().getDIEIndex(Die)];305  }306 307  /// \p Die308  /// \returns PlainDieInfo descriptor.309  const DIEInfo &getDIEInfo(const DWARFDie &Die) const {310    return DieInfoArray[getOrigUnit().getDIEIndex(Die)];311  }312 313  /// \p Idx index of the DIE.314  /// \returns DieInfo descriptor.315  uint64_t getDieOutOffset(uint32_t Idx) {316    return reinterpret_cast<std::atomic<uint64_t> *>(&OutDieOffsetArray[Idx])317        ->load();318  }319 320  /// \p Idx index of the DIE.321  /// \returns type entry.322  TypeEntry *getDieTypeEntry(uint32_t Idx) {323    return reinterpret_cast<std::atomic<TypeEntry *> *>(&TypeEntries[Idx])324        ->load();325  }326 327  /// \p InputDieEntry debug info entry.328  /// \returns DieInfo descriptor.329  uint64_t getDieOutOffset(const DWARFDebugInfoEntry *InputDieEntry) {330    return reinterpret_cast<std::atomic<uint64_t> *>(331               &OutDieOffsetArray[getOrigUnit().getDIEIndex(InputDieEntry)])332        ->load();333  }334 335  /// \p InputDieEntry debug info entry.336  /// \returns type entry.337  TypeEntry *getDieTypeEntry(const DWARFDebugInfoEntry *InputDieEntry) {338    return reinterpret_cast<std::atomic<TypeEntry *> *>(339               &TypeEntries[getOrigUnit().getDIEIndex(InputDieEntry)])340        ->load();341  }342 343  /// \p Idx index of the DIE.344  /// \returns DieInfo descriptor.345  void rememberDieOutOffset(uint32_t Idx, uint64_t Offset) {346    reinterpret_cast<std::atomic<uint64_t> *>(&OutDieOffsetArray[Idx])347        ->store(Offset);348  }349 350  /// \p Idx index of the DIE.351  /// \p Type entry.352  void setDieTypeEntry(uint32_t Idx, TypeEntry *Entry) {353    reinterpret_cast<std::atomic<TypeEntry *> *>(&TypeEntries[Idx])354        ->store(Entry);355  }356 357  /// \p InputDieEntry debug info entry.358  /// \p Type entry.359  void setDieTypeEntry(const DWARFDebugInfoEntry *InputDieEntry,360                       TypeEntry *Entry) {361    reinterpret_cast<std::atomic<TypeEntry *> *>(362        &TypeEntries[getOrigUnit().getDIEIndex(InputDieEntry)])363        ->store(Entry);364  }365 366  /// @}367 368  /// Returns value of DW_AT_low_pc attribute.369  std::optional<uint64_t> getLowPc() const { return LowPc; }370 371  /// Returns value of DW_AT_high_pc attribute.372  uint64_t getHighPc() const { return HighPc; }373 374  /// Returns true if there is a label corresponding to the specified \p Addr.375  bool hasLabelAt(uint64_t Addr) const { return Labels.count(Addr); }376 377  /// Add the low_pc of a label that is relocated by applying378  /// offset \p PCOffset.379  void addLabelLowPc(uint64_t LabelLowPc, int64_t PcOffset);380 381  /// Resolve the DIE attribute reference that has been extracted in \p382  /// RefValue. The resulting DIE might be in another CompileUnit.383  /// \returns referenced die and corresponding compilation unit.384  ///          compilation unit is null if reference could not be resolved.385  std::optional<UnitEntryPairTy>386  resolveDIEReference(const DWARFFormValue &RefValue,387                      ResolveInterCUReferencesMode CanResolveInterCUReferences);388 389  std::optional<UnitEntryPairTy>390  resolveDIEReference(const DWARFDebugInfoEntry *DieEntry,391                      dwarf::Attribute Attr,392                      ResolveInterCUReferencesMode CanResolveInterCUReferences);393 394  /// @}395 396  /// Add a function range [\p LowPC, \p HighPC) that is relocated by applying397  /// offset \p PCOffset.398  void addFunctionRange(uint64_t LowPC, uint64_t HighPC, int64_t PCOffset);399 400  /// Returns function ranges of this unit.401  const RangesTy &getFunctionRanges() const { return Ranges; }402 403  /// Clone and emit this compilation unit.404  Error405  cloneAndEmit(std::optional<std::reference_wrapper<const Triple>> TargetTriple,406               TypeUnit *ArtificialTypeUnit);407 408  /// Clone and emit debug locations(.debug_loc/.debug_loclists).409  Error cloneAndEmitDebugLocations();410 411  /// Clone and emit ranges.412  Error cloneAndEmitRanges();413 414  /// Clone and emit debug macros(.debug_macinfo/.debug_macro).415  Error cloneAndEmitDebugMacro();416 417  // Clone input DIE entry.418  std::pair<DIE *, TypeEntry *>419  cloneDIE(const DWARFDebugInfoEntry *InputDieEntry,420           TypeEntry *ClonedParentTypeDIE, uint64_t OutOffset,421           std::optional<int64_t> FuncAddressAdjustment,422           std::optional<int64_t> VarAddressAdjustment,423           BumpPtrAllocator &Allocator, TypeUnit *ArtificialTypeUnit);424 425  // Clone and emit line table.426  Error cloneAndEmitLineTable(const Triple &TargetTriple);427 428  /// Clone attribute location axpression.429  void cloneDieAttrExpression(const DWARFExpression &InputExpression,430                              SmallVectorImpl<uint8_t> &OutputExpression,431                              SectionDescriptor &Section,432                              std::optional<int64_t> VarAddressAdjustment,433                              OffsetsPtrVector &PatchesOffsets);434 435  /// Returns index(inside .debug_addr) of an address.436  uint64_t getDebugAddrIndex(uint64_t Addr) {437    return DebugAddrIndexMap.getValueIndex(Addr);438  }439 440  /// Returns directory and file from the line table by index.441  std::optional<std::pair<StringRef, StringRef>>442  getDirAndFilenameFromLineTable(const DWARFFormValue &FileIdxValue);443 444  /// Returns directory and file from the line table by index.445  std::optional<std::pair<StringRef, StringRef>>446  getDirAndFilenameFromLineTable(uint64_t FileIdx);447 448  /// \defgroup Helper methods to access OrigUnit.449  ///450  /// @{451 452  /// Returns paired compile unit from input DWARF.453  DWARFUnit &getOrigUnit() const {454    assert(OrigUnit != nullptr);455    return *OrigUnit;456  }457 458  const DWARFDebugInfoEntry *459  getFirstChildEntry(const DWARFDebugInfoEntry *Die) const {460    assert(OrigUnit != nullptr);461    return OrigUnit->getFirstChildEntry(Die);462  }463 464  const DWARFDebugInfoEntry *465  getSiblingEntry(const DWARFDebugInfoEntry *Die) const {466    assert(OrigUnit != nullptr);467    return OrigUnit->getSiblingEntry(Die);468  }469 470  DWARFDie getParent(const DWARFDebugInfoEntry *Die) {471    assert(OrigUnit != nullptr);472    return OrigUnit->getParent(Die);473  }474 475  DWARFDie getDIEAtIndex(unsigned Index) {476    assert(OrigUnit != nullptr);477    return OrigUnit->getDIEAtIndex(Index);478  }479 480  const DWARFDebugInfoEntry *getDebugInfoEntry(unsigned Index) const {481    assert(OrigUnit != nullptr);482    return OrigUnit->getDebugInfoEntry(Index);483  }484 485  DWARFDie getUnitDIE(bool ExtractUnitDIEOnly = true) {486    assert(OrigUnit != nullptr);487    return OrigUnit->getUnitDIE(ExtractUnitDIEOnly);488  }489 490  DWARFDie getDIE(const DWARFDebugInfoEntry *Die) {491    assert(OrigUnit != nullptr);492    return DWARFDie(OrigUnit, Die);493  }494 495  uint32_t getDIEIndex(const DWARFDebugInfoEntry *Die) const {496    assert(OrigUnit != nullptr);497    return OrigUnit->getDIEIndex(Die);498  }499 500  uint32_t getDIEIndex(const DWARFDie &Die) const {501    assert(OrigUnit != nullptr);502    return OrigUnit->getDIEIndex(Die);503  }504 505  std::optional<DWARFFormValue> find(uint32_t DieIdx,506                                     ArrayRef<dwarf::Attribute> Attrs) const {507    assert(OrigUnit != nullptr);508    return find(OrigUnit->getDebugInfoEntry(DieIdx), Attrs);509  }510 511  std::optional<DWARFFormValue> find(const DWARFDebugInfoEntry *Die,512                                     ArrayRef<dwarf::Attribute> Attrs) const {513    if (!Die)514      return std::nullopt;515    auto AbbrevDecl = Die->getAbbreviationDeclarationPtr();516    if (AbbrevDecl) {517      for (auto Attr : Attrs) {518        if (auto Value = AbbrevDecl->getAttributeValue(Die->getOffset(), Attr,519                                                       *OrigUnit))520          return Value;521      }522    }523    return std::nullopt;524  }525 526  std::optional<uint32_t> getDIEIndexForOffset(uint64_t Offset) {527    return OrigUnit->getDIEIndexForOffset(Offset);528  }529 530  /// @}531 532  /// \defgroup Methods used for reporting warnings and errors:533  ///534  /// @{535 536  void warn(const Twine &Warning, const DWARFDie *DIE = nullptr) {537    GlobalData.warn(Warning, getUnitName(), DIE);538  }539 540  void warn(Error Warning, const DWARFDie *DIE = nullptr) {541    handleAllErrors(std::move(Warning), [&](ErrorInfoBase &Info) {542      GlobalData.warn(Info.message(), getUnitName(), DIE);543    });544  }545 546  void warn(const Twine &Warning, const DWARFDebugInfoEntry *DieEntry) {547    if (DieEntry != nullptr) {548      DWARFDie DIE(&getOrigUnit(), DieEntry);549      GlobalData.warn(Warning, getUnitName(), &DIE);550      return;551    }552 553    GlobalData.warn(Warning, getUnitName());554  }555 556  void error(const Twine &Err, const DWARFDie *DIE = nullptr) {557    GlobalData.warn(Err, getUnitName(), DIE);558  }559 560  void error(Error Err, const DWARFDie *DIE = nullptr) {561    handleAllErrors(std::move(Err), [&](ErrorInfoBase &Info) {562      GlobalData.error(Info.message(), getUnitName(), DIE);563    });564  }565 566  /// @}567 568  /// Save specified accelerator info \p Info.569  void saveAcceleratorInfo(const DwarfUnit::AccelInfo &Info) {570    AcceleratorRecords.add(Info);571  }572 573  /// Enumerates all units accelerator records.574  void575  forEachAcceleratorRecord(function_ref<void(AccelInfo &)> Handler) override {576    AcceleratorRecords.forEach(Handler);577  }578 579  /// Output unit selector.580  class OutputUnitVariantPtr {581  public:582    OutputUnitVariantPtr(CompileUnit *U);583    OutputUnitVariantPtr(TypeUnit *U);584 585    /// Accessor for common functionality.586    DwarfUnit *operator->();587 588    bool isCompileUnit();589 590    bool isTypeUnit();591 592    /// Returns CompileUnit if applicable.593    CompileUnit *getAsCompileUnit();594 595    /// Returns TypeUnit if applicable.596    TypeUnit *getAsTypeUnit();597 598  protected:599    PointerUnion<CompileUnit *, TypeUnit *> Ptr;600  };601 602private:603  /// Navigate DWARF tree recursively and set die properties.604  void analyzeDWARFStructureRec(const DWARFDebugInfoEntry *DieEntry,605                                bool IsODRUnavailableFunctionScope);606 607  struct LinkedLocationExpressionsWithOffsetPatches {608    DWARFLocationExpression Expression;609    OffsetsPtrVector Patches;610  };611  using LinkedLocationExpressionsVector =612      SmallVector<LinkedLocationExpressionsWithOffsetPatches>;613 614  /// Emit debug locations.615  void emitLocations(DebugSectionKind LocationSectionKind);616 617  /// Emit location list header.618  uint64_t emitLocListHeader(SectionDescriptor &OutLocationSection);619 620  /// Emit location list fragment.621  uint64_t emitLocListFragment(622      const LinkedLocationExpressionsVector &LinkedLocationExpression,623      SectionDescriptor &OutLocationSection);624 625  /// Emit the .debug_addr section fragment for current unit.626  Error emitDebugAddrSection();627 628  /// Emit .debug_aranges.629  void emitAranges(AddressRanges &LinkedFunctionRanges);630 631  /// Clone and emit .debug_ranges/.debug_rnglists.632  void cloneAndEmitRangeList(DebugSectionKind RngSectionKind,633                             AddressRanges &LinkedFunctionRanges);634 635  /// Emit range list header.636  uint64_t emitRangeListHeader(SectionDescriptor &OutRangeSection);637 638  /// Emit range list fragment.639  void emitRangeListFragment(const AddressRanges &LinkedRanges,640                             SectionDescriptor &OutRangeSection);641 642  /// Insert the new line info sequence \p Seq into the current643  /// set of already linked line info \p Rows.644  void insertLineSequence(std::vector<DWARFDebugLine::Row> &Seq,645                          std::vector<DWARFDebugLine::Row> &Rows);646 647  /// Emits body for both macro sections.648  void emitMacroTableImpl(const DWARFDebugMacro *MacroTable,649                          uint64_t OffsetToMacroTable, bool hasDWARFv5Header);650 651  /// Creates DIE which would be placed into the "Plain" compile unit.652  DIE *createPlainDIEandCloneAttributes(653      const DWARFDebugInfoEntry *InputDieEntry, DIEGenerator &PlainDIEGenerator,654      uint64_t &OutOffset, std::optional<int64_t> &FuncAddressAdjustment,655      std::optional<int64_t> &VarAddressAdjustment);656 657  /// Creates DIE which would be placed into the "Type" compile unit.658  TypeEntry *createTypeDIEandCloneAttributes(659      const DWARFDebugInfoEntry *InputDieEntry, DIEGenerator &TypeDIEGenerator,660      TypeEntry *ClonedParentTypeDIE, TypeUnit *ArtificialTypeUnit);661 662  /// Create output DIE inside specified \p TypeDescriptor.663  DIE *allocateTypeDie(TypeEntryBody *TypeDescriptor,664                       DIEGenerator &TypeDIEGenerator, dwarf::Tag DieTag,665                       bool IsDeclaration, bool IsParentDeclaration);666 667  /// Enumerate \p DieEntry children and assign names for them.668  Error assignTypeNamesRec(const DWARFDebugInfoEntry *DieEntry,669                           SyntheticTypeNameBuilder &NameBuilder);670 671  /// DWARFFile containing this compile unit.672  DWARFFile &File;673 674  /// Pointer to the paired compile unit from the input DWARF.675  DWARFUnit *OrigUnit = nullptr;676 677  /// The DW_AT_language of this unit.678  std::optional<uint16_t> Language;679 680  /// Line table for this unit.681  const DWARFDebugLine::LineTable *LineTablePtr = nullptr;682 683  /// Cached resolved paths from the line table.684  /// The key is <UniqueUnitID, FileIdx>.685  using ResolvedPathsMap = DenseMap<unsigned, StringEntry *>;686  ResolvedPathsMap ResolvedFullPaths;687  StringMap<StringEntry *> ResolvedParentPaths;688 689  /// Maps an address into the index inside .debug_addr section.690  IndexedValuesMap<uint64_t> DebugAddrIndexMap;691 692  std::unique_ptr<DependencyTracker> Dependencies;693 694  /// \defgroup Data Members accessed asinchronously.695  ///696  /// @{697  OffsetToUnitTy getUnitFromOffset;698 699  std::optional<uint64_t> LowPc;700  uint64_t HighPc = 0;701 702  /// Flag indicating whether type de-duplication is forbidden.703  bool NoODR = true;704 705  /// The ranges in that map are the PC ranges for functions in this unit,706  /// associated with the PC offset to apply to the addresses to get707  /// the linked address.708  RangesTy Ranges;709  std::mutex RangesMutex;710 711  /// The DW_AT_low_pc of each DW_TAG_label.712  using LabelMapTy = SmallDenseMap<uint64_t, uint64_t, 1>;713  LabelMapTy Labels;714  std::mutex LabelsMutex;715 716  /// This field keeps current stage of overall compile unit processing.717  std::atomic<Stage> Stage;718 719  /// DIE info indexed by DIE index.720  SmallVector<DIEInfo> DieInfoArray;721  SmallVector<uint64_t> OutDieOffsetArray;722  SmallVector<TypeEntry *> TypeEntries;723 724  /// The list of accelerator records for this unit.725  ArrayList<AccelInfo> AcceleratorRecords;726  /// @}727};728 729/// \returns list of attributes referencing type DIEs which might be730/// deduplicated.731/// Note: it does not include DW_AT_containing_type attribute to avoid732/// infinite recursion.733ArrayRef<dwarf::Attribute> getODRAttributes();734 735} // end of namespace parallel736} // end of namespace dwarf_linker737} // end of namespace llvm738 739#endif // LLVM_LIB_DWARFLINKER_PARALLEL_DWARFLINKERCOMPILEUNIT_H740