1 | //===- llvm/IR/DebugInfoMetadata.h - Debug info metadata --------*- C++ -*-===// |
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 | // Declarations for metadata specific to debug info. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #ifndef LLVM_IR_DEBUGINFOMETADATA_H |
15 | #define LLVM_IR_DEBUGINFOMETADATA_H |
16 | |
17 | #include "llvm/ADT/ArrayRef.h" |
18 | #include "llvm/ADT/BitmaskEnum.h" |
19 | #include "llvm/ADT/None.h" |
20 | #include "llvm/ADT/Optional.h" |
21 | #include "llvm/ADT/PointerUnion.h" |
22 | #include "llvm/ADT/STLExtras.h" |
23 | #include "llvm/ADT/SmallVector.h" |
24 | #include "llvm/ADT/StringRef.h" |
25 | #include "llvm/ADT/iterator_range.h" |
26 | #include "llvm/BinaryFormat/Dwarf.h" |
27 | #include "llvm/IR/Constants.h" |
28 | #include "llvm/IR/Metadata.h" |
29 | #include "llvm/Support/Casting.h" |
30 | #include <cassert> |
31 | #include <climits> |
32 | #include <cstddef> |
33 | #include <cstdint> |
34 | #include <iterator> |
35 | #include <type_traits> |
36 | #include <vector> |
37 | |
38 | // Helper macros for defining get() overrides. |
39 | #define DEFINE_MDNODE_GET_UNPACK_IMPL(...) __VA_ARGS__ |
40 | #define DEFINE_MDNODE_GET_UNPACK(ARGS) DEFINE_MDNODE_GET_UNPACK_IMPL ARGS |
41 | #define DEFINE_MDNODE_GET_DISTINCT_TEMPORARY(CLASS, FORMAL, ARGS) \ |
42 | static CLASS *getDistinct(LLVMContext &Context, \ |
43 | DEFINE_MDNODE_GET_UNPACK(FORMAL)) { \ |
44 | return getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Distinct); \ |
45 | } \ |
46 | static Temp##CLASS getTemporary(LLVMContext &Context, \ |
47 | DEFINE_MDNODE_GET_UNPACK(FORMAL)) { \ |
48 | return Temp##CLASS( \ |
49 | getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Temporary)); \ |
50 | } |
51 | #define DEFINE_MDNODE_GET(CLASS, FORMAL, ARGS) \ |
52 | static CLASS *get(LLVMContext &Context, DEFINE_MDNODE_GET_UNPACK(FORMAL)) { \ |
53 | return getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Uniqued); \ |
54 | } \ |
55 | static CLASS *getIfExists(LLVMContext &Context, \ |
56 | DEFINE_MDNODE_GET_UNPACK(FORMAL)) { \ |
57 | return getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Uniqued, \ |
58 | /* ShouldCreate */ false); \ |
59 | } \ |
60 | DEFINE_MDNODE_GET_DISTINCT_TEMPORARY(CLASS, FORMAL, ARGS) |
61 | |
62 | namespace llvm { |
63 | |
64 | /// Holds a subclass of DINode. |
65 | /// |
66 | /// FIXME: This class doesn't currently make much sense. Previously it was a |
67 | /// union beteen MDString (for ODR-uniqued types) and things like DIType. To |
68 | /// support CodeView work, it wasn't deleted outright when MDString-based type |
69 | /// references were deleted; we'll soon need a similar concept for CodeView |
70 | /// DITypeIndex. |
71 | template <class T> class TypedDINodeRef { |
72 | const Metadata *MD = nullptr; |
73 | |
74 | public: |
75 | TypedDINodeRef() = default; |
76 | TypedDINodeRef(std::nullptr_t) {} |
77 | TypedDINodeRef(const T *MD) : MD(MD) {} |
78 | |
79 | explicit TypedDINodeRef(const Metadata *MD) : MD(MD) { |
80 | assert((!MD || isa<T>(MD)) && "Expected valid type ref" ); |
81 | } |
82 | |
83 | template <class U> |
84 | TypedDINodeRef( |
85 | const TypedDINodeRef<U> &X, |
86 | typename std::enable_if<std::is_convertible<U *, T *>::value>::type * = |
87 | nullptr) |
88 | : MD(X) {} |
89 | |
90 | operator Metadata *() const { return const_cast<Metadata *>(MD); } |
91 | |
92 | T *resolve() const { return const_cast<T *>(cast_or_null<T>(MD)); } |
93 | |
94 | bool operator==(const TypedDINodeRef<T> &X) const { return MD == X.MD; } |
95 | bool operator!=(const TypedDINodeRef<T> &X) const { return MD != X.MD; } |
96 | }; |
97 | |
98 | using DINodeRef = TypedDINodeRef<DINode>; |
99 | using DIScopeRef = TypedDINodeRef<DIScope>; |
100 | using DITypeRef = TypedDINodeRef<DIType>; |
101 | |
102 | class DITypeRefArray { |
103 | const MDTuple *N = nullptr; |
104 | |
105 | public: |
106 | DITypeRefArray() = default; |
107 | DITypeRefArray(const MDTuple *N) : N(N) {} |
108 | |
109 | explicit operator bool() const { return get(); } |
110 | explicit operator MDTuple *() const { return get(); } |
111 | |
112 | MDTuple *get() const { return const_cast<MDTuple *>(N); } |
113 | MDTuple *operator->() const { return get(); } |
114 | MDTuple &operator*() const { return *get(); } |
115 | |
116 | // FIXME: Fix callers and remove condition on N. |
117 | unsigned size() const { return N ? N->getNumOperands() : 0u; } |
118 | DITypeRef operator[](unsigned I) const { return DITypeRef(N->getOperand(I)); } |
119 | |
120 | class iterator : std::iterator<std::input_iterator_tag, DITypeRef, |
121 | std::ptrdiff_t, void, DITypeRef> { |
122 | MDNode::op_iterator I = nullptr; |
123 | |
124 | public: |
125 | iterator() = default; |
126 | explicit iterator(MDNode::op_iterator I) : I(I) {} |
127 | |
128 | DITypeRef operator*() const { return DITypeRef(*I); } |
129 | |
130 | iterator &operator++() { |
131 | ++I; |
132 | return *this; |
133 | } |
134 | |
135 | iterator operator++(int) { |
136 | iterator Temp(*this); |
137 | ++I; |
138 | return Temp; |
139 | } |
140 | |
141 | bool operator==(const iterator &X) const { return I == X.I; } |
142 | bool operator!=(const iterator &X) const { return I != X.I; } |
143 | }; |
144 | |
145 | // FIXME: Fix callers and remove condition on N. |
146 | iterator begin() const { return N ? iterator(N->op_begin()) : iterator(); } |
147 | iterator end() const { return N ? iterator(N->op_end()) : iterator(); } |
148 | }; |
149 | |
150 | /// Tagged DWARF-like metadata node. |
151 | /// |
152 | /// A metadata node with a DWARF tag (i.e., a constant named \c DW_TAG_*, |
153 | /// defined in llvm/BinaryFormat/Dwarf.h). Called \a DINode because it's |
154 | /// potentially used for non-DWARF output. |
155 | class DINode : public MDNode { |
156 | friend class LLVMContextImpl; |
157 | friend class MDNode; |
158 | |
159 | protected: |
160 | DINode(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag, |
161 | ArrayRef<Metadata *> Ops1, ArrayRef<Metadata *> Ops2 = None) |
162 | : MDNode(C, ID, Storage, Ops1, Ops2) { |
163 | assert(Tag < 1u << 16); |
164 | SubclassData16 = Tag; |
165 | } |
166 | ~DINode() = default; |
167 | |
168 | template <class Ty> Ty *getOperandAs(unsigned I) const { |
169 | return cast_or_null<Ty>(getOperand(I)); |
170 | } |
171 | |
172 | StringRef getStringOperand(unsigned I) const { |
173 | if (auto *S = getOperandAs<MDString>(I)) |
174 | return S->getString(); |
175 | return StringRef(); |
176 | } |
177 | |
178 | static MDString *getCanonicalMDString(LLVMContext &Context, StringRef S) { |
179 | if (S.empty()) |
180 | return nullptr; |
181 | return MDString::get(Context, S); |
182 | } |
183 | |
184 | /// Allow subclasses to mutate the tag. |
185 | void setTag(unsigned Tag) { SubclassData16 = Tag; } |
186 | |
187 | public: |
188 | unsigned getTag() const { return SubclassData16; } |
189 | |
190 | /// Debug info flags. |
191 | /// |
192 | /// The three accessibility flags are mutually exclusive and rolled together |
193 | /// in the first two bits. |
194 | enum DIFlags : uint32_t { |
195 | #define HANDLE_DI_FLAG(ID, NAME) Flag##NAME = ID, |
196 | #define DI_FLAG_LARGEST_NEEDED |
197 | #include "llvm/IR/DebugInfoFlags.def" |
198 | FlagAccessibility = FlagPrivate | FlagProtected | FlagPublic, |
199 | FlagPtrToMemberRep = FlagSingleInheritance | FlagMultipleInheritance | |
200 | FlagVirtualInheritance, |
201 | LLVM_MARK_AS_BITMASK_ENUM(FlagLargest) |
202 | }; |
203 | |
204 | static DIFlags getFlag(StringRef Flag); |
205 | static StringRef getFlagString(DIFlags Flag); |
206 | |
207 | /// Split up a flags bitfield. |
208 | /// |
209 | /// Split \c Flags into \c SplitFlags, a vector of its components. Returns |
210 | /// any remaining (unrecognized) bits. |
211 | static DIFlags splitFlags(DIFlags Flags, |
212 | SmallVectorImpl<DIFlags> &SplitFlags); |
213 | |
214 | static bool classof(const Metadata *MD) { |
215 | switch (MD->getMetadataID()) { |
216 | default: |
217 | return false; |
218 | case GenericDINodeKind: |
219 | case DISubrangeKind: |
220 | case DIEnumeratorKind: |
221 | case DIBasicTypeKind: |
222 | case DIDerivedTypeKind: |
223 | case DICompositeTypeKind: |
224 | case DISubroutineTypeKind: |
225 | case DIFileKind: |
226 | case DICompileUnitKind: |
227 | case DISubprogramKind: |
228 | case DILexicalBlockKind: |
229 | case DILexicalBlockFileKind: |
230 | case DINamespaceKind: |
231 | case DITemplateTypeParameterKind: |
232 | case DITemplateValueParameterKind: |
233 | case DIGlobalVariableKind: |
234 | case DILocalVariableKind: |
235 | case DILabelKind: |
236 | case DIObjCPropertyKind: |
237 | case DIImportedEntityKind: |
238 | case DIModuleKind: |
239 | return true; |
240 | } |
241 | } |
242 | }; |
243 | |
244 | template <class T> struct simplify_type<const TypedDINodeRef<T>> { |
245 | using SimpleType = Metadata *; |
246 | |
247 | static SimpleType getSimplifiedValue(const TypedDINodeRef<T> &MD) { |
248 | return MD; |
249 | } |
250 | }; |
251 | |
252 | template <class T> |
253 | struct simplify_type<TypedDINodeRef<T>> |
254 | : simplify_type<const TypedDINodeRef<T>> {}; |
255 | |
256 | /// Generic tagged DWARF-like metadata node. |
257 | /// |
258 | /// An un-specialized DWARF-like metadata node. The first operand is a |
259 | /// (possibly empty) null-separated \a MDString header that contains arbitrary |
260 | /// fields. The remaining operands are \a dwarf_operands(), and are pointers |
261 | /// to other metadata. |
262 | class GenericDINode : public DINode { |
263 | friend class LLVMContextImpl; |
264 | friend class MDNode; |
265 | |
266 | GenericDINode(LLVMContext &C, StorageType Storage, unsigned Hash, |
267 | unsigned Tag, ArrayRef<Metadata *> Ops1, |
268 | ArrayRef<Metadata *> Ops2) |
269 | : DINode(C, GenericDINodeKind, Storage, Tag, Ops1, Ops2) { |
270 | setHash(Hash); |
271 | } |
272 | ~GenericDINode() { dropAllReferences(); } |
273 | |
274 | void setHash(unsigned Hash) { SubclassData32 = Hash; } |
275 | void recalculateHash(); |
276 | |
277 | static GenericDINode *getImpl(LLVMContext &Context, unsigned Tag, |
278 | StringRef , ArrayRef<Metadata *> DwarfOps, |
279 | StorageType Storage, bool ShouldCreate = true) { |
280 | return getImpl(Context, Tag, getCanonicalMDString(Context, Header), |
281 | DwarfOps, Storage, ShouldCreate); |
282 | } |
283 | |
284 | static GenericDINode *getImpl(LLVMContext &Context, unsigned Tag, |
285 | MDString *, ArrayRef<Metadata *> DwarfOps, |
286 | StorageType Storage, bool ShouldCreate = true); |
287 | |
288 | TempGenericDINode cloneImpl() const { |
289 | return getTemporary( |
290 | getContext(), getTag(), getHeader(), |
291 | SmallVector<Metadata *, 4>(dwarf_op_begin(), dwarf_op_end())); |
292 | } |
293 | |
294 | public: |
295 | unsigned getHash() const { return SubclassData32; } |
296 | |
297 | DEFINE_MDNODE_GET(GenericDINode, (unsigned Tag, StringRef , |
298 | ArrayRef<Metadata *> DwarfOps), |
299 | (Tag, Header, DwarfOps)) |
300 | DEFINE_MDNODE_GET(GenericDINode, (unsigned Tag, MDString *, |
301 | ArrayRef<Metadata *> DwarfOps), |
302 | (Tag, Header, DwarfOps)) |
303 | |
304 | /// Return a (temporary) clone of this. |
305 | TempGenericDINode clone() const { return cloneImpl(); } |
306 | |
307 | unsigned getTag() const { return SubclassData16; } |
308 | StringRef () const { return getStringOperand(0); } |
309 | MDString *() const { return getOperandAs<MDString>(0); } |
310 | |
311 | op_iterator dwarf_op_begin() const { return op_begin() + 1; } |
312 | op_iterator dwarf_op_end() const { return op_end(); } |
313 | op_range dwarf_operands() const { |
314 | return op_range(dwarf_op_begin(), dwarf_op_end()); |
315 | } |
316 | |
317 | unsigned getNumDwarfOperands() const { return getNumOperands() - 1; } |
318 | const MDOperand &getDwarfOperand(unsigned I) const { |
319 | return getOperand(I + 1); |
320 | } |
321 | void replaceDwarfOperandWith(unsigned I, Metadata *New) { |
322 | replaceOperandWith(I + 1, New); |
323 | } |
324 | |
325 | static bool classof(const Metadata *MD) { |
326 | return MD->getMetadataID() == GenericDINodeKind; |
327 | } |
328 | }; |
329 | |
330 | /// Array subrange. |
331 | /// |
332 | /// TODO: Merge into node for DW_TAG_array_type, which should have a custom |
333 | /// type. |
334 | class DISubrange : public DINode { |
335 | friend class LLVMContextImpl; |
336 | friend class MDNode; |
337 | |
338 | int64_t LowerBound; |
339 | |
340 | DISubrange(LLVMContext &C, StorageType Storage, Metadata *Node, |
341 | int64_t LowerBound, ArrayRef<Metadata *> Ops) |
342 | : DINode(C, DISubrangeKind, Storage, dwarf::DW_TAG_subrange_type, Ops), |
343 | LowerBound(LowerBound) {} |
344 | |
345 | ~DISubrange() = default; |
346 | |
347 | static DISubrange *getImpl(LLVMContext &Context, int64_t Count, |
348 | int64_t LowerBound, StorageType Storage, |
349 | bool ShouldCreate = true); |
350 | |
351 | static DISubrange *getImpl(LLVMContext &Context, Metadata *CountNode, |
352 | int64_t LowerBound, StorageType Storage, |
353 | bool ShouldCreate = true); |
354 | |
355 | TempDISubrange cloneImpl() const { |
356 | return getTemporary(getContext(), getRawCountNode(), getLowerBound()); |
357 | } |
358 | |
359 | public: |
360 | DEFINE_MDNODE_GET(DISubrange, (int64_t Count, int64_t LowerBound = 0), |
361 | (Count, LowerBound)) |
362 | |
363 | DEFINE_MDNODE_GET(DISubrange, (Metadata *CountNode, int64_t LowerBound = 0), |
364 | (CountNode, LowerBound)) |
365 | |
366 | TempDISubrange clone() const { return cloneImpl(); } |
367 | |
368 | int64_t getLowerBound() const { return LowerBound; } |
369 | |
370 | Metadata *getRawCountNode() const { |
371 | return getOperand(0).get(); |
372 | } |
373 | |
374 | typedef PointerUnion<ConstantInt*, DIVariable*> CountType; |
375 | |
376 | CountType getCount() const { |
377 | if (auto *MD = dyn_cast<ConstantAsMetadata>(getRawCountNode())) |
378 | return CountType(cast<ConstantInt>(MD->getValue())); |
379 | |
380 | if (auto *DV = dyn_cast<DIVariable>(getRawCountNode())) |
381 | return CountType(DV); |
382 | |
383 | return CountType(); |
384 | } |
385 | |
386 | static bool classof(const Metadata *MD) { |
387 | return MD->getMetadataID() == DISubrangeKind; |
388 | } |
389 | }; |
390 | |
391 | /// Enumeration value. |
392 | /// |
393 | /// TODO: Add a pointer to the context (DW_TAG_enumeration_type) once that no |
394 | /// longer creates a type cycle. |
395 | class DIEnumerator : public DINode { |
396 | friend class LLVMContextImpl; |
397 | friend class MDNode; |
398 | |
399 | int64_t Value; |
400 | DIEnumerator(LLVMContext &C, StorageType Storage, int64_t Value, |
401 | bool IsUnsigned, ArrayRef<Metadata *> Ops) |
402 | : DINode(C, DIEnumeratorKind, Storage, dwarf::DW_TAG_enumerator, Ops), |
403 | Value(Value) { |
404 | SubclassData32 = IsUnsigned; |
405 | } |
406 | ~DIEnumerator() = default; |
407 | |
408 | static DIEnumerator *getImpl(LLVMContext &Context, int64_t Value, |
409 | bool IsUnsigned, StringRef Name, |
410 | StorageType Storage, bool ShouldCreate = true) { |
411 | return getImpl(Context, Value, IsUnsigned, |
412 | getCanonicalMDString(Context, Name), Storage, ShouldCreate); |
413 | } |
414 | static DIEnumerator *getImpl(LLVMContext &Context, int64_t Value, |
415 | bool IsUnsigned, MDString *Name, |
416 | StorageType Storage, bool ShouldCreate = true); |
417 | |
418 | TempDIEnumerator cloneImpl() const { |
419 | return getTemporary(getContext(), getValue(), isUnsigned(), getName()); |
420 | } |
421 | |
422 | public: |
423 | DEFINE_MDNODE_GET(DIEnumerator, (int64_t Value, bool IsUnsigned, StringRef Name), |
424 | (Value, IsUnsigned, Name)) |
425 | DEFINE_MDNODE_GET(DIEnumerator, (int64_t Value, bool IsUnsigned, MDString *Name), |
426 | (Value, IsUnsigned, Name)) |
427 | |
428 | TempDIEnumerator clone() const { return cloneImpl(); } |
429 | |
430 | int64_t getValue() const { return Value; } |
431 | bool isUnsigned() const { return SubclassData32; } |
432 | StringRef getName() const { return getStringOperand(0); } |
433 | |
434 | MDString *getRawName() const { return getOperandAs<MDString>(0); } |
435 | |
436 | static bool classof(const Metadata *MD) { |
437 | return MD->getMetadataID() == DIEnumeratorKind; |
438 | } |
439 | }; |
440 | |
441 | /// Base class for scope-like contexts. |
442 | /// |
443 | /// Base class for lexical scopes and types (which are also declaration |
444 | /// contexts). |
445 | /// |
446 | /// TODO: Separate the concepts of declaration contexts and lexical scopes. |
447 | class DIScope : public DINode { |
448 | protected: |
449 | DIScope(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag, |
450 | ArrayRef<Metadata *> Ops) |
451 | : DINode(C, ID, Storage, Tag, Ops) {} |
452 | ~DIScope() = default; |
453 | |
454 | public: |
455 | DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); } |
456 | |
457 | inline StringRef getFilename() const; |
458 | inline StringRef getDirectory() const; |
459 | inline Optional<StringRef> getSource() const; |
460 | |
461 | StringRef getName() const; |
462 | DIScopeRef getScope() const; |
463 | |
464 | /// Return the raw underlying file. |
465 | /// |
466 | /// A \a DIFile is a \a DIScope, but it doesn't point at a separate file (it |
467 | /// \em is the file). If \c this is an \a DIFile, we need to return \c this. |
468 | /// Otherwise, return the first operand, which is where all other subclasses |
469 | /// store their file pointer. |
470 | Metadata *getRawFile() const { |
471 | return isa<DIFile>(this) ? const_cast<DIScope *>(this) |
472 | : static_cast<Metadata *>(getOperand(0)); |
473 | } |
474 | |
475 | static bool classof(const Metadata *MD) { |
476 | switch (MD->getMetadataID()) { |
477 | default: |
478 | return false; |
479 | case DIBasicTypeKind: |
480 | case DIDerivedTypeKind: |
481 | case DICompositeTypeKind: |
482 | case DISubroutineTypeKind: |
483 | case DIFileKind: |
484 | case DICompileUnitKind: |
485 | case DISubprogramKind: |
486 | case DILexicalBlockKind: |
487 | case DILexicalBlockFileKind: |
488 | case DINamespaceKind: |
489 | case DIModuleKind: |
490 | return true; |
491 | } |
492 | } |
493 | }; |
494 | |
495 | /// File. |
496 | /// |
497 | /// TODO: Merge with directory/file node (including users). |
498 | /// TODO: Canonicalize paths on creation. |
499 | class DIFile : public DIScope { |
500 | friend class LLVMContextImpl; |
501 | friend class MDNode; |
502 | |
503 | public: |
504 | /// Which algorithm (e.g. MD5) a checksum was generated with. |
505 | /// |
506 | /// The encoding is explicit because it is used directly in Bitcode. The |
507 | /// value 0 is reserved to indicate the absence of a checksum in Bitcode. |
508 | enum ChecksumKind { |
509 | // The first variant was originally CSK_None, encoded as 0. The new |
510 | // internal representation removes the need for this by wrapping the |
511 | // ChecksumInfo in an Optional, but to preserve Bitcode compatibility the 0 |
512 | // encoding is reserved. |
513 | CSK_MD5 = 1, |
514 | CSK_SHA1 = 2, |
515 | CSK_Last = CSK_SHA1 // Should be last enumeration. |
516 | }; |
517 | |
518 | /// A single checksum, represented by a \a Kind and a \a Value (a string). |
519 | template <typename T> |
520 | struct ChecksumInfo { |
521 | /// The kind of checksum which \a Value encodes. |
522 | ChecksumKind Kind; |
523 | /// The string value of the checksum. |
524 | T Value; |
525 | |
526 | ChecksumInfo(ChecksumKind Kind, T Value) : Kind(Kind), Value(Value) { } |
527 | ~ChecksumInfo() = default; |
528 | bool operator==(const ChecksumInfo<T> &X) const { |
529 | return Kind == X.Kind && Value == X.Value; |
530 | } |
531 | bool operator!=(const ChecksumInfo<T> &X) const { return !(*this == X); } |
532 | StringRef getKindAsString() const { return getChecksumKindAsString(Kind); } |
533 | }; |
534 | |
535 | private: |
536 | Optional<ChecksumInfo<MDString *>> Checksum; |
537 | Optional<MDString *> Source; |
538 | |
539 | DIFile(LLVMContext &C, StorageType Storage, |
540 | Optional<ChecksumInfo<MDString *>> CS, Optional<MDString *> Src, |
541 | ArrayRef<Metadata *> Ops) |
542 | : DIScope(C, DIFileKind, Storage, dwarf::DW_TAG_file_type, Ops), |
543 | Checksum(CS), Source(Src) {} |
544 | ~DIFile() = default; |
545 | |
546 | static DIFile *getImpl(LLVMContext &Context, StringRef Filename, |
547 | StringRef Directory, |
548 | Optional<ChecksumInfo<StringRef>> CS, |
549 | Optional<StringRef> Source, |
550 | StorageType Storage, bool ShouldCreate = true) { |
551 | Optional<ChecksumInfo<MDString *>> MDChecksum; |
552 | if (CS) |
553 | MDChecksum.emplace(CS->Kind, getCanonicalMDString(Context, CS->Value)); |
554 | return getImpl(Context, getCanonicalMDString(Context, Filename), |
555 | getCanonicalMDString(Context, Directory), MDChecksum, |
556 | Source ? Optional<MDString *>(getCanonicalMDString(Context, *Source)) : None, |
557 | Storage, ShouldCreate); |
558 | } |
559 | static DIFile *getImpl(LLVMContext &Context, MDString *Filename, |
560 | MDString *Directory, |
561 | Optional<ChecksumInfo<MDString *>> CS, |
562 | Optional<MDString *> Source, StorageType Storage, |
563 | bool ShouldCreate = true); |
564 | |
565 | TempDIFile cloneImpl() const { |
566 | return getTemporary(getContext(), getFilename(), getDirectory(), |
567 | getChecksum(), getSource()); |
568 | } |
569 | |
570 | public: |
571 | DEFINE_MDNODE_GET(DIFile, (StringRef Filename, StringRef Directory, |
572 | Optional<ChecksumInfo<StringRef>> CS = None, |
573 | Optional<StringRef> Source = None), |
574 | (Filename, Directory, CS, Source)) |
575 | DEFINE_MDNODE_GET(DIFile, (MDString * Filename, MDString *Directory, |
576 | Optional<ChecksumInfo<MDString *>> CS = None, |
577 | Optional<MDString *> Source = None), |
578 | (Filename, Directory, CS, Source)) |
579 | |
580 | TempDIFile clone() const { return cloneImpl(); } |
581 | |
582 | StringRef getFilename() const { return getStringOperand(0); } |
583 | StringRef getDirectory() const { return getStringOperand(1); } |
584 | Optional<ChecksumInfo<StringRef>> getChecksum() const { |
585 | Optional<ChecksumInfo<StringRef>> StringRefChecksum; |
586 | if (Checksum) |
587 | StringRefChecksum.emplace(Checksum->Kind, Checksum->Value->getString()); |
588 | return StringRefChecksum; |
589 | } |
590 | Optional<StringRef> getSource() const { |
591 | return Source ? Optional<StringRef>((*Source)->getString()) : None; |
592 | } |
593 | |
594 | MDString *getRawFilename() const { return getOperandAs<MDString>(0); } |
595 | MDString *getRawDirectory() const { return getOperandAs<MDString>(1); } |
596 | Optional<ChecksumInfo<MDString *>> getRawChecksum() const { return Checksum; } |
597 | Optional<MDString *> getRawSource() const { return Source; } |
598 | |
599 | static StringRef getChecksumKindAsString(ChecksumKind CSKind); |
600 | static Optional<ChecksumKind> getChecksumKind(StringRef CSKindStr); |
601 | |
602 | static bool classof(const Metadata *MD) { |
603 | return MD->getMetadataID() == DIFileKind; |
604 | } |
605 | }; |
606 | |
607 | StringRef DIScope::getFilename() const { |
608 | if (auto *F = getFile()) |
609 | return F->getFilename(); |
610 | return "" ; |
611 | } |
612 | |
613 | StringRef DIScope::getDirectory() const { |
614 | if (auto *F = getFile()) |
615 | return F->getDirectory(); |
616 | return "" ; |
617 | } |
618 | |
619 | Optional<StringRef> DIScope::getSource() const { |
620 | if (auto *F = getFile()) |
621 | return F->getSource(); |
622 | return None; |
623 | } |
624 | |
625 | /// Base class for types. |
626 | /// |
627 | /// TODO: Remove the hardcoded name and context, since many types don't use |
628 | /// them. |
629 | /// TODO: Split up flags. |
630 | class DIType : public DIScope { |
631 | unsigned Line; |
632 | DIFlags Flags; |
633 | uint64_t SizeInBits; |
634 | uint64_t OffsetInBits; |
635 | uint32_t AlignInBits; |
636 | |
637 | protected: |
638 | DIType(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag, |
639 | unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits, |
640 | uint64_t OffsetInBits, DIFlags Flags, ArrayRef<Metadata *> Ops) |
641 | : DIScope(C, ID, Storage, Tag, Ops) { |
642 | init(Line, SizeInBits, AlignInBits, OffsetInBits, Flags); |
643 | } |
644 | ~DIType() = default; |
645 | |
646 | void init(unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits, |
647 | uint64_t OffsetInBits, DIFlags Flags) { |
648 | this->Line = Line; |
649 | this->Flags = Flags; |
650 | this->SizeInBits = SizeInBits; |
651 | this->AlignInBits = AlignInBits; |
652 | this->OffsetInBits = OffsetInBits; |
653 | } |
654 | |
655 | /// Change fields in place. |
656 | void mutate(unsigned Tag, unsigned Line, uint64_t SizeInBits, |
657 | uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags) { |
658 | assert(isDistinct() && "Only distinct nodes can mutate" ); |
659 | setTag(Tag); |
660 | init(Line, SizeInBits, AlignInBits, OffsetInBits, Flags); |
661 | } |
662 | |
663 | public: |
664 | TempDIType clone() const { |
665 | return TempDIType(cast<DIType>(MDNode::clone().release())); |
666 | } |
667 | |
668 | unsigned getLine() const { return Line; } |
669 | uint64_t getSizeInBits() const { return SizeInBits; } |
670 | uint32_t getAlignInBits() const { return AlignInBits; } |
671 | uint32_t getAlignInBytes() const { return getAlignInBits() / CHAR_BIT; } |
672 | uint64_t getOffsetInBits() const { return OffsetInBits; } |
673 | DIFlags getFlags() const { return Flags; } |
674 | |
675 | DIScopeRef getScope() const { return DIScopeRef(getRawScope()); } |
676 | StringRef getName() const { return getStringOperand(2); } |
677 | |
678 | |
679 | Metadata *getRawScope() const { return getOperand(1); } |
680 | MDString *getRawName() const { return getOperandAs<MDString>(2); } |
681 | |
682 | /// Returns a new temporary DIType with updated Flags |
683 | TempDIType cloneWithFlags(DIFlags NewFlags) const { |
684 | auto NewTy = clone(); |
685 | NewTy->Flags = NewFlags; |
686 | return NewTy; |
687 | } |
688 | |
689 | bool isPrivate() const { |
690 | return (getFlags() & FlagAccessibility) == FlagPrivate; |
691 | } |
692 | bool isProtected() const { |
693 | return (getFlags() & FlagAccessibility) == FlagProtected; |
694 | } |
695 | bool isPublic() const { |
696 | return (getFlags() & FlagAccessibility) == FlagPublic; |
697 | } |
698 | bool isForwardDecl() const { return getFlags() & FlagFwdDecl; } |
699 | bool isAppleBlockExtension() const { return getFlags() & FlagAppleBlock; } |
700 | bool isBlockByrefStruct() const { return getFlags() & FlagBlockByrefStruct; } |
701 | bool isVirtual() const { return getFlags() & FlagVirtual; } |
702 | bool isArtificial() const { return getFlags() & FlagArtificial; } |
703 | bool isObjectPointer() const { return getFlags() & FlagObjectPointer; } |
704 | bool isObjcClassComplete() const { |
705 | return getFlags() & FlagObjcClassComplete; |
706 | } |
707 | bool isVector() const { return getFlags() & FlagVector; } |
708 | bool isBitField() const { return getFlags() & FlagBitField; } |
709 | bool isStaticMember() const { return getFlags() & FlagStaticMember; } |
710 | bool isLValueReference() const { return getFlags() & FlagLValueReference; } |
711 | bool isRValueReference() const { return getFlags() & FlagRValueReference; } |
712 | bool isTypePassByValue() const { return getFlags() & FlagTypePassByValue; } |
713 | bool isTypePassByReference() const { |
714 | return getFlags() & FlagTypePassByReference; |
715 | } |
716 | bool isBigEndian() const { return getFlags() & FlagBigEndian; } |
717 | bool isLittleEndian() const { return getFlags() & FlagLittleEndian; } |
718 | |
719 | static bool classof(const Metadata *MD) { |
720 | switch (MD->getMetadataID()) { |
721 | default: |
722 | return false; |
723 | case DIBasicTypeKind: |
724 | case DIDerivedTypeKind: |
725 | case DICompositeTypeKind: |
726 | case DISubroutineTypeKind: |
727 | return true; |
728 | } |
729 | } |
730 | }; |
731 | |
732 | /// Basic type, like 'int' or 'float'. |
733 | /// |
734 | /// TODO: Split out DW_TAG_unspecified_type. |
735 | /// TODO: Drop unused accessors. |
736 | class DIBasicType : public DIType { |
737 | friend class LLVMContextImpl; |
738 | friend class MDNode; |
739 | |
740 | unsigned Encoding; |
741 | |
742 | DIBasicType(LLVMContext &C, StorageType Storage, unsigned Tag, |
743 | uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding, |
744 | DIFlags Flags, ArrayRef<Metadata *> Ops) |
745 | : DIType(C, DIBasicTypeKind, Storage, Tag, 0, SizeInBits, AlignInBits, 0, |
746 | Flags, Ops), |
747 | Encoding(Encoding) {} |
748 | ~DIBasicType() = default; |
749 | |
750 | static DIBasicType *getImpl(LLVMContext &Context, unsigned Tag, |
751 | StringRef Name, uint64_t SizeInBits, |
752 | uint32_t AlignInBits, unsigned Encoding, |
753 | DIFlags Flags, StorageType Storage, |
754 | bool ShouldCreate = true) { |
755 | return getImpl(Context, Tag, getCanonicalMDString(Context, Name), |
756 | SizeInBits, AlignInBits, Encoding, Flags, Storage, |
757 | ShouldCreate); |
758 | } |
759 | static DIBasicType *getImpl(LLVMContext &Context, unsigned Tag, |
760 | MDString *Name, uint64_t SizeInBits, |
761 | uint32_t AlignInBits, unsigned Encoding, |
762 | DIFlags Flags, StorageType Storage, |
763 | bool ShouldCreate = true); |
764 | |
765 | TempDIBasicType cloneImpl() const { |
766 | return getTemporary(getContext(), getTag(), getName(), getSizeInBits(), |
767 | getAlignInBits(), getEncoding(), getFlags()); |
768 | } |
769 | |
770 | public: |
771 | DEFINE_MDNODE_GET(DIBasicType, (unsigned Tag, StringRef Name), |
772 | (Tag, Name, 0, 0, 0, FlagZero)) |
773 | DEFINE_MDNODE_GET(DIBasicType, |
774 | (unsigned Tag, StringRef Name, uint64_t SizeInBits, |
775 | uint32_t AlignInBits, unsigned Encoding, DIFlags Flags), |
776 | (Tag, Name, SizeInBits, AlignInBits, Encoding, Flags)) |
777 | DEFINE_MDNODE_GET(DIBasicType, |
778 | (unsigned Tag, MDString *Name, uint64_t SizeInBits, |
779 | uint32_t AlignInBits, unsigned Encoding, DIFlags Flags), |
780 | (Tag, Name, SizeInBits, AlignInBits, Encoding, Flags)) |
781 | |
782 | TempDIBasicType clone() const { return cloneImpl(); } |
783 | |
784 | unsigned getEncoding() const { return Encoding; } |
785 | |
786 | enum class Signedness { Signed, Unsigned }; |
787 | |
788 | /// Return the signedness of this type, or None if this type is neither |
789 | /// signed nor unsigned. |
790 | Optional<Signedness> getSignedness() const; |
791 | |
792 | static bool classof(const Metadata *MD) { |
793 | return MD->getMetadataID() == DIBasicTypeKind; |
794 | } |
795 | }; |
796 | |
797 | /// Derived types. |
798 | /// |
799 | /// This includes qualified types, pointers, references, friends, typedefs, and |
800 | /// class members. |
801 | /// |
802 | /// TODO: Split out members (inheritance, fields, methods, etc.). |
803 | class DIDerivedType : public DIType { |
804 | friend class LLVMContextImpl; |
805 | friend class MDNode; |
806 | |
807 | /// The DWARF address space of the memory pointed to or referenced by a |
808 | /// pointer or reference type respectively. |
809 | Optional<unsigned> DWARFAddressSpace; |
810 | |
811 | DIDerivedType(LLVMContext &C, StorageType Storage, unsigned Tag, |
812 | unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits, |
813 | uint64_t OffsetInBits, Optional<unsigned> DWARFAddressSpace, |
814 | DIFlags Flags, ArrayRef<Metadata *> Ops) |
815 | : DIType(C, DIDerivedTypeKind, Storage, Tag, Line, SizeInBits, |
816 | AlignInBits, OffsetInBits, Flags, Ops), |
817 | DWARFAddressSpace(DWARFAddressSpace) {} |
818 | ~DIDerivedType() = default; |
819 | |
820 | static DIDerivedType *getImpl(LLVMContext &Context, unsigned Tag, |
821 | StringRef Name, DIFile *File, unsigned Line, |
822 | DIScopeRef Scope, DITypeRef BaseType, |
823 | uint64_t SizeInBits, uint32_t AlignInBits, |
824 | uint64_t OffsetInBits, |
825 | Optional<unsigned> DWARFAddressSpace, |
826 | DIFlags Flags, Metadata *, |
827 | StorageType Storage, bool ShouldCreate = true) { |
828 | return getImpl(Context, Tag, getCanonicalMDString(Context, Name), File, |
829 | Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, |
830 | DWARFAddressSpace, Flags, ExtraData, Storage, ShouldCreate); |
831 | } |
832 | static DIDerivedType *getImpl(LLVMContext &Context, unsigned Tag, |
833 | MDString *Name, Metadata *File, unsigned Line, |
834 | Metadata *Scope, Metadata *BaseType, |
835 | uint64_t SizeInBits, uint32_t AlignInBits, |
836 | uint64_t OffsetInBits, |
837 | Optional<unsigned> DWARFAddressSpace, |
838 | DIFlags Flags, Metadata *, |
839 | StorageType Storage, bool ShouldCreate = true); |
840 | |
841 | TempDIDerivedType cloneImpl() const { |
842 | return getTemporary(getContext(), getTag(), getName(), getFile(), getLine(), |
843 | getScope(), getBaseType(), getSizeInBits(), |
844 | getAlignInBits(), getOffsetInBits(), |
845 | getDWARFAddressSpace(), getFlags(), getExtraData()); |
846 | } |
847 | |
848 | public: |
849 | DEFINE_MDNODE_GET(DIDerivedType, |
850 | (unsigned Tag, MDString *Name, Metadata *File, |
851 | unsigned Line, Metadata *Scope, Metadata *BaseType, |
852 | uint64_t SizeInBits, uint32_t AlignInBits, |
853 | uint64_t OffsetInBits, |
854 | Optional<unsigned> DWARFAddressSpace, DIFlags Flags, |
855 | Metadata * = nullptr), |
856 | (Tag, Name, File, Line, Scope, BaseType, SizeInBits, |
857 | AlignInBits, OffsetInBits, DWARFAddressSpace, Flags, |
858 | ExtraData)) |
859 | DEFINE_MDNODE_GET(DIDerivedType, |
860 | (unsigned Tag, StringRef Name, DIFile *File, unsigned Line, |
861 | DIScopeRef Scope, DITypeRef BaseType, uint64_t SizeInBits, |
862 | uint32_t AlignInBits, uint64_t OffsetInBits, |
863 | Optional<unsigned> DWARFAddressSpace, DIFlags Flags, |
864 | Metadata * = nullptr), |
865 | (Tag, Name, File, Line, Scope, BaseType, SizeInBits, |
866 | AlignInBits, OffsetInBits, DWARFAddressSpace, Flags, |
867 | ExtraData)) |
868 | |
869 | TempDIDerivedType clone() const { return cloneImpl(); } |
870 | |
871 | /// Get the base type this is derived from. |
872 | DITypeRef getBaseType() const { return DITypeRef(getRawBaseType()); } |
873 | Metadata *getRawBaseType() const { return getOperand(3); } |
874 | |
875 | /// \returns The DWARF address space of the memory pointed to or referenced by |
876 | /// a pointer or reference type respectively. |
877 | Optional<unsigned> getDWARFAddressSpace() const { return DWARFAddressSpace; } |
878 | |
879 | /// Get extra data associated with this derived type. |
880 | /// |
881 | /// Class type for pointer-to-members, objective-c property node for ivars, |
882 | /// global constant wrapper for static members, or virtual base pointer offset |
883 | /// for inheritance. |
884 | /// |
885 | /// TODO: Separate out types that need this extra operand: pointer-to-member |
886 | /// types and member fields (static members and ivars). |
887 | Metadata *() const { return getRawExtraData(); } |
888 | Metadata *() const { return getOperand(4); } |
889 | |
890 | /// Get casted version of extra data. |
891 | /// @{ |
892 | DITypeRef getClassType() const { |
893 | assert(getTag() == dwarf::DW_TAG_ptr_to_member_type); |
894 | return DITypeRef(getExtraData()); |
895 | } |
896 | |
897 | DIObjCProperty *getObjCProperty() const { |
898 | return dyn_cast_or_null<DIObjCProperty>(getExtraData()); |
899 | } |
900 | |
901 | uint32_t getVBPtrOffset() const { |
902 | assert(getTag() == dwarf::DW_TAG_inheritance); |
903 | if (auto *CM = cast_or_null<ConstantAsMetadata>(getExtraData())) |
904 | if (auto *CI = dyn_cast_or_null<ConstantInt>(CM->getValue())) |
905 | return static_cast<uint32_t>(CI->getZExtValue()); |
906 | return 0; |
907 | } |
908 | |
909 | Constant *getStorageOffsetInBits() const { |
910 | assert(getTag() == dwarf::DW_TAG_member && isBitField()); |
911 | if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData())) |
912 | return C->getValue(); |
913 | return nullptr; |
914 | } |
915 | |
916 | Constant *getConstant() const { |
917 | assert(getTag() == dwarf::DW_TAG_member && isStaticMember()); |
918 | if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData())) |
919 | return C->getValue(); |
920 | return nullptr; |
921 | } |
922 | Constant *getDiscriminantValue() const { |
923 | assert(getTag() == dwarf::DW_TAG_member && !isStaticMember()); |
924 | if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData())) |
925 | return C->getValue(); |
926 | return nullptr; |
927 | } |
928 | /// @} |
929 | |
930 | static bool classof(const Metadata *MD) { |
931 | return MD->getMetadataID() == DIDerivedTypeKind; |
932 | } |
933 | }; |
934 | |
935 | /// Composite types. |
936 | /// |
937 | /// TODO: Detach from DerivedTypeBase (split out MDEnumType?). |
938 | /// TODO: Create a custom, unrelated node for DW_TAG_array_type. |
939 | class DICompositeType : public DIType { |
940 | friend class LLVMContextImpl; |
941 | friend class MDNode; |
942 | |
943 | unsigned RuntimeLang; |
944 | |
945 | DICompositeType(LLVMContext &C, StorageType Storage, unsigned Tag, |
946 | unsigned Line, unsigned RuntimeLang, uint64_t SizeInBits, |
947 | uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags, |
948 | ArrayRef<Metadata *> Ops) |
949 | : DIType(C, DICompositeTypeKind, Storage, Tag, Line, SizeInBits, |
950 | AlignInBits, OffsetInBits, Flags, Ops), |
951 | RuntimeLang(RuntimeLang) {} |
952 | ~DICompositeType() = default; |
953 | |
954 | /// Change fields in place. |
955 | void mutate(unsigned Tag, unsigned Line, unsigned RuntimeLang, |
956 | uint64_t SizeInBits, uint32_t AlignInBits, |
957 | uint64_t OffsetInBits, DIFlags Flags) { |
958 | assert(isDistinct() && "Only distinct nodes can mutate" ); |
959 | assert(getRawIdentifier() && "Only ODR-uniqued nodes should mutate" ); |
960 | this->RuntimeLang = RuntimeLang; |
961 | DIType::mutate(Tag, Line, SizeInBits, AlignInBits, OffsetInBits, Flags); |
962 | } |
963 | |
964 | static DICompositeType * |
965 | getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, Metadata *File, |
966 | unsigned Line, DIScopeRef Scope, DITypeRef BaseType, |
967 | uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, |
968 | DIFlags Flags, DINodeArray Elements, unsigned RuntimeLang, |
969 | DITypeRef VTableHolder, DITemplateParameterArray TemplateParams, |
970 | StringRef Identifier, DIDerivedType *Discriminator, |
971 | StorageType Storage, bool ShouldCreate = true) { |
972 | return getImpl( |
973 | Context, Tag, getCanonicalMDString(Context, Name), File, Line, Scope, |
974 | BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements.get(), |
975 | RuntimeLang, VTableHolder, TemplateParams.get(), |
976 | getCanonicalMDString(Context, Identifier), Discriminator, Storage, ShouldCreate); |
977 | } |
978 | static DICompositeType * |
979 | getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File, |
980 | unsigned Line, Metadata *Scope, Metadata *BaseType, |
981 | uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, |
982 | DIFlags Flags, Metadata *Elements, unsigned RuntimeLang, |
983 | Metadata *VTableHolder, Metadata *TemplateParams, |
984 | MDString *Identifier, Metadata *Discriminator, |
985 | StorageType Storage, bool ShouldCreate = true); |
986 | |
987 | TempDICompositeType cloneImpl() const { |
988 | return getTemporary(getContext(), getTag(), getName(), getFile(), getLine(), |
989 | getScope(), getBaseType(), getSizeInBits(), |
990 | getAlignInBits(), getOffsetInBits(), getFlags(), |
991 | getElements(), getRuntimeLang(), getVTableHolder(), |
992 | getTemplateParams(), getIdentifier(), getDiscriminator()); |
993 | } |
994 | |
995 | public: |
996 | DEFINE_MDNODE_GET(DICompositeType, |
997 | (unsigned Tag, StringRef Name, DIFile *File, unsigned Line, |
998 | DIScopeRef Scope, DITypeRef BaseType, uint64_t SizeInBits, |
999 | uint32_t AlignInBits, uint64_t OffsetInBits, |
1000 | DIFlags Flags, DINodeArray Elements, unsigned RuntimeLang, |
1001 | DITypeRef VTableHolder, |
1002 | DITemplateParameterArray TemplateParams = nullptr, |
1003 | StringRef Identifier = "" , DIDerivedType *Discriminator = nullptr), |
1004 | (Tag, Name, File, Line, Scope, BaseType, SizeInBits, |
1005 | AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, |
1006 | VTableHolder, TemplateParams, Identifier, Discriminator)) |
1007 | DEFINE_MDNODE_GET(DICompositeType, |
1008 | (unsigned Tag, MDString *Name, Metadata *File, |
1009 | unsigned Line, Metadata *Scope, Metadata *BaseType, |
1010 | uint64_t SizeInBits, uint32_t AlignInBits, |
1011 | uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements, |
1012 | unsigned RuntimeLang, Metadata *VTableHolder, |
1013 | Metadata *TemplateParams = nullptr, |
1014 | MDString *Identifier = nullptr, |
1015 | Metadata *Discriminator = nullptr), |
1016 | (Tag, Name, File, Line, Scope, BaseType, SizeInBits, |
1017 | AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, |
1018 | VTableHolder, TemplateParams, Identifier, Discriminator)) |
1019 | |
1020 | TempDICompositeType clone() const { return cloneImpl(); } |
1021 | |
1022 | /// Get a DICompositeType with the given ODR identifier. |
1023 | /// |
1024 | /// If \a LLVMContext::isODRUniquingDebugTypes(), gets the mapped |
1025 | /// DICompositeType for the given ODR \c Identifier. If none exists, creates |
1026 | /// a new node. |
1027 | /// |
1028 | /// Else, returns \c nullptr. |
1029 | static DICompositeType * |
1030 | getODRType(LLVMContext &Context, MDString &Identifier, unsigned Tag, |
1031 | MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, |
1032 | Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits, |
1033 | uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements, |
1034 | unsigned RuntimeLang, Metadata *VTableHolder, |
1035 | Metadata *TemplateParams, Metadata *Discriminator); |
1036 | static DICompositeType *getODRTypeIfExists(LLVMContext &Context, |
1037 | MDString &Identifier); |
1038 | |
1039 | /// Build a DICompositeType with the given ODR identifier. |
1040 | /// |
1041 | /// Looks up the mapped DICompositeType for the given ODR \c Identifier. If |
1042 | /// it doesn't exist, creates a new one. If it does exist and \a |
1043 | /// isForwardDecl(), and the new arguments would be a definition, mutates the |
1044 | /// the type in place. In either case, returns the type. |
1045 | /// |
1046 | /// If not \a LLVMContext::isODRUniquingDebugTypes(), this function returns |
1047 | /// nullptr. |
1048 | static DICompositeType * |
1049 | buildODRType(LLVMContext &Context, MDString &Identifier, unsigned Tag, |
1050 | MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, |
1051 | Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits, |
1052 | uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements, |
1053 | unsigned RuntimeLang, Metadata *VTableHolder, |
1054 | Metadata *TemplateParams, Metadata *Discriminator); |
1055 | |
1056 | DITypeRef getBaseType() const { return DITypeRef(getRawBaseType()); } |
1057 | DINodeArray getElements() const { |
1058 | return cast_or_null<MDTuple>(getRawElements()); |
1059 | } |
1060 | DITypeRef getVTableHolder() const { return DITypeRef(getRawVTableHolder()); } |
1061 | DITemplateParameterArray getTemplateParams() const { |
1062 | return cast_or_null<MDTuple>(getRawTemplateParams()); |
1063 | } |
1064 | StringRef getIdentifier() const { return getStringOperand(7); } |
1065 | unsigned getRuntimeLang() const { return RuntimeLang; } |
1066 | |
1067 | Metadata *getRawBaseType() const { return getOperand(3); } |
1068 | Metadata *getRawElements() const { return getOperand(4); } |
1069 | Metadata *getRawVTableHolder() const { return getOperand(5); } |
1070 | Metadata *getRawTemplateParams() const { return getOperand(6); } |
1071 | MDString *getRawIdentifier() const { return getOperandAs<MDString>(7); } |
1072 | Metadata *getRawDiscriminator() const { return getOperand(8); } |
1073 | DIDerivedType *getDiscriminator() const { return getOperandAs<DIDerivedType>(8); } |
1074 | |
1075 | /// Replace operands. |
1076 | /// |
1077 | /// If this \a isUniqued() and not \a isResolved(), on a uniquing collision |
1078 | /// this will be RAUW'ed and deleted. Use a \a TrackingMDRef to keep track |
1079 | /// of its movement if necessary. |
1080 | /// @{ |
1081 | void replaceElements(DINodeArray Elements) { |
1082 | #ifndef NDEBUG |
1083 | for (DINode *Op : getElements()) |
1084 | assert(is_contained(Elements->operands(), Op) && |
1085 | "Lost a member during member list replacement" ); |
1086 | #endif |
1087 | replaceOperandWith(4, Elements.get()); |
1088 | } |
1089 | |
1090 | void replaceVTableHolder(DITypeRef VTableHolder) { |
1091 | replaceOperandWith(5, VTableHolder); |
1092 | } |
1093 | |
1094 | void replaceTemplateParams(DITemplateParameterArray TemplateParams) { |
1095 | replaceOperandWith(6, TemplateParams.get()); |
1096 | } |
1097 | /// @} |
1098 | |
1099 | static bool classof(const Metadata *MD) { |
1100 | return MD->getMetadataID() == DICompositeTypeKind; |
1101 | } |
1102 | }; |
1103 | |
1104 | /// Type array for a subprogram. |
1105 | /// |
1106 | /// TODO: Fold the array of types in directly as operands. |
1107 | class DISubroutineType : public DIType { |
1108 | friend class LLVMContextImpl; |
1109 | friend class MDNode; |
1110 | |
1111 | /// The calling convention used with DW_AT_calling_convention. Actually of |
1112 | /// type dwarf::CallingConvention. |
1113 | uint8_t CC; |
1114 | |
1115 | DISubroutineType(LLVMContext &C, StorageType Storage, DIFlags Flags, |
1116 | uint8_t CC, ArrayRef<Metadata *> Ops) |
1117 | : DIType(C, DISubroutineTypeKind, Storage, dwarf::DW_TAG_subroutine_type, |
1118 | 0, 0, 0, 0, Flags, Ops), |
1119 | CC(CC) {} |
1120 | ~DISubroutineType() = default; |
1121 | |
1122 | static DISubroutineType *getImpl(LLVMContext &Context, DIFlags Flags, |
1123 | uint8_t CC, DITypeRefArray TypeArray, |
1124 | StorageType Storage, |
1125 | bool ShouldCreate = true) { |
1126 | return getImpl(Context, Flags, CC, TypeArray.get(), Storage, ShouldCreate); |
1127 | } |
1128 | static DISubroutineType *getImpl(LLVMContext &Context, DIFlags Flags, |
1129 | uint8_t CC, Metadata *TypeArray, |
1130 | StorageType Storage, |
1131 | bool ShouldCreate = true); |
1132 | |
1133 | TempDISubroutineType cloneImpl() const { |
1134 | return getTemporary(getContext(), getFlags(), getCC(), getTypeArray()); |
1135 | } |
1136 | |
1137 | public: |
1138 | DEFINE_MDNODE_GET(DISubroutineType, |
1139 | (DIFlags Flags, uint8_t CC, DITypeRefArray TypeArray), |
1140 | (Flags, CC, TypeArray)) |
1141 | DEFINE_MDNODE_GET(DISubroutineType, |
1142 | (DIFlags Flags, uint8_t CC, Metadata *TypeArray), |
1143 | (Flags, CC, TypeArray)) |
1144 | |
1145 | TempDISubroutineType clone() const { return cloneImpl(); } |
1146 | |
1147 | uint8_t getCC() const { return CC; } |
1148 | |
1149 | DITypeRefArray getTypeArray() const { |
1150 | return cast_or_null<MDTuple>(getRawTypeArray()); |
1151 | } |
1152 | |
1153 | Metadata *getRawTypeArray() const { return getOperand(3); } |
1154 | |
1155 | static bool classof(const Metadata *MD) { |
1156 | return MD->getMetadataID() == DISubroutineTypeKind; |
1157 | } |
1158 | }; |
1159 | |
1160 | /// Compile unit. |
1161 | class DICompileUnit : public DIScope { |
1162 | friend class LLVMContextImpl; |
1163 | friend class MDNode; |
1164 | |
1165 | public: |
1166 | enum DebugEmissionKind : unsigned { |
1167 | NoDebug = 0, |
1168 | FullDebug, |
1169 | LineTablesOnly, |
1170 | DebugDirectivesOnly, |
1171 | LastEmissionKind = DebugDirectivesOnly |
1172 | }; |
1173 | |
1174 | enum class DebugNameTableKind : unsigned { |
1175 | Default = 0, |
1176 | GNU = 1, |
1177 | None = 2, |
1178 | LastDebugNameTableKind = None |
1179 | }; |
1180 | |
1181 | static Optional<DebugEmissionKind> getEmissionKind(StringRef Str); |
1182 | static const char *emissionKindString(DebugEmissionKind EK); |
1183 | static Optional<DebugNameTableKind> getNameTableKind(StringRef Str); |
1184 | static const char *nameTableKindString(DebugNameTableKind PK); |
1185 | |
1186 | private: |
1187 | unsigned SourceLanguage; |
1188 | bool IsOptimized; |
1189 | unsigned RuntimeVersion; |
1190 | unsigned EmissionKind; |
1191 | uint64_t DWOId; |
1192 | bool SplitDebugInlining; |
1193 | bool DebugInfoForProfiling; |
1194 | unsigned NameTableKind; |
1195 | bool RangesBaseAddress; |
1196 | |
1197 | DICompileUnit(LLVMContext &C, StorageType Storage, unsigned SourceLanguage, |
1198 | bool IsOptimized, unsigned RuntimeVersion, |
1199 | unsigned EmissionKind, uint64_t DWOId, bool SplitDebugInlining, |
1200 | bool DebugInfoForProfiling, unsigned NameTableKind, |
1201 | bool RangesBaseAddress, ArrayRef<Metadata *> Ops) |
1202 | : DIScope(C, DICompileUnitKind, Storage, dwarf::DW_TAG_compile_unit, Ops), |
1203 | SourceLanguage(SourceLanguage), IsOptimized(IsOptimized), |
1204 | RuntimeVersion(RuntimeVersion), EmissionKind(EmissionKind), |
1205 | DWOId(DWOId), SplitDebugInlining(SplitDebugInlining), |
1206 | DebugInfoForProfiling(DebugInfoForProfiling), |
1207 | NameTableKind(NameTableKind), RangesBaseAddress(RangesBaseAddress) { |
1208 | assert(Storage != Uniqued); |
1209 | } |
1210 | ~DICompileUnit() = default; |
1211 | |
1212 | static DICompileUnit * |
1213 | getImpl(LLVMContext &Context, unsigned SourceLanguage, DIFile *File, |
1214 | StringRef Producer, bool IsOptimized, StringRef Flags, |
1215 | unsigned RuntimeVersion, StringRef SplitDebugFilename, |
1216 | unsigned EmissionKind, DICompositeTypeArray EnumTypes, |
1217 | DIScopeArray RetainedTypes, |
1218 | DIGlobalVariableExpressionArray GlobalVariables, |
1219 | DIImportedEntityArray ImportedEntities, DIMacroNodeArray Macros, |
1220 | uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling, |
1221 | unsigned NameTableKind, bool RangesBaseAddress, StorageType Storage, |
1222 | bool ShouldCreate = true) { |
1223 | return getImpl(Context, SourceLanguage, File, |
1224 | getCanonicalMDString(Context, Producer), IsOptimized, |
1225 | getCanonicalMDString(Context, Flags), RuntimeVersion, |
1226 | getCanonicalMDString(Context, SplitDebugFilename), |
1227 | EmissionKind, EnumTypes.get(), RetainedTypes.get(), |
1228 | GlobalVariables.get(), ImportedEntities.get(), Macros.get(), |
1229 | DWOId, SplitDebugInlining, DebugInfoForProfiling, |
1230 | NameTableKind, RangesBaseAddress, Storage, ShouldCreate); |
1231 | } |
1232 | static DICompileUnit * |
1233 | getImpl(LLVMContext &Context, unsigned SourceLanguage, Metadata *File, |
1234 | MDString *Producer, bool IsOptimized, MDString *Flags, |
1235 | unsigned RuntimeVersion, MDString *SplitDebugFilename, |
1236 | unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes, |
1237 | Metadata *GlobalVariables, Metadata *ImportedEntities, |
1238 | Metadata *Macros, uint64_t DWOId, bool SplitDebugInlining, |
1239 | bool DebugInfoForProfiling, unsigned NameTableKind, |
1240 | bool RangesBaseAddress, StorageType Storage, bool ShouldCreate = true); |
1241 | |
1242 | TempDICompileUnit cloneImpl() const { |
1243 | return getTemporary( |
1244 | getContext(), getSourceLanguage(), getFile(), getProducer(), |
1245 | isOptimized(), getFlags(), getRuntimeVersion(), getSplitDebugFilename(), |
1246 | getEmissionKind(), getEnumTypes(), getRetainedTypes(), |
1247 | getGlobalVariables(), getImportedEntities(), getMacros(), DWOId, |
1248 | getSplitDebugInlining(), getDebugInfoForProfiling(), getNameTableKind(), |
1249 | getRangesBaseAddress()); |
1250 | } |
1251 | |
1252 | public: |
1253 | static void get() = delete; |
1254 | static void getIfExists() = delete; |
1255 | |
1256 | DEFINE_MDNODE_GET_DISTINCT_TEMPORARY( |
1257 | DICompileUnit, |
1258 | (unsigned SourceLanguage, DIFile *File, StringRef Producer, |
1259 | bool IsOptimized, StringRef Flags, unsigned RuntimeVersion, |
1260 | StringRef SplitDebugFilename, DebugEmissionKind EmissionKind, |
1261 | DICompositeTypeArray EnumTypes, DIScopeArray RetainedTypes, |
1262 | DIGlobalVariableExpressionArray GlobalVariables, |
1263 | DIImportedEntityArray ImportedEntities, DIMacroNodeArray Macros, |
1264 | uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling, |
1265 | DebugNameTableKind NameTableKind, bool RangesBaseAddress), |
1266 | (SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion, |
1267 | SplitDebugFilename, EmissionKind, EnumTypes, RetainedTypes, |
1268 | GlobalVariables, ImportedEntities, Macros, DWOId, SplitDebugInlining, |
1269 | DebugInfoForProfiling, (unsigned)NameTableKind, RangesBaseAddress)) |
1270 | DEFINE_MDNODE_GET_DISTINCT_TEMPORARY( |
1271 | DICompileUnit, |
1272 | (unsigned SourceLanguage, Metadata *File, MDString *Producer, |
1273 | bool IsOptimized, MDString *Flags, unsigned RuntimeVersion, |
1274 | MDString *SplitDebugFilename, unsigned EmissionKind, Metadata *EnumTypes, |
1275 | Metadata *RetainedTypes, Metadata *GlobalVariables, |
1276 | Metadata *ImportedEntities, Metadata *Macros, uint64_t DWOId, |
1277 | bool SplitDebugInlining, bool DebugInfoForProfiling, |
1278 | unsigned NameTableKind, bool RangesBaseAddress), |
1279 | (SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion, |
1280 | SplitDebugFilename, EmissionKind, EnumTypes, RetainedTypes, |
1281 | GlobalVariables, ImportedEntities, Macros, DWOId, SplitDebugInlining, |
1282 | DebugInfoForProfiling, NameTableKind, RangesBaseAddress)) |
1283 | |
1284 | TempDICompileUnit clone() const { return cloneImpl(); } |
1285 | |
1286 | unsigned getSourceLanguage() const { return SourceLanguage; } |
1287 | bool isOptimized() const { return IsOptimized; } |
1288 | unsigned getRuntimeVersion() const { return RuntimeVersion; } |
1289 | DebugEmissionKind getEmissionKind() const { |
1290 | return (DebugEmissionKind)EmissionKind; |
1291 | } |
1292 | bool isDebugDirectivesOnly() const { |
1293 | return EmissionKind == DebugDirectivesOnly; |
1294 | } |
1295 | bool getDebugInfoForProfiling() const { return DebugInfoForProfiling; } |
1296 | DebugNameTableKind getNameTableKind() const { |
1297 | return (DebugNameTableKind)NameTableKind; |
1298 | } |
1299 | bool getRangesBaseAddress() const { |
1300 | return RangesBaseAddress; } |
1301 | StringRef getProducer() const { |
1302 | return getStringOperand(1); } |
1303 | StringRef getFlags() const { |
1304 | return getStringOperand(2); } |
1305 | StringRef getSplitDebugFilename() const { |
1306 | return getStringOperand(3); } |
1307 | DICompositeTypeArray getEnumTypes() const { |
1308 | return cast_or_null<MDTuple>(getRawEnumTypes()); |
1309 | } |
1310 | DIScopeArray getRetainedTypes() const { |
1311 | return cast_or_null<MDTuple>(getRawRetainedTypes()); |
1312 | } |
1313 | DIGlobalVariableExpressionArray getGlobalVariables() const { |
1314 | return cast_or_null<MDTuple>(getRawGlobalVariables()); |
1315 | } |
1316 | DIImportedEntityArray getImportedEntities() const { |
1317 | return cast_or_null<MDTuple>(getRawImportedEntities()); |
1318 | } |
1319 | DIMacroNodeArray getMacros() const { |
1320 | return cast_or_null<MDTuple>(getRawMacros()); |
1321 | } |
1322 | uint64_t getDWOId() const { return DWOId; } |
1323 | void setDWOId(uint64_t DwoId) { DWOId = DwoId; } |
1324 | bool getSplitDebugInlining() const { return SplitDebugInlining; } |
1325 | void setSplitDebugInlining(bool SplitDebugInlining) { |
1326 | this->SplitDebugInlining = SplitDebugInlining; |
1327 | } |
1328 | |
1329 | MDString *getRawProducer() const { return getOperandAs<MDString>(1); } |
1330 | MDString *getRawFlags() const { return getOperandAs<MDString>(2); } |
1331 | MDString *getRawSplitDebugFilename() const { |
1332 | return getOperandAs<MDString>(3); |
1333 | } |
1334 | Metadata *getRawEnumTypes() const { return getOperand(4); } |
1335 | Metadata *getRawRetainedTypes() const { return getOperand(5); } |
1336 | Metadata *getRawGlobalVariables() const { return getOperand(6); } |
1337 | Metadata *getRawImportedEntities() const { return getOperand(7); } |
1338 | Metadata *getRawMacros() const { return getOperand(8); } |
1339 | |
1340 | /// Replace arrays. |
1341 | /// |
1342 | /// If this \a isUniqued() and not \a isResolved(), it will be RAUW'ed and |
1343 | /// deleted on a uniquing collision. In practice, uniquing collisions on \a |
1344 | /// DICompileUnit should be fairly rare. |
1345 | /// @{ |
1346 | void replaceEnumTypes(DICompositeTypeArray N) { |
1347 | replaceOperandWith(4, N.get()); |
1348 | } |
1349 | void replaceRetainedTypes(DITypeArray N) { |
1350 | replaceOperandWith(5, N.get()); |
1351 | } |
1352 | void replaceGlobalVariables(DIGlobalVariableExpressionArray N) { |
1353 | replaceOperandWith(6, N.get()); |
1354 | } |
1355 | void replaceImportedEntities(DIImportedEntityArray N) { |
1356 | replaceOperandWith(7, N.get()); |
1357 | } |
1358 | void replaceMacros(DIMacroNodeArray N) { replaceOperandWith(8, N.get()); } |
1359 | /// @} |
1360 | |
1361 | static bool classof(const Metadata *MD) { |
1362 | return MD->getMetadataID() == DICompileUnitKind; |
1363 | } |
1364 | }; |
1365 | |
1366 | /// A scope for locals. |
1367 | /// |
1368 | /// A legal scope for lexical blocks, local variables, and debug info |
1369 | /// locations. Subclasses are \a DISubprogram, \a DILexicalBlock, and \a |
1370 | /// DILexicalBlockFile. |
1371 | class DILocalScope : public DIScope { |
1372 | protected: |
1373 | DILocalScope(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag, |
1374 | ArrayRef<Metadata *> Ops) |
1375 | : DIScope(C, ID, Storage, Tag, Ops) {} |
1376 | ~DILocalScope() = default; |
1377 | |
1378 | public: |
1379 | /// Get the subprogram for this scope. |
1380 | /// |
1381 | /// Return this if it's an \a DISubprogram; otherwise, look up the scope |
1382 | /// chain. |
1383 | DISubprogram *getSubprogram() const; |
1384 | |
1385 | /// Get the first non DILexicalBlockFile scope of this scope. |
1386 | /// |
1387 | /// Return this if it's not a \a DILexicalBlockFIle; otherwise, look up the |
1388 | /// scope chain. |
1389 | DILocalScope *getNonLexicalBlockFileScope() const; |
1390 | |
1391 | static bool classof(const Metadata *MD) { |
1392 | return MD->getMetadataID() == DISubprogramKind || |
1393 | MD->getMetadataID() == DILexicalBlockKind || |
1394 | MD->getMetadataID() == DILexicalBlockFileKind; |
1395 | } |
1396 | }; |
1397 | |
1398 | /// Debug location. |
1399 | /// |
1400 | /// A debug location in source code, used for debug info and otherwise. |
1401 | class DILocation : public MDNode { |
1402 | friend class LLVMContextImpl; |
1403 | friend class MDNode; |
1404 | |
1405 | DILocation(LLVMContext &C, StorageType Storage, unsigned Line, |
1406 | unsigned Column, ArrayRef<Metadata *> MDs, bool ImplicitCode); |
1407 | ~DILocation() { dropAllReferences(); } |
1408 | |
1409 | static DILocation *getImpl(LLVMContext &Context, unsigned Line, |
1410 | unsigned Column, Metadata *Scope, |
1411 | Metadata *InlinedAt, bool ImplicitCode, |
1412 | StorageType Storage, bool ShouldCreate = true); |
1413 | static DILocation *getImpl(LLVMContext &Context, unsigned Line, |
1414 | unsigned Column, DILocalScope *Scope, |
1415 | DILocation *InlinedAt, bool ImplicitCode, |
1416 | StorageType Storage, bool ShouldCreate = true) { |
1417 | return getImpl(Context, Line, Column, static_cast<Metadata *>(Scope), |
1418 | static_cast<Metadata *>(InlinedAt), ImplicitCode, Storage, |
1419 | ShouldCreate); |
1420 | } |
1421 | |
1422 | /// With a given unsigned int \p U, use up to 13 bits to represent it. |
1423 | /// old_bit 1~5 --> new_bit 1~5 |
1424 | /// old_bit 6~12 --> new_bit 7~13 |
1425 | /// new_bit_6 is 0 if higher bits (7~13) are all 0 |
1426 | static unsigned getPrefixEncodingFromUnsigned(unsigned U) { |
1427 | U &= 0xfff; |
1428 | return U > 0x1f ? (((U & 0xfe0) << 1) | (U & 0x1f) | 0x20) : U; |
1429 | } |
1430 | |
1431 | /// Reverse transformation as getPrefixEncodingFromUnsigned. |
1432 | static unsigned getUnsignedFromPrefixEncoding(unsigned U) { |
1433 | if (U & 1) |
1434 | return 0; |
1435 | U >>= 1; |
1436 | return (U & 0x20) ? (((U >> 1) & 0xfe0) | (U & 0x1f)) : (U & 0x1f); |
1437 | } |
1438 | |
1439 | /// Returns the next component stored in discriminator. |
1440 | static unsigned getNextComponentInDiscriminator(unsigned D) { |
1441 | if ((D & 1) == 0) |
1442 | return D >> ((D & 0x40) ? 14 : 7); |
1443 | else |
1444 | return D >> 1; |
1445 | } |
1446 | |
1447 | TempDILocation cloneImpl() const { |
1448 | // Get the raw scope/inlinedAt since it is possible to invoke this on |
1449 | // a DILocation containing temporary metadata. |
1450 | return getTemporary(getContext(), getLine(), getColumn(), getRawScope(), |
1451 | getRawInlinedAt(), isImplicitCode()); |
1452 | } |
1453 | |
1454 | static unsigned encodeComponent(unsigned C) { |
1455 | return (C == 0) ? 1U : (getPrefixEncodingFromUnsigned(C) << 1); |
1456 | } |
1457 | |
1458 | static unsigned encodingBits(unsigned C) { |
1459 | return (C == 0) ? 1 : (C > 0x1f ? 14 : 7); |
1460 | } |
1461 | |
1462 | public: |
1463 | // Disallow replacing operands. |
1464 | void replaceOperandWith(unsigned I, Metadata *New) = delete; |
1465 | |
1466 | DEFINE_MDNODE_GET(DILocation, |
1467 | (unsigned Line, unsigned Column, Metadata *Scope, |
1468 | Metadata *InlinedAt = nullptr, bool ImplicitCode = false), |
1469 | (Line, Column, Scope, InlinedAt, ImplicitCode)) |
1470 | DEFINE_MDNODE_GET(DILocation, |
1471 | (unsigned Line, unsigned Column, DILocalScope *Scope, |
1472 | DILocation *InlinedAt = nullptr, |
1473 | bool ImplicitCode = false), |
1474 | (Line, Column, Scope, InlinedAt, ImplicitCode)) |
1475 | |
1476 | /// Return a (temporary) clone of this. |
1477 | TempDILocation clone() const { return cloneImpl(); } |
1478 | |
1479 | unsigned getLine() const { return SubclassData32; } |
1480 | unsigned getColumn() const { return SubclassData16; } |
1481 | DILocalScope *getScope() const { return cast<DILocalScope>(getRawScope()); } |
1482 | |
1483 | DILocation *getInlinedAt() const { |
1484 | return cast_or_null<DILocation>(getRawInlinedAt()); |
1485 | } |
1486 | |
1487 | /// Check if the location corresponds to an implicit code. |
1488 | /// When the ImplicitCode flag is true, it means that the Instruction |
1489 | /// with this DILocation has been added by the front-end but it hasn't been |
1490 | /// written explicitly by the user (e.g. cleanup stuff in C++ put on a closing |
1491 | /// bracket). It's useful for code coverage to not show a counter on "empty" |
1492 | /// lines. |
1493 | bool isImplicitCode() const { return ImplicitCode; } |
1494 | void setImplicitCode(bool ImplicitCode) { this->ImplicitCode = ImplicitCode; } |
1495 | |
1496 | DIFile *getFile() const { return getScope()->getFile(); } |
1497 | StringRef getFilename() const { return getScope()->getFilename(); } |
1498 | StringRef getDirectory() const { return getScope()->getDirectory(); } |
1499 | Optional<StringRef> getSource() const { return getScope()->getSource(); } |
1500 | |
1501 | /// Get the scope where this is inlined. |
1502 | /// |
1503 | /// Walk through \a getInlinedAt() and return \a getScope() from the deepest |
1504 | /// location. |
1505 | DILocalScope *getInlinedAtScope() const { |
1506 | if (auto *IA = getInlinedAt()) |
1507 | return IA->getInlinedAtScope(); |
1508 | return getScope(); |
1509 | } |
1510 | |
1511 | /// Get the DWARF discriminator. |
1512 | /// |
1513 | /// DWARF discriminators distinguish identical file locations between |
1514 | /// instructions that are on different basic blocks. |
1515 | /// |
1516 | /// There are 3 components stored in discriminator, from lower bits: |
1517 | /// |
1518 | /// Base discriminator: assigned by AddDiscriminators pass to identify IRs |
1519 | /// that are defined by the same source line, but |
1520 | /// different basic blocks. |
1521 | /// Duplication factor: assigned by optimizations that will scale down |
1522 | /// the execution frequency of the original IR. |
1523 | /// Copy Identifier: assigned by optimizations that clones the IR. |
1524 | /// Each copy of the IR will be assigned an identifier. |
1525 | /// |
1526 | /// Encoding: |
1527 | /// |
1528 | /// The above 3 components are encoded into a 32bit unsigned integer in |
1529 | /// order. If the lowest bit is 1, the current component is empty, and the |
1530 | /// next component will start in the next bit. Otherwise, the current |
1531 | /// component is non-empty, and its content starts in the next bit. The |
1532 | /// value of each components is either 5 bit or 12 bit: if the 7th bit |
1533 | /// is 0, the bit 2~6 (5 bits) are used to represent the component; if the |
1534 | /// 7th bit is 1, the bit 2~6 (5 bits) and 8~14 (7 bits) are combined to |
1535 | /// represent the component. Thus, the number of bits used for a component |
1536 | /// is either 0 (if it and all the next components are empty); 1 - if it is |
1537 | /// empty; 7 - if its value is up to and including 0x1f (lsb and msb are both |
1538 | /// 0); or 14, if its value is up to and including 0x1ff. Note that the last |
1539 | /// component is also capped at 0x1ff, even in the case when both first |
1540 | /// components are 0, and we'd technically have 29 bits available. |
1541 | /// |
1542 | /// For precise control over the data being encoded in the discriminator, |
1543 | /// use encodeDiscriminator/decodeDiscriminator. |
1544 | /// |
1545 | /// Use {get|set}BaseDiscriminator and cloneWithDuplicationFactor after reading |
1546 | /// their documentation, as their behavior has side-effects. |
1547 | |
1548 | inline unsigned getDiscriminator() const; |
1549 | |
1550 | /// Returns a new DILocation with updated \p Discriminator. |
1551 | inline const DILocation *cloneWithDiscriminator(unsigned Discriminator) const; |
1552 | |
1553 | /// Returns a new DILocation with updated base discriminator \p BD. Only the |
1554 | /// base discriminator is set in the new DILocation, the other encoded values |
1555 | /// are elided. |
1556 | /// If the discriminator cannot be encoded, the function returns None. |
1557 | inline Optional<const DILocation *> setBaseDiscriminator(unsigned BD) const; |
1558 | |
1559 | /// Returns the duplication factor stored in the discriminator, or 1 if no |
1560 | /// duplication factor (or 0) is encoded. |
1561 | inline unsigned getDuplicationFactor() const; |
1562 | |
1563 | /// Returns the copy identifier stored in the discriminator. |
1564 | inline unsigned getCopyIdentifier() const; |
1565 | |
1566 | /// Returns the base discriminator stored in the discriminator. |
1567 | inline unsigned getBaseDiscriminator() const; |
1568 | |
1569 | /// Returns a new DILocation with duplication factor \p DF * current |
1570 | /// duplication factor encoded in the discriminator. The current duplication |
1571 | /// factor is as defined by getDuplicationFactor(). |
1572 | /// Returns None if encoding failed. |
1573 | inline Optional<const DILocation *> cloneWithDuplicationFactor(unsigned DF) const; |
1574 | |
1575 | /// When two instructions are combined into a single instruction we also |
1576 | /// need to combine the original locations into a single location. |
1577 | /// |
1578 | /// When the locations are the same we can use either location. When they |
1579 | /// differ, we need a third location which is distinct from either. If they |
1580 | /// have the same file/line but have a different discriminator we could |
1581 | /// create a location with a new discriminator. If they are from different |
1582 | /// files/lines the location is ambiguous and can't be represented in a line |
1583 | /// entry. In this case, if \p GenerateLocation is true, we will set the |
1584 | /// merged debug location as line 0 of the nearest common scope where the two |
1585 | /// locations are inlined from. |
1586 | /// |
1587 | /// \p GenerateLocation: Whether the merged location can be generated when |
1588 | /// \p LocA and \p LocB differ. |
1589 | static const DILocation *getMergedLocation(const DILocation *LocA, |
1590 | const DILocation *LocB); |
1591 | |
1592 | /// Returns the base discriminator for a given encoded discriminator \p D. |
1593 | static unsigned getBaseDiscriminatorFromDiscriminator(unsigned D) { |
1594 | return getUnsignedFromPrefixEncoding(D); |
1595 | } |
1596 | |
1597 | /// Raw encoding of the discriminator. APIs such as setBaseDiscriminator or |
1598 | /// cloneWithDuplicationFactor have certain side-effects. This API, in |
1599 | /// conjunction with cloneWithDiscriminator, may be used to encode precisely |
1600 | /// the values provided. \p BD: base discriminator \p DF: duplication factor |
1601 | /// \p CI: copy index |
1602 | /// The return is None if the values cannot be encoded in 32 bits - for |
1603 | /// example, values for BD or DF larger than 12 bits. Otherwise, the return |
1604 | /// is the encoded value. |
1605 | static Optional<unsigned> encodeDiscriminator(unsigned BD, unsigned DF, unsigned CI); |
1606 | |
1607 | /// Raw decoder for values in an encoded discriminator D. |
1608 | static void decodeDiscriminator(unsigned D, unsigned &BD, unsigned &DF, |
1609 | unsigned &CI); |
1610 | |
1611 | /// Returns the duplication factor for a given encoded discriminator \p D, or |
1612 | /// 1 if no value or 0 is encoded. |
1613 | static unsigned getDuplicationFactorFromDiscriminator(unsigned D) { |
1614 | D = getNextComponentInDiscriminator(D); |
1615 | unsigned Ret = getUnsignedFromPrefixEncoding(D); |
1616 | if (Ret == 0) |
1617 | return 1; |
1618 | return Ret; |
1619 | } |
1620 | |
1621 | /// Returns the copy identifier for a given encoded discriminator \p D. |
1622 | static unsigned getCopyIdentifierFromDiscriminator(unsigned D) { |
1623 | return getUnsignedFromPrefixEncoding(getNextComponentInDiscriminator( |
1624 | getNextComponentInDiscriminator(D))); |
1625 | } |
1626 | |
1627 | |
1628 | Metadata *getRawScope() const { return getOperand(0); } |
1629 | Metadata *getRawInlinedAt() const { |
1630 | if (getNumOperands() == 2) |
1631 | return getOperand(1); |
1632 | return nullptr; |
1633 | } |
1634 | |
1635 | static bool classof(const Metadata *MD) { |
1636 | return MD->getMetadataID() == DILocationKind; |
1637 | } |
1638 | }; |
1639 | |
1640 | /// Subprogram description. |
1641 | /// |
1642 | /// TODO: Remove DisplayName. It's always equal to Name. |
1643 | /// TODO: Split up flags. |
1644 | class DISubprogram : public DILocalScope { |
1645 | friend class LLVMContextImpl; |
1646 | friend class MDNode; |
1647 | |
1648 | unsigned Line; |
1649 | unsigned ScopeLine; |
1650 | unsigned VirtualIndex; |
1651 | |
1652 | /// In the MS ABI, the implicit 'this' parameter is adjusted in the prologue |
1653 | /// of method overrides from secondary bases by this amount. It may be |
1654 | /// negative. |
1655 | int ThisAdjustment; |
1656 | |
1657 | public: |
1658 | /// Debug info subprogram flags. |
1659 | enum DISPFlags : uint32_t { |
1660 | #define HANDLE_DISP_FLAG(ID, NAME) SPFlag##NAME = ID, |
1661 | #define DISP_FLAG_LARGEST_NEEDED |
1662 | #include "llvm/IR/DebugInfoFlags.def" |
1663 | SPFlagNonvirtual = SPFlagZero, |
1664 | SPFlagVirtuality = SPFlagVirtual | SPFlagPureVirtual, |
1665 | LLVM_MARK_AS_BITMASK_ENUM(SPFlagLargest) |
1666 | }; |
1667 | |
1668 | static DISPFlags getFlag(StringRef Flag); |
1669 | static StringRef getFlagString(DISPFlags Flag); |
1670 | |
1671 | /// Split up a flags bitfield for easier printing. |
1672 | /// |
1673 | /// Split \c Flags into \c SplitFlags, a vector of its components. Returns |
1674 | /// any remaining (unrecognized) bits. |
1675 | static DISPFlags splitFlags(DISPFlags Flags, |
1676 | SmallVectorImpl<DISPFlags> &SplitFlags); |
1677 | |
1678 | // Helper for converting old bitfields to new flags word. |
1679 | static DISPFlags toSPFlags(bool IsLocalToUnit, bool IsDefinition, |
1680 | bool IsOptimized, |
1681 | unsigned Virtuality = SPFlagNonvirtual) { |
1682 | // We're assuming virtuality is the low-order field. |
1683 | static_assert( |
1684 | int(SPFlagVirtual) == int(dwarf::DW_VIRTUALITY_virtual) && |
1685 | int(SPFlagPureVirtual) == int(dwarf::DW_VIRTUALITY_pure_virtual), |
1686 | "Virtuality constant mismatch" ); |
1687 | return static_cast<DISPFlags>( |
1688 | (Virtuality & SPFlagVirtuality) | |
1689 | (IsLocalToUnit ? SPFlagLocalToUnit : SPFlagZero) | |
1690 | (IsDefinition ? SPFlagDefinition : SPFlagZero) | |
1691 | (IsOptimized ? SPFlagOptimized : SPFlagZero)); |
1692 | } |
1693 | |
1694 | private: |
1695 | DIFlags Flags; |
1696 | DISPFlags SPFlags; |
1697 | |
1698 | DISubprogram(LLVMContext &C, StorageType Storage, unsigned Line, |
1699 | unsigned ScopeLine, unsigned VirtualIndex, int ThisAdjustment, |
1700 | DIFlags Flags, DISPFlags SPFlags, ArrayRef<Metadata *> Ops) |
1701 | : DILocalScope(C, DISubprogramKind, Storage, dwarf::DW_TAG_subprogram, |
1702 | Ops), |
1703 | Line(Line), ScopeLine(ScopeLine), VirtualIndex(VirtualIndex), |
1704 | ThisAdjustment(ThisAdjustment), Flags(Flags), SPFlags(SPFlags) { |
1705 | static_assert(dwarf::DW_VIRTUALITY_max < 4, "Virtuality out of range" ); |
1706 | } |
1707 | ~DISubprogram() = default; |
1708 | |
1709 | static DISubprogram * |
1710 | getImpl(LLVMContext &Context, DIScopeRef Scope, StringRef Name, |
1711 | StringRef LinkageName, DIFile *File, unsigned Line, |
1712 | DISubroutineType *Type, unsigned ScopeLine, DITypeRef ContainingType, |
1713 | unsigned VirtualIndex, int ThisAdjustment, DIFlags Flags, |
1714 | DISPFlags SPFlags, DICompileUnit *Unit, |
1715 | DITemplateParameterArray TemplateParams, DISubprogram *Declaration, |
1716 | DINodeArray RetainedNodes, DITypeArray ThrownTypes, |
1717 | StorageType Storage, bool ShouldCreate = true) { |
1718 | return getImpl(Context, Scope, getCanonicalMDString(Context, Name), |
1719 | getCanonicalMDString(Context, LinkageName), File, Line, Type, |
1720 | ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, |
1721 | Flags, SPFlags, Unit, TemplateParams.get(), Declaration, |
1722 | RetainedNodes.get(), ThrownTypes.get(), Storage, |
1723 | ShouldCreate); |
1724 | } |
1725 | static DISubprogram *getImpl(LLVMContext &Context, Metadata *Scope, |
1726 | MDString *Name, MDString *LinkageName, |
1727 | Metadata *File, unsigned Line, Metadata *Type, |
1728 | unsigned ScopeLine, Metadata *ContainingType, |
1729 | unsigned VirtualIndex, int ThisAdjustment, |
1730 | DIFlags Flags, DISPFlags SPFlags, Metadata *Unit, |
1731 | Metadata *TemplateParams, Metadata *Declaration, |
1732 | Metadata *RetainedNodes, Metadata *ThrownTypes, |
1733 | StorageType Storage, bool ShouldCreate = true); |
1734 | |
1735 | TempDISubprogram cloneImpl() const { |
1736 | return getTemporary(getContext(), getScope(), getName(), getLinkageName(), |
1737 | getFile(), getLine(), getType(), getScopeLine(), |
1738 | getContainingType(), getVirtualIndex(), |
1739 | getThisAdjustment(), getFlags(), getSPFlags(), |
1740 | getUnit(), getTemplateParams(), getDeclaration(), |
1741 | getRetainedNodes(), getThrownTypes()); |
1742 | } |
1743 | |
1744 | public: |
1745 | DEFINE_MDNODE_GET( |
1746 | DISubprogram, |
1747 | (DIScopeRef Scope, StringRef Name, StringRef LinkageName, DIFile *File, |
1748 | unsigned Line, DISubroutineType *Type, unsigned ScopeLine, |
1749 | DITypeRef ContainingType, unsigned VirtualIndex, int ThisAdjustment, |
1750 | DIFlags Flags, DISPFlags SPFlags, DICompileUnit *Unit, |
1751 | DITemplateParameterArray TemplateParams = nullptr, |
1752 | DISubprogram *Declaration = nullptr, DINodeArray RetainedNodes = nullptr, |
1753 | DITypeArray ThrownTypes = nullptr), |
1754 | (Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType, |
1755 | VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams, |
1756 | Declaration, RetainedNodes, ThrownTypes)) |
1757 | |
1758 | DEFINE_MDNODE_GET( |
1759 | DISubprogram, |
1760 | (Metadata * Scope, MDString *Name, MDString *LinkageName, Metadata *File, |
1761 | unsigned Line, Metadata *Type, unsigned ScopeLine, |
1762 | Metadata *ContainingType, unsigned VirtualIndex, int ThisAdjustment, |
1763 | DIFlags Flags, DISPFlags SPFlags, Metadata *Unit, |
1764 | Metadata *TemplateParams = nullptr, Metadata *Declaration = nullptr, |
1765 | Metadata *RetainedNodes = nullptr, Metadata *ThrownTypes = nullptr), |
1766 | (Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType, |
1767 | VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams, |
1768 | Declaration, RetainedNodes, ThrownTypes)) |
1769 | |
1770 | TempDISubprogram clone() const { return cloneImpl(); } |
1771 | |
1772 | /// Returns a new temporary DISubprogram with updated Flags |
1773 | TempDISubprogram cloneWithFlags(DIFlags NewFlags) const { |
1774 | auto NewSP = clone(); |
1775 | NewSP->Flags = NewFlags; |
1776 | return NewSP; |
1777 | } |
1778 | |
1779 | public: |
1780 | unsigned getLine() const { return Line; } |
1781 | unsigned getVirtuality() const { return getSPFlags() & SPFlagVirtuality; } |
1782 | unsigned getVirtualIndex() const { return VirtualIndex; } |
1783 | int getThisAdjustment() const { return ThisAdjustment; } |
1784 | unsigned getScopeLine() const { return ScopeLine; } |
1785 | DIFlags getFlags() const { return Flags; } |
1786 | DISPFlags getSPFlags() const { return SPFlags; } |
1787 | bool isLocalToUnit() const { return getSPFlags() & SPFlagLocalToUnit; } |
1788 | bool isDefinition() const { return getSPFlags() & SPFlagDefinition; } |
1789 | bool isOptimized() const { return getSPFlags() & SPFlagOptimized; } |
1790 | |
1791 | bool isArtificial() const { return getFlags() & FlagArtificial; } |
1792 | bool isPrivate() const { |
1793 | return (getFlags() & FlagAccessibility) == FlagPrivate; |
1794 | } |
1795 | bool isProtected() const { |
1796 | return (getFlags() & FlagAccessibility) == FlagProtected; |
1797 | } |
1798 | bool isPublic() const { |
1799 | return (getFlags() & FlagAccessibility) == FlagPublic; |
1800 | } |
1801 | bool isExplicit() const { return getFlags() & FlagExplicit; } |
1802 | bool isPrototyped() const { return getFlags() & FlagPrototyped; } |
1803 | bool areAllCallsDescribed() const { |
1804 | return getFlags() & FlagAllCallsDescribed; |
1805 | } |
1806 | bool isMainSubprogram() const { return getFlags() & FlagMainSubprogram; } |
1807 | |
1808 | /// Check if this is reference-qualified. |
1809 | /// |
1810 | /// Return true if this subprogram is a C++11 reference-qualified non-static |
1811 | /// member function (void foo() &). |
1812 | bool isLValueReference() const { return getFlags() & FlagLValueReference; } |
1813 | |
1814 | /// Check if this is rvalue-reference-qualified. |
1815 | /// |
1816 | /// Return true if this subprogram is a C++11 rvalue-reference-qualified |
1817 | /// non-static member function (void foo() &&). |
1818 | bool isRValueReference() const { return getFlags() & FlagRValueReference; } |
1819 | |
1820 | /// Check if this is marked as noreturn. |
1821 | /// |
1822 | /// Return true if this subprogram is C++11 noreturn or C11 _Noreturn |
1823 | bool isNoReturn() const { return getFlags() & FlagNoReturn; } |
1824 | |
1825 | // Check if this routine is a compiler-generated thunk. |
1826 | // |
1827 | // Returns true if this subprogram is a thunk generated by the compiler. |
1828 | bool isThunk() const { return getFlags() & FlagThunk; } |
1829 | |
1830 | DIScopeRef getScope() const { return DIScopeRef(getRawScope()); } |
1831 | |
1832 | StringRef getName() const { return getStringOperand(2); } |
1833 | StringRef getLinkageName() const { return getStringOperand(3); } |
1834 | |
1835 | DISubroutineType *getType() const { |
1836 | return cast_or_null<DISubroutineType>(getRawType()); |
1837 | } |
1838 | DITypeRef getContainingType() const { |
1839 | return DITypeRef(getRawContainingType()); |
1840 | } |
1841 | |
1842 | DICompileUnit *getUnit() const { |
1843 | return cast_or_null<DICompileUnit>(getRawUnit()); |
1844 | } |
1845 | void replaceUnit(DICompileUnit *CU) { replaceOperandWith(5, CU); } |
1846 | DITemplateParameterArray getTemplateParams() const { |
1847 | return cast_or_null<MDTuple>(getRawTemplateParams()); |
1848 | } |
1849 | DISubprogram *getDeclaration() const { |
1850 | return cast_or_null<DISubprogram>(getRawDeclaration()); |
1851 | } |
1852 | DINodeArray getRetainedNodes() const { |
1853 | return cast_or_null<MDTuple>(getRawRetainedNodes()); |
1854 | } |
1855 | DITypeArray getThrownTypes() const { |
1856 | return cast_or_null<MDTuple>(getRawThrownTypes()); |
1857 | } |
1858 | |
1859 | Metadata *getRawScope() const { return getOperand(1); } |
1860 | MDString *getRawName() const { return getOperandAs<MDString>(2); } |
1861 | MDString *getRawLinkageName() const { return getOperandAs<MDString>(3); } |
1862 | Metadata *getRawType() const { return getOperand(4); } |
1863 | Metadata *getRawUnit() const { return getOperand(5); } |
1864 | Metadata *getRawDeclaration() const { return getOperand(6); } |
1865 | Metadata *getRawRetainedNodes() const { return getOperand(7); } |
1866 | Metadata *getRawContainingType() const { |
1867 | return getNumOperands() > 8 ? getOperandAs<Metadata>(8) : nullptr; |
1868 | } |
1869 | Metadata *getRawTemplateParams() const { |
1870 | return getNumOperands() > 9 ? getOperandAs<Metadata>(9) : nullptr; |
1871 | } |
1872 | Metadata *getRawThrownTypes() const { |
1873 | return getNumOperands() > 10 ? getOperandAs<Metadata>(10) : nullptr; |
1874 | } |
1875 | |
1876 | /// Check if this subprogram describes the given function. |
1877 | /// |
1878 | /// FIXME: Should this be looking through bitcasts? |
1879 | bool describes(const Function *F) const; |
1880 | |
1881 | static bool classof(const Metadata *MD) { |
1882 | return MD->getMetadataID() == DISubprogramKind; |
1883 | } |
1884 | }; |
1885 | |
1886 | class DILexicalBlockBase : public DILocalScope { |
1887 | protected: |
1888 | DILexicalBlockBase(LLVMContext &C, unsigned ID, StorageType Storage, |
1889 | ArrayRef<Metadata *> Ops) |
1890 | : DILocalScope(C, ID, Storage, dwarf::DW_TAG_lexical_block, Ops) {} |
1891 | ~DILexicalBlockBase() = default; |
1892 | |
1893 | public: |
1894 | DILocalScope *getScope() const { return cast<DILocalScope>(getRawScope()); } |
1895 | |
1896 | Metadata *getRawScope() const { return getOperand(1); } |
1897 | |
1898 | static bool classof(const Metadata *MD) { |
1899 | return MD->getMetadataID() == DILexicalBlockKind || |
1900 | MD->getMetadataID() == DILexicalBlockFileKind; |
1901 | } |
1902 | }; |
1903 | |
1904 | class DILexicalBlock : public DILexicalBlockBase { |
1905 | friend class LLVMContextImpl; |
1906 | friend class MDNode; |
1907 | |
1908 | unsigned Line; |
1909 | uint16_t Column; |
1910 | |
1911 | DILexicalBlock(LLVMContext &C, StorageType Storage, unsigned Line, |
1912 | unsigned Column, ArrayRef<Metadata *> Ops) |
1913 | : DILexicalBlockBase(C, DILexicalBlockKind, Storage, Ops), Line(Line), |
1914 | Column(Column) { |
1915 | assert(Column < (1u << 16) && "Expected 16-bit column" ); |
1916 | } |
1917 | ~DILexicalBlock() = default; |
1918 | |
1919 | static DILexicalBlock *getImpl(LLVMContext &Context, DILocalScope *Scope, |
1920 | DIFile *File, unsigned Line, unsigned Column, |
1921 | StorageType Storage, |
1922 | bool ShouldCreate = true) { |
1923 | return getImpl(Context, static_cast<Metadata *>(Scope), |
1924 | static_cast<Metadata *>(File), Line, Column, Storage, |
1925 | ShouldCreate); |
1926 | } |
1927 | |
1928 | static DILexicalBlock *getImpl(LLVMContext &Context, Metadata *Scope, |
1929 | Metadata *File, unsigned Line, unsigned Column, |
1930 | StorageType Storage, bool ShouldCreate = true); |
1931 | |
1932 | TempDILexicalBlock cloneImpl() const { |
1933 | return getTemporary(getContext(), getScope(), getFile(), getLine(), |
1934 | getColumn()); |
1935 | } |
1936 | |
1937 | public: |
1938 | DEFINE_MDNODE_GET(DILexicalBlock, (DILocalScope * Scope, DIFile *File, |
1939 | unsigned Line, unsigned Column), |
1940 | (Scope, File, Line, Column)) |
1941 | DEFINE_MDNODE_GET(DILexicalBlock, (Metadata * Scope, Metadata *File, |
1942 | unsigned Line, unsigned Column), |
1943 | (Scope, File, Line, Column)) |
1944 | |
1945 | TempDILexicalBlock clone() const { return cloneImpl(); } |
1946 | |
1947 | unsigned getLine() const { return Line; } |
1948 | unsigned getColumn() const { return Column; } |
1949 | |
1950 | static bool classof(const Metadata *MD) { |
1951 | return MD->getMetadataID() == DILexicalBlockKind; |
1952 | } |
1953 | }; |
1954 | |
1955 | class DILexicalBlockFile : public DILexicalBlockBase { |
1956 | friend class LLVMContextImpl; |
1957 | friend class MDNode; |
1958 | |
1959 | unsigned Discriminator; |
1960 | |
1961 | DILexicalBlockFile(LLVMContext &C, StorageType Storage, |
1962 | unsigned Discriminator, ArrayRef<Metadata *> Ops) |
1963 | : DILexicalBlockBase(C, DILexicalBlockFileKind, Storage, Ops), |
1964 | Discriminator(Discriminator) {} |
1965 | ~DILexicalBlockFile() = default; |
1966 | |
1967 | static DILexicalBlockFile *getImpl(LLVMContext &Context, DILocalScope *Scope, |
1968 | DIFile *File, unsigned Discriminator, |
1969 | StorageType Storage, |
1970 | bool ShouldCreate = true) { |
1971 | return getImpl(Context, static_cast<Metadata *>(Scope), |
1972 | static_cast<Metadata *>(File), Discriminator, Storage, |
1973 | ShouldCreate); |
1974 | } |
1975 | |
1976 | static DILexicalBlockFile *getImpl(LLVMContext &Context, Metadata *Scope, |
1977 | Metadata *File, unsigned Discriminator, |
1978 | StorageType Storage, |
1979 | bool ShouldCreate = true); |
1980 | |
1981 | TempDILexicalBlockFile cloneImpl() const { |
1982 | return getTemporary(getContext(), getScope(), getFile(), |
1983 | getDiscriminator()); |
1984 | } |
1985 | |
1986 | public: |
1987 | DEFINE_MDNODE_GET(DILexicalBlockFile, (DILocalScope * Scope, DIFile *File, |
1988 | unsigned Discriminator), |
1989 | (Scope, File, Discriminator)) |
1990 | DEFINE_MDNODE_GET(DILexicalBlockFile, |
1991 | (Metadata * Scope, Metadata *File, unsigned Discriminator), |
1992 | (Scope, File, Discriminator)) |
1993 | |
1994 | TempDILexicalBlockFile clone() const { return cloneImpl(); } |
1995 | |
1996 | // TODO: Remove these once they're gone from DILexicalBlockBase. |
1997 | unsigned getLine() const = delete; |
1998 | unsigned getColumn() const = delete; |
1999 | |
2000 | unsigned getDiscriminator() const { return Discriminator; } |
2001 | |
2002 | static bool classof(const Metadata *MD) { |
2003 | return MD->getMetadataID() == DILexicalBlockFileKind; |
2004 | } |
2005 | }; |
2006 | |
2007 | unsigned DILocation::getDiscriminator() const { |
2008 | if (auto *F = dyn_cast<DILexicalBlockFile>(getScope())) |
2009 | return F->getDiscriminator(); |
2010 | return 0; |
2011 | } |
2012 | |
2013 | const DILocation * |
2014 | DILocation::cloneWithDiscriminator(unsigned Discriminator) const { |
2015 | DIScope *Scope = getScope(); |
2016 | // Skip all parent DILexicalBlockFile that already have a discriminator |
2017 | // assigned. We do not want to have nested DILexicalBlockFiles that have |
2018 | // mutliple discriminators because only the leaf DILexicalBlockFile's |
2019 | // dominator will be used. |
2020 | for (auto *LBF = dyn_cast<DILexicalBlockFile>(Scope); |
2021 | LBF && LBF->getDiscriminator() != 0; |
2022 | LBF = dyn_cast<DILexicalBlockFile>(Scope)) |
2023 | Scope = LBF->getScope(); |
2024 | DILexicalBlockFile *NewScope = |
2025 | DILexicalBlockFile::get(getContext(), Scope, getFile(), Discriminator); |
2026 | return DILocation::get(getContext(), getLine(), getColumn(), NewScope, |
2027 | getInlinedAt()); |
2028 | } |
2029 | |
2030 | unsigned DILocation::getBaseDiscriminator() const { |
2031 | return getBaseDiscriminatorFromDiscriminator(getDiscriminator()); |
2032 | } |
2033 | |
2034 | unsigned DILocation::getDuplicationFactor() const { |
2035 | return getDuplicationFactorFromDiscriminator(getDiscriminator()); |
2036 | } |
2037 | |
2038 | unsigned DILocation::getCopyIdentifier() const { |
2039 | return getCopyIdentifierFromDiscriminator(getDiscriminator()); |
2040 | } |
2041 | |
2042 | Optional<const DILocation *> DILocation::setBaseDiscriminator(unsigned D) const { |
2043 | if (D == 0) |
2044 | return this; |
2045 | if (D > 0xfff) |
2046 | return None; |
2047 | return cloneWithDiscriminator(encodeComponent(D)); |
2048 | } |
2049 | |
2050 | Optional<const DILocation *> DILocation::cloneWithDuplicationFactor(unsigned DF) const { |
2051 | DF *= getDuplicationFactor(); |
2052 | if (DF <= 1) |
2053 | return this; |
2054 | |
2055 | unsigned BD = getBaseDiscriminator(); |
2056 | unsigned CI = getCopyIdentifier(); |
2057 | if (Optional<unsigned> D = encodeDiscriminator(BD, DF, CI)) |
2058 | return cloneWithDiscriminator(*D); |
2059 | return None; |
2060 | } |
2061 | |
2062 | class DINamespace : public DIScope { |
2063 | friend class LLVMContextImpl; |
2064 | friend class MDNode; |
2065 | |
2066 | unsigned ExportSymbols : 1; |
2067 | |
2068 | DINamespace(LLVMContext &Context, StorageType Storage, bool ExportSymbols, |
2069 | ArrayRef<Metadata *> Ops) |
2070 | : DIScope(Context, DINamespaceKind, Storage, dwarf::DW_TAG_namespace, |
2071 | Ops), |
2072 | ExportSymbols(ExportSymbols) {} |
2073 | ~DINamespace() = default; |
2074 | |
2075 | static DINamespace *getImpl(LLVMContext &Context, DIScope *Scope, |
2076 | StringRef Name, bool ExportSymbols, |
2077 | StorageType Storage, bool ShouldCreate = true) { |
2078 | return getImpl(Context, Scope, getCanonicalMDString(Context, Name), |
2079 | ExportSymbols, Storage, ShouldCreate); |
2080 | } |
2081 | static DINamespace *getImpl(LLVMContext &Context, Metadata *Scope, |
2082 | MDString *Name, bool ExportSymbols, |
2083 | StorageType Storage, bool ShouldCreate = true); |
2084 | |
2085 | TempDINamespace cloneImpl() const { |
2086 | return getTemporary(getContext(), getScope(), getName(), |
2087 | getExportSymbols()); |
2088 | } |
2089 | |
2090 | public: |
2091 | DEFINE_MDNODE_GET(DINamespace, |
2092 | (DIScope *Scope, StringRef Name, bool ExportSymbols), |
2093 | (Scope, Name, ExportSymbols)) |
2094 | DEFINE_MDNODE_GET(DINamespace, |
2095 | (Metadata *Scope, MDString *Name, bool ExportSymbols), |
2096 | (Scope, Name, ExportSymbols)) |
2097 | |
2098 | TempDINamespace clone() const { return cloneImpl(); } |
2099 | |
2100 | bool getExportSymbols() const { return ExportSymbols; } |
2101 | DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); } |
2102 | StringRef getName() const { return getStringOperand(2); } |
2103 | |
2104 | Metadata *getRawScope() const { return getOperand(1); } |
2105 | MDString *getRawName() const { return getOperandAs<MDString>(2); } |
2106 | |
2107 | static bool classof(const Metadata *MD) { |
2108 | return MD->getMetadataID() == DINamespaceKind; |
2109 | } |
2110 | }; |
2111 | |
2112 | /// A (clang) module that has been imported by the compile unit. |
2113 | /// |
2114 | class DIModule : public DIScope { |
2115 | friend class LLVMContextImpl; |
2116 | friend class MDNode; |
2117 | |
2118 | DIModule(LLVMContext &Context, StorageType Storage, ArrayRef<Metadata *> Ops) |
2119 | : DIScope(Context, DIModuleKind, Storage, dwarf::DW_TAG_module, Ops) {} |
2120 | ~DIModule() = default; |
2121 | |
2122 | static DIModule *getImpl(LLVMContext &Context, DIScope *Scope, |
2123 | StringRef Name, StringRef ConfigurationMacros, |
2124 | StringRef IncludePath, StringRef ISysRoot, |
2125 | StorageType Storage, bool ShouldCreate = true) { |
2126 | return getImpl(Context, Scope, getCanonicalMDString(Context, Name), |
2127 | getCanonicalMDString(Context, ConfigurationMacros), |
2128 | getCanonicalMDString(Context, IncludePath), |
2129 | getCanonicalMDString(Context, ISysRoot), |
2130 | Storage, ShouldCreate); |
2131 | } |
2132 | static DIModule *getImpl(LLVMContext &Context, Metadata *Scope, |
2133 | MDString *Name, MDString *ConfigurationMacros, |
2134 | MDString *IncludePath, MDString *ISysRoot, |
2135 | StorageType Storage, bool ShouldCreate = true); |
2136 | |
2137 | TempDIModule cloneImpl() const { |
2138 | return getTemporary(getContext(), getScope(), getName(), |
2139 | getConfigurationMacros(), getIncludePath(), |
2140 | getISysRoot()); |
2141 | } |
2142 | |
2143 | public: |
2144 | DEFINE_MDNODE_GET(DIModule, (DIScope *Scope, StringRef Name, |
2145 | StringRef ConfigurationMacros, StringRef IncludePath, |
2146 | StringRef ISysRoot), |
2147 | (Scope, Name, ConfigurationMacros, IncludePath, ISysRoot)) |
2148 | DEFINE_MDNODE_GET(DIModule, |
2149 | (Metadata *Scope, MDString *Name, MDString *ConfigurationMacros, |
2150 | MDString *IncludePath, MDString *ISysRoot), |
2151 | (Scope, Name, ConfigurationMacros, IncludePath, ISysRoot)) |
2152 | |
2153 | TempDIModule clone() const { return cloneImpl(); } |
2154 | |
2155 | DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); } |
2156 | StringRef getName() const { return getStringOperand(1); } |
2157 | StringRef getConfigurationMacros() const { return getStringOperand(2); } |
2158 | StringRef getIncludePath() const { return getStringOperand(3); } |
2159 | StringRef getISysRoot() const { return getStringOperand(4); } |
2160 | |
2161 | Metadata *getRawScope() const { return getOperand(0); } |
2162 | MDString *getRawName() const { return getOperandAs<MDString>(1); } |
2163 | MDString *getRawConfigurationMacros() const { return getOperandAs<MDString>(2); } |
2164 | MDString *getRawIncludePath() const { return getOperandAs<MDString>(3); } |
2165 | MDString *getRawISysRoot() const { return getOperandAs<MDString>(4); } |
2166 | |
2167 | static bool classof(const Metadata *MD) { |
2168 | return MD->getMetadataID() == DIModuleKind; |
2169 | } |
2170 | }; |
2171 | |
2172 | /// Base class for template parameters. |
2173 | class DITemplateParameter : public DINode { |
2174 | protected: |
2175 | DITemplateParameter(LLVMContext &Context, unsigned ID, StorageType Storage, |
2176 | unsigned Tag, ArrayRef<Metadata *> Ops) |
2177 | : DINode(Context, ID, Storage, Tag, Ops) {} |
2178 | ~DITemplateParameter() = default; |
2179 | |
2180 | public: |
2181 | StringRef getName() const { return getStringOperand(0); } |
2182 | DITypeRef getType() const { return DITypeRef(getRawType()); } |
2183 | |
2184 | MDString *getRawName() const { return getOperandAs<MDString>(0); } |
2185 | Metadata *getRawType() const { return getOperand(1); } |
2186 | |
2187 | static bool classof(const Metadata *MD) { |
2188 | return MD->getMetadataID() == DITemplateTypeParameterKind || |
2189 | MD->getMetadataID() == DITemplateValueParameterKind; |
2190 | } |
2191 | }; |
2192 | |
2193 | class DITemplateTypeParameter : public DITemplateParameter { |
2194 | friend class LLVMContextImpl; |
2195 | friend class MDNode; |
2196 | |
2197 | DITemplateTypeParameter(LLVMContext &Context, StorageType Storage, |
2198 | ArrayRef<Metadata *> Ops) |
2199 | : DITemplateParameter(Context, DITemplateTypeParameterKind, Storage, |
2200 | dwarf::DW_TAG_template_type_parameter, Ops) {} |
2201 | ~DITemplateTypeParameter() = default; |
2202 | |
2203 | static DITemplateTypeParameter *getImpl(LLVMContext &Context, StringRef Name, |
2204 | DITypeRef Type, StorageType Storage, |
2205 | bool ShouldCreate = true) { |
2206 | return getImpl(Context, getCanonicalMDString(Context, Name), Type, Storage, |
2207 | ShouldCreate); |
2208 | } |
2209 | static DITemplateTypeParameter *getImpl(LLVMContext &Context, MDString *Name, |
2210 | Metadata *Type, StorageType Storage, |
2211 | bool ShouldCreate = true); |
2212 | |
2213 | TempDITemplateTypeParameter cloneImpl() const { |
2214 | return getTemporary(getContext(), getName(), getType()); |
2215 | } |
2216 | |
2217 | public: |
2218 | DEFINE_MDNODE_GET(DITemplateTypeParameter, (StringRef Name, DITypeRef Type), |
2219 | (Name, Type)) |
2220 | DEFINE_MDNODE_GET(DITemplateTypeParameter, (MDString * Name, Metadata *Type), |
2221 | (Name, Type)) |
2222 | |
2223 | TempDITemplateTypeParameter clone() const { return cloneImpl(); } |
2224 | |
2225 | static bool classof(const Metadata *MD) { |
2226 | return MD->getMetadataID() == DITemplateTypeParameterKind; |
2227 | } |
2228 | }; |
2229 | |
2230 | class DITemplateValueParameter : public DITemplateParameter { |
2231 | friend class LLVMContextImpl; |
2232 | friend class MDNode; |
2233 | |
2234 | DITemplateValueParameter(LLVMContext &Context, StorageType Storage, |
2235 | unsigned Tag, ArrayRef<Metadata *> Ops) |
2236 | : DITemplateParameter(Context, DITemplateValueParameterKind, Storage, Tag, |
2237 | Ops) {} |
2238 | ~DITemplateValueParameter() = default; |
2239 | |
2240 | static DITemplateValueParameter *getImpl(LLVMContext &Context, unsigned Tag, |
2241 | StringRef Name, DITypeRef Type, |
2242 | Metadata *Value, StorageType Storage, |
2243 | bool ShouldCreate = true) { |
2244 | return getImpl(Context, Tag, getCanonicalMDString(Context, Name), Type, |
2245 | Value, Storage, ShouldCreate); |
2246 | } |
2247 | static DITemplateValueParameter *getImpl(LLVMContext &Context, unsigned Tag, |
2248 | MDString *Name, Metadata *Type, |
2249 | Metadata *Value, StorageType Storage, |
2250 | bool ShouldCreate = true); |
2251 | |
2252 | TempDITemplateValueParameter cloneImpl() const { |
2253 | return getTemporary(getContext(), getTag(), getName(), getType(), |
2254 | getValue()); |
2255 | } |
2256 | |
2257 | public: |
2258 | DEFINE_MDNODE_GET(DITemplateValueParameter, (unsigned Tag, StringRef Name, |
2259 | DITypeRef Type, Metadata *Value), |
2260 | (Tag, Name, Type, Value)) |
2261 | DEFINE_MDNODE_GET(DITemplateValueParameter, (unsigned Tag, MDString *Name, |
2262 | Metadata *Type, Metadata *Value), |
2263 | (Tag, Name, Type, Value)) |
2264 | |
2265 | TempDITemplateValueParameter clone() const { return cloneImpl(); } |
2266 | |
2267 | Metadata *getValue() const { return getOperand(2); } |
2268 | |
2269 | static bool classof(const Metadata *MD) { |
2270 | return MD->getMetadataID() == DITemplateValueParameterKind; |
2271 | } |
2272 | }; |
2273 | |
2274 | /// Base class for variables. |
2275 | class DIVariable : public DINode { |
2276 | unsigned Line; |
2277 | uint32_t AlignInBits; |
2278 | |
2279 | protected: |
2280 | DIVariable(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Line, |
2281 | ArrayRef<Metadata *> Ops, uint32_t AlignInBits = 0) |
2282 | : DINode(C, ID, Storage, dwarf::DW_TAG_variable, Ops), Line(Line), |
2283 | AlignInBits(AlignInBits) {} |
2284 | ~DIVariable() = default; |
2285 | |
2286 | public: |
2287 | unsigned getLine() const { return Line; } |
2288 | DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); } |
2289 | StringRef getName() const { return getStringOperand(1); } |
2290 | DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); } |
2291 | DITypeRef getType() const { return DITypeRef(getRawType()); } |
2292 | uint32_t getAlignInBits() const { return AlignInBits; } |
2293 | uint32_t getAlignInBytes() const { return getAlignInBits() / CHAR_BIT; } |
2294 | /// Determines the size of the variable's type. |
2295 | Optional<uint64_t> getSizeInBits() const; |
2296 | |
2297 | /// Return the signedness of this variable's type, or None if this type is |
2298 | /// neither signed nor unsigned. |
2299 | Optional<DIBasicType::Signedness> getSignedness() const { |
2300 | if (auto *BT = dyn_cast<DIBasicType>(getType().resolve())) |
2301 | return BT->getSignedness(); |
2302 | return None; |
2303 | } |
2304 | |
2305 | StringRef getFilename() const { |
2306 | if (auto *F = getFile()) |
2307 | return F->getFilename(); |
2308 | return "" ; |
2309 | } |
2310 | |
2311 | StringRef getDirectory() const { |
2312 | if (auto *F = getFile()) |
2313 | return F->getDirectory(); |
2314 | return "" ; |
2315 | } |
2316 | |
2317 | Optional<StringRef> getSource() const { |
2318 | if (auto *F = getFile()) |
2319 | return F->getSource(); |
2320 | return None; |
2321 | } |
2322 | |
2323 | Metadata *getRawScope() const { return getOperand(0); } |
2324 | MDString *getRawName() const { return getOperandAs<MDString>(1); } |
2325 | Metadata *getRawFile() const { return getOperand(2); } |
2326 | Metadata *getRawType() const { return getOperand(3); } |
2327 | |
2328 | static bool classof(const Metadata *MD) { |
2329 | return MD->getMetadataID() == DILocalVariableKind || |
2330 | MD->getMetadataID() == DIGlobalVariableKind; |
2331 | } |
2332 | }; |
2333 | |
2334 | /// DWARF expression. |
2335 | /// |
2336 | /// This is (almost) a DWARF expression that modifies the location of a |
2337 | /// variable, or the location of a single piece of a variable, or (when using |
2338 | /// DW_OP_stack_value) is the constant variable value. |
2339 | /// |
2340 | /// TODO: Co-allocate the expression elements. |
2341 | /// TODO: Separate from MDNode, or otherwise drop Distinct and Temporary |
2342 | /// storage types. |
2343 | class DIExpression : public MDNode { |
2344 | friend class LLVMContextImpl; |
2345 | friend class MDNode; |
2346 | |
2347 | std::vector<uint64_t> Elements; |
2348 | |
2349 | DIExpression(LLVMContext &C, StorageType Storage, ArrayRef<uint64_t> Elements) |
2350 | : MDNode(C, DIExpressionKind, Storage, None), |
2351 | Elements(Elements.begin(), Elements.end()) {} |
2352 | ~DIExpression() = default; |
2353 | |
2354 | static DIExpression *getImpl(LLVMContext &Context, |
2355 | ArrayRef<uint64_t> Elements, StorageType Storage, |
2356 | bool ShouldCreate = true); |
2357 | |
2358 | TempDIExpression cloneImpl() const { |
2359 | return getTemporary(getContext(), getElements()); |
2360 | } |
2361 | |
2362 | public: |
2363 | DEFINE_MDNODE_GET(DIExpression, (ArrayRef<uint64_t> Elements), (Elements)) |
2364 | |
2365 | TempDIExpression clone() const { return cloneImpl(); } |
2366 | |
2367 | ArrayRef<uint64_t> getElements() const { return Elements; } |
2368 | |
2369 | unsigned getNumElements() const { return Elements.size(); } |
2370 | |
2371 | uint64_t getElement(unsigned I) const { |
2372 | assert(I < Elements.size() && "Index out of range" ); |
2373 | return Elements[I]; |
2374 | } |
2375 | |
2376 | /// Determine whether this represents a standalone constant value. |
2377 | bool isConstant() const; |
2378 | |
2379 | using element_iterator = ArrayRef<uint64_t>::iterator; |
2380 | |
2381 | element_iterator elements_begin() const { return getElements().begin(); } |
2382 | element_iterator elements_end() const { return getElements().end(); } |
2383 | |
2384 | /// A lightweight wrapper around an expression operand. |
2385 | /// |
2386 | /// TODO: Store arguments directly and change \a DIExpression to store a |
2387 | /// range of these. |
2388 | class ExprOperand { |
2389 | const uint64_t *Op = nullptr; |
2390 | |
2391 | public: |
2392 | ExprOperand() = default; |
2393 | explicit ExprOperand(const uint64_t *Op) : Op(Op) {} |
2394 | |
2395 | const uint64_t *get() const { return Op; } |
2396 | |
2397 | /// Get the operand code. |
2398 | uint64_t getOp() const { return *Op; } |
2399 | |
2400 | /// Get an argument to the operand. |
2401 | /// |
2402 | /// Never returns the operand itself. |
2403 | uint64_t getArg(unsigned I) const { return Op[I + 1]; } |
2404 | |
2405 | unsigned getNumArgs() const { return getSize() - 1; } |
2406 | |
2407 | /// Return the size of the operand. |
2408 | /// |
2409 | /// Return the number of elements in the operand (1 + args). |
2410 | unsigned getSize() const; |
2411 | |
2412 | /// Append the elements of this operand to \p V. |
2413 | void appendToVector(SmallVectorImpl<uint64_t> &V) const { |
2414 | V.append(get(), get() + getSize()); |
2415 | } |
2416 | }; |
2417 | |
2418 | /// An iterator for expression operands. |
2419 | class expr_op_iterator |
2420 | : public std::iterator<std::input_iterator_tag, ExprOperand> { |
2421 | ExprOperand Op; |
2422 | |
2423 | public: |
2424 | expr_op_iterator() = default; |
2425 | explicit expr_op_iterator(element_iterator I) : Op(I) {} |
2426 | |
2427 | element_iterator getBase() const { return Op.get(); } |
2428 | const ExprOperand &operator*() const { return Op; } |
2429 | const ExprOperand *operator->() const { return &Op; } |
2430 | |
2431 | expr_op_iterator &operator++() { |
2432 | increment(); |
2433 | return *this; |
2434 | } |
2435 | expr_op_iterator operator++(int) { |
2436 | expr_op_iterator T(*this); |
2437 | increment(); |
2438 | return T; |
2439 | } |
2440 | |
2441 | /// Get the next iterator. |
2442 | /// |
2443 | /// \a std::next() doesn't work because this is technically an |
2444 | /// input_iterator, but it's a perfectly valid operation. This is an |
2445 | /// accessor to provide the same functionality. |
2446 | expr_op_iterator getNext() const { return ++expr_op_iterator(*this); } |
2447 | |
2448 | bool operator==(const expr_op_iterator &X) const { |
2449 | return getBase() == X.getBase(); |
2450 | } |
2451 | bool operator!=(const expr_op_iterator &X) const { |
2452 | return getBase() != X.getBase(); |
2453 | } |
2454 | |
2455 | private: |
2456 | void increment() { Op = ExprOperand(getBase() + Op.getSize()); } |
2457 | }; |
2458 | |
2459 | /// Visit the elements via ExprOperand wrappers. |
2460 | /// |
2461 | /// These range iterators visit elements through \a ExprOperand wrappers. |
2462 | /// This is not guaranteed to be a valid range unless \a isValid() gives \c |
2463 | /// true. |
2464 | /// |
2465 | /// \pre \a isValid() gives \c true. |
2466 | /// @{ |
2467 | expr_op_iterator expr_op_begin() const { |
2468 | return expr_op_iterator(elements_begin()); |
2469 | } |
2470 | expr_op_iterator expr_op_end() const { |
2471 | return expr_op_iterator(elements_end()); |
2472 | } |
2473 | iterator_range<expr_op_iterator> expr_ops() const { |
2474 | return {expr_op_begin(), expr_op_end()}; |
2475 | } |
2476 | /// @} |
2477 | |
2478 | bool isValid() const; |
2479 | |
2480 | static bool classof(const Metadata *MD) { |
2481 | return MD->getMetadataID() == DIExpressionKind; |
2482 | } |
2483 | |
2484 | /// Return whether the first element a DW_OP_deref. |
2485 | bool startsWithDeref() const { |
2486 | return getNumElements() > 0 && getElement(0) == dwarf::DW_OP_deref; |
2487 | } |
2488 | |
2489 | /// Holds the characteristics of one fragment of a larger variable. |
2490 | struct FragmentInfo { |
2491 | uint64_t SizeInBits; |
2492 | uint64_t OffsetInBits; |
2493 | }; |
2494 | |
2495 | /// Retrieve the details of this fragment expression. |
2496 | static Optional<FragmentInfo> getFragmentInfo(expr_op_iterator Start, |
2497 | expr_op_iterator End); |
2498 | |
2499 | /// Retrieve the details of this fragment expression. |
2500 | Optional<FragmentInfo> getFragmentInfo() const { |
2501 | return getFragmentInfo(expr_op_begin(), expr_op_end()); |
2502 | } |
2503 | |
2504 | /// Return whether this is a piece of an aggregate variable. |
2505 | bool isFragment() const { return getFragmentInfo().hasValue(); } |
2506 | |
2507 | /// Append \p Ops with operations to apply the \p Offset. |
2508 | static void appendOffset(SmallVectorImpl<uint64_t> &Ops, int64_t Offset); |
2509 | |
2510 | /// If this is a constant offset, extract it. If there is no expression, |
2511 | /// return true with an offset of zero. |
2512 | bool (int64_t &Offset) const; |
2513 | |
2514 | /// Constants for DIExpression::prepend. |
2515 | enum { NoDeref = false, WithDeref = true, WithStackValue = true }; |
2516 | |
2517 | /// Prepend \p DIExpr with a deref and offset operation and optionally turn it |
2518 | /// into a stack value. |
2519 | static DIExpression *prepend(const DIExpression *Expr, bool DerefBefore, |
2520 | int64_t Offset = 0, bool DerefAfter = false, |
2521 | bool StackValue = false); |
2522 | |
2523 | /// Prepend \p DIExpr with the given opcodes and optionally turn it into a |
2524 | /// stack value. |
2525 | static DIExpression *prependOpcodes(const DIExpression *Expr, |
2526 | SmallVectorImpl<uint64_t> &Ops, |
2527 | bool StackValue = false); |
2528 | |
2529 | /// Append the opcodes \p Ops to \p DIExpr. Unlike \ref appendToStack, the |
2530 | /// returned expression is a stack value only if \p DIExpr is a stack value. |
2531 | /// If \p DIExpr describes a fragment, the returned expression will describe |
2532 | /// the same fragment. |
2533 | static DIExpression *append(const DIExpression *Expr, ArrayRef<uint64_t> Ops); |
2534 | |
2535 | /// Convert \p DIExpr into a stack value if it isn't one already by appending |
2536 | /// DW_OP_deref if needed, and appending \p Ops to the resulting expression. |
2537 | /// If \p DIExpr describes a fragment, the returned expression will describe |
2538 | /// the same fragment. |
2539 | static DIExpression *appendToStack(const DIExpression *Expr, |
2540 | ArrayRef<uint64_t> Ops); |
2541 | |
2542 | /// Create a DIExpression to describe one part of an aggregate variable that |
2543 | /// is fragmented across multiple Values. The DW_OP_LLVM_fragment operation |
2544 | /// will be appended to the elements of \c Expr. If \c Expr already contains |
2545 | /// a \c DW_OP_LLVM_fragment \c OffsetInBits is interpreted as an offset |
2546 | /// into the existing fragment. |
2547 | /// |
2548 | /// \param OffsetInBits Offset of the piece in bits. |
2549 | /// \param SizeInBits Size of the piece in bits. |
2550 | /// \return Creating a fragment expression may fail if \c Expr |
2551 | /// contains arithmetic operations that would be truncated. |
2552 | static Optional<DIExpression *> |
2553 | createFragmentExpression(const DIExpression *Expr, unsigned OffsetInBits, |
2554 | unsigned SizeInBits); |
2555 | |
2556 | /// Determine the relative position of the fragments described by this |
2557 | /// DIExpression and \p Other. |
2558 | /// Returns -1 if this is entirely before Other, 0 if this and Other overlap, |
2559 | /// 1 if this is entirely after Other. |
2560 | int fragmentCmp(const DIExpression *Other) const { |
2561 | auto Fragment1 = *getFragmentInfo(); |
2562 | auto Fragment2 = *Other->getFragmentInfo(); |
2563 | unsigned l1 = Fragment1.OffsetInBits; |
2564 | unsigned l2 = Fragment2.OffsetInBits; |
2565 | unsigned r1 = l1 + Fragment1.SizeInBits; |
2566 | unsigned r2 = l2 + Fragment2.SizeInBits; |
2567 | if (r1 <= l2) |
2568 | return -1; |
2569 | else if (r2 <= l1) |
2570 | return 1; |
2571 | else |
2572 | return 0; |
2573 | } |
2574 | |
2575 | /// Check if fragments overlap between this DIExpression and \p Other. |
2576 | bool fragmentsOverlap(const DIExpression *Other) const { |
2577 | if (!isFragment() || !Other->isFragment()) |
2578 | return true; |
2579 | return fragmentCmp(Other) == 0; |
2580 | } |
2581 | }; |
2582 | |
2583 | /// Global variables. |
2584 | /// |
2585 | /// TODO: Remove DisplayName. It's always equal to Name. |
2586 | class DIGlobalVariable : public DIVariable { |
2587 | friend class LLVMContextImpl; |
2588 | friend class MDNode; |
2589 | |
2590 | bool IsLocalToUnit; |
2591 | bool IsDefinition; |
2592 | |
2593 | DIGlobalVariable(LLVMContext &C, StorageType Storage, unsigned Line, |
2594 | bool IsLocalToUnit, bool IsDefinition, uint32_t AlignInBits, |
2595 | ArrayRef<Metadata *> Ops) |
2596 | : DIVariable(C, DIGlobalVariableKind, Storage, Line, Ops, AlignInBits), |
2597 | IsLocalToUnit(IsLocalToUnit), IsDefinition(IsDefinition) {} |
2598 | ~DIGlobalVariable() = default; |
2599 | |
2600 | static DIGlobalVariable * |
2601 | getImpl(LLVMContext &Context, DIScope *Scope, StringRef Name, |
2602 | StringRef LinkageName, DIFile *File, unsigned Line, DITypeRef Type, |
2603 | bool IsLocalToUnit, bool IsDefinition, |
2604 | DIDerivedType *StaticDataMemberDeclaration, MDTuple *TemplateParams, |
2605 | uint32_t AlignInBits, StorageType Storage, bool ShouldCreate = true) { |
2606 | return getImpl(Context, Scope, getCanonicalMDString(Context, Name), |
2607 | getCanonicalMDString(Context, LinkageName), File, Line, Type, |
2608 | IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration, |
2609 | cast_or_null<Metadata>(TemplateParams), AlignInBits, Storage, |
2610 | ShouldCreate); |
2611 | } |
2612 | static DIGlobalVariable * |
2613 | getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name, |
2614 | MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type, |
2615 | bool IsLocalToUnit, bool IsDefinition, |
2616 | Metadata *StaticDataMemberDeclaration, Metadata *TemplateParams, |
2617 | uint32_t AlignInBits, StorageType Storage, bool ShouldCreate = true); |
2618 | |
2619 | TempDIGlobalVariable cloneImpl() const { |
2620 | return getTemporary(getContext(), getScope(), getName(), getLinkageName(), |
2621 | getFile(), getLine(), getType(), isLocalToUnit(), |
2622 | isDefinition(), getStaticDataMemberDeclaration(), |
2623 | getTemplateParams(), getAlignInBits()); |
2624 | } |
2625 | |
2626 | public: |
2627 | DEFINE_MDNODE_GET(DIGlobalVariable, |
2628 | (DIScope * Scope, StringRef Name, StringRef LinkageName, |
2629 | DIFile *File, unsigned Line, DITypeRef Type, |
2630 | bool IsLocalToUnit, bool IsDefinition, |
2631 | DIDerivedType *StaticDataMemberDeclaration, |
2632 | MDTuple *TemplateParams, uint32_t AlignInBits), |
2633 | (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, |
2634 | IsDefinition, StaticDataMemberDeclaration, TemplateParams, |
2635 | AlignInBits)) |
2636 | DEFINE_MDNODE_GET(DIGlobalVariable, |
2637 | (Metadata * Scope, MDString *Name, MDString *LinkageName, |
2638 | Metadata *File, unsigned Line, Metadata *Type, |
2639 | bool IsLocalToUnit, bool IsDefinition, |
2640 | Metadata *StaticDataMemberDeclaration, |
2641 | Metadata *TemplateParams, uint32_t AlignInBits), |
2642 | (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, |
2643 | IsDefinition, StaticDataMemberDeclaration, TemplateParams, |
2644 | AlignInBits)) |
2645 | |
2646 | TempDIGlobalVariable clone() const { return cloneImpl(); } |
2647 | |
2648 | bool isLocalToUnit() const { return IsLocalToUnit; } |
2649 | bool isDefinition() const { return IsDefinition; } |
2650 | StringRef getDisplayName() const { return getStringOperand(4); } |
2651 | StringRef getLinkageName() const { return getStringOperand(5); } |
2652 | DIDerivedType *getStaticDataMemberDeclaration() const { |
2653 | return cast_or_null<DIDerivedType>(getRawStaticDataMemberDeclaration()); |
2654 | } |
2655 | |
2656 | MDString *getRawLinkageName() const { return getOperandAs<MDString>(5); } |
2657 | Metadata *getRawStaticDataMemberDeclaration() const { return getOperand(6); } |
2658 | Metadata *getRawTemplateParams() const { return getOperand(7); } |
2659 | MDTuple *getTemplateParams() const { return getOperandAs<MDTuple>(7); } |
2660 | |
2661 | static bool classof(const Metadata *MD) { |
2662 | return MD->getMetadataID() == DIGlobalVariableKind; |
2663 | } |
2664 | }; |
2665 | |
2666 | /// Local variable. |
2667 | /// |
2668 | /// TODO: Split up flags. |
2669 | class DILocalVariable : public DIVariable { |
2670 | friend class LLVMContextImpl; |
2671 | friend class MDNode; |
2672 | |
2673 | unsigned Arg : 16; |
2674 | DIFlags Flags; |
2675 | |
2676 | DILocalVariable(LLVMContext &C, StorageType Storage, unsigned Line, |
2677 | unsigned Arg, DIFlags Flags, uint32_t AlignInBits, |
2678 | ArrayRef<Metadata *> Ops) |
2679 | : DIVariable(C, DILocalVariableKind, Storage, Line, Ops, AlignInBits), |
2680 | Arg(Arg), Flags(Flags) { |
2681 | assert(Arg < (1 << 16) && "DILocalVariable: Arg out of range" ); |
2682 | } |
2683 | ~DILocalVariable() = default; |
2684 | |
2685 | static DILocalVariable *getImpl(LLVMContext &Context, DIScope *Scope, |
2686 | StringRef Name, DIFile *File, unsigned Line, |
2687 | DITypeRef Type, unsigned Arg, DIFlags Flags, |
2688 | uint32_t AlignInBits, StorageType Storage, |
2689 | bool ShouldCreate = true) { |
2690 | return getImpl(Context, Scope, getCanonicalMDString(Context, Name), File, |
2691 | Line, Type, Arg, Flags, AlignInBits, Storage, ShouldCreate); |
2692 | } |
2693 | static DILocalVariable *getImpl(LLVMContext &Context, Metadata *Scope, |
2694 | MDString *Name, Metadata *File, unsigned Line, |
2695 | Metadata *Type, unsigned Arg, DIFlags Flags, |
2696 | uint32_t AlignInBits, StorageType Storage, |
2697 | bool ShouldCreate = true); |
2698 | |
2699 | TempDILocalVariable cloneImpl() const { |
2700 | return getTemporary(getContext(), getScope(), getName(), getFile(), |
2701 | getLine(), getType(), getArg(), getFlags(), |
2702 | getAlignInBits()); |
2703 | } |
2704 | |
2705 | public: |
2706 | DEFINE_MDNODE_GET(DILocalVariable, |
2707 | (DILocalScope * Scope, StringRef Name, DIFile *File, |
2708 | unsigned Line, DITypeRef Type, unsigned Arg, |
2709 | DIFlags Flags, uint32_t AlignInBits), |
2710 | (Scope, Name, File, Line, Type, Arg, Flags, AlignInBits)) |
2711 | DEFINE_MDNODE_GET(DILocalVariable, |
2712 | (Metadata * Scope, MDString *Name, Metadata *File, |
2713 | unsigned Line, Metadata *Type, unsigned Arg, |
2714 | DIFlags Flags, uint32_t AlignInBits), |
2715 | (Scope, Name, File, Line, Type, Arg, Flags, AlignInBits)) |
2716 | |
2717 | TempDILocalVariable clone() const { return cloneImpl(); } |
2718 | |
2719 | /// Get the local scope for this variable. |
2720 | /// |
2721 | /// Variables must be defined in a local scope. |
2722 | DILocalScope *getScope() const { |
2723 | return cast<DILocalScope>(DIVariable::getScope()); |
2724 | } |
2725 | |
2726 | bool isParameter() const { return Arg; } |
2727 | unsigned getArg() const { return Arg; } |
2728 | DIFlags getFlags() const { return Flags; } |
2729 | |
2730 | bool isArtificial() const { return getFlags() & FlagArtificial; } |
2731 | bool isObjectPointer() const { return getFlags() & FlagObjectPointer; } |
2732 | |
2733 | /// Check that a location is valid for this variable. |
2734 | /// |
2735 | /// Check that \c DL exists, is in the same subprogram, and has the same |
2736 | /// inlined-at location as \c this. (Otherwise, it's not a valid attachment |
2737 | /// to a \a DbgInfoIntrinsic.) |
2738 | bool isValidLocationForIntrinsic(const DILocation *DL) const { |
2739 | return DL && getScope()->getSubprogram() == DL->getScope()->getSubprogram(); |
2740 | } |
2741 | |
2742 | static bool classof(const Metadata *MD) { |
2743 | return MD->getMetadataID() == DILocalVariableKind; |
2744 | } |
2745 | }; |
2746 | |
2747 | /// Label. |
2748 | /// |
2749 | class DILabel : public DINode { |
2750 | friend class LLVMContextImpl; |
2751 | friend class MDNode; |
2752 | |
2753 | unsigned Line; |
2754 | |
2755 | DILabel(LLVMContext &C, StorageType Storage, unsigned Line, |
2756 | ArrayRef<Metadata *> Ops) |
2757 | : DINode(C, DILabelKind, Storage, dwarf::DW_TAG_label, Ops), Line(Line) {} |
2758 | ~DILabel() = default; |
2759 | |
2760 | static DILabel *getImpl(LLVMContext &Context, DIScope *Scope, |
2761 | StringRef Name, DIFile *File, unsigned Line, |
2762 | StorageType Storage, |
2763 | bool ShouldCreate = true) { |
2764 | return getImpl(Context, Scope, getCanonicalMDString(Context, Name), File, |
2765 | Line, Storage, ShouldCreate); |
2766 | } |
2767 | static DILabel *getImpl(LLVMContext &Context, Metadata *Scope, |
2768 | MDString *Name, Metadata *File, unsigned Line, |
2769 | StorageType Storage, |
2770 | bool ShouldCreate = true); |
2771 | |
2772 | TempDILabel cloneImpl() const { |
2773 | return getTemporary(getContext(), getScope(), getName(), getFile(), |
2774 | getLine()); |
2775 | } |
2776 | |
2777 | public: |
2778 | DEFINE_MDNODE_GET(DILabel, |
2779 | (DILocalScope * Scope, StringRef Name, DIFile *File, |
2780 | unsigned Line), |
2781 | (Scope, Name, File, Line)) |
2782 | DEFINE_MDNODE_GET(DILabel, |
2783 | (Metadata * Scope, MDString *Name, Metadata *File, |
2784 | unsigned Line), |
2785 | (Scope, Name, File, Line)) |
2786 | |
2787 | TempDILabel clone() const { return cloneImpl(); } |
2788 | |
2789 | /// Get the local scope for this label. |
2790 | /// |
2791 | /// Labels must be defined in a local scope. |
2792 | DILocalScope *getScope() const { |
2793 | return cast_or_null<DILocalScope>(getRawScope()); |
2794 | } |
2795 | unsigned getLine() const { return Line; } |
2796 | StringRef getName() const { return getStringOperand(1); } |
2797 | DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); } |
2798 | |
2799 | Metadata *getRawScope() const { return getOperand(0); } |
2800 | MDString *getRawName() const { return getOperandAs<MDString>(1); } |
2801 | Metadata *getRawFile() const { return getOperand(2); } |
2802 | |
2803 | /// Check that a location is valid for this label. |
2804 | /// |
2805 | /// Check that \c DL exists, is in the same subprogram, and has the same |
2806 | /// inlined-at location as \c this. (Otherwise, it's not a valid attachment |
2807 | /// to a \a DbgInfoIntrinsic.) |
2808 | bool isValidLocationForIntrinsic(const DILocation *DL) const { |
2809 | return DL && getScope()->getSubprogram() == DL->getScope()->getSubprogram(); |
2810 | } |
2811 | |
2812 | static bool classof(const Metadata *MD) { |
2813 | return MD->getMetadataID() == DILabelKind; |
2814 | } |
2815 | }; |
2816 | |
2817 | class DIObjCProperty : public DINode { |
2818 | friend class LLVMContextImpl; |
2819 | friend class MDNode; |
2820 | |
2821 | unsigned Line; |
2822 | unsigned Attributes; |
2823 | |
2824 | DIObjCProperty(LLVMContext &C, StorageType Storage, unsigned Line, |
2825 | unsigned Attributes, ArrayRef<Metadata *> Ops) |
2826 | : DINode(C, DIObjCPropertyKind, Storage, dwarf::DW_TAG_APPLE_property, |
2827 | Ops), |
2828 | Line(Line), Attributes(Attributes) {} |
2829 | ~DIObjCProperty() = default; |
2830 | |
2831 | static DIObjCProperty * |
2832 | getImpl(LLVMContext &Context, StringRef Name, DIFile *File, unsigned Line, |
2833 | StringRef GetterName, StringRef SetterName, unsigned Attributes, |
2834 | DITypeRef Type, StorageType Storage, bool ShouldCreate = true) { |
2835 | return getImpl(Context, getCanonicalMDString(Context, Name), File, Line, |
2836 | getCanonicalMDString(Context, GetterName), |
2837 | getCanonicalMDString(Context, SetterName), Attributes, Type, |
2838 | Storage, ShouldCreate); |
2839 | } |
2840 | static DIObjCProperty *getImpl(LLVMContext &Context, MDString *Name, |
2841 | Metadata *File, unsigned Line, |
2842 | MDString *GetterName, MDString *SetterName, |
2843 | unsigned Attributes, Metadata *Type, |
2844 | StorageType Storage, bool ShouldCreate = true); |
2845 | |
2846 | TempDIObjCProperty cloneImpl() const { |
2847 | return getTemporary(getContext(), getName(), getFile(), getLine(), |
2848 | getGetterName(), getSetterName(), getAttributes(), |
2849 | getType()); |
2850 | } |
2851 | |
2852 | public: |
2853 | DEFINE_MDNODE_GET(DIObjCProperty, |
2854 | (StringRef Name, DIFile *File, unsigned Line, |
2855 | StringRef GetterName, StringRef SetterName, |
2856 | unsigned Attributes, DITypeRef Type), |
2857 | (Name, File, Line, GetterName, SetterName, Attributes, |
2858 | Type)) |
2859 | DEFINE_MDNODE_GET(DIObjCProperty, |
2860 | (MDString * Name, Metadata *File, unsigned Line, |
2861 | MDString *GetterName, MDString *SetterName, |
2862 | unsigned Attributes, Metadata *Type), |
2863 | (Name, File, Line, GetterName, SetterName, Attributes, |
2864 | Type)) |
2865 | |
2866 | TempDIObjCProperty clone() const { return cloneImpl(); } |
2867 | |
2868 | unsigned getLine() const { return Line; } |
2869 | unsigned getAttributes() const { return Attributes; } |
2870 | StringRef getName() const { return getStringOperand(0); } |
2871 | DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); } |
2872 | StringRef getGetterName() const { return getStringOperand(2); } |
2873 | StringRef getSetterName() const { return getStringOperand(3); } |
2874 | DITypeRef getType() const { return DITypeRef(getRawType()); } |
2875 | |
2876 | StringRef getFilename() const { |
2877 | if (auto *F = getFile()) |
2878 | return F->getFilename(); |
2879 | return "" ; |
2880 | } |
2881 | |
2882 | StringRef getDirectory() const { |
2883 | if (auto *F = getFile()) |
2884 | return F->getDirectory(); |
2885 | return "" ; |
2886 | } |
2887 | |
2888 | Optional<StringRef> getSource() const { |
2889 | if (auto *F = getFile()) |
2890 | return F->getSource(); |
2891 | return None; |
2892 | } |
2893 | |
2894 | MDString *getRawName() const { return getOperandAs<MDString>(0); } |
2895 | Metadata *getRawFile() const { return getOperand(1); } |
2896 | MDString *getRawGetterName() const { return getOperandAs<MDString>(2); } |
2897 | MDString *getRawSetterName() const { return getOperandAs<MDString>(3); } |
2898 | Metadata *getRawType() const { return getOperand(4); } |
2899 | |
2900 | static bool classof(const Metadata *MD) { |
2901 | return MD->getMetadataID() == DIObjCPropertyKind; |
2902 | } |
2903 | }; |
2904 | |
2905 | /// An imported module (C++ using directive or similar). |
2906 | class DIImportedEntity : public DINode { |
2907 | friend class LLVMContextImpl; |
2908 | friend class MDNode; |
2909 | |
2910 | unsigned Line; |
2911 | |
2912 | DIImportedEntity(LLVMContext &C, StorageType Storage, unsigned Tag, |
2913 | unsigned Line, ArrayRef<Metadata *> Ops) |
2914 | : DINode(C, DIImportedEntityKind, Storage, Tag, Ops), Line(Line) {} |
2915 | ~DIImportedEntity() = default; |
2916 | |
2917 | static DIImportedEntity *getImpl(LLVMContext &Context, unsigned Tag, |
2918 | DIScope *Scope, DINodeRef Entity, |
2919 | DIFile *File, unsigned Line, StringRef Name, |
2920 | StorageType Storage, |
2921 | bool ShouldCreate = true) { |
2922 | return getImpl(Context, Tag, Scope, Entity, File, Line, |
2923 | getCanonicalMDString(Context, Name), Storage, ShouldCreate); |
2924 | } |
2925 | static DIImportedEntity *getImpl(LLVMContext &Context, unsigned Tag, |
2926 | Metadata *Scope, Metadata *Entity, |
2927 | Metadata *File, unsigned Line, |
2928 | MDString *Name, StorageType Storage, |
2929 | bool ShouldCreate = true); |
2930 | |
2931 | TempDIImportedEntity cloneImpl() const { |
2932 | return getTemporary(getContext(), getTag(), getScope(), getEntity(), |
2933 | getFile(), getLine(), getName()); |
2934 | } |
2935 | |
2936 | public: |
2937 | DEFINE_MDNODE_GET(DIImportedEntity, |
2938 | (unsigned Tag, DIScope *Scope, DINodeRef Entity, |
2939 | DIFile *File, unsigned Line, StringRef Name = "" ), |
2940 | (Tag, Scope, Entity, File, Line, Name)) |
2941 | DEFINE_MDNODE_GET(DIImportedEntity, |
2942 | (unsigned Tag, Metadata *Scope, Metadata *Entity, |
2943 | Metadata *File, unsigned Line, MDString *Name), |
2944 | (Tag, Scope, Entity, File, Line, Name)) |
2945 | |
2946 | TempDIImportedEntity clone() const { return cloneImpl(); } |
2947 | |
2948 | unsigned getLine() const { return Line; } |
2949 | DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); } |
2950 | DINodeRef getEntity() const { return DINodeRef(getRawEntity()); } |
2951 | StringRef getName() const { return getStringOperand(2); } |
2952 | DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); } |
2953 | |
2954 | Metadata *getRawScope() const { return getOperand(0); } |
2955 | Metadata *getRawEntity() const { return getOperand(1); } |
2956 | MDString *getRawName() const { return getOperandAs<MDString>(2); } |
2957 | Metadata *getRawFile() const { return getOperand(3); } |
2958 | |
2959 | static bool classof(const Metadata *MD) { |
2960 | return MD->getMetadataID() == DIImportedEntityKind; |
2961 | } |
2962 | }; |
2963 | |
2964 | /// A pair of DIGlobalVariable and DIExpression. |
2965 | class DIGlobalVariableExpression : public MDNode { |
2966 | friend class LLVMContextImpl; |
2967 | friend class MDNode; |
2968 | |
2969 | DIGlobalVariableExpression(LLVMContext &C, StorageType Storage, |
2970 | ArrayRef<Metadata *> Ops) |
2971 | : MDNode(C, DIGlobalVariableExpressionKind, Storage, Ops) {} |
2972 | ~DIGlobalVariableExpression() = default; |
2973 | |
2974 | static DIGlobalVariableExpression * |
2975 | getImpl(LLVMContext &Context, Metadata *Variable, Metadata *Expression, |
2976 | StorageType Storage, bool ShouldCreate = true); |
2977 | |
2978 | TempDIGlobalVariableExpression cloneImpl() const { |
2979 | return getTemporary(getContext(), getVariable(), getExpression()); |
2980 | } |
2981 | |
2982 | public: |
2983 | DEFINE_MDNODE_GET(DIGlobalVariableExpression, |
2984 | (Metadata * Variable, Metadata *Expression), |
2985 | (Variable, Expression)) |
2986 | |
2987 | TempDIGlobalVariableExpression clone() const { return cloneImpl(); } |
2988 | |
2989 | Metadata *getRawVariable() const { return getOperand(0); } |
2990 | |
2991 | DIGlobalVariable *getVariable() const { |
2992 | return cast_or_null<DIGlobalVariable>(getRawVariable()); |
2993 | } |
2994 | |
2995 | Metadata *getRawExpression() const { return getOperand(1); } |
2996 | |
2997 | DIExpression *getExpression() const { |
2998 | return cast<DIExpression>(getRawExpression()); |
2999 | } |
3000 | |
3001 | static bool classof(const Metadata *MD) { |
3002 | return MD->getMetadataID() == DIGlobalVariableExpressionKind; |
3003 | } |
3004 | }; |
3005 | |
3006 | /// Macro Info DWARF-like metadata node. |
3007 | /// |
3008 | /// A metadata node with a DWARF macro info (i.e., a constant named |
3009 | /// \c DW_MACINFO_*, defined in llvm/BinaryFormat/Dwarf.h). Called \a |
3010 | /// DIMacroNode |
3011 | /// because it's potentially used for non-DWARF output. |
3012 | class DIMacroNode : public MDNode { |
3013 | friend class LLVMContextImpl; |
3014 | friend class MDNode; |
3015 | |
3016 | protected: |
3017 | DIMacroNode(LLVMContext &C, unsigned ID, StorageType Storage, unsigned MIType, |
3018 | ArrayRef<Metadata *> Ops1, ArrayRef<Metadata *> Ops2 = None) |
3019 | : MDNode(C, ID, Storage, Ops1, Ops2) { |
3020 | assert(MIType < 1u << 16); |
3021 | SubclassData16 = MIType; |
3022 | } |
3023 | ~DIMacroNode() = default; |
3024 | |
3025 | template <class Ty> Ty *getOperandAs(unsigned I) const { |
3026 | return cast_or_null<Ty>(getOperand(I)); |
3027 | } |
3028 | |
3029 | StringRef getStringOperand(unsigned I) const { |
3030 | if (auto *S = getOperandAs<MDString>(I)) |
3031 | return S->getString(); |
3032 | return StringRef(); |
3033 | } |
3034 | |
3035 | static MDString *getCanonicalMDString(LLVMContext &Context, StringRef S) { |
3036 | if (S.empty()) |
3037 | return nullptr; |
3038 | return MDString::get(Context, S); |
3039 | } |
3040 | |
3041 | public: |
3042 | unsigned getMacinfoType() const { return SubclassData16; } |
3043 | |
3044 | static bool classof(const Metadata *MD) { |
3045 | switch (MD->getMetadataID()) { |
3046 | default: |
3047 | return false; |
3048 | case DIMacroKind: |
3049 | case DIMacroFileKind: |
3050 | return true; |
3051 | } |
3052 | } |
3053 | }; |
3054 | |
3055 | class DIMacro : public DIMacroNode { |
3056 | friend class LLVMContextImpl; |
3057 | friend class MDNode; |
3058 | |
3059 | unsigned Line; |
3060 | |
3061 | DIMacro(LLVMContext &C, StorageType Storage, unsigned MIType, unsigned Line, |
3062 | ArrayRef<Metadata *> Ops) |
3063 | : DIMacroNode(C, DIMacroKind, Storage, MIType, Ops), Line(Line) {} |
3064 | ~DIMacro() = default; |
3065 | |
3066 | static DIMacro *getImpl(LLVMContext &Context, unsigned MIType, unsigned Line, |
3067 | StringRef Name, StringRef Value, StorageType Storage, |
3068 | bool ShouldCreate = true) { |
3069 | return getImpl(Context, MIType, Line, getCanonicalMDString(Context, Name), |
3070 | getCanonicalMDString(Context, Value), Storage, ShouldCreate); |
3071 | } |
3072 | static DIMacro *getImpl(LLVMContext &Context, unsigned MIType, unsigned Line, |
3073 | MDString *Name, MDString *Value, StorageType Storage, |
3074 | bool ShouldCreate = true); |
3075 | |
3076 | TempDIMacro cloneImpl() const { |
3077 | return getTemporary(getContext(), getMacinfoType(), getLine(), getName(), |
3078 | getValue()); |
3079 | } |
3080 | |
3081 | public: |
3082 | DEFINE_MDNODE_GET(DIMacro, (unsigned MIType, unsigned Line, StringRef Name, |
3083 | StringRef Value = "" ), |
3084 | (MIType, Line, Name, Value)) |
3085 | DEFINE_MDNODE_GET(DIMacro, (unsigned MIType, unsigned Line, MDString *Name, |
3086 | MDString *Value), |
3087 | (MIType, Line, Name, Value)) |
3088 | |
3089 | TempDIMacro clone() const { return cloneImpl(); } |
3090 | |
3091 | unsigned getLine() const { return Line; } |
3092 | |
3093 | StringRef getName() const { return getStringOperand(0); } |
3094 | StringRef getValue() const { return getStringOperand(1); } |
3095 | |
3096 | MDString *getRawName() const { return getOperandAs<MDString>(0); } |
3097 | MDString *getRawValue() const { return getOperandAs<MDString>(1); } |
3098 | |
3099 | static bool classof(const Metadata *MD) { |
3100 | return MD->getMetadataID() == DIMacroKind; |
3101 | } |
3102 | }; |
3103 | |
3104 | class DIMacroFile : public DIMacroNode { |
3105 | friend class LLVMContextImpl; |
3106 | friend class MDNode; |
3107 | |
3108 | unsigned Line; |
3109 | |
3110 | DIMacroFile(LLVMContext &C, StorageType Storage, unsigned MIType, |
3111 | unsigned Line, ArrayRef<Metadata *> Ops) |
3112 | : DIMacroNode(C, DIMacroFileKind, Storage, MIType, Ops), Line(Line) {} |
3113 | ~DIMacroFile() = default; |
3114 | |
3115 | static DIMacroFile *getImpl(LLVMContext &Context, unsigned MIType, |
3116 | unsigned Line, DIFile *File, |
3117 | DIMacroNodeArray Elements, StorageType Storage, |
3118 | bool ShouldCreate = true) { |
3119 | return getImpl(Context, MIType, Line, static_cast<Metadata *>(File), |
3120 | Elements.get(), Storage, ShouldCreate); |
3121 | } |
3122 | |
3123 | static DIMacroFile *getImpl(LLVMContext &Context, unsigned MIType, |
3124 | unsigned Line, Metadata *File, Metadata *Elements, |
3125 | StorageType Storage, bool ShouldCreate = true); |
3126 | |
3127 | TempDIMacroFile cloneImpl() const { |
3128 | return getTemporary(getContext(), getMacinfoType(), getLine(), getFile(), |
3129 | getElements()); |
3130 | } |
3131 | |
3132 | public: |
3133 | DEFINE_MDNODE_GET(DIMacroFile, (unsigned MIType, unsigned Line, DIFile *File, |
3134 | DIMacroNodeArray Elements), |
3135 | (MIType, Line, File, Elements)) |
3136 | DEFINE_MDNODE_GET(DIMacroFile, (unsigned MIType, unsigned Line, |
3137 | Metadata *File, Metadata *Elements), |
3138 | (MIType, Line, File, Elements)) |
3139 | |
3140 | TempDIMacroFile clone() const { return cloneImpl(); } |
3141 | |
3142 | void replaceElements(DIMacroNodeArray Elements) { |
3143 | #ifndef NDEBUG |
3144 | for (DIMacroNode *Op : getElements()) |
3145 | assert(is_contained(Elements->operands(), Op) && |
3146 | "Lost a macro node during macro node list replacement" ); |
3147 | #endif |
3148 | replaceOperandWith(1, Elements.get()); |
3149 | } |
3150 | |
3151 | unsigned getLine() const { return Line; } |
3152 | DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); } |
3153 | |
3154 | DIMacroNodeArray getElements() const { |
3155 | return cast_or_null<MDTuple>(getRawElements()); |
3156 | } |
3157 | |
3158 | Metadata *getRawFile() const { return getOperand(0); } |
3159 | Metadata *getRawElements() const { return getOperand(1); } |
3160 | |
3161 | static bool classof(const Metadata *MD) { |
3162 | return MD->getMetadataID() == DIMacroFileKind; |
3163 | } |
3164 | }; |
3165 | |
3166 | } // end namespace llvm |
3167 | |
3168 | #undef DEFINE_MDNODE_GET_UNPACK_IMPL |
3169 | #undef DEFINE_MDNODE_GET_UNPACK |
3170 | #undef DEFINE_MDNODE_GET |
3171 | |
3172 | #endif // LLVM_IR_DEBUGINFOMETADATA_H |
3173 | |