blob: 9dc6dfbb0f680ff0b886b3178f275be4ec856474 [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===- llvm/IR/DebugInfoMetadata.h - Debug info metadata --------*- C++ -*-===//
2//
Andrew Walbran16937d02019-10-22 13:54:20 +01003// 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
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01006//
7//===----------------------------------------------------------------------===//
8//
9// Declarations for metadata specific to debug info.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_IR_DEBUGINFOMETADATA_H
14#define LLVM_IR_DEBUGINFOMETADATA_H
15
16#include "llvm/ADT/ArrayRef.h"
17#include "llvm/ADT/BitmaskEnum.h"
18#include "llvm/ADT/None.h"
19#include "llvm/ADT/Optional.h"
20#include "llvm/ADT/PointerUnion.h"
21#include "llvm/ADT/STLExtras.h"
22#include "llvm/ADT/SmallVector.h"
23#include "llvm/ADT/StringRef.h"
24#include "llvm/ADT/iterator_range.h"
25#include "llvm/BinaryFormat/Dwarf.h"
26#include "llvm/IR/Constants.h"
27#include "llvm/IR/Metadata.h"
28#include "llvm/Support/Casting.h"
29#include <cassert>
30#include <climits>
31#include <cstddef>
32#include <cstdint>
33#include <iterator>
34#include <type_traits>
35#include <vector>
36
37// Helper macros for defining get() overrides.
38#define DEFINE_MDNODE_GET_UNPACK_IMPL(...) __VA_ARGS__
39#define DEFINE_MDNODE_GET_UNPACK(ARGS) DEFINE_MDNODE_GET_UNPACK_IMPL ARGS
40#define DEFINE_MDNODE_GET_DISTINCT_TEMPORARY(CLASS, FORMAL, ARGS) \
41 static CLASS *getDistinct(LLVMContext &Context, \
42 DEFINE_MDNODE_GET_UNPACK(FORMAL)) { \
43 return getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Distinct); \
44 } \
45 static Temp##CLASS getTemporary(LLVMContext &Context, \
46 DEFINE_MDNODE_GET_UNPACK(FORMAL)) { \
47 return Temp##CLASS( \
48 getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Temporary)); \
49 }
50#define DEFINE_MDNODE_GET(CLASS, FORMAL, ARGS) \
51 static CLASS *get(LLVMContext &Context, DEFINE_MDNODE_GET_UNPACK(FORMAL)) { \
52 return getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Uniqued); \
53 } \
54 static CLASS *getIfExists(LLVMContext &Context, \
55 DEFINE_MDNODE_GET_UNPACK(FORMAL)) { \
56 return getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Uniqued, \
57 /* ShouldCreate */ false); \
58 } \
59 DEFINE_MDNODE_GET_DISTINCT_TEMPORARY(CLASS, FORMAL, ARGS)
60
61namespace llvm {
62
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010063class DITypeRefArray {
64 const MDTuple *N = nullptr;
65
66public:
67 DITypeRefArray() = default;
68 DITypeRefArray(const MDTuple *N) : N(N) {}
69
70 explicit operator bool() const { return get(); }
71 explicit operator MDTuple *() const { return get(); }
72
73 MDTuple *get() const { return const_cast<MDTuple *>(N); }
74 MDTuple *operator->() const { return get(); }
75 MDTuple &operator*() const { return *get(); }
76
77 // FIXME: Fix callers and remove condition on N.
78 unsigned size() const { return N ? N->getNumOperands() : 0u; }
Andrew Walbran3d2c1972020-04-07 12:24:26 +010079 DIType *operator[](unsigned I) const {
80 return cast_or_null<DIType>(N->getOperand(I));
81 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010082
Andrew Walbran3d2c1972020-04-07 12:24:26 +010083 class iterator : std::iterator<std::input_iterator_tag, DIType *,
84 std::ptrdiff_t, void, DIType *> {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010085 MDNode::op_iterator I = nullptr;
86
87 public:
88 iterator() = default;
89 explicit iterator(MDNode::op_iterator I) : I(I) {}
90
Andrew Walbran3d2c1972020-04-07 12:24:26 +010091 DIType *operator*() const { return cast_or_null<DIType>(*I); }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010092
93 iterator &operator++() {
94 ++I;
95 return *this;
96 }
97
98 iterator operator++(int) {
99 iterator Temp(*this);
100 ++I;
101 return Temp;
102 }
103
104 bool operator==(const iterator &X) const { return I == X.I; }
105 bool operator!=(const iterator &X) const { return I != X.I; }
106 };
107
108 // FIXME: Fix callers and remove condition on N.
109 iterator begin() const { return N ? iterator(N->op_begin()) : iterator(); }
110 iterator end() const { return N ? iterator(N->op_end()) : iterator(); }
111};
112
113/// Tagged DWARF-like metadata node.
114///
115/// A metadata node with a DWARF tag (i.e., a constant named \c DW_TAG_*,
116/// defined in llvm/BinaryFormat/Dwarf.h). Called \a DINode because it's
117/// potentially used for non-DWARF output.
118class DINode : public MDNode {
119 friend class LLVMContextImpl;
120 friend class MDNode;
121
122protected:
123 DINode(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
124 ArrayRef<Metadata *> Ops1, ArrayRef<Metadata *> Ops2 = None)
125 : MDNode(C, ID, Storage, Ops1, Ops2) {
126 assert(Tag < 1u << 16);
127 SubclassData16 = Tag;
128 }
129 ~DINode() = default;
130
131 template <class Ty> Ty *getOperandAs(unsigned I) const {
132 return cast_or_null<Ty>(getOperand(I));
133 }
134
135 StringRef getStringOperand(unsigned I) const {
136 if (auto *S = getOperandAs<MDString>(I))
137 return S->getString();
138 return StringRef();
139 }
140
141 static MDString *getCanonicalMDString(LLVMContext &Context, StringRef S) {
142 if (S.empty())
143 return nullptr;
144 return MDString::get(Context, S);
145 }
146
147 /// Allow subclasses to mutate the tag.
148 void setTag(unsigned Tag) { SubclassData16 = Tag; }
149
150public:
151 unsigned getTag() const { return SubclassData16; }
152
153 /// Debug info flags.
154 ///
155 /// The three accessibility flags are mutually exclusive and rolled together
156 /// in the first two bits.
157 enum DIFlags : uint32_t {
158#define HANDLE_DI_FLAG(ID, NAME) Flag##NAME = ID,
159#define DI_FLAG_LARGEST_NEEDED
160#include "llvm/IR/DebugInfoFlags.def"
161 FlagAccessibility = FlagPrivate | FlagProtected | FlagPublic,
162 FlagPtrToMemberRep = FlagSingleInheritance | FlagMultipleInheritance |
163 FlagVirtualInheritance,
164 LLVM_MARK_AS_BITMASK_ENUM(FlagLargest)
165 };
166
167 static DIFlags getFlag(StringRef Flag);
168 static StringRef getFlagString(DIFlags Flag);
169
170 /// Split up a flags bitfield.
171 ///
172 /// Split \c Flags into \c SplitFlags, a vector of its components. Returns
173 /// any remaining (unrecognized) bits.
174 static DIFlags splitFlags(DIFlags Flags,
175 SmallVectorImpl<DIFlags> &SplitFlags);
176
177 static bool classof(const Metadata *MD) {
178 switch (MD->getMetadataID()) {
179 default:
180 return false;
181 case GenericDINodeKind:
182 case DISubrangeKind:
183 case DIEnumeratorKind:
184 case DIBasicTypeKind:
185 case DIDerivedTypeKind:
186 case DICompositeTypeKind:
187 case DISubroutineTypeKind:
188 case DIFileKind:
189 case DICompileUnitKind:
190 case DISubprogramKind:
191 case DILexicalBlockKind:
192 case DILexicalBlockFileKind:
193 case DINamespaceKind:
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100194 case DICommonBlockKind:
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100195 case DITemplateTypeParameterKind:
196 case DITemplateValueParameterKind:
197 case DIGlobalVariableKind:
198 case DILocalVariableKind:
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100199 case DILabelKind:
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100200 case DIObjCPropertyKind:
201 case DIImportedEntityKind:
202 case DIModuleKind:
203 return true;
204 }
205 }
206};
207
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100208/// Generic tagged DWARF-like metadata node.
209///
210/// An un-specialized DWARF-like metadata node. The first operand is a
211/// (possibly empty) null-separated \a MDString header that contains arbitrary
212/// fields. The remaining operands are \a dwarf_operands(), and are pointers
213/// to other metadata.
214class GenericDINode : public DINode {
215 friend class LLVMContextImpl;
216 friend class MDNode;
217
218 GenericDINode(LLVMContext &C, StorageType Storage, unsigned Hash,
219 unsigned Tag, ArrayRef<Metadata *> Ops1,
220 ArrayRef<Metadata *> Ops2)
221 : DINode(C, GenericDINodeKind, Storage, Tag, Ops1, Ops2) {
222 setHash(Hash);
223 }
224 ~GenericDINode() { dropAllReferences(); }
225
226 void setHash(unsigned Hash) { SubclassData32 = Hash; }
227 void recalculateHash();
228
229 static GenericDINode *getImpl(LLVMContext &Context, unsigned Tag,
230 StringRef Header, ArrayRef<Metadata *> DwarfOps,
231 StorageType Storage, bool ShouldCreate = true) {
232 return getImpl(Context, Tag, getCanonicalMDString(Context, Header),
233 DwarfOps, Storage, ShouldCreate);
234 }
235
236 static GenericDINode *getImpl(LLVMContext &Context, unsigned Tag,
237 MDString *Header, ArrayRef<Metadata *> DwarfOps,
238 StorageType Storage, bool ShouldCreate = true);
239
240 TempGenericDINode cloneImpl() const {
241 return getTemporary(
242 getContext(), getTag(), getHeader(),
243 SmallVector<Metadata *, 4>(dwarf_op_begin(), dwarf_op_end()));
244 }
245
246public:
247 unsigned getHash() const { return SubclassData32; }
248
249 DEFINE_MDNODE_GET(GenericDINode, (unsigned Tag, StringRef Header,
250 ArrayRef<Metadata *> DwarfOps),
251 (Tag, Header, DwarfOps))
252 DEFINE_MDNODE_GET(GenericDINode, (unsigned Tag, MDString *Header,
253 ArrayRef<Metadata *> DwarfOps),
254 (Tag, Header, DwarfOps))
255
256 /// Return a (temporary) clone of this.
257 TempGenericDINode clone() const { return cloneImpl(); }
258
259 unsigned getTag() const { return SubclassData16; }
260 StringRef getHeader() const { return getStringOperand(0); }
261 MDString *getRawHeader() const { return getOperandAs<MDString>(0); }
262
263 op_iterator dwarf_op_begin() const { return op_begin() + 1; }
264 op_iterator dwarf_op_end() const { return op_end(); }
265 op_range dwarf_operands() const {
266 return op_range(dwarf_op_begin(), dwarf_op_end());
267 }
268
269 unsigned getNumDwarfOperands() const { return getNumOperands() - 1; }
270 const MDOperand &getDwarfOperand(unsigned I) const {
271 return getOperand(I + 1);
272 }
273 void replaceDwarfOperandWith(unsigned I, Metadata *New) {
274 replaceOperandWith(I + 1, New);
275 }
276
277 static bool classof(const Metadata *MD) {
278 return MD->getMetadataID() == GenericDINodeKind;
279 }
280};
281
282/// Array subrange.
283///
284/// TODO: Merge into node for DW_TAG_array_type, which should have a custom
285/// type.
286class DISubrange : public DINode {
287 friend class LLVMContextImpl;
288 friend class MDNode;
289
290 int64_t LowerBound;
291
292 DISubrange(LLVMContext &C, StorageType Storage, Metadata *Node,
293 int64_t LowerBound, ArrayRef<Metadata *> Ops)
294 : DINode(C, DISubrangeKind, Storage, dwarf::DW_TAG_subrange_type, Ops),
295 LowerBound(LowerBound) {}
296
297 ~DISubrange() = default;
298
299 static DISubrange *getImpl(LLVMContext &Context, int64_t Count,
300 int64_t LowerBound, StorageType Storage,
301 bool ShouldCreate = true);
302
303 static DISubrange *getImpl(LLVMContext &Context, Metadata *CountNode,
304 int64_t LowerBound, StorageType Storage,
305 bool ShouldCreate = true);
306
307 TempDISubrange cloneImpl() const {
308 return getTemporary(getContext(), getRawCountNode(), getLowerBound());
309 }
310
311public:
312 DEFINE_MDNODE_GET(DISubrange, (int64_t Count, int64_t LowerBound = 0),
313 (Count, LowerBound))
314
315 DEFINE_MDNODE_GET(DISubrange, (Metadata *CountNode, int64_t LowerBound = 0),
316 (CountNode, LowerBound))
317
318 TempDISubrange clone() const { return cloneImpl(); }
319
320 int64_t getLowerBound() const { return LowerBound; }
321
322 Metadata *getRawCountNode() const {
323 return getOperand(0).get();
324 }
325
326 typedef PointerUnion<ConstantInt*, DIVariable*> CountType;
327
328 CountType getCount() const {
329 if (auto *MD = dyn_cast<ConstantAsMetadata>(getRawCountNode()))
330 return CountType(cast<ConstantInt>(MD->getValue()));
331
332 if (auto *DV = dyn_cast<DIVariable>(getRawCountNode()))
333 return CountType(DV);
334
335 return CountType();
336 }
337
338 static bool classof(const Metadata *MD) {
339 return MD->getMetadataID() == DISubrangeKind;
340 }
341};
342
343/// Enumeration value.
344///
345/// TODO: Add a pointer to the context (DW_TAG_enumeration_type) once that no
346/// longer creates a type cycle.
347class DIEnumerator : public DINode {
348 friend class LLVMContextImpl;
349 friend class MDNode;
350
351 int64_t Value;
352 DIEnumerator(LLVMContext &C, StorageType Storage, int64_t Value,
353 bool IsUnsigned, ArrayRef<Metadata *> Ops)
354 : DINode(C, DIEnumeratorKind, Storage, dwarf::DW_TAG_enumerator, Ops),
355 Value(Value) {
356 SubclassData32 = IsUnsigned;
357 }
358 ~DIEnumerator() = default;
359
360 static DIEnumerator *getImpl(LLVMContext &Context, int64_t Value,
361 bool IsUnsigned, StringRef Name,
362 StorageType Storage, bool ShouldCreate = true) {
363 return getImpl(Context, Value, IsUnsigned,
364 getCanonicalMDString(Context, Name), Storage, ShouldCreate);
365 }
366 static DIEnumerator *getImpl(LLVMContext &Context, int64_t Value,
367 bool IsUnsigned, MDString *Name,
368 StorageType Storage, bool ShouldCreate = true);
369
370 TempDIEnumerator cloneImpl() const {
371 return getTemporary(getContext(), getValue(), isUnsigned(), getName());
372 }
373
374public:
375 DEFINE_MDNODE_GET(DIEnumerator, (int64_t Value, bool IsUnsigned, StringRef Name),
376 (Value, IsUnsigned, Name))
377 DEFINE_MDNODE_GET(DIEnumerator, (int64_t Value, bool IsUnsigned, MDString *Name),
378 (Value, IsUnsigned, Name))
379
380 TempDIEnumerator clone() const { return cloneImpl(); }
381
382 int64_t getValue() const { return Value; }
383 bool isUnsigned() const { return SubclassData32; }
384 StringRef getName() const { return getStringOperand(0); }
385
386 MDString *getRawName() const { return getOperandAs<MDString>(0); }
387
388 static bool classof(const Metadata *MD) {
389 return MD->getMetadataID() == DIEnumeratorKind;
390 }
391};
392
393/// Base class for scope-like contexts.
394///
395/// Base class for lexical scopes and types (which are also declaration
396/// contexts).
397///
398/// TODO: Separate the concepts of declaration contexts and lexical scopes.
399class DIScope : public DINode {
400protected:
401 DIScope(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
402 ArrayRef<Metadata *> Ops)
403 : DINode(C, ID, Storage, Tag, Ops) {}
404 ~DIScope() = default;
405
406public:
407 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
408
409 inline StringRef getFilename() const;
410 inline StringRef getDirectory() const;
411 inline Optional<StringRef> getSource() const;
412
413 StringRef getName() const;
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100414 DIScope *getScope() const;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100415
416 /// Return the raw underlying file.
417 ///
418 /// A \a DIFile is a \a DIScope, but it doesn't point at a separate file (it
419 /// \em is the file). If \c this is an \a DIFile, we need to return \c this.
420 /// Otherwise, return the first operand, which is where all other subclasses
421 /// store their file pointer.
422 Metadata *getRawFile() const {
423 return isa<DIFile>(this) ? const_cast<DIScope *>(this)
424 : static_cast<Metadata *>(getOperand(0));
425 }
426
427 static bool classof(const Metadata *MD) {
428 switch (MD->getMetadataID()) {
429 default:
430 return false;
431 case DIBasicTypeKind:
432 case DIDerivedTypeKind:
433 case DICompositeTypeKind:
434 case DISubroutineTypeKind:
435 case DIFileKind:
436 case DICompileUnitKind:
437 case DISubprogramKind:
438 case DILexicalBlockKind:
439 case DILexicalBlockFileKind:
440 case DINamespaceKind:
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100441 case DICommonBlockKind:
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100442 case DIModuleKind:
443 return true;
444 }
445 }
446};
447
448/// File.
449///
450/// TODO: Merge with directory/file node (including users).
451/// TODO: Canonicalize paths on creation.
452class DIFile : public DIScope {
453 friend class LLVMContextImpl;
454 friend class MDNode;
455
456public:
457 /// Which algorithm (e.g. MD5) a checksum was generated with.
458 ///
459 /// The encoding is explicit because it is used directly in Bitcode. The
460 /// value 0 is reserved to indicate the absence of a checksum in Bitcode.
461 enum ChecksumKind {
462 // The first variant was originally CSK_None, encoded as 0. The new
463 // internal representation removes the need for this by wrapping the
464 // ChecksumInfo in an Optional, but to preserve Bitcode compatibility the 0
465 // encoding is reserved.
466 CSK_MD5 = 1,
467 CSK_SHA1 = 2,
468 CSK_Last = CSK_SHA1 // Should be last enumeration.
469 };
470
471 /// A single checksum, represented by a \a Kind and a \a Value (a string).
472 template <typename T>
473 struct ChecksumInfo {
474 /// The kind of checksum which \a Value encodes.
475 ChecksumKind Kind;
476 /// The string value of the checksum.
477 T Value;
478
479 ChecksumInfo(ChecksumKind Kind, T Value) : Kind(Kind), Value(Value) { }
480 ~ChecksumInfo() = default;
481 bool operator==(const ChecksumInfo<T> &X) const {
482 return Kind == X.Kind && Value == X.Value;
483 }
484 bool operator!=(const ChecksumInfo<T> &X) const { return !(*this == X); }
485 StringRef getKindAsString() const { return getChecksumKindAsString(Kind); }
486 };
487
488private:
489 Optional<ChecksumInfo<MDString *>> Checksum;
490 Optional<MDString *> Source;
491
492 DIFile(LLVMContext &C, StorageType Storage,
493 Optional<ChecksumInfo<MDString *>> CS, Optional<MDString *> Src,
494 ArrayRef<Metadata *> Ops)
495 : DIScope(C, DIFileKind, Storage, dwarf::DW_TAG_file_type, Ops),
496 Checksum(CS), Source(Src) {}
497 ~DIFile() = default;
498
499 static DIFile *getImpl(LLVMContext &Context, StringRef Filename,
500 StringRef Directory,
501 Optional<ChecksumInfo<StringRef>> CS,
502 Optional<StringRef> Source,
503 StorageType Storage, bool ShouldCreate = true) {
504 Optional<ChecksumInfo<MDString *>> MDChecksum;
505 if (CS)
506 MDChecksum.emplace(CS->Kind, getCanonicalMDString(Context, CS->Value));
507 return getImpl(Context, getCanonicalMDString(Context, Filename),
508 getCanonicalMDString(Context, Directory), MDChecksum,
509 Source ? Optional<MDString *>(getCanonicalMDString(Context, *Source)) : None,
510 Storage, ShouldCreate);
511 }
512 static DIFile *getImpl(LLVMContext &Context, MDString *Filename,
513 MDString *Directory,
514 Optional<ChecksumInfo<MDString *>> CS,
515 Optional<MDString *> Source, StorageType Storage,
516 bool ShouldCreate = true);
517
518 TempDIFile cloneImpl() const {
519 return getTemporary(getContext(), getFilename(), getDirectory(),
520 getChecksum(), getSource());
521 }
522
523public:
524 DEFINE_MDNODE_GET(DIFile, (StringRef Filename, StringRef Directory,
525 Optional<ChecksumInfo<StringRef>> CS = None,
526 Optional<StringRef> Source = None),
527 (Filename, Directory, CS, Source))
528 DEFINE_MDNODE_GET(DIFile, (MDString * Filename, MDString *Directory,
529 Optional<ChecksumInfo<MDString *>> CS = None,
530 Optional<MDString *> Source = None),
531 (Filename, Directory, CS, Source))
532
533 TempDIFile clone() const { return cloneImpl(); }
534
535 StringRef getFilename() const { return getStringOperand(0); }
536 StringRef getDirectory() const { return getStringOperand(1); }
537 Optional<ChecksumInfo<StringRef>> getChecksum() const {
538 Optional<ChecksumInfo<StringRef>> StringRefChecksum;
539 if (Checksum)
540 StringRefChecksum.emplace(Checksum->Kind, Checksum->Value->getString());
541 return StringRefChecksum;
542 }
543 Optional<StringRef> getSource() const {
544 return Source ? Optional<StringRef>((*Source)->getString()) : None;
545 }
546
547 MDString *getRawFilename() const { return getOperandAs<MDString>(0); }
548 MDString *getRawDirectory() const { return getOperandAs<MDString>(1); }
549 Optional<ChecksumInfo<MDString *>> getRawChecksum() const { return Checksum; }
550 Optional<MDString *> getRawSource() const { return Source; }
551
552 static StringRef getChecksumKindAsString(ChecksumKind CSKind);
553 static Optional<ChecksumKind> getChecksumKind(StringRef CSKindStr);
554
555 static bool classof(const Metadata *MD) {
556 return MD->getMetadataID() == DIFileKind;
557 }
558};
559
560StringRef DIScope::getFilename() const {
561 if (auto *F = getFile())
562 return F->getFilename();
563 return "";
564}
565
566StringRef DIScope::getDirectory() const {
567 if (auto *F = getFile())
568 return F->getDirectory();
569 return "";
570}
571
572Optional<StringRef> DIScope::getSource() const {
573 if (auto *F = getFile())
574 return F->getSource();
575 return None;
576}
577
578/// Base class for types.
579///
580/// TODO: Remove the hardcoded name and context, since many types don't use
581/// them.
582/// TODO: Split up flags.
583class DIType : public DIScope {
584 unsigned Line;
585 DIFlags Flags;
586 uint64_t SizeInBits;
587 uint64_t OffsetInBits;
588 uint32_t AlignInBits;
589
590protected:
591 DIType(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
592 unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits,
593 uint64_t OffsetInBits, DIFlags Flags, ArrayRef<Metadata *> Ops)
594 : DIScope(C, ID, Storage, Tag, Ops) {
595 init(Line, SizeInBits, AlignInBits, OffsetInBits, Flags);
596 }
597 ~DIType() = default;
598
599 void init(unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits,
600 uint64_t OffsetInBits, DIFlags Flags) {
601 this->Line = Line;
602 this->Flags = Flags;
603 this->SizeInBits = SizeInBits;
604 this->AlignInBits = AlignInBits;
605 this->OffsetInBits = OffsetInBits;
606 }
607
608 /// Change fields in place.
609 void mutate(unsigned Tag, unsigned Line, uint64_t SizeInBits,
610 uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags) {
611 assert(isDistinct() && "Only distinct nodes can mutate");
612 setTag(Tag);
613 init(Line, SizeInBits, AlignInBits, OffsetInBits, Flags);
614 }
615
616public:
617 TempDIType clone() const {
618 return TempDIType(cast<DIType>(MDNode::clone().release()));
619 }
620
621 unsigned getLine() const { return Line; }
622 uint64_t getSizeInBits() const { return SizeInBits; }
623 uint32_t getAlignInBits() const { return AlignInBits; }
624 uint32_t getAlignInBytes() const { return getAlignInBits() / CHAR_BIT; }
625 uint64_t getOffsetInBits() const { return OffsetInBits; }
626 DIFlags getFlags() const { return Flags; }
627
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100628 DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100629 StringRef getName() const { return getStringOperand(2); }
630
631
632 Metadata *getRawScope() const { return getOperand(1); }
633 MDString *getRawName() const { return getOperandAs<MDString>(2); }
634
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100635 /// Returns a new temporary DIType with updated Flags
636 TempDIType cloneWithFlags(DIFlags NewFlags) const {
637 auto NewTy = clone();
638 NewTy->Flags = NewFlags;
639 return NewTy;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100640 }
641
642 bool isPrivate() const {
643 return (getFlags() & FlagAccessibility) == FlagPrivate;
644 }
645 bool isProtected() const {
646 return (getFlags() & FlagAccessibility) == FlagProtected;
647 }
648 bool isPublic() const {
649 return (getFlags() & FlagAccessibility) == FlagPublic;
650 }
651 bool isForwardDecl() const { return getFlags() & FlagFwdDecl; }
652 bool isAppleBlockExtension() const { return getFlags() & FlagAppleBlock; }
653 bool isBlockByrefStruct() const { return getFlags() & FlagBlockByrefStruct; }
654 bool isVirtual() const { return getFlags() & FlagVirtual; }
655 bool isArtificial() const { return getFlags() & FlagArtificial; }
656 bool isObjectPointer() const { return getFlags() & FlagObjectPointer; }
657 bool isObjcClassComplete() const {
658 return getFlags() & FlagObjcClassComplete;
659 }
660 bool isVector() const { return getFlags() & FlagVector; }
661 bool isBitField() const { return getFlags() & FlagBitField; }
662 bool isStaticMember() const { return getFlags() & FlagStaticMember; }
663 bool isLValueReference() const { return getFlags() & FlagLValueReference; }
664 bool isRValueReference() const { return getFlags() & FlagRValueReference; }
665 bool isTypePassByValue() const { return getFlags() & FlagTypePassByValue; }
666 bool isTypePassByReference() const {
667 return getFlags() & FlagTypePassByReference;
668 }
Andrew Scull0372a572018-11-16 15:47:06 +0000669 bool isBigEndian() const { return getFlags() & FlagBigEndian; }
670 bool isLittleEndian() const { return getFlags() & FlagLittleEndian; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100671
672 static bool classof(const Metadata *MD) {
673 switch (MD->getMetadataID()) {
674 default:
675 return false;
676 case DIBasicTypeKind:
677 case DIDerivedTypeKind:
678 case DICompositeTypeKind:
679 case DISubroutineTypeKind:
680 return true;
681 }
682 }
683};
684
685/// Basic type, like 'int' or 'float'.
686///
687/// TODO: Split out DW_TAG_unspecified_type.
688/// TODO: Drop unused accessors.
689class DIBasicType : public DIType {
690 friend class LLVMContextImpl;
691 friend class MDNode;
692
693 unsigned Encoding;
694
695 DIBasicType(LLVMContext &C, StorageType Storage, unsigned Tag,
696 uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding,
Andrew Scull0372a572018-11-16 15:47:06 +0000697 DIFlags Flags, ArrayRef<Metadata *> Ops)
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100698 : DIType(C, DIBasicTypeKind, Storage, Tag, 0, SizeInBits, AlignInBits, 0,
Andrew Scull0372a572018-11-16 15:47:06 +0000699 Flags, Ops),
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100700 Encoding(Encoding) {}
701 ~DIBasicType() = default;
702
703 static DIBasicType *getImpl(LLVMContext &Context, unsigned Tag,
704 StringRef Name, uint64_t SizeInBits,
705 uint32_t AlignInBits, unsigned Encoding,
Andrew Scull0372a572018-11-16 15:47:06 +0000706 DIFlags Flags, StorageType Storage,
707 bool ShouldCreate = true) {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100708 return getImpl(Context, Tag, getCanonicalMDString(Context, Name),
Andrew Scull0372a572018-11-16 15:47:06 +0000709 SizeInBits, AlignInBits, Encoding, Flags, Storage,
710 ShouldCreate);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100711 }
712 static DIBasicType *getImpl(LLVMContext &Context, unsigned Tag,
713 MDString *Name, uint64_t SizeInBits,
714 uint32_t AlignInBits, unsigned Encoding,
Andrew Scull0372a572018-11-16 15:47:06 +0000715 DIFlags Flags, StorageType Storage,
716 bool ShouldCreate = true);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100717
718 TempDIBasicType cloneImpl() const {
719 return getTemporary(getContext(), getTag(), getName(), getSizeInBits(),
Andrew Scull0372a572018-11-16 15:47:06 +0000720 getAlignInBits(), getEncoding(), getFlags());
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100721 }
722
723public:
724 DEFINE_MDNODE_GET(DIBasicType, (unsigned Tag, StringRef Name),
Andrew Scull0372a572018-11-16 15:47:06 +0000725 (Tag, Name, 0, 0, 0, FlagZero))
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100726 DEFINE_MDNODE_GET(DIBasicType,
727 (unsigned Tag, StringRef Name, uint64_t SizeInBits,
Andrew Scull0372a572018-11-16 15:47:06 +0000728 uint32_t AlignInBits, unsigned Encoding, DIFlags Flags),
729 (Tag, Name, SizeInBits, AlignInBits, Encoding, Flags))
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100730 DEFINE_MDNODE_GET(DIBasicType,
731 (unsigned Tag, MDString *Name, uint64_t SizeInBits,
Andrew Scull0372a572018-11-16 15:47:06 +0000732 uint32_t AlignInBits, unsigned Encoding, DIFlags Flags),
733 (Tag, Name, SizeInBits, AlignInBits, Encoding, Flags))
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100734
735 TempDIBasicType clone() const { return cloneImpl(); }
736
737 unsigned getEncoding() const { return Encoding; }
738
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100739 enum class Signedness { Signed, Unsigned };
740
741 /// Return the signedness of this type, or None if this type is neither
742 /// signed nor unsigned.
743 Optional<Signedness> getSignedness() const;
744
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100745 static bool classof(const Metadata *MD) {
746 return MD->getMetadataID() == DIBasicTypeKind;
747 }
748};
749
750/// Derived types.
751///
752/// This includes qualified types, pointers, references, friends, typedefs, and
753/// class members.
754///
755/// TODO: Split out members (inheritance, fields, methods, etc.).
756class DIDerivedType : public DIType {
757 friend class LLVMContextImpl;
758 friend class MDNode;
759
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100760 /// The DWARF address space of the memory pointed to or referenced by a
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100761 /// pointer or reference type respectively.
762 Optional<unsigned> DWARFAddressSpace;
763
764 DIDerivedType(LLVMContext &C, StorageType Storage, unsigned Tag,
765 unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits,
766 uint64_t OffsetInBits, Optional<unsigned> DWARFAddressSpace,
767 DIFlags Flags, ArrayRef<Metadata *> Ops)
768 : DIType(C, DIDerivedTypeKind, Storage, Tag, Line, SizeInBits,
769 AlignInBits, OffsetInBits, Flags, Ops),
770 DWARFAddressSpace(DWARFAddressSpace) {}
771 ~DIDerivedType() = default;
772
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100773 static DIDerivedType *
774 getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, DIFile *File,
775 unsigned Line, DIScope *Scope, DIType *BaseType, uint64_t SizeInBits,
776 uint32_t AlignInBits, uint64_t OffsetInBits,
777 Optional<unsigned> DWARFAddressSpace, DIFlags Flags,
778 Metadata *ExtraData, StorageType Storage, bool ShouldCreate = true) {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100779 return getImpl(Context, Tag, getCanonicalMDString(Context, Name), File,
780 Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits,
781 DWARFAddressSpace, Flags, ExtraData, Storage, ShouldCreate);
782 }
783 static DIDerivedType *getImpl(LLVMContext &Context, unsigned Tag,
784 MDString *Name, Metadata *File, unsigned Line,
785 Metadata *Scope, Metadata *BaseType,
786 uint64_t SizeInBits, uint32_t AlignInBits,
787 uint64_t OffsetInBits,
788 Optional<unsigned> DWARFAddressSpace,
789 DIFlags Flags, Metadata *ExtraData,
790 StorageType Storage, bool ShouldCreate = true);
791
792 TempDIDerivedType cloneImpl() const {
793 return getTemporary(getContext(), getTag(), getName(), getFile(), getLine(),
794 getScope(), getBaseType(), getSizeInBits(),
795 getAlignInBits(), getOffsetInBits(),
796 getDWARFAddressSpace(), getFlags(), getExtraData());
797 }
798
799public:
800 DEFINE_MDNODE_GET(DIDerivedType,
801 (unsigned Tag, MDString *Name, Metadata *File,
802 unsigned Line, Metadata *Scope, Metadata *BaseType,
803 uint64_t SizeInBits, uint32_t AlignInBits,
804 uint64_t OffsetInBits,
805 Optional<unsigned> DWARFAddressSpace, DIFlags Flags,
806 Metadata *ExtraData = nullptr),
807 (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
808 AlignInBits, OffsetInBits, DWARFAddressSpace, Flags,
809 ExtraData))
810 DEFINE_MDNODE_GET(DIDerivedType,
811 (unsigned Tag, StringRef Name, DIFile *File, unsigned Line,
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100812 DIScope *Scope, DIType *BaseType, uint64_t SizeInBits,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100813 uint32_t AlignInBits, uint64_t OffsetInBits,
814 Optional<unsigned> DWARFAddressSpace, DIFlags Flags,
815 Metadata *ExtraData = nullptr),
816 (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
817 AlignInBits, OffsetInBits, DWARFAddressSpace, Flags,
818 ExtraData))
819
820 TempDIDerivedType clone() const { return cloneImpl(); }
821
822 /// Get the base type this is derived from.
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100823 DIType *getBaseType() const { return cast_or_null<DIType>(getRawBaseType()); }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100824 Metadata *getRawBaseType() const { return getOperand(3); }
825
826 /// \returns The DWARF address space of the memory pointed to or referenced by
827 /// a pointer or reference type respectively.
828 Optional<unsigned> getDWARFAddressSpace() const { return DWARFAddressSpace; }
829
830 /// Get extra data associated with this derived type.
831 ///
832 /// Class type for pointer-to-members, objective-c property node for ivars,
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100833 /// global constant wrapper for static members, or virtual base pointer offset
834 /// for inheritance.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100835 ///
836 /// TODO: Separate out types that need this extra operand: pointer-to-member
837 /// types and member fields (static members and ivars).
838 Metadata *getExtraData() const { return getRawExtraData(); }
839 Metadata *getRawExtraData() const { return getOperand(4); }
840
841 /// Get casted version of extra data.
842 /// @{
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100843 DIType *getClassType() const {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100844 assert(getTag() == dwarf::DW_TAG_ptr_to_member_type);
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100845 return cast_or_null<DIType>(getExtraData());
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100846 }
847
848 DIObjCProperty *getObjCProperty() const {
849 return dyn_cast_or_null<DIObjCProperty>(getExtraData());
850 }
851
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100852 uint32_t getVBPtrOffset() const {
853 assert(getTag() == dwarf::DW_TAG_inheritance);
854 if (auto *CM = cast_or_null<ConstantAsMetadata>(getExtraData()))
855 if (auto *CI = dyn_cast_or_null<ConstantInt>(CM->getValue()))
856 return static_cast<uint32_t>(CI->getZExtValue());
857 return 0;
858 }
859
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100860 Constant *getStorageOffsetInBits() const {
861 assert(getTag() == dwarf::DW_TAG_member && isBitField());
862 if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData()))
863 return C->getValue();
864 return nullptr;
865 }
866
867 Constant *getConstant() const {
868 assert(getTag() == dwarf::DW_TAG_member && isStaticMember());
869 if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData()))
870 return C->getValue();
871 return nullptr;
872 }
873 Constant *getDiscriminantValue() const {
874 assert(getTag() == dwarf::DW_TAG_member && !isStaticMember());
875 if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData()))
876 return C->getValue();
877 return nullptr;
878 }
879 /// @}
880
881 static bool classof(const Metadata *MD) {
882 return MD->getMetadataID() == DIDerivedTypeKind;
883 }
884};
885
886/// Composite types.
887///
888/// TODO: Detach from DerivedTypeBase (split out MDEnumType?).
889/// TODO: Create a custom, unrelated node for DW_TAG_array_type.
890class DICompositeType : public DIType {
891 friend class LLVMContextImpl;
892 friend class MDNode;
893
894 unsigned RuntimeLang;
895
896 DICompositeType(LLVMContext &C, StorageType Storage, unsigned Tag,
897 unsigned Line, unsigned RuntimeLang, uint64_t SizeInBits,
898 uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags,
899 ArrayRef<Metadata *> Ops)
900 : DIType(C, DICompositeTypeKind, Storage, Tag, Line, SizeInBits,
901 AlignInBits, OffsetInBits, Flags, Ops),
902 RuntimeLang(RuntimeLang) {}
903 ~DICompositeType() = default;
904
905 /// Change fields in place.
906 void mutate(unsigned Tag, unsigned Line, unsigned RuntimeLang,
907 uint64_t SizeInBits, uint32_t AlignInBits,
908 uint64_t OffsetInBits, DIFlags Flags) {
909 assert(isDistinct() && "Only distinct nodes can mutate");
910 assert(getRawIdentifier() && "Only ODR-uniqued nodes should mutate");
911 this->RuntimeLang = RuntimeLang;
912 DIType::mutate(Tag, Line, SizeInBits, AlignInBits, OffsetInBits, Flags);
913 }
914
915 static DICompositeType *
916 getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, Metadata *File,
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100917 unsigned Line, DIScope *Scope, DIType *BaseType, uint64_t SizeInBits,
918 uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags,
919 DINodeArray Elements, unsigned RuntimeLang, DIType *VTableHolder,
920 DITemplateParameterArray TemplateParams, StringRef Identifier,
921 DIDerivedType *Discriminator, StorageType Storage,
922 bool ShouldCreate = true) {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100923 return getImpl(
924 Context, Tag, getCanonicalMDString(Context, Name), File, Line, Scope,
925 BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements.get(),
926 RuntimeLang, VTableHolder, TemplateParams.get(),
927 getCanonicalMDString(Context, Identifier), Discriminator, Storage, ShouldCreate);
928 }
929 static DICompositeType *
930 getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
931 unsigned Line, Metadata *Scope, Metadata *BaseType,
932 uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
933 DIFlags Flags, Metadata *Elements, unsigned RuntimeLang,
934 Metadata *VTableHolder, Metadata *TemplateParams,
935 MDString *Identifier, Metadata *Discriminator,
936 StorageType Storage, bool ShouldCreate = true);
937
938 TempDICompositeType cloneImpl() const {
939 return getTemporary(getContext(), getTag(), getName(), getFile(), getLine(),
940 getScope(), getBaseType(), getSizeInBits(),
941 getAlignInBits(), getOffsetInBits(), getFlags(),
942 getElements(), getRuntimeLang(), getVTableHolder(),
943 getTemplateParams(), getIdentifier(), getDiscriminator());
944 }
945
946public:
947 DEFINE_MDNODE_GET(DICompositeType,
948 (unsigned Tag, StringRef Name, DIFile *File, unsigned Line,
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100949 DIScope *Scope, DIType *BaseType, uint64_t SizeInBits,
950 uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags,
951 DINodeArray Elements, unsigned RuntimeLang,
952 DIType *VTableHolder,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100953 DITemplateParameterArray TemplateParams = nullptr,
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100954 StringRef Identifier = "",
955 DIDerivedType *Discriminator = nullptr),
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100956 (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
957 AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
958 VTableHolder, TemplateParams, Identifier, Discriminator))
959 DEFINE_MDNODE_GET(DICompositeType,
960 (unsigned Tag, MDString *Name, Metadata *File,
961 unsigned Line, Metadata *Scope, Metadata *BaseType,
962 uint64_t SizeInBits, uint32_t AlignInBits,
963 uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements,
964 unsigned RuntimeLang, Metadata *VTableHolder,
965 Metadata *TemplateParams = nullptr,
966 MDString *Identifier = nullptr,
967 Metadata *Discriminator = nullptr),
968 (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
969 AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
970 VTableHolder, TemplateParams, Identifier, Discriminator))
971
972 TempDICompositeType clone() const { return cloneImpl(); }
973
974 /// Get a DICompositeType with the given ODR identifier.
975 ///
976 /// If \a LLVMContext::isODRUniquingDebugTypes(), gets the mapped
977 /// DICompositeType for the given ODR \c Identifier. If none exists, creates
978 /// a new node.
979 ///
980 /// Else, returns \c nullptr.
981 static DICompositeType *
982 getODRType(LLVMContext &Context, MDString &Identifier, unsigned Tag,
983 MDString *Name, Metadata *File, unsigned Line, Metadata *Scope,
984 Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits,
985 uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements,
986 unsigned RuntimeLang, Metadata *VTableHolder,
987 Metadata *TemplateParams, Metadata *Discriminator);
988 static DICompositeType *getODRTypeIfExists(LLVMContext &Context,
989 MDString &Identifier);
990
991 /// Build a DICompositeType with the given ODR identifier.
992 ///
993 /// Looks up the mapped DICompositeType for the given ODR \c Identifier. If
994 /// it doesn't exist, creates a new one. If it does exist and \a
995 /// isForwardDecl(), and the new arguments would be a definition, mutates the
996 /// the type in place. In either case, returns the type.
997 ///
998 /// If not \a LLVMContext::isODRUniquingDebugTypes(), this function returns
999 /// nullptr.
1000 static DICompositeType *
1001 buildODRType(LLVMContext &Context, MDString &Identifier, unsigned Tag,
1002 MDString *Name, Metadata *File, unsigned Line, Metadata *Scope,
1003 Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits,
1004 uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements,
1005 unsigned RuntimeLang, Metadata *VTableHolder,
1006 Metadata *TemplateParams, Metadata *Discriminator);
1007
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001008 DIType *getBaseType() const { return cast_or_null<DIType>(getRawBaseType()); }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001009 DINodeArray getElements() const {
1010 return cast_or_null<MDTuple>(getRawElements());
1011 }
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001012 DIType *getVTableHolder() const {
1013 return cast_or_null<DIType>(getRawVTableHolder());
1014 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001015 DITemplateParameterArray getTemplateParams() const {
1016 return cast_or_null<MDTuple>(getRawTemplateParams());
1017 }
1018 StringRef getIdentifier() const { return getStringOperand(7); }
1019 unsigned getRuntimeLang() const { return RuntimeLang; }
1020
1021 Metadata *getRawBaseType() const { return getOperand(3); }
1022 Metadata *getRawElements() const { return getOperand(4); }
1023 Metadata *getRawVTableHolder() const { return getOperand(5); }
1024 Metadata *getRawTemplateParams() const { return getOperand(6); }
1025 MDString *getRawIdentifier() const { return getOperandAs<MDString>(7); }
1026 Metadata *getRawDiscriminator() const { return getOperand(8); }
1027 DIDerivedType *getDiscriminator() const { return getOperandAs<DIDerivedType>(8); }
1028
1029 /// Replace operands.
1030 ///
1031 /// If this \a isUniqued() and not \a isResolved(), on a uniquing collision
1032 /// this will be RAUW'ed and deleted. Use a \a TrackingMDRef to keep track
1033 /// of its movement if necessary.
1034 /// @{
1035 void replaceElements(DINodeArray Elements) {
1036#ifndef NDEBUG
1037 for (DINode *Op : getElements())
1038 assert(is_contained(Elements->operands(), Op) &&
1039 "Lost a member during member list replacement");
1040#endif
1041 replaceOperandWith(4, Elements.get());
1042 }
1043
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001044 void replaceVTableHolder(DIType *VTableHolder) {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001045 replaceOperandWith(5, VTableHolder);
1046 }
1047
1048 void replaceTemplateParams(DITemplateParameterArray TemplateParams) {
1049 replaceOperandWith(6, TemplateParams.get());
1050 }
1051 /// @}
1052
1053 static bool classof(const Metadata *MD) {
1054 return MD->getMetadataID() == DICompositeTypeKind;
1055 }
1056};
1057
1058/// Type array for a subprogram.
1059///
1060/// TODO: Fold the array of types in directly as operands.
1061class DISubroutineType : public DIType {
1062 friend class LLVMContextImpl;
1063 friend class MDNode;
1064
1065 /// The calling convention used with DW_AT_calling_convention. Actually of
1066 /// type dwarf::CallingConvention.
1067 uint8_t CC;
1068
1069 DISubroutineType(LLVMContext &C, StorageType Storage, DIFlags Flags,
1070 uint8_t CC, ArrayRef<Metadata *> Ops)
1071 : DIType(C, DISubroutineTypeKind, Storage, dwarf::DW_TAG_subroutine_type,
1072 0, 0, 0, 0, Flags, Ops),
1073 CC(CC) {}
1074 ~DISubroutineType() = default;
1075
1076 static DISubroutineType *getImpl(LLVMContext &Context, DIFlags Flags,
1077 uint8_t CC, DITypeRefArray TypeArray,
1078 StorageType Storage,
1079 bool ShouldCreate = true) {
1080 return getImpl(Context, Flags, CC, TypeArray.get(), Storage, ShouldCreate);
1081 }
1082 static DISubroutineType *getImpl(LLVMContext &Context, DIFlags Flags,
1083 uint8_t CC, Metadata *TypeArray,
1084 StorageType Storage,
1085 bool ShouldCreate = true);
1086
1087 TempDISubroutineType cloneImpl() const {
1088 return getTemporary(getContext(), getFlags(), getCC(), getTypeArray());
1089 }
1090
1091public:
1092 DEFINE_MDNODE_GET(DISubroutineType,
1093 (DIFlags Flags, uint8_t CC, DITypeRefArray TypeArray),
1094 (Flags, CC, TypeArray))
1095 DEFINE_MDNODE_GET(DISubroutineType,
1096 (DIFlags Flags, uint8_t CC, Metadata *TypeArray),
1097 (Flags, CC, TypeArray))
1098
1099 TempDISubroutineType clone() const { return cloneImpl(); }
1100
1101 uint8_t getCC() const { return CC; }
1102
1103 DITypeRefArray getTypeArray() const {
1104 return cast_or_null<MDTuple>(getRawTypeArray());
1105 }
1106
1107 Metadata *getRawTypeArray() const { return getOperand(3); }
1108
1109 static bool classof(const Metadata *MD) {
1110 return MD->getMetadataID() == DISubroutineTypeKind;
1111 }
1112};
1113
1114/// Compile unit.
1115class DICompileUnit : public DIScope {
1116 friend class LLVMContextImpl;
1117 friend class MDNode;
1118
1119public:
1120 enum DebugEmissionKind : unsigned {
1121 NoDebug = 0,
1122 FullDebug,
1123 LineTablesOnly,
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001124 DebugDirectivesOnly,
1125 LastEmissionKind = DebugDirectivesOnly
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001126 };
1127
Andrew Scull0372a572018-11-16 15:47:06 +00001128 enum class DebugNameTableKind : unsigned {
1129 Default = 0,
1130 GNU = 1,
1131 None = 2,
1132 LastDebugNameTableKind = None
1133 };
1134
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001135 static Optional<DebugEmissionKind> getEmissionKind(StringRef Str);
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001136 static const char *emissionKindString(DebugEmissionKind EK);
Andrew Scull0372a572018-11-16 15:47:06 +00001137 static Optional<DebugNameTableKind> getNameTableKind(StringRef Str);
1138 static const char *nameTableKindString(DebugNameTableKind PK);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001139
1140private:
1141 unsigned SourceLanguage;
1142 bool IsOptimized;
1143 unsigned RuntimeVersion;
1144 unsigned EmissionKind;
1145 uint64_t DWOId;
1146 bool SplitDebugInlining;
1147 bool DebugInfoForProfiling;
Andrew Scull0372a572018-11-16 15:47:06 +00001148 unsigned NameTableKind;
Andrew Walbran16937d02019-10-22 13:54:20 +01001149 bool RangesBaseAddress;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001150
1151 DICompileUnit(LLVMContext &C, StorageType Storage, unsigned SourceLanguage,
1152 bool IsOptimized, unsigned RuntimeVersion,
1153 unsigned EmissionKind, uint64_t DWOId, bool SplitDebugInlining,
Andrew Scull0372a572018-11-16 15:47:06 +00001154 bool DebugInfoForProfiling, unsigned NameTableKind,
Andrew Walbran16937d02019-10-22 13:54:20 +01001155 bool RangesBaseAddress, ArrayRef<Metadata *> Ops)
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001156 : DIScope(C, DICompileUnitKind, Storage, dwarf::DW_TAG_compile_unit, Ops),
1157 SourceLanguage(SourceLanguage), IsOptimized(IsOptimized),
1158 RuntimeVersion(RuntimeVersion), EmissionKind(EmissionKind),
1159 DWOId(DWOId), SplitDebugInlining(SplitDebugInlining),
Andrew Scull0372a572018-11-16 15:47:06 +00001160 DebugInfoForProfiling(DebugInfoForProfiling),
Andrew Walbran16937d02019-10-22 13:54:20 +01001161 NameTableKind(NameTableKind), RangesBaseAddress(RangesBaseAddress) {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001162 assert(Storage != Uniqued);
1163 }
1164 ~DICompileUnit() = default;
1165
1166 static DICompileUnit *
1167 getImpl(LLVMContext &Context, unsigned SourceLanguage, DIFile *File,
1168 StringRef Producer, bool IsOptimized, StringRef Flags,
1169 unsigned RuntimeVersion, StringRef SplitDebugFilename,
1170 unsigned EmissionKind, DICompositeTypeArray EnumTypes,
1171 DIScopeArray RetainedTypes,
1172 DIGlobalVariableExpressionArray GlobalVariables,
1173 DIImportedEntityArray ImportedEntities, DIMacroNodeArray Macros,
1174 uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling,
Andrew Walbran16937d02019-10-22 13:54:20 +01001175 unsigned NameTableKind, bool RangesBaseAddress, StorageType Storage,
Andrew Scull0372a572018-11-16 15:47:06 +00001176 bool ShouldCreate = true) {
Andrew Walbran16937d02019-10-22 13:54:20 +01001177 return getImpl(Context, SourceLanguage, File,
1178 getCanonicalMDString(Context, Producer), IsOptimized,
1179 getCanonicalMDString(Context, Flags), RuntimeVersion,
1180 getCanonicalMDString(Context, SplitDebugFilename),
1181 EmissionKind, EnumTypes.get(), RetainedTypes.get(),
1182 GlobalVariables.get(), ImportedEntities.get(), Macros.get(),
1183 DWOId, SplitDebugInlining, DebugInfoForProfiling,
1184 NameTableKind, RangesBaseAddress, Storage, ShouldCreate);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001185 }
1186 static DICompileUnit *
1187 getImpl(LLVMContext &Context, unsigned SourceLanguage, Metadata *File,
1188 MDString *Producer, bool IsOptimized, MDString *Flags,
1189 unsigned RuntimeVersion, MDString *SplitDebugFilename,
1190 unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes,
1191 Metadata *GlobalVariables, Metadata *ImportedEntities,
1192 Metadata *Macros, uint64_t DWOId, bool SplitDebugInlining,
Andrew Scull0372a572018-11-16 15:47:06 +00001193 bool DebugInfoForProfiling, unsigned NameTableKind,
Andrew Walbran16937d02019-10-22 13:54:20 +01001194 bool RangesBaseAddress, StorageType Storage, bool ShouldCreate = true);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001195
1196 TempDICompileUnit cloneImpl() const {
Andrew Walbran16937d02019-10-22 13:54:20 +01001197 return getTemporary(
1198 getContext(), getSourceLanguage(), getFile(), getProducer(),
1199 isOptimized(), getFlags(), getRuntimeVersion(), getSplitDebugFilename(),
1200 getEmissionKind(), getEnumTypes(), getRetainedTypes(),
1201 getGlobalVariables(), getImportedEntities(), getMacros(), DWOId,
1202 getSplitDebugInlining(), getDebugInfoForProfiling(), getNameTableKind(),
1203 getRangesBaseAddress());
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001204 }
1205
1206public:
1207 static void get() = delete;
1208 static void getIfExists() = delete;
1209
1210 DEFINE_MDNODE_GET_DISTINCT_TEMPORARY(
1211 DICompileUnit,
1212 (unsigned SourceLanguage, DIFile *File, StringRef Producer,
1213 bool IsOptimized, StringRef Flags, unsigned RuntimeVersion,
1214 StringRef SplitDebugFilename, DebugEmissionKind EmissionKind,
1215 DICompositeTypeArray EnumTypes, DIScopeArray RetainedTypes,
1216 DIGlobalVariableExpressionArray GlobalVariables,
1217 DIImportedEntityArray ImportedEntities, DIMacroNodeArray Macros,
1218 uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling,
Andrew Walbran16937d02019-10-22 13:54:20 +01001219 DebugNameTableKind NameTableKind, bool RangesBaseAddress),
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001220 (SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion,
1221 SplitDebugFilename, EmissionKind, EnumTypes, RetainedTypes,
1222 GlobalVariables, ImportedEntities, Macros, DWOId, SplitDebugInlining,
Andrew Walbran16937d02019-10-22 13:54:20 +01001223 DebugInfoForProfiling, (unsigned)NameTableKind, RangesBaseAddress))
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001224 DEFINE_MDNODE_GET_DISTINCT_TEMPORARY(
1225 DICompileUnit,
1226 (unsigned SourceLanguage, Metadata *File, MDString *Producer,
1227 bool IsOptimized, MDString *Flags, unsigned RuntimeVersion,
1228 MDString *SplitDebugFilename, unsigned EmissionKind, Metadata *EnumTypes,
1229 Metadata *RetainedTypes, Metadata *GlobalVariables,
1230 Metadata *ImportedEntities, Metadata *Macros, uint64_t DWOId,
Andrew Scull0372a572018-11-16 15:47:06 +00001231 bool SplitDebugInlining, bool DebugInfoForProfiling,
Andrew Walbran16937d02019-10-22 13:54:20 +01001232 unsigned NameTableKind, bool RangesBaseAddress),
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001233 (SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion,
1234 SplitDebugFilename, EmissionKind, EnumTypes, RetainedTypes,
1235 GlobalVariables, ImportedEntities, Macros, DWOId, SplitDebugInlining,
Andrew Walbran16937d02019-10-22 13:54:20 +01001236 DebugInfoForProfiling, NameTableKind, RangesBaseAddress))
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001237
1238 TempDICompileUnit clone() const { return cloneImpl(); }
1239
1240 unsigned getSourceLanguage() const { return SourceLanguage; }
1241 bool isOptimized() const { return IsOptimized; }
1242 unsigned getRuntimeVersion() const { return RuntimeVersion; }
1243 DebugEmissionKind getEmissionKind() const {
1244 return (DebugEmissionKind)EmissionKind;
1245 }
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001246 bool isDebugDirectivesOnly() const {
1247 return EmissionKind == DebugDirectivesOnly;
1248 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001249 bool getDebugInfoForProfiling() const { return DebugInfoForProfiling; }
Andrew Scull0372a572018-11-16 15:47:06 +00001250 DebugNameTableKind getNameTableKind() const {
1251 return (DebugNameTableKind)NameTableKind;
1252 }
Andrew Walbran16937d02019-10-22 13:54:20 +01001253 bool getRangesBaseAddress() const {
1254 return RangesBaseAddress; }
1255 StringRef getProducer() const {
1256 return getStringOperand(1); }
1257 StringRef getFlags() const {
1258 return getStringOperand(2); }
1259 StringRef getSplitDebugFilename() const {
1260 return getStringOperand(3); }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001261 DICompositeTypeArray getEnumTypes() const {
1262 return cast_or_null<MDTuple>(getRawEnumTypes());
1263 }
1264 DIScopeArray getRetainedTypes() const {
1265 return cast_or_null<MDTuple>(getRawRetainedTypes());
1266 }
1267 DIGlobalVariableExpressionArray getGlobalVariables() const {
1268 return cast_or_null<MDTuple>(getRawGlobalVariables());
1269 }
1270 DIImportedEntityArray getImportedEntities() const {
1271 return cast_or_null<MDTuple>(getRawImportedEntities());
1272 }
1273 DIMacroNodeArray getMacros() const {
1274 return cast_or_null<MDTuple>(getRawMacros());
1275 }
1276 uint64_t getDWOId() const { return DWOId; }
1277 void setDWOId(uint64_t DwoId) { DWOId = DwoId; }
1278 bool getSplitDebugInlining() const { return SplitDebugInlining; }
1279 void setSplitDebugInlining(bool SplitDebugInlining) {
1280 this->SplitDebugInlining = SplitDebugInlining;
1281 }
1282
1283 MDString *getRawProducer() const { return getOperandAs<MDString>(1); }
1284 MDString *getRawFlags() const { return getOperandAs<MDString>(2); }
1285 MDString *getRawSplitDebugFilename() const {
1286 return getOperandAs<MDString>(3);
1287 }
1288 Metadata *getRawEnumTypes() const { return getOperand(4); }
1289 Metadata *getRawRetainedTypes() const { return getOperand(5); }
1290 Metadata *getRawGlobalVariables() const { return getOperand(6); }
1291 Metadata *getRawImportedEntities() const { return getOperand(7); }
1292 Metadata *getRawMacros() const { return getOperand(8); }
1293
1294 /// Replace arrays.
1295 ///
1296 /// If this \a isUniqued() and not \a isResolved(), it will be RAUW'ed and
1297 /// deleted on a uniquing collision. In practice, uniquing collisions on \a
1298 /// DICompileUnit should be fairly rare.
1299 /// @{
1300 void replaceEnumTypes(DICompositeTypeArray N) {
1301 replaceOperandWith(4, N.get());
1302 }
1303 void replaceRetainedTypes(DITypeArray N) {
1304 replaceOperandWith(5, N.get());
1305 }
1306 void replaceGlobalVariables(DIGlobalVariableExpressionArray N) {
1307 replaceOperandWith(6, N.get());
1308 }
1309 void replaceImportedEntities(DIImportedEntityArray N) {
1310 replaceOperandWith(7, N.get());
1311 }
1312 void replaceMacros(DIMacroNodeArray N) { replaceOperandWith(8, N.get()); }
1313 /// @}
1314
1315 static bool classof(const Metadata *MD) {
1316 return MD->getMetadataID() == DICompileUnitKind;
1317 }
1318};
1319
1320/// A scope for locals.
1321///
1322/// A legal scope for lexical blocks, local variables, and debug info
1323/// locations. Subclasses are \a DISubprogram, \a DILexicalBlock, and \a
1324/// DILexicalBlockFile.
1325class DILocalScope : public DIScope {
1326protected:
1327 DILocalScope(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
1328 ArrayRef<Metadata *> Ops)
1329 : DIScope(C, ID, Storage, Tag, Ops) {}
1330 ~DILocalScope() = default;
1331
1332public:
1333 /// Get the subprogram for this scope.
1334 ///
1335 /// Return this if it's an \a DISubprogram; otherwise, look up the scope
1336 /// chain.
1337 DISubprogram *getSubprogram() const;
1338
1339 /// Get the first non DILexicalBlockFile scope of this scope.
1340 ///
1341 /// Return this if it's not a \a DILexicalBlockFIle; otherwise, look up the
1342 /// scope chain.
1343 DILocalScope *getNonLexicalBlockFileScope() const;
1344
1345 static bool classof(const Metadata *MD) {
1346 return MD->getMetadataID() == DISubprogramKind ||
1347 MD->getMetadataID() == DILexicalBlockKind ||
1348 MD->getMetadataID() == DILexicalBlockFileKind;
1349 }
1350};
1351
1352/// Debug location.
1353///
1354/// A debug location in source code, used for debug info and otherwise.
1355class DILocation : public MDNode {
1356 friend class LLVMContextImpl;
1357 friend class MDNode;
1358
1359 DILocation(LLVMContext &C, StorageType Storage, unsigned Line,
Andrew Scull0372a572018-11-16 15:47:06 +00001360 unsigned Column, ArrayRef<Metadata *> MDs, bool ImplicitCode);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001361 ~DILocation() { dropAllReferences(); }
1362
1363 static DILocation *getImpl(LLVMContext &Context, unsigned Line,
1364 unsigned Column, Metadata *Scope,
Andrew Scull0372a572018-11-16 15:47:06 +00001365 Metadata *InlinedAt, bool ImplicitCode,
1366 StorageType Storage, bool ShouldCreate = true);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001367 static DILocation *getImpl(LLVMContext &Context, unsigned Line,
1368 unsigned Column, DILocalScope *Scope,
Andrew Scull0372a572018-11-16 15:47:06 +00001369 DILocation *InlinedAt, bool ImplicitCode,
1370 StorageType Storage, bool ShouldCreate = true) {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001371 return getImpl(Context, Line, Column, static_cast<Metadata *>(Scope),
Andrew Scull0372a572018-11-16 15:47:06 +00001372 static_cast<Metadata *>(InlinedAt), ImplicitCode, Storage,
1373 ShouldCreate);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001374 }
1375
1376 /// With a given unsigned int \p U, use up to 13 bits to represent it.
1377 /// old_bit 1~5 --> new_bit 1~5
1378 /// old_bit 6~12 --> new_bit 7~13
1379 /// new_bit_6 is 0 if higher bits (7~13) are all 0
1380 static unsigned getPrefixEncodingFromUnsigned(unsigned U) {
1381 U &= 0xfff;
1382 return U > 0x1f ? (((U & 0xfe0) << 1) | (U & 0x1f) | 0x20) : U;
1383 }
1384
1385 /// Reverse transformation as getPrefixEncodingFromUnsigned.
1386 static unsigned getUnsignedFromPrefixEncoding(unsigned U) {
Andrew Walbran16937d02019-10-22 13:54:20 +01001387 if (U & 1)
1388 return 0;
1389 U >>= 1;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001390 return (U & 0x20) ? (((U >> 1) & 0xfe0) | (U & 0x1f)) : (U & 0x1f);
1391 }
1392
1393 /// Returns the next component stored in discriminator.
1394 static unsigned getNextComponentInDiscriminator(unsigned D) {
1395 if ((D & 1) == 0)
1396 return D >> ((D & 0x40) ? 14 : 7);
1397 else
1398 return D >> 1;
1399 }
1400
1401 TempDILocation cloneImpl() const {
1402 // Get the raw scope/inlinedAt since it is possible to invoke this on
1403 // a DILocation containing temporary metadata.
1404 return getTemporary(getContext(), getLine(), getColumn(), getRawScope(),
Andrew Scull0372a572018-11-16 15:47:06 +00001405 getRawInlinedAt(), isImplicitCode());
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001406 }
1407
Andrew Walbran16937d02019-10-22 13:54:20 +01001408 static unsigned encodeComponent(unsigned C) {
1409 return (C == 0) ? 1U : (getPrefixEncodingFromUnsigned(C) << 1);
1410 }
1411
1412 static unsigned encodingBits(unsigned C) {
1413 return (C == 0) ? 1 : (C > 0x1f ? 14 : 7);
1414 }
1415
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001416public:
1417 // Disallow replacing operands.
1418 void replaceOperandWith(unsigned I, Metadata *New) = delete;
1419
1420 DEFINE_MDNODE_GET(DILocation,
1421 (unsigned Line, unsigned Column, Metadata *Scope,
Andrew Scull0372a572018-11-16 15:47:06 +00001422 Metadata *InlinedAt = nullptr, bool ImplicitCode = false),
1423 (Line, Column, Scope, InlinedAt, ImplicitCode))
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001424 DEFINE_MDNODE_GET(DILocation,
1425 (unsigned Line, unsigned Column, DILocalScope *Scope,
Andrew Scull0372a572018-11-16 15:47:06 +00001426 DILocation *InlinedAt = nullptr,
1427 bool ImplicitCode = false),
1428 (Line, Column, Scope, InlinedAt, ImplicitCode))
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001429
1430 /// Return a (temporary) clone of this.
1431 TempDILocation clone() const { return cloneImpl(); }
1432
1433 unsigned getLine() const { return SubclassData32; }
1434 unsigned getColumn() const { return SubclassData16; }
1435 DILocalScope *getScope() const { return cast<DILocalScope>(getRawScope()); }
1436
1437 DILocation *getInlinedAt() const {
1438 return cast_or_null<DILocation>(getRawInlinedAt());
1439 }
1440
Andrew Scull0372a572018-11-16 15:47:06 +00001441 /// Check if the location corresponds to an implicit code.
1442 /// When the ImplicitCode flag is true, it means that the Instruction
1443 /// with this DILocation has been added by the front-end but it hasn't been
1444 /// written explicitly by the user (e.g. cleanup stuff in C++ put on a closing
1445 /// bracket). It's useful for code coverage to not show a counter on "empty"
1446 /// lines.
1447 bool isImplicitCode() const { return ImplicitCode; }
1448 void setImplicitCode(bool ImplicitCode) { this->ImplicitCode = ImplicitCode; }
1449
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001450 DIFile *getFile() const { return getScope()->getFile(); }
1451 StringRef getFilename() const { return getScope()->getFilename(); }
1452 StringRef getDirectory() const { return getScope()->getDirectory(); }
1453 Optional<StringRef> getSource() const { return getScope()->getSource(); }
1454
1455 /// Get the scope where this is inlined.
1456 ///
1457 /// Walk through \a getInlinedAt() and return \a getScope() from the deepest
1458 /// location.
1459 DILocalScope *getInlinedAtScope() const {
1460 if (auto *IA = getInlinedAt())
1461 return IA->getInlinedAtScope();
1462 return getScope();
1463 }
1464
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001465 /// Get the DWARF discriminator.
1466 ///
1467 /// DWARF discriminators distinguish identical file locations between
1468 /// instructions that are on different basic blocks.
1469 ///
1470 /// There are 3 components stored in discriminator, from lower bits:
1471 ///
1472 /// Base discriminator: assigned by AddDiscriminators pass to identify IRs
1473 /// that are defined by the same source line, but
1474 /// different basic blocks.
1475 /// Duplication factor: assigned by optimizations that will scale down
1476 /// the execution frequency of the original IR.
1477 /// Copy Identifier: assigned by optimizations that clones the IR.
1478 /// Each copy of the IR will be assigned an identifier.
1479 ///
1480 /// Encoding:
1481 ///
1482 /// The above 3 components are encoded into a 32bit unsigned integer in
1483 /// order. If the lowest bit is 1, the current component is empty, and the
1484 /// next component will start in the next bit. Otherwise, the current
1485 /// component is non-empty, and its content starts in the next bit. The
Andrew Walbran16937d02019-10-22 13:54:20 +01001486 /// value of each components is either 5 bit or 12 bit: if the 7th bit
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001487 /// is 0, the bit 2~6 (5 bits) are used to represent the component; if the
1488 /// 7th bit is 1, the bit 2~6 (5 bits) and 8~14 (7 bits) are combined to
Andrew Walbran16937d02019-10-22 13:54:20 +01001489 /// represent the component. Thus, the number of bits used for a component
1490 /// is either 0 (if it and all the next components are empty); 1 - if it is
1491 /// empty; 7 - if its value is up to and including 0x1f (lsb and msb are both
1492 /// 0); or 14, if its value is up to and including 0x1ff. Note that the last
1493 /// component is also capped at 0x1ff, even in the case when both first
1494 /// components are 0, and we'd technically have 29 bits available.
1495 ///
1496 /// For precise control over the data being encoded in the discriminator,
1497 /// use encodeDiscriminator/decodeDiscriminator.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001498
1499 inline unsigned getDiscriminator() const;
1500
1501 /// Returns a new DILocation with updated \p Discriminator.
1502 inline const DILocation *cloneWithDiscriminator(unsigned Discriminator) const;
1503
Andrew Walbran16937d02019-10-22 13:54:20 +01001504 /// Returns a new DILocation with updated base discriminator \p BD. Only the
1505 /// base discriminator is set in the new DILocation, the other encoded values
1506 /// are elided.
1507 /// If the discriminator cannot be encoded, the function returns None.
1508 inline Optional<const DILocation *> cloneWithBaseDiscriminator(unsigned BD) const;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001509
Andrew Walbran16937d02019-10-22 13:54:20 +01001510 /// Returns the duplication factor stored in the discriminator, or 1 if no
1511 /// duplication factor (or 0) is encoded.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001512 inline unsigned getDuplicationFactor() const;
1513
1514 /// Returns the copy identifier stored in the discriminator.
1515 inline unsigned getCopyIdentifier() const;
1516
1517 /// Returns the base discriminator stored in the discriminator.
1518 inline unsigned getBaseDiscriminator() const;
1519
Andrew Walbran16937d02019-10-22 13:54:20 +01001520 /// Returns a new DILocation with duplication factor \p DF * current
1521 /// duplication factor encoded in the discriminator. The current duplication
1522 /// factor is as defined by getDuplicationFactor().
1523 /// Returns None if encoding failed.
1524 inline Optional<const DILocation *> cloneByMultiplyingDuplicationFactor(unsigned DF) const;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001525
1526 /// When two instructions are combined into a single instruction we also
1527 /// need to combine the original locations into a single location.
1528 ///
1529 /// When the locations are the same we can use either location. When they
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001530 /// differ, we need a third location which is distinct from either. If they
1531 /// have the same file/line but have a different discriminator we could
1532 /// create a location with a new discriminator. If they are from different
1533 /// files/lines the location is ambiguous and can't be represented in a line
1534 /// entry. In this case, if \p GenerateLocation is true, we will set the
1535 /// merged debug location as line 0 of the nearest common scope where the two
1536 /// locations are inlined from.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001537 ///
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001538 /// \p GenerateLocation: Whether the merged location can be generated when
1539 /// \p LocA and \p LocB differ.
Andrew Scull0372a572018-11-16 15:47:06 +00001540 static const DILocation *getMergedLocation(const DILocation *LocA,
1541 const DILocation *LocB);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001542
1543 /// Returns the base discriminator for a given encoded discriminator \p D.
1544 static unsigned getBaseDiscriminatorFromDiscriminator(unsigned D) {
Andrew Walbran16937d02019-10-22 13:54:20 +01001545 return getUnsignedFromPrefixEncoding(D);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001546 }
1547
Andrew Walbran16937d02019-10-22 13:54:20 +01001548 /// Raw encoding of the discriminator. APIs such as cloneWithDuplicationFactor
1549 /// have certain special case behavior (e.g. treating empty duplication factor
1550 /// as the value '1').
1551 /// This API, in conjunction with cloneWithDiscriminator, may be used to encode
1552 /// the raw values provided. \p BD: base discriminator \p DF: duplication factor
1553 /// \p CI: copy index
1554 /// The return is None if the values cannot be encoded in 32 bits - for
1555 /// example, values for BD or DF larger than 12 bits. Otherwise, the return
1556 /// is the encoded value.
1557 static Optional<unsigned> encodeDiscriminator(unsigned BD, unsigned DF, unsigned CI);
1558
1559 /// Raw decoder for values in an encoded discriminator D.
1560 static void decodeDiscriminator(unsigned D, unsigned &BD, unsigned &DF,
1561 unsigned &CI);
1562
1563 /// Returns the duplication factor for a given encoded discriminator \p D, or
1564 /// 1 if no value or 0 is encoded.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001565 static unsigned getDuplicationFactorFromDiscriminator(unsigned D) {
1566 D = getNextComponentInDiscriminator(D);
Andrew Walbran16937d02019-10-22 13:54:20 +01001567 unsigned Ret = getUnsignedFromPrefixEncoding(D);
1568 if (Ret == 0)
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001569 return 1;
Andrew Walbran16937d02019-10-22 13:54:20 +01001570 return Ret;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001571 }
1572
1573 /// Returns the copy identifier for a given encoded discriminator \p D.
1574 static unsigned getCopyIdentifierFromDiscriminator(unsigned D) {
1575 return getUnsignedFromPrefixEncoding(getNextComponentInDiscriminator(
1576 getNextComponentInDiscriminator(D)));
1577 }
1578
1579
1580 Metadata *getRawScope() const { return getOperand(0); }
1581 Metadata *getRawInlinedAt() const {
1582 if (getNumOperands() == 2)
1583 return getOperand(1);
1584 return nullptr;
1585 }
1586
1587 static bool classof(const Metadata *MD) {
1588 return MD->getMetadataID() == DILocationKind;
1589 }
1590};
1591
1592/// Subprogram description.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001593class DISubprogram : public DILocalScope {
1594 friend class LLVMContextImpl;
1595 friend class MDNode;
1596
1597 unsigned Line;
1598 unsigned ScopeLine;
1599 unsigned VirtualIndex;
1600
1601 /// In the MS ABI, the implicit 'this' parameter is adjusted in the prologue
1602 /// of method overrides from secondary bases by this amount. It may be
1603 /// negative.
1604 int ThisAdjustment;
1605
Andrew Walbran16937d02019-10-22 13:54:20 +01001606public:
1607 /// Debug info subprogram flags.
1608 enum DISPFlags : uint32_t {
1609#define HANDLE_DISP_FLAG(ID, NAME) SPFlag##NAME = ID,
1610#define DISP_FLAG_LARGEST_NEEDED
1611#include "llvm/IR/DebugInfoFlags.def"
1612 SPFlagNonvirtual = SPFlagZero,
1613 SPFlagVirtuality = SPFlagVirtual | SPFlagPureVirtual,
1614 LLVM_MARK_AS_BITMASK_ENUM(SPFlagLargest)
1615 };
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001616
Andrew Walbran16937d02019-10-22 13:54:20 +01001617 static DISPFlags getFlag(StringRef Flag);
1618 static StringRef getFlagString(DISPFlags Flag);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001619
Andrew Walbran16937d02019-10-22 13:54:20 +01001620 /// Split up a flags bitfield for easier printing.
1621 ///
1622 /// Split \c Flags into \c SplitFlags, a vector of its components. Returns
1623 /// any remaining (unrecognized) bits.
1624 static DISPFlags splitFlags(DISPFlags Flags,
1625 SmallVectorImpl<DISPFlags> &SplitFlags);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001626
Andrew Walbran16937d02019-10-22 13:54:20 +01001627 // Helper for converting old bitfields to new flags word.
1628 static DISPFlags toSPFlags(bool IsLocalToUnit, bool IsDefinition,
1629 bool IsOptimized,
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001630 unsigned Virtuality = SPFlagNonvirtual,
1631 bool IsMainSubprogram = false) {
Andrew Walbran16937d02019-10-22 13:54:20 +01001632 // We're assuming virtuality is the low-order field.
1633 static_assert(
1634 int(SPFlagVirtual) == int(dwarf::DW_VIRTUALITY_virtual) &&
1635 int(SPFlagPureVirtual) == int(dwarf::DW_VIRTUALITY_pure_virtual),
1636 "Virtuality constant mismatch");
1637 return static_cast<DISPFlags>(
1638 (Virtuality & SPFlagVirtuality) |
1639 (IsLocalToUnit ? SPFlagLocalToUnit : SPFlagZero) |
1640 (IsDefinition ? SPFlagDefinition : SPFlagZero) |
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001641 (IsOptimized ? SPFlagOptimized : SPFlagZero) |
1642 (IsMainSubprogram ? SPFlagMainSubprogram : SPFlagZero));
Andrew Walbran16937d02019-10-22 13:54:20 +01001643 }
1644
1645private:
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001646 DIFlags Flags;
Andrew Walbran16937d02019-10-22 13:54:20 +01001647 DISPFlags SPFlags;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001648
1649 DISubprogram(LLVMContext &C, StorageType Storage, unsigned Line,
Andrew Walbran16937d02019-10-22 13:54:20 +01001650 unsigned ScopeLine, unsigned VirtualIndex, int ThisAdjustment,
1651 DIFlags Flags, DISPFlags SPFlags, ArrayRef<Metadata *> Ops)
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001652 : DILocalScope(C, DISubprogramKind, Storage, dwarf::DW_TAG_subprogram,
1653 Ops),
1654 Line(Line), ScopeLine(ScopeLine), VirtualIndex(VirtualIndex),
Andrew Walbran16937d02019-10-22 13:54:20 +01001655 ThisAdjustment(ThisAdjustment), Flags(Flags), SPFlags(SPFlags) {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001656 static_assert(dwarf::DW_VIRTUALITY_max < 4, "Virtuality out of range");
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001657 }
1658 ~DISubprogram() = default;
1659
1660 static DISubprogram *
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001661 getImpl(LLVMContext &Context, DIScope *Scope, StringRef Name,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001662 StringRef LinkageName, DIFile *File, unsigned Line,
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001663 DISubroutineType *Type, unsigned ScopeLine, DIType *ContainingType,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001664 unsigned VirtualIndex, int ThisAdjustment, DIFlags Flags,
Andrew Walbran16937d02019-10-22 13:54:20 +01001665 DISPFlags SPFlags, DICompileUnit *Unit,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001666 DITemplateParameterArray TemplateParams, DISubprogram *Declaration,
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001667 DINodeArray RetainedNodes, DITypeArray ThrownTypes,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001668 StorageType Storage, bool ShouldCreate = true) {
1669 return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
1670 getCanonicalMDString(Context, LinkageName), File, Line, Type,
Andrew Walbran16937d02019-10-22 13:54:20 +01001671 ScopeLine, ContainingType, VirtualIndex, ThisAdjustment,
1672 Flags, SPFlags, Unit, TemplateParams.get(), Declaration,
1673 RetainedNodes.get(), ThrownTypes.get(), Storage,
1674 ShouldCreate);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001675 }
Andrew Walbran16937d02019-10-22 13:54:20 +01001676 static DISubprogram *getImpl(LLVMContext &Context, Metadata *Scope,
1677 MDString *Name, MDString *LinkageName,
1678 Metadata *File, unsigned Line, Metadata *Type,
1679 unsigned ScopeLine, Metadata *ContainingType,
1680 unsigned VirtualIndex, int ThisAdjustment,
1681 DIFlags Flags, DISPFlags SPFlags, Metadata *Unit,
1682 Metadata *TemplateParams, Metadata *Declaration,
1683 Metadata *RetainedNodes, Metadata *ThrownTypes,
1684 StorageType Storage, bool ShouldCreate = true);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001685
1686 TempDISubprogram cloneImpl() const {
1687 return getTemporary(getContext(), getScope(), getName(), getLinkageName(),
Andrew Walbran16937d02019-10-22 13:54:20 +01001688 getFile(), getLine(), getType(), getScopeLine(),
1689 getContainingType(), getVirtualIndex(),
1690 getThisAdjustment(), getFlags(), getSPFlags(),
1691 getUnit(), getTemplateParams(), getDeclaration(),
1692 getRetainedNodes(), getThrownTypes());
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001693 }
1694
1695public:
Andrew Walbran16937d02019-10-22 13:54:20 +01001696 DEFINE_MDNODE_GET(
1697 DISubprogram,
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001698 (DIScope * Scope, StringRef Name, StringRef LinkageName, DIFile *File,
Andrew Walbran16937d02019-10-22 13:54:20 +01001699 unsigned Line, DISubroutineType *Type, unsigned ScopeLine,
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001700 DIType *ContainingType, unsigned VirtualIndex, int ThisAdjustment,
Andrew Walbran16937d02019-10-22 13:54:20 +01001701 DIFlags Flags, DISPFlags SPFlags, DICompileUnit *Unit,
1702 DITemplateParameterArray TemplateParams = nullptr,
1703 DISubprogram *Declaration = nullptr, DINodeArray RetainedNodes = nullptr,
1704 DITypeArray ThrownTypes = nullptr),
1705 (Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType,
1706 VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams,
1707 Declaration, RetainedNodes, ThrownTypes))
1708
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001709 DEFINE_MDNODE_GET(
1710 DISubprogram,
1711 (Metadata * Scope, MDString *Name, MDString *LinkageName, Metadata *File,
Andrew Walbran16937d02019-10-22 13:54:20 +01001712 unsigned Line, Metadata *Type, unsigned ScopeLine,
1713 Metadata *ContainingType, unsigned VirtualIndex, int ThisAdjustment,
1714 DIFlags Flags, DISPFlags SPFlags, Metadata *Unit,
1715 Metadata *TemplateParams = nullptr, Metadata *Declaration = nullptr,
1716 Metadata *RetainedNodes = nullptr, Metadata *ThrownTypes = nullptr),
1717 (Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType,
1718 VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams,
1719 Declaration, RetainedNodes, ThrownTypes))
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001720
1721 TempDISubprogram clone() const { return cloneImpl(); }
1722
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001723 /// Returns a new temporary DISubprogram with updated Flags
1724 TempDISubprogram cloneWithFlags(DIFlags NewFlags) const {
1725 auto NewSP = clone();
1726 NewSP->Flags = NewFlags;
1727 return NewSP;
1728 }
1729
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001730public:
1731 unsigned getLine() const { return Line; }
Andrew Walbran16937d02019-10-22 13:54:20 +01001732 unsigned getVirtuality() const { return getSPFlags() & SPFlagVirtuality; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001733 unsigned getVirtualIndex() const { return VirtualIndex; }
1734 int getThisAdjustment() const { return ThisAdjustment; }
1735 unsigned getScopeLine() const { return ScopeLine; }
1736 DIFlags getFlags() const { return Flags; }
Andrew Walbran16937d02019-10-22 13:54:20 +01001737 DISPFlags getSPFlags() const { return SPFlags; }
1738 bool isLocalToUnit() const { return getSPFlags() & SPFlagLocalToUnit; }
1739 bool isDefinition() const { return getSPFlags() & SPFlagDefinition; }
1740 bool isOptimized() const { return getSPFlags() & SPFlagOptimized; }
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001741 bool isMainSubprogram() const { return getSPFlags() & SPFlagMainSubprogram; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001742
1743 bool isArtificial() const { return getFlags() & FlagArtificial; }
1744 bool isPrivate() const {
1745 return (getFlags() & FlagAccessibility) == FlagPrivate;
1746 }
1747 bool isProtected() const {
1748 return (getFlags() & FlagAccessibility) == FlagProtected;
1749 }
1750 bool isPublic() const {
1751 return (getFlags() & FlagAccessibility) == FlagPublic;
1752 }
1753 bool isExplicit() const { return getFlags() & FlagExplicit; }
1754 bool isPrototyped() const { return getFlags() & FlagPrototyped; }
Andrew Scull0372a572018-11-16 15:47:06 +00001755 bool areAllCallsDescribed() const {
1756 return getFlags() & FlagAllCallsDescribed;
1757 }
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001758 bool isPure() const { return getSPFlags() & SPFlagPure; }
1759 bool isElemental() const { return getSPFlags() & SPFlagElemental; }
1760 bool isRecursive() const { return getSPFlags() & SPFlagRecursive; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001761
1762 /// Check if this is reference-qualified.
1763 ///
1764 /// Return true if this subprogram is a C++11 reference-qualified non-static
1765 /// member function (void foo() &).
1766 bool isLValueReference() const { return getFlags() & FlagLValueReference; }
1767
1768 /// Check if this is rvalue-reference-qualified.
1769 ///
1770 /// Return true if this subprogram is a C++11 rvalue-reference-qualified
1771 /// non-static member function (void foo() &&).
1772 bool isRValueReference() const { return getFlags() & FlagRValueReference; }
1773
1774 /// Check if this is marked as noreturn.
1775 ///
1776 /// Return true if this subprogram is C++11 noreturn or C11 _Noreturn
1777 bool isNoReturn() const { return getFlags() & FlagNoReturn; }
1778
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001779 // Check if this routine is a compiler-generated thunk.
1780 //
1781 // Returns true if this subprogram is a thunk generated by the compiler.
1782 bool isThunk() const { return getFlags() & FlagThunk; }
1783
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001784 DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001785
1786 StringRef getName() const { return getStringOperand(2); }
1787 StringRef getLinkageName() const { return getStringOperand(3); }
1788
1789 DISubroutineType *getType() const {
1790 return cast_or_null<DISubroutineType>(getRawType());
1791 }
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001792 DIType *getContainingType() const {
1793 return cast_or_null<DIType>(getRawContainingType());
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001794 }
1795
1796 DICompileUnit *getUnit() const {
1797 return cast_or_null<DICompileUnit>(getRawUnit());
1798 }
1799 void replaceUnit(DICompileUnit *CU) { replaceOperandWith(5, CU); }
1800 DITemplateParameterArray getTemplateParams() const {
1801 return cast_or_null<MDTuple>(getRawTemplateParams());
1802 }
1803 DISubprogram *getDeclaration() const {
1804 return cast_or_null<DISubprogram>(getRawDeclaration());
1805 }
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001806 DINodeArray getRetainedNodes() const {
1807 return cast_or_null<MDTuple>(getRawRetainedNodes());
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001808 }
1809 DITypeArray getThrownTypes() const {
1810 return cast_or_null<MDTuple>(getRawThrownTypes());
1811 }
1812
1813 Metadata *getRawScope() const { return getOperand(1); }
1814 MDString *getRawName() const { return getOperandAs<MDString>(2); }
1815 MDString *getRawLinkageName() const { return getOperandAs<MDString>(3); }
1816 Metadata *getRawType() const { return getOperand(4); }
1817 Metadata *getRawUnit() const { return getOperand(5); }
1818 Metadata *getRawDeclaration() const { return getOperand(6); }
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001819 Metadata *getRawRetainedNodes() const { return getOperand(7); }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001820 Metadata *getRawContainingType() const {
1821 return getNumOperands() > 8 ? getOperandAs<Metadata>(8) : nullptr;
1822 }
1823 Metadata *getRawTemplateParams() const {
1824 return getNumOperands() > 9 ? getOperandAs<Metadata>(9) : nullptr;
1825 }
1826 Metadata *getRawThrownTypes() const {
1827 return getNumOperands() > 10 ? getOperandAs<Metadata>(10) : nullptr;
1828 }
1829
1830 /// Check if this subprogram describes the given function.
1831 ///
1832 /// FIXME: Should this be looking through bitcasts?
1833 bool describes(const Function *F) const;
1834
1835 static bool classof(const Metadata *MD) {
1836 return MD->getMetadataID() == DISubprogramKind;
1837 }
1838};
1839
1840class DILexicalBlockBase : public DILocalScope {
1841protected:
1842 DILexicalBlockBase(LLVMContext &C, unsigned ID, StorageType Storage,
1843 ArrayRef<Metadata *> Ops)
1844 : DILocalScope(C, ID, Storage, dwarf::DW_TAG_lexical_block, Ops) {}
1845 ~DILexicalBlockBase() = default;
1846
1847public:
1848 DILocalScope *getScope() const { return cast<DILocalScope>(getRawScope()); }
1849
1850 Metadata *getRawScope() const { return getOperand(1); }
1851
1852 static bool classof(const Metadata *MD) {
1853 return MD->getMetadataID() == DILexicalBlockKind ||
1854 MD->getMetadataID() == DILexicalBlockFileKind;
1855 }
1856};
1857
1858class DILexicalBlock : public DILexicalBlockBase {
1859 friend class LLVMContextImpl;
1860 friend class MDNode;
1861
1862 unsigned Line;
1863 uint16_t Column;
1864
1865 DILexicalBlock(LLVMContext &C, StorageType Storage, unsigned Line,
1866 unsigned Column, ArrayRef<Metadata *> Ops)
1867 : DILexicalBlockBase(C, DILexicalBlockKind, Storage, Ops), Line(Line),
1868 Column(Column) {
1869 assert(Column < (1u << 16) && "Expected 16-bit column");
1870 }
1871 ~DILexicalBlock() = default;
1872
1873 static DILexicalBlock *getImpl(LLVMContext &Context, DILocalScope *Scope,
1874 DIFile *File, unsigned Line, unsigned Column,
1875 StorageType Storage,
1876 bool ShouldCreate = true) {
1877 return getImpl(Context, static_cast<Metadata *>(Scope),
1878 static_cast<Metadata *>(File), Line, Column, Storage,
1879 ShouldCreate);
1880 }
1881
1882 static DILexicalBlock *getImpl(LLVMContext &Context, Metadata *Scope,
1883 Metadata *File, unsigned Line, unsigned Column,
1884 StorageType Storage, bool ShouldCreate = true);
1885
1886 TempDILexicalBlock cloneImpl() const {
1887 return getTemporary(getContext(), getScope(), getFile(), getLine(),
1888 getColumn());
1889 }
1890
1891public:
1892 DEFINE_MDNODE_GET(DILexicalBlock, (DILocalScope * Scope, DIFile *File,
1893 unsigned Line, unsigned Column),
1894 (Scope, File, Line, Column))
1895 DEFINE_MDNODE_GET(DILexicalBlock, (Metadata * Scope, Metadata *File,
1896 unsigned Line, unsigned Column),
1897 (Scope, File, Line, Column))
1898
1899 TempDILexicalBlock clone() const { return cloneImpl(); }
1900
1901 unsigned getLine() const { return Line; }
1902 unsigned getColumn() const { return Column; }
1903
1904 static bool classof(const Metadata *MD) {
1905 return MD->getMetadataID() == DILexicalBlockKind;
1906 }
1907};
1908
1909class DILexicalBlockFile : public DILexicalBlockBase {
1910 friend class LLVMContextImpl;
1911 friend class MDNode;
1912
1913 unsigned Discriminator;
1914
1915 DILexicalBlockFile(LLVMContext &C, StorageType Storage,
1916 unsigned Discriminator, ArrayRef<Metadata *> Ops)
1917 : DILexicalBlockBase(C, DILexicalBlockFileKind, Storage, Ops),
1918 Discriminator(Discriminator) {}
1919 ~DILexicalBlockFile() = default;
1920
1921 static DILexicalBlockFile *getImpl(LLVMContext &Context, DILocalScope *Scope,
1922 DIFile *File, unsigned Discriminator,
1923 StorageType Storage,
1924 bool ShouldCreate = true) {
1925 return getImpl(Context, static_cast<Metadata *>(Scope),
1926 static_cast<Metadata *>(File), Discriminator, Storage,
1927 ShouldCreate);
1928 }
1929
1930 static DILexicalBlockFile *getImpl(LLVMContext &Context, Metadata *Scope,
1931 Metadata *File, unsigned Discriminator,
1932 StorageType Storage,
1933 bool ShouldCreate = true);
1934
1935 TempDILexicalBlockFile cloneImpl() const {
1936 return getTemporary(getContext(), getScope(), getFile(),
1937 getDiscriminator());
1938 }
1939
1940public:
1941 DEFINE_MDNODE_GET(DILexicalBlockFile, (DILocalScope * Scope, DIFile *File,
1942 unsigned Discriminator),
1943 (Scope, File, Discriminator))
1944 DEFINE_MDNODE_GET(DILexicalBlockFile,
1945 (Metadata * Scope, Metadata *File, unsigned Discriminator),
1946 (Scope, File, Discriminator))
1947
1948 TempDILexicalBlockFile clone() const { return cloneImpl(); }
1949
1950 // TODO: Remove these once they're gone from DILexicalBlockBase.
1951 unsigned getLine() const = delete;
1952 unsigned getColumn() const = delete;
1953
1954 unsigned getDiscriminator() const { return Discriminator; }
1955
1956 static bool classof(const Metadata *MD) {
1957 return MD->getMetadataID() == DILexicalBlockFileKind;
1958 }
1959};
1960
1961unsigned DILocation::getDiscriminator() const {
1962 if (auto *F = dyn_cast<DILexicalBlockFile>(getScope()))
1963 return F->getDiscriminator();
1964 return 0;
1965}
1966
1967const DILocation *
1968DILocation::cloneWithDiscriminator(unsigned Discriminator) const {
1969 DIScope *Scope = getScope();
1970 // Skip all parent DILexicalBlockFile that already have a discriminator
1971 // assigned. We do not want to have nested DILexicalBlockFiles that have
1972 // mutliple discriminators because only the leaf DILexicalBlockFile's
1973 // dominator will be used.
1974 for (auto *LBF = dyn_cast<DILexicalBlockFile>(Scope);
1975 LBF && LBF->getDiscriminator() != 0;
1976 LBF = dyn_cast<DILexicalBlockFile>(Scope))
1977 Scope = LBF->getScope();
1978 DILexicalBlockFile *NewScope =
1979 DILexicalBlockFile::get(getContext(), Scope, getFile(), Discriminator);
1980 return DILocation::get(getContext(), getLine(), getColumn(), NewScope,
1981 getInlinedAt());
1982}
1983
1984unsigned DILocation::getBaseDiscriminator() const {
1985 return getBaseDiscriminatorFromDiscriminator(getDiscriminator());
1986}
1987
1988unsigned DILocation::getDuplicationFactor() const {
1989 return getDuplicationFactorFromDiscriminator(getDiscriminator());
1990}
1991
1992unsigned DILocation::getCopyIdentifier() const {
1993 return getCopyIdentifierFromDiscriminator(getDiscriminator());
1994}
1995
Andrew Walbran16937d02019-10-22 13:54:20 +01001996Optional<const DILocation *> DILocation::cloneWithBaseDiscriminator(unsigned D) const {
1997 unsigned BD, DF, CI;
1998 decodeDiscriminator(getDiscriminator(), BD, DF, CI);
1999 if (D == BD)
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002000 return this;
Andrew Walbran16937d02019-10-22 13:54:20 +01002001 if (Optional<unsigned> Encoded = encodeDiscriminator(D, DF, CI))
2002 return cloneWithDiscriminator(*Encoded);
2003 return None;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002004}
2005
Andrew Walbran16937d02019-10-22 13:54:20 +01002006Optional<const DILocation *> DILocation::cloneByMultiplyingDuplicationFactor(unsigned DF) const {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002007 DF *= getDuplicationFactor();
2008 if (DF <= 1)
2009 return this;
2010
2011 unsigned BD = getBaseDiscriminator();
Andrew Walbran16937d02019-10-22 13:54:20 +01002012 unsigned CI = getCopyIdentifier();
2013 if (Optional<unsigned> D = encodeDiscriminator(BD, DF, CI))
2014 return cloneWithDiscriminator(*D);
2015 return None;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002016}
2017
2018class DINamespace : public DIScope {
2019 friend class LLVMContextImpl;
2020 friend class MDNode;
2021
2022 unsigned ExportSymbols : 1;
2023
2024 DINamespace(LLVMContext &Context, StorageType Storage, bool ExportSymbols,
2025 ArrayRef<Metadata *> Ops)
2026 : DIScope(Context, DINamespaceKind, Storage, dwarf::DW_TAG_namespace,
2027 Ops),
2028 ExportSymbols(ExportSymbols) {}
2029 ~DINamespace() = default;
2030
2031 static DINamespace *getImpl(LLVMContext &Context, DIScope *Scope,
2032 StringRef Name, bool ExportSymbols,
2033 StorageType Storage, bool ShouldCreate = true) {
2034 return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
2035 ExportSymbols, Storage, ShouldCreate);
2036 }
2037 static DINamespace *getImpl(LLVMContext &Context, Metadata *Scope,
2038 MDString *Name, bool ExportSymbols,
2039 StorageType Storage, bool ShouldCreate = true);
2040
2041 TempDINamespace cloneImpl() const {
2042 return getTemporary(getContext(), getScope(), getName(),
2043 getExportSymbols());
2044 }
2045
2046public:
2047 DEFINE_MDNODE_GET(DINamespace,
2048 (DIScope *Scope, StringRef Name, bool ExportSymbols),
2049 (Scope, Name, ExportSymbols))
2050 DEFINE_MDNODE_GET(DINamespace,
2051 (Metadata *Scope, MDString *Name, bool ExportSymbols),
2052 (Scope, Name, ExportSymbols))
2053
2054 TempDINamespace clone() const { return cloneImpl(); }
2055
2056 bool getExportSymbols() const { return ExportSymbols; }
2057 DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
2058 StringRef getName() const { return getStringOperand(2); }
2059
2060 Metadata *getRawScope() const { return getOperand(1); }
2061 MDString *getRawName() const { return getOperandAs<MDString>(2); }
2062
2063 static bool classof(const Metadata *MD) {
2064 return MD->getMetadataID() == DINamespaceKind;
2065 }
2066};
2067
2068/// A (clang) module that has been imported by the compile unit.
2069///
2070class DIModule : public DIScope {
2071 friend class LLVMContextImpl;
2072 friend class MDNode;
2073
2074 DIModule(LLVMContext &Context, StorageType Storage, ArrayRef<Metadata *> Ops)
2075 : DIScope(Context, DIModuleKind, Storage, dwarf::DW_TAG_module, Ops) {}
2076 ~DIModule() = default;
2077
2078 static DIModule *getImpl(LLVMContext &Context, DIScope *Scope,
2079 StringRef Name, StringRef ConfigurationMacros,
2080 StringRef IncludePath, StringRef ISysRoot,
2081 StorageType Storage, bool ShouldCreate = true) {
2082 return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
2083 getCanonicalMDString(Context, ConfigurationMacros),
2084 getCanonicalMDString(Context, IncludePath),
2085 getCanonicalMDString(Context, ISysRoot),
2086 Storage, ShouldCreate);
2087 }
2088 static DIModule *getImpl(LLVMContext &Context, Metadata *Scope,
2089 MDString *Name, MDString *ConfigurationMacros,
2090 MDString *IncludePath, MDString *ISysRoot,
2091 StorageType Storage, bool ShouldCreate = true);
2092
2093 TempDIModule cloneImpl() const {
2094 return getTemporary(getContext(), getScope(), getName(),
2095 getConfigurationMacros(), getIncludePath(),
2096 getISysRoot());
2097 }
2098
2099public:
2100 DEFINE_MDNODE_GET(DIModule, (DIScope *Scope, StringRef Name,
2101 StringRef ConfigurationMacros, StringRef IncludePath,
2102 StringRef ISysRoot),
2103 (Scope, Name, ConfigurationMacros, IncludePath, ISysRoot))
2104 DEFINE_MDNODE_GET(DIModule,
2105 (Metadata *Scope, MDString *Name, MDString *ConfigurationMacros,
2106 MDString *IncludePath, MDString *ISysRoot),
2107 (Scope, Name, ConfigurationMacros, IncludePath, ISysRoot))
2108
2109 TempDIModule clone() const { return cloneImpl(); }
2110
2111 DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
2112 StringRef getName() const { return getStringOperand(1); }
2113 StringRef getConfigurationMacros() const { return getStringOperand(2); }
2114 StringRef getIncludePath() const { return getStringOperand(3); }
2115 StringRef getISysRoot() const { return getStringOperand(4); }
2116
2117 Metadata *getRawScope() const { return getOperand(0); }
2118 MDString *getRawName() const { return getOperandAs<MDString>(1); }
2119 MDString *getRawConfigurationMacros() const { return getOperandAs<MDString>(2); }
2120 MDString *getRawIncludePath() const { return getOperandAs<MDString>(3); }
2121 MDString *getRawISysRoot() const { return getOperandAs<MDString>(4); }
2122
2123 static bool classof(const Metadata *MD) {
2124 return MD->getMetadataID() == DIModuleKind;
2125 }
2126};
2127
2128/// Base class for template parameters.
2129class DITemplateParameter : public DINode {
2130protected:
2131 DITemplateParameter(LLVMContext &Context, unsigned ID, StorageType Storage,
2132 unsigned Tag, ArrayRef<Metadata *> Ops)
2133 : DINode(Context, ID, Storage, Tag, Ops) {}
2134 ~DITemplateParameter() = default;
2135
2136public:
2137 StringRef getName() const { return getStringOperand(0); }
Andrew Walbran3d2c1972020-04-07 12:24:26 +01002138 DIType *getType() const { return cast_or_null<DIType>(getRawType()); }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002139
2140 MDString *getRawName() const { return getOperandAs<MDString>(0); }
2141 Metadata *getRawType() const { return getOperand(1); }
2142
2143 static bool classof(const Metadata *MD) {
2144 return MD->getMetadataID() == DITemplateTypeParameterKind ||
2145 MD->getMetadataID() == DITemplateValueParameterKind;
2146 }
2147};
2148
2149class DITemplateTypeParameter : public DITemplateParameter {
2150 friend class LLVMContextImpl;
2151 friend class MDNode;
2152
2153 DITemplateTypeParameter(LLVMContext &Context, StorageType Storage,
2154 ArrayRef<Metadata *> Ops)
2155 : DITemplateParameter(Context, DITemplateTypeParameterKind, Storage,
2156 dwarf::DW_TAG_template_type_parameter, Ops) {}
2157 ~DITemplateTypeParameter() = default;
2158
2159 static DITemplateTypeParameter *getImpl(LLVMContext &Context, StringRef Name,
Andrew Walbran3d2c1972020-04-07 12:24:26 +01002160 DIType *Type, StorageType Storage,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002161 bool ShouldCreate = true) {
2162 return getImpl(Context, getCanonicalMDString(Context, Name), Type, Storage,
2163 ShouldCreate);
2164 }
2165 static DITemplateTypeParameter *getImpl(LLVMContext &Context, MDString *Name,
2166 Metadata *Type, StorageType Storage,
2167 bool ShouldCreate = true);
2168
2169 TempDITemplateTypeParameter cloneImpl() const {
2170 return getTemporary(getContext(), getName(), getType());
2171 }
2172
2173public:
Andrew Walbran3d2c1972020-04-07 12:24:26 +01002174 DEFINE_MDNODE_GET(DITemplateTypeParameter, (StringRef Name, DIType *Type),
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002175 (Name, Type))
2176 DEFINE_MDNODE_GET(DITemplateTypeParameter, (MDString * Name, Metadata *Type),
2177 (Name, Type))
2178
2179 TempDITemplateTypeParameter clone() const { return cloneImpl(); }
2180
2181 static bool classof(const Metadata *MD) {
2182 return MD->getMetadataID() == DITemplateTypeParameterKind;
2183 }
2184};
2185
2186class DITemplateValueParameter : public DITemplateParameter {
2187 friend class LLVMContextImpl;
2188 friend class MDNode;
2189
2190 DITemplateValueParameter(LLVMContext &Context, StorageType Storage,
2191 unsigned Tag, ArrayRef<Metadata *> Ops)
2192 : DITemplateParameter(Context, DITemplateValueParameterKind, Storage, Tag,
2193 Ops) {}
2194 ~DITemplateValueParameter() = default;
2195
2196 static DITemplateValueParameter *getImpl(LLVMContext &Context, unsigned Tag,
Andrew Walbran3d2c1972020-04-07 12:24:26 +01002197 StringRef Name, DIType *Type,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002198 Metadata *Value, StorageType Storage,
2199 bool ShouldCreate = true) {
2200 return getImpl(Context, Tag, getCanonicalMDString(Context, Name), Type,
2201 Value, Storage, ShouldCreate);
2202 }
2203 static DITemplateValueParameter *getImpl(LLVMContext &Context, unsigned Tag,
2204 MDString *Name, Metadata *Type,
2205 Metadata *Value, StorageType Storage,
2206 bool ShouldCreate = true);
2207
2208 TempDITemplateValueParameter cloneImpl() const {
2209 return getTemporary(getContext(), getTag(), getName(), getType(),
2210 getValue());
2211 }
2212
2213public:
Andrew Walbran3d2c1972020-04-07 12:24:26 +01002214 DEFINE_MDNODE_GET(DITemplateValueParameter,
2215 (unsigned Tag, StringRef Name, DIType *Type,
2216 Metadata *Value),
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002217 (Tag, Name, Type, Value))
2218 DEFINE_MDNODE_GET(DITemplateValueParameter, (unsigned Tag, MDString *Name,
2219 Metadata *Type, Metadata *Value),
2220 (Tag, Name, Type, Value))
2221
2222 TempDITemplateValueParameter clone() const { return cloneImpl(); }
2223
2224 Metadata *getValue() const { return getOperand(2); }
2225
2226 static bool classof(const Metadata *MD) {
2227 return MD->getMetadataID() == DITemplateValueParameterKind;
2228 }
2229};
2230
2231/// Base class for variables.
2232class DIVariable : public DINode {
2233 unsigned Line;
2234 uint32_t AlignInBits;
2235
2236protected:
2237 DIVariable(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Line,
2238 ArrayRef<Metadata *> Ops, uint32_t AlignInBits = 0)
2239 : DINode(C, ID, Storage, dwarf::DW_TAG_variable, Ops), Line(Line),
2240 AlignInBits(AlignInBits) {}
2241 ~DIVariable() = default;
2242
2243public:
2244 unsigned getLine() const { return Line; }
2245 DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
2246 StringRef getName() const { return getStringOperand(1); }
2247 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
Andrew Walbran3d2c1972020-04-07 12:24:26 +01002248 DIType *getType() const { return cast_or_null<DIType>(getRawType()); }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002249 uint32_t getAlignInBits() const { return AlignInBits; }
2250 uint32_t getAlignInBytes() const { return getAlignInBits() / CHAR_BIT; }
2251 /// Determines the size of the variable's type.
2252 Optional<uint64_t> getSizeInBits() const;
2253
Andrew Scullcdfcccc2018-10-05 20:58:37 +01002254 /// Return the signedness of this variable's type, or None if this type is
2255 /// neither signed nor unsigned.
2256 Optional<DIBasicType::Signedness> getSignedness() const {
Andrew Walbran3d2c1972020-04-07 12:24:26 +01002257 if (auto *BT = dyn_cast<DIBasicType>(getType()))
Andrew Scullcdfcccc2018-10-05 20:58:37 +01002258 return BT->getSignedness();
2259 return None;
2260 }
2261
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002262 StringRef getFilename() const {
2263 if (auto *F = getFile())
2264 return F->getFilename();
2265 return "";
2266 }
2267
2268 StringRef getDirectory() const {
2269 if (auto *F = getFile())
2270 return F->getDirectory();
2271 return "";
2272 }
2273
2274 Optional<StringRef> getSource() const {
2275 if (auto *F = getFile())
2276 return F->getSource();
2277 return None;
2278 }
2279
2280 Metadata *getRawScope() const { return getOperand(0); }
2281 MDString *getRawName() const { return getOperandAs<MDString>(1); }
2282 Metadata *getRawFile() const { return getOperand(2); }
2283 Metadata *getRawType() const { return getOperand(3); }
2284
2285 static bool classof(const Metadata *MD) {
2286 return MD->getMetadataID() == DILocalVariableKind ||
2287 MD->getMetadataID() == DIGlobalVariableKind;
2288 }
2289};
2290
2291/// DWARF expression.
2292///
2293/// This is (almost) a DWARF expression that modifies the location of a
2294/// variable, or the location of a single piece of a variable, or (when using
2295/// DW_OP_stack_value) is the constant variable value.
2296///
2297/// TODO: Co-allocate the expression elements.
2298/// TODO: Separate from MDNode, or otherwise drop Distinct and Temporary
2299/// storage types.
2300class DIExpression : public MDNode {
2301 friend class LLVMContextImpl;
2302 friend class MDNode;
2303
2304 std::vector<uint64_t> Elements;
2305
2306 DIExpression(LLVMContext &C, StorageType Storage, ArrayRef<uint64_t> Elements)
2307 : MDNode(C, DIExpressionKind, Storage, None),
2308 Elements(Elements.begin(), Elements.end()) {}
2309 ~DIExpression() = default;
2310
2311 static DIExpression *getImpl(LLVMContext &Context,
2312 ArrayRef<uint64_t> Elements, StorageType Storage,
2313 bool ShouldCreate = true);
2314
2315 TempDIExpression cloneImpl() const {
2316 return getTemporary(getContext(), getElements());
2317 }
2318
2319public:
2320 DEFINE_MDNODE_GET(DIExpression, (ArrayRef<uint64_t> Elements), (Elements))
2321
2322 TempDIExpression clone() const { return cloneImpl(); }
2323
2324 ArrayRef<uint64_t> getElements() const { return Elements; }
2325
2326 unsigned getNumElements() const { return Elements.size(); }
2327
2328 uint64_t getElement(unsigned I) const {
2329 assert(I < Elements.size() && "Index out of range");
2330 return Elements[I];
2331 }
2332
2333 /// Determine whether this represents a standalone constant value.
2334 bool isConstant() const;
2335
2336 using element_iterator = ArrayRef<uint64_t>::iterator;
2337
2338 element_iterator elements_begin() const { return getElements().begin(); }
2339 element_iterator elements_end() const { return getElements().end(); }
2340
2341 /// A lightweight wrapper around an expression operand.
2342 ///
2343 /// TODO: Store arguments directly and change \a DIExpression to store a
2344 /// range of these.
2345 class ExprOperand {
2346 const uint64_t *Op = nullptr;
2347
2348 public:
2349 ExprOperand() = default;
2350 explicit ExprOperand(const uint64_t *Op) : Op(Op) {}
2351
2352 const uint64_t *get() const { return Op; }
2353
2354 /// Get the operand code.
2355 uint64_t getOp() const { return *Op; }
2356
2357 /// Get an argument to the operand.
2358 ///
2359 /// Never returns the operand itself.
2360 uint64_t getArg(unsigned I) const { return Op[I + 1]; }
2361
2362 unsigned getNumArgs() const { return getSize() - 1; }
2363
2364 /// Return the size of the operand.
2365 ///
2366 /// Return the number of elements in the operand (1 + args).
2367 unsigned getSize() const;
Andrew Scullcdfcccc2018-10-05 20:58:37 +01002368
2369 /// Append the elements of this operand to \p V.
2370 void appendToVector(SmallVectorImpl<uint64_t> &V) const {
2371 V.append(get(), get() + getSize());
2372 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002373 };
2374
2375 /// An iterator for expression operands.
2376 class expr_op_iterator
2377 : public std::iterator<std::input_iterator_tag, ExprOperand> {
2378 ExprOperand Op;
2379
2380 public:
2381 expr_op_iterator() = default;
2382 explicit expr_op_iterator(element_iterator I) : Op(I) {}
2383
2384 element_iterator getBase() const { return Op.get(); }
2385 const ExprOperand &operator*() const { return Op; }
2386 const ExprOperand *operator->() const { return &Op; }
2387
2388 expr_op_iterator &operator++() {
2389 increment();
2390 return *this;
2391 }
2392 expr_op_iterator operator++(int) {
2393 expr_op_iterator T(*this);
2394 increment();
2395 return T;
2396 }
2397
2398 /// Get the next iterator.
2399 ///
2400 /// \a std::next() doesn't work because this is technically an
2401 /// input_iterator, but it's a perfectly valid operation. This is an
2402 /// accessor to provide the same functionality.
2403 expr_op_iterator getNext() const { return ++expr_op_iterator(*this); }
2404
2405 bool operator==(const expr_op_iterator &X) const {
2406 return getBase() == X.getBase();
2407 }
2408 bool operator!=(const expr_op_iterator &X) const {
2409 return getBase() != X.getBase();
2410 }
2411
2412 private:
2413 void increment() { Op = ExprOperand(getBase() + Op.getSize()); }
2414 };
2415
2416 /// Visit the elements via ExprOperand wrappers.
2417 ///
2418 /// These range iterators visit elements through \a ExprOperand wrappers.
2419 /// This is not guaranteed to be a valid range unless \a isValid() gives \c
2420 /// true.
2421 ///
2422 /// \pre \a isValid() gives \c true.
2423 /// @{
2424 expr_op_iterator expr_op_begin() const {
2425 return expr_op_iterator(elements_begin());
2426 }
2427 expr_op_iterator expr_op_end() const {
2428 return expr_op_iterator(elements_end());
2429 }
2430 iterator_range<expr_op_iterator> expr_ops() const {
2431 return {expr_op_begin(), expr_op_end()};
2432 }
2433 /// @}
2434
2435 bool isValid() const;
2436
2437 static bool classof(const Metadata *MD) {
2438 return MD->getMetadataID() == DIExpressionKind;
2439 }
2440
2441 /// Return whether the first element a DW_OP_deref.
2442 bool startsWithDeref() const {
2443 return getNumElements() > 0 && getElement(0) == dwarf::DW_OP_deref;
2444 }
2445
2446 /// Holds the characteristics of one fragment of a larger variable.
2447 struct FragmentInfo {
2448 uint64_t SizeInBits;
2449 uint64_t OffsetInBits;
2450 };
2451
2452 /// Retrieve the details of this fragment expression.
2453 static Optional<FragmentInfo> getFragmentInfo(expr_op_iterator Start,
2454 expr_op_iterator End);
2455
2456 /// Retrieve the details of this fragment expression.
2457 Optional<FragmentInfo> getFragmentInfo() const {
2458 return getFragmentInfo(expr_op_begin(), expr_op_end());
2459 }
2460
2461 /// Return whether this is a piece of an aggregate variable.
2462 bool isFragment() const { return getFragmentInfo().hasValue(); }
2463
Andrew Walbran3d2c1972020-04-07 12:24:26 +01002464 /// Return whether this is an implicit location description.
2465 bool isImplicit() const;
2466
2467 /// Return whether the location is computed on the expression stack, meaning
2468 /// it cannot be a simple register location.
2469 bool isComplex() const;
2470
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002471 /// Append \p Ops with operations to apply the \p Offset.
2472 static void appendOffset(SmallVectorImpl<uint64_t> &Ops, int64_t Offset);
2473
2474 /// If this is a constant offset, extract it. If there is no expression,
2475 /// return true with an offset of zero.
2476 bool extractIfOffset(int64_t &Offset) const;
2477
Andrew Walbran16937d02019-10-22 13:54:20 +01002478 /// Checks if the last 4 elements of the expression are DW_OP_constu <DWARF
2479 /// Address Space> DW_OP_swap DW_OP_xderef and extracts the <DWARF Address
2480 /// Space>.
2481 static const DIExpression *extractAddressClass(const DIExpression *Expr,
2482 unsigned &AddrClass);
2483
Andrew Walbran3d2c1972020-04-07 12:24:26 +01002484 /// Used for DIExpression::prepend.
2485 enum PrependOps : uint8_t {
2486 ApplyOffset = 0,
2487 DerefBefore = 1 << 0,
2488 DerefAfter = 1 << 1,
2489 StackValue = 1 << 2,
2490 EntryValue = 1 << 3
2491 };
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002492
2493 /// Prepend \p DIExpr with a deref and offset operation and optionally turn it
Andrew Walbran3d2c1972020-04-07 12:24:26 +01002494 /// into a stack value or/and an entry value.
2495 static DIExpression *prepend(const DIExpression *Expr, uint8_t Flags,
2496 int64_t Offset = 0);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002497
2498 /// Prepend \p DIExpr with the given opcodes and optionally turn it into a
2499 /// stack value.
Andrew Scullcdfcccc2018-10-05 20:58:37 +01002500 static DIExpression *prependOpcodes(const DIExpression *Expr,
2501 SmallVectorImpl<uint64_t> &Ops,
Andrew Walbran3d2c1972020-04-07 12:24:26 +01002502 bool StackValue = false,
2503 bool EntryValue = false);
Andrew Scullcdfcccc2018-10-05 20:58:37 +01002504
2505 /// Append the opcodes \p Ops to \p DIExpr. Unlike \ref appendToStack, the
2506 /// returned expression is a stack value only if \p DIExpr is a stack value.
2507 /// If \p DIExpr describes a fragment, the returned expression will describe
2508 /// the same fragment.
2509 static DIExpression *append(const DIExpression *Expr, ArrayRef<uint64_t> Ops);
2510
2511 /// Convert \p DIExpr into a stack value if it isn't one already by appending
2512 /// DW_OP_deref if needed, and appending \p Ops to the resulting expression.
2513 /// If \p DIExpr describes a fragment, the returned expression will describe
2514 /// the same fragment.
2515 static DIExpression *appendToStack(const DIExpression *Expr,
2516 ArrayRef<uint64_t> Ops);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002517
2518 /// Create a DIExpression to describe one part of an aggregate variable that
2519 /// is fragmented across multiple Values. The DW_OP_LLVM_fragment operation
2520 /// will be appended to the elements of \c Expr. If \c Expr already contains
2521 /// a \c DW_OP_LLVM_fragment \c OffsetInBits is interpreted as an offset
2522 /// into the existing fragment.
2523 ///
2524 /// \param OffsetInBits Offset of the piece in bits.
2525 /// \param SizeInBits Size of the piece in bits.
2526 /// \return Creating a fragment expression may fail if \c Expr
2527 /// contains arithmetic operations that would be truncated.
2528 static Optional<DIExpression *>
2529 createFragmentExpression(const DIExpression *Expr, unsigned OffsetInBits,
2530 unsigned SizeInBits);
2531
Andrew Walbran3d2c1972020-04-07 12:24:26 +01002532 /// Determine the relative position of the fragments passed in.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002533 /// Returns -1 if this is entirely before Other, 0 if this and Other overlap,
2534 /// 1 if this is entirely after Other.
Andrew Walbran3d2c1972020-04-07 12:24:26 +01002535 static int fragmentCmp(const FragmentInfo &A, const FragmentInfo &B) {
2536 uint64_t l1 = A.OffsetInBits;
2537 uint64_t l2 = B.OffsetInBits;
2538 uint64_t r1 = l1 + A.SizeInBits;
2539 uint64_t r2 = l2 + B.SizeInBits;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002540 if (r1 <= l2)
2541 return -1;
2542 else if (r2 <= l1)
2543 return 1;
2544 else
2545 return 0;
2546 }
2547
Andrew Walbran3d2c1972020-04-07 12:24:26 +01002548 /// Check if fragments overlap between a pair of FragmentInfos.
2549 static bool fragmentsOverlap(const FragmentInfo &A, const FragmentInfo &B) {
2550 return fragmentCmp(A, B) == 0;
2551 }
2552
2553 /// Determine the relative position of the fragments described by this
2554 /// DIExpression and \p Other. Calls static fragmentCmp implementation.
2555 int fragmentCmp(const DIExpression *Other) const {
2556 auto Fragment1 = *getFragmentInfo();
2557 auto Fragment2 = *Other->getFragmentInfo();
2558 return fragmentCmp(Fragment1, Fragment2);
2559 }
2560
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002561 /// Check if fragments overlap between this DIExpression and \p Other.
2562 bool fragmentsOverlap(const DIExpression *Other) const {
2563 if (!isFragment() || !Other->isFragment())
2564 return true;
2565 return fragmentCmp(Other) == 0;
2566 }
Andrew Walbran3d2c1972020-04-07 12:24:26 +01002567
2568 /// Check if the expression consists of exactly one entry value operand.
2569 /// (This is the only configuration of entry values that is supported.)
2570 bool isEntryValue() const {
2571 return getNumElements() > 0 &&
2572 getElement(0) == dwarf::DW_OP_entry_value;
2573 }
2574};
2575
2576inline bool operator==(const DIExpression::FragmentInfo &A,
2577 const DIExpression::FragmentInfo &B) {
2578 return std::tie(A.SizeInBits, A.OffsetInBits) ==
2579 std::tie(B.SizeInBits, B.OffsetInBits);
2580}
2581
2582inline bool operator<(const DIExpression::FragmentInfo &A,
2583 const DIExpression::FragmentInfo &B) {
2584 return std::tie(A.SizeInBits, A.OffsetInBits) <
2585 std::tie(B.SizeInBits, B.OffsetInBits);
2586}
2587
2588template <> struct DenseMapInfo<DIExpression::FragmentInfo> {
2589 using FragInfo = DIExpression::FragmentInfo;
2590 static const uint64_t MaxVal = std::numeric_limits<uint64_t>::max();
2591
2592 static inline FragInfo getEmptyKey() { return {MaxVal, MaxVal}; }
2593
2594 static inline FragInfo getTombstoneKey() { return {MaxVal - 1, MaxVal - 1}; }
2595
2596 static unsigned getHashValue(const FragInfo &Frag) {
2597 return (Frag.SizeInBits & 0xffff) << 16 | (Frag.OffsetInBits & 0xffff);
2598 }
2599
2600 static bool isEqual(const FragInfo &A, const FragInfo &B) { return A == B; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002601};
2602
2603/// Global variables.
2604///
2605/// TODO: Remove DisplayName. It's always equal to Name.
2606class DIGlobalVariable : public DIVariable {
2607 friend class LLVMContextImpl;
2608 friend class MDNode;
2609
2610 bool IsLocalToUnit;
2611 bool IsDefinition;
2612
2613 DIGlobalVariable(LLVMContext &C, StorageType Storage, unsigned Line,
2614 bool IsLocalToUnit, bool IsDefinition, uint32_t AlignInBits,
2615 ArrayRef<Metadata *> Ops)
2616 : DIVariable(C, DIGlobalVariableKind, Storage, Line, Ops, AlignInBits),
2617 IsLocalToUnit(IsLocalToUnit), IsDefinition(IsDefinition) {}
2618 ~DIGlobalVariable() = default;
2619
Andrew Scull0372a572018-11-16 15:47:06 +00002620 static DIGlobalVariable *
2621 getImpl(LLVMContext &Context, DIScope *Scope, StringRef Name,
Andrew Walbran3d2c1972020-04-07 12:24:26 +01002622 StringRef LinkageName, DIFile *File, unsigned Line, DIType *Type,
Andrew Scull0372a572018-11-16 15:47:06 +00002623 bool IsLocalToUnit, bool IsDefinition,
2624 DIDerivedType *StaticDataMemberDeclaration, MDTuple *TemplateParams,
2625 uint32_t AlignInBits, StorageType Storage, bool ShouldCreate = true) {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002626 return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
2627 getCanonicalMDString(Context, LinkageName), File, Line, Type,
2628 IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration,
Andrew Scull0372a572018-11-16 15:47:06 +00002629 cast_or_null<Metadata>(TemplateParams), AlignInBits, Storage,
2630 ShouldCreate);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002631 }
2632 static DIGlobalVariable *
2633 getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
2634 MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type,
2635 bool IsLocalToUnit, bool IsDefinition,
Andrew Scull0372a572018-11-16 15:47:06 +00002636 Metadata *StaticDataMemberDeclaration, Metadata *TemplateParams,
2637 uint32_t AlignInBits, StorageType Storage, bool ShouldCreate = true);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002638
2639 TempDIGlobalVariable cloneImpl() const {
2640 return getTemporary(getContext(), getScope(), getName(), getLinkageName(),
2641 getFile(), getLine(), getType(), isLocalToUnit(),
2642 isDefinition(), getStaticDataMemberDeclaration(),
Andrew Scull0372a572018-11-16 15:47:06 +00002643 getTemplateParams(), getAlignInBits());
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002644 }
2645
2646public:
2647 DEFINE_MDNODE_GET(DIGlobalVariable,
2648 (DIScope * Scope, StringRef Name, StringRef LinkageName,
Andrew Walbran3d2c1972020-04-07 12:24:26 +01002649 DIFile *File, unsigned Line, DIType *Type,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002650 bool IsLocalToUnit, bool IsDefinition,
2651 DIDerivedType *StaticDataMemberDeclaration,
Andrew Scull0372a572018-11-16 15:47:06 +00002652 MDTuple *TemplateParams, uint32_t AlignInBits),
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002653 (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
Andrew Scull0372a572018-11-16 15:47:06 +00002654 IsDefinition, StaticDataMemberDeclaration, TemplateParams,
2655 AlignInBits))
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002656 DEFINE_MDNODE_GET(DIGlobalVariable,
2657 (Metadata * Scope, MDString *Name, MDString *LinkageName,
2658 Metadata *File, unsigned Line, Metadata *Type,
2659 bool IsLocalToUnit, bool IsDefinition,
2660 Metadata *StaticDataMemberDeclaration,
Andrew Scull0372a572018-11-16 15:47:06 +00002661 Metadata *TemplateParams, uint32_t AlignInBits),
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002662 (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
Andrew Scull0372a572018-11-16 15:47:06 +00002663 IsDefinition, StaticDataMemberDeclaration, TemplateParams,
2664 AlignInBits))
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002665
2666 TempDIGlobalVariable clone() const { return cloneImpl(); }
2667
2668 bool isLocalToUnit() const { return IsLocalToUnit; }
2669 bool isDefinition() const { return IsDefinition; }
2670 StringRef getDisplayName() const { return getStringOperand(4); }
2671 StringRef getLinkageName() const { return getStringOperand(5); }
2672 DIDerivedType *getStaticDataMemberDeclaration() const {
2673 return cast_or_null<DIDerivedType>(getRawStaticDataMemberDeclaration());
2674 }
2675
2676 MDString *getRawLinkageName() const { return getOperandAs<MDString>(5); }
2677 Metadata *getRawStaticDataMemberDeclaration() const { return getOperand(6); }
Andrew Scull0372a572018-11-16 15:47:06 +00002678 Metadata *getRawTemplateParams() const { return getOperand(7); }
2679 MDTuple *getTemplateParams() const { return getOperandAs<MDTuple>(7); }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002680
2681 static bool classof(const Metadata *MD) {
2682 return MD->getMetadataID() == DIGlobalVariableKind;
2683 }
2684};
2685
Andrew Walbran3d2c1972020-04-07 12:24:26 +01002686class DICommonBlock : public DIScope {
2687 unsigned LineNo;
2688
2689 friend class LLVMContextImpl;
2690 friend class MDNode;
2691
2692 DICommonBlock(LLVMContext &Context, StorageType Storage, unsigned LineNo,
2693 ArrayRef<Metadata *> Ops)
2694 : DIScope(Context, DICommonBlockKind, Storage, dwarf::DW_TAG_common_block,
2695 Ops), LineNo(LineNo) {}
2696
2697 static DICommonBlock *getImpl(LLVMContext &Context, DIScope *Scope,
2698 DIGlobalVariable *Decl, StringRef Name,
2699 DIFile *File, unsigned LineNo,
2700 StorageType Storage,
2701 bool ShouldCreate = true) {
2702 return getImpl(Context, Scope, Decl, getCanonicalMDString(Context, Name),
2703 File, LineNo, Storage, ShouldCreate);
2704 }
2705 static DICommonBlock *getImpl(LLVMContext &Context, Metadata *Scope,
2706 Metadata *Decl, MDString *Name, Metadata *File,
2707 unsigned LineNo,
2708 StorageType Storage, bool ShouldCreate = true);
2709
2710 TempDICommonBlock cloneImpl() const {
2711 return getTemporary(getContext(), getScope(), getDecl(), getName(),
2712 getFile(), getLineNo());
2713 }
2714
2715public:
2716 DEFINE_MDNODE_GET(DICommonBlock,
2717 (DIScope *Scope, DIGlobalVariable *Decl, StringRef Name,
2718 DIFile *File, unsigned LineNo),
2719 (Scope, Decl, Name, File, LineNo))
2720 DEFINE_MDNODE_GET(DICommonBlock,
2721 (Metadata *Scope, Metadata *Decl, MDString *Name,
2722 Metadata *File, unsigned LineNo),
2723 (Scope, Decl, Name, File, LineNo))
2724
2725 TempDICommonBlock clone() const { return cloneImpl(); }
2726
2727 DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
2728 DIGlobalVariable *getDecl() const {
2729 return cast_or_null<DIGlobalVariable>(getRawDecl());
2730 }
2731 StringRef getName() const { return getStringOperand(2); }
2732 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
2733 unsigned getLineNo() const { return LineNo; }
2734
2735 Metadata *getRawScope() const { return getOperand(0); }
2736 Metadata *getRawDecl() const { return getOperand(1); }
2737 MDString *getRawName() const { return getOperandAs<MDString>(2); }
2738 Metadata *getRawFile() const { return getOperand(3); }
2739
2740 static bool classof(const Metadata *MD) {
2741 return MD->getMetadataID() == DICommonBlockKind;
2742 }
2743};
2744
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002745/// Local variable.
2746///
2747/// TODO: Split up flags.
2748class DILocalVariable : public DIVariable {
2749 friend class LLVMContextImpl;
2750 friend class MDNode;
2751
2752 unsigned Arg : 16;
2753 DIFlags Flags;
2754
2755 DILocalVariable(LLVMContext &C, StorageType Storage, unsigned Line,
2756 unsigned Arg, DIFlags Flags, uint32_t AlignInBits,
2757 ArrayRef<Metadata *> Ops)
2758 : DIVariable(C, DILocalVariableKind, Storage, Line, Ops, AlignInBits),
2759 Arg(Arg), Flags(Flags) {
2760 assert(Arg < (1 << 16) && "DILocalVariable: Arg out of range");
2761 }
2762 ~DILocalVariable() = default;
2763
2764 static DILocalVariable *getImpl(LLVMContext &Context, DIScope *Scope,
2765 StringRef Name, DIFile *File, unsigned Line,
Andrew Walbran3d2c1972020-04-07 12:24:26 +01002766 DIType *Type, unsigned Arg, DIFlags Flags,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002767 uint32_t AlignInBits, StorageType Storage,
2768 bool ShouldCreate = true) {
2769 return getImpl(Context, Scope, getCanonicalMDString(Context, Name), File,
2770 Line, Type, Arg, Flags, AlignInBits, Storage, ShouldCreate);
2771 }
2772 static DILocalVariable *getImpl(LLVMContext &Context, Metadata *Scope,
2773 MDString *Name, Metadata *File, unsigned Line,
2774 Metadata *Type, unsigned Arg, DIFlags Flags,
2775 uint32_t AlignInBits, StorageType Storage,
2776 bool ShouldCreate = true);
2777
2778 TempDILocalVariable cloneImpl() const {
2779 return getTemporary(getContext(), getScope(), getName(), getFile(),
2780 getLine(), getType(), getArg(), getFlags(),
2781 getAlignInBits());
2782 }
2783
2784public:
2785 DEFINE_MDNODE_GET(DILocalVariable,
2786 (DILocalScope * Scope, StringRef Name, DIFile *File,
Andrew Walbran3d2c1972020-04-07 12:24:26 +01002787 unsigned Line, DIType *Type, unsigned Arg, DIFlags Flags,
2788 uint32_t AlignInBits),
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002789 (Scope, Name, File, Line, Type, Arg, Flags, AlignInBits))
2790 DEFINE_MDNODE_GET(DILocalVariable,
2791 (Metadata * Scope, MDString *Name, Metadata *File,
2792 unsigned Line, Metadata *Type, unsigned Arg,
2793 DIFlags Flags, uint32_t AlignInBits),
2794 (Scope, Name, File, Line, Type, Arg, Flags, AlignInBits))
2795
2796 TempDILocalVariable clone() const { return cloneImpl(); }
2797
2798 /// Get the local scope for this variable.
2799 ///
2800 /// Variables must be defined in a local scope.
2801 DILocalScope *getScope() const {
2802 return cast<DILocalScope>(DIVariable::getScope());
2803 }
2804
2805 bool isParameter() const { return Arg; }
2806 unsigned getArg() const { return Arg; }
2807 DIFlags getFlags() const { return Flags; }
2808
2809 bool isArtificial() const { return getFlags() & FlagArtificial; }
2810 bool isObjectPointer() const { return getFlags() & FlagObjectPointer; }
2811
Andrew Walbran3d2c1972020-04-07 12:24:26 +01002812 /// Check that an argument is unmodified.
2813 bool isNotModified() const { return getFlags() & FlagArgumentNotModified; }
2814 /// Set the flag if an argument is unmodified.
2815 void setIsNotModified() { Flags |= FlagArgumentNotModified; }
2816
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002817 /// Check that a location is valid for this variable.
2818 ///
2819 /// Check that \c DL exists, is in the same subprogram, and has the same
2820 /// inlined-at location as \c this. (Otherwise, it's not a valid attachment
2821 /// to a \a DbgInfoIntrinsic.)
2822 bool isValidLocationForIntrinsic(const DILocation *DL) const {
2823 return DL && getScope()->getSubprogram() == DL->getScope()->getSubprogram();
2824 }
2825
2826 static bool classof(const Metadata *MD) {
2827 return MD->getMetadataID() == DILocalVariableKind;
2828 }
2829};
2830
Andrew Scullcdfcccc2018-10-05 20:58:37 +01002831/// Label.
2832///
2833class DILabel : public DINode {
2834 friend class LLVMContextImpl;
2835 friend class MDNode;
2836
2837 unsigned Line;
2838
2839 DILabel(LLVMContext &C, StorageType Storage, unsigned Line,
2840 ArrayRef<Metadata *> Ops)
2841 : DINode(C, DILabelKind, Storage, dwarf::DW_TAG_label, Ops), Line(Line) {}
2842 ~DILabel() = default;
2843
2844 static DILabel *getImpl(LLVMContext &Context, DIScope *Scope,
2845 StringRef Name, DIFile *File, unsigned Line,
2846 StorageType Storage,
2847 bool ShouldCreate = true) {
2848 return getImpl(Context, Scope, getCanonicalMDString(Context, Name), File,
2849 Line, Storage, ShouldCreate);
2850 }
2851 static DILabel *getImpl(LLVMContext &Context, Metadata *Scope,
2852 MDString *Name, Metadata *File, unsigned Line,
2853 StorageType Storage,
2854 bool ShouldCreate = true);
2855
2856 TempDILabel cloneImpl() const {
2857 return getTemporary(getContext(), getScope(), getName(), getFile(),
2858 getLine());
2859 }
2860
2861public:
2862 DEFINE_MDNODE_GET(DILabel,
2863 (DILocalScope * Scope, StringRef Name, DIFile *File,
2864 unsigned Line),
2865 (Scope, Name, File, Line))
2866 DEFINE_MDNODE_GET(DILabel,
2867 (Metadata * Scope, MDString *Name, Metadata *File,
2868 unsigned Line),
2869 (Scope, Name, File, Line))
2870
2871 TempDILabel clone() const { return cloneImpl(); }
2872
2873 /// Get the local scope for this label.
2874 ///
2875 /// Labels must be defined in a local scope.
2876 DILocalScope *getScope() const {
2877 return cast_or_null<DILocalScope>(getRawScope());
2878 }
2879 unsigned getLine() const { return Line; }
2880 StringRef getName() const { return getStringOperand(1); }
2881 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
2882
2883 Metadata *getRawScope() const { return getOperand(0); }
2884 MDString *getRawName() const { return getOperandAs<MDString>(1); }
2885 Metadata *getRawFile() const { return getOperand(2); }
2886
2887 /// Check that a location is valid for this label.
2888 ///
2889 /// Check that \c DL exists, is in the same subprogram, and has the same
2890 /// inlined-at location as \c this. (Otherwise, it's not a valid attachment
2891 /// to a \a DbgInfoIntrinsic.)
2892 bool isValidLocationForIntrinsic(const DILocation *DL) const {
2893 return DL && getScope()->getSubprogram() == DL->getScope()->getSubprogram();
2894 }
2895
2896 static bool classof(const Metadata *MD) {
2897 return MD->getMetadataID() == DILabelKind;
2898 }
2899};
2900
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002901class DIObjCProperty : public DINode {
2902 friend class LLVMContextImpl;
2903 friend class MDNode;
2904
2905 unsigned Line;
2906 unsigned Attributes;
2907
2908 DIObjCProperty(LLVMContext &C, StorageType Storage, unsigned Line,
2909 unsigned Attributes, ArrayRef<Metadata *> Ops)
2910 : DINode(C, DIObjCPropertyKind, Storage, dwarf::DW_TAG_APPLE_property,
2911 Ops),
2912 Line(Line), Attributes(Attributes) {}
2913 ~DIObjCProperty() = default;
2914
2915 static DIObjCProperty *
2916 getImpl(LLVMContext &Context, StringRef Name, DIFile *File, unsigned Line,
2917 StringRef GetterName, StringRef SetterName, unsigned Attributes,
Andrew Walbran3d2c1972020-04-07 12:24:26 +01002918 DIType *Type, StorageType Storage, bool ShouldCreate = true) {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002919 return getImpl(Context, getCanonicalMDString(Context, Name), File, Line,
2920 getCanonicalMDString(Context, GetterName),
2921 getCanonicalMDString(Context, SetterName), Attributes, Type,
2922 Storage, ShouldCreate);
2923 }
2924 static DIObjCProperty *getImpl(LLVMContext &Context, MDString *Name,
2925 Metadata *File, unsigned Line,
2926 MDString *GetterName, MDString *SetterName,
2927 unsigned Attributes, Metadata *Type,
2928 StorageType Storage, bool ShouldCreate = true);
2929
2930 TempDIObjCProperty cloneImpl() const {
2931 return getTemporary(getContext(), getName(), getFile(), getLine(),
2932 getGetterName(), getSetterName(), getAttributes(),
2933 getType());
2934 }
2935
2936public:
2937 DEFINE_MDNODE_GET(DIObjCProperty,
2938 (StringRef Name, DIFile *File, unsigned Line,
2939 StringRef GetterName, StringRef SetterName,
Andrew Walbran3d2c1972020-04-07 12:24:26 +01002940 unsigned Attributes, DIType *Type),
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002941 (Name, File, Line, GetterName, SetterName, Attributes,
2942 Type))
2943 DEFINE_MDNODE_GET(DIObjCProperty,
2944 (MDString * Name, Metadata *File, unsigned Line,
2945 MDString *GetterName, MDString *SetterName,
2946 unsigned Attributes, Metadata *Type),
2947 (Name, File, Line, GetterName, SetterName, Attributes,
2948 Type))
2949
2950 TempDIObjCProperty clone() const { return cloneImpl(); }
2951
2952 unsigned getLine() const { return Line; }
2953 unsigned getAttributes() const { return Attributes; }
2954 StringRef getName() const { return getStringOperand(0); }
2955 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
2956 StringRef getGetterName() const { return getStringOperand(2); }
2957 StringRef getSetterName() const { return getStringOperand(3); }
Andrew Walbran3d2c1972020-04-07 12:24:26 +01002958 DIType *getType() const { return cast_or_null<DIType>(getRawType()); }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002959
2960 StringRef getFilename() const {
2961 if (auto *F = getFile())
2962 return F->getFilename();
2963 return "";
2964 }
2965
2966 StringRef getDirectory() const {
2967 if (auto *F = getFile())
2968 return F->getDirectory();
2969 return "";
2970 }
2971
2972 Optional<StringRef> getSource() const {
2973 if (auto *F = getFile())
2974 return F->getSource();
2975 return None;
2976 }
2977
2978 MDString *getRawName() const { return getOperandAs<MDString>(0); }
2979 Metadata *getRawFile() const { return getOperand(1); }
2980 MDString *getRawGetterName() const { return getOperandAs<MDString>(2); }
2981 MDString *getRawSetterName() const { return getOperandAs<MDString>(3); }
2982 Metadata *getRawType() const { return getOperand(4); }
2983
2984 static bool classof(const Metadata *MD) {
2985 return MD->getMetadataID() == DIObjCPropertyKind;
2986 }
2987};
2988
2989/// An imported module (C++ using directive or similar).
2990class DIImportedEntity : public DINode {
2991 friend class LLVMContextImpl;
2992 friend class MDNode;
2993
2994 unsigned Line;
2995
2996 DIImportedEntity(LLVMContext &C, StorageType Storage, unsigned Tag,
2997 unsigned Line, ArrayRef<Metadata *> Ops)
2998 : DINode(C, DIImportedEntityKind, Storage, Tag, Ops), Line(Line) {}
2999 ~DIImportedEntity() = default;
3000
3001 static DIImportedEntity *getImpl(LLVMContext &Context, unsigned Tag,
Andrew Walbran3d2c1972020-04-07 12:24:26 +01003002 DIScope *Scope, DINode *Entity, DIFile *File,
3003 unsigned Line, StringRef Name,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01003004 StorageType Storage,
3005 bool ShouldCreate = true) {
3006 return getImpl(Context, Tag, Scope, Entity, File, Line,
3007 getCanonicalMDString(Context, Name), Storage, ShouldCreate);
3008 }
3009 static DIImportedEntity *getImpl(LLVMContext &Context, unsigned Tag,
3010 Metadata *Scope, Metadata *Entity,
3011 Metadata *File, unsigned Line,
3012 MDString *Name, StorageType Storage,
3013 bool ShouldCreate = true);
3014
3015 TempDIImportedEntity cloneImpl() const {
3016 return getTemporary(getContext(), getTag(), getScope(), getEntity(),
3017 getFile(), getLine(), getName());
3018 }
3019
3020public:
3021 DEFINE_MDNODE_GET(DIImportedEntity,
Andrew Walbran3d2c1972020-04-07 12:24:26 +01003022 (unsigned Tag, DIScope *Scope, DINode *Entity, DIFile *File,
3023 unsigned Line, StringRef Name = ""),
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01003024 (Tag, Scope, Entity, File, Line, Name))
3025 DEFINE_MDNODE_GET(DIImportedEntity,
3026 (unsigned Tag, Metadata *Scope, Metadata *Entity,
3027 Metadata *File, unsigned Line, MDString *Name),
3028 (Tag, Scope, Entity, File, Line, Name))
3029
3030 TempDIImportedEntity clone() const { return cloneImpl(); }
3031
3032 unsigned getLine() const { return Line; }
3033 DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
Andrew Walbran3d2c1972020-04-07 12:24:26 +01003034 DINode *getEntity() const { return cast_or_null<DINode>(getRawEntity()); }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01003035 StringRef getName() const { return getStringOperand(2); }
3036 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
3037
3038 Metadata *getRawScope() const { return getOperand(0); }
3039 Metadata *getRawEntity() const { return getOperand(1); }
3040 MDString *getRawName() const { return getOperandAs<MDString>(2); }
3041 Metadata *getRawFile() const { return getOperand(3); }
3042
3043 static bool classof(const Metadata *MD) {
3044 return MD->getMetadataID() == DIImportedEntityKind;
3045 }
3046};
3047
3048/// A pair of DIGlobalVariable and DIExpression.
3049class DIGlobalVariableExpression : public MDNode {
3050 friend class LLVMContextImpl;
3051 friend class MDNode;
3052
3053 DIGlobalVariableExpression(LLVMContext &C, StorageType Storage,
3054 ArrayRef<Metadata *> Ops)
3055 : MDNode(C, DIGlobalVariableExpressionKind, Storage, Ops) {}
3056 ~DIGlobalVariableExpression() = default;
3057
3058 static DIGlobalVariableExpression *
3059 getImpl(LLVMContext &Context, Metadata *Variable, Metadata *Expression,
3060 StorageType Storage, bool ShouldCreate = true);
3061
3062 TempDIGlobalVariableExpression cloneImpl() const {
3063 return getTemporary(getContext(), getVariable(), getExpression());
3064 }
3065
3066public:
3067 DEFINE_MDNODE_GET(DIGlobalVariableExpression,
3068 (Metadata * Variable, Metadata *Expression),
3069 (Variable, Expression))
3070
3071 TempDIGlobalVariableExpression clone() const { return cloneImpl(); }
3072
3073 Metadata *getRawVariable() const { return getOperand(0); }
3074
3075 DIGlobalVariable *getVariable() const {
3076 return cast_or_null<DIGlobalVariable>(getRawVariable());
3077 }
3078
3079 Metadata *getRawExpression() const { return getOperand(1); }
3080
3081 DIExpression *getExpression() const {
3082 return cast<DIExpression>(getRawExpression());
3083 }
3084
3085 static bool classof(const Metadata *MD) {
3086 return MD->getMetadataID() == DIGlobalVariableExpressionKind;
3087 }
3088};
3089
3090/// Macro Info DWARF-like metadata node.
3091///
3092/// A metadata node with a DWARF macro info (i.e., a constant named
3093/// \c DW_MACINFO_*, defined in llvm/BinaryFormat/Dwarf.h). Called \a
3094/// DIMacroNode
3095/// because it's potentially used for non-DWARF output.
3096class DIMacroNode : public MDNode {
3097 friend class LLVMContextImpl;
3098 friend class MDNode;
3099
3100protected:
3101 DIMacroNode(LLVMContext &C, unsigned ID, StorageType Storage, unsigned MIType,
3102 ArrayRef<Metadata *> Ops1, ArrayRef<Metadata *> Ops2 = None)
3103 : MDNode(C, ID, Storage, Ops1, Ops2) {
3104 assert(MIType < 1u << 16);
3105 SubclassData16 = MIType;
3106 }
3107 ~DIMacroNode() = default;
3108
3109 template <class Ty> Ty *getOperandAs(unsigned I) const {
3110 return cast_or_null<Ty>(getOperand(I));
3111 }
3112
3113 StringRef getStringOperand(unsigned I) const {
3114 if (auto *S = getOperandAs<MDString>(I))
3115 return S->getString();
3116 return StringRef();
3117 }
3118
3119 static MDString *getCanonicalMDString(LLVMContext &Context, StringRef S) {
3120 if (S.empty())
3121 return nullptr;
3122 return MDString::get(Context, S);
3123 }
3124
3125public:
3126 unsigned getMacinfoType() const { return SubclassData16; }
3127
3128 static bool classof(const Metadata *MD) {
3129 switch (MD->getMetadataID()) {
3130 default:
3131 return false;
3132 case DIMacroKind:
3133 case DIMacroFileKind:
3134 return true;
3135 }
3136 }
3137};
3138
3139class DIMacro : public DIMacroNode {
3140 friend class LLVMContextImpl;
3141 friend class MDNode;
3142
3143 unsigned Line;
3144
3145 DIMacro(LLVMContext &C, StorageType Storage, unsigned MIType, unsigned Line,
3146 ArrayRef<Metadata *> Ops)
3147 : DIMacroNode(C, DIMacroKind, Storage, MIType, Ops), Line(Line) {}
3148 ~DIMacro() = default;
3149
3150 static DIMacro *getImpl(LLVMContext &Context, unsigned MIType, unsigned Line,
3151 StringRef Name, StringRef Value, StorageType Storage,
3152 bool ShouldCreate = true) {
3153 return getImpl(Context, MIType, Line, getCanonicalMDString(Context, Name),
3154 getCanonicalMDString(Context, Value), Storage, ShouldCreate);
3155 }
3156 static DIMacro *getImpl(LLVMContext &Context, unsigned MIType, unsigned Line,
3157 MDString *Name, MDString *Value, StorageType Storage,
3158 bool ShouldCreate = true);
3159
3160 TempDIMacro cloneImpl() const {
3161 return getTemporary(getContext(), getMacinfoType(), getLine(), getName(),
3162 getValue());
3163 }
3164
3165public:
3166 DEFINE_MDNODE_GET(DIMacro, (unsigned MIType, unsigned Line, StringRef Name,
3167 StringRef Value = ""),
3168 (MIType, Line, Name, Value))
3169 DEFINE_MDNODE_GET(DIMacro, (unsigned MIType, unsigned Line, MDString *Name,
3170 MDString *Value),
3171 (MIType, Line, Name, Value))
3172
3173 TempDIMacro clone() const { return cloneImpl(); }
3174
3175 unsigned getLine() const { return Line; }
3176
3177 StringRef getName() const { return getStringOperand(0); }
3178 StringRef getValue() const { return getStringOperand(1); }
3179
3180 MDString *getRawName() const { return getOperandAs<MDString>(0); }
3181 MDString *getRawValue() const { return getOperandAs<MDString>(1); }
3182
3183 static bool classof(const Metadata *MD) {
3184 return MD->getMetadataID() == DIMacroKind;
3185 }
3186};
3187
3188class DIMacroFile : public DIMacroNode {
3189 friend class LLVMContextImpl;
3190 friend class MDNode;
3191
3192 unsigned Line;
3193
3194 DIMacroFile(LLVMContext &C, StorageType Storage, unsigned MIType,
3195 unsigned Line, ArrayRef<Metadata *> Ops)
3196 : DIMacroNode(C, DIMacroFileKind, Storage, MIType, Ops), Line(Line) {}
3197 ~DIMacroFile() = default;
3198
3199 static DIMacroFile *getImpl(LLVMContext &Context, unsigned MIType,
3200 unsigned Line, DIFile *File,
3201 DIMacroNodeArray Elements, StorageType Storage,
3202 bool ShouldCreate = true) {
3203 return getImpl(Context, MIType, Line, static_cast<Metadata *>(File),
3204 Elements.get(), Storage, ShouldCreate);
3205 }
3206
3207 static DIMacroFile *getImpl(LLVMContext &Context, unsigned MIType,
3208 unsigned Line, Metadata *File, Metadata *Elements,
3209 StorageType Storage, bool ShouldCreate = true);
3210
3211 TempDIMacroFile cloneImpl() const {
3212 return getTemporary(getContext(), getMacinfoType(), getLine(), getFile(),
3213 getElements());
3214 }
3215
3216public:
3217 DEFINE_MDNODE_GET(DIMacroFile, (unsigned MIType, unsigned Line, DIFile *File,
3218 DIMacroNodeArray Elements),
3219 (MIType, Line, File, Elements))
3220 DEFINE_MDNODE_GET(DIMacroFile, (unsigned MIType, unsigned Line,
3221 Metadata *File, Metadata *Elements),
3222 (MIType, Line, File, Elements))
3223
3224 TempDIMacroFile clone() const { return cloneImpl(); }
3225
3226 void replaceElements(DIMacroNodeArray Elements) {
3227#ifndef NDEBUG
3228 for (DIMacroNode *Op : getElements())
3229 assert(is_contained(Elements->operands(), Op) &&
3230 "Lost a macro node during macro node list replacement");
3231#endif
3232 replaceOperandWith(1, Elements.get());
3233 }
3234
3235 unsigned getLine() const { return Line; }
3236 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
3237
3238 DIMacroNodeArray getElements() const {
3239 return cast_or_null<MDTuple>(getRawElements());
3240 }
3241
3242 Metadata *getRawFile() const { return getOperand(0); }
3243 Metadata *getRawElements() const { return getOperand(1); }
3244
3245 static bool classof(const Metadata *MD) {
3246 return MD->getMetadataID() == DIMacroFileKind;
3247 }
3248};
3249
3250} // end namespace llvm
3251
3252#undef DEFINE_MDNODE_GET_UNPACK_IMPL
3253#undef DEFINE_MDNODE_GET_UNPACK
3254#undef DEFINE_MDNODE_GET
3255
3256#endif // LLVM_IR_DEBUGINFOMETADATA_H