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