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