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_CODEGEN_DIE_H |
14 | #define LLVM_CODEGEN_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 = 0; |
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(Elt: 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(Elt: DIEAbbrevData(Attribute, Value)); |
116 | } |
117 | |
118 | /// Adds another set of attribute information to the abbreviation. |
119 | void AddAttribute(const DIEAbbrevData &AbbrevData) { |
120 | Data.push_back(Elt: AbbrevData); |
121 | } |
122 | |
123 | /// Used to gather unique data for the abbreviation folding set. |
124 | void Profile(FoldingSetNodeID &ID) const; |
125 | |
126 | /// Print the abbreviation using the specified asm printer. |
127 | void Emit(const AsmPrinter *AP) const; |
128 | |
129 | void print(raw_ostream &O) const; |
130 | void dump() const; |
131 | }; |
132 | |
133 | //===--------------------------------------------------------------------===// |
134 | /// Helps unique DIEAbbrev objects and assigns abbreviation numbers. |
135 | /// |
136 | /// This class will unique the DIE abbreviations for a llvm::DIE object and |
137 | /// assign a unique abbreviation number to each unique DIEAbbrev object it |
138 | /// finds. The resulting collection of DIEAbbrev objects can then be emitted |
139 | /// into the .debug_abbrev section. |
140 | class DIEAbbrevSet { |
141 | /// The bump allocator to use when creating DIEAbbrev objects in the uniqued |
142 | /// storage container. |
143 | BumpPtrAllocator &Alloc; |
144 | /// FoldingSet that uniques the abbreviations. |
145 | FoldingSet<DIEAbbrev> AbbreviationsSet; |
146 | /// A list of all the unique abbreviations in use. |
147 | std::vector<DIEAbbrev *> Abbreviations; |
148 | |
149 | public: |
150 | DIEAbbrevSet(BumpPtrAllocator &A) : Alloc(A) {} |
151 | ~DIEAbbrevSet(); |
152 | |
153 | /// Generate the abbreviation declaration for a DIE and return a pointer to |
154 | /// the generated abbreviation. |
155 | /// |
156 | /// \param Die the debug info entry to generate the abbreviation for. |
157 | /// \returns A reference to the uniqued abbreviation declaration that is |
158 | /// owned by this class. |
159 | DIEAbbrev &uniqueAbbreviation(DIE &Die); |
160 | |
161 | /// Print all abbreviations using the specified asm printer. |
162 | void Emit(const AsmPrinter *AP, MCSection *Section) const; |
163 | }; |
164 | |
165 | //===--------------------------------------------------------------------===// |
166 | /// An integer value DIE. |
167 | /// |
168 | class DIEInteger { |
169 | uint64_t Integer; |
170 | |
171 | public: |
172 | explicit DIEInteger(uint64_t I) : Integer(I) {} |
173 | |
174 | /// Choose the best form for integer. |
175 | static dwarf::Form BestForm(bool IsSigned, uint64_t Int) { |
176 | if (IsSigned) { |
177 | const int64_t SignedInt = Int; |
178 | if ((char)Int == SignedInt) |
179 | return dwarf::DW_FORM_data1; |
180 | if ((short)Int == SignedInt) |
181 | return dwarf::DW_FORM_data2; |
182 | if ((int)Int == SignedInt) |
183 | return dwarf::DW_FORM_data4; |
184 | } else { |
185 | if ((unsigned char)Int == Int) |
186 | return dwarf::DW_FORM_data1; |
187 | if ((unsigned short)Int == Int) |
188 | return dwarf::DW_FORM_data2; |
189 | if ((unsigned int)Int == Int) |
190 | return dwarf::DW_FORM_data4; |
191 | } |
192 | return dwarf::DW_FORM_data8; |
193 | } |
194 | |
195 | uint64_t getValue() const { return Integer; } |
196 | void setValue(uint64_t Val) { Integer = Val; } |
197 | |
198 | void emitValue(const AsmPrinter *Asm, dwarf::Form Form) const; |
199 | unsigned sizeOf(const dwarf::FormParams &FormParams, dwarf::Form Form) const; |
200 | |
201 | void print(raw_ostream &O) const; |
202 | }; |
203 | |
204 | //===--------------------------------------------------------------------===// |
205 | /// An expression DIE. |
206 | class DIEExpr { |
207 | const MCExpr *Expr; |
208 | |
209 | public: |
210 | explicit DIEExpr(const MCExpr *E) : Expr(E) {} |
211 | |
212 | /// Get MCExpr. |
213 | const MCExpr *getValue() const { return Expr; } |
214 | |
215 | void emitValue(const AsmPrinter *AP, dwarf::Form Form) const; |
216 | unsigned sizeOf(const dwarf::FormParams &FormParams, dwarf::Form Form) const; |
217 | |
218 | void print(raw_ostream &O) const; |
219 | }; |
220 | |
221 | //===--------------------------------------------------------------------===// |
222 | /// A label DIE. |
223 | class DIELabel { |
224 | const MCSymbol *Label; |
225 | |
226 | public: |
227 | explicit DIELabel(const MCSymbol *L) : Label(L) {} |
228 | |
229 | /// Get MCSymbol. |
230 | const MCSymbol *getValue() const { return Label; } |
231 | |
232 | void emitValue(const AsmPrinter *AP, dwarf::Form Form) const; |
233 | unsigned sizeOf(const dwarf::FormParams &FormParams, dwarf::Form Form) const; |
234 | |
235 | void print(raw_ostream &O) const; |
236 | }; |
237 | |
238 | //===--------------------------------------------------------------------===// |
239 | /// A BaseTypeRef DIE. |
240 | class DIEBaseTypeRef { |
241 | const DwarfCompileUnit *CU; |
242 | const uint64_t Index; |
243 | static constexpr unsigned ULEB128PadSize = 4; |
244 | |
245 | public: |
246 | explicit DIEBaseTypeRef(const DwarfCompileUnit *TheCU, uint64_t Idx) |
247 | : CU(TheCU), Index(Idx) {} |
248 | |
249 | /// EmitValue - Emit base type reference. |
250 | void emitValue(const AsmPrinter *AP, dwarf::Form Form) const; |
251 | /// sizeOf - Determine size of the base type reference in bytes. |
252 | unsigned sizeOf(const dwarf::FormParams &, dwarf::Form) const; |
253 | |
254 | void print(raw_ostream &O) const; |
255 | uint64_t getIndex() const { return Index; } |
256 | }; |
257 | |
258 | //===--------------------------------------------------------------------===// |
259 | /// A simple label difference DIE. |
260 | /// |
261 | class DIEDelta { |
262 | const MCSymbol *LabelHi; |
263 | const MCSymbol *LabelLo; |
264 | |
265 | public: |
266 | DIEDelta(const MCSymbol *Hi, const MCSymbol *Lo) : LabelHi(Hi), LabelLo(Lo) {} |
267 | |
268 | void emitValue(const AsmPrinter *AP, dwarf::Form Form) const; |
269 | unsigned sizeOf(const dwarf::FormParams &FormParams, dwarf::Form Form) const; |
270 | |
271 | void print(raw_ostream &O) const; |
272 | }; |
273 | |
274 | //===--------------------------------------------------------------------===// |
275 | /// A container for string pool string values. |
276 | /// |
277 | /// This class is used with the DW_FORM_strp and DW_FORM_GNU_str_index forms. |
278 | class DIEString { |
279 | DwarfStringPoolEntryRef S; |
280 | |
281 | public: |
282 | DIEString(DwarfStringPoolEntryRef S) : S(S) {} |
283 | |
284 | /// Grab the string out of the object. |
285 | StringRef getString() const { return S.getString(); } |
286 | |
287 | void emitValue(const AsmPrinter *AP, dwarf::Form Form) const; |
288 | unsigned sizeOf(const dwarf::FormParams &FormParams, dwarf::Form Form) const; |
289 | |
290 | void print(raw_ostream &O) const; |
291 | }; |
292 | |
293 | //===--------------------------------------------------------------------===// |
294 | /// A container for inline string values. |
295 | /// |
296 | /// This class is used with the DW_FORM_string form. |
297 | class DIEInlineString { |
298 | StringRef S; |
299 | |
300 | public: |
301 | template <typename Allocator> |
302 | explicit DIEInlineString(StringRef Str, Allocator &A) : S(Str.copy(A)) {} |
303 | |
304 | ~DIEInlineString() = default; |
305 | |
306 | /// Grab the string out of the object. |
307 | StringRef getString() const { return S; } |
308 | |
309 | void emitValue(const AsmPrinter *AP, dwarf::Form Form) const; |
310 | unsigned sizeOf(const dwarf::FormParams &, dwarf::Form) const; |
311 | |
312 | void print(raw_ostream &O) const; |
313 | }; |
314 | |
315 | //===--------------------------------------------------------------------===// |
316 | /// A pointer to another debug information entry. An instance of this class can |
317 | /// also be used as a proxy for a debug information entry not yet defined |
318 | /// (ie. types.) |
319 | class DIEEntry { |
320 | DIE *Entry; |
321 | |
322 | public: |
323 | DIEEntry() = delete; |
324 | explicit DIEEntry(DIE &E) : Entry(&E) {} |
325 | |
326 | DIE &getEntry() const { return *Entry; } |
327 | |
328 | void emitValue(const AsmPrinter *AP, dwarf::Form Form) const; |
329 | unsigned sizeOf(const dwarf::FormParams &FormParams, dwarf::Form Form) const; |
330 | |
331 | void print(raw_ostream &O) const; |
332 | }; |
333 | |
334 | //===--------------------------------------------------------------------===// |
335 | /// Represents a pointer to a location list in the debug_loc |
336 | /// section. |
337 | class DIELocList { |
338 | /// Index into the .debug_loc vector. |
339 | size_t Index; |
340 | |
341 | public: |
342 | DIELocList(size_t I) : Index(I) {} |
343 | |
344 | /// Grab the current index out. |
345 | size_t getValue() const { return Index; } |
346 | |
347 | void emitValue(const AsmPrinter *AP, dwarf::Form Form) const; |
348 | unsigned sizeOf(const dwarf::FormParams &FormParams, dwarf::Form Form) const; |
349 | |
350 | void print(raw_ostream &O) const; |
351 | }; |
352 | |
353 | //===--------------------------------------------------------------------===// |
354 | /// A BaseTypeRef DIE. |
355 | class DIEAddrOffset { |
356 | DIEInteger Addr; |
357 | DIEDelta Offset; |
358 | |
359 | public: |
360 | explicit DIEAddrOffset(uint64_t Idx, const MCSymbol *Hi, const MCSymbol *Lo) |
361 | : Addr(Idx), Offset(Hi, Lo) {} |
362 | |
363 | void emitValue(const AsmPrinter *AP, dwarf::Form Form) const; |
364 | unsigned sizeOf(const dwarf::FormParams &FormParams, dwarf::Form Form) const; |
365 | |
366 | void print(raw_ostream &O) const; |
367 | }; |
368 | |
369 | //===--------------------------------------------------------------------===// |
370 | /// A debug information entry value. Some of these roughly correlate |
371 | /// to DWARF attribute classes. |
372 | class DIEBlock; |
373 | class DIELoc; |
374 | class DIEValue { |
375 | public: |
376 | enum Type { |
377 | isNone, |
378 | #define HANDLE_DIEVALUE(T) is##T, |
379 | #include "llvm/CodeGen/DIEValue.def" |
380 | }; |
381 | |
382 | private: |
383 | /// Type of data stored in the value. |
384 | Type Ty = isNone; |
385 | dwarf::Attribute Attribute = (dwarf::Attribute)0; |
386 | dwarf::Form Form = (dwarf::Form)0; |
387 | |
388 | /// Storage for the value. |
389 | /// |
390 | /// All values that aren't standard layout (or are larger than 8 bytes) |
391 | /// should be stored by reference instead of by value. |
392 | using ValTy = |
393 | AlignedCharArrayUnion<DIEInteger, DIEString, DIEExpr, DIELabel, |
394 | DIEDelta *, DIEEntry, DIEBlock *, DIELoc *, |
395 | DIELocList, DIEBaseTypeRef *, DIEAddrOffset *>; |
396 | |
397 | static_assert(sizeof(ValTy) <= sizeof(uint64_t) || |
398 | sizeof(ValTy) <= sizeof(void *), |
399 | "Expected all large types to be stored via pointer" ); |
400 | |
401 | /// Underlying stored value. |
402 | ValTy Val; |
403 | |
404 | template <class T> void construct(T V) { |
405 | static_assert(std::is_standard_layout<T>::value || |
406 | std::is_pointer<T>::value, |
407 | "Expected standard layout or pointer" ); |
408 | new (reinterpret_cast<void *>(&Val)) T(V); |
409 | } |
410 | |
411 | template <class T> T *get() { return reinterpret_cast<T *>(&Val); } |
412 | template <class T> const T *get() const { |
413 | return reinterpret_cast<const T *>(&Val); |
414 | } |
415 | template <class T> void destruct() { get<T>()->~T(); } |
416 | |
417 | /// Destroy the underlying value. |
418 | /// |
419 | /// This should get optimized down to a no-op. We could skip it if we could |
420 | /// add a static assert on \a std::is_trivially_copyable(), but we currently |
421 | /// support versions of GCC that don't understand that. |
422 | void destroyVal() { |
423 | switch (Ty) { |
424 | case isNone: |
425 | return; |
426 | #define HANDLE_DIEVALUE_SMALL(T) \ |
427 | case is##T: \ |
428 | destruct<DIE##T>(); \ |
429 | return; |
430 | #define HANDLE_DIEVALUE_LARGE(T) \ |
431 | case is##T: \ |
432 | destruct<const DIE##T *>(); \ |
433 | return; |
434 | #include "llvm/CodeGen/DIEValue.def" |
435 | } |
436 | } |
437 | |
438 | /// Copy the underlying value. |
439 | /// |
440 | /// This should get optimized down to a simple copy. We need to actually |
441 | /// construct the value, rather than calling memcpy, to satisfy strict |
442 | /// aliasing rules. |
443 | void copyVal(const DIEValue &X) { |
444 | switch (Ty) { |
445 | case isNone: |
446 | return; |
447 | #define HANDLE_DIEVALUE_SMALL(T) \ |
448 | case is##T: \ |
449 | construct<DIE##T>(*X.get<DIE##T>()); \ |
450 | return; |
451 | #define HANDLE_DIEVALUE_LARGE(T) \ |
452 | case is##T: \ |
453 | construct<const DIE##T *>(*X.get<const DIE##T *>()); \ |
454 | return; |
455 | #include "llvm/CodeGen/DIEValue.def" |
456 | } |
457 | } |
458 | |
459 | public: |
460 | DIEValue() = default; |
461 | |
462 | DIEValue(const DIEValue &X) : Ty(X.Ty), Attribute(X.Attribute), Form(X.Form) { |
463 | copyVal(X); |
464 | } |
465 | |
466 | DIEValue &operator=(const DIEValue &X) { |
467 | if (this == &X) |
468 | return *this; |
469 | destroyVal(); |
470 | Ty = X.Ty; |
471 | Attribute = X.Attribute; |
472 | Form = X.Form; |
473 | copyVal(X); |
474 | return *this; |
475 | } |
476 | |
477 | ~DIEValue() { destroyVal(); } |
478 | |
479 | #define HANDLE_DIEVALUE_SMALL(T) \ |
480 | DIEValue(dwarf::Attribute Attribute, dwarf::Form Form, const DIE##T &V) \ |
481 | : Ty(is##T), Attribute(Attribute), Form(Form) { \ |
482 | construct<DIE##T>(V); \ |
483 | } |
484 | #define HANDLE_DIEVALUE_LARGE(T) \ |
485 | DIEValue(dwarf::Attribute Attribute, dwarf::Form Form, const DIE##T *V) \ |
486 | : Ty(is##T), Attribute(Attribute), Form(Form) { \ |
487 | assert(V && "Expected valid value"); \ |
488 | construct<const DIE##T *>(V); \ |
489 | } |
490 | #include "llvm/CodeGen/DIEValue.def" |
491 | |
492 | /// Accessors. |
493 | /// @{ |
494 | Type getType() const { return Ty; } |
495 | dwarf::Attribute getAttribute() const { return Attribute; } |
496 | dwarf::Form getForm() const { return Form; } |
497 | explicit operator bool() const { return Ty; } |
498 | /// @} |
499 | |
500 | #define HANDLE_DIEVALUE_SMALL(T) \ |
501 | const DIE##T &getDIE##T() const { \ |
502 | assert(getType() == is##T && "Expected " #T); \ |
503 | return *get<DIE##T>(); \ |
504 | } |
505 | #define HANDLE_DIEVALUE_LARGE(T) \ |
506 | const DIE##T &getDIE##T() const { \ |
507 | assert(getType() == is##T && "Expected " #T); \ |
508 | return **get<const DIE##T *>(); \ |
509 | } |
510 | #include "llvm/CodeGen/DIEValue.def" |
511 | |
512 | /// Emit value via the Dwarf writer. |
513 | void emitValue(const AsmPrinter *AP) const; |
514 | |
515 | /// Return the size of a value in bytes. |
516 | unsigned sizeOf(const dwarf::FormParams &FormParams) const; |
517 | |
518 | void print(raw_ostream &O) const; |
519 | void dump() const; |
520 | }; |
521 | |
522 | struct IntrusiveBackListNode { |
523 | PointerIntPair<IntrusiveBackListNode *, 1> Next; |
524 | |
525 | IntrusiveBackListNode() : Next(this, true) {} |
526 | |
527 | IntrusiveBackListNode *getNext() const { |
528 | return Next.getInt() ? nullptr : Next.getPointer(); |
529 | } |
530 | }; |
531 | |
532 | struct IntrusiveBackListBase { |
533 | using Node = IntrusiveBackListNode; |
534 | |
535 | Node *Last = nullptr; |
536 | |
537 | bool empty() const { return !Last; } |
538 | |
539 | void push_back(Node &N) { |
540 | assert(N.Next.getPointer() == &N && "Expected unlinked node" ); |
541 | assert(N.Next.getInt() == true && "Expected unlinked node" ); |
542 | |
543 | if (Last) { |
544 | N.Next = Last->Next; |
545 | Last->Next.setPointerAndInt(PtrVal: &N, IntVal: false); |
546 | } |
547 | Last = &N; |
548 | } |
549 | |
550 | void push_front(Node &N) { |
551 | assert(N.Next.getPointer() == &N && "Expected unlinked node" ); |
552 | assert(N.Next.getInt() == true && "Expected unlinked node" ); |
553 | |
554 | if (Last) { |
555 | N.Next.setPointerAndInt(PtrVal: Last->Next.getPointer(), IntVal: false); |
556 | Last->Next.setPointerAndInt(PtrVal: &N, IntVal: true); |
557 | } else { |
558 | Last = &N; |
559 | } |
560 | } |
561 | }; |
562 | |
563 | template <class T> class IntrusiveBackList : IntrusiveBackListBase { |
564 | public: |
565 | using IntrusiveBackListBase::empty; |
566 | |
567 | void push_back(T &N) { IntrusiveBackListBase::push_back(N); } |
568 | void push_front(T &N) { IntrusiveBackListBase::push_front(N); } |
569 | |
570 | T &back() { return *static_cast<T *>(Last); } |
571 | const T &back() const { return *static_cast<T *>(Last); } |
572 | T &front() { |
573 | return *static_cast<T *>(Last ? Last->Next.getPointer() : nullptr); |
574 | } |
575 | const T &front() const { |
576 | return *static_cast<T *>(Last ? Last->Next.getPointer() : nullptr); |
577 | } |
578 | |
579 | void takeNodes(IntrusiveBackList<T> &Other) { |
580 | if (Other.empty()) |
581 | return; |
582 | |
583 | T *FirstNode = static_cast<T *>(Other.Last->Next.getPointer()); |
584 | T *IterNode = FirstNode; |
585 | do { |
586 | // Keep a pointer to the node and increment the iterator. |
587 | T *TmpNode = IterNode; |
588 | IterNode = static_cast<T *>(IterNode->Next.getPointer()); |
589 | |
590 | // Unlink the node and push it back to this list. |
591 | TmpNode->Next.setPointerAndInt(TmpNode, true); |
592 | push_back(N&: *TmpNode); |
593 | } while (IterNode != FirstNode); |
594 | |
595 | Other.Last = nullptr; |
596 | } |
597 | |
598 | bool deleteNode(T &N) { |
599 | if (Last == &N) { |
600 | Last = Last->Next.getPointer(); |
601 | Last->Next.setInt(true); |
602 | return true; |
603 | } |
604 | |
605 | Node *cur = Last; |
606 | while (cur && cur->Next.getPointer()) { |
607 | if (cur->Next.getPointer() == &N) { |
608 | cur->Next.setPointer(cur->Next.getPointer()->Next.getPointer()); |
609 | return true; |
610 | } |
611 | cur = cur->Next.getPointer(); |
612 | } |
613 | |
614 | return false; |
615 | } |
616 | |
617 | class const_iterator; |
618 | class iterator |
619 | : public iterator_facade_base<iterator, std::forward_iterator_tag, T> { |
620 | friend class const_iterator; |
621 | |
622 | Node *N = nullptr; |
623 | |
624 | public: |
625 | iterator() = default; |
626 | explicit iterator(T *N) : N(N) {} |
627 | |
628 | iterator &operator++() { |
629 | N = N->getNext(); |
630 | return *this; |
631 | } |
632 | |
633 | explicit operator bool() const { return N; } |
634 | T &operator*() const { return *static_cast<T *>(N); } |
635 | |
636 | bool operator==(const iterator &X) const { return N == X.N; } |
637 | }; |
638 | |
639 | class const_iterator |
640 | : public iterator_facade_base<const_iterator, std::forward_iterator_tag, |
641 | const T> { |
642 | const Node *N = nullptr; |
643 | |
644 | public: |
645 | const_iterator() = default; |
646 | // Placate MSVC by explicitly scoping 'iterator'. |
647 | const_iterator(typename IntrusiveBackList<T>::iterator X) : N(X.N) {} |
648 | explicit const_iterator(const T *N) : N(N) {} |
649 | |
650 | const_iterator &operator++() { |
651 | N = N->getNext(); |
652 | return *this; |
653 | } |
654 | |
655 | explicit operator bool() const { return N; } |
656 | const T &operator*() const { return *static_cast<const T *>(N); } |
657 | |
658 | bool operator==(const const_iterator &X) const { return N == X.N; } |
659 | }; |
660 | |
661 | iterator begin() { |
662 | return Last ? iterator(static_cast<T *>(Last->Next.getPointer())) : end(); |
663 | } |
664 | const_iterator begin() const { |
665 | return const_cast<IntrusiveBackList *>(this)->begin(); |
666 | } |
667 | iterator end() { return iterator(); } |
668 | const_iterator end() const { return const_iterator(); } |
669 | |
670 | static iterator toIterator(T &N) { return iterator(&N); } |
671 | static const_iterator toIterator(const T &N) { return const_iterator(&N); } |
672 | }; |
673 | |
674 | /// A list of DIE values. |
675 | /// |
676 | /// This is a singly-linked list, but instead of reversing the order of |
677 | /// insertion, we keep a pointer to the back of the list so we can push in |
678 | /// order. |
679 | /// |
680 | /// There are two main reasons to choose a linked list over a customized |
681 | /// vector-like data structure. |
682 | /// |
683 | /// 1. For teardown efficiency, we want DIEs to be BumpPtrAllocated. Using a |
684 | /// linked list here makes this way easier to accomplish. |
685 | /// 2. Carrying an extra pointer per \a DIEValue isn't expensive. 45% of DIEs |
686 | /// have 2 or fewer values, and 90% have 5 or fewer. A vector would be |
687 | /// over-allocated by 50% on average anyway, the same cost as the |
688 | /// linked-list node. |
689 | class DIEValueList { |
690 | struct Node : IntrusiveBackListNode { |
691 | DIEValue V; |
692 | |
693 | explicit Node(DIEValue V) : V(V) {} |
694 | }; |
695 | |
696 | using ListTy = IntrusiveBackList<Node>; |
697 | |
698 | ListTy List; |
699 | |
700 | public: |
701 | class const_value_iterator; |
702 | class value_iterator |
703 | : public iterator_adaptor_base<value_iterator, ListTy::iterator, |
704 | std::forward_iterator_tag, DIEValue> { |
705 | friend class const_value_iterator; |
706 | |
707 | using iterator_adaptor = |
708 | iterator_adaptor_base<value_iterator, ListTy::iterator, |
709 | std::forward_iterator_tag, DIEValue>; |
710 | |
711 | public: |
712 | value_iterator() = default; |
713 | explicit value_iterator(ListTy::iterator X) : iterator_adaptor(X) {} |
714 | |
715 | explicit operator bool() const { return bool(wrapped()); } |
716 | DIEValue &operator*() const { return wrapped()->V; } |
717 | }; |
718 | |
719 | class const_value_iterator : public iterator_adaptor_base< |
720 | const_value_iterator, ListTy::const_iterator, |
721 | std::forward_iterator_tag, const DIEValue> { |
722 | using iterator_adaptor = |
723 | iterator_adaptor_base<const_value_iterator, ListTy::const_iterator, |
724 | std::forward_iterator_tag, const DIEValue>; |
725 | |
726 | public: |
727 | const_value_iterator() = default; |
728 | const_value_iterator(DIEValueList::value_iterator X) |
729 | : iterator_adaptor(X.wrapped()) {} |
730 | explicit const_value_iterator(ListTy::const_iterator X) |
731 | : iterator_adaptor(X) {} |
732 | |
733 | explicit operator bool() const { return bool(wrapped()); } |
734 | const DIEValue &operator*() const { return wrapped()->V; } |
735 | }; |
736 | |
737 | using value_range = iterator_range<value_iterator>; |
738 | using const_value_range = iterator_range<const_value_iterator>; |
739 | |
740 | value_iterator addValue(BumpPtrAllocator &Alloc, const DIEValue &V) { |
741 | List.push_back(N&: *new (Alloc) Node(V)); |
742 | return value_iterator(ListTy::toIterator(N&: List.back())); |
743 | } |
744 | template <class T> |
745 | value_iterator addValue(BumpPtrAllocator &Alloc, dwarf::Attribute Attribute, |
746 | dwarf::Form Form, T &&Value) { |
747 | return addValue(Alloc, V: DIEValue(Attribute, Form, std::forward<T>(Value))); |
748 | } |
749 | |
750 | /* zr33: add method here */ |
751 | template <class T> |
752 | bool replaceValue(BumpPtrAllocator &Alloc, dwarf::Attribute Attribute, |
753 | dwarf::Attribute NewAttribute, dwarf::Form Form, |
754 | T &&NewValue) { |
755 | for (llvm::DIEValue &val : values()) { |
756 | if (val.getAttribute() == Attribute) { |
757 | val = *new (Alloc) |
758 | DIEValue(NewAttribute, Form, std::forward<T>(NewValue)); |
759 | return true; |
760 | } |
761 | } |
762 | |
763 | return false; |
764 | } |
765 | |
766 | template <class T> |
767 | bool replaceValue(BumpPtrAllocator &Alloc, dwarf::Attribute Attribute, |
768 | dwarf::Form Form, T &&NewValue) { |
769 | for (llvm::DIEValue &val : values()) { |
770 | if (val.getAttribute() == Attribute) { |
771 | val = *new (Alloc) DIEValue(Attribute, Form, std::forward<T>(NewValue)); |
772 | return true; |
773 | } |
774 | } |
775 | |
776 | return false; |
777 | } |
778 | |
779 | bool replaceValue(BumpPtrAllocator &Alloc, dwarf::Attribute Attribute, |
780 | dwarf::Form Form, DIEValue &NewValue) { |
781 | for (llvm::DIEValue &val : values()) { |
782 | if (val.getAttribute() == Attribute) { |
783 | val = NewValue; |
784 | return true; |
785 | } |
786 | } |
787 | |
788 | return false; |
789 | } |
790 | |
791 | bool deleteValue(dwarf::Attribute Attribute) { |
792 | |
793 | for (auto &node : List) { |
794 | if (node.V.getAttribute() == Attribute) { |
795 | return List.deleteNode(N&: node); |
796 | } |
797 | } |
798 | |
799 | return false; |
800 | } |
801 | /* end */ |
802 | |
803 | /// Take ownership of the nodes in \p Other, and append them to the back of |
804 | /// the list. |
805 | void takeValues(DIEValueList &Other) { List.takeNodes(Other&: Other.List); } |
806 | |
807 | value_range values() { |
808 | return make_range(x: value_iterator(List.begin()), y: value_iterator(List.end())); |
809 | } |
810 | const_value_range values() const { |
811 | return make_range(x: const_value_iterator(List.begin()), |
812 | y: const_value_iterator(List.end())); |
813 | } |
814 | }; |
815 | |
816 | //===--------------------------------------------------------------------===// |
817 | /// A structured debug information entry. Has an abbreviation which |
818 | /// describes its organization. |
819 | class DIE : IntrusiveBackListNode, public DIEValueList { |
820 | friend class IntrusiveBackList<DIE>; |
821 | friend class DIEUnit; |
822 | |
823 | /// Dwarf unit relative offset. |
824 | unsigned Offset = 0; |
825 | /// Size of instance + children. |
826 | unsigned Size = 0; |
827 | unsigned AbbrevNumber = ~0u; |
828 | /// Dwarf tag code. |
829 | dwarf::Tag Tag = (dwarf::Tag)0; |
830 | /// Set to true to force a DIE to emit an abbreviation that says it has |
831 | /// children even when it doesn't. This is used for unit testing purposes. |
832 | bool ForceChildren = false; |
833 | /// Children DIEs. |
834 | IntrusiveBackList<DIE> Children; |
835 | |
836 | /// The owner is either the parent DIE for children of other DIEs, or a |
837 | /// DIEUnit which contains this DIE as its unit DIE. |
838 | PointerUnion<DIE *, DIEUnit *> Owner; |
839 | |
840 | explicit DIE(dwarf::Tag Tag) : Tag(Tag) {} |
841 | |
842 | public: |
843 | DIE() = delete; |
844 | DIE(const DIE &RHS) = delete; |
845 | DIE(DIE &&RHS) = delete; |
846 | DIE &operator=(const DIE &RHS) = delete; |
847 | DIE &operator=(const DIE &&RHS) = delete; |
848 | |
849 | static DIE *get(BumpPtrAllocator &Alloc, dwarf::Tag Tag) { |
850 | return new (Alloc) DIE(Tag); |
851 | } |
852 | |
853 | // Accessors. |
854 | unsigned getAbbrevNumber() const { return AbbrevNumber; } |
855 | dwarf::Tag getTag() const { return Tag; } |
856 | /// Get the compile/type unit relative offset of this DIE. |
857 | unsigned getOffset() const { |
858 | // A real Offset can't be zero because the unit headers are at offset zero. |
859 | assert(Offset && "Offset being queried before it's been computed." ); |
860 | return Offset; |
861 | } |
862 | unsigned getSize() const { |
863 | // A real Size can't be zero because it includes the non-empty abbrev code. |
864 | assert(Size && "Size being queried before it's been ocmputed." ); |
865 | return Size; |
866 | } |
867 | bool hasChildren() const { return ForceChildren || !Children.empty(); } |
868 | void setForceChildren(bool B) { ForceChildren = B; } |
869 | |
870 | using child_iterator = IntrusiveBackList<DIE>::iterator; |
871 | using const_child_iterator = IntrusiveBackList<DIE>::const_iterator; |
872 | using child_range = iterator_range<child_iterator>; |
873 | using const_child_range = iterator_range<const_child_iterator>; |
874 | |
875 | child_range children() { |
876 | return make_range(x: Children.begin(), y: Children.end()); |
877 | } |
878 | const_child_range children() const { |
879 | return make_range(x: Children.begin(), y: Children.end()); |
880 | } |
881 | |
882 | DIE *getParent() const; |
883 | |
884 | /// Generate the abbreviation for this DIE. |
885 | /// |
886 | /// Calculate the abbreviation for this, which should be uniqued and |
887 | /// eventually used to call \a setAbbrevNumber(). |
888 | DIEAbbrev generateAbbrev() const; |
889 | |
890 | /// Set the abbreviation number for this DIE. |
891 | void setAbbrevNumber(unsigned I) { AbbrevNumber = I; } |
892 | |
893 | /// Get the absolute offset within the .debug_info or .debug_types section |
894 | /// for this DIE. |
895 | uint64_t getDebugSectionOffset() const; |
896 | |
897 | /// Compute the offset of this DIE and all its children. |
898 | /// |
899 | /// This function gets called just before we are going to generate the debug |
900 | /// information and gives each DIE a chance to figure out its CU relative DIE |
901 | /// offset, unique its abbreviation and fill in the abbreviation code, and |
902 | /// return the unit offset that points to where the next DIE will be emitted |
903 | /// within the debug unit section. After this function has been called for all |
904 | /// DIE objects, the DWARF can be generated since all DIEs will be able to |
905 | /// properly refer to other DIE objects since all DIEs have calculated their |
906 | /// offsets. |
907 | /// |
908 | /// \param FormParams Used when calculating sizes. |
909 | /// \param AbbrevSet the abbreviation used to unique DIE abbreviations. |
910 | /// \param CUOffset the compile/type unit relative offset in bytes. |
911 | /// \returns the offset for the DIE that follows this DIE within the |
912 | /// current compile/type unit. |
913 | unsigned computeOffsetsAndAbbrevs(const dwarf::FormParams &FormParams, |
914 | DIEAbbrevSet &AbbrevSet, unsigned CUOffset); |
915 | |
916 | /// Climb up the parent chain to get the compile unit or type unit DIE that |
917 | /// this DIE belongs to. |
918 | /// |
919 | /// \returns the compile or type unit DIE that owns this DIE, or NULL if |
920 | /// this DIE hasn't been added to a unit DIE. |
921 | const DIE *getUnitDie() const; |
922 | |
923 | /// Climb up the parent chain to get the compile unit or type unit that this |
924 | /// DIE belongs to. |
925 | /// |
926 | /// \returns the DIEUnit that represents the compile or type unit that owns |
927 | /// this DIE, or NULL if this DIE hasn't been added to a unit DIE. |
928 | DIEUnit *getUnit() const; |
929 | |
930 | void setOffset(unsigned O) { Offset = O; } |
931 | void setSize(unsigned S) { Size = S; } |
932 | |
933 | /// Add a child to the DIE. |
934 | DIE &addChild(DIE *Child) { |
935 | assert(!Child->getParent() && "Child should be orphaned" ); |
936 | Child->Owner = this; |
937 | Children.push_back(N&: *Child); |
938 | return Children.back(); |
939 | } |
940 | |
941 | DIE &addChildFront(DIE *Child) { |
942 | assert(!Child->getParent() && "Child should be orphaned" ); |
943 | Child->Owner = this; |
944 | Children.push_front(N&: *Child); |
945 | return Children.front(); |
946 | } |
947 | |
948 | /// Find a value in the DIE with the attribute given. |
949 | /// |
950 | /// Returns a default-constructed DIEValue (where \a DIEValue::getType() |
951 | /// gives \a DIEValue::isNone) if no such attribute exists. |
952 | DIEValue findAttribute(dwarf::Attribute Attribute) const; |
953 | |
954 | void print(raw_ostream &O, unsigned IndentCount = 0) const; |
955 | void dump() const; |
956 | }; |
957 | |
958 | //===--------------------------------------------------------------------===// |
959 | /// Represents a compile or type unit. |
960 | class DIEUnit { |
961 | /// The compile unit or type unit DIE. This variable must be an instance of |
962 | /// DIE so that we can calculate the DIEUnit from any DIE by traversing the |
963 | /// parent backchain and getting the Unit DIE, and then casting itself to a |
964 | /// DIEUnit. This allows us to be able to find the DIEUnit for any DIE without |
965 | /// having to store a pointer to the DIEUnit in each DIE instance. |
966 | DIE Die; |
967 | /// The section this unit will be emitted in. This may or may not be set to |
968 | /// a valid section depending on the client that is emitting DWARF. |
969 | MCSection *Section = nullptr; |
970 | uint64_t Offset = 0; /// .debug_info or .debug_types absolute section offset. |
971 | protected: |
972 | virtual ~DIEUnit() = default; |
973 | |
974 | public: |
975 | explicit DIEUnit(dwarf::Tag UnitTag); |
976 | DIEUnit(const DIEUnit &RHS) = delete; |
977 | DIEUnit(DIEUnit &&RHS) = delete; |
978 | void operator=(const DIEUnit &RHS) = delete; |
979 | void operator=(const DIEUnit &&RHS) = delete; |
980 | /// Set the section that this DIEUnit will be emitted into. |
981 | /// |
982 | /// This function is used by some clients to set the section. Not all clients |
983 | /// that emit DWARF use this section variable. |
984 | void setSection(MCSection *Section) { |
985 | assert(!this->Section); |
986 | this->Section = Section; |
987 | } |
988 | |
989 | virtual const MCSymbol *getCrossSectionRelativeBaseAddress() const { |
990 | return nullptr; |
991 | } |
992 | |
993 | /// Return the section that this DIEUnit will be emitted into. |
994 | /// |
995 | /// \returns Section pointer which can be NULL. |
996 | MCSection *getSection() const { return Section; } |
997 | void setDebugSectionOffset(uint64_t O) { Offset = O; } |
998 | uint64_t getDebugSectionOffset() const { return Offset; } |
999 | DIE &getUnitDie() { return Die; } |
1000 | const DIE &getUnitDie() const { return Die; } |
1001 | }; |
1002 | |
1003 | struct BasicDIEUnit final : DIEUnit { |
1004 | explicit BasicDIEUnit(dwarf::Tag UnitTag) : DIEUnit(UnitTag) {} |
1005 | }; |
1006 | |
1007 | //===--------------------------------------------------------------------===// |
1008 | /// DIELoc - Represents an expression location. |
1009 | // |
1010 | class DIELoc : public DIEValueList { |
1011 | mutable unsigned Size = 0; // Size in bytes excluding size header. |
1012 | |
1013 | public: |
1014 | DIELoc() = default; |
1015 | |
1016 | /// Calculate the size of the location expression. |
1017 | unsigned computeSize(const dwarf::FormParams &FormParams) const; |
1018 | |
1019 | // TODO: move setSize() and Size to DIEValueList. |
1020 | void setSize(unsigned size) { Size = size; } |
1021 | |
1022 | /// BestForm - Choose the best form for data. |
1023 | /// |
1024 | dwarf::Form BestForm(unsigned DwarfVersion) const { |
1025 | if (DwarfVersion > 3) |
1026 | return dwarf::DW_FORM_exprloc; |
1027 | // Pre-DWARF4 location expressions were blocks and not exprloc. |
1028 | if ((unsigned char)Size == Size) |
1029 | return dwarf::DW_FORM_block1; |
1030 | if ((unsigned short)Size == Size) |
1031 | return dwarf::DW_FORM_block2; |
1032 | if ((unsigned int)Size == Size) |
1033 | return dwarf::DW_FORM_block4; |
1034 | return dwarf::DW_FORM_block; |
1035 | } |
1036 | |
1037 | void emitValue(const AsmPrinter *Asm, dwarf::Form Form) const; |
1038 | unsigned sizeOf(const dwarf::FormParams &, dwarf::Form Form) const; |
1039 | |
1040 | void print(raw_ostream &O) const; |
1041 | }; |
1042 | |
1043 | //===--------------------------------------------------------------------===// |
1044 | /// DIEBlock - Represents a block of values. |
1045 | // |
1046 | class DIEBlock : public DIEValueList { |
1047 | mutable unsigned Size = 0; // Size in bytes excluding size header. |
1048 | |
1049 | public: |
1050 | DIEBlock() = default; |
1051 | |
1052 | /// Calculate the size of the location expression. |
1053 | unsigned computeSize(const dwarf::FormParams &FormParams) const; |
1054 | |
1055 | // TODO: move setSize() and Size to DIEValueList. |
1056 | void setSize(unsigned size) { Size = size; } |
1057 | |
1058 | /// BestForm - Choose the best form for data. |
1059 | /// |
1060 | dwarf::Form BestForm() const { |
1061 | if ((unsigned char)Size == Size) |
1062 | return dwarf::DW_FORM_block1; |
1063 | if ((unsigned short)Size == Size) |
1064 | return dwarf::DW_FORM_block2; |
1065 | if ((unsigned int)Size == Size) |
1066 | return dwarf::DW_FORM_block4; |
1067 | return dwarf::DW_FORM_block; |
1068 | } |
1069 | |
1070 | void emitValue(const AsmPrinter *Asm, dwarf::Form Form) const; |
1071 | unsigned sizeOf(const dwarf::FormParams &, dwarf::Form Form) const; |
1072 | |
1073 | void print(raw_ostream &O) const; |
1074 | }; |
1075 | |
1076 | } // end namespace llvm |
1077 | |
1078 | #endif // LLVM_CODEGEN_DIE_H |
1079 | |