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