brintos

brintos / llvm-project-archived public Read only

0
0
Text · 72.9 KiB · 2e4a26e Raw
1855 lines · cpp
1//===- llvm/CodeGen/DwarfCompileUnit.cpp - Dwarf Compile Units ------------===//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// This file contains support for constructing a dwarf compile unit.10//11//===----------------------------------------------------------------------===//12 13#include "DwarfCompileUnit.h"14#include "AddressPool.h"15#include "DwarfExpression.h"16#include "llvm/ADT/STLExtras.h"17#include "llvm/ADT/SmallString.h"18#include "llvm/BinaryFormat/Dwarf.h"19#include "llvm/CodeGen/AsmPrinter.h"20#include "llvm/CodeGen/DIE.h"21#include "llvm/CodeGen/MachineFunction.h"22#include "llvm/CodeGen/MachineInstr.h"23#include "llvm/CodeGen/TargetFrameLowering.h"24#include "llvm/CodeGen/TargetRegisterInfo.h"25#include "llvm/CodeGen/TargetSubtargetInfo.h"26#include "llvm/IR/DataLayout.h"27#include "llvm/IR/DebugInfo.h"28#include "llvm/IR/GlobalVariable.h"29#include "llvm/MC/MCAsmInfo.h"30#include "llvm/MC/MCSection.h"31#include "llvm/MC/MCStreamer.h"32#include "llvm/MC/MCSymbol.h"33#include "llvm/MC/MCSymbolWasm.h"34#include "llvm/MC/MachineLocation.h"35#include "llvm/Support/CommandLine.h"36#include "llvm/Support/NVPTXAddrSpace.h"37#include "llvm/Target/TargetLoweringObjectFile.h"38#include "llvm/Target/TargetMachine.h"39#include "llvm/Target/TargetOptions.h"40#include <optional>41#include <string>42#include <utility>43 44using namespace llvm;45 46/// Query value using AddLinkageNamesToDeclCallOriginsForTuning.47static cl::opt<cl::boolOrDefault> AddLinkageNamesToDeclCallOrigins(48    "add-linkage-names-to-declaration-call-origins", cl::Hidden,49    cl::desc("Add DW_AT_linkage_name to function declaration DIEs "50             "referenced by DW_AT_call_origin attributes. Enabled by default "51             "for -gsce debugger tuning."));52 53static cl::opt<bool> EmitFuncLineTableOffsetsOption(54    "emit-func-debug-line-table-offsets", cl::Hidden,55    cl::desc("Include line table offset in function's debug info and emit end "56             "sequence after each function's line data."),57    cl::init(false));58 59static bool AddLinkageNamesToDeclCallOriginsForTuning(const DwarfDebug *DD) {60  bool EnabledByDefault = DD->tuneForSCE();61  if (EnabledByDefault)62    return AddLinkageNamesToDeclCallOrigins != cl::boolOrDefault::BOU_FALSE;63  return AddLinkageNamesToDeclCallOrigins == cl::boolOrDefault::BOU_TRUE;64}65 66static dwarf::Tag GetCompileUnitType(UnitKind Kind, DwarfDebug *DW) {67 68  //  According to DWARF Debugging Information Format Version 5,69  //  3.1.2 Skeleton Compilation Unit Entries:70  //  "When generating a split DWARF object file (see Section 7.3.271  //  on page 187), the compilation unit in the .debug_info section72  //  is a "skeleton" compilation unit with the tag DW_TAG_skeleton_unit"73  if (DW->getDwarfVersion() >= 5 && Kind == UnitKind::Skeleton)74    return dwarf::DW_TAG_skeleton_unit;75 76  return dwarf::DW_TAG_compile_unit;77}78 79/// Translate NVVM IR address space code to DWARF correspondent value80static unsigned translateToNVVMDWARFAddrSpace(unsigned AddrSpace) {81  switch (AddrSpace) {82  case NVPTXAS::ADDRESS_SPACE_GENERIC:83    return NVPTXAS::DWARF_ADDR_generic_space;84  case NVPTXAS::ADDRESS_SPACE_GLOBAL:85    return NVPTXAS::DWARF_ADDR_global_space;86  case NVPTXAS::ADDRESS_SPACE_SHARED:87    return NVPTXAS::DWARF_ADDR_shared_space;88  case NVPTXAS::ADDRESS_SPACE_CONST:89    return NVPTXAS::DWARF_ADDR_const_space;90  case NVPTXAS::ADDRESS_SPACE_LOCAL:91    return NVPTXAS::DWARF_ADDR_local_space;92  default:93    llvm_unreachable(94        "Cannot translate unknown address space to DWARF address space");95    return AddrSpace;96  }97}98 99DwarfCompileUnit::DwarfCompileUnit(unsigned UID, const DICompileUnit *Node,100                                   AsmPrinter *A, DwarfDebug *DW,101                                   DwarfFile *DWU, UnitKind Kind)102    : DwarfUnit(GetCompileUnitType(Kind, DW), Node, A, DW, DWU, UID) {103  insertDIE(Node, &getUnitDie());104  MacroLabelBegin = Asm->createTempSymbol("cu_macro_begin");105}106 107/// addLabelAddress - Add a dwarf label attribute data and value using108/// DW_FORM_addr or DW_FORM_GNU_addr_index.109void DwarfCompileUnit::addLabelAddress(DIE &Die, dwarf::Attribute Attribute,110                                       const MCSymbol *Label) {111  if ((Skeleton || !DD->useSplitDwarf()) && Label)112    DD->addArangeLabel(SymbolCU(this, Label));113 114  // Don't use the address pool in non-fission or in the skeleton unit itself.115  if ((!DD->useSplitDwarf() || !Skeleton) && DD->getDwarfVersion() < 5)116    return addLocalLabelAddress(Die, Attribute, Label);117 118  bool UseAddrOffsetFormOrExpressions =119      DD->useAddrOffsetForm() || DD->useAddrOffsetExpressions();120 121  const MCSymbol *Base = nullptr;122  if (Label->isInSection() && UseAddrOffsetFormOrExpressions)123    Base = DD->getSectionLabel(&Label->getSection());124 125  if (!Base || Base == Label) {126    unsigned idx = DD->getAddressPool().getIndex(Label);127    addAttribute(Die, Attribute,128                 DD->getDwarfVersion() >= 5 ? dwarf::DW_FORM_addrx129                                            : dwarf::DW_FORM_GNU_addr_index,130                 DIEInteger(idx));131    return;132  }133 134  // Could be extended to work with DWARFv4 Split DWARF if that's important for135  // someone. In that case DW_FORM_data would be used.136  assert(DD->getDwarfVersion() >= 5 &&137         "Addr+offset expressions are only valuable when using debug_addr (to "138         "reduce relocations) available in DWARFv5 or higher");139  if (DD->useAddrOffsetExpressions()) {140    auto *Loc = new (DIEValueAllocator) DIEBlock();141    addPoolOpAddress(*Loc, Label);142    addBlock(Die, Attribute, dwarf::DW_FORM_exprloc, Loc);143  } else144    addAttribute(Die, Attribute, dwarf::DW_FORM_LLVM_addrx_offset,145                 new (DIEValueAllocator) DIEAddrOffset(146                     DD->getAddressPool().getIndex(Base), Label, Base));147}148 149void DwarfCompileUnit::addLocalLabelAddress(DIE &Die,150                                            dwarf::Attribute Attribute,151                                            const MCSymbol *Label) {152  if (Label)153    addAttribute(Die, Attribute, dwarf::DW_FORM_addr, DIELabel(Label));154  else155    addAttribute(Die, Attribute, dwarf::DW_FORM_addr, DIEInteger(0));156}157 158unsigned DwarfCompileUnit::getOrCreateSourceID(const DIFile *File) {159  // If we print assembly, we can't separate .file entries according to160  // compile units. Thus all files will belong to the default compile unit.161 162  // FIXME: add a better feature test than hasRawTextSupport. Even better,163  // extend .file to support this.164  unsigned CUID = Asm->OutStreamer->hasRawTextSupport() ? 0 : getUniqueID();165  if (!File)166    return Asm->OutStreamer->emitDwarfFileDirective(0, "", "", std::nullopt,167                                                    std::nullopt, CUID);168 169  if (LastFile != File) {170    LastFile = File;171    LastFileID = Asm->OutStreamer->emitDwarfFileDirective(172        0, File->getDirectory(), File->getFilename(), DD->getMD5AsBytes(File),173        File->getSource(), CUID);174  }175  return LastFileID;176}177 178DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE(179    const DIGlobalVariable *GV, ArrayRef<GlobalExpr> GlobalExprs) {180  // Check for pre-existence.181  if (DIE *Die = getDIE(GV))182    return Die;183 184  assert(GV);185 186  auto *GVContext = GV->getScope();187  const DIType *GTy = GV->getType();188 189  auto *CB = GVContext ? dyn_cast<DICommonBlock>(GVContext) : nullptr;190  DIE *ContextDIE = CB ? getOrCreateCommonBlock(CB, GlobalExprs)191    : getOrCreateContextDIE(GVContext);192 193  // Add to map.194  DIE *VariableDIE = &createAndAddDIE(GV->getTag(), *ContextDIE, GV);195  DIScope *DeclContext;196  if (auto *SDMDecl = GV->getStaticDataMemberDeclaration()) {197    DeclContext = SDMDecl->getScope();198    assert(SDMDecl->isStaticMember() && "Expected static member decl");199    assert(GV->isDefinition());200    // We need the declaration DIE that is in the static member's class.201    DIE *VariableSpecDIE = getOrCreateStaticMemberDIE(SDMDecl);202    addDIEEntry(*VariableDIE, dwarf::DW_AT_specification, *VariableSpecDIE);203    // If the global variable's type is different from the one in the class204    // member type, assume that it's more specific and also emit it.205    if (GTy != SDMDecl->getBaseType())206      addType(*VariableDIE, GTy);207  } else {208    DeclContext = GV->getScope();209    // Add name and type.210    StringRef DisplayName = GV->getDisplayName();211    if (!DisplayName.empty())212      addString(*VariableDIE, dwarf::DW_AT_name, GV->getDisplayName());213    if (GTy)214      addType(*VariableDIE, GTy);215 216    // Add scoping info.217    if (!GV->isLocalToUnit())218      addFlag(*VariableDIE, dwarf::DW_AT_external);219 220    // Add line number info.221    addSourceLine(*VariableDIE, GV);222  }223 224  if (!GV->isDefinition())225    addFlag(*VariableDIE, dwarf::DW_AT_declaration);226  else227    addGlobalName(GV->getName(), *VariableDIE, DeclContext);228 229  addAnnotation(*VariableDIE, GV->getAnnotations());230 231  if (uint32_t AlignInBytes = GV->getAlignInBytes())232    addUInt(*VariableDIE, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,233            AlignInBytes);234 235  if (MDTuple *TP = GV->getTemplateParams())236    addTemplateParams(*VariableDIE, DINodeArray(TP));237 238  // Add location.239  addLocationAttribute(VariableDIE, GV, GlobalExprs);240 241  return VariableDIE;242}243 244void DwarfCompileUnit::addLocationAttribute(245    DIE *VariableDIE, const DIGlobalVariable *GV, ArrayRef<GlobalExpr> GlobalExprs) {246  bool addToAccelTable = false;247  DIELoc *Loc = nullptr;248  std::optional<unsigned> NVPTXAddressSpace;249  std::unique_ptr<DIEDwarfExpression> DwarfExpr;250  for (const auto &GE : GlobalExprs) {251    const GlobalVariable *Global = GE.Var;252    const DIExpression *Expr = GE.Expr;253 254    // For compatibility with DWARF 3 and earlier,255    // DW_AT_location(DW_OP_constu, X, DW_OP_stack_value) or256    // DW_AT_location(DW_OP_consts, X, DW_OP_stack_value) becomes257    // DW_AT_const_value(X).258    if (GlobalExprs.size() == 1 && Expr && Expr->isConstant()) {259      addToAccelTable = true;260      addConstantValue(261          *VariableDIE,262          DIExpression::SignedOrUnsignedConstant::UnsignedConstant ==263              *Expr->isConstant(),264          Expr->getElement(1));265      break;266    }267 268    // We cannot describe the location of dllimport'd variables: the269    // computation of their address requires loads from the IAT.270    if (Global && Global->hasDLLImportStorageClass())271      continue;272 273    // Nothing to describe without address or constant.274    if (!Global && (!Expr || !Expr->isConstant()))275      continue;276 277    if (Global && Global->isThreadLocal() &&278        !Asm->getObjFileLowering().supportDebugThreadLocalLocation())279      continue;280 281    if (!Loc) {282      addToAccelTable = true;283      Loc = new (DIEValueAllocator) DIELoc;284      DwarfExpr = std::make_unique<DIEDwarfExpression>(*Asm, *this, *Loc);285    }286 287    if (Expr) {288      // cuda-gdb special requirement. See NVPTXAS::DWARF_AddressSpace289      // Decode DW_OP_constu <DWARF Address Space> DW_OP_swap DW_OP_xderef290      // sequence to specify corresponding address space.291      if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) {292        unsigned LocalNVPTXAddressSpace;293        const DIExpression *NewExpr =294            DIExpression::extractAddressClass(Expr, LocalNVPTXAddressSpace);295        if (NewExpr != Expr) {296          Expr = NewExpr;297          NVPTXAddressSpace = LocalNVPTXAddressSpace;298        }299      }300      DwarfExpr->addFragmentOffset(Expr);301    }302 303    if (Global) {304      const MCSymbol *Sym = Asm->getSymbol(Global);305      // 16-bit platforms like MSP430 and AVR take this path, so sink this306      // assert to platforms that use it.307      auto GetPointerSizedFormAndOp = [this]() {308        unsigned PointerSize = Asm->MAI->getCodePointerSize();309        assert((PointerSize == 4 || PointerSize == 8) &&310               "Add support for other sizes if necessary");311        struct FormAndOp {312          dwarf::Form Form;313          dwarf::LocationAtom Op;314        };315        return PointerSize == 4316                   ? FormAndOp{dwarf::DW_FORM_data4, dwarf::DW_OP_const4u}317                   : FormAndOp{dwarf::DW_FORM_data8, dwarf::DW_OP_const8u};318      };319      if (Global->isThreadLocal()) {320        if (Asm->TM.getTargetTriple().isWasm()) {321          // FIXME This is not guaranteed, but in practice, in static linking,322          // if present, __tls_base's index is 1. This doesn't hold for dynamic323          // linking, so TLS variables used in dynamic linking won't have324          // correct debug info for now. See325          // https://github.com/llvm/llvm-project/blob/19afbfe33156d211fa959dadeea46cd17b9c723c/lld/wasm/Driver.cpp#L786-L823326          addWasmRelocBaseGlobal(Loc, "__tls_base", 1);327          addOpAddress(*Loc, Sym);328          addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);329        } else if (Asm->TM.useEmulatedTLS()) {330          // TODO: add debug info for emulated thread local mode.331        } else {332          // FIXME: Make this work with -gsplit-dwarf.333          // Based on GCC's support for TLS:334          if (!DD->useSplitDwarf()) {335            auto FormAndOp = GetPointerSizedFormAndOp();336            // 1) Start with a constNu of the appropriate pointer size337            addUInt(*Loc, dwarf::DW_FORM_data1, FormAndOp.Op);338            // 2) containing the (relocated) offset of the TLS variable339            //    within the module's TLS block.340            addExpr(*Loc, FormAndOp.Form,341                    Asm->getObjFileLowering().getDebugThreadLocalSymbol(Sym));342          } else {343            addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_const_index);344            addUInt(*Loc, dwarf::DW_FORM_udata,345                    DD->getAddressPool().getIndex(Sym, /* TLS */ true));346          }347          // 3) followed by an OP to make the debugger do a TLS lookup.348          addUInt(*Loc, dwarf::DW_FORM_data1,349                  DD->useGNUTLSOpcode() ? dwarf::DW_OP_GNU_push_tls_address350                                        : dwarf::DW_OP_form_tls_address);351        }352      } else if (Asm->TM.getTargetTriple().isWasm() &&353                 Asm->TM.getRelocationModel() == Reloc::PIC_) {354        // FIXME This is not guaranteed, but in practice, if present,355        // __memory_base's index is 1. See356        // https://github.com/llvm/llvm-project/blob/19afbfe33156d211fa959dadeea46cd17b9c723c/lld/wasm/Driver.cpp#L786-L823357        addWasmRelocBaseGlobal(Loc, "__memory_base", 1);358        addOpAddress(*Loc, Sym);359        addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);360      } else if ((Asm->TM.getRelocationModel() == Reloc::RWPI ||361                  Asm->TM.getRelocationModel() == Reloc::ROPI_RWPI) &&362                 !Asm->getObjFileLowering()363                      .getKindForGlobal(Global, Asm->TM)364                      .isReadOnly()) {365        auto FormAndOp = GetPointerSizedFormAndOp();366        // Constant367        addUInt(*Loc, dwarf::DW_FORM_data1, FormAndOp.Op);368        // Relocation offset369        addExpr(*Loc, FormAndOp.Form,370                Asm->getObjFileLowering().getIndirectSymViaRWPI(Sym));371        // Base register372        Register BaseReg = Asm->getObjFileLowering().getStaticBase();373        unsigned DwarfBaseReg =374            Asm->TM.getMCRegisterInfo()->getDwarfRegNum(BaseReg, false);375        addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + DwarfBaseReg);376        // Offset from base register377        addSInt(*Loc, dwarf::DW_FORM_sdata, 0);378        // Operation379        addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);380      } else {381        DD->addArangeLabel(SymbolCU(this, Sym));382        addOpAddress(*Loc, Sym);383      }384      if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB() &&385          !NVPTXAddressSpace)386        NVPTXAddressSpace =387            translateToNVVMDWARFAddrSpace(Global->getType()->getAddressSpace());388    }389    // Global variables attached to symbols are memory locations.390    // It would be better if this were unconditional, but malformed input that391    // mixes non-fragments and fragments for the same variable is too expensive392    // to detect in the verifier.393    if (DwarfExpr->isUnknownLocation())394      DwarfExpr->setMemoryLocationKind();395    DwarfExpr->addExpression(Expr);396  }397  if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) {398    // cuda-gdb special requirement. See NVPTXAS::DWARF_AddressSpace399    addUInt(*VariableDIE, dwarf::DW_AT_address_class, dwarf::DW_FORM_data1,400            NVPTXAddressSpace.value_or(NVPTXAS::DWARF_ADDR_global_space));401  }402  if (Loc)403    addBlock(*VariableDIE, dwarf::DW_AT_location, DwarfExpr->finalize());404 405  if (DD->useAllLinkageNames())406    addLinkageName(*VariableDIE, GV->getLinkageName());407 408  if (addToAccelTable) {409    DD->addAccelName(*this, CUNode->getNameTableKind(), GV->getName(),410                     *VariableDIE);411 412    // If the linkage name is different than the name, go ahead and output413    // that as well into the name table.414    if (GV->getLinkageName() != "" && GV->getName() != GV->getLinkageName() &&415        DD->useAllLinkageNames())416      DD->addAccelName(*this, CUNode->getNameTableKind(), GV->getLinkageName(),417                       *VariableDIE);418  }419}420 421DIE *DwarfCompileUnit::getOrCreateCommonBlock(422    const DICommonBlock *CB, ArrayRef<GlobalExpr> GlobalExprs) {423  // Check for pre-existence.424  if (DIE *NDie = getDIE(CB))425    return NDie;426  DIE *ContextDIE = getOrCreateContextDIE(CB->getScope());427  DIE &NDie = createAndAddDIE(dwarf::DW_TAG_common_block, *ContextDIE, CB);428  StringRef Name = CB->getName().empty() ? "_BLNK_" : CB->getName();429  addString(NDie, dwarf::DW_AT_name, Name);430  addGlobalName(Name, NDie, CB->getScope());431  if (CB->getFile())432    addSourceLine(NDie, CB->getLineNo(), /*Column*/ 0, CB->getFile());433  if (DIGlobalVariable *V = CB->getDecl())434    getCU().addLocationAttribute(&NDie, V, GlobalExprs);435  return &NDie;436}437 438void DwarfCompileUnit::addRange(RangeSpan Range) {439  DD->insertSectionLabel(Range.Begin);440 441  auto *PrevCU = DD->getPrevCU();442  bool SameAsPrevCU = this == PrevCU;443  DD->setPrevCU(this);444  // If we have no current ranges just add the range and return, otherwise,445  // check the current section and CU against the previous section and CU we446  // emitted into and the subprogram was contained within. If these are the447  // same then extend our current range, otherwise add this as a new range.448  if (CURanges.empty() || !SameAsPrevCU ||449      (&CURanges.back().End->getSection() !=450       &Range.End->getSection())) {451    // Before a new range is added, always terminate the prior line table.452    if (PrevCU)453      DD->terminateLineTable(PrevCU);454    CURanges.push_back(Range);455    return;456  }457 458  CURanges.back().End = Range.End;459}460 461void DwarfCompileUnit::initStmtList() {462  if (CUNode->isDebugDirectivesOnly())463    return;464 465  const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();466  if (DD->useSectionsAsReferences()) {467    LineTableStartSym = TLOF.getDwarfLineSection()->getBeginSymbol();468  } else {469    LineTableStartSym =470        Asm->OutStreamer->getDwarfLineTableSymbol(getUniqueID());471  }472 473  // DW_AT_stmt_list is a offset of line number information for this474  // compile unit in debug_line section. For split dwarf this is475  // left in the skeleton CU and so not included.476  // The line table entries are not always emitted in assembly, so it477  // is not okay to use line_table_start here.478      addSectionLabel(getUnitDie(), dwarf::DW_AT_stmt_list, LineTableStartSym,479                      TLOF.getDwarfLineSection()->getBeginSymbol());480}481 482void DwarfCompileUnit::applyStmtList(DIE &D) {483  const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();484  addSectionLabel(D, dwarf::DW_AT_stmt_list, LineTableStartSym,485                  TLOF.getDwarfLineSection()->getBeginSymbol());486}487 488void DwarfCompileUnit::attachLowHighPC(DIE &D, const MCSymbol *Begin,489                                       const MCSymbol *End) {490  assert(Begin && "Begin label should not be null!");491  assert(End && "End label should not be null!");492  assert(Begin->isDefined() && "Invalid starting label");493  assert(End->isDefined() && "Invalid end label");494 495  addLabelAddress(D, dwarf::DW_AT_low_pc, Begin);496  if (DD->getDwarfVersion() >= 4 &&497      (!isDwoUnit() || !llvm::isRangeRelaxable(Begin, End))) {498    addLabelDelta(D, dwarf::DW_AT_high_pc, End, Begin);499    return;500  }501  addLabelAddress(D, dwarf::DW_AT_high_pc, End);502}503 504// Add info for Wasm-global-based relocation.505// 'GlobalIndex' is used for split dwarf, which currently relies on a few506// assumptions that are not guaranteed in a formal way but work in practice.507void DwarfCompileUnit::addWasmRelocBaseGlobal(DIELoc *Loc, StringRef GlobalName,508                                              uint64_t GlobalIndex) {509  // FIXME: duplicated from Target/WebAssembly/WebAssembly.h510  // don't want to depend on target specific headers in this code?511  const unsigned TI_GLOBAL_RELOC = 3;512  unsigned PointerSize = Asm->getDataLayout().getPointerSize();513  auto *Sym =514      static_cast<MCSymbolWasm *>(Asm->GetExternalSymbolSymbol(GlobalName));515  // FIXME: this repeats what WebAssemblyMCInstLower::516  // GetExternalSymbolSymbol does, since if there's no code that517  // refers to this symbol, we have to set it here.518  Sym->setType(wasm::WASM_SYMBOL_TYPE_GLOBAL);519  Sym->setGlobalType(wasm::WasmGlobalType{520      static_cast<uint8_t>(PointerSize == 4 ? wasm::WASM_TYPE_I32521                                            : wasm::WASM_TYPE_I64),522      true});523  addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_WASM_location);524  addSInt(*Loc, dwarf::DW_FORM_sdata, TI_GLOBAL_RELOC);525  if (!isDwoUnit()) {526    addLabel(*Loc, dwarf::DW_FORM_data4, Sym);527  } else {528    // FIXME: when writing dwo, we need to avoid relocations. Probably529    // the "right" solution is to treat globals the way func and data530    // symbols are (with entries in .debug_addr).531    // For now we hardcode the indices in the callsites. Global indices are not532    // fixed, but in practice a few are fixed; for example, __stack_pointer is533    // always index 0.534    addUInt(*Loc, dwarf::DW_FORM_data4, GlobalIndex);535  }536}537 538// Find DIE for the given subprogram and attach appropriate DW_AT_low_pc539// and DW_AT_high_pc attributes. If there are global variables in this540// scope then create and insert DIEs for these variables.541DIE &DwarfCompileUnit::updateSubprogramScopeDIE(const DISubprogram *SP,542                                                const Function &F,543                                                MCSymbol *LineTableSym) {544  DIE *SPDie = getOrCreateSubprogramDIE(SP, &F, includeMinimalInlineScopes());545  SmallVector<RangeSpan, 2> BB_List;546  // If basic block sections are on, ranges for each basic block section has547  // to be emitted separately.548  for (const auto &R : Asm->MBBSectionRanges)549    BB_List.push_back({R.second.BeginLabel, R.second.EndLabel});550 551  attachRangesOrLowHighPC(*SPDie, BB_List);552 553  if (DD->useAppleExtensionAttributes() &&554      !DD->getCurrentFunction()->getTarget().Options.DisableFramePointerElim(555          *DD->getCurrentFunction()))556    addFlag(*SPDie, dwarf::DW_AT_APPLE_omit_frame_ptr);557 558  if (emitFuncLineTableOffsets() && LineTableSym) {559    addSectionLabel(560        *SPDie, dwarf::DW_AT_LLVM_stmt_sequence, LineTableSym,561        Asm->getObjFileLowering().getDwarfLineSection()->getBeginSymbol());562  }563 564  // Only include DW_AT_frame_base in full debug info565  if (!includeMinimalInlineScopes()) {566    const TargetFrameLowering *TFI = Asm->MF->getSubtarget().getFrameLowering();567    TargetFrameLowering::DwarfFrameBase FrameBase =568        TFI->getDwarfFrameBase(*Asm->MF);569    switch (FrameBase.Kind) {570    case TargetFrameLowering::DwarfFrameBase::Register: {571      if (Register::isPhysicalRegister(FrameBase.Location.Reg)) {572        MachineLocation Location(FrameBase.Location.Reg);573        addAddress(*SPDie, dwarf::DW_AT_frame_base, Location);574      }575      break;576    }577    case TargetFrameLowering::DwarfFrameBase::CFA: {578      DIELoc *Loc = new (DIEValueAllocator) DIELoc;579      addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_call_frame_cfa);580      if (FrameBase.Location.Offset != 0) {581        addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_consts);582        addSInt(*Loc, dwarf::DW_FORM_sdata, FrameBase.Location.Offset);583        addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);584      }585      addBlock(*SPDie, dwarf::DW_AT_frame_base, Loc);586      break;587    }588    case TargetFrameLowering::DwarfFrameBase::WasmFrameBase: {589      // FIXME: duplicated from Target/WebAssembly/WebAssembly.h590      const unsigned TI_GLOBAL_RELOC = 3;591      if (FrameBase.Location.WasmLoc.Kind == TI_GLOBAL_RELOC) {592        // These need to be relocatable.593        DIELoc *Loc = new (DIEValueAllocator) DIELoc;594        assert(FrameBase.Location.WasmLoc.Index == 0); // Only SP so far.595        // For now, since we only ever use index 0, this should work as-is.596        addWasmRelocBaseGlobal(Loc, "__stack_pointer",597                               FrameBase.Location.WasmLoc.Index);598        addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_stack_value);599        addBlock(*SPDie, dwarf::DW_AT_frame_base, Loc);600      } else {601        DIELoc *Loc = new (DIEValueAllocator) DIELoc;602        DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);603        DIExpressionCursor Cursor({});604        DwarfExpr.addWasmLocation(FrameBase.Location.WasmLoc.Kind,605            FrameBase.Location.WasmLoc.Index);606        DwarfExpr.addExpression(std::move(Cursor));607        addBlock(*SPDie, dwarf::DW_AT_frame_base, DwarfExpr.finalize());608      }609      break;610    }611    }612  }613 614  // Add name to the name table, we do this here because we're guaranteed615  // to have concrete versions of our DW_TAG_subprogram nodes.616  DD->addSubprogramNames(*this, CUNode->getNameTableKind(), SP, *SPDie);617 618  return *SPDie;619}620 621// Construct a DIE for this scope.622void DwarfCompileUnit::constructScopeDIE(LexicalScope *Scope,623                                         DIE &ParentScopeDIE) {624  if (!Scope || !Scope->getScopeNode())625    return;626 627  auto *DS = Scope->getScopeNode();628 629  assert((Scope->getInlinedAt() || !isa<DISubprogram>(DS)) &&630         "Only handle inlined subprograms here, use "631         "constructSubprogramScopeDIE for non-inlined "632         "subprograms");633 634  // Emit inlined subprograms.635  if (Scope->getParent() && isa<DISubprogram>(DS)) {636    DIE *ScopeDIE = constructInlinedScopeDIE(Scope, ParentScopeDIE);637    assert(ScopeDIE && "Scope DIE should not be null.");638    createAndAddScopeChildren(Scope, *ScopeDIE);639    return;640  }641 642  // Early exit when we know the scope DIE is going to be null.643  if (DD->isLexicalScopeDIENull(Scope))644    return;645 646  // Emit lexical blocks.647  DIE *ScopeDIE = constructLexicalScopeDIE(Scope);648  assert(ScopeDIE && "Scope DIE should not be null.");649 650  ParentScopeDIE.addChild(ScopeDIE);651  createAndAddScopeChildren(Scope, *ScopeDIE);652}653 654void DwarfCompileUnit::addScopeRangeList(DIE &ScopeDIE,655                                         SmallVector<RangeSpan, 2> Range) {656 657  HasRangeLists = true;658 659  // Add the range list to the set of ranges to be emitted.660  auto IndexAndList =661      (DD->getDwarfVersion() < 5 && Skeleton ? Skeleton->DU : DU)662          ->addRange(*(Skeleton ? Skeleton : this), std::move(Range));663 664  uint32_t Index = IndexAndList.first;665  auto &List = *IndexAndList.second;666 667  // Under fission, ranges are specified by constant offsets relative to the668  // CU's DW_AT_GNU_ranges_base.669  // FIXME: For DWARF v5, do not generate the DW_AT_ranges attribute under670  // fission until we support the forms using the .debug_addr section671  // (DW_RLE_startx_endx etc.).672  if (DD->getDwarfVersion() >= 5)673    addUInt(ScopeDIE, dwarf::DW_AT_ranges, dwarf::DW_FORM_rnglistx, Index);674  else {675    const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();676    const MCSymbol *RangeSectionSym =677        TLOF.getDwarfRangesSection()->getBeginSymbol();678    if (isDwoUnit())679      addSectionDelta(ScopeDIE, dwarf::DW_AT_ranges, List.Label,680                      RangeSectionSym);681    else682      addSectionLabel(ScopeDIE, dwarf::DW_AT_ranges, List.Label,683                      RangeSectionSym);684  }685}686 687void DwarfCompileUnit::attachRangesOrLowHighPC(688    DIE &Die, SmallVector<RangeSpan, 2> Ranges) {689  assert(!Ranges.empty());690  if (!DD->useRangesSection() ||691      (Ranges.size() == 1 &&692       (!DD->alwaysUseRanges(*this) ||693        DD->getSectionLabel(&Ranges.front().Begin->getSection()) ==694            Ranges.front().Begin))) {695    const RangeSpan &Front = Ranges.front();696    const RangeSpan &Back = Ranges.back();697    attachLowHighPC(Die, Front.Begin, Back.End);698  } else699    addScopeRangeList(Die, std::move(Ranges));700}701 702void DwarfCompileUnit::attachRangesOrLowHighPC(703    DIE &Die, const SmallVectorImpl<InsnRange> &Ranges) {704  SmallVector<RangeSpan, 2> List;705  List.reserve(Ranges.size());706  for (const InsnRange &R : Ranges) {707    auto *BeginLabel = DD->getLabelBeforeInsn(R.first);708    auto *EndLabel = DD->getLabelAfterInsn(R.second);709 710    const auto *BeginMBB = R.first->getParent();711    const auto *EndMBB = R.second->getParent();712 713    const auto *MBB = BeginMBB;714    // Basic block sections allows basic block subsets to be placed in unique715    // sections. For each section, the begin and end label must be added to the716    // list. If there is more than one range, debug ranges must be used.717    // Otherwise, low/high PC can be used.718    // FIXME: Debug Info Emission depends on block order and this assumes that719    // the order of blocks will be frozen beyond this point.720    do {721      if (MBB->sameSection(EndMBB) || MBB->isEndSection()) {722        auto MBBSectionRange = Asm->MBBSectionRanges[MBB->getSectionID()];723        List.push_back(724            {MBB->sameSection(BeginMBB) ? BeginLabel725                                        : MBBSectionRange.BeginLabel,726             MBB->sameSection(EndMBB) ? EndLabel : MBBSectionRange.EndLabel});727      }728      if (MBB->sameSection(EndMBB))729        break;730      MBB = MBB->getNextNode();731    } while (true);732  }733  attachRangesOrLowHighPC(Die, std::move(List));734}735 736DIE *DwarfCompileUnit::constructInlinedScopeDIE(LexicalScope *Scope,737                                                DIE &ParentScopeDIE) {738  assert(Scope->getScopeNode());739  auto *DS = Scope->getScopeNode();740  auto *InlinedSP = getDISubprogram(DS);741  // Find the subprogram's DwarfCompileUnit in the SPMap in case the subprogram742  // was inlined from another compile unit.743  DIE *OriginDIE = getAbstractScopeDIEs()[InlinedSP];744  assert(OriginDIE && "Unable to find original DIE for an inlined subprogram.");745 746  auto ScopeDIE = DIE::get(DIEValueAllocator, dwarf::DW_TAG_inlined_subroutine);747  ParentScopeDIE.addChild(ScopeDIE);748  addDIEEntry(*ScopeDIE, dwarf::DW_AT_abstract_origin, *OriginDIE);749 750  attachRangesOrLowHighPC(*ScopeDIE, Scope->getRanges());751 752  // Add the call site information to the DIE.753  const DILocation *IA = Scope->getInlinedAt();754  addUInt(*ScopeDIE, dwarf::DW_AT_call_file, std::nullopt,755          getOrCreateSourceID(IA->getFile()));756  addUInt(*ScopeDIE, dwarf::DW_AT_call_line, std::nullopt, IA->getLine());757  if (IA->getColumn())758    addUInt(*ScopeDIE, dwarf::DW_AT_call_column, std::nullopt, IA->getColumn());759  if (IA->getDiscriminator() && DD->getDwarfVersion() >= 4)760    addUInt(*ScopeDIE, dwarf::DW_AT_GNU_discriminator, std::nullopt,761            IA->getDiscriminator());762 763  // Add name to the name table, we do this here because we're guaranteed764  // to have concrete versions of our DW_TAG_inlined_subprogram nodes.765  DD->addSubprogramNames(*this, CUNode->getNameTableKind(), InlinedSP,766                         *ScopeDIE);767 768  return ScopeDIE;769}770 771// Construct new DW_TAG_lexical_block for this scope and attach772// DW_AT_low_pc/DW_AT_high_pc labels.773DIE *DwarfCompileUnit::constructLexicalScopeDIE(LexicalScope *Scope) {774  if (DD->isLexicalScopeDIENull(Scope))775    return nullptr;776  const auto *DS = Scope->getScopeNode();777 778  auto ScopeDIE = DIE::get(DIEValueAllocator, dwarf::DW_TAG_lexical_block);779  if (Scope->isAbstractScope()) {780    assert(!getAbstractScopeDIEs().count(DS) &&781           "Abstract DIE for this scope exists!");782    getAbstractScopeDIEs()[DS] = ScopeDIE;783    return ScopeDIE;784  }785  if (!Scope->getInlinedAt()) {786    assert(!LexicalBlockDIEs.count(DS) &&787           "Concrete out-of-line DIE for this scope exists!");788    LexicalBlockDIEs[DS] = ScopeDIE;789  } else {790    InlinedLocalScopeDIEs[DS].push_back(ScopeDIE);791  }792 793  attachRangesOrLowHighPC(*ScopeDIE, Scope->getRanges());794 795  return ScopeDIE;796}797 798DIE *DwarfCompileUnit::constructVariableDIE(DbgVariable &DV, bool Abstract) {799  auto *VariableDie = DIE::get(DIEValueAllocator, DV.getTag());800  insertDIE(DV.getVariable(), VariableDie);801  DV.setDIE(*VariableDie);802  // Abstract variables don't get common attributes later, so apply them now.803  if (Abstract) {804    applyCommonDbgVariableAttributes(DV, *VariableDie);805  } else {806    std::visit(807        [&](const auto &V) {808          applyConcreteDbgVariableAttributes(V, DV, *VariableDie);809        },810        DV.asVariant());811  }812  return VariableDie;813}814 815void DwarfCompileUnit::applyConcreteDbgVariableAttributes(816    const Loc::Single &Single, const DbgVariable &DV, DIE &VariableDie) {817  const DbgValueLoc *DVal = &Single.getValueLoc();818  if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB() &&819      !Single.getExpr()) {820    // cuda-gdb special requirement. See NVPTXAS::DWARF_AddressSpace821    // Lack of expression means it is a register.822    addUInt(VariableDie, dwarf::DW_AT_address_class, dwarf::DW_FORM_data1,823            NVPTXAS::DWARF_ADDR_reg_space);824  }825  if (!DVal->isVariadic()) {826    const DbgValueLocEntry *Entry = DVal->getLocEntries().begin();827    if (Entry->isLocation()) {828      addVariableAddress(DV, VariableDie, Entry->getLoc());829    } else if (Entry->isInt()) {830      auto *Expr = Single.getExpr();831      if (Expr && Expr->getNumElements()) {832        DIELoc *Loc = new (DIEValueAllocator) DIELoc;833        DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);834        // If there is an expression, emit raw unsigned bytes.835        DwarfExpr.addFragmentOffset(Expr);836        DwarfExpr.addUnsignedConstant(Entry->getInt());837        DwarfExpr.addExpression(Expr);838        addBlock(VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());839        if (DwarfExpr.TagOffset)840          addUInt(VariableDie, dwarf::DW_AT_LLVM_tag_offset,841                  dwarf::DW_FORM_data1, *DwarfExpr.TagOffset);842      } else843        addConstantValue(VariableDie, Entry->getInt(), DV.getType());844    } else if (Entry->isConstantFP()) {845      addConstantFPValue(VariableDie, Entry->getConstantFP());846    } else if (Entry->isConstantInt()) {847      addConstantValue(VariableDie, Entry->getConstantInt(), DV.getType());848    } else if (Entry->isTargetIndexLocation()) {849      DIELoc *Loc = new (DIEValueAllocator) DIELoc;850      DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);851      const DIBasicType *BT = dyn_cast<DIBasicType>(852          static_cast<const Metadata *>(DV.getVariable()->getType()));853      DwarfDebug::emitDebugLocValue(*Asm, BT, *DVal, DwarfExpr);854      addBlock(VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());855    }856    return;857  }858  // If any of the location entries are registers with the value 0,859  // then the location is undefined.860  if (any_of(DVal->getLocEntries(), [](const DbgValueLocEntry &Entry) {861        return Entry.isLocation() && !Entry.getLoc().getReg();862      }))863    return;864  const DIExpression *Expr = Single.getExpr();865  assert(Expr && "Variadic Debug Value must have an Expression.");866  DIELoc *Loc = new (DIEValueAllocator) DIELoc;867  DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);868  DwarfExpr.addFragmentOffset(Expr);869  DIExpressionCursor Cursor(Expr);870  const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();871 872  auto AddEntry = [&](const DbgValueLocEntry &Entry,873                      DIExpressionCursor &Cursor) {874    if (Entry.isLocation()) {875      if (!DwarfExpr.addMachineRegExpression(TRI, Cursor,876                                             Entry.getLoc().getReg()))877        return false;878    } else if (Entry.isInt()) {879      // If there is an expression, emit raw unsigned bytes.880      DwarfExpr.addUnsignedConstant(Entry.getInt());881    } else if (Entry.isConstantFP()) {882      // DwarfExpression does not support arguments wider than 64 bits883      // (see PR52584).884      // TODO: Consider chunking expressions containing overly wide885      // arguments into separate pointer-sized fragment expressions.886      APInt RawBytes = Entry.getConstantFP()->getValueAPF().bitcastToAPInt();887      if (RawBytes.getBitWidth() > 64)888        return false;889      DwarfExpr.addUnsignedConstant(RawBytes.getZExtValue());890    } else if (Entry.isConstantInt()) {891      APInt RawBytes = Entry.getConstantInt()->getValue();892      if (RawBytes.getBitWidth() > 64)893        return false;894      DwarfExpr.addUnsignedConstant(RawBytes.getZExtValue());895    } else if (Entry.isTargetIndexLocation()) {896      TargetIndexLocation Loc = Entry.getTargetIndexLocation();897      // TODO TargetIndexLocation is a target-independent. Currently898      // only the WebAssembly-specific encoding is supported.899      assert(Asm->TM.getTargetTriple().isWasm());900      DwarfExpr.addWasmLocation(Loc.Index, static_cast<uint64_t>(Loc.Offset));901    } else {902      llvm_unreachable("Unsupported Entry type.");903    }904    return true;905  };906 907  if (!DwarfExpr.addExpression(908          std::move(Cursor),909          [&](unsigned Idx, DIExpressionCursor &Cursor) -> bool {910            return AddEntry(DVal->getLocEntries()[Idx], Cursor);911          }))912    return;913 914  // Now attach the location information to the DIE.915  addBlock(VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());916  if (DwarfExpr.TagOffset)917    addUInt(VariableDie, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,918            *DwarfExpr.TagOffset);919}920 921void DwarfCompileUnit::applyConcreteDbgVariableAttributes(922    const Loc::Multi &Multi, const DbgVariable &DV, DIE &VariableDie) {923  addLocationList(VariableDie, dwarf::DW_AT_location,924                  Multi.getDebugLocListIndex());925  auto TagOffset = Multi.getDebugLocListTagOffset();926  if (TagOffset)927    addUInt(VariableDie, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,928            *TagOffset);929}930 931void DwarfCompileUnit::applyConcreteDbgVariableAttributes(const Loc::MMI &MMI,932                                                          const DbgVariable &DV,933                                                          DIE &VariableDie) {934  std::optional<unsigned> NVPTXAddressSpace;935  DIELoc *Loc = new (DIEValueAllocator) DIELoc;936  DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);937  for (const auto &Fragment : MMI.getFrameIndexExprs()) {938    Register FrameReg;939    const DIExpression *Expr = Fragment.Expr;940    const TargetFrameLowering *TFI = Asm->MF->getSubtarget().getFrameLowering();941    StackOffset Offset =942        TFI->getFrameIndexReference(*Asm->MF, Fragment.FI, FrameReg);943    DwarfExpr.addFragmentOffset(Expr);944 945    auto *TRI = Asm->MF->getSubtarget().getRegisterInfo();946    SmallVector<uint64_t, 8> Ops;947    TRI->getOffsetOpcodes(Offset, Ops);948 949    // cuda-gdb special requirement. See NVPTXAS::DWARF_AddressSpace.950    // Decode DW_OP_constu <DWARF Address Space> DW_OP_swap951    // DW_OP_xderef sequence to specify address space.952    if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) {953      unsigned LocalNVPTXAddressSpace;954      const DIExpression *NewExpr =955          DIExpression::extractAddressClass(Expr, LocalNVPTXAddressSpace);956      if (NewExpr != Expr) {957        Expr = NewExpr;958        NVPTXAddressSpace = LocalNVPTXAddressSpace;959      }960    }961    if (Expr)962      Ops.append(Expr->elements_begin(), Expr->elements_end());963    DIExpressionCursor Cursor(Ops);964    DwarfExpr.setMemoryLocationKind();965    if (const MCSymbol *FrameSymbol = Asm->getFunctionFrameSymbol())966      addOpAddress(*Loc, FrameSymbol);967    else968      DwarfExpr.addMachineRegExpression(969          *Asm->MF->getSubtarget().getRegisterInfo(), Cursor, FrameReg);970    DwarfExpr.addExpression(std::move(Cursor));971  }972  if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) {973    // cuda-gdb special requirement. See NVPTXAS::DWARF_AddressSpace.974    addUInt(VariableDie, dwarf::DW_AT_address_class, dwarf::DW_FORM_data1,975            NVPTXAddressSpace.value_or(NVPTXAS::DWARF_ADDR_local_space));976  }977  addBlock(VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());978  if (DwarfExpr.TagOffset)979    addUInt(VariableDie, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,980            *DwarfExpr.TagOffset);981}982 983void DwarfCompileUnit::applyConcreteDbgVariableAttributes(984    const Loc::EntryValue &EntryValue, const DbgVariable &DV,985    DIE &VariableDie) {986  DIELoc *Loc = new (DIEValueAllocator) DIELoc;987  DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);988  // Emit each expression as: EntryValue(Register) <other ops> <Fragment>.989  for (auto [Register, Expr] : EntryValue.EntryValues) {990    DwarfExpr.addFragmentOffset(&Expr);991    DIExpressionCursor Cursor(Expr.getElements());992    DwarfExpr.beginEntryValueExpression(Cursor);993    DwarfExpr.addMachineRegExpression(994        *Asm->MF->getSubtarget().getRegisterInfo(), Cursor, Register);995    DwarfExpr.addExpression(std::move(Cursor));996  }997  addBlock(VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());998}999 1000void DwarfCompileUnit::applyConcreteDbgVariableAttributes(1001    const std::monostate &, const DbgVariable &DV, DIE &VariableDie) {}1002 1003DIE *DwarfCompileUnit::constructVariableDIE(DbgVariable &DV,1004                                            const LexicalScope &Scope,1005                                            DIE *&ObjectPointer) {1006  auto Var = constructVariableDIE(DV, Scope.isAbstractScope());1007  if (DV.isObjectPointer())1008    ObjectPointer = Var;1009  return Var;1010}1011 1012DIE *DwarfCompileUnit::constructLabelDIE(DbgLabel &DL,1013                                         const LexicalScope &Scope) {1014  auto LabelDie = DIE::get(DIEValueAllocator, DL.getTag());1015  insertDIE(DL.getLabel(), LabelDie);1016  DL.setDIE(*LabelDie);1017 1018  if (Scope.isAbstractScope())1019    applyLabelAttributes(DL, *LabelDie);1020 1021  return LabelDie;1022}1023 1024/// Return all DIVariables that appear in count: expressions.1025static SmallVector<const DIVariable *, 2> dependencies(DbgVariable *Var) {1026  SmallVector<const DIVariable *, 2> Result;1027  auto *Array = dyn_cast<DICompositeType>(Var->getType());1028  if (!Array || Array->getTag() != dwarf::DW_TAG_array_type)1029    return Result;1030  if (auto *DLVar = Array->getDataLocation())1031    Result.push_back(DLVar);1032  if (auto *AsVar = Array->getAssociated())1033    Result.push_back(AsVar);1034  if (auto *AlVar = Array->getAllocated())1035    Result.push_back(AlVar);1036  for (auto *El : Array->getElements()) {1037    if (auto *Subrange = dyn_cast<DISubrange>(El)) {1038      if (auto Count = Subrange->getCount())1039        if (auto *Dependency = dyn_cast_if_present<DIVariable *>(Count))1040          Result.push_back(Dependency);1041      if (auto LB = Subrange->getLowerBound())1042        if (auto *Dependency = dyn_cast_if_present<DIVariable *>(LB))1043          Result.push_back(Dependency);1044      if (auto UB = Subrange->getUpperBound())1045        if (auto *Dependency = dyn_cast_if_present<DIVariable *>(UB))1046          Result.push_back(Dependency);1047      if (auto ST = Subrange->getStride())1048        if (auto *Dependency = dyn_cast_if_present<DIVariable *>(ST))1049          Result.push_back(Dependency);1050    } else if (auto *GenericSubrange = dyn_cast<DIGenericSubrange>(El)) {1051      if (auto Count = GenericSubrange->getCount())1052        if (auto *Dependency = dyn_cast_if_present<DIVariable *>(Count))1053          Result.push_back(Dependency);1054      if (auto LB = GenericSubrange->getLowerBound())1055        if (auto *Dependency = dyn_cast_if_present<DIVariable *>(LB))1056          Result.push_back(Dependency);1057      if (auto UB = GenericSubrange->getUpperBound())1058        if (auto *Dependency = dyn_cast_if_present<DIVariable *>(UB))1059          Result.push_back(Dependency);1060      if (auto ST = GenericSubrange->getStride())1061        if (auto *Dependency = dyn_cast_if_present<DIVariable *>(ST))1062          Result.push_back(Dependency);1063    }1064  }1065  return Result;1066}1067 1068/// Sort local variables so that variables appearing inside of helper1069/// expressions come first.1070static SmallVector<DbgVariable *, 8>1071sortLocalVars(SmallVectorImpl<DbgVariable *> &Input) {1072  SmallVector<DbgVariable *, 8> Result;1073  SmallVector<PointerIntPair<DbgVariable *, 1>, 8> WorkList;1074  // Map back from a DIVariable to its containing DbgVariable.1075  SmallDenseMap<const DILocalVariable *, DbgVariable *> DbgVar;1076  // Set of DbgVariables in Result.1077  SmallDenseSet<DbgVariable *, 8> Visited;1078  // For cycle detection.1079  SmallDenseSet<DbgVariable *, 8> Visiting;1080 1081  // Initialize the worklist and the DIVariable lookup table.1082  for (auto *Var : reverse(Input)) {1083    DbgVar.insert({Var->getVariable(), Var});1084    WorkList.push_back({Var, 0});1085  }1086 1087  // Perform a stable topological sort by doing a DFS.1088  while (!WorkList.empty()) {1089    auto Item = WorkList.back();1090    DbgVariable *Var = Item.getPointer();1091    bool visitedAllDependencies = Item.getInt();1092    WorkList.pop_back();1093 1094    assert(Var);1095 1096    // Already handled.1097    if (Visited.count(Var))1098      continue;1099 1100    // Add to Result if all dependencies are visited.1101    if (visitedAllDependencies) {1102      Visited.insert(Var);1103      Result.push_back(Var);1104      continue;1105    }1106 1107    // Detect cycles.1108    auto Res = Visiting.insert(Var);1109    if (!Res.second) {1110      assert(false && "dependency cycle in local variables");1111      return Result;1112    }1113 1114    // Push dependencies and this node onto the worklist, so that this node is1115    // visited again after all of its dependencies are handled.1116    WorkList.push_back({Var, 1});1117    for (const auto *Dependency : dependencies(Var)) {1118      // Don't add dependency if it is in a different lexical scope or a global.1119      if (const auto *Dep = dyn_cast<const DILocalVariable>(Dependency))1120        if (DbgVariable *Var = DbgVar.lookup(Dep))1121          WorkList.push_back({Var, 0});1122    }1123  }1124  return Result;1125}1126 1127DIE &DwarfCompileUnit::constructSubprogramScopeDIE(const DISubprogram *Sub,1128                                                   const Function &F,1129                                                   LexicalScope *Scope,1130                                                   MCSymbol *LineTableSym) {1131  DIE &ScopeDIE = updateSubprogramScopeDIE(Sub, F, LineTableSym);1132 1133  if (Scope) {1134    assert(!Scope->getInlinedAt());1135    assert(!Scope->isAbstractScope());1136    // Collect lexical scope children first.1137    // ObjectPointer might be a local (non-argument) local variable if it's a1138    // block's synthetic this pointer.1139    if (DIE *ObjectPointer = createAndAddScopeChildren(Scope, ScopeDIE))1140      addDIEEntry(ScopeDIE, dwarf::DW_AT_object_pointer, *ObjectPointer);1141  }1142 1143  // If this is a variadic function, add an unspecified parameter.1144  DITypeRefArray FnArgs = Sub->getType()->getTypeArray();1145 1146  // If we have a single element of null, it is a function that returns void.1147  // If we have more than one elements and the last one is null, it is a1148  // variadic function.1149  if (FnArgs.size() > 1 && !FnArgs[FnArgs.size() - 1] &&1150      !includeMinimalInlineScopes())1151    ScopeDIE.addChild(1152        DIE::get(DIEValueAllocator, dwarf::DW_TAG_unspecified_parameters));1153 1154  return ScopeDIE;1155}1156 1157DIE *DwarfCompileUnit::createAndAddScopeChildren(LexicalScope *Scope,1158                                                 DIE &ScopeDIE) {1159  DIE *ObjectPointer = nullptr;1160 1161  // Emit function arguments (order is significant).1162  auto Vars = DU->getScopeVariables().lookup(Scope);1163  for (auto &DV : Vars.Args)1164    ScopeDIE.addChild(constructVariableDIE(*DV.second, *Scope, ObjectPointer));1165 1166  // Emit local variables.1167  auto Locals = sortLocalVars(Vars.Locals);1168  for (DbgVariable *DV : Locals)1169    ScopeDIE.addChild(constructVariableDIE(*DV, *Scope, ObjectPointer));1170 1171  // Emit labels.1172  for (DbgLabel *DL : DU->getScopeLabels().lookup(Scope))1173    ScopeDIE.addChild(constructLabelDIE(*DL, *Scope));1174 1175  // Track other local entities (skipped in gmlt-like data).1176  // This creates mapping between CU and a set of local declarations that1177  // should be emitted for subprograms in this CU.1178  if (!includeMinimalInlineScopes() && !Scope->getInlinedAt()) {1179    auto &LocalDecls = DD->getLocalDeclsForScope(Scope->getScopeNode());1180    DeferredLocalDecls.insert_range(LocalDecls);1181  }1182 1183  // Emit inner lexical scopes.1184  auto skipLexicalScope = [this](LexicalScope *S) -> bool {1185    if (isa<DISubprogram>(S->getScopeNode()))1186      return false;1187    auto Vars = DU->getScopeVariables().lookup(S);1188    if (!Vars.Args.empty() || !Vars.Locals.empty())1189      return false;1190    return includeMinimalInlineScopes() ||1191           DD->getLocalDeclsForScope(S->getScopeNode()).empty();1192  };1193  for (LexicalScope *LS : Scope->getChildren()) {1194    // If the lexical block doesn't have non-scope children, skip1195    // its emission and put its children directly to the parent scope.1196    if (skipLexicalScope(LS))1197      createAndAddScopeChildren(LS, ScopeDIE);1198    else1199      constructScopeDIE(LS, ScopeDIE);1200  }1201 1202  return ObjectPointer;1203}1204 1205DIE &DwarfCompileUnit::getOrCreateAbstractSubprogramDIE(1206    const DISubprogram *SP) {1207  if (auto *AbsDef = getAbstractScopeDIEs().lookup(SP))1208    return *AbsDef;1209 1210  auto [ContextDIE, ContextCU] = getOrCreateAbstractSubprogramContextDIE(SP);1211  return createAbstractSubprogramDIE(SP, ContextDIE, ContextCU);1212}1213 1214DIE &DwarfCompileUnit::createAbstractSubprogramDIE(1215    const DISubprogram *SP, DIE *ContextDIE, DwarfCompileUnit *ContextCU) {1216  // Passing null as the associated node because the abstract definition1217  // shouldn't be found by lookup.1218  DIE &AbsDef = ContextCU->createAndAddDIE(dwarf::DW_TAG_subprogram,1219                                           *ContextDIE, nullptr);1220 1221  // Store the DIE before creating children.1222  ContextCU->getAbstractScopeDIEs()[SP] = &AbsDef;1223 1224  ContextCU->applySubprogramAttributesToDefinition(SP, AbsDef);1225  ContextCU->addSInt(AbsDef, dwarf::DW_AT_inline,1226                     DD->getDwarfVersion() <= 4 ? std::optional<dwarf::Form>()1227                                                : dwarf::DW_FORM_implicit_const,1228                     dwarf::DW_INL_inlined);1229 1230  return AbsDef;1231}1232 1233std::pair<DIE *, DwarfCompileUnit *>1234DwarfCompileUnit::getOrCreateAbstractSubprogramContextDIE(1235    const DISubprogram *SP) {1236  bool Minimal = includeMinimalInlineScopes();1237  bool IgnoreScope = shouldPlaceInUnitDIE(SP, Minimal);1238  DIE *ContextDIE = getOrCreateSubprogramContextDIE(SP, IgnoreScope);1239 1240  if (auto *SPDecl = SP->getDeclaration())1241    if (!Minimal)1242      getOrCreateSubprogramDIE(SPDecl, nullptr);1243 1244  // The scope may be shared with a subprogram that has already been1245  // constructed in another CU, in which case we need to construct this1246  // subprogram in the same CU.1247  auto *ContextCU = IgnoreScope ? this : DD->lookupCU(ContextDIE->getUnitDie());1248 1249  return std::make_pair(ContextDIE, ContextCU);1250}1251 1252void DwarfCompileUnit::constructAbstractSubprogramScopeDIE(1253    LexicalScope *Scope) {1254  auto *SP = cast<DISubprogram>(Scope->getScopeNode());1255 1256  // Populate subprogram DIE only once.1257  if (!getFinalizedAbstractSubprograms().insert(SP).second)1258    return;1259 1260  auto [ContextDIE, ContextCU] = getOrCreateAbstractSubprogramContextDIE(SP);1261  DIE *AbsDef = getAbstractScopeDIEs().lookup(SP);1262  if (!AbsDef)1263    AbsDef = &createAbstractSubprogramDIE(SP, ContextDIE, ContextCU);1264 1265  if (DIE *ObjectPointer = ContextCU->createAndAddScopeChildren(Scope, *AbsDef))1266    ContextCU->addDIEEntry(*AbsDef, dwarf::DW_AT_object_pointer,1267                           *ObjectPointer);1268}1269 1270bool DwarfCompileUnit::useGNUAnalogForDwarf5Feature() const {1271  return DD->getDwarfVersion() <= 4 && !DD->tuneForLLDB();1272}1273 1274dwarf::Tag DwarfCompileUnit::getDwarf5OrGNUTag(dwarf::Tag Tag) const {1275  if (!useGNUAnalogForDwarf5Feature())1276    return Tag;1277  switch (Tag) {1278  case dwarf::DW_TAG_call_site:1279    return dwarf::DW_TAG_GNU_call_site;1280  case dwarf::DW_TAG_call_site_parameter:1281    return dwarf::DW_TAG_GNU_call_site_parameter;1282  default:1283    llvm_unreachable("DWARF5 tag with no GNU analog");1284  }1285}1286 1287dwarf::Attribute1288DwarfCompileUnit::getDwarf5OrGNUAttr(dwarf::Attribute Attr) const {1289  if (!useGNUAnalogForDwarf5Feature())1290    return Attr;1291  switch (Attr) {1292  case dwarf::DW_AT_call_all_calls:1293    return dwarf::DW_AT_GNU_all_call_sites;1294  case dwarf::DW_AT_call_target:1295    return dwarf::DW_AT_GNU_call_site_target;1296  case dwarf::DW_AT_call_origin:1297    return dwarf::DW_AT_abstract_origin;1298  case dwarf::DW_AT_call_return_pc:1299    return dwarf::DW_AT_low_pc;1300  case dwarf::DW_AT_call_value:1301    return dwarf::DW_AT_GNU_call_site_value;1302  case dwarf::DW_AT_call_tail_call:1303    return dwarf::DW_AT_GNU_tail_call;1304  default:1305    llvm_unreachable("DWARF5 attribute with no GNU analog");1306  }1307}1308 1309dwarf::LocationAtom1310DwarfCompileUnit::getDwarf5OrGNULocationAtom(dwarf::LocationAtom Loc) const {1311  if (!useGNUAnalogForDwarf5Feature())1312    return Loc;1313  switch (Loc) {1314  case dwarf::DW_OP_entry_value:1315    return dwarf::DW_OP_GNU_entry_value;1316  default:1317    llvm_unreachable("DWARF5 location atom with no GNU analog");1318  }1319}1320 1321DIE &DwarfCompileUnit::constructCallSiteEntryDIE(1322    DIE &ScopeDIE, const DISubprogram *CalleeSP, const Function *CalleeF,1323    bool IsTail, const MCSymbol *PCAddr, const MCSymbol *CallAddr,1324    unsigned CallReg, DIType *AllocSiteTy) {1325  // Insert a call site entry DIE within ScopeDIE.1326  DIE &CallSiteDIE = createAndAddDIE(getDwarf5OrGNUTag(dwarf::DW_TAG_call_site),1327                                     ScopeDIE, nullptr);1328 1329  if (CallReg) {1330    // Indirect call.1331    addAddress(CallSiteDIE, getDwarf5OrGNUAttr(dwarf::DW_AT_call_target),1332               MachineLocation(CallReg));1333  } else if (CalleeSP) {1334    DIE *CalleeDIE = getOrCreateSubprogramDIE(CalleeSP, CalleeF);1335    assert(CalleeDIE && "Could not create DIE for call site entry origin");1336    if (AddLinkageNamesToDeclCallOriginsForTuning(DD) &&1337        !CalleeSP->isDefinition() &&1338        !CalleeDIE->findAttribute(dwarf::DW_AT_linkage_name)) {1339      addLinkageName(*CalleeDIE, CalleeSP->getLinkageName());1340    }1341 1342    addDIEEntry(CallSiteDIE, getDwarf5OrGNUAttr(dwarf::DW_AT_call_origin),1343                *CalleeDIE);1344  }1345 1346  if (IsTail) {1347    // Attach DW_AT_call_tail_call to tail calls for standards compliance.1348    addFlag(CallSiteDIE, getDwarf5OrGNUAttr(dwarf::DW_AT_call_tail_call));1349 1350    // Attach the address of the branch instruction to allow the debugger to1351    // show where the tail call occurred. This attribute has no GNU analog.1352    //1353    // GDB works backwards from non-standard usage of DW_AT_low_pc (in DWARF41354    // mode -- equivalently, in DWARF5 mode, DW_AT_call_return_pc) at tail-call1355    // site entries to figure out the PC of tail-calling branch instructions.1356    // This means it doesn't need the compiler to emit DW_AT_call_pc, so we1357    // don't emit it here.1358    //1359    // There's no need to tie non-GDB debuggers to this non-standardness, as it1360    // adds unnecessary complexity to the debugger. For non-GDB debuggers, emit1361    // the standard DW_AT_call_pc info.1362    if (!useGNUAnalogForDwarf5Feature())1363      addLabelAddress(CallSiteDIE, dwarf::DW_AT_call_pc, CallAddr);1364  }1365 1366  // Attach the return PC to allow the debugger to disambiguate call paths1367  // from one function to another.1368  //1369  // The return PC is only really needed when the call /isn't/ a tail call, but1370  // GDB expects it in DWARF4 mode, even for tail calls (see the comment above1371  // the DW_AT_call_pc emission logic for an explanation).1372  if (!IsTail || useGNUAnalogForDwarf5Feature()) {1373    assert(PCAddr && "Missing return PC information for a call");1374    addLabelAddress(CallSiteDIE,1375                    getDwarf5OrGNUAttr(dwarf::DW_AT_call_return_pc), PCAddr);1376  }1377 1378  if (AllocSiteTy)1379    addType(CallSiteDIE, AllocSiteTy, dwarf::DW_AT_LLVM_alloc_type);1380 1381  return CallSiteDIE;1382}1383 1384void DwarfCompileUnit::constructCallSiteParmEntryDIEs(1385    DIE &CallSiteDIE, SmallVector<DbgCallSiteParam, 4> &Params) {1386  for (const auto &Param : Params) {1387    unsigned Register = Param.getRegister();1388    auto CallSiteDieParam =1389        DIE::get(DIEValueAllocator,1390                 getDwarf5OrGNUTag(dwarf::DW_TAG_call_site_parameter));1391    insertDIE(CallSiteDieParam);1392    addAddress(*CallSiteDieParam, dwarf::DW_AT_location,1393               MachineLocation(Register));1394 1395    DIELoc *Loc = new (DIEValueAllocator) DIELoc;1396    DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);1397    DwarfExpr.setCallSiteParamValueFlag();1398 1399    DwarfDebug::emitDebugLocValue(*Asm, nullptr, Param.getValue(), DwarfExpr);1400 1401    addBlock(*CallSiteDieParam, getDwarf5OrGNUAttr(dwarf::DW_AT_call_value),1402             DwarfExpr.finalize());1403 1404    CallSiteDIE.addChild(CallSiteDieParam);1405  }1406}1407 1408DIE *DwarfCompileUnit::constructImportedEntityDIE(1409    const DIImportedEntity *Module) {1410  DIE *IMDie = DIE::get(DIEValueAllocator, Module->getTag());1411  insertDIE(Module, IMDie);1412  DIE *EntityDie;1413  auto *Entity = Module->getEntity();1414  if (auto *NS = dyn_cast<DINamespace>(Entity))1415    EntityDie = getOrCreateNameSpace(NS);1416  else if (auto *M = dyn_cast<DIModule>(Entity))1417    EntityDie = getOrCreateModule(M);1418  else if (auto *SP = dyn_cast<DISubprogram>(Entity)) {1419    // If there is an abstract subprogram, refer to it. Note that this assumes1420    // that all the abstract subprograms have been already created (which is1421    // correct until imported entities get emitted in DwarfDebug::endModule()).1422    if (auto *AbsSPDie = getAbstractScopeDIEs().lookup(SP))1423      EntityDie = AbsSPDie;1424    else1425      EntityDie = getOrCreateSubprogramDIE(SP, nullptr);1426  } else if (auto *T = dyn_cast<DIType>(Entity))1427    EntityDie = getOrCreateTypeDIE(T);1428  else if (auto *GV = dyn_cast<DIGlobalVariable>(Entity))1429    EntityDie = getOrCreateGlobalVariableDIE(GV, {});1430  else if (auto *IE = dyn_cast<DIImportedEntity>(Entity))1431    EntityDie = getOrCreateImportedEntityDIE(IE);1432  else1433    EntityDie = getDIE(Entity);1434  assert(EntityDie);1435  addSourceLine(*IMDie, Module->getLine(), /*Column*/ 0, Module->getFile());1436  addDIEEntry(*IMDie, dwarf::DW_AT_import, *EntityDie);1437  StringRef Name = Module->getName();1438  if (!Name.empty()) {1439    addString(*IMDie, dwarf::DW_AT_name, Name);1440 1441    // FIXME: if consumers ever start caring about handling1442    // unnamed import declarations such as `using ::nullptr_t`1443    // or `using namespace std::ranges`, we could add the1444    // import declaration into the accelerator table with the1445    // name being the one of the entity being imported.1446    DD->addAccelNamespace(*this, CUNode->getNameTableKind(), Name, *IMDie);1447  }1448 1449  // This is for imported module with renamed entities (such as variables and1450  // subprograms).1451  DINodeArray Elements = Module->getElements();1452  for (const auto *Element : Elements) {1453    if (!Element)1454      continue;1455    IMDie->addChild(1456        constructImportedEntityDIE(cast<DIImportedEntity>(Element)));1457  }1458 1459  return IMDie;1460}1461 1462DIE *DwarfCompileUnit::getOrCreateImportedEntityDIE(1463    const DIImportedEntity *IE) {1464 1465  // Check for pre-existence.1466  if (DIE *Die = getDIE(IE))1467    return Die;1468 1469  DIE *ContextDIE = getOrCreateContextDIE(IE->getScope());1470  assert(ContextDIE && "Empty scope for the imported entity!");1471 1472  DIE *IMDie = constructImportedEntityDIE(IE);1473  ContextDIE->addChild(IMDie);1474  return IMDie;1475}1476 1477void DwarfCompileUnit::finishSubprogramDefinition(const DISubprogram *SP) {1478  DIE *D = getDIE(SP);1479  if (DIE *AbsSPDIE = getAbstractScopeDIEs().lookup(SP)) {1480    if (D)1481      // If this subprogram has an abstract definition, reference that1482      addDIEEntry(*D, dwarf::DW_AT_abstract_origin, *AbsSPDIE);1483  } else {1484    assert(D || includeMinimalInlineScopes());1485    if (D)1486      // And attach the attributes1487      applySubprogramAttributesToDefinition(SP, *D);1488  }1489}1490 1491void DwarfCompileUnit::finishEntityDefinition(const DbgEntity *Entity) {1492  DbgEntity *AbsEntity = getExistingAbstractEntity(Entity->getEntity());1493 1494  auto *Die = Entity->getDIE();1495  /// Label may be used to generate DW_AT_low_pc, so put it outside1496  /// if/else block.1497  const DbgLabel *Label = nullptr;1498  if (AbsEntity && AbsEntity->getDIE()) {1499    addDIEEntry(*Die, dwarf::DW_AT_abstract_origin, *AbsEntity->getDIE());1500    Label = dyn_cast<const DbgLabel>(Entity);1501  } else {1502    if (const DbgVariable *Var = dyn_cast<const DbgVariable>(Entity))1503      applyCommonDbgVariableAttributes(*Var, *Die);1504    else if ((Label = dyn_cast<const DbgLabel>(Entity)))1505      applyLabelAttributes(*Label, *Die);1506    else1507      llvm_unreachable("DbgEntity must be DbgVariable or DbgLabel.");1508  }1509 1510  if (!Label)1511    return;1512 1513  const auto *Sym = Label->getSymbol();1514  if (!Sym)1515    return;1516 1517  addLabelAddress(*Die, dwarf::DW_AT_low_pc, Sym);1518 1519  // A TAG_label with a name and an AT_low_pc must be placed in debug_names.1520  if (StringRef Name = Label->getName(); !Name.empty())1521    getDwarfDebug().addAccelName(*this, CUNode->getNameTableKind(), Name, *Die);1522}1523 1524void DwarfCompileUnit::attachLexicalScopesAbstractOrigins() {1525  auto AttachAO = [&](const DILocalScope *LS, DIE *ScopeDIE) {1526    if (auto *AbsLSDie = getAbstractScopeDIEs().lookup(LS))1527      addDIEEntry(*ScopeDIE, dwarf::DW_AT_abstract_origin, *AbsLSDie);1528  };1529 1530  for (auto [LScope, ScopeDIE] : LexicalBlockDIEs)1531    AttachAO(LScope, ScopeDIE);1532  for (auto &[LScope, ScopeDIEs] : InlinedLocalScopeDIEs)1533    for (auto *ScopeDIE : ScopeDIEs)1534      AttachAO(LScope, ScopeDIE);1535}1536 1537DbgEntity *DwarfCompileUnit::getExistingAbstractEntity(const DINode *Node) {1538  auto &AbstractEntities = getAbstractEntities();1539  auto I = AbstractEntities.find(Node);1540  if (I != AbstractEntities.end())1541    return I->second.get();1542  return nullptr;1543}1544 1545void DwarfCompileUnit::createAbstractEntity(const DINode *Node,1546                                            LexicalScope *Scope) {1547  assert(Scope && Scope->isAbstractScope());1548  auto &Entity = getAbstractEntities()[Node];1549  if (isa<const DILocalVariable>(Node)) {1550    Entity = std::make_unique<DbgVariable>(cast<const DILocalVariable>(Node),1551                                           nullptr /* IA */);1552    DU->addScopeVariable(Scope, cast<DbgVariable>(Entity.get()));1553  } else if (isa<const DILabel>(Node)) {1554    Entity = std::make_unique<DbgLabel>(1555                        cast<const DILabel>(Node), nullptr /* IA */);1556    DU->addScopeLabel(Scope, cast<DbgLabel>(Entity.get()));1557  }1558}1559 1560void DwarfCompileUnit::emitHeader(bool UseOffsets) {1561  // Don't bother labeling the .dwo unit, as its offset isn't used.1562  if (!Skeleton && !DD->useSectionsAsReferences()) {1563    LabelBegin = Asm->createTempSymbol("cu_begin");1564    Asm->OutStreamer->emitLabel(LabelBegin);1565  }1566 1567  dwarf::UnitType UT = Skeleton ? dwarf::DW_UT_split_compile1568                                : DD->useSplitDwarf() ? dwarf::DW_UT_skeleton1569                                                      : dwarf::DW_UT_compile;1570  DwarfUnit::emitCommonHeader(UseOffsets, UT);1571  if (DD->getDwarfVersion() >= 5 && UT != dwarf::DW_UT_compile)1572    Asm->emitInt64(getDWOId());1573}1574 1575bool DwarfCompileUnit::hasDwarfPubSections() const {1576  switch (CUNode->getNameTableKind()) {1577  case DICompileUnit::DebugNameTableKind::None:1578    return false;1579    // Opting in to GNU Pubnames/types overrides the default to ensure these are1580    // generated for things like Gold's gdb_index generation.1581  case DICompileUnit::DebugNameTableKind::GNU:1582    return true;1583  case DICompileUnit::DebugNameTableKind::Apple:1584    return false;1585  case DICompileUnit::DebugNameTableKind::Default:1586    return DD->tuneForGDB() && !includeMinimalInlineScopes() &&1587           !CUNode->isDebugDirectivesOnly() &&1588           DD->getAccelTableKind() != AccelTableKind::Apple &&1589           DD->getDwarfVersion() < 5;1590  }1591  llvm_unreachable("Unhandled DICompileUnit::DebugNameTableKind enum");1592}1593 1594/// addGlobalName - Add a new global name to the compile unit.1595void DwarfCompileUnit::addGlobalName(StringRef Name, const DIE &Die,1596                                     const DIScope *Context) {1597  if (!hasDwarfPubSections())1598    return;1599  std::string FullName = getParentContextString(Context) + Name.str();1600  GlobalNames[FullName] = &Die;1601}1602 1603void DwarfCompileUnit::addGlobalNameForTypeUnit(StringRef Name,1604                                                const DIScope *Context) {1605  if (!hasDwarfPubSections())1606    return;1607  std::string FullName = getParentContextString(Context) + Name.str();1608  // Insert, allowing the entry to remain as-is if it's already present1609  // This way the CU-level type DIE is preferred over the "can't describe this1610  // type as a unit offset because it's not really in the CU at all, it's only1611  // in a type unit"1612  GlobalNames.insert(std::make_pair(std::move(FullName), &getUnitDie()));1613}1614 1615/// Add a new global type to the unit.1616void DwarfCompileUnit::addGlobalTypeImpl(const DIType *Ty, const DIE &Die,1617                                         const DIScope *Context) {1618  if (!hasDwarfPubSections())1619    return;1620  std::string FullName = getParentContextString(Context) + Ty->getName().str();1621  GlobalTypes[FullName] = &Die;1622}1623 1624void DwarfCompileUnit::addGlobalTypeUnitType(const DIType *Ty,1625                                             const DIScope *Context) {1626  if (!hasDwarfPubSections())1627    return;1628  std::string FullName = getParentContextString(Context) + Ty->getName().str();1629  // Insert, allowing the entry to remain as-is if it's already present1630  // This way the CU-level type DIE is preferred over the "can't describe this1631  // type as a unit offset because it's not really in the CU at all, it's only1632  // in a type unit"1633  GlobalTypes.insert(std::make_pair(std::move(FullName), &getUnitDie()));1634}1635 1636void DwarfCompileUnit::addVariableAddress(const DbgVariable &DV, DIE &Die,1637                                          MachineLocation Location) {1638  auto *Single = std::get_if<Loc::Single>(&DV);1639  if (Single && Single->getExpr())1640    addComplexAddress(Single->getExpr(), Die, dwarf::DW_AT_location, Location);1641  else1642    addAddress(Die, dwarf::DW_AT_location, Location);1643}1644 1645/// Add an address attribute to a die based on the location provided.1646void DwarfCompileUnit::addAddress(DIE &Die, dwarf::Attribute Attribute,1647                                  const MachineLocation &Location) {1648  DIELoc *Loc = new (DIEValueAllocator) DIELoc;1649  DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);1650  if (Location.isIndirect())1651    DwarfExpr.setMemoryLocationKind();1652 1653  DIExpressionCursor Cursor({});1654  const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();1655  if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))1656    return;1657  DwarfExpr.addExpression(std::move(Cursor));1658 1659  // Now attach the location information to the DIE.1660  addBlock(Die, Attribute, DwarfExpr.finalize());1661 1662  if (DwarfExpr.TagOffset)1663    addUInt(Die, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,1664            *DwarfExpr.TagOffset);1665}1666 1667/// Start with the address based on the location provided, and generate the1668/// DWARF information necessary to find the actual variable given the extra1669/// address information encoded in the DbgVariable, starting from the starting1670/// location.  Add the DWARF information to the die.1671void DwarfCompileUnit::addComplexAddress(const DIExpression *DIExpr, DIE &Die,1672                                         dwarf::Attribute Attribute,1673                                         const MachineLocation &Location) {1674  DIELoc *Loc = new (DIEValueAllocator) DIELoc;1675  DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);1676  DwarfExpr.addFragmentOffset(DIExpr);1677  DwarfExpr.setLocation(Location, DIExpr);1678 1679  DIExpressionCursor Cursor(DIExpr);1680 1681  if (DIExpr->isEntryValue())1682    DwarfExpr.beginEntryValueExpression(Cursor);1683 1684  const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();1685  if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))1686    return;1687  DwarfExpr.addExpression(std::move(Cursor));1688 1689  // Now attach the location information to the DIE.1690  addBlock(Die, Attribute, DwarfExpr.finalize());1691 1692  if (DwarfExpr.TagOffset)1693    addUInt(Die, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,1694            *DwarfExpr.TagOffset);1695}1696 1697/// Add a Dwarf loclistptr attribute data and value.1698void DwarfCompileUnit::addLocationList(DIE &Die, dwarf::Attribute Attribute,1699                                       unsigned Index) {1700  dwarf::Form Form = (DD->getDwarfVersion() >= 5)1701                         ? dwarf::DW_FORM_loclistx1702                         : DD->getDwarfSectionOffsetForm();1703  addAttribute(Die, Attribute, Form, DIELocList(Index));1704}1705 1706void DwarfCompileUnit::applyCommonDbgVariableAttributes(const DbgVariable &Var,1707                                                        DIE &VariableDie) {1708  StringRef Name = Var.getName();1709  if (!Name.empty())1710    addString(VariableDie, dwarf::DW_AT_name, Name);1711  const auto *DIVar = Var.getVariable();1712  if (DIVar) {1713    if (uint32_t AlignInBytes = DIVar->getAlignInBytes())1714      addUInt(VariableDie, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,1715              AlignInBytes);1716    addAnnotation(VariableDie, DIVar->getAnnotations());1717  }1718 1719  addSourceLine(VariableDie, DIVar);1720  addType(VariableDie, Var.getType());1721  if (Var.isArtificial())1722    addFlag(VariableDie, dwarf::DW_AT_artificial);1723}1724 1725void DwarfCompileUnit::applyLabelAttributes(const DbgLabel &Label,1726                                            DIE &LabelDie) {1727  StringRef Name = Label.getName();1728  if (!Name.empty())1729    addString(LabelDie, dwarf::DW_AT_name, Name);1730  const auto *DILabel = Label.getLabel();1731  addSourceLine(LabelDie, DILabel);1732  if (DILabel->isArtificial())1733    addFlag(LabelDie, dwarf::DW_AT_artificial);1734  if (DILabel->getCoroSuspendIdx())1735    addUInt(LabelDie, dwarf::DW_AT_LLVM_coro_suspend_idx, std::nullopt,1736            *DILabel->getCoroSuspendIdx());1737}1738 1739/// Add a Dwarf expression attribute data and value.1740void DwarfCompileUnit::addExpr(DIELoc &Die, dwarf::Form Form,1741                               const MCExpr *Expr) {1742  addAttribute(Die, (dwarf::Attribute)0, Form, DIEExpr(Expr));1743}1744 1745void DwarfCompileUnit::applySubprogramAttributesToDefinition(1746    const DISubprogram *SP, DIE &SPDie) {1747  auto *SPDecl = SP->getDeclaration();1748  auto *Context = SPDecl ? SPDecl->getScope() : SP->getScope();1749  applySubprogramAttributes(SP, SPDie, includeMinimalInlineScopes());1750  addGlobalName(SP->getName(), SPDie, Context);1751}1752 1753bool DwarfCompileUnit::isDwoUnit() const {1754  return DD->useSplitDwarf() && Skeleton;1755}1756 1757void DwarfCompileUnit::finishNonUnitTypeDIE(DIE& D, const DICompositeType *CTy) {1758  constructTypeDIE(D, CTy);1759}1760 1761bool DwarfCompileUnit::includeMinimalInlineScopes() const {1762  return getCUNode()->getEmissionKind() == DICompileUnit::LineTablesOnly ||1763         (DD->useSplitDwarf() && !Skeleton);1764}1765 1766bool DwarfCompileUnit::emitFuncLineTableOffsets() const {1767  return EmitFuncLineTableOffsetsOption;1768}1769 1770void DwarfCompileUnit::addAddrTableBase() {1771  const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();1772  MCSymbol *Label = DD->getAddressPool().getLabel();1773  addSectionLabel(getUnitDie(),1774                  DD->getDwarfVersion() >= 5 ? dwarf::DW_AT_addr_base1775                                             : dwarf::DW_AT_GNU_addr_base,1776                  Label, TLOF.getDwarfAddrSection()->getBeginSymbol());1777}1778 1779void DwarfCompileUnit::addBaseTypeRef(DIEValueList &Die, int64_t Idx) {1780  addAttribute(Die, (dwarf::Attribute)0, dwarf::DW_FORM_udata,1781               new (DIEValueAllocator) DIEBaseTypeRef(this, Idx));1782}1783 1784void DwarfCompileUnit::createBaseTypeDIEs() {1785  // Insert the base_type DIEs directly after the CU so that their offsets will1786  // fit in the fixed size ULEB128 used inside the location expressions.1787  // Maintain order by iterating backwards and inserting to the front of CU1788  // child list.1789  for (auto &Btr : reverse(ExprRefedBaseTypes)) {1790    DIE &Die = getUnitDie().addChildFront(1791      DIE::get(DIEValueAllocator, dwarf::DW_TAG_base_type));1792    SmallString<32> Str;1793    addString(Die, dwarf::DW_AT_name,1794              Twine(dwarf::AttributeEncodingString(Btr.Encoding) +1795                    "_" + Twine(Btr.BitSize)).toStringRef(Str));1796    addUInt(Die, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, Btr.Encoding);1797    // Round up to smallest number of bytes that contains this number of bits.1798    // ExprRefedBaseTypes is populated with types referenced by1799    // DW_OP_LLVM_convert operations in location expressions. These are often1800    // byte-sized, but one common counter-example is 1-bit sized conversions1801    // from `i1` types. TODO: Should these use DW_AT_bit_size? See1802    // DwarfUnit::constructTypeDIE.1803    addUInt(Die, dwarf::DW_AT_byte_size, std::nullopt,1804            divideCeil(Btr.BitSize, 8));1805    Btr.Die = &Die;1806  }1807}1808 1809DIE *DwarfCompileUnit::getLexicalBlockDIE(const DILexicalBlock *LB) {1810  // Assume if there is an abstract tree all the DIEs are already emitted.1811  bool isAbstract = getAbstractScopeDIEs().count(LB->getSubprogram());1812  if (isAbstract) {1813    auto &DIEs = getAbstractScopeDIEs();1814    if (auto It = DIEs.find(LB); It != DIEs.end())1815      return It->second;1816  }1817  assert(!isAbstract && "Missed lexical block DIE in abstract tree!");1818 1819  // Return a concrete DIE if it exists or nullptr otherwise.1820  return LexicalBlockDIEs.lookup(LB);1821}1822 1823DIE *DwarfCompileUnit::getOrCreateContextDIE(const DIScope *Context) {1824  if (isa_and_nonnull<DILocalScope>(Context)) {1825    if (auto *LFScope = dyn_cast<DILexicalBlockFile>(Context))1826      Context = LFScope->getNonLexicalBlockFileScope();1827    if (auto *LScope = dyn_cast<DILexicalBlock>(Context))1828      return getLexicalBlockDIE(LScope);1829 1830    // Otherwise the context must be a DISubprogram.1831    auto *SPScope = cast<DISubprogram>(Context);1832    const auto &DIEs = getAbstractScopeDIEs();1833    if (auto It = DIEs.find(SPScope); It != DIEs.end())1834      return It->second;1835  }1836  return DwarfUnit::getOrCreateContextDIE(Context);1837}1838 1839DIE *DwarfCompileUnit::getOrCreateSubprogramDIE(const DISubprogram *SP,1840                                                const Function *F,1841                                                bool Minimal) {1842  if (!F && SP->isDefinition()) {1843    F = DD->getLexicalScopes().getFunction(SP);1844 1845    if (!F) {1846      // SP may belong to another CU. Determine the CU similarly1847      // to DwarfDebug::constructAbstractSubprogramScopeDIE.1848      return &DD->getOrCreateAbstractSubprogramCU(SP, *this)1849                  .getOrCreateAbstractSubprogramDIE(SP);1850    }1851  }1852 1853  return DwarfUnit::getOrCreateSubprogramDIE(SP, F, Minimal);1854}1855