blob: 22dd5ee6efacd5f8dd03655fb3d9f4084af42485 [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:
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200185 case DIStringTypeKind:
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100186 case DIDerivedTypeKind:
187 case DICompositeTypeKind:
188 case DISubroutineTypeKind:
189 case DIFileKind:
190 case DICompileUnitKind:
191 case DISubprogramKind:
192 case DILexicalBlockKind:
193 case DILexicalBlockFileKind:
194 case DINamespaceKind:
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100195 case DICommonBlockKind:
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100196 case DITemplateTypeParameterKind:
197 case DITemplateValueParameterKind:
198 case DIGlobalVariableKind:
199 case DILocalVariableKind:
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100200 case DILabelKind:
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100201 case DIObjCPropertyKind:
202 case DIImportedEntityKind:
203 case DIModuleKind:
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200204 case DIGenericSubrangeKind:
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100205 return true;
206 }
207 }
208};
209
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100210/// Generic tagged DWARF-like metadata node.
211///
212/// An un-specialized DWARF-like metadata node. The first operand is a
213/// (possibly empty) null-separated \a MDString header that contains arbitrary
214/// fields. The remaining operands are \a dwarf_operands(), and are pointers
215/// to other metadata.
216class GenericDINode : public DINode {
217 friend class LLVMContextImpl;
218 friend class MDNode;
219
220 GenericDINode(LLVMContext &C, StorageType Storage, unsigned Hash,
221 unsigned Tag, ArrayRef<Metadata *> Ops1,
222 ArrayRef<Metadata *> Ops2)
223 : DINode(C, GenericDINodeKind, Storage, Tag, Ops1, Ops2) {
224 setHash(Hash);
225 }
226 ~GenericDINode() { dropAllReferences(); }
227
228 void setHash(unsigned Hash) { SubclassData32 = Hash; }
229 void recalculateHash();
230
231 static GenericDINode *getImpl(LLVMContext &Context, unsigned Tag,
232 StringRef Header, ArrayRef<Metadata *> DwarfOps,
233 StorageType Storage, bool ShouldCreate = true) {
234 return getImpl(Context, Tag, getCanonicalMDString(Context, Header),
235 DwarfOps, Storage, ShouldCreate);
236 }
237
238 static GenericDINode *getImpl(LLVMContext &Context, unsigned Tag,
239 MDString *Header, ArrayRef<Metadata *> DwarfOps,
240 StorageType Storage, bool ShouldCreate = true);
241
242 TempGenericDINode cloneImpl() const {
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200243 return getTemporary(getContext(), getTag(), getHeader(),
244 SmallVector<Metadata *, 4>(dwarf_operands()));
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100245 }
246
247public:
248 unsigned getHash() const { return SubclassData32; }
249
250 DEFINE_MDNODE_GET(GenericDINode, (unsigned Tag, StringRef Header,
251 ArrayRef<Metadata *> DwarfOps),
252 (Tag, Header, DwarfOps))
253 DEFINE_MDNODE_GET(GenericDINode, (unsigned Tag, MDString *Header,
254 ArrayRef<Metadata *> DwarfOps),
255 (Tag, Header, DwarfOps))
256
257 /// Return a (temporary) clone of this.
258 TempGenericDINode clone() const { return cloneImpl(); }
259
260 unsigned getTag() const { return SubclassData16; }
261 StringRef getHeader() const { return getStringOperand(0); }
262 MDString *getRawHeader() const { return getOperandAs<MDString>(0); }
263
264 op_iterator dwarf_op_begin() const { return op_begin() + 1; }
265 op_iterator dwarf_op_end() const { return op_end(); }
266 op_range dwarf_operands() const {
267 return op_range(dwarf_op_begin(), dwarf_op_end());
268 }
269
270 unsigned getNumDwarfOperands() const { return getNumOperands() - 1; }
271 const MDOperand &getDwarfOperand(unsigned I) const {
272 return getOperand(I + 1);
273 }
274 void replaceDwarfOperandWith(unsigned I, Metadata *New) {
275 replaceOperandWith(I + 1, New);
276 }
277
278 static bool classof(const Metadata *MD) {
279 return MD->getMetadataID() == GenericDINodeKind;
280 }
281};
282
283/// Array subrange.
284///
285/// TODO: Merge into node for DW_TAG_array_type, which should have a custom
286/// type.
287class DISubrange : public DINode {
288 friend class LLVMContextImpl;
289 friend class MDNode;
290
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200291 DISubrange(LLVMContext &C, StorageType Storage, ArrayRef<Metadata *> Ops)
292 : DINode(C, DISubrangeKind, Storage, dwarf::DW_TAG_subrange_type, Ops) {}
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100293
294 ~DISubrange() = default;
295
296 static DISubrange *getImpl(LLVMContext &Context, int64_t Count,
297 int64_t LowerBound, StorageType Storage,
298 bool ShouldCreate = true);
299
300 static DISubrange *getImpl(LLVMContext &Context, Metadata *CountNode,
301 int64_t LowerBound, StorageType Storage,
302 bool ShouldCreate = true);
303
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200304 static DISubrange *getImpl(LLVMContext &Context, Metadata *CountNode,
305 Metadata *LowerBound, Metadata *UpperBound,
306 Metadata *Stride, StorageType Storage,
307 bool ShouldCreate = true);
308
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100309 TempDISubrange cloneImpl() const {
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200310 return getTemporary(getContext(), getRawCountNode(), getRawLowerBound(),
311 getRawUpperBound(), getRawStride());
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100312 }
313
314public:
315 DEFINE_MDNODE_GET(DISubrange, (int64_t Count, int64_t LowerBound = 0),
316 (Count, LowerBound))
317
318 DEFINE_MDNODE_GET(DISubrange, (Metadata *CountNode, int64_t LowerBound = 0),
319 (CountNode, LowerBound))
320
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200321 DEFINE_MDNODE_GET(DISubrange,
322 (Metadata * CountNode, Metadata *LowerBound,
323 Metadata *UpperBound, Metadata *Stride),
324 (CountNode, LowerBound, UpperBound, Stride))
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100325
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200326 TempDISubrange clone() const { return cloneImpl(); }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100327
328 Metadata *getRawCountNode() const {
329 return getOperand(0).get();
330 }
331
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200332 Metadata *getRawLowerBound() const { return getOperand(1).get(); }
333
334 Metadata *getRawUpperBound() const { return getOperand(2).get(); }
335
336 Metadata *getRawStride() const { return getOperand(3).get(); }
337
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100338 typedef PointerUnion<ConstantInt*, DIVariable*> CountType;
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200339 typedef PointerUnion<ConstantInt *, DIVariable *, DIExpression *> BoundType;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100340
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200341 CountType getCount() const;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100342
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200343 BoundType getLowerBound() const;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100344
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200345 BoundType getUpperBound() const;
346
347 BoundType getStride() const;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100348
349 static bool classof(const Metadata *MD) {
350 return MD->getMetadataID() == DISubrangeKind;
351 }
352};
353
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200354class DIGenericSubrange : public DINode {
355 friend class LLVMContextImpl;
356 friend class MDNode;
357
358 DIGenericSubrange(LLVMContext &C, StorageType Storage,
359 ArrayRef<Metadata *> Ops)
360 : DINode(C, DIGenericSubrangeKind, Storage,
361 dwarf::DW_TAG_generic_subrange, Ops) {}
362
363 ~DIGenericSubrange() = default;
364
365 static DIGenericSubrange *getImpl(LLVMContext &Context, Metadata *CountNode,
366 Metadata *LowerBound, Metadata *UpperBound,
367 Metadata *Stride, StorageType Storage,
368 bool ShouldCreate = true);
369
370 TempDIGenericSubrange cloneImpl() const {
371 return getTemporary(getContext(), getRawCountNode(), getRawLowerBound(),
372 getRawUpperBound(), getRawStride());
373 }
374
375public:
376 DEFINE_MDNODE_GET(DIGenericSubrange,
377 (Metadata * CountNode, Metadata *LowerBound,
378 Metadata *UpperBound, Metadata *Stride),
379 (CountNode, LowerBound, UpperBound, Stride))
380
381 TempDIGenericSubrange clone() const { return cloneImpl(); }
382
383 Metadata *getRawCountNode() const { return getOperand(0).get(); }
384 Metadata *getRawLowerBound() const { return getOperand(1).get(); }
385 Metadata *getRawUpperBound() const { return getOperand(2).get(); }
386 Metadata *getRawStride() const { return getOperand(3).get(); }
387
388 using BoundType = PointerUnion<DIVariable *, DIExpression *>;
389
390 BoundType getCount() const;
391 BoundType getLowerBound() const;
392 BoundType getUpperBound() const;
393 BoundType getStride() const;
394
395 static bool classof(const Metadata *MD) {
396 return MD->getMetadataID() == DIGenericSubrangeKind;
397 }
398};
399
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100400/// Enumeration value.
401///
402/// TODO: Add a pointer to the context (DW_TAG_enumeration_type) once that no
403/// longer creates a type cycle.
404class DIEnumerator : public DINode {
405 friend class LLVMContextImpl;
406 friend class MDNode;
407
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200408 APInt Value;
409 DIEnumerator(LLVMContext &C, StorageType Storage, const APInt &Value,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100410 bool IsUnsigned, ArrayRef<Metadata *> Ops)
411 : DINode(C, DIEnumeratorKind, Storage, dwarf::DW_TAG_enumerator, Ops),
412 Value(Value) {
413 SubclassData32 = IsUnsigned;
414 }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200415 DIEnumerator(LLVMContext &C, StorageType Storage, int64_t Value,
416 bool IsUnsigned, ArrayRef<Metadata *> Ops)
417 : DIEnumerator(C, Storage, APInt(64, Value, !IsUnsigned), IsUnsigned,
418 Ops) {}
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100419 ~DIEnumerator() = default;
420
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200421 static DIEnumerator *getImpl(LLVMContext &Context, const APInt &Value,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100422 bool IsUnsigned, StringRef Name,
423 StorageType Storage, bool ShouldCreate = true) {
424 return getImpl(Context, Value, IsUnsigned,
425 getCanonicalMDString(Context, Name), Storage, ShouldCreate);
426 }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200427 static DIEnumerator *getImpl(LLVMContext &Context, const APInt &Value,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100428 bool IsUnsigned, MDString *Name,
429 StorageType Storage, bool ShouldCreate = true);
430
431 TempDIEnumerator cloneImpl() const {
432 return getTemporary(getContext(), getValue(), isUnsigned(), getName());
433 }
434
435public:
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200436 DEFINE_MDNODE_GET(DIEnumerator,
437 (int64_t Value, bool IsUnsigned, StringRef Name),
438 (APInt(64, Value, !IsUnsigned), IsUnsigned, Name))
439 DEFINE_MDNODE_GET(DIEnumerator,
440 (int64_t Value, bool IsUnsigned, MDString *Name),
441 (APInt(64, Value, !IsUnsigned), IsUnsigned, Name))
442 DEFINE_MDNODE_GET(DIEnumerator,
443 (APInt Value, bool IsUnsigned, StringRef Name),
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100444 (Value, IsUnsigned, Name))
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200445 DEFINE_MDNODE_GET(DIEnumerator,
446 (APInt Value, bool IsUnsigned, MDString *Name),
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100447 (Value, IsUnsigned, Name))
448
449 TempDIEnumerator clone() const { return cloneImpl(); }
450
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200451 const APInt &getValue() const { return Value; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100452 bool isUnsigned() const { return SubclassData32; }
453 StringRef getName() const { return getStringOperand(0); }
454
455 MDString *getRawName() const { return getOperandAs<MDString>(0); }
456
457 static bool classof(const Metadata *MD) {
458 return MD->getMetadataID() == DIEnumeratorKind;
459 }
460};
461
462/// Base class for scope-like contexts.
463///
464/// Base class for lexical scopes and types (which are also declaration
465/// contexts).
466///
467/// TODO: Separate the concepts of declaration contexts and lexical scopes.
468class DIScope : public DINode {
469protected:
470 DIScope(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
471 ArrayRef<Metadata *> Ops)
472 : DINode(C, ID, Storage, Tag, Ops) {}
473 ~DIScope() = default;
474
475public:
476 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
477
478 inline StringRef getFilename() const;
479 inline StringRef getDirectory() const;
480 inline Optional<StringRef> getSource() const;
481
482 StringRef getName() const;
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100483 DIScope *getScope() const;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100484
485 /// Return the raw underlying file.
486 ///
487 /// A \a DIFile is a \a DIScope, but it doesn't point at a separate file (it
488 /// \em is the file). If \c this is an \a DIFile, we need to return \c this.
489 /// Otherwise, return the first operand, which is where all other subclasses
490 /// store their file pointer.
491 Metadata *getRawFile() const {
492 return isa<DIFile>(this) ? const_cast<DIScope *>(this)
493 : static_cast<Metadata *>(getOperand(0));
494 }
495
496 static bool classof(const Metadata *MD) {
497 switch (MD->getMetadataID()) {
498 default:
499 return false;
500 case DIBasicTypeKind:
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200501 case DIStringTypeKind:
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100502 case DIDerivedTypeKind:
503 case DICompositeTypeKind:
504 case DISubroutineTypeKind:
505 case DIFileKind:
506 case DICompileUnitKind:
507 case DISubprogramKind:
508 case DILexicalBlockKind:
509 case DILexicalBlockFileKind:
510 case DINamespaceKind:
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100511 case DICommonBlockKind:
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100512 case DIModuleKind:
513 return true;
514 }
515 }
516};
517
518/// File.
519///
520/// TODO: Merge with directory/file node (including users).
521/// TODO: Canonicalize paths on creation.
522class DIFile : public DIScope {
523 friend class LLVMContextImpl;
524 friend class MDNode;
525
526public:
527 /// Which algorithm (e.g. MD5) a checksum was generated with.
528 ///
529 /// The encoding is explicit because it is used directly in Bitcode. The
530 /// value 0 is reserved to indicate the absence of a checksum in Bitcode.
531 enum ChecksumKind {
532 // The first variant was originally CSK_None, encoded as 0. The new
533 // internal representation removes the need for this by wrapping the
534 // ChecksumInfo in an Optional, but to preserve Bitcode compatibility the 0
535 // encoding is reserved.
536 CSK_MD5 = 1,
537 CSK_SHA1 = 2,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200538 CSK_SHA256 = 3,
539 CSK_Last = CSK_SHA256 // Should be last enumeration.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100540 };
541
542 /// A single checksum, represented by a \a Kind and a \a Value (a string).
543 template <typename T>
544 struct ChecksumInfo {
545 /// The kind of checksum which \a Value encodes.
546 ChecksumKind Kind;
547 /// The string value of the checksum.
548 T Value;
549
550 ChecksumInfo(ChecksumKind Kind, T Value) : Kind(Kind), Value(Value) { }
551 ~ChecksumInfo() = default;
552 bool operator==(const ChecksumInfo<T> &X) const {
553 return Kind == X.Kind && Value == X.Value;
554 }
555 bool operator!=(const ChecksumInfo<T> &X) const { return !(*this == X); }
556 StringRef getKindAsString() const { return getChecksumKindAsString(Kind); }
557 };
558
559private:
560 Optional<ChecksumInfo<MDString *>> Checksum;
561 Optional<MDString *> Source;
562
563 DIFile(LLVMContext &C, StorageType Storage,
564 Optional<ChecksumInfo<MDString *>> CS, Optional<MDString *> Src,
565 ArrayRef<Metadata *> Ops)
566 : DIScope(C, DIFileKind, Storage, dwarf::DW_TAG_file_type, Ops),
567 Checksum(CS), Source(Src) {}
568 ~DIFile() = default;
569
570 static DIFile *getImpl(LLVMContext &Context, StringRef Filename,
571 StringRef Directory,
572 Optional<ChecksumInfo<StringRef>> CS,
573 Optional<StringRef> Source,
574 StorageType Storage, bool ShouldCreate = true) {
575 Optional<ChecksumInfo<MDString *>> MDChecksum;
576 if (CS)
577 MDChecksum.emplace(CS->Kind, getCanonicalMDString(Context, CS->Value));
578 return getImpl(Context, getCanonicalMDString(Context, Filename),
579 getCanonicalMDString(Context, Directory), MDChecksum,
580 Source ? Optional<MDString *>(getCanonicalMDString(Context, *Source)) : None,
581 Storage, ShouldCreate);
582 }
583 static DIFile *getImpl(LLVMContext &Context, MDString *Filename,
584 MDString *Directory,
585 Optional<ChecksumInfo<MDString *>> CS,
586 Optional<MDString *> Source, StorageType Storage,
587 bool ShouldCreate = true);
588
589 TempDIFile cloneImpl() const {
590 return getTemporary(getContext(), getFilename(), getDirectory(),
591 getChecksum(), getSource());
592 }
593
594public:
595 DEFINE_MDNODE_GET(DIFile, (StringRef Filename, StringRef Directory,
596 Optional<ChecksumInfo<StringRef>> CS = None,
597 Optional<StringRef> Source = None),
598 (Filename, Directory, CS, Source))
599 DEFINE_MDNODE_GET(DIFile, (MDString * Filename, MDString *Directory,
600 Optional<ChecksumInfo<MDString *>> CS = None,
601 Optional<MDString *> Source = None),
602 (Filename, Directory, CS, Source))
603
604 TempDIFile clone() const { return cloneImpl(); }
605
606 StringRef getFilename() const { return getStringOperand(0); }
607 StringRef getDirectory() const { return getStringOperand(1); }
608 Optional<ChecksumInfo<StringRef>> getChecksum() const {
609 Optional<ChecksumInfo<StringRef>> StringRefChecksum;
610 if (Checksum)
611 StringRefChecksum.emplace(Checksum->Kind, Checksum->Value->getString());
612 return StringRefChecksum;
613 }
614 Optional<StringRef> getSource() const {
615 return Source ? Optional<StringRef>((*Source)->getString()) : None;
616 }
617
618 MDString *getRawFilename() const { return getOperandAs<MDString>(0); }
619 MDString *getRawDirectory() const { return getOperandAs<MDString>(1); }
620 Optional<ChecksumInfo<MDString *>> getRawChecksum() const { return Checksum; }
621 Optional<MDString *> getRawSource() const { return Source; }
622
623 static StringRef getChecksumKindAsString(ChecksumKind CSKind);
624 static Optional<ChecksumKind> getChecksumKind(StringRef CSKindStr);
625
626 static bool classof(const Metadata *MD) {
627 return MD->getMetadataID() == DIFileKind;
628 }
629};
630
631StringRef DIScope::getFilename() const {
632 if (auto *F = getFile())
633 return F->getFilename();
634 return "";
635}
636
637StringRef DIScope::getDirectory() const {
638 if (auto *F = getFile())
639 return F->getDirectory();
640 return "";
641}
642
643Optional<StringRef> DIScope::getSource() const {
644 if (auto *F = getFile())
645 return F->getSource();
646 return None;
647}
648
649/// Base class for types.
650///
651/// TODO: Remove the hardcoded name and context, since many types don't use
652/// them.
653/// TODO: Split up flags.
654class DIType : public DIScope {
655 unsigned Line;
656 DIFlags Flags;
657 uint64_t SizeInBits;
658 uint64_t OffsetInBits;
659 uint32_t AlignInBits;
660
661protected:
662 DIType(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
663 unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits,
664 uint64_t OffsetInBits, DIFlags Flags, ArrayRef<Metadata *> Ops)
665 : DIScope(C, ID, Storage, Tag, Ops) {
666 init(Line, SizeInBits, AlignInBits, OffsetInBits, Flags);
667 }
668 ~DIType() = default;
669
670 void init(unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits,
671 uint64_t OffsetInBits, DIFlags Flags) {
672 this->Line = Line;
673 this->Flags = Flags;
674 this->SizeInBits = SizeInBits;
675 this->AlignInBits = AlignInBits;
676 this->OffsetInBits = OffsetInBits;
677 }
678
679 /// Change fields in place.
680 void mutate(unsigned Tag, unsigned Line, uint64_t SizeInBits,
681 uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags) {
682 assert(isDistinct() && "Only distinct nodes can mutate");
683 setTag(Tag);
684 init(Line, SizeInBits, AlignInBits, OffsetInBits, Flags);
685 }
686
687public:
688 TempDIType clone() const {
689 return TempDIType(cast<DIType>(MDNode::clone().release()));
690 }
691
692 unsigned getLine() const { return Line; }
693 uint64_t getSizeInBits() const { return SizeInBits; }
694 uint32_t getAlignInBits() const { return AlignInBits; }
695 uint32_t getAlignInBytes() const { return getAlignInBits() / CHAR_BIT; }
696 uint64_t getOffsetInBits() const { return OffsetInBits; }
697 DIFlags getFlags() const { return Flags; }
698
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100699 DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100700 StringRef getName() const { return getStringOperand(2); }
701
702
703 Metadata *getRawScope() const { return getOperand(1); }
704 MDString *getRawName() const { return getOperandAs<MDString>(2); }
705
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100706 /// Returns a new temporary DIType with updated Flags
707 TempDIType cloneWithFlags(DIFlags NewFlags) const {
708 auto NewTy = clone();
709 NewTy->Flags = NewFlags;
710 return NewTy;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100711 }
712
713 bool isPrivate() const {
714 return (getFlags() & FlagAccessibility) == FlagPrivate;
715 }
716 bool isProtected() const {
717 return (getFlags() & FlagAccessibility) == FlagProtected;
718 }
719 bool isPublic() const {
720 return (getFlags() & FlagAccessibility) == FlagPublic;
721 }
722 bool isForwardDecl() const { return getFlags() & FlagFwdDecl; }
723 bool isAppleBlockExtension() const { return getFlags() & FlagAppleBlock; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100724 bool isVirtual() const { return getFlags() & FlagVirtual; }
725 bool isArtificial() const { return getFlags() & FlagArtificial; }
726 bool isObjectPointer() const { return getFlags() & FlagObjectPointer; }
727 bool isObjcClassComplete() const {
728 return getFlags() & FlagObjcClassComplete;
729 }
730 bool isVector() const { return getFlags() & FlagVector; }
731 bool isBitField() const { return getFlags() & FlagBitField; }
732 bool isStaticMember() const { return getFlags() & FlagStaticMember; }
733 bool isLValueReference() const { return getFlags() & FlagLValueReference; }
734 bool isRValueReference() const { return getFlags() & FlagRValueReference; }
735 bool isTypePassByValue() const { return getFlags() & FlagTypePassByValue; }
736 bool isTypePassByReference() const {
737 return getFlags() & FlagTypePassByReference;
738 }
Andrew Scull0372a572018-11-16 15:47:06 +0000739 bool isBigEndian() const { return getFlags() & FlagBigEndian; }
740 bool isLittleEndian() const { return getFlags() & FlagLittleEndian; }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200741 bool getExportSymbols() const { return getFlags() & FlagExportSymbols; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100742
743 static bool classof(const Metadata *MD) {
744 switch (MD->getMetadataID()) {
745 default:
746 return false;
747 case DIBasicTypeKind:
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200748 case DIStringTypeKind:
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100749 case DIDerivedTypeKind:
750 case DICompositeTypeKind:
751 case DISubroutineTypeKind:
752 return true;
753 }
754 }
755};
756
757/// Basic type, like 'int' or 'float'.
758///
759/// TODO: Split out DW_TAG_unspecified_type.
760/// TODO: Drop unused accessors.
761class DIBasicType : public DIType {
762 friend class LLVMContextImpl;
763 friend class MDNode;
764
765 unsigned Encoding;
766
767 DIBasicType(LLVMContext &C, StorageType Storage, unsigned Tag,
768 uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding,
Andrew Scull0372a572018-11-16 15:47:06 +0000769 DIFlags Flags, ArrayRef<Metadata *> Ops)
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100770 : DIType(C, DIBasicTypeKind, Storage, Tag, 0, SizeInBits, AlignInBits, 0,
Andrew Scull0372a572018-11-16 15:47:06 +0000771 Flags, Ops),
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100772 Encoding(Encoding) {}
773 ~DIBasicType() = default;
774
775 static DIBasicType *getImpl(LLVMContext &Context, unsigned Tag,
776 StringRef Name, uint64_t SizeInBits,
777 uint32_t AlignInBits, unsigned Encoding,
Andrew Scull0372a572018-11-16 15:47:06 +0000778 DIFlags Flags, StorageType Storage,
779 bool ShouldCreate = true) {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100780 return getImpl(Context, Tag, getCanonicalMDString(Context, Name),
Andrew Scull0372a572018-11-16 15:47:06 +0000781 SizeInBits, AlignInBits, Encoding, Flags, Storage,
782 ShouldCreate);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100783 }
784 static DIBasicType *getImpl(LLVMContext &Context, unsigned Tag,
785 MDString *Name, uint64_t SizeInBits,
786 uint32_t AlignInBits, unsigned Encoding,
Andrew Scull0372a572018-11-16 15:47:06 +0000787 DIFlags Flags, StorageType Storage,
788 bool ShouldCreate = true);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100789
790 TempDIBasicType cloneImpl() const {
791 return getTemporary(getContext(), getTag(), getName(), getSizeInBits(),
Andrew Scull0372a572018-11-16 15:47:06 +0000792 getAlignInBits(), getEncoding(), getFlags());
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100793 }
794
795public:
796 DEFINE_MDNODE_GET(DIBasicType, (unsigned Tag, StringRef Name),
Andrew Scull0372a572018-11-16 15:47:06 +0000797 (Tag, Name, 0, 0, 0, FlagZero))
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100798 DEFINE_MDNODE_GET(DIBasicType,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200799 (unsigned Tag, StringRef Name, uint64_t SizeInBits),
800 (Tag, Name, SizeInBits, 0, 0, FlagZero))
801 DEFINE_MDNODE_GET(DIBasicType,
802 (unsigned Tag, MDString *Name, uint64_t SizeInBits),
803 (Tag, Name, SizeInBits, 0, 0, FlagZero))
804 DEFINE_MDNODE_GET(DIBasicType,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100805 (unsigned Tag, StringRef Name, uint64_t SizeInBits,
Andrew Scull0372a572018-11-16 15:47:06 +0000806 uint32_t AlignInBits, unsigned Encoding, DIFlags Flags),
807 (Tag, Name, SizeInBits, AlignInBits, Encoding, Flags))
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100808 DEFINE_MDNODE_GET(DIBasicType,
809 (unsigned Tag, MDString *Name, uint64_t SizeInBits,
Andrew Scull0372a572018-11-16 15:47:06 +0000810 uint32_t AlignInBits, unsigned Encoding, DIFlags Flags),
811 (Tag, Name, SizeInBits, AlignInBits, Encoding, Flags))
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100812
813 TempDIBasicType clone() const { return cloneImpl(); }
814
815 unsigned getEncoding() const { return Encoding; }
816
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100817 enum class Signedness { Signed, Unsigned };
818
819 /// Return the signedness of this type, or None if this type is neither
820 /// signed nor unsigned.
821 Optional<Signedness> getSignedness() const;
822
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100823 static bool classof(const Metadata *MD) {
824 return MD->getMetadataID() == DIBasicTypeKind;
825 }
826};
827
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200828/// String type, Fortran CHARACTER(n)
829class DIStringType : public DIType {
830 friend class LLVMContextImpl;
831 friend class MDNode;
832
833 unsigned Encoding;
834
835 DIStringType(LLVMContext &C, StorageType Storage, unsigned Tag,
836 uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding,
837 ArrayRef<Metadata *> Ops)
838 : DIType(C, DIStringTypeKind, Storage, Tag, 0, SizeInBits, AlignInBits, 0,
839 FlagZero, Ops),
840 Encoding(Encoding) {}
841 ~DIStringType() = default;
842
843 static DIStringType *getImpl(LLVMContext &Context, unsigned Tag,
844 StringRef Name, Metadata *StringLength,
845 Metadata *StrLenExp, uint64_t SizeInBits,
846 uint32_t AlignInBits, unsigned Encoding,
847 StorageType Storage, bool ShouldCreate = true) {
848 return getImpl(Context, Tag, getCanonicalMDString(Context, Name),
849 StringLength, StrLenExp, SizeInBits, AlignInBits, Encoding,
850 Storage, ShouldCreate);
851 }
852 static DIStringType *getImpl(LLVMContext &Context, unsigned Tag,
853 MDString *Name, Metadata *StringLength,
854 Metadata *StrLenExp, uint64_t SizeInBits,
855 uint32_t AlignInBits, unsigned Encoding,
856 StorageType Storage, bool ShouldCreate = true);
857
858 TempDIStringType cloneImpl() const {
859 return getTemporary(getContext(), getTag(), getRawName(),
860 getRawStringLength(), getRawStringLengthExp(),
861 getSizeInBits(), getAlignInBits(), getEncoding());
862 }
863
864public:
865 DEFINE_MDNODE_GET(DIStringType,
866 (unsigned Tag, StringRef Name, uint64_t SizeInBits,
867 uint32_t AlignInBits),
868 (Tag, Name, nullptr, nullptr, SizeInBits, AlignInBits, 0))
869 DEFINE_MDNODE_GET(DIStringType,
870 (unsigned Tag, MDString *Name, Metadata *StringLength,
871 Metadata *StringLengthExp, uint64_t SizeInBits,
872 uint32_t AlignInBits, unsigned Encoding),
873 (Tag, Name, StringLength, StringLengthExp, SizeInBits,
874 AlignInBits, Encoding))
875 DEFINE_MDNODE_GET(DIStringType,
876 (unsigned Tag, StringRef Name, Metadata *StringLength,
877 Metadata *StringLengthExp, uint64_t SizeInBits,
878 uint32_t AlignInBits, unsigned Encoding),
879 (Tag, Name, StringLength, StringLengthExp, SizeInBits,
880 AlignInBits, Encoding))
881
882 TempDIStringType clone() const { return cloneImpl(); }
883
884 static bool classof(const Metadata *MD) {
885 return MD->getMetadataID() == DIStringTypeKind;
886 }
887
888 DIVariable *getStringLength() const {
889 return cast_or_null<DIVariable>(getRawStringLength());
890 }
891
892 DIExpression *getStringLengthExp() const {
893 return cast_or_null<DIExpression>(getRawStringLengthExp());
894 }
895
896 unsigned getEncoding() const { return Encoding; }
897
898 Metadata *getRawStringLength() const { return getOperand(3); }
899
900 Metadata *getRawStringLengthExp() const { return getOperand(4); }
901};
902
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100903/// Derived types.
904///
905/// This includes qualified types, pointers, references, friends, typedefs, and
906/// class members.
907///
908/// TODO: Split out members (inheritance, fields, methods, etc.).
909class DIDerivedType : public DIType {
910 friend class LLVMContextImpl;
911 friend class MDNode;
912
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100913 /// The DWARF address space of the memory pointed to or referenced by a
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100914 /// pointer or reference type respectively.
915 Optional<unsigned> DWARFAddressSpace;
916
917 DIDerivedType(LLVMContext &C, StorageType Storage, unsigned Tag,
918 unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits,
919 uint64_t OffsetInBits, Optional<unsigned> DWARFAddressSpace,
920 DIFlags Flags, ArrayRef<Metadata *> Ops)
921 : DIType(C, DIDerivedTypeKind, Storage, Tag, Line, SizeInBits,
922 AlignInBits, OffsetInBits, Flags, Ops),
923 DWARFAddressSpace(DWARFAddressSpace) {}
924 ~DIDerivedType() = default;
925
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100926 static DIDerivedType *
927 getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, DIFile *File,
928 unsigned Line, DIScope *Scope, DIType *BaseType, uint64_t SizeInBits,
929 uint32_t AlignInBits, uint64_t OffsetInBits,
930 Optional<unsigned> DWARFAddressSpace, DIFlags Flags,
931 Metadata *ExtraData, StorageType Storage, bool ShouldCreate = true) {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100932 return getImpl(Context, Tag, getCanonicalMDString(Context, Name), File,
933 Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits,
934 DWARFAddressSpace, Flags, ExtraData, Storage, ShouldCreate);
935 }
936 static DIDerivedType *getImpl(LLVMContext &Context, unsigned Tag,
937 MDString *Name, Metadata *File, unsigned Line,
938 Metadata *Scope, Metadata *BaseType,
939 uint64_t SizeInBits, uint32_t AlignInBits,
940 uint64_t OffsetInBits,
941 Optional<unsigned> DWARFAddressSpace,
942 DIFlags Flags, Metadata *ExtraData,
943 StorageType Storage, bool ShouldCreate = true);
944
945 TempDIDerivedType cloneImpl() const {
946 return getTemporary(getContext(), getTag(), getName(), getFile(), getLine(),
947 getScope(), getBaseType(), getSizeInBits(),
948 getAlignInBits(), getOffsetInBits(),
949 getDWARFAddressSpace(), getFlags(), getExtraData());
950 }
951
952public:
953 DEFINE_MDNODE_GET(DIDerivedType,
954 (unsigned Tag, MDString *Name, Metadata *File,
955 unsigned Line, Metadata *Scope, Metadata *BaseType,
956 uint64_t SizeInBits, uint32_t AlignInBits,
957 uint64_t OffsetInBits,
958 Optional<unsigned> DWARFAddressSpace, DIFlags Flags,
959 Metadata *ExtraData = nullptr),
960 (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
961 AlignInBits, OffsetInBits, DWARFAddressSpace, Flags,
962 ExtraData))
963 DEFINE_MDNODE_GET(DIDerivedType,
964 (unsigned Tag, StringRef Name, DIFile *File, unsigned Line,
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100965 DIScope *Scope, DIType *BaseType, uint64_t SizeInBits,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100966 uint32_t AlignInBits, uint64_t OffsetInBits,
967 Optional<unsigned> DWARFAddressSpace, DIFlags Flags,
968 Metadata *ExtraData = nullptr),
969 (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
970 AlignInBits, OffsetInBits, DWARFAddressSpace, Flags,
971 ExtraData))
972
973 TempDIDerivedType clone() const { return cloneImpl(); }
974
975 /// Get the base type this is derived from.
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100976 DIType *getBaseType() const { return cast_or_null<DIType>(getRawBaseType()); }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100977 Metadata *getRawBaseType() const { return getOperand(3); }
978
979 /// \returns The DWARF address space of the memory pointed to or referenced by
980 /// a pointer or reference type respectively.
981 Optional<unsigned> getDWARFAddressSpace() const { return DWARFAddressSpace; }
982
983 /// Get extra data associated with this derived type.
984 ///
985 /// Class type for pointer-to-members, objective-c property node for ivars,
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100986 /// global constant wrapper for static members, or virtual base pointer offset
987 /// for inheritance.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100988 ///
989 /// TODO: Separate out types that need this extra operand: pointer-to-member
990 /// types and member fields (static members and ivars).
991 Metadata *getExtraData() const { return getRawExtraData(); }
992 Metadata *getRawExtraData() const { return getOperand(4); }
993
994 /// Get casted version of extra data.
995 /// @{
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100996 DIType *getClassType() const {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100997 assert(getTag() == dwarf::DW_TAG_ptr_to_member_type);
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100998 return cast_or_null<DIType>(getExtraData());
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100999 }
1000
1001 DIObjCProperty *getObjCProperty() const {
1002 return dyn_cast_or_null<DIObjCProperty>(getExtraData());
1003 }
1004
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001005 uint32_t getVBPtrOffset() const {
1006 assert(getTag() == dwarf::DW_TAG_inheritance);
1007 if (auto *CM = cast_or_null<ConstantAsMetadata>(getExtraData()))
1008 if (auto *CI = dyn_cast_or_null<ConstantInt>(CM->getValue()))
1009 return static_cast<uint32_t>(CI->getZExtValue());
1010 return 0;
1011 }
1012
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001013 Constant *getStorageOffsetInBits() const {
1014 assert(getTag() == dwarf::DW_TAG_member && isBitField());
1015 if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData()))
1016 return C->getValue();
1017 return nullptr;
1018 }
1019
1020 Constant *getConstant() const {
1021 assert(getTag() == dwarf::DW_TAG_member && isStaticMember());
1022 if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData()))
1023 return C->getValue();
1024 return nullptr;
1025 }
1026 Constant *getDiscriminantValue() const {
1027 assert(getTag() == dwarf::DW_TAG_member && !isStaticMember());
1028 if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData()))
1029 return C->getValue();
1030 return nullptr;
1031 }
1032 /// @}
1033
1034 static bool classof(const Metadata *MD) {
1035 return MD->getMetadataID() == DIDerivedTypeKind;
1036 }
1037};
1038
1039/// Composite types.
1040///
1041/// TODO: Detach from DerivedTypeBase (split out MDEnumType?).
1042/// TODO: Create a custom, unrelated node for DW_TAG_array_type.
1043class DICompositeType : public DIType {
1044 friend class LLVMContextImpl;
1045 friend class MDNode;
1046
1047 unsigned RuntimeLang;
1048
1049 DICompositeType(LLVMContext &C, StorageType Storage, unsigned Tag,
1050 unsigned Line, unsigned RuntimeLang, uint64_t SizeInBits,
1051 uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags,
1052 ArrayRef<Metadata *> Ops)
1053 : DIType(C, DICompositeTypeKind, Storage, Tag, Line, SizeInBits,
1054 AlignInBits, OffsetInBits, Flags, Ops),
1055 RuntimeLang(RuntimeLang) {}
1056 ~DICompositeType() = default;
1057
1058 /// Change fields in place.
1059 void mutate(unsigned Tag, unsigned Line, unsigned RuntimeLang,
1060 uint64_t SizeInBits, uint32_t AlignInBits,
1061 uint64_t OffsetInBits, DIFlags Flags) {
1062 assert(isDistinct() && "Only distinct nodes can mutate");
1063 assert(getRawIdentifier() && "Only ODR-uniqued nodes should mutate");
1064 this->RuntimeLang = RuntimeLang;
1065 DIType::mutate(Tag, Line, SizeInBits, AlignInBits, OffsetInBits, Flags);
1066 }
1067
1068 static DICompositeType *
1069 getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, Metadata *File,
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001070 unsigned Line, DIScope *Scope, DIType *BaseType, uint64_t SizeInBits,
1071 uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags,
1072 DINodeArray Elements, unsigned RuntimeLang, DIType *VTableHolder,
1073 DITemplateParameterArray TemplateParams, StringRef Identifier,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001074 DIDerivedType *Discriminator, Metadata *DataLocation,
1075 Metadata *Associated, Metadata *Allocated, Metadata *Rank,
1076 StorageType Storage, bool ShouldCreate = true) {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001077 return getImpl(
1078 Context, Tag, getCanonicalMDString(Context, Name), File, Line, Scope,
1079 BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements.get(),
1080 RuntimeLang, VTableHolder, TemplateParams.get(),
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001081 getCanonicalMDString(Context, Identifier), Discriminator, DataLocation,
1082 Associated, Allocated, Rank, Storage, ShouldCreate);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001083 }
1084 static DICompositeType *
1085 getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
1086 unsigned Line, Metadata *Scope, Metadata *BaseType,
1087 uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
1088 DIFlags Flags, Metadata *Elements, unsigned RuntimeLang,
1089 Metadata *VTableHolder, Metadata *TemplateParams,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001090 MDString *Identifier, Metadata *Discriminator, Metadata *DataLocation,
1091 Metadata *Associated, Metadata *Allocated, Metadata *Rank,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001092 StorageType Storage, bool ShouldCreate = true);
1093
1094 TempDICompositeType cloneImpl() const {
1095 return getTemporary(getContext(), getTag(), getName(), getFile(), getLine(),
1096 getScope(), getBaseType(), getSizeInBits(),
1097 getAlignInBits(), getOffsetInBits(), getFlags(),
1098 getElements(), getRuntimeLang(), getVTableHolder(),
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001099 getTemplateParams(), getIdentifier(),
1100 getDiscriminator(), getRawDataLocation(),
1101 getRawAssociated(), getRawAllocated(), getRawRank());
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001102 }
1103
1104public:
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001105 DEFINE_MDNODE_GET(
1106 DICompositeType,
1107 (unsigned Tag, StringRef Name, DIFile *File, unsigned Line,
1108 DIScope *Scope, DIType *BaseType, uint64_t SizeInBits,
1109 uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags,
1110 DINodeArray Elements, unsigned RuntimeLang, DIType *VTableHolder,
1111 DITemplateParameterArray TemplateParams = nullptr,
1112 StringRef Identifier = "", DIDerivedType *Discriminator = nullptr,
1113 Metadata *DataLocation = nullptr, Metadata *Associated = nullptr,
1114 Metadata *Allocated = nullptr, Metadata *Rank = nullptr),
1115 (Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
1116 OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams,
1117 Identifier, Discriminator, DataLocation, Associated, Allocated, Rank))
1118 DEFINE_MDNODE_GET(
1119 DICompositeType,
1120 (unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
1121 Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits,
1122 uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags,
1123 Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder,
1124 Metadata *TemplateParams = nullptr, MDString *Identifier = nullptr,
1125 Metadata *Discriminator = nullptr, Metadata *DataLocation = nullptr,
1126 Metadata *Associated = nullptr, Metadata *Allocated = nullptr,
1127 Metadata *Rank = nullptr),
1128 (Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
1129 OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams,
1130 Identifier, Discriminator, DataLocation, Associated, Allocated, Rank))
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001131
1132 TempDICompositeType clone() const { return cloneImpl(); }
1133
1134 /// Get a DICompositeType with the given ODR identifier.
1135 ///
1136 /// If \a LLVMContext::isODRUniquingDebugTypes(), gets the mapped
1137 /// DICompositeType for the given ODR \c Identifier. If none exists, creates
1138 /// a new node.
1139 ///
1140 /// Else, returns \c nullptr.
1141 static DICompositeType *
1142 getODRType(LLVMContext &Context, MDString &Identifier, unsigned Tag,
1143 MDString *Name, Metadata *File, unsigned Line, Metadata *Scope,
1144 Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits,
1145 uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements,
1146 unsigned RuntimeLang, Metadata *VTableHolder,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001147 Metadata *TemplateParams, Metadata *Discriminator,
1148 Metadata *DataLocation, Metadata *Associated, Metadata *Allocated,
1149 Metadata *Rank);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001150 static DICompositeType *getODRTypeIfExists(LLVMContext &Context,
1151 MDString &Identifier);
1152
1153 /// Build a DICompositeType with the given ODR identifier.
1154 ///
1155 /// Looks up the mapped DICompositeType for the given ODR \c Identifier. If
1156 /// it doesn't exist, creates a new one. If it does exist and \a
1157 /// isForwardDecl(), and the new arguments would be a definition, mutates the
1158 /// the type in place. In either case, returns the type.
1159 ///
1160 /// If not \a LLVMContext::isODRUniquingDebugTypes(), this function returns
1161 /// nullptr.
1162 static DICompositeType *
1163 buildODRType(LLVMContext &Context, MDString &Identifier, unsigned Tag,
1164 MDString *Name, Metadata *File, unsigned Line, Metadata *Scope,
1165 Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits,
1166 uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements,
1167 unsigned RuntimeLang, Metadata *VTableHolder,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001168 Metadata *TemplateParams, Metadata *Discriminator,
1169 Metadata *DataLocation, Metadata *Associated,
1170 Metadata *Allocated, Metadata *Rank);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001171
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001172 DIType *getBaseType() const { return cast_or_null<DIType>(getRawBaseType()); }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001173 DINodeArray getElements() const {
1174 return cast_or_null<MDTuple>(getRawElements());
1175 }
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001176 DIType *getVTableHolder() const {
1177 return cast_or_null<DIType>(getRawVTableHolder());
1178 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001179 DITemplateParameterArray getTemplateParams() const {
1180 return cast_or_null<MDTuple>(getRawTemplateParams());
1181 }
1182 StringRef getIdentifier() const { return getStringOperand(7); }
1183 unsigned getRuntimeLang() const { return RuntimeLang; }
1184
1185 Metadata *getRawBaseType() const { return getOperand(3); }
1186 Metadata *getRawElements() const { return getOperand(4); }
1187 Metadata *getRawVTableHolder() const { return getOperand(5); }
1188 Metadata *getRawTemplateParams() const { return getOperand(6); }
1189 MDString *getRawIdentifier() const { return getOperandAs<MDString>(7); }
1190 Metadata *getRawDiscriminator() const { return getOperand(8); }
1191 DIDerivedType *getDiscriminator() const { return getOperandAs<DIDerivedType>(8); }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001192 Metadata *getRawDataLocation() const { return getOperand(9); }
1193 DIVariable *getDataLocation() const {
1194 return dyn_cast_or_null<DIVariable>(getRawDataLocation());
1195 }
1196 DIExpression *getDataLocationExp() const {
1197 return dyn_cast_or_null<DIExpression>(getRawDataLocation());
1198 }
1199 Metadata *getRawAssociated() const { return getOperand(10); }
1200 DIVariable *getAssociated() const {
1201 return dyn_cast_or_null<DIVariable>(getRawAssociated());
1202 }
1203 DIExpression *getAssociatedExp() const {
1204 return dyn_cast_or_null<DIExpression>(getRawAssociated());
1205 }
1206 Metadata *getRawAllocated() const { return getOperand(11); }
1207 DIVariable *getAllocated() const {
1208 return dyn_cast_or_null<DIVariable>(getRawAllocated());
1209 }
1210 DIExpression *getAllocatedExp() const {
1211 return dyn_cast_or_null<DIExpression>(getRawAllocated());
1212 }
1213 Metadata *getRawRank() const { return getOperand(12); }
1214 ConstantInt *getRankConst() const {
1215 if (auto *MD = dyn_cast_or_null<ConstantAsMetadata>(getRawRank()))
1216 return dyn_cast_or_null<ConstantInt>(MD->getValue());
1217 return nullptr;
1218 }
1219 DIExpression *getRankExp() const {
1220 return dyn_cast_or_null<DIExpression>(getRawRank());
1221 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001222
1223 /// Replace operands.
1224 ///
1225 /// If this \a isUniqued() and not \a isResolved(), on a uniquing collision
1226 /// this will be RAUW'ed and deleted. Use a \a TrackingMDRef to keep track
1227 /// of its movement if necessary.
1228 /// @{
1229 void replaceElements(DINodeArray Elements) {
1230#ifndef NDEBUG
1231 for (DINode *Op : getElements())
1232 assert(is_contained(Elements->operands(), Op) &&
1233 "Lost a member during member list replacement");
1234#endif
1235 replaceOperandWith(4, Elements.get());
1236 }
1237
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001238 void replaceVTableHolder(DIType *VTableHolder) {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001239 replaceOperandWith(5, VTableHolder);
1240 }
1241
1242 void replaceTemplateParams(DITemplateParameterArray TemplateParams) {
1243 replaceOperandWith(6, TemplateParams.get());
1244 }
1245 /// @}
1246
1247 static bool classof(const Metadata *MD) {
1248 return MD->getMetadataID() == DICompositeTypeKind;
1249 }
1250};
1251
1252/// Type array for a subprogram.
1253///
1254/// TODO: Fold the array of types in directly as operands.
1255class DISubroutineType : public DIType {
1256 friend class LLVMContextImpl;
1257 friend class MDNode;
1258
1259 /// The calling convention used with DW_AT_calling_convention. Actually of
1260 /// type dwarf::CallingConvention.
1261 uint8_t CC;
1262
1263 DISubroutineType(LLVMContext &C, StorageType Storage, DIFlags Flags,
1264 uint8_t CC, ArrayRef<Metadata *> Ops)
1265 : DIType(C, DISubroutineTypeKind, Storage, dwarf::DW_TAG_subroutine_type,
1266 0, 0, 0, 0, Flags, Ops),
1267 CC(CC) {}
1268 ~DISubroutineType() = default;
1269
1270 static DISubroutineType *getImpl(LLVMContext &Context, DIFlags Flags,
1271 uint8_t CC, DITypeRefArray TypeArray,
1272 StorageType Storage,
1273 bool ShouldCreate = true) {
1274 return getImpl(Context, Flags, CC, TypeArray.get(), Storage, ShouldCreate);
1275 }
1276 static DISubroutineType *getImpl(LLVMContext &Context, DIFlags Flags,
1277 uint8_t CC, Metadata *TypeArray,
1278 StorageType Storage,
1279 bool ShouldCreate = true);
1280
1281 TempDISubroutineType cloneImpl() const {
1282 return getTemporary(getContext(), getFlags(), getCC(), getTypeArray());
1283 }
1284
1285public:
1286 DEFINE_MDNODE_GET(DISubroutineType,
1287 (DIFlags Flags, uint8_t CC, DITypeRefArray TypeArray),
1288 (Flags, CC, TypeArray))
1289 DEFINE_MDNODE_GET(DISubroutineType,
1290 (DIFlags Flags, uint8_t CC, Metadata *TypeArray),
1291 (Flags, CC, TypeArray))
1292
1293 TempDISubroutineType clone() const { return cloneImpl(); }
1294
1295 uint8_t getCC() const { return CC; }
1296
1297 DITypeRefArray getTypeArray() const {
1298 return cast_or_null<MDTuple>(getRawTypeArray());
1299 }
1300
1301 Metadata *getRawTypeArray() const { return getOperand(3); }
1302
1303 static bool classof(const Metadata *MD) {
1304 return MD->getMetadataID() == DISubroutineTypeKind;
1305 }
1306};
1307
1308/// Compile unit.
1309class DICompileUnit : public DIScope {
1310 friend class LLVMContextImpl;
1311 friend class MDNode;
1312
1313public:
1314 enum DebugEmissionKind : unsigned {
1315 NoDebug = 0,
1316 FullDebug,
1317 LineTablesOnly,
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001318 DebugDirectivesOnly,
1319 LastEmissionKind = DebugDirectivesOnly
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001320 };
1321
Andrew Scull0372a572018-11-16 15:47:06 +00001322 enum class DebugNameTableKind : unsigned {
1323 Default = 0,
1324 GNU = 1,
1325 None = 2,
1326 LastDebugNameTableKind = None
1327 };
1328
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001329 static Optional<DebugEmissionKind> getEmissionKind(StringRef Str);
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001330 static const char *emissionKindString(DebugEmissionKind EK);
Andrew Scull0372a572018-11-16 15:47:06 +00001331 static Optional<DebugNameTableKind> getNameTableKind(StringRef Str);
1332 static const char *nameTableKindString(DebugNameTableKind PK);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001333
1334private:
1335 unsigned SourceLanguage;
1336 bool IsOptimized;
1337 unsigned RuntimeVersion;
1338 unsigned EmissionKind;
1339 uint64_t DWOId;
1340 bool SplitDebugInlining;
1341 bool DebugInfoForProfiling;
Andrew Scull0372a572018-11-16 15:47:06 +00001342 unsigned NameTableKind;
Andrew Walbran16937d02019-10-22 13:54:20 +01001343 bool RangesBaseAddress;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001344
1345 DICompileUnit(LLVMContext &C, StorageType Storage, unsigned SourceLanguage,
1346 bool IsOptimized, unsigned RuntimeVersion,
1347 unsigned EmissionKind, uint64_t DWOId, bool SplitDebugInlining,
Andrew Scull0372a572018-11-16 15:47:06 +00001348 bool DebugInfoForProfiling, unsigned NameTableKind,
Andrew Walbran16937d02019-10-22 13:54:20 +01001349 bool RangesBaseAddress, ArrayRef<Metadata *> Ops)
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001350 : DIScope(C, DICompileUnitKind, Storage, dwarf::DW_TAG_compile_unit, Ops),
1351 SourceLanguage(SourceLanguage), IsOptimized(IsOptimized),
1352 RuntimeVersion(RuntimeVersion), EmissionKind(EmissionKind),
1353 DWOId(DWOId), SplitDebugInlining(SplitDebugInlining),
Andrew Scull0372a572018-11-16 15:47:06 +00001354 DebugInfoForProfiling(DebugInfoForProfiling),
Andrew Walbran16937d02019-10-22 13:54:20 +01001355 NameTableKind(NameTableKind), RangesBaseAddress(RangesBaseAddress) {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001356 assert(Storage != Uniqued);
1357 }
1358 ~DICompileUnit() = default;
1359
1360 static DICompileUnit *
1361 getImpl(LLVMContext &Context, unsigned SourceLanguage, DIFile *File,
1362 StringRef Producer, bool IsOptimized, StringRef Flags,
1363 unsigned RuntimeVersion, StringRef SplitDebugFilename,
1364 unsigned EmissionKind, DICompositeTypeArray EnumTypes,
1365 DIScopeArray RetainedTypes,
1366 DIGlobalVariableExpressionArray GlobalVariables,
1367 DIImportedEntityArray ImportedEntities, DIMacroNodeArray Macros,
1368 uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001369 unsigned NameTableKind, bool RangesBaseAddress, StringRef SysRoot,
1370 StringRef SDK, StorageType Storage, bool ShouldCreate = true) {
1371 return getImpl(
1372 Context, SourceLanguage, File, getCanonicalMDString(Context, Producer),
1373 IsOptimized, getCanonicalMDString(Context, Flags), RuntimeVersion,
1374 getCanonicalMDString(Context, SplitDebugFilename), EmissionKind,
1375 EnumTypes.get(), RetainedTypes.get(), GlobalVariables.get(),
1376 ImportedEntities.get(), Macros.get(), DWOId, SplitDebugInlining,
1377 DebugInfoForProfiling, NameTableKind, RangesBaseAddress,
1378 getCanonicalMDString(Context, SysRoot),
1379 getCanonicalMDString(Context, SDK), Storage, ShouldCreate);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001380 }
1381 static DICompileUnit *
1382 getImpl(LLVMContext &Context, unsigned SourceLanguage, Metadata *File,
1383 MDString *Producer, bool IsOptimized, MDString *Flags,
1384 unsigned RuntimeVersion, MDString *SplitDebugFilename,
1385 unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes,
1386 Metadata *GlobalVariables, Metadata *ImportedEntities,
1387 Metadata *Macros, uint64_t DWOId, bool SplitDebugInlining,
Andrew Scull0372a572018-11-16 15:47:06 +00001388 bool DebugInfoForProfiling, unsigned NameTableKind,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001389 bool RangesBaseAddress, MDString *SysRoot, MDString *SDK,
1390 StorageType Storage, bool ShouldCreate = true);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001391
1392 TempDICompileUnit cloneImpl() const {
Andrew Walbran16937d02019-10-22 13:54:20 +01001393 return getTemporary(
1394 getContext(), getSourceLanguage(), getFile(), getProducer(),
1395 isOptimized(), getFlags(), getRuntimeVersion(), getSplitDebugFilename(),
1396 getEmissionKind(), getEnumTypes(), getRetainedTypes(),
1397 getGlobalVariables(), getImportedEntities(), getMacros(), DWOId,
1398 getSplitDebugInlining(), getDebugInfoForProfiling(), getNameTableKind(),
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001399 getRangesBaseAddress(), getSysRoot(), getSDK());
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001400 }
1401
1402public:
1403 static void get() = delete;
1404 static void getIfExists() = delete;
1405
1406 DEFINE_MDNODE_GET_DISTINCT_TEMPORARY(
1407 DICompileUnit,
1408 (unsigned SourceLanguage, DIFile *File, StringRef Producer,
1409 bool IsOptimized, StringRef Flags, unsigned RuntimeVersion,
1410 StringRef SplitDebugFilename, DebugEmissionKind EmissionKind,
1411 DICompositeTypeArray EnumTypes, DIScopeArray RetainedTypes,
1412 DIGlobalVariableExpressionArray GlobalVariables,
1413 DIImportedEntityArray ImportedEntities, DIMacroNodeArray Macros,
1414 uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001415 DebugNameTableKind NameTableKind, bool RangesBaseAddress,
1416 StringRef SysRoot, StringRef SDK),
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001417 (SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion,
1418 SplitDebugFilename, EmissionKind, EnumTypes, RetainedTypes,
1419 GlobalVariables, ImportedEntities, Macros, DWOId, SplitDebugInlining,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001420 DebugInfoForProfiling, (unsigned)NameTableKind, RangesBaseAddress,
1421 SysRoot, SDK))
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001422 DEFINE_MDNODE_GET_DISTINCT_TEMPORARY(
1423 DICompileUnit,
1424 (unsigned SourceLanguage, Metadata *File, MDString *Producer,
1425 bool IsOptimized, MDString *Flags, unsigned RuntimeVersion,
1426 MDString *SplitDebugFilename, unsigned EmissionKind, Metadata *EnumTypes,
1427 Metadata *RetainedTypes, Metadata *GlobalVariables,
1428 Metadata *ImportedEntities, Metadata *Macros, uint64_t DWOId,
Andrew Scull0372a572018-11-16 15:47:06 +00001429 bool SplitDebugInlining, bool DebugInfoForProfiling,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001430 unsigned NameTableKind, bool RangesBaseAddress, MDString *SysRoot,
1431 MDString *SDK),
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001432 (SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion,
1433 SplitDebugFilename, EmissionKind, EnumTypes, RetainedTypes,
1434 GlobalVariables, ImportedEntities, Macros, DWOId, SplitDebugInlining,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001435 DebugInfoForProfiling, NameTableKind, RangesBaseAddress, SysRoot, SDK))
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001436
1437 TempDICompileUnit clone() const { return cloneImpl(); }
1438
1439 unsigned getSourceLanguage() const { return SourceLanguage; }
1440 bool isOptimized() const { return IsOptimized; }
1441 unsigned getRuntimeVersion() const { return RuntimeVersion; }
1442 DebugEmissionKind getEmissionKind() const {
1443 return (DebugEmissionKind)EmissionKind;
1444 }
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001445 bool isDebugDirectivesOnly() const {
1446 return EmissionKind == DebugDirectivesOnly;
1447 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001448 bool getDebugInfoForProfiling() const { return DebugInfoForProfiling; }
Andrew Scull0372a572018-11-16 15:47:06 +00001449 DebugNameTableKind getNameTableKind() const {
1450 return (DebugNameTableKind)NameTableKind;
1451 }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001452 bool getRangesBaseAddress() const { return RangesBaseAddress; }
1453 StringRef getProducer() const { return getStringOperand(1); }
1454 StringRef getFlags() const { return getStringOperand(2); }
1455 StringRef getSplitDebugFilename() const { return getStringOperand(3); }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001456 DICompositeTypeArray getEnumTypes() const {
1457 return cast_or_null<MDTuple>(getRawEnumTypes());
1458 }
1459 DIScopeArray getRetainedTypes() const {
1460 return cast_or_null<MDTuple>(getRawRetainedTypes());
1461 }
1462 DIGlobalVariableExpressionArray getGlobalVariables() const {
1463 return cast_or_null<MDTuple>(getRawGlobalVariables());
1464 }
1465 DIImportedEntityArray getImportedEntities() const {
1466 return cast_or_null<MDTuple>(getRawImportedEntities());
1467 }
1468 DIMacroNodeArray getMacros() const {
1469 return cast_or_null<MDTuple>(getRawMacros());
1470 }
1471 uint64_t getDWOId() const { return DWOId; }
1472 void setDWOId(uint64_t DwoId) { DWOId = DwoId; }
1473 bool getSplitDebugInlining() const { return SplitDebugInlining; }
1474 void setSplitDebugInlining(bool SplitDebugInlining) {
1475 this->SplitDebugInlining = SplitDebugInlining;
1476 }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001477 StringRef getSysRoot() const { return getStringOperand(9); }
1478 StringRef getSDK() const { return getStringOperand(10); }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001479
1480 MDString *getRawProducer() const { return getOperandAs<MDString>(1); }
1481 MDString *getRawFlags() const { return getOperandAs<MDString>(2); }
1482 MDString *getRawSplitDebugFilename() const {
1483 return getOperandAs<MDString>(3);
1484 }
1485 Metadata *getRawEnumTypes() const { return getOperand(4); }
1486 Metadata *getRawRetainedTypes() const { return getOperand(5); }
1487 Metadata *getRawGlobalVariables() const { return getOperand(6); }
1488 Metadata *getRawImportedEntities() const { return getOperand(7); }
1489 Metadata *getRawMacros() const { return getOperand(8); }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001490 MDString *getRawSysRoot() const { return getOperandAs<MDString>(9); }
1491 MDString *getRawSDK() const { return getOperandAs<MDString>(10); }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001492
1493 /// Replace arrays.
1494 ///
1495 /// If this \a isUniqued() and not \a isResolved(), it will be RAUW'ed and
1496 /// deleted on a uniquing collision. In practice, uniquing collisions on \a
1497 /// DICompileUnit should be fairly rare.
1498 /// @{
1499 void replaceEnumTypes(DICompositeTypeArray N) {
1500 replaceOperandWith(4, N.get());
1501 }
1502 void replaceRetainedTypes(DITypeArray N) {
1503 replaceOperandWith(5, N.get());
1504 }
1505 void replaceGlobalVariables(DIGlobalVariableExpressionArray N) {
1506 replaceOperandWith(6, N.get());
1507 }
1508 void replaceImportedEntities(DIImportedEntityArray N) {
1509 replaceOperandWith(7, N.get());
1510 }
1511 void replaceMacros(DIMacroNodeArray N) { replaceOperandWith(8, N.get()); }
1512 /// @}
1513
1514 static bool classof(const Metadata *MD) {
1515 return MD->getMetadataID() == DICompileUnitKind;
1516 }
1517};
1518
1519/// A scope for locals.
1520///
1521/// A legal scope for lexical blocks, local variables, and debug info
1522/// locations. Subclasses are \a DISubprogram, \a DILexicalBlock, and \a
1523/// DILexicalBlockFile.
1524class DILocalScope : public DIScope {
1525protected:
1526 DILocalScope(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
1527 ArrayRef<Metadata *> Ops)
1528 : DIScope(C, ID, Storage, Tag, Ops) {}
1529 ~DILocalScope() = default;
1530
1531public:
1532 /// Get the subprogram for this scope.
1533 ///
1534 /// Return this if it's an \a DISubprogram; otherwise, look up the scope
1535 /// chain.
1536 DISubprogram *getSubprogram() const;
1537
1538 /// Get the first non DILexicalBlockFile scope of this scope.
1539 ///
1540 /// Return this if it's not a \a DILexicalBlockFIle; otherwise, look up the
1541 /// scope chain.
1542 DILocalScope *getNonLexicalBlockFileScope() const;
1543
1544 static bool classof(const Metadata *MD) {
1545 return MD->getMetadataID() == DISubprogramKind ||
1546 MD->getMetadataID() == DILexicalBlockKind ||
1547 MD->getMetadataID() == DILexicalBlockFileKind;
1548 }
1549};
1550
1551/// Debug location.
1552///
1553/// A debug location in source code, used for debug info and otherwise.
1554class DILocation : public MDNode {
1555 friend class LLVMContextImpl;
1556 friend class MDNode;
1557
1558 DILocation(LLVMContext &C, StorageType Storage, unsigned Line,
Andrew Scull0372a572018-11-16 15:47:06 +00001559 unsigned Column, ArrayRef<Metadata *> MDs, bool ImplicitCode);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001560 ~DILocation() { dropAllReferences(); }
1561
1562 static DILocation *getImpl(LLVMContext &Context, unsigned Line,
1563 unsigned Column, Metadata *Scope,
Andrew Scull0372a572018-11-16 15:47:06 +00001564 Metadata *InlinedAt, bool ImplicitCode,
1565 StorageType Storage, bool ShouldCreate = true);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001566 static DILocation *getImpl(LLVMContext &Context, unsigned Line,
1567 unsigned Column, DILocalScope *Scope,
Andrew Scull0372a572018-11-16 15:47:06 +00001568 DILocation *InlinedAt, bool ImplicitCode,
1569 StorageType Storage, bool ShouldCreate = true) {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001570 return getImpl(Context, Line, Column, static_cast<Metadata *>(Scope),
Andrew Scull0372a572018-11-16 15:47:06 +00001571 static_cast<Metadata *>(InlinedAt), ImplicitCode, Storage,
1572 ShouldCreate);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001573 }
1574
1575 /// With a given unsigned int \p U, use up to 13 bits to represent it.
1576 /// old_bit 1~5 --> new_bit 1~5
1577 /// old_bit 6~12 --> new_bit 7~13
1578 /// new_bit_6 is 0 if higher bits (7~13) are all 0
1579 static unsigned getPrefixEncodingFromUnsigned(unsigned U) {
1580 U &= 0xfff;
1581 return U > 0x1f ? (((U & 0xfe0) << 1) | (U & 0x1f) | 0x20) : U;
1582 }
1583
1584 /// Reverse transformation as getPrefixEncodingFromUnsigned.
1585 static unsigned getUnsignedFromPrefixEncoding(unsigned U) {
Andrew Walbran16937d02019-10-22 13:54:20 +01001586 if (U & 1)
1587 return 0;
1588 U >>= 1;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001589 return (U & 0x20) ? (((U >> 1) & 0xfe0) | (U & 0x1f)) : (U & 0x1f);
1590 }
1591
1592 /// Returns the next component stored in discriminator.
1593 static unsigned getNextComponentInDiscriminator(unsigned D) {
1594 if ((D & 1) == 0)
1595 return D >> ((D & 0x40) ? 14 : 7);
1596 else
1597 return D >> 1;
1598 }
1599
1600 TempDILocation cloneImpl() const {
1601 // Get the raw scope/inlinedAt since it is possible to invoke this on
1602 // a DILocation containing temporary metadata.
1603 return getTemporary(getContext(), getLine(), getColumn(), getRawScope(),
Andrew Scull0372a572018-11-16 15:47:06 +00001604 getRawInlinedAt(), isImplicitCode());
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001605 }
1606
Andrew Walbran16937d02019-10-22 13:54:20 +01001607 static unsigned encodeComponent(unsigned C) {
1608 return (C == 0) ? 1U : (getPrefixEncodingFromUnsigned(C) << 1);
1609 }
1610
1611 static unsigned encodingBits(unsigned C) {
1612 return (C == 0) ? 1 : (C > 0x1f ? 14 : 7);
1613 }
1614
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001615public:
1616 // Disallow replacing operands.
1617 void replaceOperandWith(unsigned I, Metadata *New) = delete;
1618
1619 DEFINE_MDNODE_GET(DILocation,
1620 (unsigned Line, unsigned Column, Metadata *Scope,
Andrew Scull0372a572018-11-16 15:47:06 +00001621 Metadata *InlinedAt = nullptr, bool ImplicitCode = false),
1622 (Line, Column, Scope, InlinedAt, ImplicitCode))
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001623 DEFINE_MDNODE_GET(DILocation,
1624 (unsigned Line, unsigned Column, DILocalScope *Scope,
Andrew Scull0372a572018-11-16 15:47:06 +00001625 DILocation *InlinedAt = nullptr,
1626 bool ImplicitCode = false),
1627 (Line, Column, Scope, InlinedAt, ImplicitCode))
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001628
1629 /// Return a (temporary) clone of this.
1630 TempDILocation clone() const { return cloneImpl(); }
1631
1632 unsigned getLine() const { return SubclassData32; }
1633 unsigned getColumn() const { return SubclassData16; }
1634 DILocalScope *getScope() const { return cast<DILocalScope>(getRawScope()); }
1635
1636 DILocation *getInlinedAt() const {
1637 return cast_or_null<DILocation>(getRawInlinedAt());
1638 }
1639
Andrew Scull0372a572018-11-16 15:47:06 +00001640 /// Check if the location corresponds to an implicit code.
1641 /// When the ImplicitCode flag is true, it means that the Instruction
1642 /// with this DILocation has been added by the front-end but it hasn't been
1643 /// written explicitly by the user (e.g. cleanup stuff in C++ put on a closing
1644 /// bracket). It's useful for code coverage to not show a counter on "empty"
1645 /// lines.
1646 bool isImplicitCode() const { return ImplicitCode; }
1647 void setImplicitCode(bool ImplicitCode) { this->ImplicitCode = ImplicitCode; }
1648
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001649 DIFile *getFile() const { return getScope()->getFile(); }
1650 StringRef getFilename() const { return getScope()->getFilename(); }
1651 StringRef getDirectory() const { return getScope()->getDirectory(); }
1652 Optional<StringRef> getSource() const { return getScope()->getSource(); }
1653
1654 /// Get the scope where this is inlined.
1655 ///
1656 /// Walk through \a getInlinedAt() and return \a getScope() from the deepest
1657 /// location.
1658 DILocalScope *getInlinedAtScope() const {
1659 if (auto *IA = getInlinedAt())
1660 return IA->getInlinedAtScope();
1661 return getScope();
1662 }
1663
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001664 /// Get the DWARF discriminator.
1665 ///
1666 /// DWARF discriminators distinguish identical file locations between
1667 /// instructions that are on different basic blocks.
1668 ///
1669 /// There are 3 components stored in discriminator, from lower bits:
1670 ///
1671 /// Base discriminator: assigned by AddDiscriminators pass to identify IRs
1672 /// that are defined by the same source line, but
1673 /// different basic blocks.
1674 /// Duplication factor: assigned by optimizations that will scale down
1675 /// the execution frequency of the original IR.
1676 /// Copy Identifier: assigned by optimizations that clones the IR.
1677 /// Each copy of the IR will be assigned an identifier.
1678 ///
1679 /// Encoding:
1680 ///
1681 /// The above 3 components are encoded into a 32bit unsigned integer in
1682 /// order. If the lowest bit is 1, the current component is empty, and the
1683 /// next component will start in the next bit. Otherwise, the current
1684 /// component is non-empty, and its content starts in the next bit. The
Andrew Walbran16937d02019-10-22 13:54:20 +01001685 /// value of each components is either 5 bit or 12 bit: if the 7th bit
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001686 /// is 0, the bit 2~6 (5 bits) are used to represent the component; if the
1687 /// 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 +01001688 /// represent the component. Thus, the number of bits used for a component
1689 /// is either 0 (if it and all the next components are empty); 1 - if it is
1690 /// empty; 7 - if its value is up to and including 0x1f (lsb and msb are both
1691 /// 0); or 14, if its value is up to and including 0x1ff. Note that the last
1692 /// component is also capped at 0x1ff, even in the case when both first
1693 /// components are 0, and we'd technically have 29 bits available.
1694 ///
1695 /// For precise control over the data being encoded in the discriminator,
1696 /// use encodeDiscriminator/decodeDiscriminator.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001697
1698 inline unsigned getDiscriminator() const;
1699
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001700 // For the regular discriminator, it stands for all empty components if all
1701 // the lowest 3 bits are non-zero and all higher 29 bits are unused(zero by
1702 // default). Here we fully leverage the higher 29 bits for pseudo probe use.
1703 // This is the format:
1704 // [2:0] - 0x7
1705 // [31:3] - pseudo probe fields guaranteed to be non-zero as a whole
1706 // So if the lower 3 bits is non-zero and the others has at least one
1707 // non-zero bit, it guarantees to be a pseudo probe discriminator
1708 inline static bool isPseudoProbeDiscriminator(unsigned Discriminator) {
1709 return ((Discriminator & 0x7) == 0x7) && (Discriminator & 0xFFFFFFF8);
1710 }
1711
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001712 /// Returns a new DILocation with updated \p Discriminator.
1713 inline const DILocation *cloneWithDiscriminator(unsigned Discriminator) const;
1714
Andrew Walbran16937d02019-10-22 13:54:20 +01001715 /// Returns a new DILocation with updated base discriminator \p BD. Only the
1716 /// base discriminator is set in the new DILocation, the other encoded values
1717 /// are elided.
1718 /// If the discriminator cannot be encoded, the function returns None.
1719 inline Optional<const DILocation *> cloneWithBaseDiscriminator(unsigned BD) const;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001720
Andrew Walbran16937d02019-10-22 13:54:20 +01001721 /// Returns the duplication factor stored in the discriminator, or 1 if no
1722 /// duplication factor (or 0) is encoded.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001723 inline unsigned getDuplicationFactor() const;
1724
1725 /// Returns the copy identifier stored in the discriminator.
1726 inline unsigned getCopyIdentifier() const;
1727
1728 /// Returns the base discriminator stored in the discriminator.
1729 inline unsigned getBaseDiscriminator() const;
1730
Andrew Walbran16937d02019-10-22 13:54:20 +01001731 /// Returns a new DILocation with duplication factor \p DF * current
1732 /// duplication factor encoded in the discriminator. The current duplication
1733 /// factor is as defined by getDuplicationFactor().
1734 /// Returns None if encoding failed.
1735 inline Optional<const DILocation *> cloneByMultiplyingDuplicationFactor(unsigned DF) const;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001736
1737 /// When two instructions are combined into a single instruction we also
1738 /// need to combine the original locations into a single location.
1739 ///
1740 /// When the locations are the same we can use either location. When they
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001741 /// differ, we need a third location which is distinct from either. If they
1742 /// have the same file/line but have a different discriminator we could
1743 /// create a location with a new discriminator. If they are from different
1744 /// files/lines the location is ambiguous and can't be represented in a line
1745 /// entry. In this case, if \p GenerateLocation is true, we will set the
1746 /// merged debug location as line 0 of the nearest common scope where the two
1747 /// locations are inlined from.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001748 ///
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001749 /// \p GenerateLocation: Whether the merged location can be generated when
1750 /// \p LocA and \p LocB differ.
Andrew Scull0372a572018-11-16 15:47:06 +00001751 static const DILocation *getMergedLocation(const DILocation *LocA,
1752 const DILocation *LocB);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001753
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001754 /// Try to combine the vector of locations passed as input in a single one.
1755 /// This function applies getMergedLocation() repeatedly left-to-right.
1756 ///
1757 /// \p Locs: The locations to be merged.
1758 static
1759 const DILocation *getMergedLocations(ArrayRef<const DILocation *> Locs);
1760
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001761 /// Returns the base discriminator for a given encoded discriminator \p D.
1762 static unsigned getBaseDiscriminatorFromDiscriminator(unsigned D) {
Andrew Walbran16937d02019-10-22 13:54:20 +01001763 return getUnsignedFromPrefixEncoding(D);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001764 }
1765
Andrew Walbran16937d02019-10-22 13:54:20 +01001766 /// Raw encoding of the discriminator. APIs such as cloneWithDuplicationFactor
1767 /// have certain special case behavior (e.g. treating empty duplication factor
1768 /// as the value '1').
1769 /// This API, in conjunction with cloneWithDiscriminator, may be used to encode
1770 /// the raw values provided. \p BD: base discriminator \p DF: duplication factor
1771 /// \p CI: copy index
1772 /// The return is None if the values cannot be encoded in 32 bits - for
1773 /// example, values for BD or DF larger than 12 bits. Otherwise, the return
1774 /// is the encoded value.
1775 static Optional<unsigned> encodeDiscriminator(unsigned BD, unsigned DF, unsigned CI);
1776
1777 /// Raw decoder for values in an encoded discriminator D.
1778 static void decodeDiscriminator(unsigned D, unsigned &BD, unsigned &DF,
1779 unsigned &CI);
1780
1781 /// Returns the duplication factor for a given encoded discriminator \p D, or
1782 /// 1 if no value or 0 is encoded.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001783 static unsigned getDuplicationFactorFromDiscriminator(unsigned D) {
1784 D = getNextComponentInDiscriminator(D);
Andrew Walbran16937d02019-10-22 13:54:20 +01001785 unsigned Ret = getUnsignedFromPrefixEncoding(D);
1786 if (Ret == 0)
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001787 return 1;
Andrew Walbran16937d02019-10-22 13:54:20 +01001788 return Ret;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001789 }
1790
1791 /// Returns the copy identifier for a given encoded discriminator \p D.
1792 static unsigned getCopyIdentifierFromDiscriminator(unsigned D) {
1793 return getUnsignedFromPrefixEncoding(getNextComponentInDiscriminator(
1794 getNextComponentInDiscriminator(D)));
1795 }
1796
1797
1798 Metadata *getRawScope() const { return getOperand(0); }
1799 Metadata *getRawInlinedAt() const {
1800 if (getNumOperands() == 2)
1801 return getOperand(1);
1802 return nullptr;
1803 }
1804
1805 static bool classof(const Metadata *MD) {
1806 return MD->getMetadataID() == DILocationKind;
1807 }
1808};
1809
1810/// Subprogram description.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001811class DISubprogram : public DILocalScope {
1812 friend class LLVMContextImpl;
1813 friend class MDNode;
1814
1815 unsigned Line;
1816 unsigned ScopeLine;
1817 unsigned VirtualIndex;
1818
1819 /// In the MS ABI, the implicit 'this' parameter is adjusted in the prologue
1820 /// of method overrides from secondary bases by this amount. It may be
1821 /// negative.
1822 int ThisAdjustment;
1823
Andrew Walbran16937d02019-10-22 13:54:20 +01001824public:
1825 /// Debug info subprogram flags.
1826 enum DISPFlags : uint32_t {
1827#define HANDLE_DISP_FLAG(ID, NAME) SPFlag##NAME = ID,
1828#define DISP_FLAG_LARGEST_NEEDED
1829#include "llvm/IR/DebugInfoFlags.def"
1830 SPFlagNonvirtual = SPFlagZero,
1831 SPFlagVirtuality = SPFlagVirtual | SPFlagPureVirtual,
1832 LLVM_MARK_AS_BITMASK_ENUM(SPFlagLargest)
1833 };
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001834
Andrew Walbran16937d02019-10-22 13:54:20 +01001835 static DISPFlags getFlag(StringRef Flag);
1836 static StringRef getFlagString(DISPFlags Flag);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001837
Andrew Walbran16937d02019-10-22 13:54:20 +01001838 /// Split up a flags bitfield for easier printing.
1839 ///
1840 /// Split \c Flags into \c SplitFlags, a vector of its components. Returns
1841 /// any remaining (unrecognized) bits.
1842 static DISPFlags splitFlags(DISPFlags Flags,
1843 SmallVectorImpl<DISPFlags> &SplitFlags);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001844
Andrew Walbran16937d02019-10-22 13:54:20 +01001845 // Helper for converting old bitfields to new flags word.
1846 static DISPFlags toSPFlags(bool IsLocalToUnit, bool IsDefinition,
1847 bool IsOptimized,
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001848 unsigned Virtuality = SPFlagNonvirtual,
1849 bool IsMainSubprogram = false) {
Andrew Walbran16937d02019-10-22 13:54:20 +01001850 // We're assuming virtuality is the low-order field.
1851 static_assert(
1852 int(SPFlagVirtual) == int(dwarf::DW_VIRTUALITY_virtual) &&
1853 int(SPFlagPureVirtual) == int(dwarf::DW_VIRTUALITY_pure_virtual),
1854 "Virtuality constant mismatch");
1855 return static_cast<DISPFlags>(
1856 (Virtuality & SPFlagVirtuality) |
1857 (IsLocalToUnit ? SPFlagLocalToUnit : SPFlagZero) |
1858 (IsDefinition ? SPFlagDefinition : SPFlagZero) |
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001859 (IsOptimized ? SPFlagOptimized : SPFlagZero) |
1860 (IsMainSubprogram ? SPFlagMainSubprogram : SPFlagZero));
Andrew Walbran16937d02019-10-22 13:54:20 +01001861 }
1862
1863private:
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001864 DIFlags Flags;
Andrew Walbran16937d02019-10-22 13:54:20 +01001865 DISPFlags SPFlags;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001866
1867 DISubprogram(LLVMContext &C, StorageType Storage, unsigned Line,
Andrew Walbran16937d02019-10-22 13:54:20 +01001868 unsigned ScopeLine, unsigned VirtualIndex, int ThisAdjustment,
1869 DIFlags Flags, DISPFlags SPFlags, ArrayRef<Metadata *> Ops)
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001870 : DILocalScope(C, DISubprogramKind, Storage, dwarf::DW_TAG_subprogram,
1871 Ops),
1872 Line(Line), ScopeLine(ScopeLine), VirtualIndex(VirtualIndex),
Andrew Walbran16937d02019-10-22 13:54:20 +01001873 ThisAdjustment(ThisAdjustment), Flags(Flags), SPFlags(SPFlags) {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001874 static_assert(dwarf::DW_VIRTUALITY_max < 4, "Virtuality out of range");
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001875 }
1876 ~DISubprogram() = default;
1877
1878 static DISubprogram *
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001879 getImpl(LLVMContext &Context, DIScope *Scope, StringRef Name,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001880 StringRef LinkageName, DIFile *File, unsigned Line,
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001881 DISubroutineType *Type, unsigned ScopeLine, DIType *ContainingType,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001882 unsigned VirtualIndex, int ThisAdjustment, DIFlags Flags,
Andrew Walbran16937d02019-10-22 13:54:20 +01001883 DISPFlags SPFlags, DICompileUnit *Unit,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001884 DITemplateParameterArray TemplateParams, DISubprogram *Declaration,
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001885 DINodeArray RetainedNodes, DITypeArray ThrownTypes,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001886 StorageType Storage, bool ShouldCreate = true) {
1887 return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
1888 getCanonicalMDString(Context, LinkageName), File, Line, Type,
Andrew Walbran16937d02019-10-22 13:54:20 +01001889 ScopeLine, ContainingType, VirtualIndex, ThisAdjustment,
1890 Flags, SPFlags, Unit, TemplateParams.get(), Declaration,
1891 RetainedNodes.get(), ThrownTypes.get(), Storage,
1892 ShouldCreate);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001893 }
Andrew Walbran16937d02019-10-22 13:54:20 +01001894 static DISubprogram *getImpl(LLVMContext &Context, Metadata *Scope,
1895 MDString *Name, MDString *LinkageName,
1896 Metadata *File, unsigned Line, Metadata *Type,
1897 unsigned ScopeLine, Metadata *ContainingType,
1898 unsigned VirtualIndex, int ThisAdjustment,
1899 DIFlags Flags, DISPFlags SPFlags, Metadata *Unit,
1900 Metadata *TemplateParams, Metadata *Declaration,
1901 Metadata *RetainedNodes, Metadata *ThrownTypes,
1902 StorageType Storage, bool ShouldCreate = true);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001903
1904 TempDISubprogram cloneImpl() const {
1905 return getTemporary(getContext(), getScope(), getName(), getLinkageName(),
Andrew Walbran16937d02019-10-22 13:54:20 +01001906 getFile(), getLine(), getType(), getScopeLine(),
1907 getContainingType(), getVirtualIndex(),
1908 getThisAdjustment(), getFlags(), getSPFlags(),
1909 getUnit(), getTemplateParams(), getDeclaration(),
1910 getRetainedNodes(), getThrownTypes());
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001911 }
1912
1913public:
Andrew Walbran16937d02019-10-22 13:54:20 +01001914 DEFINE_MDNODE_GET(
1915 DISubprogram,
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001916 (DIScope * Scope, StringRef Name, StringRef LinkageName, DIFile *File,
Andrew Walbran16937d02019-10-22 13:54:20 +01001917 unsigned Line, DISubroutineType *Type, unsigned ScopeLine,
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001918 DIType *ContainingType, unsigned VirtualIndex, int ThisAdjustment,
Andrew Walbran16937d02019-10-22 13:54:20 +01001919 DIFlags Flags, DISPFlags SPFlags, DICompileUnit *Unit,
1920 DITemplateParameterArray TemplateParams = nullptr,
1921 DISubprogram *Declaration = nullptr, DINodeArray RetainedNodes = nullptr,
1922 DITypeArray ThrownTypes = nullptr),
1923 (Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType,
1924 VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams,
1925 Declaration, RetainedNodes, ThrownTypes))
1926
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001927 DEFINE_MDNODE_GET(
1928 DISubprogram,
1929 (Metadata * Scope, MDString *Name, MDString *LinkageName, Metadata *File,
Andrew Walbran16937d02019-10-22 13:54:20 +01001930 unsigned Line, Metadata *Type, unsigned ScopeLine,
1931 Metadata *ContainingType, unsigned VirtualIndex, int ThisAdjustment,
1932 DIFlags Flags, DISPFlags SPFlags, Metadata *Unit,
1933 Metadata *TemplateParams = nullptr, Metadata *Declaration = nullptr,
1934 Metadata *RetainedNodes = nullptr, Metadata *ThrownTypes = nullptr),
1935 (Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType,
1936 VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams,
1937 Declaration, RetainedNodes, ThrownTypes))
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001938
1939 TempDISubprogram clone() const { return cloneImpl(); }
1940
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001941 /// Returns a new temporary DISubprogram with updated Flags
1942 TempDISubprogram cloneWithFlags(DIFlags NewFlags) const {
1943 auto NewSP = clone();
1944 NewSP->Flags = NewFlags;
1945 return NewSP;
1946 }
1947
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001948public:
1949 unsigned getLine() const { return Line; }
Andrew Walbran16937d02019-10-22 13:54:20 +01001950 unsigned getVirtuality() const { return getSPFlags() & SPFlagVirtuality; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001951 unsigned getVirtualIndex() const { return VirtualIndex; }
1952 int getThisAdjustment() const { return ThisAdjustment; }
1953 unsigned getScopeLine() const { return ScopeLine; }
1954 DIFlags getFlags() const { return Flags; }
Andrew Walbran16937d02019-10-22 13:54:20 +01001955 DISPFlags getSPFlags() const { return SPFlags; }
1956 bool isLocalToUnit() const { return getSPFlags() & SPFlagLocalToUnit; }
1957 bool isDefinition() const { return getSPFlags() & SPFlagDefinition; }
1958 bool isOptimized() const { return getSPFlags() & SPFlagOptimized; }
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001959 bool isMainSubprogram() const { return getSPFlags() & SPFlagMainSubprogram; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001960
1961 bool isArtificial() const { return getFlags() & FlagArtificial; }
1962 bool isPrivate() const {
1963 return (getFlags() & FlagAccessibility) == FlagPrivate;
1964 }
1965 bool isProtected() const {
1966 return (getFlags() & FlagAccessibility) == FlagProtected;
1967 }
1968 bool isPublic() const {
1969 return (getFlags() & FlagAccessibility) == FlagPublic;
1970 }
1971 bool isExplicit() const { return getFlags() & FlagExplicit; }
1972 bool isPrototyped() const { return getFlags() & FlagPrototyped; }
Andrew Scull0372a572018-11-16 15:47:06 +00001973 bool areAllCallsDescribed() const {
1974 return getFlags() & FlagAllCallsDescribed;
1975 }
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001976 bool isPure() const { return getSPFlags() & SPFlagPure; }
1977 bool isElemental() const { return getSPFlags() & SPFlagElemental; }
1978 bool isRecursive() const { return getSPFlags() & SPFlagRecursive; }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001979 bool isObjCDirect() const { return getSPFlags() & SPFlagObjCDirect; }
1980
1981 /// Check if this is deleted member function.
1982 ///
1983 /// Return true if this subprogram is a C++11 special
1984 /// member function declared deleted.
1985 bool isDeleted() const { return getSPFlags() & SPFlagDeleted; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001986
1987 /// Check if this is reference-qualified.
1988 ///
1989 /// Return true if this subprogram is a C++11 reference-qualified non-static
1990 /// member function (void foo() &).
1991 bool isLValueReference() const { return getFlags() & FlagLValueReference; }
1992
1993 /// Check if this is rvalue-reference-qualified.
1994 ///
1995 /// Return true if this subprogram is a C++11 rvalue-reference-qualified
1996 /// non-static member function (void foo() &&).
1997 bool isRValueReference() const { return getFlags() & FlagRValueReference; }
1998
1999 /// Check if this is marked as noreturn.
2000 ///
2001 /// Return true if this subprogram is C++11 noreturn or C11 _Noreturn
2002 bool isNoReturn() const { return getFlags() & FlagNoReturn; }
2003
Andrew Scullcdfcccc2018-10-05 20:58:37 +01002004 // Check if this routine is a compiler-generated thunk.
2005 //
2006 // Returns true if this subprogram is a thunk generated by the compiler.
2007 bool isThunk() const { return getFlags() & FlagThunk; }
2008
Andrew Walbran3d2c1972020-04-07 12:24:26 +01002009 DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002010
2011 StringRef getName() const { return getStringOperand(2); }
2012 StringRef getLinkageName() const { return getStringOperand(3); }
2013
2014 DISubroutineType *getType() const {
2015 return cast_or_null<DISubroutineType>(getRawType());
2016 }
Andrew Walbran3d2c1972020-04-07 12:24:26 +01002017 DIType *getContainingType() const {
2018 return cast_or_null<DIType>(getRawContainingType());
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002019 }
2020
2021 DICompileUnit *getUnit() const {
2022 return cast_or_null<DICompileUnit>(getRawUnit());
2023 }
2024 void replaceUnit(DICompileUnit *CU) { replaceOperandWith(5, CU); }
2025 DITemplateParameterArray getTemplateParams() const {
2026 return cast_or_null<MDTuple>(getRawTemplateParams());
2027 }
2028 DISubprogram *getDeclaration() const {
2029 return cast_or_null<DISubprogram>(getRawDeclaration());
2030 }
Andrew Scullcdfcccc2018-10-05 20:58:37 +01002031 DINodeArray getRetainedNodes() const {
2032 return cast_or_null<MDTuple>(getRawRetainedNodes());
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002033 }
2034 DITypeArray getThrownTypes() const {
2035 return cast_or_null<MDTuple>(getRawThrownTypes());
2036 }
2037
2038 Metadata *getRawScope() const { return getOperand(1); }
2039 MDString *getRawName() const { return getOperandAs<MDString>(2); }
2040 MDString *getRawLinkageName() const { return getOperandAs<MDString>(3); }
2041 Metadata *getRawType() const { return getOperand(4); }
2042 Metadata *getRawUnit() const { return getOperand(5); }
2043 Metadata *getRawDeclaration() const { return getOperand(6); }
Andrew Scullcdfcccc2018-10-05 20:58:37 +01002044 Metadata *getRawRetainedNodes() const { return getOperand(7); }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002045 Metadata *getRawContainingType() const {
2046 return getNumOperands() > 8 ? getOperandAs<Metadata>(8) : nullptr;
2047 }
2048 Metadata *getRawTemplateParams() const {
2049 return getNumOperands() > 9 ? getOperandAs<Metadata>(9) : nullptr;
2050 }
2051 Metadata *getRawThrownTypes() const {
2052 return getNumOperands() > 10 ? getOperandAs<Metadata>(10) : nullptr;
2053 }
2054
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02002055 void replaceRawLinkageName(MDString *LinkageName) {
2056 replaceOperandWith(3, LinkageName);
2057 }
2058
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002059 /// Check if this subprogram describes the given function.
2060 ///
2061 /// FIXME: Should this be looking through bitcasts?
2062 bool describes(const Function *F) const;
2063
2064 static bool classof(const Metadata *MD) {
2065 return MD->getMetadataID() == DISubprogramKind;
2066 }
2067};
2068
2069class DILexicalBlockBase : public DILocalScope {
2070protected:
2071 DILexicalBlockBase(LLVMContext &C, unsigned ID, StorageType Storage,
2072 ArrayRef<Metadata *> Ops)
2073 : DILocalScope(C, ID, Storage, dwarf::DW_TAG_lexical_block, Ops) {}
2074 ~DILexicalBlockBase() = default;
2075
2076public:
2077 DILocalScope *getScope() const { return cast<DILocalScope>(getRawScope()); }
2078
2079 Metadata *getRawScope() const { return getOperand(1); }
2080
2081 static bool classof(const Metadata *MD) {
2082 return MD->getMetadataID() == DILexicalBlockKind ||
2083 MD->getMetadataID() == DILexicalBlockFileKind;
2084 }
2085};
2086
2087class DILexicalBlock : public DILexicalBlockBase {
2088 friend class LLVMContextImpl;
2089 friend class MDNode;
2090
2091 unsigned Line;
2092 uint16_t Column;
2093
2094 DILexicalBlock(LLVMContext &C, StorageType Storage, unsigned Line,
2095 unsigned Column, ArrayRef<Metadata *> Ops)
2096 : DILexicalBlockBase(C, DILexicalBlockKind, Storage, Ops), Line(Line),
2097 Column(Column) {
2098 assert(Column < (1u << 16) && "Expected 16-bit column");
2099 }
2100 ~DILexicalBlock() = default;
2101
2102 static DILexicalBlock *getImpl(LLVMContext &Context, DILocalScope *Scope,
2103 DIFile *File, unsigned Line, unsigned Column,
2104 StorageType Storage,
2105 bool ShouldCreate = true) {
2106 return getImpl(Context, static_cast<Metadata *>(Scope),
2107 static_cast<Metadata *>(File), Line, Column, Storage,
2108 ShouldCreate);
2109 }
2110
2111 static DILexicalBlock *getImpl(LLVMContext &Context, Metadata *Scope,
2112 Metadata *File, unsigned Line, unsigned Column,
2113 StorageType Storage, bool ShouldCreate = true);
2114
2115 TempDILexicalBlock cloneImpl() const {
2116 return getTemporary(getContext(), getScope(), getFile(), getLine(),
2117 getColumn());
2118 }
2119
2120public:
2121 DEFINE_MDNODE_GET(DILexicalBlock, (DILocalScope * Scope, DIFile *File,
2122 unsigned Line, unsigned Column),
2123 (Scope, File, Line, Column))
2124 DEFINE_MDNODE_GET(DILexicalBlock, (Metadata * Scope, Metadata *File,
2125 unsigned Line, unsigned Column),
2126 (Scope, File, Line, Column))
2127
2128 TempDILexicalBlock clone() const { return cloneImpl(); }
2129
2130 unsigned getLine() const { return Line; }
2131 unsigned getColumn() const { return Column; }
2132
2133 static bool classof(const Metadata *MD) {
2134 return MD->getMetadataID() == DILexicalBlockKind;
2135 }
2136};
2137
2138class DILexicalBlockFile : public DILexicalBlockBase {
2139 friend class LLVMContextImpl;
2140 friend class MDNode;
2141
2142 unsigned Discriminator;
2143
2144 DILexicalBlockFile(LLVMContext &C, StorageType Storage,
2145 unsigned Discriminator, ArrayRef<Metadata *> Ops)
2146 : DILexicalBlockBase(C, DILexicalBlockFileKind, Storage, Ops),
2147 Discriminator(Discriminator) {}
2148 ~DILexicalBlockFile() = default;
2149
2150 static DILexicalBlockFile *getImpl(LLVMContext &Context, DILocalScope *Scope,
2151 DIFile *File, unsigned Discriminator,
2152 StorageType Storage,
2153 bool ShouldCreate = true) {
2154 return getImpl(Context, static_cast<Metadata *>(Scope),
2155 static_cast<Metadata *>(File), Discriminator, Storage,
2156 ShouldCreate);
2157 }
2158
2159 static DILexicalBlockFile *getImpl(LLVMContext &Context, Metadata *Scope,
2160 Metadata *File, unsigned Discriminator,
2161 StorageType Storage,
2162 bool ShouldCreate = true);
2163
2164 TempDILexicalBlockFile cloneImpl() const {
2165 return getTemporary(getContext(), getScope(), getFile(),
2166 getDiscriminator());
2167 }
2168
2169public:
2170 DEFINE_MDNODE_GET(DILexicalBlockFile, (DILocalScope * Scope, DIFile *File,
2171 unsigned Discriminator),
2172 (Scope, File, Discriminator))
2173 DEFINE_MDNODE_GET(DILexicalBlockFile,
2174 (Metadata * Scope, Metadata *File, unsigned Discriminator),
2175 (Scope, File, Discriminator))
2176
2177 TempDILexicalBlockFile clone() const { return cloneImpl(); }
2178
2179 // TODO: Remove these once they're gone from DILexicalBlockBase.
2180 unsigned getLine() const = delete;
2181 unsigned getColumn() const = delete;
2182
2183 unsigned getDiscriminator() const { return Discriminator; }
2184
2185 static bool classof(const Metadata *MD) {
2186 return MD->getMetadataID() == DILexicalBlockFileKind;
2187 }
2188};
2189
2190unsigned DILocation::getDiscriminator() const {
2191 if (auto *F = dyn_cast<DILexicalBlockFile>(getScope()))
2192 return F->getDiscriminator();
2193 return 0;
2194}
2195
2196const DILocation *
2197DILocation::cloneWithDiscriminator(unsigned Discriminator) const {
2198 DIScope *Scope = getScope();
2199 // Skip all parent DILexicalBlockFile that already have a discriminator
2200 // assigned. We do not want to have nested DILexicalBlockFiles that have
2201 // mutliple discriminators because only the leaf DILexicalBlockFile's
2202 // dominator will be used.
2203 for (auto *LBF = dyn_cast<DILexicalBlockFile>(Scope);
2204 LBF && LBF->getDiscriminator() != 0;
2205 LBF = dyn_cast<DILexicalBlockFile>(Scope))
2206 Scope = LBF->getScope();
2207 DILexicalBlockFile *NewScope =
2208 DILexicalBlockFile::get(getContext(), Scope, getFile(), Discriminator);
2209 return DILocation::get(getContext(), getLine(), getColumn(), NewScope,
2210 getInlinedAt());
2211}
2212
2213unsigned DILocation::getBaseDiscriminator() const {
2214 return getBaseDiscriminatorFromDiscriminator(getDiscriminator());
2215}
2216
2217unsigned DILocation::getDuplicationFactor() const {
2218 return getDuplicationFactorFromDiscriminator(getDiscriminator());
2219}
2220
2221unsigned DILocation::getCopyIdentifier() const {
2222 return getCopyIdentifierFromDiscriminator(getDiscriminator());
2223}
2224
Andrew Walbran16937d02019-10-22 13:54:20 +01002225Optional<const DILocation *> DILocation::cloneWithBaseDiscriminator(unsigned D) const {
2226 unsigned BD, DF, CI;
2227 decodeDiscriminator(getDiscriminator(), BD, DF, CI);
2228 if (D == BD)
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002229 return this;
Andrew Walbran16937d02019-10-22 13:54:20 +01002230 if (Optional<unsigned> Encoded = encodeDiscriminator(D, DF, CI))
2231 return cloneWithDiscriminator(*Encoded);
2232 return None;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002233}
2234
Andrew Walbran16937d02019-10-22 13:54:20 +01002235Optional<const DILocation *> DILocation::cloneByMultiplyingDuplicationFactor(unsigned DF) const {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002236 DF *= getDuplicationFactor();
2237 if (DF <= 1)
2238 return this;
2239
2240 unsigned BD = getBaseDiscriminator();
Andrew Walbran16937d02019-10-22 13:54:20 +01002241 unsigned CI = getCopyIdentifier();
2242 if (Optional<unsigned> D = encodeDiscriminator(BD, DF, CI))
2243 return cloneWithDiscriminator(*D);
2244 return None;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002245}
2246
2247class DINamespace : public DIScope {
2248 friend class LLVMContextImpl;
2249 friend class MDNode;
2250
2251 unsigned ExportSymbols : 1;
2252
2253 DINamespace(LLVMContext &Context, StorageType Storage, bool ExportSymbols,
2254 ArrayRef<Metadata *> Ops)
2255 : DIScope(Context, DINamespaceKind, Storage, dwarf::DW_TAG_namespace,
2256 Ops),
2257 ExportSymbols(ExportSymbols) {}
2258 ~DINamespace() = default;
2259
2260 static DINamespace *getImpl(LLVMContext &Context, DIScope *Scope,
2261 StringRef Name, bool ExportSymbols,
2262 StorageType Storage, bool ShouldCreate = true) {
2263 return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
2264 ExportSymbols, Storage, ShouldCreate);
2265 }
2266 static DINamespace *getImpl(LLVMContext &Context, Metadata *Scope,
2267 MDString *Name, bool ExportSymbols,
2268 StorageType Storage, bool ShouldCreate = true);
2269
2270 TempDINamespace cloneImpl() const {
2271 return getTemporary(getContext(), getScope(), getName(),
2272 getExportSymbols());
2273 }
2274
2275public:
2276 DEFINE_MDNODE_GET(DINamespace,
2277 (DIScope *Scope, StringRef Name, bool ExportSymbols),
2278 (Scope, Name, ExportSymbols))
2279 DEFINE_MDNODE_GET(DINamespace,
2280 (Metadata *Scope, MDString *Name, bool ExportSymbols),
2281 (Scope, Name, ExportSymbols))
2282
2283 TempDINamespace clone() const { return cloneImpl(); }
2284
2285 bool getExportSymbols() const { return ExportSymbols; }
2286 DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
2287 StringRef getName() const { return getStringOperand(2); }
2288
2289 Metadata *getRawScope() const { return getOperand(1); }
2290 MDString *getRawName() const { return getOperandAs<MDString>(2); }
2291
2292 static bool classof(const Metadata *MD) {
2293 return MD->getMetadataID() == DINamespaceKind;
2294 }
2295};
2296
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02002297/// Represents a module in the programming language, for example, a Clang
2298/// module, or a Fortran module.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002299class DIModule : public DIScope {
2300 friend class LLVMContextImpl;
2301 friend class MDNode;
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02002302 unsigned LineNo;
2303 bool IsDecl;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002304
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02002305 DIModule(LLVMContext &Context, StorageType Storage, unsigned LineNo,
2306 bool IsDecl, ArrayRef<Metadata *> Ops)
2307 : DIScope(Context, DIModuleKind, Storage, dwarf::DW_TAG_module, Ops),
2308 LineNo(LineNo), IsDecl(IsDecl) {}
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002309 ~DIModule() = default;
2310
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02002311 static DIModule *getImpl(LLVMContext &Context, DIFile *File, DIScope *Scope,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002312 StringRef Name, StringRef ConfigurationMacros,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02002313 StringRef IncludePath, StringRef APINotesFile,
2314 unsigned LineNo, bool IsDecl, StorageType Storage,
2315 bool ShouldCreate = true) {
2316 return getImpl(Context, File, Scope, getCanonicalMDString(Context, Name),
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002317 getCanonicalMDString(Context, ConfigurationMacros),
2318 getCanonicalMDString(Context, IncludePath),
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02002319 getCanonicalMDString(Context, APINotesFile), LineNo, IsDecl,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002320 Storage, ShouldCreate);
2321 }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02002322 static DIModule *getImpl(LLVMContext &Context, Metadata *File,
2323 Metadata *Scope, MDString *Name,
2324 MDString *ConfigurationMacros, MDString *IncludePath,
2325 MDString *APINotesFile, unsigned LineNo, bool IsDecl,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002326 StorageType Storage, bool ShouldCreate = true);
2327
2328 TempDIModule cloneImpl() const {
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02002329 return getTemporary(getContext(), getFile(), getScope(), getName(),
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002330 getConfigurationMacros(), getIncludePath(),
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02002331 getAPINotesFile(), getLineNo(), getIsDecl());
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002332 }
2333
2334public:
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002335 DEFINE_MDNODE_GET(DIModule,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02002336 (DIFile * File, DIScope *Scope, StringRef Name,
2337 StringRef ConfigurationMacros, StringRef IncludePath,
2338 StringRef APINotesFile, unsigned LineNo,
2339 bool IsDecl = false),
2340 (File, Scope, Name, ConfigurationMacros, IncludePath,
2341 APINotesFile, LineNo, IsDecl))
2342 DEFINE_MDNODE_GET(DIModule,
2343 (Metadata * File, Metadata *Scope, MDString *Name,
2344 MDString *ConfigurationMacros, MDString *IncludePath,
2345 MDString *APINotesFile, unsigned LineNo,
2346 bool IsDecl = false),
2347 (File, Scope, Name, ConfigurationMacros, IncludePath,
2348 APINotesFile, LineNo, IsDecl))
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002349
2350 TempDIModule clone() const { return cloneImpl(); }
2351
2352 DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02002353 StringRef getName() const { return getStringOperand(2); }
2354 StringRef getConfigurationMacros() const { return getStringOperand(3); }
2355 StringRef getIncludePath() const { return getStringOperand(4); }
2356 StringRef getAPINotesFile() const { return getStringOperand(5); }
2357 unsigned getLineNo() const { return LineNo; }
2358 bool getIsDecl() const { return IsDecl; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002359
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02002360 Metadata *getRawScope() const { return getOperand(1); }
2361 MDString *getRawName() const { return getOperandAs<MDString>(2); }
2362 MDString *getRawConfigurationMacros() const {
2363 return getOperandAs<MDString>(3);
2364 }
2365 MDString *getRawIncludePath() const { return getOperandAs<MDString>(4); }
2366 MDString *getRawAPINotesFile() const { return getOperandAs<MDString>(5); }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002367
2368 static bool classof(const Metadata *MD) {
2369 return MD->getMetadataID() == DIModuleKind;
2370 }
2371};
2372
2373/// Base class for template parameters.
2374class DITemplateParameter : public DINode {
2375protected:
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02002376 bool IsDefault;
2377
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002378 DITemplateParameter(LLVMContext &Context, unsigned ID, StorageType Storage,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02002379 unsigned Tag, bool IsDefault, ArrayRef<Metadata *> Ops)
2380 : DINode(Context, ID, Storage, Tag, Ops), IsDefault(IsDefault) {}
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002381 ~DITemplateParameter() = default;
2382
2383public:
2384 StringRef getName() const { return getStringOperand(0); }
Andrew Walbran3d2c1972020-04-07 12:24:26 +01002385 DIType *getType() const { return cast_or_null<DIType>(getRawType()); }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002386
2387 MDString *getRawName() const { return getOperandAs<MDString>(0); }
2388 Metadata *getRawType() const { return getOperand(1); }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02002389 bool isDefault() const { return IsDefault; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002390
2391 static bool classof(const Metadata *MD) {
2392 return MD->getMetadataID() == DITemplateTypeParameterKind ||
2393 MD->getMetadataID() == DITemplateValueParameterKind;
2394 }
2395};
2396
2397class DITemplateTypeParameter : public DITemplateParameter {
2398 friend class LLVMContextImpl;
2399 friend class MDNode;
2400
2401 DITemplateTypeParameter(LLVMContext &Context, StorageType Storage,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02002402 bool IsDefault, ArrayRef<Metadata *> Ops)
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002403 : DITemplateParameter(Context, DITemplateTypeParameterKind, Storage,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02002404 dwarf::DW_TAG_template_type_parameter, IsDefault,
2405 Ops) {}
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002406 ~DITemplateTypeParameter() = default;
2407
2408 static DITemplateTypeParameter *getImpl(LLVMContext &Context, StringRef Name,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02002409 DIType *Type, bool IsDefault,
2410 StorageType Storage,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002411 bool ShouldCreate = true) {
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02002412 return getImpl(Context, getCanonicalMDString(Context, Name), Type,
2413 IsDefault, Storage, ShouldCreate);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002414 }
2415 static DITemplateTypeParameter *getImpl(LLVMContext &Context, MDString *Name,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02002416 Metadata *Type, bool IsDefault,
2417 StorageType Storage,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002418 bool ShouldCreate = true);
2419
2420 TempDITemplateTypeParameter cloneImpl() const {
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02002421 return getTemporary(getContext(), getName(), getType(), isDefault());
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002422 }
2423
2424public:
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02002425 DEFINE_MDNODE_GET(DITemplateTypeParameter,
2426 (StringRef Name, DIType *Type, bool IsDefault),
2427 (Name, Type, IsDefault))
2428 DEFINE_MDNODE_GET(DITemplateTypeParameter,
2429 (MDString *Name, Metadata *Type, bool IsDefault),
2430 (Name, Type, IsDefault))
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002431
2432 TempDITemplateTypeParameter clone() const { return cloneImpl(); }
2433
2434 static bool classof(const Metadata *MD) {
2435 return MD->getMetadataID() == DITemplateTypeParameterKind;
2436 }
2437};
2438
2439class DITemplateValueParameter : public DITemplateParameter {
2440 friend class LLVMContextImpl;
2441 friend class MDNode;
2442
2443 DITemplateValueParameter(LLVMContext &Context, StorageType Storage,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02002444 unsigned Tag, bool IsDefault,
2445 ArrayRef<Metadata *> Ops)
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002446 : DITemplateParameter(Context, DITemplateValueParameterKind, Storage, Tag,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02002447 IsDefault, Ops) {}
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002448 ~DITemplateValueParameter() = default;
2449
2450 static DITemplateValueParameter *getImpl(LLVMContext &Context, unsigned Tag,
Andrew Walbran3d2c1972020-04-07 12:24:26 +01002451 StringRef Name, DIType *Type,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02002452 bool IsDefault, Metadata *Value,
2453 StorageType Storage,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002454 bool ShouldCreate = true) {
2455 return getImpl(Context, Tag, getCanonicalMDString(Context, Name), Type,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02002456 IsDefault, Value, Storage, ShouldCreate);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002457 }
2458 static DITemplateValueParameter *getImpl(LLVMContext &Context, unsigned Tag,
2459 MDString *Name, Metadata *Type,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02002460 bool IsDefault, Metadata *Value,
2461 StorageType Storage,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002462 bool ShouldCreate = true);
2463
2464 TempDITemplateValueParameter cloneImpl() const {
2465 return getTemporary(getContext(), getTag(), getName(), getType(),
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02002466 isDefault(), getValue());
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002467 }
2468
2469public:
Andrew Walbran3d2c1972020-04-07 12:24:26 +01002470 DEFINE_MDNODE_GET(DITemplateValueParameter,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02002471 (unsigned Tag, StringRef Name, DIType *Type, bool IsDefault,
Andrew Walbran3d2c1972020-04-07 12:24:26 +01002472 Metadata *Value),
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02002473 (Tag, Name, Type, IsDefault, Value))
2474 DEFINE_MDNODE_GET(DITemplateValueParameter,
2475 (unsigned Tag, MDString *Name, Metadata *Type,
2476 bool IsDefault, Metadata *Value),
2477 (Tag, Name, Type, IsDefault, Value))
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002478
2479 TempDITemplateValueParameter clone() const { return cloneImpl(); }
2480
2481 Metadata *getValue() const { return getOperand(2); }
2482
2483 static bool classof(const Metadata *MD) {
2484 return MD->getMetadataID() == DITemplateValueParameterKind;
2485 }
2486};
2487
2488/// Base class for variables.
2489class DIVariable : public DINode {
2490 unsigned Line;
2491 uint32_t AlignInBits;
2492
2493protected:
2494 DIVariable(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Line,
2495 ArrayRef<Metadata *> Ops, uint32_t AlignInBits = 0)
2496 : DINode(C, ID, Storage, dwarf::DW_TAG_variable, Ops), Line(Line),
2497 AlignInBits(AlignInBits) {}
2498 ~DIVariable() = default;
2499
2500public:
2501 unsigned getLine() const { return Line; }
2502 DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
2503 StringRef getName() const { return getStringOperand(1); }
2504 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
Andrew Walbran3d2c1972020-04-07 12:24:26 +01002505 DIType *getType() const { return cast_or_null<DIType>(getRawType()); }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002506 uint32_t getAlignInBits() const { return AlignInBits; }
2507 uint32_t getAlignInBytes() const { return getAlignInBits() / CHAR_BIT; }
2508 /// Determines the size of the variable's type.
2509 Optional<uint64_t> getSizeInBits() const;
2510
Andrew Scullcdfcccc2018-10-05 20:58:37 +01002511 /// Return the signedness of this variable's type, or None if this type is
2512 /// neither signed nor unsigned.
2513 Optional<DIBasicType::Signedness> getSignedness() const {
Andrew Walbran3d2c1972020-04-07 12:24:26 +01002514 if (auto *BT = dyn_cast<DIBasicType>(getType()))
Andrew Scullcdfcccc2018-10-05 20:58:37 +01002515 return BT->getSignedness();
2516 return None;
2517 }
2518
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002519 StringRef getFilename() const {
2520 if (auto *F = getFile())
2521 return F->getFilename();
2522 return "";
2523 }
2524
2525 StringRef getDirectory() const {
2526 if (auto *F = getFile())
2527 return F->getDirectory();
2528 return "";
2529 }
2530
2531 Optional<StringRef> getSource() const {
2532 if (auto *F = getFile())
2533 return F->getSource();
2534 return None;
2535 }
2536
2537 Metadata *getRawScope() const { return getOperand(0); }
2538 MDString *getRawName() const { return getOperandAs<MDString>(1); }
2539 Metadata *getRawFile() const { return getOperand(2); }
2540 Metadata *getRawType() const { return getOperand(3); }
2541
2542 static bool classof(const Metadata *MD) {
2543 return MD->getMetadataID() == DILocalVariableKind ||
2544 MD->getMetadataID() == DIGlobalVariableKind;
2545 }
2546};
2547
2548/// DWARF expression.
2549///
2550/// This is (almost) a DWARF expression that modifies the location of a
2551/// variable, or the location of a single piece of a variable, or (when using
2552/// DW_OP_stack_value) is the constant variable value.
2553///
2554/// TODO: Co-allocate the expression elements.
2555/// TODO: Separate from MDNode, or otherwise drop Distinct and Temporary
2556/// storage types.
2557class DIExpression : public MDNode {
2558 friend class LLVMContextImpl;
2559 friend class MDNode;
2560
2561 std::vector<uint64_t> Elements;
2562
2563 DIExpression(LLVMContext &C, StorageType Storage, ArrayRef<uint64_t> Elements)
2564 : MDNode(C, DIExpressionKind, Storage, None),
2565 Elements(Elements.begin(), Elements.end()) {}
2566 ~DIExpression() = default;
2567
2568 static DIExpression *getImpl(LLVMContext &Context,
2569 ArrayRef<uint64_t> Elements, StorageType Storage,
2570 bool ShouldCreate = true);
2571
2572 TempDIExpression cloneImpl() const {
2573 return getTemporary(getContext(), getElements());
2574 }
2575
2576public:
2577 DEFINE_MDNODE_GET(DIExpression, (ArrayRef<uint64_t> Elements), (Elements))
2578
2579 TempDIExpression clone() const { return cloneImpl(); }
2580
2581 ArrayRef<uint64_t> getElements() const { return Elements; }
2582
2583 unsigned getNumElements() const { return Elements.size(); }
2584
2585 uint64_t getElement(unsigned I) const {
2586 assert(I < Elements.size() && "Index out of range");
2587 return Elements[I];
2588 }
2589
2590 /// Determine whether this represents a standalone constant value.
2591 bool isConstant() const;
2592
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02002593 /// Determine whether this represents a standalone signed constant value.
2594 bool isSignedConstant() const;
2595
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002596 using element_iterator = ArrayRef<uint64_t>::iterator;
2597
2598 element_iterator elements_begin() const { return getElements().begin(); }
2599 element_iterator elements_end() const { return getElements().end(); }
2600
2601 /// A lightweight wrapper around an expression operand.
2602 ///
2603 /// TODO: Store arguments directly and change \a DIExpression to store a
2604 /// range of these.
2605 class ExprOperand {
2606 const uint64_t *Op = nullptr;
2607
2608 public:
2609 ExprOperand() = default;
2610 explicit ExprOperand(const uint64_t *Op) : Op(Op) {}
2611
2612 const uint64_t *get() const { return Op; }
2613
2614 /// Get the operand code.
2615 uint64_t getOp() const { return *Op; }
2616
2617 /// Get an argument to the operand.
2618 ///
2619 /// Never returns the operand itself.
2620 uint64_t getArg(unsigned I) const { return Op[I + 1]; }
2621
2622 unsigned getNumArgs() const { return getSize() - 1; }
2623
2624 /// Return the size of the operand.
2625 ///
2626 /// Return the number of elements in the operand (1 + args).
2627 unsigned getSize() const;
Andrew Scullcdfcccc2018-10-05 20:58:37 +01002628
2629 /// Append the elements of this operand to \p V.
2630 void appendToVector(SmallVectorImpl<uint64_t> &V) const {
2631 V.append(get(), get() + getSize());
2632 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002633 };
2634
2635 /// An iterator for expression operands.
2636 class expr_op_iterator
2637 : public std::iterator<std::input_iterator_tag, ExprOperand> {
2638 ExprOperand Op;
2639
2640 public:
2641 expr_op_iterator() = default;
2642 explicit expr_op_iterator(element_iterator I) : Op(I) {}
2643
2644 element_iterator getBase() const { return Op.get(); }
2645 const ExprOperand &operator*() const { return Op; }
2646 const ExprOperand *operator->() const { return &Op; }
2647
2648 expr_op_iterator &operator++() {
2649 increment();
2650 return *this;
2651 }
2652 expr_op_iterator operator++(int) {
2653 expr_op_iterator T(*this);
2654 increment();
2655 return T;
2656 }
2657
2658 /// Get the next iterator.
2659 ///
2660 /// \a std::next() doesn't work because this is technically an
2661 /// input_iterator, but it's a perfectly valid operation. This is an
2662 /// accessor to provide the same functionality.
2663 expr_op_iterator getNext() const { return ++expr_op_iterator(*this); }
2664
2665 bool operator==(const expr_op_iterator &X) const {
2666 return getBase() == X.getBase();
2667 }
2668 bool operator!=(const expr_op_iterator &X) const {
2669 return getBase() != X.getBase();
2670 }
2671
2672 private:
2673 void increment() { Op = ExprOperand(getBase() + Op.getSize()); }
2674 };
2675
2676 /// Visit the elements via ExprOperand wrappers.
2677 ///
2678 /// These range iterators visit elements through \a ExprOperand wrappers.
2679 /// This is not guaranteed to be a valid range unless \a isValid() gives \c
2680 /// true.
2681 ///
2682 /// \pre \a isValid() gives \c true.
2683 /// @{
2684 expr_op_iterator expr_op_begin() const {
2685 return expr_op_iterator(elements_begin());
2686 }
2687 expr_op_iterator expr_op_end() const {
2688 return expr_op_iterator(elements_end());
2689 }
2690 iterator_range<expr_op_iterator> expr_ops() const {
2691 return {expr_op_begin(), expr_op_end()};
2692 }
2693 /// @}
2694
2695 bool isValid() const;
2696
2697 static bool classof(const Metadata *MD) {
2698 return MD->getMetadataID() == DIExpressionKind;
2699 }
2700
2701 /// Return whether the first element a DW_OP_deref.
2702 bool startsWithDeref() const {
2703 return getNumElements() > 0 && getElement(0) == dwarf::DW_OP_deref;
2704 }
2705
2706 /// Holds the characteristics of one fragment of a larger variable.
2707 struct FragmentInfo {
2708 uint64_t SizeInBits;
2709 uint64_t OffsetInBits;
2710 };
2711
2712 /// Retrieve the details of this fragment expression.
2713 static Optional<FragmentInfo> getFragmentInfo(expr_op_iterator Start,
2714 expr_op_iterator End);
2715
2716 /// Retrieve the details of this fragment expression.
2717 Optional<FragmentInfo> getFragmentInfo() const {
2718 return getFragmentInfo(expr_op_begin(), expr_op_end());
2719 }
2720
2721 /// Return whether this is a piece of an aggregate variable.
2722 bool isFragment() const { return getFragmentInfo().hasValue(); }
2723
Andrew Walbran3d2c1972020-04-07 12:24:26 +01002724 /// Return whether this is an implicit location description.
2725 bool isImplicit() const;
2726
2727 /// Return whether the location is computed on the expression stack, meaning
2728 /// it cannot be a simple register location.
2729 bool isComplex() const;
2730
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002731 /// Append \p Ops with operations to apply the \p Offset.
2732 static void appendOffset(SmallVectorImpl<uint64_t> &Ops, int64_t Offset);
2733
2734 /// If this is a constant offset, extract it. If there is no expression,
2735 /// return true with an offset of zero.
2736 bool extractIfOffset(int64_t &Offset) const;
2737
Andrew Walbran16937d02019-10-22 13:54:20 +01002738 /// Checks if the last 4 elements of the expression are DW_OP_constu <DWARF
2739 /// Address Space> DW_OP_swap DW_OP_xderef and extracts the <DWARF Address
2740 /// Space>.
2741 static const DIExpression *extractAddressClass(const DIExpression *Expr,
2742 unsigned &AddrClass);
2743
Andrew Walbran3d2c1972020-04-07 12:24:26 +01002744 /// Used for DIExpression::prepend.
2745 enum PrependOps : uint8_t {
2746 ApplyOffset = 0,
2747 DerefBefore = 1 << 0,
2748 DerefAfter = 1 << 1,
2749 StackValue = 1 << 2,
2750 EntryValue = 1 << 3
2751 };
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002752
2753 /// Prepend \p DIExpr with a deref and offset operation and optionally turn it
Andrew Walbran3d2c1972020-04-07 12:24:26 +01002754 /// into a stack value or/and an entry value.
2755 static DIExpression *prepend(const DIExpression *Expr, uint8_t Flags,
2756 int64_t Offset = 0);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002757
2758 /// Prepend \p DIExpr with the given opcodes and optionally turn it into a
2759 /// stack value.
Andrew Scullcdfcccc2018-10-05 20:58:37 +01002760 static DIExpression *prependOpcodes(const DIExpression *Expr,
2761 SmallVectorImpl<uint64_t> &Ops,
Andrew Walbran3d2c1972020-04-07 12:24:26 +01002762 bool StackValue = false,
2763 bool EntryValue = false);
Andrew Scullcdfcccc2018-10-05 20:58:37 +01002764
2765 /// Append the opcodes \p Ops to \p DIExpr. Unlike \ref appendToStack, the
2766 /// returned expression is a stack value only if \p DIExpr is a stack value.
2767 /// If \p DIExpr describes a fragment, the returned expression will describe
2768 /// the same fragment.
2769 static DIExpression *append(const DIExpression *Expr, ArrayRef<uint64_t> Ops);
2770
2771 /// Convert \p DIExpr into a stack value if it isn't one already by appending
2772 /// DW_OP_deref if needed, and appending \p Ops to the resulting expression.
2773 /// If \p DIExpr describes a fragment, the returned expression will describe
2774 /// the same fragment.
2775 static DIExpression *appendToStack(const DIExpression *Expr,
2776 ArrayRef<uint64_t> Ops);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002777
2778 /// Create a DIExpression to describe one part of an aggregate variable that
2779 /// is fragmented across multiple Values. The DW_OP_LLVM_fragment operation
2780 /// will be appended to the elements of \c Expr. If \c Expr already contains
2781 /// a \c DW_OP_LLVM_fragment \c OffsetInBits is interpreted as an offset
2782 /// into the existing fragment.
2783 ///
2784 /// \param OffsetInBits Offset of the piece in bits.
2785 /// \param SizeInBits Size of the piece in bits.
2786 /// \return Creating a fragment expression may fail if \c Expr
2787 /// contains arithmetic operations that would be truncated.
2788 static Optional<DIExpression *>
2789 createFragmentExpression(const DIExpression *Expr, unsigned OffsetInBits,
2790 unsigned SizeInBits);
2791
Andrew Walbran3d2c1972020-04-07 12:24:26 +01002792 /// Determine the relative position of the fragments passed in.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002793 /// Returns -1 if this is entirely before Other, 0 if this and Other overlap,
2794 /// 1 if this is entirely after Other.
Andrew Walbran3d2c1972020-04-07 12:24:26 +01002795 static int fragmentCmp(const FragmentInfo &A, const FragmentInfo &B) {
2796 uint64_t l1 = A.OffsetInBits;
2797 uint64_t l2 = B.OffsetInBits;
2798 uint64_t r1 = l1 + A.SizeInBits;
2799 uint64_t r2 = l2 + B.SizeInBits;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002800 if (r1 <= l2)
2801 return -1;
2802 else if (r2 <= l1)
2803 return 1;
2804 else
2805 return 0;
2806 }
2807
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02002808 using ExtOps = std::array<uint64_t, 6>;
2809
2810 /// Returns the ops for a zero- or sign-extension in a DIExpression.
2811 static ExtOps getExtOps(unsigned FromSize, unsigned ToSize, bool Signed);
2812
2813 /// Append a zero- or sign-extension to \p Expr. Converts the expression to a
2814 /// stack value if it isn't one already.
2815 static DIExpression *appendExt(const DIExpression *Expr, unsigned FromSize,
2816 unsigned ToSize, bool Signed);
2817
Andrew Walbran3d2c1972020-04-07 12:24:26 +01002818 /// Check if fragments overlap between a pair of FragmentInfos.
2819 static bool fragmentsOverlap(const FragmentInfo &A, const FragmentInfo &B) {
2820 return fragmentCmp(A, B) == 0;
2821 }
2822
2823 /// Determine the relative position of the fragments described by this
2824 /// DIExpression and \p Other. Calls static fragmentCmp implementation.
2825 int fragmentCmp(const DIExpression *Other) const {
2826 auto Fragment1 = *getFragmentInfo();
2827 auto Fragment2 = *Other->getFragmentInfo();
2828 return fragmentCmp(Fragment1, Fragment2);
2829 }
2830
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002831 /// Check if fragments overlap between this DIExpression and \p Other.
2832 bool fragmentsOverlap(const DIExpression *Other) const {
2833 if (!isFragment() || !Other->isFragment())
2834 return true;
2835 return fragmentCmp(Other) == 0;
2836 }
Andrew Walbran3d2c1972020-04-07 12:24:26 +01002837
2838 /// Check if the expression consists of exactly one entry value operand.
2839 /// (This is the only configuration of entry values that is supported.)
2840 bool isEntryValue() const {
2841 return getNumElements() > 0 &&
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02002842 getElement(0) == dwarf::DW_OP_LLVM_entry_value;
Andrew Walbran3d2c1972020-04-07 12:24:26 +01002843 }
2844};
2845
2846inline bool operator==(const DIExpression::FragmentInfo &A,
2847 const DIExpression::FragmentInfo &B) {
2848 return std::tie(A.SizeInBits, A.OffsetInBits) ==
2849 std::tie(B.SizeInBits, B.OffsetInBits);
2850}
2851
2852inline bool operator<(const DIExpression::FragmentInfo &A,
2853 const DIExpression::FragmentInfo &B) {
2854 return std::tie(A.SizeInBits, A.OffsetInBits) <
2855 std::tie(B.SizeInBits, B.OffsetInBits);
2856}
2857
2858template <> struct DenseMapInfo<DIExpression::FragmentInfo> {
2859 using FragInfo = DIExpression::FragmentInfo;
2860 static const uint64_t MaxVal = std::numeric_limits<uint64_t>::max();
2861
2862 static inline FragInfo getEmptyKey() { return {MaxVal, MaxVal}; }
2863
2864 static inline FragInfo getTombstoneKey() { return {MaxVal - 1, MaxVal - 1}; }
2865
2866 static unsigned getHashValue(const FragInfo &Frag) {
2867 return (Frag.SizeInBits & 0xffff) << 16 | (Frag.OffsetInBits & 0xffff);
2868 }
2869
2870 static bool isEqual(const FragInfo &A, const FragInfo &B) { return A == B; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002871};
2872
2873/// Global variables.
2874///
2875/// TODO: Remove DisplayName. It's always equal to Name.
2876class DIGlobalVariable : public DIVariable {
2877 friend class LLVMContextImpl;
2878 friend class MDNode;
2879
2880 bool IsLocalToUnit;
2881 bool IsDefinition;
2882
2883 DIGlobalVariable(LLVMContext &C, StorageType Storage, unsigned Line,
2884 bool IsLocalToUnit, bool IsDefinition, uint32_t AlignInBits,
2885 ArrayRef<Metadata *> Ops)
2886 : DIVariable(C, DIGlobalVariableKind, Storage, Line, Ops, AlignInBits),
2887 IsLocalToUnit(IsLocalToUnit), IsDefinition(IsDefinition) {}
2888 ~DIGlobalVariable() = default;
2889
Andrew Scull0372a572018-11-16 15:47:06 +00002890 static DIGlobalVariable *
2891 getImpl(LLVMContext &Context, DIScope *Scope, StringRef Name,
Andrew Walbran3d2c1972020-04-07 12:24:26 +01002892 StringRef LinkageName, DIFile *File, unsigned Line, DIType *Type,
Andrew Scull0372a572018-11-16 15:47:06 +00002893 bool IsLocalToUnit, bool IsDefinition,
2894 DIDerivedType *StaticDataMemberDeclaration, MDTuple *TemplateParams,
2895 uint32_t AlignInBits, StorageType Storage, bool ShouldCreate = true) {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002896 return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
2897 getCanonicalMDString(Context, LinkageName), File, Line, Type,
2898 IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration,
Andrew Scull0372a572018-11-16 15:47:06 +00002899 cast_or_null<Metadata>(TemplateParams), AlignInBits, Storage,
2900 ShouldCreate);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002901 }
2902 static DIGlobalVariable *
2903 getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
2904 MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type,
2905 bool IsLocalToUnit, bool IsDefinition,
Andrew Scull0372a572018-11-16 15:47:06 +00002906 Metadata *StaticDataMemberDeclaration, Metadata *TemplateParams,
2907 uint32_t AlignInBits, StorageType Storage, bool ShouldCreate = true);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002908
2909 TempDIGlobalVariable cloneImpl() const {
2910 return getTemporary(getContext(), getScope(), getName(), getLinkageName(),
2911 getFile(), getLine(), getType(), isLocalToUnit(),
2912 isDefinition(), getStaticDataMemberDeclaration(),
Andrew Scull0372a572018-11-16 15:47:06 +00002913 getTemplateParams(), getAlignInBits());
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002914 }
2915
2916public:
2917 DEFINE_MDNODE_GET(DIGlobalVariable,
2918 (DIScope * Scope, StringRef Name, StringRef LinkageName,
Andrew Walbran3d2c1972020-04-07 12:24:26 +01002919 DIFile *File, unsigned Line, DIType *Type,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002920 bool IsLocalToUnit, bool IsDefinition,
2921 DIDerivedType *StaticDataMemberDeclaration,
Andrew Scull0372a572018-11-16 15:47:06 +00002922 MDTuple *TemplateParams, uint32_t AlignInBits),
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002923 (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
Andrew Scull0372a572018-11-16 15:47:06 +00002924 IsDefinition, StaticDataMemberDeclaration, TemplateParams,
2925 AlignInBits))
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002926 DEFINE_MDNODE_GET(DIGlobalVariable,
2927 (Metadata * Scope, MDString *Name, MDString *LinkageName,
2928 Metadata *File, unsigned Line, Metadata *Type,
2929 bool IsLocalToUnit, bool IsDefinition,
2930 Metadata *StaticDataMemberDeclaration,
Andrew Scull0372a572018-11-16 15:47:06 +00002931 Metadata *TemplateParams, uint32_t AlignInBits),
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002932 (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
Andrew Scull0372a572018-11-16 15:47:06 +00002933 IsDefinition, StaticDataMemberDeclaration, TemplateParams,
2934 AlignInBits))
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002935
2936 TempDIGlobalVariable clone() const { return cloneImpl(); }
2937
2938 bool isLocalToUnit() const { return IsLocalToUnit; }
2939 bool isDefinition() const { return IsDefinition; }
2940 StringRef getDisplayName() const { return getStringOperand(4); }
2941 StringRef getLinkageName() const { return getStringOperand(5); }
2942 DIDerivedType *getStaticDataMemberDeclaration() const {
2943 return cast_or_null<DIDerivedType>(getRawStaticDataMemberDeclaration());
2944 }
2945
2946 MDString *getRawLinkageName() const { return getOperandAs<MDString>(5); }
2947 Metadata *getRawStaticDataMemberDeclaration() const { return getOperand(6); }
Andrew Scull0372a572018-11-16 15:47:06 +00002948 Metadata *getRawTemplateParams() const { return getOperand(7); }
2949 MDTuple *getTemplateParams() const { return getOperandAs<MDTuple>(7); }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002950
2951 static bool classof(const Metadata *MD) {
2952 return MD->getMetadataID() == DIGlobalVariableKind;
2953 }
2954};
2955
Andrew Walbran3d2c1972020-04-07 12:24:26 +01002956class DICommonBlock : public DIScope {
2957 unsigned LineNo;
2958
2959 friend class LLVMContextImpl;
2960 friend class MDNode;
2961
2962 DICommonBlock(LLVMContext &Context, StorageType Storage, unsigned LineNo,
2963 ArrayRef<Metadata *> Ops)
2964 : DIScope(Context, DICommonBlockKind, Storage, dwarf::DW_TAG_common_block,
2965 Ops), LineNo(LineNo) {}
2966
2967 static DICommonBlock *getImpl(LLVMContext &Context, DIScope *Scope,
2968 DIGlobalVariable *Decl, StringRef Name,
2969 DIFile *File, unsigned LineNo,
2970 StorageType Storage,
2971 bool ShouldCreate = true) {
2972 return getImpl(Context, Scope, Decl, getCanonicalMDString(Context, Name),
2973 File, LineNo, Storage, ShouldCreate);
2974 }
2975 static DICommonBlock *getImpl(LLVMContext &Context, Metadata *Scope,
2976 Metadata *Decl, MDString *Name, Metadata *File,
2977 unsigned LineNo,
2978 StorageType Storage, bool ShouldCreate = true);
2979
2980 TempDICommonBlock cloneImpl() const {
2981 return getTemporary(getContext(), getScope(), getDecl(), getName(),
2982 getFile(), getLineNo());
2983 }
2984
2985public:
2986 DEFINE_MDNODE_GET(DICommonBlock,
2987 (DIScope *Scope, DIGlobalVariable *Decl, StringRef Name,
2988 DIFile *File, unsigned LineNo),
2989 (Scope, Decl, Name, File, LineNo))
2990 DEFINE_MDNODE_GET(DICommonBlock,
2991 (Metadata *Scope, Metadata *Decl, MDString *Name,
2992 Metadata *File, unsigned LineNo),
2993 (Scope, Decl, Name, File, LineNo))
2994
2995 TempDICommonBlock clone() const { return cloneImpl(); }
2996
2997 DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
2998 DIGlobalVariable *getDecl() const {
2999 return cast_or_null<DIGlobalVariable>(getRawDecl());
3000 }
3001 StringRef getName() const { return getStringOperand(2); }
3002 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
3003 unsigned getLineNo() const { return LineNo; }
3004
3005 Metadata *getRawScope() const { return getOperand(0); }
3006 Metadata *getRawDecl() const { return getOperand(1); }
3007 MDString *getRawName() const { return getOperandAs<MDString>(2); }
3008 Metadata *getRawFile() const { return getOperand(3); }
3009
3010 static bool classof(const Metadata *MD) {
3011 return MD->getMetadataID() == DICommonBlockKind;
3012 }
3013};
3014
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01003015/// Local variable.
3016///
3017/// TODO: Split up flags.
3018class DILocalVariable : public DIVariable {
3019 friend class LLVMContextImpl;
3020 friend class MDNode;
3021
3022 unsigned Arg : 16;
3023 DIFlags Flags;
3024
3025 DILocalVariable(LLVMContext &C, StorageType Storage, unsigned Line,
3026 unsigned Arg, DIFlags Flags, uint32_t AlignInBits,
3027 ArrayRef<Metadata *> Ops)
3028 : DIVariable(C, DILocalVariableKind, Storage, Line, Ops, AlignInBits),
3029 Arg(Arg), Flags(Flags) {
3030 assert(Arg < (1 << 16) && "DILocalVariable: Arg out of range");
3031 }
3032 ~DILocalVariable() = default;
3033
3034 static DILocalVariable *getImpl(LLVMContext &Context, DIScope *Scope,
3035 StringRef Name, DIFile *File, unsigned Line,
Andrew Walbran3d2c1972020-04-07 12:24:26 +01003036 DIType *Type, unsigned Arg, DIFlags Flags,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01003037 uint32_t AlignInBits, StorageType Storage,
3038 bool ShouldCreate = true) {
3039 return getImpl(Context, Scope, getCanonicalMDString(Context, Name), File,
3040 Line, Type, Arg, Flags, AlignInBits, Storage, ShouldCreate);
3041 }
3042 static DILocalVariable *getImpl(LLVMContext &Context, Metadata *Scope,
3043 MDString *Name, Metadata *File, unsigned Line,
3044 Metadata *Type, unsigned Arg, DIFlags Flags,
3045 uint32_t AlignInBits, StorageType Storage,
3046 bool ShouldCreate = true);
3047
3048 TempDILocalVariable cloneImpl() const {
3049 return getTemporary(getContext(), getScope(), getName(), getFile(),
3050 getLine(), getType(), getArg(), getFlags(),
3051 getAlignInBits());
3052 }
3053
3054public:
3055 DEFINE_MDNODE_GET(DILocalVariable,
3056 (DILocalScope * Scope, StringRef Name, DIFile *File,
Andrew Walbran3d2c1972020-04-07 12:24:26 +01003057 unsigned Line, DIType *Type, unsigned Arg, DIFlags Flags,
3058 uint32_t AlignInBits),
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01003059 (Scope, Name, File, Line, Type, Arg, Flags, AlignInBits))
3060 DEFINE_MDNODE_GET(DILocalVariable,
3061 (Metadata * Scope, MDString *Name, Metadata *File,
3062 unsigned Line, Metadata *Type, unsigned Arg,
3063 DIFlags Flags, uint32_t AlignInBits),
3064 (Scope, Name, File, Line, Type, Arg, Flags, AlignInBits))
3065
3066 TempDILocalVariable clone() const { return cloneImpl(); }
3067
3068 /// Get the local scope for this variable.
3069 ///
3070 /// Variables must be defined in a local scope.
3071 DILocalScope *getScope() const {
3072 return cast<DILocalScope>(DIVariable::getScope());
3073 }
3074
3075 bool isParameter() const { return Arg; }
3076 unsigned getArg() const { return Arg; }
3077 DIFlags getFlags() const { return Flags; }
3078
3079 bool isArtificial() const { return getFlags() & FlagArtificial; }
3080 bool isObjectPointer() const { return getFlags() & FlagObjectPointer; }
3081
3082 /// Check that a location is valid for this variable.
3083 ///
3084 /// Check that \c DL exists, is in the same subprogram, and has the same
3085 /// inlined-at location as \c this. (Otherwise, it's not a valid attachment
3086 /// to a \a DbgInfoIntrinsic.)
3087 bool isValidLocationForIntrinsic(const DILocation *DL) const {
3088 return DL && getScope()->getSubprogram() == DL->getScope()->getSubprogram();
3089 }
3090
3091 static bool classof(const Metadata *MD) {
3092 return MD->getMetadataID() == DILocalVariableKind;
3093 }
3094};
3095
Andrew Scullcdfcccc2018-10-05 20:58:37 +01003096/// Label.
3097///
3098class DILabel : public DINode {
3099 friend class LLVMContextImpl;
3100 friend class MDNode;
3101
3102 unsigned Line;
3103
3104 DILabel(LLVMContext &C, StorageType Storage, unsigned Line,
3105 ArrayRef<Metadata *> Ops)
3106 : DINode(C, DILabelKind, Storage, dwarf::DW_TAG_label, Ops), Line(Line) {}
3107 ~DILabel() = default;
3108
3109 static DILabel *getImpl(LLVMContext &Context, DIScope *Scope,
3110 StringRef Name, DIFile *File, unsigned Line,
3111 StorageType Storage,
3112 bool ShouldCreate = true) {
3113 return getImpl(Context, Scope, getCanonicalMDString(Context, Name), File,
3114 Line, Storage, ShouldCreate);
3115 }
3116 static DILabel *getImpl(LLVMContext &Context, Metadata *Scope,
3117 MDString *Name, Metadata *File, unsigned Line,
3118 StorageType Storage,
3119 bool ShouldCreate = true);
3120
3121 TempDILabel cloneImpl() const {
3122 return getTemporary(getContext(), getScope(), getName(), getFile(),
3123 getLine());
3124 }
3125
3126public:
3127 DEFINE_MDNODE_GET(DILabel,
3128 (DILocalScope * Scope, StringRef Name, DIFile *File,
3129 unsigned Line),
3130 (Scope, Name, File, Line))
3131 DEFINE_MDNODE_GET(DILabel,
3132 (Metadata * Scope, MDString *Name, Metadata *File,
3133 unsigned Line),
3134 (Scope, Name, File, Line))
3135
3136 TempDILabel clone() const { return cloneImpl(); }
3137
3138 /// Get the local scope for this label.
3139 ///
3140 /// Labels must be defined in a local scope.
3141 DILocalScope *getScope() const {
3142 return cast_or_null<DILocalScope>(getRawScope());
3143 }
3144 unsigned getLine() const { return Line; }
3145 StringRef getName() const { return getStringOperand(1); }
3146 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
3147
3148 Metadata *getRawScope() const { return getOperand(0); }
3149 MDString *getRawName() const { return getOperandAs<MDString>(1); }
3150 Metadata *getRawFile() const { return getOperand(2); }
3151
3152 /// Check that a location is valid for this label.
3153 ///
3154 /// Check that \c DL exists, is in the same subprogram, and has the same
3155 /// inlined-at location as \c this. (Otherwise, it's not a valid attachment
3156 /// to a \a DbgInfoIntrinsic.)
3157 bool isValidLocationForIntrinsic(const DILocation *DL) const {
3158 return DL && getScope()->getSubprogram() == DL->getScope()->getSubprogram();
3159 }
3160
3161 static bool classof(const Metadata *MD) {
3162 return MD->getMetadataID() == DILabelKind;
3163 }
3164};
3165
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01003166class DIObjCProperty : public DINode {
3167 friend class LLVMContextImpl;
3168 friend class MDNode;
3169
3170 unsigned Line;
3171 unsigned Attributes;
3172
3173 DIObjCProperty(LLVMContext &C, StorageType Storage, unsigned Line,
3174 unsigned Attributes, ArrayRef<Metadata *> Ops)
3175 : DINode(C, DIObjCPropertyKind, Storage, dwarf::DW_TAG_APPLE_property,
3176 Ops),
3177 Line(Line), Attributes(Attributes) {}
3178 ~DIObjCProperty() = default;
3179
3180 static DIObjCProperty *
3181 getImpl(LLVMContext &Context, StringRef Name, DIFile *File, unsigned Line,
3182 StringRef GetterName, StringRef SetterName, unsigned Attributes,
Andrew Walbran3d2c1972020-04-07 12:24:26 +01003183 DIType *Type, StorageType Storage, bool ShouldCreate = true) {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01003184 return getImpl(Context, getCanonicalMDString(Context, Name), File, Line,
3185 getCanonicalMDString(Context, GetterName),
3186 getCanonicalMDString(Context, SetterName), Attributes, Type,
3187 Storage, ShouldCreate);
3188 }
3189 static DIObjCProperty *getImpl(LLVMContext &Context, MDString *Name,
3190 Metadata *File, unsigned Line,
3191 MDString *GetterName, MDString *SetterName,
3192 unsigned Attributes, Metadata *Type,
3193 StorageType Storage, bool ShouldCreate = true);
3194
3195 TempDIObjCProperty cloneImpl() const {
3196 return getTemporary(getContext(), getName(), getFile(), getLine(),
3197 getGetterName(), getSetterName(), getAttributes(),
3198 getType());
3199 }
3200
3201public:
3202 DEFINE_MDNODE_GET(DIObjCProperty,
3203 (StringRef Name, DIFile *File, unsigned Line,
3204 StringRef GetterName, StringRef SetterName,
Andrew Walbran3d2c1972020-04-07 12:24:26 +01003205 unsigned Attributes, DIType *Type),
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01003206 (Name, File, Line, GetterName, SetterName, Attributes,
3207 Type))
3208 DEFINE_MDNODE_GET(DIObjCProperty,
3209 (MDString * Name, Metadata *File, unsigned Line,
3210 MDString *GetterName, MDString *SetterName,
3211 unsigned Attributes, Metadata *Type),
3212 (Name, File, Line, GetterName, SetterName, Attributes,
3213 Type))
3214
3215 TempDIObjCProperty clone() const { return cloneImpl(); }
3216
3217 unsigned getLine() const { return Line; }
3218 unsigned getAttributes() const { return Attributes; }
3219 StringRef getName() const { return getStringOperand(0); }
3220 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
3221 StringRef getGetterName() const { return getStringOperand(2); }
3222 StringRef getSetterName() const { return getStringOperand(3); }
Andrew Walbran3d2c1972020-04-07 12:24:26 +01003223 DIType *getType() const { return cast_or_null<DIType>(getRawType()); }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01003224
3225 StringRef getFilename() const {
3226 if (auto *F = getFile())
3227 return F->getFilename();
3228 return "";
3229 }
3230
3231 StringRef getDirectory() const {
3232 if (auto *F = getFile())
3233 return F->getDirectory();
3234 return "";
3235 }
3236
3237 Optional<StringRef> getSource() const {
3238 if (auto *F = getFile())
3239 return F->getSource();
3240 return None;
3241 }
3242
3243 MDString *getRawName() const { return getOperandAs<MDString>(0); }
3244 Metadata *getRawFile() const { return getOperand(1); }
3245 MDString *getRawGetterName() const { return getOperandAs<MDString>(2); }
3246 MDString *getRawSetterName() const { return getOperandAs<MDString>(3); }
3247 Metadata *getRawType() const { return getOperand(4); }
3248
3249 static bool classof(const Metadata *MD) {
3250 return MD->getMetadataID() == DIObjCPropertyKind;
3251 }
3252};
3253
3254/// An imported module (C++ using directive or similar).
3255class DIImportedEntity : public DINode {
3256 friend class LLVMContextImpl;
3257 friend class MDNode;
3258
3259 unsigned Line;
3260
3261 DIImportedEntity(LLVMContext &C, StorageType Storage, unsigned Tag,
3262 unsigned Line, ArrayRef<Metadata *> Ops)
3263 : DINode(C, DIImportedEntityKind, Storage, Tag, Ops), Line(Line) {}
3264 ~DIImportedEntity() = default;
3265
3266 static DIImportedEntity *getImpl(LLVMContext &Context, unsigned Tag,
Andrew Walbran3d2c1972020-04-07 12:24:26 +01003267 DIScope *Scope, DINode *Entity, DIFile *File,
3268 unsigned Line, StringRef Name,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01003269 StorageType Storage,
3270 bool ShouldCreate = true) {
3271 return getImpl(Context, Tag, Scope, Entity, File, Line,
3272 getCanonicalMDString(Context, Name), Storage, ShouldCreate);
3273 }
3274 static DIImportedEntity *getImpl(LLVMContext &Context, unsigned Tag,
3275 Metadata *Scope, Metadata *Entity,
3276 Metadata *File, unsigned Line,
3277 MDString *Name, StorageType Storage,
3278 bool ShouldCreate = true);
3279
3280 TempDIImportedEntity cloneImpl() const {
3281 return getTemporary(getContext(), getTag(), getScope(), getEntity(),
3282 getFile(), getLine(), getName());
3283 }
3284
3285public:
3286 DEFINE_MDNODE_GET(DIImportedEntity,
Andrew Walbran3d2c1972020-04-07 12:24:26 +01003287 (unsigned Tag, DIScope *Scope, DINode *Entity, DIFile *File,
3288 unsigned Line, StringRef Name = ""),
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01003289 (Tag, Scope, Entity, File, Line, Name))
3290 DEFINE_MDNODE_GET(DIImportedEntity,
3291 (unsigned Tag, Metadata *Scope, Metadata *Entity,
3292 Metadata *File, unsigned Line, MDString *Name),
3293 (Tag, Scope, Entity, File, Line, Name))
3294
3295 TempDIImportedEntity clone() const { return cloneImpl(); }
3296
3297 unsigned getLine() const { return Line; }
3298 DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
Andrew Walbran3d2c1972020-04-07 12:24:26 +01003299 DINode *getEntity() const { return cast_or_null<DINode>(getRawEntity()); }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01003300 StringRef getName() const { return getStringOperand(2); }
3301 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
3302
3303 Metadata *getRawScope() const { return getOperand(0); }
3304 Metadata *getRawEntity() const { return getOperand(1); }
3305 MDString *getRawName() const { return getOperandAs<MDString>(2); }
3306 Metadata *getRawFile() const { return getOperand(3); }
3307
3308 static bool classof(const Metadata *MD) {
3309 return MD->getMetadataID() == DIImportedEntityKind;
3310 }
3311};
3312
3313/// A pair of DIGlobalVariable and DIExpression.
3314class DIGlobalVariableExpression : public MDNode {
3315 friend class LLVMContextImpl;
3316 friend class MDNode;
3317
3318 DIGlobalVariableExpression(LLVMContext &C, StorageType Storage,
3319 ArrayRef<Metadata *> Ops)
3320 : MDNode(C, DIGlobalVariableExpressionKind, Storage, Ops) {}
3321 ~DIGlobalVariableExpression() = default;
3322
3323 static DIGlobalVariableExpression *
3324 getImpl(LLVMContext &Context, Metadata *Variable, Metadata *Expression,
3325 StorageType Storage, bool ShouldCreate = true);
3326
3327 TempDIGlobalVariableExpression cloneImpl() const {
3328 return getTemporary(getContext(), getVariable(), getExpression());
3329 }
3330
3331public:
3332 DEFINE_MDNODE_GET(DIGlobalVariableExpression,
3333 (Metadata * Variable, Metadata *Expression),
3334 (Variable, Expression))
3335
3336 TempDIGlobalVariableExpression clone() const { return cloneImpl(); }
3337
3338 Metadata *getRawVariable() const { return getOperand(0); }
3339
3340 DIGlobalVariable *getVariable() const {
3341 return cast_or_null<DIGlobalVariable>(getRawVariable());
3342 }
3343
3344 Metadata *getRawExpression() const { return getOperand(1); }
3345
3346 DIExpression *getExpression() const {
3347 return cast<DIExpression>(getRawExpression());
3348 }
3349
3350 static bool classof(const Metadata *MD) {
3351 return MD->getMetadataID() == DIGlobalVariableExpressionKind;
3352 }
3353};
3354
3355/// Macro Info DWARF-like metadata node.
3356///
3357/// A metadata node with a DWARF macro info (i.e., a constant named
3358/// \c DW_MACINFO_*, defined in llvm/BinaryFormat/Dwarf.h). Called \a
3359/// DIMacroNode
3360/// because it's potentially used for non-DWARF output.
3361class DIMacroNode : public MDNode {
3362 friend class LLVMContextImpl;
3363 friend class MDNode;
3364
3365protected:
3366 DIMacroNode(LLVMContext &C, unsigned ID, StorageType Storage, unsigned MIType,
3367 ArrayRef<Metadata *> Ops1, ArrayRef<Metadata *> Ops2 = None)
3368 : MDNode(C, ID, Storage, Ops1, Ops2) {
3369 assert(MIType < 1u << 16);
3370 SubclassData16 = MIType;
3371 }
3372 ~DIMacroNode() = default;
3373
3374 template <class Ty> Ty *getOperandAs(unsigned I) const {
3375 return cast_or_null<Ty>(getOperand(I));
3376 }
3377
3378 StringRef getStringOperand(unsigned I) const {
3379 if (auto *S = getOperandAs<MDString>(I))
3380 return S->getString();
3381 return StringRef();
3382 }
3383
3384 static MDString *getCanonicalMDString(LLVMContext &Context, StringRef S) {
3385 if (S.empty())
3386 return nullptr;
3387 return MDString::get(Context, S);
3388 }
3389
3390public:
3391 unsigned getMacinfoType() const { return SubclassData16; }
3392
3393 static bool classof(const Metadata *MD) {
3394 switch (MD->getMetadataID()) {
3395 default:
3396 return false;
3397 case DIMacroKind:
3398 case DIMacroFileKind:
3399 return true;
3400 }
3401 }
3402};
3403
3404class DIMacro : public DIMacroNode {
3405 friend class LLVMContextImpl;
3406 friend class MDNode;
3407
3408 unsigned Line;
3409
3410 DIMacro(LLVMContext &C, StorageType Storage, unsigned MIType, unsigned Line,
3411 ArrayRef<Metadata *> Ops)
3412 : DIMacroNode(C, DIMacroKind, Storage, MIType, Ops), Line(Line) {}
3413 ~DIMacro() = default;
3414
3415 static DIMacro *getImpl(LLVMContext &Context, unsigned MIType, unsigned Line,
3416 StringRef Name, StringRef Value, StorageType Storage,
3417 bool ShouldCreate = true) {
3418 return getImpl(Context, MIType, Line, getCanonicalMDString(Context, Name),
3419 getCanonicalMDString(Context, Value), Storage, ShouldCreate);
3420 }
3421 static DIMacro *getImpl(LLVMContext &Context, unsigned MIType, unsigned Line,
3422 MDString *Name, MDString *Value, StorageType Storage,
3423 bool ShouldCreate = true);
3424
3425 TempDIMacro cloneImpl() const {
3426 return getTemporary(getContext(), getMacinfoType(), getLine(), getName(),
3427 getValue());
3428 }
3429
3430public:
3431 DEFINE_MDNODE_GET(DIMacro, (unsigned MIType, unsigned Line, StringRef Name,
3432 StringRef Value = ""),
3433 (MIType, Line, Name, Value))
3434 DEFINE_MDNODE_GET(DIMacro, (unsigned MIType, unsigned Line, MDString *Name,
3435 MDString *Value),
3436 (MIType, Line, Name, Value))
3437
3438 TempDIMacro clone() const { return cloneImpl(); }
3439
3440 unsigned getLine() const { return Line; }
3441
3442 StringRef getName() const { return getStringOperand(0); }
3443 StringRef getValue() const { return getStringOperand(1); }
3444
3445 MDString *getRawName() const { return getOperandAs<MDString>(0); }
3446 MDString *getRawValue() const { return getOperandAs<MDString>(1); }
3447
3448 static bool classof(const Metadata *MD) {
3449 return MD->getMetadataID() == DIMacroKind;
3450 }
3451};
3452
3453class DIMacroFile : public DIMacroNode {
3454 friend class LLVMContextImpl;
3455 friend class MDNode;
3456
3457 unsigned Line;
3458
3459 DIMacroFile(LLVMContext &C, StorageType Storage, unsigned MIType,
3460 unsigned Line, ArrayRef<Metadata *> Ops)
3461 : DIMacroNode(C, DIMacroFileKind, Storage, MIType, Ops), Line(Line) {}
3462 ~DIMacroFile() = default;
3463
3464 static DIMacroFile *getImpl(LLVMContext &Context, unsigned MIType,
3465 unsigned Line, DIFile *File,
3466 DIMacroNodeArray Elements, StorageType Storage,
3467 bool ShouldCreate = true) {
3468 return getImpl(Context, MIType, Line, static_cast<Metadata *>(File),
3469 Elements.get(), Storage, ShouldCreate);
3470 }
3471
3472 static DIMacroFile *getImpl(LLVMContext &Context, unsigned MIType,
3473 unsigned Line, Metadata *File, Metadata *Elements,
3474 StorageType Storage, bool ShouldCreate = true);
3475
3476 TempDIMacroFile cloneImpl() const {
3477 return getTemporary(getContext(), getMacinfoType(), getLine(), getFile(),
3478 getElements());
3479 }
3480
3481public:
3482 DEFINE_MDNODE_GET(DIMacroFile, (unsigned MIType, unsigned Line, DIFile *File,
3483 DIMacroNodeArray Elements),
3484 (MIType, Line, File, Elements))
3485 DEFINE_MDNODE_GET(DIMacroFile, (unsigned MIType, unsigned Line,
3486 Metadata *File, Metadata *Elements),
3487 (MIType, Line, File, Elements))
3488
3489 TempDIMacroFile clone() const { return cloneImpl(); }
3490
3491 void replaceElements(DIMacroNodeArray Elements) {
3492#ifndef NDEBUG
3493 for (DIMacroNode *Op : getElements())
3494 assert(is_contained(Elements->operands(), Op) &&
3495 "Lost a macro node during macro node list replacement");
3496#endif
3497 replaceOperandWith(1, Elements.get());
3498 }
3499
3500 unsigned getLine() const { return Line; }
3501 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
3502
3503 DIMacroNodeArray getElements() const {
3504 return cast_or_null<MDTuple>(getRawElements());
3505 }
3506
3507 Metadata *getRawFile() const { return getOperand(0); }
3508 Metadata *getRawElements() const { return getOperand(1); }
3509
3510 static bool classof(const Metadata *MD) {
3511 return MD->getMetadataID() == DIMacroFileKind;
3512 }
3513};
3514
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02003515/// Identifies a unique instance of a variable.
3516///
3517/// Storage for identifying a potentially inlined instance of a variable,
3518/// or a fragment thereof. This guarantees that exactly one variable instance
3519/// may be identified by this class, even when that variable is a fragment of
3520/// an aggregate variable and/or there is another inlined instance of the same
3521/// source code variable nearby.
3522/// This class does not necessarily uniquely identify that variable: it is
3523/// possible that a DebugVariable with different parameters may point to the
3524/// same variable instance, but not that one DebugVariable points to multiple
3525/// variable instances.
3526class DebugVariable {
3527 using FragmentInfo = DIExpression::FragmentInfo;
3528
3529 const DILocalVariable *Variable;
3530 Optional<FragmentInfo> Fragment;
3531 const DILocation *InlinedAt;
3532
3533 /// Fragment that will overlap all other fragments. Used as default when
3534 /// caller demands a fragment.
3535 static const FragmentInfo DefaultFragment;
3536
3537public:
3538 DebugVariable(const DILocalVariable *Var, Optional<FragmentInfo> FragmentInfo,
3539 const DILocation *InlinedAt)
3540 : Variable(Var), Fragment(FragmentInfo), InlinedAt(InlinedAt) {}
3541
3542 DebugVariable(const DILocalVariable *Var, const DIExpression *DIExpr,
3543 const DILocation *InlinedAt)
3544 : Variable(Var),
3545 Fragment(DIExpr ? DIExpr->getFragmentInfo() : NoneType()),
3546 InlinedAt(InlinedAt) {}
3547
3548 const DILocalVariable *getVariable() const { return Variable; }
3549 const Optional<FragmentInfo> getFragment() const { return Fragment; }
3550 const DILocation *getInlinedAt() const { return InlinedAt; }
3551
3552 const FragmentInfo getFragmentOrDefault() const {
3553 return Fragment.getValueOr(DefaultFragment);
3554 }
3555
3556 static bool isDefaultFragment(const FragmentInfo F) {
3557 return F == DefaultFragment;
3558 }
3559
3560 bool operator==(const DebugVariable &Other) const {
3561 return std::tie(Variable, Fragment, InlinedAt) ==
3562 std::tie(Other.Variable, Other.Fragment, Other.InlinedAt);
3563 }
3564
3565 bool operator<(const DebugVariable &Other) const {
3566 return std::tie(Variable, Fragment, InlinedAt) <
3567 std::tie(Other.Variable, Other.Fragment, Other.InlinedAt);
3568 }
3569};
3570
3571template <> struct DenseMapInfo<DebugVariable> {
3572 using FragmentInfo = DIExpression::FragmentInfo;
3573
3574 /// Empty key: no key should be generated that has no DILocalVariable.
3575 static inline DebugVariable getEmptyKey() {
3576 return DebugVariable(nullptr, NoneType(), nullptr);
3577 }
3578
3579 /// Difference in tombstone is that the Optional is meaningful.
3580 static inline DebugVariable getTombstoneKey() {
3581 return DebugVariable(nullptr, {{0, 0}}, nullptr);
3582 }
3583
3584 static unsigned getHashValue(const DebugVariable &D) {
3585 unsigned HV = 0;
3586 const Optional<FragmentInfo> Fragment = D.getFragment();
3587 if (Fragment)
3588 HV = DenseMapInfo<FragmentInfo>::getHashValue(*Fragment);
3589
3590 return hash_combine(D.getVariable(), HV, D.getInlinedAt());
3591 }
3592
3593 static bool isEqual(const DebugVariable &A, const DebugVariable &B) {
3594 return A == B;
3595 }
3596};
3597
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01003598} // end namespace llvm
3599
3600#undef DEFINE_MDNODE_GET_UNPACK_IMPL
3601#undef DEFINE_MDNODE_GET_UNPACK
3602#undef DEFINE_MDNODE_GET
3603
3604#endif // LLVM_IR_DEBUGINFOMETADATA_H