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