16e07bfd0SEugene Zelenko //===- llvm/CodeGen/DwarfCompileUnit.cpp - Dwarf Compile Units ------------===//
23443575cSPaul Robinson //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
63443575cSPaul Robinson //
73443575cSPaul Robinson //===----------------------------------------------------------------------===//
83443575cSPaul Robinson //
93443575cSPaul Robinson // This file contains support for constructing a dwarf compile unit.
103443575cSPaul Robinson //
113443575cSPaul Robinson //===----------------------------------------------------------------------===//
123443575cSPaul Robinson 
1337c52310SDavid Blaikie #include "DwarfCompileUnit.h"
146e07bfd0SEugene Zelenko #include "AddressPool.h"
157813d9c9SAdrian Prantl #include "DwarfExpression.h"
166e07bfd0SEugene Zelenko #include "llvm/ADT/None.h"
176e07bfd0SEugene Zelenko #include "llvm/ADT/STLExtras.h"
18b86ce219SMarkus Lavin #include "llvm/ADT/SmallString.h"
194318028cSDavid Blaikie #include "llvm/BinaryFormat/Dwarf.h"
206e07bfd0SEugene Zelenko #include "llvm/CodeGen/AsmPrinter.h"
216e07bfd0SEugene Zelenko #include "llvm/CodeGen/DIE.h"
22cda2aa82SDavid Blaikie #include "llvm/CodeGen/MachineFunction.h"
236e07bfd0SEugene Zelenko #include "llvm/CodeGen/MachineInstr.h"
24b3bde2eaSDavid Blaikie #include "llvm/CodeGen/TargetFrameLowering.h"
25b3bde2eaSDavid Blaikie #include "llvm/CodeGen/TargetRegisterInfo.h"
26b3bde2eaSDavid Blaikie #include "llvm/CodeGen/TargetSubtargetInfo.h"
2737c52310SDavid Blaikie #include "llvm/IR/DataLayout.h"
286e07bfd0SEugene Zelenko #include "llvm/IR/DebugInfo.h"
2937c52310SDavid Blaikie #include "llvm/IR/GlobalVariable.h"
306e07bfd0SEugene Zelenko #include "llvm/MC/MCSection.h"
3137c52310SDavid Blaikie #include "llvm/MC/MCStreamer.h"
326e07bfd0SEugene Zelenko #include "llvm/MC/MCSymbol.h"
3348139ebcSWouter van Oortmerssen #include "llvm/MC/MCSymbolWasm.h"
34b3bde2eaSDavid Blaikie #include "llvm/MC/MachineLocation.h"
356054e650SDavid Blaikie #include "llvm/Target/TargetLoweringObjectFile.h"
36cda2aa82SDavid Blaikie #include "llvm/Target/TargetMachine.h"
376e07bfd0SEugene Zelenko #include "llvm/Target/TargetOptions.h"
386e07bfd0SEugene Zelenko #include <iterator>
396e07bfd0SEugene Zelenko #include <string>
406e07bfd0SEugene Zelenko #include <utility>
4137c52310SDavid Blaikie 
426e07bfd0SEugene Zelenko using namespace llvm;
4337c52310SDavid Blaikie 
GetCompileUnitType(UnitKind Kind,DwarfDebug * DW)44789e257cSAlexey Lapshin static dwarf::Tag GetCompileUnitType(UnitKind Kind, DwarfDebug *DW) {
45789e257cSAlexey Lapshin 
46789e257cSAlexey Lapshin   //  According to DWARF Debugging Information Format Version 5,
47789e257cSAlexey Lapshin   //  3.1.2 Skeleton Compilation Unit Entries:
48789e257cSAlexey Lapshin   //  "When generating a split DWARF object file (see Section 7.3.2
49789e257cSAlexey Lapshin   //  on page 187), the compilation unit in the .debug_info section
50789e257cSAlexey Lapshin   //  is a "skeleton" compilation unit with the tag DW_TAG_skeleton_unit"
51789e257cSAlexey Lapshin   if (DW->getDwarfVersion() >= 5 && Kind == UnitKind::Skeleton)
52789e257cSAlexey Lapshin     return dwarf::DW_TAG_skeleton_unit;
53789e257cSAlexey Lapshin 
54789e257cSAlexey Lapshin   return dwarf::DW_TAG_compile_unit;
55789e257cSAlexey Lapshin }
56789e257cSAlexey Lapshin 
DwarfCompileUnit(unsigned UID,const DICompileUnit * Node,AsmPrinter * A,DwarfDebug * DW,DwarfFile * DWU,UnitKind Kind)57a9308c49SDuncan P. N. Exon Smith DwarfCompileUnit::DwarfCompileUnit(unsigned UID, const DICompileUnit *Node,
5837c52310SDavid Blaikie                                    AsmPrinter *A, DwarfDebug *DW,
59789e257cSAlexey Lapshin                                    DwarfFile *DWU, UnitKind Kind)
60789e257cSAlexey Lapshin     : DwarfUnit(GetCompileUnitType(Kind, DW), Node, A, DW, DWU), UniqueID(UID) {
6137c52310SDavid Blaikie   insertDIE(Node, &getUnitDie());
628bbce8adSAmjad Aboud   MacroLabelBegin = Asm->createTempSymbol("cu_macro_begin");
6337c52310SDavid Blaikie }
6437c52310SDavid Blaikie 
6537c52310SDavid Blaikie /// addLabelAddress - Add a dwarf label attribute data and value using
6637c52310SDavid Blaikie /// DW_FORM_addr or DW_FORM_GNU_addr_index.
addLabelAddress(DIE & Die,dwarf::Attribute Attribute,const MCSymbol * Label)6737c52310SDavid Blaikie void DwarfCompileUnit::addLabelAddress(DIE &Die, dwarf::Attribute Attribute,
6837c52310SDavid Blaikie                                        const MCSymbol *Label) {
691be6ccfcSAlexander Yermolovich   if ((Skeleton || !DD->useSplitDwarf()) && Label)
701be6ccfcSAlexander Yermolovich     DD->addArangeLabel(SymbolCU(this, Label));
711be6ccfcSAlexander Yermolovich 
7237c52310SDavid Blaikie   // Don't use the address pool in non-fission or in the skeleton unit itself.
73161dd3c1SDavid Blaikie   if ((!DD->useSplitDwarf() || !Skeleton) && DD->getDwarfVersion() < 5)
7437c52310SDavid Blaikie     return addLocalLabelAddress(Die, Attribute, Label);
7537c52310SDavid Blaikie 
764318028cSDavid Blaikie   bool UseAddrOffsetFormOrExpressions =
774318028cSDavid Blaikie       DD->useAddrOffsetForm() || DD->useAddrOffsetExpressions();
784318028cSDavid Blaikie 
794318028cSDavid Blaikie   const MCSymbol *Base = nullptr;
804318028cSDavid Blaikie   if (Label->isInSection() && UseAddrOffsetFormOrExpressions)
814318028cSDavid Blaikie     Base = DD->getSectionLabel(&Label->getSection());
824318028cSDavid Blaikie 
834318028cSDavid Blaikie   if (!Base || Base == Label) {
8437c52310SDavid Blaikie     unsigned idx = DD->getAddressPool().getIndex(Label);
859deb7eeaSChen Zheng     addAttribute(Die, Attribute,
86161dd3c1SDavid Blaikie                  DD->getDwarfVersion() >= 5 ? dwarf::DW_FORM_addrx
87161dd3c1SDavid Blaikie                                             : dwarf::DW_FORM_GNU_addr_index,
884fb1f9cdSDuncan P. N. Exon Smith                  DIEInteger(idx));
897e6c87eeSDavid Blaikie     return;
907e6c87eeSDavid Blaikie   }
917e6c87eeSDavid Blaikie 
927e6c87eeSDavid Blaikie   // Could be extended to work with DWARFv4 Split DWARF if that's important for
937e6c87eeSDavid Blaikie   // someone. In that case DW_FORM_data would be used.
947e6c87eeSDavid Blaikie   assert(DD->getDwarfVersion() >= 5 &&
957e6c87eeSDavid Blaikie          "Addr+offset expressions are only valuable when using debug_addr (to "
967e6c87eeSDavid Blaikie          "reduce relocations) available in DWARFv5 or higher");
974318028cSDavid Blaikie   if (DD->useAddrOffsetExpressions()) {
987e6c87eeSDavid Blaikie     auto *Loc = new (DIEValueAllocator) DIEBlock();
997e6c87eeSDavid Blaikie     addPoolOpAddress(*Loc, Label);
1007e6c87eeSDavid Blaikie     addBlock(Die, Attribute, dwarf::DW_FORM_exprloc, Loc);
1014318028cSDavid Blaikie   } else
1029deb7eeaSChen Zheng     addAttribute(Die, Attribute, dwarf::DW_FORM_LLVM_addrx_offset,
10385b7b562SDavid Blaikie                  new (DIEValueAllocator) DIEAddrOffset(
10485b7b562SDavid Blaikie                      DD->getAddressPool().getIndex(Base), Label, Base));
10537c52310SDavid Blaikie }
10637c52310SDavid Blaikie 
addLocalLabelAddress(DIE & Die,dwarf::Attribute Attribute,const MCSymbol * Label)10737c52310SDavid Blaikie void DwarfCompileUnit::addLocalLabelAddress(DIE &Die,
10837c52310SDavid Blaikie                                             dwarf::Attribute Attribute,
10937c52310SDavid Blaikie                                             const MCSymbol *Label) {
11037c52310SDavid Blaikie   if (Label)
1119deb7eeaSChen Zheng     addAttribute(Die, Attribute, dwarf::DW_FORM_addr, DIELabel(Label));
112815a6eb5SDuncan P. N. Exon Smith   else
1139deb7eeaSChen Zheng     addAttribute(Die, Attribute, dwarf::DW_FORM_addr, DIEInteger(0));
11437c52310SDavid Blaikie }
11537c52310SDavid Blaikie 
getOrCreateSourceID(const DIFile * File)116612e89d7SPaul Robinson unsigned DwarfCompileUnit::getOrCreateSourceID(const DIFile *File) {
11737c52310SDavid Blaikie   // If we print assembly, we can't separate .file entries according to
11837c52310SDavid Blaikie   // compile units. Thus all files will belong to the default compile unit.
11937c52310SDavid Blaikie 
12037c52310SDavid Blaikie   // FIXME: add a better feature test than hasRawTextSupport. Even better,
12137c52310SDavid Blaikie   // extend .file to support this.
122612e89d7SPaul Robinson   unsigned CUID = Asm->OutStreamer->hasRawTextSupport() ? 0 : getUniqueID();
123612e89d7SPaul Robinson   if (!File)
1240bc77a0fSFangrui Song     return Asm->OutStreamer->emitDwarfFileDirective(0, "", "", None, None,
1250bc77a0fSFangrui Song                                                     CUID);
1269554aaa2SNikita Popov 
1279554aaa2SNikita Popov   if (LastFile != File) {
1289554aaa2SNikita Popov     LastFile = File;
1299554aaa2SNikita Popov     LastFileID = Asm->OutStreamer->emitDwarfFileDirective(
13038fbba4cSDavid Blaikie         0, File->getDirectory(), File->getFilename(), DD->getMD5AsBytes(File),
13116c7bdafSScott Linder         File->getSource(), CUID);
13237c52310SDavid Blaikie   }
1339554aaa2SNikita Popov   return LastFileID;
1349554aaa2SNikita Popov }
13537c52310SDavid Blaikie 
getOrCreateGlobalVariableDIE(const DIGlobalVariable * GV,ArrayRef<GlobalExpr> GlobalExprs)13660635e39SDuncan P. N. Exon Smith DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE(
137bceaaa96SAdrian Prantl     const DIGlobalVariable *GV, ArrayRef<GlobalExpr> GlobalExprs) {
13837c52310SDavid Blaikie   // Check for pre-existence.
13937c52310SDavid Blaikie   if (DIE *Die = getDIE(GV))
14037c52310SDavid Blaikie     return Die;
14137c52310SDavid Blaikie 
142e686f159SDuncan P. N. Exon Smith   assert(GV);
14337c52310SDavid Blaikie 
144be9e4fe7SDuncan P. N. Exon Smith   auto *GVContext = GV->getScope();
145da82ce99SFangrui Song   const DIType *GTy = GV->getType();
14637c52310SDavid Blaikie 
1476ed5706aSAdrian Prantl   auto *CB = GVContext ? dyn_cast<DICommonBlock>(GVContext) : nullptr;
1486ed5706aSAdrian Prantl   DIE *ContextDIE = CB ? getOrCreateCommonBlock(CB, GlobalExprs)
1496ed5706aSAdrian Prantl     : getOrCreateContextDIE(GVContext);
15037c52310SDavid Blaikie 
15172da9391SAmjad Aboud   // Add to map.
15272da9391SAmjad Aboud   DIE *VariableDIE = &createAndAddDIE(GV->getTag(), *ContextDIE, GV);
153a9308c49SDuncan P. N. Exon Smith   DIScope *DeclContext;
154b1055640SDuncan P. N. Exon Smith   if (auto *SDMDecl = GV->getStaticDataMemberDeclaration()) {
155da82ce99SFangrui Song     DeclContext = SDMDecl->getScope();
156b1055640SDuncan P. N. Exon Smith     assert(SDMDecl->isStaticMember() && "Expected static member decl");
1577348ddaaSDuncan P. N. Exon Smith     assert(GV->isDefinition());
15849cfc8caSDavid Blaikie     // We need the declaration DIE that is in the static member's class.
15949cfc8caSDavid Blaikie     DIE *VariableSpecDIE = getOrCreateStaticMemberDIE(SDMDecl);
16049cfc8caSDavid Blaikie     addDIEEntry(*VariableDIE, dwarf::DW_AT_specification, *VariableSpecDIE);
1613502f208SAdrian Prantl     // If the global variable's type is different from the one in the class
1623502f208SAdrian Prantl     // member type, assume that it's more specific and also emit it.
163da82ce99SFangrui Song     if (GTy != SDMDecl->getBaseType())
1643502f208SAdrian Prantl       addType(*VariableDIE, GTy);
16549cfc8caSDavid Blaikie   } else {
1667348ddaaSDuncan P. N. Exon Smith     DeclContext = GV->getScope();
16737c52310SDavid Blaikie     // Add name and type.
1687aa1fa0aSMitch Phillips     StringRef DisplayName = GV->getDisplayName();
1697aa1fa0aSMitch Phillips     if (!DisplayName.empty())
1707348ddaaSDuncan P. N. Exon Smith       addString(*VariableDIE, dwarf::DW_AT_name, GV->getDisplayName());
1713eb465a3SYonghong Song     if (GTy)
17237c52310SDavid Blaikie       addType(*VariableDIE, GTy);
17337c52310SDavid Blaikie 
17437c52310SDavid Blaikie     // Add scoping info.
1757348ddaaSDuncan P. N. Exon Smith     if (!GV->isLocalToUnit())
17637c52310SDavid Blaikie       addFlag(*VariableDIE, dwarf::DW_AT_external);
17737c52310SDavid Blaikie 
17837c52310SDavid Blaikie     // Add line number info.
17937c52310SDavid Blaikie     addSourceLine(*VariableDIE, GV);
18037c52310SDavid Blaikie   }
18137c52310SDavid Blaikie 
1827348ddaaSDuncan P. N. Exon Smith   if (!GV->isDefinition())
18349cfc8caSDavid Blaikie     addFlag(*VariableDIE, dwarf::DW_AT_declaration);
184877354a2SDavid Blaikie   else
185877354a2SDavid Blaikie     addGlobalName(GV->getName(), *VariableDIE, DeclContext);
18649cfc8caSDavid Blaikie 
18789424a82SYonghong Song   addAnnotation(*VariableDIE, GV->getAnnotations());
18889424a82SYonghong Song 
1893c989984SVictor Leschuk   if (uint32_t AlignInBytes = GV->getAlignInBytes())
1903c989984SVictor Leschuk     addUInt(*VariableDIE, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,
1913c989984SVictor Leschuk             AlignInBytes);
1923c989984SVictor Leschuk 
193f8ab35a4SMatthew Voss   if (MDTuple *TP = GV->getTemplateParams())
194f8ab35a4SMatthew Voss     addTemplateParams(*VariableDIE, DINodeArray(TP));
195f8ab35a4SMatthew Voss 
19637c52310SDavid Blaikie   // Add location.
1976ed5706aSAdrian Prantl   addLocationAttribute(VariableDIE, GV, GlobalExprs);
1986ed5706aSAdrian Prantl 
1996ed5706aSAdrian Prantl   return VariableDIE;
2006ed5706aSAdrian Prantl }
2016ed5706aSAdrian Prantl 
addLocationAttribute(DIE * VariableDIE,const DIGlobalVariable * GV,ArrayRef<GlobalExpr> GlobalExprs)2026ed5706aSAdrian Prantl void DwarfCompileUnit::addLocationAttribute(
2036ed5706aSAdrian Prantl     DIE *VariableDIE, const DIGlobalVariable *GV, ArrayRef<GlobalExpr> GlobalExprs) {
20437c52310SDavid Blaikie   bool addToAccelTable = false;
205bceaaa96SAdrian Prantl   DIELoc *Loc = nullptr;
206f3a91503SAlexey Bataev   Optional<unsigned> NVPTXAddressSpace;
207bceaaa96SAdrian Prantl   std::unique_ptr<DIEDwarfExpression> DwarfExpr;
208bceaaa96SAdrian Prantl   for (const auto &GE : GlobalExprs) {
209bceaaa96SAdrian Prantl     const GlobalVariable *Global = GE.Var;
210bceaaa96SAdrian Prantl     const DIExpression *Expr = GE.Expr;
211b216e3e9SAdrian Prantl 
212d4135bbcSPeter Collingbourne     // For compatibility with DWARF 3 and earlier,
213f13f0505SSourabh Singh Tomar     // DW_AT_location(DW_OP_constu, X, DW_OP_stack_value) or
214f13f0505SSourabh Singh Tomar     // DW_AT_location(DW_OP_consts, X, DW_OP_stack_value) becomes
215d4135bbcSPeter Collingbourne     // DW_AT_const_value(X).
216bceaaa96SAdrian Prantl     if (GlobalExprs.size() == 1 && Expr && Expr->isConstant()) {
217b216e3e9SAdrian Prantl       addToAccelTable = true;
218f13f0505SSourabh Singh Tomar       addConstantValue(
219f13f0505SSourabh Singh Tomar           *VariableDIE,
220f13f0505SSourabh Singh Tomar           DIExpression::SignedOrUnsignedConstant::UnsignedConstant ==
221f13f0505SSourabh Singh Tomar               *Expr->isConstant(),
222f13f0505SSourabh Singh Tomar           Expr->getElement(1));
223b216e3e9SAdrian Prantl       break;
224b216e3e9SAdrian Prantl     }
225b216e3e9SAdrian Prantl 
226bceaaa96SAdrian Prantl     // We cannot describe the location of dllimport'd variables: the
227bceaaa96SAdrian Prantl     // computation of their address requires loads from the IAT.
228b216e3e9SAdrian Prantl     if (Global && Global->hasDLLImportStorageClass())
229b216e3e9SAdrian Prantl       continue;
230b216e3e9SAdrian Prantl 
231b216e3e9SAdrian Prantl     // Nothing to describe without address or constant.
232b216e3e9SAdrian Prantl     if (!Global && (!Expr || !Expr->isConstant()))
233b216e3e9SAdrian Prantl       continue;
234b216e3e9SAdrian Prantl 
2358e422b84SLei Liu     if (Global && Global->isThreadLocal() &&
2368e422b84SLei Liu         !Asm->getObjFileLowering().supportDebugThreadLocalLocation())
2378e422b84SLei Liu       continue;
2388e422b84SLei Liu 
239bceaaa96SAdrian Prantl     if (!Loc) {
240b216e3e9SAdrian Prantl       addToAccelTable = true;
241bceaaa96SAdrian Prantl       Loc = new (DIEValueAllocator) DIELoc;
2420eaee545SJonas Devlieghere       DwarfExpr = std::make_unique<DIEDwarfExpression>(*Asm, *this, *Loc);
243bceaaa96SAdrian Prantl     }
244b216e3e9SAdrian Prantl 
245f3a91503SAlexey Bataev     if (Expr) {
246f3a91503SAlexey Bataev       // According to
247f3a91503SAlexey Bataev       // https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf
248f3a91503SAlexey Bataev       // cuda-gdb requires DW_AT_address_class for all variables to be able to
249f3a91503SAlexey Bataev       // correctly interpret address space of the variable address.
250f3a91503SAlexey Bataev       // Decode DW_OP_constu <DWARF Address Space> DW_OP_swap DW_OP_xderef
251f3a91503SAlexey Bataev       // sequence for the NVPTX + gdb target.
252f3a91503SAlexey Bataev       unsigned LocalNVPTXAddressSpace;
253f3a91503SAlexey Bataev       if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) {
254f3a91503SAlexey Bataev         const DIExpression *NewExpr =
255f3a91503SAlexey Bataev             DIExpression::extractAddressClass(Expr, LocalNVPTXAddressSpace);
256f3a91503SAlexey Bataev         if (NewExpr != Expr) {
257f3a91503SAlexey Bataev           Expr = NewExpr;
258f3a91503SAlexey Bataev           NVPTXAddressSpace = LocalNVPTXAddressSpace;
259f3a91503SAlexey Bataev         }
260f3a91503SAlexey Bataev       }
261a9e31537SMikael Holmen       DwarfExpr->addFragmentOffset(Expr);
262f3a91503SAlexey Bataev     }
263a9e31537SMikael Holmen 
264bceaaa96SAdrian Prantl     if (Global) {
265cca5f68eSDuncan P. N. Exon Smith       const MCSymbol *Sym = Asm->getSymbol(Global);
2665b133718SJack Andersen       // 16-bit platforms like MSP430 and AVR take this path, so sink this
2675b133718SJack Andersen       // assert to platforms that use it.
2685b133718SJack Andersen       auto GetPointerSizedFormAndOp = [this]() {
26904dc6871SAlexandros Lamprineas         unsigned PointerSize = Asm->getDataLayout().getPointerSize();
27004dc6871SAlexandros Lamprineas         assert((PointerSize == 4 || PointerSize == 8) &&
27104dc6871SAlexandros Lamprineas                "Add support for other sizes if necessary");
2725b133718SJack Andersen         struct FormAndOp {
2735b133718SJack Andersen           dwarf::Form Form;
2745b133718SJack Andersen           dwarf::LocationAtom Op;
2755b133718SJack Andersen         };
2765b133718SJack Andersen         return PointerSize == 4
2775b133718SJack Andersen                    ? FormAndOp{dwarf::DW_FORM_data4, dwarf::DW_OP_const4u}
2785b133718SJack Andersen                    : FormAndOp{dwarf::DW_FORM_data8, dwarf::DW_OP_const8u};
2795b133718SJack Andersen       };
280cca5f68eSDuncan P. N. Exon Smith       if (Global->isThreadLocal()) {
2819f9e4681SChih-Hung Hsieh         if (Asm->TM.useEmulatedTLS()) {
2821e859582SChih-Hung Hsieh           // TODO: add debug info for emulated thread local mode.
2831e859582SChih-Hung Hsieh         } else {
28437c52310SDavid Blaikie           // FIXME: Make this work with -gsplit-dwarf.
28537c52310SDavid Blaikie           // Based on GCC's support for TLS:
28637c52310SDavid Blaikie           if (!DD->useSplitDwarf()) {
2875b133718SJack Andersen             auto FormAndOp = GetPointerSizedFormAndOp();
28837c52310SDavid Blaikie             // 1) Start with a constNu of the appropriate pointer size
2895b133718SJack Andersen             addUInt(*Loc, dwarf::DW_FORM_data1, FormAndOp.Op);
29037c52310SDavid Blaikie             // 2) containing the (relocated) offset of the TLS variable
29137c52310SDavid Blaikie             //    within the module's TLS block.
2925b133718SJack Andersen             addExpr(*Loc, FormAndOp.Form,
29337c52310SDavid Blaikie                     Asm->getObjFileLowering().getDebugThreadLocalSymbol(Sym));
29437c52310SDavid Blaikie           } else {
29537c52310SDavid Blaikie             addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_const_index);
29637c52310SDavid Blaikie             addUInt(*Loc, dwarf::DW_FORM_udata,
29737c52310SDavid Blaikie                     DD->getAddressPool().getIndex(Sym, /* TLS */ true));
29837c52310SDavid Blaikie           }
29978cc0821SPaul Robinson           // 3) followed by an OP to make the debugger do a TLS lookup.
30078cc0821SPaul Robinson           addUInt(*Loc, dwarf::DW_FORM_data1,
30178cc0821SPaul Robinson                   DD->useGNUTLSOpcode() ? dwarf::DW_OP_GNU_push_tls_address
30278cc0821SPaul Robinson                                         : dwarf::DW_OP_form_tls_address);
3031e859582SChih-Hung Hsieh         }
30494fac097SKeith Walker       } else if ((Asm->TM.getRelocationModel() == Reloc::RWPI ||
30594fac097SKeith Walker                   Asm->TM.getRelocationModel() == Reloc::ROPI_RWPI) &&
30694fac097SKeith Walker                  !Asm->getObjFileLowering()
30794fac097SKeith Walker                       .getKindForGlobal(Global, Asm->TM)
30894fac097SKeith Walker                       .isReadOnly()) {
3095b133718SJack Andersen         auto FormAndOp = GetPointerSizedFormAndOp();
31004dc6871SAlexandros Lamprineas         // Constant
3115b133718SJack Andersen         addUInt(*Loc, dwarf::DW_FORM_data1, FormAndOp.Op);
31204dc6871SAlexandros Lamprineas         // Relocation offset
3135b133718SJack Andersen         addExpr(*Loc, FormAndOp.Form,
31404dc6871SAlexandros Lamprineas                 Asm->getObjFileLowering().getIndirectSymViaRWPI(Sym));
31504dc6871SAlexandros Lamprineas         // Base register
31604dc6871SAlexandros Lamprineas         Register BaseReg = Asm->getObjFileLowering().getStaticBase();
31704dc6871SAlexandros Lamprineas         BaseReg = Asm->TM.getMCRegisterInfo()->getDwarfRegNum(BaseReg, false);
31804dc6871SAlexandros Lamprineas         addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + BaseReg);
31904dc6871SAlexandros Lamprineas         // Offset from base register
32004dc6871SAlexandros Lamprineas         addSInt(*Loc, dwarf::DW_FORM_sdata, 0);
32104dc6871SAlexandros Lamprineas         // Operation
32204dc6871SAlexandros Lamprineas         addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
32337c52310SDavid Blaikie       } else {
32437c52310SDavid Blaikie         DD->addArangeLabel(SymbolCU(this, Sym));
32537c52310SDavid Blaikie         addOpAddress(*Loc, Sym);
32637c52310SDavid Blaikie       }
327bceaaa96SAdrian Prantl     }
3284b542c6eSAdrian Prantl     // Global variables attached to symbols are memory locations.
3294b542c6eSAdrian Prantl     // It would be better if this were unconditional, but malformed input that
3304b542c6eSAdrian Prantl     // mixes non-fragments and fragments for the same variable is too expensive
3314b542c6eSAdrian Prantl     // to detect in the verifier.
3323edc63a5SAdrian Prantl     if (DwarfExpr->isUnknownLocation())
3334b542c6eSAdrian Prantl       DwarfExpr->setMemoryLocationKind();
334a63b8e82SAdrian Prantl     DwarfExpr->addExpression(Expr);
335d4135bbcSPeter Collingbourne   }
336f3a91503SAlexey Bataev   if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) {
337f3a91503SAlexey Bataev     // According to
338f3a91503SAlexey Bataev     // https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf
339f3a91503SAlexey Bataev     // cuda-gdb requires DW_AT_address_class for all variables to be able to
340f3a91503SAlexey Bataev     // correctly interpret address space of the variable address.
341f3a91503SAlexey Bataev     const unsigned NVPTX_ADDR_global_space = 5;
342f3a91503SAlexey Bataev     addUInt(*VariableDIE, dwarf::DW_AT_address_class, dwarf::DW_FORM_data1,
343f3a91503SAlexey Bataev             NVPTXAddressSpace ? *NVPTXAddressSpace : NVPTX_ADDR_global_space);
344f3a91503SAlexey Bataev   }
345bceaaa96SAdrian Prantl   if (Loc)
346bceaaa96SAdrian Prantl     addBlock(*VariableDIE, dwarf::DW_AT_location, DwarfExpr->finalize());
347d4135bbcSPeter Collingbourne 
34843d1e453SPaul Robinson   if (DD->useAllLinkageNames())
3497348ddaaSDuncan P. N. Exon Smith     addLinkageName(*VariableDIE, GV->getLinkageName());
35037c52310SDavid Blaikie 
35137c52310SDavid Blaikie   if (addToAccelTable) {
35266cf14d0SDavid Blaikie     DD->addAccelName(*CUNode, GV->getName(), *VariableDIE);
35337c52310SDavid Blaikie 
35437c52310SDavid Blaikie     // If the linkage name is different than the name, go ahead and output
35537c52310SDavid Blaikie     // that as well into the name table.
3562a6afe5fSPavel Labath     if (GV->getLinkageName() != "" && GV->getName() != GV->getLinkageName() &&
3572a6afe5fSPavel Labath         DD->useAllLinkageNames())
35866cf14d0SDavid Blaikie       DD->addAccelName(*CUNode, GV->getLinkageName(), *VariableDIE);
35937c52310SDavid Blaikie   }
3606ed5706aSAdrian Prantl }
36137c52310SDavid Blaikie 
getOrCreateCommonBlock(const DICommonBlock * CB,ArrayRef<GlobalExpr> GlobalExprs)3626ed5706aSAdrian Prantl DIE *DwarfCompileUnit::getOrCreateCommonBlock(
3636ed5706aSAdrian Prantl     const DICommonBlock *CB, ArrayRef<GlobalExpr> GlobalExprs) {
3645b4bfd8cSKristina Bessonova   // Check for pre-existence.
3656ed5706aSAdrian Prantl   if (DIE *NDie = getDIE(CB))
3666ed5706aSAdrian Prantl     return NDie;
3675b4bfd8cSKristina Bessonova   DIE *ContextDIE = getOrCreateContextDIE(CB->getScope());
3686ed5706aSAdrian Prantl   DIE &NDie = createAndAddDIE(dwarf::DW_TAG_common_block, *ContextDIE, CB);
3696ed5706aSAdrian Prantl   StringRef Name = CB->getName().empty() ? "_BLNK_" : CB->getName();
3706ed5706aSAdrian Prantl   addString(NDie, dwarf::DW_AT_name, Name);
3716ed5706aSAdrian Prantl   addGlobalName(Name, NDie, CB->getScope());
3726ed5706aSAdrian Prantl   if (CB->getFile())
3736ed5706aSAdrian Prantl     addSourceLine(NDie, CB->getLineNo(), CB->getFile());
3746ed5706aSAdrian Prantl   if (DIGlobalVariable *V = CB->getDecl())
3756ed5706aSAdrian Prantl     getCU().addLocationAttribute(&NDie, V, GlobalExprs);
3766ed5706aSAdrian Prantl   return &NDie;
37737c52310SDavid Blaikie }
37837c52310SDavid Blaikie 
addRange(RangeSpan Range)37937c52310SDavid Blaikie void DwarfCompileUnit::addRange(RangeSpan Range) {
38058b10df5SDavid Blaikie   DD->insertSectionLabel(Range.Begin);
38158b10df5SDavid Blaikie 
3826747d44bSKyungwoo Lee   auto *PrevCU = DD->getPrevCU();
3836747d44bSKyungwoo Lee   bool SameAsPrevCU = this == PrevCU;
38437c52310SDavid Blaikie   DD->setPrevCU(this);
38537c52310SDavid Blaikie   // If we have no current ranges just add the range and return, otherwise,
38637c52310SDavid Blaikie   // check the current section and CU against the previous section and CU we
38737c52310SDavid Blaikie   // emitted into and the subprogram was contained within. If these are the
38837c52310SDavid Blaikie   // same then extend our current range, otherwise add this as a new range.
38937c52310SDavid Blaikie   if (CURanges.empty() || !SameAsPrevCU ||
390b677cb8dSDavid Blaikie       (&CURanges.back().End->getSection() !=
391b677cb8dSDavid Blaikie        &Range.End->getSection())) {
3926747d44bSKyungwoo Lee     // Before a new range is added, always terminate the prior line table.
3936747d44bSKyungwoo Lee     if (PrevCU)
3946747d44bSKyungwoo Lee       DD->terminateLineTable(PrevCU);
39537c52310SDavid Blaikie     CURanges.push_back(Range);
39637c52310SDavid Blaikie     return;
39737c52310SDavid Blaikie   }
39837c52310SDavid Blaikie 
399b677cb8dSDavid Blaikie   CURanges.back().End = Range.End;
40037c52310SDavid Blaikie }
40137c52310SDavid Blaikie 
initStmtList()402063d725fSRafael Espindola void DwarfCompileUnit::initStmtList() {
403d4dd7215SAlexey Bataev   if (CUNode->isDebugDirectivesOnly())
404d4dd7215SAlexey Bataev     return;
405d4dd7215SAlexey Bataev 
406bff36086SAlexey Bataev   const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
407bff36086SAlexey Bataev   if (DD->useSectionsAsReferences()) {
408bff36086SAlexey Bataev     LineTableStartSym = TLOF.getDwarfLineSection()->getBeginSymbol();
409bff36086SAlexey Bataev   } else {
410bff36086SAlexey Bataev     LineTableStartSym =
4119ff69c8fSLang Hames         Asm->OutStreamer->getDwarfLineTableSymbol(getUniqueID());
412bff36086SAlexey Bataev   }
41337c52310SDavid Blaikie 
41437c52310SDavid Blaikie   // DW_AT_stmt_list is a offset of line number information for this
41537c52310SDavid Blaikie   // compile unit in debug_line section. For split dwarf this is
41637c52310SDavid Blaikie   // left in the skeleton CU and so not included.
41737c52310SDavid Blaikie   // The line table entries are not always emitted in assembly, so it
41837c52310SDavid Blaikie   // is not okay to use line_table_start here.
41935630c33SGreg Clayton       addSectionLabel(getUnitDie(), dwarf::DW_AT_stmt_list, LineTableStartSym,
420063d725fSRafael Espindola                       TLOF.getDwarfLineSection()->getBeginSymbol());
42137c52310SDavid Blaikie }
42237c52310SDavid Blaikie 
applyStmtList(DIE & D)42337c52310SDavid Blaikie void DwarfCompileUnit::applyStmtList(DIE &D) {
4240d71782fSSourabh Singh Tomar   const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
4250d71782fSSourabh Singh Tomar   addSectionLabel(D, dwarf::DW_AT_stmt_list, LineTableStartSym,
4260d71782fSSourabh Singh Tomar                   TLOF.getDwarfLineSection()->getBeginSymbol());
42737c52310SDavid Blaikie }
42837c52310SDavid Blaikie 
attachLowHighPC(DIE & D,const MCSymbol * Begin,const MCSymbol * End)42914499a7dSDavid Blaikie void DwarfCompileUnit::attachLowHighPC(DIE &D, const MCSymbol *Begin,
43014499a7dSDavid Blaikie                                        const MCSymbol *End) {
43114499a7dSDavid Blaikie   assert(Begin && "Begin label should not be null!");
43214499a7dSDavid Blaikie   assert(End && "End label should not be null!");
43314499a7dSDavid Blaikie   assert(Begin->isDefined() && "Invalid starting label");
43414499a7dSDavid Blaikie   assert(End->isDefined() && "Invalid end label");
43514499a7dSDavid Blaikie 
43614499a7dSDavid Blaikie   addLabelAddress(D, dwarf::DW_AT_low_pc, Begin);
43714499a7dSDavid Blaikie   if (DD->getDwarfVersion() < 4)
43814499a7dSDavid Blaikie     addLabelAddress(D, dwarf::DW_AT_high_pc, End);
43914499a7dSDavid Blaikie   else
44014499a7dSDavid Blaikie     addLabelDelta(D, dwarf::DW_AT_high_pc, End, Begin);
44114499a7dSDavid Blaikie }
44214499a7dSDavid Blaikie 
443cda2aa82SDavid Blaikie // Find DIE for the given subprogram and attach appropriate DW_AT_low_pc
444cda2aa82SDavid Blaikie // and DW_AT_high_pc attributes. If there are global variables in this
445cda2aa82SDavid Blaikie // scope then create and insert DIEs for these variables.
updateSubprogramScopeDIE(const DISubprogram * SP)446a9308c49SDuncan P. N. Exon Smith DIE &DwarfCompileUnit::updateSubprogramScopeDIE(const DISubprogram *SP) {
4473a443c29SDavid Blaikie   DIE *SPDie = getOrCreateSubprogramDIE(SP, includeMinimalInlineScopes());
448cda2aa82SDavid Blaikie 
449e4b3c138SKrzysztof Pszeniczny   SmallVector<RangeSpan, 2> BB_List;
450e4b3c138SKrzysztof Pszeniczny   // If basic block sections are on, ranges for each basic block section has
451e4b3c138SKrzysztof Pszeniczny   // to be emitted separately.
452e4b3c138SKrzysztof Pszeniczny   for (const auto &R : Asm->MBBSectionRanges)
453e4b3c138SKrzysztof Pszeniczny     BB_List.push_back({R.second.BeginLabel, R.second.EndLabel});
454e4b3c138SKrzysztof Pszeniczny 
455e4b3c138SKrzysztof Pszeniczny   attachRangesOrLowHighPC(*SPDie, BB_List);
456e4b3c138SKrzysztof Pszeniczny 
457c53e18d9SDavid Blaikie   if (DD->useAppleExtensionAttributes() &&
458c53e18d9SDavid Blaikie       !DD->getCurrentFunction()->getTarget().Options.DisableFramePointerElim(
459cda2aa82SDavid Blaikie           *DD->getCurrentFunction()))
460cda2aa82SDavid Blaikie     addFlag(*SPDie, dwarf::DW_AT_APPLE_omit_frame_ptr);
461cda2aa82SDavid Blaikie 
462cda2aa82SDavid Blaikie   // Only include DW_AT_frame_base in full debug info
4633a443c29SDavid Blaikie   if (!includeMinimalInlineScopes()) {
464ff171acfSDerek Schuff     const TargetFrameLowering *TFI = Asm->MF->getSubtarget().getFrameLowering();
465ff171acfSDerek Schuff     TargetFrameLowering::DwarfFrameBase FrameBase =
466ff171acfSDerek Schuff         TFI->getDwarfFrameBase(*Asm->MF);
467ff171acfSDerek Schuff     switch (FrameBase.Kind) {
468ff171acfSDerek Schuff     case TargetFrameLowering::DwarfFrameBase::Register: {
469ff171acfSDerek Schuff       if (Register::isPhysicalRegister(FrameBase.Location.Reg)) {
470ff171acfSDerek Schuff         MachineLocation Location(FrameBase.Location.Reg);
471ff171acfSDerek Schuff         addAddress(*SPDie, dwarf::DW_AT_frame_base, Location);
472ff171acfSDerek Schuff       }
473ff171acfSDerek Schuff       break;
474ff171acfSDerek Schuff     }
475ff171acfSDerek Schuff     case TargetFrameLowering::DwarfFrameBase::CFA: {
4767ae86fe7SAlexey Bataev       DIELoc *Loc = new (DIEValueAllocator) DIELoc;
4777ae86fe7SAlexey Bataev       addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_call_frame_cfa);
4787ae86fe7SAlexey Bataev       addBlock(*SPDie, dwarf::DW_AT_frame_base, Loc);
479ff171acfSDerek Schuff       break;
480ff171acfSDerek Schuff     }
481ff171acfSDerek Schuff     case TargetFrameLowering::DwarfFrameBase::WasmFrameBase: {
48248139ebcSWouter van Oortmerssen       // FIXME: duplicated from Target/WebAssembly/WebAssembly.h
48348139ebcSWouter van Oortmerssen       // don't want to depend on target specific headers in this code?
48448139ebcSWouter van Oortmerssen       const unsigned TI_GLOBAL_RELOC = 3;
485a0f45268SWouter van Oortmerssen       if (FrameBase.Location.WasmLoc.Kind == TI_GLOBAL_RELOC) {
48648139ebcSWouter van Oortmerssen         // These need to be relocatable.
48748139ebcSWouter van Oortmerssen         assert(FrameBase.Location.WasmLoc.Index == 0);  // Only SP so far.
48848139ebcSWouter van Oortmerssen         auto SPSym = cast<MCSymbolWasm>(
48948139ebcSWouter van Oortmerssen           Asm->GetExternalSymbolSymbol("__stack_pointer"));
49048139ebcSWouter van Oortmerssen         // FIXME: this repeats what WebAssemblyMCInstLower::
49148139ebcSWouter van Oortmerssen         // GetExternalSymbolSymbol does, since if there's no code that
49248139ebcSWouter van Oortmerssen         // refers to this symbol, we have to set it here.
49348139ebcSWouter van Oortmerssen         SPSym->setType(wasm::WASM_SYMBOL_TYPE_GLOBAL);
494b9a539c0SWouter van Oortmerssen         SPSym->setGlobalType(wasm::WasmGlobalType{
495b9a539c0SWouter van Oortmerssen             uint8_t(Asm->getSubtargetInfo().getTargetTriple().getArch() ==
496b9a539c0SWouter van Oortmerssen                             Triple::wasm64
497b9a539c0SWouter van Oortmerssen                         ? wasm::WASM_TYPE_I64
498b9a539c0SWouter van Oortmerssen                         : wasm::WASM_TYPE_I32),
499b9a539c0SWouter van Oortmerssen             true});
50048139ebcSWouter van Oortmerssen         DIELoc *Loc = new (DIEValueAllocator) DIELoc;
50148139ebcSWouter van Oortmerssen         addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_WASM_location);
502f98e03a3SIgor Kudrin         addSInt(*Loc, dwarf::DW_FORM_sdata, TI_GLOBAL_RELOC);
503a0f45268SWouter van Oortmerssen         if (!isDwoUnit()) {
504f98e03a3SIgor Kudrin           addLabel(*Loc, dwarf::DW_FORM_data4, SPSym);
505a0f45268SWouter van Oortmerssen         } else {
506a0f45268SWouter van Oortmerssen           // FIXME: when writing dwo, we need to avoid relocations. Probably
507a0f45268SWouter van Oortmerssen           // the "right" solution is to treat globals the way func and data
508a0f45268SWouter van Oortmerssen           // symbols are (with entries in .debug_addr).
509a0f45268SWouter van Oortmerssen           // For now, since we only ever use index 0, this should work as-is.
510a0f45268SWouter van Oortmerssen           addUInt(*Loc, dwarf::DW_FORM_data4, FrameBase.Location.WasmLoc.Index);
511a0f45268SWouter van Oortmerssen         }
51248139ebcSWouter van Oortmerssen         addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_stack_value);
51348139ebcSWouter van Oortmerssen         addBlock(*SPDie, dwarf::DW_AT_frame_base, Loc);
51448139ebcSWouter van Oortmerssen       } else {
515ff171acfSDerek Schuff         DIELoc *Loc = new (DIEValueAllocator) DIELoc;
516ff171acfSDerek Schuff         DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
517ff171acfSDerek Schuff         DIExpressionCursor Cursor({});
518ff171acfSDerek Schuff         DwarfExpr.addWasmLocation(FrameBase.Location.WasmLoc.Kind,
519ff171acfSDerek Schuff             FrameBase.Location.WasmLoc.Index);
520ff171acfSDerek Schuff         DwarfExpr.addExpression(std::move(Cursor));
521ff171acfSDerek Schuff         addBlock(*SPDie, dwarf::DW_AT_frame_base, DwarfExpr.finalize());
52248139ebcSWouter van Oortmerssen       }
523ff171acfSDerek Schuff       break;
524ff171acfSDerek Schuff     }
525cda2aa82SDavid Blaikie     }
5267ae86fe7SAlexey Bataev   }
527cda2aa82SDavid Blaikie 
528cda2aa82SDavid Blaikie   // Add name to the name table, we do this here because we're guaranteed
529cda2aa82SDavid Blaikie   // to have concrete versions of our DW_TAG_subprogram nodes.
53066cf14d0SDavid Blaikie   DD->addSubprogramNames(*CUNode, SP, *SPDie);
531cda2aa82SDavid Blaikie 
532cda2aa82SDavid Blaikie   return *SPDie;
533cda2aa82SDavid Blaikie }
534cda2aa82SDavid Blaikie 
5359c65b135SDavid Blaikie // Construct a DIE for this scope.
constructScopeDIE(LexicalScope * Scope,DIE & ParentScopeDIE)53690432893SKristina Bessonova void DwarfCompileUnit::constructScopeDIE(LexicalScope *Scope,
53790432893SKristina Bessonova                                          DIE &ParentScopeDIE) {
5389c65b135SDavid Blaikie   if (!Scope || !Scope->getScopeNode())
5399c65b135SDavid Blaikie     return;
5409c65b135SDavid Blaikie 
541be9e4fe7SDuncan P. N. Exon Smith   auto *DS = Scope->getScopeNode();
5429c65b135SDavid Blaikie 
543a9308c49SDuncan P. N. Exon Smith   assert((Scope->getInlinedAt() || !isa<DISubprogram>(DS)) &&
5449c65b135SDavid Blaikie          "Only handle inlined subprograms here, use "
5459c65b135SDavid Blaikie          "constructSubprogramScopeDIE for non-inlined "
5469c65b135SDavid Blaikie          "subprograms");
5479c65b135SDavid Blaikie 
54890432893SKristina Bessonova   // Emit inlined subprograms.
549a9308c49SDuncan P. N. Exon Smith   if (Scope->getParent() && isa<DISubprogram>(DS)) {
55090432893SKristina Bessonova     DIE *ScopeDIE = constructInlinedScopeDIE(Scope);
5519c65b135SDavid Blaikie     if (!ScopeDIE)
5529c65b135SDavid Blaikie       return;
55390432893SKristina Bessonova 
55490432893SKristina Bessonova     ParentScopeDIE.addChild(ScopeDIE);
55590432893SKristina Bessonova     createAndAddScopeChildren(Scope, *ScopeDIE);
55690432893SKristina Bessonova     return;
55790432893SKristina Bessonova   }
55890432893SKristina Bessonova 
5599c65b135SDavid Blaikie   // Early exit when we know the scope DIE is going to be null.
5609c65b135SDavid Blaikie   if (DD->isLexicalScopeDIENull(Scope))
5619c65b135SDavid Blaikie     return;
5629c65b135SDavid Blaikie 
56390432893SKristina Bessonova   // Emit lexical blocks.
56490432893SKristina Bessonova   DIE *ScopeDIE = constructLexicalScopeDIE(Scope);
5659c65b135SDavid Blaikie   assert(ScopeDIE && "Scope DIE should not be null.");
56681378f7eSKristina Bessonova 
56790432893SKristina Bessonova   ParentScopeDIE.addChild(ScopeDIE);
56890432893SKristina Bessonova   createAndAddScopeChildren(Scope, *ScopeDIE);
5699c65b135SDavid Blaikie }
5709c65b135SDavid Blaikie 
addScopeRangeList(DIE & ScopeDIE,SmallVector<RangeSpan,2> Range)5715b02a19fSDavid Blaikie void DwarfCompileUnit::addScopeRangeList(DIE &ScopeDIE,
5725b02a19fSDavid Blaikie                                          SmallVector<RangeSpan, 2> Range) {
57352400200SDavid Blaikie 
574c4af8bf2SDavid Blaikie   HasRangeLists = true;
575c4af8bf2SDavid Blaikie 
576c4af8bf2SDavid Blaikie   // Add the range list to the set of ranges to be emitted.
577c4af8bf2SDavid Blaikie   auto IndexAndList =
578c4af8bf2SDavid Blaikie       (DD->getDwarfVersion() < 5 && Skeleton ? Skeleton->DU : DU)
579c8f7e6c1SDavid Blaikie           ->addRange(*(Skeleton ? Skeleton : this), std::move(Range));
580c4af8bf2SDavid Blaikie 
581c4af8bf2SDavid Blaikie   uint32_t Index = IndexAndList.first;
582c4af8bf2SDavid Blaikie   auto &List = *IndexAndList.second;
5835b02a19fSDavid Blaikie 
58452400200SDavid Blaikie   // Under fission, ranges are specified by constant offsets relative to the
58552400200SDavid Blaikie   // CU's DW_AT_GNU_ranges_base.
586fcf3810cSWolfgang Pieb   // FIXME: For DWARF v5, do not generate the DW_AT_ranges attribute under
587fcf3810cSWolfgang Pieb   // fission until we support the forms using the .debug_addr section
588fcf3810cSWolfgang Pieb   // (DW_RLE_startx_endx etc.).
58932e09de9SDavid Blaikie   if (DD->getDwarfVersion() >= 5)
59032e09de9SDavid Blaikie     addUInt(ScopeDIE, dwarf::DW_AT_ranges, dwarf::DW_FORM_rnglistx, Index);
591de9aa37bSDavid Blaikie   else {
592de9aa37bSDavid Blaikie     const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
593de9aa37bSDavid Blaikie     const MCSymbol *RangeSectionSym =
594de9aa37bSDavid Blaikie         TLOF.getDwarfRangesSection()->getBeginSymbol();
595de9aa37bSDavid Blaikie     if (isDwoUnit())
59664fa76efSDavid Blaikie       addSectionDelta(ScopeDIE, dwarf::DW_AT_ranges, List.Label,
5975b02a19fSDavid Blaikie                       RangeSectionSym);
598c4af8bf2SDavid Blaikie     else
59964fa76efSDavid Blaikie       addSectionLabel(ScopeDIE, dwarf::DW_AT_ranges, List.Label,
6005b02a19fSDavid Blaikie                       RangeSectionSym);
601fcf3810cSWolfgang Pieb   }
602de9aa37bSDavid Blaikie }
60352400200SDavid Blaikie 
attachRangesOrLowHighPC(DIE & Die,SmallVector<RangeSpan,2> Ranges)604de12375cSDavid Blaikie void DwarfCompileUnit::attachRangesOrLowHighPC(
6055b02a19fSDavid Blaikie     DIE &Die, SmallVector<RangeSpan, 2> Ranges) {
606ad18b075SDavid Blaikie   assert(!Ranges.empty());
607ad18b075SDavid Blaikie   if (!DD->useRangesSection() ||
608ad18b075SDavid Blaikie       (Ranges.size() == 1 &&
609ad18b075SDavid Blaikie        (!DD->alwaysUseRanges() ||
610ad18b075SDavid Blaikie         DD->getSectionLabel(&Ranges.front().Begin->getSection()) ==
611ad18b075SDavid Blaikie             Ranges.front().Begin))) {
612858a7dd6SAlexey Bataev     const RangeSpan &Front = Ranges.front();
613858a7dd6SAlexey Bataev     const RangeSpan &Back = Ranges.back();
614b677cb8dSDavid Blaikie     attachLowHighPC(Die, Front.Begin, Back.End);
6155b02a19fSDavid Blaikie   } else
6165b02a19fSDavid Blaikie     addScopeRangeList(Die, std::move(Ranges));
6175b02a19fSDavid Blaikie }
6185b02a19fSDavid Blaikie 
attachRangesOrLowHighPC(DIE & Die,const SmallVectorImpl<InsnRange> & Ranges)6195b02a19fSDavid Blaikie void DwarfCompileUnit::attachRangesOrLowHighPC(
620de12375cSDavid Blaikie     DIE &Die, const SmallVectorImpl<InsnRange> &Ranges) {
6215b02a19fSDavid Blaikie   SmallVector<RangeSpan, 2> List;
6225b02a19fSDavid Blaikie   List.reserve(Ranges.size());
623e4b3c138SKrzysztof Pszeniczny   for (const InsnRange &R : Ranges) {
624e4b3c138SKrzysztof Pszeniczny     auto *BeginLabel = DD->getLabelBeforeInsn(R.first);
625e4b3c138SKrzysztof Pszeniczny     auto *EndLabel = DD->getLabelAfterInsn(R.second);
626e4b3c138SKrzysztof Pszeniczny 
627e4b3c138SKrzysztof Pszeniczny     const auto *BeginMBB = R.first->getParent();
628e4b3c138SKrzysztof Pszeniczny     const auto *EndMBB = R.second->getParent();
629e4b3c138SKrzysztof Pszeniczny 
630e4b3c138SKrzysztof Pszeniczny     const auto *MBB = BeginMBB;
631e4b3c138SKrzysztof Pszeniczny     // Basic block sections allows basic block subsets to be placed in unique
632e4b3c138SKrzysztof Pszeniczny     // sections. For each section, the begin and end label must be added to the
633e4b3c138SKrzysztof Pszeniczny     // list. If there is more than one range, debug ranges must be used.
634e4b3c138SKrzysztof Pszeniczny     // Otherwise, low/high PC can be used.
635e4b3c138SKrzysztof Pszeniczny     // FIXME: Debug Info Emission depends on block order and this assumes that
636e4b3c138SKrzysztof Pszeniczny     // the order of blocks will be frozen beyond this point.
637e4b3c138SKrzysztof Pszeniczny     do {
638e4b3c138SKrzysztof Pszeniczny       if (MBB->sameSection(EndMBB) || MBB->isEndSection()) {
639e4b3c138SKrzysztof Pszeniczny         auto MBBSectionRange = Asm->MBBSectionRanges[MBB->getSectionIDNum()];
640b677cb8dSDavid Blaikie         List.push_back(
641e4b3c138SKrzysztof Pszeniczny             {MBB->sameSection(BeginMBB) ? BeginLabel
642e4b3c138SKrzysztof Pszeniczny                                         : MBBSectionRange.BeginLabel,
643e4b3c138SKrzysztof Pszeniczny              MBB->sameSection(EndMBB) ? EndLabel : MBBSectionRange.EndLabel});
644e4b3c138SKrzysztof Pszeniczny       }
645e4b3c138SKrzysztof Pszeniczny       if (MBB->sameSection(EndMBB))
646e4b3c138SKrzysztof Pszeniczny         break;
647e4b3c138SKrzysztof Pszeniczny       MBB = MBB->getNextNode();
648e4b3c138SKrzysztof Pszeniczny     } while (true);
649e4b3c138SKrzysztof Pszeniczny   }
6505b02a19fSDavid Blaikie   attachRangesOrLowHighPC(Die, std::move(List));
651de12375cSDavid Blaikie }
652de12375cSDavid Blaikie 
65301b48a84SDavid Blaikie // This scope represents inlined body of a function. Construct DIE to
65401b48a84SDavid Blaikie // represent this concrete inlined copy of the function.
constructInlinedScopeDIE(LexicalScope * Scope)655827200c8SDuncan P. N. Exon Smith DIE *DwarfCompileUnit::constructInlinedScopeDIE(LexicalScope *Scope) {
65601b48a84SDavid Blaikie   assert(Scope->getScopeNode());
657be9e4fe7SDuncan P. N. Exon Smith   auto *DS = Scope->getScopeNode();
658be9e4fe7SDuncan P. N. Exon Smith   auto *InlinedSP = getDISubprogram(DS);
65901b48a84SDavid Blaikie   // Find the subprogram's DwarfCompileUnit in the SPMap in case the subprogram
66001b48a84SDavid Blaikie   // was inlined from another compile unit.
66181378f7eSKristina Bessonova   DIE *OriginDIE = getAbstractSPDies()[InlinedSP];
66201b48a84SDavid Blaikie   assert(OriginDIE && "Unable to find original DIE for an inlined subprogram.");
66301b48a84SDavid Blaikie 
664827200c8SDuncan P. N. Exon Smith   auto ScopeDIE = DIE::get(DIEValueAllocator, dwarf::DW_TAG_inlined_subroutine);
66501b48a84SDavid Blaikie   addDIEEntry(*ScopeDIE, dwarf::DW_AT_abstract_origin, *OriginDIE);
66601b48a84SDavid Blaikie 
66701b48a84SDavid Blaikie   attachRangesOrLowHighPC(*ScopeDIE, Scope->getRanges());
66801b48a84SDavid Blaikie 
66901b48a84SDavid Blaikie   // Add the call site information to the DIE.
670a9308c49SDuncan P. N. Exon Smith   const DILocation *IA = Scope->getInlinedAt();
67101b48a84SDavid Blaikie   addUInt(*ScopeDIE, dwarf::DW_AT_call_file, None,
672612e89d7SPaul Robinson           getOrCreateSourceID(IA->getFile()));
673b7e221baSDuncan P. N. Exon Smith   addUInt(*ScopeDIE, dwarf::DW_AT_call_line, None, IA->getLine());
67440580d36SDavid Blaikie   if (IA->getColumn())
67583264b35SJonas Devlieghere     addUInt(*ScopeDIE, dwarf::DW_AT_call_column, None, IA->getColumn());
6766e0c8446SDehao Chen   if (IA->getDiscriminator() && DD->getDwarfVersion() >= 4)
67754511353SDehao Chen     addUInt(*ScopeDIE, dwarf::DW_AT_GNU_discriminator, None,
67854511353SDehao Chen             IA->getDiscriminator());
67901b48a84SDavid Blaikie 
68001b48a84SDavid Blaikie   // Add name to the name table, we do this here because we're guaranteed
68101b48a84SDavid Blaikie   // to have concrete versions of our DW_TAG_inlined_subprogram nodes.
68266cf14d0SDavid Blaikie   DD->addSubprogramNames(*CUNode, InlinedSP, *ScopeDIE);
68301b48a84SDavid Blaikie 
68401b48a84SDavid Blaikie   return ScopeDIE;
68501b48a84SDavid Blaikie }
68601b48a84SDavid Blaikie 
6870fbf8bdbSDavid Blaikie // Construct new DW_TAG_lexical_block for this scope and attach
6880fbf8bdbSDavid Blaikie // DW_AT_low_pc/DW_AT_high_pc labels.
constructLexicalScopeDIE(LexicalScope * Scope)689827200c8SDuncan P. N. Exon Smith DIE *DwarfCompileUnit::constructLexicalScopeDIE(LexicalScope *Scope) {
6900fbf8bdbSDavid Blaikie   if (DD->isLexicalScopeDIENull(Scope))
6910fbf8bdbSDavid Blaikie     return nullptr;
6920fbf8bdbSDavid Blaikie 
693827200c8SDuncan P. N. Exon Smith   auto ScopeDIE = DIE::get(DIEValueAllocator, dwarf::DW_TAG_lexical_block);
6940fbf8bdbSDavid Blaikie   if (Scope->isAbstractScope())
6950fbf8bdbSDavid Blaikie     return ScopeDIE;
6960fbf8bdbSDavid Blaikie 
6970fbf8bdbSDavid Blaikie   attachRangesOrLowHighPC(*ScopeDIE, Scope->getRanges());
6980fbf8bdbSDavid Blaikie 
6990fbf8bdbSDavid Blaikie   return ScopeDIE;
7000fbf8bdbSDavid Blaikie }
7010fbf8bdbSDavid Blaikie 
702ee7df553SDavid Blaikie /// constructVariableDIE - Construct a DIE for the given DbgVariable.
constructVariableDIE(DbgVariable & DV,bool Abstract)703827200c8SDuncan P. N. Exon Smith DIE *DwarfCompileUnit::constructVariableDIE(DbgVariable &DV, bool Abstract) {
704ee7df553SDavid Blaikie   auto D = constructVariableDIEImpl(DV, Abstract);
705ee7df553SDavid Blaikie   DV.setDIE(*D);
706ee7df553SDavid Blaikie   return D;
707ee7df553SDavid Blaikie }
708ee7df553SDavid Blaikie 
constructLabelDIE(DbgLabel & DL,const LexicalScope & Scope)7092532ac88SHsiangkai Wang DIE *DwarfCompileUnit::constructLabelDIE(DbgLabel &DL,
7102532ac88SHsiangkai Wang                                          const LexicalScope &Scope) {
7112532ac88SHsiangkai Wang   auto LabelDie = DIE::get(DIEValueAllocator, DL.getTag());
7122532ac88SHsiangkai Wang   insertDIE(DL.getLabel(), LabelDie);
7132532ac88SHsiangkai Wang   DL.setDIE(*LabelDie);
7142532ac88SHsiangkai Wang 
7152532ac88SHsiangkai Wang   if (Scope.isAbstractScope())
7162532ac88SHsiangkai Wang     applyLabelAttributes(DL, *LabelDie);
7172532ac88SHsiangkai Wang 
7182532ac88SHsiangkai Wang   return LabelDie;
7192532ac88SHsiangkai Wang }
7202532ac88SHsiangkai Wang 
constructVariableDIEImpl(const DbgVariable & DV,bool Abstract)721827200c8SDuncan P. N. Exon Smith DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV,
722ee7df553SDavid Blaikie                                                 bool Abstract) {
723ee7df553SDavid Blaikie   // Define variable debug information entry.
724827200c8SDuncan P. N. Exon Smith   auto VariableDie = DIE::get(DIEValueAllocator, DV.getTag());
725dc00becdSSander de Smalen   insertDIE(DV.getVariable(), VariableDie);
726ee7df553SDavid Blaikie 
727ee7df553SDavid Blaikie   if (Abstract) {
728ee7df553SDavid Blaikie     applyVariableAttributes(DV, *VariableDie);
729ee7df553SDavid Blaikie     return VariableDie;
730ee7df553SDavid Blaikie   }
731ee7df553SDavid Blaikie 
732ee7df553SDavid Blaikie   // Add variable address.
733ee7df553SDavid Blaikie 
7348feff8d1SIgor Kudrin   unsigned Index = DV.getDebugLocListIndex();
7358feff8d1SIgor Kudrin   if (Index != ~0U) {
7368feff8d1SIgor Kudrin     addLocationList(*VariableDie, dwarf::DW_AT_location, Index);
737dabd2622SEvgenii Stepanov     auto TagOffset = DV.getDebugLocListTagOffset();
738dabd2622SEvgenii Stepanov     if (TagOffset)
739dabd2622SEvgenii Stepanov       addUInt(*VariableDie, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,
740dabd2622SEvgenii Stepanov               *TagOffset);
741ee7df553SDavid Blaikie     return VariableDie;
742ee7df553SDavid Blaikie   }
743ee7df553SDavid Blaikie 
744abc1dff7SNikola Prica   // Check if variable has a single location description.
745abc1dff7SNikola Prica   if (auto *DVal = DV.getValueLoc()) {
746e64f3cccSStephen Tozer     if (!DVal->isVariadic()) {
747e64f3cccSStephen Tozer       const DbgValueLocEntry *Entry = DVal->getLocEntries().begin();
748e64f3cccSStephen Tozer       if (Entry->isLocation()) {
749e64f3cccSStephen Tozer         addVariableAddress(DV, *VariableDie, Entry->getLoc());
750e64f3cccSStephen Tozer       } else if (Entry->isInt()) {
7513b89e663SAdrian Prantl         auto *Expr = DV.getSingleExpression();
7523b89e663SAdrian Prantl         if (Expr && Expr->getNumElements()) {
7533b89e663SAdrian Prantl           DIELoc *Loc = new (DIEValueAllocator) DIELoc;
7543b89e663SAdrian Prantl           DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
7553b89e663SAdrian Prantl           // If there is an expression, emit raw unsigned bytes.
7568fafb8d3SAdrian Prantl           DwarfExpr.addFragmentOffset(Expr);
757e64f3cccSStephen Tozer           DwarfExpr.addUnsignedConstant(Entry->getInt());
758a63b8e82SAdrian Prantl           DwarfExpr.addExpression(Expr);
759bceaaa96SAdrian Prantl           addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
760dabd2622SEvgenii Stepanov           if (DwarfExpr.TagOffset)
761dabd2622SEvgenii Stepanov             addUInt(*VariableDie, dwarf::DW_AT_LLVM_tag_offset,
762dabd2622SEvgenii Stepanov                     dwarf::DW_FORM_data1, *DwarfExpr.TagOffset);
7633b89e663SAdrian Prantl         } else
764e64f3cccSStephen Tozer           addConstantValue(*VariableDie, Entry->getInt(), DV.getType());
765e64f3cccSStephen Tozer       } else if (Entry->isConstantFP()) {
766e64f3cccSStephen Tozer         addConstantFPValue(*VariableDie, Entry->getConstantFP());
767e64f3cccSStephen Tozer       } else if (Entry->isConstantInt()) {
768e64f3cccSStephen Tozer         addConstantValue(*VariableDie, Entry->getConstantInt(), DV.getType());
769e64f3cccSStephen Tozer       } else if (Entry->isTargetIndexLocation()) {
7705c38ae36SWouter van Oortmerssen         DIELoc *Loc = new (DIEValueAllocator) DIELoc;
7715c38ae36SWouter van Oortmerssen         DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
7725c38ae36SWouter van Oortmerssen         const DIBasicType *BT = dyn_cast<DIBasicType>(
7735c38ae36SWouter van Oortmerssen             static_cast<const Metadata *>(DV.getVariable()->getType()));
7745c38ae36SWouter van Oortmerssen         DwarfDebug::emitDebugLocValue(*Asm, BT, *DVal, DwarfExpr);
7755c38ae36SWouter van Oortmerssen         addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
776abc1dff7SNikola Prica       }
777ee7df553SDavid Blaikie       return VariableDie;
778ee7df553SDavid Blaikie     }
779e64f3cccSStephen Tozer     // If any of the location entries are registers with the value 0, then the
780e64f3cccSStephen Tozer     // location is undefined.
781e64f3cccSStephen Tozer     if (any_of(DVal->getLocEntries(), [](const DbgValueLocEntry &Entry) {
782e64f3cccSStephen Tozer           return Entry.isLocation() && !Entry.getLoc().getReg();
783e64f3cccSStephen Tozer         }))
784e64f3cccSStephen Tozer       return VariableDie;
785e64f3cccSStephen Tozer     const DIExpression *Expr = DV.getSingleExpression();
786e64f3cccSStephen Tozer     assert(Expr && "Variadic Debug Value must have an Expression.");
787e64f3cccSStephen Tozer     DIELoc *Loc = new (DIEValueAllocator) DIELoc;
788e64f3cccSStephen Tozer     DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
789e64f3cccSStephen Tozer     DwarfExpr.addFragmentOffset(Expr);
790e64f3cccSStephen Tozer     DIExpressionCursor Cursor(Expr);
791e64f3cccSStephen Tozer     const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();
792e64f3cccSStephen Tozer 
79380d1f657SDavid Blaikie     auto AddEntry = [&](const DbgValueLocEntry &Entry,
794e64f3cccSStephen Tozer                         DIExpressionCursor &Cursor) {
795e64f3cccSStephen Tozer       if (Entry.isLocation()) {
796e64f3cccSStephen Tozer         if (!DwarfExpr.addMachineRegExpression(TRI, Cursor,
797e64f3cccSStephen Tozer                                                Entry.getLoc().getReg()))
798e64f3cccSStephen Tozer           return false;
799e64f3cccSStephen Tozer       } else if (Entry.isInt()) {
800e64f3cccSStephen Tozer         // If there is an expression, emit raw unsigned bytes.
801e64f3cccSStephen Tozer         DwarfExpr.addUnsignedConstant(Entry.getInt());
802e64f3cccSStephen Tozer       } else if (Entry.isConstantFP()) {
803c7c84b90SAdrian Prantl         // DwarfExpression does not support arguments wider than 64 bits
804c7c84b90SAdrian Prantl         // (see PR52584).
805c7c84b90SAdrian Prantl         // TODO: Consider chunking expressions containing overly wide
806c7c84b90SAdrian Prantl         // arguments into separate pointer-sized fragment expressions.
807e64f3cccSStephen Tozer         APInt RawBytes = Entry.getConstantFP()->getValueAPF().bitcastToAPInt();
808c7c84b90SAdrian Prantl         if (RawBytes.getBitWidth() > 64)
809c7c84b90SAdrian Prantl           return false;
810c7c84b90SAdrian Prantl         DwarfExpr.addUnsignedConstant(RawBytes.getZExtValue());
811e64f3cccSStephen Tozer       } else if (Entry.isConstantInt()) {
812e64f3cccSStephen Tozer         APInt RawBytes = Entry.getConstantInt()->getValue();
813c7c84b90SAdrian Prantl         if (RawBytes.getBitWidth() > 64)
814c7c84b90SAdrian Prantl           return false;
815c7c84b90SAdrian Prantl         DwarfExpr.addUnsignedConstant(RawBytes.getZExtValue());
816e64f3cccSStephen Tozer       } else if (Entry.isTargetIndexLocation()) {
817e64f3cccSStephen Tozer         TargetIndexLocation Loc = Entry.getTargetIndexLocation();
818e64f3cccSStephen Tozer         // TODO TargetIndexLocation is a target-independent. Currently only the
819e64f3cccSStephen Tozer         // WebAssembly-specific encoding is supported.
82080d1f657SDavid Blaikie         assert(Asm->TM.getTargetTriple().isWasm());
821e64f3cccSStephen Tozer         DwarfExpr.addWasmLocation(Loc.Index, static_cast<uint64_t>(Loc.Offset));
822e64f3cccSStephen Tozer       } else {
823e64f3cccSStephen Tozer         llvm_unreachable("Unsupported Entry type.");
824e64f3cccSStephen Tozer       }
825e64f3cccSStephen Tozer       return true;
826e64f3cccSStephen Tozer     };
827e64f3cccSStephen Tozer 
828c7c84b90SAdrian Prantl     if (!DwarfExpr.addExpression(
829e64f3cccSStephen Tozer             std::move(Cursor),
83080d1f657SDavid Blaikie             [&](unsigned Idx, DIExpressionCursor &Cursor) -> bool {
831e64f3cccSStephen Tozer               return AddEntry(DVal->getLocEntries()[Idx], Cursor);
832c7c84b90SAdrian Prantl             }))
833c7c84b90SAdrian Prantl       return VariableDie;
834e64f3cccSStephen Tozer 
835e64f3cccSStephen Tozer     // Now attach the location information to the DIE.
836e64f3cccSStephen Tozer     addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
837e64f3cccSStephen Tozer     if (DwarfExpr.TagOffset)
838e64f3cccSStephen Tozer       addUInt(*VariableDie, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,
839e64f3cccSStephen Tozer               *DwarfExpr.TagOffset);
840e64f3cccSStephen Tozer 
841e64f3cccSStephen Tozer     return VariableDie;
842e64f3cccSStephen Tozer   }
843ee7df553SDavid Blaikie 
844ee7df553SDavid Blaikie   // .. else use frame index.
84567c24422SAdrian Prantl   if (!DV.hasFrameIndexExprs())
846ca7e4702SAdrian Prantl     return VariableDie;
847ca7e4702SAdrian Prantl 
848f3a91503SAlexey Bataev   Optional<unsigned> NVPTXAddressSpace;
849e7e1d0c7SDuncan P. N. Exon Smith   DIELoc *Loc = new (DIEValueAllocator) DIELoc;
850ca7e4702SAdrian Prantl   DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
851*9e6d1f4bSKazu Hirata   for (const auto &Fragment : DV.getFrameIndexExprs()) {
8522481f26aSMatt Arsenault     Register FrameReg;
8536825fb64SAdrian Prantl     const DIExpression *Expr = Fragment.Expr;
854d4e723f2SEric Christopher     const TargetFrameLowering *TFI = Asm->MF->getSubtarget().getFrameLowering();
855d57bba7cSSander de Smalen     StackOffset Offset =
856d57bba7cSSander de Smalen         TFI->getFrameIndexReference(*Asm->MF, Fragment.FI, FrameReg);
8576825fb64SAdrian Prantl     DwarfExpr.addFragmentOffset(Expr);
858d57bba7cSSander de Smalen 
859aa280c99SSander de Smalen     auto *TRI = Asm->MF->getSubtarget().getRegisterInfo();
860956484b7SAdrian Prantl     SmallVector<uint64_t, 8> Ops;
861aa280c99SSander de Smalen     TRI->getOffsetOpcodes(Offset, Ops);
862aa280c99SSander de Smalen 
863f3a91503SAlexey Bataev     // According to
864f3a91503SAlexey Bataev     // https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf
865f3a91503SAlexey Bataev     // cuda-gdb requires DW_AT_address_class for all variables to be able to
866f3a91503SAlexey Bataev     // correctly interpret address space of the variable address.
867f3a91503SAlexey Bataev     // Decode DW_OP_constu <DWARF Address Space> DW_OP_swap DW_OP_xderef
868f3a91503SAlexey Bataev     // sequence for the NVPTX + gdb target.
869f3a91503SAlexey Bataev     unsigned LocalNVPTXAddressSpace;
870f3a91503SAlexey Bataev     if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) {
871f3a91503SAlexey Bataev       const DIExpression *NewExpr =
872f3a91503SAlexey Bataev           DIExpression::extractAddressClass(Expr, LocalNVPTXAddressSpace);
873f3a91503SAlexey Bataev       if (NewExpr != Expr) {
874f3a91503SAlexey Bataev         Expr = NewExpr;
875f3a91503SAlexey Bataev         NVPTXAddressSpace = LocalNVPTXAddressSpace;
876f3a91503SAlexey Bataev       }
877f3a91503SAlexey Bataev     }
878f3a91503SAlexey Bataev     if (Expr)
8796825fb64SAdrian Prantl       Ops.append(Expr->elements_begin(), Expr->elements_end());
8806825fb64SAdrian Prantl     DIExpressionCursor Cursor(Ops);
881c12cee36SAdrian Prantl     DwarfExpr.setMemoryLocationKind();
8824dd7558fSAlexey Bataev     if (const MCSymbol *FrameSymbol = Asm->getFunctionFrameSymbol())
8834dd7558fSAlexey Bataev       addOpAddress(*Loc, FrameSymbol);
8844dd7558fSAlexey Bataev     else
885c12cee36SAdrian Prantl       DwarfExpr.addMachineRegExpression(
886c12cee36SAdrian Prantl           *Asm->MF->getSubtarget().getRegisterInfo(), Cursor, FrameReg);
8876825fb64SAdrian Prantl     DwarfExpr.addExpression(std::move(Cursor));
888ee7df553SDavid Blaikie   }
889f3a91503SAlexey Bataev   if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) {
890f3a91503SAlexey Bataev     // According to
891f3a91503SAlexey Bataev     // https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf
892f3a91503SAlexey Bataev     // cuda-gdb requires DW_AT_address_class for all variables to be able to
893f3a91503SAlexey Bataev     // correctly interpret address space of the variable address.
894f3a91503SAlexey Bataev     const unsigned NVPTX_ADDR_local_space = 6;
895f3a91503SAlexey Bataev     addUInt(*VariableDie, dwarf::DW_AT_address_class, dwarf::DW_FORM_data1,
896f3a91503SAlexey Bataev             NVPTXAddressSpace ? *NVPTXAddressSpace : NVPTX_ADDR_local_space);
897f3a91503SAlexey Bataev   }
898bceaaa96SAdrian Prantl   addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
899fb9ce100SPeter Collingbourne   if (DwarfExpr.TagOffset)
900fb9ce100SPeter Collingbourne     addUInt(*VariableDie, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,
901fb9ce100SPeter Collingbourne             *DwarfExpr.TagOffset);
902ee7df553SDavid Blaikie 
903ee7df553SDavid Blaikie   return VariableDie;
904ee7df553SDavid Blaikie }
905ee7df553SDavid Blaikie 
constructVariableDIE(DbgVariable & DV,const LexicalScope & Scope,DIE * & ObjectPointer)906827200c8SDuncan P. N. Exon Smith DIE *DwarfCompileUnit::constructVariableDIE(DbgVariable &DV,
907827200c8SDuncan P. N. Exon Smith                                             const LexicalScope &Scope,
908827200c8SDuncan P. N. Exon Smith                                             DIE *&ObjectPointer) {
9094a1a44e3SDavid Blaikie   auto Var = constructVariableDIE(DV, Scope.isAbstractScope());
9104a1a44e3SDavid Blaikie   if (DV.isObjectPointer())
911827200c8SDuncan P. N. Exon Smith     ObjectPointer = Var;
9124a1a44e3SDavid Blaikie   return Var;
9134a1a44e3SDavid Blaikie }
9144a1a44e3SDavid Blaikie 
91503dd6f57SAdrian Prantl /// Return all DIVariables that appear in count: expressions.
dependencies(DbgVariable * Var)91603dd6f57SAdrian Prantl static SmallVector<const DIVariable *, 2> dependencies(DbgVariable *Var) {
91703dd6f57SAdrian Prantl   SmallVector<const DIVariable *, 2> Result;
91803dd6f57SAdrian Prantl   auto *Array = dyn_cast<DICompositeType>(Var->getType());
919c929f7adSAdrian Prantl   if (!Array || Array->getTag() != dwarf::DW_TAG_array_type)
92003dd6f57SAdrian Prantl     return Result;
9214042ada1SAlok Kumar Sharma   if (auto *DLVar = Array->getDataLocation())
9224042ada1SAlok Kumar Sharma     Result.push_back(DLVar);
9232d10258aSAlok Kumar Sharma   if (auto *AsVar = Array->getAssociated())
9242d10258aSAlok Kumar Sharma     Result.push_back(AsVar);
9252d10258aSAlok Kumar Sharma   if (auto *AlVar = Array->getAllocated())
9262d10258aSAlok Kumar Sharma     Result.push_back(AlVar);
92703dd6f57SAdrian Prantl   for (auto *El : Array->getElements()) {
928c929f7adSAdrian Prantl     if (auto *Subrange = dyn_cast<DISubrange>(El)) {
929d20bf5a7SAlok Kumar Sharma       if (auto Count = Subrange->getCount())
93003dd6f57SAdrian Prantl         if (auto *Dependency = Count.dyn_cast<DIVariable *>())
93103dd6f57SAdrian Prantl           Result.push_back(Dependency);
932d20bf5a7SAlok Kumar Sharma       if (auto LB = Subrange->getLowerBound())
933d20bf5a7SAlok Kumar Sharma         if (auto *Dependency = LB.dyn_cast<DIVariable *>())
934d20bf5a7SAlok Kumar Sharma           Result.push_back(Dependency);
935d20bf5a7SAlok Kumar Sharma       if (auto UB = Subrange->getUpperBound())
936d20bf5a7SAlok Kumar Sharma         if (auto *Dependency = UB.dyn_cast<DIVariable *>())
937d20bf5a7SAlok Kumar Sharma           Result.push_back(Dependency);
938d20bf5a7SAlok Kumar Sharma       if (auto ST = Subrange->getStride())
939d20bf5a7SAlok Kumar Sharma         if (auto *Dependency = ST.dyn_cast<DIVariable *>())
940d20bf5a7SAlok Kumar Sharma           Result.push_back(Dependency);
941a6dd01afSAlok Kumar Sharma     } else if (auto *GenericSubrange = dyn_cast<DIGenericSubrange>(El)) {
942a6dd01afSAlok Kumar Sharma       if (auto Count = GenericSubrange->getCount())
943a6dd01afSAlok Kumar Sharma         if (auto *Dependency = Count.dyn_cast<DIVariable *>())
944a6dd01afSAlok Kumar Sharma           Result.push_back(Dependency);
945a6dd01afSAlok Kumar Sharma       if (auto LB = GenericSubrange->getLowerBound())
946a6dd01afSAlok Kumar Sharma         if (auto *Dependency = LB.dyn_cast<DIVariable *>())
947a6dd01afSAlok Kumar Sharma           Result.push_back(Dependency);
948a6dd01afSAlok Kumar Sharma       if (auto UB = GenericSubrange->getUpperBound())
949a6dd01afSAlok Kumar Sharma         if (auto *Dependency = UB.dyn_cast<DIVariable *>())
950a6dd01afSAlok Kumar Sharma           Result.push_back(Dependency);
951a6dd01afSAlok Kumar Sharma       if (auto ST = GenericSubrange->getStride())
952a6dd01afSAlok Kumar Sharma         if (auto *Dependency = ST.dyn_cast<DIVariable *>())
953a6dd01afSAlok Kumar Sharma           Result.push_back(Dependency);
954c929f7adSAdrian Prantl     }
95503dd6f57SAdrian Prantl   }
95603dd6f57SAdrian Prantl   return Result;
957c929f7adSAdrian Prantl }
958c929f7adSAdrian Prantl 
959c929f7adSAdrian Prantl /// Sort local variables so that variables appearing inside of helper
960c929f7adSAdrian Prantl /// expressions come first.
96103dd6f57SAdrian Prantl static SmallVector<DbgVariable *, 8>
sortLocalVars(SmallVectorImpl<DbgVariable * > & Input)96203dd6f57SAdrian Prantl sortLocalVars(SmallVectorImpl<DbgVariable *> &Input) {
96303dd6f57SAdrian Prantl   SmallVector<DbgVariable *, 8> Result;
96403dd6f57SAdrian Prantl   SmallVector<PointerIntPair<DbgVariable *, 1>, 8> WorkList;
96503dd6f57SAdrian Prantl   // Map back from a DIVariable to its containing DbgVariable.
96603dd6f57SAdrian Prantl   SmallDenseMap<const DILocalVariable *, DbgVariable *> DbgVar;
96703dd6f57SAdrian Prantl   // Set of DbgVariables in Result.
96803dd6f57SAdrian Prantl   SmallDenseSet<DbgVariable *, 8> Visited;
96903dd6f57SAdrian Prantl   // For cycle detection.
97003dd6f57SAdrian Prantl   SmallDenseSet<DbgVariable *, 8> Visiting;
97103dd6f57SAdrian Prantl 
97203dd6f57SAdrian Prantl   // Initialize the worklist and the DIVariable lookup table.
973*9e6d1f4bSKazu Hirata   for (auto *Var : reverse(Input)) {
97403dd6f57SAdrian Prantl     DbgVar.insert({Var->getVariable(), Var});
97503dd6f57SAdrian Prantl     WorkList.push_back({Var, 0});
97603dd6f57SAdrian Prantl   }
97703dd6f57SAdrian Prantl 
97803dd6f57SAdrian Prantl   // Perform a stable topological sort by doing a DFS.
97903dd6f57SAdrian Prantl   while (!WorkList.empty()) {
98003dd6f57SAdrian Prantl     auto Item = WorkList.back();
98103dd6f57SAdrian Prantl     DbgVariable *Var = Item.getPointer();
98203dd6f57SAdrian Prantl     bool visitedAllDependencies = Item.getInt();
98303dd6f57SAdrian Prantl     WorkList.pop_back();
98403dd6f57SAdrian Prantl 
985b20da511SAaron Puchert     assert(Var);
98603dd6f57SAdrian Prantl 
98703dd6f57SAdrian Prantl     // Already handled.
98803dd6f57SAdrian Prantl     if (Visited.count(Var))
98903dd6f57SAdrian Prantl       continue;
99003dd6f57SAdrian Prantl 
99103dd6f57SAdrian Prantl     // Add to Result if all dependencies are visited.
99203dd6f57SAdrian Prantl     if (visitedAllDependencies) {
99303dd6f57SAdrian Prantl       Visited.insert(Var);
99403dd6f57SAdrian Prantl       Result.push_back(Var);
99503dd6f57SAdrian Prantl       continue;
99603dd6f57SAdrian Prantl     }
99703dd6f57SAdrian Prantl 
99803dd6f57SAdrian Prantl     // Detect cycles.
99903dd6f57SAdrian Prantl     auto Res = Visiting.insert(Var);
100003dd6f57SAdrian Prantl     if (!Res.second) {
100103dd6f57SAdrian Prantl       assert(false && "dependency cycle in local variables");
100203dd6f57SAdrian Prantl       return Result;
100303dd6f57SAdrian Prantl     }
100403dd6f57SAdrian Prantl 
100503dd6f57SAdrian Prantl     // Push dependencies and this node onto the worklist, so that this node is
100603dd6f57SAdrian Prantl     // visited again after all of its dependencies are handled.
100703dd6f57SAdrian Prantl     WorkList.push_back({Var, 1});
1008*9e6d1f4bSKazu Hirata     for (const auto *Dependency : dependencies(Var)) {
1009b20da511SAaron Puchert       // Don't add dependency if it is in a different lexical scope or a global.
1010b20da511SAaron Puchert       if (const auto *Dep = dyn_cast<const DILocalVariable>(Dependency))
1011b20da511SAaron Puchert         if (DbgVariable *Var = DbgVar.lookup(Dep))
1012b20da511SAaron Puchert           WorkList.push_back({Var, 0});
101303dd6f57SAdrian Prantl     }
101403dd6f57SAdrian Prantl   }
101503dd6f57SAdrian Prantl   return Result;
1016c929f7adSAdrian Prantl }
1017c929f7adSAdrian Prantl 
constructSubprogramScopeDIE(const DISubprogram * Sub,LexicalScope * Scope)10185931b4e5SVedant Kumar DIE &DwarfCompileUnit::constructSubprogramScopeDIE(const DISubprogram *Sub,
10195931b4e5SVedant Kumar                                                    LexicalScope *Scope) {
10201d072348SDavid Blaikie   DIE &ScopeDIE = updateSubprogramScopeDIE(Sub);
10211d072348SDavid Blaikie 
10223e3eb33eSDavid Blaikie   if (Scope) {
10233e3eb33eSDavid Blaikie     assert(!Scope->getInlinedAt());
10243e3eb33eSDavid Blaikie     assert(!Scope->isAbstractScope());
10251dd573dbSDavid Blaikie     // Collect lexical scope children first.
10261dd573dbSDavid Blaikie     // ObjectPointer might be a local (non-argument) local variable if it's a
10271dd573dbSDavid Blaikie     // block's synthetic this pointer.
10281dd573dbSDavid Blaikie     if (DIE *ObjectPointer = createAndAddScopeChildren(Scope, ScopeDIE))
10291dd573dbSDavid Blaikie       addDIEEntry(ScopeDIE, dwarf::DW_AT_object_pointer, *ObjectPointer);
10303e3eb33eSDavid Blaikie   }
10313e3eb33eSDavid Blaikie 
10323e3eb33eSDavid Blaikie   // If this is a variadic function, add an unspecified parameter.
10333e3eb33eSDavid Blaikie   DITypeRefArray FnArgs = Sub->getType()->getTypeArray();
10341dd573dbSDavid Blaikie 
10351d072348SDavid Blaikie   // If we have a single element of null, it is a function that returns void.
10361d072348SDavid Blaikie   // If we have more than one elements and the last one is null, it is a
10371d072348SDavid Blaikie   // variadic function.
1038000fa2c6SDuncan P. N. Exon Smith   if (FnArgs.size() > 1 && !FnArgs[FnArgs.size() - 1] &&
10393a443c29SDavid Blaikie       !includeMinimalInlineScopes())
1040827200c8SDuncan P. N. Exon Smith     ScopeDIE.addChild(
1041827200c8SDuncan P. N. Exon Smith         DIE::get(DIEValueAllocator, dwarf::DW_TAG_unspecified_parameters));
10425931b4e5SVedant Kumar 
10435931b4e5SVedant Kumar   return ScopeDIE;
10441d072348SDavid Blaikie }
10451d072348SDavid Blaikie 
createAndAddScopeChildren(LexicalScope * Scope,DIE & ScopeDIE)104678b65b6fSDavid Blaikie DIE *DwarfCompileUnit::createAndAddScopeChildren(LexicalScope *Scope,
104778b65b6fSDavid Blaikie                                                  DIE &ScopeDIE) {
104890432893SKristina Bessonova   DIE *ObjectPointer = nullptr;
104978b65b6fSDavid Blaikie 
105090432893SKristina Bessonova   // Emit function arguments (order is significant).
105190432893SKristina Bessonova   auto Vars = DU->getScopeVariables().lookup(Scope);
105290432893SKristina Bessonova   for (auto &DV : Vars.Args)
105390432893SKristina Bessonova     ScopeDIE.addChild(constructVariableDIE(*DV.second, *Scope, ObjectPointer));
105490432893SKristina Bessonova 
105590432893SKristina Bessonova   // Emit local variables.
105690432893SKristina Bessonova   auto Locals = sortLocalVars(Vars.Locals);
105790432893SKristina Bessonova   for (DbgVariable *DV : Locals)
105890432893SKristina Bessonova     ScopeDIE.addChild(constructVariableDIE(*DV, *Scope, ObjectPointer));
105990432893SKristina Bessonova 
106081378f7eSKristina Bessonova   // Emit imported entities (skipped in gmlt-like data).
106181378f7eSKristina Bessonova   if (!includeMinimalInlineScopes()) {
106281378f7eSKristina Bessonova     for (const auto *IE : ImportedEntities[Scope->getScopeNode()])
106381378f7eSKristina Bessonova       ScopeDIE.addChild(constructImportedEntityDIE(cast<DIImportedEntity>(IE)));
106481378f7eSKristina Bessonova   }
106581378f7eSKristina Bessonova 
106690432893SKristina Bessonova   // Emit labels.
106790432893SKristina Bessonova   for (DbgLabel *DL : DU->getScopeLabels().lookup(Scope))
106890432893SKristina Bessonova     ScopeDIE.addChild(constructLabelDIE(*DL, *Scope));
106990432893SKristina Bessonova 
107090432893SKristina Bessonova   // Emit inner lexical scopes.
107181378f7eSKristina Bessonova   auto needToEmitLexicalScope = [this](LexicalScope *LS) {
107290432893SKristina Bessonova     if (isa<DISubprogram>(LS->getScopeNode()))
107390432893SKristina Bessonova       return true;
107490432893SKristina Bessonova     auto Vars = DU->getScopeVariables().lookup(LS);
107590432893SKristina Bessonova     if (!Vars.Args.empty() || !Vars.Locals.empty())
107690432893SKristina Bessonova       return true;
107781378f7eSKristina Bessonova     if (!includeMinimalInlineScopes() &&
107881378f7eSKristina Bessonova         !ImportedEntities[LS->getScopeNode()].empty())
107981378f7eSKristina Bessonova       return true;
108081378f7eSKristina Bessonova     return false;
108190432893SKristina Bessonova   };
108290432893SKristina Bessonova   for (LexicalScope *LS : Scope->getChildren()) {
108390432893SKristina Bessonova     // If the lexical block doesn't have non-scope children, skip
108490432893SKristina Bessonova     // its emission and put its children directly to the parent scope.
108590432893SKristina Bessonova     if (needToEmitLexicalScope(LS))
108690432893SKristina Bessonova       constructScopeDIE(LS, ScopeDIE);
108790432893SKristina Bessonova     else
108890432893SKristina Bessonova       createAndAddScopeChildren(LS, ScopeDIE);
108990432893SKristina Bessonova   }
109078b65b6fSDavid Blaikie 
109178b65b6fSDavid Blaikie   return ObjectPointer;
109278b65b6fSDavid Blaikie }
109378b65b6fSDavid Blaikie 
constructAbstractSubprogramScopeDIE(LexicalScope * Scope)109454511353SDehao Chen void DwarfCompileUnit::constructAbstractSubprogramScopeDIE(
109554511353SDehao Chen     LexicalScope *Scope) {
109681378f7eSKristina Bessonova   DIE *&AbsDef = getAbstractSPDies()[Scope->getScopeNode()];
109781378f7eSKristina Bessonova   if (AbsDef)
109881378f7eSKristina Bessonova     return;
109949be5b35SDavid Blaikie 
1100a9308c49SDuncan P. N. Exon Smith   auto *SP = cast<DISubprogram>(Scope->getScopeNode());
110158410f24SDavid Blaikie 
110258410f24SDavid Blaikie   DIE *ContextDIE;
1103294e6895SJonas Devlieghere   DwarfCompileUnit *ContextCU = this;
110458410f24SDavid Blaikie 
11053a443c29SDavid Blaikie   if (includeMinimalInlineScopes())
11063a443c29SDavid Blaikie     ContextDIE = &getUnitDie();
110758410f24SDavid Blaikie   // Some of this is duplicated from DwarfUnit::getOrCreateSubprogramDIE, with
11087c60f20eSDuncan P. N. Exon Smith   // the important distinction that the debug node is not associated with the
11097c60f20eSDuncan P. N. Exon Smith   // DIE (since the debug node will be associated with the concrete DIE, if
111058410f24SDavid Blaikie   // any). It could be refactored to some common utility function.
1111537b4a81SDuncan P. N. Exon Smith   else if (auto *SPDecl = SP->getDeclaration()) {
111258410f24SDavid Blaikie     ContextDIE = &getUnitDie();
111358410f24SDavid Blaikie     getOrCreateSubprogramDIE(SPDecl);
1114294e6895SJonas Devlieghere   } else {
1115da82ce99SFangrui Song     ContextDIE = getOrCreateContextDIE(SP->getScope());
1116294e6895SJonas Devlieghere     // The scope may be shared with a subprogram that has already been
1117294e6895SJonas Devlieghere     // constructed in another CU, in which case we need to construct this
1118294e6895SJonas Devlieghere     // subprogram in the same CU.
1119294e6895SJonas Devlieghere     ContextCU = DD->lookupCU(ContextDIE->getUnitDie());
1120294e6895SJonas Devlieghere   }
112158410f24SDavid Blaikie 
1122f0d997c4SAdrian Kuegel   // Passing null as the associated node because the abstract definition
1123f0d997c4SAdrian Kuegel   // shouldn't be found by lookup.
112481378f7eSKristina Bessonova   AbsDef = &ContextCU->createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE, nullptr);
112581378f7eSKristina Bessonova   ContextCU->applySubprogramAttributesToDefinition(SP, *AbsDef);
112681378f7eSKristina Bessonova   ContextCU->addSInt(*AbsDef, dwarf::DW_AT_inline,
112712f80c0bSZequan Wu                      DD->getDwarfVersion() <= 4 ? Optional<dwarf::Form>()
112812f80c0bSZequan Wu                                                 : dwarf::DW_FORM_implicit_const,
112912f80c0bSZequan Wu                      dwarf::DW_INL_inlined);
113081378f7eSKristina Bessonova   if (DIE *ObjectPointer = ContextCU->createAndAddScopeChildren(Scope, *AbsDef))
113181378f7eSKristina Bessonova     ContextCU->addDIEEntry(*AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer);
113258410f24SDavid Blaikie }
113358410f24SDavid Blaikie 
useGNUAnalogForDwarf5Feature() const1134f7052da6SVedant Kumar bool DwarfCompileUnit::useGNUAnalogForDwarf5Feature() const {
11356371a0a0SDjordje Todorovic   return DD->getDwarfVersion() == 4 && !DD->tuneForLLDB();
1136533dd021SVedant Kumar }
1137533dd021SVedant Kumar 
getDwarf5OrGNUTag(dwarf::Tag Tag) const113858a07148SVedant Kumar dwarf::Tag DwarfCompileUnit::getDwarf5OrGNUTag(dwarf::Tag Tag) const {
1139f7052da6SVedant Kumar   if (!useGNUAnalogForDwarf5Feature())
1140b9973f87SDjordje Todorovic     return Tag;
1141b9973f87SDjordje Todorovic   switch (Tag) {
1142b9973f87SDjordje Todorovic   case dwarf::DW_TAG_call_site:
1143b9973f87SDjordje Todorovic     return dwarf::DW_TAG_GNU_call_site;
1144b9973f87SDjordje Todorovic   case dwarf::DW_TAG_call_site_parameter:
1145b9973f87SDjordje Todorovic     return dwarf::DW_TAG_GNU_call_site_parameter;
1146b9973f87SDjordje Todorovic   default:
114758a07148SVedant Kumar     llvm_unreachable("DWARF5 tag with no GNU analog");
1148b9973f87SDjordje Todorovic   }
1149b9973f87SDjordje Todorovic }
1150b9973f87SDjordje Todorovic 
1151b9973f87SDjordje Todorovic dwarf::Attribute
getDwarf5OrGNUAttr(dwarf::Attribute Attr) const115258a07148SVedant Kumar DwarfCompileUnit::getDwarf5OrGNUAttr(dwarf::Attribute Attr) const {
1153f7052da6SVedant Kumar   if (!useGNUAnalogForDwarf5Feature())
1154b9973f87SDjordje Todorovic     return Attr;
1155b9973f87SDjordje Todorovic   switch (Attr) {
1156b9973f87SDjordje Todorovic   case dwarf::DW_AT_call_all_calls:
1157b9973f87SDjordje Todorovic     return dwarf::DW_AT_GNU_all_call_sites;
1158b9973f87SDjordje Todorovic   case dwarf::DW_AT_call_target:
1159b9973f87SDjordje Todorovic     return dwarf::DW_AT_GNU_call_site_target;
1160b9973f87SDjordje Todorovic   case dwarf::DW_AT_call_origin:
1161b9973f87SDjordje Todorovic     return dwarf::DW_AT_abstract_origin;
116243464509SVedant Kumar   case dwarf::DW_AT_call_return_pc:
1163b9973f87SDjordje Todorovic     return dwarf::DW_AT_low_pc;
1164b9973f87SDjordje Todorovic   case dwarf::DW_AT_call_value:
1165b9973f87SDjordje Todorovic     return dwarf::DW_AT_GNU_call_site_value;
1166b9973f87SDjordje Todorovic   case dwarf::DW_AT_call_tail_call:
1167b9973f87SDjordje Todorovic     return dwarf::DW_AT_GNU_tail_call;
1168b9973f87SDjordje Todorovic   default:
116958a07148SVedant Kumar     llvm_unreachable("DWARF5 attribute with no GNU analog");
1170b9973f87SDjordje Todorovic   }
1171b9973f87SDjordje Todorovic }
1172b9973f87SDjordje Todorovic 
1173533dd021SVedant Kumar dwarf::LocationAtom
getDwarf5OrGNULocationAtom(dwarf::LocationAtom Loc) const1174533dd021SVedant Kumar DwarfCompileUnit::getDwarf5OrGNULocationAtom(dwarf::LocationAtom Loc) const {
1175f7052da6SVedant Kumar   if (!useGNUAnalogForDwarf5Feature())
1176533dd021SVedant Kumar     return Loc;
1177533dd021SVedant Kumar   switch (Loc) {
1178533dd021SVedant Kumar   case dwarf::DW_OP_entry_value:
1179533dd021SVedant Kumar     return dwarf::DW_OP_GNU_entry_value;
1180533dd021SVedant Kumar   default:
1181533dd021SVedant Kumar     llvm_unreachable("DWARF5 location atom with no GNU analog");
1182533dd021SVedant Kumar   }
1183533dd021SVedant Kumar }
1184533dd021SVedant Kumar 
constructCallSiteEntryDIE(DIE & ScopeDIE,const DISubprogram * CalleeSP,bool IsTail,const MCSymbol * PCAddr,const MCSymbol * CallAddr,unsigned CallReg)1185f0120556SVedant Kumar DIE &DwarfCompileUnit::constructCallSiteEntryDIE(DIE &ScopeDIE,
1186d4ce9e46SJeremy Morse                                                  const DISubprogram *CalleeSP,
1187f0120556SVedant Kumar                                                  bool IsTail,
1188f0120556SVedant Kumar                                                  const MCSymbol *PCAddr,
1189f7052da6SVedant Kumar                                                  const MCSymbol *CallAddr,
1190f0120556SVedant Kumar                                                  unsigned CallReg) {
11915931b4e5SVedant Kumar   // Insert a call site entry DIE within ScopeDIE.
119258a07148SVedant Kumar   DIE &CallSiteDIE = createAndAddDIE(getDwarf5OrGNUTag(dwarf::DW_TAG_call_site),
119358a07148SVedant Kumar                                      ScopeDIE, nullptr);
11945931b4e5SVedant Kumar 
1195b9973f87SDjordje Todorovic   if (CallReg) {
1196b9973f87SDjordje Todorovic     // Indirect call.
119758a07148SVedant Kumar     addAddress(CallSiteDIE, getDwarf5OrGNUAttr(dwarf::DW_AT_call_target),
1198b9973f87SDjordje Todorovic                MachineLocation(CallReg));
11990739ccd3SDjordje Todorovic   } else {
1200d4ce9e46SJeremy Morse     DIE *CalleeDIE = getOrCreateSubprogramDIE(CalleeSP);
1201d4ce9e46SJeremy Morse     assert(CalleeDIE && "Could not create DIE for call site entry origin");
120258a07148SVedant Kumar     addDIEEntry(CallSiteDIE, getDwarf5OrGNUAttr(dwarf::DW_AT_call_origin),
1203b9973f87SDjordje Todorovic                 *CalleeDIE);
1204b9973f87SDjordje Todorovic   }
1205b9973f87SDjordje Todorovic 
1206f7052da6SVedant Kumar   if (IsTail) {
1207b9973f87SDjordje Todorovic     // Attach DW_AT_call_tail_call to tail calls for standards compliance.
120858a07148SVedant Kumar     addFlag(CallSiteDIE, getDwarf5OrGNUAttr(dwarf::DW_AT_call_tail_call));
1209b9973f87SDjordje Todorovic 
1210f7052da6SVedant Kumar     // Attach the address of the branch instruction to allow the debugger to
1211f7052da6SVedant Kumar     // show where the tail call occurred. This attribute has no GNU analog.
1212f7052da6SVedant Kumar     //
1213f7052da6SVedant Kumar     // GDB works backwards from non-standard usage of DW_AT_low_pc (in DWARF4
1214f7052da6SVedant Kumar     // mode -- equivalently, in DWARF5 mode, DW_AT_call_return_pc) at tail-call
1215f7052da6SVedant Kumar     // site entries to figure out the PC of tail-calling branch instructions.
1216f7052da6SVedant Kumar     // This means it doesn't need the compiler to emit DW_AT_call_pc, so we
1217f7052da6SVedant Kumar     // don't emit it here.
1218f7052da6SVedant Kumar     //
1219f7052da6SVedant Kumar     // There's no need to tie non-GDB debuggers to this non-standardness, as it
1220f7052da6SVedant Kumar     // adds unnecessary complexity to the debugger. For non-GDB debuggers, emit
1221f7052da6SVedant Kumar     // the standard DW_AT_call_pc info.
1222f7052da6SVedant Kumar     if (!useGNUAnalogForDwarf5Feature())
1223f7052da6SVedant Kumar       addLabelAddress(CallSiteDIE, dwarf::DW_AT_call_pc, CallAddr);
1224f7052da6SVedant Kumar   }
1225f7052da6SVedant Kumar 
12265931b4e5SVedant Kumar   // Attach the return PC to allow the debugger to disambiguate call paths
12275931b4e5SVedant Kumar   // from one function to another.
122843464509SVedant Kumar   //
122943464509SVedant Kumar   // The return PC is only really needed when the call /isn't/ a tail call, but
1230f7052da6SVedant Kumar   // GDB expects it in DWARF4 mode, even for tail calls (see the comment above
1231f7052da6SVedant Kumar   // the DW_AT_call_pc emission logic for an explanation).
1232f7052da6SVedant Kumar   if (!IsTail || useGNUAnalogForDwarf5Feature()) {
1233f0120556SVedant Kumar     assert(PCAddr && "Missing return PC information for a call");
123443464509SVedant Kumar     addLabelAddress(CallSiteDIE,
123543464509SVedant Kumar                     getDwarf5OrGNUAttr(dwarf::DW_AT_call_return_pc), PCAddr);
12365931b4e5SVedant Kumar   }
1237b9973f87SDjordje Todorovic 
12385931b4e5SVedant Kumar   return CallSiteDIE;
12395931b4e5SVedant Kumar }
12405931b4e5SVedant Kumar 
constructCallSiteParmEntryDIEs(DIE & CallSiteDIE,SmallVector<DbgCallSiteParam,4> & Params)1241b9973f87SDjordje Todorovic void DwarfCompileUnit::constructCallSiteParmEntryDIEs(
1242b9973f87SDjordje Todorovic     DIE &CallSiteDIE, SmallVector<DbgCallSiteParam, 4> &Params) {
1243b9973f87SDjordje Todorovic   for (const auto &Param : Params) {
1244b9973f87SDjordje Todorovic     unsigned Register = Param.getRegister();
1245b9973f87SDjordje Todorovic     auto CallSiteDieParam =
1246b9973f87SDjordje Todorovic         DIE::get(DIEValueAllocator,
124758a07148SVedant Kumar                  getDwarf5OrGNUTag(dwarf::DW_TAG_call_site_parameter));
1248b9973f87SDjordje Todorovic     insertDIE(CallSiteDieParam);
1249b9973f87SDjordje Todorovic     addAddress(*CallSiteDieParam, dwarf::DW_AT_location,
1250b9973f87SDjordje Todorovic                MachineLocation(Register));
1251b9973f87SDjordje Todorovic 
1252b9973f87SDjordje Todorovic     DIELoc *Loc = new (DIEValueAllocator) DIELoc;
1253b9973f87SDjordje Todorovic     DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
1254b9973f87SDjordje Todorovic     DwarfExpr.setCallSiteParamValueFlag();
1255b9973f87SDjordje Todorovic 
1256b9973f87SDjordje Todorovic     DwarfDebug::emitDebugLocValue(*Asm, nullptr, Param.getValue(), DwarfExpr);
1257b9973f87SDjordje Todorovic 
125858a07148SVedant Kumar     addBlock(*CallSiteDieParam, getDwarf5OrGNUAttr(dwarf::DW_AT_call_value),
1259b9973f87SDjordje Todorovic              DwarfExpr.finalize());
1260b9973f87SDjordje Todorovic 
1261b9973f87SDjordje Todorovic     CallSiteDIE.addChild(CallSiteDieParam);
1262b9973f87SDjordje Todorovic   }
1263b9973f87SDjordje Todorovic }
1264b9973f87SDjordje Todorovic 
constructImportedEntityDIE(const DIImportedEntity * Module)126581378f7eSKristina Bessonova DIE *DwarfCompileUnit::constructImportedEntityDIE(
126681378f7eSKristina Bessonova     const DIImportedEntity *Module) {
126781378f7eSKristina Bessonova   DIE *IMDie = DIE::get(DIEValueAllocator, (dwarf::Tag)Module->getTag());
126881378f7eSKristina Bessonova   insertDIE(Module, IMDie);
1269987fe227SFrederic Riss   DIE *EntityDie;
127081378f7eSKristina Bessonova   auto *Entity = Module->getEntity();
1271a9308c49SDuncan P. N. Exon Smith   if (auto *NS = dyn_cast<DINamespace>(Entity))
1272e686f159SDuncan P. N. Exon Smith     EntityDie = getOrCreateNameSpace(NS);
127308a388baSAdrian Prantl   else if (auto *M = dyn_cast<DIModule>(Entity))
127408a388baSAdrian Prantl     EntityDie = getOrCreateModule(M);
127581378f7eSKristina Bessonova   else if (auto *SP = dyn_cast<DISubprogram>(Entity))
1276e686f159SDuncan P. N. Exon Smith     EntityDie = getOrCreateSubprogramDIE(SP);
127781378f7eSKristina Bessonova   else if (auto *T = dyn_cast<DIType>(Entity))
1278e686f159SDuncan P. N. Exon Smith     EntityDie = getOrCreateTypeDIE(T);
1279a9308c49SDuncan P. N. Exon Smith   else if (auto *GV = dyn_cast<DIGlobalVariable>(Entity))
1280bceaaa96SAdrian Prantl     EntityDie = getOrCreateGlobalVariableDIE(GV, {});
1281987fe227SFrederic Riss   else
1282987fe227SFrederic Riss     EntityDie = getDIE(Entity);
1283987fe227SFrederic Riss   assert(EntityDie);
128481378f7eSKristina Bessonova   addSourceLine(*IMDie, Module->getLine(), Module->getFile());
1285987fe227SFrederic Riss   addDIEEntry(*IMDie, dwarf::DW_AT_import, *EntityDie);
128681378f7eSKristina Bessonova   StringRef Name = Module->getName();
1287987fe227SFrederic Riss   if (!Name.empty())
1288987fe227SFrederic Riss     addString(*IMDie, dwarf::DW_AT_name, Name);
1289987fe227SFrederic Riss 
1290a5b72abcSAlok Kumar Sharma   // This is for imported module with renamed entities (such as variables and
1291a5b72abcSAlok Kumar Sharma   // subprograms).
129281378f7eSKristina Bessonova   DINodeArray Elements = Module->getElements();
1293a5b72abcSAlok Kumar Sharma   for (const auto *Element : Elements) {
1294a5b72abcSAlok Kumar Sharma     if (!Element)
1295a5b72abcSAlok Kumar Sharma       continue;
129681378f7eSKristina Bessonova     IMDie->addChild(
129781378f7eSKristina Bessonova         constructImportedEntityDIE(cast<DIImportedEntity>(Element)));
1298f9607d45SMuhammad Omair Javaid   }
129981378f7eSKristina Bessonova 
1300f9607d45SMuhammad Omair Javaid   return IMDie;
130175b622a7SKristina Bessonova }
130262a6b9e9SDavid Blaikie 
finishSubprogramDefinition(const DISubprogram * SP)1303a9308c49SDuncan P. N. Exon Smith void DwarfCompileUnit::finishSubprogramDefinition(const DISubprogram *SP) {
130472da9391SAmjad Aboud   DIE *D = getDIE(SP);
130581378f7eSKristina Bessonova   if (DIE *AbsSPDIE = getAbstractSPDies().lookup(SP)) {
1306f0d997c4SAdrian Kuegel     if (D)
13074191cbceSDavid Blaikie       // If this subprogram has an abstract definition, reference that
13084191cbceSDavid Blaikie       addDIEEntry(*D, dwarf::DW_AT_abstract_origin, *AbsSPDIE);
130972da9391SAmjad Aboud   } else {
13103e3eb33eSDavid Blaikie     assert(D || includeMinimalInlineScopes());
131172da9391SAmjad Aboud     if (D)
13124191cbceSDavid Blaikie       // And attach the attributes
13134191cbceSDavid Blaikie       applySubprogramAttributesToDefinition(SP, *D);
13144191cbceSDavid Blaikie   }
13154191cbceSDavid Blaikie }
13164191cbceSDavid Blaikie 
finishEntityDefinition(const DbgEntity * Entity)13172532ac88SHsiangkai Wang void DwarfCompileUnit::finishEntityDefinition(const DbgEntity *Entity) {
13182532ac88SHsiangkai Wang   DbgEntity *AbsEntity = getExistingAbstractEntity(Entity->getEntity());
13192532ac88SHsiangkai Wang 
13202532ac88SHsiangkai Wang   auto *Die = Entity->getDIE();
13212532ac88SHsiangkai Wang   /// Label may be used to generate DW_AT_low_pc, so put it outside
13222532ac88SHsiangkai Wang   /// if/else block.
13232532ac88SHsiangkai Wang   const DbgLabel *Label = nullptr;
13242532ac88SHsiangkai Wang   if (AbsEntity && AbsEntity->getDIE()) {
13252532ac88SHsiangkai Wang     addDIEEntry(*Die, dwarf::DW_AT_abstract_origin, *AbsEntity->getDIE());
13262532ac88SHsiangkai Wang     Label = dyn_cast<const DbgLabel>(Entity);
13272532ac88SHsiangkai Wang   } else {
13282532ac88SHsiangkai Wang     if (const DbgVariable *Var = dyn_cast<const DbgVariable>(Entity))
13292532ac88SHsiangkai Wang       applyVariableAttributes(*Var, *Die);
13302532ac88SHsiangkai Wang     else if ((Label = dyn_cast<const DbgLabel>(Entity)))
13312532ac88SHsiangkai Wang       applyLabelAttributes(*Label, *Die);
13322532ac88SHsiangkai Wang     else
13332532ac88SHsiangkai Wang       llvm_unreachable("DbgEntity must be DbgVariable or DbgLabel.");
1334488393f8SDavid Blaikie   }
1335488393f8SDavid Blaikie 
133655321d82SHsiangkai Wang   if (Label)
133755321d82SHsiangkai Wang     if (const auto *Sym = Label->getSymbol())
13382532ac88SHsiangkai Wang       addLabelAddress(*Die, dwarf::DW_AT_low_pc, Sym);
13392532ac88SHsiangkai Wang }
1340488393f8SDavid Blaikie 
getExistingAbstractEntity(const DINode * Node)13412532ac88SHsiangkai Wang DbgEntity *DwarfCompileUnit::getExistingAbstractEntity(const DINode *Node) {
13422532ac88SHsiangkai Wang   auto &AbstractEntities = getAbstractEntities();
13432532ac88SHsiangkai Wang   auto I = AbstractEntities.find(Node);
13442532ac88SHsiangkai Wang   if (I != AbstractEntities.end())
1345488393f8SDavid Blaikie     return I->second.get();
1346488393f8SDavid Blaikie   return nullptr;
1347488393f8SDavid Blaikie }
1348488393f8SDavid Blaikie 
createAbstractEntity(const DINode * Node,LexicalScope * Scope)13492532ac88SHsiangkai Wang void DwarfCompileUnit::createAbstractEntity(const DINode *Node,
1350488393f8SDavid Blaikie                                             LexicalScope *Scope) {
1351488393f8SDavid Blaikie   assert(Scope && Scope->isAbstractScope());
13522532ac88SHsiangkai Wang   auto &Entity = getAbstractEntities()[Node];
13532532ac88SHsiangkai Wang   if (isa<const DILocalVariable>(Node)) {
13540eaee545SJonas Devlieghere     Entity = std::make_unique<DbgVariable>(
13552532ac88SHsiangkai Wang                         cast<const DILocalVariable>(Node), nullptr /* IA */);;
13562532ac88SHsiangkai Wang     DU->addScopeVariable(Scope, cast<DbgVariable>(Entity.get()));
13572532ac88SHsiangkai Wang   } else if (isa<const DILabel>(Node)) {
13580eaee545SJonas Devlieghere     Entity = std::make_unique<DbgLabel>(
13592532ac88SHsiangkai Wang                         cast<const DILabel>(Node), nullptr /* IA */);
13602532ac88SHsiangkai Wang     DU->addScopeLabel(Scope, cast<DbgLabel>(Entity.get()));
13612532ac88SHsiangkai Wang   }
1362488393f8SDavid Blaikie }
1363488393f8SDavid Blaikie 
emitHeader(bool UseOffsets)1364063d725fSRafael Espindola void DwarfCompileUnit::emitHeader(bool UseOffsets) {
1365b6726a9eSDavid Blaikie   // Don't bother labeling the .dwo unit, as its offset isn't used.
1366bff36086SAlexey Bataev   if (!Skeleton && !DD->useSectionsAsReferences()) {
13679ab09237SRafael Espindola     LabelBegin = Asm->createTempSymbol("cu_begin");
13686d2d589bSFangrui Song     Asm->OutStreamer->emitLabel(LabelBegin);
13693c311148SRafael Espindola   }
1370ae57e66eSDavid Blaikie 
1371cddd6044SPaul Robinson   dwarf::UnitType UT = Skeleton ? dwarf::DW_UT_split_compile
1372cddd6044SPaul Robinson                                 : DD->useSplitDwarf() ? dwarf::DW_UT_skeleton
1373cddd6044SPaul Robinson                                                       : dwarf::DW_UT_compile;
1374cddd6044SPaul Robinson   DwarfUnit::emitCommonHeader(UseOffsets, UT);
1375543c0e1dSPaul Robinson   if (DD->getDwarfVersion() >= 5 && UT != dwarf::DW_UT_compile)
1376543c0e1dSPaul Robinson     Asm->emitInt64(getDWOId());
1377ae57e66eSDavid Blaikie }
1378ae57e66eSDavid Blaikie 
hasDwarfPubSections() const1379b52e2366SPeter Collingbourne bool DwarfCompileUnit::hasDwarfPubSections() const {
138066cf14d0SDavid Blaikie   switch (CUNode->getNameTableKind()) {
138166cf14d0SDavid Blaikie   case DICompileUnit::DebugNameTableKind::None:
138266cf14d0SDavid Blaikie     return false;
1383b52e2366SPeter Collingbourne     // Opting in to GNU Pubnames/types overrides the default to ensure these are
1384b52e2366SPeter Collingbourne     // generated for things like Gold's gdb_index generation.
138566cf14d0SDavid Blaikie   case DICompileUnit::DebugNameTableKind::GNU:
1386b52e2366SPeter Collingbourne     return true;
138766cf14d0SDavid Blaikie   case DICompileUnit::DebugNameTableKind::Default:
13880e03047eSDavid Blaikie     return DD->tuneForGDB() && !includeMinimalInlineScopes() &&
13892f511762SDavid Blaikie            !CUNode->isDebugDirectivesOnly() &&
13902f511762SDavid Blaikie            DD->getAccelTableKind() != AccelTableKind::Apple &&
13912f511762SDavid Blaikie            DD->getDwarfVersion() < 5;
1392b52e2366SPeter Collingbourne   }
139322d580f2SSimon Pilgrim   llvm_unreachable("Unhandled DICompileUnit::DebugNameTableKind enum");
139466cf14d0SDavid Blaikie }
1395b52e2366SPeter Collingbourne 
1396192b45c1SDavid Blaikie /// addGlobalName - Add a new global name to the compile unit.
addGlobalName(StringRef Name,const DIE & Die,const DIScope * Context)1397a0e3c751SDavid Blaikie void DwarfCompileUnit::addGlobalName(StringRef Name, const DIE &Die,
1398a9308c49SDuncan P. N. Exon Smith                                      const DIScope *Context) {
1399b52e2366SPeter Collingbourne   if (!hasDwarfPubSections())
1400192b45c1SDavid Blaikie     return;
1401192b45c1SDavid Blaikie   std::string FullName = getParentContextString(Context) + Name.str();
1402192b45c1SDavid Blaikie   GlobalNames[FullName] = &Die;
1403192b45c1SDavid Blaikie }
1404192b45c1SDavid Blaikie 
addGlobalNameForTypeUnit(StringRef Name,const DIScope * Context)1405a0e3c751SDavid Blaikie void DwarfCompileUnit::addGlobalNameForTypeUnit(StringRef Name,
1406a0e3c751SDavid Blaikie                                                 const DIScope *Context) {
1407b52e2366SPeter Collingbourne   if (!hasDwarfPubSections())
1408a0e3c751SDavid Blaikie     return;
1409a0e3c751SDavid Blaikie   std::string FullName = getParentContextString(Context) + Name.str();
1410a0e3c751SDavid Blaikie   // Insert, allowing the entry to remain as-is if it's already present
1411a0e3c751SDavid Blaikie   // This way the CU-level type DIE is preferred over the "can't describe this
1412a0e3c751SDavid Blaikie   // type as a unit offset because it's not really in the CU at all, it's only
1413a0e3c751SDavid Blaikie   // in a type unit"
1414a0e3c751SDavid Blaikie   GlobalNames.insert(std::make_pair(std::move(FullName), &getUnitDie()));
1415a0e3c751SDavid Blaikie }
1416a0e3c751SDavid Blaikie 
1417192b45c1SDavid Blaikie /// Add a new global type to the unit.
addGlobalType(const DIType * Ty,const DIE & Die,const DIScope * Context)1418a9308c49SDuncan P. N. Exon Smith void DwarfCompileUnit::addGlobalType(const DIType *Ty, const DIE &Die,
1419a9308c49SDuncan P. N. Exon Smith                                      const DIScope *Context) {
1420b52e2366SPeter Collingbourne   if (!hasDwarfPubSections())
1421192b45c1SDavid Blaikie     return;
1422b1055640SDuncan P. N. Exon Smith   std::string FullName = getParentContextString(Context) + Ty->getName().str();
1423192b45c1SDavid Blaikie   GlobalTypes[FullName] = &Die;
1424192b45c1SDavid Blaikie }
1425ae57e66eSDavid Blaikie 
addGlobalTypeUnitType(const DIType * Ty,const DIScope * Context)1426a0e3c751SDavid Blaikie void DwarfCompileUnit::addGlobalTypeUnitType(const DIType *Ty,
1427a0e3c751SDavid Blaikie                                              const DIScope *Context) {
1428b52e2366SPeter Collingbourne   if (!hasDwarfPubSections())
1429a0e3c751SDavid Blaikie     return;
1430a0e3c751SDavid Blaikie   std::string FullName = getParentContextString(Context) + Ty->getName().str();
1431a0e3c751SDavid Blaikie   // Insert, allowing the entry to remain as-is if it's already present
1432a0e3c751SDavid Blaikie   // This way the CU-level type DIE is preferred over the "can't describe this
1433a0e3c751SDavid Blaikie   // type as a unit offset because it's not really in the CU at all, it's only
1434a0e3c751SDavid Blaikie   // in a type unit"
1435a0e3c751SDavid Blaikie   GlobalTypes.insert(std::make_pair(std::move(FullName), &getUnitDie()));
1436a0e3c751SDavid Blaikie }
1437a0e3c751SDavid Blaikie 
addVariableAddress(const DbgVariable & DV,DIE & Die,MachineLocation Location)14387d48be2bSDavid Blaikie void DwarfCompileUnit::addVariableAddress(const DbgVariable &DV, DIE &Die,
14397d48be2bSDavid Blaikie                                           MachineLocation Location) {
1440e6cc531bSDuncan P. N. Exon Smith   if (DV.hasComplexAddress())
14417d48be2bSDavid Blaikie     addComplexAddress(DV, Die, dwarf::DW_AT_location, Location);
14427d48be2bSDavid Blaikie   else
14435883af3fSAdrian Prantl     addAddress(Die, dwarf::DW_AT_location, Location);
14447d48be2bSDavid Blaikie }
1445f7435ee6SDavid Blaikie 
1446f7435ee6SDavid Blaikie /// Add an address attribute to a die based on the location provided.
addAddress(DIE & Die,dwarf::Attribute Attribute,const MachineLocation & Location)1447f7435ee6SDavid Blaikie void DwarfCompileUnit::addAddress(DIE &Die, dwarf::Attribute Attribute,
14485883af3fSAdrian Prantl                                   const MachineLocation &Location) {
1449e7e1d0c7SDuncan P. N. Exon Smith   DIELoc *Loc = new (DIEValueAllocator) DIELoc;
1450956484b7SAdrian Prantl   DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
1451c12cee36SAdrian Prantl   if (Location.isIndirect())
1452c12cee36SAdrian Prantl     DwarfExpr.setMemoryLocationKind();
1453f7435ee6SDavid Blaikie 
14542049c0d7SAdrian Prantl   DIExpressionCursor Cursor({});
1455956484b7SAdrian Prantl   const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();
1456c12cee36SAdrian Prantl   if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
1457ab255fcdSAdrian Prantl     return;
1458956484b7SAdrian Prantl   DwarfExpr.addExpression(std::move(Cursor));
1459ab255fcdSAdrian Prantl 
1460f7435ee6SDavid Blaikie   // Now attach the location information to the DIE.
1461956484b7SAdrian Prantl   addBlock(Die, Attribute, DwarfExpr.finalize());
1462dabd2622SEvgenii Stepanov 
1463dabd2622SEvgenii Stepanov   if (DwarfExpr.TagOffset)
1464dabd2622SEvgenii Stepanov     addUInt(Die, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,
1465dabd2622SEvgenii Stepanov             *DwarfExpr.TagOffset);
1466f7435ee6SDavid Blaikie }
146777895fb2SDavid Blaikie 
146877895fb2SDavid Blaikie /// Start with the address based on the location provided, and generate the
146977895fb2SDavid Blaikie /// DWARF information necessary to find the actual variable given the extra
147077895fb2SDavid Blaikie /// address information encoded in the DbgVariable, starting from the starting
147177895fb2SDavid Blaikie /// location.  Add the DWARF information to the die.
addComplexAddress(const DbgVariable & DV,DIE & Die,dwarf::Attribute Attribute,const MachineLocation & Location)147277895fb2SDavid Blaikie void DwarfCompileUnit::addComplexAddress(const DbgVariable &DV, DIE &Die,
147377895fb2SDavid Blaikie                                          dwarf::Attribute Attribute,
147477895fb2SDavid Blaikie                                          const MachineLocation &Location) {
1475e7e1d0c7SDuncan P. N. Exon Smith   DIELoc *Loc = new (DIEValueAllocator) DIELoc;
14767813d9c9SAdrian Prantl   DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
1477956484b7SAdrian Prantl   const DIExpression *DIExpr = DV.getSingleExpression();
1478956484b7SAdrian Prantl   DwarfExpr.addFragmentOffset(DIExpr);
14796e39379bSVedant Kumar   DwarfExpr.setLocation(Location, DIExpr);
1480956484b7SAdrian Prantl 
14812049c0d7SAdrian Prantl   DIExpressionCursor Cursor(DIExpr);
148212aca5deSDjordje Todorovic 
14836e39379bSVedant Kumar   if (DIExpr->isEntryValue())
14841ae2d9a2SDavid Stenberg     DwarfExpr.beginEntryValueExpression(Cursor);
148512aca5deSDjordje Todorovic 
148696c9ae6aSPeter Collingbourne   const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();
1487c12cee36SAdrian Prantl   if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
148854286bdaSAdrian Prantl     return;
1489956484b7SAdrian Prantl   DwarfExpr.addExpression(std::move(Cursor));
149077895fb2SDavid Blaikie 
149177895fb2SDavid Blaikie   // Now attach the location information to the DIE.
1492956484b7SAdrian Prantl   addBlock(Die, Attribute, DwarfExpr.finalize());
1493dabd2622SEvgenii Stepanov 
1494dabd2622SEvgenii Stepanov   if (DwarfExpr.TagOffset)
1495dabd2622SEvgenii Stepanov     addUInt(Die, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,
1496dabd2622SEvgenii Stepanov             *DwarfExpr.TagOffset);
149777895fb2SDavid Blaikie }
14984bc0881aSDavid Blaikie 
14994bc0881aSDavid Blaikie /// Add a Dwarf loclistptr attribute data and value.
addLocationList(DIE & Die,dwarf::Attribute Attribute,unsigned Index)15004bc0881aSDavid Blaikie void DwarfCompileUnit::addLocationList(DIE &Die, dwarf::Attribute Attribute,
15014bc0881aSDavid Blaikie                                        unsigned Index) {
150226f1f188SIgor Kudrin   dwarf::Form Form = (DD->getDwarfVersion() >= 5)
150326f1f188SIgor Kudrin                          ? dwarf::DW_FORM_loclistx
150426f1f188SIgor Kudrin                          : DD->getDwarfSectionOffsetForm();
15059deb7eeaSChen Zheng   addAttribute(Die, Attribute, Form, DIELocList(Index));
15064bc0881aSDavid Blaikie }
150702a6333bSDavid Blaikie 
applyVariableAttributes(const DbgVariable & Var,DIE & VariableDie)15088c485b5dSDavid Blaikie void DwarfCompileUnit::applyVariableAttributes(const DbgVariable &Var,
150902a6333bSDavid Blaikie                                                DIE &VariableDie) {
151002a6333bSDavid Blaikie   StringRef Name = Var.getName();
151102a6333bSDavid Blaikie   if (!Name.empty())
151202a6333bSDavid Blaikie     addString(VariableDie, dwarf::DW_AT_name, Name);
15133c989984SVictor Leschuk   const auto *DIVar = Var.getVariable();
151489424a82SYonghong Song   if (DIVar) {
15153c989984SVictor Leschuk     if (uint32_t AlignInBytes = DIVar->getAlignInBytes())
15163c989984SVictor Leschuk       addUInt(VariableDie, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,
15173c989984SVictor Leschuk               AlignInBytes);
151889424a82SYonghong Song     addAnnotation(VariableDie, DIVar->getAnnotations());
151989424a82SYonghong Song   }
15203c989984SVictor Leschuk 
15213c989984SVictor Leschuk   addSourceLine(VariableDie, DIVar);
152202a6333bSDavid Blaikie   addType(VariableDie, Var.getType());
152302a6333bSDavid Blaikie   if (Var.isArtificial())
152402a6333bSDavid Blaikie     addFlag(VariableDie, dwarf::DW_AT_artificial);
152502a6333bSDavid Blaikie }
152697802080SDavid Blaikie 
applyLabelAttributes(const DbgLabel & Label,DIE & LabelDie)15272532ac88SHsiangkai Wang void DwarfCompileUnit::applyLabelAttributes(const DbgLabel &Label,
15282532ac88SHsiangkai Wang                                             DIE &LabelDie) {
15292532ac88SHsiangkai Wang   StringRef Name = Label.getName();
15302532ac88SHsiangkai Wang   if (!Name.empty())
15312532ac88SHsiangkai Wang     addString(LabelDie, dwarf::DW_AT_name, Name);
15322532ac88SHsiangkai Wang   const auto *DILabel = Label.getLabel();
15332532ac88SHsiangkai Wang   addSourceLine(LabelDie, DILabel);
15342532ac88SHsiangkai Wang }
15352532ac88SHsiangkai Wang 
153697802080SDavid Blaikie /// Add a Dwarf expression attribute data and value.
addExpr(DIELoc & Die,dwarf::Form Form,const MCExpr * Expr)153797802080SDavid Blaikie void DwarfCompileUnit::addExpr(DIELoc &Die, dwarf::Form Form,
153897802080SDavid Blaikie                                const MCExpr *Expr) {
15399deb7eeaSChen Zheng   addAttribute(Die, (dwarf::Attribute)0, Form, DIEExpr(Expr));
154097802080SDavid Blaikie }
15413363a57cSDavid Blaikie 
applySubprogramAttributesToDefinition(const DISubprogram * SP,DIE & SPDie)15422fbe1354SDuncan P. N. Exon Smith void DwarfCompileUnit::applySubprogramAttributesToDefinition(
1543a9308c49SDuncan P. N. Exon Smith     const DISubprogram *SP, DIE &SPDie) {
1544537b4a81SDuncan P. N. Exon Smith   auto *SPDecl = SP->getDeclaration();
1545da82ce99SFangrui Song   auto *Context = SPDecl ? SPDecl->getScope() : SP->getScope();
15463a443c29SDavid Blaikie   applySubprogramAttributes(SP, SPDie, includeMinimalInlineScopes());
1547537b4a81SDuncan P. N. Exon Smith   addGlobalName(SP->getName(), SPDie, Context);
15483363a57cSDavid Blaikie }
1549cafd962dSDavid Blaikie 
isDwoUnit() const1550cafd962dSDavid Blaikie bool DwarfCompileUnit::isDwoUnit() const {
1551cafd962dSDavid Blaikie   return DD->useSplitDwarf() && Skeleton;
1552cafd962dSDavid Blaikie }
15533a443c29SDavid Blaikie 
finishNonUnitTypeDIE(DIE & D,const DICompositeType * CTy)1554832c7d9fSDavid Blaikie void DwarfCompileUnit::finishNonUnitTypeDIE(DIE& D, const DICompositeType *CTy) {
1555832c7d9fSDavid Blaikie   constructTypeDIE(D, CTy);
1556832c7d9fSDavid Blaikie }
1557832c7d9fSDavid Blaikie 
includeMinimalInlineScopes() const15583a443c29SDavid Blaikie bool DwarfCompileUnit::includeMinimalInlineScopes() const {
1559b939a257SAdrian Prantl   return getCUNode()->getEmissionKind() == DICompileUnit::LineTablesOnly ||
15603a443c29SDavid Blaikie          (DD->useSplitDwarf() && !Skeleton);
15613a443c29SDavid Blaikie }
156261c127c1SDavid Blaikie 
addAddrTableBase()156361c127c1SDavid Blaikie void DwarfCompileUnit::addAddrTableBase() {
156461c127c1SDavid Blaikie   const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
156561c127c1SDavid Blaikie   MCSymbol *Label = DD->getAddressPool().getLabel();
156661c127c1SDavid Blaikie   addSectionLabel(getUnitDie(),
15671eade73dSIgor Kudrin                   DD->getDwarfVersion() >= 5 ? dwarf::DW_AT_addr_base
156861c127c1SDavid Blaikie                                              : dwarf::DW_AT_GNU_addr_base,
156961c127c1SDavid Blaikie                   Label, TLOF.getDwarfAddrSection()->getBeginSymbol());
157061c127c1SDavid Blaikie }
1571b86ce219SMarkus Lavin 
addBaseTypeRef(DIEValueList & Die,int64_t Idx)1572b86ce219SMarkus Lavin void DwarfCompileUnit::addBaseTypeRef(DIEValueList &Die, int64_t Idx) {
15739deb7eeaSChen Zheng   addAttribute(Die, (dwarf::Attribute)0, dwarf::DW_FORM_udata,
1574b86ce219SMarkus Lavin                new (DIEValueAllocator) DIEBaseTypeRef(this, Idx));
1575b86ce219SMarkus Lavin }
1576b86ce219SMarkus Lavin 
createBaseTypeDIEs()1577b86ce219SMarkus Lavin void DwarfCompileUnit::createBaseTypeDIEs() {
1578b86ce219SMarkus Lavin   // Insert the base_type DIEs directly after the CU so that their offsets will
1579b86ce219SMarkus Lavin   // fit in the fixed size ULEB128 used inside the location expressions.
1580b86ce219SMarkus Lavin   // Maintain order by iterating backwards and inserting to the front of CU
1581b86ce219SMarkus Lavin   // child list.
1582b86ce219SMarkus Lavin   for (auto &Btr : reverse(ExprRefedBaseTypes)) {
1583b86ce219SMarkus Lavin     DIE &Die = getUnitDie().addChildFront(
1584b86ce219SMarkus Lavin       DIE::get(DIEValueAllocator, dwarf::DW_TAG_base_type));
1585b86ce219SMarkus Lavin     SmallString<32> Str;
1586b86ce219SMarkus Lavin     addString(Die, dwarf::DW_AT_name,
1587b86ce219SMarkus Lavin               Twine(dwarf::AttributeEncodingString(Btr.Encoding) +
1588b86ce219SMarkus Lavin                     "_" + Twine(Btr.BitSize)).toStringRef(Str));
1589b86ce219SMarkus Lavin     addUInt(Die, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, Btr.Encoding);
1590b6a41fddSOCHyams     // Round up to smallest number of bytes that contains this number of bits.
1591b6a41fddSOCHyams     addUInt(Die, dwarf::DW_AT_byte_size, None, divideCeil(Btr.BitSize, 8));
1592b86ce219SMarkus Lavin 
1593b86ce219SMarkus Lavin     Btr.Die = &Die;
1594b86ce219SMarkus Lavin   }
1595b86ce219SMarkus Lavin }
1596