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