xref: /openbsd-src/gnu/llvm/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp (revision d415bd752c734aee168c4ee86ff32e8cc249eb16)
109467b48Spatrick //===- llvm/CodeGen/DwarfCompileUnit.cpp - Dwarf Compile Units ------------===//
209467b48Spatrick //
309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick //
709467b48Spatrick //===----------------------------------------------------------------------===//
809467b48Spatrick //
909467b48Spatrick // This file contains support for constructing a dwarf compile unit.
1009467b48Spatrick //
1109467b48Spatrick //===----------------------------------------------------------------------===//
1209467b48Spatrick 
1309467b48Spatrick #include "DwarfCompileUnit.h"
1409467b48Spatrick #include "AddressPool.h"
1509467b48Spatrick #include "DwarfExpression.h"
1609467b48Spatrick #include "llvm/ADT/STLExtras.h"
1709467b48Spatrick #include "llvm/ADT/SmallString.h"
1809467b48Spatrick #include "llvm/BinaryFormat/Dwarf.h"
1909467b48Spatrick #include "llvm/CodeGen/AsmPrinter.h"
2009467b48Spatrick #include "llvm/CodeGen/DIE.h"
2109467b48Spatrick #include "llvm/CodeGen/MachineFunction.h"
2209467b48Spatrick #include "llvm/CodeGen/MachineInstr.h"
2309467b48Spatrick #include "llvm/CodeGen/TargetFrameLowering.h"
2409467b48Spatrick #include "llvm/CodeGen/TargetRegisterInfo.h"
2509467b48Spatrick #include "llvm/CodeGen/TargetSubtargetInfo.h"
2609467b48Spatrick #include "llvm/IR/DataLayout.h"
2709467b48Spatrick #include "llvm/IR/DebugInfo.h"
2809467b48Spatrick #include "llvm/IR/GlobalVariable.h"
2909467b48Spatrick #include "llvm/MC/MCSection.h"
3009467b48Spatrick #include "llvm/MC/MCStreamer.h"
3109467b48Spatrick #include "llvm/MC/MCSymbol.h"
32097a140dSpatrick #include "llvm/MC/MCSymbolWasm.h"
3309467b48Spatrick #include "llvm/MC/MachineLocation.h"
3409467b48Spatrick #include "llvm/Target/TargetLoweringObjectFile.h"
3509467b48Spatrick #include "llvm/Target/TargetMachine.h"
3609467b48Spatrick #include "llvm/Target/TargetOptions.h"
3709467b48Spatrick #include <iterator>
38*d415bd75Srobert #include <optional>
3909467b48Spatrick #include <string>
4009467b48Spatrick #include <utility>
4109467b48Spatrick 
4209467b48Spatrick using namespace llvm;
4309467b48Spatrick 
GetCompileUnitType(UnitKind Kind,DwarfDebug * DW)4409467b48Spatrick static dwarf::Tag GetCompileUnitType(UnitKind Kind, DwarfDebug *DW) {
4509467b48Spatrick 
4609467b48Spatrick   //  According to DWARF Debugging Information Format Version 5,
4709467b48Spatrick   //  3.1.2 Skeleton Compilation Unit Entries:
4809467b48Spatrick   //  "When generating a split DWARF object file (see Section 7.3.2
4909467b48Spatrick   //  on page 187), the compilation unit in the .debug_info section
5009467b48Spatrick   //  is a "skeleton" compilation unit with the tag DW_TAG_skeleton_unit"
5109467b48Spatrick   if (DW->getDwarfVersion() >= 5 && Kind == UnitKind::Skeleton)
5209467b48Spatrick     return dwarf::DW_TAG_skeleton_unit;
5309467b48Spatrick 
5409467b48Spatrick   return dwarf::DW_TAG_compile_unit;
5509467b48Spatrick }
5609467b48Spatrick 
DwarfCompileUnit(unsigned UID,const DICompileUnit * Node,AsmPrinter * A,DwarfDebug * DW,DwarfFile * DWU,UnitKind Kind)5709467b48Spatrick DwarfCompileUnit::DwarfCompileUnit(unsigned UID, const DICompileUnit *Node,
5809467b48Spatrick                                    AsmPrinter *A, DwarfDebug *DW,
5909467b48Spatrick                                    DwarfFile *DWU, UnitKind Kind)
6009467b48Spatrick     : DwarfUnit(GetCompileUnitType(Kind, DW), Node, A, DW, DWU), UniqueID(UID) {
6109467b48Spatrick   insertDIE(Node, &getUnitDie());
6209467b48Spatrick   MacroLabelBegin = Asm->createTempSymbol("cu_macro_begin");
6309467b48Spatrick }
6409467b48Spatrick 
6509467b48Spatrick /// addLabelAddress - Add a dwarf label attribute data and value using
6609467b48Spatrick /// DW_FORM_addr or DW_FORM_GNU_addr_index.
addLabelAddress(DIE & Die,dwarf::Attribute Attribute,const MCSymbol * Label)6709467b48Spatrick void DwarfCompileUnit::addLabelAddress(DIE &Die, dwarf::Attribute Attribute,
6809467b48Spatrick                                        const MCSymbol *Label) {
69*d415bd75Srobert   if ((Skeleton || !DD->useSplitDwarf()) && Label)
70*d415bd75Srobert     DD->addArangeLabel(SymbolCU(this, Label));
71*d415bd75Srobert 
7209467b48Spatrick   // Don't use the address pool in non-fission or in the skeleton unit itself.
7309467b48Spatrick   if ((!DD->useSplitDwarf() || !Skeleton) && DD->getDwarfVersion() < 5)
7409467b48Spatrick     return addLocalLabelAddress(Die, Attribute, Label);
7509467b48Spatrick 
7673471bf0Spatrick   bool UseAddrOffsetFormOrExpressions =
7773471bf0Spatrick       DD->useAddrOffsetForm() || DD->useAddrOffsetExpressions();
7873471bf0Spatrick 
7973471bf0Spatrick   const MCSymbol *Base = nullptr;
8073471bf0Spatrick   if (Label->isInSection() && UseAddrOffsetFormOrExpressions)
8173471bf0Spatrick     Base = DD->getSectionLabel(&Label->getSection());
8273471bf0Spatrick 
8373471bf0Spatrick   if (!Base || Base == Label) {
8409467b48Spatrick     unsigned idx = DD->getAddressPool().getIndex(Label);
8573471bf0Spatrick     addAttribute(Die, Attribute,
8609467b48Spatrick                  DD->getDwarfVersion() >= 5 ? dwarf::DW_FORM_addrx
8709467b48Spatrick                                             : dwarf::DW_FORM_GNU_addr_index,
8809467b48Spatrick                  DIEInteger(idx));
8973471bf0Spatrick     return;
9073471bf0Spatrick   }
9173471bf0Spatrick 
9273471bf0Spatrick   // Could be extended to work with DWARFv4 Split DWARF if that's important for
9373471bf0Spatrick   // someone. In that case DW_FORM_data would be used.
9473471bf0Spatrick   assert(DD->getDwarfVersion() >= 5 &&
9573471bf0Spatrick          "Addr+offset expressions are only valuable when using debug_addr (to "
9673471bf0Spatrick          "reduce relocations) available in DWARFv5 or higher");
9773471bf0Spatrick   if (DD->useAddrOffsetExpressions()) {
9873471bf0Spatrick     auto *Loc = new (DIEValueAllocator) DIEBlock();
9973471bf0Spatrick     addPoolOpAddress(*Loc, Label);
10073471bf0Spatrick     addBlock(Die, Attribute, dwarf::DW_FORM_exprloc, Loc);
10173471bf0Spatrick   } else
10273471bf0Spatrick     addAttribute(Die, Attribute, dwarf::DW_FORM_LLVM_addrx_offset,
10373471bf0Spatrick                  new (DIEValueAllocator) DIEAddrOffset(
10473471bf0Spatrick                      DD->getAddressPool().getIndex(Base), Label, Base));
10509467b48Spatrick }
10609467b48Spatrick 
addLocalLabelAddress(DIE & Die,dwarf::Attribute Attribute,const MCSymbol * Label)10709467b48Spatrick void DwarfCompileUnit::addLocalLabelAddress(DIE &Die,
10809467b48Spatrick                                             dwarf::Attribute Attribute,
10909467b48Spatrick                                             const MCSymbol *Label) {
11009467b48Spatrick   if (Label)
11173471bf0Spatrick     addAttribute(Die, Attribute, dwarf::DW_FORM_addr, DIELabel(Label));
11209467b48Spatrick   else
11373471bf0Spatrick     addAttribute(Die, Attribute, dwarf::DW_FORM_addr, DIEInteger(0));
11409467b48Spatrick }
11509467b48Spatrick 
getOrCreateSourceID(const DIFile * File)11609467b48Spatrick unsigned DwarfCompileUnit::getOrCreateSourceID(const DIFile *File) {
11709467b48Spatrick   // If we print assembly, we can't separate .file entries according to
11809467b48Spatrick   // compile units. Thus all files will belong to the default compile unit.
11909467b48Spatrick 
12009467b48Spatrick   // FIXME: add a better feature test than hasRawTextSupport. Even better,
12109467b48Spatrick   // extend .file to support this.
12209467b48Spatrick   unsigned CUID = Asm->OutStreamer->hasRawTextSupport() ? 0 : getUniqueID();
12309467b48Spatrick   if (!File)
124*d415bd75Srobert     return Asm->OutStreamer->emitDwarfFileDirective(0, "", "", std::nullopt,
125*d415bd75Srobert                                                     std::nullopt, CUID);
126*d415bd75Srobert 
127*d415bd75Srobert   if (LastFile != File) {
128*d415bd75Srobert     LastFile = File;
129*d415bd75Srobert     LastFileID = Asm->OutStreamer->emitDwarfFileDirective(
13073471bf0Spatrick         0, File->getDirectory(), File->getFilename(), DD->getMD5AsBytes(File),
13109467b48Spatrick         File->getSource(), CUID);
13209467b48Spatrick   }
133*d415bd75Srobert   return LastFileID;
134*d415bd75Srobert }
13509467b48Spatrick 
getOrCreateGlobalVariableDIE(const DIGlobalVariable * GV,ArrayRef<GlobalExpr> GlobalExprs)13609467b48Spatrick DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE(
13709467b48Spatrick     const DIGlobalVariable *GV, ArrayRef<GlobalExpr> GlobalExprs) {
13809467b48Spatrick   // Check for pre-existence.
13909467b48Spatrick   if (DIE *Die = getDIE(GV))
14009467b48Spatrick     return Die;
14109467b48Spatrick 
14209467b48Spatrick   assert(GV);
14309467b48Spatrick 
14409467b48Spatrick   auto *GVContext = GV->getScope();
14509467b48Spatrick   const DIType *GTy = GV->getType();
14609467b48Spatrick 
14709467b48Spatrick   auto *CB = GVContext ? dyn_cast<DICommonBlock>(GVContext) : nullptr;
14809467b48Spatrick   DIE *ContextDIE = CB ? getOrCreateCommonBlock(CB, GlobalExprs)
14909467b48Spatrick     : getOrCreateContextDIE(GVContext);
15009467b48Spatrick 
15109467b48Spatrick   // Add to map.
15209467b48Spatrick   DIE *VariableDIE = &createAndAddDIE(GV->getTag(), *ContextDIE, GV);
15309467b48Spatrick   DIScope *DeclContext;
15409467b48Spatrick   if (auto *SDMDecl = GV->getStaticDataMemberDeclaration()) {
15509467b48Spatrick     DeclContext = SDMDecl->getScope();
15609467b48Spatrick     assert(SDMDecl->isStaticMember() && "Expected static member decl");
15709467b48Spatrick     assert(GV->isDefinition());
15809467b48Spatrick     // We need the declaration DIE that is in the static member's class.
15909467b48Spatrick     DIE *VariableSpecDIE = getOrCreateStaticMemberDIE(SDMDecl);
16009467b48Spatrick     addDIEEntry(*VariableDIE, dwarf::DW_AT_specification, *VariableSpecDIE);
16109467b48Spatrick     // If the global variable's type is different from the one in the class
16209467b48Spatrick     // member type, assume that it's more specific and also emit it.
16309467b48Spatrick     if (GTy != SDMDecl->getBaseType())
16409467b48Spatrick       addType(*VariableDIE, GTy);
16509467b48Spatrick   } else {
16609467b48Spatrick     DeclContext = GV->getScope();
16709467b48Spatrick     // Add name and type.
168*d415bd75Srobert     StringRef DisplayName = GV->getDisplayName();
169*d415bd75Srobert     if (!DisplayName.empty())
17009467b48Spatrick       addString(*VariableDIE, dwarf::DW_AT_name, GV->getDisplayName());
171097a140dSpatrick     if (GTy)
17209467b48Spatrick       addType(*VariableDIE, GTy);
17309467b48Spatrick 
17409467b48Spatrick     // Add scoping info.
17509467b48Spatrick     if (!GV->isLocalToUnit())
17609467b48Spatrick       addFlag(*VariableDIE, dwarf::DW_AT_external);
17709467b48Spatrick 
17809467b48Spatrick     // Add line number info.
17909467b48Spatrick     addSourceLine(*VariableDIE, GV);
18009467b48Spatrick   }
18109467b48Spatrick 
18209467b48Spatrick   if (!GV->isDefinition())
18309467b48Spatrick     addFlag(*VariableDIE, dwarf::DW_AT_declaration);
18409467b48Spatrick   else
18509467b48Spatrick     addGlobalName(GV->getName(), *VariableDIE, DeclContext);
18609467b48Spatrick 
187*d415bd75Srobert   addAnnotation(*VariableDIE, GV->getAnnotations());
188*d415bd75Srobert 
18909467b48Spatrick   if (uint32_t AlignInBytes = GV->getAlignInBytes())
19009467b48Spatrick     addUInt(*VariableDIE, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,
19109467b48Spatrick             AlignInBytes);
19209467b48Spatrick 
19309467b48Spatrick   if (MDTuple *TP = GV->getTemplateParams())
19409467b48Spatrick     addTemplateParams(*VariableDIE, DINodeArray(TP));
19509467b48Spatrick 
19609467b48Spatrick   // Add location.
19709467b48Spatrick   addLocationAttribute(VariableDIE, GV, GlobalExprs);
19809467b48Spatrick 
19909467b48Spatrick   return VariableDIE;
20009467b48Spatrick }
20109467b48Spatrick 
addLocationAttribute(DIE * VariableDIE,const DIGlobalVariable * GV,ArrayRef<GlobalExpr> GlobalExprs)20209467b48Spatrick void DwarfCompileUnit::addLocationAttribute(
20309467b48Spatrick     DIE *VariableDIE, const DIGlobalVariable *GV, ArrayRef<GlobalExpr> GlobalExprs) {
20409467b48Spatrick   bool addToAccelTable = false;
20509467b48Spatrick   DIELoc *Loc = nullptr;
206*d415bd75Srobert   std::optional<unsigned> NVPTXAddressSpace;
20709467b48Spatrick   std::unique_ptr<DIEDwarfExpression> DwarfExpr;
20809467b48Spatrick   for (const auto &GE : GlobalExprs) {
20909467b48Spatrick     const GlobalVariable *Global = GE.Var;
21009467b48Spatrick     const DIExpression *Expr = GE.Expr;
21109467b48Spatrick 
21209467b48Spatrick     // For compatibility with DWARF 3 and earlier,
21373471bf0Spatrick     // DW_AT_location(DW_OP_constu, X, DW_OP_stack_value) or
21473471bf0Spatrick     // DW_AT_location(DW_OP_consts, X, DW_OP_stack_value) becomes
21509467b48Spatrick     // DW_AT_const_value(X).
21609467b48Spatrick     if (GlobalExprs.size() == 1 && Expr && Expr->isConstant()) {
21709467b48Spatrick       addToAccelTable = true;
21873471bf0Spatrick       addConstantValue(
21973471bf0Spatrick           *VariableDIE,
22073471bf0Spatrick           DIExpression::SignedOrUnsignedConstant::UnsignedConstant ==
22173471bf0Spatrick               *Expr->isConstant(),
22273471bf0Spatrick           Expr->getElement(1));
22309467b48Spatrick       break;
22409467b48Spatrick     }
22509467b48Spatrick 
22609467b48Spatrick     // We cannot describe the location of dllimport'd variables: the
22709467b48Spatrick     // computation of their address requires loads from the IAT.
22809467b48Spatrick     if (Global && Global->hasDLLImportStorageClass())
22909467b48Spatrick       continue;
23009467b48Spatrick 
23109467b48Spatrick     // Nothing to describe without address or constant.
23209467b48Spatrick     if (!Global && (!Expr || !Expr->isConstant()))
23309467b48Spatrick       continue;
23409467b48Spatrick 
23509467b48Spatrick     if (Global && Global->isThreadLocal() &&
23609467b48Spatrick         !Asm->getObjFileLowering().supportDebugThreadLocalLocation())
23709467b48Spatrick       continue;
23809467b48Spatrick 
23909467b48Spatrick     if (!Loc) {
24009467b48Spatrick       addToAccelTable = true;
24109467b48Spatrick       Loc = new (DIEValueAllocator) DIELoc;
24209467b48Spatrick       DwarfExpr = std::make_unique<DIEDwarfExpression>(*Asm, *this, *Loc);
24309467b48Spatrick     }
24409467b48Spatrick 
24509467b48Spatrick     if (Expr) {
24609467b48Spatrick       // According to
24709467b48Spatrick       // https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf
24809467b48Spatrick       // cuda-gdb requires DW_AT_address_class for all variables to be able to
24909467b48Spatrick       // correctly interpret address space of the variable address.
25009467b48Spatrick       // Decode DW_OP_constu <DWARF Address Space> DW_OP_swap DW_OP_xderef
25109467b48Spatrick       // sequence for the NVPTX + gdb target.
25209467b48Spatrick       unsigned LocalNVPTXAddressSpace;
25309467b48Spatrick       if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) {
25409467b48Spatrick         const DIExpression *NewExpr =
25509467b48Spatrick             DIExpression::extractAddressClass(Expr, LocalNVPTXAddressSpace);
25609467b48Spatrick         if (NewExpr != Expr) {
25709467b48Spatrick           Expr = NewExpr;
25809467b48Spatrick           NVPTXAddressSpace = LocalNVPTXAddressSpace;
25909467b48Spatrick         }
26009467b48Spatrick       }
26109467b48Spatrick       DwarfExpr->addFragmentOffset(Expr);
26209467b48Spatrick     }
26309467b48Spatrick 
26409467b48Spatrick     if (Global) {
26509467b48Spatrick       const MCSymbol *Sym = Asm->getSymbol(Global);
266*d415bd75Srobert       // 16-bit platforms like MSP430 and AVR take this path, so sink this
267*d415bd75Srobert       // assert to platforms that use it.
268*d415bd75Srobert       auto GetPointerSizedFormAndOp = [this]() {
269*d415bd75Srobert         unsigned PointerSize = Asm->getDataLayout().getPointerSize();
270*d415bd75Srobert         assert((PointerSize == 4 || PointerSize == 8) &&
271*d415bd75Srobert                "Add support for other sizes if necessary");
272*d415bd75Srobert         struct FormAndOp {
273*d415bd75Srobert           dwarf::Form Form;
274*d415bd75Srobert           dwarf::LocationAtom Op;
275*d415bd75Srobert         };
276*d415bd75Srobert         return PointerSize == 4
277*d415bd75Srobert                    ? FormAndOp{dwarf::DW_FORM_data4, dwarf::DW_OP_const4u}
278*d415bd75Srobert                    : FormAndOp{dwarf::DW_FORM_data8, dwarf::DW_OP_const8u};
279*d415bd75Srobert       };
28009467b48Spatrick       if (Global->isThreadLocal()) {
28109467b48Spatrick         if (Asm->TM.useEmulatedTLS()) {
28209467b48Spatrick           // TODO: add debug info for emulated thread local mode.
28309467b48Spatrick         } else {
28409467b48Spatrick           // FIXME: Make this work with -gsplit-dwarf.
28509467b48Spatrick           // Based on GCC's support for TLS:
28609467b48Spatrick           if (!DD->useSplitDwarf()) {
287*d415bd75Srobert             auto FormAndOp = GetPointerSizedFormAndOp();
28809467b48Spatrick             // 1) Start with a constNu of the appropriate pointer size
289*d415bd75Srobert             addUInt(*Loc, dwarf::DW_FORM_data1, FormAndOp.Op);
29009467b48Spatrick             // 2) containing the (relocated) offset of the TLS variable
29109467b48Spatrick             //    within the module's TLS block.
292*d415bd75Srobert             addExpr(*Loc, FormAndOp.Form,
29309467b48Spatrick                     Asm->getObjFileLowering().getDebugThreadLocalSymbol(Sym));
29409467b48Spatrick           } else {
29509467b48Spatrick             addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_const_index);
29609467b48Spatrick             addUInt(*Loc, dwarf::DW_FORM_udata,
29709467b48Spatrick                     DD->getAddressPool().getIndex(Sym, /* TLS */ true));
29809467b48Spatrick           }
29909467b48Spatrick           // 3) followed by an OP to make the debugger do a TLS lookup.
30009467b48Spatrick           addUInt(*Loc, dwarf::DW_FORM_data1,
30109467b48Spatrick                   DD->useGNUTLSOpcode() ? dwarf::DW_OP_GNU_push_tls_address
30209467b48Spatrick                                         : dwarf::DW_OP_form_tls_address);
30309467b48Spatrick         }
304*d415bd75Srobert       } else if ((Asm->TM.getRelocationModel() == Reloc::RWPI ||
305*d415bd75Srobert                   Asm->TM.getRelocationModel() == Reloc::ROPI_RWPI) &&
306*d415bd75Srobert                  !Asm->getObjFileLowering()
307*d415bd75Srobert                       .getKindForGlobal(Global, Asm->TM)
308*d415bd75Srobert                       .isReadOnly()) {
309*d415bd75Srobert         auto FormAndOp = GetPointerSizedFormAndOp();
310*d415bd75Srobert         // Constant
311*d415bd75Srobert         addUInt(*Loc, dwarf::DW_FORM_data1, FormAndOp.Op);
312*d415bd75Srobert         // Relocation offset
313*d415bd75Srobert         addExpr(*Loc, FormAndOp.Form,
314*d415bd75Srobert                 Asm->getObjFileLowering().getIndirectSymViaRWPI(Sym));
315*d415bd75Srobert         // Base register
316*d415bd75Srobert         Register BaseReg = Asm->getObjFileLowering().getStaticBase();
317*d415bd75Srobert         BaseReg = Asm->TM.getMCRegisterInfo()->getDwarfRegNum(BaseReg, false);
318*d415bd75Srobert         addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + BaseReg);
319*d415bd75Srobert         // Offset from base register
320*d415bd75Srobert         addSInt(*Loc, dwarf::DW_FORM_sdata, 0);
321*d415bd75Srobert         // Operation
322*d415bd75Srobert         addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
32309467b48Spatrick       } else {
32409467b48Spatrick         DD->addArangeLabel(SymbolCU(this, Sym));
32509467b48Spatrick         addOpAddress(*Loc, Sym);
32609467b48Spatrick       }
32709467b48Spatrick     }
32809467b48Spatrick     // Global variables attached to symbols are memory locations.
32909467b48Spatrick     // It would be better if this were unconditional, but malformed input that
33009467b48Spatrick     // mixes non-fragments and fragments for the same variable is too expensive
33109467b48Spatrick     // to detect in the verifier.
33209467b48Spatrick     if (DwarfExpr->isUnknownLocation())
33309467b48Spatrick       DwarfExpr->setMemoryLocationKind();
33409467b48Spatrick     DwarfExpr->addExpression(Expr);
33509467b48Spatrick   }
33609467b48Spatrick   if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) {
33709467b48Spatrick     // According to
33809467b48Spatrick     // https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf
33909467b48Spatrick     // cuda-gdb requires DW_AT_address_class for all variables to be able to
34009467b48Spatrick     // correctly interpret address space of the variable address.
34109467b48Spatrick     const unsigned NVPTX_ADDR_global_space = 5;
34209467b48Spatrick     addUInt(*VariableDIE, dwarf::DW_AT_address_class, dwarf::DW_FORM_data1,
343*d415bd75Srobert             NVPTXAddressSpace.value_or(NVPTX_ADDR_global_space));
34409467b48Spatrick   }
34509467b48Spatrick   if (Loc)
34609467b48Spatrick     addBlock(*VariableDIE, dwarf::DW_AT_location, DwarfExpr->finalize());
34709467b48Spatrick 
34809467b48Spatrick   if (DD->useAllLinkageNames())
34909467b48Spatrick     addLinkageName(*VariableDIE, GV->getLinkageName());
35009467b48Spatrick 
35109467b48Spatrick   if (addToAccelTable) {
35209467b48Spatrick     DD->addAccelName(*CUNode, GV->getName(), *VariableDIE);
35309467b48Spatrick 
35409467b48Spatrick     // If the linkage name is different than the name, go ahead and output
35509467b48Spatrick     // that as well into the name table.
35609467b48Spatrick     if (GV->getLinkageName() != "" && GV->getName() != GV->getLinkageName() &&
35709467b48Spatrick         DD->useAllLinkageNames())
35809467b48Spatrick       DD->addAccelName(*CUNode, GV->getLinkageName(), *VariableDIE);
35909467b48Spatrick   }
36009467b48Spatrick }
36109467b48Spatrick 
getOrCreateCommonBlock(const DICommonBlock * CB,ArrayRef<GlobalExpr> GlobalExprs)36209467b48Spatrick DIE *DwarfCompileUnit::getOrCreateCommonBlock(
36309467b48Spatrick     const DICommonBlock *CB, ArrayRef<GlobalExpr> GlobalExprs) {
364*d415bd75Srobert   // Check for pre-existence.
36509467b48Spatrick   if (DIE *NDie = getDIE(CB))
36609467b48Spatrick     return NDie;
367*d415bd75Srobert   DIE *ContextDIE = getOrCreateContextDIE(CB->getScope());
36809467b48Spatrick   DIE &NDie = createAndAddDIE(dwarf::DW_TAG_common_block, *ContextDIE, CB);
36909467b48Spatrick   StringRef Name = CB->getName().empty() ? "_BLNK_" : CB->getName();
37009467b48Spatrick   addString(NDie, dwarf::DW_AT_name, Name);
37109467b48Spatrick   addGlobalName(Name, NDie, CB->getScope());
37209467b48Spatrick   if (CB->getFile())
37309467b48Spatrick     addSourceLine(NDie, CB->getLineNo(), CB->getFile());
37409467b48Spatrick   if (DIGlobalVariable *V = CB->getDecl())
37509467b48Spatrick     getCU().addLocationAttribute(&NDie, V, GlobalExprs);
37609467b48Spatrick   return &NDie;
37709467b48Spatrick }
37809467b48Spatrick 
addRange(RangeSpan Range)37909467b48Spatrick void DwarfCompileUnit::addRange(RangeSpan Range) {
380097a140dSpatrick   DD->insertSectionLabel(Range.Begin);
381097a140dSpatrick 
382*d415bd75Srobert   auto *PrevCU = DD->getPrevCU();
383*d415bd75Srobert   bool SameAsPrevCU = this == PrevCU;
38409467b48Spatrick   DD->setPrevCU(this);
38509467b48Spatrick   // If we have no current ranges just add the range and return, otherwise,
38609467b48Spatrick   // check the current section and CU against the previous section and CU we
38709467b48Spatrick   // emitted into and the subprogram was contained within. If these are the
38809467b48Spatrick   // same then extend our current range, otherwise add this as a new range.
38909467b48Spatrick   if (CURanges.empty() || !SameAsPrevCU ||
39009467b48Spatrick       (&CURanges.back().End->getSection() !=
39109467b48Spatrick        &Range.End->getSection())) {
392*d415bd75Srobert     // Before a new range is added, always terminate the prior line table.
393*d415bd75Srobert     if (PrevCU)
394*d415bd75Srobert       DD->terminateLineTable(PrevCU);
39509467b48Spatrick     CURanges.push_back(Range);
39609467b48Spatrick     return;
39709467b48Spatrick   }
39809467b48Spatrick 
39909467b48Spatrick   CURanges.back().End = Range.End;
40009467b48Spatrick }
40109467b48Spatrick 
initStmtList()40209467b48Spatrick void DwarfCompileUnit::initStmtList() {
40309467b48Spatrick   if (CUNode->isDebugDirectivesOnly())
40409467b48Spatrick     return;
40509467b48Spatrick 
40609467b48Spatrick   const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
40709467b48Spatrick   if (DD->useSectionsAsReferences()) {
40809467b48Spatrick     LineTableStartSym = TLOF.getDwarfLineSection()->getBeginSymbol();
40909467b48Spatrick   } else {
41009467b48Spatrick     LineTableStartSym =
41109467b48Spatrick         Asm->OutStreamer->getDwarfLineTableSymbol(getUniqueID());
41209467b48Spatrick   }
41309467b48Spatrick 
41409467b48Spatrick   // DW_AT_stmt_list is a offset of line number information for this
41509467b48Spatrick   // compile unit in debug_line section. For split dwarf this is
41609467b48Spatrick   // left in the skeleton CU and so not included.
41709467b48Spatrick   // The line table entries are not always emitted in assembly, so it
41809467b48Spatrick   // is not okay to use line_table_start here.
41909467b48Spatrick       addSectionLabel(getUnitDie(), dwarf::DW_AT_stmt_list, LineTableStartSym,
42009467b48Spatrick                       TLOF.getDwarfLineSection()->getBeginSymbol());
42109467b48Spatrick }
42209467b48Spatrick 
applyStmtList(DIE & D)42309467b48Spatrick void DwarfCompileUnit::applyStmtList(DIE &D) {
424097a140dSpatrick   const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
425097a140dSpatrick   addSectionLabel(D, dwarf::DW_AT_stmt_list, LineTableStartSym,
426097a140dSpatrick                   TLOF.getDwarfLineSection()->getBeginSymbol());
42709467b48Spatrick }
42809467b48Spatrick 
attachLowHighPC(DIE & D,const MCSymbol * Begin,const MCSymbol * End)42909467b48Spatrick void DwarfCompileUnit::attachLowHighPC(DIE &D, const MCSymbol *Begin,
43009467b48Spatrick                                        const MCSymbol *End) {
43109467b48Spatrick   assert(Begin && "Begin label should not be null!");
43209467b48Spatrick   assert(End && "End label should not be null!");
43309467b48Spatrick   assert(Begin->isDefined() && "Invalid starting label");
43409467b48Spatrick   assert(End->isDefined() && "Invalid end label");
43509467b48Spatrick 
43609467b48Spatrick   addLabelAddress(D, dwarf::DW_AT_low_pc, Begin);
43709467b48Spatrick   if (DD->getDwarfVersion() < 4)
43809467b48Spatrick     addLabelAddress(D, dwarf::DW_AT_high_pc, End);
43909467b48Spatrick   else
44009467b48Spatrick     addLabelDelta(D, dwarf::DW_AT_high_pc, End, Begin);
44109467b48Spatrick }
44209467b48Spatrick 
44309467b48Spatrick // Find DIE for the given subprogram and attach appropriate DW_AT_low_pc
44409467b48Spatrick // and DW_AT_high_pc attributes. If there are global variables in this
44509467b48Spatrick // scope then create and insert DIEs for these variables.
updateSubprogramScopeDIE(const DISubprogram * SP)44609467b48Spatrick DIE &DwarfCompileUnit::updateSubprogramScopeDIE(const DISubprogram *SP) {
44709467b48Spatrick   DIE *SPDie = getOrCreateSubprogramDIE(SP, includeMinimalInlineScopes());
448*d415bd75Srobert   auto *ContextCU = static_cast<DwarfCompileUnit *>(SPDie->getUnit());
449*d415bd75Srobert   return ContextCU->updateSubprogramScopeDIEImpl(SP, SPDie);
450*d415bd75Srobert }
45109467b48Spatrick 
updateSubprogramScopeDIEImpl(const DISubprogram * SP,DIE * SPDie)452*d415bd75Srobert DIE &DwarfCompileUnit::updateSubprogramScopeDIEImpl(const DISubprogram *SP,
453*d415bd75Srobert                                                     DIE *SPDie) {
454097a140dSpatrick   SmallVector<RangeSpan, 2> BB_List;
455097a140dSpatrick   // If basic block sections are on, ranges for each basic block section has
456097a140dSpatrick   // to be emitted separately.
457097a140dSpatrick   for (const auto &R : Asm->MBBSectionRanges)
458097a140dSpatrick     BB_List.push_back({R.second.BeginLabel, R.second.EndLabel});
459097a140dSpatrick 
460097a140dSpatrick   attachRangesOrLowHighPC(*SPDie, BB_List);
461097a140dSpatrick 
46209467b48Spatrick   if (DD->useAppleExtensionAttributes() &&
46309467b48Spatrick       !DD->getCurrentFunction()->getTarget().Options.DisableFramePointerElim(
46409467b48Spatrick           *DD->getCurrentFunction()))
46509467b48Spatrick     addFlag(*SPDie, dwarf::DW_AT_APPLE_omit_frame_ptr);
46609467b48Spatrick 
46709467b48Spatrick   // Only include DW_AT_frame_base in full debug info
46809467b48Spatrick   if (!includeMinimalInlineScopes()) {
469097a140dSpatrick     const TargetFrameLowering *TFI = Asm->MF->getSubtarget().getFrameLowering();
470097a140dSpatrick     TargetFrameLowering::DwarfFrameBase FrameBase =
471097a140dSpatrick         TFI->getDwarfFrameBase(*Asm->MF);
472097a140dSpatrick     switch (FrameBase.Kind) {
473097a140dSpatrick     case TargetFrameLowering::DwarfFrameBase::Register: {
474097a140dSpatrick       if (Register::isPhysicalRegister(FrameBase.Location.Reg)) {
475097a140dSpatrick         MachineLocation Location(FrameBase.Location.Reg);
476097a140dSpatrick         addAddress(*SPDie, dwarf::DW_AT_frame_base, Location);
477097a140dSpatrick       }
478097a140dSpatrick       break;
479097a140dSpatrick     }
480097a140dSpatrick     case TargetFrameLowering::DwarfFrameBase::CFA: {
48109467b48Spatrick       DIELoc *Loc = new (DIEValueAllocator) DIELoc;
48209467b48Spatrick       addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_call_frame_cfa);
48309467b48Spatrick       addBlock(*SPDie, dwarf::DW_AT_frame_base, Loc);
484097a140dSpatrick       break;
485097a140dSpatrick     }
486097a140dSpatrick     case TargetFrameLowering::DwarfFrameBase::WasmFrameBase: {
487097a140dSpatrick       // FIXME: duplicated from Target/WebAssembly/WebAssembly.h
488097a140dSpatrick       // don't want to depend on target specific headers in this code?
489097a140dSpatrick       const unsigned TI_GLOBAL_RELOC = 3;
490097a140dSpatrick       if (FrameBase.Location.WasmLoc.Kind == TI_GLOBAL_RELOC) {
491097a140dSpatrick         // These need to be relocatable.
492097a140dSpatrick         assert(FrameBase.Location.WasmLoc.Index == 0);  // Only SP so far.
493097a140dSpatrick         auto SPSym = cast<MCSymbolWasm>(
494097a140dSpatrick           Asm->GetExternalSymbolSymbol("__stack_pointer"));
495097a140dSpatrick         // FIXME: this repeats what WebAssemblyMCInstLower::
496097a140dSpatrick         // GetExternalSymbolSymbol does, since if there's no code that
497097a140dSpatrick         // refers to this symbol, we have to set it here.
498097a140dSpatrick         SPSym->setType(wasm::WASM_SYMBOL_TYPE_GLOBAL);
499097a140dSpatrick         SPSym->setGlobalType(wasm::WasmGlobalType{
500097a140dSpatrick             uint8_t(Asm->getSubtargetInfo().getTargetTriple().getArch() ==
501097a140dSpatrick                             Triple::wasm64
502097a140dSpatrick                         ? wasm::WASM_TYPE_I64
503097a140dSpatrick                         : wasm::WASM_TYPE_I32),
504097a140dSpatrick             true});
505097a140dSpatrick         DIELoc *Loc = new (DIEValueAllocator) DIELoc;
506097a140dSpatrick         addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_WASM_location);
50773471bf0Spatrick         addSInt(*Loc, dwarf::DW_FORM_sdata, TI_GLOBAL_RELOC);
50873471bf0Spatrick         if (!isDwoUnit()) {
50973471bf0Spatrick           addLabel(*Loc, dwarf::DW_FORM_data4, SPSym);
51073471bf0Spatrick         } else {
51173471bf0Spatrick           // FIXME: when writing dwo, we need to avoid relocations. Probably
51273471bf0Spatrick           // the "right" solution is to treat globals the way func and data
51373471bf0Spatrick           // symbols are (with entries in .debug_addr).
51473471bf0Spatrick           // For now, since we only ever use index 0, this should work as-is.
51573471bf0Spatrick           addUInt(*Loc, dwarf::DW_FORM_data4, FrameBase.Location.WasmLoc.Index);
51673471bf0Spatrick         }
517097a140dSpatrick         addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_stack_value);
518097a140dSpatrick         addBlock(*SPDie, dwarf::DW_AT_frame_base, Loc);
51909467b48Spatrick       } else {
520097a140dSpatrick         DIELoc *Loc = new (DIEValueAllocator) DIELoc;
521097a140dSpatrick         DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
522097a140dSpatrick         DIExpressionCursor Cursor({});
523097a140dSpatrick         DwarfExpr.addWasmLocation(FrameBase.Location.WasmLoc.Kind,
524097a140dSpatrick             FrameBase.Location.WasmLoc.Index);
525097a140dSpatrick         DwarfExpr.addExpression(std::move(Cursor));
526097a140dSpatrick         addBlock(*SPDie, dwarf::DW_AT_frame_base, DwarfExpr.finalize());
527097a140dSpatrick       }
528097a140dSpatrick       break;
529097a140dSpatrick     }
53009467b48Spatrick     }
53109467b48Spatrick   }
53209467b48Spatrick 
53309467b48Spatrick   // Add name to the name table, we do this here because we're guaranteed
53409467b48Spatrick   // to have concrete versions of our DW_TAG_subprogram nodes.
53509467b48Spatrick   DD->addSubprogramNames(*CUNode, SP, *SPDie);
53609467b48Spatrick 
53709467b48Spatrick   return *SPDie;
53809467b48Spatrick }
53909467b48Spatrick 
54009467b48Spatrick // Construct a DIE for this scope.
constructScopeDIE(LexicalScope * Scope,DIE & ParentScopeDIE)541*d415bd75Srobert void DwarfCompileUnit::constructScopeDIE(LexicalScope *Scope,
542*d415bd75Srobert                                          DIE &ParentScopeDIE) {
54309467b48Spatrick   if (!Scope || !Scope->getScopeNode())
54409467b48Spatrick     return;
54509467b48Spatrick 
54609467b48Spatrick   auto *DS = Scope->getScopeNode();
54709467b48Spatrick 
54809467b48Spatrick   assert((Scope->getInlinedAt() || !isa<DISubprogram>(DS)) &&
54909467b48Spatrick          "Only handle inlined subprograms here, use "
55009467b48Spatrick          "constructSubprogramScopeDIE for non-inlined "
55109467b48Spatrick          "subprograms");
55209467b48Spatrick 
553*d415bd75Srobert   // Emit inlined subprograms.
55409467b48Spatrick   if (Scope->getParent() && isa<DISubprogram>(DS)) {
555*d415bd75Srobert     DIE *ScopeDIE = constructInlinedScopeDIE(Scope, ParentScopeDIE);
556*d415bd75Srobert     assert(ScopeDIE && "Scope DIE should not be null.");
557*d415bd75Srobert     createAndAddScopeChildren(Scope, *ScopeDIE);
55809467b48Spatrick     return;
559*d415bd75Srobert   }
560*d415bd75Srobert 
56109467b48Spatrick   // Early exit when we know the scope DIE is going to be null.
56209467b48Spatrick   if (DD->isLexicalScopeDIENull(Scope))
56309467b48Spatrick     return;
56409467b48Spatrick 
565*d415bd75Srobert   // Emit lexical blocks.
566*d415bd75Srobert   DIE *ScopeDIE = constructLexicalScopeDIE(Scope);
56709467b48Spatrick   assert(ScopeDIE && "Scope DIE should not be null.");
56809467b48Spatrick 
569*d415bd75Srobert   ParentScopeDIE.addChild(ScopeDIE);
570*d415bd75Srobert   createAndAddScopeChildren(Scope, *ScopeDIE);
57109467b48Spatrick }
57209467b48Spatrick 
addScopeRangeList(DIE & ScopeDIE,SmallVector<RangeSpan,2> Range)57309467b48Spatrick void DwarfCompileUnit::addScopeRangeList(DIE &ScopeDIE,
57409467b48Spatrick                                          SmallVector<RangeSpan, 2> Range) {
57509467b48Spatrick 
57609467b48Spatrick   HasRangeLists = true;
57709467b48Spatrick 
57809467b48Spatrick   // Add the range list to the set of ranges to be emitted.
57909467b48Spatrick   auto IndexAndList =
58009467b48Spatrick       (DD->getDwarfVersion() < 5 && Skeleton ? Skeleton->DU : DU)
58109467b48Spatrick           ->addRange(*(Skeleton ? Skeleton : this), std::move(Range));
58209467b48Spatrick 
58309467b48Spatrick   uint32_t Index = IndexAndList.first;
58409467b48Spatrick   auto &List = *IndexAndList.second;
58509467b48Spatrick 
58609467b48Spatrick   // Under fission, ranges are specified by constant offsets relative to the
58709467b48Spatrick   // CU's DW_AT_GNU_ranges_base.
58809467b48Spatrick   // FIXME: For DWARF v5, do not generate the DW_AT_ranges attribute under
58909467b48Spatrick   // fission until we support the forms using the .debug_addr section
59009467b48Spatrick   // (DW_RLE_startx_endx etc.).
59109467b48Spatrick   if (DD->getDwarfVersion() >= 5)
59209467b48Spatrick     addUInt(ScopeDIE, dwarf::DW_AT_ranges, dwarf::DW_FORM_rnglistx, Index);
59309467b48Spatrick   else {
59409467b48Spatrick     const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
59509467b48Spatrick     const MCSymbol *RangeSectionSym =
59609467b48Spatrick         TLOF.getDwarfRangesSection()->getBeginSymbol();
59709467b48Spatrick     if (isDwoUnit())
59809467b48Spatrick       addSectionDelta(ScopeDIE, dwarf::DW_AT_ranges, List.Label,
59909467b48Spatrick                       RangeSectionSym);
60009467b48Spatrick     else
60109467b48Spatrick       addSectionLabel(ScopeDIE, dwarf::DW_AT_ranges, List.Label,
60209467b48Spatrick                       RangeSectionSym);
60309467b48Spatrick   }
60409467b48Spatrick }
60509467b48Spatrick 
attachRangesOrLowHighPC(DIE & Die,SmallVector<RangeSpan,2> Ranges)60609467b48Spatrick void DwarfCompileUnit::attachRangesOrLowHighPC(
60709467b48Spatrick     DIE &Die, SmallVector<RangeSpan, 2> Ranges) {
60873471bf0Spatrick   assert(!Ranges.empty());
60973471bf0Spatrick   if (!DD->useRangesSection() ||
61073471bf0Spatrick       (Ranges.size() == 1 &&
61173471bf0Spatrick        (!DD->alwaysUseRanges() ||
61273471bf0Spatrick         DD->getSectionLabel(&Ranges.front().Begin->getSection()) ==
61373471bf0Spatrick             Ranges.front().Begin))) {
61409467b48Spatrick     const RangeSpan &Front = Ranges.front();
61509467b48Spatrick     const RangeSpan &Back = Ranges.back();
61609467b48Spatrick     attachLowHighPC(Die, Front.Begin, Back.End);
61709467b48Spatrick   } else
61809467b48Spatrick     addScopeRangeList(Die, std::move(Ranges));
61909467b48Spatrick }
62009467b48Spatrick 
attachRangesOrLowHighPC(DIE & Die,const SmallVectorImpl<InsnRange> & Ranges)62109467b48Spatrick void DwarfCompileUnit::attachRangesOrLowHighPC(
62209467b48Spatrick     DIE &Die, const SmallVectorImpl<InsnRange> &Ranges) {
62309467b48Spatrick   SmallVector<RangeSpan, 2> List;
62409467b48Spatrick   List.reserve(Ranges.size());
625097a140dSpatrick   for (const InsnRange &R : Ranges) {
626097a140dSpatrick     auto *BeginLabel = DD->getLabelBeforeInsn(R.first);
627097a140dSpatrick     auto *EndLabel = DD->getLabelAfterInsn(R.second);
628097a140dSpatrick 
629097a140dSpatrick     const auto *BeginMBB = R.first->getParent();
630097a140dSpatrick     const auto *EndMBB = R.second->getParent();
631097a140dSpatrick 
632097a140dSpatrick     const auto *MBB = BeginMBB;
633097a140dSpatrick     // Basic block sections allows basic block subsets to be placed in unique
634097a140dSpatrick     // sections. For each section, the begin and end label must be added to the
635097a140dSpatrick     // list. If there is more than one range, debug ranges must be used.
636097a140dSpatrick     // Otherwise, low/high PC can be used.
637097a140dSpatrick     // FIXME: Debug Info Emission depends on block order and this assumes that
638097a140dSpatrick     // the order of blocks will be frozen beyond this point.
639097a140dSpatrick     do {
640097a140dSpatrick       if (MBB->sameSection(EndMBB) || MBB->isEndSection()) {
641097a140dSpatrick         auto MBBSectionRange = Asm->MBBSectionRanges[MBB->getSectionIDNum()];
64209467b48Spatrick         List.push_back(
643097a140dSpatrick             {MBB->sameSection(BeginMBB) ? BeginLabel
644097a140dSpatrick                                         : MBBSectionRange.BeginLabel,
645097a140dSpatrick              MBB->sameSection(EndMBB) ? EndLabel : MBBSectionRange.EndLabel});
646097a140dSpatrick       }
647097a140dSpatrick       if (MBB->sameSection(EndMBB))
648097a140dSpatrick         break;
649097a140dSpatrick       MBB = MBB->getNextNode();
650097a140dSpatrick     } while (true);
651097a140dSpatrick   }
65209467b48Spatrick   attachRangesOrLowHighPC(Die, std::move(List));
65309467b48Spatrick }
65409467b48Spatrick 
constructInlinedScopeDIE(LexicalScope * Scope,DIE & ParentScopeDIE)655*d415bd75Srobert DIE *DwarfCompileUnit::constructInlinedScopeDIE(LexicalScope *Scope,
656*d415bd75Srobert                                                 DIE &ParentScopeDIE) {
65709467b48Spatrick   assert(Scope->getScopeNode());
65809467b48Spatrick   auto *DS = Scope->getScopeNode();
65909467b48Spatrick   auto *InlinedSP = getDISubprogram(DS);
66009467b48Spatrick   // Find the subprogram's DwarfCompileUnit in the SPMap in case the subprogram
66109467b48Spatrick   // was inlined from another compile unit.
66209467b48Spatrick   DIE *OriginDIE = getAbstractSPDies()[InlinedSP];
66309467b48Spatrick   assert(OriginDIE && "Unable to find original DIE for an inlined subprogram.");
66409467b48Spatrick 
66509467b48Spatrick   auto ScopeDIE = DIE::get(DIEValueAllocator, dwarf::DW_TAG_inlined_subroutine);
666*d415bd75Srobert   ParentScopeDIE.addChild(ScopeDIE);
66709467b48Spatrick   addDIEEntry(*ScopeDIE, dwarf::DW_AT_abstract_origin, *OriginDIE);
66809467b48Spatrick 
66909467b48Spatrick   attachRangesOrLowHighPC(*ScopeDIE, Scope->getRanges());
67009467b48Spatrick 
67109467b48Spatrick   // Add the call site information to the DIE.
67209467b48Spatrick   const DILocation *IA = Scope->getInlinedAt();
673*d415bd75Srobert   addUInt(*ScopeDIE, dwarf::DW_AT_call_file, std::nullopt,
67409467b48Spatrick           getOrCreateSourceID(IA->getFile()));
675*d415bd75Srobert   addUInt(*ScopeDIE, dwarf::DW_AT_call_line, std::nullopt, IA->getLine());
67609467b48Spatrick   if (IA->getColumn())
677*d415bd75Srobert     addUInt(*ScopeDIE, dwarf::DW_AT_call_column, std::nullopt, IA->getColumn());
67809467b48Spatrick   if (IA->getDiscriminator() && DD->getDwarfVersion() >= 4)
679*d415bd75Srobert     addUInt(*ScopeDIE, dwarf::DW_AT_GNU_discriminator, std::nullopt,
68009467b48Spatrick             IA->getDiscriminator());
68109467b48Spatrick 
68209467b48Spatrick   // Add name to the name table, we do this here because we're guaranteed
68309467b48Spatrick   // to have concrete versions of our DW_TAG_inlined_subprogram nodes.
68409467b48Spatrick   DD->addSubprogramNames(*CUNode, InlinedSP, *ScopeDIE);
68509467b48Spatrick 
68609467b48Spatrick   return ScopeDIE;
68709467b48Spatrick }
68809467b48Spatrick 
68909467b48Spatrick // Construct new DW_TAG_lexical_block for this scope and attach
69009467b48Spatrick // DW_AT_low_pc/DW_AT_high_pc labels.
constructLexicalScopeDIE(LexicalScope * Scope)69109467b48Spatrick DIE *DwarfCompileUnit::constructLexicalScopeDIE(LexicalScope *Scope) {
69209467b48Spatrick   if (DD->isLexicalScopeDIENull(Scope))
69309467b48Spatrick     return nullptr;
69409467b48Spatrick 
69509467b48Spatrick   auto ScopeDIE = DIE::get(DIEValueAllocator, dwarf::DW_TAG_lexical_block);
69609467b48Spatrick   if (Scope->isAbstractScope())
69709467b48Spatrick     return ScopeDIE;
69809467b48Spatrick 
69909467b48Spatrick   attachRangesOrLowHighPC(*ScopeDIE, Scope->getRanges());
70009467b48Spatrick 
70109467b48Spatrick   return ScopeDIE;
70209467b48Spatrick }
70309467b48Spatrick 
70409467b48Spatrick /// constructVariableDIE - Construct a DIE for the given DbgVariable.
constructVariableDIE(DbgVariable & DV,bool Abstract)70509467b48Spatrick DIE *DwarfCompileUnit::constructVariableDIE(DbgVariable &DV, bool Abstract) {
70609467b48Spatrick   auto D = constructVariableDIEImpl(DV, Abstract);
70709467b48Spatrick   DV.setDIE(*D);
70809467b48Spatrick   return D;
70909467b48Spatrick }
71009467b48Spatrick 
constructLabelDIE(DbgLabel & DL,const LexicalScope & Scope)71109467b48Spatrick DIE *DwarfCompileUnit::constructLabelDIE(DbgLabel &DL,
71209467b48Spatrick                                          const LexicalScope &Scope) {
71309467b48Spatrick   auto LabelDie = DIE::get(DIEValueAllocator, DL.getTag());
71409467b48Spatrick   insertDIE(DL.getLabel(), LabelDie);
71509467b48Spatrick   DL.setDIE(*LabelDie);
71609467b48Spatrick 
71709467b48Spatrick   if (Scope.isAbstractScope())
71809467b48Spatrick     applyLabelAttributes(DL, *LabelDie);
71909467b48Spatrick 
72009467b48Spatrick   return LabelDie;
72109467b48Spatrick }
72209467b48Spatrick 
constructVariableDIEImpl(const DbgVariable & DV,bool Abstract)72309467b48Spatrick DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV,
72409467b48Spatrick                                                 bool Abstract) {
72509467b48Spatrick   // Define variable debug information entry.
72609467b48Spatrick   auto VariableDie = DIE::get(DIEValueAllocator, DV.getTag());
72709467b48Spatrick   insertDIE(DV.getVariable(), VariableDie);
72809467b48Spatrick 
72909467b48Spatrick   if (Abstract) {
73009467b48Spatrick     applyVariableAttributes(DV, *VariableDie);
73109467b48Spatrick     return VariableDie;
73209467b48Spatrick   }
73309467b48Spatrick 
73409467b48Spatrick   // Add variable address.
73509467b48Spatrick 
73673471bf0Spatrick   unsigned Index = DV.getDebugLocListIndex();
73773471bf0Spatrick   if (Index != ~0U) {
73873471bf0Spatrick     addLocationList(*VariableDie, dwarf::DW_AT_location, Index);
73909467b48Spatrick     auto TagOffset = DV.getDebugLocListTagOffset();
74009467b48Spatrick     if (TagOffset)
74109467b48Spatrick       addUInt(*VariableDie, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,
74209467b48Spatrick               *TagOffset);
74309467b48Spatrick     return VariableDie;
74409467b48Spatrick   }
74509467b48Spatrick 
74609467b48Spatrick   // Check if variable has a single location description.
74709467b48Spatrick   if (auto *DVal = DV.getValueLoc()) {
74873471bf0Spatrick     if (!DVal->isVariadic()) {
74973471bf0Spatrick       const DbgValueLocEntry *Entry = DVal->getLocEntries().begin();
75073471bf0Spatrick       if (Entry->isLocation()) {
75173471bf0Spatrick         addVariableAddress(DV, *VariableDie, Entry->getLoc());
75273471bf0Spatrick       } else if (Entry->isInt()) {
75309467b48Spatrick         auto *Expr = DV.getSingleExpression();
75409467b48Spatrick         if (Expr && Expr->getNumElements()) {
75509467b48Spatrick           DIELoc *Loc = new (DIEValueAllocator) DIELoc;
75609467b48Spatrick           DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
75709467b48Spatrick           // If there is an expression, emit raw unsigned bytes.
75809467b48Spatrick           DwarfExpr.addFragmentOffset(Expr);
75973471bf0Spatrick           DwarfExpr.addUnsignedConstant(Entry->getInt());
76009467b48Spatrick           DwarfExpr.addExpression(Expr);
76109467b48Spatrick           addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
76209467b48Spatrick           if (DwarfExpr.TagOffset)
76309467b48Spatrick             addUInt(*VariableDie, dwarf::DW_AT_LLVM_tag_offset,
76409467b48Spatrick                     dwarf::DW_FORM_data1, *DwarfExpr.TagOffset);
76509467b48Spatrick         } else
76673471bf0Spatrick           addConstantValue(*VariableDie, Entry->getInt(), DV.getType());
76773471bf0Spatrick       } else if (Entry->isConstantFP()) {
76873471bf0Spatrick         addConstantFPValue(*VariableDie, Entry->getConstantFP());
76973471bf0Spatrick       } else if (Entry->isConstantInt()) {
77073471bf0Spatrick         addConstantValue(*VariableDie, Entry->getConstantInt(), DV.getType());
77173471bf0Spatrick       } else if (Entry->isTargetIndexLocation()) {
77273471bf0Spatrick         DIELoc *Loc = new (DIEValueAllocator) DIELoc;
77373471bf0Spatrick         DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
77473471bf0Spatrick         const DIBasicType *BT = dyn_cast<DIBasicType>(
77573471bf0Spatrick             static_cast<const Metadata *>(DV.getVariable()->getType()));
77673471bf0Spatrick         DwarfDebug::emitDebugLocValue(*Asm, BT, *DVal, DwarfExpr);
77773471bf0Spatrick         addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
77809467b48Spatrick       }
77909467b48Spatrick       return VariableDie;
78009467b48Spatrick     }
78173471bf0Spatrick     // If any of the location entries are registers with the value 0, then the
78273471bf0Spatrick     // location is undefined.
78373471bf0Spatrick     if (any_of(DVal->getLocEntries(), [](const DbgValueLocEntry &Entry) {
78473471bf0Spatrick           return Entry.isLocation() && !Entry.getLoc().getReg();
78573471bf0Spatrick         }))
78673471bf0Spatrick       return VariableDie;
78773471bf0Spatrick     const DIExpression *Expr = DV.getSingleExpression();
78873471bf0Spatrick     assert(Expr && "Variadic Debug Value must have an Expression.");
78973471bf0Spatrick     DIELoc *Loc = new (DIEValueAllocator) DIELoc;
79073471bf0Spatrick     DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
79173471bf0Spatrick     DwarfExpr.addFragmentOffset(Expr);
79273471bf0Spatrick     DIExpressionCursor Cursor(Expr);
79373471bf0Spatrick     const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();
79473471bf0Spatrick 
79573471bf0Spatrick     auto AddEntry = [&](const DbgValueLocEntry &Entry,
79673471bf0Spatrick                         DIExpressionCursor &Cursor) {
79773471bf0Spatrick       if (Entry.isLocation()) {
79873471bf0Spatrick         if (!DwarfExpr.addMachineRegExpression(TRI, Cursor,
79973471bf0Spatrick                                                Entry.getLoc().getReg()))
80073471bf0Spatrick           return false;
80173471bf0Spatrick       } else if (Entry.isInt()) {
80273471bf0Spatrick         // If there is an expression, emit raw unsigned bytes.
80373471bf0Spatrick         DwarfExpr.addUnsignedConstant(Entry.getInt());
80473471bf0Spatrick       } else if (Entry.isConstantFP()) {
805*d415bd75Srobert         // DwarfExpression does not support arguments wider than 64 bits
806*d415bd75Srobert         // (see PR52584).
807*d415bd75Srobert         // TODO: Consider chunking expressions containing overly wide
808*d415bd75Srobert         // arguments into separate pointer-sized fragment expressions.
80973471bf0Spatrick         APInt RawBytes = Entry.getConstantFP()->getValueAPF().bitcastToAPInt();
810*d415bd75Srobert         if (RawBytes.getBitWidth() > 64)
811*d415bd75Srobert           return false;
812*d415bd75Srobert         DwarfExpr.addUnsignedConstant(RawBytes.getZExtValue());
81373471bf0Spatrick       } else if (Entry.isConstantInt()) {
81473471bf0Spatrick         APInt RawBytes = Entry.getConstantInt()->getValue();
815*d415bd75Srobert         if (RawBytes.getBitWidth() > 64)
816*d415bd75Srobert           return false;
817*d415bd75Srobert         DwarfExpr.addUnsignedConstant(RawBytes.getZExtValue());
81873471bf0Spatrick       } else if (Entry.isTargetIndexLocation()) {
81973471bf0Spatrick         TargetIndexLocation Loc = Entry.getTargetIndexLocation();
82073471bf0Spatrick         // TODO TargetIndexLocation is a target-independent. Currently only the
82173471bf0Spatrick         // WebAssembly-specific encoding is supported.
82273471bf0Spatrick         assert(Asm->TM.getTargetTriple().isWasm());
82373471bf0Spatrick         DwarfExpr.addWasmLocation(Loc.Index, static_cast<uint64_t>(Loc.Offset));
82473471bf0Spatrick       } else {
82573471bf0Spatrick         llvm_unreachable("Unsupported Entry type.");
82673471bf0Spatrick       }
82773471bf0Spatrick       return true;
82873471bf0Spatrick     };
82973471bf0Spatrick 
830*d415bd75Srobert     if (!DwarfExpr.addExpression(
83173471bf0Spatrick             std::move(Cursor),
83273471bf0Spatrick             [&](unsigned Idx, DIExpressionCursor &Cursor) -> bool {
83373471bf0Spatrick               return AddEntry(DVal->getLocEntries()[Idx], Cursor);
834*d415bd75Srobert             }))
835*d415bd75Srobert       return VariableDie;
83673471bf0Spatrick 
83773471bf0Spatrick     // Now attach the location information to the DIE.
83873471bf0Spatrick     addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
83973471bf0Spatrick     if (DwarfExpr.TagOffset)
84073471bf0Spatrick       addUInt(*VariableDie, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,
84173471bf0Spatrick               *DwarfExpr.TagOffset);
84273471bf0Spatrick 
84373471bf0Spatrick     return VariableDie;
84473471bf0Spatrick   }
84509467b48Spatrick 
84609467b48Spatrick   // .. else use frame index.
84709467b48Spatrick   if (!DV.hasFrameIndexExprs())
84809467b48Spatrick     return VariableDie;
84909467b48Spatrick 
850*d415bd75Srobert   std::optional<unsigned> NVPTXAddressSpace;
85109467b48Spatrick   DIELoc *Loc = new (DIEValueAllocator) DIELoc;
85209467b48Spatrick   DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
853*d415bd75Srobert   for (const auto &Fragment : DV.getFrameIndexExprs()) {
854097a140dSpatrick     Register FrameReg;
85509467b48Spatrick     const DIExpression *Expr = Fragment.Expr;
85609467b48Spatrick     const TargetFrameLowering *TFI = Asm->MF->getSubtarget().getFrameLowering();
85773471bf0Spatrick     StackOffset Offset =
85873471bf0Spatrick         TFI->getFrameIndexReference(*Asm->MF, Fragment.FI, FrameReg);
85909467b48Spatrick     DwarfExpr.addFragmentOffset(Expr);
86073471bf0Spatrick 
86173471bf0Spatrick     auto *TRI = Asm->MF->getSubtarget().getRegisterInfo();
86209467b48Spatrick     SmallVector<uint64_t, 8> Ops;
86373471bf0Spatrick     TRI->getOffsetOpcodes(Offset, Ops);
86473471bf0Spatrick 
86509467b48Spatrick     // According to
86609467b48Spatrick     // https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf
86709467b48Spatrick     // cuda-gdb requires DW_AT_address_class for all variables to be able to
86809467b48Spatrick     // correctly interpret address space of the variable address.
86909467b48Spatrick     // Decode DW_OP_constu <DWARF Address Space> DW_OP_swap DW_OP_xderef
87009467b48Spatrick     // sequence for the NVPTX + gdb target.
87109467b48Spatrick     unsigned LocalNVPTXAddressSpace;
87209467b48Spatrick     if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) {
87309467b48Spatrick       const DIExpression *NewExpr =
87409467b48Spatrick           DIExpression::extractAddressClass(Expr, LocalNVPTXAddressSpace);
87509467b48Spatrick       if (NewExpr != Expr) {
87609467b48Spatrick         Expr = NewExpr;
87709467b48Spatrick         NVPTXAddressSpace = LocalNVPTXAddressSpace;
87809467b48Spatrick       }
87909467b48Spatrick     }
88009467b48Spatrick     if (Expr)
88109467b48Spatrick       Ops.append(Expr->elements_begin(), Expr->elements_end());
88209467b48Spatrick     DIExpressionCursor Cursor(Ops);
88309467b48Spatrick     DwarfExpr.setMemoryLocationKind();
88409467b48Spatrick     if (const MCSymbol *FrameSymbol = Asm->getFunctionFrameSymbol())
88509467b48Spatrick       addOpAddress(*Loc, FrameSymbol);
88609467b48Spatrick     else
88709467b48Spatrick       DwarfExpr.addMachineRegExpression(
88809467b48Spatrick           *Asm->MF->getSubtarget().getRegisterInfo(), Cursor, FrameReg);
88909467b48Spatrick     DwarfExpr.addExpression(std::move(Cursor));
89009467b48Spatrick   }
89109467b48Spatrick   if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) {
89209467b48Spatrick     // According to
89309467b48Spatrick     // https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf
89409467b48Spatrick     // cuda-gdb requires DW_AT_address_class for all variables to be able to
89509467b48Spatrick     // correctly interpret address space of the variable address.
89609467b48Spatrick     const unsigned NVPTX_ADDR_local_space = 6;
89709467b48Spatrick     addUInt(*VariableDie, dwarf::DW_AT_address_class, dwarf::DW_FORM_data1,
898*d415bd75Srobert             NVPTXAddressSpace.value_or(NVPTX_ADDR_local_space));
89909467b48Spatrick   }
90009467b48Spatrick   addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
90109467b48Spatrick   if (DwarfExpr.TagOffset)
90209467b48Spatrick     addUInt(*VariableDie, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,
90309467b48Spatrick             *DwarfExpr.TagOffset);
90409467b48Spatrick 
90509467b48Spatrick   return VariableDie;
90609467b48Spatrick }
90709467b48Spatrick 
constructVariableDIE(DbgVariable & DV,const LexicalScope & Scope,DIE * & ObjectPointer)90809467b48Spatrick DIE *DwarfCompileUnit::constructVariableDIE(DbgVariable &DV,
90909467b48Spatrick                                             const LexicalScope &Scope,
91009467b48Spatrick                                             DIE *&ObjectPointer) {
91109467b48Spatrick   auto Var = constructVariableDIE(DV, Scope.isAbstractScope());
91209467b48Spatrick   if (DV.isObjectPointer())
91309467b48Spatrick     ObjectPointer = Var;
91409467b48Spatrick   return Var;
91509467b48Spatrick }
91609467b48Spatrick 
91709467b48Spatrick /// Return all DIVariables that appear in count: expressions.
dependencies(DbgVariable * Var)91809467b48Spatrick static SmallVector<const DIVariable *, 2> dependencies(DbgVariable *Var) {
91909467b48Spatrick   SmallVector<const DIVariable *, 2> Result;
92009467b48Spatrick   auto *Array = dyn_cast<DICompositeType>(Var->getType());
92109467b48Spatrick   if (!Array || Array->getTag() != dwarf::DW_TAG_array_type)
92209467b48Spatrick     return Result;
923097a140dSpatrick   if (auto *DLVar = Array->getDataLocation())
924097a140dSpatrick     Result.push_back(DLVar);
92573471bf0Spatrick   if (auto *AsVar = Array->getAssociated())
92673471bf0Spatrick     Result.push_back(AsVar);
92773471bf0Spatrick   if (auto *AlVar = Array->getAllocated())
92873471bf0Spatrick     Result.push_back(AlVar);
92909467b48Spatrick   for (auto *El : Array->getElements()) {
93009467b48Spatrick     if (auto *Subrange = dyn_cast<DISubrange>(El)) {
931097a140dSpatrick       if (auto Count = Subrange->getCount())
93209467b48Spatrick         if (auto *Dependency = Count.dyn_cast<DIVariable *>())
93309467b48Spatrick           Result.push_back(Dependency);
934097a140dSpatrick       if (auto LB = Subrange->getLowerBound())
935097a140dSpatrick         if (auto *Dependency = LB.dyn_cast<DIVariable *>())
936097a140dSpatrick           Result.push_back(Dependency);
937097a140dSpatrick       if (auto UB = Subrange->getUpperBound())
938097a140dSpatrick         if (auto *Dependency = UB.dyn_cast<DIVariable *>())
939097a140dSpatrick           Result.push_back(Dependency);
940097a140dSpatrick       if (auto ST = Subrange->getStride())
941097a140dSpatrick         if (auto *Dependency = ST.dyn_cast<DIVariable *>())
942097a140dSpatrick           Result.push_back(Dependency);
94373471bf0Spatrick     } else if (auto *GenericSubrange = dyn_cast<DIGenericSubrange>(El)) {
94473471bf0Spatrick       if (auto Count = GenericSubrange->getCount())
94573471bf0Spatrick         if (auto *Dependency = Count.dyn_cast<DIVariable *>())
94673471bf0Spatrick           Result.push_back(Dependency);
94773471bf0Spatrick       if (auto LB = GenericSubrange->getLowerBound())
94873471bf0Spatrick         if (auto *Dependency = LB.dyn_cast<DIVariable *>())
94973471bf0Spatrick           Result.push_back(Dependency);
95073471bf0Spatrick       if (auto UB = GenericSubrange->getUpperBound())
95173471bf0Spatrick         if (auto *Dependency = UB.dyn_cast<DIVariable *>())
95273471bf0Spatrick           Result.push_back(Dependency);
95373471bf0Spatrick       if (auto ST = GenericSubrange->getStride())
95473471bf0Spatrick         if (auto *Dependency = ST.dyn_cast<DIVariable *>())
95573471bf0Spatrick           Result.push_back(Dependency);
95609467b48Spatrick     }
95709467b48Spatrick   }
95809467b48Spatrick   return Result;
95909467b48Spatrick }
96009467b48Spatrick 
96109467b48Spatrick /// Sort local variables so that variables appearing inside of helper
96209467b48Spatrick /// expressions come first.
96309467b48Spatrick static SmallVector<DbgVariable *, 8>
sortLocalVars(SmallVectorImpl<DbgVariable * > & Input)96409467b48Spatrick sortLocalVars(SmallVectorImpl<DbgVariable *> &Input) {
96509467b48Spatrick   SmallVector<DbgVariable *, 8> Result;
96609467b48Spatrick   SmallVector<PointerIntPair<DbgVariable *, 1>, 8> WorkList;
96709467b48Spatrick   // Map back from a DIVariable to its containing DbgVariable.
96809467b48Spatrick   SmallDenseMap<const DILocalVariable *, DbgVariable *> DbgVar;
96909467b48Spatrick   // Set of DbgVariables in Result.
97009467b48Spatrick   SmallDenseSet<DbgVariable *, 8> Visited;
97109467b48Spatrick   // For cycle detection.
97209467b48Spatrick   SmallDenseSet<DbgVariable *, 8> Visiting;
97309467b48Spatrick 
97409467b48Spatrick   // Initialize the worklist and the DIVariable lookup table.
975*d415bd75Srobert   for (auto *Var : reverse(Input)) {
97609467b48Spatrick     DbgVar.insert({Var->getVariable(), Var});
97709467b48Spatrick     WorkList.push_back({Var, 0});
97809467b48Spatrick   }
97909467b48Spatrick 
98009467b48Spatrick   // Perform a stable topological sort by doing a DFS.
98109467b48Spatrick   while (!WorkList.empty()) {
98209467b48Spatrick     auto Item = WorkList.back();
98309467b48Spatrick     DbgVariable *Var = Item.getPointer();
98409467b48Spatrick     bool visitedAllDependencies = Item.getInt();
98509467b48Spatrick     WorkList.pop_back();
98609467b48Spatrick 
987*d415bd75Srobert     assert(Var);
98809467b48Spatrick 
98909467b48Spatrick     // Already handled.
99009467b48Spatrick     if (Visited.count(Var))
99109467b48Spatrick       continue;
99209467b48Spatrick 
99309467b48Spatrick     // Add to Result if all dependencies are visited.
99409467b48Spatrick     if (visitedAllDependencies) {
99509467b48Spatrick       Visited.insert(Var);
99609467b48Spatrick       Result.push_back(Var);
99709467b48Spatrick       continue;
99809467b48Spatrick     }
99909467b48Spatrick 
100009467b48Spatrick     // Detect cycles.
100109467b48Spatrick     auto Res = Visiting.insert(Var);
100209467b48Spatrick     if (!Res.second) {
100309467b48Spatrick       assert(false && "dependency cycle in local variables");
100409467b48Spatrick       return Result;
100509467b48Spatrick     }
100609467b48Spatrick 
100709467b48Spatrick     // Push dependencies and this node onto the worklist, so that this node is
100809467b48Spatrick     // visited again after all of its dependencies are handled.
100909467b48Spatrick     WorkList.push_back({Var, 1});
1010*d415bd75Srobert     for (const auto *Dependency : dependencies(Var)) {
1011*d415bd75Srobert       // Don't add dependency if it is in a different lexical scope or a global.
1012*d415bd75Srobert       if (const auto *Dep = dyn_cast<const DILocalVariable>(Dependency))
1013*d415bd75Srobert         if (DbgVariable *Var = DbgVar.lookup(Dep))
1014*d415bd75Srobert           WorkList.push_back({Var, 0});
101509467b48Spatrick     }
101609467b48Spatrick   }
101709467b48Spatrick   return Result;
101809467b48Spatrick }
101909467b48Spatrick 
constructSubprogramScopeDIE(const DISubprogram * Sub,LexicalScope * Scope)102009467b48Spatrick DIE &DwarfCompileUnit::constructSubprogramScopeDIE(const DISubprogram *Sub,
102109467b48Spatrick                                                    LexicalScope *Scope) {
102209467b48Spatrick   DIE &ScopeDIE = updateSubprogramScopeDIE(Sub);
1023*d415bd75Srobert   auto *ContextCU = static_cast<DwarfCompileUnit *>(ScopeDIE.getUnit());
102409467b48Spatrick 
102509467b48Spatrick   if (Scope) {
102609467b48Spatrick     assert(!Scope->getInlinedAt());
102709467b48Spatrick     assert(!Scope->isAbstractScope());
102809467b48Spatrick     // Collect lexical scope children first.
102909467b48Spatrick     // ObjectPointer might be a local (non-argument) local variable if it's a
103009467b48Spatrick     // block's synthetic this pointer.
1031*d415bd75Srobert     if (DIE *ObjectPointer =
1032*d415bd75Srobert             ContextCU->createAndAddScopeChildren(Scope, ScopeDIE))
1033*d415bd75Srobert       ContextCU->addDIEEntry(ScopeDIE, dwarf::DW_AT_object_pointer,
1034*d415bd75Srobert                              *ObjectPointer);
103509467b48Spatrick   }
103609467b48Spatrick 
103709467b48Spatrick   // If this is a variadic function, add an unspecified parameter.
103809467b48Spatrick   DITypeRefArray FnArgs = Sub->getType()->getTypeArray();
103909467b48Spatrick 
104009467b48Spatrick   // If we have a single element of null, it is a function that returns void.
104109467b48Spatrick   // If we have more than one elements and the last one is null, it is a
104209467b48Spatrick   // variadic function.
104309467b48Spatrick   if (FnArgs.size() > 1 && !FnArgs[FnArgs.size() - 1] &&
104409467b48Spatrick       !includeMinimalInlineScopes())
104509467b48Spatrick     ScopeDIE.addChild(
104609467b48Spatrick         DIE::get(DIEValueAllocator, dwarf::DW_TAG_unspecified_parameters));
104709467b48Spatrick 
104809467b48Spatrick   return ScopeDIE;
104909467b48Spatrick }
105009467b48Spatrick 
createAndAddScopeChildren(LexicalScope * Scope,DIE & ScopeDIE)105109467b48Spatrick DIE *DwarfCompileUnit::createAndAddScopeChildren(LexicalScope *Scope,
105209467b48Spatrick                                                  DIE &ScopeDIE) {
1053*d415bd75Srobert   DIE *ObjectPointer = nullptr;
105409467b48Spatrick 
1055*d415bd75Srobert   // Emit function arguments (order is significant).
1056*d415bd75Srobert   auto Vars = DU->getScopeVariables().lookup(Scope);
1057*d415bd75Srobert   for (auto &DV : Vars.Args)
1058*d415bd75Srobert     ScopeDIE.addChild(constructVariableDIE(*DV.second, *Scope, ObjectPointer));
1059*d415bd75Srobert 
1060*d415bd75Srobert   // Emit local variables.
1061*d415bd75Srobert   auto Locals = sortLocalVars(Vars.Locals);
1062*d415bd75Srobert   for (DbgVariable *DV : Locals)
1063*d415bd75Srobert     ScopeDIE.addChild(constructVariableDIE(*DV, *Scope, ObjectPointer));
1064*d415bd75Srobert 
1065*d415bd75Srobert   // Emit imported entities (skipped in gmlt-like data).
1066*d415bd75Srobert   if (!includeMinimalInlineScopes()) {
1067*d415bd75Srobert     for (const auto *IE : ImportedEntities[Scope->getScopeNode()])
1068*d415bd75Srobert       ScopeDIE.addChild(constructImportedEntityDIE(cast<DIImportedEntity>(IE)));
1069*d415bd75Srobert   }
1070*d415bd75Srobert 
1071*d415bd75Srobert   // Emit labels.
1072*d415bd75Srobert   for (DbgLabel *DL : DU->getScopeLabels().lookup(Scope))
1073*d415bd75Srobert     ScopeDIE.addChild(constructLabelDIE(*DL, *Scope));
1074*d415bd75Srobert 
1075*d415bd75Srobert   // Emit inner lexical scopes.
1076*d415bd75Srobert   auto needToEmitLexicalScope = [this](LexicalScope *LS) {
1077*d415bd75Srobert     if (isa<DISubprogram>(LS->getScopeNode()))
1078*d415bd75Srobert       return true;
1079*d415bd75Srobert     auto Vars = DU->getScopeVariables().lookup(LS);
1080*d415bd75Srobert     if (!Vars.Args.empty() || !Vars.Locals.empty())
1081*d415bd75Srobert       return true;
1082*d415bd75Srobert     if (!includeMinimalInlineScopes() &&
1083*d415bd75Srobert         !ImportedEntities[LS->getScopeNode()].empty())
1084*d415bd75Srobert       return true;
1085*d415bd75Srobert     return false;
1086*d415bd75Srobert   };
1087*d415bd75Srobert   for (LexicalScope *LS : Scope->getChildren()) {
1088*d415bd75Srobert     // If the lexical block doesn't have non-scope children, skip
1089*d415bd75Srobert     // its emission and put its children directly to the parent scope.
1090*d415bd75Srobert     if (needToEmitLexicalScope(LS))
1091*d415bd75Srobert       constructScopeDIE(LS, ScopeDIE);
1092*d415bd75Srobert     else
1093*d415bd75Srobert       createAndAddScopeChildren(LS, ScopeDIE);
1094*d415bd75Srobert   }
109509467b48Spatrick 
109609467b48Spatrick   return ObjectPointer;
109709467b48Spatrick }
109809467b48Spatrick 
constructAbstractSubprogramScopeDIE(LexicalScope * Scope)109909467b48Spatrick void DwarfCompileUnit::constructAbstractSubprogramScopeDIE(
110009467b48Spatrick     LexicalScope *Scope) {
110109467b48Spatrick   DIE *&AbsDef = getAbstractSPDies()[Scope->getScopeNode()];
110209467b48Spatrick   if (AbsDef)
110309467b48Spatrick     return;
110409467b48Spatrick 
110509467b48Spatrick   auto *SP = cast<DISubprogram>(Scope->getScopeNode());
110609467b48Spatrick 
110709467b48Spatrick   DIE *ContextDIE;
110809467b48Spatrick   DwarfCompileUnit *ContextCU = this;
110909467b48Spatrick 
111009467b48Spatrick   if (includeMinimalInlineScopes())
111109467b48Spatrick     ContextDIE = &getUnitDie();
111209467b48Spatrick   // Some of this is duplicated from DwarfUnit::getOrCreateSubprogramDIE, with
111309467b48Spatrick   // the important distinction that the debug node is not associated with the
111409467b48Spatrick   // DIE (since the debug node will be associated with the concrete DIE, if
111509467b48Spatrick   // any). It could be refactored to some common utility function.
111609467b48Spatrick   else if (auto *SPDecl = SP->getDeclaration()) {
111709467b48Spatrick     ContextDIE = &getUnitDie();
111809467b48Spatrick     getOrCreateSubprogramDIE(SPDecl);
111909467b48Spatrick   } else {
112009467b48Spatrick     ContextDIE = getOrCreateContextDIE(SP->getScope());
112109467b48Spatrick     // The scope may be shared with a subprogram that has already been
112209467b48Spatrick     // constructed in another CU, in which case we need to construct this
112309467b48Spatrick     // subprogram in the same CU.
112409467b48Spatrick     ContextCU = DD->lookupCU(ContextDIE->getUnitDie());
112509467b48Spatrick   }
112609467b48Spatrick 
112709467b48Spatrick   // Passing null as the associated node because the abstract definition
112809467b48Spatrick   // shouldn't be found by lookup.
112909467b48Spatrick   AbsDef = &ContextCU->createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE, nullptr);
113009467b48Spatrick   ContextCU->applySubprogramAttributesToDefinition(SP, *AbsDef);
1131*d415bd75Srobert   ContextCU->addSInt(*AbsDef, dwarf::DW_AT_inline,
1132*d415bd75Srobert                      DD->getDwarfVersion() <= 4 ? std::optional<dwarf::Form>()
1133*d415bd75Srobert                                                 : dwarf::DW_FORM_implicit_const,
1134*d415bd75Srobert                      dwarf::DW_INL_inlined);
113509467b48Spatrick   if (DIE *ObjectPointer = ContextCU->createAndAddScopeChildren(Scope, *AbsDef))
113609467b48Spatrick     ContextCU->addDIEEntry(*AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer);
113709467b48Spatrick }
113809467b48Spatrick 
useGNUAnalogForDwarf5Feature() const1139097a140dSpatrick bool DwarfCompileUnit::useGNUAnalogForDwarf5Feature() const {
114073471bf0Spatrick   return DD->getDwarfVersion() == 4 && !DD->tuneForLLDB();
114109467b48Spatrick }
114209467b48Spatrick 
getDwarf5OrGNUTag(dwarf::Tag Tag) const114309467b48Spatrick dwarf::Tag DwarfCompileUnit::getDwarf5OrGNUTag(dwarf::Tag Tag) const {
1144097a140dSpatrick   if (!useGNUAnalogForDwarf5Feature())
114509467b48Spatrick     return Tag;
114609467b48Spatrick   switch (Tag) {
114709467b48Spatrick   case dwarf::DW_TAG_call_site:
114809467b48Spatrick     return dwarf::DW_TAG_GNU_call_site;
114909467b48Spatrick   case dwarf::DW_TAG_call_site_parameter:
115009467b48Spatrick     return dwarf::DW_TAG_GNU_call_site_parameter;
115109467b48Spatrick   default:
115209467b48Spatrick     llvm_unreachable("DWARF5 tag with no GNU analog");
115309467b48Spatrick   }
115409467b48Spatrick }
115509467b48Spatrick 
115609467b48Spatrick dwarf::Attribute
getDwarf5OrGNUAttr(dwarf::Attribute Attr) const115709467b48Spatrick DwarfCompileUnit::getDwarf5OrGNUAttr(dwarf::Attribute Attr) const {
1158097a140dSpatrick   if (!useGNUAnalogForDwarf5Feature())
115909467b48Spatrick     return Attr;
116009467b48Spatrick   switch (Attr) {
116109467b48Spatrick   case dwarf::DW_AT_call_all_calls:
116209467b48Spatrick     return dwarf::DW_AT_GNU_all_call_sites;
116309467b48Spatrick   case dwarf::DW_AT_call_target:
116409467b48Spatrick     return dwarf::DW_AT_GNU_call_site_target;
116509467b48Spatrick   case dwarf::DW_AT_call_origin:
116609467b48Spatrick     return dwarf::DW_AT_abstract_origin;
1167097a140dSpatrick   case dwarf::DW_AT_call_return_pc:
116809467b48Spatrick     return dwarf::DW_AT_low_pc;
116909467b48Spatrick   case dwarf::DW_AT_call_value:
117009467b48Spatrick     return dwarf::DW_AT_GNU_call_site_value;
117109467b48Spatrick   case dwarf::DW_AT_call_tail_call:
117209467b48Spatrick     return dwarf::DW_AT_GNU_tail_call;
117309467b48Spatrick   default:
117409467b48Spatrick     llvm_unreachable("DWARF5 attribute with no GNU analog");
117509467b48Spatrick   }
117609467b48Spatrick }
117709467b48Spatrick 
117809467b48Spatrick dwarf::LocationAtom
getDwarf5OrGNULocationAtom(dwarf::LocationAtom Loc) const117909467b48Spatrick DwarfCompileUnit::getDwarf5OrGNULocationAtom(dwarf::LocationAtom Loc) const {
1180097a140dSpatrick   if (!useGNUAnalogForDwarf5Feature())
118109467b48Spatrick     return Loc;
118209467b48Spatrick   switch (Loc) {
118309467b48Spatrick   case dwarf::DW_OP_entry_value:
118409467b48Spatrick     return dwarf::DW_OP_GNU_entry_value;
118509467b48Spatrick   default:
118609467b48Spatrick     llvm_unreachable("DWARF5 location atom with no GNU analog");
118709467b48Spatrick   }
118809467b48Spatrick }
118909467b48Spatrick 
constructCallSiteEntryDIE(DIE & ScopeDIE,const DISubprogram * CalleeSP,bool IsTail,const MCSymbol * PCAddr,const MCSymbol * CallAddr,unsigned CallReg)1190097a140dSpatrick DIE &DwarfCompileUnit::constructCallSiteEntryDIE(DIE &ScopeDIE,
119173471bf0Spatrick                                                  const DISubprogram *CalleeSP,
1192097a140dSpatrick                                                  bool IsTail,
1193097a140dSpatrick                                                  const MCSymbol *PCAddr,
1194097a140dSpatrick                                                  const MCSymbol *CallAddr,
1195097a140dSpatrick                                                  unsigned CallReg) {
119609467b48Spatrick   // Insert a call site entry DIE within ScopeDIE.
119709467b48Spatrick   DIE &CallSiteDIE = createAndAddDIE(getDwarf5OrGNUTag(dwarf::DW_TAG_call_site),
119809467b48Spatrick                                      ScopeDIE, nullptr);
119909467b48Spatrick 
120009467b48Spatrick   if (CallReg) {
120109467b48Spatrick     // Indirect call.
120209467b48Spatrick     addAddress(CallSiteDIE, getDwarf5OrGNUAttr(dwarf::DW_AT_call_target),
120309467b48Spatrick                MachineLocation(CallReg));
120409467b48Spatrick   } else {
120573471bf0Spatrick     DIE *CalleeDIE = getOrCreateSubprogramDIE(CalleeSP);
120673471bf0Spatrick     assert(CalleeDIE && "Could not create DIE for call site entry origin");
120709467b48Spatrick     addDIEEntry(CallSiteDIE, getDwarf5OrGNUAttr(dwarf::DW_AT_call_origin),
120809467b48Spatrick                 *CalleeDIE);
120909467b48Spatrick   }
121009467b48Spatrick 
1211097a140dSpatrick   if (IsTail) {
121209467b48Spatrick     // Attach DW_AT_call_tail_call to tail calls for standards compliance.
121309467b48Spatrick     addFlag(CallSiteDIE, getDwarf5OrGNUAttr(dwarf::DW_AT_call_tail_call));
121409467b48Spatrick 
1215097a140dSpatrick     // Attach the address of the branch instruction to allow the debugger to
1216097a140dSpatrick     // show where the tail call occurred. This attribute has no GNU analog.
1217097a140dSpatrick     //
1218097a140dSpatrick     // GDB works backwards from non-standard usage of DW_AT_low_pc (in DWARF4
1219097a140dSpatrick     // mode -- equivalently, in DWARF5 mode, DW_AT_call_return_pc) at tail-call
1220097a140dSpatrick     // site entries to figure out the PC of tail-calling branch instructions.
1221097a140dSpatrick     // This means it doesn't need the compiler to emit DW_AT_call_pc, so we
1222097a140dSpatrick     // don't emit it here.
1223097a140dSpatrick     //
1224097a140dSpatrick     // There's no need to tie non-GDB debuggers to this non-standardness, as it
1225097a140dSpatrick     // adds unnecessary complexity to the debugger. For non-GDB debuggers, emit
1226097a140dSpatrick     // the standard DW_AT_call_pc info.
1227097a140dSpatrick     if (!useGNUAnalogForDwarf5Feature())
1228097a140dSpatrick       addLabelAddress(CallSiteDIE, dwarf::DW_AT_call_pc, CallAddr);
1229097a140dSpatrick   }
1230097a140dSpatrick 
123109467b48Spatrick   // Attach the return PC to allow the debugger to disambiguate call paths
123209467b48Spatrick   // from one function to another.
1233097a140dSpatrick   //
1234097a140dSpatrick   // The return PC is only really needed when the call /isn't/ a tail call, but
1235097a140dSpatrick   // GDB expects it in DWARF4 mode, even for tail calls (see the comment above
1236097a140dSpatrick   // the DW_AT_call_pc emission logic for an explanation).
1237097a140dSpatrick   if (!IsTail || useGNUAnalogForDwarf5Feature()) {
1238097a140dSpatrick     assert(PCAddr && "Missing return PC information for a call");
1239097a140dSpatrick     addLabelAddress(CallSiteDIE,
1240097a140dSpatrick                     getDwarf5OrGNUAttr(dwarf::DW_AT_call_return_pc), PCAddr);
124109467b48Spatrick   }
124209467b48Spatrick 
124309467b48Spatrick   return CallSiteDIE;
124409467b48Spatrick }
124509467b48Spatrick 
constructCallSiteParmEntryDIEs(DIE & CallSiteDIE,SmallVector<DbgCallSiteParam,4> & Params)124609467b48Spatrick void DwarfCompileUnit::constructCallSiteParmEntryDIEs(
124709467b48Spatrick     DIE &CallSiteDIE, SmallVector<DbgCallSiteParam, 4> &Params) {
124809467b48Spatrick   for (const auto &Param : Params) {
124909467b48Spatrick     unsigned Register = Param.getRegister();
125009467b48Spatrick     auto CallSiteDieParam =
125109467b48Spatrick         DIE::get(DIEValueAllocator,
125209467b48Spatrick                  getDwarf5OrGNUTag(dwarf::DW_TAG_call_site_parameter));
125309467b48Spatrick     insertDIE(CallSiteDieParam);
125409467b48Spatrick     addAddress(*CallSiteDieParam, dwarf::DW_AT_location,
125509467b48Spatrick                MachineLocation(Register));
125609467b48Spatrick 
125709467b48Spatrick     DIELoc *Loc = new (DIEValueAllocator) DIELoc;
125809467b48Spatrick     DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
125909467b48Spatrick     DwarfExpr.setCallSiteParamValueFlag();
126009467b48Spatrick 
126109467b48Spatrick     DwarfDebug::emitDebugLocValue(*Asm, nullptr, Param.getValue(), DwarfExpr);
126209467b48Spatrick 
126309467b48Spatrick     addBlock(*CallSiteDieParam, getDwarf5OrGNUAttr(dwarf::DW_AT_call_value),
126409467b48Spatrick              DwarfExpr.finalize());
126509467b48Spatrick 
126609467b48Spatrick     CallSiteDIE.addChild(CallSiteDieParam);
126709467b48Spatrick   }
126809467b48Spatrick }
126909467b48Spatrick 
constructImportedEntityDIE(const DIImportedEntity * Module)127009467b48Spatrick DIE *DwarfCompileUnit::constructImportedEntityDIE(
127109467b48Spatrick     const DIImportedEntity *Module) {
127209467b48Spatrick   DIE *IMDie = DIE::get(DIEValueAllocator, (dwarf::Tag)Module->getTag());
127309467b48Spatrick   insertDIE(Module, IMDie);
127409467b48Spatrick   DIE *EntityDie;
127509467b48Spatrick   auto *Entity = Module->getEntity();
127609467b48Spatrick   if (auto *NS = dyn_cast<DINamespace>(Entity))
127709467b48Spatrick     EntityDie = getOrCreateNameSpace(NS);
127809467b48Spatrick   else if (auto *M = dyn_cast<DIModule>(Entity))
127909467b48Spatrick     EntityDie = getOrCreateModule(M);
128009467b48Spatrick   else if (auto *SP = dyn_cast<DISubprogram>(Entity))
128109467b48Spatrick     EntityDie = getOrCreateSubprogramDIE(SP);
128209467b48Spatrick   else if (auto *T = dyn_cast<DIType>(Entity))
128309467b48Spatrick     EntityDie = getOrCreateTypeDIE(T);
128409467b48Spatrick   else if (auto *GV = dyn_cast<DIGlobalVariable>(Entity))
128509467b48Spatrick     EntityDie = getOrCreateGlobalVariableDIE(GV, {});
128609467b48Spatrick   else
128709467b48Spatrick     EntityDie = getDIE(Entity);
128809467b48Spatrick   assert(EntityDie);
128909467b48Spatrick   addSourceLine(*IMDie, Module->getLine(), Module->getFile());
129009467b48Spatrick   addDIEEntry(*IMDie, dwarf::DW_AT_import, *EntityDie);
129109467b48Spatrick   StringRef Name = Module->getName();
129209467b48Spatrick   if (!Name.empty())
129309467b48Spatrick     addString(*IMDie, dwarf::DW_AT_name, Name);
129409467b48Spatrick 
1295*d415bd75Srobert   // This is for imported module with renamed entities (such as variables and
1296*d415bd75Srobert   // subprograms).
1297*d415bd75Srobert   DINodeArray Elements = Module->getElements();
1298*d415bd75Srobert   for (const auto *Element : Elements) {
1299*d415bd75Srobert     if (!Element)
1300*d415bd75Srobert       continue;
1301*d415bd75Srobert     IMDie->addChild(
1302*d415bd75Srobert         constructImportedEntityDIE(cast<DIImportedEntity>(Element)));
1303*d415bd75Srobert   }
1304*d415bd75Srobert 
130509467b48Spatrick   return IMDie;
130609467b48Spatrick }
130709467b48Spatrick 
finishSubprogramDefinition(const DISubprogram * SP)130809467b48Spatrick void DwarfCompileUnit::finishSubprogramDefinition(const DISubprogram *SP) {
130909467b48Spatrick   DIE *D = getDIE(SP);
131009467b48Spatrick   if (DIE *AbsSPDIE = getAbstractSPDies().lookup(SP)) {
131109467b48Spatrick     if (D)
131209467b48Spatrick       // If this subprogram has an abstract definition, reference that
131309467b48Spatrick       addDIEEntry(*D, dwarf::DW_AT_abstract_origin, *AbsSPDIE);
131409467b48Spatrick   } else {
131509467b48Spatrick     assert(D || includeMinimalInlineScopes());
131609467b48Spatrick     if (D)
131709467b48Spatrick       // And attach the attributes
131809467b48Spatrick       applySubprogramAttributesToDefinition(SP, *D);
131909467b48Spatrick   }
132009467b48Spatrick }
132109467b48Spatrick 
finishEntityDefinition(const DbgEntity * Entity)132209467b48Spatrick void DwarfCompileUnit::finishEntityDefinition(const DbgEntity *Entity) {
132309467b48Spatrick   DbgEntity *AbsEntity = getExistingAbstractEntity(Entity->getEntity());
132409467b48Spatrick 
132509467b48Spatrick   auto *Die = Entity->getDIE();
132609467b48Spatrick   /// Label may be used to generate DW_AT_low_pc, so put it outside
132709467b48Spatrick   /// if/else block.
132809467b48Spatrick   const DbgLabel *Label = nullptr;
132909467b48Spatrick   if (AbsEntity && AbsEntity->getDIE()) {
133009467b48Spatrick     addDIEEntry(*Die, dwarf::DW_AT_abstract_origin, *AbsEntity->getDIE());
133109467b48Spatrick     Label = dyn_cast<const DbgLabel>(Entity);
133209467b48Spatrick   } else {
133309467b48Spatrick     if (const DbgVariable *Var = dyn_cast<const DbgVariable>(Entity))
133409467b48Spatrick       applyVariableAttributes(*Var, *Die);
133509467b48Spatrick     else if ((Label = dyn_cast<const DbgLabel>(Entity)))
133609467b48Spatrick       applyLabelAttributes(*Label, *Die);
133709467b48Spatrick     else
133809467b48Spatrick       llvm_unreachable("DbgEntity must be DbgVariable or DbgLabel.");
133909467b48Spatrick   }
134009467b48Spatrick 
134109467b48Spatrick   if (Label)
134209467b48Spatrick     if (const auto *Sym = Label->getSymbol())
134309467b48Spatrick       addLabelAddress(*Die, dwarf::DW_AT_low_pc, Sym);
134409467b48Spatrick }
134509467b48Spatrick 
getExistingAbstractEntity(const DINode * Node)134609467b48Spatrick DbgEntity *DwarfCompileUnit::getExistingAbstractEntity(const DINode *Node) {
134709467b48Spatrick   auto &AbstractEntities = getAbstractEntities();
134809467b48Spatrick   auto I = AbstractEntities.find(Node);
134909467b48Spatrick   if (I != AbstractEntities.end())
135009467b48Spatrick     return I->second.get();
135109467b48Spatrick   return nullptr;
135209467b48Spatrick }
135309467b48Spatrick 
createAbstractEntity(const DINode * Node,LexicalScope * Scope)135409467b48Spatrick void DwarfCompileUnit::createAbstractEntity(const DINode *Node,
135509467b48Spatrick                                             LexicalScope *Scope) {
135609467b48Spatrick   assert(Scope && Scope->isAbstractScope());
135709467b48Spatrick   auto &Entity = getAbstractEntities()[Node];
135809467b48Spatrick   if (isa<const DILocalVariable>(Node)) {
135909467b48Spatrick     Entity = std::make_unique<DbgVariable>(
136009467b48Spatrick                         cast<const DILocalVariable>(Node), nullptr /* IA */);;
136109467b48Spatrick     DU->addScopeVariable(Scope, cast<DbgVariable>(Entity.get()));
136209467b48Spatrick   } else if (isa<const DILabel>(Node)) {
136309467b48Spatrick     Entity = std::make_unique<DbgLabel>(
136409467b48Spatrick                         cast<const DILabel>(Node), nullptr /* IA */);
136509467b48Spatrick     DU->addScopeLabel(Scope, cast<DbgLabel>(Entity.get()));
136609467b48Spatrick   }
136709467b48Spatrick }
136809467b48Spatrick 
emitHeader(bool UseOffsets)136909467b48Spatrick void DwarfCompileUnit::emitHeader(bool UseOffsets) {
137009467b48Spatrick   // Don't bother labeling the .dwo unit, as its offset isn't used.
137109467b48Spatrick   if (!Skeleton && !DD->useSectionsAsReferences()) {
137209467b48Spatrick     LabelBegin = Asm->createTempSymbol("cu_begin");
1373097a140dSpatrick     Asm->OutStreamer->emitLabel(LabelBegin);
137409467b48Spatrick   }
137509467b48Spatrick 
137609467b48Spatrick   dwarf::UnitType UT = Skeleton ? dwarf::DW_UT_split_compile
137709467b48Spatrick                                 : DD->useSplitDwarf() ? dwarf::DW_UT_skeleton
137809467b48Spatrick                                                       : dwarf::DW_UT_compile;
137909467b48Spatrick   DwarfUnit::emitCommonHeader(UseOffsets, UT);
138009467b48Spatrick   if (DD->getDwarfVersion() >= 5 && UT != dwarf::DW_UT_compile)
138109467b48Spatrick     Asm->emitInt64(getDWOId());
138209467b48Spatrick }
138309467b48Spatrick 
hasDwarfPubSections() const138409467b48Spatrick bool DwarfCompileUnit::hasDwarfPubSections() const {
138509467b48Spatrick   switch (CUNode->getNameTableKind()) {
138609467b48Spatrick   case DICompileUnit::DebugNameTableKind::None:
138709467b48Spatrick     return false;
138809467b48Spatrick     // Opting in to GNU Pubnames/types overrides the default to ensure these are
138909467b48Spatrick     // generated for things like Gold's gdb_index generation.
139009467b48Spatrick   case DICompileUnit::DebugNameTableKind::GNU:
139109467b48Spatrick     return true;
139209467b48Spatrick   case DICompileUnit::DebugNameTableKind::Default:
139309467b48Spatrick     return DD->tuneForGDB() && !includeMinimalInlineScopes() &&
139409467b48Spatrick            !CUNode->isDebugDirectivesOnly() &&
139509467b48Spatrick            DD->getAccelTableKind() != AccelTableKind::Apple &&
139609467b48Spatrick            DD->getDwarfVersion() < 5;
139709467b48Spatrick   }
139809467b48Spatrick   llvm_unreachable("Unhandled DICompileUnit::DebugNameTableKind enum");
139909467b48Spatrick }
140009467b48Spatrick 
140109467b48Spatrick /// addGlobalName - Add a new global name to the compile unit.
addGlobalName(StringRef Name,const DIE & Die,const DIScope * Context)140209467b48Spatrick void DwarfCompileUnit::addGlobalName(StringRef Name, const DIE &Die,
140309467b48Spatrick                                      const DIScope *Context) {
140409467b48Spatrick   if (!hasDwarfPubSections())
140509467b48Spatrick     return;
140609467b48Spatrick   std::string FullName = getParentContextString(Context) + Name.str();
140709467b48Spatrick   GlobalNames[FullName] = &Die;
140809467b48Spatrick }
140909467b48Spatrick 
addGlobalNameForTypeUnit(StringRef Name,const DIScope * Context)141009467b48Spatrick void DwarfCompileUnit::addGlobalNameForTypeUnit(StringRef Name,
141109467b48Spatrick                                                 const DIScope *Context) {
141209467b48Spatrick   if (!hasDwarfPubSections())
141309467b48Spatrick     return;
141409467b48Spatrick   std::string FullName = getParentContextString(Context) + Name.str();
141509467b48Spatrick   // Insert, allowing the entry to remain as-is if it's already present
141609467b48Spatrick   // This way the CU-level type DIE is preferred over the "can't describe this
141709467b48Spatrick   // type as a unit offset because it's not really in the CU at all, it's only
141809467b48Spatrick   // in a type unit"
141909467b48Spatrick   GlobalNames.insert(std::make_pair(std::move(FullName), &getUnitDie()));
142009467b48Spatrick }
142109467b48Spatrick 
142209467b48Spatrick /// Add a new global type to the unit.
addGlobalType(const DIType * Ty,const DIE & Die,const DIScope * Context)142309467b48Spatrick void DwarfCompileUnit::addGlobalType(const DIType *Ty, const DIE &Die,
142409467b48Spatrick                                      const DIScope *Context) {
142509467b48Spatrick   if (!hasDwarfPubSections())
142609467b48Spatrick     return;
142709467b48Spatrick   std::string FullName = getParentContextString(Context) + Ty->getName().str();
142809467b48Spatrick   GlobalTypes[FullName] = &Die;
142909467b48Spatrick }
143009467b48Spatrick 
addGlobalTypeUnitType(const DIType * Ty,const DIScope * Context)143109467b48Spatrick void DwarfCompileUnit::addGlobalTypeUnitType(const DIType *Ty,
143209467b48Spatrick                                              const DIScope *Context) {
143309467b48Spatrick   if (!hasDwarfPubSections())
143409467b48Spatrick     return;
143509467b48Spatrick   std::string FullName = getParentContextString(Context) + Ty->getName().str();
143609467b48Spatrick   // Insert, allowing the entry to remain as-is if it's already present
143709467b48Spatrick   // This way the CU-level type DIE is preferred over the "can't describe this
143809467b48Spatrick   // type as a unit offset because it's not really in the CU at all, it's only
143909467b48Spatrick   // in a type unit"
144009467b48Spatrick   GlobalTypes.insert(std::make_pair(std::move(FullName), &getUnitDie()));
144109467b48Spatrick }
144209467b48Spatrick 
addVariableAddress(const DbgVariable & DV,DIE & Die,MachineLocation Location)144309467b48Spatrick void DwarfCompileUnit::addVariableAddress(const DbgVariable &DV, DIE &Die,
144409467b48Spatrick                                           MachineLocation Location) {
144509467b48Spatrick   if (DV.hasComplexAddress())
144609467b48Spatrick     addComplexAddress(DV, Die, dwarf::DW_AT_location, Location);
144709467b48Spatrick   else
144809467b48Spatrick     addAddress(Die, dwarf::DW_AT_location, Location);
144909467b48Spatrick }
145009467b48Spatrick 
145109467b48Spatrick /// Add an address attribute to a die based on the location provided.
addAddress(DIE & Die,dwarf::Attribute Attribute,const MachineLocation & Location)145209467b48Spatrick void DwarfCompileUnit::addAddress(DIE &Die, dwarf::Attribute Attribute,
145309467b48Spatrick                                   const MachineLocation &Location) {
145409467b48Spatrick   DIELoc *Loc = new (DIEValueAllocator) DIELoc;
145509467b48Spatrick   DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
145609467b48Spatrick   if (Location.isIndirect())
145709467b48Spatrick     DwarfExpr.setMemoryLocationKind();
145809467b48Spatrick 
145909467b48Spatrick   DIExpressionCursor Cursor({});
146009467b48Spatrick   const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();
146109467b48Spatrick   if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
146209467b48Spatrick     return;
146309467b48Spatrick   DwarfExpr.addExpression(std::move(Cursor));
146409467b48Spatrick 
146509467b48Spatrick   // Now attach the location information to the DIE.
146609467b48Spatrick   addBlock(Die, Attribute, DwarfExpr.finalize());
146709467b48Spatrick 
146809467b48Spatrick   if (DwarfExpr.TagOffset)
146909467b48Spatrick     addUInt(Die, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,
147009467b48Spatrick             *DwarfExpr.TagOffset);
147109467b48Spatrick }
147209467b48Spatrick 
147309467b48Spatrick /// Start with the address based on the location provided, and generate the
147409467b48Spatrick /// DWARF information necessary to find the actual variable given the extra
147509467b48Spatrick /// address information encoded in the DbgVariable, starting from the starting
147609467b48Spatrick /// location.  Add the DWARF information to the die.
addComplexAddress(const DbgVariable & DV,DIE & Die,dwarf::Attribute Attribute,const MachineLocation & Location)147709467b48Spatrick void DwarfCompileUnit::addComplexAddress(const DbgVariable &DV, DIE &Die,
147809467b48Spatrick                                          dwarf::Attribute Attribute,
147909467b48Spatrick                                          const MachineLocation &Location) {
148009467b48Spatrick   DIELoc *Loc = new (DIEValueAllocator) DIELoc;
148109467b48Spatrick   DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
148209467b48Spatrick   const DIExpression *DIExpr = DV.getSingleExpression();
148309467b48Spatrick   DwarfExpr.addFragmentOffset(DIExpr);
1484097a140dSpatrick   DwarfExpr.setLocation(Location, DIExpr);
148509467b48Spatrick 
148609467b48Spatrick   DIExpressionCursor Cursor(DIExpr);
148709467b48Spatrick 
1488097a140dSpatrick   if (DIExpr->isEntryValue())
148909467b48Spatrick     DwarfExpr.beginEntryValueExpression(Cursor);
149009467b48Spatrick 
149109467b48Spatrick   const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();
149209467b48Spatrick   if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
149309467b48Spatrick     return;
149409467b48Spatrick   DwarfExpr.addExpression(std::move(Cursor));
149509467b48Spatrick 
149609467b48Spatrick   // Now attach the location information to the DIE.
149709467b48Spatrick   addBlock(Die, Attribute, DwarfExpr.finalize());
149809467b48Spatrick 
149909467b48Spatrick   if (DwarfExpr.TagOffset)
150009467b48Spatrick     addUInt(Die, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,
150109467b48Spatrick             *DwarfExpr.TagOffset);
150209467b48Spatrick }
150309467b48Spatrick 
150409467b48Spatrick /// Add a Dwarf loclistptr attribute data and value.
addLocationList(DIE & Die,dwarf::Attribute Attribute,unsigned Index)150509467b48Spatrick void DwarfCompileUnit::addLocationList(DIE &Die, dwarf::Attribute Attribute,
150609467b48Spatrick                                        unsigned Index) {
150773471bf0Spatrick   dwarf::Form Form = (DD->getDwarfVersion() >= 5)
150873471bf0Spatrick                          ? dwarf::DW_FORM_loclistx
150973471bf0Spatrick                          : DD->getDwarfSectionOffsetForm();
151073471bf0Spatrick   addAttribute(Die, Attribute, Form, DIELocList(Index));
151109467b48Spatrick }
151209467b48Spatrick 
applyVariableAttributes(const DbgVariable & Var,DIE & VariableDie)151309467b48Spatrick void DwarfCompileUnit::applyVariableAttributes(const DbgVariable &Var,
151409467b48Spatrick                                                DIE &VariableDie) {
151509467b48Spatrick   StringRef Name = Var.getName();
151609467b48Spatrick   if (!Name.empty())
151709467b48Spatrick     addString(VariableDie, dwarf::DW_AT_name, Name);
151809467b48Spatrick   const auto *DIVar = Var.getVariable();
1519*d415bd75Srobert   if (DIVar) {
152009467b48Spatrick     if (uint32_t AlignInBytes = DIVar->getAlignInBytes())
152109467b48Spatrick       addUInt(VariableDie, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,
152209467b48Spatrick               AlignInBytes);
1523*d415bd75Srobert     addAnnotation(VariableDie, DIVar->getAnnotations());
1524*d415bd75Srobert   }
152509467b48Spatrick 
152609467b48Spatrick   addSourceLine(VariableDie, DIVar);
152709467b48Spatrick   addType(VariableDie, Var.getType());
152809467b48Spatrick   if (Var.isArtificial())
152909467b48Spatrick     addFlag(VariableDie, dwarf::DW_AT_artificial);
153009467b48Spatrick }
153109467b48Spatrick 
applyLabelAttributes(const DbgLabel & Label,DIE & LabelDie)153209467b48Spatrick void DwarfCompileUnit::applyLabelAttributes(const DbgLabel &Label,
153309467b48Spatrick                                             DIE &LabelDie) {
153409467b48Spatrick   StringRef Name = Label.getName();
153509467b48Spatrick   if (!Name.empty())
153609467b48Spatrick     addString(LabelDie, dwarf::DW_AT_name, Name);
153709467b48Spatrick   const auto *DILabel = Label.getLabel();
153809467b48Spatrick   addSourceLine(LabelDie, DILabel);
153909467b48Spatrick }
154009467b48Spatrick 
154109467b48Spatrick /// Add a Dwarf expression attribute data and value.
addExpr(DIELoc & Die,dwarf::Form Form,const MCExpr * Expr)154209467b48Spatrick void DwarfCompileUnit::addExpr(DIELoc &Die, dwarf::Form Form,
154309467b48Spatrick                                const MCExpr *Expr) {
154473471bf0Spatrick   addAttribute(Die, (dwarf::Attribute)0, Form, DIEExpr(Expr));
154509467b48Spatrick }
154609467b48Spatrick 
applySubprogramAttributesToDefinition(const DISubprogram * SP,DIE & SPDie)154709467b48Spatrick void DwarfCompileUnit::applySubprogramAttributesToDefinition(
154809467b48Spatrick     const DISubprogram *SP, DIE &SPDie) {
154909467b48Spatrick   auto *SPDecl = SP->getDeclaration();
155009467b48Spatrick   auto *Context = SPDecl ? SPDecl->getScope() : SP->getScope();
155109467b48Spatrick   applySubprogramAttributes(SP, SPDie, includeMinimalInlineScopes());
155209467b48Spatrick   addGlobalName(SP->getName(), SPDie, Context);
155309467b48Spatrick }
155409467b48Spatrick 
isDwoUnit() const155509467b48Spatrick bool DwarfCompileUnit::isDwoUnit() const {
155609467b48Spatrick   return DD->useSplitDwarf() && Skeleton;
155709467b48Spatrick }
155809467b48Spatrick 
finishNonUnitTypeDIE(DIE & D,const DICompositeType * CTy)155909467b48Spatrick void DwarfCompileUnit::finishNonUnitTypeDIE(DIE& D, const DICompositeType *CTy) {
156009467b48Spatrick   constructTypeDIE(D, CTy);
156109467b48Spatrick }
156209467b48Spatrick 
includeMinimalInlineScopes() const156309467b48Spatrick bool DwarfCompileUnit::includeMinimalInlineScopes() const {
156409467b48Spatrick   return getCUNode()->getEmissionKind() == DICompileUnit::LineTablesOnly ||
156509467b48Spatrick          (DD->useSplitDwarf() && !Skeleton);
156609467b48Spatrick }
156709467b48Spatrick 
addAddrTableBase()156809467b48Spatrick void DwarfCompileUnit::addAddrTableBase() {
156909467b48Spatrick   const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
157009467b48Spatrick   MCSymbol *Label = DD->getAddressPool().getLabel();
157109467b48Spatrick   addSectionLabel(getUnitDie(),
157273471bf0Spatrick                   DD->getDwarfVersion() >= 5 ? dwarf::DW_AT_addr_base
157309467b48Spatrick                                              : dwarf::DW_AT_GNU_addr_base,
157409467b48Spatrick                   Label, TLOF.getDwarfAddrSection()->getBeginSymbol());
157509467b48Spatrick }
157609467b48Spatrick 
addBaseTypeRef(DIEValueList & Die,int64_t Idx)157709467b48Spatrick void DwarfCompileUnit::addBaseTypeRef(DIEValueList &Die, int64_t Idx) {
157873471bf0Spatrick   addAttribute(Die, (dwarf::Attribute)0, dwarf::DW_FORM_udata,
157909467b48Spatrick                new (DIEValueAllocator) DIEBaseTypeRef(this, Idx));
158009467b48Spatrick }
158109467b48Spatrick 
createBaseTypeDIEs()158209467b48Spatrick void DwarfCompileUnit::createBaseTypeDIEs() {
158309467b48Spatrick   // Insert the base_type DIEs directly after the CU so that their offsets will
158409467b48Spatrick   // fit in the fixed size ULEB128 used inside the location expressions.
158509467b48Spatrick   // Maintain order by iterating backwards and inserting to the front of CU
158609467b48Spatrick   // child list.
158709467b48Spatrick   for (auto &Btr : reverse(ExprRefedBaseTypes)) {
158809467b48Spatrick     DIE &Die = getUnitDie().addChildFront(
158909467b48Spatrick       DIE::get(DIEValueAllocator, dwarf::DW_TAG_base_type));
159009467b48Spatrick     SmallString<32> Str;
159109467b48Spatrick     addString(Die, dwarf::DW_AT_name,
159209467b48Spatrick               Twine(dwarf::AttributeEncodingString(Btr.Encoding) +
159309467b48Spatrick                     "_" + Twine(Btr.BitSize)).toStringRef(Str));
159409467b48Spatrick     addUInt(Die, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, Btr.Encoding);
1595*d415bd75Srobert     // Round up to smallest number of bytes that contains this number of bits.
1596*d415bd75Srobert     addUInt(Die, dwarf::DW_AT_byte_size, std::nullopt,
1597*d415bd75Srobert             divideCeil(Btr.BitSize, 8));
159809467b48Spatrick 
159909467b48Spatrick     Btr.Die = &Die;
160009467b48Spatrick   }
160109467b48Spatrick }
1602