12cab237bSDimitry Andric //===- llvm/CodeGen/DwarfCompileUnit.cpp - Dwarf Compile Units ------------===//
27a7e6055SDimitry Andric //
37a7e6055SDimitry Andric // The LLVM Compiler Infrastructure
47a7e6055SDimitry Andric //
57a7e6055SDimitry Andric // This file is distributed under the University of Illinois Open Source
67a7e6055SDimitry Andric // License. See LICENSE.TXT for details.
77a7e6055SDimitry Andric //
87a7e6055SDimitry Andric //===----------------------------------------------------------------------===//
97a7e6055SDimitry Andric //
107a7e6055SDimitry Andric // This file contains support for constructing a dwarf compile unit.
117a7e6055SDimitry Andric //
127a7e6055SDimitry Andric //===----------------------------------------------------------------------===//
137a7e6055SDimitry Andric
1439d628a0SDimitry Andric #include "DwarfCompileUnit.h"
152cab237bSDimitry Andric #include "AddressPool.h"
162cab237bSDimitry Andric #include "DwarfDebug.h"
1739d628a0SDimitry Andric #include "DwarfExpression.h"
182cab237bSDimitry Andric #include "DwarfUnit.h"
192cab237bSDimitry Andric #include "llvm/ADT/None.h"
202cab237bSDimitry Andric #include "llvm/ADT/STLExtras.h"
212cab237bSDimitry Andric #include "llvm/ADT/SmallVector.h"
222cab237bSDimitry Andric #include "llvm/ADT/StringRef.h"
232cab237bSDimitry Andric #include "llvm/BinaryFormat/Dwarf.h"
242cab237bSDimitry Andric #include "llvm/CodeGen/AsmPrinter.h"
252cab237bSDimitry Andric #include "llvm/CodeGen/DIE.h"
262cab237bSDimitry Andric #include "llvm/CodeGen/LexicalScopes.h"
2739d628a0SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
282cab237bSDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
292cab237bSDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
302cab237bSDimitry Andric #include "llvm/CodeGen/TargetFrameLowering.h"
312cab237bSDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
322cab237bSDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
3339d628a0SDimitry Andric #include "llvm/IR/DataLayout.h"
342cab237bSDimitry Andric #include "llvm/IR/DebugInfo.h"
352cab237bSDimitry Andric #include "llvm/IR/DebugInfoMetadata.h"
3639d628a0SDimitry Andric #include "llvm/IR/GlobalVariable.h"
372cab237bSDimitry Andric #include "llvm/MC/MCSection.h"
3839d628a0SDimitry Andric #include "llvm/MC/MCStreamer.h"
392cab237bSDimitry Andric #include "llvm/MC/MCSymbol.h"
402cab237bSDimitry Andric #include "llvm/MC/MachineLocation.h"
412cab237bSDimitry Andric #include "llvm/Support/Casting.h"
424ba319b5SDimitry Andric #include "llvm/Target/TargetLoweringObjectFile.h"
4339d628a0SDimitry Andric #include "llvm/Target/TargetMachine.h"
442cab237bSDimitry Andric #include "llvm/Target/TargetOptions.h"
452cab237bSDimitry Andric #include <algorithm>
462cab237bSDimitry Andric #include <cassert>
472cab237bSDimitry Andric #include <cstdint>
482cab237bSDimitry Andric #include <iterator>
492cab237bSDimitry Andric #include <memory>
502cab237bSDimitry Andric #include <string>
512cab237bSDimitry Andric #include <utility>
5239d628a0SDimitry Andric
532cab237bSDimitry Andric using namespace llvm;
5439d628a0SDimitry Andric
DwarfCompileUnit(unsigned UID,const DICompileUnit * Node,AsmPrinter * A,DwarfDebug * DW,DwarfFile * DWU)55ff0cc061SDimitry Andric DwarfCompileUnit::DwarfCompileUnit(unsigned UID, const DICompileUnit *Node,
5639d628a0SDimitry Andric AsmPrinter *A, DwarfDebug *DW,
5739d628a0SDimitry Andric DwarfFile *DWU)
582cab237bSDimitry Andric : DwarfUnit(dwarf::DW_TAG_compile_unit, Node, A, DW, DWU), UniqueID(UID) {
5939d628a0SDimitry Andric insertDIE(Node, &getUnitDie());
603ca95b02SDimitry Andric MacroLabelBegin = Asm->createTempSymbol("cu_macro_begin");
6139d628a0SDimitry Andric }
6239d628a0SDimitry Andric
6339d628a0SDimitry Andric /// addLabelAddress - Add a dwarf label attribute data and value using
6439d628a0SDimitry Andric /// DW_FORM_addr or DW_FORM_GNU_addr_index.
addLabelAddress(DIE & Die,dwarf::Attribute Attribute,const MCSymbol * Label)6539d628a0SDimitry Andric void DwarfCompileUnit::addLabelAddress(DIE &Die, dwarf::Attribute Attribute,
6639d628a0SDimitry Andric const MCSymbol *Label) {
6739d628a0SDimitry Andric // Don't use the address pool in non-fission or in the skeleton unit itself.
6839d628a0SDimitry Andric // FIXME: Once GDB supports this, it's probably worthwhile using the address
6939d628a0SDimitry Andric // pool from the skeleton - maybe even in non-fission (possibly fewer
7039d628a0SDimitry Andric // relocations by sharing them in the pool, but we have other ideas about how
7139d628a0SDimitry Andric // to reduce the number of relocations as well/instead).
72*b5893f02SDimitry Andric if ((!DD->useSplitDwarf() || !Skeleton) && DD->getDwarfVersion() < 5)
7339d628a0SDimitry Andric return addLocalLabelAddress(Die, Attribute, Label);
7439d628a0SDimitry Andric
7539d628a0SDimitry Andric if (Label)
7639d628a0SDimitry Andric DD->addArangeLabel(SymbolCU(this, Label));
7739d628a0SDimitry Andric
7839d628a0SDimitry Andric unsigned idx = DD->getAddressPool().getIndex(Label);
79*b5893f02SDimitry Andric Die.addValue(DIEValueAllocator, Attribute,
80*b5893f02SDimitry Andric DD->getDwarfVersion() >= 5 ? dwarf::DW_FORM_addrx
81*b5893f02SDimitry Andric : dwarf::DW_FORM_GNU_addr_index,
823dac3a9bSDimitry Andric DIEInteger(idx));
8339d628a0SDimitry Andric }
8439d628a0SDimitry Andric
addLocalLabelAddress(DIE & Die,dwarf::Attribute Attribute,const MCSymbol * Label)8539d628a0SDimitry Andric void DwarfCompileUnit::addLocalLabelAddress(DIE &Die,
8639d628a0SDimitry Andric dwarf::Attribute Attribute,
8739d628a0SDimitry Andric const MCSymbol *Label) {
8839d628a0SDimitry Andric if (Label)
8939d628a0SDimitry Andric DD->addArangeLabel(SymbolCU(this, Label));
9039d628a0SDimitry Andric
9197bc6c73SDimitry Andric if (Label)
923dac3a9bSDimitry Andric Die.addValue(DIEValueAllocator, Attribute, dwarf::DW_FORM_addr,
933dac3a9bSDimitry Andric DIELabel(Label));
9497bc6c73SDimitry Andric else
953dac3a9bSDimitry Andric Die.addValue(DIEValueAllocator, Attribute, dwarf::DW_FORM_addr,
963dac3a9bSDimitry Andric DIEInteger(0));
9739d628a0SDimitry Andric }
9839d628a0SDimitry Andric
getOrCreateSourceID(const DIFile * File)994ba319b5SDimitry Andric unsigned DwarfCompileUnit::getOrCreateSourceID(const DIFile *File) {
10039d628a0SDimitry Andric // If we print assembly, we can't separate .file entries according to
10139d628a0SDimitry Andric // compile units. Thus all files will belong to the default compile unit.
10239d628a0SDimitry Andric
10339d628a0SDimitry Andric // FIXME: add a better feature test than hasRawTextSupport. Even better,
10439d628a0SDimitry Andric // extend .file to support this.
1054ba319b5SDimitry Andric unsigned CUID = Asm->OutStreamer->hasRawTextSupport() ? 0 : getUniqueID();
1064ba319b5SDimitry Andric if (!File)
1074ba319b5SDimitry Andric return Asm->OutStreamer->EmitDwarfFileDirective(0, "", "", nullptr, None, CUID);
108ff0cc061SDimitry Andric return Asm->OutStreamer->EmitDwarfFileDirective(
1094ba319b5SDimitry Andric 0, File->getDirectory(), File->getFilename(), getMD5AsBytes(File),
1104ba319b5SDimitry Andric File->getSource(), CUID);
11139d628a0SDimitry Andric }
11239d628a0SDimitry Andric
getOrCreateGlobalVariableDIE(const DIGlobalVariable * GV,ArrayRef<GlobalExpr> GlobalExprs)113ff0cc061SDimitry Andric DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE(
114d88c1a5aSDimitry Andric const DIGlobalVariable *GV, ArrayRef<GlobalExpr> GlobalExprs) {
11539d628a0SDimitry Andric // Check for pre-existence.
11639d628a0SDimitry Andric if (DIE *Die = getDIE(GV))
11739d628a0SDimitry Andric return Die;
11839d628a0SDimitry Andric
119ff0cc061SDimitry Andric assert(GV);
12039d628a0SDimitry Andric
121ff0cc061SDimitry Andric auto *GVContext = GV->getScope();
122ff0cc061SDimitry Andric auto *GTy = DD->resolve(GV->getType());
12339d628a0SDimitry Andric
12439d628a0SDimitry Andric // Construct the context before querying for the existence of the DIE in
12539d628a0SDimitry Andric // case such construction creates the DIE.
12639d628a0SDimitry Andric DIE *ContextDIE = getOrCreateContextDIE(GVContext);
12739d628a0SDimitry Andric
12839d628a0SDimitry Andric // Add to map.
129ff0cc061SDimitry Andric DIE *VariableDIE = &createAndAddDIE(GV->getTag(), *ContextDIE, GV);
130ff0cc061SDimitry Andric DIScope *DeclContext;
131ff0cc061SDimitry Andric if (auto *SDMDecl = GV->getStaticDataMemberDeclaration()) {
132ff0cc061SDimitry Andric DeclContext = resolve(SDMDecl->getScope());
133ff0cc061SDimitry Andric assert(SDMDecl->isStaticMember() && "Expected static member decl");
134ff0cc061SDimitry Andric assert(GV->isDefinition());
13539d628a0SDimitry Andric // We need the declaration DIE that is in the static member's class.
13639d628a0SDimitry Andric DIE *VariableSpecDIE = getOrCreateStaticMemberDIE(SDMDecl);
13739d628a0SDimitry Andric addDIEEntry(*VariableDIE, dwarf::DW_AT_specification, *VariableSpecDIE);
138d88c1a5aSDimitry Andric // If the global variable's type is different from the one in the class
139d88c1a5aSDimitry Andric // member type, assume that it's more specific and also emit it.
140d88c1a5aSDimitry Andric if (GTy != DD->resolve(SDMDecl->getBaseType()))
141d88c1a5aSDimitry Andric addType(*VariableDIE, GTy);
14239d628a0SDimitry Andric } else {
143ff0cc061SDimitry Andric DeclContext = GV->getScope();
14439d628a0SDimitry Andric // Add name and type.
145ff0cc061SDimitry Andric addString(*VariableDIE, dwarf::DW_AT_name, GV->getDisplayName());
14639d628a0SDimitry Andric addType(*VariableDIE, GTy);
14739d628a0SDimitry Andric
14839d628a0SDimitry Andric // Add scoping info.
149ff0cc061SDimitry Andric if (!GV->isLocalToUnit())
15039d628a0SDimitry Andric addFlag(*VariableDIE, dwarf::DW_AT_external);
15139d628a0SDimitry Andric
15239d628a0SDimitry Andric // Add line number info.
15339d628a0SDimitry Andric addSourceLine(*VariableDIE, GV);
15439d628a0SDimitry Andric }
15539d628a0SDimitry Andric
156ff0cc061SDimitry Andric if (!GV->isDefinition())
15739d628a0SDimitry Andric addFlag(*VariableDIE, dwarf::DW_AT_declaration);
158ff0cc061SDimitry Andric else
159ff0cc061SDimitry Andric addGlobalName(GV->getName(), *VariableDIE, DeclContext);
16039d628a0SDimitry Andric
161d88c1a5aSDimitry Andric if (uint32_t AlignInBytes = GV->getAlignInBytes())
162d88c1a5aSDimitry Andric addUInt(*VariableDIE, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,
163d88c1a5aSDimitry Andric AlignInBytes);
164d88c1a5aSDimitry Andric
165*b5893f02SDimitry Andric if (MDTuple *TP = GV->getTemplateParams())
166*b5893f02SDimitry Andric addTemplateParams(*VariableDIE, DINodeArray(TP));
167*b5893f02SDimitry Andric
16839d628a0SDimitry Andric // Add location.
16939d628a0SDimitry Andric bool addToAccelTable = false;
170d88c1a5aSDimitry Andric DIELoc *Loc = nullptr;
171d88c1a5aSDimitry Andric std::unique_ptr<DIEDwarfExpression> DwarfExpr;
172d88c1a5aSDimitry Andric for (const auto &GE : GlobalExprs) {
173d88c1a5aSDimitry Andric const GlobalVariable *Global = GE.Var;
174d88c1a5aSDimitry Andric const DIExpression *Expr = GE.Expr;
1757a7e6055SDimitry Andric
176d88c1a5aSDimitry Andric // For compatibility with DWARF 3 and earlier,
177d88c1a5aSDimitry Andric // DW_AT_location(DW_OP_constu, X, DW_OP_stack_value) becomes
178d88c1a5aSDimitry Andric // DW_AT_const_value(X).
179d88c1a5aSDimitry Andric if (GlobalExprs.size() == 1 && Expr && Expr->isConstant()) {
1807a7e6055SDimitry Andric addToAccelTable = true;
181d88c1a5aSDimitry Andric addConstantValue(*VariableDIE, /*Unsigned=*/true, Expr->getElement(1));
1827a7e6055SDimitry Andric break;
1837a7e6055SDimitry Andric }
1847a7e6055SDimitry Andric
185d88c1a5aSDimitry Andric // We cannot describe the location of dllimport'd variables: the
186d88c1a5aSDimitry Andric // computation of their address requires loads from the IAT.
1877a7e6055SDimitry Andric if (Global && Global->hasDLLImportStorageClass())
1887a7e6055SDimitry Andric continue;
1897a7e6055SDimitry Andric
1907a7e6055SDimitry Andric // Nothing to describe without address or constant.
1917a7e6055SDimitry Andric if (!Global && (!Expr || !Expr->isConstant()))
1927a7e6055SDimitry Andric continue;
1937a7e6055SDimitry Andric
194*b5893f02SDimitry Andric if (Global && Global->isThreadLocal() &&
195*b5893f02SDimitry Andric !Asm->getObjFileLowering().supportDebugThreadLocalLocation())
196*b5893f02SDimitry Andric continue;
197*b5893f02SDimitry Andric
198d88c1a5aSDimitry Andric if (!Loc) {
1997a7e6055SDimitry Andric addToAccelTable = true;
200d88c1a5aSDimitry Andric Loc = new (DIEValueAllocator) DIELoc;
201d88c1a5aSDimitry Andric DwarfExpr = llvm::make_unique<DIEDwarfExpression>(*Asm, *this, *Loc);
202d88c1a5aSDimitry Andric }
2037a7e6055SDimitry Andric
2044ba319b5SDimitry Andric if (Expr)
2054ba319b5SDimitry Andric DwarfExpr->addFragmentOffset(Expr);
2064ba319b5SDimitry Andric
207d88c1a5aSDimitry Andric if (Global) {
208ff0cc061SDimitry Andric const MCSymbol *Sym = Asm->getSymbol(Global);
209ff0cc061SDimitry Andric if (Global->isThreadLocal()) {
2104ba319b5SDimitry Andric if (Asm->TM.useEmulatedTLS()) {
2117d523365SDimitry Andric // TODO: add debug info for emulated thread local mode.
2127d523365SDimitry Andric } else {
21339d628a0SDimitry Andric // FIXME: Make this work with -gsplit-dwarf.
21439d628a0SDimitry Andric unsigned PointerSize = Asm->getDataLayout().getPointerSize();
21539d628a0SDimitry Andric assert((PointerSize == 4 || PointerSize == 8) &&
21639d628a0SDimitry Andric "Add support for other sizes if necessary");
21739d628a0SDimitry Andric // Based on GCC's support for TLS:
21839d628a0SDimitry Andric if (!DD->useSplitDwarf()) {
21939d628a0SDimitry Andric // 1) Start with a constNu of the appropriate pointer size
220d88c1a5aSDimitry Andric addUInt(*Loc, dwarf::DW_FORM_data1,
221d88c1a5aSDimitry Andric PointerSize == 4 ? dwarf::DW_OP_const4u
2227d523365SDimitry Andric : dwarf::DW_OP_const8u);
22339d628a0SDimitry Andric // 2) containing the (relocated) offset of the TLS variable
22439d628a0SDimitry Andric // within the module's TLS block.
22539d628a0SDimitry Andric addExpr(*Loc, dwarf::DW_FORM_udata,
22639d628a0SDimitry Andric Asm->getObjFileLowering().getDebugThreadLocalSymbol(Sym));
22739d628a0SDimitry Andric } else {
22839d628a0SDimitry Andric addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_const_index);
22939d628a0SDimitry Andric addUInt(*Loc, dwarf::DW_FORM_udata,
23039d628a0SDimitry Andric DD->getAddressPool().getIndex(Sym, /* TLS */ true));
23139d628a0SDimitry Andric }
232ff0cc061SDimitry Andric // 3) followed by an OP to make the debugger do a TLS lookup.
233ff0cc061SDimitry Andric addUInt(*Loc, dwarf::DW_FORM_data1,
234ff0cc061SDimitry Andric DD->useGNUTLSOpcode() ? dwarf::DW_OP_GNU_push_tls_address
235ff0cc061SDimitry Andric : dwarf::DW_OP_form_tls_address);
2367d523365SDimitry Andric }
23739d628a0SDimitry Andric } else {
23839d628a0SDimitry Andric DD->addArangeLabel(SymbolCU(this, Sym));
23939d628a0SDimitry Andric addOpAddress(*Loc, Sym);
24039d628a0SDimitry Andric }
241d88c1a5aSDimitry Andric }
2424ba319b5SDimitry Andric // Global variables attached to symbols are memory locations.
2434ba319b5SDimitry Andric // It would be better if this were unconditional, but malformed input that
2444ba319b5SDimitry Andric // mixes non-fragments and fragments for the same variable is too expensive
2454ba319b5SDimitry Andric // to detect in the verifier.
2464ba319b5SDimitry Andric if (DwarfExpr->isUnknownLocation())
2474ba319b5SDimitry Andric DwarfExpr->setMemoryLocationKind();
2487a7e6055SDimitry Andric DwarfExpr->addExpression(Expr);
249d88c1a5aSDimitry Andric }
250d88c1a5aSDimitry Andric if (Loc)
251d88c1a5aSDimitry Andric addBlock(*VariableDIE, dwarf::DW_AT_location, DwarfExpr->finalize());
25239d628a0SDimitry Andric
2533ca95b02SDimitry Andric if (DD->useAllLinkageNames())
254ff0cc061SDimitry Andric addLinkageName(*VariableDIE, GV->getLinkageName());
25539d628a0SDimitry Andric
25639d628a0SDimitry Andric if (addToAccelTable) {
257*b5893f02SDimitry Andric DD->addAccelName(*CUNode, GV->getName(), *VariableDIE);
25839d628a0SDimitry Andric
25939d628a0SDimitry Andric // If the linkage name is different than the name, go ahead and output
26039d628a0SDimitry Andric // that as well into the name table.
2614ba319b5SDimitry Andric if (GV->getLinkageName() != "" && GV->getName() != GV->getLinkageName() &&
2624ba319b5SDimitry Andric DD->useAllLinkageNames())
263*b5893f02SDimitry Andric DD->addAccelName(*CUNode, GV->getLinkageName(), *VariableDIE);
26439d628a0SDimitry Andric }
26539d628a0SDimitry Andric
26639d628a0SDimitry Andric return VariableDIE;
26739d628a0SDimitry Andric }
26839d628a0SDimitry Andric
addRange(RangeSpan Range)26939d628a0SDimitry Andric void DwarfCompileUnit::addRange(RangeSpan Range) {
27039d628a0SDimitry Andric bool SameAsPrevCU = this == DD->getPrevCU();
27139d628a0SDimitry Andric DD->setPrevCU(this);
27239d628a0SDimitry Andric // If we have no current ranges just add the range and return, otherwise,
27339d628a0SDimitry Andric // check the current section and CU against the previous section and CU we
27439d628a0SDimitry Andric // emitted into and the subprogram was contained within. If these are the
27539d628a0SDimitry Andric // same then extend our current range, otherwise add this as a new range.
27639d628a0SDimitry Andric if (CURanges.empty() || !SameAsPrevCU ||
27739d628a0SDimitry Andric (&CURanges.back().getEnd()->getSection() !=
27839d628a0SDimitry Andric &Range.getEnd()->getSection())) {
27939d628a0SDimitry Andric CURanges.push_back(Range);
280*b5893f02SDimitry Andric DD->addSectionLabel(Range.getStart());
28139d628a0SDimitry Andric return;
28239d628a0SDimitry Andric }
28339d628a0SDimitry Andric
28439d628a0SDimitry Andric CURanges.back().setEnd(Range.getEnd());
28539d628a0SDimitry Andric }
28639d628a0SDimitry Andric
initStmtList()287ff0cc061SDimitry Andric void DwarfCompileUnit::initStmtList() {
288*b5893f02SDimitry Andric if (CUNode->isDebugDirectivesOnly())
289*b5893f02SDimitry Andric return;
290*b5893f02SDimitry Andric
29139d628a0SDimitry Andric // Define start line table label for each Compile Unit.
2924ba319b5SDimitry Andric MCSymbol *LineTableStartSym;
2934ba319b5SDimitry Andric const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
2944ba319b5SDimitry Andric if (DD->useSectionsAsReferences()) {
2954ba319b5SDimitry Andric LineTableStartSym = TLOF.getDwarfLineSection()->getBeginSymbol();
2964ba319b5SDimitry Andric } else {
2974ba319b5SDimitry Andric LineTableStartSym =
298ff0cc061SDimitry Andric Asm->OutStreamer->getDwarfLineTableSymbol(getUniqueID());
2994ba319b5SDimitry Andric }
30039d628a0SDimitry Andric
30139d628a0SDimitry Andric // DW_AT_stmt_list is a offset of line number information for this
30239d628a0SDimitry Andric // compile unit in debug_line section. For split dwarf this is
30339d628a0SDimitry Andric // left in the skeleton CU and so not included.
30439d628a0SDimitry Andric // The line table entries are not always emitted in assembly, so it
30539d628a0SDimitry Andric // is not okay to use line_table_start here.
3063dac3a9bSDimitry Andric StmtListValue =
307d88c1a5aSDimitry Andric addSectionLabel(getUnitDie(), dwarf::DW_AT_stmt_list, LineTableStartSym,
308ff0cc061SDimitry Andric TLOF.getDwarfLineSection()->getBeginSymbol());
30939d628a0SDimitry Andric }
31039d628a0SDimitry Andric
applyStmtList(DIE & D)31139d628a0SDimitry Andric void DwarfCompileUnit::applyStmtList(DIE &D) {
3123dac3a9bSDimitry Andric D.addValue(DIEValueAllocator, *StmtListValue);
31339d628a0SDimitry Andric }
31439d628a0SDimitry Andric
attachLowHighPC(DIE & D,const MCSymbol * Begin,const MCSymbol * End)31539d628a0SDimitry Andric void DwarfCompileUnit::attachLowHighPC(DIE &D, const MCSymbol *Begin,
31639d628a0SDimitry Andric const MCSymbol *End) {
31739d628a0SDimitry Andric assert(Begin && "Begin label should not be null!");
31839d628a0SDimitry Andric assert(End && "End label should not be null!");
31939d628a0SDimitry Andric assert(Begin->isDefined() && "Invalid starting label");
32039d628a0SDimitry Andric assert(End->isDefined() && "Invalid end label");
32139d628a0SDimitry Andric
32239d628a0SDimitry Andric addLabelAddress(D, dwarf::DW_AT_low_pc, Begin);
32339d628a0SDimitry Andric if (DD->getDwarfVersion() < 4)
32439d628a0SDimitry Andric addLabelAddress(D, dwarf::DW_AT_high_pc, End);
32539d628a0SDimitry Andric else
32639d628a0SDimitry Andric addLabelDelta(D, dwarf::DW_AT_high_pc, End, Begin);
32739d628a0SDimitry Andric }
32839d628a0SDimitry Andric
32939d628a0SDimitry Andric // Find DIE for the given subprogram and attach appropriate DW_AT_low_pc
33039d628a0SDimitry Andric // and DW_AT_high_pc attributes. If there are global variables in this
33139d628a0SDimitry Andric // scope then create and insert DIEs for these variables.
updateSubprogramScopeDIE(const DISubprogram * SP)332ff0cc061SDimitry Andric DIE &DwarfCompileUnit::updateSubprogramScopeDIE(const DISubprogram *SP) {
33339d628a0SDimitry Andric DIE *SPDie = getOrCreateSubprogramDIE(SP, includeMinimalInlineScopes());
33439d628a0SDimitry Andric
335ff0cc061SDimitry Andric attachLowHighPC(*SPDie, Asm->getFunctionBegin(), Asm->getFunctionEnd());
3363ca95b02SDimitry Andric if (DD->useAppleExtensionAttributes() &&
3373ca95b02SDimitry Andric !DD->getCurrentFunction()->getTarget().Options.DisableFramePointerElim(
33839d628a0SDimitry Andric *DD->getCurrentFunction()))
33939d628a0SDimitry Andric addFlag(*SPDie, dwarf::DW_AT_APPLE_omit_frame_ptr);
34039d628a0SDimitry Andric
34139d628a0SDimitry Andric // Only include DW_AT_frame_base in full debug info
34239d628a0SDimitry Andric if (!includeMinimalInlineScopes()) {
3434ba319b5SDimitry Andric if (Asm->MF->getTarget().getTargetTriple().isNVPTX()) {
3444ba319b5SDimitry Andric DIELoc *Loc = new (DIEValueAllocator) DIELoc;
3454ba319b5SDimitry Andric addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_call_frame_cfa);
3464ba319b5SDimitry Andric addBlock(*SPDie, dwarf::DW_AT_frame_base, Loc);
3474ba319b5SDimitry Andric } else {
348ff0cc061SDimitry Andric const TargetRegisterInfo *RI = Asm->MF->getSubtarget().getRegisterInfo();
34939d628a0SDimitry Andric MachineLocation Location(RI->getFrameRegister(*Asm->MF));
35039d628a0SDimitry Andric if (RI->isPhysicalRegister(Location.getReg()))
35139d628a0SDimitry Andric addAddress(*SPDie, dwarf::DW_AT_frame_base, Location);
35239d628a0SDimitry Andric }
3534ba319b5SDimitry Andric }
35439d628a0SDimitry Andric
35539d628a0SDimitry Andric // Add name to the name table, we do this here because we're guaranteed
35639d628a0SDimitry Andric // to have concrete versions of our DW_TAG_subprogram nodes.
357*b5893f02SDimitry Andric DD->addSubprogramNames(*CUNode, SP, *SPDie);
35839d628a0SDimitry Andric
35939d628a0SDimitry Andric return *SPDie;
36039d628a0SDimitry Andric }
36139d628a0SDimitry Andric
36239d628a0SDimitry Andric // Construct a DIE for this scope.
constructScopeDIE(LexicalScope * Scope,SmallVectorImpl<DIE * > & FinalChildren)36339d628a0SDimitry Andric void DwarfCompileUnit::constructScopeDIE(
3643dac3a9bSDimitry Andric LexicalScope *Scope, SmallVectorImpl<DIE *> &FinalChildren) {
36539d628a0SDimitry Andric if (!Scope || !Scope->getScopeNode())
36639d628a0SDimitry Andric return;
36739d628a0SDimitry Andric
368ff0cc061SDimitry Andric auto *DS = Scope->getScopeNode();
36939d628a0SDimitry Andric
370ff0cc061SDimitry Andric assert((Scope->getInlinedAt() || !isa<DISubprogram>(DS)) &&
37139d628a0SDimitry Andric "Only handle inlined subprograms here, use "
37239d628a0SDimitry Andric "constructSubprogramScopeDIE for non-inlined "
37339d628a0SDimitry Andric "subprograms");
37439d628a0SDimitry Andric
3753dac3a9bSDimitry Andric SmallVector<DIE *, 8> Children;
37639d628a0SDimitry Andric
37739d628a0SDimitry Andric // We try to create the scope DIE first, then the children DIEs. This will
37839d628a0SDimitry Andric // avoid creating un-used children then removing them later when we find out
37939d628a0SDimitry Andric // the scope DIE is null.
3803dac3a9bSDimitry Andric DIE *ScopeDIE;
381ff0cc061SDimitry Andric if (Scope->getParent() && isa<DISubprogram>(DS)) {
38239d628a0SDimitry Andric ScopeDIE = constructInlinedScopeDIE(Scope);
38339d628a0SDimitry Andric if (!ScopeDIE)
38439d628a0SDimitry Andric return;
38539d628a0SDimitry Andric // We create children when the scope DIE is not null.
38639d628a0SDimitry Andric createScopeChildrenDIE(Scope, Children);
38739d628a0SDimitry Andric } else {
38839d628a0SDimitry Andric // Early exit when we know the scope DIE is going to be null.
38939d628a0SDimitry Andric if (DD->isLexicalScopeDIENull(Scope))
39039d628a0SDimitry Andric return;
39139d628a0SDimitry Andric
3922cab237bSDimitry Andric bool HasNonScopeChildren = false;
39339d628a0SDimitry Andric
39439d628a0SDimitry Andric // We create children here when we know the scope DIE is not going to be
39539d628a0SDimitry Andric // null and the children will be added to the scope DIE.
3962cab237bSDimitry Andric createScopeChildrenDIE(Scope, Children, &HasNonScopeChildren);
39739d628a0SDimitry Andric
39839d628a0SDimitry Andric // If there are only other scopes as children, put them directly in the
39939d628a0SDimitry Andric // parent instead, as this scope would serve no purpose.
4002cab237bSDimitry Andric if (!HasNonScopeChildren) {
40139d628a0SDimitry Andric FinalChildren.insert(FinalChildren.end(),
40239d628a0SDimitry Andric std::make_move_iterator(Children.begin()),
40339d628a0SDimitry Andric std::make_move_iterator(Children.end()));
40439d628a0SDimitry Andric return;
40539d628a0SDimitry Andric }
40639d628a0SDimitry Andric ScopeDIE = constructLexicalScopeDIE(Scope);
40739d628a0SDimitry Andric assert(ScopeDIE && "Scope DIE should not be null.");
40839d628a0SDimitry Andric }
40939d628a0SDimitry Andric
41039d628a0SDimitry Andric // Add children
41139d628a0SDimitry Andric for (auto &I : Children)
41239d628a0SDimitry Andric ScopeDIE->addChild(std::move(I));
41339d628a0SDimitry Andric
41439d628a0SDimitry Andric FinalChildren.push_back(std::move(ScopeDIE));
41539d628a0SDimitry Andric }
41639d628a0SDimitry Andric
addScopeRangeList(DIE & ScopeDIE,SmallVector<RangeSpan,2> Range)41739d628a0SDimitry Andric void DwarfCompileUnit::addScopeRangeList(DIE &ScopeDIE,
41839d628a0SDimitry Andric SmallVector<RangeSpan, 2> Range) {
419ff0cc061SDimitry Andric const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
420ff0cc061SDimitry Andric
4214ba319b5SDimitry Andric // Emit the offset into .debug_ranges or .debug_rnglists as a relocatable
4224ba319b5SDimitry Andric // label. emitDIE() will handle emitting it appropriately.
423ff0cc061SDimitry Andric const MCSymbol *RangeSectionSym =
4244ba319b5SDimitry Andric DD->getDwarfVersion() >= 5
4254ba319b5SDimitry Andric ? TLOF.getDwarfRnglistsSection()->getBeginSymbol()
4264ba319b5SDimitry Andric : TLOF.getDwarfRangesSection()->getBeginSymbol();
42739d628a0SDimitry Andric
428*b5893f02SDimitry Andric HasRangeLists = true;
429*b5893f02SDimitry Andric
430*b5893f02SDimitry Andric // Add the range list to the set of ranges to be emitted.
431*b5893f02SDimitry Andric auto IndexAndList =
432*b5893f02SDimitry Andric (DD->getDwarfVersion() < 5 && Skeleton ? Skeleton->DU : DU)
433*b5893f02SDimitry Andric ->addRange(*(Skeleton ? Skeleton : this), std::move(Range));
434*b5893f02SDimitry Andric
435*b5893f02SDimitry Andric uint32_t Index = IndexAndList.first;
436*b5893f02SDimitry Andric auto &List = *IndexAndList.second;
43739d628a0SDimitry Andric
43839d628a0SDimitry Andric // Under fission, ranges are specified by constant offsets relative to the
43939d628a0SDimitry Andric // CU's DW_AT_GNU_ranges_base.
4404ba319b5SDimitry Andric // FIXME: For DWARF v5, do not generate the DW_AT_ranges attribute under
4414ba319b5SDimitry Andric // fission until we support the forms using the .debug_addr section
4424ba319b5SDimitry Andric // (DW_RLE_startx_endx etc.).
443*b5893f02SDimitry Andric if (DD->getDwarfVersion() >= 5)
444*b5893f02SDimitry Andric addUInt(ScopeDIE, dwarf::DW_AT_ranges, dwarf::DW_FORM_rnglistx, Index);
445*b5893f02SDimitry Andric else if (isDwoUnit())
44639d628a0SDimitry Andric addSectionDelta(ScopeDIE, dwarf::DW_AT_ranges, List.getSym(),
44739d628a0SDimitry Andric RangeSectionSym);
448*b5893f02SDimitry Andric else
44939d628a0SDimitry Andric addSectionLabel(ScopeDIE, dwarf::DW_AT_ranges, List.getSym(),
45039d628a0SDimitry Andric RangeSectionSym);
4514ba319b5SDimitry Andric }
45239d628a0SDimitry Andric
attachRangesOrLowHighPC(DIE & Die,SmallVector<RangeSpan,2> Ranges)45339d628a0SDimitry Andric void DwarfCompileUnit::attachRangesOrLowHighPC(
45439d628a0SDimitry Andric DIE &Die, SmallVector<RangeSpan, 2> Ranges) {
4554ba319b5SDimitry Andric if (Ranges.size() == 1 || !DD->useRangesSection()) {
4564ba319b5SDimitry Andric const RangeSpan &Front = Ranges.front();
4574ba319b5SDimitry Andric const RangeSpan &Back = Ranges.back();
4584ba319b5SDimitry Andric attachLowHighPC(Die, Front.getStart(), Back.getEnd());
45939d628a0SDimitry Andric } else
46039d628a0SDimitry Andric addScopeRangeList(Die, std::move(Ranges));
46139d628a0SDimitry Andric }
46239d628a0SDimitry Andric
attachRangesOrLowHighPC(DIE & Die,const SmallVectorImpl<InsnRange> & Ranges)46339d628a0SDimitry Andric void DwarfCompileUnit::attachRangesOrLowHighPC(
46439d628a0SDimitry Andric DIE &Die, const SmallVectorImpl<InsnRange> &Ranges) {
46539d628a0SDimitry Andric SmallVector<RangeSpan, 2> List;
46639d628a0SDimitry Andric List.reserve(Ranges.size());
46739d628a0SDimitry Andric for (const InsnRange &R : Ranges)
46839d628a0SDimitry Andric List.push_back(RangeSpan(DD->getLabelBeforeInsn(R.first),
46939d628a0SDimitry Andric DD->getLabelAfterInsn(R.second)));
47039d628a0SDimitry Andric attachRangesOrLowHighPC(Die, std::move(List));
47139d628a0SDimitry Andric }
47239d628a0SDimitry Andric
47339d628a0SDimitry Andric // This scope represents inlined body of a function. Construct DIE to
47439d628a0SDimitry Andric // represent this concrete inlined copy of the function.
constructInlinedScopeDIE(LexicalScope * Scope)4753dac3a9bSDimitry Andric DIE *DwarfCompileUnit::constructInlinedScopeDIE(LexicalScope *Scope) {
47639d628a0SDimitry Andric assert(Scope->getScopeNode());
477ff0cc061SDimitry Andric auto *DS = Scope->getScopeNode();
478ff0cc061SDimitry Andric auto *InlinedSP = getDISubprogram(DS);
47939d628a0SDimitry Andric // Find the subprogram's DwarfCompileUnit in the SPMap in case the subprogram
48039d628a0SDimitry Andric // was inlined from another compile unit.
4815517e702SDimitry Andric DIE *OriginDIE = getAbstractSPDies()[InlinedSP];
48239d628a0SDimitry Andric assert(OriginDIE && "Unable to find original DIE for an inlined subprogram.");
48339d628a0SDimitry Andric
4843dac3a9bSDimitry Andric auto ScopeDIE = DIE::get(DIEValueAllocator, dwarf::DW_TAG_inlined_subroutine);
48539d628a0SDimitry Andric addDIEEntry(*ScopeDIE, dwarf::DW_AT_abstract_origin, *OriginDIE);
48639d628a0SDimitry Andric
48739d628a0SDimitry Andric attachRangesOrLowHighPC(*ScopeDIE, Scope->getRanges());
48839d628a0SDimitry Andric
48939d628a0SDimitry Andric // Add the call site information to the DIE.
490ff0cc061SDimitry Andric const DILocation *IA = Scope->getInlinedAt();
49139d628a0SDimitry Andric addUInt(*ScopeDIE, dwarf::DW_AT_call_file, None,
4924ba319b5SDimitry Andric getOrCreateSourceID(IA->getFile()));
493ff0cc061SDimitry Andric addUInt(*ScopeDIE, dwarf::DW_AT_call_line, None, IA->getLine());
494d88c1a5aSDimitry Andric if (IA->getDiscriminator() && DD->getDwarfVersion() >= 4)
4957d523365SDimitry Andric addUInt(*ScopeDIE, dwarf::DW_AT_GNU_discriminator, None,
4967d523365SDimitry Andric IA->getDiscriminator());
49739d628a0SDimitry Andric
49839d628a0SDimitry Andric // Add name to the name table, we do this here because we're guaranteed
49939d628a0SDimitry Andric // to have concrete versions of our DW_TAG_inlined_subprogram nodes.
500*b5893f02SDimitry Andric DD->addSubprogramNames(*CUNode, InlinedSP, *ScopeDIE);
50139d628a0SDimitry Andric
50239d628a0SDimitry Andric return ScopeDIE;
50339d628a0SDimitry Andric }
50439d628a0SDimitry Andric
50539d628a0SDimitry Andric // Construct new DW_TAG_lexical_block for this scope and attach
50639d628a0SDimitry Andric // DW_AT_low_pc/DW_AT_high_pc labels.
constructLexicalScopeDIE(LexicalScope * Scope)5073dac3a9bSDimitry Andric DIE *DwarfCompileUnit::constructLexicalScopeDIE(LexicalScope *Scope) {
50839d628a0SDimitry Andric if (DD->isLexicalScopeDIENull(Scope))
50939d628a0SDimitry Andric return nullptr;
51039d628a0SDimitry Andric
5113dac3a9bSDimitry Andric auto ScopeDIE = DIE::get(DIEValueAllocator, dwarf::DW_TAG_lexical_block);
51239d628a0SDimitry Andric if (Scope->isAbstractScope())
51339d628a0SDimitry Andric return ScopeDIE;
51439d628a0SDimitry Andric
51539d628a0SDimitry Andric attachRangesOrLowHighPC(*ScopeDIE, Scope->getRanges());
51639d628a0SDimitry Andric
51739d628a0SDimitry Andric return ScopeDIE;
51839d628a0SDimitry Andric }
51939d628a0SDimitry Andric
52039d628a0SDimitry Andric /// constructVariableDIE - Construct a DIE for the given DbgVariable.
constructVariableDIE(DbgVariable & DV,bool Abstract)5213dac3a9bSDimitry Andric DIE *DwarfCompileUnit::constructVariableDIE(DbgVariable &DV, bool Abstract) {
52239d628a0SDimitry Andric auto D = constructVariableDIEImpl(DV, Abstract);
52339d628a0SDimitry Andric DV.setDIE(*D);
52439d628a0SDimitry Andric return D;
52539d628a0SDimitry Andric }
52639d628a0SDimitry Andric
constructLabelDIE(DbgLabel & DL,const LexicalScope & Scope)527*b5893f02SDimitry Andric DIE *DwarfCompileUnit::constructLabelDIE(DbgLabel &DL,
528*b5893f02SDimitry Andric const LexicalScope &Scope) {
529*b5893f02SDimitry Andric auto LabelDie = DIE::get(DIEValueAllocator, DL.getTag());
530*b5893f02SDimitry Andric insertDIE(DL.getLabel(), LabelDie);
531*b5893f02SDimitry Andric DL.setDIE(*LabelDie);
532*b5893f02SDimitry Andric
533*b5893f02SDimitry Andric if (Scope.isAbstractScope())
534*b5893f02SDimitry Andric applyLabelAttributes(DL, *LabelDie);
535*b5893f02SDimitry Andric
536*b5893f02SDimitry Andric return LabelDie;
537*b5893f02SDimitry Andric }
538*b5893f02SDimitry Andric
constructVariableDIEImpl(const DbgVariable & DV,bool Abstract)5393dac3a9bSDimitry Andric DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV,
54039d628a0SDimitry Andric bool Abstract) {
54139d628a0SDimitry Andric // Define variable debug information entry.
5423dac3a9bSDimitry Andric auto VariableDie = DIE::get(DIEValueAllocator, DV.getTag());
5434ba319b5SDimitry Andric insertDIE(DV.getVariable(), VariableDie);
54439d628a0SDimitry Andric
54539d628a0SDimitry Andric if (Abstract) {
54639d628a0SDimitry Andric applyVariableAttributes(DV, *VariableDie);
54739d628a0SDimitry Andric return VariableDie;
54839d628a0SDimitry Andric }
54939d628a0SDimitry Andric
55039d628a0SDimitry Andric // Add variable address.
55139d628a0SDimitry Andric
552ff0cc061SDimitry Andric unsigned Offset = DV.getDebugLocListIndex();
55339d628a0SDimitry Andric if (Offset != ~0U) {
55439d628a0SDimitry Andric addLocationList(*VariableDie, dwarf::DW_AT_location, Offset);
55539d628a0SDimitry Andric return VariableDie;
55639d628a0SDimitry Andric }
55739d628a0SDimitry Andric
55839d628a0SDimitry Andric // Check if variable is described by a DBG_VALUE instruction.
55939d628a0SDimitry Andric if (const MachineInstr *DVInsn = DV.getMInsn()) {
56039d628a0SDimitry Andric assert(DVInsn->getNumOperands() == 4);
56139d628a0SDimitry Andric if (DVInsn->getOperand(0).isReg()) {
5622cab237bSDimitry Andric auto RegOp = DVInsn->getOperand(0);
5632cab237bSDimitry Andric auto Op1 = DVInsn->getOperand(1);
56439d628a0SDimitry Andric // If the second operand is an immediate, this is an indirect value.
5652cab237bSDimitry Andric assert((!Op1.isImm() || (Op1.getImm() == 0)) && "unexpected offset");
5662cab237bSDimitry Andric MachineLocation Location(RegOp.getReg(), Op1.isImm());
56739d628a0SDimitry Andric addVariableAddress(DV, *VariableDie, Location);
5683ca95b02SDimitry Andric } else if (DVInsn->getOperand(0).isImm()) {
5693ca95b02SDimitry Andric // This variable is described by a single constant.
5703ca95b02SDimitry Andric // Check whether it has a DIExpression.
5713ca95b02SDimitry Andric auto *Expr = DV.getSingleExpression();
5723ca95b02SDimitry Andric if (Expr && Expr->getNumElements()) {
5733ca95b02SDimitry Andric DIELoc *Loc = new (DIEValueAllocator) DIELoc;
5743ca95b02SDimitry Andric DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
5753ca95b02SDimitry Andric // If there is an expression, emit raw unsigned bytes.
576d88c1a5aSDimitry Andric DwarfExpr.addFragmentOffset(Expr);
5777a7e6055SDimitry Andric DwarfExpr.addUnsignedConstant(DVInsn->getOperand(0).getImm());
5787a7e6055SDimitry Andric DwarfExpr.addExpression(Expr);
579d88c1a5aSDimitry Andric addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
5803ca95b02SDimitry Andric } else
58139d628a0SDimitry Andric addConstantValue(*VariableDie, DVInsn->getOperand(0), DV.getType());
5823ca95b02SDimitry Andric } else if (DVInsn->getOperand(0).isFPImm())
58339d628a0SDimitry Andric addConstantFPValue(*VariableDie, DVInsn->getOperand(0));
58439d628a0SDimitry Andric else if (DVInsn->getOperand(0).isCImm())
58539d628a0SDimitry Andric addConstantValue(*VariableDie, DVInsn->getOperand(0).getCImm(),
58639d628a0SDimitry Andric DV.getType());
58739d628a0SDimitry Andric
58839d628a0SDimitry Andric return VariableDie;
58939d628a0SDimitry Andric }
59039d628a0SDimitry Andric
59139d628a0SDimitry Andric // .. else use frame index.
5925d193882SDimitry Andric if (!DV.hasFrameIndexExprs())
593ff0cc061SDimitry Andric return VariableDie;
594ff0cc061SDimitry Andric
59597bc6c73SDimitry Andric DIELoc *Loc = new (DIEValueAllocator) DIELoc;
596ff0cc061SDimitry Andric DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
5975d193882SDimitry Andric for (auto &Fragment : DV.getFrameIndexExprs()) {
59839d628a0SDimitry Andric unsigned FrameReg = 0;
5996bc11b14SDimitry Andric const DIExpression *Expr = Fragment.Expr;
600ff0cc061SDimitry Andric const TargetFrameLowering *TFI = Asm->MF->getSubtarget().getFrameLowering();
6015d193882SDimitry Andric int Offset = TFI->getFrameIndexReference(*Asm->MF, Fragment.FI, FrameReg);
6026bc11b14SDimitry Andric DwarfExpr.addFragmentOffset(Expr);
6037a7e6055SDimitry Andric SmallVector<uint64_t, 8> Ops;
60424d58133SDimitry Andric Ops.push_back(dwarf::DW_OP_plus_uconst);
6057a7e6055SDimitry Andric Ops.push_back(Offset);
6066bc11b14SDimitry Andric Ops.append(Expr->elements_begin(), Expr->elements_end());
6076bc11b14SDimitry Andric DIExpressionCursor Cursor(Ops);
6086bc11b14SDimitry Andric DwarfExpr.setMemoryLocationKind();
6094ba319b5SDimitry Andric if (const MCSymbol *FrameSymbol = Asm->getFunctionFrameSymbol())
6104ba319b5SDimitry Andric addOpAddress(*Loc, FrameSymbol);
6114ba319b5SDimitry Andric else
6127a7e6055SDimitry Andric DwarfExpr.addMachineRegExpression(
6136bc11b14SDimitry Andric *Asm->MF->getSubtarget().getRegisterInfo(), Cursor, FrameReg);
6146bc11b14SDimitry Andric DwarfExpr.addExpression(std::move(Cursor));
61539d628a0SDimitry Andric }
616d88c1a5aSDimitry Andric addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
61739d628a0SDimitry Andric
61839d628a0SDimitry Andric return VariableDie;
61939d628a0SDimitry Andric }
62039d628a0SDimitry Andric
constructVariableDIE(DbgVariable & DV,const LexicalScope & Scope,DIE * & ObjectPointer)6213dac3a9bSDimitry Andric DIE *DwarfCompileUnit::constructVariableDIE(DbgVariable &DV,
6223dac3a9bSDimitry Andric const LexicalScope &Scope,
6233dac3a9bSDimitry Andric DIE *&ObjectPointer) {
62439d628a0SDimitry Andric auto Var = constructVariableDIE(DV, Scope.isAbstractScope());
62539d628a0SDimitry Andric if (DV.isObjectPointer())
6263dac3a9bSDimitry Andric ObjectPointer = Var;
62739d628a0SDimitry Andric return Var;
62839d628a0SDimitry Andric }
62939d628a0SDimitry Andric
6304ba319b5SDimitry Andric /// Return all DIVariables that appear in count: expressions.
dependencies(DbgVariable * Var)6314ba319b5SDimitry Andric static SmallVector<const DIVariable *, 2> dependencies(DbgVariable *Var) {
6324ba319b5SDimitry Andric SmallVector<const DIVariable *, 2> Result;
6334ba319b5SDimitry Andric auto *Array = dyn_cast<DICompositeType>(Var->getType());
6344ba319b5SDimitry Andric if (!Array || Array->getTag() != dwarf::DW_TAG_array_type)
6354ba319b5SDimitry Andric return Result;
6364ba319b5SDimitry Andric for (auto *El : Array->getElements()) {
6374ba319b5SDimitry Andric if (auto *Subrange = dyn_cast<DISubrange>(El)) {
6384ba319b5SDimitry Andric auto Count = Subrange->getCount();
6394ba319b5SDimitry Andric if (auto *Dependency = Count.dyn_cast<DIVariable *>())
6404ba319b5SDimitry Andric Result.push_back(Dependency);
6414ba319b5SDimitry Andric }
6424ba319b5SDimitry Andric }
6434ba319b5SDimitry Andric return Result;
6444ba319b5SDimitry Andric }
6454ba319b5SDimitry Andric
6464ba319b5SDimitry Andric /// Sort local variables so that variables appearing inside of helper
6474ba319b5SDimitry Andric /// expressions come first.
6484ba319b5SDimitry Andric static SmallVector<DbgVariable *, 8>
sortLocalVars(SmallVectorImpl<DbgVariable * > & Input)6494ba319b5SDimitry Andric sortLocalVars(SmallVectorImpl<DbgVariable *> &Input) {
6504ba319b5SDimitry Andric SmallVector<DbgVariable *, 8> Result;
6514ba319b5SDimitry Andric SmallVector<PointerIntPair<DbgVariable *, 1>, 8> WorkList;
6524ba319b5SDimitry Andric // Map back from a DIVariable to its containing DbgVariable.
6534ba319b5SDimitry Andric SmallDenseMap<const DILocalVariable *, DbgVariable *> DbgVar;
6544ba319b5SDimitry Andric // Set of DbgVariables in Result.
6554ba319b5SDimitry Andric SmallDenseSet<DbgVariable *, 8> Visited;
6564ba319b5SDimitry Andric // For cycle detection.
6574ba319b5SDimitry Andric SmallDenseSet<DbgVariable *, 8> Visiting;
6584ba319b5SDimitry Andric
6594ba319b5SDimitry Andric // Initialize the worklist and the DIVariable lookup table.
6604ba319b5SDimitry Andric for (auto Var : reverse(Input)) {
6614ba319b5SDimitry Andric DbgVar.insert({Var->getVariable(), Var});
6624ba319b5SDimitry Andric WorkList.push_back({Var, 0});
6634ba319b5SDimitry Andric }
6644ba319b5SDimitry Andric
6654ba319b5SDimitry Andric // Perform a stable topological sort by doing a DFS.
6664ba319b5SDimitry Andric while (!WorkList.empty()) {
6674ba319b5SDimitry Andric auto Item = WorkList.back();
6684ba319b5SDimitry Andric DbgVariable *Var = Item.getPointer();
6694ba319b5SDimitry Andric bool visitedAllDependencies = Item.getInt();
6704ba319b5SDimitry Andric WorkList.pop_back();
6714ba319b5SDimitry Andric
6724ba319b5SDimitry Andric // Dependency is in a different lexical scope or a global.
6734ba319b5SDimitry Andric if (!Var)
6744ba319b5SDimitry Andric continue;
6754ba319b5SDimitry Andric
6764ba319b5SDimitry Andric // Already handled.
6774ba319b5SDimitry Andric if (Visited.count(Var))
6784ba319b5SDimitry Andric continue;
6794ba319b5SDimitry Andric
6804ba319b5SDimitry Andric // Add to Result if all dependencies are visited.
6814ba319b5SDimitry Andric if (visitedAllDependencies) {
6824ba319b5SDimitry Andric Visited.insert(Var);
6834ba319b5SDimitry Andric Result.push_back(Var);
6844ba319b5SDimitry Andric continue;
6854ba319b5SDimitry Andric }
6864ba319b5SDimitry Andric
6874ba319b5SDimitry Andric // Detect cycles.
6884ba319b5SDimitry Andric auto Res = Visiting.insert(Var);
6894ba319b5SDimitry Andric if (!Res.second) {
6904ba319b5SDimitry Andric assert(false && "dependency cycle in local variables");
6914ba319b5SDimitry Andric return Result;
6924ba319b5SDimitry Andric }
6934ba319b5SDimitry Andric
6944ba319b5SDimitry Andric // Push dependencies and this node onto the worklist, so that this node is
6954ba319b5SDimitry Andric // visited again after all of its dependencies are handled.
6964ba319b5SDimitry Andric WorkList.push_back({Var, 1});
6974ba319b5SDimitry Andric for (auto *Dependency : dependencies(Var)) {
6984ba319b5SDimitry Andric auto Dep = dyn_cast_or_null<const DILocalVariable>(Dependency);
6994ba319b5SDimitry Andric WorkList.push_back({DbgVar[Dep], 0});
7004ba319b5SDimitry Andric }
7014ba319b5SDimitry Andric }
7024ba319b5SDimitry Andric return Result;
7034ba319b5SDimitry Andric }
7044ba319b5SDimitry Andric
createScopeChildrenDIE(LexicalScope * Scope,SmallVectorImpl<DIE * > & Children,bool * HasNonScopeChildren)7053dac3a9bSDimitry Andric DIE *DwarfCompileUnit::createScopeChildrenDIE(LexicalScope *Scope,
7063dac3a9bSDimitry Andric SmallVectorImpl<DIE *> &Children,
7072cab237bSDimitry Andric bool *HasNonScopeChildren) {
7082cab237bSDimitry Andric assert(Children.empty());
70939d628a0SDimitry Andric DIE *ObjectPointer = nullptr;
71039d628a0SDimitry Andric
7114ba319b5SDimitry Andric // Emit function arguments (order is significant).
7124ba319b5SDimitry Andric auto Vars = DU->getScopeVariables().lookup(Scope);
7134ba319b5SDimitry Andric for (auto &DV : Vars.Args)
7144ba319b5SDimitry Andric Children.push_back(constructVariableDIE(*DV.second, *Scope, ObjectPointer));
7154ba319b5SDimitry Andric
7164ba319b5SDimitry Andric // Emit local variables.
7174ba319b5SDimitry Andric auto Locals = sortLocalVars(Vars.Locals);
7184ba319b5SDimitry Andric for (DbgVariable *DV : Locals)
71939d628a0SDimitry Andric Children.push_back(constructVariableDIE(*DV, *Scope, ObjectPointer));
72039d628a0SDimitry Andric
7212cab237bSDimitry Andric // Skip imported directives in gmlt-like data.
7222cab237bSDimitry Andric if (!includeMinimalInlineScopes()) {
7232cab237bSDimitry Andric // There is no need to emit empty lexical block DIE.
7242cab237bSDimitry Andric for (const auto *IE : ImportedEntities[Scope->getScopeNode()])
7252cab237bSDimitry Andric Children.push_back(
7262cab237bSDimitry Andric constructImportedEntityDIE(cast<DIImportedEntity>(IE)));
7272cab237bSDimitry Andric }
7282cab237bSDimitry Andric
7292cab237bSDimitry Andric if (HasNonScopeChildren)
7302cab237bSDimitry Andric *HasNonScopeChildren = !Children.empty();
73139d628a0SDimitry Andric
732*b5893f02SDimitry Andric for (DbgLabel *DL : DU->getScopeLabels().lookup(Scope))
733*b5893f02SDimitry Andric Children.push_back(constructLabelDIE(*DL, *Scope));
734*b5893f02SDimitry Andric
73539d628a0SDimitry Andric for (LexicalScope *LS : Scope->getChildren())
73639d628a0SDimitry Andric constructScopeDIE(LS, Children);
73739d628a0SDimitry Andric
73839d628a0SDimitry Andric return ObjectPointer;
73939d628a0SDimitry Andric }
74039d628a0SDimitry Andric
constructSubprogramScopeDIE(const DISubprogram * Sub,LexicalScope * Scope)741*b5893f02SDimitry Andric DIE &DwarfCompileUnit::constructSubprogramScopeDIE(const DISubprogram *Sub,
742*b5893f02SDimitry Andric LexicalScope *Scope) {
74339d628a0SDimitry Andric DIE &ScopeDIE = updateSubprogramScopeDIE(Sub);
74439d628a0SDimitry Andric
745d88c1a5aSDimitry Andric if (Scope) {
746d88c1a5aSDimitry Andric assert(!Scope->getInlinedAt());
747d88c1a5aSDimitry Andric assert(!Scope->isAbstractScope());
74839d628a0SDimitry Andric // Collect lexical scope children first.
74939d628a0SDimitry Andric // ObjectPointer might be a local (non-argument) local variable if it's a
75039d628a0SDimitry Andric // block's synthetic this pointer.
75139d628a0SDimitry Andric if (DIE *ObjectPointer = createAndAddScopeChildren(Scope, ScopeDIE))
75239d628a0SDimitry Andric addDIEEntry(ScopeDIE, dwarf::DW_AT_object_pointer, *ObjectPointer);
753d88c1a5aSDimitry Andric }
754d88c1a5aSDimitry Andric
755d88c1a5aSDimitry Andric // If this is a variadic function, add an unspecified parameter.
756d88c1a5aSDimitry Andric DITypeRefArray FnArgs = Sub->getType()->getTypeArray();
75739d628a0SDimitry Andric
75839d628a0SDimitry Andric // If we have a single element of null, it is a function that returns void.
75939d628a0SDimitry Andric // If we have more than one elements and the last one is null, it is a
76039d628a0SDimitry Andric // variadic function.
761ff0cc061SDimitry Andric if (FnArgs.size() > 1 && !FnArgs[FnArgs.size() - 1] &&
76239d628a0SDimitry Andric !includeMinimalInlineScopes())
7633dac3a9bSDimitry Andric ScopeDIE.addChild(
7643dac3a9bSDimitry Andric DIE::get(DIEValueAllocator, dwarf::DW_TAG_unspecified_parameters));
765*b5893f02SDimitry Andric
766*b5893f02SDimitry Andric return ScopeDIE;
76739d628a0SDimitry Andric }
76839d628a0SDimitry Andric
createAndAddScopeChildren(LexicalScope * Scope,DIE & ScopeDIE)76939d628a0SDimitry Andric DIE *DwarfCompileUnit::createAndAddScopeChildren(LexicalScope *Scope,
77039d628a0SDimitry Andric DIE &ScopeDIE) {
77139d628a0SDimitry Andric // We create children when the scope DIE is not null.
7723dac3a9bSDimitry Andric SmallVector<DIE *, 8> Children;
77339d628a0SDimitry Andric DIE *ObjectPointer = createScopeChildrenDIE(Scope, Children);
77439d628a0SDimitry Andric
77539d628a0SDimitry Andric // Add children
77639d628a0SDimitry Andric for (auto &I : Children)
77739d628a0SDimitry Andric ScopeDIE.addChild(std::move(I));
77839d628a0SDimitry Andric
77939d628a0SDimitry Andric return ObjectPointer;
78039d628a0SDimitry Andric }
78139d628a0SDimitry Andric
constructAbstractSubprogramScopeDIE(LexicalScope * Scope)7827d523365SDimitry Andric void DwarfCompileUnit::constructAbstractSubprogramScopeDIE(
7837d523365SDimitry Andric LexicalScope *Scope) {
7845517e702SDimitry Andric DIE *&AbsDef = getAbstractSPDies()[Scope->getScopeNode()];
78539d628a0SDimitry Andric if (AbsDef)
78639d628a0SDimitry Andric return;
78739d628a0SDimitry Andric
788ff0cc061SDimitry Andric auto *SP = cast<DISubprogram>(Scope->getScopeNode());
78939d628a0SDimitry Andric
79039d628a0SDimitry Andric DIE *ContextDIE;
791d4419f6fSDimitry Andric DwarfCompileUnit *ContextCU = this;
79239d628a0SDimitry Andric
79339d628a0SDimitry Andric if (includeMinimalInlineScopes())
79439d628a0SDimitry Andric ContextDIE = &getUnitDie();
79539d628a0SDimitry Andric // Some of this is duplicated from DwarfUnit::getOrCreateSubprogramDIE, with
796ff0cc061SDimitry Andric // the important distinction that the debug node is not associated with the
797ff0cc061SDimitry Andric // DIE (since the debug node will be associated with the concrete DIE, if
79839d628a0SDimitry Andric // any). It could be refactored to some common utility function.
799ff0cc061SDimitry Andric else if (auto *SPDecl = SP->getDeclaration()) {
80039d628a0SDimitry Andric ContextDIE = &getUnitDie();
80139d628a0SDimitry Andric getOrCreateSubprogramDIE(SPDecl);
802d4419f6fSDimitry Andric } else {
803ff0cc061SDimitry Andric ContextDIE = getOrCreateContextDIE(resolve(SP->getScope()));
804d4419f6fSDimitry Andric // The scope may be shared with a subprogram that has already been
805d4419f6fSDimitry Andric // constructed in another CU, in which case we need to construct this
806d4419f6fSDimitry Andric // subprogram in the same CU.
807d4419f6fSDimitry Andric ContextCU = DD->lookupCU(ContextDIE->getUnitDie());
808d4419f6fSDimitry Andric }
80939d628a0SDimitry Andric
810ff0cc061SDimitry Andric // Passing null as the associated node because the abstract definition
81139d628a0SDimitry Andric // shouldn't be found by lookup.
812d4419f6fSDimitry Andric AbsDef = &ContextCU->createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE, nullptr);
813d4419f6fSDimitry Andric ContextCU->applySubprogramAttributesToDefinition(SP, *AbsDef);
81439d628a0SDimitry Andric
815d4419f6fSDimitry Andric if (!ContextCU->includeMinimalInlineScopes())
816d4419f6fSDimitry Andric ContextCU->addUInt(*AbsDef, dwarf::DW_AT_inline, None, dwarf::DW_INL_inlined);
817d4419f6fSDimitry Andric if (DIE *ObjectPointer = ContextCU->createAndAddScopeChildren(Scope, *AbsDef))
818d4419f6fSDimitry Andric ContextCU->addDIEEntry(*AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer);
81939d628a0SDimitry Andric }
82039d628a0SDimitry Andric
constructCallSiteEntryDIE(DIE & ScopeDIE,const DISubprogram & CalleeSP,bool IsTail,const MCExpr * PCOffset)821*b5893f02SDimitry Andric DIE &DwarfCompileUnit::constructCallSiteEntryDIE(DIE &ScopeDIE,
822*b5893f02SDimitry Andric const DISubprogram &CalleeSP,
823*b5893f02SDimitry Andric bool IsTail,
824*b5893f02SDimitry Andric const MCExpr *PCOffset) {
825*b5893f02SDimitry Andric // Insert a call site entry DIE within ScopeDIE.
826*b5893f02SDimitry Andric DIE &CallSiteDIE =
827*b5893f02SDimitry Andric createAndAddDIE(dwarf::DW_TAG_call_site, ScopeDIE, nullptr);
828*b5893f02SDimitry Andric
829*b5893f02SDimitry Andric // For the purposes of showing tail call frames in backtraces, a key piece of
830*b5893f02SDimitry Andric // information is DW_AT_call_origin, a pointer to the callee DIE.
831*b5893f02SDimitry Andric DIE *CalleeDIE = getOrCreateSubprogramDIE(&CalleeSP);
832*b5893f02SDimitry Andric assert(CalleeDIE && "Could not create DIE for call site entry origin");
833*b5893f02SDimitry Andric addDIEEntry(CallSiteDIE, dwarf::DW_AT_call_origin, *CalleeDIE);
834*b5893f02SDimitry Andric
835*b5893f02SDimitry Andric if (IsTail) {
836*b5893f02SDimitry Andric // Attach DW_AT_call_tail_call to tail calls for standards compliance.
837*b5893f02SDimitry Andric addFlag(CallSiteDIE, dwarf::DW_AT_call_tail_call);
838*b5893f02SDimitry Andric } else {
839*b5893f02SDimitry Andric // Attach the return PC to allow the debugger to disambiguate call paths
840*b5893f02SDimitry Andric // from one function to another.
841*b5893f02SDimitry Andric assert(PCOffset && "Missing return PC information for a call");
842*b5893f02SDimitry Andric addAddressExpr(CallSiteDIE, dwarf::DW_AT_call_return_pc, PCOffset);
843*b5893f02SDimitry Andric }
844*b5893f02SDimitry Andric return CallSiteDIE;
845*b5893f02SDimitry Andric }
846*b5893f02SDimitry Andric
constructImportedEntityDIE(const DIImportedEntity * Module)8473dac3a9bSDimitry Andric DIE *DwarfCompileUnit::constructImportedEntityDIE(
8483dac3a9bSDimitry Andric const DIImportedEntity *Module) {
8493dac3a9bSDimitry Andric DIE *IMDie = DIE::get(DIEValueAllocator, (dwarf::Tag)Module->getTag());
8503dac3a9bSDimitry Andric insertDIE(Module, IMDie);
85139d628a0SDimitry Andric DIE *EntityDie;
852ff0cc061SDimitry Andric auto *Entity = resolve(Module->getEntity());
853ff0cc061SDimitry Andric if (auto *NS = dyn_cast<DINamespace>(Entity))
854ff0cc061SDimitry Andric EntityDie = getOrCreateNameSpace(NS);
8553dac3a9bSDimitry Andric else if (auto *M = dyn_cast<DIModule>(Entity))
8563dac3a9bSDimitry Andric EntityDie = getOrCreateModule(M);
857ff0cc061SDimitry Andric else if (auto *SP = dyn_cast<DISubprogram>(Entity))
858ff0cc061SDimitry Andric EntityDie = getOrCreateSubprogramDIE(SP);
859ff0cc061SDimitry Andric else if (auto *T = dyn_cast<DIType>(Entity))
860ff0cc061SDimitry Andric EntityDie = getOrCreateTypeDIE(T);
861ff0cc061SDimitry Andric else if (auto *GV = dyn_cast<DIGlobalVariable>(Entity))
862d88c1a5aSDimitry Andric EntityDie = getOrCreateGlobalVariableDIE(GV, {});
86339d628a0SDimitry Andric else
86439d628a0SDimitry Andric EntityDie = getDIE(Entity);
86539d628a0SDimitry Andric assert(EntityDie);
8664ba319b5SDimitry Andric addSourceLine(*IMDie, Module->getLine(), Module->getFile());
86739d628a0SDimitry Andric addDIEEntry(*IMDie, dwarf::DW_AT_import, *EntityDie);
868ff0cc061SDimitry Andric StringRef Name = Module->getName();
86939d628a0SDimitry Andric if (!Name.empty())
87039d628a0SDimitry Andric addString(*IMDie, dwarf::DW_AT_name, Name);
87139d628a0SDimitry Andric
87239d628a0SDimitry Andric return IMDie;
87339d628a0SDimitry Andric }
87439d628a0SDimitry Andric
finishSubprogramDefinition(const DISubprogram * SP)875ff0cc061SDimitry Andric void DwarfCompileUnit::finishSubprogramDefinition(const DISubprogram *SP) {
87639d628a0SDimitry Andric DIE *D = getDIE(SP);
8775517e702SDimitry Andric if (DIE *AbsSPDIE = getAbstractSPDies().lookup(SP)) {
87839d628a0SDimitry Andric if (D)
87939d628a0SDimitry Andric // If this subprogram has an abstract definition, reference that
88039d628a0SDimitry Andric addDIEEntry(*D, dwarf::DW_AT_abstract_origin, *AbsSPDIE);
88139d628a0SDimitry Andric } else {
882d88c1a5aSDimitry Andric assert(D || includeMinimalInlineScopes());
88339d628a0SDimitry Andric if (D)
88439d628a0SDimitry Andric // And attach the attributes
88539d628a0SDimitry Andric applySubprogramAttributesToDefinition(SP, *D);
88639d628a0SDimitry Andric }
88739d628a0SDimitry Andric }
88839d628a0SDimitry Andric
finishEntityDefinition(const DbgEntity * Entity)889*b5893f02SDimitry Andric void DwarfCompileUnit::finishEntityDefinition(const DbgEntity *Entity) {
890*b5893f02SDimitry Andric DbgEntity *AbsEntity = getExistingAbstractEntity(Entity->getEntity());
891*b5893f02SDimitry Andric
892*b5893f02SDimitry Andric auto *Die = Entity->getDIE();
893*b5893f02SDimitry Andric /// Label may be used to generate DW_AT_low_pc, so put it outside
894*b5893f02SDimitry Andric /// if/else block.
895*b5893f02SDimitry Andric const DbgLabel *Label = nullptr;
896*b5893f02SDimitry Andric if (AbsEntity && AbsEntity->getDIE()) {
897*b5893f02SDimitry Andric addDIEEntry(*Die, dwarf::DW_AT_abstract_origin, *AbsEntity->getDIE());
898*b5893f02SDimitry Andric Label = dyn_cast<const DbgLabel>(Entity);
899*b5893f02SDimitry Andric } else {
900*b5893f02SDimitry Andric if (const DbgVariable *Var = dyn_cast<const DbgVariable>(Entity))
901*b5893f02SDimitry Andric applyVariableAttributes(*Var, *Die);
902*b5893f02SDimitry Andric else if ((Label = dyn_cast<const DbgLabel>(Entity)))
903*b5893f02SDimitry Andric applyLabelAttributes(*Label, *Die);
904*b5893f02SDimitry Andric else
905*b5893f02SDimitry Andric llvm_unreachable("DbgEntity must be DbgVariable or DbgLabel.");
9065517e702SDimitry Andric }
9075517e702SDimitry Andric
908*b5893f02SDimitry Andric if (Label)
909*b5893f02SDimitry Andric if (const auto *Sym = Label->getSymbol())
910*b5893f02SDimitry Andric addLabelAddress(*Die, dwarf::DW_AT_low_pc, Sym);
9115517e702SDimitry Andric }
9125517e702SDimitry Andric
getExistingAbstractEntity(const DINode * Node)913*b5893f02SDimitry Andric DbgEntity *DwarfCompileUnit::getExistingAbstractEntity(const DINode *Node) {
914*b5893f02SDimitry Andric auto &AbstractEntities = getAbstractEntities();
915*b5893f02SDimitry Andric auto I = AbstractEntities.find(Node);
916*b5893f02SDimitry Andric if (I != AbstractEntities.end())
9175517e702SDimitry Andric return I->second.get();
9185517e702SDimitry Andric return nullptr;
9195517e702SDimitry Andric }
9205517e702SDimitry Andric
createAbstractEntity(const DINode * Node,LexicalScope * Scope)921*b5893f02SDimitry Andric void DwarfCompileUnit::createAbstractEntity(const DINode *Node,
9225517e702SDimitry Andric LexicalScope *Scope) {
9235517e702SDimitry Andric assert(Scope && Scope->isAbstractScope());
924*b5893f02SDimitry Andric auto &Entity = getAbstractEntities()[Node];
925*b5893f02SDimitry Andric if (isa<const DILocalVariable>(Node)) {
926*b5893f02SDimitry Andric Entity = llvm::make_unique<DbgVariable>(
927*b5893f02SDimitry Andric cast<const DILocalVariable>(Node), nullptr /* IA */);;
928*b5893f02SDimitry Andric DU->addScopeVariable(Scope, cast<DbgVariable>(Entity.get()));
929*b5893f02SDimitry Andric } else if (isa<const DILabel>(Node)) {
930*b5893f02SDimitry Andric Entity = llvm::make_unique<DbgLabel>(
931*b5893f02SDimitry Andric cast<const DILabel>(Node), nullptr /* IA */);
932*b5893f02SDimitry Andric DU->addScopeLabel(Scope, cast<DbgLabel>(Entity.get()));
933*b5893f02SDimitry Andric }
9345517e702SDimitry Andric }
9355517e702SDimitry Andric
emitHeader(bool UseOffsets)936ff0cc061SDimitry Andric void DwarfCompileUnit::emitHeader(bool UseOffsets) {
93739d628a0SDimitry Andric // Don't bother labeling the .dwo unit, as its offset isn't used.
9384ba319b5SDimitry Andric if (!Skeleton && !DD->useSectionsAsReferences()) {
939ff0cc061SDimitry Andric LabelBegin = Asm->createTempSymbol("cu_begin");
940ff0cc061SDimitry Andric Asm->OutStreamer->EmitLabel(LabelBegin);
941ff0cc061SDimitry Andric }
94239d628a0SDimitry Andric
9437a7e6055SDimitry Andric dwarf::UnitType UT = Skeleton ? dwarf::DW_UT_split_compile
9447a7e6055SDimitry Andric : DD->useSplitDwarf() ? dwarf::DW_UT_skeleton
9457a7e6055SDimitry Andric : dwarf::DW_UT_compile;
9467a7e6055SDimitry Andric DwarfUnit::emitCommonHeader(UseOffsets, UT);
9474ba319b5SDimitry Andric if (DD->getDwarfVersion() >= 5 && UT != dwarf::DW_UT_compile)
9484ba319b5SDimitry Andric Asm->emitInt64(getDWOId());
94939d628a0SDimitry Andric }
95039d628a0SDimitry Andric
hasDwarfPubSections() const9512cab237bSDimitry Andric bool DwarfCompileUnit::hasDwarfPubSections() const {
952*b5893f02SDimitry Andric switch (CUNode->getNameTableKind()) {
953*b5893f02SDimitry Andric case DICompileUnit::DebugNameTableKind::None:
954*b5893f02SDimitry Andric return false;
9552cab237bSDimitry Andric // Opting in to GNU Pubnames/types overrides the default to ensure these are
9562cab237bSDimitry Andric // generated for things like Gold's gdb_index generation.
957*b5893f02SDimitry Andric case DICompileUnit::DebugNameTableKind::GNU:
9582cab237bSDimitry Andric return true;
959*b5893f02SDimitry Andric case DICompileUnit::DebugNameTableKind::Default:
960*b5893f02SDimitry Andric return DD->tuneForGDB() && !includeMinimalInlineScopes() &&
961*b5893f02SDimitry Andric !CUNode->isDebugDirectivesOnly();
962*b5893f02SDimitry Andric }
963*b5893f02SDimitry Andric llvm_unreachable("Unhandled DICompileUnit::DebugNameTableKind enum");
9642cab237bSDimitry Andric }
9652cab237bSDimitry Andric
96639d628a0SDimitry Andric /// addGlobalName - Add a new global name to the compile unit.
addGlobalName(StringRef Name,const DIE & Die,const DIScope * Context)9677a7e6055SDimitry Andric void DwarfCompileUnit::addGlobalName(StringRef Name, const DIE &Die,
968ff0cc061SDimitry Andric const DIScope *Context) {
9692cab237bSDimitry Andric if (!hasDwarfPubSections())
97039d628a0SDimitry Andric return;
97139d628a0SDimitry Andric std::string FullName = getParentContextString(Context) + Name.str();
97239d628a0SDimitry Andric GlobalNames[FullName] = &Die;
97339d628a0SDimitry Andric }
97439d628a0SDimitry Andric
addGlobalNameForTypeUnit(StringRef Name,const DIScope * Context)9757a7e6055SDimitry Andric void DwarfCompileUnit::addGlobalNameForTypeUnit(StringRef Name,
9767a7e6055SDimitry Andric const DIScope *Context) {
9772cab237bSDimitry Andric if (!hasDwarfPubSections())
9787a7e6055SDimitry Andric return;
9797a7e6055SDimitry Andric std::string FullName = getParentContextString(Context) + Name.str();
9807a7e6055SDimitry Andric // Insert, allowing the entry to remain as-is if it's already present
9817a7e6055SDimitry Andric // This way the CU-level type DIE is preferred over the "can't describe this
9827a7e6055SDimitry Andric // type as a unit offset because it's not really in the CU at all, it's only
9837a7e6055SDimitry Andric // in a type unit"
9847a7e6055SDimitry Andric GlobalNames.insert(std::make_pair(std::move(FullName), &getUnitDie()));
9857a7e6055SDimitry Andric }
9867a7e6055SDimitry Andric
98739d628a0SDimitry Andric /// Add a new global type to the unit.
addGlobalType(const DIType * Ty,const DIE & Die,const DIScope * Context)988ff0cc061SDimitry Andric void DwarfCompileUnit::addGlobalType(const DIType *Ty, const DIE &Die,
989ff0cc061SDimitry Andric const DIScope *Context) {
9902cab237bSDimitry Andric if (!hasDwarfPubSections())
99139d628a0SDimitry Andric return;
992ff0cc061SDimitry Andric std::string FullName = getParentContextString(Context) + Ty->getName().str();
99339d628a0SDimitry Andric GlobalTypes[FullName] = &Die;
99439d628a0SDimitry Andric }
99539d628a0SDimitry Andric
addGlobalTypeUnitType(const DIType * Ty,const DIScope * Context)9967a7e6055SDimitry Andric void DwarfCompileUnit::addGlobalTypeUnitType(const DIType *Ty,
9977a7e6055SDimitry Andric const DIScope *Context) {
9982cab237bSDimitry Andric if (!hasDwarfPubSections())
9997a7e6055SDimitry Andric return;
10007a7e6055SDimitry Andric std::string FullName = getParentContextString(Context) + Ty->getName().str();
10017a7e6055SDimitry Andric // Insert, allowing the entry to remain as-is if it's already present
10027a7e6055SDimitry Andric // This way the CU-level type DIE is preferred over the "can't describe this
10037a7e6055SDimitry Andric // type as a unit offset because it's not really in the CU at all, it's only
10047a7e6055SDimitry Andric // in a type unit"
10057a7e6055SDimitry Andric GlobalTypes.insert(std::make_pair(std::move(FullName), &getUnitDie()));
10067a7e6055SDimitry Andric }
10077a7e6055SDimitry Andric
100839d628a0SDimitry Andric /// addVariableAddress - Add DW_AT_location attribute for a
100939d628a0SDimitry Andric /// DbgVariable based on provided MachineLocation.
addVariableAddress(const DbgVariable & DV,DIE & Die,MachineLocation Location)101039d628a0SDimitry Andric void DwarfCompileUnit::addVariableAddress(const DbgVariable &DV, DIE &Die,
101139d628a0SDimitry Andric MachineLocation Location) {
10122cab237bSDimitry Andric // addBlockByrefAddress is obsolete and will be removed soon.
10132cab237bSDimitry Andric // The clang frontend always generates block byref variables with a
10142cab237bSDimitry Andric // complex expression that encodes exactly what addBlockByrefAddress
10152cab237bSDimitry Andric // would do.
10162cab237bSDimitry Andric assert((!DV.isBlockByrefVariable() || DV.hasComplexAddress()) &&
10172cab237bSDimitry Andric "block byref variable without a complex expression");
10183dac3a9bSDimitry Andric if (DV.hasComplexAddress())
101939d628a0SDimitry Andric addComplexAddress(DV, Die, dwarf::DW_AT_location, Location);
102039d628a0SDimitry Andric else
1021ff0cc061SDimitry Andric addAddress(Die, dwarf::DW_AT_location, Location);
102239d628a0SDimitry Andric }
102339d628a0SDimitry Andric
102439d628a0SDimitry Andric /// Add an address attribute to a die based on the location provided.
addAddress(DIE & Die,dwarf::Attribute Attribute,const MachineLocation & Location)102539d628a0SDimitry Andric void DwarfCompileUnit::addAddress(DIE &Die, dwarf::Attribute Attribute,
1026ff0cc061SDimitry Andric const MachineLocation &Location) {
102797bc6c73SDimitry Andric DIELoc *Loc = new (DIEValueAllocator) DIELoc;
10287a7e6055SDimitry Andric DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
10296bc11b14SDimitry Andric if (Location.isIndirect())
10306bc11b14SDimitry Andric DwarfExpr.setMemoryLocationKind();
103139d628a0SDimitry Andric
10322cab237bSDimitry Andric DIExpressionCursor Cursor({});
10337a7e6055SDimitry Andric const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();
10347a7e6055SDimitry Andric if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
103539d628a0SDimitry Andric return;
10367a7e6055SDimitry Andric DwarfExpr.addExpression(std::move(Cursor));
103739d628a0SDimitry Andric
103839d628a0SDimitry Andric // Now attach the location information to the DIE.
10397a7e6055SDimitry Andric addBlock(Die, Attribute, DwarfExpr.finalize());
104039d628a0SDimitry Andric }
104139d628a0SDimitry Andric
104239d628a0SDimitry Andric /// Start with the address based on the location provided, and generate the
104339d628a0SDimitry Andric /// DWARF information necessary to find the actual variable given the extra
104439d628a0SDimitry Andric /// address information encoded in the DbgVariable, starting from the starting
104539d628a0SDimitry Andric /// location. Add the DWARF information to the die.
addComplexAddress(const DbgVariable & DV,DIE & Die,dwarf::Attribute Attribute,const MachineLocation & Location)104639d628a0SDimitry Andric void DwarfCompileUnit::addComplexAddress(const DbgVariable &DV, DIE &Die,
104739d628a0SDimitry Andric dwarf::Attribute Attribute,
104839d628a0SDimitry Andric const MachineLocation &Location) {
104997bc6c73SDimitry Andric DIELoc *Loc = new (DIEValueAllocator) DIELoc;
105039d628a0SDimitry Andric DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
10517a7e6055SDimitry Andric const DIExpression *DIExpr = DV.getSingleExpression();
10527a7e6055SDimitry Andric DwarfExpr.addFragmentOffset(DIExpr);
10536bc11b14SDimitry Andric if (Location.isIndirect())
10546bc11b14SDimitry Andric DwarfExpr.setMemoryLocationKind();
10557a7e6055SDimitry Andric
10562cab237bSDimitry Andric DIExpressionCursor Cursor(DIExpr);
10573ca95b02SDimitry Andric const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();
10587a7e6055SDimitry Andric if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
1059d88c1a5aSDimitry Andric return;
10607a7e6055SDimitry Andric DwarfExpr.addExpression(std::move(Cursor));
106139d628a0SDimitry Andric
106239d628a0SDimitry Andric // Now attach the location information to the DIE.
10637a7e6055SDimitry Andric addBlock(Die, Attribute, DwarfExpr.finalize());
106439d628a0SDimitry Andric }
106539d628a0SDimitry Andric
106639d628a0SDimitry Andric /// Add a Dwarf loclistptr attribute data and value.
addLocationList(DIE & Die,dwarf::Attribute Attribute,unsigned Index)106739d628a0SDimitry Andric void DwarfCompileUnit::addLocationList(DIE &Die, dwarf::Attribute Attribute,
106839d628a0SDimitry Andric unsigned Index) {
106939d628a0SDimitry Andric dwarf::Form Form = DD->getDwarfVersion() >= 4 ? dwarf::DW_FORM_sec_offset
107039d628a0SDimitry Andric : dwarf::DW_FORM_data4;
10713dac3a9bSDimitry Andric Die.addValue(DIEValueAllocator, Attribute, Form, DIELocList(Index));
107239d628a0SDimitry Andric }
107339d628a0SDimitry Andric
applyVariableAttributes(const DbgVariable & Var,DIE & VariableDie)107439d628a0SDimitry Andric void DwarfCompileUnit::applyVariableAttributes(const DbgVariable &Var,
107539d628a0SDimitry Andric DIE &VariableDie) {
107639d628a0SDimitry Andric StringRef Name = Var.getName();
107739d628a0SDimitry Andric if (!Name.empty())
107839d628a0SDimitry Andric addString(VariableDie, dwarf::DW_AT_name, Name);
1079d88c1a5aSDimitry Andric const auto *DIVar = Var.getVariable();
1080d88c1a5aSDimitry Andric if (DIVar)
1081d88c1a5aSDimitry Andric if (uint32_t AlignInBytes = DIVar->getAlignInBytes())
1082d88c1a5aSDimitry Andric addUInt(VariableDie, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,
1083d88c1a5aSDimitry Andric AlignInBytes);
1084d88c1a5aSDimitry Andric
1085d88c1a5aSDimitry Andric addSourceLine(VariableDie, DIVar);
108639d628a0SDimitry Andric addType(VariableDie, Var.getType());
108739d628a0SDimitry Andric if (Var.isArtificial())
108839d628a0SDimitry Andric addFlag(VariableDie, dwarf::DW_AT_artificial);
108939d628a0SDimitry Andric }
109039d628a0SDimitry Andric
applyLabelAttributes(const DbgLabel & Label,DIE & LabelDie)1091*b5893f02SDimitry Andric void DwarfCompileUnit::applyLabelAttributes(const DbgLabel &Label,
1092*b5893f02SDimitry Andric DIE &LabelDie) {
1093*b5893f02SDimitry Andric StringRef Name = Label.getName();
1094*b5893f02SDimitry Andric if (!Name.empty())
1095*b5893f02SDimitry Andric addString(LabelDie, dwarf::DW_AT_name, Name);
1096*b5893f02SDimitry Andric const auto *DILabel = Label.getLabel();
1097*b5893f02SDimitry Andric addSourceLine(LabelDie, DILabel);
1098*b5893f02SDimitry Andric }
1099*b5893f02SDimitry Andric
110039d628a0SDimitry Andric /// Add a Dwarf expression attribute data and value.
addExpr(DIELoc & Die,dwarf::Form Form,const MCExpr * Expr)110139d628a0SDimitry Andric void DwarfCompileUnit::addExpr(DIELoc &Die, dwarf::Form Form,
110239d628a0SDimitry Andric const MCExpr *Expr) {
11033dac3a9bSDimitry Andric Die.addValue(DIEValueAllocator, (dwarf::Attribute)0, Form, DIEExpr(Expr));
110439d628a0SDimitry Andric }
110539d628a0SDimitry Andric
addAddressExpr(DIE & Die,dwarf::Attribute Attribute,const MCExpr * Expr)1106*b5893f02SDimitry Andric void DwarfCompileUnit::addAddressExpr(DIE &Die, dwarf::Attribute Attribute,
1107*b5893f02SDimitry Andric const MCExpr *Expr) {
1108*b5893f02SDimitry Andric Die.addValue(DIEValueAllocator, Attribute, dwarf::DW_FORM_addr,
1109*b5893f02SDimitry Andric DIEExpr(Expr));
1110*b5893f02SDimitry Andric }
1111*b5893f02SDimitry Andric
applySubprogramAttributesToDefinition(const DISubprogram * SP,DIE & SPDie)1112ff0cc061SDimitry Andric void DwarfCompileUnit::applySubprogramAttributesToDefinition(
1113ff0cc061SDimitry Andric const DISubprogram *SP, DIE &SPDie) {
1114ff0cc061SDimitry Andric auto *SPDecl = SP->getDeclaration();
1115ff0cc061SDimitry Andric auto *Context = resolve(SPDecl ? SPDecl->getScope() : SP->getScope());
111639d628a0SDimitry Andric applySubprogramAttributes(SP, SPDie, includeMinimalInlineScopes());
1117ff0cc061SDimitry Andric addGlobalName(SP->getName(), SPDie, Context);
111839d628a0SDimitry Andric }
111939d628a0SDimitry Andric
isDwoUnit() const112039d628a0SDimitry Andric bool DwarfCompileUnit::isDwoUnit() const {
112139d628a0SDimitry Andric return DD->useSplitDwarf() && Skeleton;
112239d628a0SDimitry Andric }
112339d628a0SDimitry Andric
includeMinimalInlineScopes() const112439d628a0SDimitry Andric bool DwarfCompileUnit::includeMinimalInlineScopes() const {
11253ca95b02SDimitry Andric return getCUNode()->getEmissionKind() == DICompileUnit::LineTablesOnly ||
112639d628a0SDimitry Andric (DD->useSplitDwarf() && !Skeleton);
112739d628a0SDimitry Andric }
1128*b5893f02SDimitry Andric
addAddrTableBase()1129*b5893f02SDimitry Andric void DwarfCompileUnit::addAddrTableBase() {
1130*b5893f02SDimitry Andric const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
1131*b5893f02SDimitry Andric MCSymbol *Label = DD->getAddressPool().getLabel();
1132*b5893f02SDimitry Andric addSectionLabel(getUnitDie(),
1133*b5893f02SDimitry Andric getDwarfVersion() >= 5 ? dwarf::DW_AT_addr_base
1134*b5893f02SDimitry Andric : dwarf::DW_AT_GNU_addr_base,
1135*b5893f02SDimitry Andric Label, TLOF.getDwarfAddrSection()->getBeginSymbol());
1136*b5893f02SDimitry Andric }
1137