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, virtual base pointer offset
1097 /// for inheritance, or a tuple of template parameters for template aliases.
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 the template parameters from a template alias.
1105 DITemplateParameterArray getTemplateParams() const {
1106 return cast_or_null<MDTuple>(getExtraData());
1107 }
1108
1109 /// Get annotations associated with this derived type.
1110 DINodeArray getAnnotations() const {
1111 return cast_or_null<MDTuple>(getRawAnnotations());
1112 }
1113 Metadata *getRawAnnotations() const { return getOperand(5); }
1114
1115 /// Get casted version of extra data.
1116 /// @{
1117 DIType *getClassType() const;
1118
1120 return dyn_cast_or_null<DIObjCProperty>(getExtraData());
1121 }
1122
1123 uint32_t getVBPtrOffset() const;
1124
1126
1127 Constant *getConstant() const;
1128
1130 /// @}
1131
1132 static bool classof(const Metadata *MD) {
1133 return MD->getMetadataID() == DIDerivedTypeKind;
1134 }
1135};
1136
1139 return Lhs.RawData == Rhs.RawData;
1140}
1141
1144 return !(Lhs == Rhs);
1145}
1146
1147/// Composite types.
1148///
1149/// TODO: Detach from DerivedTypeBase (split out MDEnumType?).
1150/// TODO: Create a custom, unrelated node for DW_TAG_array_type.
1151class DICompositeType : public DIType {
1152 friend class LLVMContextImpl;
1153 friend class MDNode;
1154
1155 unsigned RuntimeLang;
1156
1158 unsigned Line, unsigned RuntimeLang, uint64_t SizeInBits,
1161 : DIType(C, DICompositeTypeKind, Storage, Tag, Line, SizeInBits,
1163 RuntimeLang(RuntimeLang) {}
1164 ~DICompositeType() = default;
1165
1166 /// Change fields in place.
1167 void mutate(unsigned Tag, unsigned Line, unsigned RuntimeLang,
1169 DIFlags Flags) {
1170 assert(isDistinct() && "Only distinct nodes can mutate");
1171 assert(getRawIdentifier() && "Only ODR-uniqued nodes should mutate");
1172 this->RuntimeLang = RuntimeLang;
1174 }
1175
1176 static DICompositeType *
1177 getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, Metadata *File,
1178 unsigned Line, DIScope *Scope, DIType *BaseType, uint64_t SizeInBits,
1180 DINodeArray Elements, unsigned RuntimeLang, DIType *VTableHolder,
1181 DITemplateParameterArray TemplateParams, StringRef Identifier,
1182 DIDerivedType *Discriminator, Metadata *DataLocation,
1184 DINodeArray Annotations, StorageType Storage,
1185 bool ShouldCreate = true) {
1186 return getImpl(
1187 Context, Tag, getCanonicalMDString(Context, Name), File, Line, Scope,
1189 RuntimeLang, VTableHolder, TemplateParams.get(),
1191 Associated, Allocated, Rank, Annotations.get(), Storage, ShouldCreate);
1192 }
1193 static DICompositeType *
1194 getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
1195 unsigned Line, Metadata *Scope, Metadata *BaseType,
1197 DIFlags Flags, Metadata *Elements, unsigned RuntimeLang,
1201 Metadata *Annotations, StorageType Storage, bool ShouldCreate = true);
1202
1203 TempDICompositeType cloneImpl() const {
1204 return getTemporary(
1211 }
1212
1213public:
1216 (unsigned Tag, StringRef Name, DIFile *File, unsigned Line,
1219 DINodeArray Elements, unsigned RuntimeLang, DIType *VTableHolder,
1220 DITemplateParameterArray TemplateParams = nullptr,
1222 Metadata *DataLocation = nullptr, Metadata *Associated = nullptr,
1223 Metadata *Allocated = nullptr, Metadata *Rank = nullptr,
1224 DINodeArray Annotations = nullptr),
1228 Annotations))
1231 (unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
1234 Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder,
1237 Metadata *Associated = nullptr, Metadata *Allocated = nullptr,
1238 Metadata *Rank = nullptr, Metadata *Annotations = nullptr),
1242 Annotations))
1243
1244 TempDICompositeType clone() const { return cloneImpl(); }
1245
1246 /// Get a DICompositeType with the given ODR identifier.
1247 ///
1248 /// If \a LLVMContext::isODRUniquingDebugTypes(), gets the mapped
1249 /// DICompositeType for the given ODR \c Identifier. If none exists, creates
1250 /// a new node.
1251 ///
1252 /// Else, returns \c nullptr.
1253 static DICompositeType *
1254 getODRType(LLVMContext &Context, MDString &Identifier, unsigned Tag,
1255 MDString *Name, Metadata *File, unsigned Line, Metadata *Scope,
1258 unsigned RuntimeLang, Metadata *VTableHolder,
1264
1265 /// Build a DICompositeType with the given ODR identifier.
1266 ///
1267 /// Looks up the mapped DICompositeType for the given ODR \c Identifier. If
1268 /// it doesn't exist, creates a new one. If it does exist and \a
1269 /// isForwardDecl(), and the new arguments would be a definition, mutates the
1270 /// the type in place. In either case, returns the type.
1271 ///
1272 /// If not \a LLVMContext::isODRUniquingDebugTypes(), this function returns
1273 /// nullptr.
1274 static DICompositeType *
1275 buildODRType(LLVMContext &Context, MDString &Identifier, unsigned Tag,
1276 MDString *Name, Metadata *File, unsigned Line, Metadata *Scope,
1279 unsigned RuntimeLang, Metadata *VTableHolder,
1283
1284 DIType *getBaseType() const { return cast_or_null<DIType>(getRawBaseType()); }
1285 DINodeArray getElements() const {
1286 return cast_or_null<MDTuple>(getRawElements());
1287 }
1289 return cast_or_null<DIType>(getRawVTableHolder());
1290 }
1291 DITemplateParameterArray getTemplateParams() const {
1292 return cast_or_null<MDTuple>(getRawTemplateParams());
1293 }
1295 unsigned getRuntimeLang() const { return RuntimeLang; }
1296
1297 Metadata *getRawBaseType() const { return getOperand(3); }
1298 Metadata *getRawElements() const { return getOperand(4); }
1301 MDString *getRawIdentifier() const { return getOperandAs<MDString>(7); }
1304 return getOperandAs<DIDerivedType>(8);
1305 }
1308 return dyn_cast_or_null<DIVariable>(getRawDataLocation());
1309 }
1311 return dyn_cast_or_null<DIExpression>(getRawDataLocation());
1312 }
1313 Metadata *getRawAssociated() const { return getOperand(10); }
1315 return dyn_cast_or_null<DIVariable>(getRawAssociated());
1316 }
1318 return dyn_cast_or_null<DIExpression>(getRawAssociated());
1319 }
1320 Metadata *getRawAllocated() const { return getOperand(11); }
1322 return dyn_cast_or_null<DIVariable>(getRawAllocated());
1323 }
1325 return dyn_cast_or_null<DIExpression>(getRawAllocated());
1326 }
1327 Metadata *getRawRank() const { return getOperand(12); }
1329 if (auto *MD = dyn_cast_or_null<ConstantAsMetadata>(getRawRank()))
1330 return dyn_cast_or_null<ConstantInt>(MD->getValue());
1331 return nullptr;
1332 }
1334 return dyn_cast_or_null<DIExpression>(getRawRank());
1335 }
1336
1337 Metadata *getRawAnnotations() const { return getOperand(13); }
1338 DINodeArray getAnnotations() const {
1339 return cast_or_null<MDTuple>(getRawAnnotations());
1340 }
1341
1342 /// Replace operands.
1343 ///
1344 /// If this \a isUniqued() and not \a isResolved(), on a uniquing collision
1345 /// this will be RAUW'ed and deleted. Use a \a TrackingMDRef to keep track
1346 /// of its movement if necessary.
1347 /// @{
1348 void replaceElements(DINodeArray Elements) {
1349#ifndef NDEBUG
1350 for (DINode *Op : getElements())
1351 assert(is_contained(Elements->operands(), Op) &&
1352 "Lost a member during member list replacement");
1353#endif
1354 replaceOperandWith(4, Elements.get());
1355 }
1356
1359 }
1360
1361 void replaceTemplateParams(DITemplateParameterArray TemplateParams) {
1363 }
1364 /// @}
1365
1366 static bool classof(const Metadata *MD) {
1367 return MD->getMetadataID() == DICompositeTypeKind;
1368 }
1369};
1370
1371/// Type array for a subprogram.
1372///
1373/// TODO: Fold the array of types in directly as operands.
1374class DISubroutineType : public DIType {
1375 friend class LLVMContextImpl;
1376 friend class MDNode;
1377
1378 /// The calling convention used with DW_AT_calling_convention. Actually of
1379 /// type dwarf::CallingConvention.
1380 uint8_t CC;
1381
1383 uint8_t CC, ArrayRef<Metadata *> Ops);
1384 ~DISubroutineType() = default;
1385
1386 static DISubroutineType *getImpl(LLVMContext &Context, DIFlags Flags,
1387 uint8_t CC, DITypeRefArray TypeArray,
1389 bool ShouldCreate = true) {
1390 return getImpl(Context, Flags, CC, TypeArray.get(), Storage, ShouldCreate);
1391 }
1392 static DISubroutineType *getImpl(LLVMContext &Context, DIFlags Flags,
1393 uint8_t CC, Metadata *TypeArray,
1395 bool ShouldCreate = true);
1396
1397 TempDISubroutineType cloneImpl() const {
1399 }
1400
1401public:
1404 (Flags, CC, TypeArray))
1408
1409 TempDISubroutineType clone() const { return cloneImpl(); }
1410 // Returns a new temporary DISubroutineType with updated CC
1411 TempDISubroutineType cloneWithCC(uint8_t CC) const {
1412 auto NewTy = clone();
1413 NewTy->CC = CC;
1414 return NewTy;
1415 }
1416
1417 uint8_t getCC() const { return CC; }
1418
1420 return cast_or_null<MDTuple>(getRawTypeArray());
1421 }
1422
1423 Metadata *getRawTypeArray() const { return getOperand(3); }
1424
1425 static bool classof(const Metadata *MD) {
1426 return MD->getMetadataID() == DISubroutineTypeKind;
1427 }
1428};
1429
1430/// Compile unit.
1431class DICompileUnit : public DIScope {
1432 friend class LLVMContextImpl;
1433 friend class MDNode;
1434
1435public:
1436 enum DebugEmissionKind : unsigned {
1443
1444 enum class DebugNameTableKind : unsigned {
1445 Default = 0,
1446 GNU = 1,
1447 None = 2,
1448 Apple = 3,
1450 };
1451
1452 static std::optional<DebugEmissionKind> getEmissionKind(StringRef Str);
1453 static const char *emissionKindString(DebugEmissionKind EK);
1454 static std::optional<DebugNameTableKind> getNameTableKind(StringRef Str);
1455 static const char *nameTableKindString(DebugNameTableKind PK);
1456
1457private:
1458 unsigned SourceLanguage;
1459 unsigned RuntimeVersion;
1460 uint64_t DWOId;
1461 unsigned EmissionKind;
1462 unsigned NameTableKind;
1463 bool IsOptimized;
1464 bool SplitDebugInlining;
1465 bool DebugInfoForProfiling;
1466 bool RangesBaseAddress;
1467
1469 bool IsOptimized, unsigned RuntimeVersion,
1470 unsigned EmissionKind, uint64_t DWOId, bool SplitDebugInlining,
1471 bool DebugInfoForProfiling, unsigned NameTableKind,
1472 bool RangesBaseAddress, ArrayRef<Metadata *> Ops);
1473 ~DICompileUnit() = default;
1474
1475 static DICompileUnit *
1476 getImpl(LLVMContext &Context, unsigned SourceLanguage, DIFile *File,
1477 StringRef Producer, bool IsOptimized, StringRef Flags,
1478 unsigned RuntimeVersion, StringRef SplitDebugFilename,
1479 unsigned EmissionKind, DICompositeTypeArray EnumTypes,
1480 DIScopeArray RetainedTypes,
1481 DIGlobalVariableExpressionArray GlobalVariables,
1482 DIImportedEntityArray ImportedEntities, DIMacroNodeArray Macros,
1483 uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling,
1484 unsigned NameTableKind, bool RangesBaseAddress, StringRef SysRoot,
1485 StringRef SDK, StorageType Storage, bool ShouldCreate = true) {
1486 return getImpl(
1487 Context, SourceLanguage, File, getCanonicalMDString(Context, Producer),
1488 IsOptimized, getCanonicalMDString(Context, Flags), RuntimeVersion,
1489 getCanonicalMDString(Context, SplitDebugFilename), EmissionKind,
1490 EnumTypes.get(), RetainedTypes.get(), GlobalVariables.get(),
1491 ImportedEntities.get(), Macros.get(), DWOId, SplitDebugInlining,
1492 DebugInfoForProfiling, NameTableKind, RangesBaseAddress,
1493 getCanonicalMDString(Context, SysRoot),
1494 getCanonicalMDString(Context, SDK), Storage, ShouldCreate);
1495 }
1496 static DICompileUnit *
1497 getImpl(LLVMContext &Context, unsigned SourceLanguage, Metadata *File,
1498 MDString *Producer, bool IsOptimized, MDString *Flags,
1499 unsigned RuntimeVersion, MDString *SplitDebugFilename,
1500 unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes,
1502 Metadata *Macros, uint64_t DWOId, bool SplitDebugInlining,
1503 bool DebugInfoForProfiling, unsigned NameTableKind,
1504 bool RangesBaseAddress, MDString *SysRoot, MDString *SDK,
1505 StorageType Storage, bool ShouldCreate = true);
1506
1507 TempDICompileUnit cloneImpl() const {
1508 return getTemporary(
1515 }
1516
1517public:
1518 static void get() = delete;
1519 static void getIfExists() = delete;
1520
1524 bool IsOptimized, StringRef Flags, unsigned RuntimeVersion,
1526 DICompositeTypeArray EnumTypes, DIScopeArray RetainedTypes,
1527 DIGlobalVariableExpressionArray GlobalVariables,
1528 DIImportedEntityArray ImportedEntities, DIMacroNodeArray Macros,
1529 uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling,
1530 DebugNameTableKind NameTableKind, bool RangesBaseAddress,
1532 (SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion,
1534 GlobalVariables, ImportedEntities, Macros, DWOId, SplitDebugInlining,
1535 DebugInfoForProfiling, (unsigned)NameTableKind, RangesBaseAddress,
1536 SysRoot, SDK))
1540 bool IsOptimized, MDString *Flags, unsigned RuntimeVersion,
1544 bool SplitDebugInlining, bool DebugInfoForProfiling,
1545 unsigned NameTableKind, bool RangesBaseAddress, MDString *SysRoot,
1547 (SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion,
1549 GlobalVariables, ImportedEntities, Macros, DWOId, SplitDebugInlining,
1550 DebugInfoForProfiling, NameTableKind, RangesBaseAddress, SysRoot, SDK))
1551
1552 TempDICompileUnit clone() const { return cloneImpl(); }
1553
1554 unsigned getSourceLanguage() const { return SourceLanguage; }
1555 bool isOptimized() const { return IsOptimized; }
1556 unsigned getRuntimeVersion() const { return RuntimeVersion; }
1558 return (DebugEmissionKind)EmissionKind;
1559 }
1561 return EmissionKind == DebugDirectivesOnly;
1562 }
1563 bool getDebugInfoForProfiling() const { return DebugInfoForProfiling; }
1565 return (DebugNameTableKind)NameTableKind;
1566 }
1567 bool getRangesBaseAddress() const { return RangesBaseAddress; }
1569 StringRef getFlags() const { return getStringOperand(2); }
1571 DICompositeTypeArray getEnumTypes() const {
1572 return cast_or_null<MDTuple>(getRawEnumTypes());
1573 }
1574 DIScopeArray getRetainedTypes() const {
1575 return cast_or_null<MDTuple>(getRawRetainedTypes());
1576 }
1577 DIGlobalVariableExpressionArray getGlobalVariables() const {
1578 return cast_or_null<MDTuple>(getRawGlobalVariables());
1579 }
1580 DIImportedEntityArray getImportedEntities() const {
1581 return cast_or_null<MDTuple>(getRawImportedEntities());
1582 }
1583 DIMacroNodeArray getMacros() const {
1584 return cast_or_null<MDTuple>(getRawMacros());
1585 }
1586 uint64_t getDWOId() const { return DWOId; }
1587 void setDWOId(uint64_t DwoId) { DWOId = DwoId; }
1588 bool getSplitDebugInlining() const { return SplitDebugInlining; }
1589 void setSplitDebugInlining(bool SplitDebugInlining) {
1590 this->SplitDebugInlining = SplitDebugInlining;
1591 }
1593 StringRef getSDK() const { return getStringOperand(10); }
1594
1595 MDString *getRawProducer() const { return getOperandAs<MDString>(1); }
1596 MDString *getRawFlags() const { return getOperandAs<MDString>(2); }
1598 return getOperandAs<MDString>(3);
1599 }
1600 Metadata *getRawEnumTypes() const { return getOperand(4); }
1604 Metadata *getRawMacros() const { return getOperand(8); }
1605 MDString *getRawSysRoot() const { return getOperandAs<MDString>(9); }
1606 MDString *getRawSDK() const { return getOperandAs<MDString>(10); }
1607
1608 /// Replace arrays.
1609 ///
1610 /// If this \a isUniqued() and not \a isResolved(), it will be RAUW'ed and
1611 /// deleted on a uniquing collision. In practice, uniquing collisions on \a
1612 /// DICompileUnit should be fairly rare.
1613 /// @{
1614 void replaceEnumTypes(DICompositeTypeArray N) {
1615 replaceOperandWith(4, N.get());
1616 }
1617 void replaceRetainedTypes(DITypeArray N) { replaceOperandWith(5, N.get()); }
1618 void replaceGlobalVariables(DIGlobalVariableExpressionArray N) {
1619 replaceOperandWith(6, N.get());
1620 }
1621 void replaceImportedEntities(DIImportedEntityArray N) {
1622 replaceOperandWith(7, N.get());
1623 }
1624 void replaceMacros(DIMacroNodeArray N) { replaceOperandWith(8, N.get()); }
1625 /// @}
1626
1627 static bool classof(const Metadata *MD) {
1628 return MD->getMetadataID() == DICompileUnitKind;
1629 }
1630};
1631
1632/// A scope for locals.
1633///
1634/// A legal scope for lexical blocks, local variables, and debug info
1635/// locations. Subclasses are \a DISubprogram, \a DILexicalBlock, and \a
1636/// DILexicalBlockFile.
1637class DILocalScope : public DIScope {
1638protected:
1641 : DIScope(C, ID, Storage, Tag, Ops) {}
1642 ~DILocalScope() = default;
1643
1644public:
1645 /// Get the subprogram for this scope.
1646 ///
1647 /// Return this if it's an \a DISubprogram; otherwise, look up the scope
1648 /// chain.
1649 DISubprogram *getSubprogram() const;
1650
1651 /// Traverses the scope chain rooted at RootScope until it hits a Subprogram,
1652 /// recreating the chain with "NewSP" instead.
1653 static DILocalScope *
1655 LLVMContext &Ctx,
1657
1658 /// Get the first non DILexicalBlockFile scope of this scope.
1659 ///
1660 /// Return this if it's not a \a DILexicalBlockFIle; otherwise, look up the
1661 /// scope chain.
1663
1664 static bool classof(const Metadata *MD) {
1665 return MD->getMetadataID() == DISubprogramKind ||
1666 MD->getMetadataID() == DILexicalBlockKind ||
1667 MD->getMetadataID() == DILexicalBlockFileKind;
1668 }
1669};
1670
1671/// Subprogram description.
1673 friend class LLVMContextImpl;
1674 friend class MDNode;
1675
1676 unsigned Line;
1677 unsigned ScopeLine;
1678 unsigned VirtualIndex;
1679
1680 /// In the MS ABI, the implicit 'this' parameter is adjusted in the prologue
1681 /// of method overrides from secondary bases by this amount. It may be
1682 /// negative.
1683 int ThisAdjustment;
1684
1685public:
1686 /// Debug info subprogram flags.
1688#define HANDLE_DISP_FLAG(ID, NAME) SPFlag##NAME = ID,
1689#define DISP_FLAG_LARGEST_NEEDED
1690#include "llvm/IR/DebugInfoFlags.def"
1691 SPFlagNonvirtual = SPFlagZero,
1692 SPFlagVirtuality = SPFlagVirtual | SPFlagPureVirtual,
1693 LLVM_MARK_AS_BITMASK_ENUM(SPFlagLargest)
1694 };
1695
1696 static DISPFlags getFlag(StringRef Flag);
1697 static StringRef getFlagString(DISPFlags Flag);
1698
1699 /// Split up a flags bitfield for easier printing.
1700 ///
1701 /// Split \c Flags into \c SplitFlags, a vector of its components. Returns
1702 /// any remaining (unrecognized) bits.
1703 static DISPFlags splitFlags(DISPFlags Flags,
1704 SmallVectorImpl<DISPFlags> &SplitFlags);
1705
1706 // Helper for converting old bitfields to new flags word.
1707 static DISPFlags toSPFlags(bool IsLocalToUnit, bool IsDefinition,
1708 bool IsOptimized,
1709 unsigned Virtuality = SPFlagNonvirtual,
1710 bool IsMainSubprogram = false);
1711
1712private:
1713 DIFlags Flags;
1714 DISPFlags SPFlags;
1715
1716 DISubprogram(LLVMContext &C, StorageType Storage, unsigned Line,
1717 unsigned ScopeLine, unsigned VirtualIndex, int ThisAdjustment,
1718 DIFlags Flags, DISPFlags SPFlags, ArrayRef<Metadata *> Ops);
1719 ~DISubprogram() = default;
1720
1721 static DISubprogram *
1722 getImpl(LLVMContext &Context, DIScope *Scope, StringRef Name,
1723 StringRef LinkageName, DIFile *File, unsigned Line,
1724 DISubroutineType *Type, unsigned ScopeLine, DIType *ContainingType,
1725 unsigned VirtualIndex, int ThisAdjustment, DIFlags Flags,
1726 DISPFlags SPFlags, DICompileUnit *Unit,
1727 DITemplateParameterArray TemplateParams, DISubprogram *Declaration,
1728 DINodeArray RetainedNodes, DITypeArray ThrownTypes,
1730 StorageType Storage, bool ShouldCreate = true) {
1731 return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
1732 getCanonicalMDString(Context, LinkageName), File, Line, Type,
1733 ScopeLine, ContainingType, VirtualIndex, ThisAdjustment,
1734 Flags, SPFlags, Unit, TemplateParams.get(), Declaration,
1735 RetainedNodes.get(), ThrownTypes.get(), Annotations.get(),
1737 Storage, ShouldCreate);
1738 }
1739 static DISubprogram *
1740 getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
1741 MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type,
1742 unsigned ScopeLine, Metadata *ContainingType, unsigned VirtualIndex,
1743 int ThisAdjustment, DIFlags Flags, DISPFlags SPFlags, Metadata *Unit,
1747 bool ShouldCreate = true);
1748
1749 TempDISubprogram cloneImpl() const {
1751 getFile(), getLine(), getType(), getScopeLine(),
1752 getContainingType(), getVirtualIndex(),
1753 getThisAdjustment(), getFlags(), getSPFlags(),
1754 getUnit(), getTemplateParams(), getDeclaration(),
1755 getRetainedNodes(), getThrownTypes(), getAnnotations(),
1756 getTargetFuncName());
1757 }
1758
1759public:
1763 unsigned Line, DISubroutineType *Type, unsigned ScopeLine,
1764 DIType *ContainingType, unsigned VirtualIndex, int ThisAdjustment,
1765 DIFlags Flags, DISPFlags SPFlags, DICompileUnit *Unit,
1766 DITemplateParameterArray TemplateParams = nullptr,
1767 DISubprogram *Declaration = nullptr, DINodeArray RetainedNodes = nullptr,
1768 DITypeArray ThrownTypes = nullptr, DINodeArray Annotations = nullptr,
1770 (Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType,
1771 VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams,
1773
1777 unsigned Line, Metadata *Type, unsigned ScopeLine,
1778 Metadata *ContainingType, unsigned VirtualIndex, int ThisAdjustment,
1779 DIFlags Flags, DISPFlags SPFlags, Metadata *Unit,
1783 (Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType,
1784 VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams,
1786
1787 TempDISubprogram clone() const { return cloneImpl(); }
1788
1789 /// Returns a new temporary DISubprogram with updated Flags
1790 TempDISubprogram cloneWithFlags(DIFlags NewFlags) const {
1791 auto NewSP = clone();
1792 NewSP->Flags = NewFlags;
1793 return NewSP;
1794 }
1795
1796public:
1797 unsigned getLine() const { return Line; }
1798 unsigned getVirtuality() const { return getSPFlags() & SPFlagVirtuality; }
1799 unsigned getVirtualIndex() const { return VirtualIndex; }
1800 int getThisAdjustment() const { return ThisAdjustment; }
1801 unsigned getScopeLine() const { return ScopeLine; }
1802 void setScopeLine(unsigned L) {
1803 assert(isDistinct());
1804 ScopeLine = L;
1805 }
1806 DIFlags getFlags() const { return Flags; }
1807 DISPFlags getSPFlags() const { return SPFlags; }
1808 bool isLocalToUnit() const { return getSPFlags() & SPFlagLocalToUnit; }
1809 bool isDefinition() const { return getSPFlags() & SPFlagDefinition; }
1810 bool isOptimized() const { return getSPFlags() & SPFlagOptimized; }
1811 bool isMainSubprogram() const { return getSPFlags() & SPFlagMainSubprogram; }
1812
1813 bool isArtificial() const { return getFlags() & FlagArtificial; }
1814 bool isPrivate() const {
1815 return (getFlags() & FlagAccessibility) == FlagPrivate;
1816 }
1817 bool isProtected() const {
1818 return (getFlags() & FlagAccessibility) == FlagProtected;
1819 }
1820 bool isPublic() const {
1821 return (getFlags() & FlagAccessibility) == FlagPublic;
1822 }
1823 bool isExplicit() const { return getFlags() & FlagExplicit; }
1824 bool isPrototyped() const { return getFlags() & FlagPrototyped; }
1825 bool areAllCallsDescribed() const {
1826 return getFlags() & FlagAllCallsDescribed;
1827 }
1828 bool isPure() const { return getSPFlags() & SPFlagPure; }
1829 bool isElemental() const { return getSPFlags() & SPFlagElemental; }
1830 bool isRecursive() const { return getSPFlags() & SPFlagRecursive; }
1831 bool isObjCDirect() const { return getSPFlags() & SPFlagObjCDirect; }
1832
1833 /// Check if this is deleted member function.
1834 ///
1835 /// Return true if this subprogram is a C++11 special
1836 /// member function declared deleted.
1837 bool isDeleted() const { return getSPFlags() & SPFlagDeleted; }
1838
1839 /// Check if this is reference-qualified.
1840 ///
1841 /// Return true if this subprogram is a C++11 reference-qualified non-static
1842 /// member function (void foo() &).
1843 bool isLValueReference() const { return getFlags() & FlagLValueReference; }
1844
1845 /// Check if this is rvalue-reference-qualified.
1846 ///
1847 /// Return true if this subprogram is a C++11 rvalue-reference-qualified
1848 /// non-static member function (void foo() &&).
1849 bool isRValueReference() const { return getFlags() & FlagRValueReference; }
1850
1851 /// Check if this is marked as noreturn.
1852 ///
1853 /// Return true if this subprogram is C++11 noreturn or C11 _Noreturn
1854 bool isNoReturn() const { return getFlags() & FlagNoReturn; }
1855
1856 // Check if this routine is a compiler-generated thunk.
1857 //
1858 // Returns true if this subprogram is a thunk generated by the compiler.
1859 bool isThunk() const { return getFlags() & FlagThunk; }
1860
1861 DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
1862
1863 StringRef getName() const { return getStringOperand(2); }
1864 StringRef getLinkageName() const { return getStringOperand(3); }
1865 /// Only used by clients of CloneFunction, and only right after the cloning.
1866 void replaceLinkageName(MDString *LN) { replaceOperandWith(3, LN); }
1867
1868 DISubroutineType *getType() const {
1869 return cast_or_null<DISubroutineType>(getRawType());
1870 }
1871 DIType *getContainingType() const {
1872 return cast_or_null<DIType>(getRawContainingType());
1873 }
1874 void replaceType(DISubroutineType *Ty) {
1875 assert(isDistinct() && "Only distinct nodes can mutate");
1876 replaceOperandWith(4, Ty);
1877 }
1878
1879 DICompileUnit *getUnit() const {
1880 return cast_or_null<DICompileUnit>(getRawUnit());
1881 }
1882 void replaceUnit(DICompileUnit *CU) { replaceOperandWith(5, CU); }
1883 DITemplateParameterArray getTemplateParams() const {
1884 return cast_or_null<MDTuple>(getRawTemplateParams());
1885 }
1886 DISubprogram *getDeclaration() const {
1887 return cast_or_null<DISubprogram>(getRawDeclaration());
1888 }
1889 void replaceDeclaration(DISubprogram *Decl) { replaceOperandWith(6, Decl); }
1890 DINodeArray getRetainedNodes() const {
1891 return cast_or_null<MDTuple>(getRawRetainedNodes());
1892 }
1893 DITypeArray getThrownTypes() const {
1894 return cast_or_null<MDTuple>(getRawThrownTypes());
1895 }
1896 DINodeArray getAnnotations() const {
1897 return cast_or_null<MDTuple>(getRawAnnotations());
1898 }
1899 StringRef getTargetFuncName() const {
1900 return (getRawTargetFuncName()) ? getStringOperand(12) : StringRef();
1901 }
1902
1903 Metadata *getRawScope() const { return getOperand(1); }
1904 MDString *getRawName() const { return getOperandAs<MDString>(2); }
1905 MDString *getRawLinkageName() const { return getOperandAs<MDString>(3); }
1906 Metadata *getRawType() const { return getOperand(4); }
1907 Metadata *getRawUnit() const { return getOperand(5); }
1908 Metadata *getRawDeclaration() const { return getOperand(6); }
1909 Metadata *getRawRetainedNodes() const { return getOperand(7); }
1910 Metadata *getRawContainingType() const {
1911 return getNumOperands() > 8 ? getOperandAs<Metadata>(8) : nullptr;
1912 }
1913 Metadata *getRawTemplateParams() const {
1914 return getNumOperands() > 9 ? getOperandAs<Metadata>(9) : nullptr;
1915 }
1916 Metadata *getRawThrownTypes() const {
1917 return getNumOperands() > 10 ? getOperandAs<Metadata>(10) : nullptr;
1918 }
1919 Metadata *getRawAnnotations() const {
1920 return getNumOperands() > 11 ? getOperandAs<Metadata>(11) : nullptr;
1921 }
1922 MDString *getRawTargetFuncName() const {
1923 return getNumOperands() > 12 ? getOperandAs<MDString>(12) : nullptr;
1924 }
1925
1926 void replaceRawLinkageName(MDString *LinkageName) {
1928 }
1929 void replaceRetainedNodes(DINodeArray N) {
1930 replaceOperandWith(7, N.get());
1931 }
1932
1933 /// Check if this subprogram describes the given function.
1934 ///
1935 /// FIXME: Should this be looking through bitcasts?
1936 bool describes(const Function *F) const;
1937
1938 static bool classof(const Metadata *MD) {
1939 return MD->getMetadataID() == DISubprogramKind;
1940 }
1941};
1942
1943/// Debug location.
1944///
1945/// A debug location in source code, used for debug info and otherwise.
1946///
1947/// Uses the SubclassData1, SubclassData16 and SubclassData32
1948/// Metadata slots.
1949
1950class DILocation : public MDNode {
1951 friend class LLVMContextImpl;
1952 friend class MDNode;
1953
1955 unsigned Column, ArrayRef<Metadata *> MDs, bool ImplicitCode);
1957
1958 static DILocation *getImpl(LLVMContext &Context, unsigned Line,
1959 unsigned Column, Metadata *Scope,
1961 StorageType Storage, bool ShouldCreate = true);
1962 static DILocation *getImpl(LLVMContext &Context, unsigned Line,
1963 unsigned Column, DILocalScope *Scope,
1965 StorageType Storage, bool ShouldCreate = true) {
1966 return getImpl(Context, Line, Column, static_cast<Metadata *>(Scope),
1967 static_cast<Metadata *>(InlinedAt), ImplicitCode, Storage,
1968 ShouldCreate);
1969 }
1970
1971 TempDILocation cloneImpl() const {
1972 // Get the raw scope/inlinedAt since it is possible to invoke this on
1973 // a DILocation containing temporary metadata.
1974 return getTemporary(getContext(), getLine(), getColumn(), getRawScope(),
1975 getRawInlinedAt(), isImplicitCode());
1976 }
1977
1978public:
1979 // Disallow replacing operands.
1980 void replaceOperandWith(unsigned I, Metadata *New) = delete;
1981
1983 (unsigned Line, unsigned Column, Metadata *Scope,
1984 Metadata *InlinedAt = nullptr, bool ImplicitCode = false),
1987 (unsigned Line, unsigned Column, DILocalScope *Scope,
1989 bool ImplicitCode = false),
1991
1992 /// Return a (temporary) clone of this.
1993 TempDILocation clone() const { return cloneImpl(); }
1994
1995 unsigned getLine() const { return SubclassData32; }
1996 unsigned getColumn() const { return SubclassData16; }
1997 DILocalScope *getScope() const { return cast<DILocalScope>(getRawScope()); }
1998
1999 /// Return the linkage name of Subprogram. If the linkage name is empty,
2000 /// return scope name (the demangled name).
2001 StringRef getSubprogramLinkageName() const {
2002 DISubprogram *SP = getScope()->getSubprogram();
2003 if (!SP)
2004 return "";
2005 auto Name = SP->getLinkageName();
2006 if (!Name.empty())
2007 return Name;
2008 return SP->getName();
2009 }
2010
2011 DILocation *getInlinedAt() const {
2012 return cast_or_null<DILocation>(getRawInlinedAt());
2013 }
2014
2015 /// Check if the location corresponds to an implicit code.
2016 /// When the ImplicitCode flag is true, it means that the Instruction
2017 /// with this DILocation has been added by the front-end but it hasn't been
2018 /// written explicitly by the user (e.g. cleanup stuff in C++ put on a closing
2019 /// bracket). It's useful for code coverage to not show a counter on "empty"
2020 /// lines.
2021 bool isImplicitCode() const { return SubclassData1; }
2022 void setImplicitCode(bool ImplicitCode) { SubclassData1 = ImplicitCode; }
2023
2024 DIFile *getFile() const { return getScope()->getFile(); }
2025 StringRef getFilename() const { return getScope()->getFilename(); }
2026 StringRef getDirectory() const { return getScope()->getDirectory(); }
2027 std::optional<StringRef> getSource() const { return getScope()->getSource(); }
2028
2029 /// Get the scope where this is inlined.
2030 ///
2031 /// Walk through \a getInlinedAt() and return \a getScope() from the deepest
2032 /// location.
2033 DILocalScope *getInlinedAtScope() const {
2034 if (auto *IA = getInlinedAt())
2035 return IA->getInlinedAtScope();
2036 return getScope();
2037 }
2038
2039 /// Get the DWARF discriminator.
2040 ///
2041 /// DWARF discriminators distinguish identical file locations between
2042 /// instructions that are on different basic blocks.
2043 ///
2044 /// There are 3 components stored in discriminator, from lower bits:
2045 ///
2046 /// Base discriminator: assigned by AddDiscriminators pass to identify IRs
2047 /// that are defined by the same source line, but
2048 /// different basic blocks.
2049 /// Duplication factor: assigned by optimizations that will scale down
2050 /// the execution frequency of the original IR.
2051 /// Copy Identifier: assigned by optimizations that clones the IR.
2052 /// Each copy of the IR will be assigned an identifier.
2053 ///
2054 /// Encoding:
2055 ///
2056 /// The above 3 components are encoded into a 32bit unsigned integer in
2057 /// order. If the lowest bit is 1, the current component is empty, and the
2058 /// next component will start in the next bit. Otherwise, the current
2059 /// component is non-empty, and its content starts in the next bit. The
2060 /// value of each components is either 5 bit or 12 bit: if the 7th bit
2061 /// is 0, the bit 2~6 (5 bits) are used to represent the component; if the
2062 /// 7th bit is 1, the bit 2~6 (5 bits) and 8~14 (7 bits) are combined to
2063 /// represent the component. Thus, the number of bits used for a component
2064 /// is either 0 (if it and all the next components are empty); 1 - if it is
2065 /// empty; 7 - if its value is up to and including 0x1f (lsb and msb are both
2066 /// 0); or 14, if its value is up to and including 0x1ff. Note that the last
2067 /// component is also capped at 0x1ff, even in the case when both first
2068 /// components are 0, and we'd technically have 29 bits available.
2069 ///
2070 /// For precise control over the data being encoded in the discriminator,
2071 /// use encodeDiscriminator/decodeDiscriminator.
2072
2073 inline unsigned getDiscriminator() const;
2074
2075 // For the regular discriminator, it stands for all empty components if all
2076 // the lowest 3 bits are non-zero and all higher 29 bits are unused(zero by
2077 // default). Here we fully leverage the higher 29 bits for pseudo probe use.
2078 // This is the format:
2079 // [2:0] - 0x7
2080 // [31:3] - pseudo probe fields guaranteed to be non-zero as a whole
2081 // So if the lower 3 bits is non-zero and the others has at least one
2082 // non-zero bit, it guarantees to be a pseudo probe discriminator
2083 inline static bool isPseudoProbeDiscriminator(unsigned Discriminator) {
2084 return ((Discriminator & 0x7) == 0x7) && (Discriminator & 0xFFFFFFF8);
2085 }
2086
2087 /// Returns a new DILocation with updated \p Discriminator.
2088 inline const DILocation *cloneWithDiscriminator(unsigned Discriminator) const;
2089
2090 /// Returns a new DILocation with updated base discriminator \p BD. Only the
2091 /// base discriminator is set in the new DILocation, the other encoded values
2092 /// are elided.
2093 /// If the discriminator cannot be encoded, the function returns std::nullopt.
2094 inline std::optional<const DILocation *>
2095 cloneWithBaseDiscriminator(unsigned BD) const;
2096
2097 /// Returns the duplication factor stored in the discriminator, or 1 if no
2098 /// duplication factor (or 0) is encoded.
2099 inline unsigned getDuplicationFactor() const;
2100
2101 /// Returns the copy identifier stored in the discriminator.
2102 inline unsigned getCopyIdentifier() const;
2103
2104 /// Returns the base discriminator stored in the discriminator.
2105 inline unsigned getBaseDiscriminator() const;
2106
2107 /// Returns a new DILocation with duplication factor \p DF * current
2108 /// duplication factor encoded in the discriminator. The current duplication
2109 /// factor is as defined by getDuplicationFactor().
2110 /// Returns std::nullopt if encoding failed.
2111 inline std::optional<const DILocation *>
2113
2114 /// When two instructions are combined into a single instruction we also
2115 /// need to combine the original locations into a single location.
2116 /// When the locations are the same we can use either location.
2117 /// When they differ, we need a third location which is distinct from either.
2118 /// If they share a common scope, use this scope and compare the line/column
2119 /// pair of the locations with the common scope:
2120 /// * if both match, keep the line and column;
2121 /// * if only the line number matches, keep the line and set the column as 0;
2122 /// * otherwise set line and column as 0.
2123 /// If they do not share a common scope the location is ambiguous and can't be
2124 /// represented in a line entry. In this case, set line and column as 0 and
2125 /// use the scope of any location.
2126 ///
2127 /// \p LocA \p LocB: The locations to be merged.
2128 static DILocation *getMergedLocation(DILocation *LocA, DILocation *LocB);
2129
2130 /// Try to combine the vector of locations passed as input in a single one.
2131 /// This function applies getMergedLocation() repeatedly left-to-right.
2132 ///
2133 /// \p Locs: The locations to be merged.
2135
2136 /// Return the masked discriminator value for an input discrimnator value D
2137 /// (i.e. zero out the (B+1)-th and above bits for D (B is 0-base).
2138 // Example: an input of (0x1FF, 7) returns 0xFF.
2139 static unsigned getMaskedDiscriminator(unsigned D, unsigned B) {
2140 return (D & getN1Bits(B));
2141 }
2142
2143 /// Return the bits used for base discriminators.
2144 static unsigned getBaseDiscriminatorBits() { return getBaseFSBitEnd(); }
2145
2146 /// Returns the base discriminator for a given encoded discriminator \p D.
2147 static unsigned
2149 bool IsFSDiscriminator = false) {
2150 // Return the probe id instead of zero for a pseudo probe discriminator.
2151 // This should help differenciate callsites with same line numbers to
2152 // achieve a decent AutoFDO profile under -fpseudo-probe-for-profiling,
2153 // where the original callsite dwarf discriminator is overwritten by
2154 // callsite probe information.
2157
2158 if (IsFSDiscriminator)
2161 }
2162
2163 /// Raw encoding of the discriminator. APIs such as cloneWithDuplicationFactor
2164 /// have certain special case behavior (e.g. treating empty duplication factor
2165 /// as the value '1').
2166 /// This API, in conjunction with cloneWithDiscriminator, may be used to
2167 /// encode the raw values provided.
2168 ///
2169 /// \p BD: base discriminator
2170 /// \p DF: duplication factor
2171 /// \p CI: copy index
2172 ///
2173 /// The return is std::nullopt if the values cannot be encoded in 32 bits -
2174 /// for example, values for BD or DF larger than 12 bits. Otherwise, the
2175 /// return is the encoded value.
2176 static std::optional<unsigned> encodeDiscriminator(unsigned BD, unsigned DF,
2177 unsigned CI);
2178
2179 /// Raw decoder for values in an encoded discriminator D.
2180 static void decodeDiscriminator(unsigned D, unsigned &BD, unsigned &DF,
2181 unsigned &CI);
2182
2183 /// Returns the duplication factor for a given encoded discriminator \p D, or
2184 /// 1 if no value or 0 is encoded.
2185 static unsigned getDuplicationFactorFromDiscriminator(unsigned D) {
2187 return 1;
2189 unsigned Ret = getUnsignedFromPrefixEncoding(D);
2190 if (Ret == 0)
2191 return 1;
2192 return Ret;
2193 }
2194
2195 /// Returns the copy identifier for a given encoded discriminator \p D.
2196 static unsigned getCopyIdentifierFromDiscriminator(unsigned D) {
2199 }
2200
2201 Metadata *getRawScope() const { return getOperand(0); }
2203 if (getNumOperands() == 2)
2204 return getOperand(1);
2205 return nullptr;
2206 }
2207
2208 static bool classof(const Metadata *MD) {
2209 return MD->getMetadataID() == DILocationKind;
2210 }
2211};
2212
2214protected:
2218
2219public:
2220 DILocalScope *getScope() const { return cast<DILocalScope>(getRawScope()); }
2221
2222 Metadata *getRawScope() const { return getOperand(1); }
2223
2224 void replaceScope(DIScope *Scope) {
2225 assert(!isUniqued());
2226 setOperand(1, Scope);
2227 }
2228
2229 static bool classof(const Metadata *MD) {
2230 return MD->getMetadataID() == DILexicalBlockKind ||
2231 MD->getMetadataID() == DILexicalBlockFileKind;
2232 }
2233};
2234
2235/// Debug lexical block.
2236///
2237/// Uses the SubclassData32 Metadata slot.
2239 friend class LLVMContextImpl;
2240 friend class MDNode;
2241
2242 uint16_t Column;
2243
2245 unsigned Column, ArrayRef<Metadata *> Ops)
2246 : DILexicalBlockBase(C, DILexicalBlockKind, Storage, Ops),
2247 Column(Column) {
2249 assert(Column < (1u << 16) && "Expected 16-bit column");
2250 }
2251 ~DILexicalBlock() = default;
2252
2253 static DILexicalBlock *getImpl(LLVMContext &Context, DILocalScope *Scope,
2254 DIFile *File, unsigned Line, unsigned Column,
2256 bool ShouldCreate = true) {
2257 return getImpl(Context, static_cast<Metadata *>(Scope),
2258 static_cast<Metadata *>(File), Line, Column, Storage,
2259 ShouldCreate);
2260 }
2261
2262 static DILexicalBlock *getImpl(LLVMContext &Context, Metadata *Scope,
2263 Metadata *File, unsigned Line, unsigned Column,
2264 StorageType Storage, bool ShouldCreate = true);
2265
2266 TempDILexicalBlock cloneImpl() const {
2268 getColumn());
2269 }
2270
2271public:
2273 (DILocalScope * Scope, DIFile *File, unsigned Line,
2274 unsigned Column),
2275 (Scope, File, Line, Column))
2278 unsigned Column),
2279 (Scope, File, Line, Column))
2280
2281 TempDILexicalBlock clone() const { return cloneImpl(); }
2282
2283 unsigned getLine() const { return SubclassData32; }
2284 unsigned getColumn() const { return Column; }
2285
2286 static bool classof(const Metadata *MD) {
2287 return MD->getMetadataID() == DILexicalBlockKind;
2288 }
2289};
2290
2292 friend class LLVMContextImpl;
2293 friend class MDNode;
2294
2296 unsigned Discriminator, ArrayRef<Metadata *> Ops)
2297 : DILexicalBlockBase(C, DILexicalBlockFileKind, Storage, Ops) {
2299 }
2300 ~DILexicalBlockFile() = default;
2301
2302 static DILexicalBlockFile *getImpl(LLVMContext &Context, DILocalScope *Scope,
2303 DIFile *File, unsigned Discriminator,
2305 bool ShouldCreate = true) {
2306 return getImpl(Context, static_cast<Metadata *>(Scope),
2307 static_cast<Metadata *>(File), Discriminator, Storage,
2308 ShouldCreate);
2309 }
2310
2311 static DILexicalBlockFile *getImpl(LLVMContext &Context, Metadata *Scope,
2312 Metadata *File, unsigned Discriminator,
2314 bool ShouldCreate = true);
2315
2316 TempDILexicalBlockFile cloneImpl() const {
2317 return getTemporary(getContext(), getScope(), getFile(),
2319 }
2320
2321public:
2324 unsigned Discriminator),
2329
2330 TempDILexicalBlockFile clone() const { return cloneImpl(); }
2331 unsigned getDiscriminator() const { return SubclassData32; }
2332
2333 static bool classof(const Metadata *MD) {
2334 return MD->getMetadataID() == DILexicalBlockFileKind;
2335 }
2336};
2337
2338unsigned DILocation::getDiscriminator() const {
2339 if (auto *F = dyn_cast<DILexicalBlockFile>(getScope()))
2340 return F->getDiscriminator();
2341 return 0;
2342}
2343
2344const DILocation *
2345DILocation::cloneWithDiscriminator(unsigned Discriminator) const {
2346 DIScope *Scope = getScope();
2347 // Skip all parent DILexicalBlockFile that already have a discriminator
2348 // assigned. We do not want to have nested DILexicalBlockFiles that have
2349 // mutliple discriminators because only the leaf DILexicalBlockFile's
2350 // dominator will be used.
2351 for (auto *LBF = dyn_cast<DILexicalBlockFile>(Scope);
2352 LBF && LBF->getDiscriminator() != 0;
2353 LBF = dyn_cast<DILexicalBlockFile>(Scope))
2354 Scope = LBF->getScope();
2355 DILexicalBlockFile *NewScope =
2356 DILexicalBlockFile::get(getContext(), Scope, getFile(), Discriminator);
2357 return DILocation::get(getContext(), getLine(), getColumn(), NewScope,
2358 getInlinedAt());
2359}
2360
2362 return getBaseDiscriminatorFromDiscriminator(getDiscriminator(),
2364}
2365
2367 return getDuplicationFactorFromDiscriminator(getDiscriminator());
2368}
2369
2371 return getCopyIdentifierFromDiscriminator(getDiscriminator());
2372}
2373
2374std::optional<const DILocation *>
2376 unsigned BD, DF, CI;
2377
2379 BD = getBaseDiscriminator();
2380 if (D == BD)
2381 return this;
2382 return cloneWithDiscriminator(D);
2383 }
2384
2385 decodeDiscriminator(getDiscriminator(), BD, DF, CI);
2386 if (D == BD)
2387 return this;
2388 if (std::optional<unsigned> Encoded = encodeDiscriminator(D, DF, CI))
2389 return cloneWithDiscriminator(*Encoded);
2390 return std::nullopt;
2391}
2392
2393std::optional<const DILocation *>
2395 assert(!EnableFSDiscriminator && "FSDiscriminator should not call this.");
2396 // Do no interfere with pseudo probes. Pseudo probe doesn't need duplication
2397 // factor support as samples collected on cloned probes will be aggregated.
2398 // Also pseudo probe at a callsite uses the dwarf discriminator to store
2399 // pseudo probe related information, such as the probe id.
2400 if (isPseudoProbeDiscriminator(getDiscriminator()))
2401 return this;
2402
2404 if (DF <= 1)
2405 return this;
2406
2407 unsigned BD = getBaseDiscriminator();
2408 unsigned CI = getCopyIdentifier();
2409 if (std::optional<unsigned> D = encodeDiscriminator(BD, DF, CI))
2410 return cloneWithDiscriminator(*D);
2411 return std::nullopt;
2412}
2413
2414/// Debug lexical block.
2415///
2416/// Uses the SubclassData1 Metadata slot.
2417class DINamespace : public DIScope {
2418 friend class LLVMContextImpl;
2419 friend class MDNode;
2420
2423 ~DINamespace() = default;
2424
2425 static DINamespace *getImpl(LLVMContext &Context, DIScope *Scope,
2427 StorageType Storage, bool ShouldCreate = true) {
2428 return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
2429 ExportSymbols, Storage, ShouldCreate);
2430 }
2431 static DINamespace *getImpl(LLVMContext &Context, Metadata *Scope,
2433 StorageType Storage, bool ShouldCreate = true);
2434
2435 TempDINamespace cloneImpl() const {
2436 return getTemporary(getContext(), getScope(), getName(),
2438 }
2439
2440public:
2447
2448 TempDINamespace clone() const { return cloneImpl(); }
2449
2450 bool getExportSymbols() const { return SubclassData1; }
2451 DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
2452 StringRef getName() const { return getStringOperand(2); }
2453
2454 Metadata *getRawScope() const { return getOperand(1); }
2455 MDString *getRawName() const { return getOperandAs<MDString>(2); }
2456
2457 static bool classof(const Metadata *MD) {
2458 return MD->getMetadataID() == DINamespaceKind;
2459 }
2460};
2461
2462/// Represents a module in the programming language, for example, a Clang
2463/// module, or a Fortran module.
2464///
2465/// Uses the SubclassData1 and SubclassData32 Metadata slots.
2466class DIModule : public DIScope {
2467 friend class LLVMContextImpl;
2468 friend class MDNode;
2469
2470 DIModule(LLVMContext &Context, StorageType Storage, unsigned LineNo,
2471 bool IsDecl, ArrayRef<Metadata *> Ops);
2472 ~DIModule() = default;
2473
2474 static DIModule *getImpl(LLVMContext &Context, DIFile *File, DIScope *Scope,
2477 unsigned LineNo, bool IsDecl, StorageType Storage,
2478 bool ShouldCreate = true) {
2479 return getImpl(Context, File, Scope, getCanonicalMDString(Context, Name),
2482 getCanonicalMDString(Context, APINotesFile), LineNo, IsDecl,
2483 Storage, ShouldCreate);
2484 }
2485 static DIModule *getImpl(LLVMContext &Context, Metadata *File,
2488 MDString *APINotesFile, unsigned LineNo, bool IsDecl,
2489 StorageType Storage, bool ShouldCreate = true);
2490
2491 TempDIModule cloneImpl() const {
2493 getConfigurationMacros(), getIncludePath(),
2494 getAPINotesFile(), getLineNo(), getIsDecl());
2495 }
2496
2497public:
2501 StringRef APINotesFile, unsigned LineNo,
2502 bool IsDecl = false),
2504 APINotesFile, LineNo, IsDecl))
2509 bool IsDecl = false),
2511 APINotesFile, LineNo, IsDecl))
2512
2513 TempDIModule clone() const { return cloneImpl(); }
2514
2515 DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
2516 StringRef getName() const { return getStringOperand(2); }
2517 StringRef getConfigurationMacros() const { return getStringOperand(3); }
2518 StringRef getIncludePath() const { return getStringOperand(4); }
2519 StringRef getAPINotesFile() const { return getStringOperand(5); }
2520 unsigned getLineNo() const { return SubclassData32; }
2521 bool getIsDecl() const { return SubclassData1; }
2522
2523 Metadata *getRawScope() const { return getOperand(1); }
2524 MDString *getRawName() const { return getOperandAs<MDString>(2); }
2525 MDString *getRawConfigurationMacros() const {
2526 return getOperandAs<MDString>(3);
2527 }
2528 MDString *getRawIncludePath() const { return getOperandAs<MDString>(4); }
2529 MDString *getRawAPINotesFile() const { return getOperandAs<MDString>(5); }
2530
2531 static bool classof(const Metadata *MD) {
2532 return MD->getMetadataID() == DIModuleKind;
2533 }
2534};
2535
2536/// Base class for template parameters.
2537///
2538/// Uses the SubclassData1 Metadata slot.
2540protected:
2542 unsigned Tag, bool IsDefault, ArrayRef<Metadata *> Ops)
2543 : DINode(Context, ID, Storage, Tag, Ops) {
2544 SubclassData1 = IsDefault;
2545 }
2547
2548public:
2549 StringRef getName() const { return getStringOperand(0); }
2550 DIType *getType() const { return cast_or_null<DIType>(getRawType()); }
2551
2552 MDString *getRawName() const { return getOperandAs<MDString>(0); }
2553 Metadata *getRawType() const { return getOperand(1); }
2554 bool isDefault() const { return SubclassData1; }
2555
2556 static bool classof(const Metadata *MD) {
2557 return MD->getMetadataID() == DITemplateTypeParameterKind ||
2558 MD->getMetadataID() == DITemplateValueParameterKind;
2559 }
2560};
2561
2563 friend class LLVMContextImpl;
2564 friend class MDNode;
2565
2568 ~DITemplateTypeParameter() = default;
2569
2570 static DITemplateTypeParameter *getImpl(LLVMContext &Context, StringRef Name,
2571 DIType *Type, bool IsDefault,
2573 bool ShouldCreate = true) {
2574 return getImpl(Context, getCanonicalMDString(Context, Name), Type,
2575 IsDefault, Storage, ShouldCreate);
2576 }
2577 static DITemplateTypeParameter *getImpl(LLVMContext &Context, MDString *Name,
2578 Metadata *Type, bool IsDefault,
2580 bool ShouldCreate = true);
2581
2582 TempDITemplateTypeParameter cloneImpl() const {
2583 return getTemporary(getContext(), getName(), getType(), isDefault());
2584 }
2585
2586public:
2589 (Name, Type, IsDefault))
2593
2594 TempDITemplateTypeParameter clone() const { return cloneImpl(); }
2595
2596 static bool classof(const Metadata *MD) {
2597 return MD->getMetadataID() == DITemplateTypeParameterKind;
2598 }
2599};
2600
2602 friend class LLVMContextImpl;
2603 friend class MDNode;
2604
2606 unsigned Tag, bool IsDefault,
2608 : DITemplateParameter(Context, DITemplateValueParameterKind, Storage, Tag,
2609 IsDefault, Ops) {}
2610 ~DITemplateValueParameter() = default;
2611
2612 static DITemplateValueParameter *getImpl(LLVMContext &Context, unsigned Tag,
2614 bool IsDefault, Metadata *Value,
2616 bool ShouldCreate = true) {
2617 return getImpl(Context, Tag, getCanonicalMDString(Context, Name), Type,
2618 IsDefault, Value, Storage, ShouldCreate);
2619 }
2620 static DITemplateValueParameter *getImpl(LLVMContext &Context, unsigned Tag,
2621 MDString *Name, Metadata *Type,
2622 bool IsDefault, Metadata *Value,
2624 bool ShouldCreate = true);
2625
2626 TempDITemplateValueParameter cloneImpl() const {
2627 return getTemporary(getContext(), getTag(), getName(), getType(),
2628 isDefault(), getValue());
2629 }
2630
2631public:
2633 (unsigned Tag, StringRef Name, DIType *Type, bool IsDefault,
2634 Metadata *Value),
2635 (Tag, Name, Type, IsDefault, Value))
2640
2641 TempDITemplateValueParameter clone() const { return cloneImpl(); }
2642
2643 Metadata *getValue() const { return getOperand(2); }
2644
2645 static bool classof(const Metadata *MD) {
2646 return MD->getMetadataID() == DITemplateValueParameterKind;
2647 }
2648};
2649
2650/// Base class for variables.
2651///
2652/// Uses the SubclassData32 Metadata slot.
2653class DIVariable : public DINode {
2654 unsigned Line;
2655
2656protected:
2657 DIVariable(LLVMContext &C, unsigned ID, StorageType Storage, signed Line,
2658 ArrayRef<Metadata *> Ops, uint32_t AlignInBits = 0);
2659 ~DIVariable() = default;
2660
2661public:
2662 unsigned getLine() const { return Line; }
2663 DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
2664 StringRef getName() const { return getStringOperand(1); }
2665 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
2666 DIType *getType() const { return cast_or_null<DIType>(getRawType()); }
2668 uint32_t getAlignInBytes() const { return getAlignInBits() / CHAR_BIT; }
2669 /// Determines the size of the variable's type.
2670 std::optional<uint64_t> getSizeInBits() const;
2671
2672 /// Return the signedness of this variable's type, or std::nullopt if this
2673 /// type is neither signed nor unsigned.
2674 std::optional<DIBasicType::Signedness> getSignedness() const {
2675 if (auto *BT = dyn_cast<DIBasicType>(getType()))
2676 return BT->getSignedness();
2677 return std::nullopt;
2678 }
2679
2681 if (auto *F = getFile())
2682 return F->getFilename();
2683 return "";
2684 }
2685
2687 if (auto *F = getFile())
2688 return F->getDirectory();
2689 return "";
2690 }
2691
2692 std::optional<StringRef> getSource() const {
2693 if (auto *F = getFile())
2694 return F->getSource();
2695 return std::nullopt;
2696 }
2697
2698 Metadata *getRawScope() const { return getOperand(0); }
2699 MDString *getRawName() const { return getOperandAs<MDString>(1); }
2700 Metadata *getRawFile() const { return getOperand(2); }
2701 Metadata *getRawType() const { return getOperand(3); }
2702
2703 static bool classof(const Metadata *MD) {
2704 return MD->getMetadataID() == DILocalVariableKind ||
2705 MD->getMetadataID() == DIGlobalVariableKind;
2706 }
2707};
2708
2709/// DWARF expression.
2710///
2711/// This is (almost) a DWARF expression that modifies the location of a
2712/// variable, or the location of a single piece of a variable, or (when using
2713/// DW_OP_stack_value) is the constant variable value.
2714///
2715/// TODO: Co-allocate the expression elements.
2716/// TODO: Separate from MDNode, or otherwise drop Distinct and Temporary
2717/// storage types.
2718class DIExpression : public MDNode {
2719 friend class LLVMContextImpl;
2720 friend class MDNode;
2721
2722 std::vector<uint64_t> Elements;
2723
2725 : MDNode(C, DIExpressionKind, Storage, std::nullopt),
2726 Elements(Elements.begin(), Elements.end()) {}
2727 ~DIExpression() = default;
2728
2729 static DIExpression *getImpl(LLVMContext &Context,
2731 bool ShouldCreate = true);
2732
2733 TempDIExpression cloneImpl() const {
2734 return getTemporary(getContext(), getElements());
2735 }
2736
2737public:
2739
2740 TempDIExpression clone() const { return cloneImpl(); }
2741
2742 ArrayRef<uint64_t> getElements() const { return Elements; }
2743
2744 unsigned getNumElements() const { return Elements.size(); }
2745
2746 uint64_t getElement(unsigned I) const {
2747 assert(I < Elements.size() && "Index out of range");
2748 return Elements[I];
2749 }
2750
2752 /// Determine whether this represents a constant value, if so
2753 // return it's sign information.
2754 std::optional<SignedOrUnsignedConstant> isConstant() const;
2755
2756 /// Return the number of unique location operands referred to (via
2757 /// DW_OP_LLVM_arg) in this expression; this is not necessarily the number of
2758 /// instances of DW_OP_LLVM_arg within the expression.
2759 /// For example, for the expression:
2760 /// (DW_OP_LLVM_arg 0, DW_OP_LLVM_arg 1, DW_OP_plus,
2761 /// DW_OP_LLVM_arg 0, DW_OP_mul)
2762 /// This function would return 2, as there are two unique location operands
2763 /// (0 and 1).
2765
2767
2770
2771 /// A lightweight wrapper around an expression operand.
2772 ///
2773 /// TODO: Store arguments directly and change \a DIExpression to store a
2774 /// range of these.
2776 const uint64_t *Op = nullptr;
2777
2778 public:
2779 ExprOperand() = default;
2780 explicit ExprOperand(const uint64_t *Op) : Op(Op) {}
2781
2782 const uint64_t *get() const { return Op; }
2783
2784 /// Get the operand code.
2785 uint64_t getOp() const { return *Op; }
2786
2787 /// Get an argument to the operand.
2788 ///
2789 /// Never returns the operand itself.
2790 uint64_t getArg(unsigned I) const { return Op[I + 1]; }
2791
2792 unsigned getNumArgs() const { return getSize() - 1; }
2793
2794 /// Return the size of the operand.
2795 ///
2796 /// Return the number of elements in the operand (1 + args).
2797 unsigned getSize() const;
2798
2799 /// Append the elements of this operand to \p V.
2801 V.append(get(), get() + getSize());
2802 }
2803 };
2804
2805 /// An iterator for expression operands.
2808
2809 public:
2810 using iterator_category = std::input_iterator_tag;
2812 using difference_type = std::ptrdiff_t;
2815
2816 expr_op_iterator() = default;
2818
2819 element_iterator getBase() const { return Op.get(); }
2820 const ExprOperand &operator*() const { return Op; }
2821 const ExprOperand *operator->() const { return &Op; }
2822
2824 increment();
2825 return *this;
2826 }
2828 expr_op_iterator T(*this);
2829 increment();
2830 return T;
2831 }
2832
2833 /// Get the next iterator.
2834 ///
2835 /// \a std::next() doesn't work because this is technically an
2836 /// input_iterator, but it's a perfectly valid operation. This is an
2837 /// accessor to provide the same functionality.
2838 expr_op_iterator getNext() const { return ++expr_op_iterator(*this); }
2839
2840 bool operator==(const expr_op_iterator &X) const {
2841 return getBase() == X.getBase();
2842 }
2843 bool operator!=(const expr_op_iterator &X) const {
2844 return getBase() != X.getBase();
2845 }
2846
2847 private:
2848 void increment() { Op = ExprOperand(getBase() + Op.getSize()); }
2849 };
2850
2851 /// Visit the elements via ExprOperand wrappers.
2852 ///
2853 /// These range iterators visit elements through \a ExprOperand wrappers.
2854 /// This is not guaranteed to be a valid range unless \a isValid() gives \c
2855 /// true.
2856 ///
2857 /// \pre \a isValid() gives \c true.
2858 /// @{
2861 }
2864 }
2866 return {expr_op_begin(), expr_op_end()};
2867 }
2868 /// @}
2869
2870 bool isValid() const;
2871
2872 static bool classof(const Metadata *MD) {
2873 return MD->getMetadataID() == DIExpressionKind;
2874 }
2875
2876 /// Return whether the first element a DW_OP_deref.
2877 bool startsWithDeref() const;
2878
2879 /// Return whether there is exactly one operator and it is a DW_OP_deref;
2880 bool isDeref() const;
2881
2882 /// Holds the characteristics of one fragment of a larger variable.
2884 FragmentInfo() = default;
2889 /// Return the index of the first bit of the fragment.
2891 /// Return the index of the bit after the end of the fragment, e.g. for
2892 /// fragment offset=16 and size=32 return their sum, 48.
2894
2895 /// Returns a zero-sized fragment if A and B don't intersect.
2898 uint64_t StartInBits = std::max(A.OffsetInBits, B.OffsetInBits);
2899 uint64_t EndInBits = std::min(A.endInBits(), B.endInBits());
2900 if (EndInBits <= StartInBits)
2901 return {0, 0};
2902 return DIExpression::FragmentInfo(EndInBits - StartInBits, StartInBits);
2903 }
2904 };
2905
2906 /// Retrieve the details of this fragment expression.
2907 static std::optional<FragmentInfo> getFragmentInfo(expr_op_iterator Start,
2908 expr_op_iterator End);
2909
2910 /// Retrieve the details of this fragment expression.
2911 std::optional<FragmentInfo> getFragmentInfo() const {
2913 }
2914
2915 /// Return whether this is a piece of an aggregate variable.
2916 bool isFragment() const { return getFragmentInfo().has_value(); }
2917
2918 /// Return whether this is an implicit location description.
2919 bool isImplicit() const;
2920
2921 /// Return whether the location is computed on the expression stack, meaning
2922 /// it cannot be a simple register location.
2923 bool isComplex() const;
2924
2925 /// Return whether the evaluated expression makes use of a single location at
2926 /// the start of the expression, i.e. if it contains only a single
2927 /// DW_OP_LLVM_arg op as its first operand, or if it contains none.
2928 bool isSingleLocationExpression() const;
2929
2930 /// Returns a reference to the elements contained in this expression, skipping
2931 /// past the leading `DW_OP_LLVM_arg, 0` if one is present.
2932 /// Similar to `convertToNonVariadicExpression`, but faster and cheaper - it
2933 /// does not check whether the expression is a single-location expression, and
2934 /// it returns elements rather than creating a new DIExpression.
2935 std::optional<ArrayRef<uint64_t>> getSingleLocationExpressionElements() const;
2936
2937 /// Removes all elements from \p Expr that do not apply to an undef debug
2938 /// value, which includes every operator that computes the value/location on
2939 /// the DWARF stack, including any DW_OP_LLVM_arg elements (making the result
2940 /// of this function always a single-location expression) while leaving
2941 /// everything that defines what the computed value applies to, i.e. the
2942 /// fragment information.
2943 static const DIExpression *convertToUndefExpression(const DIExpression *Expr);
2944
2945 /// If \p Expr is a non-variadic expression (i.e. one that does not contain
2946 /// DW_OP_LLVM_arg), returns \p Expr converted to variadic form by adding a
2947 /// leading [DW_OP_LLVM_arg, 0] to the expression; otherwise returns \p Expr.
2948 static const DIExpression *
2950
2951 /// If \p Expr is a valid single-location expression, i.e. it refers to only a
2952 /// single debug operand at the start of the expression, then return that
2953 /// expression in a non-variadic form by removing DW_OP_LLVM_arg from the
2954 /// expression if it is present; otherwise returns std::nullopt.
2955 /// See also `getSingleLocationExpressionElements` above, which skips
2956 /// checking `isSingleLocationExpression` and returns a list of elements
2957 /// rather than a DIExpression.
2958 static std::optional<const DIExpression *>
2960
2961 /// Inserts the elements of \p Expr into \p Ops modified to a canonical form,
2962 /// which uses DW_OP_LLVM_arg (i.e. is a variadic expression) and folds the
2963 /// implied derefence from the \p IsIndirect flag into the expression. This
2964 /// allows us to check equivalence between expressions with differing
2965 /// directness or variadicness.
2967 const DIExpression *Expr,
2968 bool IsIndirect);
2969
2970 /// Determines whether two debug values should produce equivalent DWARF
2971 /// expressions, using their DIExpressions and directness, ignoring the
2972 /// differences between otherwise identical expressions in variadic and
2973 /// non-variadic form and not considering the debug operands.
2974 /// \p FirstExpr is the DIExpression for the first debug value.
2975 /// \p FirstIndirect should be true if the first debug value is indirect; in
2976 /// IR this should be true for dbg.declare intrinsics and false for
2977 /// dbg.values, and in MIR this should be true only for DBG_VALUE instructions
2978 /// whose second operand is an immediate value.
2979 /// \p SecondExpr and \p SecondIndirect have the same meaning as the prior
2980 /// arguments, but apply to the second debug value.
2981 static bool isEqualExpression(const DIExpression *FirstExpr,
2982 bool FirstIndirect,
2983 const DIExpression *SecondExpr,
2984 bool SecondIndirect);
2985
2986 /// Append \p Ops with operations to apply the \p Offset.
2987 static void appendOffset(SmallVectorImpl<uint64_t> &Ops, int64_t Offset);
2988
2989 /// If this is a constant offset, extract it. If there is no expression,
2990 /// return true with an offset of zero.
2991 bool extractIfOffset(int64_t &Offset) const;
2992
2993 /// Returns true iff this DIExpression contains at least one instance of
2994 /// `DW_OP_LLVM_arg, n` for all n in [0, N).
2995 bool hasAllLocationOps(unsigned N) const;
2996
2997 /// Checks if the last 4 elements of the expression are DW_OP_constu <DWARF
2998 /// Address Space> DW_OP_swap DW_OP_xderef and extracts the <DWARF Address
2999 /// Space>.
3000 static const DIExpression *extractAddressClass(const DIExpression *Expr,
3001 unsigned &AddrClass);
3002
3003 /// Used for DIExpression::prepend.
3004 enum PrependOps : uint8_t {
3006 DerefBefore = 1 << 0,
3007 DerefAfter = 1 << 1,
3008 StackValue = 1 << 2,
3009 EntryValue = 1 << 3
3011
3012 /// Prepend \p DIExpr with a deref and offset operation and optionally turn it
3013 /// into a stack value or/and an entry value.
3014 static DIExpression *prepend(const DIExpression *Expr, uint8_t Flags,
3015 int64_t Offset = 0);
3016
3017 /// Prepend \p DIExpr with the given opcodes and optionally turn it into a
3018 /// stack value.
3019 static DIExpression *prependOpcodes(const DIExpression *Expr,
3021 bool StackValue = false,
3022 bool EntryValue = false);
3023
3024 /// Append the opcodes \p Ops to \p DIExpr. Unlike \ref appendToStack, the
3025 /// returned expression is a stack value only if \p DIExpr is a stack value.
3026 /// If \p DIExpr describes a fragment, the returned expression will describe
3027 /// the same fragment.
3028 static DIExpression *append(const DIExpression *Expr, ArrayRef<uint64_t> Ops);
3029
3030 /// Convert \p DIExpr into a stack value if it isn't one already by appending
3031 /// DW_OP_deref if needed, and appending \p Ops to the resulting expression.
3032 /// If \p DIExpr describes a fragment, the returned expression will describe
3033 /// the same fragment.
3034 static DIExpression *appendToStack(const DIExpression *Expr,
3035 ArrayRef<uint64_t> Ops);
3036
3037 /// Create a copy of \p Expr by appending the given list of \p Ops to each
3038 /// instance of the operand `DW_OP_LLVM_arg, \p ArgNo`. This is used to
3039 /// modify a specific location used by \p Expr, such as when salvaging that
3040 /// location.
3041 static DIExpression *appendOpsToArg(const DIExpression *Expr,
3042 ArrayRef<uint64_t> Ops, unsigned ArgNo,
3043 bool StackValue = false);
3044
3045 /// Create a copy of \p Expr with each instance of
3046 /// `DW_OP_LLVM_arg, \p OldArg` replaced with `DW_OP_LLVM_arg, \p NewArg`,
3047 /// and each instance of `DW_OP_LLVM_arg, Arg` with `DW_OP_LLVM_arg, Arg - 1`
3048 /// for all Arg > \p OldArg.
3049 /// This is used when replacing one of the operands of a debug value list
3050 /// with another operand in the same list and deleting the old operand.
3051 static DIExpression *replaceArg(const DIExpression *Expr, uint64_t OldArg,
3052 uint64_t NewArg);
3053
3054 /// Create a DIExpression to describe one part of an aggregate variable that
3055 /// is fragmented across multiple Values. The DW_OP_LLVM_fragment operation
3056 /// will be appended to the elements of \c Expr. If \c Expr already contains
3057 /// a \c DW_OP_LLVM_fragment \c OffsetInBits is interpreted as an offset
3058 /// into the existing fragment.
3059 ///
3060 /// \param OffsetInBits Offset of the piece in bits.
3061 /// \param SizeInBits Size of the piece in bits.
3062 /// \return Creating a fragment expression may fail if \c Expr
3063 /// contains arithmetic operations that would be
3064 /// truncated.
3065 static std::optional<DIExpression *>
3066 createFragmentExpression(const DIExpression *Expr, unsigned OffsetInBits,
3067 unsigned SizeInBits);
3068
3069 /// Determine the relative position of the fragments passed in.
3070 /// Returns -1 if this is entirely before Other, 0 if this and Other overlap,
3071 /// 1 if this is entirely after Other.
3072 static int fragmentCmp(const FragmentInfo &A, const FragmentInfo &B) {
3073 uint64_t l1 = A.OffsetInBits;
3074 uint64_t l2 = B.OffsetInBits;
3075 uint64_t r1 = l1 + A.SizeInBits;
3076 uint64_t r2 = l2 + B.SizeInBits;
3077 if (r1 <= l2)
3078 return -1;
3079 else if (r2 <= l1)
3080 return 1;
3081 else
3082 return 0;
3083 }
3084
3085 using ExtOps = std::array<uint64_t, 6>;
3086
3087 /// Returns the ops for a zero- or sign-extension in a DIExpression.
3088 static ExtOps getExtOps(unsigned FromSize, unsigned ToSize, bool Signed);
3089
3090 /// Append a zero- or sign-extension to \p Expr. Converts the expression to a
3091 /// stack value if it isn't one already.
3092 static DIExpression *appendExt(const DIExpression *Expr, unsigned FromSize,
3093 unsigned ToSize, bool Signed);
3094
3095 /// Check if fragments overlap between a pair of FragmentInfos.
3096 static bool fragmentsOverlap(const FragmentInfo &A, const FragmentInfo &B) {
3097 return fragmentCmp(A, B) == 0;
3098 }
3099
3100 /// Determine the relative position of the fragments described by this
3101 /// DIExpression and \p Other. Calls static fragmentCmp implementation.
3102 int fragmentCmp(const DIExpression *Other) const {
3103 auto Fragment1 = *getFragmentInfo();
3104 auto Fragment2 = *Other->getFragmentInfo();
3105 return fragmentCmp(Fragment1, Fragment2);
3106 }
3107
3108 /// Check if fragments overlap between this DIExpression and \p Other.
3110 if (!isFragment() || !Other->isFragment())
3111 return true;
3112 return fragmentCmp(Other) == 0;
3113 }
3114
3115 /// Check if the expression consists of exactly one entry value operand.
3116 /// (This is the only configuration of entry values that is supported.)
3117 bool isEntryValue() const;
3118
3119 /// Try to shorten an expression with an initial constant operand.
3120 /// Returns a new expression and constant on success, or the original
3121 /// expression and constant on failure.
3122 std::pair<DIExpression *, const ConstantInt *>
3123 constantFold(const ConstantInt *CI);
3124};
3125
3128 return std::tie(A.SizeInBits, A.OffsetInBits) ==
3129 std::tie(B.SizeInBits, B.OffsetInBits);
3130}
3131
3134 return std::tie(A.SizeInBits, A.OffsetInBits) <
3135 std::tie(B.SizeInBits, B.OffsetInBits);
3136}
3137
3138template <> struct DenseMapInfo<DIExpression::FragmentInfo> {
3140 static const uint64_t MaxVal = std::numeric_limits<uint64_t>::max();
3141
3142 static inline FragInfo getEmptyKey() { return {MaxVal, MaxVal}; }
3143
3144 static inline FragInfo getTombstoneKey() { return {MaxVal - 1, MaxVal - 1}; }
3145
3146 static unsigned getHashValue(const FragInfo &Frag) {
3147 return (Frag.SizeInBits & 0xffff) << 16 | (Frag.OffsetInBits & 0xffff);
3148 }
3149
3150 static bool isEqual(const FragInfo &A, const FragInfo &B) { return A == B; }
3151};
3152
3153/// Global variables.
3154///
3155/// TODO: Remove DisplayName. It's always equal to Name.
3157 friend class LLVMContextImpl;
3158 friend class MDNode;
3159
3160 bool IsLocalToUnit;
3161 bool IsDefinition;
3162
3164 bool IsLocalToUnit, bool IsDefinition, uint32_t AlignInBits,
3166 : DIVariable(C, DIGlobalVariableKind, Storage, Line, Ops, AlignInBits),
3167 IsLocalToUnit(IsLocalToUnit), IsDefinition(IsDefinition) {}
3168 ~DIGlobalVariable() = default;
3169
3170 static DIGlobalVariable *
3171 getImpl(LLVMContext &Context, DIScope *Scope, StringRef Name,
3173 bool IsLocalToUnit, bool IsDefinition,
3176 bool ShouldCreate = true) {
3177 return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
3179 IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration,
3180 cast_or_null<Metadata>(TemplateParams), AlignInBits,
3181 Annotations.get(), Storage, ShouldCreate);
3182 }
3183 static DIGlobalVariable *
3184 getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
3185 MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type,
3186 bool IsLocalToUnit, bool IsDefinition,
3189 bool ShouldCreate = true);
3190
3191 TempDIGlobalVariable cloneImpl() const {
3196 getAnnotations());
3197 }
3198
3199public:
3203 unsigned Line, DIType *Type, bool IsLocalToUnit, bool IsDefinition,
3205 uint32_t AlignInBits, DINodeArray Annotations),
3206 (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition,
3211 unsigned Line, Metadata *Type, bool IsLocalToUnit, bool IsDefinition,
3214 (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition,
3216
3217 TempDIGlobalVariable clone() const { return cloneImpl(); }
3218
3219 bool isLocalToUnit() const { return IsLocalToUnit; }
3220 bool isDefinition() const { return IsDefinition; }
3224 return cast_or_null<DIDerivedType>(getRawStaticDataMemberDeclaration());
3225 }
3226 DINodeArray getAnnotations() const {
3227 return cast_or_null<MDTuple>(getRawAnnotations());
3228 }
3229
3230 MDString *getRawLinkageName() const { return getOperandAs<MDString>(5); }
3233 MDTuple *getTemplateParams() const { return getOperandAs<MDTuple>(7); }
3234 Metadata *getRawAnnotations() const { return getOperand(8); }
3235
3236 static bool classof(const Metadata *MD) {
3237 return MD->getMetadataID() == DIGlobalVariableKind;
3238 }
3239};
3240
3241/// Debug common block.
3242///
3243/// Uses the SubclassData32 Metadata slot.
3244class DICommonBlock : public DIScope {
3245 friend class LLVMContextImpl;
3246 friend class MDNode;
3247
3250
3251 static DICommonBlock *getImpl(LLVMContext &Context, DIScope *Scope,
3253 DIFile *File, unsigned LineNo,
3254 StorageType Storage, bool ShouldCreate = true) {
3255 return getImpl(Context, Scope, Decl, getCanonicalMDString(Context, Name),
3256 File, LineNo, Storage, ShouldCreate);
3257 }
3258 static DICommonBlock *getImpl(LLVMContext &Context, Metadata *Scope,
3260 unsigned LineNo, StorageType Storage,
3261 bool ShouldCreate = true);
3262
3263 TempDICommonBlock cloneImpl() const {
3265 getFile(), getLineNo());
3266 }
3267
3268public:
3271 DIFile *File, unsigned LineNo),
3272 (Scope, Decl, Name, File, LineNo))
3275 Metadata *File, unsigned LineNo),
3277
3278 TempDICommonBlock clone() const { return cloneImpl(); }
3279
3280 DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
3282 return cast_or_null<DIGlobalVariable>(getRawDecl());
3283 }
3284 StringRef getName() const { return getStringOperand(2); }
3285 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
3286 unsigned getLineNo() const { return SubclassData32; }
3287
3288 Metadata *getRawScope() const { return getOperand(0); }
3289 Metadata *getRawDecl() const { return getOperand(1); }
3290 MDString *getRawName() const { return getOperandAs<MDString>(2); }
3291 Metadata *getRawFile() const { return getOperand(3); }
3292
3293 static bool classof(const Metadata *MD) {
3294 return MD->getMetadataID() == DICommonBlockKind;
3295 }
3296};
3297
3298/// Local variable.
3299///
3300/// TODO: Split up flags.
3302 friend class LLVMContextImpl;
3303 friend class MDNode;
3304
3305 unsigned Arg : 16;
3306 DIFlags Flags;
3307
3309 unsigned Arg, DIFlags Flags, uint32_t AlignInBits,
3311 : DIVariable(C, DILocalVariableKind, Storage, Line, Ops, AlignInBits),
3312 Arg(Arg), Flags(Flags) {
3313 assert(Arg < (1 << 16) && "DILocalVariable: Arg out of range");
3314 }
3315 ~DILocalVariable() = default;
3316
3317 static DILocalVariable *getImpl(LLVMContext &Context, DIScope *Scope,
3318 StringRef Name, DIFile *File, unsigned Line,
3319 DIType *Type, unsigned Arg, DIFlags Flags,
3320 uint32_t AlignInBits, DINodeArray Annotations,
3322 bool ShouldCreate = true) {
3323 return getImpl(Context, Scope, getCanonicalMDString(Context, Name), File,
3324 Line, Type, Arg, Flags, AlignInBits, Annotations.get(),
3325 Storage, ShouldCreate);
3326 }
3327 static DILocalVariable *getImpl(LLVMContext &Context, Metadata *Scope,
3328 MDString *Name, Metadata *File, unsigned Line,
3329 Metadata *Type, unsigned Arg, DIFlags Flags,
3332 bool ShouldCreate = true);
3333
3334 TempDILocalVariable cloneImpl() const {
3336 getLine(), getType(), getArg(), getFlags(),
3338 }
3339
3340public:
3343 unsigned Line, DIType *Type, unsigned Arg, DIFlags Flags,
3344 uint32_t AlignInBits, DINodeArray Annotations),
3345 (Scope, Name, File, Line, Type, Arg, Flags, AlignInBits,
3346 Annotations))
3349 unsigned Line, Metadata *Type, unsigned Arg, DIFlags Flags,
3351 (Scope, Name, File, Line, Type, Arg, Flags, AlignInBits,
3352 Annotations))
3353
3354 TempDILocalVariable clone() const { return cloneImpl(); }
3355
3356 /// Get the local scope for this variable.
3357 ///
3358 /// Variables must be defined in a local scope.
3360 return cast<DILocalScope>(DIVariable::getScope());
3361 }
3362
3363 bool isParameter() const { return Arg; }
3364 unsigned getArg() const { return Arg; }
3365 DIFlags getFlags() const { return Flags; }
3366
3367 DINodeArray getAnnotations() const {
3368 return cast_or_null<MDTuple>(getRawAnnotations());
3369 }
3370 Metadata *getRawAnnotations() const { return getOperand(4); }
3371
3372 bool isArtificial() const { return getFlags() & FlagArtificial; }
3373 bool isObjectPointer() const { return getFlags() & FlagObjectPointer; }
3374
3375 /// Check that a location is valid for this variable.
3376 ///
3377 /// Check that \c DL exists, is in the same subprogram, and has the same
3378 /// inlined-at location as \c this. (Otherwise, it's not a valid attachment
3379 /// to a \a DbgInfoIntrinsic.)
3381 return DL && getScope()->getSubprogram() == DL->getScope()->getSubprogram();
3382 }
3383
3384 static bool classof(const Metadata *MD) {
3385 return MD->getMetadataID() == DILocalVariableKind;
3386 }
3387};
3388
3389/// Label.
3390///
3391/// Uses the SubclassData32 Metadata slot.
3392class DILabel : public DINode {
3393 friend class LLVMContextImpl;
3394 friend class MDNode;
3395
3398 ~DILabel() = default;
3399
3400 static DILabel *getImpl(LLVMContext &Context, DIScope *Scope, StringRef Name,
3401 DIFile *File, unsigned Line, StorageType Storage,
3402 bool ShouldCreate = true) {
3403 return getImpl(Context, Scope, getCanonicalMDString(Context, Name), File,
3404 Line, Storage, ShouldCreate);
3405 }
3406 static DILabel *getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
3407 Metadata *File, unsigned Line, StorageType Storage,
3408 bool ShouldCreate = true);
3409
3410 TempDILabel cloneImpl() const {
3412 getLine());
3413 }
3414
3415public:
3418 unsigned Line),
3419 (Scope, Name, File, Line))
3422 unsigned Line),
3424
3425 TempDILabel clone() const { return cloneImpl(); }
3426
3427 /// Get the local scope for this label.
3428 ///
3429 /// Labels must be defined in a local scope.
3431 return cast_or_null<DILocalScope>(getRawScope());
3432 }
3433 unsigned getLine() const { return SubclassData32; }
3434 StringRef getName() const { return getStringOperand(1); }
3435 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
3436
3437 Metadata *getRawScope() const { return getOperand(0); }
3438 MDString *getRawName() const { return getOperandAs<MDString>(1); }
3439 Metadata *getRawFile() const { return getOperand(2); }
3440
3441 /// Check that a location is valid for this label.
3442 ///
3443 /// Check that \c DL exists, is in the same subprogram, and has the same
3444 /// inlined-at location as \c this. (Otherwise, it's not a valid attachment
3445 /// to a \a DbgInfoIntrinsic.)
3447 return DL && getScope()->getSubprogram() == DL->getScope()->getSubprogram();
3448 }
3449
3450 static bool classof(const Metadata *MD) {
3451 return MD->getMetadataID() == DILabelKind;
3452 }
3453};
3454
3455class DIObjCProperty : public DINode {
3456 friend class LLVMContextImpl;
3457 friend class MDNode;
3458
3459 unsigned Line;
3460 unsigned Attributes;
3461
3463 unsigned Attributes, ArrayRef<Metadata *> Ops);
3464 ~DIObjCProperty() = default;
3465
3466 static DIObjCProperty *
3467 getImpl(LLVMContext &Context, StringRef Name, DIFile *File, unsigned Line,
3468 StringRef GetterName, StringRef SetterName, unsigned Attributes,
3469 DIType *Type, StorageType Storage, bool ShouldCreate = true) {
3470 return getImpl(Context, getCanonicalMDString(Context, Name), File, Line,
3472 getCanonicalMDString(Context, SetterName), Attributes, Type,
3473 Storage, ShouldCreate);
3474 }
3475 static DIObjCProperty *getImpl(LLVMContext &Context, MDString *Name,
3476 Metadata *File, unsigned Line,
3478 unsigned Attributes, Metadata *Type,
3479 StorageType Storage, bool ShouldCreate = true);
3480
3481 TempDIObjCProperty cloneImpl() const {
3482 return getTemporary(getContext(), getName(), getFile(), getLine(),
3484 getType());
3485 }
3486
3487public:
3489 (StringRef Name, DIFile *File, unsigned Line,
3491 unsigned Attributes, DIType *Type),
3492 (Name, File, Line, GetterName, SetterName, Attributes,
3493 Type))
3495 (MDString * Name, Metadata *File, unsigned Line,
3497 unsigned Attributes, Metadata *Type),
3498 (Name, File, Line, GetterName, SetterName, Attributes,
3499 Type))
3500
3501 TempDIObjCProperty clone() const { return cloneImpl(); }
3502
3503 unsigned getLine() const { return Line; }
3504 unsigned getAttributes() const { return Attributes; }
3505 StringRef getName() const { return getStringOperand(0); }
3506 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
3509 DIType *getType() const { return cast_or_null<DIType>(getRawType()); }
3510
3512 if (auto *F = getFile())
3513 return F->getFilename();
3514 return "";
3515 }
3516
3518 if (auto *F = getFile())
3519 return F->getDirectory();
3520 return "";
3521 }
3522
3523 MDString *getRawName() const { return getOperandAs<MDString>(0); }
3524 Metadata *getRawFile() const { return getOperand(1); }
3525 MDString *getRawGetterName() const { return getOperandAs<MDString>(2); }
3526 MDString *getRawSetterName() const { return getOperandAs<MDString>(3); }
3527 Metadata *getRawType() const { return getOperand(4); }
3528
3529 static bool classof(const Metadata *MD) {
3530 return MD->getMetadataID() == DIObjCPropertyKind;
3531 }
3532};
3533
3534/// An imported module (C++ using directive or similar).
3535///
3536/// Uses the SubclassData32 Metadata slot.
3537class DIImportedEntity : public DINode {
3538 friend class LLVMContextImpl;
3539 friend class MDNode;
3540
3542 unsigned Line, ArrayRef<Metadata *> Ops)
3543 : DINode(C, DIImportedEntityKind, Storage, Tag, Ops) {
3545 }
3546 ~DIImportedEntity() = default;
3547
3548 static DIImportedEntity *getImpl(LLVMContext &Context, unsigned Tag,
3550 unsigned Line, StringRef Name,
3551 DINodeArray Elements, StorageType Storage,
3552 bool ShouldCreate = true) {
3553 return getImpl(Context, Tag, Scope, Entity, File, Line,
3554 getCanonicalMDString(Context, Name), Elements.get(), Storage,
3555 ShouldCreate);
3556 }
3557 static DIImportedEntity *
3558 getImpl(LLVMContext &Context, unsigned Tag, Metadata *Scope, Metadata *Entity,
3559 Metadata *File, unsigned Line, MDString *Name, Metadata *Elements,
3560 StorageType Storage, bool ShouldCreate = true);
3561
3562 TempDIImportedEntity cloneImpl() const {
3563 return getTemporary(getContext(), getTag(), getScope(), getEntity(),
3564 getFile(), getLine(), getName(), getElements());
3565 }
3566
3567public:
3569 (unsigned Tag, DIScope *Scope, DINode *Entity, DIFile *File,
3570 unsigned Line, StringRef Name = "",
3571 DINodeArray Elements = nullptr),
3572 (Tag, Scope, Entity, File, Line, Name, Elements))
3576 Metadata *Elements = nullptr),
3577 (Tag, Scope, Entity, File, Line, Name, Elements))
3578
3579 TempDIImportedEntity clone() const { return cloneImpl(); }
3580
3581 unsigned getLine() const { return SubclassData32; }
3582 DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
3583 DINode *getEntity() const { return cast_or_null<DINode>(getRawEntity()); }
3584 StringRef getName() const { return getStringOperand(2); }
3585 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
3586 DINodeArray getElements() const {
3587 return cast_or_null<MDTuple>(getRawElements());
3588 }
3589
3590 Metadata *getRawScope() const { return getOperand(0); }
3591 Metadata *getRawEntity() const { return getOperand(1); }
3592 MDString *getRawName() const { return getOperandAs<MDString>(2); }
3593 Metadata *getRawFile() const { return getOperand(3); }
3594 Metadata *getRawElements() const { return getOperand(4); }
3595
3596 static bool classof(const Metadata *MD) {
3597 return MD->getMetadataID() == DIImportedEntityKind;
3598 }
3599};
3600
3601/// A pair of DIGlobalVariable and DIExpression.
3603 friend class LLVMContextImpl;
3604 friend class MDNode;
3605
3608 : MDNode(C, DIGlobalVariableExpressionKind, Storage, Ops) {}
3609 ~DIGlobalVariableExpression() = default;
3610
3612 getImpl(LLVMContext &Context, Metadata *Variable, Metadata *Expression,
3613 StorageType Storage, bool ShouldCreate = true);
3614
3615 TempDIGlobalVariableExpression cloneImpl() const {
3617 }
3618
3619public:
3621 (Metadata * Variable, Metadata *Expression),
3622 (Variable, Expression))
3623
3624 TempDIGlobalVariableExpression clone() const { return cloneImpl(); }
3625
3626 Metadata *getRawVariable() const { return getOperand(0); }
3627
3629 return cast_or_null<DIGlobalVariable>(getRawVariable());
3630 }
3631
3632 Metadata *getRawExpression() const { return getOperand(1); }
3633
3635 return cast<DIExpression>(getRawExpression());
3636 }
3637
3638 static bool classof(const Metadata *MD) {
3639 return MD->getMetadataID() == DIGlobalVariableExpressionKind;
3640 }
3641};
3642
3643/// Macro Info DWARF-like metadata node.
3644///
3645/// A metadata node with a DWARF macro info (i.e., a constant named
3646/// \c DW_MACINFO_*, defined in llvm/BinaryFormat/Dwarf.h). Called \a
3647/// DIMacroNode
3648/// because it's potentially used for non-DWARF output.
3649///
3650/// Uses the SubclassData16 Metadata slot.
3651class DIMacroNode : public MDNode {
3652 friend class LLVMContextImpl;
3653 friend class MDNode;
3654
3655protected:
3656 DIMacroNode(LLVMContext &C, unsigned ID, StorageType Storage, unsigned MIType,
3658 ArrayRef<Metadata *> Ops2 = std::nullopt)
3659 : MDNode(C, ID, Storage, Ops1, Ops2) {
3660 assert(MIType < 1u << 16);
3661 SubclassData16 = MIType;
3662 }
3663 ~DIMacroNode() = default;
3664
3665 template <class Ty> Ty *getOperandAs(unsigned I) const {
3666 return cast_or_null<Ty>(getOperand(I));
3667 }
3668
3669 StringRef getStringOperand(unsigned I) const {
3670 if (auto *S = getOperandAs<MDString>(I))
3671 return S->getString();
3672 return StringRef();
3673 }
3674
3676 if (S.empty())
3677 return nullptr;
3678 return MDString::get(Context, S);
3679 }
3680
3681public:
3682 unsigned getMacinfoType() const { return SubclassData16; }
3683
3684 static bool classof(const Metadata *MD) {
3685 switch (MD->getMetadataID()) {
3686 default:
3687 return false;
3688 case DIMacroKind:
3689 case DIMacroFileKind:
3690 return true;
3691 }
3692 }
3693};
3694
3695/// Macro
3696///
3697/// Uses the SubclassData32 Metadata slot.
3698class DIMacro : public DIMacroNode {
3699 friend class LLVMContextImpl;
3700 friend class MDNode;
3701
3702 DIMacro(LLVMContext &C, StorageType Storage, unsigned MIType, unsigned Line,
3704 : DIMacroNode(C, DIMacroKind, Storage, MIType, Ops) {
3706 }
3707 ~DIMacro() = default;
3708
3709 static DIMacro *getImpl(LLVMContext &Context, unsigned MIType, unsigned Line,
3711 bool ShouldCreate = true) {
3712 return getImpl(Context, MIType, Line, getCanonicalMDString(Context, Name),
3713 getCanonicalMDString(Context, Value), Storage, ShouldCreate);
3714 }
3715 static DIMacro *getImpl(LLVMContext &Context, unsigned MIType, unsigned Line,
3716 MDString *Name, MDString *Value, StorageType Storage,
3717 bool ShouldCreate = true);
3718
3719 TempDIMacro cloneImpl() const {
3721 getValue());
3722 }
3723
3724public:
3726 (unsigned MIType, unsigned Line, StringRef Name,
3727 StringRef Value = ""),
3728 (MIType, Line, Name, Value))
3730 (unsigned MIType, unsigned Line, MDString *Name,
3733
3734 TempDIMacro clone() const { return cloneImpl(); }
3735
3736 unsigned getLine() const { return SubclassData32; }
3737
3738 StringRef getName() const { return getStringOperand(0); }
3739 StringRef getValue() const { return getStringOperand(1); }
3740
3741 MDString *getRawName() const { return getOperandAs<MDString>(0); }
3742 MDString *getRawValue() const { return getOperandAs<MDString>(1); }
3743
3744 static bool classof(const Metadata *MD) {
3745 return MD->getMetadataID() == DIMacroKind;
3746 }
3747};
3748
3749/// Macro file
3750///
3751/// Uses the SubclassData32 Metadata slot.
3752class DIMacroFile : public DIMacroNode {
3753 friend class LLVMContextImpl;
3754 friend class MDNode;
3755
3757 unsigned Line, ArrayRef<Metadata *> Ops)
3758 : DIMacroNode(C, DIMacroFileKind, Storage, MIType, Ops) {
3760 }
3761 ~DIMacroFile() = default;
3762
3763 static DIMacroFile *getImpl(LLVMContext &Context, unsigned MIType,
3764 unsigned Line, DIFile *File,
3765 DIMacroNodeArray Elements, StorageType Storage,
3766 bool ShouldCreate = true) {
3767 return getImpl(Context, MIType, Line, static_cast<Metadata *>(File),
3768 Elements.get(), Storage, ShouldCreate);
3769 }
3770
3771 static DIMacroFile *getImpl(LLVMContext &Context, unsigned MIType,
3772 unsigned Line, Metadata *File, Metadata *Elements,
3773 StorageType Storage, bool ShouldCreate = true);
3774
3775 TempDIMacroFile cloneImpl() const {
3777 getElements());
3778 }
3779
3780public:
3782 (unsigned MIType, unsigned Line, DIFile *File,
3783 DIMacroNodeArray Elements),
3784 (MIType, Line, File, Elements))
3786 (unsigned MIType, unsigned Line, Metadata *File,
3789
3790 TempDIMacroFile clone() const { return cloneImpl(); }
3791
3792 void replaceElements(DIMacroNodeArray Elements) {
3793#ifndef NDEBUG
3794 for (DIMacroNode *Op : getElements())
3795 assert(is_contained(Elements->operands(), Op) &&
3796 "Lost a macro node during macro node list replacement");
3797#endif
3798 replaceOperandWith(1, Elements.get());
3799 }
3800
3801 unsigned getLine() const { return SubclassData32; }
3802 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
3803
3804 DIMacroNodeArray getElements() const {
3805 return cast_or_null<MDTuple>(getRawElements());
3806 }
3807
3808 Metadata *getRawFile() const { return getOperand(0); }
3809 Metadata *getRawElements() const { return getOperand(1); }
3810
3811 static bool classof(const Metadata *MD) {
3812 return MD->getMetadataID() == DIMacroFileKind;
3813 }
3814};
3815
3816/// List of ValueAsMetadata, to be used as an argument to a dbg.value
3817/// intrinsic.
3820 friend class LLVMContextImpl;
3822
3824
3826 : Metadata(DIArgListKind, Uniqued), ReplaceableMetadataImpl(Context),
3827 Args(Args.begin(), Args.end()) {
3828 track();
3829 }
3830 ~DIArgList() { untrack(); }
3831
3832 void track();
3833 void untrack();
3834 void dropAllReferences(bool Untrack);
3835
3836public:
3837 static DIArgList *get(LLVMContext &Context, ArrayRef<ValueAsMetadata *> Args);
3838
3839 ArrayRef<ValueAsMetadata *> getArgs() const { return Args; }
3840
3841 iterator args_begin() { return Args.begin(); }
3842 iterator args_end() { return Args.end(); }
3843
3844 static bool classof(const Metadata *MD) {
3845 return MD->getMetadataID() == DIArgListKind;
3846 }
3847
3850 }
3851
3852 void handleChangedOperand(void *Ref, Metadata *New);
3853};
3854
3855/// Identifies a unique instance of a variable.
3856///
3857/// Storage for identifying a potentially inlined instance of a variable,
3858/// or a fragment thereof. This guarantees that exactly one variable instance
3859/// may be identified by this class, even when that variable is a fragment of
3860/// an aggregate variable and/or there is another inlined instance of the same
3861/// source code variable nearby.
3862/// This class does not necessarily uniquely identify that variable: it is
3863/// possible that a DebugVariable with different parameters may point to the
3864/// same variable instance, but not that one DebugVariable points to multiple
3865/// variable instances.
3868
3869 const DILocalVariable *Variable;
3870 std::optional<FragmentInfo> Fragment;
3871 const DILocation *InlinedAt;
3872
3873 /// Fragment that will overlap all other fragments. Used as default when
3874 /// caller demands a fragment.
3875 static const FragmentInfo DefaultFragment;
3876
3877public:
3879 DebugVariable(const DbgVariableRecord *DVR);
3880
3882 std::optional<FragmentInfo> FragmentInfo,
3883 const DILocation *InlinedAt)
3884 : Variable(Var), Fragment(FragmentInfo), InlinedAt(InlinedAt) {}
3885
3886 DebugVariable(const DILocalVariable *Var, const DIExpression *DIExpr,
3887 const DILocation *InlinedAt)
3888 : Variable(Var),
3889 Fragment(DIExpr ? DIExpr->getFragmentInfo() : std::nullopt),
3890 InlinedAt(InlinedAt) {}
3891
3892 const DILocalVariable *getVariable() const { return Variable; }
3893 std::optional<FragmentInfo> getFragment() const { return Fragment; }
3894 const DILocation *getInlinedAt() const { return InlinedAt; }
3895
3897 return Fragment.value_or(DefaultFragment);
3898 }
3899
3900 static bool isDefaultFragment(const FragmentInfo F) {
3901 return F == DefaultFragment;
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 bool operator<(const DebugVariable &Other) const {
3910 return std::tie(Variable, Fragment, InlinedAt) <
3911 std::tie(Other.Variable, Other.Fragment, Other.InlinedAt);
3912 }
3913};
3914
3915template <> struct DenseMapInfo<DebugVariable> {
3917
3918 /// Empty key: no key should be generated that has no DILocalVariable.
3919 static inline DebugVariable getEmptyKey() {
3920 return DebugVariable(nullptr, std::nullopt, nullptr);
3921 }
3922
3923 /// Difference in tombstone is that the Optional is meaningful.
3925 return DebugVariable(nullptr, {{0, 0}}, nullptr);
3926 }
3927
3928 static unsigned getHashValue(const DebugVariable &D) {
3929 unsigned HV = 0;
3930 const std::optional<FragmentInfo> Fragment = D.getFragment();
3931 if (Fragment)
3933
3934 return hash_combine(D.getVariable(), HV, D.getInlinedAt());
3935 }
3936
3937 static bool isEqual(const DebugVariable &A, const DebugVariable &B) {
3938 return A == B;
3939 }
3940};
3941
3942/// Identifies a unique instance of a whole variable (discards/ignores fragment
3943/// information).
3945public:
3948 : DebugVariable(V.getVariable(), std::nullopt, V.getInlinedAt()) {}
3949};
3950
3951template <>
3953 : public DenseMapInfo<DebugVariable> {};
3954} // end namespace llvm
3955
3956#undef DEFINE_MDNODE_GET_UNPACK_IMPL
3957#undef DEFINE_MDNODE_GET_UNPACK
3958#undef DEFINE_MDNODE_GET
3959
3960#endif // LLVM_IR_DEBUGINFOMETADATA_H
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
AMDGPU Kernel Attributes
static std::string getLinkageName(GlobalValue::LinkageTypes LT)
Definition: AsmWriter.cpp:3260
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
DITemplateParameterArray getTemplateParams() const
Get the template parameters from a template alias.
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:1461
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:1879
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