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
61namespace llvm {
62
63class DITypeRefArray {
64 const MDTuple *N = nullptr;
65
66public:
67 DITypeRefArray() = default;
68 DITypeRefArray(const MDTuple *N) : N(N) {}
69
70 explicit operator bool() const { return get(); }
71 explicit operator MDTuple *() const { return get(); }
72
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.
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 {
84 MDNode::op_iterator I = nullptr;
85
86 public:
87 using iterator_category = std::input_iterator_tag;
88 using value_type = DIType *;
89 using difference_type = std::ptrdiff_t;
90 using pointer = void;
91 using reference = DIType *;
92
93 iterator() = default;
94 explicit iterator(MDNode::op_iterator I) : I(I) {}
95
96 DIType *operator*() const { return cast_or_null<DIType>(*I); }
97
98 iterator &operator++() {
99 ++I;
100 return *this;
101 }
102
103 iterator operator++(int) {
104 iterator Temp(*this);
105 ++I;
106 return Temp;
107 }
108
109 bool operator==(const iterator &X) const { return I == X.I; }
110 bool operator!=(const iterator &X) const { return I != X.I; }
111 };
112
113 // FIXME: Fix callers and remove condition on N.
114 iterator begin() const { return N ? iterator(N->op_begin()) : iterator(); }
115 iterator end() const { return N ? iterator(N->op_end()) : iterator(); }
116};
117
118/// Tagged DWARF-like metadata node.
119///
120/// A metadata node with a DWARF tag (i.e., a constant named \c DW_TAG_*,
121/// defined in llvm/BinaryFormat/Dwarf.h). Called \a DINode because it's
122/// potentially used for non-DWARF output.
123class DINode : public MDNode {
124 friend class LLVMContextImpl;
125 friend class MDNode;
126
127protected:
128 DINode(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
129 ArrayRef<Metadata *> Ops1, ArrayRef<Metadata *> Ops2 = None)
130 : MDNode(C, ID, Storage, Ops1, Ops2) {
131 assert(Tag < 1u << 16);
132 SubclassData16 = Tag;
133 }
134 ~DINode() = default;
135
136 template <class Ty> Ty *getOperandAs(unsigned I) const {
137 return cast_or_null<Ty>(getOperand(I));
138 }
139
140 StringRef getStringOperand(unsigned I) const {
141 if (auto *S = getOperandAs<MDString>(I))
142 return S->getString();
143 return StringRef();
144 }
145
146 static MDString *getCanonicalMDString(LLVMContext &Context, StringRef S) {
147 if (S.empty())
148 return nullptr;
149 return MDString::get(Context, S);
150 }
151
152 /// Allow subclasses to mutate the tag.
153 void setTag(unsigned Tag) { SubclassData16 = Tag; }
154
155public:
156 unsigned getTag() const { return SubclassData16; }
157
158 /// Debug info flags.
159 ///
160 /// The three accessibility flags are mutually exclusive and rolled together
161 /// in the first two bits.
162 enum DIFlags : uint32_t {
163#define HANDLE_DI_FLAG(ID, NAME) Flag##NAME = ID,
164#define DI_FLAG_LARGEST_NEEDED
165#include "llvm/IR/DebugInfoFlags.def"
166 FlagAccessibility = FlagPrivate | FlagProtected | FlagPublic,
167 FlagPtrToMemberRep = FlagSingleInheritance | FlagMultipleInheritance |
168 FlagVirtualInheritance,
169 LLVM_MARK_AS_BITMASK_ENUM(FlagLargest)
170 };
171
172 static DIFlags getFlag(StringRef Flag);
173 static StringRef getFlagString(DIFlags Flag);
174
175 /// Split up a flags bitfield.
176 ///
177 /// Split \c Flags into \c SplitFlags, a vector of its components. Returns
178 /// any remaining (unrecognized) bits.
179 static DIFlags splitFlags(DIFlags Flags,
180 SmallVectorImpl<DIFlags> &SplitFlags);
181
182 static bool classof(const Metadata *MD) {
183 switch (MD->getMetadataID()) {
184 default:
185 return false;
186 case GenericDINodeKind:
187 case DISubrangeKind:
188 case DIEnumeratorKind:
189 case DIBasicTypeKind:
190 case DIStringTypeKind:
191 case DIDerivedTypeKind:
192 case DICompositeTypeKind:
193 case DISubroutineTypeKind:
194 case DIFileKind:
195 case DICompileUnitKind:
196 case DISubprogramKind:
197 case DILexicalBlockKind:
198 case DILexicalBlockFileKind:
199 case DINamespaceKind:
200 case DICommonBlockKind:
201 case DITemplateTypeParameterKind:
202 case DITemplateValueParameterKind:
203 case DIGlobalVariableKind:
204 case DILocalVariableKind:
205 case DILabelKind:
206 case DIObjCPropertyKind:
207 case DIImportedEntityKind:
208 case DIModuleKind:
209 case DIGenericSubrangeKind:
210 return true;
211 }
212 }
213};
214
215/// Generic tagged DWARF-like metadata node.
216///
217/// An un-specialized DWARF-like metadata node. The first operand is a
218/// (possibly empty) null-separated \a MDString header that contains arbitrary
219/// fields. The remaining operands are \a dwarf_operands(), and are pointers
220/// to other metadata.
221class GenericDINode : public DINode {
222 friend class LLVMContextImpl;
223 friend class MDNode;
224
225 GenericDINode(LLVMContext &C, StorageType Storage, unsigned Hash,
226 unsigned Tag, ArrayRef<Metadata *> Ops1,
227 ArrayRef<Metadata *> Ops2)
228 : DINode(C, GenericDINodeKind, Storage, Tag, Ops1, Ops2) {
229 setHash(Hash);
230 }
231 ~GenericDINode() { dropAllReferences(); }
232
233 void setHash(unsigned Hash) { SubclassData32 = Hash; }
234 void recalculateHash();
235
236 static GenericDINode *getImpl(LLVMContext &Context, unsigned Tag,
237 StringRef Header, ArrayRef<Metadata *> DwarfOps,
238 StorageType Storage, bool ShouldCreate = true) {
239 return getImpl(Context, Tag, getCanonicalMDString(Context, Header),
240 DwarfOps, Storage, ShouldCreate);
241 }
242
243 static GenericDINode *getImpl(LLVMContext &Context, unsigned Tag,
244 MDString *Header, ArrayRef<Metadata *> DwarfOps,
245 StorageType Storage, bool ShouldCreate = true);
246
247 TempGenericDINode cloneImpl() const {
248 return getTemporary(getContext(), getTag(), getHeader(),
249 SmallVector<Metadata *, 4>(dwarf_operands()));
250 }
251
252public:
253 unsigned getHash() const { return SubclassData32; }
254
255 DEFINE_MDNODE_GET(GenericDINode, (unsigned Tag, StringRef Header,
256 ArrayRef<Metadata *> DwarfOps),
257 (Tag, Header, DwarfOps))
258 DEFINE_MDNODE_GET(GenericDINode, (unsigned Tag, MDString *Header,
259 ArrayRef<Metadata *> DwarfOps),
260 (Tag, Header, DwarfOps))
261
262 /// Return a (temporary) clone of this.
263 TempGenericDINode clone() const { return cloneImpl(); }
264
265 unsigned getTag() const { return SubclassData16; }
266 StringRef getHeader() const { return getStringOperand(0); }
267 MDString *getRawHeader() const { return getOperandAs<MDString>(0); }
268
269 op_iterator dwarf_op_begin() const { return op_begin() + 1; }
270 op_iterator dwarf_op_end() const { return op_end(); }
271 op_range dwarf_operands() const {
272 return op_range(dwarf_op_begin(), dwarf_op_end());
273 }
274
275 unsigned getNumDwarfOperands() const { return getNumOperands() - 1; }
276 const MDOperand &getDwarfOperand(unsigned I) const {
277 return getOperand(I + 1);
278 }
279 void replaceDwarfOperandWith(unsigned I, Metadata *New) {
280 replaceOperandWith(I + 1, New);
281 }
282
283 static bool classof(const Metadata *MD) {
284 return MD->getMetadataID() == GenericDINodeKind;
285 }
286};
287
288/// Array subrange.
289///
290/// TODO: Merge into node for DW_TAG_array_type, which should have a custom
291/// type.
292class DISubrange : public DINode {
293 friend class LLVMContextImpl;
294 friend class MDNode;
295
296 DISubrange(LLVMContext &C, StorageType Storage, ArrayRef<Metadata *> Ops)
297 : DINode(C, DISubrangeKind, Storage, dwarf::DW_TAG_subrange_type, Ops) {}
298
299 ~DISubrange() = default;
300
301 static DISubrange *getImpl(LLVMContext &Context, int64_t Count,
302 int64_t LowerBound, StorageType Storage,
303 bool ShouldCreate = true);
304
305 static DISubrange *getImpl(LLVMContext &Context, Metadata *CountNode,
306 int64_t LowerBound, StorageType Storage,
307 bool ShouldCreate = true);
308
309 static DISubrange *getImpl(LLVMContext &Context, Metadata *CountNode,
310 Metadata *LowerBound, Metadata *UpperBound,
311 Metadata *Stride, StorageType Storage,
312 bool ShouldCreate = true);
313
314 TempDISubrange cloneImpl() const {
315 return getTemporary(getContext(), getRawCountNode(), getRawLowerBound(),
316 getRawUpperBound(), getRawStride());
317 }
318
319public:
320 DEFINE_MDNODE_GET(DISubrange, (int64_t Count, int64_t LowerBound = 0),
321 (Count, LowerBound))
322
323 DEFINE_MDNODE_GET(DISubrange, (Metadata *CountNode, int64_t LowerBound = 0),
324 (CountNode, LowerBound))
325
326 DEFINE_MDNODE_GET(DISubrange,
327 (Metadata * CountNode, Metadata *LowerBound,
328 Metadata *UpperBound, Metadata *Stride),
329 (CountNode, LowerBound, UpperBound, Stride))
330
331 TempDISubrange clone() const { return cloneImpl(); }
332
333 Metadata *getRawCountNode() const {
334 return getOperand(0).get();
335 }
336
337 Metadata *getRawLowerBound() const { return getOperand(1).get(); }
338
339 Metadata *getRawUpperBound() const { return getOperand(2).get(); }
340
341 Metadata *getRawStride() const { return getOperand(3).get(); }
342
343 typedef PointerUnion<ConstantInt *, DIVariable *, DIExpression *> BoundType;
344
345 BoundType getCount() const;
346
347 BoundType getLowerBound() const;
348
349 BoundType getUpperBound() const;
350
351 BoundType getStride() const;
352
353 static bool classof(const Metadata *MD) {
354 return MD->getMetadataID() == DISubrangeKind;
355 }
356};
357
358class DIGenericSubrange : public DINode {
359 friend class LLVMContextImpl;
360 friend class MDNode;
361
362 DIGenericSubrange(LLVMContext &C, StorageType Storage,
363 ArrayRef<Metadata *> Ops)
364 : DINode(C, DIGenericSubrangeKind, Storage,
365 dwarf::DW_TAG_generic_subrange, Ops) {}
366
367 ~DIGenericSubrange() = default;
368
369 static DIGenericSubrange *getImpl(LLVMContext &Context, Metadata *CountNode,
370 Metadata *LowerBound, Metadata *UpperBound,
371 Metadata *Stride, StorageType Storage,
372 bool ShouldCreate = true);
373
374 TempDIGenericSubrange cloneImpl() const {
375 return getTemporary(getContext(), getRawCountNode(), getRawLowerBound(),
376 getRawUpperBound(), getRawStride());
377 }
378
379public:
380 DEFINE_MDNODE_GET(DIGenericSubrange,
381 (Metadata * CountNode, Metadata *LowerBound,
382 Metadata *UpperBound, Metadata *Stride),
383 (CountNode, LowerBound, UpperBound, Stride))
384
385 TempDIGenericSubrange clone() const { return cloneImpl(); }
386
387 Metadata *getRawCountNode() const { return getOperand(0).get(); }
388 Metadata *getRawLowerBound() const { return getOperand(1).get(); }
389 Metadata *getRawUpperBound() const { return getOperand(2).get(); }
390 Metadata *getRawStride() const { return getOperand(3).get(); }
391
392 using BoundType = PointerUnion<DIVariable *, DIExpression *>;
393
394 BoundType getCount() const;
395 BoundType getLowerBound() const;
396 BoundType getUpperBound() const;
397 BoundType getStride() const;
398
399 static bool classof(const Metadata *MD) {
400 return MD->getMetadataID() == DIGenericSubrangeKind;
401 }
402};
403
404/// Enumeration value.
405///
406/// TODO: Add a pointer to the context (DW_TAG_enumeration_type) once that no
407/// longer creates a type cycle.
408class DIEnumerator : public DINode {
409 friend class LLVMContextImpl;
410 friend class MDNode;
411
412 APInt Value;
413 DIEnumerator(LLVMContext &C, StorageType Storage, const APInt &Value,
414 bool IsUnsigned, ArrayRef<Metadata *> Ops)
415 : DINode(C, DIEnumeratorKind, Storage, dwarf::DW_TAG_enumerator, Ops),
416 Value(Value) {
417 SubclassData32 = IsUnsigned;
418 }
419 DIEnumerator(LLVMContext &C, StorageType Storage, int64_t Value,
420 bool IsUnsigned, ArrayRef<Metadata *> Ops)
421 : DIEnumerator(C, Storage, APInt(64, Value, !IsUnsigned), IsUnsigned,
422 Ops) {}
423 ~DIEnumerator() = default;
424
425 static DIEnumerator *getImpl(LLVMContext &Context, const APInt &Value,
426 bool IsUnsigned, StringRef Name,
427 StorageType Storage, bool ShouldCreate = true) {
428 return getImpl(Context, Value, IsUnsigned,
429 getCanonicalMDString(Context, Name), Storage, ShouldCreate);
430 }
431 static DIEnumerator *getImpl(LLVMContext &Context, const APInt &Value,
432 bool IsUnsigned, MDString *Name,
433 StorageType Storage, bool ShouldCreate = true);
434
435 TempDIEnumerator cloneImpl() const {
436 return getTemporary(getContext(), getValue(), isUnsigned(), getName());
437 }
438
439public:
440 DEFINE_MDNODE_GET(DIEnumerator,
441 (int64_t Value, bool IsUnsigned, StringRef Name),
442 (APInt(64, Value, !IsUnsigned), IsUnsigned, Name))
443 DEFINE_MDNODE_GET(DIEnumerator,
444 (int64_t Value, bool IsUnsigned, MDString *Name),
445 (APInt(64, Value, !IsUnsigned), IsUnsigned, Name))
446 DEFINE_MDNODE_GET(DIEnumerator,
447 (APInt Value, bool IsUnsigned, StringRef Name),
448 (Value, IsUnsigned, Name))
449 DEFINE_MDNODE_GET(DIEnumerator,
450 (APInt Value, bool IsUnsigned, MDString *Name),
451 (Value, IsUnsigned, Name))
452
453 TempDIEnumerator clone() const { return cloneImpl(); }
454
455 const APInt &getValue() const { return Value; }
456 bool isUnsigned() const { return SubclassData32; }
457 StringRef getName() const { return getStringOperand(0); }
458
459 MDString *getRawName() const { return getOperandAs<MDString>(0); }
460
461 static bool classof(const Metadata *MD) {
462 return MD->getMetadataID() == DIEnumeratorKind;
463 }
464};
465
466/// Base class for scope-like contexts.
467///
468/// Base class for lexical scopes and types (which are also declaration
469/// contexts).
470///
471/// TODO: Separate the concepts of declaration contexts and lexical scopes.
472class DIScope : public DINode {
473protected:
474 DIScope(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
475 ArrayRef<Metadata *> Ops)
476 : DINode(C, ID, Storage, Tag, Ops) {}
477 ~DIScope() = default;
478
479public:
480 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
481
482 inline StringRef getFilename() const;
483 inline StringRef getDirectory() const;
484 inline Optional<StringRef> getSource() const;
485
486 StringRef getName() const;
487 DIScope *getScope() const;
488
489 /// Return the raw underlying file.
490 ///
491 /// A \a DIFile is a \a DIScope, but it doesn't point at a separate file (it
492 /// \em is the file). If \c this is an \a DIFile, we need to return \c this.
493 /// Otherwise, return the first operand, which is where all other subclasses
494 /// store their file pointer.
495 Metadata *getRawFile() const {
496 return isa<DIFile>(this) ? const_cast<DIScope *>(this)
497 : static_cast<Metadata *>(getOperand(0));
498 }
499
500 static bool classof(const Metadata *MD) {
501 switch (MD->getMetadataID()) {
502 default:
503 return false;
504 case DIBasicTypeKind:
505 case DIStringTypeKind:
506 case DIDerivedTypeKind:
507 case DICompositeTypeKind:
508 case DISubroutineTypeKind:
509 case DIFileKind:
510 case DICompileUnitKind:
511 case DISubprogramKind:
512 case DILexicalBlockKind:
513 case DILexicalBlockFileKind:
514 case DINamespaceKind:
515 case DICommonBlockKind:
516 case DIModuleKind:
517 return true;
518 }
519 }
520};
521
522/// File.
523///
524/// TODO: Merge with directory/file node (including users).
525/// TODO: Canonicalize paths on creation.
526class DIFile : public DIScope {
527 friend class LLVMContextImpl;
528 friend class MDNode;
529
530public:
531 /// Which algorithm (e.g. MD5) a checksum was generated with.
532 ///
533 /// The encoding is explicit because it is used directly in Bitcode. The
534 /// value 0 is reserved to indicate the absence of a checksum in Bitcode.
535 enum ChecksumKind {
536 // The first variant was originally CSK_None, encoded as 0. The new
537 // internal representation removes the need for this by wrapping the
538 // ChecksumInfo in an Optional, but to preserve Bitcode compatibility the 0
539 // encoding is reserved.
540 CSK_MD5 = 1,
541 CSK_SHA1 = 2,
542 CSK_SHA256 = 3,
543 CSK_Last = CSK_SHA256 // Should be last enumeration.
544 };
545
546 /// A single checksum, represented by a \a Kind and a \a Value (a string).
547 template <typename T>
548 struct ChecksumInfo {
549 /// The kind of checksum which \a Value encodes.
550 ChecksumKind Kind;
551 /// The string value of the checksum.
552 T Value;
553
554 ChecksumInfo(ChecksumKind Kind, T Value) : Kind(Kind), Value(Value) { }
555 ~ChecksumInfo() = default;
556 bool operator==(const ChecksumInfo<T> &X) const {
557 return Kind == X.Kind && Value == X.Value;
558 }
559 bool operator!=(const ChecksumInfo<T> &X) const { return !(*this == X); }
560 StringRef getKindAsString() const { return getChecksumKindAsString(Kind); }
561 };
562
563private:
564 Optional<ChecksumInfo<MDString *>> Checksum;
565 Optional<MDString *> Source;
566
567 DIFile(LLVMContext &C, StorageType Storage,
568 Optional<ChecksumInfo<MDString *>> CS, Optional<MDString *> Src,
569 ArrayRef<Metadata *> Ops)
570 : DIScope(C, DIFileKind, Storage, dwarf::DW_TAG_file_type, Ops),
571 Checksum(CS), Source(Src) {}
572 ~DIFile() = default;
573
574 static DIFile *getImpl(LLVMContext &Context, StringRef Filename,
575 StringRef Directory,
576 Optional<ChecksumInfo<StringRef>> CS,
577 Optional<StringRef> Source,
578 StorageType Storage, bool ShouldCreate = true) {
579 Optional<ChecksumInfo<MDString *>> MDChecksum;
580 if (CS)
581 MDChecksum.emplace(CS->Kind, getCanonicalMDString(Context, CS->Value));
582 return getImpl(Context, getCanonicalMDString(Context, Filename),
583 getCanonicalMDString(Context, Directory), MDChecksum,
584 Source ? Optional<MDString *>(getCanonicalMDString(Context, *Source)) : None,
585 Storage, ShouldCreate);
586 }
587 static DIFile *getImpl(LLVMContext &Context, MDString *Filename,
588 MDString *Directory,
589 Optional<ChecksumInfo<MDString *>> CS,
590 Optional<MDString *> Source, StorageType Storage,
591 bool ShouldCreate = true);
592
593 TempDIFile cloneImpl() const {
594 return getTemporary(getContext(), getFilename(), getDirectory(),
595 getChecksum(), getSource());
596 }
597
598public:
599 DEFINE_MDNODE_GET(DIFile, (StringRef Filename, StringRef Directory,
600 Optional<ChecksumInfo<StringRef>> CS = None,
601 Optional<StringRef> Source = None),
602 (Filename, Directory, CS, Source))
603 DEFINE_MDNODE_GET(DIFile, (MDString * Filename, MDString *Directory,
604 Optional<ChecksumInfo<MDString *>> CS = None,
605 Optional<MDString *> Source = None),
606 (Filename, Directory, CS, Source))
607
608 TempDIFile clone() const { return cloneImpl(); }
609
610 StringRef getFilename() const { return getStringOperand(0); }
611 StringRef getDirectory() const { return getStringOperand(1); }
612 Optional<ChecksumInfo<StringRef>> getChecksum() const {
613 Optional<ChecksumInfo<StringRef>> StringRefChecksum;
614 if (Checksum)
615 StringRefChecksum.emplace(Checksum->Kind, Checksum->Value->getString());
616 return StringRefChecksum;
617 }
618 Optional<StringRef> getSource() const {
619 return Source ? Optional<StringRef>((*Source)->getString()) : None;
620 }
621
622 MDString *getRawFilename() const { return getOperandAs<MDString>(0); }
623 MDString *getRawDirectory() const { return getOperandAs<MDString>(1); }
624 Optional<ChecksumInfo<MDString *>> getRawChecksum() const { return Checksum; }
625 Optional<MDString *> getRawSource() const { return Source; }
626
627 static StringRef getChecksumKindAsString(ChecksumKind CSKind);
628 static Optional<ChecksumKind> getChecksumKind(StringRef CSKindStr);
629
630 static bool classof(const Metadata *MD) {
631 return MD->getMetadataID() == DIFileKind;
632 }
633};
634
635StringRef DIScope::getFilename() const {
636 if (auto *F = getFile())
637 return F->getFilename();
638 return "";
639}
640
641StringRef DIScope::getDirectory() const {
642 if (auto *F = getFile())
643 return F->getDirectory();
644 return "";
645}
646
647Optional<StringRef> DIScope::getSource() const {
648 if (auto *F = getFile())
649 return F->getSource();
650 return None;
651}
652
653/// Base class for types.
654///
655/// TODO: Remove the hardcoded name and context, since many types don't use
656/// them.
657/// TODO: Split up flags.
658class DIType : public DIScope {
659 unsigned Line;
660 DIFlags Flags;
661 uint64_t SizeInBits;
662 uint64_t OffsetInBits;
663 uint32_t AlignInBits;
664
665protected:
666 DIType(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
667 unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits,
668 uint64_t OffsetInBits, DIFlags Flags, ArrayRef<Metadata *> Ops)
669 : DIScope(C, ID, Storage, Tag, Ops) {
670 init(Line, SizeInBits, AlignInBits, OffsetInBits, Flags);
671 }
672 ~DIType() = default;
673
674 void init(unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits,
675 uint64_t OffsetInBits, DIFlags Flags) {
676 this->Line = Line;
677 this->Flags = Flags;
678 this->SizeInBits = SizeInBits;
679 this->AlignInBits = AlignInBits;
680 this->OffsetInBits = OffsetInBits;
681 }
682
683 /// Change fields in place.
684 void mutate(unsigned Tag, unsigned Line, uint64_t SizeInBits,
685 uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags) {
686 assert(isDistinct() && "Only distinct nodes can mutate");
687 setTag(Tag);
688 init(Line, SizeInBits, AlignInBits, OffsetInBits, Flags);
689 }
690
691public:
692 TempDIType clone() const {
693 return TempDIType(cast<DIType>(MDNode::clone().release()));
694 }
695
696 unsigned getLine() const { return Line; }
697 uint64_t getSizeInBits() const { return SizeInBits; }
698 uint32_t getAlignInBits() const { return AlignInBits; }
699 uint32_t getAlignInBytes() const { return getAlignInBits() / CHAR_BIT; }
700 uint64_t getOffsetInBits() const { return OffsetInBits; }
701 DIFlags getFlags() const { return Flags; }
702
703 DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
704 StringRef getName() const { return getStringOperand(2); }
705
706
707 Metadata *getRawScope() const { return getOperand(1); }
708 MDString *getRawName() const { return getOperandAs<MDString>(2); }
709
710 /// Returns a new temporary DIType with updated Flags
711 TempDIType cloneWithFlags(DIFlags NewFlags) const {
712 auto NewTy = clone();
713 NewTy->Flags = NewFlags;
714 return NewTy;
715 }
716
717 bool isPrivate() const {
718 return (getFlags() & FlagAccessibility) == FlagPrivate;
719 }
720 bool isProtected() const {
721 return (getFlags() & FlagAccessibility) == FlagProtected;
722 }
723 bool isPublic() const {
724 return (getFlags() & FlagAccessibility) == FlagPublic;
725 }
726 bool isForwardDecl() const { return getFlags() & FlagFwdDecl; }
727 bool isAppleBlockExtension() const { return getFlags() & FlagAppleBlock; }
728 bool isVirtual() const { return getFlags() & FlagVirtual; }
729 bool isArtificial() const { return getFlags() & FlagArtificial; }
730 bool isObjectPointer() const { return getFlags() & FlagObjectPointer; }
731 bool isObjcClassComplete() const {
732 return getFlags() & FlagObjcClassComplete;
733 }
734 bool isVector() const { return getFlags() & FlagVector; }
735 bool isBitField() const { return getFlags() & FlagBitField; }
736 bool isStaticMember() const { return getFlags() & FlagStaticMember; }
737 bool isLValueReference() const { return getFlags() & FlagLValueReference; }
738 bool isRValueReference() const { return getFlags() & FlagRValueReference; }
739 bool isTypePassByValue() const { return getFlags() & FlagTypePassByValue; }
740 bool isTypePassByReference() const {
741 return getFlags() & FlagTypePassByReference;
742 }
743 bool isBigEndian() const { return getFlags() & FlagBigEndian; }
744 bool isLittleEndian() const { return getFlags() & FlagLittleEndian; }
745 bool getExportSymbols() const { return getFlags() & FlagExportSymbols; }
746
747 static bool classof(const Metadata *MD) {
748 switch (MD->getMetadataID()) {
749 default:
750 return false;
751 case DIBasicTypeKind:
752 case DIStringTypeKind:
753 case DIDerivedTypeKind:
754 case DICompositeTypeKind:
755 case DISubroutineTypeKind:
756 return true;
757 }
758 }
759};
760
761/// Basic type, like 'int' or 'float'.
762///
763/// TODO: Split out DW_TAG_unspecified_type.
764/// TODO: Drop unused accessors.
765class DIBasicType : public DIType {
766 friend class LLVMContextImpl;
767 friend class MDNode;
768
769 unsigned Encoding;
770
771 DIBasicType(LLVMContext &C, StorageType Storage, unsigned Tag,
772 uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding,
773 DIFlags Flags, ArrayRef<Metadata *> Ops)
774 : DIType(C, DIBasicTypeKind, Storage, Tag, 0, SizeInBits, AlignInBits, 0,
775 Flags, Ops),
776 Encoding(Encoding) {}
777 ~DIBasicType() = default;
778
779 static DIBasicType *getImpl(LLVMContext &Context, unsigned Tag,
780 StringRef Name, uint64_t SizeInBits,
781 uint32_t AlignInBits, unsigned Encoding,
782 DIFlags Flags, StorageType Storage,
783 bool ShouldCreate = true) {
784 return getImpl(Context, Tag, getCanonicalMDString(Context, Name),
785 SizeInBits, AlignInBits, Encoding, Flags, Storage,
786 ShouldCreate);
787 }
788 static DIBasicType *getImpl(LLVMContext &Context, unsigned Tag,
789 MDString *Name, uint64_t SizeInBits,
790 uint32_t AlignInBits, unsigned Encoding,
791 DIFlags Flags, StorageType Storage,
792 bool ShouldCreate = true);
793
794 TempDIBasicType cloneImpl() const {
795 return getTemporary(getContext(), getTag(), getName(), getSizeInBits(),
796 getAlignInBits(), getEncoding(), getFlags());
797 }
798
799public:
800 DEFINE_MDNODE_GET(DIBasicType, (unsigned Tag, StringRef Name),
801 (Tag, Name, 0, 0, 0, FlagZero))
802 DEFINE_MDNODE_GET(DIBasicType,
803 (unsigned Tag, StringRef Name, uint64_t SizeInBits),
804 (Tag, Name, SizeInBits, 0, 0, FlagZero))
805 DEFINE_MDNODE_GET(DIBasicType,
806 (unsigned Tag, MDString *Name, uint64_t SizeInBits),
807 (Tag, Name, SizeInBits, 0, 0, FlagZero))
808 DEFINE_MDNODE_GET(DIBasicType,
809 (unsigned Tag, StringRef Name, uint64_t SizeInBits,
810 uint32_t AlignInBits, unsigned Encoding, DIFlags Flags),
811 (Tag, Name, SizeInBits, AlignInBits, Encoding, Flags))
812 DEFINE_MDNODE_GET(DIBasicType,
813 (unsigned Tag, MDString *Name, uint64_t SizeInBits,
814 uint32_t AlignInBits, unsigned Encoding, DIFlags Flags),
815 (Tag, Name, SizeInBits, AlignInBits, Encoding, Flags))
816
817 TempDIBasicType clone() const { return cloneImpl(); }
818
819 unsigned getEncoding() const { return Encoding; }
820
821 enum class Signedness { Signed, Unsigned };
822
823 /// Return the signedness of this type, or None if this type is neither
824 /// signed nor unsigned.
825 Optional<Signedness> getSignedness() const;
826
827 static bool classof(const Metadata *MD) {
828 return MD->getMetadataID() == DIBasicTypeKind;
829 }
830};
831
832/// String type, Fortran CHARACTER(n)
833class DIStringType : public DIType {
834 friend class LLVMContextImpl;
835 friend class MDNode;
836
837 unsigned Encoding;
838
839 DIStringType(LLVMContext &C, StorageType Storage, unsigned Tag,
840 uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding,
841 ArrayRef<Metadata *> Ops)
842 : DIType(C, DIStringTypeKind, Storage, Tag, 0, SizeInBits, AlignInBits, 0,
843 FlagZero, Ops),
844 Encoding(Encoding) {}
845 ~DIStringType() = default;
846
847 static DIStringType *getImpl(LLVMContext &Context, unsigned Tag,
848 StringRef Name, Metadata *StringLength,
849 Metadata *StrLenExp, uint64_t SizeInBits,
850 uint32_t AlignInBits, unsigned Encoding,
851 StorageType Storage, bool ShouldCreate = true) {
852 return getImpl(Context, Tag, getCanonicalMDString(Context, Name),
853 StringLength, StrLenExp, SizeInBits, AlignInBits, Encoding,
854 Storage, ShouldCreate);
855 }
856 static DIStringType *getImpl(LLVMContext &Context, unsigned Tag,
857 MDString *Name, Metadata *StringLength,
858 Metadata *StrLenExp, uint64_t SizeInBits,
859 uint32_t AlignInBits, unsigned Encoding,
860 StorageType Storage, bool ShouldCreate = true);
861
862 TempDIStringType cloneImpl() const {
863 return getTemporary(getContext(), getTag(), getRawName(),
864 getRawStringLength(), getRawStringLengthExp(),
865 getSizeInBits(), getAlignInBits(), getEncoding());
866 }
867
868public:
869 DEFINE_MDNODE_GET(DIStringType,
870 (unsigned Tag, StringRef Name, uint64_t SizeInBits,
871 uint32_t AlignInBits),
872 (Tag, Name, nullptr, nullptr, SizeInBits, AlignInBits, 0))
873 DEFINE_MDNODE_GET(DIStringType,
874 (unsigned Tag, MDString *Name, Metadata *StringLength,
875 Metadata *StringLengthExp, uint64_t SizeInBits,
876 uint32_t AlignInBits, unsigned Encoding),
877 (Tag, Name, StringLength, StringLengthExp, SizeInBits,
878 AlignInBits, Encoding))
879 DEFINE_MDNODE_GET(DIStringType,
880 (unsigned Tag, StringRef Name, Metadata *StringLength,
881 Metadata *StringLengthExp, uint64_t SizeInBits,
882 uint32_t AlignInBits, unsigned Encoding),
883 (Tag, Name, StringLength, StringLengthExp, SizeInBits,
884 AlignInBits, Encoding))
885
886 TempDIStringType clone() const { return cloneImpl(); }
887
888 static bool classof(const Metadata *MD) {
889 return MD->getMetadataID() == DIStringTypeKind;
890 }
891
892 DIVariable *getStringLength() const {
893 return cast_or_null<DIVariable>(getRawStringLength());
894 }
895
896 DIExpression *getStringLengthExp() const {
897 return cast_or_null<DIExpression>(getRawStringLengthExp());
898 }
899
900 unsigned getEncoding() const { return Encoding; }
901
902 Metadata *getRawStringLength() const { return getOperand(3); }
903
904 Metadata *getRawStringLengthExp() const { return getOperand(4); }
905};
906
907/// Derived types.
908///
909/// This includes qualified types, pointers, references, friends, typedefs, and
910/// class members.
911///
912/// TODO: Split out members (inheritance, fields, methods, etc.).
913class DIDerivedType : public DIType {
914 friend class LLVMContextImpl;
915 friend class MDNode;
916
917 /// The DWARF address space of the memory pointed to or referenced by a
918 /// pointer or reference type respectively.
919 Optional<unsigned> DWARFAddressSpace;
920
921 DIDerivedType(LLVMContext &C, StorageType Storage, unsigned Tag,
922 unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits,
923 uint64_t OffsetInBits, Optional<unsigned> DWARFAddressSpace,
924 DIFlags Flags, ArrayRef<Metadata *> Ops)
925 : DIType(C, DIDerivedTypeKind, Storage, Tag, Line, SizeInBits,
926 AlignInBits, OffsetInBits, Flags, Ops),
927 DWARFAddressSpace(DWARFAddressSpace) {}
928 ~DIDerivedType() = default;
929
930 static DIDerivedType *
931 getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, DIFile *File,
932 unsigned Line, DIScope *Scope, DIType *BaseType, uint64_t SizeInBits,
933 uint32_t AlignInBits, uint64_t OffsetInBits,
934 Optional<unsigned> DWARFAddressSpace, DIFlags Flags,
935 Metadata *ExtraData, StorageType Storage, bool ShouldCreate = true) {
936 return getImpl(Context, Tag, getCanonicalMDString(Context, Name), File,
937 Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits,
938 DWARFAddressSpace, Flags, ExtraData, Storage, ShouldCreate);
939 }
940 static DIDerivedType *getImpl(LLVMContext &Context, unsigned Tag,
941 MDString *Name, Metadata *File, unsigned Line,
942 Metadata *Scope, Metadata *BaseType,
943 uint64_t SizeInBits, uint32_t AlignInBits,
944 uint64_t OffsetInBits,
945 Optional<unsigned> DWARFAddressSpace,
946 DIFlags Flags, Metadata *ExtraData,
947 StorageType Storage, bool ShouldCreate = true);
948
949 TempDIDerivedType cloneImpl() const {
950 return getTemporary(getContext(), getTag(), getName(), getFile(), getLine(),
951 getScope(), getBaseType(), getSizeInBits(),
952 getAlignInBits(), getOffsetInBits(),
953 getDWARFAddressSpace(), getFlags(), getExtraData());
954 }
955
956public:
957 DEFINE_MDNODE_GET(DIDerivedType,
958 (unsigned Tag, MDString *Name, Metadata *File,
959 unsigned Line, Metadata *Scope, Metadata *BaseType,
960 uint64_t SizeInBits, uint32_t AlignInBits,
961 uint64_t OffsetInBits,
962 Optional<unsigned> DWARFAddressSpace, DIFlags Flags,
963 Metadata *ExtraData = nullptr),
964 (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
965 AlignInBits, OffsetInBits, DWARFAddressSpace, Flags,
966 ExtraData))
967 DEFINE_MDNODE_GET(DIDerivedType,
968 (unsigned Tag, StringRef Name, DIFile *File, unsigned Line,
969 DIScope *Scope, DIType *BaseType, uint64_t SizeInBits,
970 uint32_t AlignInBits, uint64_t OffsetInBits,
971 Optional<unsigned> DWARFAddressSpace, DIFlags Flags,
972 Metadata *ExtraData = nullptr),
973 (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
974 AlignInBits, OffsetInBits, DWARFAddressSpace, Flags,
975 ExtraData))
976
977 TempDIDerivedType clone() const { return cloneImpl(); }
978
979 /// Get the base type this is derived from.
980 DIType *getBaseType() const { return cast_or_null<DIType>(getRawBaseType()); }
981 Metadata *getRawBaseType() const { return getOperand(3); }
982
983 /// \returns The DWARF address space of the memory pointed to or referenced by
984 /// a pointer or reference type respectively.
985 Optional<unsigned> getDWARFAddressSpace() const { return DWARFAddressSpace; }
986
987 /// Get extra data associated with this derived type.
988 ///
989 /// Class type for pointer-to-members, objective-c property node for ivars,
990 /// global constant wrapper for static members, or virtual base pointer offset
991 /// for inheritance.
992 ///
993 /// TODO: Separate out types that need this extra operand: pointer-to-member
994 /// types and member fields (static members and ivars).
995 Metadata *getExtraData() const { return getRawExtraData(); }
996 Metadata *getRawExtraData() const { return getOperand(4); }
997
998 /// Get casted version of extra data.
999 /// @{
1000 DIType *getClassType() const {
1001 assert(getTag() == dwarf::DW_TAG_ptr_to_member_type);
1002 return cast_or_null<DIType>(getExtraData());
1003 }
1004
1005 DIObjCProperty *getObjCProperty() const {
1006 return dyn_cast_or_null<DIObjCProperty>(getExtraData());
1007 }
1008
1009 uint32_t getVBPtrOffset() const {
1010 assert(getTag() == dwarf::DW_TAG_inheritance);
1011 if (auto *CM = cast_or_null<ConstantAsMetadata>(getExtraData()))
1012 if (auto *CI = dyn_cast_or_null<ConstantInt>(CM->getValue()))
1013 return static_cast<uint32_t>(CI->getZExtValue());
1014 return 0;
1015 }
1016
1017 Constant *getStorageOffsetInBits() const {
1018 assert(getTag() == dwarf::DW_TAG_member && isBitField());
1019 if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData()))
1020 return C->getValue();
1021 return nullptr;
1022 }
1023
1024 Constant *getConstant() const {
1025 assert(getTag() == dwarf::DW_TAG_member && isStaticMember());
1026 if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData()))
1027 return C->getValue();
1028 return nullptr;
1029 }
1030 Constant *getDiscriminantValue() const {
1031 assert(getTag() == dwarf::DW_TAG_member && !isStaticMember());
1032 if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData()))
1033 return C->getValue();
1034 return nullptr;
1035 }
1036 /// @}
1037
1038 static bool classof(const Metadata *MD) {
1039 return MD->getMetadataID() == DIDerivedTypeKind;
1040 }
1041};
1042
1043/// Composite types.
1044///
1045/// TODO: Detach from DerivedTypeBase (split out MDEnumType?).
1046/// TODO: Create a custom, unrelated node for DW_TAG_array_type.
1047class DICompositeType : public DIType {
1048 friend class LLVMContextImpl;
1049 friend class MDNode;
1050
1051 unsigned RuntimeLang;
1052
1053 DICompositeType(LLVMContext &C, StorageType Storage, unsigned Tag,
1054 unsigned Line, unsigned RuntimeLang, uint64_t SizeInBits,
1055 uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags,
1056 ArrayRef<Metadata *> Ops)
1057 : DIType(C, DICompositeTypeKind, Storage, Tag, Line, SizeInBits,
1058 AlignInBits, OffsetInBits, Flags, Ops),
1059 RuntimeLang(RuntimeLang) {}
1060 ~DICompositeType() = default;
1061
1062 /// Change fields in place.
1063 void mutate(unsigned Tag, unsigned Line, unsigned RuntimeLang,
1064 uint64_t SizeInBits, uint32_t AlignInBits,
1065 uint64_t OffsetInBits, DIFlags Flags) {
1066 assert(isDistinct() && "Only distinct nodes can mutate");
1067 assert(getRawIdentifier() && "Only ODR-uniqued nodes should mutate");
1068 this->RuntimeLang = RuntimeLang;
1069 DIType::mutate(Tag, Line, SizeInBits, AlignInBits, OffsetInBits, Flags);
1070 }
1071
1072 static DICompositeType *
1073 getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, Metadata *File,
1074 unsigned Line, DIScope *Scope, DIType *BaseType, uint64_t SizeInBits,
1075 uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags,
1076 DINodeArray Elements, unsigned RuntimeLang, DIType *VTableHolder,
1077 DITemplateParameterArray TemplateParams, StringRef Identifier,
1078 DIDerivedType *Discriminator, Metadata *DataLocation,
1079 Metadata *Associated, Metadata *Allocated, Metadata *Rank,
1080 StorageType Storage, bool ShouldCreate = true) {
1081 return getImpl(
1082 Context, Tag, getCanonicalMDString(Context, Name), File, Line, Scope,
1083 BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements.get(),
1084 RuntimeLang, VTableHolder, TemplateParams.get(),
1085 getCanonicalMDString(Context, Identifier), Discriminator, DataLocation,
1086 Associated, Allocated, Rank, Storage, ShouldCreate);
1087 }
1088 static DICompositeType *
1089 getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
1090 unsigned Line, Metadata *Scope, Metadata *BaseType,
1091 uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
1092 DIFlags Flags, Metadata *Elements, unsigned RuntimeLang,
1093 Metadata *VTableHolder, Metadata *TemplateParams,
1094 MDString *Identifier, Metadata *Discriminator, Metadata *DataLocation,
1095 Metadata *Associated, Metadata *Allocated, Metadata *Rank,
1096 StorageType Storage, bool ShouldCreate = true);
1097
1098 TempDICompositeType cloneImpl() const {
1099 return getTemporary(getContext(), getTag(), getName(), getFile(), getLine(),
1100 getScope(), getBaseType(), getSizeInBits(),
1101 getAlignInBits(), getOffsetInBits(), getFlags(),
1102 getElements(), getRuntimeLang(), getVTableHolder(),
1103 getTemplateParams(), getIdentifier(),
1104 getDiscriminator(), getRawDataLocation(),
1105 getRawAssociated(), getRawAllocated(), getRawRank());
1106 }
1107
1108public:
1109 DEFINE_MDNODE_GET(
1110 DICompositeType,
1111 (unsigned Tag, StringRef Name, DIFile *File, unsigned Line,
1112 DIScope *Scope, DIType *BaseType, uint64_t SizeInBits,
1113 uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags,
1114 DINodeArray Elements, unsigned RuntimeLang, DIType *VTableHolder,
1115 DITemplateParameterArray TemplateParams = nullptr,
1116 StringRef Identifier = "", DIDerivedType *Discriminator = nullptr,
1117 Metadata *DataLocation = nullptr, Metadata *Associated = nullptr,
1118 Metadata *Allocated = nullptr, Metadata *Rank = nullptr),
1119 (Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
1120 OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams,
1121 Identifier, Discriminator, DataLocation, Associated, Allocated, Rank))
1122 DEFINE_MDNODE_GET(
1123 DICompositeType,
1124 (unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
1125 Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits,
1126 uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags,
1127 Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder,
1128 Metadata *TemplateParams = nullptr, MDString *Identifier = nullptr,
1129 Metadata *Discriminator = nullptr, Metadata *DataLocation = nullptr,
1130 Metadata *Associated = nullptr, Metadata *Allocated = nullptr,
1131 Metadata *Rank = nullptr),
1132 (Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
1133 OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams,
1134 Identifier, Discriminator, DataLocation, Associated, Allocated, Rank))
1135
1136 TempDICompositeType clone() const { return cloneImpl(); }
1137
1138 /// Get a DICompositeType with the given ODR identifier.
1139 ///
1140 /// If \a LLVMContext::isODRUniquingDebugTypes(), gets the mapped
1141 /// DICompositeType for the given ODR \c Identifier. If none exists, creates
1142 /// a new node.
1143 ///
1144 /// Else, returns \c nullptr.
1145 static DICompositeType *
1146 getODRType(LLVMContext &Context, MDString &Identifier, unsigned Tag,
1147 MDString *Name, Metadata *File, unsigned Line, Metadata *Scope,
1148 Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits,
1149 uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements,
1150 unsigned RuntimeLang, Metadata *VTableHolder,
1151 Metadata *TemplateParams, Metadata *Discriminator,
1152 Metadata *DataLocation, Metadata *Associated, Metadata *Allocated,
1153 Metadata *Rank);
1154 static DICompositeType *getODRTypeIfExists(LLVMContext &Context,
1155 MDString &Identifier);
1156
1157 /// Build a DICompositeType with the given ODR identifier.
1158 ///
1159 /// Looks up the mapped DICompositeType for the given ODR \c Identifier. If
1160 /// it doesn't exist, creates a new one. If it does exist and \a
1161 /// isForwardDecl(), and the new arguments would be a definition, mutates the
1162 /// the type in place. In either case, returns the type.
1163 ///
1164 /// If not \a LLVMContext::isODRUniquingDebugTypes(), this function returns
1165 /// nullptr.
1166 static DICompositeType *
1167 buildODRType(LLVMContext &Context, MDString &Identifier, unsigned Tag,
1168 MDString *Name, Metadata *File, unsigned Line, Metadata *Scope,
1169 Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits,
1170 uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements,
1171 unsigned RuntimeLang, Metadata *VTableHolder,
1172 Metadata *TemplateParams, Metadata *Discriminator,
1173 Metadata *DataLocation, Metadata *Associated,
1174 Metadata *Allocated, Metadata *Rank);
1175
1176 DIType *getBaseType() const { return cast_or_null<DIType>(getRawBaseType()); }
1177 DINodeArray getElements() const {
1178 return cast_or_null<MDTuple>(getRawElements());
1179 }
1180 DIType *getVTableHolder() const {
1181 return cast_or_null<DIType>(getRawVTableHolder());
1182 }
1183 DITemplateParameterArray getTemplateParams() const {
1184 return cast_or_null<MDTuple>(getRawTemplateParams());
1185 }
1186 StringRef getIdentifier() const { return getStringOperand(7); }
1187 unsigned getRuntimeLang() const { return RuntimeLang; }
1188
1189 Metadata *getRawBaseType() const { return getOperand(3); }
1190 Metadata *getRawElements() const { return getOperand(4); }
1191 Metadata *getRawVTableHolder() const { return getOperand(5); }
1192 Metadata *getRawTemplateParams() const { return getOperand(6); }
1193 MDString *getRawIdentifier() const { return getOperandAs<MDString>(7); }
1194 Metadata *getRawDiscriminator() const { return getOperand(8); }
1195 DIDerivedType *getDiscriminator() const { return getOperandAs<DIDerivedType>(8); }
1196 Metadata *getRawDataLocation() const { return getOperand(9); }
1197 DIVariable *getDataLocation() const {
1198 return dyn_cast_or_null<DIVariable>(getRawDataLocation());
1199 }
1200 DIExpression *getDataLocationExp() const {
1201 return dyn_cast_or_null<DIExpression>(getRawDataLocation());
1202 }
1203 Metadata *getRawAssociated() const { return getOperand(10); }
1204 DIVariable *getAssociated() const {
1205 return dyn_cast_or_null<DIVariable>(getRawAssociated());
1206 }
1207 DIExpression *getAssociatedExp() const {
1208 return dyn_cast_or_null<DIExpression>(getRawAssociated());
1209 }
1210 Metadata *getRawAllocated() const { return getOperand(11); }
1211 DIVariable *getAllocated() const {
1212 return dyn_cast_or_null<DIVariable>(getRawAllocated());
1213 }
1214 DIExpression *getAllocatedExp() const {
1215 return dyn_cast_or_null<DIExpression>(getRawAllocated());
1216 }
1217 Metadata *getRawRank() const { return getOperand(12); }
1218 ConstantInt *getRankConst() const {
1219 if (auto *MD = dyn_cast_or_null<ConstantAsMetadata>(getRawRank()))
1220 return dyn_cast_or_null<ConstantInt>(MD->getValue());
1221 return nullptr;
1222 }
1223 DIExpression *getRankExp() const {
1224 return dyn_cast_or_null<DIExpression>(getRawRank());
1225 }
1226
1227 /// Replace operands.
1228 ///
1229 /// If this \a isUniqued() and not \a isResolved(), on a uniquing collision
1230 /// this will be RAUW'ed and deleted. Use a \a TrackingMDRef to keep track
1231 /// of its movement if necessary.
1232 /// @{
1233 void replaceElements(DINodeArray Elements) {
1234#ifndef NDEBUG
1235 for (DINode *Op : getElements())
1236 assert(is_contained(Elements->operands(), Op) &&
1237 "Lost a member during member list replacement");
1238#endif
1239 replaceOperandWith(4, Elements.get());
1240 }
1241
1242 void replaceVTableHolder(DIType *VTableHolder) {
1243 replaceOperandWith(5, VTableHolder);
1244 }
1245
1246 void replaceTemplateParams(DITemplateParameterArray TemplateParams) {
1247 replaceOperandWith(6, TemplateParams.get());
1248 }
1249 /// @}
1250
1251 static bool classof(const Metadata *MD) {
1252 return MD->getMetadataID() == DICompositeTypeKind;
1253 }
1254};
1255
1256/// Type array for a subprogram.
1257///
1258/// TODO: Fold the array of types in directly as operands.
1259class DISubroutineType : public DIType {
1260 friend class LLVMContextImpl;
1261 friend class MDNode;
1262
1263 /// The calling convention used with DW_AT_calling_convention. Actually of
1264 /// type dwarf::CallingConvention.
1265 uint8_t CC;
1266
1267 DISubroutineType(LLVMContext &C, StorageType Storage, DIFlags Flags,
1268 uint8_t CC, ArrayRef<Metadata *> Ops)
1269 : DIType(C, DISubroutineTypeKind, Storage, dwarf::DW_TAG_subroutine_type,
1270 0, 0, 0, 0, Flags, Ops),
1271 CC(CC) {}
1272 ~DISubroutineType() = default;
1273
1274 static DISubroutineType *getImpl(LLVMContext &Context, DIFlags Flags,
1275 uint8_t CC, DITypeRefArray TypeArray,
1276 StorageType Storage,
1277 bool ShouldCreate = true) {
1278 return getImpl(Context, Flags, CC, TypeArray.get(), Storage, ShouldCreate);
1279 }
1280 static DISubroutineType *getImpl(LLVMContext &Context, DIFlags Flags,
1281 uint8_t CC, Metadata *TypeArray,
1282 StorageType Storage,
1283 bool ShouldCreate = true);
1284
1285 TempDISubroutineType cloneImpl() const {
1286 return getTemporary(getContext(), getFlags(), getCC(), getTypeArray());
1287 }
1288
1289public:
1290 DEFINE_MDNODE_GET(DISubroutineType,
1291 (DIFlags Flags, uint8_t CC, DITypeRefArray TypeArray),
1292 (Flags, CC, TypeArray))
1293 DEFINE_MDNODE_GET(DISubroutineType,
1294 (DIFlags Flags, uint8_t CC, Metadata *TypeArray),
1295 (Flags, CC, TypeArray))
1296
1297 TempDISubroutineType clone() const { return cloneImpl(); }
1298
1299 uint8_t getCC() const { return CC; }
1300
1301 DITypeRefArray getTypeArray() const {
1302 return cast_or_null<MDTuple>(getRawTypeArray());
1303 }
1304
1305 Metadata *getRawTypeArray() const { return getOperand(3); }
1306
1307 static bool classof(const Metadata *MD) {
1308 return MD->getMetadataID() == DISubroutineTypeKind;
1309 }
1310};
1311
1312/// Compile unit.
1313class DICompileUnit : public DIScope {
1314 friend class LLVMContextImpl;
1315 friend class MDNode;
1316
1317public:
1318 enum DebugEmissionKind : unsigned {
1319 NoDebug = 0,
1320 FullDebug,
1321 LineTablesOnly,
1322 DebugDirectivesOnly,
1323 LastEmissionKind = DebugDirectivesOnly
1324 };
1325
1326 enum class DebugNameTableKind : unsigned {
1327 Default = 0,
1328