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