LLVM 19.0.0git
DebugInfoMetadata.h
Go to the documentation of this file.
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"
19#include "llvm/ADT/STLExtras.h"
21#include "llvm/ADT/StringRef.h"
23#include "llvm/IR/Constants.h"
24#include "llvm/IR/Metadata.h"
25#include "llvm/IR/PseudoProbe.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 DbgVariableRecord;
69
70extern cl::opt<bool> EnableFSDiscriminator;
71
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>(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>(*I); }
106
108 ++I;
109 return *this;
110 }
111
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);
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
158 if (S.empty())
159 return nullptr;
160 return MDString::get(Context, 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.
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
240 unsigned Tag, ArrayRef<Metadata *> Ops1,
242 : DINode(C, GenericDINodeKind, Storage, Tag, Ops1, Ops2) {
243 setHash(Hash);
244 }
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, getCanonicalMDString(Context, 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 {
263 SmallVector<Metadata *, 4>(dwarf_operands()));
264 }
265
266public:
267 unsigned getHash() const { return SubclassData32; }
268
270 (unsigned Tag, StringRef Header,
272 (Tag, Header, DwarfOps))
274 (unsigned Tag, MDString *Header,
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(0); }
283 MDString *getRawHeader() const { return getOperandAs<MDString>(0); }
284
285 op_iterator dwarf_op_begin() const { return op_begin() + 1; }
286 op_iterator dwarf_op_end() const { return op_end(); }
289 }
290
291 unsigned getNumDwarfOperands() const { return getNumOperands() - 1; }
292 const MDOperand &getDwarfOperand(unsigned I) const {
293 return getOperand(I + 1);
294 }
295 void replaceDwarfOperandWith(unsigned I, Metadata *New) {
296 replaceOperandWith(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
313 : MDNode(C, DIAssignIDKind, Storage, std::nullopt) {}
314
316
317 static DIAssignID *getImpl(LLVMContext &Context, StorageType Storage,
318 bool ShouldCreate = true);
319
320 TempDIAssignID cloneImpl() const { return getTemporary(getContext()); }
321
322public:
323 // This node has no operands to replace.
324 void replaceOperandWith(unsigned I, Metadata *New) = delete;
325
327 return Context.getReplaceableUses()->getAllDbgVariableRecordUsers();
328 }
329
331 return getImpl(Context, Distinct);
332 }
333 static TempDIAssignID getTemporary(LLVMContext &Context) {
334 return TempDIAssignID(getImpl(Context, 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
352
353 ~DISubrange() = default;
354
355 static DISubrange *getImpl(LLVMContext &Context, int64_t Count,
357 bool ShouldCreate = true);
358
359 static DISubrange *getImpl(LLVMContext &Context, Metadata *CountNode,
361 bool ShouldCreate = true);
362
363 static DISubrange *getImpl(LLVMContext &Context, Metadata *CountNode,
364 Metadata *LowerBound, Metadata *UpperBound,
366 bool ShouldCreate = true);
367
368 TempDISubrange cloneImpl() const {
369 return getTemporary(getContext(), getRawCountNode(), getRawLowerBound(),
370 getRawUpperBound(), getRawStride());
371 }
372
373public:
374 DEFINE_MDNODE_GET(DISubrange, (int64_t Count, int64_t LowerBound = 0),
375 (Count, LowerBound))
376
379
382 Metadata *UpperBound, Metadata *Stride),
383 (CountNode, LowerBound, UpperBound, Stride))
384
385 TempDISubrange clone() const { return cloneImpl(); }
386
387 Metadata *getRawCountNode() const { return getOperand(0).get(); }
388
389 Metadata *getRawLowerBound() const { return getOperand(1).get(); }
390
391 Metadata *getRawUpperBound() const { return getOperand(2).get(); }
392
393 Metadata *getRawStride() const { return getOperand(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
416
417 ~DIGenericSubrange() = default;
418
419 static DIGenericSubrange *getImpl(LLVMContext &Context, Metadata *CountNode,
420 Metadata *LowerBound, Metadata *UpperBound,
422 bool ShouldCreate = true);
423
424 TempDIGenericSubrange cloneImpl() const {
427 }
428
429public:
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(0).get(); }
438 Metadata *getRawLowerBound() const { return getOperand(1).get(); }
439 Metadata *getRawUpperBound() const { return getOperand(2).get(); }
440 Metadata *getRawStride() const { return getOperand(3).get(); }
441
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;
468 Ops) {}
469 ~DIEnumerator() = default;
470
471 static DIEnumerator *getImpl(LLVMContext &Context, const APInt &Value,
473 StorageType Storage, bool ShouldCreate = true) {
474 return getImpl(Context, Value, IsUnsigned,
475 getCanonicalMDString(Context, 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 {
483 }
484
485public:
487 (int64_t Value, bool IsUnsigned, StringRef Name),
490 (int64_t Value, bool IsUnsigned, MDString *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(0); }
504
505 MDString *getRawName() const { return getOperandAs<MDString>(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:
522 : DINode(C, ID, Storage, Tag, Ops) {}
523 ~DIScope() = default;
524
525public:
526 DIFile *getFile() const { return cast_or_null<DIFile>(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.
542 return isa<DIFile>(this) ? const_cast<DIScope *>(this)
543 : static_cast<Metadata *>(getOperand(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.
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.
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.
596 /// The string value of the checksum.
598
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(Kind); }
606 };
607
608private:
609 std::optional<ChecksumInfo<MDString *>> Checksum;
610 /// An optional source. A nullptr means none.
611 MDString *Source;
612
614 std::optional<ChecksumInfo<MDString *>> CS, MDString *Src,
616 ~DIFile() = default;
617
618 static DIFile *getImpl(LLVMContext &Context, StringRef Filename,
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(CS->Kind, getCanonicalMDString(Context, CS->Value));
626 return getImpl(Context, getCanonicalMDString(Context, Filename),
627 getCanonicalMDString(Context, Directory), MDChecksum,
628 Source ? MDString::get(Context, *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 {
639 getChecksum(), getSource());
640 }
641
642public:
645 std::optional<ChecksumInfo<StringRef>> CS = std::nullopt,
646 std::optional<StringRef> Source = std::nullopt),
647 (Filename, Directory, CS, Source))
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(0); }
657 StringRef getDirectory() const { return getStringOperand(1); }
658 std::optional<ChecksumInfo<StringRef>> getChecksum() const {
659 std::optional<ChecksumInfo<StringRef>> StringRefChecksum;
660 if (Checksum)
661 StringRefChecksum.emplace(Checksum->Kind, 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>(0); }
670 MDString *getRawDirectory() const { return getOperandAs<MDString>(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
685 if (auto *F = getFile())
686 return F->getFilename();
687 return "";
688}
689
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>(MDNode::clone().release()));
744 }
745
746 unsigned getLine() const { return Line; }
747 uint64_t getSizeInBits() const { return SizeInBits; }
748 uint32_t getAlignInBits() const;
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>(getRawScope()); }
754 StringRef getName() const { return getStringOperand(2); }
755
756 Metadata *getRawScope() const { return getOperand(1); }
757 MDString *getRawName() const { return getOperandAs<MDString>(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; }
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
821 uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding,
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,
830 uint32_t AlignInBits, unsigned Encoding,
832 bool ShouldCreate = true) {
833 return getImpl(Context, Tag, getCanonicalMDString(Context, 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,
841 bool ShouldCreate = true);
842
843 TempDIBasicType cloneImpl() const {
846 }
847
848public:
850 (Tag, Name, 0, 0, 0, FlagZero))
853 (Tag, Name, SizeInBits, 0, 0, FlagZero))
855 (unsigned Tag, MDString *Name, uint64_t SizeInBits),
856 (Tag, Name, SizeInBits, 0, 0, FlagZero))
859 uint32_t AlignInBits, unsigned Encoding, DIFlags Flags),
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
889 uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding,
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,
898 Metadata *StrLenExp, Metadata *StrLocationExp,
900 unsigned Encoding, StorageType Storage,
901 bool ShouldCreate = true) {
902 return getImpl(Context, Tag, getCanonicalMDString(Context, 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,
910 unsigned Encoding, StorageType Storage,
911 bool ShouldCreate = true);
912
913 TempDIStringType cloneImpl() const {
918 }
919
920public:
924 (Tag, Name, nullptr, nullptr, nullptr, SizeInBits,
925 AlignInBits, 0))
930 unsigned Encoding),
937 unsigned Encoding),
940
941 TempDIStringType clone() const { return cloneImpl(); }
942
943 static bool classof(const Metadata *MD) {
944 return MD->getMetadataID() == DIStringTypeKind;
945 }
946
948 return cast_or_null<DIVariable>(getRawStringLength());
949 }
950
952 return cast_or_null<DIExpression>(getRawStringLengthExp());
953 }
954
956 return cast_or_null<DIExpression>(getRawStringLocationExp());
957 }
958
959 unsigned getEncoding() const { return Encoding; }
960
961 Metadata *getRawStringLength() const { return getOperand(3); }
962
964
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 {
975public:
976 /// Pointer authentication (__ptrauth) metadata.
977 struct PtrAuthData {
978 // RawData layout:
979 // - Bits 0..3: Key
980 // - Bit 4: IsAddressDiscriminated
981 // - Bits 5..20: ExtraDiscriminator
982 // - Bit 21: IsaPointer
983 // - Bit 22: AuthenticatesNullValues
984 unsigned RawData;
985
986 PtrAuthData(unsigned FromRawData) : RawData(FromRawData) {}
987 PtrAuthData(unsigned Key, bool IsDiscr, unsigned Discriminator,
988 bool IsaPointer, bool AuthenticatesNullValues) {
989 assert(Key < 16);
990 assert(Discriminator <= 0xffff);
991 RawData = (Key << 0) | (IsDiscr ? (1 << 4) : 0) | (Discriminator << 5) |
992 (IsaPointer ? (1 << 21) : 0) |
993 (AuthenticatesNullValues ? (1 << 22) : 0);
994 }
995
996 unsigned key() { return (RawData >> 0) & 0b1111; }
997 bool isAddressDiscriminated() { return (RawData >> 4) & 1; }
998 unsigned extraDiscriminator() { return (RawData >> 5) & 0xffff; }
999 bool isaPointer() { return (RawData >> 21) & 1; }
1000 bool authenticatesNullValues() { return (RawData >> 22) & 1; }
1001 };
1002
1003private:
1004 friend class LLVMContextImpl;
1005 friend class MDNode;
1006
1007 /// The DWARF address space of the memory pointed to or referenced by a
1008 /// pointer or reference type respectively.
1009 std::optional<unsigned> DWARFAddressSpace;
1010
1014 std::optional<unsigned> DWARFAddressSpace,
1015 std::optional<PtrAuthData> PtrAuthData, DIFlags Flags,
1017 : DIType(C, DIDerivedTypeKind, Storage, Tag, Line, SizeInBits,
1019 DWARFAddressSpace(DWARFAddressSpace) {
1020 if (PtrAuthData)
1022 }
1023 ~DIDerivedType() = default;
1024 static DIDerivedType *
1025 getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, DIFile *File,
1028 std::optional<unsigned> DWARFAddressSpace,
1029 std::optional<PtrAuthData> PtrAuthData, DIFlags Flags,
1031 bool ShouldCreate = true) {
1032 return getImpl(Context, Tag, getCanonicalMDString(Context, Name), File,
1034 DWARFAddressSpace, PtrAuthData, Flags, ExtraData,
1035 Annotations.get(), Storage, ShouldCreate);
1036 }
1037 static DIDerivedType *
1038 getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
1039 unsigned Line, Metadata *Scope, Metadata *BaseType,
1041 std::optional<unsigned> DWARFAddressSpace,
1042 std::optional<PtrAuthData> PtrAuthData, DIFlags Flags,
1044 bool ShouldCreate = true);
1045
1046 TempDIDerivedType cloneImpl() const {
1047 return getTemporary(getContext(), getTag(), getName(), getFile(), getLine(),
1050 getDWARFAddressSpace(), getPtrAuthData(), getFlags(),
1052 }
1053
1054public:
1056 (unsigned Tag, MDString *Name, Metadata *File,
1057 unsigned Line, Metadata *Scope, Metadata *BaseType,
1060 std::optional<unsigned> DWARFAddressSpace,
1061 std::optional<PtrAuthData> PtrAuthData, DIFlags Flags,
1062 Metadata *ExtraData = nullptr,
1063 Metadata *Annotations = nullptr),
1065 AlignInBits, OffsetInBits, DWARFAddressSpace, PtrAuthData,
1068 (unsigned Tag, StringRef Name, DIFile *File, unsigned Line,
1071 std::optional<unsigned> DWARFAddressSpace,
1072 std::optional<PtrAuthData> PtrAuthData, DIFlags Flags,
1074 DINodeArray Annotations = nullptr),
1076 AlignInBits, OffsetInBits, DWARFAddressSpace, PtrAuthData,
1078
1079 TempDIDerivedType clone() const { return cloneImpl(); }
1080
1081 /// Get the base type this is derived from.
1082 DIType *getBaseType() const { return cast_or_null<DIType>(getRawBaseType()); }
1083 Metadata *getRawBaseType() const { return getOperand(3); }
1084
1085 /// \returns The DWARF address space of the memory pointed to or referenced by
1086 /// a pointer or reference type respectively.
1087 std::optional<unsigned> getDWARFAddressSpace() const {
1088 return DWARFAddressSpace;
1089 }
1090
1091 std::optional<PtrAuthData> getPtrAuthData() const;
1092
1093 /// Get extra data associated with this derived type.
1094 ///
1095 /// Class type for pointer-to-members, objective-c property node for ivars,
1096 /// global constant wrapper for static members, or virtual base pointer offset
1097 /// for inheritance.
1098 ///
1099 /// TODO: Separate out types that need this extra operand: pointer-to-member
1100 /// types and member fields (static members and ivars).
1102 Metadata *getRawExtraData() const { return getOperand(4); }
1103
1104 /// Get annotations associated with this derived type.
1105 DINodeArray getAnnotations() const {
1106 return cast_or_null<MDTuple>(getRawAnnotations());
1107 }
1108 Metadata *getRawAnnotations() const { return getOperand(5); }
1109
1110 /// Get casted version of extra data.
1111 /// @{
1112 DIType *getClassType() const;
1113
1115 return dyn_cast_or_null<DIObjCProperty>(getExtraData());
1116 }
1117
1118 uint32_t getVBPtrOffset() const;
1119
1121
1122 Constant *getConstant() const;
1123
1125 /// @}
1126
1127 static bool classof(const Metadata *MD) {
1128 return MD->getMetadataID() == DIDerivedTypeKind;
1129 }
1130};
1131
1134 return Lhs.RawData == Rhs.RawData;
1135}
1136
1139 return !(Lhs == Rhs);
1140}
1141
1142/// Composite types.
1143///
1144/// TODO: Detach from DerivedTypeBase (split out MDEnumType?).
1145/// TODO: Create a custom, unrelated node for DW_TAG_array_type.
1146class DICompositeType : public DIType {
1147 friend class LLVMContextImpl;
1148 friend class MDNode;
1149
1150 unsigned RuntimeLang;
1151
1153 unsigned Line, unsigned RuntimeLang, uint64_t SizeInBits,
1156 : DIType(C, DICompositeTypeKind, Storage, Tag, Line, SizeInBits,
1158 RuntimeLang(RuntimeLang) {}
1159 ~DICompositeType() = default;
1160
1161 /// Change fields in place.
1162 void mutate(unsigned Tag, unsigned Line, unsigned RuntimeLang,
1164 DIFlags Flags) {
1165 assert(isDistinct() && "Only distinct nodes can mutate");
1166 assert(getRawIdentifier() && "Only ODR-uniqued nodes should mutate");
1167 this->RuntimeLang = RuntimeLang;
1169 }
1170
1171 static DICompositeType *
1172 getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, Metadata *File,
1173 unsigned Line, DIScope *Scope, DIType *BaseType, uint64_t SizeInBits,
1175 DINodeArray Elements, unsigned RuntimeLang, DIType *VTableHolder,
1176 DITemplateParameterArray TemplateParams, StringRef Identifier,
1177 DIDerivedType *Discriminator, Metadata *DataLocation,
1179 DINodeArray Annotations, StorageType Storage,
1180 bool ShouldCreate = true) {
1181 return getImpl(
1182 Context, Tag, getCanonicalMDString(Context, Name), File, Line, Scope,
1184 RuntimeLang, VTableHolder, TemplateParams.get(),
1186 Associated, Allocated, Rank, Annotations.get(), Storage, ShouldCreate);
1187 }
1188 static DICompositeType *
1189 getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
1190 unsigned Line, Metadata *Scope, Metadata *BaseType,
1192 DIFlags Flags, Metadata *Elements, unsigned RuntimeLang,
1196 Metadata *Annotations, StorageType Storage, bool ShouldCreate = true);
1197
1198 TempDICompositeType cloneImpl() const {
1199 return getTemporary(
1206 }
1207
1208public:
1211 (unsigned Tag, StringRef Name, DIFile *File, unsigned Line,
1214 DINodeArray Elements, unsigned RuntimeLang, DIType *VTableHolder,
1215 DITemplateParameterArray TemplateParams = nullptr,
1217 Metadata *DataLocation = nullptr, Metadata *Associated = nullptr,
1218 Metadata *Allocated = nullptr, Metadata *Rank = nullptr,
1219 DINodeArray Annotations = nullptr),
1223 Annotations))
1226 (unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
1229 Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder,
1232 Metadata *Associated = nullptr, Metadata *Allocated = nullptr,
1233 Metadata *Rank = nullptr, Metadata *Annotations = nullptr),
1237 Annotations))
1238
1239 TempDICompositeType clone() const { return cloneImpl(); }
1240
1241 /// Get a DICompositeType with the given ODR identifier.
1242 ///
1243 /// If \a LLVMContext::isODRUniquingDebugTypes(), gets the mapped
1244 /// DICompositeType for the given ODR \c Identifier. If none exists, creates
1245 /// a new node.
1246 ///
1247 /// Else, returns \c nullptr.
1248 static DICompositeType *
1249 getODRType(LLVMContext &Context, MDString &Identifier, unsigned Tag,
1250 MDString *Name, Metadata *File, unsigned Line, Metadata *Scope,
1253 unsigned RuntimeLang, Metadata *VTableHolder,
1259
1260 /// Build a DICompositeType with the given ODR identifier.
1261 ///
1262 /// Looks up the mapped DICompositeType for the given ODR \c Identifier. If
1263 /// it doesn't exist, creates a new one. If it does exist and \a
1264 /// isForwardDecl(), and the new arguments would be a definition, mutates the
1265 /// the type in place. In either case, returns the type.
1266 ///
1267 /// If not \a LLVMContext::isODRUniquingDebugTypes(), this function returns
1268 /// nullptr.
1269 static DICompositeType *
1270 buildODRType(LLVMContext &Context, MDString &Identifier, unsigned Tag,
1271 MDString *Name, Metadata *File, unsigned Line, Metadata *Scope,
1274 unsigned RuntimeLang, Metadata *VTableHolder,
1278
1279 DIType *getBaseType() const { return cast_or_null<DIType>(getRawBaseType()); }
1280 DINodeArray getElements() const {
1281 return cast_or_null<MDTuple>(getRawElements());
1282 }
1284 return cast_or_null<DIType>(getRawVTableHolder());
1285 }
1286 DITemplateParameterArray getTemplateParams() const {
1287 return cast_or_null<MDTuple>(getRawTemplateParams());
1288 }
1290 unsigned getRuntimeLang() const { return RuntimeLang; }
1291
1292 Metadata *getRawBaseType() const { return getOperand(3); }
1293 Metadata *getRawElements() const { return getOperand(4); }
1296 MDString *getRawIdentifier() const { return getOperandAs<MDString>(7); }
1299 return getOperandAs<DIDerivedType>(8);
1300 }
1303 return dyn_cast_or_null<DIVariable>(getRawDataLocation());
1304 }
1306 return dyn_cast_or_null<DIExpression>(getRawDataLocation());
1307 }
1308 Metadata *getRawAssociated() const { return getOperand(10); }
1310 return dyn_cast_or_null<DIVariable>(getRawAssociated());
1311 }
1313 return dyn_cast_or_null<DIExpression>(getRawAssociated());
1314 }
1315 Metadata *getRawAllocated() const { return getOperand(11); }
1317 return dyn_cast_or_null<DIVariable>(getRawAllocated());
1318 }
1320 return dyn_cast_or_null<DIExpression>(getRawAllocated());
1321 }
1322 Metadata *getRawRank() const { return getOperand(12); }
1324 if (auto *MD = dyn_cast_or_null<ConstantAsMetadata>(getRawRank()))
1325 return dyn_cast_or_null<ConstantInt>(MD->getValue());
1326 return nullptr;
1327 }
1329 return dyn_cast_or_null<DIExpression>(getRawRank());
1330 }
1331
1332 Metadata *getRawAnnotations() const { return getOperand(13); }
1333 DINodeArray getAnnotations() const {
1334 return cast_or_null<MDTuple>(getRawAnnotations());
1335 }
1336
1337 /// Replace operands.
1338 ///
1339 /// If this \a isUniqued() and not \a isResolved(), on a uniquing collision
1340 /// this will be RAUW'ed and deleted. Use a \a TrackingMDRef to keep track
1341 /// of its movement if necessary.
1342 /// @{
1343 void replaceElements(DINodeArray Elements) {
1344#ifndef NDEBUG
1345 for (DINode *Op : getElements())
1346 assert(is_contained(Elements->operands(), Op) &&
1347 "Lost a member during member list replacement");
1348#endif
1349 replaceOperandWith(4, Elements.get());
1350 }
1351
1354 }
1355
1356 void replaceTemplateParams(DITemplateParameterArray TemplateParams) {
1358 }
1359 /// @}
1360
1361 static bool classof(const Metadata *MD) {
1362 return MD->getMetadataID() == DICompositeTypeKind;
1363 }
1364};
1365
1366/// Type array for a subprogram.
1367///
1368/// TODO: Fold the array of types in directly as operands.
1369class DISubroutineType : public DIType {
1370 friend class LLVMContextImpl;
1371 friend class MDNode;
1372
1373 /// The calling convention used with DW_AT_calling_convention. Actually of
1374 /// type dwarf::CallingConvention.
1375 uint8_t CC;
1376
1378 uint8_t CC, ArrayRef<Metadata *> Ops);
1379 ~DISubroutineType() = default;
1380
1381 static DISubroutineType *getImpl(LLVMContext &Context, DIFlags Flags,
1382 uint8_t CC, DITypeRefArray TypeArray,
1384 bool ShouldCreate = true) {
1385 return getImpl(Context, Flags, CC, TypeArray.get(), Storage, ShouldCreate);
1386 }
1387 static DISubroutineType *getImpl(LLVMContext &Context, DIFlags Flags,
1388 uint8_t CC, Metadata *TypeArray,
1390 bool ShouldCreate = true);
1391
1392 TempDISubroutineType cloneImpl() const {
1394 }
1395
1396public:
1399 (Flags, CC, TypeArray))
1403
1404 TempDISubroutineType clone() const { return cloneImpl(); }
1405 // Returns a new temporary DISubroutineType with updated CC
1406 TempDISubroutineType cloneWithCC(uint8_t CC) const {
1407 auto NewTy = clone();
1408 NewTy->CC = CC;
1409 return NewTy;
1410 }
1411
1412 uint8_t getCC() const { return CC; }
1413
1415 return cast_or_null<MDTuple>(getRawTypeArray());
1416 }
1417
1418 Metadata *getRawTypeArray() const { return getOperand(3); }
1419
1420 static bool classof(const Metadata *MD) {
1421 return MD->getMetadataID() == DISubroutineTypeKind;
1422 }
1423};
1424
1425/// Compile unit.
1426class DICompileUnit : public DIScope {
1427 friend class LLVMContextImpl;
1428 friend class MDNode;
1429
1430public:
1431 enum DebugEmissionKind : unsigned {
1438
1439 enum class DebugNameTableKind : unsigned {
1440 Default = 0,
1441 GNU = 1,
1442 None = 2,
1443 Apple = 3,
1445 };
1446
1447 static std::optional<DebugEmissionKind> getEmissionKind(StringRef Str);
1448 static const char *emissionKindString(DebugEmissionKind EK);
1449 static std::optional<DebugNameTableKind> getNameTableKind(StringRef Str);
1450 static const char *nameTableKindString(DebugNameTableKind PK);
1451
1452private:
1453 unsigned SourceLanguage;
1454 unsigned RuntimeVersion;
1455 uint64_t DWOId;
1456 unsigned EmissionKind;
1457 unsigned NameTableKind;
1458 bool IsOptimized;
1459 bool SplitDebugInlining;
1460 bool DebugInfoForProfiling;
1461 bool RangesBaseAddress;
1462
1464 bool IsOptimized, unsigned RuntimeVersion,
1465 unsigned EmissionKind, uint64_t DWOId, bool SplitDebugInlining,
1466 bool DebugInfoForProfiling, unsigned NameTableKind,
1467 bool RangesBaseAddress, ArrayRef<Metadata *> Ops);
1468 ~DICompileUnit() = default;
1469
1470 static DICompileUnit *
1471 getImpl(LLVMContext &Context, unsigned SourceLanguage, DIFile *File,
1472 StringRef Producer, bool IsOptimized, StringRef Flags,
1473 unsigned RuntimeVersion, StringRef SplitDebugFilename,
1474 unsigned EmissionKind, DICompositeTypeArray EnumTypes,
1475 DIScopeArray RetainedTypes,
1476 DIGlobalVariableExpressionArray GlobalVariables,
1477 DIImportedEntityArray ImportedEntities, DIMacroNodeArray Macros,
1478 uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling,
1479 unsigned NameTableKind, bool RangesBaseAddress, StringRef SysRoot,
1480 StringRef SDK, StorageType Storage, bool ShouldCreate = true) {
1481 return getImpl(
1482 Context, SourceLanguage, File, getCanonicalMDString(Context, Producer),
1483 IsOptimized, getCanonicalMDString(Context, Flags), RuntimeVersion,
1484 getCanonicalMDString(Context, SplitDebugFilename), EmissionKind,
1485 EnumTypes.get(), RetainedTypes.get(), GlobalVariables.get(),
1486 ImportedEntities.get(), Macros.get(), DWOId, SplitDebugInlining,
1487 DebugInfoForProfiling, NameTableKind, RangesBaseAddress,
1488 getCanonicalMDString(Context, SysRoot),
1489 getCanonicalMDString(Context, SDK), Storage, ShouldCreate);
1490 }
1491 static DICompileUnit *
1492 getImpl(LLVMContext &Context, unsigned SourceLanguage, Metadata *File,
1493 MDString *Producer, bool IsOptimized, MDString *Flags,
1494 unsigned RuntimeVersion, MDString *SplitDebugFilename,
1495 unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes,
1497 Metadata *Macros, uint64_t DWOId, bool SplitDebugInlining,
1498 bool DebugInfoForProfiling, unsigned NameTableKind,
1499 bool RangesBaseAddress, MDString *SysRoot, MDString *SDK,
1500 StorageType Storage, bool ShouldCreate = true);
1501
1502 TempDICompileUnit cloneImpl() const {
1503 return getTemporary(
1510 }
1511
1512public:
1513 static void get() = delete;
1514 static void getIfExists() = delete;
1515
1519 bool IsOptimized, StringRef Flags, unsigned RuntimeVersion,
1521 DICompositeTypeArray EnumTypes, DIScopeArray RetainedTypes,
1522 DIGlobalVariableExpressionArray GlobalVariables,
1523 DIImportedEntityArray ImportedEntities, DIMacroNodeArray Macros,
1524 uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling,
1525 DebugNameTableKind NameTableKind, bool RangesBaseAddress,
1527 (SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion,
1529 GlobalVariables, ImportedEntities, Macros, DWOId, SplitDebugInlining,
1530 DebugInfoForProfiling, (unsigned)NameTableKind, RangesBaseAddress,
1531 SysRoot, SDK))
1535 bool IsOptimized, MDString *Flags, unsigned RuntimeVersion,
1539 bool SplitDebugInlining, bool DebugInfoForProfiling,
1540 unsigned NameTableKind, bool RangesBaseAddress, MDString *SysRoot,
1542 (SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion,
1544 GlobalVariables, ImportedEntities, Macros, DWOId, SplitDebugInlining,
1545 DebugInfoForProfiling, NameTableKind, RangesBaseAddress, SysRoot, SDK))
1546
1547 TempDICompileUnit clone() const { return cloneImpl(); }
1548
1549 unsigned getSourceLanguage() const { return SourceLanguage; }
1550 bool isOptimized() const { return IsOptimized; }
1551 unsigned getRuntimeVersion() const { return RuntimeVersion; }
1553 return (DebugEmissionKind)EmissionKind;
1554 }
1556 return EmissionKind == DebugDirectivesOnly;
1557 }
1558 bool getDebugInfoForProfiling() const { return DebugInfoForProfiling; }
1560 return (DebugNameTableKind)NameTableKind;
1561 }
1562 bool getRangesBaseAddress() const { return RangesBaseAddress; }
1564 StringRef getFlags() const { return getStringOperand(2); }
1566 DICompositeTypeArray getEnumTypes() const {
1567 return cast_or_null<MDTuple>(getRawEnumTypes());
1568 }
1569 DIScopeArray getRetainedTypes() const {
1570 return cast_or_null<MDTuple>(getRawRetainedTypes());
1571 }
1572 DIGlobalVariableExpressionArray getGlobalVariables() const {
1573 return cast_or_null<MDTuple>(getRawGlobalVariables());
1574 }
1575 DIImportedEntityArray getImportedEntities() const {
1576 return cast_or_null<MDTuple>(getRawImportedEntities());
1577 }
1578 DIMacroNodeArray getMacros() const {
1579 return cast_or_null<MDTuple>(getRawMacros());
1580 }
1581 uint64_t getDWOId() const { return DWOId; }
1582 void setDWOId(uint64_t DwoId) { DWOId = DwoId; }
1583 bool getSplitDebugInlining() const { return SplitDebugInlining; }
1584 void setSplitDebugInlining(bool SplitDebugInlining) {
1585 this->SplitDebugInlining = SplitDebugInlining;
1586 }
1588 StringRef getSDK() const { return getStringOperand(10); }
1589
1590 MDString *getRawProducer() const { return getOperandAs<MDString>(1); }
1591 MDString *getRawFlags() const { return getOperandAs<MDString>(2); }
1593 return getOperandAs<MDString>(3);
1594 }
1595 Metadata *getRawEnumTypes() const { return getOperand(4); }
1599 Metadata *getRawMacros() const { return getOperand(8); }
1600 MDString *getRawSysRoot() const { return getOperandAs<MDString>(9); }
1601 MDString *getRawSDK() const { return getOperandAs<MDString>(10); }
1602
1603 /// Replace arrays.
1604 ///
1605 /// If this \a isUniqued() and not \a isResolved(), it will be RAUW'ed and
1606 /// deleted on a uniquing collision. In practice, uniquing collisions on \a
1607 /// DICompileUnit should be fairly rare.
1608 /// @{
1609 void replaceEnumTypes(DICompositeTypeArray N) {
1610 replaceOperandWith(4, N.get());
1611 }
1612 void replaceRetainedTypes(DITypeArray N) { replaceOperandWith(5, N.get()); }
1613 void replaceGlobalVariables(DIGlobalVariableExpressionArray N) {
1614 replaceOperandWith(6, N.get());
1615 }
1616 void replaceImportedEntities(DIImportedEntityArray N) {
1617 replaceOperandWith(7, N.get());
1618 }
1619 void replaceMacros(DIMacroNodeArray N) { replaceOperandWith(8, N.get()); }
1620 /// @}
1621
1622 static bool classof(const Metadata *MD) {
1623 return MD->getMetadataID() == DICompileUnitKind;
1624 }
1625};
1626
1627/// A scope for locals.
1628///
1629/// A legal scope for lexical blocks, local variables, and debug info
1630/// locations. Subclasses are \a DISubprogram, \a DILexicalBlock, and \a
1631/// DILexicalBlockFile.
1632class DILocalScope : public DIScope {
1633protected:
1636 : DIScope(C, ID, Storage, Tag, Ops) {}
1637 ~DILocalScope() = default;
1638
1639public:
1640 /// Get the subprogram for this scope.
1641 ///
1642 /// Return this if it's an \a DISubprogram; otherwise, look up the scope
1643 /// chain.
1644 DISubprogram *getSubprogram() const;
1645
1646 /// Traverses the scope chain rooted at RootScope until it hits a Subprogram,
1647 /// recreating the chain with "NewSP" instead.
1648 static DILocalScope *
1650 LLVMContext &Ctx,
1652
1653 /// Get the first non DILexicalBlockFile scope of this scope.
1654 ///
1655 /// Return this if it's not a \a DILexicalBlockFIle; otherwise, look up the
1656 /// scope chain.
1658
1659 static bool classof(const Metadata *MD) {
1660 return MD->getMetadataID() == DISubprogramKind ||
1661 MD->getMetadataID() == DILexicalBlockKind ||
1662 MD->getMetadataID() == DILexicalBlockFileKind;
1663 }
1664};
1665
1666/// Subprogram description.
1668 friend class LLVMContextImpl;
1669 friend class MDNode;
1670
1671 unsigned Line;
1672 unsigned ScopeLine;
1673 unsigned VirtualIndex;
1674
1675 /// In the MS ABI, the implicit 'this' parameter is adjusted in the prologue
1676 /// of method overrides from secondary bases by this amount. It may be
1677 /// negative.
1678 int ThisAdjustment;
1679
1680public:
1681 /// Debug info subprogram flags.
1683#define HANDLE_DISP_FLAG(ID, NAME) SPFlag##NAME = ID,
1684#define DISP_FLAG_LARGEST_NEEDED
1685#include "llvm/IR/DebugInfoFlags.def"
1686 SPFlagNonvirtual = SPFlagZero,
1687 SPFlagVirtuality = SPFlagVirtual | SPFlagPureVirtual,
1688 LLVM_MARK_AS_BITMASK_ENUM(SPFlagLargest)
1689 };
1690
1691 static DISPFlags getFlag(StringRef Flag);
1692 static StringRef getFlagString(DISPFlags Flag);
1693
1694 /// Split up a flags bitfield for easier printing.
1695 ///
1696 /// Split \c Flags into \c SplitFlags, a vector of its components. Returns
1697 /// any remaining (unrecognized) bits.
1698 static DISPFlags splitFlags(DISPFlags Flags,
1699 SmallVectorImpl<DISPFlags> &SplitFlags);
1700
1701 // Helper for converting old bitfields to new flags word.
1702 static DISPFlags toSPFlags(bool IsLocalToUnit, bool IsDefinition,
1703 bool IsOptimized,
1704 unsigned Virtuality = SPFlagNonvirtual,
1705 bool IsMainSubprogram = false);
1706
1707private:
1708 DIFlags Flags;
1709 DISPFlags SPFlags;
1710
1711 DISubprogram(LLVMContext &C, StorageType Storage, unsigned Line,
1712 unsigned ScopeLine, unsigned VirtualIndex, int ThisAdjustment,
1713 DIFlags Flags, DISPFlags SPFlags, ArrayRef<Metadata *> Ops);
1714 ~DISubprogram() = default;
1715
1716 static DISubprogram *
1717 getImpl(LLVMContext &Context, DIScope *Scope, StringRef Name,
1718 StringRef LinkageName, DIFile *File, unsigned Line,
1719 DISubroutineType *Type, unsigned ScopeLine, DIType *ContainingType,
1720 unsigned VirtualIndex, int ThisAdjustment, DIFlags Flags,
1721 DISPFlags SPFlags, DICompileUnit *Unit,
1722 DITemplateParameterArray TemplateParams, DISubprogram *Declaration,
1723 DINodeArray RetainedNodes, DITypeArray ThrownTypes,
1725 StorageType Storage, bool ShouldCreate = true) {
1726 return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
1727 getCanonicalMDString(Context, LinkageName), File, Line, Type,
1728 ScopeLine, ContainingType, VirtualIndex, ThisAdjustment,
1729 Flags, SPFlags, Unit, TemplateParams.get(), Declaration,
1730 RetainedNodes.get(), ThrownTypes.get(), Annotations.get(),
1732 Storage, ShouldCreate);
1733 }
1734 static DISubprogram *
1735 getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
1736 MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type,
1737 unsigned ScopeLine, Metadata *ContainingType, unsigned VirtualIndex,
1738 int ThisAdjustment, DIFlags Flags, DISPFlags SPFlags, Metadata *Unit,
1742 bool ShouldCreate = true);
1743
1744 TempDISubprogram cloneImpl() const {
1746 getFile(), getLine(), getType(), getScopeLine(),
1747 getContainingType(), getVirtualIndex(),
1748 getThisAdjustment(), getFlags(), getSPFlags(),
1749 getUnit(), getTemplateParams(), getDeclaration(),
1750 getRetainedNodes(), getThrownTypes(), getAnnotations(),
1751 getTargetFuncName());
1752 }
1753
1754public:
1758 unsigned Line, DISubroutineType *Type, unsigned ScopeLine,
1759 DIType *ContainingType, unsigned VirtualIndex, int ThisAdjustment,
1760 DIFlags Flags, DISPFlags SPFlags, DICompileUnit *Unit,
1761 DITemplateParameterArray TemplateParams = nullptr,
1762 DISubprogram *Declaration = nullptr, DINodeArray RetainedNodes = nullptr,
1763 DITypeArray ThrownTypes = nullptr, DINodeArray Annotations = nullptr,
1765 (Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType,
1766 VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams,
1768
1772 unsigned Line, Metadata *Type, unsigned ScopeLine,
1773 Metadata *ContainingType, unsigned VirtualIndex, int ThisAdjustment,
1774 DIFlags Flags, DISPFlags SPFlags, Metadata *Unit,
1778 (Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType,
1779 VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams,
1781
1782 TempDISubprogram clone() const { return cloneImpl(); }
1783
1784 /// Returns a new temporary DISubprogram with updated Flags
1785 TempDISubprogram cloneWithFlags(DIFlags NewFlags) const {
1786 auto NewSP = clone();
1787 NewSP->Flags = NewFlags;
1788 return NewSP;
1789 }
1790
1791public:
1792 unsigned getLine() const { return Line; }
1793 unsigned getVirtuality() const { return getSPFlags() & SPFlagVirtuality; }
1794 unsigned getVirtualIndex() const { return VirtualIndex; }
1795 int getThisAdjustment() const { return ThisAdjustment; }
1796 unsigned getScopeLine() const { return ScopeLine; }
1797 void setScopeLine(unsigned L) {
1798 assert(isDistinct());
1799 ScopeLine = L;
1800 }
1801 DIFlags getFlags() const { return Flags; }
1802 DISPFlags getSPFlags() const { return SPFlags; }
1803 bool isLocalToUnit() const { return getSPFlags() & SPFlagLocalToUnit; }
1804 bool isDefinition() const { return getSPFlags() & SPFlagDefinition; }
1805 bool isOptimized() const { return getSPFlags() & SPFlagOptimized; }
1806 bool isMainSubprogram() const { return getSPFlags() & SPFlagMainSubprogram; }
1807
1808 bool isArtificial() const { return getFlags() & FlagArtificial; }
1809 bool isPrivate() const {
1810 return (getFlags() & FlagAccessibility) == FlagPrivate;
1811 }
1812 bool isProtected() const {
1813 return (getFlags() & FlagAccessibility) == FlagProtected;
1814 }
1815 bool isPublic() const {
1816 return (getFlags() & FlagAccessibility) == FlagPublic;
1817 }
1818 bool isExplicit() const { return getFlags() & FlagExplicit; }
1819 bool isPrototyped() const { return getFlags() & FlagPrototyped; }
1820 bool areAllCallsDescribed() const {
1821 return getFlags() & FlagAllCallsDescribed;
1822 }
1823 bool isPure() const { return getSPFlags() & SPFlagPure; }
1824 bool isElemental() const { return getSPFlags() & SPFlagElemental; }
1825 bool isRecursive() const { return getSPFlags() & SPFlagRecursive; }
1826 bool isObjCDirect() const { return getSPFlags() & SPFlagObjCDirect; }
1827
1828 /// Check if this is deleted member function.
1829 ///
1830 /// Return true if this subprogram is a C++11 special
1831 /// member function declared deleted.
1832 bool isDeleted() const { return getSPFlags() & SPFlagDeleted; }
1833
1834 /// Check if this is reference-qualified.
1835 ///
1836 /// Return true if this subprogram is a C++11 reference-qualified non-static
1837 /// member function (void foo() &).
1838 bool isLValueReference() const { return getFlags() & FlagLValueReference; }
1839
1840 /// Check if this is rvalue-reference-qualified.
1841 ///
1842 /// Return true if this subprogram is a C++11 rvalue-reference-qualified
1843 /// non-static member function (void foo() &&).
1844 bool isRValueReference() const { return getFlags() & FlagRValueReference; }
1845
1846 /// Check if this is marked as noreturn.
1847 ///
1848 /// Return true if this subprogram is C++11 noreturn or C11 _Noreturn
1849 bool isNoReturn() const { return getFlags() & FlagNoReturn; }
1850
1851 // Check if this routine is a compiler-generated thunk.
1852 //
1853 // Returns true if this subprogram is a thunk generated by the compiler.
1854 bool isThunk() const { return getFlags() & FlagThunk; }
1855
1856 DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
1857
1858 StringRef getName() const { return getStringOperand(2); }
1859 StringRef getLinkageName() const { return getStringOperand(3); }
1860 /// Only used by clients of CloneFunction, and only right after the cloning.
1861 void replaceLinkageName(MDString *LN) { replaceOperandWith(3, LN); }
1862
1863 DISubroutineType *getType() const {
1864 return cast_or_null<DISubroutineType>(getRawType());
1865 }
1866 DIType *getContainingType() const {
1867 return cast_or_null<DIType>(getRawContainingType());
1868 }
1869 void replaceType(DISubroutineType *Ty) {
1870 assert(isDistinct() && "Only distinct nodes can mutate");
1871 replaceOperandWith(4, Ty);
1872 }
1873
1874 DICompileUnit *getUnit() const {
1875 return cast_or_null<DICompileUnit>(getRawUnit());
1876 }
1877 void replaceUnit(DICompileUnit *CU) { replaceOperandWith(5, CU); }
1878 DITemplateParameterArray getTemplateParams() const {
1879 return cast_or_null<MDTuple>(getRawTemplateParams());
1880 }
1881 DISubprogram *getDeclaration() const {
1882 return cast_or_null<DISubprogram>(getRawDeclaration());
1883 }
1884 void replaceDeclaration(DISubprogram *Decl) { replaceOperandWith(6, Decl); }
1885 DINodeArray getRetainedNodes() const {
1886 return cast_or_null<MDTuple>(getRawRetainedNodes());
1887 }
1888 DITypeArray getThrownTypes() const {
1889 return cast_or_null<MDTuple>(getRawThrownTypes());
1890 }
1891 DINodeArray getAnnotations() const {
1892 return cast_or_null<MDTuple>(getRawAnnotations());
1893 }
1894 StringRef getTargetFuncName() const {
1895 return (getRawTargetFuncName()) ? getStringOperand(12) : StringRef();
1896 }
1897
1898 Metadata *getRawScope() const { return getOperand(1); }
1899 MDString *getRawName() const { return getOperandAs<MDString>(2); }
1900 MDString *getRawLinkageName() const { return getOperandAs<MDString>(3); }
1901 Metadata *getRawType() const { return getOperand(4); }
1902 Metadata *getRawUnit() const { return getOperand(5); }
1903 Metadata *getRawDeclaration() const { return getOperand(6); }
1904 Metadata *getRawRetainedNodes() const { return getOperand(7); }
1905 Metadata *getRawContainingType() const {
1906 return getNumOperands() > 8 ? getOperandAs<Metadata>(8) : nullptr;
1907 }
1908 Metadata *getRawTemplateParams() const {
1909 return getNumOperands() > 9 ? getOperandAs<Metadata>(9) : nullptr;
1910 }
1911 Metadata *getRawThrownTypes() const {
1912 return getNumOperands() > 10 ? getOperandAs<Metadata>(10) : nullptr;
1913 }
1914 Metadata *getRawAnnotations() const {
1915 return getNumOperands() > 11 ? getOperandAs<Metadata>(11) : nullptr;
1916 }
1917 MDString *getRawTargetFuncName() const {
1918 return getNumOperands() > 12 ? getOperandAs<MDString>(12) : nullptr;
1919 }
1920
1921 void replaceRawLinkageName(MDString *LinkageName) {
1923 }
1924 void replaceRetainedNodes(DINodeArray N) {
1925 replaceOperandWith(7, N.get());
1926 }
1927
1928 /// Check if this subprogram describes the given function.
1929 ///
1930 /// FIXME: Should this be looking through bitcasts?
1931 bool describes(const Function *F) const;
1932
1933 static bool classof(const Metadata *MD) {
1934 return MD->getMetadataID() == DISubprogramKind;
1935 }
1936};
1937
1938/// Debug location.
1939///
1940/// A debug location in source code, used for debug info and otherwise.
1941///
1942/// Uses the SubclassData1, SubclassData16 and SubclassData32
1943/// Metadata slots.
1944
1945class DILocation : public MDNode {
1946 friend class LLVMContextImpl;
1947 friend class MDNode;
1948
1950 unsigned Column, ArrayRef<Metadata *> MDs, bool ImplicitCode);
1952
1953 static DILocation *getImpl(LLVMContext &Context, unsigned Line,
1954 unsigned Column, Metadata *Scope,
1956 StorageType Storage, bool ShouldCreate = true);
1957 static DILocation *getImpl(LLVMContext &Context, unsigned Line,
1958 unsigned Column, DILocalScope *Scope,
1960 StorageType Storage, bool ShouldCreate = true) {
1961 return getImpl(Context, Line, Column, static_cast<Metadata *>(Scope),
1962 static_cast<Metadata *>(InlinedAt), ImplicitCode, Storage,
1963 ShouldCreate);
1964 }
1965
1966 TempDILocation cloneImpl() const {
1967 // Get the raw scope/inlinedAt since it is possible to invoke this on
1968 // a DILocation containing temporary metadata.
1969 return getTemporary(getContext(), getLine(), getColumn(), getRawScope(),
1970 getRawInlinedAt(), isImplicitCode());
1971 }
1972
1973public:
1974 // Disallow replacing operands.
1975 void replaceOperandWith(unsigned I, Metadata *New) = delete;
1976
1978 (unsigned Line, unsigned Column, Metadata *Scope,
1979 Metadata *InlinedAt = nullptr, bool ImplicitCode = false),
1982 (unsigned Line, unsigned Column, DILocalScope *Scope,
1984 bool ImplicitCode = false),
1986
1987 /// Return a (temporary) clone of this.
1988 TempDILocation clone() const { return cloneImpl(); }
1989
1990 unsigned getLine() const { return SubclassData32; }
1991 unsigned getColumn() const { return SubclassData16; }
1992 DILocalScope *getScope() const { return cast<DILocalScope>(getRawScope()); }
1993
1994 /// Return the linkage name of Subprogram. If the linkage name is empty,
1995 /// return scope name (the demangled name).
1996 StringRef getSubprogramLinkageName() const {
1997 DISubprogram *SP = getScope()->getSubprogram();
1998 if (!SP)
1999 return "";
2000 auto Name = SP->getLinkageName();
2001 if (!Name.empty())
2002 return Name;
2003 return SP->getName();
2004 }
2005
2006 DILocation *getInlinedAt() const {
2007 return cast_or_null<DILocation>(getRawInlinedAt());
2008 }
2009
2010 /// Check if the location corresponds to an implicit code.
2011 /// When the ImplicitCode flag is true, it means that the Instruction
2012 /// with this DILocation has been added by the front-end but it hasn't been
2013 /// written explicitly by the user (e.g. cleanup stuff in C++ put on a closing
2014 /// bracket). It's useful for code coverage to not show a counter on "empty"
2015 /// lines.
2016 bool isImplicitCode() const { return SubclassData1; }
2017 void setImplicitCode(bool ImplicitCode) { SubclassData1 = ImplicitCode; }
2018
2019 DIFile *getFile() const { return getScope()->getFile(); }
2020 StringRef getFilename() const { return getScope()->getFilename(); }
2021 StringRef getDirectory() const { return getScope()->getDirectory(); }
2022 std::optional<StringRef> getSource() const { return getScope()->getSource(); }
2023
2024 /// Get the scope where this is inlined.
2025 ///
2026 /// Walk through \a getInlinedAt() and return \a getScope() from the deepest
2027 /// location.
2028 DILocalScope *getInlinedAtScope() const {
2029 if (auto *IA = getInlinedAt())
2030 return IA->getInlinedAtScope();
2031 return getScope();
2032 }
2033
2034 /// Get the DWARF discriminator.
2035 ///
2036 /// DWARF discriminators distinguish identical file locations between
2037 /// instructions that are on different basic blocks.
2038 ///
2039 /// There are 3 components stored in discriminator, from lower bits:
2040 ///
2041 /// Base discriminator: assigned by AddDiscriminators pass to identify IRs
2042 /// that are defined by the same source line, but
2043 /// different basic blocks.
2044 /// Duplication factor: assigned by optimizations that will scale down
2045 /// the execution frequency of the original IR.
2046 /// Copy Identifier: assigned by optimizations that clones the IR.
2047 /// Each copy of the IR will be assigned an identifier.
2048 ///
2049 /// Encoding:
2050 ///
2051 /// The above 3 components are encoded into a 32bit unsigned integer in
2052 /// order. If the lowest bit is 1, the current component is empty, and the
2053 /// next component will start in the next bit. Otherwise, the current
2054 /// component is non-empty, and its content starts in the next bit. The
2055 /// value of each components is either 5 bit or 12 bit: if the 7th bit
2056 /// is 0, the bit 2~6 (5 bits) are used to represent the component; if the
2057 /// 7th bit is 1, the bit 2~6 (5 bits) and 8~14 (7 bits) are combined to
2058 /// represent the component. Thus, the number of bits used for a component
2059 /// is either 0 (if it and all the next components are empty); 1 - if it is
2060 /// empty; 7 - if its value is up to and including 0x1f (lsb and msb are both
2061 /// 0); or 14, if its value is up to and including 0x1ff. Note that the last
2062 /// component is also capped at 0x1ff, even in the case when both first
2063 /// components are 0, and we'd technically have 29 bits available.
2064 ///
2065 /// For precise control over the data being encoded in the discriminator,
2066 /// use encodeDiscriminator/decodeDiscriminator.
2067
2068 inline unsigned getDiscriminator() const;
2069
2070 // For the regular discriminator, it stands for all empty components if all
2071 // the lowest 3 bits are non-zero and all higher 29 bits are unused(zero by
2072 // default). Here we fully leverage the higher 29 bits for pseudo probe use.
2073 // This is the format:
2074 // [2:0] - 0x7
2075 // [31:3] - pseudo probe fields guaranteed to be non-zero as a whole
2076 // So if the lower 3 bits is non-zero and the others has at least one
2077 // non-zero bit, it guarantees to be a pseudo probe discriminator
2078 inline static bool isPseudoProbeDiscriminator(unsigned Discriminator) {
2079 return ((Discriminator & 0x7) == 0x7) && (Discriminator & 0xFFFFFFF8);
2080 }
2081
2082 /// Returns a new DILocation with updated \p Discriminator.
2083 inline const DILocation *cloneWithDiscriminator(unsigned Discriminator) const;
2084
2085 /// Returns a new DILocation with updated base discriminator \p BD. Only the
2086 /// base discriminator is set in the new DILocation, the other encoded values
2087 /// are elided.
2088 /// If the discriminator cannot be encoded, the function returns std::nullopt.
2089 inline std::optional<const DILocation *>
2090 cloneWithBaseDiscriminator(unsigned BD) const;
2091
2092 /// Returns the duplication factor stored in the discriminator, or 1 if no
2093 /// duplication factor (or 0) is encoded.
2094 inline unsigned getDuplicationFactor() const;
2095
2096 /// Returns the copy identifier stored in the discriminator.
2097 inline unsigned getCopyIdentifier() const;
2098
2099 /// Returns the base discriminator stored in the discriminator.
2100 inline unsigned getBaseDiscriminator() const;
2101
2102 /// Returns a new DILocation with duplication factor \p DF * current
2103 /// duplication factor encoded in the discriminator. The current duplication
2104 /// factor is as defined by getDuplicationFactor().
2105 /// Returns std::nullopt if encoding failed.
2106 inline std::optional<const DILocation *>
2108
2109 /// When two instructions are combined into a single instruction we also
2110 /// need to combine the original locations into a single location.
2111 /// When the locations are the same we can use either location.
2112 /// When they differ, we need a third location which is distinct from either.
2113 /// If they share a common scope, use this scope and compare the line/column
2114 /// pair of the locations with the common scope:
2115 /// * if both match, keep the line and column;
2116 /// * if only the line number matches, keep the line and set the column as 0;
2117 /// * otherwise set line and column as 0.
2118 /// If they do not share a common scope the location is ambiguous and can't be
2119 /// represented in a line entry. In this case, set line and column as 0 and
2120 /// use the scope of any location.
2121 ///
2122 /// \p LocA \p LocB: The locations to be merged.
2123 static DILocation *getMergedLocation(DILocation *LocA, DILocation *LocB);
2124
2125 /// Try to combine the vector of locations passed as input in a single one.
2126 /// This function applies getMergedLocation() repeatedly left-to-right.
2127 ///
2128 /// \p Locs: The locations to be merged.
2130
2131 /// Return the masked discriminator value for an input discrimnator value D
2132 /// (i.e. zero out the (B+1)-th and above bits for D (B is 0-base).
2133 // Example: an input of (0x1FF, 7) returns 0xFF.
2134 static unsigned getMaskedDiscriminator(unsigned D, unsigned B) {
2135 return (D & getN1Bits(B));
2136 }
2137
2138 /// Return the bits used for base discriminators.
2139 static unsigned getBaseDiscriminatorBits() { return getBaseFSBitEnd(); }
2140
2141 /// Returns the base discriminator for a given encoded discriminator \p D.
2142 static unsigned
2144 bool IsFSDiscriminator = false) {
2145 // Return the probe id instead of zero for a pseudo probe discriminator.
2146 // This should help differenciate callsites with same line numbers to
2147 // achieve a decent AutoFDO profile under -fpseudo-probe-for-profiling,
2148 // where the original callsite dwarf discriminator is overwritten by
2149 // callsite probe information.
2152
2153 if (IsFSDiscriminator)
2156 }
2157
2158 /// Raw encoding of the discriminator. APIs such as cloneWithDuplicationFactor
2159 /// have certain special case behavior (e.g. treating empty duplication factor
2160 /// as the value '1').
2161 /// This API, in conjunction with cloneWithDiscriminator, may be used to
2162 /// encode the raw values provided.
2163 ///
2164 /// \p BD: base discriminator
2165 /// \p DF: duplication factor
2166 /// \p CI: copy index
2167 ///
2168 /// The return is std::nullopt if the values cannot be encoded in 32 bits -
2169 /// for example, values for BD or DF larger than 12 bits. Otherwise, the
2170 /// return is the encoded value.
2171 static std::optional<unsigned> encodeDiscriminator(unsigned BD, unsigned DF,
2172 unsigned CI);
2173
2174 /// Raw decoder for values in an encoded discriminator D.
2175 static void decodeDiscriminator(unsigned D, unsigned &BD, unsigned &DF,
2176 unsigned &CI);
2177
2178 /// Returns the duplication factor for a given encoded discriminator \p D, or
2179 /// 1 if no value or 0 is encoded.
2180 static unsigned getDuplicationFactorFromDiscriminator(unsigned D) {
2182 return 1;
2184 unsigned Ret = getUnsignedFromPrefixEncoding(D);
2185 if (Ret == 0)
2186 return 1;
2187 return Ret;
2188 }
2189
2190 /// Returns the copy identifier for a given encoded discriminator \p D.
2191 static unsigned getCopyIdentifierFromDiscriminator(unsigned D) {
2194 }
2195
2196 Metadata *getRawScope() const { return getOperand(0); }
2198 if (getNumOperands() == 2)
2199 return getOperand(1);
2200 return nullptr;
2201 }
2202
2203 static bool classof(const Metadata *MD) {
2204 return MD->getMetadataID() == DILocationKind;
2205 }
2206};
2207
2209protected:
2213
2214public:
2215 DILocalScope *getScope() const { return cast<DILocalScope>(getRawScope()); }
2216
2217 Metadata *getRawScope() const { return getOperand(1); }
2218
2219 void replaceScope(DIScope *Scope) {
2220 assert(!isUniqued());
2221 setOperand(1, Scope);
2222 }
2223
2224 static bool classof(const Metadata *MD) {
2225 return MD->getMetadataID() == DILexicalBlockKind ||
2226 MD->getMetadataID() == DILexicalBlockFileKind;
2227 }
2228};
2229
2230/// Debug lexical block.
2231///
2232/// Uses the SubclassData32 Metadata slot.
2234 friend class LLVMContextImpl;
2235 friend class MDNode;
2236
2237 uint16_t Column;
2238
2240 unsigned Column, ArrayRef<Metadata *> Ops)
2241 : DILexicalBlockBase(C, DILexicalBlockKind, Storage, Ops),
2242 Column(Column) {
2244 assert(Column < (1u << 16) && "Expected 16-bit column");
2245 }
2246 ~DILexicalBlock() = default;
2247
2248 static DILexicalBlock *getImpl(LLVMContext &Context, DILocalScope *Scope,
2249 DIFile *File, unsigned Line, unsigned Column,
2251 bool ShouldCreate = true) {
2252 return getImpl(Context, static_cast<Metadata *>(Scope),
2253 static_cast<Metadata *>(File), Line, Column, Storage,
2254 ShouldCreate);
2255 }
2256
2257 static DILexicalBlock *getImpl(LLVMContext &Context, Metadata *Scope,
2258 Metadata *File, unsigned Line, unsigned Column,
2259 StorageType Storage, bool ShouldCreate = true);
2260
2261 TempDILexicalBlock cloneImpl() const {
2263 getColumn());
2264 }
2265
2266public:
2268 (DILocalScope * Scope, DIFile *File, unsigned Line,
2269 unsigned Column),
2270 (Scope, File, Line, Column))
2273 unsigned Column),
2274 (Scope, File, Line, Column))
2275
2276 TempDILexicalBlock clone() const { return cloneImpl(); }
2277
2278 unsigned getLine() const { return SubclassData32; }
2279 unsigned getColumn() const { return Column; }
2280
2281 static bool classof(const Metadata *MD) {
2282 return MD->getMetadataID() == DILexicalBlockKind;
2283 }
2284};
2285
2287 friend class LLVMContextImpl;
2288 friend class MDNode;
2289
2291 unsigned Discriminator, ArrayRef<Metadata *> Ops)
2292 : DILexicalBlockBase(C, DILexicalBlockFileKind, Storage, Ops) {
2294 }
2295 ~DILexicalBlockFile() = default;
2296
2297 static DILexicalBlockFile *getImpl(LLVMContext &Context, DILocalScope *Scope,
2298 DIFile *File, unsigned Discriminator,
2300 bool ShouldCreate = true) {
2301 return getImpl(Context, static_cast<Metadata *>(Scope),
2302 static_cast<Metadata *>(File), Discriminator, Storage,
2303 ShouldCreate);
2304 }
2305
2306 static DILexicalBlockFile *getImpl(LLVMContext &Context, Metadata *Scope,
2307 Metadata *File, unsigned Discriminator,
2309 bool ShouldCreate = true);
2310
2311 TempDILexicalBlockFile cloneImpl() const {
2312 return getTemporary(getContext(), getScope(), getFile(),
2314 }
2315
2316public:
2319 unsigned Discriminator),
2324
2325 TempDILexicalBlockFile clone() const { return cloneImpl(); }
2326 unsigned getDiscriminator() const { return SubclassData32; }
2327
2328 static bool classof(const Metadata *MD) {
2329 return MD->getMetadataID() == DILexicalBlockFileKind;
2330 }
2331};
2332
2333unsigned DILocation::getDiscriminator() const {
2334 if (auto *F = dyn_cast<DILexicalBlockFile>(getScope()))
2335 return F->getDiscriminator();
2336 return 0;
2337}
2338
2339const DILocation *
2340DILocation::cloneWithDiscriminator(unsigned Discriminator) const {
2341 DIScope *Scope = getScope();
2342 // Skip all parent DILexicalBlockFile that already have a discriminator
2343 // assigned. We do not want to have nested DILexicalBlockFiles that have
2344 // mutliple discriminators because only the leaf DILexicalBlockFile's
2345 // dominator will be used.
2346 for (auto *LBF = dyn_cast<DILexicalBlockFile>(Scope);
2347 LBF && LBF->getDiscriminator() != 0;
2348 LBF = dyn_cast<DILexicalBlockFile>(Scope))
2349 Scope = LBF->getScope();
2350 DILexicalBlockFile *NewScope =
2351 DILexicalBlockFile::get(getContext(), Scope, getFile(), Discriminator);
2352 return DILocation::get(getContext(), getLine(), getColumn(), NewScope,
2353 getInlinedAt());
2354}
2355
2357 return getBaseDiscriminatorFromDiscriminator(getDiscriminator(),
2359}
2360
2362 return getDuplicationFactorFromDiscriminator(getDiscriminator());
2363}
2364
2366 return getCopyIdentifierFromDiscriminator(getDiscriminator());
2367}
2368
2369std::optional<const DILocation *>
2371 unsigned BD, DF, CI;
2372
2374 BD = getBaseDiscriminator();
2375 if (D == BD)
2376 return this;
2377 return cloneWithDiscriminator(D);
2378 }
2379
2380 decodeDiscriminator(getDiscriminator(), BD, DF, CI);
2381 if (D == BD)
2382 return this;
2383 if (std::optional<unsigned> Encoded = encodeDiscriminator(D, DF, CI))
2384 return cloneWithDiscriminator(*Encoded);
2385 return std::nullopt;
2386}
2387
2388std::optional<const DILocation *>
2390 assert(!EnableFSDiscriminator && "FSDiscriminator should not call this.");
2391 // Do no interfere with pseudo probes. Pseudo probe doesn't need duplication
2392 // factor support as samples collected on cloned probes will be aggregated.
2393 // Also pseudo probe at a callsite uses the dwarf discriminator to store
2394 // pseudo probe related information, such as the probe id.
2395 if (isPseudoProbeDiscriminator(getDiscriminator()))
2396 return this;
2397
2399 if (DF <= 1)
2400 return this;
2401
2402 unsigned BD = getBaseDiscriminator();
2403 unsigned CI = getCopyIdentifier();
2404 if (std::optional<unsigned> D = encodeDiscriminator(BD, DF, CI))
2405 return cloneWithDiscriminator(*D);
2406 return std::nullopt;
2407}
2408
2409/// Debug lexical block.
2410///
2411/// Uses the SubclassData1 Metadata slot.
2412class DINamespace : public DIScope {
2413 friend class LLVMContextImpl;
2414 friend class MDNode;
2415
2418 ~DINamespace() = default;
2419
2420 static DINamespace *getImpl(LLVMContext &Context, DIScope *Scope,
2422 StorageType Storage, bool ShouldCreate = true) {
2423 return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
2424 ExportSymbols, Storage, ShouldCreate);
2425 }
2426 static DINamespace *getImpl(LLVMContext &Context, Metadata *Scope,
2428 StorageType Storage, bool ShouldCreate = true);
2429
2430 TempDINamespace cloneImpl() const {
2431 return getTemporary(getContext(), getScope(), getName(),
2433 }
2434
2435public:
2442
2443 TempDINamespace clone() const { return cloneImpl(); }
2444
2445 bool getExportSymbols() const { return SubclassData1; }
2446 DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
2447 StringRef getName() const { return getStringOperand(2); }
2448
2449 Metadata *getRawScope() const { return getOperand(1); }
2450 MDString *getRawName() const { return getOperandAs<MDString>(2); }
2451
2452 static bool classof(const Metadata *MD) {
2453 return MD->getMetadataID() == DINamespaceKind;
2454 }
2455};
2456
2457/// Represents a module in the programming language, for example, a Clang
2458/// module, or a Fortran module.
2459///
2460/// Uses the SubclassData1 and SubclassData32 Metadata slots.
2461class DIModule : public DIScope {
2462 friend class LLVMContextImpl;
2463 friend class MDNode;
2464
2465 DIModule(LLVMContext &Context, StorageType Storage, unsigned LineNo,
2466 bool IsDecl, ArrayRef<Metadata *> Ops);
2467 ~DIModule() = default;
2468
2469 static DIModule *getImpl(LLVMContext &Context, DIFile *File, DIScope *Scope,
2472 unsigned LineNo, bool IsDecl, StorageType Storage,
2473 bool ShouldCreate = true) {
2474 return getImpl(Context, File, Scope, getCanonicalMDString(Context, Name),
2477 getCanonicalMDString(Context, APINotesFile), LineNo, IsDecl,
2478 Storage, ShouldCreate);
2479 }
2480 static DIModule *getImpl(LLVMContext &Context, Metadata *File,
2483 MDString *APINotesFile, unsigned LineNo, bool IsDecl,
2484 StorageType Storage, bool ShouldCreate = true);
2485
2486 TempDIModule cloneImpl() const {
2488 getConfigurationMacros(), getIncludePath(),
2489 getAPINotesFile(), getLineNo(), getIsDecl());
2490 }
2491
2492public:
2496 StringRef APINotesFile, unsigned LineNo,
2497 bool IsDecl = false),
2499 APINotesFile, LineNo, IsDecl))
2504 bool IsDecl = false),
2506 APINotesFile, LineNo, IsDecl))
2507
2508 TempDIModule clone() const { return cloneImpl(); }
2509
2510 DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
2511 StringRef getName() const { return getStringOperand(2); }
2512 StringRef getConfigurationMacros() const { return getStringOperand(3); }
2513 StringRef getIncludePath() const { return getStringOperand(4); }
2514 StringRef getAPINotesFile() const { return getStringOperand(5); }
2515 unsigned getLineNo() const { return SubclassData32; }
2516 bool getIsDecl() const { return SubclassData1; }
2517
2518 Metadata *getRawScope() const { return getOperand(1); }
2519 MDString *getRawName() const { return getOperandAs<MDString>(2); }
2520 MDString *getRawConfigurationMacros() const {
2521 return getOperandAs<MDString>(3);
2522 }
2523 MDString *getRawIncludePath() const { return getOperandAs<MDString>(4); }
2524 MDString *getRawAPINotesFile() const { return getOperandAs<MDString>(5); }
2525
2526 static bool classof(const Metadata *MD) {
2527 return MD->getMetadataID() == DIModuleKind;
2528 }
2529};
2530
2531/// Base class for template parameters.
2532///
2533/// Uses the SubclassData1 Metadata slot.
2535protected:
2537 unsigned Tag, bool IsDefault, ArrayRef<Metadata *> Ops)
2538 : DINode(Context, ID, Storage, Tag, Ops) {
2539 SubclassData1 = IsDefault;
2540 }
2542
2543public:
2544 StringRef getName() const { return getStringOperand(0); }
2545 DIType *getType() const { return cast_or_null<DIType>(getRawType()); }
2546
2547 MDString *getRawName() const { return getOperandAs<MDString>(0); }
2548 Metadata *getRawType() const { return getOperand(1); }
2549 bool isDefault() const { return SubclassData1; }
2550
2551 static bool classof(const Metadata *MD) {
2552 return MD->getMetadataID() == DITemplateTypeParameterKind ||
2553 MD->getMetadataID() == DITemplateValueParameterKind;
2554 }
2555};
2556
2558 friend class LLVMContextImpl;
2559 friend class MDNode;
2560
2563 ~DITemplateTypeParameter() = default;
2564
2565 static DITemplateTypeParameter *getImpl(LLVMContext &Context, StringRef Name,
2566 DIType *Type, bool IsDefault,
2568 bool ShouldCreate = true) {
2569 return getImpl(Context, getCanonicalMDString(Context, Name), Type,
2570 IsDefault, Storage, ShouldCreate);
2571 }
2572 static DITemplateTypeParameter *getImpl(LLVMContext &Context, MDString *Name,
2573 Metadata *Type, bool IsDefault,
2575 bool ShouldCreate = true);
2576
2577 TempDITemplateTypeParameter cloneImpl() const {
2578 return getTemporary(getContext(), getName(), getType(), isDefault());
2579 }
2580
2581public:
2584 (Name, Type, IsDefault))
2588
2589 TempDITemplateTypeParameter clone() const { return cloneImpl(); }
2590
2591 static bool classof(const Metadata *MD) {
2592 return MD->getMetadataID() == DITemplateTypeParameterKind;
2593 }
2594};
2595
2597 friend class LLVMContextImpl;
2598 friend class MDNode;
2599
2601 unsigned Tag, bool IsDefault,
2603 : DITemplateParameter(Context, DITemplateValueParameterKind, Storage, Tag,
2604 IsDefault, Ops) {}
2605 ~DITemplateValueParameter() = default;
2606
2607 static DITemplateValueParameter *getImpl(LLVMContext &Context, unsigned Tag,
2609 bool IsDefault, Metadata *Value,
2611 bool ShouldCreate = true) {
2612 return getImpl(Context, Tag, getCanonicalMDString(Context, Name), Type,
2613 IsDefault, Value, Storage, ShouldCreate);
2614 }
2615 static DITemplateValueParameter *getImpl(LLVMContext &Context, unsigned Tag,
2616 MDString *Name, Metadata *Type,
2617 bool IsDefault, Metadata *Value,
2619 bool ShouldCreate = true);
2620
2621 TempDITemplateValueParameter cloneImpl() const {
2622 return getTemporary(getContext(), getTag(), getName(), getType(),
2623 isDefault(), getValue());
2624 }
2625
2626public:
2628 (unsigned Tag, StringRef Name, DIType *Type, bool IsDefault,
2629 Metadata *Value),
2630 (Tag, Name, Type, IsDefault, Value))
2635
2636 TempDITemplateValueParameter clone() const { return cloneImpl(); }
2637
2638 Metadata *getValue() const { return getOperand(2); }
2639
2640 static bool classof(const Metadata *MD) {
2641 return MD->getMetadataID() == DITemplateValueParameterKind;
2642 }
2643};
2644
2645/// Base class for variables.
2646///
2647/// Uses the SubclassData32 Metadata slot.
2648class DIVariable : public DINode {
2649 unsigned Line;
2650
2651protected:
2652 DIVariable(LLVMContext &C, unsigned ID, StorageType Storage, signed Line,
2653 ArrayRef<Metadata *> Ops, uint32_t AlignInBits = 0);
2654 ~DIVariable() = default;
2655
2656public:
2657 unsigned getLine() const { return Line; }
2658 DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
2659 StringRef getName() const { return getStringOperand(1); }
2660 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
2661 DIType *getType() const { return cast_or_null<DIType>(getRawType()); }
2663 uint32_t getAlignInBytes() const { return getAlignInBits() / CHAR_BIT; }
2664 /// Determines the size of the variable's type.
2665 std::optional<uint64_t> getSizeInBits() const;
2666
2667 /// Return the signedness of this variable's type, or std::nullopt if this
2668 /// type is neither signed nor unsigned.
2669 std::optional<DIBasicType::Signedness> getSignedness() const {
2670 if (auto *BT = dyn_cast<DIBasicType>(getType()))
2671 return BT->getSignedness();
2672 return std::nullopt;
2673 }
2674
2676 if (auto *F = getFile())
2677 return F->getFilename();
2678 return "";
2679 }
2680
2682 if (auto *F = getFile())
2683 return F->getDirectory();
2684 return "";
2685 }
2686
2687 std::optional<StringRef> getSource() const {
2688 if (auto *F = getFile())
2689 return F->getSource();
2690 return std::nullopt;
2691 }
2692
2693 Metadata *getRawScope() const { return getOperand(0); }
2694 MDString *getRawName() const { return getOperandAs<MDString>(1); }
2695 Metadata *getRawFile() const { return getOperand(2); }
2696 Metadata *getRawType() const { return getOperand(3); }
2697
2698 static bool classof(const Metadata *MD) {
2699 return MD->getMetadataID() == DILocalVariableKind ||
2700 MD->getMetadataID() == DIGlobalVariableKind;
2701 }
2702};
2703
2704/// DWARF expression.
2705///
2706/// This is (almost) a DWARF expression that modifies the location of a
2707/// variable, or the location of a single piece of a variable, or (when using
2708/// DW_OP_stack_value) is the constant variable value.
2709///
2710/// TODO: Co-allocate the expression elements.
2711/// TODO: Separate from MDNode, or otherwise drop Distinct and Temporary
2712/// storage types.
2713class DIExpression : public MDNode {
2714 friend class LLVMContextImpl;
2715 friend class MDNode;
2716
2717 std::vector<uint64_t> Elements;
2718
2720 : MDNode(C, DIExpressionKind, Storage, std::nullopt),
2721 Elements(Elements.begin(), Elements.end()) {}
2722 ~DIExpression() = default;
2723
2724 static DIExpression *getImpl(LLVMContext &Context,
2726 bool ShouldCreate = true);
2727
2728 TempDIExpression cloneImpl() const {
2729 return getTemporary(getContext(), getElements());
2730 }
2731
2732public:
2734
2735 TempDIExpression clone() const { return cloneImpl(); }
2736
2737 ArrayRef<uint64_t> getElements() const { return Elements; }
2738
2739 unsigned getNumElements() const { return Elements.size(); }
2740
2741 uint64_t getElement(unsigned I) const {
2742 assert(I < Elements.size() && "Index out of range");
2743 return Elements[I];
2744 }
2745
2747 /// Determine whether this represents a constant value, if so
2748 // return it's sign information.
2749 std::optional<SignedOrUnsignedConstant> isConstant() const;
2750
2751 /// Return the number of unique location operands referred to (via
2752 /// DW_OP_LLVM_arg) in this expression; this is not necessarily the number of
2753 /// instances of DW_OP_LLVM_arg within the expression.
2754 /// For example, for the expression:
2755 /// (DW_OP_LLVM_arg 0, DW_OP_LLVM_arg 1, DW_OP_plus,
2756 /// DW_OP_LLVM_arg 0, DW_OP_mul)
2757 /// This function would return 2, as there are two unique location operands
2758 /// (0 and 1).
2760
2762
2765
2766 /// A lightweight wrapper around an expression operand.
2767 ///
2768 /// TODO: Store arguments directly and change \a DIExpression to store a
2769 /// range of these.
2771 const uint64_t *Op = nullptr;
2772
2773 public:
2774 ExprOperand() = default;
2775 explicit ExprOperand(const uint64_t *Op) : Op(Op) {}
2776
2777 const uint64_t *get() const { return Op; }
2778
2779 /// Get the operand code.
2780 uint64_t getOp() const { return *Op; }
2781
2782 /// Get an argument to the operand.
2783 ///
2784 /// Never returns the operand itself.
2785 uint64_t getArg(unsigned I) const { return Op[I + 1]; }
2786
2787 unsigned getNumArgs() const { return getSize() - 1; }
2788
2789 /// Return the size of the operand.
2790 ///
2791 /// Return the number of elements in the operand (1 + args).
2792 unsigned getSize() const;
2793
2794 /// Append the elements of this operand to \p V.
2796 V.append(get(), get() + getSize());
2797 }
2798 };
2799
2800 /// An iterator for expression operands.
2803
2804 public:
2805 using iterator_category = std::input_iterator_tag;
2807 using difference_type = std::ptrdiff_t;
2810
2811 expr_op_iterator() = default;
2813
2814 element_iterator getBase() const { return Op.get(); }
2815 const ExprOperand &operator*() const { return Op; }
2816 const ExprOperand *operator->() const { return &Op; }
2817
2819 increment();
2820 return *this;
2821 }
2823 expr_op_iterator T(*this);
2824 increment();
2825 return T;
2826 }
2827
2828 /// Get the next iterator.
2829 ///
2830 /// \a std::next() doesn't work because this is technically an
2831 /// input_iterator, but it's a perfectly valid operation. This is an
2832 /// accessor to provide the same functionality.
2833 expr_op_iterator getNext() const { return ++expr_op_iterator(*this); }
2834
2835 bool operator==(const expr_op_iterator &X) const {
2836 return getBase() == X.getBase();
2837 }
2838 bool operator!=(const expr_op_iterator &X) const {
2839 return getBase() != X.getBase();
2840 }
2841
2842 private:
2843 void increment() { Op = ExprOperand(getBase() + Op.getSize()); }
2844 };
2845
2846 /// Visit the elements via ExprOperand wrappers.
2847 ///
2848 /// These range iterators visit elements through \a ExprOperand wrappers.
2849 /// This is not guaranteed to be a valid range unless \a isValid() gives \c
2850 /// true.
2851 ///
2852 /// \pre \a isValid() gives \c true.
2853 /// @{
2856 }
2859 }
2861 return {expr_op_begin(), expr_op_end()};
2862 }
2863 /// @}
2864
2865 bool isValid() const;
2866
2867 static bool classof(const Metadata *MD) {
2868 return MD->getMetadataID() == DIExpressionKind;
2869 }
2870
2871 /// Return whether the first element a DW_OP_deref.
2872 bool startsWithDeref() const;
2873
2874 /// Return whether there is exactly one operator and it is a DW_OP_deref;
2875 bool isDeref() const;
2876
2877 /// Holds the characteristics of one fragment of a larger variable.
2879 FragmentInfo() = default;
2884 /// Return the index of the first bit of the fragment.
2886 /// Return the index of the bit after the end of the fragment, e.g. for
2887 /// fragment offset=16 and size=32 return their sum, 48.
2889
2890 /// Returns a zero-sized fragment if A and B don't intersect.
2893 uint64_t StartInBits = std::max(A.OffsetInBits, B.OffsetInBits);
2894 uint64_t EndInBits = std::min(A.endInBits(), B.endInBits());
2895 if (EndInBits <= StartInBits)
2896 return {0, 0};
2897 return DIExpression::FragmentInfo(EndInBits - StartInBits, StartInBits);
2898 }
2899 };
2900
2901 /// Retrieve the details of this fragment expression.
2902 static std::optional<FragmentInfo> getFragmentInfo(expr_op_iterator Start,
2903 expr_op_iterator End);
2904
2905 /// Retrieve the details of this fragment expression.
2906 std::optional<FragmentInfo> getFragmentInfo() const {
2908 }
2909
2910 /// Return whether this is a piece of an aggregate variable.
2911 bool isFragment() const { return getFragmentInfo().has_value(); }
2912
2913 /// Return whether this is an implicit location description.
2914 bool isImplicit() const;
2915
2916 /// Return whether the location is computed on the expression stack, meaning
2917 /// it cannot be a simple register location.
2918 bool isComplex() const;
2919
2920 /// Return whether the evaluated expression makes use of a single location at
2921 /// the start of the expression, i.e. if it contains only a single
2922 /// DW_OP_LLVM_arg op as its first operand, or if it contains none.
2923 bool isSingleLocationExpression() const;
2924
2925 /// Returns a reference to the elements contained in this expression, skipping
2926 /// past the leading `DW_OP_LLVM_arg, 0` if one is present.
2927 /// Similar to `convertToNonVariadicExpression`, but faster and cheaper - it
2928 /// does not check whether the expression is a single-location expression, and
2929 /// it returns elements rather than creating a new DIExpression.
2930 std::optional<ArrayRef<uint64_t>> getSingleLocationExpressionElements() const;
2931
2932 /// Removes all elements from \p Expr that do not apply to an undef debug
2933 /// value, which includes every operator that computes the value/location on
2934 /// the DWARF stack, including any DW_OP_LLVM_arg elements (making the result
2935 /// of this function always a single-location expression) while leaving
2936 /// everything that defines what the computed value applies to, i.e. the
2937 /// fragment information.
2938 static const DIExpression *convertToUndefExpression(const DIExpression *Expr);
2939
2940 /// If \p Expr is a non-variadic expression (i.e. one that does not contain
2941 /// DW_OP_LLVM_arg), returns \p Expr converted to variadic form by adding a
2942 /// leading [DW_OP_LLVM_arg, 0] to the expression; otherwise returns \p Expr.
2943 static const DIExpression *
2945
2946 /// If \p Expr is a valid single-location expression, i.e. it refers to only a
2947 /// single debug operand at the start of the expression, then return that
2948 /// expression in a non-variadic form by removing DW_OP_LLVM_arg from the
2949 /// expression if it is present; otherwise returns std::nullopt.
2950 /// See also `getSingleLocationExpressionElements` above, which skips
2951 /// checking `isSingleLocationExpression` and returns a list of elements
2952 /// rather than a DIExpression.
2953 static std::optional<const DIExpression *>
2955
2956 /// Inserts the elements of \p Expr into \p Ops modified to a canonical form,
2957 /// which uses DW_OP_LLVM_arg (i.e. is a variadic expression) and folds the
2958 /// implied derefence from the \p IsIndirect flag into the expression. This
2959 /// allows us to check equivalence between expressions with differing
2960 /// directness or variadicness.
2962 const DIExpression *Expr,
2963 bool IsIndirect);
2964
2965 /// Determines whether two debug values should produce equivalent DWARF
2966 /// expressions, using their DIExpressions and directness, ignoring the
2967 /// differences between otherwise identical expressions in variadic and
2968 /// non-variadic form and not considering the debug operands.
2969 /// \p FirstExpr is the DIExpression for the first debug value.
2970 /// \p FirstIndirect should be true if the first debug value is indirect; in
2971 /// IR this should be true for dbg.declare intrinsics and false for
2972 /// dbg.values, and in MIR this should be true only for DBG_VALUE instructions
2973 /// whose second operand is an immediate value.
2974 /// \p SecondExpr and \p SecondIndirect have the same meaning as the prior
2975 /// arguments, but apply to the second debug value.
2976 static bool isEqualExpression(const DIExpression *FirstExpr,
2977 bool FirstIndirect,
2978 const DIExpression *SecondExpr,
2979 bool SecondIndirect);
2980
2981 /// Append \p Ops with operations to apply the \p Offset.
2982 static void appendOffset(SmallVectorImpl<uint64_t> &Ops, int64_t Offset);
2983
2984 /// If this is a constant offset, extract it. If there is no expression,
2985 /// return true with an offset of zero.
2986 bool extractIfOffset(int64_t &Offset) const;
2987
2988 /// Returns true iff this DIExpression contains at least one instance of
2989 /// `DW_OP_LLVM_arg, n` for all n in [0, N).
2990 bool hasAllLocationOps(unsigned N) const;
2991
2992 /// Checks if the last 4 elements of the expression are DW_OP_constu <DWARF
2993 /// Address Space> DW_OP_swap DW_OP_xderef and extracts the <DWARF Address
2994 /// Space>.
2995 static const DIExpression *extractAddressClass(const DIExpression *Expr,
2996 unsigned &AddrClass);
2997
2998 /// Used for DIExpression::prepend.
2999 enum PrependOps : uint8_t {
3001 DerefBefore = 1 << 0,
3002 DerefAfter = 1 << 1,
3003 StackValue = 1 << 2,
3004 EntryValue = 1 << 3
3006
3007 /// Prepend \p DIExpr with a deref and offset operation and optionally turn it
3008 /// into a stack value or/and an entry value.
3009 static DIExpression *prepend(const DIExpression *Expr, uint8_t Flags,
3010 int64_t Offset = 0);
3011
3012 /// Prepend \p DIExpr with the given opcodes and optionally turn it into a
3013 /// stack value.
3014 static DIExpression *prependOpcodes(const DIExpression *Expr,
3016 bool StackValue = false,
3017 bool EntryValue = false);
3018
3019 /// Append the opcodes \p Ops to \p DIExpr. Unlike \ref appendToStack, the
3020 /// returned expression is a stack value only if \p DIExpr is a stack value.
3021 /// If \p DIExpr describes a fragment, the returned expression will describe
3022 /// the same fragment.
3023 static DIExpression *append(const DIExpression *Expr, ArrayRef<uint64_t> Ops);
3024
3025 /// Convert \p DIExpr into a stack value if it isn't one already by appending
3026 /// DW_OP_deref if needed, and appending \p Ops to the resulting expression.
3027 /// If \p DIExpr describes a fragment, the returned expression will describe
3028 /// the same fragment.
3029 static DIExpression *appendToStack(const DIExpression *Expr,
3030 ArrayRef<uint64_t> Ops);
3031
3032 /// Create a copy of \p Expr by appending the given list of \p Ops to each
3033 /// instance of the operand `DW_OP_LLVM_arg, \p ArgNo`. This is used to
3034 /// modify a specific location used by \p Expr, such as when salvaging that
3035 /// location.
3036 static DIExpression *appendOpsToArg(const DIExpression *Expr,
3037 ArrayRef<uint64_t> Ops, unsigned ArgNo,
3038 bool StackValue = false);
3039
3040 /// Create a copy of \p Expr with each instance of
3041 /// `DW_OP_LLVM_arg, \p OldArg` replaced with `DW_OP_LLVM_arg, \p NewArg`,
3042 /// and each instance of `DW_OP_LLVM_arg, Arg` with `DW_OP_LLVM_arg, Arg - 1`
3043 /// for all Arg > \p OldArg.
3044 /// This is used when replacing one of the operands of a debug value list
3045 /// with another operand in the same list and deleting the old operand.
3046 static DIExpression *replaceArg(const DIExpression *Expr, uint64_t OldArg,
3047 uint64_t NewArg);
3048
3049 /// Create a DIExpression to describe one part of an aggregate variable that
3050 /// is fragmented across multiple Values. The DW_OP_LLVM_fragment operation
3051 /// will be appended to the elements of \c Expr. If \c Expr already contains
3052 /// a \c DW_OP_LLVM_fragment \c OffsetInBits is interpreted as an offset
3053 /// into the existing fragment.
3054 ///
3055 /// \param OffsetInBits Offset of the piece in bits.
3056 /// \param SizeInBits Size of the piece in bits.
3057 /// \return Creating a fragment expression may fail if \c Expr
3058 /// contains arithmetic operations that would be
3059 /// truncated.
3060 static std::optional<DIExpression *>
3061 createFragmentExpression(const DIExpression *Expr, unsigned OffsetInBits,
3062 unsigned SizeInBits);
3063
3064 /// Determine the relative position of the fragments passed in.
3065 /// Returns -1 if this is entirely before Other, 0 if this and Other overlap,
3066 /// 1 if this is entirely after Other.
3067 static int fragmentCmp(const FragmentInfo &A, const FragmentInfo &B) {
3068 uint64_t l1 = A.OffsetInBits;
3069 uint64_t l2 = B.OffsetInBits;
3070 uint64_t r1 = l1 + A.SizeInBits;
3071 uint64_t r2 = l2 + B.SizeInBits;
3072 if (r1 <= l2)
3073 return -1;
3074 else if (r2 <= l1)
3075 return 1;
3076 else
3077 return 0;
3078 }
3079
3080 using ExtOps = std::array<uint64_t, 6>;
3081
3082 /// Returns the ops for a zero- or sign-extension in a DIExpression.
3083 static ExtOps getExtOps(unsigned FromSize, unsigned ToSize, bool Signed);
3084
3085 /// Append a zero- or sign-extension to \p Expr. Converts the expression to a
3086 /// stack value if it isn't one already.
3087 static DIExpression *appendExt(const DIExpression *Expr, unsigned FromSize,
3088 unsigned ToSize, bool Signed);
3089
3090 /// Check if fragments overlap between a pair of FragmentInfos.
3091 static bool fragmentsOverlap(const FragmentInfo &A, const FragmentInfo &B) {
3092 return fragmentCmp(A, B) == 0;
3093 }
3094
3095 /// Determine the relative position of the fragments described by this
3096 /// DIExpression and \p Other. Calls static fragmentCmp implementation.
3097 int fragmentCmp(const DIExpression *Other) const {
3098 auto Fragment1 = *getFragmentInfo();
3099 auto Fragment2 = *Other->getFragmentInfo();
3100 return fragmentCmp(Fragment1, Fragment2);
3101 }
3102
3103 /// Check if fragments overlap between this DIExpression and \p Other.
3105 if (!isFragment() || !Other->isFragment())
3106 return true;
3107 return fragmentCmp(Other) == 0;
3108 }
3109
3110 /// Check if the expression consists of exactly one entry value operand.
3111 /// (This is the only configuration of entry values that is supported.)
3112 bool isEntryValue() const;
3113
3114 /// Try to shorten an expression with an initial constant operand.
3115 /// Returns a new expression and constant on success, or the original
3116 /// expression and constant on failure.
3117 std::pair<DIExpression *, const ConstantInt *>
3118 constantFold(const ConstantInt *CI);
3119};
3120
3123 return std::tie(A.SizeInBits, A.OffsetInBits) ==
3124 std::tie(B.SizeInBits, B.OffsetInBits);
3125}
3126
3129 return std::tie(A.SizeInBits, A.OffsetInBits) <
3130 std::tie(B.SizeInBits, B.OffsetInBits);
3131}
3132
3133template <> struct DenseMapInfo<DIExpression::FragmentInfo> {
3135 static const uint64_t MaxVal = std::numeric_limits<uint64_t>::max();
3136
3137 static inline FragInfo getEmptyKey() { return {MaxVal, MaxVal}; }
3138
3139 static inline FragInfo getTombstoneKey() { return {MaxVal - 1, MaxVal - 1}; }
3140
3141 static unsigned getHashValue(const FragInfo &Frag) {
3142 return (Frag.SizeInBits & 0xffff) << 16 | (Frag.OffsetInBits & 0xffff);
3143 }
3144
3145 static bool isEqual(const FragInfo &A, const FragInfo &B) { return A == B; }
3146};
3147
3148/// Global variables.
3149///
3150/// TODO: Remove DisplayName. It's always equal to Name.
3152 friend class LLVMContextImpl;
3153 friend class MDNode;
3154
3155 bool IsLocalToUnit;
3156 bool IsDefinition;
3157
3159 bool IsLocalToUnit, bool IsDefinition, uint32_t AlignInBits,
3161 : DIVariable(C, DIGlobalVariableKind, Storage, Line, Ops, AlignInBits),
3162 IsLocalToUnit(IsLocalToUnit), IsDefinition(IsDefinition) {}
3163 ~DIGlobalVariable() = default;
3164
3165 static DIGlobalVariable *
3166 getImpl(LLVMContext &Context, DIScope *Scope, StringRef Name,
3168 bool IsLocalToUnit, bool IsDefinition,
3171 bool ShouldCreate = true) {
3172 return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
3174 IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration,
3175 cast_or_null<Metadata>(TemplateParams), AlignInBits,
3176 Annotations.get(), Storage, ShouldCreate);
3177 }
3178 static DIGlobalVariable *
3179 getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
3180 MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type,
3181 bool IsLocalToUnit, bool IsDefinition,
3184 bool ShouldCreate = true);
3185
3186 TempDIGlobalVariable cloneImpl() const {
3191 getAnnotations());
3192 }
3193
3194public:
3198 unsigned Line, DIType *Type, bool IsLocalToUnit, bool IsDefinition,
3200 uint32_t AlignInBits, DINodeArray Annotations),
3201 (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition,
3206 unsigned Line, Metadata *Type, bool IsLocalToUnit, bool IsDefinition,
3209 (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition,
3211
3212 TempDIGlobalVariable clone() const { return cloneImpl(); }
3213
3214 bool isLocalToUnit() const { return IsLocalToUnit; }
3215 bool isDefinition() const { return IsDefinition; }
3219 return cast_or_null<DIDerivedType>(getRawStaticDataMemberDeclaration());
3220 }
3221 DINodeArray getAnnotations() const {
3222 return cast_or_null<MDTuple>(getRawAnnotations());
3223 }
3224
3225 MDString *getRawLinkageName() const { return getOperandAs<MDString>(5); }
3228 MDTuple *getTemplateParams() const { return getOperandAs<MDTuple>(7); }
3229 Metadata *getRawAnnotations() const { return getOperand(8); }
3230
3231 static bool classof(const Metadata *MD) {
3232 return MD->getMetadataID() == DIGlobalVariableKind;
3233 }
3234};
3235
3236/// Debug common block.
3237///
3238/// Uses the SubclassData32 Metadata slot.
3239class DICommonBlock : public DIScope {
3240 friend class LLVMContextImpl;
3241 friend class MDNode;
3242
3245
3246 static DICommonBlock *getImpl(LLVMContext &Context, DIScope *Scope,
3248 DIFile *File, unsigned LineNo,
3249 StorageType Storage, bool ShouldCreate = true) {
3250 return getImpl(Context, Scope, Decl, getCanonicalMDString(Context, Name),
3251 File, LineNo, Storage, ShouldCreate);
3252 }
3253 static DICommonBlock *getImpl(LLVMContext &Context, Metadata *Scope,
3255 unsigned LineNo, StorageType Storage,
3256 bool ShouldCreate = true);
3257
3258 TempDICommonBlock cloneImpl() const {
3260 getFile(), getLineNo());
3261 }
3262
3263public:
3266 DIFile *File, unsigned LineNo),
3267 (Scope, Decl, Name, File, LineNo))
3270 Metadata *File, unsigned LineNo),
3272
3273 TempDICommonBlock clone() const { return cloneImpl(); }
3274
3275 DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
3277 return cast_or_null<DIGlobalVariable>(getRawDecl());
3278 }
3279 StringRef getName() const { return getStringOperand(2); }
3280 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
3281 unsigned getLineNo() const { return SubclassData32; }
3282
3283 Metadata *getRawScope() const { return getOperand(0); }
3284 Metadata *getRawDecl() const { return getOperand(1); }
3285 MDString *getRawName() const { return getOperandAs<MDString>(2); }
3286 Metadata *getRawFile() const { return getOperand(3); }
3287
3288 static bool classof(const Metadata *MD) {
3289 return MD->getMetadataID() == DICommonBlockKind;
3290 }
3291};
3292
3293/// Local variable.
3294///
3295/// TODO: Split up flags.
3297 friend class LLVMContextImpl;
3298 friend class MDNode;
3299
3300 unsigned Arg : 16;
3301 DIFlags Flags;
3302
3304 unsigned Arg, DIFlags Flags, uint32_t AlignInBits,
3306 : DIVariable(C, DILocalVariableKind, Storage, Line, Ops, AlignInBits),
3307 Arg(Arg), Flags(Flags) {
3308 assert(Arg < (1 << 16) && "DILocalVariable: Arg out of range");
3309 }
3310 ~DILocalVariable() = default;
3311
3312 static DILocalVariable *getImpl(LLVMContext &Context, DIScope *Scope,
3313 StringRef Name, DIFile *File, unsigned Line,
3314 DIType *Type, unsigned Arg, DIFlags Flags,
3315 uint32_t AlignInBits, DINodeArray Annotations,
3317 bool ShouldCreate = true) {
3318 return getImpl(Context, Scope, getCanonicalMDString(Context, Name), File,
3319 Line, Type, Arg, Flags, AlignInBits, Annotations.get(),
3320 Storage, ShouldCreate);
3321 }
3322 static DILocalVariable *getImpl(LLVMContext &Context, Metadata *Scope,
3323 MDString *Name, Metadata *File, unsigned Line,
3324 Metadata *Type, unsigned Arg, DIFlags Flags,
3327 bool ShouldCreate = true);
3328
3329 TempDILocalVariable cloneImpl() const {
3331 getLine(), getType(), getArg(), getFlags(),
3333 }
3334
3335public:
3338 unsigned Line, DIType *Type, unsigned Arg, DIFlags Flags,
3339 uint32_t AlignInBits, DINodeArray Annotations),
3340 (Scope, Name, File, Line, Type, Arg, Flags, AlignInBits,
3341 Annotations))
3344 unsigned Line, Metadata *Type, unsigned Arg, DIFlags Flags,
3346 (Scope, Name, File, Line, Type, Arg, Flags, AlignInBits,
3347 Annotations))
3348
3349 TempDILocalVariable clone() const { return cloneImpl(); }
3350
3351 /// Get the local scope for this variable.
3352 ///
3353 /// Variables must be defined in a local scope.
3355 return cast<DILocalScope>(DIVariable::getScope());
3356 }
3357
3358 bool isParameter() const { return Arg; }
3359 unsigned getArg() const { return Arg; }
3360 DIFlags getFlags() const { return Flags; }
3361
3362 DINodeArray getAnnotations() const {
3363 return cast_or_null<MDTuple>(getRawAnnotations());
3364 }
3365 Metadata *getRawAnnotations() const { return getOperand(4); }
3366
3367 bool isArtificial() const { return getFlags() & FlagArtificial; }
3368 bool isObjectPointer() const { return getFlags() & FlagObjectPointer; }
3369
3370 /// Check that a location is valid for this variable.
3371 ///
3372 /// Check that \c DL exists, is in the same subprogram, and has the same
3373 /// inlined-at location as \c this. (Otherwise, it's not a valid attachment
3374 /// to a \a DbgInfoIntrinsic.)
3376 return DL && getScope()->getSubprogram() == DL->getScope()->getSubprogram();
3377 }
3378
3379 static bool classof(const Metadata *MD) {
3380 return MD->getMetadataID() == DILocalVariableKind;
3381 }
3382};
3383
3384/// Label.
3385///
3386/// Uses the SubclassData32 Metadata slot.
3387class DILabel : public DINode {
3388 friend class LLVMContextImpl;
3389 friend class MDNode;
3390
3393 ~DILabel() = default;
3394
3395 static DILabel *getImpl(LLVMContext &Context, DIScope *Scope, StringRef Name,
3396 DIFile *File, unsigned Line, StorageType Storage,
3397 bool ShouldCreate = true) {
3398 return getImpl(Context, Scope, getCanonicalMDString(Context, Name), File,
3399 Line, Storage, ShouldCreate);
3400 }
3401 static DILabel *getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
3402 Metadata *File, unsigned Line, StorageType Storage,
3403 bool ShouldCreate = true);
3404
3405 TempDILabel cloneImpl() const {
3407 getLine());
3408 }
3409
3410public:
3413 unsigned Line),
3414 (Scope, Name, File, Line))
3417 unsigned Line),
3419
3420 TempDILabel clone() const { return cloneImpl(); }
3421
3422 /// Get the local scope for this label.
3423 ///
3424 /// Labels must be defined in a local scope.
3426 return cast_or_null<DILocalScope>(getRawScope());
3427 }
3428 unsigned getLine() const { return SubclassData32; }
3429 StringRef getName() const { return getStringOperand(1); }
3430 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
3431
3432 Metadata *getRawScope() const { return getOperand(0); }
3433 MDString *getRawName() const { return getOperandAs<MDString>(1); }
3434 Metadata *getRawFile() const { return getOperand(2); }
3435
3436 /// Check that a location is valid for this label.
3437 ///
3438 /// Check that \c DL exists, is in the same subprogram, and has the same
3439 /// inlined-at location as \c this. (Otherwise, it's not a valid attachment
3440 /// to a \a DbgInfoIntrinsic.)
3442 return DL && getScope()->getSubprogram() == DL->getScope()->getSubprogram();
3443 }
3444
3445 static bool classof(const Metadata *MD) {
3446 return MD->getMetadataID() == DILabelKind;
3447 }
3448};
3449
3450class DIObjCProperty : public DINode {
3451 friend class LLVMContextImpl;
3452 friend class MDNode;
3453
3454 unsigned Line;
3455 unsigned Attributes;
3456
3458 unsigned Attributes, ArrayRef<Metadata *> Ops);
3459 ~DIObjCProperty() = default;
3460
3461 static DIObjCProperty *
3462 getImpl(LLVMContext &Context, StringRef Name, DIFile *File, unsigned Line,
3463 StringRef GetterName, StringRef SetterName, unsigned Attributes,
3464 DIType *Type, StorageType Storage, bool ShouldCreate = true) {
3465 return getImpl(Context, getCanonicalMDString(Context, Name), File, Line,
3467 getCanonicalMDString(Context, SetterName), Attributes, Type,
3468 Storage, ShouldCreate);
3469 }
3470 static DIObjCProperty *getImpl(LLVMContext &Context, MDString *Name,
3471 Metadata *File, unsigned Line,
3473 unsigned Attributes, Metadata *Type,
3474 StorageType Storage, bool ShouldCreate = true);
3475
3476 TempDIObjCProperty cloneImpl() const {
3477 return getTemporary(getContext(), getName(), getFile(), getLine(),
3479 getType());
3480 }
3481
3482public:
3484 (StringRef Name, DIFile *File, unsigned Line,
3486 unsigned Attributes, DIType *Type),
3487 (Name, File, Line, GetterName, SetterName, Attributes,
3488 Type))
3490 (MDString * Name, Metadata *File, unsigned Line,
3492 unsigned Attributes, Metadata *Type),
3493 (Name, File, Line, GetterName, SetterName, Attributes,
3494 Type))
3495
3496 TempDIObjCProperty clone() const { return cloneImpl(); }
3497
3498 unsigned getLine() const { return Line; }
3499 unsigned getAttributes() const { return Attributes; }
3500 StringRef getName() const { return getStringOperand(0); }
3501 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
3504 DIType *getType() const { return cast_or_null<DIType>(getRawType()); }
3505
3507 if (auto *F = getFile())
3508 return F->getFilename();
3509 return "";
3510 }
3511
3513 if (auto *F = getFile())
3514 return F->getDirectory();
3515 return "";
3516 }
3517
3518 MDString *getRawName() const { return getOperandAs<MDString>(0); }
3519 Metadata *getRawFile() const { return getOperand(1); }
3520 MDString *getRawGetterName() const { return getOperandAs<MDString>(2); }
3521 MDString *getRawSetterName() const { return getOperandAs<MDString>(3); }
3522 Metadata *getRawType() const { return getOperand(4); }
3523
3524 static bool classof(const Metadata *MD) {
3525 return MD->getMetadataID() == DIObjCPropertyKind;
3526 }
3527};
3528
3529/// An imported module (C++ using directive or similar).
3530///
3531/// Uses the SubclassData32 Metadata slot.
3532class DIImportedEntity : public DINode {
3533 friend class LLVMContextImpl;
3534 friend class MDNode;
3535
3537 unsigned Line, ArrayRef<Metadata *> Ops)
3538 : DINode(C, DIImportedEntityKind, Storage, Tag, Ops) {
3540 }
3541 ~DIImportedEntity() = default;
3542
3543 static DIImportedEntity *getImpl(LLVMContext &Context, unsigned Tag,
3545 unsigned Line, StringRef Name,
3546 DINodeArray Elements, StorageType Storage,
3547 bool ShouldCreate = true) {
3548 return getImpl(Context, Tag, Scope, Entity, File, Line,
3549 getCanonicalMDString(Context, Name), Elements.get(), Storage,
3550 ShouldCreate);
3551 }
3552 static DIImportedEntity *
3553 getImpl(LLVMContext &Context, unsigned Tag, Metadata *Scope, Metadata *Entity,
3554 Metadata *File, unsigned Line, MDString *Name, Metadata *Elements,
3555 StorageType Storage, bool ShouldCreate = true);
3556
3557 TempDIImportedEntity cloneImpl() const {
3558 return getTemporary(getContext(), getTag(), getScope(), getEntity(),
3559 getFile(), getLine(), getName(), getElements());
3560 }
3561
3562public:
3564 (unsigned Tag, DIScope *Scope, DINode *Entity, DIFile *File,
3565 unsigned Line, StringRef Name = "",
3566 DINodeArray Elements = nullptr),
3567 (Tag, Scope, Entity, File, Line, Name, Elements))
3571 Metadata *Elements = nullptr),
3572 (Tag, Scope, Entity, File, Line, Name, Elements))
3573
3574 TempDIImportedEntity clone() const { return cloneImpl(); }
3575
3576 unsigned getLine() const { return SubclassData32; }
3577 DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
3578 DINode *getEntity() const { return cast_or_null<DINode>(getRawEntity()); }
3579 StringRef getName() const { return getStringOperand(2); }
3580 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
3581 DINodeArray getElements() const {
3582 return cast_or_null<MDTuple>(getRawElements());
3583 }
3584
3585 Metadata *getRawScope() const { return getOperand(0); }
3586 Metadata *getRawEntity() const { return getOperand(1); }
3587 MDString *getRawName() const { return getOperandAs<MDString>(2); }
3588 Metadata *getRawFile() const { return getOperand(3); }
3589 Metadata *getRawElements() const { return getOperand(4); }
3590
3591 static bool classof(const Metadata *MD) {
3592 return MD->getMetadataID() == DIImportedEntityKind;
3593 }
3594};
3595
3596/// A pair of DIGlobalVariable and DIExpression.
3598 friend class LLVMContextImpl;
3599 friend class MDNode;
3600
3603 : MDNode(C, DIGlobalVariableExpressionKind, Storage, Ops) {}
3604 ~DIGlobalVariableExpression() = default;
3605
3607 getImpl(LLVMContext &Context, Metadata *Variable, Metadata *Expression,
3608 StorageType Storage, bool ShouldCreate = true);
3609
3610 TempDIGlobalVariableExpression cloneImpl() const {
3612 }
3613
3614public:
3616 (Metadata * Variable, Metadata *Expression),
3617 (Variable, Expression))
3618
3619 TempDIGlobalVariableExpression clone() const { return cloneImpl(); }
3620
3621 Metadata *getRawVariable() const { return getOperand(0); }
3622
3624 return cast_or_null<DIGlobalVariable>(getRawVariable());
3625 }
3626
3627 Metadata *getRawExpression() const { return getOperand(1); }
3628
3630 return cast<DIExpression>(getRawExpression());
3631 }
3632
3633 static bool classof(const Metadata *MD) {
3634 return MD->getMetadataID() == DIGlobalVariableExpressionKind;
3635 }
3636};
3637
3638/// Macro Info DWARF-like metadata node.
3639///
3640/// A metadata node with a DWARF macro info (i.e., a constant named
3641/// \c DW_MACINFO_*, defined in llvm/BinaryFormat/Dwarf.h). Called \a
3642/// DIMacroNode
3643/// because it's potentially used for non-DWARF output.
3644///
3645/// Uses the SubclassData16 Metadata slot.
3646class DIMacroNode : public MDNode {
3647 friend class LLVMContextImpl;
3648 friend class MDNode;
3649
3650protected:
3651 DIMacroNode(LLVMContext &C, unsigned ID, StorageType Storage, unsigned MIType,
3653 ArrayRef<Metadata *> Ops2 = std::nullopt)
3654 : MDNode(C, ID, Storage, Ops1, Ops2) {
3655 assert(MIType < 1u << 16);
3656 SubclassData16 = MIType;
3657 }
3658 ~DIMacroNode() = default;
3659
3660 template <class Ty> Ty *getOperandAs(unsigned I) const {
3661 return cast_or_null<Ty>(getOperand(I));
3662 }
3663
3664 StringRef getStringOperand(unsigned I) const {
3665 if (auto *S = getOperandAs<MDString>(I))
3666 return S->getString();
3667 return StringRef();
3668 }
3669
3671 if (S.empty())
3672 return nullptr;
3673 return MDString::get(Context, S);
3674 }
3675
3676public:
3677 unsigned getMacinfoType() const { return SubclassData16; }
3678
3679 static bool classof(const Metadata *MD) {
3680 switch (MD->getMetadataID()) {
3681 default:
3682 return false;
3683 case DIMacroKind:
3684 case DIMacroFileKind:
3685 return true;
3686 }
3687 }
3688};
3689
3690/// Macro
3691///
3692/// Uses the SubclassData32 Metadata slot.
3693class DIMacro : public DIMacroNode {
3694 friend class LLVMContextImpl;
3695 friend class MDNode;
3696
3697 DIMacro(LLVMContext &C, StorageType Storage, unsigned MIType, unsigned Line,
3699 : DIMacroNode(C, DIMacroKind, Storage, MIType, Ops) {
3701 }
3702 ~DIMacro() = default;
3703
3704 static DIMacro *getImpl(LLVMContext &Context, unsigned MIType, unsigned Line,
3706 bool ShouldCreate = true) {
3707 return getImpl(Context, MIType, Line, getCanonicalMDString(Context, Name),
3708 getCanonicalMDString(Context, Value), Storage, ShouldCreate);
3709 }
3710 static DIMacro *getImpl(LLVMContext &Context, unsigned MIType, unsigned Line,
3711 MDString *Name, MDString *Value, StorageType Storage,
3712 bool ShouldCreate = true);
3713
3714 TempDIMacro cloneImpl() const {
3716 getValue());
3717 }
3718
3719public:
3721 (unsigned MIType, unsigned Line, StringRef Name,
3722 StringRef Value = ""),
3723 (MIType, Line, Name, Value))
3725 (unsigned MIType, unsigned Line, MDString *Name,
3728
3729 TempDIMacro clone() const { return cloneImpl(); }
3730
3731 unsigned getLine() const { return SubclassData32; }
3732
3733 StringRef getName() const { return getStringOperand(0); }
3734 StringRef getValue() const { return getStringOperand(1); }
3735
3736 MDString *getRawName() const { return getOperandAs<MDString>(0); }
3737 MDString *getRawValue() const { return getOperandAs<MDString>(1); }
3738
3739 static bool classof(const Metadata *MD) {
3740 return MD->getMetadataID() == DIMacroKind;
3741 }
3742};
3743
3744/// Macro file
3745///
3746/// Uses the SubclassData32 Metadata slot.
3747class DIMacroFile : public DIMacroNode {
3748 friend class LLVMContextImpl;
3749 friend class MDNode;
3750
3752 unsigned Line, ArrayRef<Metadata *> Ops)
3753 : DIMacroNode(C, DIMacroFileKind, Storage, MIType, Ops) {
3755 }
3756 ~DIMacroFile() = default;
3757
3758 static DIMacroFile *getImpl(LLVMContext &Context, unsigned MIType,
3759 unsigned Line, DIFile *File,
3760 DIMacroNodeArray Elements, StorageType Storage,
3761 bool ShouldCreate = true) {
3762 return getImpl(Context, MIType, Line, static_cast<Metadata *>(File),
3763 Elements.get(), Storage, ShouldCreate);
3764 }
3765
3766 static DIMacroFile *getImpl(LLVMContext &Context, unsigned MIType,
3767 unsigned Line, Metadata *File, Metadata *Elements,
3768 StorageType Storage, bool ShouldCreate = true);
3769
3770 TempDIMacroFile cloneImpl() const {
3772 getElements());
3773 }
3774
3775public:
3777 (unsigned MIType, unsigned Line, DIFile *File,
3778 DIMacroNodeArray Elements),
3779 (MIType, Line, File, Elements))
3781 (unsigned MIType, unsigned Line, Metadata *File,
3784
3785 TempDIMacroFile clone() const { return cloneImpl(); }
3786
3787 void replaceElements(DIMacroNodeArray Elements) {
3788#ifndef NDEBUG
3789 for (DIMacroNode *Op : getElements())
3790 assert(is_contained(Elements->operands(), Op) &&
3791 "Lost a macro node during macro node list replacement");
3792#endif
3793 replaceOperandWith(1, Elements.get());
3794 }
3795
3796 unsigned getLine() const { return SubclassData32; }
3797 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
3798
3799 DIMacroNodeArray getElements() const {
3800 return cast_or_null<MDTuple>(getRawElements());
3801 }
3802
3803 Metadata *getRawFile() const { return getOperand(0); }
3804 Metadata *getRawElements() const { return getOperand(1); }
3805
3806 static bool classof(const Metadata *MD) {
3807 return MD->getMetadataID() == DIMacroFileKind;
3808 }
3809};
3810
3811/// List of ValueAsMetadata, to be used as an argument to a dbg.value
3812/// intrinsic.
3815 friend class LLVMContextImpl;
3817
3819
3821 : Metadata(DIArgListKind, Uniqued), ReplaceableMetadataImpl(Context),
3822 Args(Args.begin(), Args.end()) {
3823 track();
3824 }
3825 ~DIArgList() { untrack(); }
3826
3827 void track();
3828 void untrack();
3829 void dropAllReferences(bool Untrack);
3830
3831public:
3832 static DIArgList *get(LLVMContext &Context, ArrayRef<ValueAsMetadata *> Args);
3833
3834 ArrayRef<ValueAsMetadata *> getArgs() const { return Args; }
3835
3836 iterator args_begin() { return Args.begin(); }
3837 iterator args_end() { return Args.end(); }
3838
3839 static bool classof(const Metadata *MD) {
3840 return MD->getMetadataID() == DIArgListKind;
3841 }
3842
3845 }
3846
3847 void handleChangedOperand(void *Ref, Metadata *New);
3848};
3849
3850/// Identifies a unique instance of a variable.
3851///
3852/// Storage for identifying a potentially inlined instance of a variable,
3853/// or a fragment thereof. This guarantees that exactly one variable instance
3854/// may be identified by this class, even when that variable is a fragment of
3855/// an aggregate variable and/or there is another inlined instance of the same
3856/// source code variable nearby.
3857/// This class does not necessarily uniquely identify that variable: it is
3858/// possible that a DebugVariable with different parameters may point to the
3859/// same variable instance, but not that one DebugVariable points to multiple
3860/// variable instances.
3863
3864 const DILocalVariable *Variable;
3865 std::optional<FragmentInfo> Fragment;
3866 const DILocation *InlinedAt;
3867
3868 /// Fragment that will overlap all other fragments. Used as default when
3869 /// caller demands a fragment.
3870 static const FragmentInfo DefaultFragment;
3871
3872public:
3874 DebugVariable(const DbgVariableRecord *DVR);
3875
3877 std::optional<FragmentInfo> FragmentInfo,
3878 const DILocation *InlinedAt)
3879 : Variable(Var), Fragment(FragmentInfo), InlinedAt(InlinedAt) {}
3880
3881 DebugVariable(const DILocalVariable *Var, const DIExpression *DIExpr,
3882 const DILocation *InlinedAt)
3883 : Variable(Var),
3884 Fragment(DIExpr ? DIExpr->getFragmentInfo() : std::nullopt),
3885 InlinedAt(InlinedAt) {}
3886
3887 const DILocalVariable *getVariable() const { return Variable; }
3888 std::optional<FragmentInfo> getFragment() const { return Fragment; }
3889 const DILocation *getInlinedAt() const { return InlinedAt; }
3890
3892 return Fragment.value_or(DefaultFragment);
3893 }
3894
3895 static bool isDefaultFragment(const FragmentInfo F) {
3896 return F == DefaultFragment;
3897 }
3898
3899 bool operator==(const DebugVariable &Other) const {
3900 return std::tie(Variable, Fragment, InlinedAt) ==
3901 std::tie(Other.Variable, Other.Fragment, Other.InlinedAt);
3902 }
3903
3904 bool operator<(const DebugVariable &Other) const {
3905 return std::tie(Variable, Fragment, InlinedAt) <
3906 std::tie(Other.Variable, Other.Fragment, Other.InlinedAt);
3907 }
3908};
3909
3910template <> struct DenseMapInfo<DebugVariable> {
3912
3913 /// Empty key: no key should be generated that has no DILocalVariable.
3914 static inline DebugVariable getEmptyKey() {
3915 return DebugVariable(nullptr, std::nullopt, nullptr);
3916 }
3917
3918 /// Difference in tombstone is that the Optional is meaningful.
3920 return DebugVariable(nullptr, {{0, 0}}, nullptr);
3921 }
3922
3923 static unsigned getHashValue(const DebugVariable &D) {
3924 unsigned HV = 0;
3925 const std::optional<FragmentInfo> Fragment = D.getFragment();
3926 if (Fragment)
3928
3929 return hash_combine(D.getVariable(), HV, D.getInlinedAt());
3930 }
3931
3932 static bool isEqual(const DebugVariable &A, const DebugVariable &B) {
3933 return A == B;
3934 }
3935};
3936
3937/// Identifies a unique instance of a whole variable (discards/ignores fragment
3938/// information).
3940public:
3943 : DebugVariable(V.getVariable(), std::nullopt, V.getInlinedAt()) {}
3944};
3945
3946template <>
3948 : public DenseMapInfo<DebugVariable> {};
3949} // end namespace llvm
3950
3951#undef DEFINE_MDNODE_GET_UNPACK_IMPL
3952#undef DEFINE_MDNODE_GET_UNPACK
3953#undef DEFINE_MDNODE_GET
3954
3955#endif // LLVM_IR_DEBUGINFOMETADATA_H
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
AMDGPU Kernel Attributes
static std::string getLinkageName(GlobalValue::LinkageTypes LT)
Definition: AsmWriter.cpp:3252
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
#define DEFINE_MDNODE_GET(CLASS, FORMAL, ARGS)
#define DEFINE_MDNODE_GET_DISTINCT_TEMPORARY(CLASS, FORMAL, ARGS)
static RegisterPass< DebugifyFunctionPass > DF("debugify-function", "Attach debug info to a function")
static unsigned getNextComponentInDiscriminator(unsigned D)
Returns the next component stored in discriminator.
Definition: Discriminator.h:38
static unsigned getUnsignedFromPrefixEncoding(unsigned U)
Reverse transformation as getPrefixEncodingFromUnsigned.
Definition: Discriminator.h:30
std::string Name
bool End
Definition: ELF_riscv.cpp:480
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
static SmallString< 128 > getFilename(const DISubprogram *SP)
Extract a filename for a DISubprogram.
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
This file contains the declarations for metadata subclasses.
#define T
LLVMContext & Context
This file defines the PointerUnion class, which is a discriminated union of pointer types.
static StringRef getName(Value *V)
static void r2(uint32_t &A, uint32_t &B, uint32_t &C, uint32_t &D, uint32_t &E, int I, uint32_t *Buf)
Definition: SHA1.cpp:51
static void r1(uint32_t &A, uint32_t &B, uint32_t &C, uint32_t &D, uint32_t &E, int I, uint32_t *Buf)
Definition: SHA1.cpp:45
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static SPIRV::Scope::Scope getScope(SyncScope::ID Ord, SPIRVMachineModuleInfo *MMI)
This file contains some templates that are useful if you are working with the STL at all.
static enum BaseType getBaseType(const Value *Val)
Return the baseType for Val which states whether Val is exclusively derived from constant/null,...
This file defines the SmallVector class.
static uint32_t getFlags(const Symbol *Sym)
Definition: TapiFile.cpp:27
static SymbolRef::Type getType(const Symbol *Sym)
Definition: TapiFile.cpp:40
Class for arbitrary precision integers.
Definition: APInt.h:76
Annotations lets you mark points and ranges inside source code, for tests:
Definition: Annotations.h:53
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
iterator end() const
Definition: ArrayRef.h:154
iterator begin() const
Definition: ArrayRef.h:153
This is the shared class of boolean and integer constants.
Definition: Constants.h:80
This is an important base class in LLVM.
Definition: Constant.h:41
List of ValueAsMetadata, to be used as an argument to a dbg.value intrinsic.
ArrayRef< ValueAsMetadata * > getArgs() const
void handleChangedOperand(void *Ref, Metadata *New)
static bool classof(const Metadata *MD)
static DIArgList * get(LLVMContext &Context, ArrayRef< ValueAsMetadata * > Args)
SmallVector< DbgVariableRecord * > getAllDbgVariableRecordUsers()
Assignment ID.
static bool classof(const Metadata *MD)
SmallVector< DbgVariableRecord * > getAllDbgVariableRecordUsers()
static TempDIAssignID getTemporary(LLVMContext &Context)
static DIAssignID * getDistinct(LLVMContext &Context)
void replaceOperandWith(unsigned I, Metadata *New)=delete
Basic type, like 'int' or 'float'.
unsigned StringRef uint64_t FlagZero unsigned StringRef uint64_t uint32_t unsigned DIFlags Flags
DEFINE_MDNODE_GET(DIBasicType,(unsigned Tag, StringRef Name),(Tag, Name, 0, 0, 0, FlagZero)) DEFINE_MDNODE_GET(DIBasicType
static bool classof(const Metadata *MD)
unsigned StringRef uint64_t SizeInBits
std::optional< Signedness > getSignedness() const
Return the signedness of this type, or std::nullopt if this type is neither signed nor unsigned.
unsigned getEncoding() const
unsigned StringRef Name
unsigned StringRef uint64_t FlagZero unsigned StringRef uint64_t uint32_t AlignInBits
Debug common block.
Metadata * getRawScope() const
Metadata Metadata MDString Metadata unsigned LineNo TempDICommonBlock clone() const
Metadata * getRawDecl() const
Metadata Metadata * Decl
Metadata * getRawFile() const
Metadata Metadata MDString Metadata unsigned LineNo
Metadata Metadata MDString * Name
MDString * getRawName() const
DIFile * getFile() const
static bool classof(const Metadata *MD)
unsigned getLineNo() const
Metadata Metadata MDString Metadata * File
StringRef getName() const
DIScope * getScope() const
DEFINE_MDNODE_GET(DICommonBlock,(DIScope *Scope, DIGlobalVariable *Decl, StringRef Name, DIFile *File, unsigned LineNo),(Scope, Decl, Name, File, LineNo)) DEFINE_MDNODE_GET(DICommonBlock
DIGlobalVariable * getDecl() const
MDString * getRawSplitDebugFilename() const
bool getDebugInfoForProfiling() const
Metadata * getRawRetainedTypes() const
static const char * nameTableKindString(DebugNameTableKind PK)
static const char * emissionKindString(DebugEmissionKind EK)
void setSplitDebugInlining(bool SplitDebugInlining)
DICompositeTypeArray getEnumTypes() const
DebugEmissionKind getEmissionKind() const
unsigned Metadata * File
unsigned Metadata MDString bool MDString unsigned MDString unsigned Metadata Metadata Metadata Metadata Metadata * Macros
unsigned Metadata MDString bool MDString * Flags
bool isDebugDirectivesOnly() const
StringRef getFlags() const
MDString * getRawProducer() const
void replaceEnumTypes(DICompositeTypeArray N)
Replace arrays.
MDString * getRawSysRoot() const
unsigned Metadata MDString bool MDString unsigned MDString unsigned Metadata * EnumTypes
unsigned Metadata MDString bool MDString unsigned MDString unsigned Metadata Metadata * RetainedTypes
StringRef getSDK() const
static void getIfExists()=delete
bool getRangesBaseAddress() const
DIMacroNodeArray getMacros() const
unsigned getRuntimeVersion() const
Metadata * getRawMacros() const
void replaceRetainedTypes(DITypeArray N)
static bool classof(const Metadata *MD)
void replaceGlobalVariables(DIGlobalVariableExpressionArray N)
void replaceMacros(DIMacroNodeArray N)
bool getSplitDebugInlining() const
StringRef getSysRoot() const
DebugNameTableKind getNameTableKind() const
MDString * getRawSDK() const
MDString * getRawFlags() const
unsigned Metadata MDString bool MDString unsigned MDString unsigned Metadata Metadata Metadata * GlobalVariables
DIImportedEntityArray getImportedEntities() const
unsigned Metadata MDString bool MDString unsigned MDString unsigned Metadata Metadata Metadata Metadata Metadata uint64_t bool bool unsigned bool MDString MDString * SDK
unsigned Metadata MDString * Producer
Metadata * getRawEnumTypes() const
unsigned Metadata MDString bool MDString unsigned MDString unsigned Metadata Metadata Metadata Metadata Metadata uint64_t bool bool unsigned bool MDString * SysRoot
StringRef getProducer() const
unsigned Metadata MDString bool MDString unsigned MDString * SplitDebugFilename
unsigned Metadata MDString bool MDString unsigned MDString unsigned Metadata Metadata Metadata Metadata * ImportedEntities
void setDWOId(uint64_t DwoId)
DIScopeArray getRetainedTypes() const
void replaceImportedEntities(DIImportedEntityArray N)
Metadata * getRawGlobalVariables() const
DIGlobalVariableExpressionArray getGlobalVariables() const
unsigned Metadata MDString bool MDString unsigned MDString unsigned Metadata Metadata Metadata Metadata Metadata uint64_t bool bool unsigned bool MDString MDString SDK TempDICompileUnit clone() const
unsigned getSourceLanguage() const
Metadata * getRawImportedEntities() const
uint64_t getDWOId() const
StringRef getSplitDebugFilename() const
static void get()=delete
DEFINE_MDNODE_GET_DISTINCT_TEMPORARY(DICompileUnit,(unsigned SourceLanguage, DIFile *File, StringRef Producer, bool IsOptimized, StringRef Flags, unsigned RuntimeVersion, StringRef SplitDebugFilename, DebugEmissionKind EmissionKind, DICompositeTypeArray EnumTypes, DIScopeArray RetainedTypes, DIGlobalVariableExpressionArray GlobalVariables, DIImportedEntityArray ImportedEntities, DIMacroNodeArray Macros, uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling, DebugNameTableKind NameTableKind, bool RangesBaseAddress, StringRef SysRoot, StringRef SDK),(SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes, RetainedTypes, GlobalVariables, ImportedEntities, Macros, DWOId, SplitDebugInlining, DebugInfoForProfiling,(unsigned) NameTableKind, RangesBaseAddress, SysRoot, SDK)) DEFINE_MDNODE_GET_DISTINCT_TEMPORARY(DICompileUnit
unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t AlignInBits
Metadata * getRawVTableHolder() const
DIExpression * getRankExp() const
unsigned MDString Metadata unsigned Line
Metadata * getRawRank() const
unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata * Elements
unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata unsigned Metadata Metadata * TemplateParams
DIExpression * getAssociatedExp() const
DIVariable * getAllocated() const
DIExpression * getDataLocationExp() const
Metadata * getRawDiscriminator() const
unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata unsigned Metadata Metadata MDString Metadata Metadata Metadata Metadata Metadata * Rank
static DICompositeType * getODRTypeIfExists(LLVMContext &Context, MDString &Identifier)
DIVariable * getAssociated() const
DIDerivedType * getDiscriminator() const
DIVariable * getDataLocation() const
unsigned getRuntimeLang() const
DEFINE_MDNODE_GET(DICompositeType,(unsigned Tag, StringRef Name, DIFile *File, unsigned Line, DIScope *Scope, DIType *BaseType, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags, DINodeArray Elements, unsigned RuntimeLang, DIType *VTableHolder, DITemplateParameterArray TemplateParams=nullptr, StringRef Identifier="", DIDerivedType *Discriminator=nullptr, Metadata *DataLocation=nullptr, Metadata *Associated=nullptr, Metadata *Allocated=nullptr, Metadata *Rank=nullptr, DINodeArray Annotations=nullptr),(Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams, Identifier, Discriminator, DataLocation, Associated, Allocated, Rank, Annotations)) DEFINE_MDNODE_GET(DICompositeType
Metadata * getRawElements() const
unsigned MDString * Name
void replaceVTableHolder(DIType *VTableHolder)
static DICompositeType * buildODRType(LLVMContext &Context, MDString &Identifier, unsigned Tag, MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated, Metadata *Allocated, Metadata *Rank, Metadata *Annotations)
Build a DICompositeType with the given ODR identifier.
StringRef getIdentifier() const
unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t OffsetInBits
unsigned MDString Metadata unsigned Metadata * Scope
unsigned MDString Metadata * File
Metadata * getRawDataLocation() const
Metadata * getRawTemplateParams() const
unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata unsigned Metadata Metadata MDString Metadata Metadata Metadata Metadata * Allocated
unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Flags
DINodeArray getElements() const
DITemplateParameterArray getTemplateParams() const
unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata unsigned Metadata Metadata MDString Metadata * Discriminator
Metadata * getRawAnnotations() const
Metadata * getRawAllocated() const
unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata unsigned Metadata Metadata MDString Metadata Metadata Metadata Metadata Metadata Metadata * Annotations
DIExpression * getAllocatedExp() const
void replaceElements(DINodeArray Elements)
Replace operands.
unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata unsigned Metadata Metadata MDString Metadata Metadata * DataLocation
unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata unsigned Metadata Metadata MDString * Identifier
unsigned MDString Metadata unsigned Metadata Metadata uint64_t SizeInBits
DIType * getVTableHolder() const
unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata unsigned Metadata Metadata MDString Metadata Metadata Metadata * Associated
DINodeArray getAnnotations() const
Metadata * getRawAssociated() const
ConstantInt * getRankConst() const
void replaceTemplateParams(DITemplateParameterArray TemplateParams)
Metadata * getRawBaseType() const
MDString * getRawIdentifier() const
static bool classof(const Metadata *MD)
unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata unsigned Metadata * VTableHolder
DIType * getBaseType() const
Metadata * getRawExtraData() const
DINodeArray getAnnotations() const
Get annotations associated with this derived type.
unsigned StringRef DIFile unsigned DIScope DIType uint64_t uint32_t uint64_t std::optional< unsigned > std::optional< PtrAuthData > DIFlags Metadata * ExtraData
unsigned StringRef DIFile unsigned DIScope DIType uint64_t SizeInBits
Metadata * getExtraData() const
Get extra data associated with this derived type.
unsigned StringRef DIFile unsigned DIScope DIType uint64_t uint32_t uint64_t std::optional< unsigned > std::optional< PtrAuthData > DIFlags Metadata DINodeArray Annotations
unsigned StringRef DIFile * File
unsigned StringRef DIFile unsigned DIScope DIType uint64_t uint32_t uint64_t OffsetInBits
DIObjCProperty * getObjCProperty() const
unsigned StringRef DIFile unsigned DIScope DIType uint64_t uint32_t AlignInBits
unsigned StringRef DIFile unsigned DIScope * Scope
Metadata * getRawAnnotations() const
DIType * getClassType() const
Get casted version of extra data.
static bool classof(const Metadata *MD)
Constant * getConstant() const
Constant * getStorageOffsetInBits() const
Constant * getDiscriminantValue() const
unsigned StringRef Name
uint32_t getVBPtrOffset() const
unsigned StringRef DIFile unsigned DIScope DIType uint64_t uint32_t uint64_t std::optional< unsigned > std::optional< PtrAuthData > DIFlags Flags
unsigned StringRef DIFile unsigned Line
DEFINE_MDNODE_GET(DIDerivedType,(unsigned Tag, MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, std::optional< unsigned > DWARFAddressSpace, std::optional< PtrAuthData > PtrAuthData, DIFlags Flags, Metadata *ExtraData=nullptr, Metadata *Annotations=nullptr),(Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, DWARFAddressSpace, PtrAuthData, Flags, ExtraData, Annotations)) DEFINE_MDNODE_GET(DIDerivedType
Enumeration value.
int64_t bool MDString APInt(64, Value, !IsUnsigned)
const APInt & getValue() const
int64_t bool MDString Name APInt bool MDString Name TempDIEnumerator clone() const
MDString * getRawName() const
StringRef getName() const
DEFINE_MDNODE_GET(DIEnumerator,(int64_t Value, bool IsUnsigned, StringRef Name),(APInt(64, Value, !IsUnsigned), IsUnsigned, Name)) DEFINE_MDNODE_GET(DIEnumerator
static bool classof(const Metadata *MD)
int64_t bool MDString * Name
A lightweight wrapper around an expression operand.
unsigned getSize() const
Return the size of the operand.
uint64_t getArg(unsigned I) const
Get an argument to the operand.
uint64_t getOp() const
Get the operand code.
const uint64_t * get() const
void appendToVector(SmallVectorImpl< uint64_t > &V) const
Append the elements of this operand to V.
An iterator for expression operands.
bool operator==(const expr_op_iterator &X) const
std::input_iterator_tag iterator_category
const ExprOperand * operator->() const
bool operator!=(const expr_op_iterator &X) const
const ExprOperand & operator*() const
expr_op_iterator getNext() const
Get the next iterator.
DWARF expression.
element_iterator elements_end() const
bool isEntryValue() const
Check if the expression consists of exactly one entry value operand.
iterator_range< expr_op_iterator > expr_ops() const
bool isFragment() const
Return whether this is a piece of an aggregate variable.
static DIExpression * append(const DIExpression *Expr, ArrayRef< uint64_t > Ops)
Append the opcodes Ops to DIExpr.
std::array< uint64_t, 6 > ExtOps
unsigned getNumElements() const
ArrayRef< uint64_t >::iterator element_iterator
static ExtOps getExtOps(unsigned FromSize, unsigned ToSize, bool Signed)
Returns the ops for a zero- or sign-extension in a DIExpression.
expr_op_iterator expr_op_begin() const
Visit the elements via ExprOperand wrappers.
bool extractIfOffset(int64_t &Offset) const
If this is a constant offset, extract it.
static void appendOffset(SmallVectorImpl< uint64_t > &Ops, int64_t Offset)
Append Ops with operations to apply the Offset.
int fragmentCmp(const DIExpression *Other) const
Determine the relative position of the fragments described by this DIExpression and Other.
bool startsWithDeref() const
Return whether the first element a DW_OP_deref.
static bool isEqualExpression(const DIExpression *FirstExpr, bool FirstIndirect, const DIExpression *SecondExpr, bool SecondIndirect)
Determines whether two debug values should produce equivalent DWARF expressions, using their DIExpres...
expr_op_iterator expr_op_end() const
bool isImplicit() const
Return whether this is an implicit location description.
DEFINE_MDNODE_GET(DIExpression,(ArrayRef< uint64_t > Elements),(Elements)) TempDIExpression clone() const
static bool fragmentsOverlap(const FragmentInfo &A, const FragmentInfo &B)
Check if fragments overlap between a pair of FragmentInfos.
element_iterator elements_begin() const
bool hasAllLocationOps(unsigned N) const
Returns true iff this DIExpression contains at least one instance of DW_OP_LLVM_arg,...
std::optional< FragmentInfo > getFragmentInfo() const
Retrieve the details of this fragment expression.
static DIExpression * appendOpsToArg(const DIExpression *Expr, ArrayRef< uint64_t > Ops, unsigned ArgNo, bool StackValue=false)
Create a copy of Expr by appending the given list of Ops to each instance of the operand DW_OP_LLVM_a...
PrependOps
Used for DIExpression::prepend.
static int fragmentCmp(const FragmentInfo &A, const FragmentInfo &B)
Determine the relative position of the fragments passed in.
bool isComplex() const
Return whether the location is computed on the expression stack, meaning it cannot be a simple regist...
bool fragmentsOverlap(const DIExpression *Other) const
Check if fragments overlap between this DIExpression and Other.
static std::optional< const DIExpression * > convertToNonVariadicExpression(const DIExpression *Expr)
If Expr is a valid single-location expression, i.e.
std::pair< DIExpression *, const ConstantInt * > constantFold(const ConstantInt *CI)
Try to shorten an expression with an initial constant operand.
bool isDeref() const
Return whether there is exactly one operator and it is a DW_OP_deref;.
static const DIExpression * convertToVariadicExpression(const DIExpression *Expr)
If Expr is a non-variadic expression (i.e.
uint64_t getNumLocationOperands() const
Return the number of unique location operands referred to (via DW_OP_LLVM_arg) in this expression; th...
ArrayRef< uint64_t > getElements() const
static DIExpression * replaceArg(const DIExpression *Expr, uint64_t OldArg, uint64_t NewArg)
Create a copy of Expr with each instance of DW_OP_LLVM_arg, \p OldArg replaced with DW_OP_LLVM_arg,...
static bool classof(const Metadata *MD)
static void canonicalizeExpressionOps(SmallVectorImpl< uint64_t > &Ops, const DIExpression *Expr, bool IsIndirect)
Inserts the elements of Expr into Ops modified to a canonical form, which uses DW_OP_LLVM_arg (i....
uint64_t getElement(unsigned I) const
static std::optional< DIExpression * > createFragmentExpression(const DIExpression *Expr, unsigned OffsetInBits, unsigned SizeInBits)
Create a DIExpression to describe one part of an aggregate variable that is fragmented across multipl...
static const DIExpression * convertToUndefExpression(const DIExpression *Expr)
Removes all elements from Expr that do not apply to an undef debug value, which includes every operat...
static DIExpression * prepend(const DIExpression *Expr, uint8_t Flags, int64_t Offset=0)
Prepend DIExpr with a deref and offset operation and optionally turn it into a stack value or/and an ...
static DIExpression * appendToStack(const DIExpression *Expr, ArrayRef< uint64_t > Ops)
Convert DIExpr into a stack value if it isn't one already by appending DW_OP_deref if needed,...
static DIExpression * appendExt(const DIExpression *Expr, unsigned FromSize, unsigned ToSize, bool Signed)
Append a zero- or sign-extension to Expr.
std::optional< ArrayRef< uint64_t > > getSingleLocationExpressionElements() const
Returns a reference to the elements contained in this expression, skipping past the leading DW_OP_LLV...
bool isSingleLocationExpression() const
Return whether the evaluated expression makes use of a single location at the start of the expression...
std::optional< SignedOrUnsignedConstant > isConstant() const
Determine whether this represents a constant value, if so.
static const DIExpression * extractAddressClass(const DIExpression *Expr, unsigned &AddrClass)
Checks if the last 4 elements of the expression are DW_OP_constu <DWARF Address Space> DW_OP_swap DW_...
static DIExpression * prependOpcodes(const DIExpression *Expr, SmallVectorImpl< uint64_t > &Ops, bool StackValue=false, bool EntryValue=false)
Prepend DIExpr with the given opcodes and optionally turn it into a stack value.
static bool classof(const Metadata *MD)
MDString MDString * Directory
DEFINE_MDNODE_GET(DIFile,(StringRef Filename, StringRef Directory, std::optional< ChecksumInfo< StringRef > > CS=std::nullopt, std::optional< StringRef > Source=std::nullopt),(Filename, Directory, CS, Source)) DEFINE_MDNODE_GET(DIFile
MDString * Filename
static std::optional< ChecksumKind > getChecksumKind(StringRef CSKindStr)
ChecksumKind
Which algorithm (e.g.
MDString MDString std::optional< ChecksumInfo< MDString * > > CS
Metadata * getRawLowerBound() const
Metadata * getRawCountNode() const
Metadata * getRawStride() const
BoundType getLowerBound() const
DEFINE_MDNODE_GET(DIGenericSubrange,(Metadata *CountNode, Metadata *LowerBound, Metadata *UpperBound, Metadata *Stride),(CountNode, LowerBound, UpperBound, Stride)) TempDIGenericSubrange clone() const
Metadata * getRawUpperBound() const
static bool classof(const Metadata *MD)
BoundType getUpperBound() const
A pair of DIGlobalVariable and DIExpression.
DEFINE_MDNODE_GET(DIGlobalVariableExpression,(Metadata *Variable, Metadata *Expression),(Variable, Expression)) TempDIGlobalVariableExpression clone() const
DIGlobalVariable * getVariable() const
static bool classof(const Metadata *MD)
DIExpression * getExpression() const
Metadata * getRawAnnotations() const
Metadata MDString MDString Metadata unsigned Metadata bool bool Metadata Metadata * TemplateParams
Metadata MDString MDString Metadata unsigned Line
Metadata MDString MDString Metadata unsigned Metadata * Type
Metadata MDString MDString Metadata unsigned Metadata bool bool Metadata Metadata uint32_t Metadata * Annotations
DIDerivedType * getStaticDataMemberDeclaration() const
DEFINE_MDNODE_GET(DIGlobalVariable,(DIScope *Scope, StringRef Name, StringRef LinkageName, DIFile *File, unsigned Line, DIType *Type, bool IsLocalToUnit, bool IsDefinition, DIDerivedType *StaticDataMemberDeclaration, MDTuple *TemplateParams, uint32_t AlignInBits, DINodeArray Annotations),(Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration, TemplateParams, AlignInBits, Annotations)) DEFINE_MDNODE_GET(DIGlobalVariable
Metadata MDString MDString Metadata unsigned Metadata bool bool Metadata Metadata uint32_t Metadata Annotations TempDIGlobalVariable clone() const
Metadata MDString * Name
MDTuple * getTemplateParams() const
Metadata MDString MDString Metadata unsigned Metadata bool bool Metadata * StaticDataMemberDeclaration
Metadata * getRawStaticDataMemberDeclaration() const
Metadata MDString MDString * LinkageName
MDString * getRawLinkageName() const
StringRef getLinkageName() const
static bool classof(const Metadata *MD)
StringRef getDisplayName() const
Metadata MDString MDString Metadata * File
DINodeArray getAnnotations() const
Metadata * getRawTemplateParams() const
Metadata MDString MDString Metadata unsigned Metadata bool bool Metadata Metadata uint32_t AlignInBits
An imported module (C++ using directive or similar).
unsigned Metadata Metadata * Entity
DEFINE_MDNODE_GET(DIImportedEntity,(unsigned Tag, DIScope *Scope, DINode *Entity, DIFile *File, unsigned Line, StringRef Name="", DINodeArray Elements=nullptr),(Tag, Scope, Entity, File, Line, Name, Elements)) DEFINE_MDNODE_GET(DIImportedEntity
unsigned Metadata Metadata Metadata unsigned Line
unsigned Metadata Metadata Metadata unsigned MDString * Name
unsigned Metadata Metadata Metadata * File
unsigned Metadata * Scope
DIFile * getFile() const
StringRef getName() const
static bool classof(const Metadata *MD)
unsigned getLine() const
Metadata MDString Metadata unsigned Line TempDILabel clone() const
DEFINE_MDNODE_GET(DILabel,(DILocalScope *Scope, StringRef Name, DIFile *File, unsigned Line),(Scope, Name, File, Line)) DEFINE_MDNODE_GET(DILabel
Metadata * getRawFile() const
DILocalScope * getScope() const
Get the local scope for this label.
MDString * getRawName() const
Metadata MDString Metadata unsigned Line
Metadata MDString * Name
bool isValidLocationForIntrinsic(const DILocation *DL) const
Check that a location is valid for this label.
Metadata * getRawScope() const
Metadata MDString Metadata * File
static bool classof(const Metadata *MD)
void replaceScope(DIScope *Scope)
Metadata * getRawScope() const
DILocalScope * getScope() const
Metadata Metadata unsigned Discriminator
static bool classof(const Metadata *MD)
unsigned getDiscriminator() const
Metadata Metadata unsigned Discriminator TempDILexicalBlockFile clone() const
Metadata Metadata * File
DEFINE_MDNODE_GET(DILexicalBlockFile,(DILocalScope *Scope, DIFile *File, unsigned Discriminator),(Scope, File, Discriminator)) DEFINE_MDNODE_GET(DILexicalBlockFile
Debug lexical block.
Metadata Metadata unsigned Line
unsigned getLine() const
DEFINE_MDNODE_GET(DILexicalBlock,(DILocalScope *Scope, DIFile *File, unsigned Line, unsigned Column),(Scope, File, Line, Column)) DEFINE_MDNODE_GET(DILexicalBlock
static bool classof(const Metadata *MD)
Metadata Metadata * File
unsigned getColumn() const
Metadata Metadata unsigned unsigned Column TempDILexicalBlock clone() const
A scope for locals.
DISubprogram * getSubprogram() const
Get the subprogram for this scope.
DILocalScope * getNonLexicalBlockFileScope() const
Get the first non DILexicalBlockFile scope of this scope.
~DILocalScope()=default
DILocalScope(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag, ArrayRef< Metadata * > Ops)
static bool classof(const Metadata *MD)
static DILocalScope * cloneScopeForSubprogram(DILocalScope &RootScope, DISubprogram &NewSP, LLVMContext &Ctx, DenseMap< const MDNode *, MDNode * > &Cache)
Traverses the scope chain rooted at RootScope until it hits a Subprogram, recreating the chain with "...
Metadata MDString Metadata unsigned Metadata * Type
Metadata MDString Metadata * File
static bool classof(const Metadata *MD)
Metadata MDString Metadata unsigned Metadata unsigned DIFlags uint32_t Metadata Annotations TempDILocalVariable clone() const
DILocalScope * getScope() const
Get the local scope for this variable.
Metadata MDString * Name
DINodeArray getAnnotations() const
DEFINE_MDNODE_GET(DILocalVariable,(DILocalScope *Scope, StringRef Name, DIFile *File, unsigned Line, DIType *Type, unsigned Arg, DIFlags Flags, uint32_t AlignInBits, DINodeArray Annotations),(Scope, Name, File, Line, Type, Arg, Flags, AlignInBits, Annotations)) DEFINE_MDNODE_GET(DILocalVariable
Metadata MDString Metadata unsigned Line
Metadata MDString Metadata unsigned Metadata unsigned DIFlags uint32_t Metadata * Annotations
Metadata MDString Metadata unsigned Metadata unsigned DIFlags uint32_t AlignInBits
bool isValidLocationForIntrinsic(const DILocation *DL) const
Check that a location is valid for this variable.
Metadata * getRawAnnotations() const
Debug location.
unsigned unsigned DILocalScope * Scope
static unsigned getDuplicationFactorFromDiscriminator(unsigned D)
Returns the duplication factor for a given encoded discriminator D, or 1 if no value or 0 is encoded.
static bool isPseudoProbeDiscriminator(unsigned Discriminator)
unsigned getDuplicationFactor() const
Returns the duplication factor stored in the discriminator, or 1 if no duplication factor (or 0) is e...
static DILocation * getMergedLocations(ArrayRef< DILocation * > Locs)
Try to combine the vector of locations passed as input in a single one.
DEFINE_MDNODE_GET(DILocation,(unsigned Line, unsigned Column, Metadata *Scope, Metadata *InlinedAt=nullptr, bool ImplicitCode=false),(Line, Column, Scope, InlinedAt, ImplicitCode)) DEFINE_MDNODE_GET(DILocation
static unsigned getBaseDiscriminatorBits()
Return the bits used for base discriminators.
static std::optional< unsigned > encodeDiscriminator(unsigned BD, unsigned DF, unsigned CI)
Raw encoding of the discriminator.
unsigned unsigned DILocalScope DILocation bool ImplicitCode
Metadata * getRawScope() const
static void decodeDiscriminator(unsigned D, unsigned &BD, unsigned &DF, unsigned &CI)
Raw decoder for values in an encoded discriminator D.
static DILocation * getMergedLocation(DILocation *LocA, DILocation *LocB)
When two instructions are combined into a single instruction we also need to combine the original loc...
std::optional< const DILocation * > cloneWithBaseDiscriminator(unsigned BD) const
Returns a new DILocation with updated base discriminator BD.
unsigned getBaseDiscriminator() const
Returns the base discriminator stored in the discriminator.
static unsigned getBaseDiscriminatorFromDiscriminator(unsigned D, bool IsFSDiscriminator=false)
Returns the base discriminator for a given encoded discriminator D.
unsigned unsigned Column
Metadata * getRawInlinedAt() const
unsigned unsigned DILocalScope DILocation * InlinedAt
static unsigned getMaskedDiscriminator(unsigned D, unsigned B)
Return the masked discriminator value for an input discrimnator value D (i.e.
const DILocation * cloneWithDiscriminator(unsigned Discriminator) const
Returns a new DILocation with updated Discriminator.
static unsigned getCopyIdentifierFromDiscriminator(unsigned D)
Returns the copy identifier for a given encoded discriminator D.
void replaceOperandWith(unsigned I, Metadata *New)=delete
std::optional< const DILocation * > cloneByMultiplyingDuplicationFactor(unsigned DF) const
Returns a new DILocation with duplication factor DF * current duplication factor encoded in the discr...
static bool classof(const Metadata *MD)
unsigned getCopyIdentifier() const
Returns the copy identifier stored in the discriminator.
unsigned unsigned Metadata * File
Metadata * getRawElements() const
DEFINE_MDNODE_GET(DIMacroFile,(unsigned MIType, unsigned Line, DIFile *File, DIMacroNodeArray Elements),(MIType, Line, File, Elements)) DEFINE_MDNODE_GET(DIMacroFile
unsigned unsigned Line
DIFile * getFile() const
unsigned getLine() const
unsigned unsigned Metadata Metadata * Elements
Metadata * getRawFile() const
static bool classof(const Metadata *MD)
void replaceElements(DIMacroNodeArray Elements)
unsigned unsigned Metadata Metadata Elements TempDIMacroFile clone() const
DIMacroNodeArray getElements() const
Macro Info DWARF-like metadata node.
unsigned getMacinfoType() const
StringRef getStringOperand(unsigned I) const
static bool classof(const Metadata *MD)
static MDString * getCanonicalMDString(LLVMContext &Context, StringRef S)
Ty * getOperandAs(unsigned I) const
~DIMacroNode()=default
DIMacroNode(LLVMContext &C, unsigned ID, StorageType Storage, unsigned MIType, ArrayRef< Metadata * > Ops1, ArrayRef< Metadata * > Ops2=std::nullopt)
unsigned getLine() const
MDString * getRawName() const
unsigned unsigned MDString MDString Value TempDIMacro clone() const
unsigned unsigned MDString MDString * Value
unsigned unsigned MDString * Name
StringRef getName() const
MDString * getRawValue() const
unsigned unsigned Line
DEFINE_MDNODE_GET(DIMacro,(unsigned MIType, unsigned Line, StringRef Name, StringRef Value=""),(MIType, Line, Name, Value)) DEFINE_MDNODE_GET(DIMacro
StringRef getValue() const
static bool classof(const Metadata *MD)
Represents a module in the programming language, for example, a Clang module, or a Fortran module.
Metadata Metadata * Scope
Metadata Metadata MDString * Name
Metadata Metadata MDString MDString MDString MDString * APINotesFile
Metadata Metadata MDString MDString MDString * IncludePath
Metadata Metadata MDString MDString * ConfigurationMacros
DEFINE_MDNODE_GET(DIModule,(DIFile *File, DIScope *Scope, StringRef Name, StringRef ConfigurationMacros, StringRef IncludePath, StringRef APINotesFile, unsigned LineNo, bool IsDecl=false),(File, Scope, Name, ConfigurationMacros, IncludePath, APINotesFile, LineNo, IsDecl)) DEFINE_MDNODE_GET(DIModule
Metadata Metadata MDString MDString MDString MDString unsigned LineNo
Debug lexical block.
Metadata MDString bool ExportSymbols TempDINamespace clone() const
static bool classof(const Metadata *MD)
DEFINE_MDNODE_GET(DINamespace,(DIScope *Scope, StringRef Name, bool ExportSymbols),(Scope, Name, ExportSymbols)) DEFINE_MDNODE_GET(DINamespace
DIScope * getScope() const
Metadata MDString bool ExportSymbols
StringRef getName() const
MDString * getRawName() const
Metadata MDString * Name
bool getExportSymbols() const
Metadata * getRawScope() const
Tagged DWARF-like metadata node.
DINode(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag, ArrayRef< Metadata * > Ops1, ArrayRef< Metadata * > Ops2=std::nullopt)
dwarf::Tag getTag() const
static MDString * getCanonicalMDString(LLVMContext &Context, StringRef S)
static DIFlags getFlag(StringRef Flag)
static DIFlags splitFlags(DIFlags Flags, SmallVectorImpl< DIFlags > &SplitFlags)
Split up a flags bitfield.
void setTag(unsigned Tag)
Allow subclasses to mutate the tag.
StringRef getStringOperand(unsigned I) const
Ty * getOperandAs(unsigned I) const
static bool classof(const Metadata *MD)
static StringRef getFlagString(DIFlags Flag)
~DINode()=default
DIFlags
Debug info flags.
MDString Metadata unsigned MDString MDString unsigned Metadata Type TempDIObjCProperty clone() const
DIType * getType() const
unsigned getAttributes() const
StringRef getFilename() const
MDString * getRawName() const
unsigned getLine() const
StringRef getDirectory() const
MDString * getRawSetterName() const
Metadata * getRawType() const
StringRef getGetterName() const
MDString Metadata * File
DIFile * getFile() const
static bool classof(const Metadata *MD)
MDString * getRawGetterName() const
Metadata * getRawFile() const
MDString Metadata unsigned MDString * GetterName
MDString Metadata unsigned MDString MDString * SetterName
StringRef getName() const
DEFINE_MDNODE_GET(DIObjCProperty,(StringRef Name, DIFile *File, unsigned Line, StringRef GetterName, StringRef SetterName, unsigned Attributes, DIType *Type),(Name, File, Line, GetterName, SetterName, Attributes, Type)) DEFINE_MDNODE_GET(DIObjCProperty
StringRef getSetterName() const
Base class for scope-like contexts.
~DIScope()=default
StringRef getFilename() const
StringRef getName() const
static bool classof(const Metadata *MD)
DIFile * getFile() const
StringRef getDirectory() const
std::optional< StringRef > getSource() const
DIScope * getScope() const
Metadata * getRawFile() const
Return the raw underlying file.
DIScope(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag, ArrayRef< Metadata * > Ops)
String type, Fortran CHARACTER(n)
unsigned MDString * Name
unsigned MDString Metadata Metadata Metadata uint64_t SizeInBits
unsigned getEncoding() const
unsigned MDString Metadata Metadata Metadata uint64_t uint32_t AlignInBits
static bool classof(const Metadata *MD)
unsigned MDString Metadata Metadata Metadata * StringLocationExp
DIExpression * getStringLengthExp() const
unsigned MDString Metadata Metadata * StringLengthExp
Metadata * getRawStringLengthExp() const
Metadata * getRawStringLength() const
DIVariable * getStringLength() const
DIExpression * getStringLocationExp() const
unsigned MDString Metadata * StringLength
Metadata * getRawStringLocationExp() const
DEFINE_MDNODE_GET(DIStringType,(unsigned Tag, StringRef Name, uint64_t SizeInBits, uint32_t AlignInBits),(Tag, Name, nullptr, nullptr, nullptr, SizeInBits, AlignInBits, 0)) DEFINE_MDNODE_GET(DIStringType
Subprogram description.
Metadata MDString MDString Metadata unsigned Metadata unsigned Metadata unsigned int DIFlags DISPFlags Metadata * Unit
Metadata MDString MDString Metadata unsigned Metadata unsigned Metadata unsigned int DIFlags DISPFlags Metadata Metadata Metadata Metadata Metadata Metadata * Annotations
Metadata MDString MDString Metadata unsigned Metadata unsigned Metadata * ContainingType
Metadata MDString MDString Metadata unsigned Metadata unsigned Metadata unsigned int DIFlags DISPFlags Metadata Metadata * TemplateParams
Metadata MDString MDString Metadata unsigned Metadata unsigned Metadata unsigned int DIFlags DISPFlags Metadata Metadata Metadata * Declaration
Metadata MDString MDString Metadata unsigned Metadata unsigned Metadata unsigned int DIFlags DISPFlags Metadata Metadata Metadata Metadata Metadata Metadata MDString * TargetFuncName
static DISPFlags toSPFlags(bool IsLocalToUnit, bool IsDefinition, bool IsOptimized, unsigned Virtuality=SPFlagNonvirtual, bool IsMainSubprogram=false)
Metadata MDString * Name
Metadata MDString MDString Metadata unsigned Metadata unsigned Metadata unsigned int DIFlags DISPFlags Metadata Metadata Metadata Metadata Metadata * ThrownTypes
static DISPFlags getFlag(StringRef Flag)
Metadata MDString MDString Metadata * File
static DISPFlags splitFlags(DISPFlags Flags, SmallVectorImpl< DISPFlags > &SplitFlags)
Split up a flags bitfield for easier printing.
static bool classof(const Metadata *MD)
Metadata MDString MDString * LinkageName
static StringRef getFlagString(DISPFlags Flag)
Metadata MDString MDString Metadata unsigned Metadata * Type
Metadata MDString MDString Metadata unsigned Metadata unsigned Metadata unsigned int DIFlags DISPFlags Metadata Metadata Metadata Metadata * RetainedNodes
DEFINE_MDNODE_GET(DISubprogram,(DIScope *Scope, StringRef Name, StringRef LinkageName, DIFile *File, unsigned Line, DISubroutineType *Type, unsigned ScopeLine, DIType *ContainingType, unsigned VirtualIndex, int ThisAdjustment, DIFlags Flags, DISPFlags SPFlags, DICompileUnit *Unit, DITemplateParameterArray TemplateParams=nullptr, DISubprogram *Declaration=nullptr, DINodeArray RetainedNodes=nullptr, DITypeArray ThrownTypes=nullptr, DINodeArray Annotations=nullptr, StringRef TargetFuncName=""),(Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams, Declaration, RetainedNodes, ThrownTypes, Annotations, TargetFuncName)) DEFINE_MDNODE_GET(DISubprogram
DISPFlags
Debug info subprogram flags.
Array subrange.
static bool classof(const Metadata *MD)
BoundType getUpperBound() const
BoundType getStride() const
BoundType getLowerBound() const
DEFINE_MDNODE_GET(DISubrange,(int64_t Count, int64_t LowerBound=0),(Count, LowerBound)) DEFINE_MDNODE_GET(DISubrange
BoundType getCount() const
Metadata int64_t LowerBound
Type array for a subprogram.
TempDISubroutineType cloneWithCC(uint8_t CC) const
DEFINE_MDNODE_GET(DISubroutineType,(DIFlags Flags, uint8_t CC, DITypeRefArray TypeArray),(Flags, CC, TypeArray)) DEFINE_MDNODE_GET(DISubroutineType
DIFlags uint8_t Metadata * TypeArray
static bool classof(const Metadata *MD)
Metadata * getRawTypeArray() const
DITypeRefArray getTypeArray() const
DIFlags uint8_t Metadata TypeArray TempDISubroutineType clone() const
Base class for template parameters.
Metadata * getRawType() const
static bool classof(const Metadata *MD)
DITemplateParameter(LLVMContext &Context, unsigned ID, StorageType Storage, unsigned Tag, bool IsDefault, ArrayRef< Metadata * > Ops)
MDString * getRawName() const
MDString Metadata bool IsDefault
DEFINE_MDNODE_GET(DITemplateTypeParameter,(StringRef Name, DIType *Type, bool IsDefault),(Name, Type, IsDefault)) DEFINE_MDNODE_GET(DITemplateTypeParameter
MDString Metadata bool IsDefault TempDITemplateTypeParameter clone() const
static bool classof(const Metadata *MD)
unsigned MDString Metadata bool Metadata Value TempDITemplateValueParameter clone() const
unsigned MDString Metadata * Type
static bool classof(const Metadata *MD)
DEFINE_MDNODE_GET(DITemplateValueParameter,(unsigned Tag, StringRef Name, DIType *Type, bool IsDefault, Metadata *Value),(Tag, Name, Type, IsDefault, Value)) DEFINE_MDNODE_GET(DITemplateValueParameter
unsigned MDString Metadata bool IsDefault
unsigned MDString Metadata bool Metadata * Value
bool operator!=(const iterator &X) const
bool operator==(const iterator &X) const
std::input_iterator_tag iterator_category
iterator(MDNode::op_iterator I)
DIType * operator[](unsigned I) const
MDTuple & operator*() const
DITypeRefArray()=default
MDTuple * operator->() const
iterator end() const
MDTuple * get() const
iterator begin() const
DITypeRefArray(const MDTuple *N)
unsigned size() const
Base class for types.
bool isLittleEndian() const
bool isPublic() const
bool isPrivate() const
bool isBigEndian() const
bool isLValueReference() const
bool isBitField() const
~DIType()=default
bool isStaticMember() const
DIType(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag, unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags, ArrayRef< Metadata * > Ops)
bool isVirtual() const
TempDIType cloneWithFlags(DIFlags NewFlags) const
Returns a new temporary DIType with updated Flags.
bool isObjcClassComplete() const
MDString * getRawName() const
bool isAppleBlockExtension() const
uint64_t getOffsetInBits() const
bool isVector() const
bool isProtected() const
bool isObjectPointer() const
void mutate(unsigned Tag, unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags)
Change fields in place.
DIFlags getFlags() const
Metadata * getRawScope() const
StringRef getName() const
bool isForwardDecl() const
bool isTypePassByValue() const
uint64_t getSizeInBits() const
static bool classof(const Metadata *MD)
uint32_t getAlignInBytes() const
uint32_t getAlignInBits() const
unsigned getLine() const
void init(unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags)
bool isRValueReference() const
bool isArtificial() const
bool getExportSymbols() const
TempDIType clone() const
DIScope * getScope() const
bool isTypePassByReference() const
Base class for variables.
std::optional< DIBasicType::Signedness > getSignedness() const
Return the signedness of this variable's type, or std::nullopt if this type is neither signed nor uns...
uint32_t getAlignInBits() const
DIFile * getFile() const
MDString * getRawName() const
uint32_t getAlignInBytes() const
DIScope * getScope() const
~DIVariable()=default
StringRef getDirectory() const
std::optional< uint64_t > getSizeInBits() const
Determines the size of the variable's type.
Metadata * getRawFile() const
std::optional< StringRef > getSource() const
StringRef getFilename() const
Metadata * getRawType() const
static bool classof(const Metadata *MD)
DIType * getType() const
unsigned getLine() const
StringRef getName() const
Metadata * getRawScope() const
This class represents an Operation in the Expression.
This is the common base class for debug info intrinsics for variables.
Record of a variable value-assignment, aka a non instruction representation of the dbg....
Identifies a unique instance of a whole variable (discards/ignores fragment information).
DebugVariableAggregate(const DebugVariable &V)
Identifies a unique instance of a variable.
static bool isDefaultFragment(const FragmentInfo F)
DebugVariable(const DILocalVariable *Var, const DIExpression *DIExpr, const DILocation *InlinedAt)
const DILocation * getInlinedAt() const
bool operator<(const DebugVariable &Other) const
DebugVariable(const DILocalVariable *Var, std::optional< FragmentInfo > FragmentInfo, const DILocation *InlinedAt)
bool operator==(const DebugVariable &Other) const
FragmentInfo getFragmentOrDefault() const
std::optional< FragmentInfo > getFragment() const
const DILocalVariable * getVariable() const
Class representing an expression and its matching format.
Generic tagged DWARF-like metadata node.
static bool classof(const Metadata *MD)
unsigned MDString ArrayRef< Metadata * > DwarfOps TempGenericDINode clone() const
Return a (temporary) clone of this.
dwarf::Tag getTag() const
StringRef getHeader() const
MDString * getRawHeader() const
const MDOperand & getDwarfOperand(unsigned I) const
unsigned getHash() const
unsigned getNumDwarfOperands() const
op_iterator dwarf_op_end() const
op_iterator dwarf_op_begin() const
unsigned MDString * Header
op_range dwarf_operands() const
DEFINE_MDNODE_GET(GenericDINode,(unsigned Tag, StringRef Header, ArrayRef< Metadata * > DwarfOps),(Tag, Header, DwarfOps)) DEFINE_MDNODE_GET(GenericDINode
void replaceDwarfOperandWith(unsigned I, Metadata *New)
unsigned MDString ArrayRef< Metadata * > DwarfOps
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:67
Metadata node.
Definition: Metadata.h:1067
friend class DIAssignID
Definition: Metadata.h:1070
void replaceOperandWith(unsigned I, Metadata *New)
Replace a specific operand.
Definition: Metadata.cpp:1071
const MDOperand & getOperand(unsigned I) const
Definition: Metadata.h:1428
static TempMDTuple getTemporary(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition: Metadata.h:1553
op_iterator op_end() const
Definition: Metadata.h:1422
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition: Metadata.h:1541
bool isUniqued() const
Definition: Metadata.h:1249
unsigned getNumOperands() const
Return number of MDNode operands.
Definition: Metadata.h:1434
iterator_range< op_iterator > op_range
Definition: Metadata.h:1416
TempMDNode clone() const
Create a (temporary) clone of this.
Definition: Metadata.cpp:661
bool isDistinct() const
Definition: Metadata.h:1250
void setOperand(unsigned I, Metadata *New)
Set an operand.
Definition: Metadata.cpp:1083
op_iterator op_begin() const
Definition: Metadata.h:1418
LLVMContext & getContext() const
Definition: Metadata.h:1231
void dropAllReferences()
Definition: Metadata.cpp:901
Tracking metadata reference owned by Metadata.
Definition: Metadata.h:889
Metadata * get() const
Definition: Metadata.h:918
A single uniqued string.
Definition: Metadata.h:720
static MDString * get(LLVMContext &Context, StringRef Str)
Definition: Metadata.cpp:600
Tuple of metadata.
Definition: Metadata.h:1470
Root of the metadata hierarchy.
Definition: Metadata.h:62
StorageType
Active type of storage.
Definition: Metadata.h:70
unsigned short SubclassData16
Definition: Metadata.h:76
unsigned SubclassData32
Definition: Metadata.h:77
unsigned char Storage
Storage flag for non-uniqued, otherwise unowned, metadata.
Definition: Metadata.h:73
unsigned getMetadataID() const
Definition: Metadata.h:102
unsigned char SubclassData1
Definition: Metadata.h:75
A discriminated union of two or more pointer types, with the discriminator in the low bit of the poin...
Definition: PointerUnion.h:118
Shared implementation of use-lists for replaceable metadata.
Definition: Metadata.h:382
SmallVector< DbgVariableRecord * > getAllDbgVariableRecordUsers()
Returns the list of all DbgVariableRecord users of this.
Definition: Metadata.cpp:272
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:586
typename SuperClass::iterator iterator
Definition: SmallVector.h:590
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:134
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
LLVM Value Representation.
Definition: Value.h:74
A range adaptor for a pair of iterators.
unsigned getVirtuality(StringRef VirtualityString)
Definition: Dwarf.cpp:353
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=std::nullopt)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
Definition: Function.cpp:1459
SourceLanguage
Definition: Dwarf.h:204
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:456
bool operator<(int64_t V1, const APSInt &V2)
Definition: APSInt.h:361
bool operator!=(uint64_t V1, const APInt &V2)
Definition: APInt.h:2043
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
cl::opt< bool > EnableFSDiscriminator
static unsigned getBaseFSBitEnd()
@ Ref
The access may reference the value stored in memory.
@ Other
Any other memory.
static unsigned getN1Bits(int N)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition: STLExtras.h:1888
hash_code hash_combine(const Ts &...args)
Combine values into a single hash_code.
Definition: Hashing.h:613
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:858
#define N
Pointer authentication (__ptrauth) metadata.
PtrAuthData(unsigned Key, bool IsDiscr, unsigned Discriminator, bool IsaPointer, bool AuthenticatesNullValues)
Holds the characteristics of one fragment of a larger variable.
FragmentInfo(uint64_t SizeInBits, uint64_t OffsetInBits)
static DIExpression::FragmentInfo intersect(DIExpression::FragmentInfo A, DIExpression::FragmentInfo B)
Returns a zero-sized fragment if A and B don't intersect.
uint64_t endInBits() const
Return the index of the bit after the end of the fragment, e.g.
uint64_t startInBits() const
Return the index of the first bit of the fragment.
A single checksum, represented by a Kind and a Value (a string).
bool operator==(const ChecksumInfo< T > &X) const
T Value
The string value of the checksum.
ChecksumKind Kind
The kind of checksum which Value encodes.
ChecksumInfo(ChecksumKind Kind, T Value)
bool operator!=(const ChecksumInfo< T > &X) const
StringRef getKindAsString() const
static bool isEqual(const FragInfo &A, const FragInfo &B)
static unsigned getHashValue(const FragInfo &Frag)
static unsigned getHashValue(const DebugVariable &D)
static DebugVariable getEmptyKey()
Empty key: no key should be generated that has no DILocalVariable.
static DebugVariable getTombstoneKey()
Difference in tombstone is that the Optional is meaningful.
static bool isEqual(const DebugVariable &A, const DebugVariable &B)
An information struct used to provide DenseMap with the various necessary components for a given valu...
Definition: DenseMapInfo.h:50
static uint32_t extractProbeIndex(uint32_t Value)
Definition: PseudoProbe.h:61