File: | lib/CodeGen/AsmPrinter/DwarfUnit.cpp |
Warning: | line 502, column 36 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===-- llvm/CodeGen/DwarfUnit.cpp - Dwarf Type and Compile Units ---------===// | |||
2 | // | |||
3 | // The LLVM Compiler Infrastructure | |||
4 | // | |||
5 | // This file is distributed under the University of Illinois Open Source | |||
6 | // License. See LICENSE.TXT for details. | |||
7 | // | |||
8 | //===----------------------------------------------------------------------===// | |||
9 | // | |||
10 | // This file contains support for constructing a dwarf compile unit. | |||
11 | // | |||
12 | //===----------------------------------------------------------------------===// | |||
13 | ||||
14 | #include "DwarfUnit.h" | |||
15 | #include "AddressPool.h" | |||
16 | #include "DwarfCompileUnit.h" | |||
17 | #include "DwarfDebug.h" | |||
18 | #include "DwarfExpression.h" | |||
19 | #include "llvm/ADT/APFloat.h" | |||
20 | #include "llvm/ADT/APInt.h" | |||
21 | #include "llvm/ADT/None.h" | |||
22 | #include "llvm/ADT/StringExtras.h" | |||
23 | #include "llvm/ADT/iterator_range.h" | |||
24 | #include "llvm/CodeGen/MachineFunction.h" | |||
25 | #include "llvm/CodeGen/MachineOperand.h" | |||
26 | #include "llvm/CodeGen/TargetRegisterInfo.h" | |||
27 | #include "llvm/CodeGen/TargetSubtargetInfo.h" | |||
28 | #include "llvm/IR/Constants.h" | |||
29 | #include "llvm/IR/DataLayout.h" | |||
30 | #include "llvm/IR/GlobalValue.h" | |||
31 | #include "llvm/IR/Metadata.h" | |||
32 | #include "llvm/MC/MCAsmInfo.h" | |||
33 | #include "llvm/MC/MCContext.h" | |||
34 | #include "llvm/MC/MCDwarf.h" | |||
35 | #include "llvm/MC/MCSection.h" | |||
36 | #include "llvm/MC/MCStreamer.h" | |||
37 | #include "llvm/MC/MachineLocation.h" | |||
38 | #include "llvm/Support/Casting.h" | |||
39 | #include "llvm/Support/CommandLine.h" | |||
40 | #include "llvm/Target/TargetLoweringObjectFile.h" | |||
41 | #include <cassert> | |||
42 | #include <cstdint> | |||
43 | #include <string> | |||
44 | #include <utility> | |||
45 | ||||
46 | using namespace llvm; | |||
47 | ||||
48 | #define DEBUG_TYPE"dwarfdebug" "dwarfdebug" | |||
49 | ||||
50 | DIEDwarfExpression::DIEDwarfExpression(const AsmPrinter &AP, DwarfUnit &DU, | |||
51 | DIELoc &DIE) | |||
52 | : DwarfExpression(AP.getDwarfVersion()), AP(AP), DU(DU), | |||
53 | DIE(DIE) {} | |||
54 | ||||
55 | void DIEDwarfExpression::emitOp(uint8_t Op, const char* Comment) { | |||
56 | DU.addUInt(DIE, dwarf::DW_FORM_data1, Op); | |||
57 | } | |||
58 | ||||
59 | void DIEDwarfExpression::emitSigned(int64_t Value) { | |||
60 | DU.addSInt(DIE, dwarf::DW_FORM_sdata, Value); | |||
61 | } | |||
62 | ||||
63 | void DIEDwarfExpression::emitUnsigned(uint64_t Value) { | |||
64 | DU.addUInt(DIE, dwarf::DW_FORM_udata, Value); | |||
65 | } | |||
66 | ||||
67 | bool DIEDwarfExpression::isFrameRegister(const TargetRegisterInfo &TRI, | |||
68 | unsigned MachineReg) { | |||
69 | return MachineReg == TRI.getFrameRegister(*AP.MF); | |||
70 | } | |||
71 | ||||
72 | DwarfUnit::DwarfUnit(dwarf::Tag UnitTag, const DICompileUnit *Node, | |||
73 | AsmPrinter *A, DwarfDebug *DW, DwarfFile *DWU) | |||
74 | : DIEUnit(A->getDwarfVersion(), A->MAI->getCodePointerSize(), UnitTag), | |||
75 | CUNode(Node), Asm(A), DD(DW), DU(DWU), IndexTyDie(nullptr) { | |||
76 | } | |||
77 | ||||
78 | DwarfTypeUnit::DwarfTypeUnit(DwarfCompileUnit &CU, AsmPrinter *A, | |||
79 | DwarfDebug *DW, DwarfFile *DWU, | |||
80 | MCDwarfDwoLineTable *SplitLineTable) | |||
81 | : DwarfUnit(dwarf::DW_TAG_type_unit, CU.getCUNode(), A, DW, DWU), CU(CU), | |||
82 | SplitLineTable(SplitLineTable) { | |||
83 | } | |||
84 | ||||
85 | DwarfUnit::~DwarfUnit() { | |||
86 | for (unsigned j = 0, M = DIEBlocks.size(); j < M; ++j) | |||
87 | DIEBlocks[j]->~DIEBlock(); | |||
88 | for (unsigned j = 0, M = DIELocs.size(); j < M; ++j) | |||
89 | DIELocs[j]->~DIELoc(); | |||
90 | } | |||
91 | ||||
92 | int64_t DwarfUnit::getDefaultLowerBound() const { | |||
93 | switch (getLanguage()) { | |||
94 | default: | |||
95 | break; | |||
96 | ||||
97 | // The languages below have valid values in all DWARF versions. | |||
98 | case dwarf::DW_LANG_C: | |||
99 | case dwarf::DW_LANG_C89: | |||
100 | case dwarf::DW_LANG_C_plus_plus: | |||
101 | return 0; | |||
102 | ||||
103 | case dwarf::DW_LANG_Fortran77: | |||
104 | case dwarf::DW_LANG_Fortran90: | |||
105 | return 1; | |||
106 | ||||
107 | // The languages below have valid values only if the DWARF version >= 3. | |||
108 | case dwarf::DW_LANG_C99: | |||
109 | case dwarf::DW_LANG_ObjC: | |||
110 | case dwarf::DW_LANG_ObjC_plus_plus: | |||
111 | if (DD->getDwarfVersion() >= 3) | |||
112 | return 0; | |||
113 | break; | |||
114 | ||||
115 | case dwarf::DW_LANG_Fortran95: | |||
116 | if (DD->getDwarfVersion() >= 3) | |||
117 | return 1; | |||
118 | break; | |||
119 | ||||
120 | // Starting with DWARF v4, all defined languages have valid values. | |||
121 | case dwarf::DW_LANG_D: | |||
122 | case dwarf::DW_LANG_Java: | |||
123 | case dwarf::DW_LANG_Python: | |||
124 | case dwarf::DW_LANG_UPC: | |||
125 | if (DD->getDwarfVersion() >= 4) | |||
126 | return 0; | |||
127 | break; | |||
128 | ||||
129 | case dwarf::DW_LANG_Ada83: | |||
130 | case dwarf::DW_LANG_Ada95: | |||
131 | case dwarf::DW_LANG_Cobol74: | |||
132 | case dwarf::DW_LANG_Cobol85: | |||
133 | case dwarf::DW_LANG_Modula2: | |||
134 | case dwarf::DW_LANG_Pascal83: | |||
135 | case dwarf::DW_LANG_PLI: | |||
136 | if (DD->getDwarfVersion() >= 4) | |||
137 | return 1; | |||
138 | break; | |||
139 | ||||
140 | // The languages below are new in DWARF v5. | |||
141 | case dwarf::DW_LANG_BLISS: | |||
142 | case dwarf::DW_LANG_C11: | |||
143 | case dwarf::DW_LANG_C_plus_plus_03: | |||
144 | case dwarf::DW_LANG_C_plus_plus_11: | |||
145 | case dwarf::DW_LANG_C_plus_plus_14: | |||
146 | case dwarf::DW_LANG_Dylan: | |||
147 | case dwarf::DW_LANG_Go: | |||
148 | case dwarf::DW_LANG_Haskell: | |||
149 | case dwarf::DW_LANG_OCaml: | |||
150 | case dwarf::DW_LANG_OpenCL: | |||
151 | case dwarf::DW_LANG_RenderScript: | |||
152 | case dwarf::DW_LANG_Rust: | |||
153 | case dwarf::DW_LANG_Swift: | |||
154 | if (DD->getDwarfVersion() >= 5) | |||
155 | return 0; | |||
156 | break; | |||
157 | ||||
158 | case dwarf::DW_LANG_Fortran03: | |||
159 | case dwarf::DW_LANG_Fortran08: | |||
160 | case dwarf::DW_LANG_Julia: | |||
161 | case dwarf::DW_LANG_Modula3: | |||
162 | if (DD->getDwarfVersion() >= 5) | |||
163 | return 1; | |||
164 | break; | |||
165 | } | |||
166 | ||||
167 | return -1; | |||
168 | } | |||
169 | ||||
170 | /// Check whether the DIE for this MDNode can be shared across CUs. | |||
171 | bool DwarfUnit::isShareableAcrossCUs(const DINode *D) const { | |||
172 | // When the MDNode can be part of the type system, the DIE can be shared | |||
173 | // across CUs. | |||
174 | // Combining type units and cross-CU DIE sharing is lower value (since | |||
175 | // cross-CU DIE sharing is used in LTO and removes type redundancy at that | |||
176 | // level already) but may be implementable for some value in projects | |||
177 | // building multiple independent libraries with LTO and then linking those | |||
178 | // together. | |||
179 | if (isDwoUnit() && !DD->shareAcrossDWOCUs()) | |||
180 | return false; | |||
181 | return (isa<DIType>(D) || | |||
182 | (isa<DISubprogram>(D) && !cast<DISubprogram>(D)->isDefinition())) && | |||
183 | !DD->generateTypeUnits(); | |||
184 | } | |||
185 | ||||
186 | DIE *DwarfUnit::getDIE(const DINode *D) const { | |||
187 | if (isShareableAcrossCUs(D)) | |||
188 | return DU->getDIE(D); | |||
189 | return MDNodeToDieMap.lookup(D); | |||
190 | } | |||
191 | ||||
192 | void DwarfUnit::insertDIE(const DINode *Desc, DIE *D) { | |||
193 | if (isShareableAcrossCUs(Desc)) { | |||
194 | DU->insertDIE(Desc, D); | |||
195 | return; | |||
196 | } | |||
197 | MDNodeToDieMap.insert(std::make_pair(Desc, D)); | |||
198 | } | |||
199 | ||||
200 | void DwarfUnit::addFlag(DIE &Die, dwarf::Attribute Attribute) { | |||
201 | if (DD->getDwarfVersion() >= 4) | |||
202 | Die.addValue(DIEValueAllocator, Attribute, dwarf::DW_FORM_flag_present, | |||
203 | DIEInteger(1)); | |||
204 | else | |||
205 | Die.addValue(DIEValueAllocator, Attribute, dwarf::DW_FORM_flag, | |||
206 | DIEInteger(1)); | |||
207 | } | |||
208 | ||||
209 | void DwarfUnit::addUInt(DIEValueList &Die, dwarf::Attribute Attribute, | |||
210 | Optional<dwarf::Form> Form, uint64_t Integer) { | |||
211 | if (!Form) | |||
212 | Form = DIEInteger::BestForm(false, Integer); | |||
213 | assert(Form != dwarf::DW_FORM_implicit_const &&(static_cast <bool> (Form != dwarf::DW_FORM_implicit_const && "DW_FORM_implicit_const is used only for signed integers" ) ? void (0) : __assert_fail ("Form != dwarf::DW_FORM_implicit_const && \"DW_FORM_implicit_const is used only for signed integers\"" , "/build/llvm-toolchain-snapshot-7~svn338205/lib/CodeGen/AsmPrinter/DwarfUnit.cpp" , 214, __extension__ __PRETTY_FUNCTION__)) | |||
214 | "DW_FORM_implicit_const is used only for signed integers")(static_cast <bool> (Form != dwarf::DW_FORM_implicit_const && "DW_FORM_implicit_const is used only for signed integers" ) ? void (0) : __assert_fail ("Form != dwarf::DW_FORM_implicit_const && \"DW_FORM_implicit_const is used only for signed integers\"" , "/build/llvm-toolchain-snapshot-7~svn338205/lib/CodeGen/AsmPrinter/DwarfUnit.cpp" , 214, __extension__ __PRETTY_FUNCTION__)); | |||
215 | Die.addValue(DIEValueAllocator, Attribute, *Form, DIEInteger(Integer)); | |||
216 | } | |||
217 | ||||
218 | void DwarfUnit::addUInt(DIEValueList &Block, dwarf::Form Form, | |||
219 | uint64_t Integer) { | |||
220 | addUInt(Block, (dwarf::Attribute)0, Form, Integer); | |||
221 | } | |||
222 | ||||
223 | void DwarfUnit::addSInt(DIEValueList &Die, dwarf::Attribute Attribute, | |||
224 | Optional<dwarf::Form> Form, int64_t Integer) { | |||
225 | if (!Form) | |||
226 | Form = DIEInteger::BestForm(true, Integer); | |||
227 | Die.addValue(DIEValueAllocator, Attribute, *Form, DIEInteger(Integer)); | |||
228 | } | |||
229 | ||||
230 | void DwarfUnit::addSInt(DIELoc &Die, Optional<dwarf::Form> Form, | |||
231 | int64_t Integer) { | |||
232 | addSInt(Die, (dwarf::Attribute)0, Form, Integer); | |||
233 | } | |||
234 | ||||
235 | void DwarfUnit::addString(DIE &Die, dwarf::Attribute Attribute, | |||
236 | StringRef String) { | |||
237 | if (DD->useInlineStrings()) { | |||
238 | Die.addValue(DIEValueAllocator, Attribute, dwarf::DW_FORM_string, | |||
239 | new (DIEValueAllocator) | |||
240 | DIEInlineString(String, DIEValueAllocator)); | |||
241 | return; | |||
242 | } | |||
243 | auto StringPoolEntry = DU->getStringPool().getEntry(*Asm, String); | |||
244 | dwarf::Form IxForm = | |||
245 | isDwoUnit() ? dwarf::DW_FORM_GNU_str_index : dwarf::DW_FORM_strp; | |||
246 | // For DWARF v5 and beyond, use the smallest strx? form possible. | |||
247 | if (useSegmentedStringOffsetsTable()) { | |||
248 | IxForm = dwarf::DW_FORM_strx1; | |||
249 | unsigned Index = StringPoolEntry.getIndex(); | |||
250 | if (Index > 0xffffff) | |||
251 | IxForm = dwarf::DW_FORM_strx4; | |||
252 | else if (Index > 0xffff) | |||
253 | IxForm = dwarf::DW_FORM_strx3; | |||
254 | else if (Index > 0xff) | |||
255 | IxForm = dwarf::DW_FORM_strx2; | |||
256 | } | |||
257 | Die.addValue(DIEValueAllocator, Attribute, IxForm, | |||
258 | DIEString(StringPoolEntry)); | |||
259 | } | |||
260 | ||||
261 | DIEValueList::value_iterator DwarfUnit::addLabel(DIEValueList &Die, | |||
262 | dwarf::Attribute Attribute, | |||
263 | dwarf::Form Form, | |||
264 | const MCSymbol *Label) { | |||
265 | return Die.addValue(DIEValueAllocator, Attribute, Form, DIELabel(Label)); | |||
266 | } | |||
267 | ||||
268 | void DwarfUnit::addLabel(DIELoc &Die, dwarf::Form Form, const MCSymbol *Label) { | |||
269 | addLabel(Die, (dwarf::Attribute)0, Form, Label); | |||
270 | } | |||
271 | ||||
272 | void DwarfUnit::addSectionOffset(DIE &Die, dwarf::Attribute Attribute, | |||
273 | uint64_t Integer) { | |||
274 | if (DD->getDwarfVersion() >= 4) | |||
275 | addUInt(Die, Attribute, dwarf::DW_FORM_sec_offset, Integer); | |||
276 | else | |||
277 | addUInt(Die, Attribute, dwarf::DW_FORM_data4, Integer); | |||
278 | } | |||
279 | ||||
280 | MD5::MD5Result *DwarfUnit::getMD5AsBytes(const DIFile *File) const { | |||
281 | assert(File)(static_cast <bool> (File) ? void (0) : __assert_fail ( "File", "/build/llvm-toolchain-snapshot-7~svn338205/lib/CodeGen/AsmPrinter/DwarfUnit.cpp" , 281, __extension__ __PRETTY_FUNCTION__)); | |||
282 | if (DD->getDwarfVersion() < 5) | |||
283 | return nullptr; | |||
284 | Optional<DIFile::ChecksumInfo<StringRef>> Checksum = File->getChecksum(); | |||
285 | if (!Checksum || Checksum->Kind != DIFile::CSK_MD5) | |||
286 | return nullptr; | |||
287 | ||||
288 | // Convert the string checksum to an MD5Result for the streamer. | |||
289 | // The verifier validates the checksum so we assume it's okay. | |||
290 | // An MD5 checksum is 16 bytes. | |||
291 | std::string ChecksumString = fromHex(Checksum->Value); | |||
292 | void *CKMem = Asm->OutStreamer->getContext().allocate(16, 1); | |||
293 | memcpy(CKMem, ChecksumString.data(), 16); | |||
294 | return reinterpret_cast<MD5::MD5Result *>(CKMem); | |||
295 | } | |||
296 | ||||
297 | unsigned DwarfTypeUnit::getOrCreateSourceID(const DIFile *File) { | |||
298 | if (!SplitLineTable) | |||
299 | return getCU().getOrCreateSourceID(File); | |||
300 | if (!UsedLineTable) { | |||
301 | UsedLineTable = true; | |||
302 | // This is a split type unit that needs a line table. | |||
303 | addSectionOffset(getUnitDie(), dwarf::DW_AT_stmt_list, 0); | |||
304 | } | |||
305 | return SplitLineTable->getFile(File->getDirectory(), File->getFilename(), | |||
306 | getMD5AsBytes(File), File->getSource()); | |||
307 | } | |||
308 | ||||
309 | void DwarfUnit::addOpAddress(DIELoc &Die, const MCSymbol *Sym) { | |||
310 | if (!DD->useSplitDwarf()) { | |||
311 | addUInt(Die, dwarf::DW_FORM_data1, dwarf::DW_OP_addr); | |||
312 | addLabel(Die, dwarf::DW_FORM_udata, Sym); | |||
313 | } else { | |||
314 | addUInt(Die, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_addr_index); | |||
315 | addUInt(Die, dwarf::DW_FORM_GNU_addr_index, | |||
316 | DD->getAddressPool().getIndex(Sym)); | |||
317 | } | |||
318 | } | |||
319 | ||||
320 | void DwarfUnit::addLabelDelta(DIE &Die, dwarf::Attribute Attribute, | |||
321 | const MCSymbol *Hi, const MCSymbol *Lo) { | |||
322 | Die.addValue(DIEValueAllocator, Attribute, dwarf::DW_FORM_data4, | |||
323 | new (DIEValueAllocator) DIEDelta(Hi, Lo)); | |||
324 | } | |||
325 | ||||
326 | void DwarfUnit::addDIEEntry(DIE &Die, dwarf::Attribute Attribute, DIE &Entry) { | |||
327 | addDIEEntry(Die, Attribute, DIEEntry(Entry)); | |||
328 | } | |||
329 | ||||
330 | void DwarfUnit::addDIETypeSignature(DIE &Die, uint64_t Signature) { | |||
331 | // Flag the type unit reference as a declaration so that if it contains | |||
332 | // members (implicit special members, static data member definitions, member | |||
333 | // declarations for definitions in this CU, etc) consumers don't get confused | |||
334 | // and think this is a full definition. | |||
335 | addFlag(Die, dwarf::DW_AT_declaration); | |||
336 | ||||
337 | Die.addValue(DIEValueAllocator, dwarf::DW_AT_signature, | |||
338 | dwarf::DW_FORM_ref_sig8, DIEInteger(Signature)); | |||
339 | } | |||
340 | ||||
341 | void DwarfUnit::addDIEEntry(DIE &Die, dwarf::Attribute Attribute, | |||
342 | DIEEntry Entry) { | |||
343 | const DIEUnit *CU = Die.getUnit(); | |||
344 | const DIEUnit *EntryCU = Entry.getEntry().getUnit(); | |||
345 | if (!CU) | |||
346 | // We assume that Die belongs to this CU, if it is not linked to any CU yet. | |||
347 | CU = getUnitDie().getUnit(); | |||
348 | if (!EntryCU) | |||
349 | EntryCU = getUnitDie().getUnit(); | |||
350 | Die.addValue(DIEValueAllocator, Attribute, | |||
351 | EntryCU == CU ? dwarf::DW_FORM_ref4 : dwarf::DW_FORM_ref_addr, | |||
352 | Entry); | |||
353 | } | |||
354 | ||||
355 | DIE &DwarfUnit::createAndAddDIE(unsigned Tag, DIE &Parent, const DINode *N) { | |||
356 | DIE &Die = Parent.addChild(DIE::get(DIEValueAllocator, (dwarf::Tag)Tag)); | |||
357 | if (N) | |||
358 | insertDIE(N, &Die); | |||
359 | return Die; | |||
360 | } | |||
361 | ||||
362 | void DwarfUnit::addBlock(DIE &Die, dwarf::Attribute Attribute, DIELoc *Loc) { | |||
363 | Loc->ComputeSize(Asm); | |||
364 | DIELocs.push_back(Loc); // Memoize so we can call the destructor later on. | |||
365 | Die.addValue(DIEValueAllocator, Attribute, | |||
366 | Loc->BestForm(DD->getDwarfVersion()), Loc); | |||
367 | } | |||
368 | ||||
369 | void DwarfUnit::addBlock(DIE &Die, dwarf::Attribute Attribute, | |||
370 | DIEBlock *Block) { | |||
371 | Block->ComputeSize(Asm); | |||
372 | DIEBlocks.push_back(Block); // Memoize so we can call the destructor later on. | |||
373 | Die.addValue(DIEValueAllocator, Attribute, Block->BestForm(), Block); | |||
374 | } | |||
375 | ||||
376 | void DwarfUnit::addSourceLine(DIE &Die, unsigned Line, const DIFile *File) { | |||
377 | if (Line == 0) | |||
378 | return; | |||
379 | ||||
380 | unsigned FileID = getOrCreateSourceID(File); | |||
381 | assert(FileID && "Invalid file id")(static_cast <bool> (FileID && "Invalid file id" ) ? void (0) : __assert_fail ("FileID && \"Invalid file id\"" , "/build/llvm-toolchain-snapshot-7~svn338205/lib/CodeGen/AsmPrinter/DwarfUnit.cpp" , 381, __extension__ __PRETTY_FUNCTION__)); | |||
382 | addUInt(Die, dwarf::DW_AT_decl_file, None, FileID); | |||
383 | addUInt(Die, dwarf::DW_AT_decl_line, None, Line); | |||
384 | } | |||
385 | ||||
386 | void DwarfUnit::addSourceLine(DIE &Die, const DILocalVariable *V) { | |||
387 | assert(V)(static_cast <bool> (V) ? void (0) : __assert_fail ("V" , "/build/llvm-toolchain-snapshot-7~svn338205/lib/CodeGen/AsmPrinter/DwarfUnit.cpp" , 387, __extension__ __PRETTY_FUNCTION__)); | |||
388 | ||||
389 | addSourceLine(Die, V->getLine(), V->getFile()); | |||
390 | } | |||
391 | ||||
392 | void DwarfUnit::addSourceLine(DIE &Die, const DIGlobalVariable *G) { | |||
393 | assert(G)(static_cast <bool> (G) ? void (0) : __assert_fail ("G" , "/build/llvm-toolchain-snapshot-7~svn338205/lib/CodeGen/AsmPrinter/DwarfUnit.cpp" , 393, __extension__ __PRETTY_FUNCTION__)); | |||
394 | ||||
395 | addSourceLine(Die, G->getLine(), G->getFile()); | |||
396 | } | |||
397 | ||||
398 | void DwarfUnit::addSourceLine(DIE &Die, const DISubprogram *SP) { | |||
399 | assert(SP)(static_cast <bool> (SP) ? void (0) : __assert_fail ("SP" , "/build/llvm-toolchain-snapshot-7~svn338205/lib/CodeGen/AsmPrinter/DwarfUnit.cpp" , 399, __extension__ __PRETTY_FUNCTION__)); | |||
400 | ||||
401 | addSourceLine(Die, SP->getLine(), SP->getFile()); | |||
402 | } | |||
403 | ||||
404 | void DwarfUnit::addSourceLine(DIE &Die, const DIType *Ty) { | |||
405 | assert(Ty)(static_cast <bool> (Ty) ? void (0) : __assert_fail ("Ty" , "/build/llvm-toolchain-snapshot-7~svn338205/lib/CodeGen/AsmPrinter/DwarfUnit.cpp" , 405, __extension__ __PRETTY_FUNCTION__)); | |||
406 | ||||
407 | addSourceLine(Die, Ty->getLine(), Ty->getFile()); | |||
408 | } | |||
409 | ||||
410 | void DwarfUnit::addSourceLine(DIE &Die, const DIObjCProperty *Ty) { | |||
411 | assert(Ty)(static_cast <bool> (Ty) ? void (0) : __assert_fail ("Ty" , "/build/llvm-toolchain-snapshot-7~svn338205/lib/CodeGen/AsmPrinter/DwarfUnit.cpp" , 411, __extension__ __PRETTY_FUNCTION__)); | |||
412 | ||||
413 | addSourceLine(Die, Ty->getLine(), Ty->getFile()); | |||
414 | } | |||
415 | ||||
416 | /* Byref variables, in Blocks, are declared by the programmer as "SomeType | |||
417 | VarName;", but the compiler creates a __Block_byref_x_VarName struct, and | |||
418 | gives the variable VarName either the struct, or a pointer to the struct, as | |||
419 | its type. This is necessary for various behind-the-scenes things the | |||
420 | compiler needs to do with by-reference variables in Blocks. | |||
421 | ||||
422 | However, as far as the original *programmer* is concerned, the variable | |||
423 | should still have type 'SomeType', as originally declared. | |||
424 | ||||
425 | The function getBlockByrefType dives into the __Block_byref_x_VarName | |||
426 | struct to find the original type of the variable, which is then assigned to | |||
427 | the variable's Debug Information Entry as its real type. So far, so good. | |||
428 | However now the debugger will expect the variable VarName to have the type | |||
429 | SomeType. So we need the location attribute for the variable to be an | |||
430 | expression that explains to the debugger how to navigate through the | |||
431 | pointers and struct to find the actual variable of type SomeType. | |||
432 | ||||
433 | The following function does just that. We start by getting | |||
434 | the "normal" location for the variable. This will be the location | |||
435 | of either the struct __Block_byref_x_VarName or the pointer to the | |||
436 | struct __Block_byref_x_VarName. | |||
437 | ||||
438 | The struct will look something like: | |||
439 | ||||
440 | struct __Block_byref_x_VarName { | |||
441 | ... <various fields> | |||
442 | struct __Block_byref_x_VarName *forwarding; | |||
443 | ... <various other fields> | |||
444 | SomeType VarName; | |||
445 | ... <maybe more fields> | |||
446 | }; | |||
447 | ||||
448 | If we are given the struct directly (as our starting point) we | |||
449 | need to tell the debugger to: | |||
450 | ||||
451 | 1). Add the offset of the forwarding field. | |||
452 | ||||
453 | 2). Follow that pointer to get the real __Block_byref_x_VarName | |||
454 | struct to use (the real one may have been copied onto the heap). | |||
455 | ||||
456 | 3). Add the offset for the field VarName, to find the actual variable. | |||
457 | ||||
458 | If we started with a pointer to the struct, then we need to | |||
459 | dereference that pointer first, before the other steps. | |||
460 | Translating this into DWARF ops, we will need to append the following | |||
461 | to the current location description for the variable: | |||
462 | ||||
463 | DW_OP_deref -- optional, if we start with a pointer | |||
464 | DW_OP_plus_uconst <forward_fld_offset> | |||
465 | DW_OP_deref | |||
466 | DW_OP_plus_uconst <varName_fld_offset> | |||
467 | ||||
468 | That is what this function does. */ | |||
469 | ||||
470 | void DwarfUnit::addBlockByrefAddress(const DbgVariable &DV, DIE &Die, | |||
471 | dwarf::Attribute Attribute, | |||
472 | const MachineLocation &Location) { | |||
473 | const DIType *Ty = DV.getType(); | |||
474 | const DIType *TmpTy = Ty; | |||
475 | uint16_t Tag = Ty->getTag(); | |||
476 | bool isPointer = false; | |||
477 | ||||
478 | StringRef varName = DV.getName(); | |||
479 | ||||
480 | if (Tag == dwarf::DW_TAG_pointer_type) { | |||
| ||||
481 | auto *DTy = cast<DIDerivedType>(Ty); | |||
482 | TmpTy = resolve(DTy->getBaseType()); | |||
483 | isPointer = true; | |||
484 | } | |||
485 | ||||
486 | // Find the __forwarding field and the variable field in the __Block_byref | |||
487 | // struct. | |||
488 | DINodeArray Fields = cast<DICompositeType>(TmpTy)->getElements(); | |||
489 | const DIDerivedType *varField = nullptr; | |||
490 | const DIDerivedType *forwardingField = nullptr; | |||
491 | ||||
492 | for (unsigned i = 0, N = Fields.size(); i < N; ++i) { | |||
493 | auto *DT = cast<DIDerivedType>(Fields[i]); | |||
494 | StringRef fieldName = DT->getName(); | |||
495 | if (fieldName == "__forwarding") | |||
496 | forwardingField = DT; | |||
497 | else if (fieldName == varName) | |||
498 | varField = DT; | |||
499 | } | |||
500 | ||||
501 | // Get the offsets for the forwarding field and the variable field. | |||
502 | unsigned forwardingFieldOffset = forwardingField->getOffsetInBits() >> 3; | |||
| ||||
503 | unsigned varFieldOffset = varField->getOffsetInBits() >> 2; | |||
504 | ||||
505 | // Decode the original location, and use that as the start of the byref | |||
506 | // variable's location. | |||
507 | DIELoc *Loc = new (DIEValueAllocator) DIELoc; | |||
508 | DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); | |||
509 | if (Location.isIndirect()) | |||
510 | DwarfExpr.setMemoryLocationKind(); | |||
511 | ||||
512 | SmallVector<uint64_t, 6> Ops; | |||
513 | // If we started with a pointer to the __Block_byref... struct, then | |||
514 | // the first thing we need to do is dereference the pointer (DW_OP_deref). | |||
515 | if (isPointer) | |||
516 | Ops.push_back(dwarf::DW_OP_deref); | |||
517 | ||||
518 | // Next add the offset for the '__forwarding' field: | |||
519 | // DW_OP_plus_uconst ForwardingFieldOffset. Note there's no point in | |||
520 | // adding the offset if it's 0. | |||
521 | if (forwardingFieldOffset > 0) { | |||
522 | Ops.push_back(dwarf::DW_OP_plus_uconst); | |||
523 | Ops.push_back(forwardingFieldOffset); | |||
524 | } | |||
525 | ||||
526 | // Now dereference the __forwarding field to get to the real __Block_byref | |||
527 | // struct: DW_OP_deref. | |||
528 | Ops.push_back(dwarf::DW_OP_deref); | |||
529 | ||||
530 | // Now that we've got the real __Block_byref... struct, add the offset | |||
531 | // for the variable's field to get to the location of the actual variable: | |||
532 | // DW_OP_plus_uconst varFieldOffset. Again, don't add if it's 0. | |||
533 | if (varFieldOffset > 0) { | |||
534 | Ops.push_back(dwarf::DW_OP_plus_uconst); | |||
535 | Ops.push_back(varFieldOffset); | |||
536 | } | |||
537 | ||||
538 | DIExpressionCursor Cursor(Ops); | |||
539 | const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo(); | |||
540 | if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg())) | |||
541 | return; | |||
542 | DwarfExpr.addExpression(std::move(Cursor)); | |||
543 | ||||
544 | // Now attach the location information to the DIE. | |||
545 | addBlock(Die, Attribute, DwarfExpr.finalize()); | |||
546 | } | |||
547 | ||||
548 | /// Return true if type encoding is unsigned. | |||
549 | static bool isUnsignedDIType(DwarfDebug *DD, const DIType *Ty) { | |||
550 | if (auto *CTy = dyn_cast<DICompositeType>(Ty)) { | |||
551 | // FIXME: Enums without a fixed underlying type have unknown signedness | |||
552 | // here, leading to incorrectly emitted constants. | |||
553 | if (CTy->getTag() == dwarf::DW_TAG_enumeration_type) | |||
554 | return false; | |||
555 | ||||
556 | // (Pieces of) aggregate types that get hacked apart by SROA may be | |||
557 | // represented by a constant. Encode them as unsigned bytes. | |||
558 | return true; | |||
559 | } | |||
560 | ||||
561 | if (auto *DTy = dyn_cast<DIDerivedType>(Ty)) { | |||
562 | dwarf::Tag T = (dwarf::Tag)Ty->getTag(); | |||
563 | // Encode pointer constants as unsigned bytes. This is used at least for | |||
564 | // null pointer constant emission. | |||
565 | // FIXME: reference and rvalue_reference /probably/ shouldn't be allowed | |||
566 | // here, but accept them for now due to a bug in SROA producing bogus | |||
567 | // dbg.values. | |||
568 | if (T == dwarf::DW_TAG_pointer_type || | |||
569 | T == dwarf::DW_TAG_ptr_to_member_type || | |||
570 | T == dwarf::DW_TAG_reference_type || | |||
571 | T == dwarf::DW_TAG_rvalue_reference_type) | |||
572 | return true; | |||
573 | assert(T == dwarf::DW_TAG_typedef || T == dwarf::DW_TAG_const_type ||(static_cast <bool> (T == dwarf::DW_TAG_typedef || T == dwarf::DW_TAG_const_type || T == dwarf::DW_TAG_volatile_type || T == dwarf::DW_TAG_restrict_type || T == dwarf::DW_TAG_atomic_type ) ? void (0) : __assert_fail ("T == dwarf::DW_TAG_typedef || T == dwarf::DW_TAG_const_type || T == dwarf::DW_TAG_volatile_type || T == dwarf::DW_TAG_restrict_type || T == dwarf::DW_TAG_atomic_type" , "/build/llvm-toolchain-snapshot-7~svn338205/lib/CodeGen/AsmPrinter/DwarfUnit.cpp" , 575, __extension__ __PRETTY_FUNCTION__)) | |||
574 | T == dwarf::DW_TAG_volatile_type ||(static_cast <bool> (T == dwarf::DW_TAG_typedef || T == dwarf::DW_TAG_const_type || T == dwarf::DW_TAG_volatile_type || T == dwarf::DW_TAG_restrict_type || T == dwarf::DW_TAG_atomic_type ) ? void (0) : __assert_fail ("T == dwarf::DW_TAG_typedef || T == dwarf::DW_TAG_const_type || T == dwarf::DW_TAG_volatile_type || T == dwarf::DW_TAG_restrict_type || T == dwarf::DW_TAG_atomic_type" , "/build/llvm-toolchain-snapshot-7~svn338205/lib/CodeGen/AsmPrinter/DwarfUnit.cpp" , 575, __extension__ __PRETTY_FUNCTION__)) | |||
575 | T == dwarf::DW_TAG_restrict_type || T == dwarf::DW_TAG_atomic_type)(static_cast <bool> (T == dwarf::DW_TAG_typedef || T == dwarf::DW_TAG_const_type || T == dwarf::DW_TAG_volatile_type || T == dwarf::DW_TAG_restrict_type || T == dwarf::DW_TAG_atomic_type ) ? void (0) : __assert_fail ("T == dwarf::DW_TAG_typedef || T == dwarf::DW_TAG_const_type || T == dwarf::DW_TAG_volatile_type || T == dwarf::DW_TAG_restrict_type || T == dwarf::DW_TAG_atomic_type" , "/build/llvm-toolchain-snapshot-7~svn338205/lib/CodeGen/AsmPrinter/DwarfUnit.cpp" , 575, __extension__ __PRETTY_FUNCTION__)); | |||
576 | DITypeRef Deriv = DTy->getBaseType(); | |||
577 | assert(Deriv && "Expected valid base type")(static_cast <bool> (Deriv && "Expected valid base type" ) ? void (0) : __assert_fail ("Deriv && \"Expected valid base type\"" , "/build/llvm-toolchain-snapshot-7~svn338205/lib/CodeGen/AsmPrinter/DwarfUnit.cpp" , 577, __extension__ __PRETTY_FUNCTION__)); | |||
578 | return isUnsignedDIType(DD, DD->resolve(Deriv)); | |||
579 | } | |||
580 | ||||
581 | auto *BTy = cast<DIBasicType>(Ty); | |||
582 | unsigned Encoding = BTy->getEncoding(); | |||
583 | assert((Encoding == dwarf::DW_ATE_unsigned ||(static_cast <bool> ((Encoding == dwarf::DW_ATE_unsigned || Encoding == dwarf::DW_ATE_unsigned_char || Encoding == dwarf ::DW_ATE_signed || Encoding == dwarf::DW_ATE_signed_char || Encoding == dwarf::DW_ATE_float || Encoding == dwarf::DW_ATE_UTF || Encoding == dwarf::DW_ATE_boolean || (Ty->getTag() == dwarf::DW_TAG_unspecified_type && Ty->getName() == "decltype(nullptr)")) && "Unsupported encoding") ? void (0) : __assert_fail ("(Encoding == dwarf::DW_ATE_unsigned || Encoding == dwarf::DW_ATE_unsigned_char || Encoding == dwarf::DW_ATE_signed || Encoding == dwarf::DW_ATE_signed_char || Encoding == dwarf::DW_ATE_float || Encoding == dwarf::DW_ATE_UTF || Encoding == dwarf::DW_ATE_boolean || (Ty->getTag() == dwarf::DW_TAG_unspecified_type && Ty->getName() == \"decltype(nullptr)\")) && \"Unsupported encoding\"" , "/build/llvm-toolchain-snapshot-7~svn338205/lib/CodeGen/AsmPrinter/DwarfUnit.cpp" , 591, __extension__ __PRETTY_FUNCTION__)) | |||
584 | Encoding == dwarf::DW_ATE_unsigned_char ||(static_cast <bool> ((Encoding == dwarf::DW_ATE_unsigned || Encoding == dwarf::DW_ATE_unsigned_char || Encoding == dwarf ::DW_ATE_signed || Encoding == dwarf::DW_ATE_signed_char || Encoding == dwarf::DW_ATE_float || Encoding == dwarf::DW_ATE_UTF || Encoding == dwarf::DW_ATE_boolean || (Ty->getTag() == dwarf::DW_TAG_unspecified_type && Ty->getName() == "decltype(nullptr)")) && "Unsupported encoding") ? void (0) : __assert_fail ("(Encoding == dwarf::DW_ATE_unsigned || Encoding == dwarf::DW_ATE_unsigned_char || Encoding == dwarf::DW_ATE_signed || Encoding == dwarf::DW_ATE_signed_char || Encoding == dwarf::DW_ATE_float || Encoding == dwarf::DW_ATE_UTF || Encoding == dwarf::DW_ATE_boolean || (Ty->getTag() == dwarf::DW_TAG_unspecified_type && Ty->getName() == \"decltype(nullptr)\")) && \"Unsupported encoding\"" , "/build/llvm-toolchain-snapshot-7~svn338205/lib/CodeGen/AsmPrinter/DwarfUnit.cpp" , 591, __extension__ __PRETTY_FUNCTION__)) | |||
585 | Encoding == dwarf::DW_ATE_signed ||(static_cast <bool> ((Encoding == dwarf::DW_ATE_unsigned || Encoding == dwarf::DW_ATE_unsigned_char || Encoding == dwarf ::DW_ATE_signed || Encoding == dwarf::DW_ATE_signed_char || Encoding == dwarf::DW_ATE_float || Encoding == dwarf::DW_ATE_UTF || Encoding == dwarf::DW_ATE_boolean || (Ty->getTag() == dwarf::DW_TAG_unspecified_type && Ty->getName() == "decltype(nullptr)")) && "Unsupported encoding") ? void (0) : __assert_fail ("(Encoding == dwarf::DW_ATE_unsigned || Encoding == dwarf::DW_ATE_unsigned_char || Encoding == dwarf::DW_ATE_signed || Encoding == dwarf::DW_ATE_signed_char || Encoding == dwarf::DW_ATE_float || Encoding == dwarf::DW_ATE_UTF || Encoding == dwarf::DW_ATE_boolean || (Ty->getTag() == dwarf::DW_TAG_unspecified_type && Ty->getName() == \"decltype(nullptr)\")) && \"Unsupported encoding\"" , "/build/llvm-toolchain-snapshot-7~svn338205/lib/CodeGen/AsmPrinter/DwarfUnit.cpp" , 591, __extension__ __PRETTY_FUNCTION__)) | |||
586 | Encoding == dwarf::DW_ATE_signed_char ||(static_cast <bool> ((Encoding == dwarf::DW_ATE_unsigned || Encoding == dwarf::DW_ATE_unsigned_char || Encoding == dwarf ::DW_ATE_signed || Encoding == dwarf::DW_ATE_signed_char || Encoding == dwarf::DW_ATE_float || Encoding == dwarf::DW_ATE_UTF || Encoding == dwarf::DW_ATE_boolean || (Ty->getTag() == dwarf::DW_TAG_unspecified_type && Ty->getName() == "decltype(nullptr)")) && "Unsupported encoding") ? void (0) : __assert_fail ("(Encoding == dwarf::DW_ATE_unsigned || Encoding == dwarf::DW_ATE_unsigned_char || Encoding == dwarf::DW_ATE_signed || Encoding == dwarf::DW_ATE_signed_char || Encoding == dwarf::DW_ATE_float || Encoding == dwarf::DW_ATE_UTF || Encoding == dwarf::DW_ATE_boolean || (Ty->getTag() == dwarf::DW_TAG_unspecified_type && Ty->getName() == \"decltype(nullptr)\")) && \"Unsupported encoding\"" , "/build/llvm-toolchain-snapshot-7~svn338205/lib/CodeGen/AsmPrinter/DwarfUnit.cpp" , 591, __extension__ __PRETTY_FUNCTION__)) | |||
587 | Encoding == dwarf::DW_ATE_float || Encoding == dwarf::DW_ATE_UTF ||(static_cast <bool> ((Encoding == dwarf::DW_ATE_unsigned || Encoding == dwarf::DW_ATE_unsigned_char || Encoding == dwarf ::DW_ATE_signed || Encoding == dwarf::DW_ATE_signed_char || Encoding == dwarf::DW_ATE_float || Encoding == dwarf::DW_ATE_UTF || Encoding == dwarf::DW_ATE_boolean || (Ty->getTag() == dwarf::DW_TAG_unspecified_type && Ty->getName() == "decltype(nullptr)")) && "Unsupported encoding") ? void (0) : __assert_fail ("(Encoding == dwarf::DW_ATE_unsigned || Encoding == dwarf::DW_ATE_unsigned_char || Encoding == dwarf::DW_ATE_signed || Encoding == dwarf::DW_ATE_signed_char || Encoding == dwarf::DW_ATE_float || Encoding == dwarf::DW_ATE_UTF || Encoding == dwarf::DW_ATE_boolean || (Ty->getTag() == dwarf::DW_TAG_unspecified_type && Ty->getName() == \"decltype(nullptr)\")) && \"Unsupported encoding\"" , "/build/llvm-toolchain-snapshot-7~svn338205/lib/CodeGen/AsmPrinter/DwarfUnit.cpp" , 591, __extension__ __PRETTY_FUNCTION__)) | |||
588 | Encoding == dwarf::DW_ATE_boolean ||(static_cast <bool> ((Encoding == dwarf::DW_ATE_unsigned || Encoding == dwarf::DW_ATE_unsigned_char || Encoding == dwarf ::DW_ATE_signed || Encoding == dwarf::DW_ATE_signed_char || Encoding == dwarf::DW_ATE_float || Encoding == dwarf::DW_ATE_UTF || Encoding == dwarf::DW_ATE_boolean || (Ty->getTag() == dwarf::DW_TAG_unspecified_type && Ty->getName() == "decltype(nullptr)")) && "Unsupported encoding") ? void (0) : __assert_fail ("(Encoding == dwarf::DW_ATE_unsigned || Encoding == dwarf::DW_ATE_unsigned_char || Encoding == dwarf::DW_ATE_signed || Encoding == dwarf::DW_ATE_signed_char || Encoding == dwarf::DW_ATE_float || Encoding == dwarf::DW_ATE_UTF || Encoding == dwarf::DW_ATE_boolean || (Ty->getTag() == dwarf::DW_TAG_unspecified_type && Ty->getName() == \"decltype(nullptr)\")) && \"Unsupported encoding\"" , "/build/llvm-toolchain-snapshot-7~svn338205/lib/CodeGen/AsmPrinter/DwarfUnit.cpp" , 591, __extension__ __PRETTY_FUNCTION__)) | |||
589 | (Ty->getTag() == dwarf::DW_TAG_unspecified_type &&(static_cast <bool> ((Encoding == dwarf::DW_ATE_unsigned || Encoding == dwarf::DW_ATE_unsigned_char || Encoding == dwarf ::DW_ATE_signed || Encoding == dwarf::DW_ATE_signed_char || Encoding == dwarf::DW_ATE_float || Encoding == dwarf::DW_ATE_UTF || Encoding == dwarf::DW_ATE_boolean || (Ty->getTag() == dwarf::DW_TAG_unspecified_type && Ty->getName() == "decltype(nullptr)")) && "Unsupported encoding") ? void (0) : __assert_fail ("(Encoding == dwarf::DW_ATE_unsigned || Encoding == dwarf::DW_ATE_unsigned_char || Encoding == dwarf::DW_ATE_signed || Encoding == dwarf::DW_ATE_signed_char || Encoding == dwarf::DW_ATE_float || Encoding == dwarf::DW_ATE_UTF || Encoding == dwarf::DW_ATE_boolean || (Ty->getTag() == dwarf::DW_TAG_unspecified_type && Ty->getName() == \"decltype(nullptr)\")) && \"Unsupported encoding\"" , "/build/llvm-toolchain-snapshot-7~svn338205/lib/CodeGen/AsmPrinter/DwarfUnit.cpp" , 591, __extension__ __PRETTY_FUNCTION__)) | |||
590 | Ty->getName() == "decltype(nullptr)")) &&(static_cast <bool> ((Encoding == dwarf::DW_ATE_unsigned || Encoding == dwarf::DW_ATE_unsigned_char || Encoding == dwarf ::DW_ATE_signed || Encoding == dwarf::DW_ATE_signed_char || Encoding == dwarf::DW_ATE_float || Encoding == dwarf::DW_ATE_UTF || Encoding == dwarf::DW_ATE_boolean || (Ty->getTag() == dwarf::DW_TAG_unspecified_type && Ty->getName() == "decltype(nullptr)")) && "Unsupported encoding") ? void (0) : __assert_fail ("(Encoding == dwarf::DW_ATE_unsigned || Encoding == dwarf::DW_ATE_unsigned_char || Encoding == dwarf::DW_ATE_signed || Encoding == dwarf::DW_ATE_signed_char || Encoding == dwarf::DW_ATE_float || Encoding == dwarf::DW_ATE_UTF || Encoding == dwarf::DW_ATE_boolean || (Ty->getTag() == dwarf::DW_TAG_unspecified_type && Ty->getName() == \"decltype(nullptr)\")) && \"Unsupported encoding\"" , "/build/llvm-toolchain-snapshot-7~svn338205/lib/CodeGen/AsmPrinter/DwarfUnit.cpp" , 591, __extension__ __PRETTY_FUNCTION__)) | |||
591 | "Unsupported encoding")(static_cast <bool> ((Encoding == dwarf::DW_ATE_unsigned || Encoding == dwarf::DW_ATE_unsigned_char || Encoding == dwarf ::DW_ATE_signed || Encoding == dwarf::DW_ATE_signed_char || Encoding == dwarf::DW_ATE_float || Encoding == dwarf::DW_ATE_UTF || Encoding == dwarf::DW_ATE_boolean || (Ty->getTag() == dwarf::DW_TAG_unspecified_type && Ty->getName() == "decltype(nullptr)")) && "Unsupported encoding") ? void (0) : __assert_fail ("(Encoding == dwarf::DW_ATE_unsigned || Encoding == dwarf::DW_ATE_unsigned_char || Encoding == dwarf::DW_ATE_signed || Encoding == dwarf::DW_ATE_signed_char || Encoding == dwarf::DW_ATE_float || Encoding == dwarf::DW_ATE_UTF || Encoding == dwarf::DW_ATE_boolean || (Ty->getTag() == dwarf::DW_TAG_unspecified_type && Ty->getName() == \"decltype(nullptr)\")) && \"Unsupported encoding\"" , "/build/llvm-toolchain-snapshot-7~svn338205/lib/CodeGen/AsmPrinter/DwarfUnit.cpp" , 591, __extension__ __PRETTY_FUNCTION__)); | |||
592 | return Encoding == dwarf::DW_ATE_unsigned || | |||
593 | Encoding == dwarf::DW_ATE_unsigned_char || | |||
594 | Encoding == dwarf::DW_ATE_UTF || Encoding == dwarf::DW_ATE_boolean || | |||
595 | Ty->getTag() == dwarf::DW_TAG_unspecified_type; | |||
596 | } | |||
597 | ||||
598 | void DwarfUnit::addConstantFPValue(DIE &Die, const MachineOperand &MO) { | |||
599 | assert(MO.isFPImm() && "Invalid machine operand!")(static_cast <bool> (MO.isFPImm() && "Invalid machine operand!" ) ? void (0) : __assert_fail ("MO.isFPImm() && \"Invalid machine operand!\"" , "/build/llvm-toolchain-snapshot-7~svn338205/lib/CodeGen/AsmPrinter/DwarfUnit.cpp" , 599, __extension__ __PRETTY_FUNCTION__)); | |||
600 | DIEBlock *Block = new (DIEValueAllocator) DIEBlock; | |||
601 | APFloat FPImm = MO.getFPImm()->getValueAPF(); | |||
602 | ||||
603 | // Get the raw data form of the floating point. | |||
604 | const APInt FltVal = FPImm.bitcastToAPInt(); | |||
605 | const char *FltPtr = (const char *)FltVal.getRawData(); | |||
606 | ||||
607 | int NumBytes = FltVal.getBitWidth() / 8; // 8 bits per byte. | |||
608 | bool LittleEndian = Asm->getDataLayout().isLittleEndian(); | |||
609 | int Incr = (LittleEndian ? 1 : -1); | |||
610 | int Start = (LittleEndian ? 0 : NumBytes - 1); | |||
611 | int Stop = (LittleEndian ? NumBytes : -1); | |||
612 | ||||
613 | // Output the constant to DWARF one byte at a time. | |||
614 | for (; Start != Stop; Start += Incr) | |||
615 | addUInt(*Block, dwarf::DW_FORM_data1, (unsigned char)0xFF & FltPtr[Start]); | |||
616 | ||||
617 | addBlock(Die, dwarf::DW_AT_const_value, Block); | |||
618 | } | |||
619 | ||||
620 | void DwarfUnit::addConstantFPValue(DIE &Die, const ConstantFP *CFP) { | |||
621 | // Pass this down to addConstantValue as an unsigned bag of bits. | |||
622 | addConstantValue(Die, CFP->getValueAPF().bitcastToAPInt(), true); | |||
623 | } | |||
624 | ||||
625 | void DwarfUnit::addConstantValue(DIE &Die, const ConstantInt *CI, | |||
626 | const DIType *Ty) { | |||
627 | addConstantValue(Die, CI->getValue(), Ty); | |||
628 | } | |||
629 | ||||
630 | void DwarfUnit::addConstantValue(DIE &Die, const MachineOperand &MO, | |||
631 | const DIType *Ty) { | |||
632 | assert(MO.isImm() && "Invalid machine operand!")(static_cast <bool> (MO.isImm() && "Invalid machine operand!" ) ? void (0) : __assert_fail ("MO.isImm() && \"Invalid machine operand!\"" , "/build/llvm-toolchain-snapshot-7~svn338205/lib/CodeGen/AsmPrinter/DwarfUnit.cpp" , 632, __extension__ __PRETTY_FUNCTION__)); | |||
633 | ||||
634 | addConstantValue(Die, isUnsignedDIType(DD, Ty), MO.getImm()); | |||
635 | } | |||
636 | ||||
637 | void DwarfUnit::addConstantValue(DIE &Die, bool Unsigned, uint64_t Val) { | |||
638 | // FIXME: This is a bit conservative/simple - it emits negative values always | |||
639 | // sign extended to 64 bits rather than minimizing the number of bytes. | |||
640 | addUInt(Die, dwarf::DW_AT_const_value, | |||
641 | Unsigned ? dwarf::DW_FORM_udata : dwarf::DW_FORM_sdata, Val); | |||
642 | } | |||
643 | ||||
644 | void DwarfUnit::addConstantValue(DIE &Die, const APInt &Val, const DIType *Ty) { | |||
645 | addConstantValue(Die, Val, isUnsignedDIType(DD, Ty)); | |||
646 | } | |||
647 | ||||
648 | void DwarfUnit::addConstantValue(DIE &Die, const APInt &Val, bool Unsigned) { | |||
649 | unsigned CIBitWidth = Val.getBitWidth(); | |||
650 | if (CIBitWidth <= 64) { | |||
651 | addConstantValue(Die, Unsigned, | |||
652 | Unsigned ? Val.getZExtValue() : Val.getSExtValue()); | |||
653 | return; | |||
654 | } | |||
655 | ||||
656 | DIEBlock *Block = new (DIEValueAllocator) DIEBlock; | |||
657 | ||||
658 | // Get the raw data form of the large APInt. | |||
659 | const uint64_t *Ptr64 = Val.getRawData(); | |||
660 | ||||
661 | int NumBytes = Val.getBitWidth() / 8; // 8 bits per byte. | |||
662 | bool LittleEndian = Asm->getDataLayout().isLittleEndian(); | |||
663 | ||||
664 | // Output the constant to DWARF one byte at a time. | |||
665 | for (int i = 0; i < NumBytes; i++) { | |||
666 | uint8_t c; | |||
667 | if (LittleEndian) | |||
668 | c = Ptr64[i / 8] >> (8 * (i & 7)); | |||
669 | else | |||
670 | c = Ptr64[(NumBytes - 1 - i) / 8] >> (8 * ((NumBytes - 1 - i) & 7)); | |||
671 | addUInt(*Block, dwarf::DW_FORM_data1, c); | |||
672 | } | |||
673 | ||||
674 | addBlock(Die, dwarf::DW_AT_const_value, Block); | |||
675 | } | |||
676 | ||||
677 | void DwarfUnit::addLinkageName(DIE &Die, StringRef LinkageName) { | |||
678 | if (!LinkageName.empty()) | |||
679 | addString(Die, | |||
680 | DD->getDwarfVersion() >= 4 ? dwarf::DW_AT_linkage_name | |||
681 | : dwarf::DW_AT_MIPS_linkage_name, | |||
682 | GlobalValue::dropLLVMManglingEscape(LinkageName)); | |||
683 | } | |||
684 | ||||
685 | void DwarfUnit::addTemplateParams(DIE &Buffer, DINodeArray TParams) { | |||
686 | // Add template parameters. | |||
687 | for (const auto *Element : TParams) { | |||
688 | if (auto *TTP = dyn_cast<DITemplateTypeParameter>(Element)) | |||
689 | constructTemplateTypeParameterDIE(Buffer, TTP); | |||
690 | else if (auto *TVP = dyn_cast<DITemplateValueParameter>(Element)) | |||
691 | constructTemplateValueParameterDIE(Buffer, TVP); | |||
692 | } | |||
693 | } | |||
694 | ||||
695 | /// Add thrown types. | |||
696 | void DwarfUnit::addThrownTypes(DIE &Die, DINodeArray ThrownTypes) { | |||
697 | for (const auto *Ty : ThrownTypes) { | |||
698 | DIE &TT = createAndAddDIE(dwarf::DW_TAG_thrown_type, Die); | |||
699 | addType(TT, cast<DIType>(Ty)); | |||
700 | } | |||
701 | } | |||
702 | ||||
703 | DIE *DwarfUnit::getOrCreateContextDIE(const DIScope *Context) { | |||
704 | if (!Context || isa<DIFile>(Context)) | |||
705 | return &getUnitDie(); | |||
706 | if (auto *T = dyn_cast<DIType>(Context)) | |||
707 | return getOrCreateTypeDIE(T); | |||
708 | if (auto *NS = dyn_cast<DINamespace>(Context)) | |||
709 | return getOrCreateNameSpace(NS); | |||
710 | if (auto *SP = dyn_cast<DISubprogram>(Context)) | |||
711 | return getOrCreateSubprogramDIE(SP); | |||
712 | if (auto *M = dyn_cast<DIModule>(Context)) | |||
713 | return getOrCreateModule(M); | |||
714 | return getDIE(Context); | |||
715 | } | |||
716 | ||||
717 | DIE *DwarfTypeUnit::createTypeDIE(const DICompositeType *Ty) { | |||
718 | auto *Context = resolve(Ty->getScope()); | |||
719 | DIE *ContextDIE = getOrCreateContextDIE(Context); | |||
720 | ||||
721 | if (DIE *TyDIE = getDIE(Ty)) | |||
722 | return TyDIE; | |||
723 | ||||
724 | // Create new type. | |||
725 | DIE &TyDIE = createAndAddDIE(Ty->getTag(), *ContextDIE, Ty); | |||
726 | ||||
727 | constructTypeDIE(TyDIE, cast<DICompositeType>(Ty)); | |||
728 | ||||
729 | updateAcceleratorTables(Context, Ty, TyDIE); | |||
730 | return &TyDIE; | |||
731 | } | |||
732 | ||||
733 | DIE *DwarfUnit::getOrCreateTypeDIE(const MDNode *TyNode) { | |||
734 | if (!TyNode) | |||
735 | return nullptr; | |||
736 | ||||
737 | auto *Ty = cast<DIType>(TyNode); | |||
738 | ||||
739 | // DW_TAG_restrict_type is not supported in DWARF2 | |||
740 | if (Ty->getTag() == dwarf::DW_TAG_restrict_type && DD->getDwarfVersion() <= 2) | |||
741 | return getOrCreateTypeDIE(resolve(cast<DIDerivedType>(Ty)->getBaseType())); | |||
742 | ||||
743 | // DW_TAG_atomic_type is not supported in DWARF < 5 | |||
744 | if (Ty->getTag() == dwarf::DW_TAG_atomic_type && DD->getDwarfVersion() < 5) | |||
745 | return getOrCreateTypeDIE(resolve(cast<DIDerivedType>(Ty)->getBaseType())); | |||
746 | ||||
747 | // Construct the context before querying for the existence of the DIE in case | |||
748 | // such construction creates the DIE. | |||
749 | auto *Context = resolve(Ty->getScope()); | |||
750 | DIE *ContextDIE = getOrCreateContextDIE(Context); | |||
751 | assert(ContextDIE)(static_cast <bool> (ContextDIE) ? void (0) : __assert_fail ("ContextDIE", "/build/llvm-toolchain-snapshot-7~svn338205/lib/CodeGen/AsmPrinter/DwarfUnit.cpp" , 751, __extension__ __PRETTY_FUNCTION__)); | |||
752 | ||||
753 | if (DIE *TyDIE = getDIE(Ty)) | |||
754 | return TyDIE; | |||
755 | ||||
756 | // Create new type. | |||
757 | DIE &TyDIE = createAndAddDIE(Ty->getTag(), *ContextDIE, Ty); | |||
758 | ||||
759 | updateAcceleratorTables(Context, Ty, TyDIE); | |||
760 | ||||
761 | if (auto *BT = dyn_cast<DIBasicType>(Ty)) | |||
762 | constructTypeDIE(TyDIE, BT); | |||
763 | else if (auto *STy = dyn_cast<DISubroutineType>(Ty)) | |||
764 | constructTypeDIE(TyDIE, STy); | |||
765 | else if (auto *CTy = dyn_cast<DICompositeType>(Ty)) { | |||
766 | if (DD->generateTypeUnits() && !Ty->isForwardDecl()) | |||
767 | if (MDString *TypeId = CTy->getRawIdentifier()) { | |||
768 | DD->addDwarfTypeUnitType(getCU(), TypeId->getString(), TyDIE, CTy); | |||
769 | // Skip updating the accelerator tables since this is not the full type. | |||
770 | return &TyDIE; | |||
771 | } | |||
772 | constructTypeDIE(TyDIE, CTy); | |||
773 | } else { | |||
774 | constructTypeDIE(TyDIE, cast<DIDerivedType>(Ty)); | |||
775 | } | |||
776 | ||||
777 | return &TyDIE; | |||
778 | } | |||
779 | ||||
780 | void DwarfUnit::updateAcceleratorTables(const DIScope *Context, | |||
781 | const DIType *Ty, const DIE &TyDIE) { | |||
782 | if (!Ty->getName().empty() && !Ty->isForwardDecl()) { | |||
783 | bool IsImplementation = false; | |||
784 | if (auto *CT = dyn_cast<DICompositeType>(Ty)) { | |||
785 | // A runtime language of 0 actually means C/C++ and that any | |||
786 | // non-negative value is some version of Objective-C/C++. | |||
787 | IsImplementation = CT->getRuntimeLang() == 0 || CT->isObjcClassComplete(); | |||
788 | } | |||
789 | unsigned Flags = IsImplementation ? dwarf::DW_FLAG_type_implementation : 0; | |||
790 | DD->addAccelType(Ty->getName(), TyDIE, Flags); | |||
791 | ||||
792 | if (!Context || isa<DICompileUnit>(Context) || isa<DIFile>(Context) || | |||
793 | isa<DINamespace>(Context)) | |||
794 | addGlobalType(Ty, TyDIE, Context); | |||
795 | } | |||
796 | } | |||
797 | ||||
798 | void DwarfUnit::addType(DIE &Entity, const DIType *Ty, | |||
799 | dwarf::Attribute Attribute) { | |||
800 | assert(Ty && "Trying to add a type that doesn't exist?")(static_cast <bool> (Ty && "Trying to add a type that doesn't exist?" ) ? void (0) : __assert_fail ("Ty && \"Trying to add a type that doesn't exist?\"" , "/build/llvm-toolchain-snapshot-7~svn338205/lib/CodeGen/AsmPrinter/DwarfUnit.cpp" , 800, __extension__ __PRETTY_FUNCTION__)); | |||
801 | addDIEEntry(Entity, Attribute, DIEEntry(*getOrCreateTypeDIE(Ty))); | |||
802 | } | |||
803 | ||||
804 | std::string DwarfUnit::getParentContextString(const DIScope *Context) const { | |||
805 | if (!Context) | |||
806 | return ""; | |||
807 | ||||
808 | // FIXME: Decide whether to implement this for non-C++ languages. | |||
809 | if (getLanguage() != dwarf::DW_LANG_C_plus_plus) | |||
810 | return ""; | |||
811 | ||||
812 | std::string CS; | |||
813 | SmallVector<const DIScope *, 1> Parents; | |||
814 | while (!isa<DICompileUnit>(Context)) { | |||
815 | Parents.push_back(Context); | |||
816 | if (Context->getScope()) | |||
817 | Context = resolve(Context->getScope()); | |||
818 | else | |||
819 | // Structure, etc types will have a NULL context if they're at the top | |||
820 | // level. | |||
821 | break; | |||
822 | } | |||
823 | ||||
824 | // Reverse iterate over our list to go from the outermost construct to the | |||
825 | // innermost. | |||
826 | for (const DIScope *Ctx : make_range(Parents.rbegin(), Parents.rend())) { | |||
827 | StringRef Name = Ctx->getName(); | |||
828 | if (Name.empty() && isa<DINamespace>(Ctx)) | |||
829 | Name = "(anonymous namespace)"; | |||
830 | if (!Name.empty()) { | |||
831 | CS += Name; | |||
832 | CS += "::"; | |||
833 | } | |||
834 | } | |||
835 | return CS; | |||
836 | } | |||
837 | ||||
838 | void DwarfUnit::constructTypeDIE(DIE &Buffer, const DIBasicType *BTy) { | |||
839 | // Get core information. | |||
840 | StringRef Name = BTy->getName(); | |||
841 | // Add name if not anonymous or intermediate type. | |||
842 | if (!Name.empty()) | |||
843 | addString(Buffer, dwarf::DW_AT_name, Name); | |||
844 | ||||
845 | // An unspecified type only has a name attribute. | |||
846 | if (BTy->getTag() == dwarf::DW_TAG_unspecified_type) | |||
847 | return; | |||
848 | ||||
849 | addUInt(Buffer, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, | |||
850 | BTy->getEncoding()); | |||
851 | ||||
852 | uint64_t Size = BTy->getSizeInBits() >> 3; | |||
853 | addUInt(Buffer, dwarf::DW_AT_byte_size, None, Size); | |||
854 | } | |||
855 | ||||
856 | void DwarfUnit::constructTypeDIE(DIE &Buffer, const DIDerivedType *DTy) { | |||
857 | // Get core information. | |||
858 | StringRef Name = DTy->getName(); | |||
859 | uint64_t Size = DTy->getSizeInBits() >> 3; | |||
860 | uint16_t Tag = Buffer.getTag(); | |||
861 | ||||
862 | // Map to main type, void will not have a type. | |||
863 | const DIType *FromTy = resolve(DTy->getBaseType()); | |||
864 | if (FromTy) | |||
865 | addType(Buffer, FromTy); | |||
866 | ||||
867 | // Add name if not anonymous or intermediate type. | |||
868 | if (!Name.empty()) | |||
869 | addString(Buffer, dwarf::DW_AT_name, Name); | |||
870 | ||||
871 | // Add size if non-zero (derived types might be zero-sized.) | |||
872 | if (Size && Tag != dwarf::DW_TAG_pointer_type | |||
873 | && Tag != dwarf::DW_TAG_ptr_to_member_type | |||
874 | && Tag != dwarf::DW_TAG_reference_type | |||
875 | && Tag != dwarf::DW_TAG_rvalue_reference_type) | |||
876 | addUInt(Buffer, dwarf::DW_AT_byte_size, None, Size); | |||
877 | ||||
878 | if (Tag == dwarf::DW_TAG_ptr_to_member_type) | |||
879 | addDIEEntry( | |||
880 | Buffer, dwarf::DW_AT_containing_type, | |||
881 | *getOrCreateTypeDIE(resolve(cast<DIDerivedType>(DTy)->getClassType()))); | |||
882 | // Add source line info if available and TyDesc is not a forward declaration. | |||
883 | if (!DTy->isForwardDecl()) | |||
884 | addSourceLine(Buffer, DTy); | |||
885 | ||||
886 | // If DWARF address space value is other than None, add it for pointer and | |||
887 | // reference types as DW_AT_address_class. | |||
888 | if (DTy->getDWARFAddressSpace() && (Tag == dwarf::DW_TAG_pointer_type || | |||
889 | Tag == dwarf::DW_TAG_reference_type)) | |||
890 | addUInt(Buffer, dwarf::DW_AT_address_class, dwarf::DW_FORM_data4, | |||
891 | DTy->getDWARFAddressSpace().getValue()); | |||
892 | } | |||
893 | ||||
894 | void DwarfUnit::constructSubprogramArguments(DIE &Buffer, DITypeRefArray Args) { | |||
895 | for (unsigned i = 1, N = Args.size(); i < N; ++i) { | |||
896 | const DIType *Ty = resolve(Args[i]); | |||
897 | if (!Ty) { | |||
898 | assert(i == N-1 && "Unspecified parameter must be the last argument")(static_cast <bool> (i == N-1 && "Unspecified parameter must be the last argument" ) ? void (0) : __assert_fail ("i == N-1 && \"Unspecified parameter must be the last argument\"" , "/build/llvm-toolchain-snapshot-7~svn338205/lib/CodeGen/AsmPrinter/DwarfUnit.cpp" , 898, __extension__ __PRETTY_FUNCTION__)); | |||
899 | createAndAddDIE(dwarf::DW_TAG_unspecified_parameters, Buffer); | |||
900 | } else { | |||
901 | DIE &Arg = createAndAddDIE(dwarf::DW_TAG_formal_parameter, Buffer); | |||
902 | addType(Arg, Ty); | |||
903 | if (Ty->isArtificial()) | |||
904 | addFlag(Arg, dwarf::DW_AT_artificial); | |||
905 | } | |||
906 | } | |||
907 | } | |||
908 | ||||
909 | void DwarfUnit::constructTypeDIE(DIE &Buffer, const DISubroutineType *CTy) { | |||
910 | // Add return type. A void return won't have a type. | |||
911 | auto Elements = cast<DISubroutineType>(CTy)->getTypeArray(); | |||
912 | if (Elements.size()) | |||
913 | if (auto RTy = resolve(Elements[0])) | |||
914 | addType(Buffer, RTy); | |||
915 | ||||
916 | bool isPrototyped = true; | |||
917 | if (Elements.size() == 2 && !Elements[1]) | |||
918 | isPrototyped = false; | |||
919 | ||||
920 | constructSubprogramArguments(Buffer, Elements); | |||
921 | ||||
922 | // Add prototype flag if we're dealing with a C language and the function has | |||
923 | // been prototyped. | |||
924 | uint16_t Language = getLanguage(); | |||
925 | if (isPrototyped && | |||
926 | (Language == dwarf::DW_LANG_C89 || Language == dwarf::DW_LANG_C99 || | |||
927 | Language == dwarf::DW_LANG_ObjC)) | |||
928 | addFlag(Buffer, dwarf::DW_AT_prototyped); | |||
929 | ||||
930 | // Add a DW_AT_calling_convention if this has an explicit convention. | |||
931 | if (CTy->getCC() && CTy->getCC() != dwarf::DW_CC_normal) | |||
932 | addUInt(Buffer, dwarf::DW_AT_calling_convention, dwarf::DW_FORM_data1, | |||
933 | CTy->getCC()); | |||
934 | ||||
935 | if (CTy->isLValueReference()) | |||
936 | addFlag(Buffer, dwarf::DW_AT_reference); | |||
937 | ||||
938 | if (CTy->isRValueReference()) | |||
939 | addFlag(Buffer, dwarf::DW_AT_rvalue_reference); | |||
940 | } | |||
941 | ||||
942 | void DwarfUnit::constructTypeDIE(DIE &Buffer, const DICompositeType *CTy) { | |||
943 | // Add name if not anonymous or intermediate type. | |||
944 | StringRef Name = CTy->getName(); | |||
945 | ||||
946 | uint64_t Size = CTy->getSizeInBits() >> 3; | |||
947 | uint16_t Tag = Buffer.getTag(); | |||
948 | ||||
949 | switch (Tag) { | |||
950 | case dwarf::DW_TAG_array_type: | |||
951 | constructArrayTypeDIE(Buffer, CTy); | |||
952 | break; | |||
953 | case dwarf::DW_TAG_enumeration_type: | |||
954 | constructEnumTypeDIE(Buffer, CTy); | |||
955 | break; | |||
956 | case dwarf::DW_TAG_variant_part: | |||
957 | case dwarf::DW_TAG_structure_type: | |||
958 | case dwarf::DW_TAG_union_type: | |||
959 | case dwarf::DW_TAG_class_type: { | |||
960 | // Emit the discriminator for a variant part. | |||
961 | DIDerivedType *Discriminator = nullptr; | |||
962 | if (Tag == dwarf::DW_TAG_variant_part) { | |||
963 | Discriminator = CTy->getDiscriminator(); | |||
964 | if (Discriminator) { | |||
965 | // DWARF says: | |||
966 | // If the variant part has a discriminant, the discriminant is | |||
967 | // represented by a separate debugging information entry which is | |||
968 | // a child of the variant part entry. | |||
969 | DIE &DiscMember = constructMemberDIE(Buffer, Discriminator); | |||
970 | addDIEEntry(Buffer, dwarf::DW_AT_discr, DiscMember); | |||
971 | } | |||
972 | } | |||
973 | ||||
974 | // Add elements to structure type. | |||
975 | DINodeArray Elements = CTy->getElements(); | |||
976 | for (const auto *Element : Elements) { | |||
977 | if (!Element) | |||
978 | continue; | |||
979 | if (auto *SP = dyn_cast<DISubprogram>(Element)) | |||
980 | getOrCreateSubprogramDIE(SP); | |||
981 | else if (auto *DDTy = dyn_cast<DIDerivedType>(Element)) { | |||
982 | if (DDTy->getTag() == dwarf::DW_TAG_friend) { | |||
983 | DIE &ElemDie = createAndAddDIE(dwarf::DW_TAG_friend, Buffer); | |||
984 | addType(ElemDie, resolve(DDTy->getBaseType()), dwarf::DW_AT_friend); | |||
985 | } else if (DDTy->isStaticMember()) { | |||
986 | getOrCreateStaticMemberDIE(DDTy); | |||
987 | } else if (Tag == dwarf::DW_TAG_variant_part) { | |||
988 | // When emitting a variant part, wrap each member in | |||
989 | // DW_TAG_variant. | |||
990 | DIE &Variant = createAndAddDIE(dwarf::DW_TAG_variant, Buffer); | |||
991 | if (const ConstantInt *CI = | |||
992 | dyn_cast_or_null<ConstantInt>(DDTy->getDiscriminantValue())) { | |||
993 | if (isUnsignedDIType(DD, resolve(Discriminator->getBaseType()))) | |||
994 | addUInt(Variant, dwarf::DW_AT_discr_value, None, CI->getZExtValue()); | |||
995 | else | |||
996 | addSInt(Variant, dwarf::DW_AT_discr_value, None, CI->getSExtValue()); | |||
997 | } | |||
998 | constructMemberDIE(Variant, DDTy); | |||
999 | } else { | |||
1000 | constructMemberDIE(Buffer, DDTy); | |||
1001 | } | |||
1002 | } else if (auto *Property = dyn_cast<DIObjCProperty>(Element)) { | |||
1003 | DIE &ElemDie = createAndAddDIE(Property->getTag(), Buffer); | |||
1004 | StringRef PropertyName = Property->getName(); | |||
1005 | addString(ElemDie, dwarf::DW_AT_APPLE_property_name, PropertyName); | |||
1006 | if (Property->getType()) | |||
1007 | addType(ElemDie, resolve(Property->getType())); | |||
1008 | addSourceLine(ElemDie, Property); | |||
1009 | StringRef GetterName = Property->getGetterName(); | |||
1010 | if (!GetterName.empty()) | |||
1011 | addString(ElemDie, dwarf::DW_AT_APPLE_property_getter, GetterName); | |||
1012 | StringRef SetterName = Property->getSetterName(); | |||
1013 | if (!SetterName.empty()) | |||
1014 | addString(ElemDie, dwarf::DW_AT_APPLE_property_setter, SetterName); | |||
1015 | if (unsigned PropertyAttributes = Property->getAttributes()) | |||
1016 | addUInt(ElemDie, dwarf::DW_AT_APPLE_property_attribute, None, | |||
1017 | PropertyAttributes); | |||
1018 | } else if (auto *Composite = dyn_cast<DICompositeType>(Element)) { | |||
1019 | if (Composite->getTag() == dwarf::DW_TAG_variant_part) { | |||
1020 | DIE &VariantPart = createAndAddDIE(Composite->getTag(), Buffer); | |||
1021 | constructTypeDIE(VariantPart, Composite); | |||
1022 | } | |||
1023 | } | |||
1024 | } | |||
1025 | ||||
1026 | if (CTy->isAppleBlockExtension()) | |||
1027 | addFlag(Buffer, dwarf::DW_AT_APPLE_block); | |||
1028 | ||||
1029 | // This is outside the DWARF spec, but GDB expects a DW_AT_containing_type | |||
1030 | // inside C++ composite types to point to the base class with the vtable. | |||
1031 | // Rust uses DW_AT_containing_type to link a vtable to the type | |||
1032 | // for which it was created. | |||
1033 | if (auto *ContainingType = resolve(CTy->getVTableHolder())) | |||
1034 | addDIEEntry(Buffer, dwarf::DW_AT_containing_type, | |||
1035 | *getOrCreateTypeDIE(ContainingType)); | |||
1036 | ||||
1037 | if (CTy->isObjcClassComplete()) | |||
1038 | addFlag(Buffer, dwarf::DW_AT_APPLE_objc_complete_type); | |||
1039 | ||||
1040 | // Add template parameters to a class, structure or union types. | |||
1041 | // FIXME: The support isn't in the metadata for this yet. | |||
1042 | if (Tag == dwarf::DW_TAG_class_type || | |||
1043 | Tag == dwarf::DW_TAG_structure_type || Tag == dwarf::DW_TAG_union_type) | |||
1044 | addTemplateParams(Buffer, CTy->getTemplateParams()); | |||
1045 | ||||
1046 | // Add the type's non-standard calling convention. | |||
1047 | uint8_t CC = 0; | |||
1048 | if (CTy->isTypePassByValue()) | |||
1049 | CC = dwarf::DW_CC_pass_by_value; | |||
1050 | else if (CTy->isTypePassByReference()) | |||
1051 | CC = dwarf::DW_CC_pass_by_reference; | |||
1052 | if (CC) | |||
1053 | addUInt(Buffer, dwarf::DW_AT_calling_convention, dwarf::DW_FORM_data1, | |||
1054 | CC); | |||
1055 | break; | |||
1056 | } | |||
1057 | default: | |||
1058 | break; | |||
1059 | } | |||
1060 | ||||
1061 | // Add name if not anonymous or intermediate type. | |||
1062 | if (!Name.empty()) | |||
1063 | addString(Buffer, dwarf::DW_AT_name, Name); | |||
1064 | ||||
1065 | if (Tag == dwarf::DW_TAG_enumeration_type || | |||
1066 | Tag == dwarf::DW_TAG_class_type || Tag == dwarf::DW_TAG_structure_type || | |||
1067 | Tag == dwarf::DW_TAG_union_type) { | |||
1068 | // Add size if non-zero (derived types might be zero-sized.) | |||
1069 | // TODO: Do we care about size for enum forward declarations? | |||
1070 | if (Size) | |||
1071 | addUInt(Buffer, dwarf::DW_AT_byte_size, None, Size); | |||
1072 | else if (!CTy->isForwardDecl()) | |||
1073 | // Add zero size if it is not a forward declaration. | |||
1074 | addUInt(Buffer, dwarf::DW_AT_byte_size, None, 0); | |||
1075 | ||||
1076 | // If we're a forward decl, say so. | |||
1077 | if (CTy->isForwardDecl()) | |||
1078 | addFlag(Buffer, dwarf::DW_AT_declaration); | |||
1079 | ||||
1080 | // Add source line info if available. | |||
1081 | if (!CTy->isForwardDecl()) | |||
1082 | addSourceLine(Buffer, CTy); | |||
1083 | ||||
1084 | // No harm in adding the runtime language to the declaration. | |||
1085 | unsigned RLang = CTy->getRuntimeLang(); | |||
1086 | if (RLang) | |||
1087 | addUInt(Buffer, dwarf::DW_AT_APPLE_runtime_class, dwarf::DW_FORM_data1, | |||
1088 | RLang); | |||
1089 | ||||
1090 | // Add align info if available. | |||
1091 | if (uint32_t AlignInBytes = CTy->getAlignInBytes()) | |||
1092 | addUInt(Buffer, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata, | |||
1093 | AlignInBytes); | |||
1094 | } | |||
1095 | } | |||
1096 | ||||
1097 | void DwarfUnit::constructTemplateTypeParameterDIE( | |||
1098 | DIE &Buffer, const DITemplateTypeParameter *TP) { | |||
1099 | DIE &ParamDIE = | |||
1100 | createAndAddDIE(dwarf::DW_TAG_template_type_parameter, Buffer); | |||
1101 | // Add the type if it exists, it could be void and therefore no type. | |||
1102 | if (TP->getType()) | |||
1103 | addType(ParamDIE, resolve(TP->getType())); | |||
1104 | if (!TP->getName().empty()) | |||
1105 | addString(ParamDIE, dwarf::DW_AT_name, TP->getName()); | |||
1106 | } | |||
1107 | ||||
1108 | void DwarfUnit::constructTemplateValueParameterDIE( | |||
1109 | DIE &Buffer, const DITemplateValueParameter *VP) { | |||
1110 | DIE &ParamDIE = createAndAddDIE(VP->getTag(), Buffer); | |||
1111 | ||||
1112 | // Add the type if there is one, template template and template parameter | |||
1113 | // packs will not have a type. | |||
1114 | if (VP->getTag() == dwarf::DW_TAG_template_value_parameter) | |||
1115 | addType(ParamDIE, resolve(VP->getType())); | |||
1116 | if (!VP->getName().empty()) | |||
1117 | addString(ParamDIE, dwarf::DW_AT_name, VP->getName()); | |||
1118 | if (Metadata *Val = VP->getValue()) { | |||
1119 | if (ConstantInt *CI = mdconst::dyn_extract<ConstantInt>(Val)) | |||
1120 | addConstantValue(ParamDIE, CI, resolve(VP->getType())); | |||
1121 | else if (GlobalValue *GV = mdconst::dyn_extract<GlobalValue>(Val)) { | |||
1122 | // We cannot describe the location of dllimport'd entities: the | |||
1123 | // computation of their address requires loads from the IAT. | |||
1124 | if (!GV->hasDLLImportStorageClass()) { | |||
1125 | // For declaration non-type template parameters (such as global values | |||
1126 | // and functions) | |||
1127 | DIELoc *Loc = new (DIEValueAllocator) DIELoc; | |||
1128 | addOpAddress(*Loc, Asm->getSymbol(GV)); | |||
1129 | // Emit DW_OP_stack_value to use the address as the immediate value of | |||
1130 | // the parameter, rather than a pointer to it. | |||
1131 | addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_stack_value); | |||
1132 | addBlock(ParamDIE, dwarf::DW_AT_location, Loc); | |||
1133 | } | |||
1134 | } else if (VP->getTag() == dwarf::DW_TAG_GNU_template_template_param) { | |||
1135 | assert(isa<MDString>(Val))(static_cast <bool> (isa<MDString>(Val)) ? void ( 0) : __assert_fail ("isa<MDString>(Val)", "/build/llvm-toolchain-snapshot-7~svn338205/lib/CodeGen/AsmPrinter/DwarfUnit.cpp" , 1135, __extension__ __PRETTY_FUNCTION__)); | |||
1136 | addString(ParamDIE, dwarf::DW_AT_GNU_template_name, | |||
1137 | cast<MDString>(Val)->getString()); | |||
1138 | } else if (VP->getTag() == dwarf::DW_TAG_GNU_template_parameter_pack) { | |||
1139 | addTemplateParams(ParamDIE, cast<MDTuple>(Val)); | |||
1140 | } | |||
1141 | } | |||
1142 | } | |||
1143 | ||||
1144 | DIE *DwarfUnit::getOrCreateNameSpace(const DINamespace *NS) { | |||
1145 | // Construct the context before querying for the existence of the DIE in case | |||
1146 | // such construction creates the DIE. | |||
1147 | DIE *ContextDIE = getOrCreateContextDIE(NS->getScope()); | |||
1148 | ||||
1149 | if (DIE *NDie = getDIE(NS)) | |||
1150 | return NDie; | |||
1151 | DIE &NDie = createAndAddDIE(dwarf::DW_TAG_namespace, *ContextDIE, NS); | |||
1152 | ||||
1153 | StringRef Name = NS->getName(); | |||
1154 | if (!Name.empty()) | |||
1155 | addString(NDie, dwarf::DW_AT_name, NS->getName()); | |||
1156 | else | |||
1157 | Name = "(anonymous namespace)"; | |||
1158 | DD->addAccelNamespace(Name, NDie); | |||
1159 | addGlobalName(Name, NDie, NS->getScope()); | |||
1160 | if (NS->getExportSymbols()) | |||
1161 | addFlag(NDie, dwarf::DW_AT_export_symbols); | |||
1162 | return &NDie; | |||
1163 | } | |||
1164 | ||||
1165 | DIE *DwarfUnit::getOrCreateModule(const DIModule *M) { | |||
1166 | // Construct the context before querying for the existence of the DIE in case | |||
1167 | // such construction creates the DIE. | |||
1168 | DIE *ContextDIE = getOrCreateContextDIE(M->getScope()); | |||
1169 | ||||
1170 | if (DIE *MDie = getDIE(M)) | |||
1171 | return MDie; | |||
1172 | DIE &MDie = createAndAddDIE(dwarf::DW_TAG_module, *ContextDIE, M); | |||
1173 | ||||
1174 | if (!M->getName().empty()) { | |||
1175 | addString(MDie, dwarf::DW_AT_name, M->getName()); | |||
1176 | addGlobalName(M->getName(), MDie, M->getScope()); | |||
1177 | } | |||
1178 | if (!M->getConfigurationMacros().empty()) | |||
1179 | addString(MDie, dwarf::DW_AT_LLVM_config_macros, | |||
1180 | M->getConfigurationMacros()); | |||
1181 | if (!M->getIncludePath().empty()) | |||
1182 | addString(MDie, dwarf::DW_AT_LLVM_include_path, M->getIncludePath()); | |||
1183 | if (!M->getISysRoot().empty()) | |||
1184 | addString(MDie, dwarf::DW_AT_LLVM_isysroot, M->getISysRoot()); | |||
1185 | ||||
1186 | return &MDie; | |||
1187 | } | |||
1188 | ||||
1189 | DIE *DwarfUnit::getOrCreateSubprogramDIE(const DISubprogram *SP, bool Minimal) { | |||
1190 | // Construct the context before querying for the existence of the DIE in case | |||
1191 | // such construction creates the DIE (as is the case for member function | |||
1192 | // declarations). | |||
1193 | DIE *ContextDIE = | |||
1194 | Minimal ? &getUnitDie() : getOrCreateContextDIE(resolve(SP->getScope())); | |||
1195 | ||||
1196 | if (DIE *SPDie = getDIE(SP)) | |||
1197 | return SPDie; | |||
1198 | ||||
1199 | if (auto *SPDecl = SP->getDeclaration()) { | |||
1200 | if (!Minimal) { | |||
1201 | // Add subprogram definitions to the CU die directly. | |||
1202 | ContextDIE = &getUnitDie(); | |||
1203 | // Build the decl now to ensure it precedes the definition. | |||
1204 | getOrCreateSubprogramDIE(SPDecl); | |||
1205 | } | |||
1206 | } | |||
1207 | ||||
1208 | // DW_TAG_inlined_subroutine may refer to this DIE. | |||
1209 | DIE &SPDie = createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE, SP); | |||
1210 | ||||
1211 | // Stop here and fill this in later, depending on whether or not this | |||
1212 | // subprogram turns out to have inlined instances or not. | |||
1213 | if (SP->isDefinition()) | |||
1214 | return &SPDie; | |||
1215 | ||||
1216 | applySubprogramAttributes(SP, SPDie); | |||
1217 | return &SPDie; | |||
1218 | } | |||
1219 | ||||
1220 | bool DwarfUnit::applySubprogramDefinitionAttributes(const DISubprogram *SP, | |||
1221 | DIE &SPDie) { | |||
1222 | DIE *DeclDie = nullptr; | |||
1223 | StringRef DeclLinkageName; | |||
1224 | if (auto *SPDecl = SP->getDeclaration()) { | |||
1225 | DeclDie = getDIE(SPDecl); | |||
1226 | assert(DeclDie && "This DIE should've already been constructed when the "(static_cast <bool> (DeclDie && "This DIE should've already been constructed when the " "definition DIE was created in " "getOrCreateSubprogramDIE") ? void (0) : __assert_fail ("DeclDie && \"This DIE should've already been constructed when the \" \"definition DIE was created in \" \"getOrCreateSubprogramDIE\"" , "/build/llvm-toolchain-snapshot-7~svn338205/lib/CodeGen/AsmPrinter/DwarfUnit.cpp" , 1228, __extension__ __PRETTY_FUNCTION__)) | |||
1227 | "definition DIE was created in "(static_cast <bool> (DeclDie && "This DIE should've already been constructed when the " "definition DIE was created in " "getOrCreateSubprogramDIE") ? void (0) : __assert_fail ("DeclDie && \"This DIE should've already been constructed when the \" \"definition DIE was created in \" \"getOrCreateSubprogramDIE\"" , "/build/llvm-toolchain-snapshot-7~svn338205/lib/CodeGen/AsmPrinter/DwarfUnit.cpp" , 1228, __extension__ __PRETTY_FUNCTION__)) | |||
1228 | "getOrCreateSubprogramDIE")(static_cast <bool> (DeclDie && "This DIE should've already been constructed when the " "definition DIE was created in " "getOrCreateSubprogramDIE") ? void (0) : __assert_fail ("DeclDie && \"This DIE should've already been constructed when the \" \"definition DIE was created in \" \"getOrCreateSubprogramDIE\"" , "/build/llvm-toolchain-snapshot-7~svn338205/lib/CodeGen/AsmPrinter/DwarfUnit.cpp" , 1228, __extension__ __PRETTY_FUNCTION__)); | |||
1229 | // Look at the Decl's linkage name only if we emitted it. | |||
1230 | if (DD->useAllLinkageNames()) | |||
1231 | DeclLinkageName = SPDecl->getLinkageName(); | |||
1232 | unsigned DeclID = getOrCreateSourceID(SPDecl->getFile()); | |||
1233 | unsigned DefID = getOrCreateSourceID(SP->getFile()); | |||
1234 | if (DeclID != DefID) | |||
1235 | addUInt(SPDie, dwarf::DW_AT_decl_file, None, DefID); | |||
1236 | ||||
1237 | if (SP->getLine() != SPDecl->getLine()) | |||
1238 | addUInt(SPDie, dwarf::DW_AT_decl_line, None, SP->getLine()); | |||
1239 | } | |||
1240 | ||||
1241 | // Add function template parameters. | |||
1242 | addTemplateParams(SPDie, SP->getTemplateParams()); | |||
1243 | ||||
1244 | // Add the linkage name if we have one and it isn't in the Decl. | |||
1245 | StringRef LinkageName = SP->getLinkageName(); | |||
1246 | assert(((LinkageName.empty() || DeclLinkageName.empty()) ||(static_cast <bool> (((LinkageName.empty() || DeclLinkageName .empty()) || LinkageName == DeclLinkageName) && "decl has a linkage name and it is different" ) ? void (0) : __assert_fail ("((LinkageName.empty() || DeclLinkageName.empty()) || LinkageName == DeclLinkageName) && \"decl has a linkage name and it is different\"" , "/build/llvm-toolchain-snapshot-7~svn338205/lib/CodeGen/AsmPrinter/DwarfUnit.cpp" , 1248, __extension__ __PRETTY_FUNCTION__)) | |||
1247 | LinkageName == DeclLinkageName) &&(static_cast <bool> (((LinkageName.empty() || DeclLinkageName .empty()) || LinkageName == DeclLinkageName) && "decl has a linkage name and it is different" ) ? void (0) : __assert_fail ("((LinkageName.empty() || DeclLinkageName.empty()) || LinkageName == DeclLinkageName) && \"decl has a linkage name and it is different\"" , "/build/llvm-toolchain-snapshot-7~svn338205/lib/CodeGen/AsmPrinter/DwarfUnit.cpp" , 1248, __extension__ __PRETTY_FUNCTION__)) | |||
1248 | "decl has a linkage name and it is different")(static_cast <bool> (((LinkageName.empty() || DeclLinkageName .empty()) || LinkageName == DeclLinkageName) && "decl has a linkage name and it is different" ) ? void (0) : __assert_fail ("((LinkageName.empty() || DeclLinkageName.empty()) || LinkageName == DeclLinkageName) && \"decl has a linkage name and it is different\"" , "/build/llvm-toolchain-snapshot-7~svn338205/lib/CodeGen/AsmPrinter/DwarfUnit.cpp" , 1248, __extension__ __PRETTY_FUNCTION__)); | |||
1249 | if (DeclLinkageName.empty() && | |||
1250 | // Always emit it for abstract subprograms. | |||
1251 | (DD->useAllLinkageNames() || DU->getAbstractSPDies().lookup(SP))) | |||
1252 | addLinkageName(SPDie, LinkageName); | |||
1253 | ||||
1254 | if (!DeclDie) | |||
1255 | return false; | |||
1256 | ||||
1257 | // Refer to the function declaration where all the other attributes will be | |||
1258 | // found. | |||
1259 | addDIEEntry(SPDie, dwarf::DW_AT_specification, *DeclDie); | |||
1260 | return true; | |||
1261 | } | |||
1262 | ||||
1263 | void DwarfUnit::applySubprogramAttributes(const DISubprogram *SP, DIE &SPDie, | |||
1264 | bool SkipSPAttributes) { | |||
1265 | // If -fdebug-info-for-profiling is enabled, need to emit the subprogram | |||
1266 | // and its source location. | |||
1267 | bool SkipSPSourceLocation = SkipSPAttributes && | |||
1268 | !CUNode->getDebugInfoForProfiling(); | |||
1269 | if (!SkipSPSourceLocation) | |||
1270 | if (applySubprogramDefinitionAttributes(SP, SPDie)) | |||
1271 | return; | |||
1272 | ||||
1273 | // Constructors and operators for anonymous aggregates do not have names. | |||
1274 | if (!SP->getName().empty()) | |||
1275 | addString(SPDie, dwarf::DW_AT_name, SP->getName()); | |||
1276 | ||||
1277 | if (!SkipSPSourceLocation) | |||
1278 | addSourceLine(SPDie, SP); | |||
1279 | ||||
1280 | // Skip the rest of the attributes under -gmlt to save space. | |||
1281 | if (SkipSPAttributes) | |||
1282 | return; | |||
1283 | ||||
1284 | // Add the prototype if we have a prototype and we have a C like | |||
1285 | // language. | |||
1286 | uint16_t Language = getLanguage(); | |||
1287 | if (SP->isPrototyped() && | |||
1288 | (Language == dwarf::DW_LANG_C89 || Language == dwarf::DW_LANG_C99 || | |||
1289 | Language == dwarf::DW_LANG_ObjC)) | |||
1290 | addFlag(SPDie, dwarf::DW_AT_prototyped); | |||
1291 | ||||
1292 | unsigned CC = 0; | |||
1293 | DITypeRefArray Args; | |||
1294 | if (const DISubroutineType *SPTy = SP->getType()) { | |||
1295 | Args = SPTy->getTypeArray(); | |||
1296 | CC = SPTy->getCC(); | |||
1297 | } | |||
1298 | ||||
1299 | // Add a DW_AT_calling_convention if this has an explicit convention. | |||
1300 | if (CC && CC != dwarf::DW_CC_normal) | |||
1301 | addUInt(SPDie, dwarf::DW_AT_calling_convention, dwarf::DW_FORM_data1, CC); | |||
1302 | ||||
1303 | // Add a return type. If this is a type like a C/C++ void type we don't add a | |||
1304 | // return type. | |||
1305 | if (Args.size()) | |||
1306 | if (auto Ty = resolve(Args[0])) | |||
1307 | addType(SPDie, Ty); | |||
1308 | ||||
1309 | unsigned VK = SP->getVirtuality(); | |||
1310 | if (VK) { | |||
1311 | addUInt(SPDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_data1, VK); | |||
1312 | if (SP->getVirtualIndex() != -1u) { | |||
1313 | DIELoc *Block = getDIELoc(); | |||
1314 | addUInt(*Block, dwarf::DW_FORM_data1, dwarf::DW_OP_constu); | |||
1315 | addUInt(*Block, dwarf::DW_FORM_udata, SP->getVirtualIndex()); | |||
1316 | addBlock(SPDie, dwarf::DW_AT_vtable_elem_location, Block); | |||
1317 | } | |||
1318 | ContainingTypeMap.insert( | |||
1319 | std::make_pair(&SPDie, resolve(SP->getContainingType()))); | |||
1320 | } | |||
1321 | ||||
1322 | if (!SP->isDefinition()) { | |||
1323 | addFlag(SPDie, dwarf::DW_AT_declaration); | |||
1324 | ||||
1325 | // Add arguments. Do not add arguments for subprogram definition. They will | |||
1326 | // be handled while processing variables. | |||
1327 | constructSubprogramArguments(SPDie, Args); | |||
1328 | } | |||
1329 | ||||
1330 | addThrownTypes(SPDie, SP->getThrownTypes()); | |||
1331 | ||||
1332 | if (SP->isArtificial()) | |||
1333 | addFlag(SPDie, dwarf::DW_AT_artificial); | |||
1334 | ||||
1335 | if (!SP->isLocalToUnit()) | |||
1336 | addFlag(SPDie, dwarf::DW_AT_external); | |||
1337 | ||||
1338 | if (DD->useAppleExtensionAttributes()) { | |||
1339 | if (SP->isOptimized()) | |||
1340 | addFlag(SPDie, dwarf::DW_AT_APPLE_optimized); | |||
1341 | ||||
1342 | if (unsigned isa = Asm->getISAEncoding()) | |||
1343 | addUInt(SPDie, dwarf::DW_AT_APPLE_isa, dwarf::DW_FORM_flag, isa); | |||
1344 | } | |||
1345 | ||||
1346 | if (SP->isLValueReference()) | |||
1347 | addFlag(SPDie, dwarf::DW_AT_reference); | |||
1348 | ||||
1349 | if (SP->isRValueReference()) | |||
1350 | addFlag(SPDie, dwarf::DW_AT_rvalue_reference); | |||
1351 | ||||
1352 | if (SP->isNoReturn()) | |||
1353 | addFlag(SPDie, dwarf::DW_AT_noreturn); | |||
1354 | ||||
1355 | if (SP->isProtected()) | |||
1356 | addUInt(SPDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1, | |||
1357 | dwarf::DW_ACCESS_protected); | |||
1358 | else if (SP->isPrivate()) | |||
1359 | addUInt(SPDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1, | |||
1360 | dwarf::DW_ACCESS_private); | |||
1361 | else if (SP->isPublic()) | |||
1362 | addUInt(SPDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1, | |||
1363 | dwarf::DW_ACCESS_public); | |||
1364 | ||||
1365 | if (SP->isExplicit()) | |||
1366 | addFlag(SPDie, dwarf::DW_AT_explicit); | |||
1367 | ||||
1368 | if (SP->isMainSubprogram()) | |||
1369 | addFlag(SPDie, dwarf::DW_AT_main_subprogram); | |||
1370 | } | |||
1371 | ||||
1372 | void DwarfUnit::constructSubrangeDIE(DIE &Buffer, const DISubrange *SR, | |||
1373 | DIE *IndexTy) { | |||
1374 | DIE &DW_Subrange = createAndAddDIE(dwarf::DW_TAG_subrange_type, Buffer); | |||
1375 | addDIEEntry(DW_Subrange, dwarf::DW_AT_type, *IndexTy); | |||
1376 | ||||
1377 | // The LowerBound value defines the lower bounds which is typically zero for | |||
1378 | // C/C++. The Count value is the number of elements. Values are 64 bit. If | |||
1379 | // Count == -1 then the array is unbounded and we do not emit | |||
1380 | // DW_AT_lower_bound and DW_AT_count attributes. | |||
1381 | int64_t LowerBound = SR->getLowerBound(); | |||
1382 | int64_t DefaultLowerBound = getDefaultLowerBound(); | |||
1383 | int64_t Count = -1; | |||
1384 | if (auto *CI = SR->getCount().dyn_cast<ConstantInt*>()) | |||
1385 | Count = CI->getSExtValue(); | |||
1386 | ||||
1387 | if (DefaultLowerBound == -1 || LowerBound != DefaultLowerBound) | |||
1388 | addUInt(DW_Subrange, dwarf::DW_AT_lower_bound, None, LowerBound); | |||
1389 | ||||
1390 | if (auto *CV = SR->getCount().dyn_cast<DIVariable*>()) { | |||
1391 | if (auto *CountVarDIE = getDIE(CV)) | |||
1392 | addDIEEntry(DW_Subrange, dwarf::DW_AT_count, *CountVarDIE); | |||
1393 | } else if (Count != -1) | |||
1394 | addUInt(DW_Subrange, dwarf::DW_AT_count, None, Count); | |||
1395 | } | |||
1396 | ||||
1397 | DIE *DwarfUnit::getIndexTyDie() { | |||
1398 | if (IndexTyDie) | |||
1399 | return IndexTyDie; | |||
1400 | // Construct an integer type to use for indexes. | |||
1401 | IndexTyDie = &createAndAddDIE(dwarf::DW_TAG_base_type, getUnitDie()); | |||
1402 | StringRef Name = "__ARRAY_SIZE_TYPE__"; | |||
1403 | addString(*IndexTyDie, dwarf::DW_AT_name, Name); | |||
1404 | addUInt(*IndexTyDie, dwarf::DW_AT_byte_size, None, sizeof(int64_t)); | |||
1405 | addUInt(*IndexTyDie, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, | |||
1406 | dwarf::DW_ATE_unsigned); | |||
1407 | DD->addAccelType(Name, *IndexTyDie, /*Flags*/ 0); | |||
1408 | return IndexTyDie; | |||
1409 | } | |||
1410 | ||||
1411 | /// Returns true if the vector's size differs from the sum of sizes of elements | |||
1412 | /// the user specified. This can occur if the vector has been rounded up to | |||
1413 | /// fit memory alignment constraints. | |||
1414 | static bool hasVectorBeenPadded(const DICompositeType *CTy) { | |||
1415 | assert(CTy && CTy->isVector() && "Composite type is not a vector")(static_cast <bool> (CTy && CTy->isVector() && "Composite type is not a vector") ? void (0) : __assert_fail ("CTy && CTy->isVector() && \"Composite type is not a vector\"" , "/build/llvm-toolchain-snapshot-7~svn338205/lib/CodeGen/AsmPrinter/DwarfUnit.cpp" , 1415, __extension__ __PRETTY_FUNCTION__)); | |||
1416 | const uint64_t ActualSize = CTy->getSizeInBits(); | |||
1417 | ||||
1418 | // Obtain the size of each element in the vector. | |||
1419 | DIType *BaseTy = CTy->getBaseType().resolve(); | |||
1420 | assert(BaseTy && "Unknown vector element type.")(static_cast <bool> (BaseTy && "Unknown vector element type." ) ? void (0) : __assert_fail ("BaseTy && \"Unknown vector element type.\"" , "/build/llvm-toolchain-snapshot-7~svn338205/lib/CodeGen/AsmPrinter/DwarfUnit.cpp" , 1420, __extension__ __PRETTY_FUNCTION__)); | |||
1421 | const uint64_t ElementSize = BaseTy->getSizeInBits(); | |||
1422 | ||||
1423 | // Locate the number of elements in the vector. | |||
1424 | const DINodeArray Elements = CTy->getElements(); | |||
1425 | assert(Elements.size() == 1 &&(static_cast <bool> (Elements.size() == 1 && Elements [0]->getTag() == dwarf::DW_TAG_subrange_type && "Invalid vector element array, expected one element of type subrange" ) ? void (0) : __assert_fail ("Elements.size() == 1 && Elements[0]->getTag() == dwarf::DW_TAG_subrange_type && \"Invalid vector element array, expected one element of type subrange\"" , "/build/llvm-toolchain-snapshot-7~svn338205/lib/CodeGen/AsmPrinter/DwarfUnit.cpp" , 1427, __extension__ __PRETTY_FUNCTION__)) | |||
1426 | Elements[0]->getTag() == dwarf::DW_TAG_subrange_type &&(static_cast <bool> (Elements.size() == 1 && Elements [0]->getTag() == dwarf::DW_TAG_subrange_type && "Invalid vector element array, expected one element of type subrange" ) ? void (0) : __assert_fail ("Elements.size() == 1 && Elements[0]->getTag() == dwarf::DW_TAG_subrange_type && \"Invalid vector element array, expected one element of type subrange\"" , "/build/llvm-toolchain-snapshot-7~svn338205/lib/CodeGen/AsmPrinter/DwarfUnit.cpp" , 1427, __extension__ __PRETTY_FUNCTION__)) | |||
1427 | "Invalid vector element array, expected one element of type subrange")(static_cast <bool> (Elements.size() == 1 && Elements [0]->getTag() == dwarf::DW_TAG_subrange_type && "Invalid vector element array, expected one element of type subrange" ) ? void (0) : __assert_fail ("Elements.size() == 1 && Elements[0]->getTag() == dwarf::DW_TAG_subrange_type && \"Invalid vector element array, expected one element of type subrange\"" , "/build/llvm-toolchain-snapshot-7~svn338205/lib/CodeGen/AsmPrinter/DwarfUnit.cpp" , 1427, __extension__ __PRETTY_FUNCTION__)); | |||
1428 | const auto Subrange = cast<DISubrange>(Elements[0]); | |||
1429 | const auto CI = Subrange->getCount().get<ConstantInt *>(); | |||
1430 | const int32_t NumVecElements = CI->getSExtValue(); | |||
1431 | ||||
1432 | // Ensure we found the element count and that the actual size is wide | |||
1433 | // enough to contain the requested size. | |||
1434 | assert(ActualSize >= (NumVecElements * ElementSize) && "Invalid vector size")(static_cast <bool> (ActualSize >= (NumVecElements * ElementSize) && "Invalid vector size") ? void (0) : __assert_fail ("ActualSize >= (NumVecElements * ElementSize) && \"Invalid vector size\"" , "/build/llvm-toolchain-snapshot-7~svn338205/lib/CodeGen/AsmPrinter/DwarfUnit.cpp" , 1434, __extension__ __PRETTY_FUNCTION__)); | |||
1435 | return ActualSize != (NumVecElements * ElementSize); | |||
1436 | } | |||
1437 | ||||
1438 | void DwarfUnit::constructArrayTypeDIE(DIE &Buffer, const DICompositeType *CTy) { | |||
1439 | if (CTy->isVector()) { | |||
1440 | addFlag(Buffer, dwarf::DW_AT_GNU_vector); | |||
1441 | if (hasVectorBeenPadded(CTy)) | |||
1442 | addUInt(Buffer, dwarf::DW_AT_byte_size, None, | |||
1443 | CTy->getSizeInBits() / CHAR_BIT8); | |||
1444 | } | |||
1445 | ||||
1446 | // Emit the element type. | |||
1447 | addType(Buffer, resolve(CTy->getBaseType())); | |||
1448 | ||||
1449 | // Get an anonymous type for index type. | |||
1450 | // FIXME: This type should be passed down from the front end | |||
1451 | // as different languages may have different sizes for indexes. | |||
1452 | DIE *IdxTy = getIndexTyDie(); | |||
1453 | ||||
1454 | // Add subranges to array type. | |||
1455 | DINodeArray Elements = CTy->getElements(); | |||
1456 | for (unsigned i = 0, N = Elements.size(); i < N; ++i) { | |||
1457 | // FIXME: Should this really be such a loose cast? | |||
1458 | if (auto *Element = dyn_cast_or_null<DINode>(Elements[i])) | |||
1459 | if (Element->getTag() == dwarf::DW_TAG_subrange_type) | |||
1460 | constructSubrangeDIE(Buffer, cast<DISubrange>(Element), IdxTy); | |||
1461 | } | |||
1462 | } | |||
1463 | ||||
1464 | void DwarfUnit::constructEnumTypeDIE(DIE &Buffer, const DICompositeType *CTy) { | |||
1465 | const DIType *DTy = resolve(CTy->getBaseType()); | |||
1466 | bool IsUnsigned = DTy && isUnsignedDIType(DD, DTy); | |||
1467 | if (DTy) { | |||
1468 | if (DD->getDwarfVersion() >= 3) | |||
1469 | addType(Buffer, DTy); | |||
1470 | if (DD->getDwarfVersion() >= 4 && (CTy->getFlags() & DINode::FlagFixedEnum)) | |||
1471 | addFlag(Buffer, dwarf::DW_AT_enum_class); | |||
1472 | } | |||
1473 | ||||
1474 | DINodeArray Elements = CTy->getElements(); | |||
1475 | ||||
1476 | // Add enumerators to enumeration type. | |||
1477 | for (unsigned i = 0, N = Elements.size(); i < N; ++i) { | |||
1478 | auto *Enum = dyn_cast_or_null<DIEnumerator>(Elements[i]); | |||
1479 | if (Enum) { | |||
1480 | DIE &Enumerator = createAndAddDIE(dwarf::DW_TAG_enumerator, Buffer); | |||
1481 | StringRef Name = Enum->getName(); | |||
1482 | addString(Enumerator, dwarf::DW_AT_name, Name); | |||
1483 | auto Value = static_cast<uint64_t>(Enum->getValue()); | |||
1484 | addConstantValue(Enumerator, IsUnsigned, Value); | |||
1485 | } | |||
1486 | } | |||
1487 | } | |||
1488 | ||||
1489 | void DwarfUnit::constructContainingTypeDIEs() { | |||
1490 | for (auto CI = ContainingTypeMap.begin(), CE = ContainingTypeMap.end(); | |||
1491 | CI != CE; ++CI) { | |||
1492 | DIE &SPDie = *CI->first; | |||
1493 | const DINode *D = CI->second; | |||
1494 | if (!D) | |||
1495 | continue; | |||
1496 | DIE *NDie = getDIE(D); | |||
1497 | if (!NDie) | |||
1498 | continue; | |||
1499 | addDIEEntry(SPDie, dwarf::DW_AT_containing_type, *NDie); | |||
1500 | } | |||
1501 | } | |||
1502 | ||||
1503 | DIE &DwarfUnit::constructMemberDIE(DIE &Buffer, const DIDerivedType *DT) { | |||
1504 | DIE &MemberDie = createAndAddDIE(DT->getTag(), Buffer); | |||
1505 | StringRef Name = DT->getName(); | |||
1506 | if (!Name.empty()) | |||
1507 | addString(MemberDie, dwarf::DW_AT_name, Name); | |||
1508 | ||||
1509 | if (DIType *Resolved = resolve(DT->getBaseType())) | |||
1510 | addType(MemberDie, Resolved); | |||
1511 | ||||
1512 | addSourceLine(MemberDie, DT); | |||
1513 | ||||
1514 | if (DT->getTag() == dwarf::DW_TAG_inheritance && DT->isVirtual()) { | |||
1515 | ||||
1516 | // For C++, virtual base classes are not at fixed offset. Use following | |||
1517 | // expression to extract appropriate offset from vtable. | |||
1518 | // BaseAddr = ObAddr + *((*ObAddr) - Offset) | |||
1519 | ||||
1520 | DIELoc *VBaseLocationDie = new (DIEValueAllocator) DIELoc; | |||
1521 | addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_dup); | |||
1522 | addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_deref); | |||
1523 | addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_constu); | |||
1524 | addUInt(*VBaseLocationDie, dwarf::DW_FORM_udata, DT->getOffsetInBits()); | |||
1525 | addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_minus); | |||
1526 | addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_deref); | |||
1527 | addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_plus); | |||
1528 | ||||
1529 | addBlock(MemberDie, dwarf::DW_AT_data_member_location, VBaseLocationDie); | |||
1530 | } else { | |||
1531 | uint64_t Size = DT->getSizeInBits(); | |||
1532 | uint64_t FieldSize = DD->getBaseTypeSize(DT); | |||
1533 | uint32_t AlignInBytes = DT->getAlignInBytes(); | |||
1534 | uint64_t OffsetInBytes; | |||
1535 | ||||
1536 | bool IsBitfield = FieldSize && Size != FieldSize; | |||
1537 | if (IsBitfield) { | |||
1538 | // Handle bitfield, assume bytes are 8 bits. | |||
1539 | if (DD->useDWARF2Bitfields()) | |||
1540 | addUInt(MemberDie, dwarf::DW_AT_byte_size, None, FieldSize/8); | |||
1541 | addUInt(MemberDie, dwarf::DW_AT_bit_size, None, Size); | |||
1542 | ||||
1543 | uint64_t Offset = DT->getOffsetInBits(); | |||
1544 | // We can't use DT->getAlignInBits() here: AlignInBits for member type | |||
1545 | // is non-zero if and only if alignment was forced (e.g. _Alignas()), | |||
1546 | // which can't be done with bitfields. Thus we use FieldSize here. | |||
1547 | uint32_t AlignInBits = FieldSize; | |||
1548 | uint32_t AlignMask = ~(AlignInBits - 1); | |||
1549 | // The bits from the start of the storage unit to the start of the field. | |||
1550 | uint64_t StartBitOffset = Offset - (Offset & AlignMask); | |||
1551 | // The byte offset of the field's aligned storage unit inside the struct. | |||
1552 | OffsetInBytes = (Offset - StartBitOffset) / 8; | |||
1553 | ||||
1554 | if (DD->useDWARF2Bitfields()) { | |||
1555 | uint64_t HiMark = (Offset + FieldSize) & AlignMask; | |||
1556 | uint64_t FieldOffset = (HiMark - FieldSize); | |||
1557 | Offset -= FieldOffset; | |||
1558 | ||||
1559 | // Maybe we need to work from the other end. | |||
1560 | if (Asm->getDataLayout().isLittleEndian()) | |||
1561 | Offset = FieldSize - (Offset + Size); | |||
1562 | ||||
1563 | addUInt(MemberDie, dwarf::DW_AT_bit_offset, None, Offset); | |||
1564 | OffsetInBytes = FieldOffset >> 3; | |||
1565 | } else { | |||
1566 | addUInt(MemberDie, dwarf::DW_AT_data_bit_offset, None, Offset); | |||
1567 | } | |||
1568 | } else { | |||
1569 | // This is not a bitfield. | |||
1570 | OffsetInBytes = DT->getOffsetInBits() / 8; | |||
1571 | if (AlignInBytes) | |||
1572 | addUInt(MemberDie, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata, | |||
1573 | AlignInBytes); | |||
1574 | } | |||
1575 | ||||
1576 | if (DD->getDwarfVersion() <= 2) { | |||
1577 | DIELoc *MemLocationDie = new (DIEValueAllocator) DIELoc; | |||
1578 | addUInt(*MemLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst); | |||
1579 | addUInt(*MemLocationDie, dwarf::DW_FORM_udata, OffsetInBytes); | |||
1580 | addBlock(MemberDie, dwarf::DW_AT_data_member_location, MemLocationDie); | |||
1581 | } else if (!IsBitfield || DD->useDWARF2Bitfields()) | |||
1582 | addUInt(MemberDie, dwarf::DW_AT_data_member_location, None, | |||
1583 | OffsetInBytes); | |||
1584 | } | |||
1585 | ||||
1586 | if (DT->isProtected()) | |||
1587 | addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1, | |||
1588 | dwarf::DW_ACCESS_protected); | |||
1589 | else if (DT->isPrivate()) | |||
1590 | addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1, | |||
1591 | dwarf::DW_ACCESS_private); | |||
1592 | // Otherwise C++ member and base classes are considered public. | |||
1593 | else if (DT->isPublic()) | |||
1594 | addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1, | |||
1595 | dwarf::DW_ACCESS_public); | |||
1596 | if (DT->isVirtual()) | |||
1597 | addUInt(MemberDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_data1, | |||
1598 | dwarf::DW_VIRTUALITY_virtual); | |||
1599 | ||||
1600 | // Objective-C properties. | |||
1601 | if (DINode *PNode = DT->getObjCProperty()) | |||
1602 | if (DIE *PDie = getDIE(PNode)) | |||
1603 | MemberDie.addValue(DIEValueAllocator, dwarf::DW_AT_APPLE_property, | |||
1604 | dwarf::DW_FORM_ref4, DIEEntry(*PDie)); | |||
1605 | ||||
1606 | if (DT->isArtificial()) | |||
1607 | addFlag(MemberDie, dwarf::DW_AT_artificial); | |||
1608 | ||||
1609 | return MemberDie; | |||
1610 | } | |||
1611 | ||||
1612 | DIE *DwarfUnit::getOrCreateStaticMemberDIE(const DIDerivedType *DT) { | |||
1613 | if (!DT) | |||
1614 | return nullptr; | |||
1615 | ||||
1616 | // Construct the context before querying for the existence of the DIE in case | |||
1617 | // such construction creates the DIE. | |||
1618 | DIE *ContextDIE = getOrCreateContextDIE(resolve(DT->getScope())); | |||
1619 | assert(dwarf::isType(ContextDIE->getTag()) &&(static_cast <bool> (dwarf::isType(ContextDIE->getTag ()) && "Static member should belong to a type.") ? void (0) : __assert_fail ("dwarf::isType(ContextDIE->getTag()) && \"Static member should belong to a type.\"" , "/build/llvm-toolchain-snapshot-7~svn338205/lib/CodeGen/AsmPrinter/DwarfUnit.cpp" , 1620, __extension__ __PRETTY_FUNCTION__)) | |||
1620 | "Static member should belong to a type.")(static_cast <bool> (dwarf::isType(ContextDIE->getTag ()) && "Static member should belong to a type.") ? void (0) : __assert_fail ("dwarf::isType(ContextDIE->getTag()) && \"Static member should belong to a type.\"" , "/build/llvm-toolchain-snapshot-7~svn338205/lib/CodeGen/AsmPrinter/DwarfUnit.cpp" , 1620, __extension__ __PRETTY_FUNCTION__)); | |||
1621 | ||||
1622 | if (DIE *StaticMemberDIE = getDIE(DT)) | |||
1623 | return StaticMemberDIE; | |||
1624 | ||||
1625 | DIE &StaticMemberDIE = createAndAddDIE(DT->getTag(), *ContextDIE, DT); | |||
1626 | ||||
1627 | const DIType *Ty = resolve(DT->getBaseType()); | |||
1628 | ||||
1629 | addString(StaticMemberDIE, dwarf::DW_AT_name, DT->getName()); | |||
1630 | addType(StaticMemberDIE, Ty); | |||
1631 | addSourceLine(StaticMemberDIE, DT); | |||
1632 | addFlag(StaticMemberDIE, dwarf::DW_AT_external); | |||
1633 | addFlag(StaticMemberDIE, dwarf::DW_AT_declaration); | |||
1634 | ||||
1635 | // FIXME: We could omit private if the parent is a class_type, and | |||
1636 | // public if the parent is something else. | |||
1637 | if (DT->isProtected()) | |||
1638 | addUInt(StaticMemberDIE, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1, | |||
1639 | dwarf::DW_ACCESS_protected); | |||
1640 | else if (DT->isPrivate()) | |||
1641 | addUInt(StaticMemberDIE, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1, | |||
1642 | dwarf::DW_ACCESS_private); | |||
1643 | else if (DT->isPublic()) | |||
1644 | addUInt(StaticMemberDIE, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1, | |||
1645 | dwarf::DW_ACCESS_public); | |||
1646 | ||||
1647 | if (const ConstantInt *CI = dyn_cast_or_null<ConstantInt>(DT->getConstant())) | |||
1648 | addConstantValue(StaticMemberDIE, CI, Ty); | |||
1649 | if (const ConstantFP *CFP = dyn_cast_or_null<ConstantFP>(DT->getConstant())) | |||
1650 | addConstantFPValue(StaticMemberDIE, CFP); | |||
1651 | ||||
1652 | if (uint32_t AlignInBytes = DT->getAlignInBytes()) | |||
1653 | addUInt(StaticMemberDIE, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata, | |||
1654 | AlignInBytes); | |||
1655 | ||||
1656 | return &StaticMemberDIE; | |||
1657 | } | |||
1658 | ||||
1659 | void DwarfUnit::emitCommonHeader(bool UseOffsets, dwarf::UnitType UT) { | |||
1660 | // Emit size of content not including length itself | |||
1661 | Asm->OutStreamer->AddComment("Length of Unit"); | |||
1662 | Asm->emitInt32(getHeaderSize() + getUnitDie().getSize()); | |||
1663 | ||||
1664 | Asm->OutStreamer->AddComment("DWARF version number"); | |||
1665 | unsigned Version = DD->getDwarfVersion(); | |||
1666 | Asm->emitInt16(Version); | |||
1667 | ||||
1668 | // DWARF v5 reorders the address size and adds a unit type. | |||
1669 | if (Version >= 5) { | |||
1670 | Asm->OutStreamer->AddComment("DWARF Unit Type"); | |||
1671 | Asm->emitInt8(UT); | |||
1672 | Asm->OutStreamer->AddComment("Address Size (in bytes)"); | |||
1673 | Asm->emitInt8(Asm->MAI->getCodePointerSize()); | |||
1674 | } | |||
1675 | ||||
1676 | // We share one abbreviations table across all units so it's always at the | |||
1677 | // start of the section. Use a relocatable offset where needed to ensure | |||
1678 | // linking doesn't invalidate that offset. | |||
1679 | Asm->OutStreamer->AddComment("Offset Into Abbrev. Section"); | |||
1680 | const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); | |||
1681 | if (UseOffsets) | |||
1682 | Asm->emitInt32(0); | |||
1683 | else | |||
1684 | Asm->emitDwarfSymbolReference( | |||
1685 | TLOF.getDwarfAbbrevSection()->getBeginSymbol(), false); | |||
1686 | ||||
1687 | if (Version <= 4) { | |||
1688 | Asm->OutStreamer->AddComment("Address Size (in bytes)"); | |||
1689 | Asm->emitInt8(Asm->MAI->getCodePointerSize()); | |||
1690 | } | |||
1691 | } | |||
1692 | ||||
1693 | void DwarfTypeUnit::emitHeader(bool UseOffsets) { | |||
1694 | DwarfUnit::emitCommonHeader(UseOffsets, | |||
1695 | DD->useSplitDwarf() ? dwarf::DW_UT_split_type | |||
1696 | : dwarf::DW_UT_type); | |||
1697 | Asm->OutStreamer->AddComment("Type Signature"); | |||
1698 | Asm->OutStreamer->EmitIntValue(TypeSignature, sizeof(TypeSignature)); | |||
1699 | Asm->OutStreamer->AddComment("Type DIE Offset"); | |||
1700 | // In a skeleton type unit there is no type DIE so emit a zero offset. | |||
1701 | Asm->OutStreamer->EmitIntValue(Ty ? Ty->getOffset() : 0, | |||
1702 | sizeof(Ty->getOffset())); | |||
1703 | } | |||
1704 | ||||
1705 | DIE::value_iterator | |||
1706 | DwarfUnit::addSectionDelta(DIE &Die, dwarf::Attribute Attribute, | |||
1707 | const MCSymbol *Hi, const MCSymbol *Lo) { | |||
1708 | return Die.addValue(DIEValueAllocator, Attribute, | |||
1709 | DD->getDwarfVersion() >= 4 ? dwarf::DW_FORM_sec_offset | |||
1710 | : dwarf::DW_FORM_data4, | |||
1711 | new (DIEValueAllocator) DIEDelta(Hi, Lo)); | |||
1712 | } | |||
1713 | ||||
1714 | DIE::value_iterator | |||
1715 | DwarfUnit::addSectionLabel(DIE &Die, dwarf::Attribute Attribute, | |||
1716 | const MCSymbol *Label, const MCSymbol *Sec) { | |||
1717 | if (Asm->MAI->doesDwarfUseRelocationsAcrossSections()) | |||
1718 | return addLabel(Die, Attribute, | |||
1719 | DD->getDwarfVersion() >= 4 ? dwarf::DW_FORM_sec_offset | |||
1720 | : dwarf::DW_FORM_data4, | |||
1721 | Label); | |||
1722 | return addSectionDelta(Die, Attribute, Label, Sec); | |||
1723 | } | |||
1724 | ||||
1725 | bool DwarfTypeUnit::isDwoUnit() const { | |||
1726 | // Since there are no skeleton type units, all type units are dwo type units | |||
1727 | // when split DWARF is being used. | |||
1728 | return DD->useSplitDwarf(); | |||
1729 | } | |||
1730 | ||||
1731 | void DwarfTypeUnit::addGlobalName(StringRef Name, const DIE &Die, | |||
1732 | const DIScope *Context) { | |||
1733 | getCU().addGlobalNameForTypeUnit(Name, Context); | |||
1734 | } | |||
1735 | ||||
1736 | void DwarfTypeUnit::addGlobalType(const DIType *Ty, const DIE &Die, | |||
1737 | const DIScope *Context) { | |||
1738 | getCU().addGlobalTypeUnitType(Ty, Context); | |||
1739 | } | |||
1740 | ||||
1741 | const MCSymbol *DwarfUnit::getCrossSectionRelativeBaseAddress() const { | |||
1742 | if (!Asm->MAI->doesDwarfUseRelocationsAcrossSections()) | |||
1743 | return nullptr; | |||
1744 | if (isDwoUnit()) | |||
1745 | return nullptr; | |||
1746 | return getSection()->getBeginSymbol(); | |||
1747 | } | |||
1748 | ||||
1749 | void DwarfUnit::addStringOffsetsStart() { | |||
1750 | const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); | |||
1751 | addSectionLabel(getUnitDie(), dwarf::DW_AT_str_offsets_base, | |||
1752 | DU->getStringOffsetsStartSym(), | |||
1753 | TLOF.getDwarfStrOffSection()->getBeginSymbol()); | |||
1754 | } | |||
1755 | ||||
1756 | void DwarfUnit::addRnglistsBase() { | |||
1757 | assert(DD->getDwarfVersion() >= 5 &&(static_cast <bool> (DD->getDwarfVersion() >= 5 && "DW_AT_rnglists_base requires DWARF version 5 or later") ? void (0) : __assert_fail ("DD->getDwarfVersion() >= 5 && \"DW_AT_rnglists_base requires DWARF version 5 or later\"" , "/build/llvm-toolchain-snapshot-7~svn338205/lib/CodeGen/AsmPrinter/DwarfUnit.cpp" , 1758, __extension__ __PRETTY_FUNCTION__)) | |||
1758 | "DW_AT_rnglists_base requires DWARF version 5 or later")(static_cast <bool> (DD->getDwarfVersion() >= 5 && "DW_AT_rnglists_base requires DWARF version 5 or later") ? void (0) : __assert_fail ("DD->getDwarfVersion() >= 5 && \"DW_AT_rnglists_base requires DWARF version 5 or later\"" , "/build/llvm-toolchain-snapshot-7~svn338205/lib/CodeGen/AsmPrinter/DwarfUnit.cpp" , 1758, __extension__ __PRETTY_FUNCTION__)); | |||
1759 | const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); | |||
1760 | addSectionLabel(getUnitDie(), dwarf::DW_AT_rnglists_base, | |||
1761 | DU->getRnglistsTableBaseSym(), | |||
1762 | TLOF.getDwarfRnglistsSection()->getBeginSymbol()); | |||
1763 | } |