1f4a2713aSLionel Sambuc #include "DwarfCompileUnit.h"
2*0a6a1f1dSLionel Sambuc #include "DwarfExpression.h"
3*0a6a1f1dSLionel Sambuc #include "llvm/CodeGen/MachineFunction.h"
4f4a2713aSLionel Sambuc #include "llvm/IR/DataLayout.h"
5*0a6a1f1dSLionel Sambuc #include "llvm/IR/GlobalValue.h"
6f4a2713aSLionel Sambuc #include "llvm/IR/GlobalVariable.h"
7*0a6a1f1dSLionel Sambuc #include "llvm/IR/Instruction.h"
8*0a6a1f1dSLionel Sambuc #include "llvm/MC/MCAsmInfo.h"
9f4a2713aSLionel Sambuc #include "llvm/MC/MCStreamer.h"
10f4a2713aSLionel Sambuc #include "llvm/Target/TargetFrameLowering.h"
11f4a2713aSLionel Sambuc #include "llvm/Target/TargetLoweringObjectFile.h"
12*0a6a1f1dSLionel Sambuc #include "llvm/Target/TargetMachine.h"
13f4a2713aSLionel Sambuc #include "llvm/Target/TargetRegisterInfo.h"
14*0a6a1f1dSLionel Sambuc #include "llvm/Target/TargetSubtargetInfo.h"
15f4a2713aSLionel Sambuc
16*0a6a1f1dSLionel Sambuc namespace llvm {
17f4a2713aSLionel Sambuc
DwarfCompileUnit(unsigned UID,DICompileUnit Node,AsmPrinter * A,DwarfDebug * DW,DwarfFile * DWU)18*0a6a1f1dSLionel Sambuc DwarfCompileUnit::DwarfCompileUnit(unsigned UID, DICompileUnit Node,
19*0a6a1f1dSLionel Sambuc AsmPrinter *A, DwarfDebug *DW,
20*0a6a1f1dSLionel Sambuc DwarfFile *DWU)
21*0a6a1f1dSLionel Sambuc : DwarfUnit(UID, dwarf::DW_TAG_compile_unit, Node, A, DW, DWU),
22*0a6a1f1dSLionel Sambuc Skeleton(nullptr), LabelBegin(nullptr), BaseAddress(nullptr) {
23*0a6a1f1dSLionel Sambuc insertDIE(Node, &getUnitDie());
24f4a2713aSLionel Sambuc }
25f4a2713aSLionel Sambuc
26f4a2713aSLionel Sambuc /// addLabelAddress - Add a dwarf label attribute data and value using
27f4a2713aSLionel Sambuc /// DW_FORM_addr or DW_FORM_GNU_addr_index.
28f4a2713aSLionel Sambuc ///
addLabelAddress(DIE & Die,dwarf::Attribute Attribute,const MCSymbol * Label)29*0a6a1f1dSLionel Sambuc void DwarfCompileUnit::addLabelAddress(DIE &Die, dwarf::Attribute Attribute,
30*0a6a1f1dSLionel Sambuc const MCSymbol *Label) {
31*0a6a1f1dSLionel Sambuc
32*0a6a1f1dSLionel Sambuc // Don't use the address pool in non-fission or in the skeleton unit itself.
33*0a6a1f1dSLionel Sambuc // FIXME: Once GDB supports this, it's probably worthwhile using the address
34*0a6a1f1dSLionel Sambuc // pool from the skeleton - maybe even in non-fission (possibly fewer
35*0a6a1f1dSLionel Sambuc // relocations by sharing them in the pool, but we have other ideas about how
36*0a6a1f1dSLionel Sambuc // to reduce the number of relocations as well/instead).
37*0a6a1f1dSLionel Sambuc if (!DD->useSplitDwarf() || !Skeleton)
38*0a6a1f1dSLionel Sambuc return addLocalLabelAddress(Die, Attribute, Label);
39*0a6a1f1dSLionel Sambuc
40f4a2713aSLionel Sambuc if (Label)
41f4a2713aSLionel Sambuc DD->addArangeLabel(SymbolCU(this, Label));
42f4a2713aSLionel Sambuc
43*0a6a1f1dSLionel Sambuc unsigned idx = DD->getAddressPool().getIndex(Label);
44f4a2713aSLionel Sambuc DIEValue *Value = new (DIEValueAllocator) DIEInteger(idx);
45*0a6a1f1dSLionel Sambuc Die.addValue(Attribute, dwarf::DW_FORM_GNU_addr_index, Value);
46f4a2713aSLionel Sambuc }
47f4a2713aSLionel Sambuc
addLocalLabelAddress(DIE & Die,dwarf::Attribute Attribute,const MCSymbol * Label)48*0a6a1f1dSLionel Sambuc void DwarfCompileUnit::addLocalLabelAddress(DIE &Die,
49*0a6a1f1dSLionel Sambuc dwarf::Attribute Attribute,
50*0a6a1f1dSLionel Sambuc const MCSymbol *Label) {
51*0a6a1f1dSLionel Sambuc if (Label)
52*0a6a1f1dSLionel Sambuc DD->addArangeLabel(SymbolCU(this, Label));
53*0a6a1f1dSLionel Sambuc
54*0a6a1f1dSLionel Sambuc Die.addValue(Attribute, dwarf::DW_FORM_addr,
55*0a6a1f1dSLionel Sambuc Label ? (DIEValue *)new (DIEValueAllocator) DIELabel(Label)
56*0a6a1f1dSLionel Sambuc : new (DIEValueAllocator) DIEInteger(0));
57f4a2713aSLionel Sambuc }
58f4a2713aSLionel Sambuc
getOrCreateSourceID(StringRef FileName,StringRef DirName)59*0a6a1f1dSLionel Sambuc unsigned DwarfCompileUnit::getOrCreateSourceID(StringRef FileName,
60*0a6a1f1dSLionel Sambuc StringRef DirName) {
61*0a6a1f1dSLionel Sambuc // If we print assembly, we can't separate .file entries according to
62*0a6a1f1dSLionel Sambuc // compile units. Thus all files will belong to the default compile unit.
63*0a6a1f1dSLionel Sambuc
64*0a6a1f1dSLionel Sambuc // FIXME: add a better feature test than hasRawTextSupport. Even better,
65*0a6a1f1dSLionel Sambuc // extend .file to support this.
66*0a6a1f1dSLionel Sambuc return Asm->OutStreamer.EmitDwarfFileDirective(
67*0a6a1f1dSLionel Sambuc 0, DirName, FileName,
68*0a6a1f1dSLionel Sambuc Asm->OutStreamer.hasRawTextSupport() ? 0 : getUniqueID());
69f4a2713aSLionel Sambuc }
70f4a2713aSLionel Sambuc
71*0a6a1f1dSLionel Sambuc // Return const expression if value is a GEP to access merged global
72*0a6a1f1dSLionel Sambuc // constant. e.g.
73*0a6a1f1dSLionel Sambuc // i8* getelementptr ({ i8, i8, i8, i8 }* @_MergedGlobals, i32 0, i32 0)
getMergedGlobalExpr(const Value * V)74*0a6a1f1dSLionel Sambuc static const ConstantExpr *getMergedGlobalExpr(const Value *V) {
75*0a6a1f1dSLionel Sambuc const ConstantExpr *CE = dyn_cast_or_null<ConstantExpr>(V);
76*0a6a1f1dSLionel Sambuc if (!CE || CE->getNumOperands() != 3 ||
77*0a6a1f1dSLionel Sambuc CE->getOpcode() != Instruction::GetElementPtr)
78*0a6a1f1dSLionel Sambuc return nullptr;
79*0a6a1f1dSLionel Sambuc
80*0a6a1f1dSLionel Sambuc // First operand points to a global struct.
81*0a6a1f1dSLionel Sambuc Value *Ptr = CE->getOperand(0);
82*0a6a1f1dSLionel Sambuc if (!isa<GlobalValue>(Ptr) ||
83*0a6a1f1dSLionel Sambuc !isa<StructType>(cast<PointerType>(Ptr->getType())->getElementType()))
84*0a6a1f1dSLionel Sambuc return nullptr;
85*0a6a1f1dSLionel Sambuc
86*0a6a1f1dSLionel Sambuc // Second operand is zero.
87*0a6a1f1dSLionel Sambuc const ConstantInt *CI = dyn_cast_or_null<ConstantInt>(CE->getOperand(1));
88*0a6a1f1dSLionel Sambuc if (!CI || !CI->isZero())
89*0a6a1f1dSLionel Sambuc return nullptr;
90*0a6a1f1dSLionel Sambuc
91*0a6a1f1dSLionel Sambuc // Third operand is offset.
92*0a6a1f1dSLionel Sambuc if (!isa<ConstantInt>(CE->getOperand(2)))
93*0a6a1f1dSLionel Sambuc return nullptr;
94*0a6a1f1dSLionel Sambuc
95*0a6a1f1dSLionel Sambuc return CE;
96f4a2713aSLionel Sambuc }
97f4a2713aSLionel Sambuc
98*0a6a1f1dSLionel Sambuc /// getOrCreateGlobalVariableDIE - get or create global variable DIE.
getOrCreateGlobalVariableDIE(DIGlobalVariable GV)99*0a6a1f1dSLionel Sambuc DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE(DIGlobalVariable GV) {
100*0a6a1f1dSLionel Sambuc // Check for pre-existence.
101*0a6a1f1dSLionel Sambuc if (DIE *Die = getDIE(GV))
102f4a2713aSLionel Sambuc return Die;
103*0a6a1f1dSLionel Sambuc
104*0a6a1f1dSLionel Sambuc assert(GV.isGlobalVariable());
105*0a6a1f1dSLionel Sambuc
106*0a6a1f1dSLionel Sambuc DIScope GVContext = GV.getContext();
107*0a6a1f1dSLionel Sambuc DIType GTy = DD->resolve(GV.getType());
108*0a6a1f1dSLionel Sambuc
109*0a6a1f1dSLionel Sambuc // Construct the context before querying for the existence of the DIE in
110*0a6a1f1dSLionel Sambuc // case such construction creates the DIE.
111*0a6a1f1dSLionel Sambuc DIE *ContextDIE = getOrCreateContextDIE(GVContext);
112*0a6a1f1dSLionel Sambuc
113*0a6a1f1dSLionel Sambuc // Add to map.
114*0a6a1f1dSLionel Sambuc DIE *VariableDIE = &createAndAddDIE(GV.getTag(), *ContextDIE, GV);
115*0a6a1f1dSLionel Sambuc DIScope DeclContext;
116*0a6a1f1dSLionel Sambuc
117*0a6a1f1dSLionel Sambuc if (DIDerivedType SDMDecl = GV.getStaticDataMemberDeclaration()) {
118*0a6a1f1dSLionel Sambuc DeclContext = resolve(SDMDecl.getContext());
119*0a6a1f1dSLionel Sambuc assert(SDMDecl.isStaticMember() && "Expected static member decl");
120*0a6a1f1dSLionel Sambuc assert(GV.isDefinition());
121*0a6a1f1dSLionel Sambuc // We need the declaration DIE that is in the static member's class.
122*0a6a1f1dSLionel Sambuc DIE *VariableSpecDIE = getOrCreateStaticMemberDIE(SDMDecl);
123*0a6a1f1dSLionel Sambuc addDIEEntry(*VariableDIE, dwarf::DW_AT_specification, *VariableSpecDIE);
124*0a6a1f1dSLionel Sambuc } else {
125*0a6a1f1dSLionel Sambuc DeclContext = GV.getContext();
126*0a6a1f1dSLionel Sambuc // Add name and type.
127*0a6a1f1dSLionel Sambuc addString(*VariableDIE, dwarf::DW_AT_name, GV.getDisplayName());
128*0a6a1f1dSLionel Sambuc addType(*VariableDIE, GTy);
129*0a6a1f1dSLionel Sambuc
130*0a6a1f1dSLionel Sambuc // Add scoping info.
131*0a6a1f1dSLionel Sambuc if (!GV.isLocalToUnit())
132*0a6a1f1dSLionel Sambuc addFlag(*VariableDIE, dwarf::DW_AT_external);
133*0a6a1f1dSLionel Sambuc
134*0a6a1f1dSLionel Sambuc // Add line number info.
135*0a6a1f1dSLionel Sambuc addSourceLine(*VariableDIE, GV);
136f4a2713aSLionel Sambuc }
137f4a2713aSLionel Sambuc
138*0a6a1f1dSLionel Sambuc if (!GV.isDefinition())
139*0a6a1f1dSLionel Sambuc addFlag(*VariableDIE, dwarf::DW_AT_declaration);
140*0a6a1f1dSLionel Sambuc
141*0a6a1f1dSLionel Sambuc // Add location.
142*0a6a1f1dSLionel Sambuc bool addToAccelTable = false;
143*0a6a1f1dSLionel Sambuc bool isGlobalVariable = GV.getGlobal() != nullptr;
144*0a6a1f1dSLionel Sambuc if (isGlobalVariable) {
145*0a6a1f1dSLionel Sambuc addToAccelTable = true;
146*0a6a1f1dSLionel Sambuc DIELoc *Loc = new (DIEValueAllocator) DIELoc();
147*0a6a1f1dSLionel Sambuc const MCSymbol *Sym = Asm->getSymbol(GV.getGlobal());
148*0a6a1f1dSLionel Sambuc if (GV.getGlobal()->isThreadLocal()) {
149*0a6a1f1dSLionel Sambuc // FIXME: Make this work with -gsplit-dwarf.
150*0a6a1f1dSLionel Sambuc unsigned PointerSize = Asm->getDataLayout().getPointerSize();
151*0a6a1f1dSLionel Sambuc assert((PointerSize == 4 || PointerSize == 8) &&
152*0a6a1f1dSLionel Sambuc "Add support for other sizes if necessary");
153*0a6a1f1dSLionel Sambuc // Based on GCC's support for TLS:
154*0a6a1f1dSLionel Sambuc if (!DD->useSplitDwarf()) {
155*0a6a1f1dSLionel Sambuc // 1) Start with a constNu of the appropriate pointer size
156*0a6a1f1dSLionel Sambuc addUInt(*Loc, dwarf::DW_FORM_data1,
157*0a6a1f1dSLionel Sambuc PointerSize == 4 ? dwarf::DW_OP_const4u : dwarf::DW_OP_const8u);
158*0a6a1f1dSLionel Sambuc // 2) containing the (relocated) offset of the TLS variable
159*0a6a1f1dSLionel Sambuc // within the module's TLS block.
160*0a6a1f1dSLionel Sambuc addExpr(*Loc, dwarf::DW_FORM_udata,
161*0a6a1f1dSLionel Sambuc Asm->getObjFileLowering().getDebugThreadLocalSymbol(Sym));
162*0a6a1f1dSLionel Sambuc } else {
163*0a6a1f1dSLionel Sambuc addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_const_index);
164*0a6a1f1dSLionel Sambuc addUInt(*Loc, dwarf::DW_FORM_udata,
165*0a6a1f1dSLionel Sambuc DD->getAddressPool().getIndex(Sym, /* TLS */ true));
166*0a6a1f1dSLionel Sambuc }
167*0a6a1f1dSLionel Sambuc // 3) followed by a custom OP to make the debugger do a TLS lookup.
168*0a6a1f1dSLionel Sambuc addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_push_tls_address);
169*0a6a1f1dSLionel Sambuc } else {
170*0a6a1f1dSLionel Sambuc DD->addArangeLabel(SymbolCU(this, Sym));
171*0a6a1f1dSLionel Sambuc addOpAddress(*Loc, Sym);
172f4a2713aSLionel Sambuc }
173f4a2713aSLionel Sambuc
174*0a6a1f1dSLionel Sambuc addBlock(*VariableDIE, dwarf::DW_AT_location, Loc);
175*0a6a1f1dSLionel Sambuc // Add the linkage name.
176*0a6a1f1dSLionel Sambuc StringRef LinkageName = GV.getLinkageName();
177*0a6a1f1dSLionel Sambuc if (!LinkageName.empty())
178*0a6a1f1dSLionel Sambuc // From DWARF4: DIEs to which DW_AT_linkage_name may apply include:
179*0a6a1f1dSLionel Sambuc // TAG_common_block, TAG_constant, TAG_entry_point, TAG_subprogram and
180*0a6a1f1dSLionel Sambuc // TAG_variable.
181*0a6a1f1dSLionel Sambuc addString(*VariableDIE,
182*0a6a1f1dSLionel Sambuc DD->getDwarfVersion() >= 4 ? dwarf::DW_AT_linkage_name
183*0a6a1f1dSLionel Sambuc : dwarf::DW_AT_MIPS_linkage_name,
184*0a6a1f1dSLionel Sambuc GlobalValue::getRealLinkageName(LinkageName));
185*0a6a1f1dSLionel Sambuc } else if (const ConstantInt *CI =
186*0a6a1f1dSLionel Sambuc dyn_cast_or_null<ConstantInt>(GV.getConstant())) {
187*0a6a1f1dSLionel Sambuc addConstantValue(*VariableDIE, CI, GTy);
188*0a6a1f1dSLionel Sambuc } else if (const ConstantExpr *CE = getMergedGlobalExpr(GV.getConstant())) {
189*0a6a1f1dSLionel Sambuc addToAccelTable = true;
190*0a6a1f1dSLionel Sambuc // GV is a merged global.
191*0a6a1f1dSLionel Sambuc DIELoc *Loc = new (DIEValueAllocator) DIELoc();
192*0a6a1f1dSLionel Sambuc Value *Ptr = CE->getOperand(0);
193*0a6a1f1dSLionel Sambuc MCSymbol *Sym = Asm->getSymbol(cast<GlobalValue>(Ptr));
194*0a6a1f1dSLionel Sambuc DD->addArangeLabel(SymbolCU(this, Sym));
195*0a6a1f1dSLionel Sambuc addOpAddress(*Loc, Sym);
196*0a6a1f1dSLionel Sambuc addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
197*0a6a1f1dSLionel Sambuc SmallVector<Value *, 3> Idx(CE->op_begin() + 1, CE->op_end());
198*0a6a1f1dSLionel Sambuc addUInt(*Loc, dwarf::DW_FORM_udata,
199*0a6a1f1dSLionel Sambuc Asm->getDataLayout().getIndexedOffset(Ptr->getType(), Idx));
200*0a6a1f1dSLionel Sambuc addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
201*0a6a1f1dSLionel Sambuc addBlock(*VariableDIE, dwarf::DW_AT_location, Loc);
202f4a2713aSLionel Sambuc }
203f4a2713aSLionel Sambuc
204*0a6a1f1dSLionel Sambuc if (addToAccelTable) {
205*0a6a1f1dSLionel Sambuc DD->addAccelName(GV.getName(), *VariableDIE);
206f4a2713aSLionel Sambuc
207*0a6a1f1dSLionel Sambuc // If the linkage name is different than the name, go ahead and output
208*0a6a1f1dSLionel Sambuc // that as well into the name table.
209*0a6a1f1dSLionel Sambuc if (GV.getLinkageName() != "" && GV.getName() != GV.getLinkageName())
210*0a6a1f1dSLionel Sambuc DD->addAccelName(GV.getLinkageName(), *VariableDIE);
211f4a2713aSLionel Sambuc }
212f4a2713aSLionel Sambuc
213*0a6a1f1dSLionel Sambuc addGlobalName(GV.getName(), *VariableDIE, DeclContext);
214*0a6a1f1dSLionel Sambuc return VariableDIE;
215f4a2713aSLionel Sambuc }
216f4a2713aSLionel Sambuc
addRange(RangeSpan Range)217*0a6a1f1dSLionel Sambuc void DwarfCompileUnit::addRange(RangeSpan Range) {
218*0a6a1f1dSLionel Sambuc bool SameAsPrevCU = this == DD->getPrevCU();
219*0a6a1f1dSLionel Sambuc DD->setPrevCU(this);
220*0a6a1f1dSLionel Sambuc // If we have no current ranges just add the range and return, otherwise,
221*0a6a1f1dSLionel Sambuc // check the current section and CU against the previous section and CU we
222*0a6a1f1dSLionel Sambuc // emitted into and the subprogram was contained within. If these are the
223*0a6a1f1dSLionel Sambuc // same then extend our current range, otherwise add this as a new range.
224*0a6a1f1dSLionel Sambuc if (CURanges.empty() || !SameAsPrevCU ||
225*0a6a1f1dSLionel Sambuc (&CURanges.back().getEnd()->getSection() !=
226*0a6a1f1dSLionel Sambuc &Range.getEnd()->getSection())) {
227*0a6a1f1dSLionel Sambuc CURanges.push_back(Range);
228f4a2713aSLionel Sambuc return;
229f4a2713aSLionel Sambuc }
230f4a2713aSLionel Sambuc
231*0a6a1f1dSLionel Sambuc CURanges.back().setEnd(Range.getEnd());
232f4a2713aSLionel Sambuc }
233f4a2713aSLionel Sambuc
addSectionLabel(DIE & Die,dwarf::Attribute Attribute,const MCSymbol * Label,const MCSymbol * Sec)234*0a6a1f1dSLionel Sambuc void DwarfCompileUnit::addSectionLabel(DIE &Die, dwarf::Attribute Attribute,
235*0a6a1f1dSLionel Sambuc const MCSymbol *Label,
236*0a6a1f1dSLionel Sambuc const MCSymbol *Sec) {
237*0a6a1f1dSLionel Sambuc if (Asm->MAI->doesDwarfUseRelocationsAcrossSections())
238*0a6a1f1dSLionel Sambuc addLabel(Die, Attribute,
239*0a6a1f1dSLionel Sambuc DD->getDwarfVersion() >= 4 ? dwarf::DW_FORM_sec_offset
240*0a6a1f1dSLionel Sambuc : dwarf::DW_FORM_data4,
241*0a6a1f1dSLionel Sambuc Label);
242*0a6a1f1dSLionel Sambuc else
243*0a6a1f1dSLionel Sambuc addSectionDelta(Die, Attribute, Label, Sec);
244*0a6a1f1dSLionel Sambuc }
245*0a6a1f1dSLionel Sambuc
initStmtList(MCSymbol * DwarfLineSectionSym)246*0a6a1f1dSLionel Sambuc void DwarfCompileUnit::initStmtList(MCSymbol *DwarfLineSectionSym) {
247*0a6a1f1dSLionel Sambuc // Define start line table label for each Compile Unit.
248*0a6a1f1dSLionel Sambuc MCSymbol *LineTableStartSym =
249*0a6a1f1dSLionel Sambuc Asm->OutStreamer.getDwarfLineTableSymbol(getUniqueID());
250*0a6a1f1dSLionel Sambuc
251*0a6a1f1dSLionel Sambuc stmtListIndex = UnitDie.getValues().size();
252*0a6a1f1dSLionel Sambuc
253*0a6a1f1dSLionel Sambuc // DW_AT_stmt_list is a offset of line number information for this
254*0a6a1f1dSLionel Sambuc // compile unit in debug_line section. For split dwarf this is
255*0a6a1f1dSLionel Sambuc // left in the skeleton CU and so not included.
256*0a6a1f1dSLionel Sambuc // The line table entries are not always emitted in assembly, so it
257*0a6a1f1dSLionel Sambuc // is not okay to use line_table_start here.
258*0a6a1f1dSLionel Sambuc addSectionLabel(UnitDie, dwarf::DW_AT_stmt_list, LineTableStartSym,
259*0a6a1f1dSLionel Sambuc DwarfLineSectionSym);
260*0a6a1f1dSLionel Sambuc }
261*0a6a1f1dSLionel Sambuc
applyStmtList(DIE & D)262*0a6a1f1dSLionel Sambuc void DwarfCompileUnit::applyStmtList(DIE &D) {
263*0a6a1f1dSLionel Sambuc D.addValue(dwarf::DW_AT_stmt_list,
264*0a6a1f1dSLionel Sambuc UnitDie.getAbbrev().getData()[stmtListIndex].getForm(),
265*0a6a1f1dSLionel Sambuc UnitDie.getValues()[stmtListIndex]);
266*0a6a1f1dSLionel Sambuc }
267*0a6a1f1dSLionel Sambuc
attachLowHighPC(DIE & D,const MCSymbol * Begin,const MCSymbol * End)268*0a6a1f1dSLionel Sambuc void DwarfCompileUnit::attachLowHighPC(DIE &D, const MCSymbol *Begin,
269*0a6a1f1dSLionel Sambuc const MCSymbol *End) {
270*0a6a1f1dSLionel Sambuc assert(Begin && "Begin label should not be null!");
271*0a6a1f1dSLionel Sambuc assert(End && "End label should not be null!");
272*0a6a1f1dSLionel Sambuc assert(Begin->isDefined() && "Invalid starting label");
273*0a6a1f1dSLionel Sambuc assert(End->isDefined() && "Invalid end label");
274*0a6a1f1dSLionel Sambuc
275*0a6a1f1dSLionel Sambuc addLabelAddress(D, dwarf::DW_AT_low_pc, Begin);
276*0a6a1f1dSLionel Sambuc if (DD->getDwarfVersion() < 4)
277*0a6a1f1dSLionel Sambuc addLabelAddress(D, dwarf::DW_AT_high_pc, End);
278*0a6a1f1dSLionel Sambuc else
279*0a6a1f1dSLionel Sambuc addLabelDelta(D, dwarf::DW_AT_high_pc, End, Begin);
280*0a6a1f1dSLionel Sambuc }
281*0a6a1f1dSLionel Sambuc
282*0a6a1f1dSLionel Sambuc // Find DIE for the given subprogram and attach appropriate DW_AT_low_pc
283*0a6a1f1dSLionel Sambuc // and DW_AT_high_pc attributes. If there are global variables in this
284*0a6a1f1dSLionel Sambuc // scope then create and insert DIEs for these variables.
updateSubprogramScopeDIE(DISubprogram SP)285*0a6a1f1dSLionel Sambuc DIE &DwarfCompileUnit::updateSubprogramScopeDIE(DISubprogram SP) {
286*0a6a1f1dSLionel Sambuc DIE *SPDie = getOrCreateSubprogramDIE(SP, includeMinimalInlineScopes());
287*0a6a1f1dSLionel Sambuc
288*0a6a1f1dSLionel Sambuc attachLowHighPC(*SPDie, DD->getFunctionBeginSym(), DD->getFunctionEndSym());
289*0a6a1f1dSLionel Sambuc if (!DD->getCurrentFunction()->getTarget().Options.DisableFramePointerElim(
290*0a6a1f1dSLionel Sambuc *DD->getCurrentFunction()))
291*0a6a1f1dSLionel Sambuc addFlag(*SPDie, dwarf::DW_AT_APPLE_omit_frame_ptr);
292*0a6a1f1dSLionel Sambuc
293*0a6a1f1dSLionel Sambuc // Only include DW_AT_frame_base in full debug info
294*0a6a1f1dSLionel Sambuc if (!includeMinimalInlineScopes()) {
295*0a6a1f1dSLionel Sambuc const TargetRegisterInfo *RI =
296*0a6a1f1dSLionel Sambuc Asm->TM.getSubtargetImpl()->getRegisterInfo();
297*0a6a1f1dSLionel Sambuc MachineLocation Location(RI->getFrameRegister(*Asm->MF));
298*0a6a1f1dSLionel Sambuc if (RI->isPhysicalRegister(Location.getReg()))
299*0a6a1f1dSLionel Sambuc addAddress(*SPDie, dwarf::DW_AT_frame_base, Location);
300*0a6a1f1dSLionel Sambuc }
301*0a6a1f1dSLionel Sambuc
302*0a6a1f1dSLionel Sambuc // Add name to the name table, we do this here because we're guaranteed
303*0a6a1f1dSLionel Sambuc // to have concrete versions of our DW_TAG_subprogram nodes.
304*0a6a1f1dSLionel Sambuc DD->addSubprogramNames(SP, *SPDie);
305*0a6a1f1dSLionel Sambuc
306*0a6a1f1dSLionel Sambuc return *SPDie;
307*0a6a1f1dSLionel Sambuc }
308*0a6a1f1dSLionel Sambuc
309*0a6a1f1dSLionel Sambuc // Construct a DIE for this scope.
constructScopeDIE(LexicalScope * Scope,SmallVectorImpl<std::unique_ptr<DIE>> & FinalChildren)310*0a6a1f1dSLionel Sambuc void DwarfCompileUnit::constructScopeDIE(
311*0a6a1f1dSLionel Sambuc LexicalScope *Scope, SmallVectorImpl<std::unique_ptr<DIE>> &FinalChildren) {
312*0a6a1f1dSLionel Sambuc if (!Scope || !Scope->getScopeNode())
313f4a2713aSLionel Sambuc return;
314f4a2713aSLionel Sambuc
315*0a6a1f1dSLionel Sambuc DIScope DS(Scope->getScopeNode());
316f4a2713aSLionel Sambuc
317*0a6a1f1dSLionel Sambuc assert((Scope->getInlinedAt() || !DS.isSubprogram()) &&
318*0a6a1f1dSLionel Sambuc "Only handle inlined subprograms here, use "
319*0a6a1f1dSLionel Sambuc "constructSubprogramScopeDIE for non-inlined "
320*0a6a1f1dSLionel Sambuc "subprograms");
321*0a6a1f1dSLionel Sambuc
322*0a6a1f1dSLionel Sambuc SmallVector<std::unique_ptr<DIE>, 8> Children;
323*0a6a1f1dSLionel Sambuc
324*0a6a1f1dSLionel Sambuc // We try to create the scope DIE first, then the children DIEs. This will
325*0a6a1f1dSLionel Sambuc // avoid creating un-used children then removing them later when we find out
326*0a6a1f1dSLionel Sambuc // the scope DIE is null.
327*0a6a1f1dSLionel Sambuc std::unique_ptr<DIE> ScopeDIE;
328*0a6a1f1dSLionel Sambuc if (Scope->getParent() && DS.isSubprogram()) {
329*0a6a1f1dSLionel Sambuc ScopeDIE = constructInlinedScopeDIE(Scope);
330*0a6a1f1dSLionel Sambuc if (!ScopeDIE)
331*0a6a1f1dSLionel Sambuc return;
332*0a6a1f1dSLionel Sambuc // We create children when the scope DIE is not null.
333*0a6a1f1dSLionel Sambuc createScopeChildrenDIE(Scope, Children);
334*0a6a1f1dSLionel Sambuc } else {
335*0a6a1f1dSLionel Sambuc // Early exit when we know the scope DIE is going to be null.
336*0a6a1f1dSLionel Sambuc if (DD->isLexicalScopeDIENull(Scope))
337*0a6a1f1dSLionel Sambuc return;
338*0a6a1f1dSLionel Sambuc
339*0a6a1f1dSLionel Sambuc unsigned ChildScopeCount;
340*0a6a1f1dSLionel Sambuc
341*0a6a1f1dSLionel Sambuc // We create children here when we know the scope DIE is not going to be
342*0a6a1f1dSLionel Sambuc // null and the children will be added to the scope DIE.
343*0a6a1f1dSLionel Sambuc createScopeChildrenDIE(Scope, Children, &ChildScopeCount);
344*0a6a1f1dSLionel Sambuc
345*0a6a1f1dSLionel Sambuc // Skip imported directives in gmlt-like data.
346*0a6a1f1dSLionel Sambuc if (!includeMinimalInlineScopes()) {
347*0a6a1f1dSLionel Sambuc // There is no need to emit empty lexical block DIE.
348*0a6a1f1dSLionel Sambuc for (const auto &E : DD->findImportedEntitiesForScope(DS))
349*0a6a1f1dSLionel Sambuc Children.push_back(
350*0a6a1f1dSLionel Sambuc constructImportedEntityDIE(DIImportedEntity(E.second)));
351*0a6a1f1dSLionel Sambuc }
352*0a6a1f1dSLionel Sambuc
353*0a6a1f1dSLionel Sambuc // If there are only other scopes as children, put them directly in the
354*0a6a1f1dSLionel Sambuc // parent instead, as this scope would serve no purpose.
355*0a6a1f1dSLionel Sambuc if (Children.size() == ChildScopeCount) {
356*0a6a1f1dSLionel Sambuc FinalChildren.insert(FinalChildren.end(),
357*0a6a1f1dSLionel Sambuc std::make_move_iterator(Children.begin()),
358*0a6a1f1dSLionel Sambuc std::make_move_iterator(Children.end()));
359*0a6a1f1dSLionel Sambuc return;
360*0a6a1f1dSLionel Sambuc }
361*0a6a1f1dSLionel Sambuc ScopeDIE = constructLexicalScopeDIE(Scope);
362*0a6a1f1dSLionel Sambuc assert(ScopeDIE && "Scope DIE should not be null.");
363*0a6a1f1dSLionel Sambuc }
364*0a6a1f1dSLionel Sambuc
365*0a6a1f1dSLionel Sambuc // Add children
366*0a6a1f1dSLionel Sambuc for (auto &I : Children)
367*0a6a1f1dSLionel Sambuc ScopeDIE->addChild(std::move(I));
368*0a6a1f1dSLionel Sambuc
369*0a6a1f1dSLionel Sambuc FinalChildren.push_back(std::move(ScopeDIE));
370*0a6a1f1dSLionel Sambuc }
371*0a6a1f1dSLionel Sambuc
addSectionDelta(DIE & Die,dwarf::Attribute Attribute,const MCSymbol * Hi,const MCSymbol * Lo)372*0a6a1f1dSLionel Sambuc void DwarfCompileUnit::addSectionDelta(DIE &Die, dwarf::Attribute Attribute,
373*0a6a1f1dSLionel Sambuc const MCSymbol *Hi, const MCSymbol *Lo) {
374*0a6a1f1dSLionel Sambuc DIEValue *Value = new (DIEValueAllocator) DIEDelta(Hi, Lo);
375*0a6a1f1dSLionel Sambuc Die.addValue(Attribute, DD->getDwarfVersion() >= 4 ? dwarf::DW_FORM_sec_offset
376*0a6a1f1dSLionel Sambuc : dwarf::DW_FORM_data4,
377*0a6a1f1dSLionel Sambuc Value);
378*0a6a1f1dSLionel Sambuc }
379*0a6a1f1dSLionel Sambuc
addScopeRangeList(DIE & ScopeDIE,SmallVector<RangeSpan,2> Range)380*0a6a1f1dSLionel Sambuc void DwarfCompileUnit::addScopeRangeList(DIE &ScopeDIE,
381*0a6a1f1dSLionel Sambuc SmallVector<RangeSpan, 2> Range) {
382*0a6a1f1dSLionel Sambuc // Emit offset in .debug_range as a relocatable label. emitDIE will handle
383*0a6a1f1dSLionel Sambuc // emitting it appropriately.
384*0a6a1f1dSLionel Sambuc auto *RangeSectionSym = DD->getRangeSectionSym();
385*0a6a1f1dSLionel Sambuc
386*0a6a1f1dSLionel Sambuc RangeSpanList List(
387*0a6a1f1dSLionel Sambuc Asm->GetTempSymbol("debug_ranges", DD->getNextRangeNumber()),
388*0a6a1f1dSLionel Sambuc std::move(Range));
389*0a6a1f1dSLionel Sambuc
390*0a6a1f1dSLionel Sambuc // Under fission, ranges are specified by constant offsets relative to the
391*0a6a1f1dSLionel Sambuc // CU's DW_AT_GNU_ranges_base.
392*0a6a1f1dSLionel Sambuc if (isDwoUnit())
393*0a6a1f1dSLionel Sambuc addSectionDelta(ScopeDIE, dwarf::DW_AT_ranges, List.getSym(),
394*0a6a1f1dSLionel Sambuc RangeSectionSym);
395*0a6a1f1dSLionel Sambuc else
396*0a6a1f1dSLionel Sambuc addSectionLabel(ScopeDIE, dwarf::DW_AT_ranges, List.getSym(),
397*0a6a1f1dSLionel Sambuc RangeSectionSym);
398*0a6a1f1dSLionel Sambuc
399*0a6a1f1dSLionel Sambuc // Add the range list to the set of ranges to be emitted.
400*0a6a1f1dSLionel Sambuc (Skeleton ? Skeleton : this)->CURangeLists.push_back(std::move(List));
401*0a6a1f1dSLionel Sambuc }
402*0a6a1f1dSLionel Sambuc
attachRangesOrLowHighPC(DIE & Die,SmallVector<RangeSpan,2> Ranges)403*0a6a1f1dSLionel Sambuc void DwarfCompileUnit::attachRangesOrLowHighPC(
404*0a6a1f1dSLionel Sambuc DIE &Die, SmallVector<RangeSpan, 2> Ranges) {
405*0a6a1f1dSLionel Sambuc if (Ranges.size() == 1) {
406*0a6a1f1dSLionel Sambuc const auto &single = Ranges.front();
407*0a6a1f1dSLionel Sambuc attachLowHighPC(Die, single.getStart(), single.getEnd());
408*0a6a1f1dSLionel Sambuc } else
409*0a6a1f1dSLionel Sambuc addScopeRangeList(Die, std::move(Ranges));
410*0a6a1f1dSLionel Sambuc }
411*0a6a1f1dSLionel Sambuc
attachRangesOrLowHighPC(DIE & Die,const SmallVectorImpl<InsnRange> & Ranges)412*0a6a1f1dSLionel Sambuc void DwarfCompileUnit::attachRangesOrLowHighPC(
413*0a6a1f1dSLionel Sambuc DIE &Die, const SmallVectorImpl<InsnRange> &Ranges) {
414*0a6a1f1dSLionel Sambuc SmallVector<RangeSpan, 2> List;
415*0a6a1f1dSLionel Sambuc List.reserve(Ranges.size());
416*0a6a1f1dSLionel Sambuc for (const InsnRange &R : Ranges)
417*0a6a1f1dSLionel Sambuc List.push_back(RangeSpan(DD->getLabelBeforeInsn(R.first),
418*0a6a1f1dSLionel Sambuc DD->getLabelAfterInsn(R.second)));
419*0a6a1f1dSLionel Sambuc attachRangesOrLowHighPC(Die, std::move(List));
420*0a6a1f1dSLionel Sambuc }
421*0a6a1f1dSLionel Sambuc
422*0a6a1f1dSLionel Sambuc // This scope represents inlined body of a function. Construct DIE to
423*0a6a1f1dSLionel Sambuc // represent this concrete inlined copy of the function.
424*0a6a1f1dSLionel Sambuc std::unique_ptr<DIE>
constructInlinedScopeDIE(LexicalScope * Scope)425*0a6a1f1dSLionel Sambuc DwarfCompileUnit::constructInlinedScopeDIE(LexicalScope *Scope) {
426*0a6a1f1dSLionel Sambuc assert(Scope->getScopeNode());
427*0a6a1f1dSLionel Sambuc DIScope DS(Scope->getScopeNode());
428*0a6a1f1dSLionel Sambuc DISubprogram InlinedSP = getDISubprogram(DS);
429*0a6a1f1dSLionel Sambuc // Find the subprogram's DwarfCompileUnit in the SPMap in case the subprogram
430*0a6a1f1dSLionel Sambuc // was inlined from another compile unit.
431*0a6a1f1dSLionel Sambuc DIE *OriginDIE = DU->getAbstractSPDies()[InlinedSP];
432*0a6a1f1dSLionel Sambuc assert(OriginDIE && "Unable to find original DIE for an inlined subprogram.");
433*0a6a1f1dSLionel Sambuc
434*0a6a1f1dSLionel Sambuc auto ScopeDIE = make_unique<DIE>(dwarf::DW_TAG_inlined_subroutine);
435*0a6a1f1dSLionel Sambuc addDIEEntry(*ScopeDIE, dwarf::DW_AT_abstract_origin, *OriginDIE);
436*0a6a1f1dSLionel Sambuc
437*0a6a1f1dSLionel Sambuc attachRangesOrLowHighPC(*ScopeDIE, Scope->getRanges());
438*0a6a1f1dSLionel Sambuc
439*0a6a1f1dSLionel Sambuc // Add the call site information to the DIE.
440*0a6a1f1dSLionel Sambuc DILocation DL(Scope->getInlinedAt());
441*0a6a1f1dSLionel Sambuc addUInt(*ScopeDIE, dwarf::DW_AT_call_file, None,
442*0a6a1f1dSLionel Sambuc getOrCreateSourceID(DL.getFilename(), DL.getDirectory()));
443*0a6a1f1dSLionel Sambuc addUInt(*ScopeDIE, dwarf::DW_AT_call_line, None, DL.getLineNumber());
444*0a6a1f1dSLionel Sambuc
445*0a6a1f1dSLionel Sambuc // Add name to the name table, we do this here because we're guaranteed
446*0a6a1f1dSLionel Sambuc // to have concrete versions of our DW_TAG_inlined_subprogram nodes.
447*0a6a1f1dSLionel Sambuc DD->addSubprogramNames(InlinedSP, *ScopeDIE);
448*0a6a1f1dSLionel Sambuc
449*0a6a1f1dSLionel Sambuc return ScopeDIE;
450*0a6a1f1dSLionel Sambuc }
451*0a6a1f1dSLionel Sambuc
452*0a6a1f1dSLionel Sambuc // Construct new DW_TAG_lexical_block for this scope and attach
453*0a6a1f1dSLionel Sambuc // DW_AT_low_pc/DW_AT_high_pc labels.
454*0a6a1f1dSLionel Sambuc std::unique_ptr<DIE>
constructLexicalScopeDIE(LexicalScope * Scope)455*0a6a1f1dSLionel Sambuc DwarfCompileUnit::constructLexicalScopeDIE(LexicalScope *Scope) {
456*0a6a1f1dSLionel Sambuc if (DD->isLexicalScopeDIENull(Scope))
457*0a6a1f1dSLionel Sambuc return nullptr;
458*0a6a1f1dSLionel Sambuc
459*0a6a1f1dSLionel Sambuc auto ScopeDIE = make_unique<DIE>(dwarf::DW_TAG_lexical_block);
460*0a6a1f1dSLionel Sambuc if (Scope->isAbstractScope())
461*0a6a1f1dSLionel Sambuc return ScopeDIE;
462*0a6a1f1dSLionel Sambuc
463*0a6a1f1dSLionel Sambuc attachRangesOrLowHighPC(*ScopeDIE, Scope->getRanges());
464*0a6a1f1dSLionel Sambuc
465*0a6a1f1dSLionel Sambuc return ScopeDIE;
466*0a6a1f1dSLionel Sambuc }
467*0a6a1f1dSLionel Sambuc
468*0a6a1f1dSLionel Sambuc /// constructVariableDIE - Construct a DIE for the given DbgVariable.
constructVariableDIE(DbgVariable & DV,bool Abstract)469*0a6a1f1dSLionel Sambuc std::unique_ptr<DIE> DwarfCompileUnit::constructVariableDIE(DbgVariable &DV,
470*0a6a1f1dSLionel Sambuc bool Abstract) {
471*0a6a1f1dSLionel Sambuc auto D = constructVariableDIEImpl(DV, Abstract);
472*0a6a1f1dSLionel Sambuc DV.setDIE(*D);
473*0a6a1f1dSLionel Sambuc return D;
474*0a6a1f1dSLionel Sambuc }
475*0a6a1f1dSLionel Sambuc
476*0a6a1f1dSLionel Sambuc std::unique_ptr<DIE>
constructVariableDIEImpl(const DbgVariable & DV,bool Abstract)477*0a6a1f1dSLionel Sambuc DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV,
478*0a6a1f1dSLionel Sambuc bool Abstract) {
479*0a6a1f1dSLionel Sambuc // Define variable debug information entry.
480*0a6a1f1dSLionel Sambuc auto VariableDie = make_unique<DIE>(DV.getTag());
481*0a6a1f1dSLionel Sambuc
482*0a6a1f1dSLionel Sambuc if (Abstract) {
483*0a6a1f1dSLionel Sambuc applyVariableAttributes(DV, *VariableDie);
484*0a6a1f1dSLionel Sambuc return VariableDie;
485*0a6a1f1dSLionel Sambuc }
486*0a6a1f1dSLionel Sambuc
487*0a6a1f1dSLionel Sambuc // Add variable address.
488*0a6a1f1dSLionel Sambuc
489*0a6a1f1dSLionel Sambuc unsigned Offset = DV.getDotDebugLocOffset();
490*0a6a1f1dSLionel Sambuc if (Offset != ~0U) {
491*0a6a1f1dSLionel Sambuc addLocationList(*VariableDie, dwarf::DW_AT_location, Offset);
492*0a6a1f1dSLionel Sambuc return VariableDie;
493*0a6a1f1dSLionel Sambuc }
494*0a6a1f1dSLionel Sambuc
495*0a6a1f1dSLionel Sambuc // Check if variable is described by a DBG_VALUE instruction.
496*0a6a1f1dSLionel Sambuc if (const MachineInstr *DVInsn = DV.getMInsn()) {
497*0a6a1f1dSLionel Sambuc assert(DVInsn->getNumOperands() == 4);
498*0a6a1f1dSLionel Sambuc if (DVInsn->getOperand(0).isReg()) {
499*0a6a1f1dSLionel Sambuc const MachineOperand RegOp = DVInsn->getOperand(0);
500*0a6a1f1dSLionel Sambuc // If the second operand is an immediate, this is an indirect value.
501*0a6a1f1dSLionel Sambuc if (DVInsn->getOperand(1).isImm()) {
502*0a6a1f1dSLionel Sambuc MachineLocation Location(RegOp.getReg(),
503*0a6a1f1dSLionel Sambuc DVInsn->getOperand(1).getImm());
504*0a6a1f1dSLionel Sambuc addVariableAddress(DV, *VariableDie, Location);
505*0a6a1f1dSLionel Sambuc } else if (RegOp.getReg())
506*0a6a1f1dSLionel Sambuc addVariableAddress(DV, *VariableDie, MachineLocation(RegOp.getReg()));
507*0a6a1f1dSLionel Sambuc } else if (DVInsn->getOperand(0).isImm())
508*0a6a1f1dSLionel Sambuc addConstantValue(*VariableDie, DVInsn->getOperand(0), DV.getType());
509*0a6a1f1dSLionel Sambuc else if (DVInsn->getOperand(0).isFPImm())
510*0a6a1f1dSLionel Sambuc addConstantFPValue(*VariableDie, DVInsn->getOperand(0));
511*0a6a1f1dSLionel Sambuc else if (DVInsn->getOperand(0).isCImm())
512*0a6a1f1dSLionel Sambuc addConstantValue(*VariableDie, DVInsn->getOperand(0).getCImm(),
513*0a6a1f1dSLionel Sambuc DV.getType());
514*0a6a1f1dSLionel Sambuc
515*0a6a1f1dSLionel Sambuc return VariableDie;
516*0a6a1f1dSLionel Sambuc }
517*0a6a1f1dSLionel Sambuc
518*0a6a1f1dSLionel Sambuc // .. else use frame index.
519*0a6a1f1dSLionel Sambuc int FI = DV.getFrameIndex();
520*0a6a1f1dSLionel Sambuc if (FI != ~0) {
521*0a6a1f1dSLionel Sambuc unsigned FrameReg = 0;
522*0a6a1f1dSLionel Sambuc const TargetFrameLowering *TFI =
523*0a6a1f1dSLionel Sambuc Asm->TM.getSubtargetImpl()->getFrameLowering();
524*0a6a1f1dSLionel Sambuc int Offset = TFI->getFrameIndexReference(*Asm->MF, FI, FrameReg);
525*0a6a1f1dSLionel Sambuc MachineLocation Location(FrameReg, Offset);
526*0a6a1f1dSLionel Sambuc addVariableAddress(DV, *VariableDie, Location);
527*0a6a1f1dSLionel Sambuc }
528*0a6a1f1dSLionel Sambuc
529*0a6a1f1dSLionel Sambuc return VariableDie;
530*0a6a1f1dSLionel Sambuc }
531*0a6a1f1dSLionel Sambuc
constructVariableDIE(DbgVariable & DV,const LexicalScope & Scope,DIE * & ObjectPointer)532*0a6a1f1dSLionel Sambuc std::unique_ptr<DIE> DwarfCompileUnit::constructVariableDIE(
533*0a6a1f1dSLionel Sambuc DbgVariable &DV, const LexicalScope &Scope, DIE *&ObjectPointer) {
534*0a6a1f1dSLionel Sambuc auto Var = constructVariableDIE(DV, Scope.isAbstractScope());
535*0a6a1f1dSLionel Sambuc if (DV.isObjectPointer())
536*0a6a1f1dSLionel Sambuc ObjectPointer = Var.get();
537*0a6a1f1dSLionel Sambuc return Var;
538*0a6a1f1dSLionel Sambuc }
539*0a6a1f1dSLionel Sambuc
createScopeChildrenDIE(LexicalScope * Scope,SmallVectorImpl<std::unique_ptr<DIE>> & Children,unsigned * ChildScopeCount)540*0a6a1f1dSLionel Sambuc DIE *DwarfCompileUnit::createScopeChildrenDIE(
541*0a6a1f1dSLionel Sambuc LexicalScope *Scope, SmallVectorImpl<std::unique_ptr<DIE>> &Children,
542*0a6a1f1dSLionel Sambuc unsigned *ChildScopeCount) {
543*0a6a1f1dSLionel Sambuc DIE *ObjectPointer = nullptr;
544*0a6a1f1dSLionel Sambuc
545*0a6a1f1dSLionel Sambuc for (DbgVariable *DV : DU->getScopeVariables().lookup(Scope))
546*0a6a1f1dSLionel Sambuc Children.push_back(constructVariableDIE(*DV, *Scope, ObjectPointer));
547*0a6a1f1dSLionel Sambuc
548*0a6a1f1dSLionel Sambuc unsigned ChildCountWithoutScopes = Children.size();
549*0a6a1f1dSLionel Sambuc
550*0a6a1f1dSLionel Sambuc for (LexicalScope *LS : Scope->getChildren())
551*0a6a1f1dSLionel Sambuc constructScopeDIE(LS, Children);
552*0a6a1f1dSLionel Sambuc
553*0a6a1f1dSLionel Sambuc if (ChildScopeCount)
554*0a6a1f1dSLionel Sambuc *ChildScopeCount = Children.size() - ChildCountWithoutScopes;
555*0a6a1f1dSLionel Sambuc
556*0a6a1f1dSLionel Sambuc return ObjectPointer;
557*0a6a1f1dSLionel Sambuc }
558*0a6a1f1dSLionel Sambuc
constructSubprogramScopeDIE(LexicalScope * Scope)559*0a6a1f1dSLionel Sambuc void DwarfCompileUnit::constructSubprogramScopeDIE(LexicalScope *Scope) {
560*0a6a1f1dSLionel Sambuc assert(Scope && Scope->getScopeNode());
561*0a6a1f1dSLionel Sambuc assert(!Scope->getInlinedAt());
562*0a6a1f1dSLionel Sambuc assert(!Scope->isAbstractScope());
563*0a6a1f1dSLionel Sambuc DISubprogram Sub(Scope->getScopeNode());
564*0a6a1f1dSLionel Sambuc
565*0a6a1f1dSLionel Sambuc assert(Sub.isSubprogram());
566*0a6a1f1dSLionel Sambuc
567*0a6a1f1dSLionel Sambuc DD->getProcessedSPNodes().insert(Sub);
568*0a6a1f1dSLionel Sambuc
569*0a6a1f1dSLionel Sambuc DIE &ScopeDIE = updateSubprogramScopeDIE(Sub);
570*0a6a1f1dSLionel Sambuc
571*0a6a1f1dSLionel Sambuc // If this is a variadic function, add an unspecified parameter.
572*0a6a1f1dSLionel Sambuc DITypeArray FnArgs = Sub.getType().getTypeArray();
573*0a6a1f1dSLionel Sambuc
574*0a6a1f1dSLionel Sambuc // Collect lexical scope children first.
575*0a6a1f1dSLionel Sambuc // ObjectPointer might be a local (non-argument) local variable if it's a
576*0a6a1f1dSLionel Sambuc // block's synthetic this pointer.
577*0a6a1f1dSLionel Sambuc if (DIE *ObjectPointer = createAndAddScopeChildren(Scope, ScopeDIE))
578*0a6a1f1dSLionel Sambuc addDIEEntry(ScopeDIE, dwarf::DW_AT_object_pointer, *ObjectPointer);
579*0a6a1f1dSLionel Sambuc
580*0a6a1f1dSLionel Sambuc // If we have a single element of null, it is a function that returns void.
581*0a6a1f1dSLionel Sambuc // If we have more than one elements and the last one is null, it is a
582*0a6a1f1dSLionel Sambuc // variadic function.
583*0a6a1f1dSLionel Sambuc if (FnArgs.getNumElements() > 1 &&
584*0a6a1f1dSLionel Sambuc !FnArgs.getElement(FnArgs.getNumElements() - 1) &&
585*0a6a1f1dSLionel Sambuc !includeMinimalInlineScopes())
586*0a6a1f1dSLionel Sambuc ScopeDIE.addChild(make_unique<DIE>(dwarf::DW_TAG_unspecified_parameters));
587*0a6a1f1dSLionel Sambuc }
588*0a6a1f1dSLionel Sambuc
createAndAddScopeChildren(LexicalScope * Scope,DIE & ScopeDIE)589*0a6a1f1dSLionel Sambuc DIE *DwarfCompileUnit::createAndAddScopeChildren(LexicalScope *Scope,
590*0a6a1f1dSLionel Sambuc DIE &ScopeDIE) {
591*0a6a1f1dSLionel Sambuc // We create children when the scope DIE is not null.
592*0a6a1f1dSLionel Sambuc SmallVector<std::unique_ptr<DIE>, 8> Children;
593*0a6a1f1dSLionel Sambuc DIE *ObjectPointer = createScopeChildrenDIE(Scope, Children);
594*0a6a1f1dSLionel Sambuc
595*0a6a1f1dSLionel Sambuc // Add children
596*0a6a1f1dSLionel Sambuc for (auto &I : Children)
597*0a6a1f1dSLionel Sambuc ScopeDIE.addChild(std::move(I));
598*0a6a1f1dSLionel Sambuc
599*0a6a1f1dSLionel Sambuc return ObjectPointer;
600*0a6a1f1dSLionel Sambuc }
601*0a6a1f1dSLionel Sambuc
602*0a6a1f1dSLionel Sambuc void
constructAbstractSubprogramScopeDIE(LexicalScope * Scope)603*0a6a1f1dSLionel Sambuc DwarfCompileUnit::constructAbstractSubprogramScopeDIE(LexicalScope *Scope) {
604*0a6a1f1dSLionel Sambuc DIE *&AbsDef = DU->getAbstractSPDies()[Scope->getScopeNode()];
605*0a6a1f1dSLionel Sambuc if (AbsDef)
606*0a6a1f1dSLionel Sambuc return;
607*0a6a1f1dSLionel Sambuc
608*0a6a1f1dSLionel Sambuc DISubprogram SP(Scope->getScopeNode());
609*0a6a1f1dSLionel Sambuc
610*0a6a1f1dSLionel Sambuc DIE *ContextDIE;
611*0a6a1f1dSLionel Sambuc
612*0a6a1f1dSLionel Sambuc if (includeMinimalInlineScopes())
613*0a6a1f1dSLionel Sambuc ContextDIE = &getUnitDie();
614*0a6a1f1dSLionel Sambuc // Some of this is duplicated from DwarfUnit::getOrCreateSubprogramDIE, with
615*0a6a1f1dSLionel Sambuc // the important distinction that the DIDescriptor is not associated with the
616*0a6a1f1dSLionel Sambuc // DIE (since the DIDescriptor will be associated with the concrete DIE, if
617*0a6a1f1dSLionel Sambuc // any). It could be refactored to some common utility function.
618*0a6a1f1dSLionel Sambuc else if (DISubprogram SPDecl = SP.getFunctionDeclaration()) {
619*0a6a1f1dSLionel Sambuc ContextDIE = &getUnitDie();
620*0a6a1f1dSLionel Sambuc getOrCreateSubprogramDIE(SPDecl);
621*0a6a1f1dSLionel Sambuc } else
622*0a6a1f1dSLionel Sambuc ContextDIE = getOrCreateContextDIE(resolve(SP.getContext()));
623*0a6a1f1dSLionel Sambuc
624*0a6a1f1dSLionel Sambuc // Passing null as the associated DIDescriptor because the abstract definition
625*0a6a1f1dSLionel Sambuc // shouldn't be found by lookup.
626*0a6a1f1dSLionel Sambuc AbsDef =
627*0a6a1f1dSLionel Sambuc &createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE, DIDescriptor());
628*0a6a1f1dSLionel Sambuc applySubprogramAttributesToDefinition(SP, *AbsDef);
629*0a6a1f1dSLionel Sambuc
630*0a6a1f1dSLionel Sambuc if (!includeMinimalInlineScopes())
631*0a6a1f1dSLionel Sambuc addUInt(*AbsDef, dwarf::DW_AT_inline, None, dwarf::DW_INL_inlined);
632*0a6a1f1dSLionel Sambuc if (DIE *ObjectPointer = createAndAddScopeChildren(Scope, *AbsDef))
633*0a6a1f1dSLionel Sambuc addDIEEntry(*AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer);
634*0a6a1f1dSLionel Sambuc }
635*0a6a1f1dSLionel Sambuc
636*0a6a1f1dSLionel Sambuc std::unique_ptr<DIE>
constructImportedEntityDIE(const DIImportedEntity & Module)637*0a6a1f1dSLionel Sambuc DwarfCompileUnit::constructImportedEntityDIE(const DIImportedEntity &Module) {
638*0a6a1f1dSLionel Sambuc assert(Module.Verify() &&
639*0a6a1f1dSLionel Sambuc "Use one of the MDNode * overloads to handle invalid metadata");
640*0a6a1f1dSLionel Sambuc std::unique_ptr<DIE> IMDie = make_unique<DIE>((dwarf::Tag)Module.getTag());
641*0a6a1f1dSLionel Sambuc insertDIE(Module, IMDie.get());
642*0a6a1f1dSLionel Sambuc DIE *EntityDie;
643*0a6a1f1dSLionel Sambuc DIDescriptor Entity = resolve(Module.getEntity());
644*0a6a1f1dSLionel Sambuc if (Entity.isNameSpace())
645*0a6a1f1dSLionel Sambuc EntityDie = getOrCreateNameSpace(DINameSpace(Entity));
646*0a6a1f1dSLionel Sambuc else if (Entity.isSubprogram())
647*0a6a1f1dSLionel Sambuc EntityDie = getOrCreateSubprogramDIE(DISubprogram(Entity));
648*0a6a1f1dSLionel Sambuc else if (Entity.isType())
649*0a6a1f1dSLionel Sambuc EntityDie = getOrCreateTypeDIE(DIType(Entity));
650*0a6a1f1dSLionel Sambuc else if (Entity.isGlobalVariable())
651*0a6a1f1dSLionel Sambuc EntityDie = getOrCreateGlobalVariableDIE(DIGlobalVariable(Entity));
652*0a6a1f1dSLionel Sambuc else
653*0a6a1f1dSLionel Sambuc EntityDie = getDIE(Entity);
654*0a6a1f1dSLionel Sambuc assert(EntityDie);
655*0a6a1f1dSLionel Sambuc addSourceLine(*IMDie, Module.getLineNumber(),
656*0a6a1f1dSLionel Sambuc Module.getContext().getFilename(),
657*0a6a1f1dSLionel Sambuc Module.getContext().getDirectory());
658*0a6a1f1dSLionel Sambuc addDIEEntry(*IMDie, dwarf::DW_AT_import, *EntityDie);
659*0a6a1f1dSLionel Sambuc StringRef Name = Module.getName();
660*0a6a1f1dSLionel Sambuc if (!Name.empty())
661*0a6a1f1dSLionel Sambuc addString(*IMDie, dwarf::DW_AT_name, Name);
662*0a6a1f1dSLionel Sambuc
663*0a6a1f1dSLionel Sambuc return IMDie;
664*0a6a1f1dSLionel Sambuc }
665*0a6a1f1dSLionel Sambuc
finishSubprogramDefinition(DISubprogram SP)666*0a6a1f1dSLionel Sambuc void DwarfCompileUnit::finishSubprogramDefinition(DISubprogram SP) {
667*0a6a1f1dSLionel Sambuc DIE *D = getDIE(SP);
668*0a6a1f1dSLionel Sambuc if (DIE *AbsSPDIE = DU->getAbstractSPDies().lookup(SP)) {
669*0a6a1f1dSLionel Sambuc if (D)
670*0a6a1f1dSLionel Sambuc // If this subprogram has an abstract definition, reference that
671*0a6a1f1dSLionel Sambuc addDIEEntry(*D, dwarf::DW_AT_abstract_origin, *AbsSPDIE);
672*0a6a1f1dSLionel Sambuc } else {
673*0a6a1f1dSLionel Sambuc if (!D && !includeMinimalInlineScopes())
674*0a6a1f1dSLionel Sambuc // Lazily construct the subprogram if we didn't see either concrete or
675*0a6a1f1dSLionel Sambuc // inlined versions during codegen. (except in -gmlt ^ where we want
676*0a6a1f1dSLionel Sambuc // to omit these entirely)
677*0a6a1f1dSLionel Sambuc D = getOrCreateSubprogramDIE(SP);
678*0a6a1f1dSLionel Sambuc if (D)
679*0a6a1f1dSLionel Sambuc // And attach the attributes
680*0a6a1f1dSLionel Sambuc applySubprogramAttributesToDefinition(SP, *D);
681*0a6a1f1dSLionel Sambuc }
682*0a6a1f1dSLionel Sambuc }
collectDeadVariables(DISubprogram SP)683*0a6a1f1dSLionel Sambuc void DwarfCompileUnit::collectDeadVariables(DISubprogram SP) {
684*0a6a1f1dSLionel Sambuc assert(SP.isSubprogram() && "CU's subprogram list contains a non-subprogram");
685*0a6a1f1dSLionel Sambuc assert(SP.isDefinition() &&
686*0a6a1f1dSLionel Sambuc "CU's subprogram list contains a subprogram declaration");
687*0a6a1f1dSLionel Sambuc DIArray Variables = SP.getVariables();
688*0a6a1f1dSLionel Sambuc if (Variables.getNumElements() == 0)
689*0a6a1f1dSLionel Sambuc return;
690*0a6a1f1dSLionel Sambuc
691*0a6a1f1dSLionel Sambuc DIE *SPDIE = DU->getAbstractSPDies().lookup(SP);
692*0a6a1f1dSLionel Sambuc if (!SPDIE)
693*0a6a1f1dSLionel Sambuc SPDIE = getDIE(SP);
694*0a6a1f1dSLionel Sambuc assert(SPDIE);
695*0a6a1f1dSLionel Sambuc for (unsigned vi = 0, ve = Variables.getNumElements(); vi != ve; ++vi) {
696*0a6a1f1dSLionel Sambuc DIVariable DV(Variables.getElement(vi));
697*0a6a1f1dSLionel Sambuc assert(DV.isVariable());
698*0a6a1f1dSLionel Sambuc DbgVariable NewVar(DV, DIExpression(nullptr), DD);
699*0a6a1f1dSLionel Sambuc auto VariableDie = constructVariableDIE(NewVar);
700*0a6a1f1dSLionel Sambuc applyVariableAttributes(NewVar, *VariableDie);
701*0a6a1f1dSLionel Sambuc SPDIE->addChild(std::move(VariableDie));
702*0a6a1f1dSLionel Sambuc }
703*0a6a1f1dSLionel Sambuc }
704*0a6a1f1dSLionel Sambuc
emitHeader(const MCSymbol * ASectionSym) const705*0a6a1f1dSLionel Sambuc void DwarfCompileUnit::emitHeader(const MCSymbol *ASectionSym) const {
706*0a6a1f1dSLionel Sambuc // Don't bother labeling the .dwo unit, as its offset isn't used.
707*0a6a1f1dSLionel Sambuc if (!Skeleton)
708*0a6a1f1dSLionel Sambuc Asm->OutStreamer.EmitLabel(LabelBegin);
709*0a6a1f1dSLionel Sambuc
710*0a6a1f1dSLionel Sambuc DwarfUnit::emitHeader(ASectionSym);
711*0a6a1f1dSLionel Sambuc }
712*0a6a1f1dSLionel Sambuc
713*0a6a1f1dSLionel Sambuc /// addGlobalName - Add a new global name to the compile unit.
addGlobalName(StringRef Name,DIE & Die,DIScope Context)714*0a6a1f1dSLionel Sambuc void DwarfCompileUnit::addGlobalName(StringRef Name, DIE &Die,
715*0a6a1f1dSLionel Sambuc DIScope Context) {
716*0a6a1f1dSLionel Sambuc if (includeMinimalInlineScopes())
717*0a6a1f1dSLionel Sambuc return;
718*0a6a1f1dSLionel Sambuc std::string FullName = getParentContextString(Context) + Name.str();
719*0a6a1f1dSLionel Sambuc GlobalNames[FullName] = &Die;
720*0a6a1f1dSLionel Sambuc }
721*0a6a1f1dSLionel Sambuc
722*0a6a1f1dSLionel Sambuc /// Add a new global type to the unit.
addGlobalType(DIType Ty,const DIE & Die,DIScope Context)723*0a6a1f1dSLionel Sambuc void DwarfCompileUnit::addGlobalType(DIType Ty, const DIE &Die,
724*0a6a1f1dSLionel Sambuc DIScope Context) {
725*0a6a1f1dSLionel Sambuc if (includeMinimalInlineScopes())
726*0a6a1f1dSLionel Sambuc return;
727*0a6a1f1dSLionel Sambuc std::string FullName = getParentContextString(Context) + Ty.getName().str();
728*0a6a1f1dSLionel Sambuc GlobalTypes[FullName] = &Die;
729f4a2713aSLionel Sambuc }
730f4a2713aSLionel Sambuc
731f4a2713aSLionel Sambuc /// addVariableAddress - Add DW_AT_location attribute for a
732f4a2713aSLionel Sambuc /// DbgVariable based on provided MachineLocation.
addVariableAddress(const DbgVariable & DV,DIE & Die,MachineLocation Location)733*0a6a1f1dSLionel Sambuc void DwarfCompileUnit::addVariableAddress(const DbgVariable &DV, DIE &Die,
734f4a2713aSLionel Sambuc MachineLocation Location) {
735f4a2713aSLionel Sambuc if (DV.variableHasComplexAddress())
736f4a2713aSLionel Sambuc addComplexAddress(DV, Die, dwarf::DW_AT_location, Location);
737f4a2713aSLionel Sambuc else if (DV.isBlockByrefVariable())
738f4a2713aSLionel Sambuc addBlockByrefAddress(DV, Die, dwarf::DW_AT_location, Location);
739f4a2713aSLionel Sambuc else
740f4a2713aSLionel Sambuc addAddress(Die, dwarf::DW_AT_location, Location,
741f4a2713aSLionel Sambuc DV.getVariable().isIndirect());
742f4a2713aSLionel Sambuc }
743f4a2713aSLionel Sambuc
744*0a6a1f1dSLionel Sambuc /// Add an address attribute to a die based on the location provided.
addAddress(DIE & Die,dwarf::Attribute Attribute,const MachineLocation & Location,bool Indirect)745*0a6a1f1dSLionel Sambuc void DwarfCompileUnit::addAddress(DIE &Die, dwarf::Attribute Attribute,
746*0a6a1f1dSLionel Sambuc const MachineLocation &Location,
747*0a6a1f1dSLionel Sambuc bool Indirect) {
748*0a6a1f1dSLionel Sambuc DIELoc *Loc = new (DIEValueAllocator) DIELoc();
749f4a2713aSLionel Sambuc
750*0a6a1f1dSLionel Sambuc bool validReg;
751f4a2713aSLionel Sambuc if (Location.isReg() && !Indirect)
752*0a6a1f1dSLionel Sambuc validReg = addRegisterOpPiece(*Loc, Location.getReg());
753*0a6a1f1dSLionel Sambuc else
754*0a6a1f1dSLionel Sambuc validReg = addRegisterOffset(*Loc, Location.getReg(), Location.getOffset());
755*0a6a1f1dSLionel Sambuc
756*0a6a1f1dSLionel Sambuc if (!validReg)
757*0a6a1f1dSLionel Sambuc return;
758*0a6a1f1dSLionel Sambuc
759*0a6a1f1dSLionel Sambuc if (!Location.isReg() && Indirect)
760*0a6a1f1dSLionel Sambuc addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
761f4a2713aSLionel Sambuc
762f4a2713aSLionel Sambuc // Now attach the location information to the DIE.
763*0a6a1f1dSLionel Sambuc addBlock(Die, Attribute, Loc);
764f4a2713aSLionel Sambuc }
765f4a2713aSLionel Sambuc
766*0a6a1f1dSLionel Sambuc /// Start with the address based on the location provided, and generate the
767*0a6a1f1dSLionel Sambuc /// DWARF information necessary to find the actual variable given the extra
768*0a6a1f1dSLionel Sambuc /// address information encoded in the DbgVariable, starting from the starting
769*0a6a1f1dSLionel Sambuc /// location. Add the DWARF information to the die.
addComplexAddress(const DbgVariable & DV,DIE & Die,dwarf::Attribute Attribute,const MachineLocation & Location)770*0a6a1f1dSLionel Sambuc void DwarfCompileUnit::addComplexAddress(const DbgVariable &DV, DIE &Die,
771f4a2713aSLionel Sambuc dwarf::Attribute Attribute,
772f4a2713aSLionel Sambuc const MachineLocation &Location) {
773*0a6a1f1dSLionel Sambuc DIELoc *Loc = new (DIEValueAllocator) DIELoc();
774*0a6a1f1dSLionel Sambuc DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
775*0a6a1f1dSLionel Sambuc DIExpression Expr = DV.getExpression();
776*0a6a1f1dSLionel Sambuc if (Location.getOffset()) {
777*0a6a1f1dSLionel Sambuc if (DwarfExpr.AddMachineRegIndirect(Location.getReg(),
778*0a6a1f1dSLionel Sambuc Location.getOffset())) {
779*0a6a1f1dSLionel Sambuc DwarfExpr.AddExpression(Expr);
780*0a6a1f1dSLionel Sambuc assert(!DV.getVariable().isIndirect()
781*0a6a1f1dSLionel Sambuc && "double indirection not handled");
782*0a6a1f1dSLionel Sambuc }
783*0a6a1f1dSLionel Sambuc } else {
784*0a6a1f1dSLionel Sambuc if (DwarfExpr.AddMachineRegExpression(Expr, Location.getReg()))
785*0a6a1f1dSLionel Sambuc if (DV.getVariable().isIndirect())
786*0a6a1f1dSLionel Sambuc DwarfExpr.EmitOp(dwarf::DW_OP_deref);
787f4a2713aSLionel Sambuc }
788f4a2713aSLionel Sambuc
789f4a2713aSLionel Sambuc // Now attach the location information to the DIE.
790*0a6a1f1dSLionel Sambuc addBlock(Die, Attribute, Loc);
791f4a2713aSLionel Sambuc }
792f4a2713aSLionel Sambuc
793*0a6a1f1dSLionel Sambuc /// Add a Dwarf loclistptr attribute data and value.
addLocationList(DIE & Die,dwarf::Attribute Attribute,unsigned Index)794*0a6a1f1dSLionel Sambuc void DwarfCompileUnit::addLocationList(DIE &Die, dwarf::Attribute Attribute,
795*0a6a1f1dSLionel Sambuc unsigned Index) {
796*0a6a1f1dSLionel Sambuc DIEValue *Value = new (DIEValueAllocator) DIELocList(Index);
797*0a6a1f1dSLionel Sambuc dwarf::Form Form = DD->getDwarfVersion() >= 4 ? dwarf::DW_FORM_sec_offset
798*0a6a1f1dSLionel Sambuc : dwarf::DW_FORM_data4;
799*0a6a1f1dSLionel Sambuc Die.addValue(Attribute, Form, Value);
800f4a2713aSLionel Sambuc }
801f4a2713aSLionel Sambuc
applyVariableAttributes(const DbgVariable & Var,DIE & VariableDie)802*0a6a1f1dSLionel Sambuc void DwarfCompileUnit::applyVariableAttributes(const DbgVariable &Var,
803*0a6a1f1dSLionel Sambuc DIE &VariableDie) {
804*0a6a1f1dSLionel Sambuc StringRef Name = Var.getName();
805f4a2713aSLionel Sambuc if (!Name.empty())
806f4a2713aSLionel Sambuc addString(VariableDie, dwarf::DW_AT_name, Name);
807*0a6a1f1dSLionel Sambuc addSourceLine(VariableDie, Var.getVariable());
808*0a6a1f1dSLionel Sambuc addType(VariableDie, Var.getType());
809*0a6a1f1dSLionel Sambuc if (Var.isArtificial())
810f4a2713aSLionel Sambuc addFlag(VariableDie, dwarf::DW_AT_artificial);
811f4a2713aSLionel Sambuc }
812f4a2713aSLionel Sambuc
813*0a6a1f1dSLionel Sambuc /// Add a Dwarf expression attribute data and value.
addExpr(DIELoc & Die,dwarf::Form Form,const MCExpr * Expr)814*0a6a1f1dSLionel Sambuc void DwarfCompileUnit::addExpr(DIELoc &Die, dwarf::Form Form,
815*0a6a1f1dSLionel Sambuc const MCExpr *Expr) {
816*0a6a1f1dSLionel Sambuc DIEValue *Value = new (DIEValueAllocator) DIEExpr(Expr);
817*0a6a1f1dSLionel Sambuc Die.addValue((dwarf::Attribute)0, Form, Value);
818f4a2713aSLionel Sambuc }
819f4a2713aSLionel Sambuc
applySubprogramAttributesToDefinition(DISubprogram SP,DIE & SPDie)820*0a6a1f1dSLionel Sambuc void DwarfCompileUnit::applySubprogramAttributesToDefinition(DISubprogram SP,
821*0a6a1f1dSLionel Sambuc DIE &SPDie) {
822*0a6a1f1dSLionel Sambuc DISubprogram SPDecl = SP.getFunctionDeclaration();
823*0a6a1f1dSLionel Sambuc DIScope Context = resolve(SPDecl ? SPDecl.getContext() : SP.getContext());
824*0a6a1f1dSLionel Sambuc applySubprogramAttributes(SP, SPDie, includeMinimalInlineScopes());
825*0a6a1f1dSLionel Sambuc addGlobalName(SP.getName(), SPDie, Context);
826f4a2713aSLionel Sambuc }
827f4a2713aSLionel Sambuc
isDwoUnit() const828*0a6a1f1dSLionel Sambuc bool DwarfCompileUnit::isDwoUnit() const {
829*0a6a1f1dSLionel Sambuc return DD->useSplitDwarf() && Skeleton;
830f4a2713aSLionel Sambuc }
831f4a2713aSLionel Sambuc
includeMinimalInlineScopes() const832*0a6a1f1dSLionel Sambuc bool DwarfCompileUnit::includeMinimalInlineScopes() const {
833*0a6a1f1dSLionel Sambuc return getCUNode().getEmissionKind() == DIBuilder::LineTablesOnly ||
834*0a6a1f1dSLionel Sambuc (DD->useSplitDwarf() && !Skeleton);
835f4a2713aSLionel Sambuc }
836*0a6a1f1dSLionel Sambuc } // end llvm namespace
837