16e07bfd0SEugene Zelenko //===- llvm/CodeGen/DwarfCompileUnit.cpp - Dwarf Compile Units ------------===//
23443575cSPaul Robinson //
33443575cSPaul Robinson //                     The LLVM Compiler Infrastructure
43443575cSPaul Robinson //
53443575cSPaul Robinson // This file is distributed under the University of Illinois Open Source
63443575cSPaul Robinson // License. See LICENSE.TXT for details.
73443575cSPaul Robinson //
83443575cSPaul Robinson //===----------------------------------------------------------------------===//
93443575cSPaul Robinson //
103443575cSPaul Robinson // This file contains support for constructing a dwarf compile unit.
113443575cSPaul Robinson //
123443575cSPaul Robinson //===----------------------------------------------------------------------===//
133443575cSPaul Robinson 
1437c52310SDavid Blaikie #include "DwarfCompileUnit.h"
156e07bfd0SEugene Zelenko #include "AddressPool.h"
166e07bfd0SEugene Zelenko #include "DwarfDebug.h"
177813d9c9SAdrian Prantl #include "DwarfExpression.h"
186e07bfd0SEugene Zelenko #include "DwarfUnit.h"
196e07bfd0SEugene Zelenko #include "llvm/ADT/None.h"
206e07bfd0SEugene Zelenko #include "llvm/ADT/STLExtras.h"
216e07bfd0SEugene Zelenko #include "llvm/ADT/SmallVector.h"
226e07bfd0SEugene Zelenko #include "llvm/ADT/StringRef.h"
236e07bfd0SEugene Zelenko #include "llvm/BinaryFormat/Dwarf.h"
246e07bfd0SEugene Zelenko #include "llvm/CodeGen/AsmPrinter.h"
256e07bfd0SEugene Zelenko #include "llvm/CodeGen/DIE.h"
266e07bfd0SEugene Zelenko #include "llvm/CodeGen/LexicalScopes.h"
27cda2aa82SDavid Blaikie #include "llvm/CodeGen/MachineFunction.h"
286e07bfd0SEugene Zelenko #include "llvm/CodeGen/MachineInstr.h"
296e07bfd0SEugene Zelenko #include "llvm/CodeGen/MachineOperand.h"
30b3bde2eaSDavid Blaikie #include "llvm/CodeGen/TargetFrameLowering.h"
31b3bde2eaSDavid Blaikie #include "llvm/CodeGen/TargetRegisterInfo.h"
32b3bde2eaSDavid Blaikie #include "llvm/CodeGen/TargetSubtargetInfo.h"
3337c52310SDavid Blaikie #include "llvm/IR/DataLayout.h"
346e07bfd0SEugene Zelenko #include "llvm/IR/DebugInfo.h"
356e07bfd0SEugene Zelenko #include "llvm/IR/DebugInfoMetadata.h"
3637c52310SDavid Blaikie #include "llvm/IR/GlobalVariable.h"
376e07bfd0SEugene Zelenko #include "llvm/MC/MCSection.h"
3837c52310SDavid Blaikie #include "llvm/MC/MCStreamer.h"
396e07bfd0SEugene Zelenko #include "llvm/MC/MCSymbol.h"
40b3bde2eaSDavid Blaikie #include "llvm/MC/MachineLocation.h"
416e07bfd0SEugene Zelenko #include "llvm/Support/Casting.h"
426054e650SDavid Blaikie #include "llvm/Target/TargetLoweringObjectFile.h"
43cda2aa82SDavid Blaikie #include "llvm/Target/TargetMachine.h"
446e07bfd0SEugene Zelenko #include "llvm/Target/TargetOptions.h"
456e07bfd0SEugene Zelenko #include <algorithm>
466e07bfd0SEugene Zelenko #include <cassert>
476e07bfd0SEugene Zelenko #include <cstdint>
486e07bfd0SEugene Zelenko #include <iterator>
496e07bfd0SEugene Zelenko #include <memory>
506e07bfd0SEugene Zelenko #include <string>
516e07bfd0SEugene Zelenko #include <utility>
5237c52310SDavid Blaikie 
536e07bfd0SEugene Zelenko using namespace llvm;
5437c52310SDavid Blaikie 
55a9308c49SDuncan P. N. Exon Smith DwarfCompileUnit::DwarfCompileUnit(unsigned UID, const DICompileUnit *Node,
5637c52310SDavid Blaikie                                    AsmPrinter *A, DwarfDebug *DW,
5737c52310SDavid Blaikie                                    DwarfFile *DWU)
586e07bfd0SEugene Zelenko     : DwarfUnit(dwarf::DW_TAG_compile_unit, Node, A, DW, DWU), UniqueID(UID) {
5937c52310SDavid Blaikie   insertDIE(Node, &getUnitDie());
608bbce8adSAmjad Aboud   MacroLabelBegin = Asm->createTempSymbol("cu_macro_begin");
6137c52310SDavid Blaikie }
6237c52310SDavid Blaikie 
6337c52310SDavid Blaikie /// addLabelAddress - Add a dwarf label attribute data and value using
6437c52310SDavid Blaikie /// DW_FORM_addr or DW_FORM_GNU_addr_index.
6537c52310SDavid Blaikie void DwarfCompileUnit::addLabelAddress(DIE &Die, dwarf::Attribute Attribute,
6637c52310SDavid Blaikie                                        const MCSymbol *Label) {
6737c52310SDavid Blaikie   // Don't use the address pool in non-fission or in the skeleton unit itself.
6837c52310SDavid Blaikie   // FIXME: Once GDB supports this, it's probably worthwhile using the address
6937c52310SDavid Blaikie   // pool from the skeleton - maybe even in non-fission (possibly fewer
7037c52310SDavid Blaikie   // relocations by sharing them in the pool, but we have other ideas about how
7137c52310SDavid Blaikie   // to reduce the number of relocations as well/instead).
72161dd3c1SDavid Blaikie   if ((!DD->useSplitDwarf() || !Skeleton) && DD->getDwarfVersion() < 5)
7337c52310SDavid Blaikie     return addLocalLabelAddress(Die, Attribute, Label);
7437c52310SDavid Blaikie 
7537c52310SDavid Blaikie   if (Label)
7637c52310SDavid Blaikie     DD->addArangeLabel(SymbolCU(this, Label));
7737c52310SDavid Blaikie 
7837c52310SDavid Blaikie   unsigned idx = DD->getAddressPool().getIndex(Label);
79161dd3c1SDavid Blaikie   Die.addValue(DIEValueAllocator, Attribute,
80161dd3c1SDavid Blaikie                DD->getDwarfVersion() >= 5 ? dwarf::DW_FORM_addrx
81161dd3c1SDavid Blaikie                                           : dwarf::DW_FORM_GNU_addr_index,
824fb1f9cdSDuncan P. N. Exon Smith                DIEInteger(idx));
8337c52310SDavid Blaikie }
8437c52310SDavid Blaikie 
8537c52310SDavid Blaikie void DwarfCompileUnit::addLocalLabelAddress(DIE &Die,
8637c52310SDavid Blaikie                                             dwarf::Attribute Attribute,
8737c52310SDavid Blaikie                                             const MCSymbol *Label) {
8837c52310SDavid Blaikie   if (Label)
8937c52310SDavid Blaikie     DD->addArangeLabel(SymbolCU(this, Label));
9037c52310SDavid Blaikie 
91815a6eb5SDuncan P. N. Exon Smith   if (Label)
924fb1f9cdSDuncan P. N. Exon Smith     Die.addValue(DIEValueAllocator, Attribute, dwarf::DW_FORM_addr,
934fb1f9cdSDuncan P. N. Exon Smith                  DIELabel(Label));
94815a6eb5SDuncan P. N. Exon Smith   else
954fb1f9cdSDuncan P. N. Exon Smith     Die.addValue(DIEValueAllocator, Attribute, dwarf::DW_FORM_addr,
964fb1f9cdSDuncan P. N. Exon Smith                  DIEInteger(0));
9737c52310SDavid Blaikie }
9837c52310SDavid Blaikie 
99612e89d7SPaul Robinson unsigned DwarfCompileUnit::getOrCreateSourceID(const DIFile *File) {
10037c52310SDavid Blaikie   // If we print assembly, we can't separate .file entries according to
10137c52310SDavid Blaikie   // compile units. Thus all files will belong to the default compile unit.
10237c52310SDavid Blaikie 
10337c52310SDavid Blaikie   // FIXME: add a better feature test than hasRawTextSupport. Even better,
10437c52310SDavid Blaikie   // extend .file to support this.
105612e89d7SPaul Robinson   unsigned CUID = Asm->OutStreamer->hasRawTextSupport() ? 0 : getUniqueID();
106612e89d7SPaul Robinson   if (!File)
10716c7bdafSScott Linder     return Asm->OutStreamer->EmitDwarfFileDirective(0, "", "", nullptr, None, CUID);
1089ff69c8fSLang Hames   return Asm->OutStreamer->EmitDwarfFileDirective(
10916c7bdafSScott Linder       0, File->getDirectory(), File->getFilename(), getMD5AsBytes(File),
11016c7bdafSScott Linder       File->getSource(), CUID);
11137c52310SDavid Blaikie }
11237c52310SDavid Blaikie 
11360635e39SDuncan P. N. Exon Smith DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE(
114bceaaa96SAdrian Prantl     const DIGlobalVariable *GV, ArrayRef<GlobalExpr> GlobalExprs) {
11537c52310SDavid Blaikie   // Check for pre-existence.
11637c52310SDavid Blaikie   if (DIE *Die = getDIE(GV))
11737c52310SDavid Blaikie     return Die;
11837c52310SDavid Blaikie 
119e686f159SDuncan P. N. Exon Smith   assert(GV);
12037c52310SDavid Blaikie 
121be9e4fe7SDuncan P. N. Exon Smith   auto *GVContext = GV->getScope();
122be9e4fe7SDuncan P. N. Exon Smith   auto *GTy = DD->resolve(GV->getType());
12337c52310SDavid Blaikie 
12437c52310SDavid Blaikie   // Construct the context before querying for the existence of the DIE in
12537c52310SDavid Blaikie   // case such construction creates the DIE.
12672da9391SAmjad Aboud   DIE *ContextDIE = getOrCreateContextDIE(GVContext);
12737c52310SDavid Blaikie 
12872da9391SAmjad Aboud   // Add to map.
12972da9391SAmjad Aboud   DIE *VariableDIE = &createAndAddDIE(GV->getTag(), *ContextDIE, GV);
130a9308c49SDuncan P. N. Exon Smith   DIScope *DeclContext;
131b1055640SDuncan P. N. Exon Smith   if (auto *SDMDecl = GV->getStaticDataMemberDeclaration()) {
132b1055640SDuncan P. N. Exon Smith     DeclContext = resolve(SDMDecl->getScope());
133b1055640SDuncan P. N. Exon Smith     assert(SDMDecl->isStaticMember() && "Expected static member decl");
1347348ddaaSDuncan P. N. Exon Smith     assert(GV->isDefinition());
13549cfc8caSDavid Blaikie     // We need the declaration DIE that is in the static member's class.
13649cfc8caSDavid Blaikie     DIE *VariableSpecDIE = getOrCreateStaticMemberDIE(SDMDecl);
13749cfc8caSDavid Blaikie     addDIEEntry(*VariableDIE, dwarf::DW_AT_specification, *VariableSpecDIE);
1383502f208SAdrian Prantl     // If the global variable's type is different from the one in the class
1393502f208SAdrian Prantl     // member type, assume that it's more specific and also emit it.
1403502f208SAdrian Prantl     if (GTy != DD->resolve(SDMDecl->getBaseType()))
1413502f208SAdrian Prantl       addType(*VariableDIE, GTy);
14249cfc8caSDavid Blaikie   } else {
1437348ddaaSDuncan P. N. Exon Smith     DeclContext = GV->getScope();
14437c52310SDavid Blaikie     // Add name and type.
1457348ddaaSDuncan P. N. Exon Smith     addString(*VariableDIE, dwarf::DW_AT_name, GV->getDisplayName());
14637c52310SDavid Blaikie     addType(*VariableDIE, GTy);
14737c52310SDavid Blaikie 
14837c52310SDavid Blaikie     // Add scoping info.
1497348ddaaSDuncan P. N. Exon Smith     if (!GV->isLocalToUnit())
15037c52310SDavid Blaikie       addFlag(*VariableDIE, dwarf::DW_AT_external);
15137c52310SDavid Blaikie 
15237c52310SDavid Blaikie     // Add line number info.
15337c52310SDavid Blaikie     addSourceLine(*VariableDIE, GV);
15437c52310SDavid Blaikie   }
15537c52310SDavid Blaikie 
1567348ddaaSDuncan P. N. Exon Smith   if (!GV->isDefinition())
15749cfc8caSDavid Blaikie     addFlag(*VariableDIE, dwarf::DW_AT_declaration);
158877354a2SDavid Blaikie   else
159877354a2SDavid Blaikie     addGlobalName(GV->getName(), *VariableDIE, DeclContext);
16049cfc8caSDavid Blaikie 
1613c989984SVictor Leschuk   if (uint32_t AlignInBytes = GV->getAlignInBytes())
1623c989984SVictor Leschuk     addUInt(*VariableDIE, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,
1633c989984SVictor Leschuk             AlignInBytes);
1643c989984SVictor Leschuk 
165f8ab35a4SMatthew Voss   if (MDTuple *TP = GV->getTemplateParams())
166f8ab35a4SMatthew Voss     addTemplateParams(*VariableDIE, DINodeArray(TP));
167f8ab35a4SMatthew Voss 
16837c52310SDavid Blaikie   // Add location.
16937c52310SDavid Blaikie   bool addToAccelTable = false;
170bceaaa96SAdrian Prantl   DIELoc *Loc = nullptr;
171bceaaa96SAdrian Prantl   std::unique_ptr<DIEDwarfExpression> DwarfExpr;
172bceaaa96SAdrian Prantl   for (const auto &GE : GlobalExprs) {
173bceaaa96SAdrian Prantl     const GlobalVariable *Global = GE.Var;
174bceaaa96SAdrian Prantl     const DIExpression *Expr = GE.Expr;
175b216e3e9SAdrian Prantl 
176d4135bbcSPeter Collingbourne     // For compatibility with DWARF 3 and earlier,
177d4135bbcSPeter Collingbourne     // DW_AT_location(DW_OP_constu, X, DW_OP_stack_value) becomes
178d4135bbcSPeter Collingbourne     // DW_AT_const_value(X).
179bceaaa96SAdrian Prantl     if (GlobalExprs.size() == 1 && Expr && Expr->isConstant()) {
180b216e3e9SAdrian Prantl       addToAccelTable = true;
181d4135bbcSPeter Collingbourne       addConstantValue(*VariableDIE, /*Unsigned=*/true, Expr->getElement(1));
182b216e3e9SAdrian Prantl       break;
183b216e3e9SAdrian Prantl     }
184b216e3e9SAdrian Prantl 
185bceaaa96SAdrian Prantl     // We cannot describe the location of dllimport'd variables: the
186bceaaa96SAdrian Prantl     // computation of their address requires loads from the IAT.
187b216e3e9SAdrian Prantl     if (Global && Global->hasDLLImportStorageClass())
188b216e3e9SAdrian Prantl       continue;
189b216e3e9SAdrian Prantl 
190b216e3e9SAdrian Prantl     // Nothing to describe without address or constant.
191b216e3e9SAdrian Prantl     if (!Global && (!Expr || !Expr->isConstant()))
192b216e3e9SAdrian Prantl       continue;
193b216e3e9SAdrian Prantl 
1948e422b84SLei Liu     if (Global && Global->isThreadLocal() &&
1958e422b84SLei Liu         !Asm->getObjFileLowering().supportDebugThreadLocalLocation())
1968e422b84SLei Liu       continue;
1978e422b84SLei Liu 
198bceaaa96SAdrian Prantl     if (!Loc) {
199b216e3e9SAdrian Prantl       addToAccelTable = true;
200bceaaa96SAdrian Prantl       Loc = new (DIEValueAllocator) DIELoc;
201bceaaa96SAdrian Prantl       DwarfExpr = llvm::make_unique<DIEDwarfExpression>(*Asm, *this, *Loc);
202bceaaa96SAdrian Prantl     }
203b216e3e9SAdrian Prantl 
204a9e31537SMikael Holmen     if (Expr)
205a9e31537SMikael Holmen       DwarfExpr->addFragmentOffset(Expr);
206a9e31537SMikael Holmen 
207bceaaa96SAdrian Prantl     if (Global) {
208cca5f68eSDuncan P. N. Exon Smith       const MCSymbol *Sym = Asm->getSymbol(Global);
209cca5f68eSDuncan P. N. Exon Smith       if (Global->isThreadLocal()) {
2109f9e4681SChih-Hung Hsieh         if (Asm->TM.useEmulatedTLS()) {
2111e859582SChih-Hung Hsieh           // TODO: add debug info for emulated thread local mode.
2121e859582SChih-Hung Hsieh         } else {
21337c52310SDavid Blaikie           // FIXME: Make this work with -gsplit-dwarf.
21437c52310SDavid Blaikie           unsigned PointerSize = Asm->getDataLayout().getPointerSize();
21537c52310SDavid Blaikie           assert((PointerSize == 4 || PointerSize == 8) &&
21637c52310SDavid Blaikie                  "Add support for other sizes if necessary");
21737c52310SDavid Blaikie           // Based on GCC's support for TLS:
21837c52310SDavid Blaikie           if (!DD->useSplitDwarf()) {
21937c52310SDavid Blaikie             // 1) Start with a constNu of the appropriate pointer size
220bceaaa96SAdrian Prantl             addUInt(*Loc, dwarf::DW_FORM_data1,
221bceaaa96SAdrian Prantl                     PointerSize == 4 ? dwarf::DW_OP_const4u
22254511353SDehao Chen                                      : dwarf::DW_OP_const8u);
22337c52310SDavid Blaikie             // 2) containing the (relocated) offset of the TLS variable
22437c52310SDavid Blaikie             //    within the module's TLS block.
22537c52310SDavid Blaikie             addExpr(*Loc, dwarf::DW_FORM_udata,
22637c52310SDavid Blaikie                     Asm->getObjFileLowering().getDebugThreadLocalSymbol(Sym));
22737c52310SDavid Blaikie           } else {
22837c52310SDavid Blaikie             addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_const_index);
22937c52310SDavid Blaikie             addUInt(*Loc, dwarf::DW_FORM_udata,
23037c52310SDavid Blaikie                     DD->getAddressPool().getIndex(Sym, /* TLS */ true));
23137c52310SDavid Blaikie           }
23278cc0821SPaul Robinson           // 3) followed by an OP to make the debugger do a TLS lookup.
23378cc0821SPaul Robinson           addUInt(*Loc, dwarf::DW_FORM_data1,
23478cc0821SPaul Robinson                   DD->useGNUTLSOpcode() ? dwarf::DW_OP_GNU_push_tls_address
23578cc0821SPaul Robinson                                         : dwarf::DW_OP_form_tls_address);
2361e859582SChih-Hung Hsieh         }
23737c52310SDavid Blaikie       } else {
23837c52310SDavid Blaikie         DD->addArangeLabel(SymbolCU(this, Sym));
23937c52310SDavid Blaikie         addOpAddress(*Loc, Sym);
24037c52310SDavid Blaikie       }
241bceaaa96SAdrian Prantl     }
2424b542c6eSAdrian Prantl     // Global variables attached to symbols are memory locations.
2434b542c6eSAdrian Prantl     // It would be better if this were unconditional, but malformed input that
2444b542c6eSAdrian Prantl     // mixes non-fragments and fragments for the same variable is too expensive
2454b542c6eSAdrian Prantl     // to detect in the verifier.
2463edc63a5SAdrian Prantl     if (DwarfExpr->isUnknownLocation())
2474b542c6eSAdrian Prantl       DwarfExpr->setMemoryLocationKind();
248a63b8e82SAdrian Prantl     DwarfExpr->addExpression(Expr);
249d4135bbcSPeter Collingbourne   }
250bceaaa96SAdrian Prantl   if (Loc)
251bceaaa96SAdrian Prantl     addBlock(*VariableDIE, dwarf::DW_AT_location, DwarfExpr->finalize());
252d4135bbcSPeter Collingbourne 
25343d1e453SPaul Robinson   if (DD->useAllLinkageNames())
2547348ddaaSDuncan P. N. Exon Smith     addLinkageName(*VariableDIE, GV->getLinkageName());
25537c52310SDavid Blaikie 
25637c52310SDavid Blaikie   if (addToAccelTable) {
25766cf14d0SDavid Blaikie     DD->addAccelName(*CUNode, GV->getName(), *VariableDIE);
25837c52310SDavid Blaikie 
25937c52310SDavid Blaikie     // If the linkage name is different than the name, go ahead and output
26037c52310SDavid Blaikie     // that as well into the name table.
2612a6afe5fSPavel Labath     if (GV->getLinkageName() != "" && GV->getName() != GV->getLinkageName() &&
2622a6afe5fSPavel Labath         DD->useAllLinkageNames())
26366cf14d0SDavid Blaikie       DD->addAccelName(*CUNode, GV->getLinkageName(), *VariableDIE);
26437c52310SDavid Blaikie   }
26537c52310SDavid Blaikie 
26649cfc8caSDavid Blaikie   return VariableDIE;
26737c52310SDavid Blaikie }
26837c52310SDavid Blaikie 
26937c52310SDavid Blaikie void DwarfCompileUnit::addRange(RangeSpan Range) {
27037c52310SDavid Blaikie   bool SameAsPrevCU = this == DD->getPrevCU();
27137c52310SDavid Blaikie   DD->setPrevCU(this);
27237c52310SDavid Blaikie   // If we have no current ranges just add the range and return, otherwise,
27337c52310SDavid Blaikie   // check the current section and CU against the previous section and CU we
27437c52310SDavid Blaikie   // emitted into and the subprogram was contained within. If these are the
27537c52310SDavid Blaikie   // same then extend our current range, otherwise add this as a new range.
27637c52310SDavid Blaikie   if (CURanges.empty() || !SameAsPrevCU ||
27737c52310SDavid Blaikie       (&CURanges.back().getEnd()->getSection() !=
27837c52310SDavid Blaikie        &Range.getEnd()->getSection())) {
27937c52310SDavid Blaikie     CURanges.push_back(Range);
280*60fddac9SDavid Blaikie     DD->addSectionLabel(Range.getStart());
28137c52310SDavid Blaikie     return;
28237c52310SDavid Blaikie   }
28337c52310SDavid Blaikie 
28437c52310SDavid Blaikie   CURanges.back().setEnd(Range.getEnd());
28537c52310SDavid Blaikie }
28637c52310SDavid Blaikie 
287063d725fSRafael Espindola void DwarfCompileUnit::initStmtList() {
288d4dd7215SAlexey Bataev   if (CUNode->isDebugDirectivesOnly())
289d4dd7215SAlexey Bataev     return;
290d4dd7215SAlexey Bataev 
29137c52310SDavid Blaikie   // Define start line table label for each Compile Unit.
292bff36086SAlexey Bataev   MCSymbol *LineTableStartSym;
293bff36086SAlexey Bataev   const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
294bff36086SAlexey Bataev   if (DD->useSectionsAsReferences()) {
295bff36086SAlexey Bataev     LineTableStartSym = TLOF.getDwarfLineSection()->getBeginSymbol();
296bff36086SAlexey Bataev   } else {
297bff36086SAlexey Bataev     LineTableStartSym =
2989ff69c8fSLang Hames         Asm->OutStreamer->getDwarfLineTableSymbol(getUniqueID());
299bff36086SAlexey Bataev   }
30037c52310SDavid Blaikie 
30137c52310SDavid Blaikie   // DW_AT_stmt_list is a offset of line number information for this
30237c52310SDavid Blaikie   // compile unit in debug_line section. For split dwarf this is
30337c52310SDavid Blaikie   // left in the skeleton CU and so not included.
30437c52310SDavid Blaikie   // The line table entries are not always emitted in assembly, so it
30537c52310SDavid Blaikie   // is not okay to use line_table_start here.
3064fb1f9cdSDuncan P. N. Exon Smith   StmtListValue =
30735630c33SGreg Clayton       addSectionLabel(getUnitDie(), dwarf::DW_AT_stmt_list, LineTableStartSym,
308063d725fSRafael Espindola                       TLOF.getDwarfLineSection()->getBeginSymbol());
30937c52310SDavid Blaikie }
31037c52310SDavid Blaikie 
31137c52310SDavid Blaikie void DwarfCompileUnit::applyStmtList(DIE &D) {
3124fb1f9cdSDuncan P. N. Exon Smith   D.addValue(DIEValueAllocator, *StmtListValue);
31337c52310SDavid Blaikie }
31437c52310SDavid Blaikie 
31514499a7dSDavid Blaikie void DwarfCompileUnit::attachLowHighPC(DIE &D, const MCSymbol *Begin,
31614499a7dSDavid Blaikie                                        const MCSymbol *End) {
31714499a7dSDavid Blaikie   assert(Begin && "Begin label should not be null!");
31814499a7dSDavid Blaikie   assert(End && "End label should not be null!");
31914499a7dSDavid Blaikie   assert(Begin->isDefined() && "Invalid starting label");
32014499a7dSDavid Blaikie   assert(End->isDefined() && "Invalid end label");
32114499a7dSDavid Blaikie 
32214499a7dSDavid Blaikie   addLabelAddress(D, dwarf::DW_AT_low_pc, Begin);
32314499a7dSDavid Blaikie   if (DD->getDwarfVersion() < 4)
32414499a7dSDavid Blaikie     addLabelAddress(D, dwarf::DW_AT_high_pc, End);
32514499a7dSDavid Blaikie   else
32614499a7dSDavid Blaikie     addLabelDelta(D, dwarf::DW_AT_high_pc, End, Begin);
32714499a7dSDavid Blaikie }
32814499a7dSDavid Blaikie 
329cda2aa82SDavid Blaikie // Find DIE for the given subprogram and attach appropriate DW_AT_low_pc
330cda2aa82SDavid Blaikie // and DW_AT_high_pc attributes. If there are global variables in this
331cda2aa82SDavid Blaikie // scope then create and insert DIEs for these variables.
332a9308c49SDuncan P. N. Exon Smith DIE &DwarfCompileUnit::updateSubprogramScopeDIE(const DISubprogram *SP) {
3333a443c29SDavid Blaikie   DIE *SPDie = getOrCreateSubprogramDIE(SP, includeMinimalInlineScopes());
334cda2aa82SDavid Blaikie 
33507c03d31SRafael Espindola   attachLowHighPC(*SPDie, Asm->getFunctionBegin(), Asm->getFunctionEnd());
336c53e18d9SDavid Blaikie   if (DD->useAppleExtensionAttributes() &&
337c53e18d9SDavid Blaikie       !DD->getCurrentFunction()->getTarget().Options.DisableFramePointerElim(
338cda2aa82SDavid Blaikie           *DD->getCurrentFunction()))
339cda2aa82SDavid Blaikie     addFlag(*SPDie, dwarf::DW_AT_APPLE_omit_frame_ptr);
340cda2aa82SDavid Blaikie 
341cda2aa82SDavid Blaikie   // Only include DW_AT_frame_base in full debug info
3423a443c29SDavid Blaikie   if (!includeMinimalInlineScopes()) {
3437ae86fe7SAlexey Bataev     if (Asm->MF->getTarget().getTargetTriple().isNVPTX()) {
3447ae86fe7SAlexey Bataev       DIELoc *Loc = new (DIEValueAllocator) DIELoc;
3457ae86fe7SAlexey Bataev       addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_call_frame_cfa);
3467ae86fe7SAlexey Bataev       addBlock(*SPDie, dwarf::DW_AT_frame_base, Loc);
3477ae86fe7SAlexey Bataev     } else {
348d4e723f2SEric Christopher       const TargetRegisterInfo *RI = Asm->MF->getSubtarget().getRegisterInfo();
349cda2aa82SDavid Blaikie       MachineLocation Location(RI->getFrameRegister(*Asm->MF));
3508efadbf8SAdrian Prantl       if (RI->isPhysicalRegister(Location.getReg()))
351cda2aa82SDavid Blaikie         addAddress(*SPDie, dwarf::DW_AT_frame_base, Location);
352cda2aa82SDavid Blaikie     }
3537ae86fe7SAlexey Bataev   }
354cda2aa82SDavid Blaikie 
355cda2aa82SDavid Blaikie   // Add name to the name table, we do this here because we're guaranteed
356cda2aa82SDavid Blaikie   // to have concrete versions of our DW_TAG_subprogram nodes.
35766cf14d0SDavid Blaikie   DD->addSubprogramNames(*CUNode, SP, *SPDie);
358cda2aa82SDavid Blaikie 
359cda2aa82SDavid Blaikie   return *SPDie;
360cda2aa82SDavid Blaikie }
361cda2aa82SDavid Blaikie 
3629c65b135SDavid Blaikie // Construct a DIE for this scope.
3639c65b135SDavid Blaikie void DwarfCompileUnit::constructScopeDIE(
364827200c8SDuncan P. N. Exon Smith     LexicalScope *Scope, SmallVectorImpl<DIE *> &FinalChildren) {
3659c65b135SDavid Blaikie   if (!Scope || !Scope->getScopeNode())
3669c65b135SDavid Blaikie     return;
3679c65b135SDavid Blaikie 
368be9e4fe7SDuncan P. N. Exon Smith   auto *DS = Scope->getScopeNode();
3699c65b135SDavid Blaikie 
370a9308c49SDuncan P. N. Exon Smith   assert((Scope->getInlinedAt() || !isa<DISubprogram>(DS)) &&
3719c65b135SDavid Blaikie          "Only handle inlined subprograms here, use "
3729c65b135SDavid Blaikie          "constructSubprogramScopeDIE for non-inlined "
3739c65b135SDavid Blaikie          "subprograms");
3749c65b135SDavid Blaikie 
375827200c8SDuncan P. N. Exon Smith   SmallVector<DIE *, 8> Children;
3769c65b135SDavid Blaikie 
3779c65b135SDavid Blaikie   // We try to create the scope DIE first, then the children DIEs. This will
3789c65b135SDavid Blaikie   // avoid creating un-used children then removing them later when we find out
3799c65b135SDavid Blaikie   // the scope DIE is null.
380827200c8SDuncan P. N. Exon Smith   DIE *ScopeDIE;
381a9308c49SDuncan P. N. Exon Smith   if (Scope->getParent() && isa<DISubprogram>(DS)) {
38201b48a84SDavid Blaikie     ScopeDIE = constructInlinedScopeDIE(Scope);
3839c65b135SDavid Blaikie     if (!ScopeDIE)
3849c65b135SDavid Blaikie       return;
3859c65b135SDavid Blaikie     // We create children when the scope DIE is not null.
3868b2fdb83SDavid Blaikie     createScopeChildrenDIE(Scope, Children);
3879c65b135SDavid Blaikie   } else {
3889c65b135SDavid Blaikie     // Early exit when we know the scope DIE is going to be null.
3899c65b135SDavid Blaikie     if (DD->isLexicalScopeDIENull(Scope))
3909c65b135SDavid Blaikie       return;
3919c65b135SDavid Blaikie 
3922195e136SDavid Blaikie     bool HasNonScopeChildren = false;
3939c65b135SDavid Blaikie 
3949c65b135SDavid Blaikie     // We create children here when we know the scope DIE is not going to be
3959c65b135SDavid Blaikie     // null and the children will be added to the scope DIE.
3962195e136SDavid Blaikie     createScopeChildrenDIE(Scope, Children, &HasNonScopeChildren);
3973a443c29SDavid Blaikie 
3989c65b135SDavid Blaikie     // If there are only other scopes as children, put them directly in the
3999c65b135SDavid Blaikie     // parent instead, as this scope would serve no purpose.
4002195e136SDavid Blaikie     if (!HasNonScopeChildren) {
4019c65b135SDavid Blaikie       FinalChildren.insert(FinalChildren.end(),
4029c65b135SDavid Blaikie                            std::make_move_iterator(Children.begin()),
4039c65b135SDavid Blaikie                            std::make_move_iterator(Children.end()));
4049c65b135SDavid Blaikie       return;
4059c65b135SDavid Blaikie     }
4060fbf8bdbSDavid Blaikie     ScopeDIE = constructLexicalScopeDIE(Scope);
4079c65b135SDavid Blaikie     assert(ScopeDIE && "Scope DIE should not be null.");
4089c65b135SDavid Blaikie   }
4099c65b135SDavid Blaikie 
4109c65b135SDavid Blaikie   // Add children
4119c65b135SDavid Blaikie   for (auto &I : Children)
4129c65b135SDavid Blaikie     ScopeDIE->addChild(std::move(I));
4139c65b135SDavid Blaikie 
4149c65b135SDavid Blaikie   FinalChildren.push_back(std::move(ScopeDIE));
4159c65b135SDavid Blaikie }
4169c65b135SDavid Blaikie 
4175b02a19fSDavid Blaikie void DwarfCompileUnit::addScopeRangeList(DIE &ScopeDIE,
4185b02a19fSDavid Blaikie                                          SmallVector<RangeSpan, 2> Range) {
419063d725fSRafael Espindola   const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
420063d725fSRafael Espindola 
421fcf3810cSWolfgang Pieb   // Emit the offset into .debug_ranges or .debug_rnglists as a relocatable
422fcf3810cSWolfgang Pieb   // label. emitDIE() will handle emitting it appropriately.
423063d725fSRafael Espindola   const MCSymbol *RangeSectionSym =
424fcf3810cSWolfgang Pieb       DD->getDwarfVersion() >= 5
425fcf3810cSWolfgang Pieb           ? TLOF.getDwarfRnglistsSection()->getBeginSymbol()
426fcf3810cSWolfgang Pieb           : TLOF.getDwarfRangesSection()->getBeginSymbol();
42752400200SDavid Blaikie 
428c4af8bf2SDavid Blaikie   HasRangeLists = true;
429c4af8bf2SDavid Blaikie 
430c4af8bf2SDavid Blaikie   // Add the range list to the set of ranges to be emitted.
431c4af8bf2SDavid Blaikie   auto IndexAndList =
432c4af8bf2SDavid Blaikie       (DD->getDwarfVersion() < 5 && Skeleton ? Skeleton->DU : DU)
433c4af8bf2SDavid Blaikie           ->addRange((Skeleton ? Skeleton->BaseAddress : BaseAddress),
434c4af8bf2SDavid Blaikie                      std::move(Range));
435c4af8bf2SDavid Blaikie 
436c4af8bf2SDavid Blaikie   uint32_t Index = IndexAndList.first;
437c4af8bf2SDavid Blaikie   auto &List = *IndexAndList.second;
4385b02a19fSDavid Blaikie 
43952400200SDavid Blaikie   // Under fission, ranges are specified by constant offsets relative to the
44052400200SDavid Blaikie   // CU's DW_AT_GNU_ranges_base.
441fcf3810cSWolfgang Pieb   // FIXME: For DWARF v5, do not generate the DW_AT_ranges attribute under
442fcf3810cSWolfgang Pieb   // fission until we support the forms using the .debug_addr section
443fcf3810cSWolfgang Pieb   // (DW_RLE_startx_endx etc.).
44432e09de9SDavid Blaikie   if (DD->getDwarfVersion() >= 5)
44532e09de9SDavid Blaikie     addUInt(ScopeDIE, dwarf::DW_AT_ranges, dwarf::DW_FORM_rnglistx, Index);
44632e09de9SDavid Blaikie   else if (isDwoUnit())
4475b02a19fSDavid Blaikie     addSectionDelta(ScopeDIE, dwarf::DW_AT_ranges, List.getSym(),
4485b02a19fSDavid Blaikie                     RangeSectionSym);
449c4af8bf2SDavid Blaikie   else
4505b02a19fSDavid Blaikie     addSectionLabel(ScopeDIE, dwarf::DW_AT_ranges, List.getSym(),
4515b02a19fSDavid Blaikie                     RangeSectionSym);
452fcf3810cSWolfgang Pieb }
45352400200SDavid Blaikie 
454de12375cSDavid Blaikie void DwarfCompileUnit::attachRangesOrLowHighPC(
4555b02a19fSDavid Blaikie     DIE &Die, SmallVector<RangeSpan, 2> Ranges) {
456858a7dd6SAlexey Bataev   if (Ranges.size() == 1 || !DD->useRangesSection()) {
457858a7dd6SAlexey Bataev     const RangeSpan &Front = Ranges.front();
458858a7dd6SAlexey Bataev     const RangeSpan &Back = Ranges.back();
459858a7dd6SAlexey Bataev     attachLowHighPC(Die, Front.getStart(), Back.getEnd());
4605b02a19fSDavid Blaikie   } else
4615b02a19fSDavid Blaikie     addScopeRangeList(Die, std::move(Ranges));
4625b02a19fSDavid Blaikie }
4635b02a19fSDavid Blaikie 
4645b02a19fSDavid Blaikie void DwarfCompileUnit::attachRangesOrLowHighPC(
465de12375cSDavid Blaikie     DIE &Die, const SmallVectorImpl<InsnRange> &Ranges) {
4665b02a19fSDavid Blaikie   SmallVector<RangeSpan, 2> List;
4675b02a19fSDavid Blaikie   List.reserve(Ranges.size());
4685b02a19fSDavid Blaikie   for (const InsnRange &R : Ranges)
4695b02a19fSDavid Blaikie     List.push_back(RangeSpan(DD->getLabelBeforeInsn(R.first),
4705b02a19fSDavid Blaikie                              DD->getLabelAfterInsn(R.second)));
4715b02a19fSDavid Blaikie   attachRangesOrLowHighPC(Die, std::move(List));
472de12375cSDavid Blaikie }
473de12375cSDavid Blaikie 
47401b48a84SDavid Blaikie // This scope represents inlined body of a function. Construct DIE to
47501b48a84SDavid Blaikie // represent this concrete inlined copy of the function.
476827200c8SDuncan P. N. Exon Smith DIE *DwarfCompileUnit::constructInlinedScopeDIE(LexicalScope *Scope) {
47701b48a84SDavid Blaikie   assert(Scope->getScopeNode());
478be9e4fe7SDuncan P. N. Exon Smith   auto *DS = Scope->getScopeNode();
479be9e4fe7SDuncan P. N. Exon Smith   auto *InlinedSP = getDISubprogram(DS);
48001b48a84SDavid Blaikie   // Find the subprogram's DwarfCompileUnit in the SPMap in case the subprogram
48101b48a84SDavid Blaikie   // was inlined from another compile unit.
482488393f8SDavid Blaikie   DIE *OriginDIE = getAbstractSPDies()[InlinedSP];
48301b48a84SDavid Blaikie   assert(OriginDIE && "Unable to find original DIE for an inlined subprogram.");
48401b48a84SDavid Blaikie 
485827200c8SDuncan P. N. Exon Smith   auto ScopeDIE = DIE::get(DIEValueAllocator, dwarf::DW_TAG_inlined_subroutine);
48601b48a84SDavid Blaikie   addDIEEntry(*ScopeDIE, dwarf::DW_AT_abstract_origin, *OriginDIE);
48701b48a84SDavid Blaikie 
48801b48a84SDavid Blaikie   attachRangesOrLowHighPC(*ScopeDIE, Scope->getRanges());
48901b48a84SDavid Blaikie 
49001b48a84SDavid Blaikie   // Add the call site information to the DIE.
491a9308c49SDuncan P. N. Exon Smith   const DILocation *IA = Scope->getInlinedAt();
49201b48a84SDavid Blaikie   addUInt(*ScopeDIE, dwarf::DW_AT_call_file, None,
493612e89d7SPaul Robinson           getOrCreateSourceID(IA->getFile()));
494b7e221baSDuncan P. N. Exon Smith   addUInt(*ScopeDIE, dwarf::DW_AT_call_line, None, IA->getLine());
4956e0c8446SDehao Chen   if (IA->getDiscriminator() && DD->getDwarfVersion() >= 4)
49654511353SDehao Chen     addUInt(*ScopeDIE, dwarf::DW_AT_GNU_discriminator, None,
49754511353SDehao Chen             IA->getDiscriminator());
49801b48a84SDavid Blaikie 
49901b48a84SDavid Blaikie   // Add name to the name table, we do this here because we're guaranteed
50001b48a84SDavid Blaikie   // to have concrete versions of our DW_TAG_inlined_subprogram nodes.
50166cf14d0SDavid Blaikie   DD->addSubprogramNames(*CUNode, InlinedSP, *ScopeDIE);
50201b48a84SDavid Blaikie 
50301b48a84SDavid Blaikie   return ScopeDIE;
50401b48a84SDavid Blaikie }
50501b48a84SDavid Blaikie 
5060fbf8bdbSDavid Blaikie // Construct new DW_TAG_lexical_block for this scope and attach
5070fbf8bdbSDavid Blaikie // DW_AT_low_pc/DW_AT_high_pc labels.
508827200c8SDuncan P. N. Exon Smith DIE *DwarfCompileUnit::constructLexicalScopeDIE(LexicalScope *Scope) {
5090fbf8bdbSDavid Blaikie   if (DD->isLexicalScopeDIENull(Scope))
5100fbf8bdbSDavid Blaikie     return nullptr;
5110fbf8bdbSDavid Blaikie 
512827200c8SDuncan P. N. Exon Smith   auto ScopeDIE = DIE::get(DIEValueAllocator, dwarf::DW_TAG_lexical_block);
5130fbf8bdbSDavid Blaikie   if (Scope->isAbstractScope())
5140fbf8bdbSDavid Blaikie     return ScopeDIE;
5150fbf8bdbSDavid Blaikie 
5160fbf8bdbSDavid Blaikie   attachRangesOrLowHighPC(*ScopeDIE, Scope->getRanges());
5170fbf8bdbSDavid Blaikie 
5180fbf8bdbSDavid Blaikie   return ScopeDIE;
5190fbf8bdbSDavid Blaikie }
5200fbf8bdbSDavid Blaikie 
521ee7df553SDavid Blaikie /// constructVariableDIE - Construct a DIE for the given DbgVariable.
522827200c8SDuncan P. N. Exon Smith DIE *DwarfCompileUnit::constructVariableDIE(DbgVariable &DV, bool Abstract) {
523ee7df553SDavid Blaikie   auto D = constructVariableDIEImpl(DV, Abstract);
524ee7df553SDavid Blaikie   DV.setDIE(*D);
525ee7df553SDavid Blaikie   return D;
526ee7df553SDavid Blaikie }
527ee7df553SDavid Blaikie 
5282532ac88SHsiangkai Wang DIE *DwarfCompileUnit::constructLabelDIE(DbgLabel &DL,
5292532ac88SHsiangkai Wang                                          const LexicalScope &Scope) {
5302532ac88SHsiangkai Wang   auto LabelDie = DIE::get(DIEValueAllocator, DL.getTag());
5312532ac88SHsiangkai Wang   insertDIE(DL.getLabel(), LabelDie);
5322532ac88SHsiangkai Wang   DL.setDIE(*LabelDie);
5332532ac88SHsiangkai Wang 
5342532ac88SHsiangkai Wang   if (Scope.isAbstractScope())
5352532ac88SHsiangkai Wang     applyLabelAttributes(DL, *LabelDie);
5362532ac88SHsiangkai Wang 
5372532ac88SHsiangkai Wang   return LabelDie;
5382532ac88SHsiangkai Wang }
5392532ac88SHsiangkai Wang 
540827200c8SDuncan P. N. Exon Smith DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV,
541ee7df553SDavid Blaikie                                                 bool Abstract) {
542ee7df553SDavid Blaikie   // Define variable debug information entry.
543827200c8SDuncan P. N. Exon Smith   auto VariableDie = DIE::get(DIEValueAllocator, DV.getTag());
544dc00becdSSander de Smalen   insertDIE(DV.getVariable(), VariableDie);
545ee7df553SDavid Blaikie 
546ee7df553SDavid Blaikie   if (Abstract) {
547ee7df553SDavid Blaikie     applyVariableAttributes(DV, *VariableDie);
548ee7df553SDavid Blaikie     return VariableDie;
549ee7df553SDavid Blaikie   }
550ee7df553SDavid Blaikie 
551ee7df553SDavid Blaikie   // Add variable address.
552ee7df553SDavid Blaikie 
553364a3005SDuncan P. N. Exon Smith   unsigned Offset = DV.getDebugLocListIndex();
554ee7df553SDavid Blaikie   if (Offset != ~0U) {
555ee7df553SDavid Blaikie     addLocationList(*VariableDie, dwarf::DW_AT_location, Offset);
556ee7df553SDavid Blaikie     return VariableDie;
557ee7df553SDavid Blaikie   }
558ee7df553SDavid Blaikie 
559ee7df553SDavid Blaikie   // Check if variable is described by a DBG_VALUE instruction.
560ee7df553SDavid Blaikie   if (const MachineInstr *DVInsn = DV.getMInsn()) {
561ee7df553SDavid Blaikie     assert(DVInsn->getNumOperands() == 4);
562ee7df553SDavid Blaikie     if (DVInsn->getOperand(0).isReg()) {
563bd6d291cSAdrian Prantl       auto RegOp = DVInsn->getOperand(0);
564bd6d291cSAdrian Prantl       auto Op1 = DVInsn->getOperand(1);
565ee7df553SDavid Blaikie       // If the second operand is an immediate, this is an indirect value.
566bd6d291cSAdrian Prantl       assert((!Op1.isImm() || (Op1.getImm() == 0)) && "unexpected offset");
567bd6d291cSAdrian Prantl       MachineLocation Location(RegOp.getReg(), Op1.isImm());
568ee7df553SDavid Blaikie       addVariableAddress(DV, *VariableDie, Location);
5693b89e663SAdrian Prantl     } else if (DVInsn->getOperand(0).isImm()) {
5703b89e663SAdrian Prantl       // This variable is described by a single constant.
5713b89e663SAdrian Prantl       // Check whether it has a DIExpression.
5723b89e663SAdrian Prantl       auto *Expr = DV.getSingleExpression();
5733b89e663SAdrian Prantl       if (Expr && Expr->getNumElements()) {
5743b89e663SAdrian Prantl         DIELoc *Loc = new (DIEValueAllocator) DIELoc;
5753b89e663SAdrian Prantl         DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
5763b89e663SAdrian Prantl         // If there is an expression, emit raw unsigned bytes.
5778fafb8d3SAdrian Prantl         DwarfExpr.addFragmentOffset(Expr);
578a63b8e82SAdrian Prantl         DwarfExpr.addUnsignedConstant(DVInsn->getOperand(0).getImm());
579a63b8e82SAdrian Prantl         DwarfExpr.addExpression(Expr);
580bceaaa96SAdrian Prantl         addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
5813b89e663SAdrian Prantl       } else
582ee7df553SDavid Blaikie         addConstantValue(*VariableDie, DVInsn->getOperand(0), DV.getType());
5833b89e663SAdrian Prantl     } else if (DVInsn->getOperand(0).isFPImm())
584ee7df553SDavid Blaikie       addConstantFPValue(*VariableDie, DVInsn->getOperand(0));
585ee7df553SDavid Blaikie     else if (DVInsn->getOperand(0).isCImm())
586ee7df553SDavid Blaikie       addConstantValue(*VariableDie, DVInsn->getOperand(0).getCImm(),
587ee7df553SDavid Blaikie                        DV.getType());
588ee7df553SDavid Blaikie 
589ee7df553SDavid Blaikie     return VariableDie;
590ee7df553SDavid Blaikie   }
591ee7df553SDavid Blaikie 
592ee7df553SDavid Blaikie   // .. else use frame index.
59367c24422SAdrian Prantl   if (!DV.hasFrameIndexExprs())
594ca7e4702SAdrian Prantl     return VariableDie;
595ca7e4702SAdrian Prantl 
596e7e1d0c7SDuncan P. N. Exon Smith   DIELoc *Loc = new (DIEValueAllocator) DIELoc;
597ca7e4702SAdrian Prantl   DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
59867c24422SAdrian Prantl   for (auto &Fragment : DV.getFrameIndexExprs()) {
599ee7df553SDavid Blaikie     unsigned FrameReg = 0;
6006825fb64SAdrian Prantl     const DIExpression *Expr = Fragment.Expr;
601d4e723f2SEric Christopher     const TargetFrameLowering *TFI = Asm->MF->getSubtarget().getFrameLowering();
60267c24422SAdrian Prantl     int Offset = TFI->getFrameIndexReference(*Asm->MF, Fragment.FI, FrameReg);
6036825fb64SAdrian Prantl     DwarfExpr.addFragmentOffset(Expr);
604956484b7SAdrian Prantl     SmallVector<uint64_t, 8> Ops;
605ffc498dfSFlorian Hahn     Ops.push_back(dwarf::DW_OP_plus_uconst);
606956484b7SAdrian Prantl     Ops.push_back(Offset);
6076825fb64SAdrian Prantl     Ops.append(Expr->elements_begin(), Expr->elements_end());
6086825fb64SAdrian Prantl     DIExpressionCursor Cursor(Ops);
609c12cee36SAdrian Prantl     DwarfExpr.setMemoryLocationKind();
6104dd7558fSAlexey Bataev     if (const MCSymbol *FrameSymbol = Asm->getFunctionFrameSymbol())
6114dd7558fSAlexey Bataev       addOpAddress(*Loc, FrameSymbol);
6124dd7558fSAlexey Bataev     else
613c12cee36SAdrian Prantl       DwarfExpr.addMachineRegExpression(
614c12cee36SAdrian Prantl           *Asm->MF->getSubtarget().getRegisterInfo(), Cursor, FrameReg);
6156825fb64SAdrian Prantl     DwarfExpr.addExpression(std::move(Cursor));
616ee7df553SDavid Blaikie   }
617bceaaa96SAdrian Prantl   addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
618ee7df553SDavid Blaikie 
619ee7df553SDavid Blaikie   return VariableDie;
620ee7df553SDavid Blaikie }
621ee7df553SDavid Blaikie 
622827200c8SDuncan P. N. Exon Smith DIE *DwarfCompileUnit::constructVariableDIE(DbgVariable &DV,
623827200c8SDuncan P. N. Exon Smith                                             const LexicalScope &Scope,
624827200c8SDuncan P. N. Exon Smith                                             DIE *&ObjectPointer) {
6254a1a44e3SDavid Blaikie   auto Var = constructVariableDIE(DV, Scope.isAbstractScope());
6264a1a44e3SDavid Blaikie   if (DV.isObjectPointer())
627827200c8SDuncan P. N. Exon Smith     ObjectPointer = Var;
6284a1a44e3SDavid Blaikie   return Var;
6294a1a44e3SDavid Blaikie }
6304a1a44e3SDavid Blaikie 
63103dd6f57SAdrian Prantl /// Return all DIVariables that appear in count: expressions.
63203dd6f57SAdrian Prantl static SmallVector<const DIVariable *, 2> dependencies(DbgVariable *Var) {
63303dd6f57SAdrian Prantl   SmallVector<const DIVariable *, 2> Result;
63403dd6f57SAdrian Prantl   auto *Array = dyn_cast<DICompositeType>(Var->getType());
635c929f7adSAdrian Prantl   if (!Array || Array->getTag() != dwarf::DW_TAG_array_type)
63603dd6f57SAdrian Prantl     return Result;
63703dd6f57SAdrian Prantl   for (auto *El : Array->getElements()) {
638c929f7adSAdrian Prantl     if (auto *Subrange = dyn_cast<DISubrange>(El)) {
639c929f7adSAdrian Prantl       auto Count = Subrange->getCount();
64003dd6f57SAdrian Prantl       if (auto *Dependency = Count.dyn_cast<DIVariable *>())
64103dd6f57SAdrian Prantl         Result.push_back(Dependency);
642c929f7adSAdrian Prantl     }
64303dd6f57SAdrian Prantl   }
64403dd6f57SAdrian Prantl   return Result;
645c929f7adSAdrian Prantl }
646c929f7adSAdrian Prantl 
647c929f7adSAdrian Prantl /// Sort local variables so that variables appearing inside of helper
648c929f7adSAdrian Prantl /// expressions come first.
64903dd6f57SAdrian Prantl static SmallVector<DbgVariable *, 8>
65003dd6f57SAdrian Prantl sortLocalVars(SmallVectorImpl<DbgVariable *> &Input) {
65103dd6f57SAdrian Prantl   SmallVector<DbgVariable *, 8> Result;
65203dd6f57SAdrian Prantl   SmallVector<PointerIntPair<DbgVariable *, 1>, 8> WorkList;
65303dd6f57SAdrian Prantl   // Map back from a DIVariable to its containing DbgVariable.
65403dd6f57SAdrian Prantl   SmallDenseMap<const DILocalVariable *, DbgVariable *> DbgVar;
65503dd6f57SAdrian Prantl   // Set of DbgVariables in Result.
65603dd6f57SAdrian Prantl   SmallDenseSet<DbgVariable *, 8> Visited;
65703dd6f57SAdrian Prantl   // For cycle detection.
65803dd6f57SAdrian Prantl   SmallDenseSet<DbgVariable *, 8> Visiting;
65903dd6f57SAdrian Prantl 
66003dd6f57SAdrian Prantl   // Initialize the worklist and the DIVariable lookup table.
66103dd6f57SAdrian Prantl   for (auto Var : reverse(Input)) {
66203dd6f57SAdrian Prantl     DbgVar.insert({Var->getVariable(), Var});
66303dd6f57SAdrian Prantl     WorkList.push_back({Var, 0});
66403dd6f57SAdrian Prantl   }
66503dd6f57SAdrian Prantl 
66603dd6f57SAdrian Prantl   // Perform a stable topological sort by doing a DFS.
66703dd6f57SAdrian Prantl   while (!WorkList.empty()) {
66803dd6f57SAdrian Prantl     auto Item = WorkList.back();
66903dd6f57SAdrian Prantl     DbgVariable *Var = Item.getPointer();
67003dd6f57SAdrian Prantl     bool visitedAllDependencies = Item.getInt();
67103dd6f57SAdrian Prantl     WorkList.pop_back();
67203dd6f57SAdrian Prantl 
67303dd6f57SAdrian Prantl     // Dependency is in a different lexical scope or a global.
67403dd6f57SAdrian Prantl     if (!Var)
67503dd6f57SAdrian Prantl       continue;
67603dd6f57SAdrian Prantl 
67703dd6f57SAdrian Prantl     // Already handled.
67803dd6f57SAdrian Prantl     if (Visited.count(Var))
67903dd6f57SAdrian Prantl       continue;
68003dd6f57SAdrian Prantl 
68103dd6f57SAdrian Prantl     // Add to Result if all dependencies are visited.
68203dd6f57SAdrian Prantl     if (visitedAllDependencies) {
68303dd6f57SAdrian Prantl       Visited.insert(Var);
68403dd6f57SAdrian Prantl       Result.push_back(Var);
68503dd6f57SAdrian Prantl       continue;
68603dd6f57SAdrian Prantl     }
68703dd6f57SAdrian Prantl 
68803dd6f57SAdrian Prantl     // Detect cycles.
68903dd6f57SAdrian Prantl     auto Res = Visiting.insert(Var);
69003dd6f57SAdrian Prantl     if (!Res.second) {
69103dd6f57SAdrian Prantl       assert(false && "dependency cycle in local variables");
69203dd6f57SAdrian Prantl       return Result;
69303dd6f57SAdrian Prantl     }
69403dd6f57SAdrian Prantl 
69503dd6f57SAdrian Prantl     // Push dependencies and this node onto the worklist, so that this node is
69603dd6f57SAdrian Prantl     // visited again after all of its dependencies are handled.
69703dd6f57SAdrian Prantl     WorkList.push_back({Var, 1});
69803dd6f57SAdrian Prantl     for (auto *Dependency : dependencies(Var)) {
69903dd6f57SAdrian Prantl       auto Dep = dyn_cast_or_null<const DILocalVariable>(Dependency);
70003dd6f57SAdrian Prantl       WorkList.push_back({DbgVar[Dep], 0});
70103dd6f57SAdrian Prantl     }
70203dd6f57SAdrian Prantl   }
70303dd6f57SAdrian Prantl   return Result;
704c929f7adSAdrian Prantl }
705c929f7adSAdrian Prantl 
706827200c8SDuncan P. N. Exon Smith DIE *DwarfCompileUnit::createScopeChildrenDIE(LexicalScope *Scope,
707827200c8SDuncan P. N. Exon Smith                                               SmallVectorImpl<DIE *> &Children,
7082195e136SDavid Blaikie                                               bool *HasNonScopeChildren) {
7092195e136SDavid Blaikie   assert(Children.empty());
7108b2fdb83SDavid Blaikie   DIE *ObjectPointer = nullptr;
7118b2fdb83SDavid Blaikie 
712c929f7adSAdrian Prantl   // Emit function arguments (order is significant).
713c929f7adSAdrian Prantl   auto Vars = DU->getScopeVariables().lookup(Scope);
714c929f7adSAdrian Prantl   for (auto &DV : Vars.Args)
715c929f7adSAdrian Prantl     Children.push_back(constructVariableDIE(*DV.second, *Scope, ObjectPointer));
716c929f7adSAdrian Prantl 
717c929f7adSAdrian Prantl   // Emit local variables.
71803dd6f57SAdrian Prantl   auto Locals = sortLocalVars(Vars.Locals);
71903dd6f57SAdrian Prantl   for (DbgVariable *DV : Locals)
7208b2fdb83SDavid Blaikie     Children.push_back(constructVariableDIE(*DV, *Scope, ObjectPointer));
7218b2fdb83SDavid Blaikie 
7222195e136SDavid Blaikie   // Skip imported directives in gmlt-like data.
7232195e136SDavid Blaikie   if (!includeMinimalInlineScopes()) {
7242195e136SDavid Blaikie     // There is no need to emit empty lexical block DIE.
7252195e136SDavid Blaikie     for (const auto *IE : ImportedEntities[Scope->getScopeNode()])
7262195e136SDavid Blaikie       Children.push_back(
7272195e136SDavid Blaikie           constructImportedEntityDIE(cast<DIImportedEntity>(IE)));
7282195e136SDavid Blaikie   }
7292195e136SDavid Blaikie 
7302195e136SDavid Blaikie   if (HasNonScopeChildren)
7312195e136SDavid Blaikie     *HasNonScopeChildren = !Children.empty();
7328b2fdb83SDavid Blaikie 
7332532ac88SHsiangkai Wang   for (DbgLabel *DL : DU->getScopeLabels().lookup(Scope))
7342532ac88SHsiangkai Wang     Children.push_back(constructLabelDIE(*DL, *Scope));
7352532ac88SHsiangkai Wang 
7368b2fdb83SDavid Blaikie   for (LexicalScope *LS : Scope->getChildren())
7378b2fdb83SDavid Blaikie     constructScopeDIE(LS, Children);
7388b2fdb83SDavid Blaikie 
7398b2fdb83SDavid Blaikie   return ObjectPointer;
7408b2fdb83SDavid Blaikie }
7418b2fdb83SDavid Blaikie 
7425931b4e5SVedant Kumar DIE &DwarfCompileUnit::constructSubprogramScopeDIE(const DISubprogram *Sub,
7435931b4e5SVedant Kumar                                                    LexicalScope *Scope) {
7441d072348SDavid Blaikie   DIE &ScopeDIE = updateSubprogramScopeDIE(Sub);
7451d072348SDavid Blaikie 
7463e3eb33eSDavid Blaikie   if (Scope) {
7473e3eb33eSDavid Blaikie     assert(!Scope->getInlinedAt());
7483e3eb33eSDavid Blaikie     assert(!Scope->isAbstractScope());
7491dd573dbSDavid Blaikie     // Collect lexical scope children first.
7501dd573dbSDavid Blaikie     // ObjectPointer might be a local (non-argument) local variable if it's a
7511dd573dbSDavid Blaikie     // block's synthetic this pointer.
7521dd573dbSDavid Blaikie     if (DIE *ObjectPointer = createAndAddScopeChildren(Scope, ScopeDIE))
7531dd573dbSDavid Blaikie       addDIEEntry(ScopeDIE, dwarf::DW_AT_object_pointer, *ObjectPointer);
7543e3eb33eSDavid Blaikie   }
7553e3eb33eSDavid Blaikie 
7563e3eb33eSDavid Blaikie   // If this is a variadic function, add an unspecified parameter.
7573e3eb33eSDavid Blaikie   DITypeRefArray FnArgs = Sub->getType()->getTypeArray();
7581dd573dbSDavid Blaikie 
7591d072348SDavid Blaikie   // If we have a single element of null, it is a function that returns void.
7601d072348SDavid Blaikie   // If we have more than one elements and the last one is null, it is a
7611d072348SDavid Blaikie   // variadic function.
762000fa2c6SDuncan P. N. Exon Smith   if (FnArgs.size() > 1 && !FnArgs[FnArgs.size() - 1] &&
7633a443c29SDavid Blaikie       !includeMinimalInlineScopes())
764827200c8SDuncan P. N. Exon Smith     ScopeDIE.addChild(
765827200c8SDuncan P. N. Exon Smith         DIE::get(DIEValueAllocator, dwarf::DW_TAG_unspecified_parameters));
7665931b4e5SVedant Kumar 
7675931b4e5SVedant Kumar   return ScopeDIE;
7681d072348SDavid Blaikie }
7691d072348SDavid Blaikie 
77078b65b6fSDavid Blaikie DIE *DwarfCompileUnit::createAndAddScopeChildren(LexicalScope *Scope,
77178b65b6fSDavid Blaikie                                                  DIE &ScopeDIE) {
77278b65b6fSDavid Blaikie   // We create children when the scope DIE is not null.
773827200c8SDuncan P. N. Exon Smith   SmallVector<DIE *, 8> Children;
77478b65b6fSDavid Blaikie   DIE *ObjectPointer = createScopeChildrenDIE(Scope, Children);
77578b65b6fSDavid Blaikie 
77678b65b6fSDavid Blaikie   // Add children
77778b65b6fSDavid Blaikie   for (auto &I : Children)
77878b65b6fSDavid Blaikie     ScopeDIE.addChild(std::move(I));
77978b65b6fSDavid Blaikie 
78078b65b6fSDavid Blaikie   return ObjectPointer;
78178b65b6fSDavid Blaikie }
78278b65b6fSDavid Blaikie 
78354511353SDehao Chen void DwarfCompileUnit::constructAbstractSubprogramScopeDIE(
78454511353SDehao Chen     LexicalScope *Scope) {
785488393f8SDavid Blaikie   DIE *&AbsDef = getAbstractSPDies()[Scope->getScopeNode()];
78649be5b35SDavid Blaikie   if (AbsDef)
78749be5b35SDavid Blaikie     return;
78849be5b35SDavid Blaikie 
789a9308c49SDuncan P. N. Exon Smith   auto *SP = cast<DISubprogram>(Scope->getScopeNode());
79058410f24SDavid Blaikie 
79158410f24SDavid Blaikie   DIE *ContextDIE;
792294e6895SJonas Devlieghere   DwarfCompileUnit *ContextCU = this;
79358410f24SDavid Blaikie 
7943a443c29SDavid Blaikie   if (includeMinimalInlineScopes())
7953a443c29SDavid Blaikie     ContextDIE = &getUnitDie();
79658410f24SDavid Blaikie   // Some of this is duplicated from DwarfUnit::getOrCreateSubprogramDIE, with
7977c60f20eSDuncan P. N. Exon Smith   // the important distinction that the debug node is not associated with the
7987c60f20eSDuncan P. N. Exon Smith   // DIE (since the debug node will be associated with the concrete DIE, if
79958410f24SDavid Blaikie   // any). It could be refactored to some common utility function.
800537b4a81SDuncan P. N. Exon Smith   else if (auto *SPDecl = SP->getDeclaration()) {
80158410f24SDavid Blaikie     ContextDIE = &getUnitDie();
80258410f24SDavid Blaikie     getOrCreateSubprogramDIE(SPDecl);
803294e6895SJonas Devlieghere   } else {
804537b4a81SDuncan P. N. Exon Smith     ContextDIE = getOrCreateContextDIE(resolve(SP->getScope()));
805294e6895SJonas Devlieghere     // The scope may be shared with a subprogram that has already been
806294e6895SJonas Devlieghere     // constructed in another CU, in which case we need to construct this
807294e6895SJonas Devlieghere     // subprogram in the same CU.
808294e6895SJonas Devlieghere     ContextCU = DD->lookupCU(ContextDIE->getUnitDie());
809294e6895SJonas Devlieghere   }
81058410f24SDavid Blaikie 
8117c60f20eSDuncan P. N. Exon Smith   // Passing null as the associated node because the abstract definition
81258410f24SDavid Blaikie   // shouldn't be found by lookup.
813294e6895SJonas Devlieghere   AbsDef = &ContextCU->createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE, nullptr);
814294e6895SJonas Devlieghere   ContextCU->applySubprogramAttributesToDefinition(SP, *AbsDef);
81558410f24SDavid Blaikie 
816294e6895SJonas Devlieghere   if (!ContextCU->includeMinimalInlineScopes())
817294e6895SJonas Devlieghere     ContextCU->addUInt(*AbsDef, dwarf::DW_AT_inline, None, dwarf::DW_INL_inlined);
818294e6895SJonas Devlieghere   if (DIE *ObjectPointer = ContextCU->createAndAddScopeChildren(Scope, *AbsDef))
819294e6895SJonas Devlieghere     ContextCU->addDIEEntry(*AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer);
82058410f24SDavid Blaikie }
82158410f24SDavid Blaikie 
8225931b4e5SVedant Kumar DIE &DwarfCompileUnit::constructCallSiteEntryDIE(DIE &ScopeDIE,
8235931b4e5SVedant Kumar                                                  const DISubprogram &CalleeSP,
8245931b4e5SVedant Kumar                                                  bool IsTail,
82574533bd3SVedant Kumar                                                  const MCExpr *PCOffset) {
8265931b4e5SVedant Kumar   // Insert a call site entry DIE within ScopeDIE.
8275931b4e5SVedant Kumar   DIE &CallSiteDIE =
8285931b4e5SVedant Kumar       createAndAddDIE(dwarf::DW_TAG_call_site, ScopeDIE, nullptr);
8295931b4e5SVedant Kumar 
8305931b4e5SVedant Kumar   // For the purposes of showing tail call frames in backtraces, a key piece of
8315931b4e5SVedant Kumar   // information is DW_AT_call_origin, a pointer to the callee DIE.
8325931b4e5SVedant Kumar   DIE *CalleeDIE = getOrCreateSubprogramDIE(&CalleeSP);
8335931b4e5SVedant Kumar   assert(CalleeDIE && "Could not create DIE for call site entry origin");
8345931b4e5SVedant Kumar   addDIEEntry(CallSiteDIE, dwarf::DW_AT_call_origin, *CalleeDIE);
8355931b4e5SVedant Kumar 
8365931b4e5SVedant Kumar   if (IsTail) {
8375931b4e5SVedant Kumar     // Attach DW_AT_call_tail_call to tail calls for standards compliance.
8385931b4e5SVedant Kumar     addFlag(CallSiteDIE, dwarf::DW_AT_call_tail_call);
8395931b4e5SVedant Kumar   } else {
8405931b4e5SVedant Kumar     // Attach the return PC to allow the debugger to disambiguate call paths
8415931b4e5SVedant Kumar     // from one function to another.
84274533bd3SVedant Kumar     assert(PCOffset && "Missing return PC information for a call");
84374533bd3SVedant Kumar     addAddressExpr(CallSiteDIE, dwarf::DW_AT_call_return_pc, PCOffset);
8445931b4e5SVedant Kumar   }
8455931b4e5SVedant Kumar   return CallSiteDIE;
8465931b4e5SVedant Kumar }
8475931b4e5SVedant Kumar 
848827200c8SDuncan P. N. Exon Smith DIE *DwarfCompileUnit::constructImportedEntityDIE(
849827200c8SDuncan P. N. Exon Smith     const DIImportedEntity *Module) {
85072da9391SAmjad Aboud   DIE *IMDie = DIE::get(DIEValueAllocator, (dwarf::Tag)Module->getTag());
85172da9391SAmjad Aboud   insertDIE(Module, IMDie);
852987fe227SFrederic Riss   DIE *EntityDie;
853de8e4273SDuncan P. N. Exon Smith   auto *Entity = resolve(Module->getEntity());
854a9308c49SDuncan P. N. Exon Smith   if (auto *NS = dyn_cast<DINamespace>(Entity))
855e686f159SDuncan P. N. Exon Smith     EntityDie = getOrCreateNameSpace(NS);
85608a388baSAdrian Prantl   else if (auto *M = dyn_cast<DIModule>(Entity))
85708a388baSAdrian Prantl     EntityDie = getOrCreateModule(M);
858a9308c49SDuncan P. N. Exon Smith   else if (auto *SP = dyn_cast<DISubprogram>(Entity))
859e686f159SDuncan P. N. Exon Smith     EntityDie = getOrCreateSubprogramDIE(SP);
860a9308c49SDuncan P. N. Exon Smith   else if (auto *T = dyn_cast<DIType>(Entity))
861e686f159SDuncan P. N. Exon Smith     EntityDie = getOrCreateTypeDIE(T);
862a9308c49SDuncan P. N. Exon Smith   else if (auto *GV = dyn_cast<DIGlobalVariable>(Entity))
863bceaaa96SAdrian Prantl     EntityDie = getOrCreateGlobalVariableDIE(GV, {});
864987fe227SFrederic Riss   else
865987fe227SFrederic Riss     EntityDie = getDIE(Entity);
866987fe227SFrederic Riss   assert(EntityDie);
867612e89d7SPaul Robinson   addSourceLine(*IMDie, Module->getLine(), Module->getFile());
868987fe227SFrederic Riss   addDIEEntry(*IMDie, dwarf::DW_AT_import, *EntityDie);
869de8e4273SDuncan P. N. Exon Smith   StringRef Name = Module->getName();
870987fe227SFrederic Riss   if (!Name.empty())
871987fe227SFrederic Riss     addString(*IMDie, dwarf::DW_AT_name, Name);
872987fe227SFrederic Riss 
873987fe227SFrederic Riss   return IMDie;
874987fe227SFrederic Riss }
875987fe227SFrederic Riss 
876a9308c49SDuncan P. N. Exon Smith void DwarfCompileUnit::finishSubprogramDefinition(const DISubprogram *SP) {
87772da9391SAmjad Aboud   DIE *D = getDIE(SP);
878488393f8SDavid Blaikie   if (DIE *AbsSPDIE = getAbstractSPDies().lookup(SP)) {
87972da9391SAmjad Aboud     if (D)
8804191cbceSDavid Blaikie       // If this subprogram has an abstract definition, reference that
8814191cbceSDavid Blaikie       addDIEEntry(*D, dwarf::DW_AT_abstract_origin, *AbsSPDIE);
88272da9391SAmjad Aboud   } else {
8833e3eb33eSDavid Blaikie     assert(D || includeMinimalInlineScopes());
88472da9391SAmjad Aboud     if (D)
8854191cbceSDavid Blaikie       // And attach the attributes
8864191cbceSDavid Blaikie       applySubprogramAttributesToDefinition(SP, *D);
8874191cbceSDavid Blaikie   }
8884191cbceSDavid Blaikie }
8894191cbceSDavid Blaikie 
8902532ac88SHsiangkai Wang void DwarfCompileUnit::finishEntityDefinition(const DbgEntity *Entity) {
8912532ac88SHsiangkai Wang   DbgEntity *AbsEntity = getExistingAbstractEntity(Entity->getEntity());
8922532ac88SHsiangkai Wang 
8932532ac88SHsiangkai Wang   auto *Die = Entity->getDIE();
8942532ac88SHsiangkai Wang   /// Label may be used to generate DW_AT_low_pc, so put it outside
8952532ac88SHsiangkai Wang   /// if/else block.
8962532ac88SHsiangkai Wang   const DbgLabel *Label = nullptr;
8972532ac88SHsiangkai Wang   if (AbsEntity && AbsEntity->getDIE()) {
8982532ac88SHsiangkai Wang     addDIEEntry(*Die, dwarf::DW_AT_abstract_origin, *AbsEntity->getDIE());
8992532ac88SHsiangkai Wang     Label = dyn_cast<const DbgLabel>(Entity);
9002532ac88SHsiangkai Wang   } else {
9012532ac88SHsiangkai Wang     if (const DbgVariable *Var = dyn_cast<const DbgVariable>(Entity))
9022532ac88SHsiangkai Wang       applyVariableAttributes(*Var, *Die);
9032532ac88SHsiangkai Wang     else if ((Label = dyn_cast<const DbgLabel>(Entity)))
9042532ac88SHsiangkai Wang       applyLabelAttributes(*Label, *Die);
9052532ac88SHsiangkai Wang     else
9062532ac88SHsiangkai Wang       llvm_unreachable("DbgEntity must be DbgVariable or DbgLabel.");
907488393f8SDavid Blaikie   }
908488393f8SDavid Blaikie 
90955321d82SHsiangkai Wang   if (Label)
91055321d82SHsiangkai Wang     if (const auto *Sym = Label->getSymbol())
9112532ac88SHsiangkai Wang       addLabelAddress(*Die, dwarf::DW_AT_low_pc, Sym);
9122532ac88SHsiangkai Wang }
913488393f8SDavid Blaikie 
9142532ac88SHsiangkai Wang DbgEntity *DwarfCompileUnit::getExistingAbstractEntity(const DINode *Node) {
9152532ac88SHsiangkai Wang   auto &AbstractEntities = getAbstractEntities();
9162532ac88SHsiangkai Wang   auto I = AbstractEntities.find(Node);
9172532ac88SHsiangkai Wang   if (I != AbstractEntities.end())
918488393f8SDavid Blaikie     return I->second.get();
919488393f8SDavid Blaikie   return nullptr;
920488393f8SDavid Blaikie }
921488393f8SDavid Blaikie 
9222532ac88SHsiangkai Wang void DwarfCompileUnit::createAbstractEntity(const DINode *Node,
923488393f8SDavid Blaikie                                             LexicalScope *Scope) {
924488393f8SDavid Blaikie   assert(Scope && Scope->isAbstractScope());
9252532ac88SHsiangkai Wang   auto &Entity = getAbstractEntities()[Node];
9262532ac88SHsiangkai Wang   if (isa<const DILocalVariable>(Node)) {
9272532ac88SHsiangkai Wang     Entity = llvm::make_unique<DbgVariable>(
9282532ac88SHsiangkai Wang                         cast<const DILocalVariable>(Node), nullptr /* IA */);;
9292532ac88SHsiangkai Wang     DU->addScopeVariable(Scope, cast<DbgVariable>(Entity.get()));
9302532ac88SHsiangkai Wang   } else if (isa<const DILabel>(Node)) {
9312532ac88SHsiangkai Wang     Entity = llvm::make_unique<DbgLabel>(
9322532ac88SHsiangkai Wang                         cast<const DILabel>(Node), nullptr /* IA */);
9332532ac88SHsiangkai Wang     DU->addScopeLabel(Scope, cast<DbgLabel>(Entity.get()));
9342532ac88SHsiangkai Wang   }
935488393f8SDavid Blaikie }
936488393f8SDavid Blaikie 
937063d725fSRafael Espindola void DwarfCompileUnit::emitHeader(bool UseOffsets) {
938b6726a9eSDavid Blaikie   // Don't bother labeling the .dwo unit, as its offset isn't used.
939bff36086SAlexey Bataev   if (!Skeleton && !DD->useSectionsAsReferences()) {
9409ab09237SRafael Espindola     LabelBegin = Asm->createTempSymbol("cu_begin");
9419ff69c8fSLang Hames     Asm->OutStreamer->EmitLabel(LabelBegin);
9423c311148SRafael Espindola   }
943ae57e66eSDavid Blaikie 
944cddd6044SPaul Robinson   dwarf::UnitType UT = Skeleton ? dwarf::DW_UT_split_compile
945cddd6044SPaul Robinson                                 : DD->useSplitDwarf() ? dwarf::DW_UT_skeleton
946cddd6044SPaul Robinson                                                       : dwarf::DW_UT_compile;
947cddd6044SPaul Robinson   DwarfUnit::emitCommonHeader(UseOffsets, UT);
948543c0e1dSPaul Robinson   if (DD->getDwarfVersion() >= 5 && UT != dwarf::DW_UT_compile)
949543c0e1dSPaul Robinson     Asm->emitInt64(getDWOId());
950ae57e66eSDavid Blaikie }
951ae57e66eSDavid Blaikie 
952b52e2366SPeter Collingbourne bool DwarfCompileUnit::hasDwarfPubSections() const {
95366cf14d0SDavid Blaikie   switch (CUNode->getNameTableKind()) {
95466cf14d0SDavid Blaikie   case DICompileUnit::DebugNameTableKind::None:
95566cf14d0SDavid Blaikie     return false;
956b52e2366SPeter Collingbourne     // Opting in to GNU Pubnames/types overrides the default to ensure these are
957b52e2366SPeter Collingbourne     // generated for things like Gold's gdb_index generation.
95866cf14d0SDavid Blaikie   case DICompileUnit::DebugNameTableKind::GNU:
959b52e2366SPeter Collingbourne     return true;
96066cf14d0SDavid Blaikie   case DICompileUnit::DebugNameTableKind::Default:
9610e03047eSDavid Blaikie     return DD->tuneForGDB() && !includeMinimalInlineScopes() &&
9620e03047eSDavid Blaikie            !CUNode->isDebugDirectivesOnly();
963b52e2366SPeter Collingbourne   }
96422d580f2SSimon Pilgrim   llvm_unreachable("Unhandled DICompileUnit::DebugNameTableKind enum");
96566cf14d0SDavid Blaikie }
966b52e2366SPeter Collingbourne 
967192b45c1SDavid Blaikie /// addGlobalName - Add a new global name to the compile unit.
968a0e3c751SDavid Blaikie void DwarfCompileUnit::addGlobalName(StringRef Name, const DIE &Die,
969a9308c49SDuncan P. N. Exon Smith                                      const DIScope *Context) {
970b52e2366SPeter Collingbourne   if (!hasDwarfPubSections())
971192b45c1SDavid Blaikie     return;
972192b45c1SDavid Blaikie   std::string FullName = getParentContextString(Context) + Name.str();
973192b45c1SDavid Blaikie   GlobalNames[FullName] = &Die;
974192b45c1SDavid Blaikie }
975192b45c1SDavid Blaikie 
976a0e3c751SDavid Blaikie void DwarfCompileUnit::addGlobalNameForTypeUnit(StringRef Name,
977a0e3c751SDavid Blaikie                                                 const DIScope *Context) {
978b52e2366SPeter Collingbourne   if (!hasDwarfPubSections())
979a0e3c751SDavid Blaikie     return;
980a0e3c751SDavid Blaikie   std::string FullName = getParentContextString(Context) + Name.str();
981a0e3c751SDavid Blaikie   // Insert, allowing the entry to remain as-is if it's already present
982a0e3c751SDavid Blaikie   // This way the CU-level type DIE is preferred over the "can't describe this
983a0e3c751SDavid Blaikie   // type as a unit offset because it's not really in the CU at all, it's only
984a0e3c751SDavid Blaikie   // in a type unit"
985a0e3c751SDavid Blaikie   GlobalNames.insert(std::make_pair(std::move(FullName), &getUnitDie()));
986a0e3c751SDavid Blaikie }
987a0e3c751SDavid Blaikie 
988192b45c1SDavid Blaikie /// Add a new global type to the unit.
989a9308c49SDuncan P. N. Exon Smith void DwarfCompileUnit::addGlobalType(const DIType *Ty, const DIE &Die,
990a9308c49SDuncan P. N. Exon Smith                                      const DIScope *Context) {
991b52e2366SPeter Collingbourne   if (!hasDwarfPubSections())
992192b45c1SDavid Blaikie     return;
993b1055640SDuncan P. N. Exon Smith   std::string FullName = getParentContextString(Context) + Ty->getName().str();
994192b45c1SDavid Blaikie   GlobalTypes[FullName] = &Die;
995192b45c1SDavid Blaikie }
996ae57e66eSDavid Blaikie 
997a0e3c751SDavid Blaikie void DwarfCompileUnit::addGlobalTypeUnitType(const DIType *Ty,
998a0e3c751SDavid Blaikie                                              const DIScope *Context) {
999b52e2366SPeter Collingbourne   if (!hasDwarfPubSections())
1000a0e3c751SDavid Blaikie     return;
1001a0e3c751SDavid Blaikie   std::string FullName = getParentContextString(Context) + Ty->getName().str();
1002a0e3c751SDavid Blaikie   // Insert, allowing the entry to remain as-is if it's already present
1003a0e3c751SDavid Blaikie   // This way the CU-level type DIE is preferred over the "can't describe this
1004a0e3c751SDavid Blaikie   // type as a unit offset because it's not really in the CU at all, it's only
1005a0e3c751SDavid Blaikie   // in a type unit"
1006a0e3c751SDavid Blaikie   GlobalTypes.insert(std::make_pair(std::move(FullName), &getUnitDie()));
1007a0e3c751SDavid Blaikie }
1008a0e3c751SDavid Blaikie 
10097d48be2bSDavid Blaikie /// addVariableAddress - Add DW_AT_location attribute for a
10107d48be2bSDavid Blaikie /// DbgVariable based on provided MachineLocation.
10117d48be2bSDavid Blaikie void DwarfCompileUnit::addVariableAddress(const DbgVariable &DV, DIE &Die,
10127d48be2bSDavid Blaikie                                           MachineLocation Location) {
1013a2f9e3a6SAdrian Prantl   // addBlockByrefAddress is obsolete and will be removed soon.
1014a2f9e3a6SAdrian Prantl   // The clang frontend always generates block byref variables with a
1015a2f9e3a6SAdrian Prantl   // complex expression that encodes exactly what addBlockByrefAddress
1016a2f9e3a6SAdrian Prantl   // would do.
1017a2f9e3a6SAdrian Prantl   assert((!DV.isBlockByrefVariable() || DV.hasComplexAddress()) &&
1018a2f9e3a6SAdrian Prantl          "block byref variable without a complex expression");
1019e6cc531bSDuncan P. N. Exon Smith   if (DV.hasComplexAddress())
10207d48be2bSDavid Blaikie     addComplexAddress(DV, Die, dwarf::DW_AT_location, Location);
10217d48be2bSDavid Blaikie   else
10225883af3fSAdrian Prantl     addAddress(Die, dwarf::DW_AT_location, Location);
10237d48be2bSDavid Blaikie }
1024f7435ee6SDavid Blaikie 
1025f7435ee6SDavid Blaikie /// Add an address attribute to a die based on the location provided.
1026f7435ee6SDavid Blaikie void DwarfCompileUnit::addAddress(DIE &Die, dwarf::Attribute Attribute,
10275883af3fSAdrian Prantl                                   const MachineLocation &Location) {
1028e7e1d0c7SDuncan P. N. Exon Smith   DIELoc *Loc = new (DIEValueAllocator) DIELoc;
1029956484b7SAdrian Prantl   DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
1030c12cee36SAdrian Prantl   if (Location.isIndirect())
1031c12cee36SAdrian Prantl     DwarfExpr.setMemoryLocationKind();
1032f7435ee6SDavid Blaikie 
10332049c0d7SAdrian Prantl   DIExpressionCursor Cursor({});
1034956484b7SAdrian Prantl   const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();
1035c12cee36SAdrian Prantl   if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
1036ab255fcdSAdrian Prantl     return;
1037956484b7SAdrian Prantl   DwarfExpr.addExpression(std::move(Cursor));
1038ab255fcdSAdrian Prantl 
1039f7435ee6SDavid Blaikie   // Now attach the location information to the DIE.
1040956484b7SAdrian Prantl   addBlock(Die, Attribute, DwarfExpr.finalize());
1041f7435ee6SDavid Blaikie }
104277895fb2SDavid Blaikie 
104377895fb2SDavid Blaikie /// Start with the address based on the location provided, and generate the
104477895fb2SDavid Blaikie /// DWARF information necessary to find the actual variable given the extra
104577895fb2SDavid Blaikie /// address information encoded in the DbgVariable, starting from the starting
104677895fb2SDavid Blaikie /// location.  Add the DWARF information to the die.
104777895fb2SDavid Blaikie void DwarfCompileUnit::addComplexAddress(const DbgVariable &DV, DIE &Die,
104877895fb2SDavid Blaikie                                          dwarf::Attribute Attribute,
104977895fb2SDavid Blaikie                                          const MachineLocation &Location) {
1050e7e1d0c7SDuncan P. N. Exon Smith   DIELoc *Loc = new (DIEValueAllocator) DIELoc;
10517813d9c9SAdrian Prantl   DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
1052956484b7SAdrian Prantl   const DIExpression *DIExpr = DV.getSingleExpression();
1053956484b7SAdrian Prantl   DwarfExpr.addFragmentOffset(DIExpr);
1054c12cee36SAdrian Prantl   if (Location.isIndirect())
1055c12cee36SAdrian Prantl     DwarfExpr.setMemoryLocationKind();
1056956484b7SAdrian Prantl 
10572049c0d7SAdrian Prantl   DIExpressionCursor Cursor(DIExpr);
105896c9ae6aSPeter Collingbourne   const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();
1059c12cee36SAdrian Prantl   if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
106054286bdaSAdrian Prantl     return;
1061956484b7SAdrian Prantl   DwarfExpr.addExpression(std::move(Cursor));
106277895fb2SDavid Blaikie 
106377895fb2SDavid Blaikie   // Now attach the location information to the DIE.
1064956484b7SAdrian Prantl   addBlock(Die, Attribute, DwarfExpr.finalize());
106577895fb2SDavid Blaikie }
10664bc0881aSDavid Blaikie 
10674bc0881aSDavid Blaikie /// Add a Dwarf loclistptr attribute data and value.
10684bc0881aSDavid Blaikie void DwarfCompileUnit::addLocationList(DIE &Die, dwarf::Attribute Attribute,
10694bc0881aSDavid Blaikie                                        unsigned Index) {
10704bc0881aSDavid Blaikie   dwarf::Form Form = DD->getDwarfVersion() >= 4 ? dwarf::DW_FORM_sec_offset
10714bc0881aSDavid Blaikie                                                 : dwarf::DW_FORM_data4;
10724fb1f9cdSDuncan P. N. Exon Smith   Die.addValue(DIEValueAllocator, Attribute, Form, DIELocList(Index));
10734bc0881aSDavid Blaikie }
107402a6333bSDavid Blaikie 
10758c485b5dSDavid Blaikie void DwarfCompileUnit::applyVariableAttributes(const DbgVariable &Var,
107602a6333bSDavid Blaikie                                                DIE &VariableDie) {
107702a6333bSDavid Blaikie   StringRef Name = Var.getName();
107802a6333bSDavid Blaikie   if (!Name.empty())
107902a6333bSDavid Blaikie     addString(VariableDie, dwarf::DW_AT_name, Name);
10803c989984SVictor Leschuk   const auto *DIVar = Var.getVariable();
10813c989984SVictor Leschuk   if (DIVar)
10823c989984SVictor Leschuk     if (uint32_t AlignInBytes = DIVar->getAlignInBytes())
10833c989984SVictor Leschuk       addUInt(VariableDie, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,
10843c989984SVictor Leschuk               AlignInBytes);
10853c989984SVictor Leschuk 
10863c989984SVictor Leschuk   addSourceLine(VariableDie, DIVar);
108702a6333bSDavid Blaikie   addType(VariableDie, Var.getType());
108802a6333bSDavid Blaikie   if (Var.isArtificial())
108902a6333bSDavid Blaikie     addFlag(VariableDie, dwarf::DW_AT_artificial);
109002a6333bSDavid Blaikie }
109197802080SDavid Blaikie 
10922532ac88SHsiangkai Wang void DwarfCompileUnit::applyLabelAttributes(const DbgLabel &Label,
10932532ac88SHsiangkai Wang                                             DIE &LabelDie) {
10942532ac88SHsiangkai Wang   StringRef Name = Label.getName();
10952532ac88SHsiangkai Wang   if (!Name.empty())
10962532ac88SHsiangkai Wang     addString(LabelDie, dwarf::DW_AT_name, Name);
10972532ac88SHsiangkai Wang   const auto *DILabel = Label.getLabel();
10982532ac88SHsiangkai Wang   addSourceLine(LabelDie, DILabel);
10992532ac88SHsiangkai Wang }
11002532ac88SHsiangkai Wang 
110197802080SDavid Blaikie /// Add a Dwarf expression attribute data and value.
110297802080SDavid Blaikie void DwarfCompileUnit::addExpr(DIELoc &Die, dwarf::Form Form,
110397802080SDavid Blaikie                                const MCExpr *Expr) {
11044fb1f9cdSDuncan P. N. Exon Smith   Die.addValue(DIEValueAllocator, (dwarf::Attribute)0, Form, DIEExpr(Expr));
110597802080SDavid Blaikie }
11063363a57cSDavid Blaikie 
110774533bd3SVedant Kumar void DwarfCompileUnit::addAddressExpr(DIE &Die, dwarf::Attribute Attribute,
110874533bd3SVedant Kumar                                       const MCExpr *Expr) {
110974533bd3SVedant Kumar   Die.addValue(DIEValueAllocator, Attribute, dwarf::DW_FORM_addr,
111074533bd3SVedant Kumar                DIEExpr(Expr));
111174533bd3SVedant Kumar }
111274533bd3SVedant Kumar 
11132fbe1354SDuncan P. N. Exon Smith void DwarfCompileUnit::applySubprogramAttributesToDefinition(
1114a9308c49SDuncan P. N. Exon Smith     const DISubprogram *SP, DIE &SPDie) {
1115537b4a81SDuncan P. N. Exon Smith   auto *SPDecl = SP->getDeclaration();
1116be9e4fe7SDuncan P. N. Exon Smith   auto *Context = resolve(SPDecl ? SPDecl->getScope() : SP->getScope());
11173a443c29SDavid Blaikie   applySubprogramAttributes(SP, SPDie, includeMinimalInlineScopes());
1118537b4a81SDuncan P. N. Exon Smith   addGlobalName(SP->getName(), SPDie, Context);
11193363a57cSDavid Blaikie }
1120cafd962dSDavid Blaikie 
1121cafd962dSDavid Blaikie bool DwarfCompileUnit::isDwoUnit() const {
1122cafd962dSDavid Blaikie   return DD->useSplitDwarf() && Skeleton;
1123cafd962dSDavid Blaikie }
11243a443c29SDavid Blaikie 
11253a443c29SDavid Blaikie bool DwarfCompileUnit::includeMinimalInlineScopes() const {
1126b939a257SAdrian Prantl   return getCUNode()->getEmissionKind() == DICompileUnit::LineTablesOnly ||
11273a443c29SDavid Blaikie          (DD->useSplitDwarf() && !Skeleton);
11283a443c29SDavid Blaikie }
1129