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

source code of llvm/include/llvm/IR/DebugInfoMetadata.h