blob: 8e502e479f1534d879b7ecdc8310a748ccf14cd0 [file] [log] [blame]
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +00001//===- llvm/IR/DebugInfoMetadata.h - Debug info metadata --------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// Declarations for metadata specific to debug info.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_IR_DEBUGINFOMETADATA_H
15#define LLVM_IR_DEBUGINFOMETADATA_H
16
Eugene Zelenko1aa40f42016-11-23 22:25:16 +000017#include "llvm/ADT/ArrayRef.h"
Leny Kholodov40c62352016-09-06 17:03:02 +000018#include "llvm/ADT/BitmaskEnum.h"
Eugene Zelenko1aa40f42016-11-23 22:25:16 +000019#include "llvm/ADT/None.h"
Eugene Zelenkod761e2c2017-05-15 21:57:41 +000020#include "llvm/ADT/Optional.h"
Sander de Smalenfdf40912018-01-24 09:56:07 +000021#include "llvm/ADT/PointerUnion.h"
Eugene Zelenkod761e2c2017-05-15 21:57:41 +000022#include "llvm/ADT/STLExtras.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000023#include "llvm/ADT/SmallVector.h"
Eugene Zelenko1aa40f42016-11-23 22:25:16 +000024#include "llvm/ADT/StringRef.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000025#include "llvm/ADT/iterator_range.h"
Zachary Turner264b5d92017-06-07 03:48:56 +000026#include "llvm/BinaryFormat/Dwarf.h"
Sander de Smalenfdf40912018-01-24 09:56:07 +000027#include "llvm/IR/Constants.h"
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +000028#include "llvm/IR/Metadata.h"
Eugene Zelenko1aa40f42016-11-23 22:25:16 +000029#include "llvm/Support/Casting.h"
Eugene Zelenko1aa40f42016-11-23 22:25:16 +000030#include <cassert>
31#include <climits>
32#include <cstddef>
33#include <cstdint>
34#include <iterator>
35#include <type_traits>
36#include <vector>
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +000037
Duncan P. N. Exon Smith61e62a52015-02-02 19:55:21 +000038// Helper macros for defining get() overrides.
39#define DEFINE_MDNODE_GET_UNPACK_IMPL(...) __VA_ARGS__
40#define DEFINE_MDNODE_GET_UNPACK(ARGS) DEFINE_MDNODE_GET_UNPACK_IMPL ARGS
Duncan P. N. Exon Smith55ca9642015-08-03 17:26:41 +000041#define DEFINE_MDNODE_GET_DISTINCT_TEMPORARY(CLASS, FORMAL, ARGS) \
Duncan P. N. Exon Smith61e62a52015-02-02 19:55:21 +000042 static CLASS *getDistinct(LLVMContext &Context, \
43 DEFINE_MDNODE_GET_UNPACK(FORMAL)) { \
44 return getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Distinct); \
45 } \
46 static Temp##CLASS getTemporary(LLVMContext &Context, \
47 DEFINE_MDNODE_GET_UNPACK(FORMAL)) { \
48 return Temp##CLASS( \
49 getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Temporary)); \
50 }
Duncan P. N. Exon Smith55ca9642015-08-03 17:26:41 +000051#define DEFINE_MDNODE_GET(CLASS, FORMAL, ARGS) \
52 static CLASS *get(LLVMContext &Context, DEFINE_MDNODE_GET_UNPACK(FORMAL)) { \
53 return getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Uniqued); \
54 } \
55 static CLASS *getIfExists(LLVMContext &Context, \
56 DEFINE_MDNODE_GET_UNPACK(FORMAL)) { \
57 return getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Uniqued, \
58 /* ShouldCreate */ false); \
59 } \
60 DEFINE_MDNODE_GET_DISTINCT_TEMPORARY(CLASS, FORMAL, ARGS)
Duncan P. N. Exon Smith61e62a52015-02-02 19:55:21 +000061
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +000062namespace llvm {
63
Duncan P. N. Exon Smitha59d3e52016-04-23 21:08:00 +000064/// Holds a subclass of DINode.
Duncan P. N. Exon Smith930f3882015-04-06 18:02:43 +000065///
Duncan P. N. Exon Smitha59d3e52016-04-23 21:08:00 +000066/// FIXME: This class doesn't currently make much sense. Previously it was a
67/// union beteen MDString (for ODR-uniqued types) and things like DIType. To
68/// support CodeView work, it wasn't deleted outright when MDString-based type
69/// references were deleted; we'll soon need a similar concept for CodeView
70/// DITypeIndex.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +000071template <class T> class TypedDINodeRef {
Duncan P. N. Exon Smith930f3882015-04-06 18:02:43 +000072 const Metadata *MD = nullptr;
73
74public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +000075 TypedDINodeRef() = default;
76 TypedDINodeRef(std::nullptr_t) {}
Duncan P. N. Exon Smitha59d3e52016-04-23 21:08:00 +000077 TypedDINodeRef(const T *MD) : MD(MD) {}
Duncan P. N. Exon Smith930f3882015-04-06 18:02:43 +000078
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +000079 explicit TypedDINodeRef(const Metadata *MD) : MD(MD) {
Duncan P. N. Exon Smitha59d3e52016-04-23 21:08:00 +000080 assert((!MD || isa<T>(MD)) && "Expected valid type ref");
Duncan P. N. Exon Smith930f3882015-04-06 18:02:43 +000081 }
82
83 template <class U>
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +000084 TypedDINodeRef(
85 const TypedDINodeRef<U> &X,
Duncan P. N. Exon Smith930f3882015-04-06 18:02:43 +000086 typename std::enable_if<std::is_convertible<U *, T *>::value>::type * =
87 nullptr)
88 : MD(X) {}
89
90 operator Metadata *() const { return const_cast<Metadata *>(MD); }
91
Duncan P. N. Exon Smitha59d3e52016-04-23 21:08:00 +000092 T *resolve() const { return const_cast<T *>(cast_or_null<T>(MD)); }
93
Hans Wennborg13958b72015-07-22 20:46:11 +000094 bool operator==(const TypedDINodeRef<T> &X) const { return MD == X.MD; }
95 bool operator!=(const TypedDINodeRef<T> &X) const { return MD != X.MD; }
Duncan P. N. Exon Smith930f3882015-04-06 18:02:43 +000096};
97
Eugene Zelenkod761e2c2017-05-15 21:57:41 +000098using DINodeRef = TypedDINodeRef<DINode>;
99using DIScopeRef = TypedDINodeRef<DIScope>;
100using DITypeRef = TypedDINodeRef<DIType>;
Duncan P. N. Exon Smith930f3882015-04-06 18:02:43 +0000101
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000102class DITypeRefArray {
Duncan P. N. Exon Smith62e93622015-04-06 19:48:50 +0000103 const MDTuple *N = nullptr;
104
105public:
Duncan P. N. Exon Smith0660bcd2015-08-28 21:38:24 +0000106 DITypeRefArray() = default;
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000107 DITypeRefArray(const MDTuple *N) : N(N) {}
Duncan P. N. Exon Smith11344732015-04-07 16:50:39 +0000108
109 explicit operator bool() const { return get(); }
110 explicit operator MDTuple *() const { return get(); }
111
112 MDTuple *get() const { return const_cast<MDTuple *>(N); }
113 MDTuple *operator->() const { return get(); }
114 MDTuple &operator*() const { return *get(); }
Duncan P. N. Exon Smith62e93622015-04-06 19:48:50 +0000115
Duncan P. N. Exon Smith000fa2c2015-04-07 04:14:33 +0000116 // FIXME: Fix callers and remove condition on N.
117 unsigned size() const { return N ? N->getNumOperands() : 0u; }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000118 DITypeRef operator[](unsigned I) const { return DITypeRef(N->getOperand(I)); }
Duncan P. N. Exon Smith62e93622015-04-06 19:48:50 +0000119
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000120 class iterator : std::iterator<std::input_iterator_tag, DITypeRef,
121 std::ptrdiff_t, void, DITypeRef> {
Duncan P. N. Exon Smith000fa2c2015-04-07 04:14:33 +0000122 MDNode::op_iterator I = nullptr;
Duncan P. N. Exon Smith62e93622015-04-06 19:48:50 +0000123
124 public:
Duncan P. N. Exon Smith000fa2c2015-04-07 04:14:33 +0000125 iterator() = default;
Duncan P. N. Exon Smith62e93622015-04-06 19:48:50 +0000126 explicit iterator(MDNode::op_iterator I) : I(I) {}
Eugene Zelenko1aa40f42016-11-23 22:25:16 +0000127
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000128 DITypeRef operator*() const { return DITypeRef(*I); }
Eugene Zelenko1aa40f42016-11-23 22:25:16 +0000129
Duncan P. N. Exon Smith62e93622015-04-06 19:48:50 +0000130 iterator &operator++() {
131 ++I;
132 return *this;
133 }
Eugene Zelenko1aa40f42016-11-23 22:25:16 +0000134
Duncan P. N. Exon Smith62e93622015-04-06 19:48:50 +0000135 iterator operator++(int) {
136 iterator Temp(*this);
137 ++I;
138 return Temp;
139 }
Eugene Zelenko1aa40f42016-11-23 22:25:16 +0000140
Duncan P. N. Exon Smith62e93622015-04-06 19:48:50 +0000141 bool operator==(const iterator &X) const { return I == X.I; }
142 bool operator!=(const iterator &X) const { return I != X.I; }
143 };
144
Duncan P. N. Exon Smith000fa2c2015-04-07 04:14:33 +0000145 // FIXME: Fix callers and remove condition on N.
146 iterator begin() const { return N ? iterator(N->op_begin()) : iterator(); }
147 iterator end() const { return N ? iterator(N->op_end()) : iterator(); }
Duncan P. N. Exon Smith62e93622015-04-06 19:48:50 +0000148};
149
Adrian Prantl1687e012016-11-14 22:09:18 +0000150/// Tagged DWARF-like metadata node.
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000151///
152/// A metadata node with a DWARF tag (i.e., a constant named \c DW_TAG_*,
Zachary Turner264b5d92017-06-07 03:48:56 +0000153/// defined in llvm/BinaryFormat/Dwarf.h). Called \a DINode because it's
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000154/// potentially used for non-DWARF output.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000155class DINode : public MDNode {
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000156 friend class LLVMContextImpl;
157 friend class MDNode;
158
159protected:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000160 DINode(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
161 ArrayRef<Metadata *> Ops1, ArrayRef<Metadata *> Ops2 = None)
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000162 : MDNode(C, ID, Storage, Ops1, Ops2) {
163 assert(Tag < 1u << 16);
164 SubclassData16 = Tag;
165 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000166 ~DINode() = default;
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000167
Duncan P. N. Exon Smith252b62d2015-02-05 01:07:47 +0000168 template <class Ty> Ty *getOperandAs(unsigned I) const {
169 return cast_or_null<Ty>(getOperand(I));
170 }
171
Duncan P. N. Exon Smith442ec022015-02-02 19:54:05 +0000172 StringRef getStringOperand(unsigned I) const {
Duncan P. N. Exon Smith252b62d2015-02-05 01:07:47 +0000173 if (auto *S = getOperandAs<MDString>(I))
Duncan P. N. Exon Smith442ec022015-02-02 19:54:05 +0000174 return S->getString();
175 return StringRef();
176 }
177
Duncan P. N. Exon Smith9146fc82015-02-02 20:01:03 +0000178 static MDString *getCanonicalMDString(LLVMContext &Context, StringRef S) {
179 if (S.empty())
180 return nullptr;
181 return MDString::get(Context, S);
182 }
183
Duncan P. N. Exon Smith97386022016-04-19 18:00:19 +0000184 /// Allow subclasses to mutate the tag.
185 void setTag(unsigned Tag) { SubclassData16 = Tag; }
186
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000187public:
188 unsigned getTag() const { return SubclassData16; }
189
Adrian Prantl1687e012016-11-14 22:09:18 +0000190 /// Debug info flags.
Duncan P. N. Exon Smith3744fd02015-03-31 01:19:51 +0000191 ///
192 /// The three accessibility flags are mutually exclusive and rolled together
193 /// in the first two bits.
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000194 enum DIFlags : uint32_t {
Duncan P. N. Exon Smith3744fd02015-03-31 01:19:51 +0000195#define HANDLE_DI_FLAG(ID, NAME) Flag##NAME = ID,
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000196#define DI_FLAG_LARGEST_NEEDED
Duncan P. N. Exon Smith3744fd02015-03-31 01:19:51 +0000197#include "llvm/IR/DebugInfoFlags.def"
Reid Kleckner604105b2016-06-17 21:31:33 +0000198 FlagAccessibility = FlagPrivate | FlagProtected | FlagPublic,
199 FlagPtrToMemberRep = FlagSingleInheritance | FlagMultipleInheritance |
200 FlagVirtualInheritance,
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000201 LLVM_MARK_AS_BITMASK_ENUM(FlagLargest)
Duncan P. N. Exon Smith3744fd02015-03-31 01:19:51 +0000202 };
203
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000204 static DIFlags getFlag(StringRef Flag);
Mehdi Aminif42ec792016-10-01 05:57:50 +0000205 static StringRef getFlagString(DIFlags Flag);
Duncan P. N. Exon Smith5261e4b2015-04-07 01:21:40 +0000206
Adrian Prantl1687e012016-11-14 22:09:18 +0000207 /// Split up a flags bitfield.
Duncan P. N. Exon Smith5261e4b2015-04-07 01:21:40 +0000208 ///
209 /// Split \c Flags into \c SplitFlags, a vector of its components. Returns
210 /// any remaining (unrecognized) bits.
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000211 static DIFlags splitFlags(DIFlags Flags,
Leny Kholodov40c62352016-09-06 17:03:02 +0000212 SmallVectorImpl<DIFlags> &SplitFlags);
Duncan P. N. Exon Smith5261e4b2015-04-07 01:21:40 +0000213
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000214 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000215 switch (MD->getMetadataID()) {
216 default:
217 return false;
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000218 case GenericDINodeKind:
219 case DISubrangeKind:
220 case DIEnumeratorKind:
221 case DIBasicTypeKind:
222 case DIDerivedTypeKind:
223 case DICompositeTypeKind:
224 case DISubroutineTypeKind:
225 case DIFileKind:
226 case DICompileUnitKind:
227 case DISubprogramKind:
228 case DILexicalBlockKind:
229 case DILexicalBlockFileKind:
230 case DINamespaceKind:
231 case DITemplateTypeParameterKind:
232 case DITemplateValueParameterKind:
233 case DIGlobalVariableKind:
234 case DILocalVariableKind:
Shiva Chen2c864552018-05-09 02:40:45 +0000235 case DILabelKind:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000236 case DIObjCPropertyKind:
237 case DIImportedEntityKind:
Adrian Prantlab1243f2015-06-29 23:03:47 +0000238 case DIModuleKind:
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000239 return true;
240 }
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000241 }
242};
243
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000244template <class T> struct simplify_type<const TypedDINodeRef<T>> {
Eugene Zelenkod761e2c2017-05-15 21:57:41 +0000245 using SimpleType = Metadata *;
246
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000247 static SimpleType getSimplifiedValue(const TypedDINodeRef<T> &MD) {
Duncan P. N. Exon Smith930f3882015-04-06 18:02:43 +0000248 return MD;
249 }
250};
251
252template <class T>
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000253struct simplify_type<TypedDINodeRef<T>>
254 : simplify_type<const TypedDINodeRef<T>> {};
Duncan P. N. Exon Smith930f3882015-04-06 18:02:43 +0000255
Adrian Prantl1687e012016-11-14 22:09:18 +0000256/// Generic tagged DWARF-like metadata node.
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000257///
258/// An un-specialized DWARF-like metadata node. The first operand is a
259/// (possibly empty) null-separated \a MDString header that contains arbitrary
260/// fields. The remaining operands are \a dwarf_operands(), and are pointers
261/// to other metadata.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000262class GenericDINode : public DINode {
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000263 friend class LLVMContextImpl;
264 friend class MDNode;
265
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000266 GenericDINode(LLVMContext &C, StorageType Storage, unsigned Hash,
267 unsigned Tag, ArrayRef<Metadata *> Ops1,
268 ArrayRef<Metadata *> Ops2)
269 : DINode(C, GenericDINodeKind, Storage, Tag, Ops1, Ops2) {
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000270 setHash(Hash);
271 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000272 ~GenericDINode() { dropAllReferences(); }
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000273
274 void setHash(unsigned Hash) { SubclassData32 = Hash; }
275 void recalculateHash();
276
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000277 static GenericDINode *getImpl(LLVMContext &Context, unsigned Tag,
278 StringRef Header, ArrayRef<Metadata *> DwarfOps,
279 StorageType Storage, bool ShouldCreate = true) {
Duncan P. N. Exon Smith9146fc82015-02-02 20:01:03 +0000280 return getImpl(Context, Tag, getCanonicalMDString(Context, Header),
281 DwarfOps, Storage, ShouldCreate);
282 }
283
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000284 static GenericDINode *getImpl(LLVMContext &Context, unsigned Tag,
285 MDString *Header, ArrayRef<Metadata *> DwarfOps,
286 StorageType Storage, bool ShouldCreate = true);
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000287
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000288 TempGenericDINode cloneImpl() const {
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000289 return getTemporary(
290 getContext(), getTag(), getHeader(),
291 SmallVector<Metadata *, 4>(dwarf_op_begin(), dwarf_op_end()));
292 }
293
294public:
295 unsigned getHash() const { return SubclassData32; }
296
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000297 DEFINE_MDNODE_GET(GenericDINode, (unsigned Tag, StringRef Header,
298 ArrayRef<Metadata *> DwarfOps),
Duncan P. N. Exon Smith61e62a52015-02-02 19:55:21 +0000299 (Tag, Header, DwarfOps))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000300 DEFINE_MDNODE_GET(GenericDINode, (unsigned Tag, MDString *Header,
301 ArrayRef<Metadata *> DwarfOps),
Duncan P. N. Exon Smith9146fc82015-02-02 20:01:03 +0000302 (Tag, Header, DwarfOps))
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000303
Adrian Prantl1687e012016-11-14 22:09:18 +0000304 /// Return a (temporary) clone of this.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000305 TempGenericDINode clone() const { return cloneImpl(); }
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000306
307 unsigned getTag() const { return SubclassData16; }
Duncan P. N. Exon Smith442ec022015-02-02 19:54:05 +0000308 StringRef getHeader() const { return getStringOperand(0); }
Mehdi Amini5d99c4e2016-03-19 01:02:34 +0000309 MDString *getRawHeader() const { return getOperandAs<MDString>(0); }
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000310
311 op_iterator dwarf_op_begin() const { return op_begin() + 1; }
312 op_iterator dwarf_op_end() const { return op_end(); }
313 op_range dwarf_operands() const {
314 return op_range(dwarf_op_begin(), dwarf_op_end());
315 }
316
317 unsigned getNumDwarfOperands() const { return getNumOperands() - 1; }
318 const MDOperand &getDwarfOperand(unsigned I) const {
319 return getOperand(I + 1);
320 }
321 void replaceDwarfOperandWith(unsigned I, Metadata *New) {
322 replaceOperandWith(I + 1, New);
323 }
324
325 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000326 return MD->getMetadataID() == GenericDINodeKind;
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000327 }
328};
329
Adrian Prantl1687e012016-11-14 22:09:18 +0000330/// Array subrange.
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000331///
332/// TODO: Merge into node for DW_TAG_array_type, which should have a custom
333/// type.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000334class DISubrange : public DINode {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000335 friend class LLVMContextImpl;
336 friend class MDNode;
337
Duncan P. N. Exon Smith5dcf6212015-04-07 00:39:59 +0000338 int64_t LowerBound;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000339
Sander de Smalenfdf40912018-01-24 09:56:07 +0000340 DISubrange(LLVMContext &C, StorageType Storage, Metadata *Node,
341 int64_t LowerBound, ArrayRef<Metadata *> Ops)
342 : DINode(C, DISubrangeKind, Storage, dwarf::DW_TAG_subrange_type, Ops),
343 LowerBound(LowerBound) {}
344
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000345 ~DISubrange() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000346
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000347 static DISubrange *getImpl(LLVMContext &Context, int64_t Count,
Duncan P. N. Exon Smith5dcf6212015-04-07 00:39:59 +0000348 int64_t LowerBound, StorageType Storage,
349 bool ShouldCreate = true);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000350
Sander de Smalenfdf40912018-01-24 09:56:07 +0000351 static DISubrange *getImpl(LLVMContext &Context, Metadata *CountNode,
352 int64_t LowerBound, StorageType Storage,
353 bool ShouldCreate = true);
354
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000355 TempDISubrange cloneImpl() const {
Sander de Smalenfdf40912018-01-24 09:56:07 +0000356 return getTemporary(getContext(), getRawCountNode(), getLowerBound());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000357 }
358
359public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000360 DEFINE_MDNODE_GET(DISubrange, (int64_t Count, int64_t LowerBound = 0),
Duncan P. N. Exon Smith5dcf6212015-04-07 00:39:59 +0000361 (Count, LowerBound))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000362
Sander de Smalenfdf40912018-01-24 09:56:07 +0000363 DEFINE_MDNODE_GET(DISubrange, (Metadata *CountNode, int64_t LowerBound = 0),
364 (CountNode, LowerBound))
365
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000366 TempDISubrange clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000367
Duncan P. N. Exon Smith5dcf6212015-04-07 00:39:59 +0000368 int64_t getLowerBound() const { return LowerBound; }
Sander de Smalenfdf40912018-01-24 09:56:07 +0000369
370 Metadata *getRawCountNode() const {
371 return getOperand(0).get();
372 }
373
374 typedef PointerUnion<ConstantInt*, DIVariable*> CountType;
375
376 CountType getCount() const {
377 if (auto *MD = dyn_cast<ConstantAsMetadata>(getRawCountNode()))
378 return CountType(cast<ConstantInt>(MD->getValue()));
379
380 if (auto *DV = dyn_cast<DIVariable>(getRawCountNode()))
381 return CountType(DV);
382
383 return CountType();
384 }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000385
386 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000387 return MD->getMetadataID() == DISubrangeKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000388 }
389};
390
Adrian Prantl1687e012016-11-14 22:09:18 +0000391/// Enumeration value.
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000392///
393/// TODO: Add a pointer to the context (DW_TAG_enumeration_type) once that no
394/// longer creates a type cycle.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000395class DIEnumerator : public DINode {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000396 friend class LLVMContextImpl;
397 friend class MDNode;
398
399 int64_t Value;
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000400 DIEnumerator(LLVMContext &C, StorageType Storage, int64_t Value,
Momchil Velikov08dc66e2018-02-12 16:10:09 +0000401 bool IsUnsigned, ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000402 : DINode(C, DIEnumeratorKind, Storage, dwarf::DW_TAG_enumerator, Ops),
Momchil Velikov08dc66e2018-02-12 16:10:09 +0000403 Value(Value) {
404 SubclassData32 = IsUnsigned;
405 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000406 ~DIEnumerator() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000407
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000408 static DIEnumerator *getImpl(LLVMContext &Context, int64_t Value,
Momchil Velikov08dc66e2018-02-12 16:10:09 +0000409 bool IsUnsigned, StringRef Name,
410 StorageType Storage, bool ShouldCreate = true) {
411 return getImpl(Context, Value, IsUnsigned,
412 getCanonicalMDString(Context, Name), Storage, ShouldCreate);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000413 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000414 static DIEnumerator *getImpl(LLVMContext &Context, int64_t Value,
Momchil Velikov08dc66e2018-02-12 16:10:09 +0000415 bool IsUnsigned, MDString *Name,
416 StorageType Storage, bool ShouldCreate = true);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000417
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000418 TempDIEnumerator cloneImpl() const {
Momchil Velikov08dc66e2018-02-12 16:10:09 +0000419 return getTemporary(getContext(), getValue(), isUnsigned(), getName());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000420 }
421
422public:
Momchil Velikov08dc66e2018-02-12 16:10:09 +0000423 DEFINE_MDNODE_GET(DIEnumerator, (int64_t Value, bool IsUnsigned, StringRef Name),
424 (Value, IsUnsigned, Name))
425 DEFINE_MDNODE_GET(DIEnumerator, (int64_t Value, bool IsUnsigned, MDString *Name),
426 (Value, IsUnsigned, Name))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000427
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000428 TempDIEnumerator clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000429
430 int64_t getValue() const { return Value; }
Momchil Velikov08dc66e2018-02-12 16:10:09 +0000431 bool isUnsigned() const { return SubclassData32; }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000432 StringRef getName() const { return getStringOperand(0); }
433
Duncan P. N. Exon Smith87754762015-02-13 01:14:11 +0000434 MDString *getRawName() const { return getOperandAs<MDString>(0); }
435
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000436 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000437 return MD->getMetadataID() == DIEnumeratorKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000438 }
439};
440
Adrian Prantl1687e012016-11-14 22:09:18 +0000441/// Base class for scope-like contexts.
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000442///
443/// Base class for lexical scopes and types (which are also declaration
444/// contexts).
445///
446/// TODO: Separate the concepts of declaration contexts and lexical scopes.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000447class DIScope : public DINode {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000448protected:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000449 DIScope(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000450 ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000451 : DINode(C, ID, Storage, Tag, Ops) {}
452 ~DIScope() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000453
454public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000455 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
Duncan P. N. Exon Smith53855f02015-03-27 23:05:04 +0000456
Duncan P. N. Exon Smith50c065b2015-04-11 00:39:43 +0000457 inline StringRef getFilename() const;
458 inline StringRef getDirectory() const;
Scott Linder16c7bda2018-02-23 23:01:06 +0000459 inline Optional<StringRef> getSource() const;
Duncan P. N. Exon Smith50c065b2015-04-11 00:39:43 +0000460
Duncan P. N. Exon Smithf0d81a52015-04-11 17:37:23 +0000461 StringRef getName() const;
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000462 DIScopeRef getScope() const;
Duncan P. N. Exon Smithf0d81a52015-04-11 17:37:23 +0000463
Adrian Prantl1687e012016-11-14 22:09:18 +0000464 /// Return the raw underlying file.
Duncan P. N. Exon Smith2c6a0a92015-02-28 21:47:02 +0000465 ///
Adrian Prantlb9a8f7a2017-07-14 23:23:58 +0000466 /// A \a DIFile is a \a DIScope, but it doesn't point at a separate file (it
467 /// \em is the file). If \c this is an \a DIFile, we need to return \c this.
468 /// Otherwise, return the first operand, which is where all other subclasses
469 /// store their file pointer.
Duncan P. N. Exon Smith53855f02015-03-27 23:05:04 +0000470 Metadata *getRawFile() const {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000471 return isa<DIFile>(this) ? const_cast<DIScope *>(this)
Duncan P. N. Exon Smith3a46c142015-02-28 21:58:10 +0000472 : static_cast<Metadata *>(getOperand(0));
Duncan P. N. Exon Smith2c6a0a92015-02-28 21:47:02 +0000473 }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000474
475 static bool classof(const Metadata *MD) {
476 switch (MD->getMetadataID()) {
477 default:
478 return false;
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000479 case DIBasicTypeKind:
480 case DIDerivedTypeKind:
481 case DICompositeTypeKind:
482 case DISubroutineTypeKind:
483 case DIFileKind:
484 case DICompileUnitKind:
485 case DISubprogramKind:
486 case DILexicalBlockKind:
487 case DILexicalBlockFileKind:
488 case DINamespaceKind:
Adrian Prantlab1243f2015-06-29 23:03:47 +0000489 case DIModuleKind:
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000490 return true;
491 }
492 }
493};
494
Adrian Prantl1687e012016-11-14 22:09:18 +0000495/// File.
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +0000496///
497/// TODO: Merge with directory/file node (including users).
498/// TODO: Canonicalize paths on creation.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000499class DIFile : public DIScope {
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +0000500 friend class LLVMContextImpl;
501 friend class MDNode;
502
Amjad Aboud7faeecc2016-12-25 10:12:09 +0000503public:
Scott Linder71603842018-02-12 19:45:54 +0000504 /// Which algorithm (e.g. MD5) a checksum was generated with.
505 ///
506 /// The encoding is explicit because it is used directly in Bitcode. The
507 /// value 0 is reserved to indicate the absence of a checksum in Bitcode.
Amjad Aboud7faeecc2016-12-25 10:12:09 +0000508 enum ChecksumKind {
Scott Linder71603842018-02-12 19:45:54 +0000509 // The first variant was originally CSK_None, encoded as 0. The new
510 // internal representation removes the need for this by wrapping the
511 // ChecksumInfo in an Optional, but to preserve Bitcode compatibility the 0
512 // encoding is reserved.
Reid Kleckner26fa1bf2017-09-19 18:14:45 +0000513 CSK_MD5 = 1,
514 CSK_SHA1 = 2,
Amjad Aboud7faeecc2016-12-25 10:12:09 +0000515 CSK_Last = CSK_SHA1 // Should be last enumeration.
516 };
517
Scott Linder71603842018-02-12 19:45:54 +0000518 /// A single checksum, represented by a \a Kind and a \a Value (a string).
519 template <typename T>
520 struct ChecksumInfo {
521 /// The kind of checksum which \a Value encodes.
522 ChecksumKind Kind;
523 /// The string value of the checksum.
524 T Value;
Amjad Aboud7faeecc2016-12-25 10:12:09 +0000525
Scott Linder71603842018-02-12 19:45:54 +0000526 ChecksumInfo(ChecksumKind Kind, T Value) : Kind(Kind), Value(Value) { }
527 ~ChecksumInfo() = default;
528 bool operator==(const ChecksumInfo<T> &X) const {
529 return Kind == X.Kind && Value == X.Value;
530 }
531 bool operator!=(const ChecksumInfo<T> &X) const { return !(*this == X); }
532 StringRef getKindAsString() const { return getChecksumKindAsString(Kind); }
533 };
534
535private:
536 Optional<ChecksumInfo<MDString *>> Checksum;
Scott Linder16c7bda2018-02-23 23:01:06 +0000537 Optional<MDString *> Source;
Scott Linder71603842018-02-12 19:45:54 +0000538
539 DIFile(LLVMContext &C, StorageType Storage,
Scott Linder16c7bda2018-02-23 23:01:06 +0000540 Optional<ChecksumInfo<MDString *>> CS, Optional<MDString *> Src,
Amjad Aboud7faeecc2016-12-25 10:12:09 +0000541 ArrayRef<Metadata *> Ops)
542 : DIScope(C, DIFileKind, Storage, dwarf::DW_TAG_file_type, Ops),
Scott Linder16c7bda2018-02-23 23:01:06 +0000543 Checksum(CS), Source(Src) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000544 ~DIFile() = default;
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +0000545
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000546 static DIFile *getImpl(LLVMContext &Context, StringRef Filename,
Scott Linder71603842018-02-12 19:45:54 +0000547 StringRef Directory,
548 Optional<ChecksumInfo<StringRef>> CS,
Scott Linder16c7bda2018-02-23 23:01:06 +0000549 Optional<StringRef> Source,
Amjad Aboud7faeecc2016-12-25 10:12:09 +0000550 StorageType Storage, bool ShouldCreate = true) {
Scott Linder71603842018-02-12 19:45:54 +0000551 Optional<ChecksumInfo<MDString *>> MDChecksum;
552 if (CS)
553 MDChecksum.emplace(CS->Kind, getCanonicalMDString(Context, CS->Value));
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +0000554 return getImpl(Context, getCanonicalMDString(Context, Filename),
Scott Linder71603842018-02-12 19:45:54 +0000555 getCanonicalMDString(Context, Directory), MDChecksum,
Scott Linder16c7bda2018-02-23 23:01:06 +0000556 Source ? Optional<MDString *>(getCanonicalMDString(Context, *Source)) : None,
Scott Linder71603842018-02-12 19:45:54 +0000557 Storage, ShouldCreate);
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +0000558 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000559 static DIFile *getImpl(LLVMContext &Context, MDString *Filename,
Scott Linder71603842018-02-12 19:45:54 +0000560 MDString *Directory,
561 Optional<ChecksumInfo<MDString *>> CS,
Scott Linder16c7bda2018-02-23 23:01:06 +0000562 Optional<MDString *> Source, StorageType Storage,
563 bool ShouldCreate = true);
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +0000564
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000565 TempDIFile cloneImpl() const {
Amjad Aboud7faeecc2016-12-25 10:12:09 +0000566 return getTemporary(getContext(), getFilename(), getDirectory(),
Scott Linder16c7bda2018-02-23 23:01:06 +0000567 getChecksum(), getSource());
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +0000568 }
569
570public:
Amjad Aboud7faeecc2016-12-25 10:12:09 +0000571 DEFINE_MDNODE_GET(DIFile, (StringRef Filename, StringRef Directory,
Scott Linder16c7bda2018-02-23 23:01:06 +0000572 Optional<ChecksumInfo<StringRef>> CS = None,
573 Optional<StringRef> Source = None),
574 (Filename, Directory, CS, Source))
Reid Kleckner26fa1bf2017-09-19 18:14:45 +0000575 DEFINE_MDNODE_GET(DIFile, (MDString * Filename, MDString *Directory,
Scott Linder16c7bda2018-02-23 23:01:06 +0000576 Optional<ChecksumInfo<MDString *>> CS = None,
577 Optional<MDString *> Source = None),
578 (Filename, Directory, CS, Source))
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +0000579
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000580 TempDIFile clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +0000581
582 StringRef getFilename() const { return getStringOperand(0); }
583 StringRef getDirectory() const { return getStringOperand(1); }
Scott Linder71603842018-02-12 19:45:54 +0000584 Optional<ChecksumInfo<StringRef>> getChecksum() const {
585 Optional<ChecksumInfo<StringRef>> StringRefChecksum;
586 if (Checksum)
587 StringRefChecksum.emplace(Checksum->Kind, Checksum->Value->getString());
588 return StringRefChecksum;
589 }
Scott Linder16c7bda2018-02-23 23:01:06 +0000590 Optional<StringRef> getSource() const {
591 return Source ? Optional<StringRef>((*Source)->getString()) : None;
592 }
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +0000593
594 MDString *getRawFilename() const { return getOperandAs<MDString>(0); }
595 MDString *getRawDirectory() const { return getOperandAs<MDString>(1); }
Scott Linder71603842018-02-12 19:45:54 +0000596 Optional<ChecksumInfo<MDString *>> getRawChecksum() const { return Checksum; }
Scott Linder16c7bda2018-02-23 23:01:06 +0000597 Optional<MDString *> getRawSource() const { return Source; }
Amjad Aboud7faeecc2016-12-25 10:12:09 +0000598
Scott Linder71603842018-02-12 19:45:54 +0000599 static StringRef getChecksumKindAsString(ChecksumKind CSKind);
600 static Optional<ChecksumKind> getChecksumKind(StringRef CSKindStr);
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +0000601
602 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000603 return MD->getMetadataID() == DIFileKind;
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +0000604 }
605};
606
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000607StringRef DIScope::getFilename() const {
Duncan P. N. Exon Smith50c065b2015-04-11 00:39:43 +0000608 if (auto *F = getFile())
609 return F->getFilename();
610 return "";
611}
612
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000613StringRef DIScope::getDirectory() const {
Duncan P. N. Exon Smith50c065b2015-04-11 00:39:43 +0000614 if (auto *F = getFile())
615 return F->getDirectory();
616 return "";
617}
618
Scott Linder16c7bda2018-02-23 23:01:06 +0000619Optional<StringRef> DIScope::getSource() const {
620 if (auto *F = getFile())
621 return F->getSource();
622 return None;
623}
624
Adrian Prantl1687e012016-11-14 22:09:18 +0000625/// Base class for types.
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000626///
627/// TODO: Remove the hardcoded name and context, since many types don't use
628/// them.
629/// TODO: Split up flags.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000630class DIType : public DIScope {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000631 unsigned Line;
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000632 DIFlags Flags;
Duncan P. N. Exon Smithd34db172015-02-19 23:56:07 +0000633 uint64_t SizeInBits;
Duncan P. N. Exon Smithd34db172015-02-19 23:56:07 +0000634 uint64_t OffsetInBits;
Victor Leschuk197aa312016-10-18 14:31:22 +0000635 uint32_t AlignInBits;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000636
637protected:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000638 DIType(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
Victor Leschuk197aa312016-10-18 14:31:22 +0000639 unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits,
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000640 uint64_t OffsetInBits, DIFlags Flags, ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smith97386022016-04-19 18:00:19 +0000641 : DIScope(C, ID, Storage, Tag, Ops) {
642 init(Line, SizeInBits, AlignInBits, OffsetInBits, Flags);
643 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000644 ~DIType() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000645
Victor Leschuk197aa312016-10-18 14:31:22 +0000646 void init(unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits,
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000647 uint64_t OffsetInBits, DIFlags Flags) {
Duncan P. N. Exon Smith97386022016-04-19 18:00:19 +0000648 this->Line = Line;
649 this->Flags = Flags;
650 this->SizeInBits = SizeInBits;
651 this->AlignInBits = AlignInBits;
652 this->OffsetInBits = OffsetInBits;
653 }
654
655 /// Change fields in place.
656 void mutate(unsigned Tag, unsigned Line, uint64_t SizeInBits,
Victor Leschuk197aa312016-10-18 14:31:22 +0000657 uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags) {
Duncan P. N. Exon Smith97386022016-04-19 18:00:19 +0000658 assert(isDistinct() && "Only distinct nodes can mutate");
659 setTag(Tag);
660 init(Line, SizeInBits, AlignInBits, OffsetInBits, Flags);
661 }
662
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000663public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000664 TempDIType clone() const {
665 return TempDIType(cast<DIType>(MDNode::clone().release()));
Duncan P. N. Exon Smithb3538492015-03-03 16:45:34 +0000666 }
667
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000668 unsigned getLine() const { return Line; }
Duncan P. N. Exon Smithd34db172015-02-19 23:56:07 +0000669 uint64_t getSizeInBits() const { return SizeInBits; }
Victor Leschuk2ede1262016-10-20 00:13:12 +0000670 uint32_t getAlignInBits() const { return AlignInBits; }
671 uint32_t getAlignInBytes() const { return getAlignInBits() / CHAR_BIT; }
Duncan P. N. Exon Smithd34db172015-02-19 23:56:07 +0000672 uint64_t getOffsetInBits() const { return OffsetInBits; }
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000673 DIFlags getFlags() const { return Flags; }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000674
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000675 DIScopeRef getScope() const { return DIScopeRef(getRawScope()); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000676 StringRef getName() const { return getStringOperand(2); }
677
Duncan P. N. Exon Smith53855f02015-03-27 23:05:04 +0000678
679 Metadata *getRawScope() const { return getOperand(1); }
Duncan P. N. Exon Smith09e03f32015-02-13 01:14:58 +0000680 MDString *getRawName() const { return getOperandAs<MDString>(2); }
681
Roman Tereshincf88ffa2018-06-01 23:15:09 +0000682 /// Returns a new temporary DIType with updated Flags
683 TempDIType cloneWithFlags(DIFlags NewFlags) const {
684 auto NewTy = clone();
685 NewTy->Flags = NewFlags;
686 return NewTy;
Duncan P. N. Exon Smithb3538492015-03-03 16:45:34 +0000687 }
688
Duncan P. N. Exon Smithaecab7a2015-04-07 01:24:30 +0000689 bool isPrivate() const {
690 return (getFlags() & FlagAccessibility) == FlagPrivate;
691 }
692 bool isProtected() const {
693 return (getFlags() & FlagAccessibility) == FlagProtected;
694 }
695 bool isPublic() const {
696 return (getFlags() & FlagAccessibility) == FlagPublic;
697 }
698 bool isForwardDecl() const { return getFlags() & FlagFwdDecl; }
699 bool isAppleBlockExtension() const { return getFlags() & FlagAppleBlock; }
700 bool isBlockByrefStruct() const { return getFlags() & FlagBlockByrefStruct; }
701 bool isVirtual() const { return getFlags() & FlagVirtual; }
702 bool isArtificial() const { return getFlags() & FlagArtificial; }
703 bool isObjectPointer() const { return getFlags() & FlagObjectPointer; }
704 bool isObjcClassComplete() const {
705 return getFlags() & FlagObjcClassComplete;
706 }
707 bool isVector() const { return getFlags() & FlagVector; }
David Majnemer9319cbc2016-06-30 03:00:20 +0000708 bool isBitField() const { return getFlags() & FlagBitField; }
Duncan P. N. Exon Smithaecab7a2015-04-07 01:24:30 +0000709 bool isStaticMember() const { return getFlags() & FlagStaticMember; }
710 bool isLValueReference() const { return getFlags() & FlagLValueReference; }
711 bool isRValueReference() const { return getFlags() & FlagRValueReference; }
Adrian Prantla29aac72018-01-05 01:13:37 +0000712 bool isTypePassByValue() const { return getFlags() & FlagTypePassByValue; }
713 bool isTypePassByReference() const {
714 return getFlags() & FlagTypePassByReference;
715 }
Adrian Prantl55f42622018-08-14 19:35:34 +0000716 bool isBigEndian() const { return getFlags() & FlagBigEndian; }
717 bool isLittleEndian() const { return getFlags() & FlagLittleEndian; }
Duncan P. N. Exon Smithaecab7a2015-04-07 01:24:30 +0000718
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000719 static bool classof(const Metadata *MD) {
720 switch (MD->getMetadataID()) {
721 default:
722 return false;
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000723 case DIBasicTypeKind:
724 case DIDerivedTypeKind:
725 case DICompositeTypeKind:
726 case DISubroutineTypeKind:
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000727 return true;
728 }
729 }
730};
731
Adrian Prantl1687e012016-11-14 22:09:18 +0000732/// Basic type, like 'int' or 'float'.
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000733///
734/// TODO: Split out DW_TAG_unspecified_type.
735/// TODO: Drop unused accessors.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000736class DIBasicType : public DIType {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000737 friend class LLVMContextImpl;
738 friend class MDNode;
739
740 unsigned Encoding;
741
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000742 DIBasicType(LLVMContext &C, StorageType Storage, unsigned Tag,
Victor Leschuk197aa312016-10-18 14:31:22 +0000743 uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding,
Adrian Prantl55f42622018-08-14 19:35:34 +0000744 DIFlags Flags, ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000745 : DIType(C, DIBasicTypeKind, Storage, Tag, 0, SizeInBits, AlignInBits, 0,
Adrian Prantl55f42622018-08-14 19:35:34 +0000746 Flags, Ops),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000747 Encoding(Encoding) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000748 ~DIBasicType() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000749
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000750 static DIBasicType *getImpl(LLVMContext &Context, unsigned Tag,
Duncan P. N. Exon Smithd34db172015-02-19 23:56:07 +0000751 StringRef Name, uint64_t SizeInBits,
Victor Leschuk197aa312016-10-18 14:31:22 +0000752 uint32_t AlignInBits, unsigned Encoding,
Adrian Prantl55f42622018-08-14 19:35:34 +0000753 DIFlags Flags, StorageType Storage,
754 bool ShouldCreate = true) {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000755 return getImpl(Context, Tag, getCanonicalMDString(Context, Name),
Adrian Prantl55f42622018-08-14 19:35:34 +0000756 SizeInBits, AlignInBits, Encoding, Flags, Storage,
757 ShouldCreate);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000758 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000759 static DIBasicType *getImpl(LLVMContext &Context, unsigned Tag,
Duncan P. N. Exon Smithd34db172015-02-19 23:56:07 +0000760 MDString *Name, uint64_t SizeInBits,
Victor Leschuk197aa312016-10-18 14:31:22 +0000761 uint32_t AlignInBits, unsigned Encoding,
Adrian Prantl55f42622018-08-14 19:35:34 +0000762 DIFlags Flags, StorageType Storage,
763 bool ShouldCreate = true);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000764
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000765 TempDIBasicType cloneImpl() const {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000766 return getTemporary(getContext(), getTag(), getName(), getSizeInBits(),
Adrian Prantl55f42622018-08-14 19:35:34 +0000767 getAlignInBits(), getEncoding(), getFlags());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000768 }
769
770public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000771 DEFINE_MDNODE_GET(DIBasicType, (unsigned Tag, StringRef Name),
Adrian Prantl55f42622018-08-14 19:35:34 +0000772 (Tag, Name, 0, 0, 0, FlagZero))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000773 DEFINE_MDNODE_GET(DIBasicType,
Duncan P. N. Exon Smithd34db172015-02-19 23:56:07 +0000774 (unsigned Tag, StringRef Name, uint64_t SizeInBits,
Adrian Prantl55f42622018-08-14 19:35:34 +0000775 uint32_t AlignInBits, unsigned Encoding, DIFlags Flags),
776 (Tag, Name, SizeInBits, AlignInBits, Encoding, Flags))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000777 DEFINE_MDNODE_GET(DIBasicType,
Duncan P. N. Exon Smithd34db172015-02-19 23:56:07 +0000778 (unsigned Tag, MDString *Name, uint64_t SizeInBits,
Adrian Prantl55f42622018-08-14 19:35:34 +0000779 uint32_t AlignInBits, unsigned Encoding, DIFlags Flags),
780 (Tag, Name, SizeInBits, AlignInBits, Encoding, Flags))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000781
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000782 TempDIBasicType clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000783
784 unsigned getEncoding() const { return Encoding; }
785
Vedant Kumar6379a622018-07-06 17:32:39 +0000786 enum class Signedness { Signed, Unsigned };
787
788 /// Return the signedness of this type, or None if this type is neither
789 /// signed nor unsigned.
790 Optional<Signedness> getSignedness() const;
791
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000792 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000793 return MD->getMetadataID() == DIBasicTypeKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000794 }
795};
796
Adrian Prantl1687e012016-11-14 22:09:18 +0000797/// Derived types.
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000798///
799/// This includes qualified types, pointers, references, friends, typedefs, and
800/// class members.
801///
802/// TODO: Split out members (inheritance, fields, methods, etc.).
Duncan P. N. Exon Smith338aef02015-07-24 20:16:36 +0000803class DIDerivedType : public DIType {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000804 friend class LLVMContextImpl;
805 friend class MDNode;
806
Adrian Prantl5f8f34e42018-05-01 15:54:18 +0000807 /// The DWARF address space of the memory pointed to or referenced by a
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000808 /// pointer or reference type respectively.
809 Optional<unsigned> DWARFAddressSpace;
810
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000811 DIDerivedType(LLVMContext &C, StorageType Storage, unsigned Tag,
Victor Leschuk197aa312016-10-18 14:31:22 +0000812 unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits,
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000813 uint64_t OffsetInBits, Optional<unsigned> DWARFAddressSpace,
814 DIFlags Flags, ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smith338aef02015-07-24 20:16:36 +0000815 : DIType(C, DIDerivedTypeKind, Storage, Tag, Line, SizeInBits,
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000816 AlignInBits, OffsetInBits, Flags, Ops),
817 DWARFAddressSpace(DWARFAddressSpace) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000818 ~DIDerivedType() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000819
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000820 static DIDerivedType *getImpl(LLVMContext &Context, unsigned Tag,
821 StringRef Name, DIFile *File, unsigned Line,
822 DIScopeRef Scope, DITypeRef BaseType,
Victor Leschuk197aa312016-10-18 14:31:22 +0000823 uint64_t SizeInBits, uint32_t AlignInBits,
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000824 uint64_t OffsetInBits,
825 Optional<unsigned> DWARFAddressSpace,
826 DIFlags Flags, Metadata *ExtraData,
827 StorageType Storage, bool ShouldCreate = true) {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000828 return getImpl(Context, Tag, getCanonicalMDString(Context, Name), File,
829 Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits,
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000830 DWARFAddressSpace, Flags, ExtraData, Storage, ShouldCreate);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000831 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000832 static DIDerivedType *getImpl(LLVMContext &Context, unsigned Tag,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000833 MDString *Name, Metadata *File, unsigned Line,
834 Metadata *Scope, Metadata *BaseType,
Victor Leschuk197aa312016-10-18 14:31:22 +0000835 uint64_t SizeInBits, uint32_t AlignInBits,
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000836 uint64_t OffsetInBits,
837 Optional<unsigned> DWARFAddressSpace,
838 DIFlags Flags, Metadata *ExtraData,
839 StorageType Storage, bool ShouldCreate = true);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000840
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000841 TempDIDerivedType cloneImpl() const {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000842 return getTemporary(getContext(), getTag(), getName(), getFile(), getLine(),
843 getScope(), getBaseType(), getSizeInBits(),
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000844 getAlignInBits(), getOffsetInBits(),
845 getDWARFAddressSpace(), getFlags(), getExtraData());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000846 }
847
848public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000849 DEFINE_MDNODE_GET(DIDerivedType,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000850 (unsigned Tag, MDString *Name, Metadata *File,
851 unsigned Line, Metadata *Scope, Metadata *BaseType,
Victor Leschuk197aa312016-10-18 14:31:22 +0000852 uint64_t SizeInBits, uint32_t AlignInBits,
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000853 uint64_t OffsetInBits,
854 Optional<unsigned> DWARFAddressSpace, DIFlags Flags,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000855 Metadata *ExtraData = nullptr),
856 (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000857 AlignInBits, OffsetInBits, DWARFAddressSpace, Flags,
858 ExtraData))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000859 DEFINE_MDNODE_GET(DIDerivedType,
860 (unsigned Tag, StringRef Name, DIFile *File, unsigned Line,
861 DIScopeRef Scope, DITypeRef BaseType, uint64_t SizeInBits,
Victor Leschuk197aa312016-10-18 14:31:22 +0000862 uint32_t AlignInBits, uint64_t OffsetInBits,
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000863 Optional<unsigned> DWARFAddressSpace, DIFlags Flags,
864 Metadata *ExtraData = nullptr),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000865 (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000866 AlignInBits, OffsetInBits, DWARFAddressSpace, Flags,
867 ExtraData))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000868
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000869 TempDIDerivedType clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000870
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000871 /// Get the base type this is derived from.
Duncan P. N. Exon Smith338aef02015-07-24 20:16:36 +0000872 DITypeRef getBaseType() const { return DITypeRef(getRawBaseType()); }
873 Metadata *getRawBaseType() const { return getOperand(3); }
874
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000875 /// \returns The DWARF address space of the memory pointed to or referenced by
876 /// a pointer or reference type respectively.
877 Optional<unsigned> getDWARFAddressSpace() const { return DWARFAddressSpace; }
878
Adrian Prantl1687e012016-11-14 22:09:18 +0000879 /// Get extra data associated with this derived type.
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000880 ///
881 /// Class type for pointer-to-members, objective-c property node for ivars,
Brock Wyma3db2b102018-05-14 21:21:22 +0000882 /// global constant wrapper for static members, or virtual base pointer offset
883 /// for inheritance.
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000884 ///
885 /// TODO: Separate out types that need this extra operand: pointer-to-member
886 /// types and member fields (static members and ivars).
Duncan P. N. Exon Smith53855f02015-03-27 23:05:04 +0000887 Metadata *getExtraData() const { return getRawExtraData(); }
888 Metadata *getRawExtraData() const { return getOperand(4); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000889
Adrian Prantl1687e012016-11-14 22:09:18 +0000890 /// Get casted version of extra data.
Duncan P. N. Exon Smith0bf8d4c2015-04-13 23:36:36 +0000891 /// @{
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000892 DITypeRef getClassType() const {
Duncan P. N. Exon Smith0bf8d4c2015-04-13 23:36:36 +0000893 assert(getTag() == dwarf::DW_TAG_ptr_to_member_type);
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000894 return DITypeRef(getExtraData());
Duncan P. N. Exon Smith0bf8d4c2015-04-13 23:36:36 +0000895 }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +0000896
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000897 DIObjCProperty *getObjCProperty() const {
898 return dyn_cast_or_null<DIObjCProperty>(getExtraData());
Duncan P. N. Exon Smith0bf8d4c2015-04-13 23:36:36 +0000899 }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +0000900
Brock Wyma3db2b102018-05-14 21:21:22 +0000901 uint32_t getVBPtrOffset() const {
902 assert(getTag() == dwarf::DW_TAG_inheritance);
903 if (auto *CM = cast_or_null<ConstantAsMetadata>(getExtraData()))
904 if (auto *CI = dyn_cast_or_null<ConstantInt>(CM->getValue()))
905 return static_cast<uint32_t>(CI->getZExtValue());
906 return 0;
907 }
908
David Majnemer9319cbc2016-06-30 03:00:20 +0000909 Constant *getStorageOffsetInBits() const {
910 assert(getTag() == dwarf::DW_TAG_member && isBitField());
911 if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData()))
912 return C->getValue();
913 return nullptr;
914 }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +0000915
Duncan P. N. Exon Smith0bf8d4c2015-04-13 23:36:36 +0000916 Constant *getConstant() const {
917 assert(getTag() == dwarf::DW_TAG_member && isStaticMember());
918 if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData()))
919 return C->getValue();
920 return nullptr;
921 }
Adrian Prantl8c599212018-02-06 23:45:59 +0000922 Constant *getDiscriminantValue() const {
923 assert(getTag() == dwarf::DW_TAG_member && !isStaticMember());
924 if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData()))
925 return C->getValue();
926 return nullptr;
927 }
Duncan P. N. Exon Smith0bf8d4c2015-04-13 23:36:36 +0000928 /// @}
929
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000930 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000931 return MD->getMetadataID() == DIDerivedTypeKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000932 }
933};
934
Adrian Prantl1687e012016-11-14 22:09:18 +0000935/// Composite types.
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000936///
937/// TODO: Detach from DerivedTypeBase (split out MDEnumType?).
938/// TODO: Create a custom, unrelated node for DW_TAG_array_type.
Duncan P. N. Exon Smithb9e045a2015-07-24 20:56:36 +0000939class DICompositeType : public DIType {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000940 friend class LLVMContextImpl;
941 friend class MDNode;
942
Duncan P. N. Exon Smithb9e045a2015-07-24 20:56:36 +0000943 unsigned RuntimeLang;
944
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000945 DICompositeType(LLVMContext &C, StorageType Storage, unsigned Tag,
Duncan P. N. Exon Smithd34db172015-02-19 23:56:07 +0000946 unsigned Line, unsigned RuntimeLang, uint64_t SizeInBits,
Victor Leschuk197aa312016-10-18 14:31:22 +0000947 uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000948 ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smithb9e045a2015-07-24 20:56:36 +0000949 : DIType(C, DICompositeTypeKind, Storage, Tag, Line, SizeInBits,
950 AlignInBits, OffsetInBits, Flags, Ops),
951 RuntimeLang(RuntimeLang) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000952 ~DICompositeType() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000953
Duncan P. N. Exon Smith97386022016-04-19 18:00:19 +0000954 /// Change fields in place.
955 void mutate(unsigned Tag, unsigned Line, unsigned RuntimeLang,
Victor Leschuk197aa312016-10-18 14:31:22 +0000956 uint64_t SizeInBits, uint32_t AlignInBits,
957 uint64_t OffsetInBits, DIFlags Flags) {
Duncan P. N. Exon Smith97386022016-04-19 18:00:19 +0000958 assert(isDistinct() && "Only distinct nodes can mutate");
959 assert(getRawIdentifier() && "Only ODR-uniqued nodes should mutate");
960 this->RuntimeLang = RuntimeLang;
961 DIType::mutate(Tag, Line, SizeInBits, AlignInBits, OffsetInBits, Flags);
962 }
963
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000964 static DICompositeType *
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000965 getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, Metadata *File,
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000966 unsigned Line, DIScopeRef Scope, DITypeRef BaseType,
Victor Leschuk197aa312016-10-18 14:31:22 +0000967 uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000968 DIFlags Flags, DINodeArray Elements, unsigned RuntimeLang,
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000969 DITypeRef VTableHolder, DITemplateParameterArray TemplateParams,
Adrian Prantl8c599212018-02-06 23:45:59 +0000970 StringRef Identifier, DIDerivedType *Discriminator,
971 StorageType Storage, bool ShouldCreate = true) {
Duncan P. N. Exon Smith11344732015-04-07 16:50:39 +0000972 return getImpl(
973 Context, Tag, getCanonicalMDString(Context, Name), File, Line, Scope,
974 BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements.get(),
975 RuntimeLang, VTableHolder, TemplateParams.get(),
Adrian Prantl8c599212018-02-06 23:45:59 +0000976 getCanonicalMDString(Context, Identifier), Discriminator, Storage, ShouldCreate);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000977 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000978 static DICompositeType *
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000979 getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
980 unsigned Line, Metadata *Scope, Metadata *BaseType,
Victor Leschuk197aa312016-10-18 14:31:22 +0000981 uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000982 DIFlags Flags, Metadata *Elements, unsigned RuntimeLang,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000983 Metadata *VTableHolder, Metadata *TemplateParams,
Adrian Prantl8c599212018-02-06 23:45:59 +0000984 MDString *Identifier, Metadata *Discriminator,
985 StorageType Storage, bool ShouldCreate = true);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000986
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000987 TempDICompositeType cloneImpl() const {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000988 return getTemporary(getContext(), getTag(), getName(), getFile(), getLine(),
989 getScope(), getBaseType(), getSizeInBits(),
990 getAlignInBits(), getOffsetInBits(), getFlags(),
991 getElements(), getRuntimeLang(), getVTableHolder(),
Adrian Prantl8c599212018-02-06 23:45:59 +0000992 getTemplateParams(), getIdentifier(), getDiscriminator());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000993 }
994
995public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000996 DEFINE_MDNODE_GET(DICompositeType,
997 (unsigned Tag, StringRef Name, DIFile *File, unsigned Line,
998 DIScopeRef Scope, DITypeRef BaseType, uint64_t SizeInBits,
Victor Leschuk197aa312016-10-18 14:31:22 +0000999 uint32_t AlignInBits, uint64_t OffsetInBits,
1000 DIFlags Flags, DINodeArray Elements, unsigned RuntimeLang,
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001001 DITypeRef VTableHolder,
1002 DITemplateParameterArray TemplateParams = nullptr,
Adrian Prantl8c599212018-02-06 23:45:59 +00001003 StringRef Identifier = "", DIDerivedType *Discriminator = nullptr),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001004 (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
1005 AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
Adrian Prantl8c599212018-02-06 23:45:59 +00001006 VTableHolder, TemplateParams, Identifier, Discriminator))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001007 DEFINE_MDNODE_GET(DICompositeType,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001008 (unsigned Tag, MDString *Name, Metadata *File,
1009 unsigned Line, Metadata *Scope, Metadata *BaseType,
Victor Leschuk197aa312016-10-18 14:31:22 +00001010 uint64_t SizeInBits, uint32_t AlignInBits,
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001011 uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001012 unsigned RuntimeLang, Metadata *VTableHolder,
1013 Metadata *TemplateParams = nullptr,
Adrian Prantl8c599212018-02-06 23:45:59 +00001014 MDString *Identifier = nullptr,
1015 Metadata *Discriminator = nullptr),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001016 (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
1017 AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
Adrian Prantl8c599212018-02-06 23:45:59 +00001018 VTableHolder, TemplateParams, Identifier, Discriminator))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001019
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001020 TempDICompositeType clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001021
Duncan P. N. Exon Smith0b0271e2016-04-19 14:55:09 +00001022 /// Get a DICompositeType with the given ODR identifier.
1023 ///
1024 /// If \a LLVMContext::isODRUniquingDebugTypes(), gets the mapped
1025 /// DICompositeType for the given ODR \c Identifier. If none exists, creates
1026 /// a new node.
1027 ///
1028 /// Else, returns \c nullptr.
1029 static DICompositeType *
1030 getODRType(LLVMContext &Context, MDString &Identifier, unsigned Tag,
1031 MDString *Name, Metadata *File, unsigned Line, Metadata *Scope,
Victor Leschuk197aa312016-10-18 14:31:22 +00001032 Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits,
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001033 uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements,
Duncan P. N. Exon Smith0b0271e2016-04-19 14:55:09 +00001034 unsigned RuntimeLang, Metadata *VTableHolder,
Adrian Prantl8c599212018-02-06 23:45:59 +00001035 Metadata *TemplateParams, Metadata *Discriminator);
Duncan P. N. Exon Smith0b0271e2016-04-19 14:55:09 +00001036 static DICompositeType *getODRTypeIfExists(LLVMContext &Context,
1037 MDString &Identifier);
1038
Duncan P. N. Exon Smith97386022016-04-19 18:00:19 +00001039 /// Build a DICompositeType with the given ODR identifier.
1040 ///
1041 /// Looks up the mapped DICompositeType for the given ODR \c Identifier. If
1042 /// it doesn't exist, creates a new one. If it does exist and \a
1043 /// isForwardDecl(), and the new arguments would be a definition, mutates the
1044 /// the type in place. In either case, returns the type.
1045 ///
1046 /// If not \a LLVMContext::isODRUniquingDebugTypes(), this function returns
1047 /// nullptr.
1048 static DICompositeType *
1049 buildODRType(LLVMContext &Context, MDString &Identifier, unsigned Tag,
1050 MDString *Name, Metadata *File, unsigned Line, Metadata *Scope,
Victor Leschuk197aa312016-10-18 14:31:22 +00001051 Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits,
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001052 uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements,
Duncan P. N. Exon Smith97386022016-04-19 18:00:19 +00001053 unsigned RuntimeLang, Metadata *VTableHolder,
Adrian Prantl8c599212018-02-06 23:45:59 +00001054 Metadata *TemplateParams, Metadata *Discriminator);
Duncan P. N. Exon Smith97386022016-04-19 18:00:19 +00001055
Duncan P. N. Exon Smithb9e045a2015-07-24 20:56:36 +00001056 DITypeRef getBaseType() const { return DITypeRef(getRawBaseType()); }
1057 DINodeArray getElements() const {
1058 return cast_or_null<MDTuple>(getRawElements());
1059 }
1060 DITypeRef getVTableHolder() const { return DITypeRef(getRawVTableHolder()); }
1061 DITemplateParameterArray getTemplateParams() const {
1062 return cast_or_null<MDTuple>(getRawTemplateParams());
1063 }
1064 StringRef getIdentifier() const { return getStringOperand(7); }
1065 unsigned getRuntimeLang() const { return RuntimeLang; }
1066
1067 Metadata *getRawBaseType() const { return getOperand(3); }
1068 Metadata *getRawElements() const { return getOperand(4); }
1069 Metadata *getRawVTableHolder() const { return getOperand(5); }
1070 Metadata *getRawTemplateParams() const { return getOperand(6); }
1071 MDString *getRawIdentifier() const { return getOperandAs<MDString>(7); }
Adrian Prantl8c599212018-02-06 23:45:59 +00001072 Metadata *getRawDiscriminator() const { return getOperand(8); }
1073 DIDerivedType *getDiscriminator() const { return getOperandAs<DIDerivedType>(8); }
Duncan P. N. Exon Smithb9e045a2015-07-24 20:56:36 +00001074
Adrian Prantl1687e012016-11-14 22:09:18 +00001075 /// Replace operands.
Duncan P. N. Exon Smithb9e045a2015-07-24 20:56:36 +00001076 ///
1077 /// If this \a isUniqued() and not \a isResolved(), on a uniquing collision
1078 /// this will be RAUW'ed and deleted. Use a \a TrackingMDRef to keep track
1079 /// of its movement if necessary.
1080 /// @{
1081 void replaceElements(DINodeArray Elements) {
1082#ifndef NDEBUG
1083 for (DINode *Op : getElements())
David Majnemer42531262016-08-12 03:55:06 +00001084 assert(is_contained(Elements->operands(), Op) &&
Duncan P. N. Exon Smithb9e045a2015-07-24 20:56:36 +00001085 "Lost a member during member list replacement");
1086#endif
1087 replaceOperandWith(4, Elements.get());
1088 }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +00001089
Duncan P. N. Exon Smithb9e045a2015-07-24 20:56:36 +00001090 void replaceVTableHolder(DITypeRef VTableHolder) {
1091 replaceOperandWith(5, VTableHolder);
1092 }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +00001093
Duncan P. N. Exon Smithb9e045a2015-07-24 20:56:36 +00001094 void replaceTemplateParams(DITemplateParameterArray TemplateParams) {
1095 replaceOperandWith(6, TemplateParams.get());
1096 }
1097 /// @}
1098
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001099 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001100 return MD->getMetadataID() == DICompositeTypeKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001101 }
1102};
1103
Adrian Prantl1687e012016-11-14 22:09:18 +00001104/// Type array for a subprogram.
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001105///
Duncan P. N. Exon Smithb9e045a2015-07-24 20:56:36 +00001106/// TODO: Fold the array of types in directly as operands.
1107class DISubroutineType : public DIType {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001108 friend class LLVMContextImpl;
1109 friend class MDNode;
1110
Reid Klecknerde3d8b52016-06-08 20:34:29 +00001111 /// The calling convention used with DW_AT_calling_convention. Actually of
1112 /// type dwarf::CallingConvention.
1113 uint8_t CC;
1114
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001115 DISubroutineType(LLVMContext &C, StorageType Storage, DIFlags Flags,
Reid Klecknerde3d8b52016-06-08 20:34:29 +00001116 uint8_t CC, ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smithb9e045a2015-07-24 20:56:36 +00001117 : DIType(C, DISubroutineTypeKind, Storage, dwarf::DW_TAG_subroutine_type,
Reid Klecknerde3d8b52016-06-08 20:34:29 +00001118 0, 0, 0, 0, Flags, Ops),
1119 CC(CC) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001120 ~DISubroutineType() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001121
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001122 static DISubroutineType *getImpl(LLVMContext &Context, DIFlags Flags,
Reid Klecknerde3d8b52016-06-08 20:34:29 +00001123 uint8_t CC, DITypeRefArray TypeArray,
Duncan P. N. Exon Smith11344732015-04-07 16:50:39 +00001124 StorageType Storage,
1125 bool ShouldCreate = true) {
Reid Klecknerde3d8b52016-06-08 20:34:29 +00001126 return getImpl(Context, Flags, CC, TypeArray.get(), Storage, ShouldCreate);
Duncan P. N. Exon Smith11344732015-04-07 16:50:39 +00001127 }
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001128 static DISubroutineType *getImpl(LLVMContext &Context, DIFlags Flags,
Reid Klecknerde3d8b52016-06-08 20:34:29 +00001129 uint8_t CC, Metadata *TypeArray,
1130 StorageType Storage,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001131 bool ShouldCreate = true);
1132
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001133 TempDISubroutineType cloneImpl() const {
Reid Klecknerde3d8b52016-06-08 20:34:29 +00001134 return getTemporary(getContext(), getFlags(), getCC(), getTypeArray());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001135 }
1136
1137public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001138 DEFINE_MDNODE_GET(DISubroutineType,
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001139 (DIFlags Flags, uint8_t CC, DITypeRefArray TypeArray),
Reid Klecknerde3d8b52016-06-08 20:34:29 +00001140 (Flags, CC, TypeArray))
1141 DEFINE_MDNODE_GET(DISubroutineType,
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001142 (DIFlags Flags, uint8_t CC, Metadata *TypeArray),
Reid Klecknerde3d8b52016-06-08 20:34:29 +00001143 (Flags, CC, TypeArray))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001144
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001145 TempDISubroutineType clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001146
Reid Klecknerde3d8b52016-06-08 20:34:29 +00001147 uint8_t getCC() const { return CC; }
1148
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001149 DITypeRefArray getTypeArray() const {
Duncan P. N. Exon Smith11344732015-04-07 16:50:39 +00001150 return cast_or_null<MDTuple>(getRawTypeArray());
1151 }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +00001152
Duncan P. N. Exon Smithb9e045a2015-07-24 20:56:36 +00001153 Metadata *getRawTypeArray() const { return getOperand(3); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001154
1155 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001156 return MD->getMetadataID() == DISubroutineTypeKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001157 }
1158};
1159
Adrian Prantl1687e012016-11-14 22:09:18 +00001160/// Compile unit.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001161class DICompileUnit : public DIScope {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001162 friend class LLVMContextImpl;
1163 friend class MDNode;
Eugene Zelenko1aa40f42016-11-23 22:25:16 +00001164
Adrian Prantlb939a252016-03-31 23:56:58 +00001165public:
1166 enum DebugEmissionKind : unsigned {
1167 NoDebug = 0,
1168 FullDebug,
1169 LineTablesOnly,
Alexey Bataevd4dd7212018-08-01 19:38:20 +00001170 DebugDirectivesOnly,
1171 LastEmissionKind = DebugDirectivesOnly
Adrian Prantlb939a252016-03-31 23:56:58 +00001172 };
Eugene Zelenko1aa40f42016-11-23 22:25:16 +00001173
David Blaikie66cf14d2018-08-16 21:29:55 +00001174 enum class DebugNameTableKind : unsigned {
1175 Default = 0,
1176 GNU = 1,
1177 None = 2,
1178 LastDebugNameTableKind = None
1179 };
1180
Adrian Prantlb939a252016-03-31 23:56:58 +00001181 static Optional<DebugEmissionKind> getEmissionKind(StringRef Str);
Fangrui Song3c1b5db2018-07-06 19:26:00 +00001182 static const char *emissionKindString(DebugEmissionKind EK);
David Blaikie66cf14d2018-08-16 21:29:55 +00001183 static Optional<DebugNameTableKind> getNameTableKind(StringRef Str);
1184 static const char *nameTableKindString(DebugNameTableKind PK);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001185
Adrian Prantlb939a252016-03-31 23:56:58 +00001186private:
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001187 unsigned SourceLanguage;
1188 bool IsOptimized;
1189 unsigned RuntimeVersion;
1190 unsigned EmissionKind;
Adrian Prantl1f599f92015-05-21 20:37:30 +00001191 uint64_t DWOId;
David Blaikiea01f2952016-08-24 18:29:49 +00001192 bool SplitDebugInlining;
Dehao Chen0944a8c2017-02-01 22:45:09 +00001193 bool DebugInfoForProfiling;
David Blaikie66cf14d2018-08-16 21:29:55 +00001194 unsigned NameTableKind;
David Blaikiebb279112018-11-13 20:08:10 +00001195 bool RangesBaseAddress;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001196
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001197 DICompileUnit(LLVMContext &C, StorageType Storage, unsigned SourceLanguage,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001198 bool IsOptimized, unsigned RuntimeVersion,
David Blaikiea01f2952016-08-24 18:29:49 +00001199 unsigned EmissionKind, uint64_t DWOId, bool SplitDebugInlining,
David Blaikie66cf14d2018-08-16 21:29:55 +00001200 bool DebugInfoForProfiling, unsigned NameTableKind,
David Blaikiebb279112018-11-13 20:08:10 +00001201 bool RangesBaseAddress, ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001202 : DIScope(C, DICompileUnitKind, Storage, dwarf::DW_TAG_compile_unit, Ops),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001203 SourceLanguage(SourceLanguage), IsOptimized(IsOptimized),
Adrian Prantl1f599f92015-05-21 20:37:30 +00001204 RuntimeVersion(RuntimeVersion), EmissionKind(EmissionKind),
Dehao Chen0944a8c2017-02-01 22:45:09 +00001205 DWOId(DWOId), SplitDebugInlining(SplitDebugInlining),
David Blaikie66cf14d2018-08-16 21:29:55 +00001206 DebugInfoForProfiling(DebugInfoForProfiling),
David Blaikiebb279112018-11-13 20:08:10 +00001207 NameTableKind(NameTableKind), RangesBaseAddress(RangesBaseAddress) {
Duncan P. N. Exon Smith55ca9642015-08-03 17:26:41 +00001208 assert(Storage != Uniqued);
1209 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001210 ~DICompileUnit() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001211
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001212 static DICompileUnit *
1213 getImpl(LLVMContext &Context, unsigned SourceLanguage, DIFile *File,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001214 StringRef Producer, bool IsOptimized, StringRef Flags,
1215 unsigned RuntimeVersion, StringRef SplitDebugFilename,
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001216 unsigned EmissionKind, DICompositeTypeArray EnumTypes,
Adrian Prantlbceaaa92016-12-20 02:09:43 +00001217 DIScopeArray RetainedTypes,
1218 DIGlobalVariableExpressionArray GlobalVariables,
Amjad Abouda9bcf162015-12-10 12:56:35 +00001219 DIImportedEntityArray ImportedEntities, DIMacroNodeArray Macros,
Dehao Chen0944a8c2017-02-01 22:45:09 +00001220 uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling,
David Blaikiebb279112018-11-13 20:08:10 +00001221 unsigned NameTableKind, bool RangesBaseAddress, StorageType Storage,
David Blaikie66cf14d2018-08-16 21:29:55 +00001222 bool ShouldCreate = true) {
David Blaikiebb279112018-11-13 20:08:10 +00001223 return getImpl(Context, SourceLanguage, File,
1224 getCanonicalMDString(Context, Producer), IsOptimized,
1225 getCanonicalMDString(Context, Flags), RuntimeVersion,
1226 getCanonicalMDString(Context, SplitDebugFilename),
1227 EmissionKind, EnumTypes.get(), RetainedTypes.get(),
1228 GlobalVariables.get(), ImportedEntities.get(), Macros.get(),
1229 DWOId, SplitDebugInlining, DebugInfoForProfiling,
1230 NameTableKind, RangesBaseAddress, Storage, ShouldCreate);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001231 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001232 static DICompileUnit *
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001233 getImpl(LLVMContext &Context, unsigned SourceLanguage, Metadata *File,
1234 MDString *Producer, bool IsOptimized, MDString *Flags,
1235 unsigned RuntimeVersion, MDString *SplitDebugFilename,
Adrian Prantl75819ae2016-04-15 15:57:41 +00001236 unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes,
Adrian Prantlb939a252016-03-31 23:56:58 +00001237 Metadata *GlobalVariables, Metadata *ImportedEntities,
David Blaikiea01f2952016-08-24 18:29:49 +00001238 Metadata *Macros, uint64_t DWOId, bool SplitDebugInlining,
David Blaikie66cf14d2018-08-16 21:29:55 +00001239 bool DebugInfoForProfiling, unsigned NameTableKind,
David Blaikiebb279112018-11-13 20:08:10 +00001240 bool RangesBaseAddress, StorageType Storage, bool ShouldCreate = true);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001241
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001242 TempDICompileUnit cloneImpl() const {
David Blaikiebb279112018-11-13 20:08:10 +00001243 return getTemporary(
1244 getContext(), getSourceLanguage(), getFile(), getProducer(),
1245 isOptimized(), getFlags(), getRuntimeVersion(), getSplitDebugFilename(),
1246 getEmissionKind(), getEnumTypes(), getRetainedTypes(),
1247 getGlobalVariables(), getImportedEntities(), getMacros(), DWOId,
1248 getSplitDebugInlining(), getDebugInfoForProfiling(), getNameTableKind(),
1249 getRangesBaseAddress());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001250 }
1251
Eugene Zelenko1aa40f42016-11-23 22:25:16 +00001252public:
Duncan P. N. Exon Smith55ca9642015-08-03 17:26:41 +00001253 static void get() = delete;
1254 static void getIfExists() = delete;
1255
Duncan P. N. Exon Smith55ca9642015-08-03 17:26:41 +00001256 DEFINE_MDNODE_GET_DISTINCT_TEMPORARY(
1257 DICompileUnit,
1258 (unsigned SourceLanguage, DIFile *File, StringRef Producer,
1259 bool IsOptimized, StringRef Flags, unsigned RuntimeVersion,
Adrian Prantlb939a252016-03-31 23:56:58 +00001260 StringRef SplitDebugFilename, DebugEmissionKind EmissionKind,
Adrian Prantl75819ae2016-04-15 15:57:41 +00001261 DICompositeTypeArray EnumTypes, DIScopeArray RetainedTypes,
Adrian Prantlbceaaa92016-12-20 02:09:43 +00001262 DIGlobalVariableExpressionArray GlobalVariables,
Amjad Abouda9bcf162015-12-10 12:56:35 +00001263 DIImportedEntityArray ImportedEntities, DIMacroNodeArray Macros,
Peter Collingbourneb52e2362017-09-12 21:50:41 +00001264 uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling,
David Blaikiebb279112018-11-13 20:08:10 +00001265 DebugNameTableKind NameTableKind, bool RangesBaseAddress),
Duncan P. N. Exon Smith55ca9642015-08-03 17:26:41 +00001266 (SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion,
Adrian Prantl75819ae2016-04-15 15:57:41 +00001267 SplitDebugFilename, EmissionKind, EnumTypes, RetainedTypes,
Dehao Chen0944a8c2017-02-01 22:45:09 +00001268 GlobalVariables, ImportedEntities, Macros, DWOId, SplitDebugInlining,
David Blaikiebb279112018-11-13 20:08:10 +00001269 DebugInfoForProfiling, (unsigned)NameTableKind, RangesBaseAddress))
Duncan P. N. Exon Smith55ca9642015-08-03 17:26:41 +00001270 DEFINE_MDNODE_GET_DISTINCT_TEMPORARY(
Adrian Prantl1f599f92015-05-21 20:37:30 +00001271 DICompileUnit,
1272 (unsigned SourceLanguage, Metadata *File, MDString *Producer,
1273 bool IsOptimized, MDString *Flags, unsigned RuntimeVersion,
1274 MDString *SplitDebugFilename, unsigned EmissionKind, Metadata *EnumTypes,
Adrian Prantl75819ae2016-04-15 15:57:41 +00001275 Metadata *RetainedTypes, Metadata *GlobalVariables,
David Blaikiea01f2952016-08-24 18:29:49 +00001276 Metadata *ImportedEntities, Metadata *Macros, uint64_t DWOId,
David Blaikie66cf14d2018-08-16 21:29:55 +00001277 bool SplitDebugInlining, bool DebugInfoForProfiling,
David Blaikiebb279112018-11-13 20:08:10 +00001278 unsigned NameTableKind, bool RangesBaseAddress),
Adrian Prantl1f599f92015-05-21 20:37:30 +00001279 (SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion,
Adrian Prantl75819ae2016-04-15 15:57:41 +00001280 SplitDebugFilename, EmissionKind, EnumTypes, RetainedTypes,
Dehao Chen0944a8c2017-02-01 22:45:09 +00001281 GlobalVariables, ImportedEntities, Macros, DWOId, SplitDebugInlining,
David Blaikiebb279112018-11-13 20:08:10 +00001282 DebugInfoForProfiling, NameTableKind, RangesBaseAddress))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001283
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001284 TempDICompileUnit clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001285
1286 unsigned getSourceLanguage() const { return SourceLanguage; }
1287 bool isOptimized() const { return IsOptimized; }
1288 unsigned getRuntimeVersion() const { return RuntimeVersion; }
Adrian Prantlb939a252016-03-31 23:56:58 +00001289 DebugEmissionKind getEmissionKind() const {
1290 return (DebugEmissionKind)EmissionKind;
1291 }
Alexey Bataevd4dd7212018-08-01 19:38:20 +00001292 bool isDebugDirectivesOnly() const {
1293 return EmissionKind == DebugDirectivesOnly;
1294 }
Dehao Chen0944a8c2017-02-01 22:45:09 +00001295 bool getDebugInfoForProfiling() const { return DebugInfoForProfiling; }
David Blaikie66cf14d2018-08-16 21:29:55 +00001296 DebugNameTableKind getNameTableKind() const {
1297 return (DebugNameTableKind)NameTableKind;
1298 }
David Blaikiebb279112018-11-13 20:08:10 +00001299 bool getRangesBaseAddress() const {
1300 return RangesBaseAddress; }
1301 StringRef getProducer() const {
1302 return getStringOperand(1); }
1303 StringRef getFlags() const {
1304 return getStringOperand(2); }
1305 StringRef getSplitDebugFilename() const {
1306 return getStringOperand(3); }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001307 DICompositeTypeArray getEnumTypes() const {
Duncan P. N. Exon Smith53855f02015-03-27 23:05:04 +00001308 return cast_or_null<MDTuple>(getRawEnumTypes());
1309 }
Adrian Prantl75819ae2016-04-15 15:57:41 +00001310 DIScopeArray getRetainedTypes() const {
Duncan P. N. Exon Smith53855f02015-03-27 23:05:04 +00001311 return cast_or_null<MDTuple>(getRawRetainedTypes());
1312 }
Adrian Prantlbceaaa92016-12-20 02:09:43 +00001313 DIGlobalVariableExpressionArray getGlobalVariables() const {
Duncan P. N. Exon Smith53855f02015-03-27 23:05:04 +00001314 return cast_or_null<MDTuple>(getRawGlobalVariables());
1315 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001316 DIImportedEntityArray getImportedEntities() const {
Duncan P. N. Exon Smith53855f02015-03-27 23:05:04 +00001317 return cast_or_null<MDTuple>(getRawImportedEntities());
1318 }
Amjad Abouda9bcf162015-12-10 12:56:35 +00001319 DIMacroNodeArray getMacros() const {
1320 return cast_or_null<MDTuple>(getRawMacros());
1321 }
Adrian Prantlfbfc58e2015-09-22 23:21:03 +00001322 uint64_t getDWOId() const { return DWOId; }
Adrian Prantl44103922015-09-22 23:21:06 +00001323 void setDWOId(uint64_t DwoId) { DWOId = DwoId; }
David Blaikiea01f2952016-08-24 18:29:49 +00001324 bool getSplitDebugInlining() const { return SplitDebugInlining; }
1325 void setSplitDebugInlining(bool SplitDebugInlining) {
1326 this->SplitDebugInlining = SplitDebugInlining;
1327 }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001328
Duncan P. N. Exon Smithc1f1acc2015-02-13 01:25:10 +00001329 MDString *getRawProducer() const { return getOperandAs<MDString>(1); }
1330 MDString *getRawFlags() const { return getOperandAs<MDString>(2); }
1331 MDString *getRawSplitDebugFilename() const {
1332 return getOperandAs<MDString>(3);
1333 }
Duncan P. N. Exon Smith53855f02015-03-27 23:05:04 +00001334 Metadata *getRawEnumTypes() const { return getOperand(4); }
1335 Metadata *getRawRetainedTypes() const { return getOperand(5); }
Adrian Prantl75819ae2016-04-15 15:57:41 +00001336 Metadata *getRawGlobalVariables() const { return getOperand(6); }
1337 Metadata *getRawImportedEntities() const { return getOperand(7); }
1338 Metadata *getRawMacros() const { return getOperand(8); }
Duncan P. N. Exon Smithc1f1acc2015-02-13 01:25:10 +00001339
Adrian Prantl1687e012016-11-14 22:09:18 +00001340 /// Replace arrays.
Duncan P. N. Exon Smith94bbbf02015-02-18 20:36:09 +00001341 ///
1342 /// If this \a isUniqued() and not \a isResolved(), it will be RAUW'ed and
1343 /// deleted on a uniquing collision. In practice, uniquing collisions on \a
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001344 /// DICompileUnit should be fairly rare.
Duncan P. N. Exon Smith94bbbf02015-02-18 20:36:09 +00001345 /// @{
Adrian Prantl4afc1f42015-07-06 16:22:07 +00001346 void replaceEnumTypes(DICompositeTypeArray N) {
Adrian Prantl18c073a2015-07-02 22:32:52 +00001347 replaceOperandWith(4, N.get());
1348 }
Adrian Prantl4afc1f42015-07-06 16:22:07 +00001349 void replaceRetainedTypes(DITypeArray N) {
Adrian Prantl18c073a2015-07-02 22:32:52 +00001350 replaceOperandWith(5, N.get());
1351 }
Adrian Prantlbceaaa92016-12-20 02:09:43 +00001352 void replaceGlobalVariables(DIGlobalVariableExpressionArray N) {
Duncan P. N. Exon Smith11344732015-04-07 16:50:39 +00001353 replaceOperandWith(6, N.get());
1354 }
Adrian Prantl75819ae2016-04-15 15:57:41 +00001355 void replaceImportedEntities(DIImportedEntityArray N) {
Duncan P. N. Exon Smith11344732015-04-07 16:50:39 +00001356 replaceOperandWith(7, N.get());
1357 }
Adrian Prantl75819ae2016-04-15 15:57:41 +00001358 void replaceMacros(DIMacroNodeArray N) { replaceOperandWith(8, N.get()); }
Duncan P. N. Exon Smith94bbbf02015-02-18 20:36:09 +00001359 /// @}
1360
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001361 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001362 return MD->getMetadataID() == DICompileUnitKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001363 }
1364};
1365
Adrian Prantl1687e012016-11-14 22:09:18 +00001366/// A scope for locals.
Duncan P. N. Exon Smitha65159a2015-03-24 16:44:29 +00001367///
1368/// A legal scope for lexical blocks, local variables, and debug info
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001369/// locations. Subclasses are \a DISubprogram, \a DILexicalBlock, and \a
1370/// DILexicalBlockFile.
1371class DILocalScope : public DIScope {
Duncan P. N. Exon Smitha65159a2015-03-24 16:44:29 +00001372protected:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001373 DILocalScope(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
Duncan P. N. Exon Smitha65159a2015-03-24 16:44:29 +00001374 ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001375 : DIScope(C, ID, Storage, Tag, Ops) {}
1376 ~DILocalScope() = default;
Duncan P. N. Exon Smitha65159a2015-03-24 16:44:29 +00001377
1378public:
Adrian Prantl1687e012016-11-14 22:09:18 +00001379 /// Get the subprogram for this scope.
Duncan P. N. Exon Smithfd07a2a2015-03-30 21:32:28 +00001380 ///
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001381 /// Return this if it's an \a DISubprogram; otherwise, look up the scope
Duncan P. N. Exon Smithfd07a2a2015-03-30 21:32:28 +00001382 /// chain.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001383 DISubprogram *getSubprogram() const;
Duncan P. N. Exon Smithfd07a2a2015-03-30 21:32:28 +00001384
Amjad Abouda5ba9912016-04-21 16:58:49 +00001385 /// Get the first non DILexicalBlockFile scope of this scope.
1386 ///
1387 /// Return this if it's not a \a DILexicalBlockFIle; otherwise, look up the
1388 /// scope chain.
1389 DILocalScope *getNonLexicalBlockFileScope() const;
1390
Duncan P. N. Exon Smitha65159a2015-03-24 16:44:29 +00001391 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001392 return MD->getMetadataID() == DISubprogramKind ||
1393 MD->getMetadataID() == DILexicalBlockKind ||
1394 MD->getMetadataID() == DILexicalBlockFileKind;
Duncan P. N. Exon Smitha65159a2015-03-24 16:44:29 +00001395 }
1396};
1397
Adrian Prantl1687e012016-11-14 22:09:18 +00001398/// Debug location.
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001399///
1400/// A debug location in source code, used for debug info and otherwise.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001401class DILocation : public MDNode {
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001402 friend class LLVMContextImpl;
1403 friend class MDNode;
1404
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001405 DILocation(LLVMContext &C, StorageType Storage, unsigned Line,
Calixte Denizeteb7f6022018-09-20 08:53:06 +00001406 unsigned Column, ArrayRef<Metadata *> MDs, bool ImplicitCode);
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001407 ~DILocation() { dropAllReferences(); }
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001408
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001409 static DILocation *getImpl(LLVMContext &Context, unsigned Line,
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001410 unsigned Column, Metadata *Scope,
Calixte Denizeteb7f6022018-09-20 08:53:06 +00001411 Metadata *InlinedAt, bool ImplicitCode,
1412 StorageType Storage, bool ShouldCreate = true);
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001413 static DILocation *getImpl(LLVMContext &Context, unsigned Line,
1414 unsigned Column, DILocalScope *Scope,
Calixte Denizeteb7f6022018-09-20 08:53:06 +00001415 DILocation *InlinedAt, bool ImplicitCode,
1416 StorageType Storage, bool ShouldCreate = true) {
Duncan P. N. Exon Smith26489982015-03-26 22:05:04 +00001417 return getImpl(Context, Line, Column, static_cast<Metadata *>(Scope),
Calixte Denizeteb7f6022018-09-20 08:53:06 +00001418 static_cast<Metadata *>(InlinedAt), ImplicitCode, Storage,
1419 ShouldCreate);
Duncan P. N. Exon Smith26489982015-03-26 22:05:04 +00001420 }
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001421
Dehao Chen726da622017-02-15 17:54:39 +00001422 /// With a given unsigned int \p U, use up to 13 bits to represent it.
1423 /// old_bit 1~5 --> new_bit 1~5
1424 /// old_bit 6~12 --> new_bit 7~13
1425 /// new_bit_6 is 0 if higher bits (7~13) are all 0
1426 static unsigned getPrefixEncodingFromUnsigned(unsigned U) {
1427 U &= 0xfff;
1428 return U > 0x1f ? (((U & 0xfe0) << 1) | (U & 0x1f) | 0x20) : U;
1429 }
1430
1431 /// Reverse transformation as getPrefixEncodingFromUnsigned.
1432 static unsigned getUnsignedFromPrefixEncoding(unsigned U) {
1433 return (U & 0x20) ? (((U >> 1) & 0xfe0) | (U & 0x1f)) : (U & 0x1f);
1434 }
1435
1436 /// Returns the next component stored in discriminator.
1437 static unsigned getNextComponentInDiscriminator(unsigned D) {
1438 if ((D & 1) == 0)
1439 return D >> ((D & 0x40) ? 14 : 7);
1440 else
1441 return D >> 1;
1442 }
1443
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001444 TempDILocation cloneImpl() const {
Teresa Johnsond98152b62015-12-07 15:05:44 +00001445 // Get the raw scope/inlinedAt since it is possible to invoke this on
1446 // a DILocation containing temporary metadata.
1447 return getTemporary(getContext(), getLine(), getColumn(), getRawScope(),
Calixte Denizeteb7f6022018-09-20 08:53:06 +00001448 getRawInlinedAt(), isImplicitCode());
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001449 }
1450
Eugene Zelenko1aa40f42016-11-23 22:25:16 +00001451public:
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001452 // Disallow replacing operands.
1453 void replaceOperandWith(unsigned I, Metadata *New) = delete;
1454
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001455 DEFINE_MDNODE_GET(DILocation,
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001456 (unsigned Line, unsigned Column, Metadata *Scope,
Calixte Denizeteb7f6022018-09-20 08:53:06 +00001457 Metadata *InlinedAt = nullptr, bool ImplicitCode = false),
1458 (Line, Column, Scope, InlinedAt, ImplicitCode))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001459 DEFINE_MDNODE_GET(DILocation,
1460 (unsigned Line, unsigned Column, DILocalScope *Scope,
Calixte Denizeteb7f6022018-09-20 08:53:06 +00001461 DILocation *InlinedAt = nullptr,
1462 bool ImplicitCode = false),
1463 (Line, Column, Scope, InlinedAt, ImplicitCode))
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001464
Adrian Prantl1687e012016-11-14 22:09:18 +00001465 /// Return a (temporary) clone of this.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001466 TempDILocation clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001467
1468 unsigned getLine() const { return SubclassData32; }
1469 unsigned getColumn() const { return SubclassData16; }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001470 DILocalScope *getScope() const { return cast<DILocalScope>(getRawScope()); }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +00001471
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001472 DILocation *getInlinedAt() const {
1473 return cast_or_null<DILocation>(getRawInlinedAt());
Duncan P. N. Exon Smith26489982015-03-26 22:05:04 +00001474 }
1475
Calixte Denizeteb7f6022018-09-20 08:53:06 +00001476 /// Check if the location corresponds to an implicit code.
1477 /// When the ImplicitCode flag is true, it means that the Instruction
1478 /// with this DILocation has been added by the front-end but it hasn't been
1479 /// written explicitly by the user (e.g. cleanup stuff in C++ put on a closing
1480 /// bracket). It's useful for code coverage to not show a counter on "empty"
1481 /// lines.
1482 bool isImplicitCode() const { return ImplicitCode; }
1483 void setImplicitCode(bool ImplicitCode) { this->ImplicitCode = ImplicitCode; }
1484
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001485 DIFile *getFile() const { return getScope()->getFile(); }
Duncan P. N. Exon Smith50c065b2015-04-11 00:39:43 +00001486 StringRef getFilename() const { return getScope()->getFilename(); }
1487 StringRef getDirectory() const { return getScope()->getDirectory(); }
Scott Linder16c7bda2018-02-23 23:01:06 +00001488 Optional<StringRef> getSource() const { return getScope()->getSource(); }
Duncan P. N. Exon Smith50c065b2015-04-11 00:39:43 +00001489
Adrian Prantl1687e012016-11-14 22:09:18 +00001490 /// Get the scope where this is inlined.
Duncan P. N. Exon Smith8f7bc792015-03-30 17:41:24 +00001491 ///
1492 /// Walk through \a getInlinedAt() and return \a getScope() from the deepest
1493 /// location.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001494 DILocalScope *getInlinedAtScope() const {
Duncan P. N. Exon Smith8f7bc792015-03-30 17:41:24 +00001495 if (auto *IA = getInlinedAt())
1496 return IA->getInlinedAtScope();
1497 return getScope();
1498 }
1499
Adrian Prantl1687e012016-11-14 22:09:18 +00001500 /// Get the DWARF discriminator.
Duncan P. N. Exon Smith2c8291e2015-04-14 00:05:13 +00001501 ///
1502 /// DWARF discriminators distinguish identical file locations between
1503 /// instructions that are on different basic blocks.
Dehao Chenfb02f712017-02-10 21:09:07 +00001504 ///
1505 /// There are 3 components stored in discriminator, from lower bits:
1506 ///
1507 /// Base discriminator: assigned by AddDiscriminators pass to identify IRs
1508 /// that are defined by the same source line, but
1509 /// different basic blocks.
1510 /// Duplication factor: assigned by optimizations that will scale down
1511 /// the execution frequency of the original IR.
1512 /// Copy Identifier: assigned by optimizations that clones the IR.
1513 /// Each copy of the IR will be assigned an identifier.
1514 ///
1515 /// Encoding:
1516 ///
1517 /// The above 3 components are encoded into a 32bit unsigned integer in
1518 /// order. If the lowest bit is 1, the current component is empty, and the
Hiroshi Inoue4cf7b882018-01-23 05:49:30 +00001519 /// next component will start in the next bit. Otherwise, the current
Dehao Chenfb02f712017-02-10 21:09:07 +00001520 /// component is non-empty, and its content starts in the next bit. The
1521 /// length of each components is either 5 bit or 12 bit: if the 7th bit
1522 /// is 0, the bit 2~6 (5 bits) are used to represent the component; if the
1523 /// 7th bit is 1, the bit 2~6 (5 bits) and 8~14 (7 bits) are combined to
1524 /// represent the component.
1525
Duncan P. N. Exon Smith2c8291e2015-04-14 00:05:13 +00001526 inline unsigned getDiscriminator() const;
1527
Dehao Chene7130002016-10-26 15:48:45 +00001528 /// Returns a new DILocation with updated \p Discriminator.
Dehao Chenfb02f712017-02-10 21:09:07 +00001529 inline const DILocation *cloneWithDiscriminator(unsigned Discriminator) const;
1530
1531 /// Returns a new DILocation with updated base discriminator \p BD.
1532 inline const DILocation *setBaseDiscriminator(unsigned BD) const;
1533
1534 /// Returns the duplication factor stored in the discriminator.
1535 inline unsigned getDuplicationFactor() const;
1536
1537 /// Returns the copy identifier stored in the discriminator.
1538 inline unsigned getCopyIdentifier() const;
1539
1540 /// Returns the base discriminator stored in the discriminator.
1541 inline unsigned getBaseDiscriminator() const;
1542
1543 /// Returns a new DILocation with duplication factor \p DF encoded in the
1544 /// discriminator.
1545 inline const DILocation *cloneWithDuplicationFactor(unsigned DF) const;
Dehao Chene7130002016-10-26 15:48:45 +00001546
Robert Lougher7bd04e32016-12-14 16:14:17 +00001547 /// When two instructions are combined into a single instruction we also
1548 /// need to combine the original locations into a single location.
1549 ///
1550 /// When the locations are the same we can use either location. When they
Vedant Kumar65b0d4d2018-04-12 20:58:24 +00001551 /// differ, we need a third location which is distinct from either. If they
1552 /// have the same file/line but have a different discriminator we could
1553 /// create a location with a new discriminator. If they are from different
1554 /// files/lines the location is ambiguous and can't be represented in a line
1555 /// entry. In this case, if \p GenerateLocation is true, we will set the
1556 /// merged debug location as line 0 of the nearest common scope where the two
1557 /// locations are inlined from.
Robert Lougher7bd04e32016-12-14 16:14:17 +00001558 ///
Vedant Kumar65b0d4d2018-04-12 20:58:24 +00001559 /// \p GenerateLocation: Whether the merged location can be generated when
1560 /// \p LocA and \p LocB differ.
David Blaikie2a813ef2018-08-23 22:35:58 +00001561 static const DILocation *getMergedLocation(const DILocation *LocA,
1562 const DILocation *LocB);
Robert Lougher7bd04e32016-12-14 16:14:17 +00001563
Dehao Chen726da622017-02-15 17:54:39 +00001564 /// Returns the base discriminator for a given encoded discriminator \p D.
1565 static unsigned getBaseDiscriminatorFromDiscriminator(unsigned D) {
1566 if ((D & 1) == 0)
1567 return getUnsignedFromPrefixEncoding(D >> 1);
1568 else
1569 return 0;
1570 }
1571
1572 /// Returns the duplication factor for a given encoded discriminator \p D.
1573 static unsigned getDuplicationFactorFromDiscriminator(unsigned D) {
1574 D = getNextComponentInDiscriminator(D);
1575 if (D == 0 || (D & 1))
1576 return 1;
1577 else
1578 return getUnsignedFromPrefixEncoding(D >> 1);
1579 }
1580
1581 /// Returns the copy identifier for a given encoded discriminator \p D.
1582 static unsigned getCopyIdentifierFromDiscriminator(unsigned D) {
1583 return getUnsignedFromPrefixEncoding(getNextComponentInDiscriminator(
1584 getNextComponentInDiscriminator(D)));
1585 }
1586
1587
Duncan P. N. Exon Smith26489982015-03-26 22:05:04 +00001588 Metadata *getRawScope() const { return getOperand(0); }
1589 Metadata *getRawInlinedAt() const {
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001590 if (getNumOperands() == 2)
1591 return getOperand(1);
1592 return nullptr;
1593 }
1594
1595 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001596 return MD->getMetadataID() == DILocationKind;
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001597 }
1598};
1599
Adrian Prantl1687e012016-11-14 22:09:18 +00001600/// Subprogram description.
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001601///
1602/// TODO: Remove DisplayName. It's always equal to Name.
1603/// TODO: Split up flags.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001604class DISubprogram : public DILocalScope {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001605 friend class LLVMContextImpl;
1606 friend class MDNode;
1607
1608 unsigned Line;
1609 unsigned ScopeLine;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001610 unsigned VirtualIndex;
Davide Italiano236e7442016-04-13 20:17:42 +00001611
Reid Klecknerb5af11d2016-07-01 02:41:21 +00001612 /// In the MS ABI, the implicit 'this' parameter is adjusted in the prologue
1613 /// of method overrides from secondary bases by this amount. It may be
1614 /// negative.
1615 int ThisAdjustment;
1616
Paul Robinsoncda54212018-11-19 18:29:28 +00001617public:
1618 /// Debug info subprogram flags.
1619 enum DISPFlags : uint32_t {
1620#define HANDLE_DISP_FLAG(ID, NAME) SPFlag##NAME = ID,
1621#define DISP_FLAG_LARGEST_NEEDED
1622#include "llvm/IR/DebugInfoFlags.def"
1623 SPFlagVirtuality = SPFlagNonvirtual | SPFlagVirtual | SPFlagPureVirtual,
1624 LLVM_MARK_AS_BITMASK_ENUM(SPFlagLargest)
1625 };
1626 // Helper for converting old bitfields to new flags word.
1627 static DISPFlags toSPFlags(bool IsLocalToUnit, bool IsDefinition,
1628 bool IsOptimized,
1629 unsigned Virtuality = SPFlagNonvirtual) {
1630 // We're assuming virtuality is the low-order field.
Paul Robinsonfdaeb0c2018-11-19 18:51:11 +00001631 static_assert(
1632 int(SPFlagVirtual) == int(dwarf::DW_VIRTUALITY_virtual &&
1633 int(SPFlagPureVirtual) == int(dwarf::DW_VIRTUALITY_pure_virtual),
1634 "Virtuality constant mismatch");
Paul Robinsoncda54212018-11-19 18:29:28 +00001635 return static_cast<DISPFlags>((Virtuality & SPFlagVirtuality) |
1636 (IsLocalToUnit ? SPFlagLocalToUnit : 0) |
1637 (IsDefinition ? SPFlagDefinition : 0) |
1638 (IsOptimized ? SPFlagOptimized : 0));
1639 }
Davide Italiano236e7442016-04-13 20:17:42 +00001640
Paul Robinsoncda54212018-11-19 18:29:28 +00001641private:
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001642 DIFlags Flags;
Paul Robinsoncda54212018-11-19 18:29:28 +00001643 DISPFlags SPFlags;
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001644
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001645 DISubprogram(LLVMContext &C, StorageType Storage, unsigned Line,
Paul Robinsoncda54212018-11-19 18:29:28 +00001646 unsigned ScopeLine, unsigned VirtualIndex, int ThisAdjustment,
1647 DIFlags Flags, DISPFlags SPFlags, ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001648 : DILocalScope(C, DISubprogramKind, Storage, dwarf::DW_TAG_subprogram,
Duncan P. N. Exon Smitha65159a2015-03-24 16:44:29 +00001649 Ops),
Davide Italiano236e7442016-04-13 20:17:42 +00001650 Line(Line), ScopeLine(ScopeLine), VirtualIndex(VirtualIndex),
Paul Robinsoncda54212018-11-19 18:29:28 +00001651 ThisAdjustment(ThisAdjustment), Flags(Flags), SPFlags(SPFlags) {
Davide Italiano236e7442016-04-13 20:17:42 +00001652 static_assert(dwarf::DW_VIRTUALITY_max < 4, "Virtuality out of range");
Davide Italiano236e7442016-04-13 20:17:42 +00001653 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001654 ~DISubprogram() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001655
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001656 static DISubprogram *
1657 getImpl(LLVMContext &Context, DIScopeRef Scope, StringRef Name,
1658 StringRef LinkageName, DIFile *File, unsigned Line,
Paul Robinsoncda54212018-11-19 18:29:28 +00001659 DISubroutineType *Type, unsigned ScopeLine, DITypeRef ContainingType,
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001660 unsigned VirtualIndex, int ThisAdjustment, DIFlags Flags,
Paul Robinsoncda54212018-11-19 18:29:28 +00001661 DISPFlags SPFlags, DICompileUnit *Unit,
Reid Klecknerb5af11d2016-07-01 02:41:21 +00001662 DITemplateParameterArray TemplateParams, DISubprogram *Declaration,
Shiva Chen2c864552018-05-09 02:40:45 +00001663 DINodeArray RetainedNodes, DITypeArray ThrownTypes,
Adrian Prantl1d12b882017-04-26 22:56:44 +00001664 StorageType Storage, bool ShouldCreate = true) {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001665 return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
1666 getCanonicalMDString(Context, LinkageName), File, Line, Type,
Paul Robinsoncda54212018-11-19 18:29:28 +00001667 ScopeLine, ContainingType, VirtualIndex, ThisAdjustment,
1668 Flags, SPFlags, Unit, TemplateParams.get(), Declaration,
1669 RetainedNodes.get(), ThrownTypes.get(), Storage,
1670 ShouldCreate);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001671 }
Paul Robinsoncda54212018-11-19 18:29:28 +00001672 static DISubprogram *getImpl(LLVMContext &Context, Metadata *Scope,
1673 MDString *Name, MDString *LinkageName,
1674 Metadata *File, unsigned Line, Metadata *Type,
1675 unsigned ScopeLine, Metadata *ContainingType,
1676 unsigned VirtualIndex, int ThisAdjustment,
1677 DIFlags Flags, DISPFlags SPFlags, Metadata *Unit,
1678 Metadata *TemplateParams, Metadata *Declaration,
1679 Metadata *RetainedNodes, Metadata *ThrownTypes,
1680 StorageType Storage, bool ShouldCreate = true);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001681
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001682 TempDISubprogram cloneImpl() const {
Adrian Prantl1d12b882017-04-26 22:56:44 +00001683 return getTemporary(getContext(), getScope(), getName(), getLinkageName(),
Paul Robinsoncda54212018-11-19 18:29:28 +00001684 getFile(), getLine(), getType(), getScopeLine(),
1685 getContainingType(), getVirtualIndex(),
1686 getThisAdjustment(), getFlags(), getSPFlags(),
1687 getUnit(), getTemplateParams(), getDeclaration(),
1688 getRetainedNodes(), getThrownTypes());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001689 }
1690
1691public:
Paul Robinsoncda54212018-11-19 18:29:28 +00001692 DEFINE_MDNODE_GET(
1693 DISubprogram,
1694 (DIScopeRef Scope, StringRef Name, StringRef LinkageName, DIFile *File,
1695 unsigned Line, DISubroutineType *Type, unsigned ScopeLine,
1696 DITypeRef ContainingType, unsigned VirtualIndex, int ThisAdjustment,
1697 DIFlags Flags, DISPFlags SPFlags, DICompileUnit *Unit,
1698 DITemplateParameterArray TemplateParams = nullptr,
1699 DISubprogram *Declaration = nullptr, DINodeArray RetainedNodes = nullptr,
1700 DITypeArray ThrownTypes = nullptr),
1701 (Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType,
1702 VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams,
1703 Declaration, RetainedNodes, ThrownTypes))
1704
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001705 DEFINE_MDNODE_GET(
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001706 DISubprogram,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001707 (Metadata * Scope, MDString *Name, MDString *LinkageName, Metadata *File,
Paul Robinsoncda54212018-11-19 18:29:28 +00001708 unsigned Line, Metadata *Type, unsigned ScopeLine,
1709 Metadata *ContainingType, unsigned VirtualIndex, int ThisAdjustment,
1710 DIFlags Flags, DISPFlags SPFlags, Metadata *Unit,
1711 Metadata *TemplateParams = nullptr, Metadata *Declaration = nullptr,
1712 Metadata *RetainedNodes = nullptr, Metadata *ThrownTypes = nullptr),
1713 (Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType,
1714 VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams,
1715 Declaration, RetainedNodes, ThrownTypes))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001716
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001717 TempDISubprogram clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001718
Roman Tereshincf88ffa2018-06-01 23:15:09 +00001719 /// Returns a new temporary DISubprogram with updated Flags
1720 TempDISubprogram cloneWithFlags(DIFlags NewFlags) const {
1721 auto NewSP = clone();
1722 NewSP->Flags = NewFlags;
1723 return NewSP;
1724 }
1725
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001726public:
1727 unsigned getLine() const { return Line; }
Paul Robinsoncda54212018-11-19 18:29:28 +00001728 unsigned getVirtuality() const { return getSPFlags() & SPFlagVirtuality; }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001729 unsigned getVirtualIndex() const { return VirtualIndex; }
Reid Klecknerb5af11d2016-07-01 02:41:21 +00001730 int getThisAdjustment() const { return ThisAdjustment; }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001731 unsigned getScopeLine() const { return ScopeLine; }
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001732 DIFlags getFlags() const { return Flags; }
Paul Robinsoncda54212018-11-19 18:29:28 +00001733 DISPFlags getSPFlags() const { return SPFlags; }
1734 bool isLocalToUnit() const { return getSPFlags() & SPFlagLocalToUnit; }
1735 bool isDefinition() const { return getSPFlags() & SPFlagDefinition; }
1736 bool isOptimized() const { return getSPFlags() & SPFlagOptimized; }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001737
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001738 bool isArtificial() const { return getFlags() & FlagArtificial; }
Duncan P. N. Exon Smitha1384912015-04-07 03:33:57 +00001739 bool isPrivate() const {
1740 return (getFlags() & FlagAccessibility) == FlagPrivate;
1741 }
1742 bool isProtected() const {
1743 return (getFlags() & FlagAccessibility) == FlagProtected;
1744 }
1745 bool isPublic() const {
1746 return (getFlags() & FlagAccessibility) == FlagPublic;
1747 }
1748 bool isExplicit() const { return getFlags() & FlagExplicit; }
1749 bool isPrototyped() const { return getFlags() & FlagPrototyped; }
Vedant Kumar5931b4e2018-10-05 20:37:17 +00001750 bool areAllCallsDescribed() const {
1751 return getFlags() & FlagAllCallsDescribed;
1752 }
David Blaikiece3c8ef2016-11-28 21:32:19 +00001753 bool isMainSubprogram() const { return getFlags() & FlagMainSubprogram; }
Duncan P. N. Exon Smitha1384912015-04-07 03:33:57 +00001754
Adrian Prantl1687e012016-11-14 22:09:18 +00001755 /// Check if this is reference-qualified.
Duncan P. N. Exon Smitha1384912015-04-07 03:33:57 +00001756 ///
1757 /// Return true if this subprogram is a C++11 reference-qualified non-static
1758 /// member function (void foo() &).
Leny Kholodov40c62352016-09-06 17:03:02 +00001759 bool isLValueReference() const { return getFlags() & FlagLValueReference; }
Duncan P. N. Exon Smitha1384912015-04-07 03:33:57 +00001760
Adrian Prantl1687e012016-11-14 22:09:18 +00001761 /// Check if this is rvalue-reference-qualified.
Duncan P. N. Exon Smitha1384912015-04-07 03:33:57 +00001762 ///
1763 /// Return true if this subprogram is a C++11 rvalue-reference-qualified
1764 /// non-static member function (void foo() &&).
Leny Kholodov40c62352016-09-06 17:03:02 +00001765 bool isRValueReference() const { return getFlags() & FlagRValueReference; }
Duncan P. N. Exon Smitha1384912015-04-07 03:33:57 +00001766
Adrian Prantl1687e012016-11-14 22:09:18 +00001767 /// Check if this is marked as noreturn.
Adrian Prantlc19dee72016-08-17 16:02:43 +00001768 ///
1769 /// Return true if this subprogram is C++11 noreturn or C11 _Noreturn
Leny Kholodov40c62352016-09-06 17:03:02 +00001770 bool isNoReturn() const { return getFlags() & FlagNoReturn; }
Adrian Prantlc19dee72016-08-17 16:02:43 +00001771
Brock Wyma94ece8f2018-04-16 16:53:57 +00001772 // Check if this routine is a compiler-generated thunk.
1773 //
1774 // Returns true if this subprogram is a thunk generated by the compiler.
1775 bool isThunk() const { return getFlags() & FlagThunk; }
1776
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001777 DIScopeRef getScope() const { return DIScopeRef(getRawScope()); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001778
1779 StringRef getName() const { return getStringOperand(2); }
Adrian Prantl9d2f0192017-04-26 23:59:52 +00001780 StringRef getLinkageName() const { return getStringOperand(3); }
Duncan P. N. Exon Smith19fc5ed2015-02-13 01:26:47 +00001781
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001782 DISubroutineType *getType() const {
1783 return cast_or_null<DISubroutineType>(getRawType());
Duncan P. N. Exon Smith869db502015-03-30 16:19:15 +00001784 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001785 DITypeRef getContainingType() const {
1786 return DITypeRef(getRawContainingType());
Duncan P. N. Exon Smith3ec5fa62015-04-06 19:03:45 +00001787 }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001788
Adrian Prantl75819ae2016-04-15 15:57:41 +00001789 DICompileUnit *getUnit() const {
1790 return cast_or_null<DICompileUnit>(getRawUnit());
1791 }
Adrian Prantl9d2f0192017-04-26 23:59:52 +00001792 void replaceUnit(DICompileUnit *CU) { replaceOperandWith(5, CU); }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001793 DITemplateParameterArray getTemplateParams() const {
Duncan P. N. Exon Smith869db502015-03-30 16:19:15 +00001794 return cast_or_null<MDTuple>(getRawTemplateParams());
1795 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001796 DISubprogram *getDeclaration() const {
1797 return cast_or_null<DISubprogram>(getRawDeclaration());
Duncan P. N. Exon Smith869db502015-03-30 16:19:15 +00001798 }
Shiva Chen2c864552018-05-09 02:40:45 +00001799 DINodeArray getRetainedNodes() const {
1800 return cast_or_null<MDTuple>(getRawRetainedNodes());
Duncan P. N. Exon Smith869db502015-03-30 16:19:15 +00001801 }
Adrian Prantl1d12b882017-04-26 22:56:44 +00001802 DITypeArray getThrownTypes() const {
1803 return cast_or_null<MDTuple>(getRawThrownTypes());
1804 }
Duncan P. N. Exon Smith869db502015-03-30 16:19:15 +00001805
1806 Metadata *getRawScope() const { return getOperand(1); }
Adrian Prantl9d2f0192017-04-26 23:59:52 +00001807 MDString *getRawName() const { return getOperandAs<MDString>(2); }
1808 MDString *getRawLinkageName() const { return getOperandAs<MDString>(3); }
1809 Metadata *getRawType() const { return getOperand(4); }
1810 Metadata *getRawUnit() const { return getOperand(5); }
1811 Metadata *getRawDeclaration() const { return getOperand(6); }
Shiva Chen2c864552018-05-09 02:40:45 +00001812 Metadata *getRawRetainedNodes() const { return getOperand(7); }
Adrian Prantl9d2f0192017-04-26 23:59:52 +00001813 Metadata *getRawContainingType() const {
1814 return getNumOperands() > 8 ? getOperandAs<Metadata>(8) : nullptr;
1815 }
1816 Metadata *getRawTemplateParams() const {
1817 return getNumOperands() > 9 ? getOperandAs<Metadata>(9) : nullptr;
1818 }
1819 Metadata *getRawThrownTypes() const {
1820 return getNumOperands() > 10 ? getOperandAs<Metadata>(10) : nullptr;
1821 }
Duncan P. N. Exon Smithdf523492015-02-18 20:32:57 +00001822
Adrian Prantl1687e012016-11-14 22:09:18 +00001823 /// Check if this subprogram describes the given function.
Duncan P. N. Exon Smith3c2d7042015-04-13 19:07:27 +00001824 ///
1825 /// FIXME: Should this be looking through bitcasts?
1826 bool describes(const Function *F) const;
1827
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001828 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001829 return MD->getMetadataID() == DISubprogramKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001830 }
1831};
1832
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001833class DILexicalBlockBase : public DILocalScope {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001834protected:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001835 DILexicalBlockBase(LLVMContext &C, unsigned ID, StorageType Storage,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001836 ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001837 : DILocalScope(C, ID, Storage, dwarf::DW_TAG_lexical_block, Ops) {}
1838 ~DILexicalBlockBase() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001839
1840public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001841 DILocalScope *getScope() const { return cast<DILocalScope>(getRawScope()); }
Duncan P. N. Exon Smith0e202b92015-03-30 16:37:48 +00001842
1843 Metadata *getRawScope() const { return getOperand(1); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001844
1845 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001846 return MD->getMetadataID() == DILexicalBlockKind ||
1847 MD->getMetadataID() == DILexicalBlockFileKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001848 }
1849};
1850
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001851class DILexicalBlock : public DILexicalBlockBase {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001852 friend class LLVMContextImpl;
1853 friend class MDNode;
1854
1855 unsigned Line;
Duncan P. N. Exon Smithb09eb9f2015-08-28 22:58:50 +00001856 uint16_t Column;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001857
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001858 DILexicalBlock(LLVMContext &C, StorageType Storage, unsigned Line,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001859 unsigned Column, ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001860 : DILexicalBlockBase(C, DILexicalBlockKind, Storage, Ops), Line(Line),
Duncan P. N. Exon Smithb09eb9f2015-08-28 22:58:50 +00001861 Column(Column) {
1862 assert(Column < (1u << 16) && "Expected 16-bit column");
1863 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001864 ~DILexicalBlock() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001865
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001866 static DILexicalBlock *getImpl(LLVMContext &Context, DILocalScope *Scope,
1867 DIFile *File, unsigned Line, unsigned Column,
Duncan P. N. Exon Smith0e202b92015-03-30 16:37:48 +00001868 StorageType Storage,
1869 bool ShouldCreate = true) {
1870 return getImpl(Context, static_cast<Metadata *>(Scope),
1871 static_cast<Metadata *>(File), Line, Column, Storage,
1872 ShouldCreate);
1873 }
1874
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001875 static DILexicalBlock *getImpl(LLVMContext &Context, Metadata *Scope,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001876 Metadata *File, unsigned Line, unsigned Column,
1877 StorageType Storage, bool ShouldCreate = true);
1878
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001879 TempDILexicalBlock cloneImpl() const {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001880 return getTemporary(getContext(), getScope(), getFile(), getLine(),
1881 getColumn());
1882 }
1883
1884public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001885 DEFINE_MDNODE_GET(DILexicalBlock, (DILocalScope * Scope, DIFile *File,
Duncan P. N. Exon Smith0e202b92015-03-30 16:37:48 +00001886 unsigned Line, unsigned Column),
1887 (Scope, File, Line, Column))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001888 DEFINE_MDNODE_GET(DILexicalBlock, (Metadata * Scope, Metadata *File,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001889 unsigned Line, unsigned Column),
1890 (Scope, File, Line, Column))
1891
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001892 TempDILexicalBlock clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001893
1894 unsigned getLine() const { return Line; }
1895 unsigned getColumn() const { return Column; }
1896
1897 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001898 return MD->getMetadataID() == DILexicalBlockKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001899 }
1900};
1901
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001902class DILexicalBlockFile : public DILexicalBlockBase {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001903 friend class LLVMContextImpl;
1904 friend class MDNode;
1905
1906 unsigned Discriminator;
1907
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001908 DILexicalBlockFile(LLVMContext &C, StorageType Storage,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001909 unsigned Discriminator, ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001910 : DILexicalBlockBase(C, DILexicalBlockFileKind, Storage, Ops),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001911 Discriminator(Discriminator) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001912 ~DILexicalBlockFile() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001913
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001914 static DILexicalBlockFile *getImpl(LLVMContext &Context, DILocalScope *Scope,
1915 DIFile *File, unsigned Discriminator,
Duncan P. N. Exon Smith0e202b92015-03-30 16:37:48 +00001916 StorageType Storage,
1917 bool ShouldCreate = true) {
1918 return getImpl(Context, static_cast<Metadata *>(Scope),
1919 static_cast<Metadata *>(File), Discriminator, Storage,
1920 ShouldCreate);
1921 }
1922
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001923 static DILexicalBlockFile *getImpl(LLVMContext &Context, Metadata *Scope,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001924 Metadata *File, unsigned Discriminator,
1925 StorageType Storage,
1926 bool ShouldCreate = true);
1927
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001928 TempDILexicalBlockFile cloneImpl() const {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001929 return getTemporary(getContext(), getScope(), getFile(),
1930 getDiscriminator());
1931 }
1932
1933public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001934 DEFINE_MDNODE_GET(DILexicalBlockFile, (DILocalScope * Scope, DIFile *File,
Duncan P. N. Exon Smith0e202b92015-03-30 16:37:48 +00001935 unsigned Discriminator),
1936 (Scope, File, Discriminator))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001937 DEFINE_MDNODE_GET(DILexicalBlockFile,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001938 (Metadata * Scope, Metadata *File, unsigned Discriminator),
1939 (Scope, File, Discriminator))
1940
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001941 TempDILexicalBlockFile clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001942
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001943 // TODO: Remove these once they're gone from DILexicalBlockBase.
Duncan P. N. Exon Smith5f88ba12015-04-14 02:50:07 +00001944 unsigned getLine() const = delete;
1945 unsigned getColumn() const = delete;
1946
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001947 unsigned getDiscriminator() const { return Discriminator; }
1948
1949 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001950 return MD->getMetadataID() == DILexicalBlockFileKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001951 }
1952};
1953
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001954unsigned DILocation::getDiscriminator() const {
1955 if (auto *F = dyn_cast<DILexicalBlockFile>(getScope()))
Duncan P. N. Exon Smith2c8291e2015-04-14 00:05:13 +00001956 return F->getDiscriminator();
1957 return 0;
1958}
1959
Dehao Chenfb02f712017-02-10 21:09:07 +00001960const DILocation *
1961DILocation::cloneWithDiscriminator(unsigned Discriminator) const {
Dehao Chene7130002016-10-26 15:48:45 +00001962 DIScope *Scope = getScope();
1963 // Skip all parent DILexicalBlockFile that already have a discriminator
1964 // assigned. We do not want to have nested DILexicalBlockFiles that have
1965 // mutliple discriminators because only the leaf DILexicalBlockFile's
1966 // dominator will be used.
1967 for (auto *LBF = dyn_cast<DILexicalBlockFile>(Scope);
1968 LBF && LBF->getDiscriminator() != 0;
1969 LBF = dyn_cast<DILexicalBlockFile>(Scope))
1970 Scope = LBF->getScope();
1971 DILexicalBlockFile *NewScope =
1972 DILexicalBlockFile::get(getContext(), Scope, getFile(), Discriminator);
1973 return DILocation::get(getContext(), getLine(), getColumn(), NewScope,
1974 getInlinedAt());
1975}
1976
Dehao Chenfb02f712017-02-10 21:09:07 +00001977unsigned DILocation::getBaseDiscriminator() const {
Dehao Chen726da622017-02-15 17:54:39 +00001978 return getBaseDiscriminatorFromDiscriminator(getDiscriminator());
Dehao Chenfb02f712017-02-10 21:09:07 +00001979}
1980
1981unsigned DILocation::getDuplicationFactor() const {
Dehao Chen726da622017-02-15 17:54:39 +00001982 return getDuplicationFactorFromDiscriminator(getDiscriminator());
Dehao Chenfb02f712017-02-10 21:09:07 +00001983}
1984
1985unsigned DILocation::getCopyIdentifier() const {
Dehao Chen726da622017-02-15 17:54:39 +00001986 return getCopyIdentifierFromDiscriminator(getDiscriminator());
Dehao Chenfb02f712017-02-10 21:09:07 +00001987}
1988
1989const DILocation *DILocation::setBaseDiscriminator(unsigned D) const {
1990 if (D == 0)
1991 return this;
1992 else
1993 return cloneWithDiscriminator(getPrefixEncodingFromUnsigned(D) << 1);
1994}
1995
1996const DILocation *DILocation::cloneWithDuplicationFactor(unsigned DF) const {
1997 DF *= getDuplicationFactor();
1998 if (DF <= 1)
1999 return this;
2000
2001 unsigned BD = getBaseDiscriminator();
2002 unsigned CI = getCopyIdentifier() << (DF > 0x1f ? 14 : 7);
2003 unsigned D = CI | (getPrefixEncodingFromUnsigned(DF) << 1);
2004
2005 if (BD == 0)
2006 D = (D << 1) | 1;
2007 else
2008 D = (D << (BD > 0x1f ? 14 : 7)) | (getPrefixEncodingFromUnsigned(BD) << 1);
2009
2010 return cloneWithDiscriminator(D);
2011}
2012
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002013class DINamespace : public DIScope {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002014 friend class LLVMContextImpl;
2015 friend class MDNode;
2016
Adrian Prantldbfda632016-11-03 19:42:02 +00002017 unsigned ExportSymbols : 1;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002018
Adrian Prantlfed4f392017-04-28 22:25:46 +00002019 DINamespace(LLVMContext &Context, StorageType Storage, bool ExportSymbols,
2020 ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002021 : DIScope(Context, DINamespaceKind, Storage, dwarf::DW_TAG_namespace,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002022 Ops),
Adrian Prantlfed4f392017-04-28 22:25:46 +00002023 ExportSymbols(ExportSymbols) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002024 ~DINamespace() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002025
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002026 static DINamespace *getImpl(LLVMContext &Context, DIScope *Scope,
Adrian Prantlfed4f392017-04-28 22:25:46 +00002027 StringRef Name, bool ExportSymbols,
2028 StorageType Storage, bool ShouldCreate = true) {
2029 return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
2030 ExportSymbols, Storage, ShouldCreate);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002031 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002032 static DINamespace *getImpl(LLVMContext &Context, Metadata *Scope,
Adrian Prantlfed4f392017-04-28 22:25:46 +00002033 MDString *Name, bool ExportSymbols,
2034 StorageType Storage, bool ShouldCreate = true);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002035
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002036 TempDINamespace cloneImpl() const {
Adrian Prantlfed4f392017-04-28 22:25:46 +00002037 return getTemporary(getContext(), getScope(), getName(),
2038 getExportSymbols());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002039 }
2040
2041public:
Adrian Prantldbfda632016-11-03 19:42:02 +00002042 DEFINE_MDNODE_GET(DINamespace,
Adrian Prantlfed4f392017-04-28 22:25:46 +00002043 (DIScope *Scope, StringRef Name, bool ExportSymbols),
2044 (Scope, Name, ExportSymbols))
2045 DEFINE_MDNODE_GET(DINamespace,
2046 (Metadata *Scope, MDString *Name, bool ExportSymbols),
2047 (Scope, Name, ExportSymbols))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002048
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002049 TempDINamespace clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002050
Adrian Prantldbfda632016-11-03 19:42:02 +00002051 bool getExportSymbols() const { return ExportSymbols; }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002052 DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002053 StringRef getName() const { return getStringOperand(2); }
2054
Duncan P. N. Exon Smithf9b47752015-03-30 17:21:38 +00002055 Metadata *getRawScope() const { return getOperand(1); }
Duncan P. N. Exon Smithe1460002015-02-13 01:32:09 +00002056 MDString *getRawName() const { return getOperandAs<MDString>(2); }
2057
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002058 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002059 return MD->getMetadataID() == DINamespaceKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002060 }
2061};
2062
Adrian Prantl1687e012016-11-14 22:09:18 +00002063/// A (clang) module that has been imported by the compile unit.
Adrian Prantlab1243f2015-06-29 23:03:47 +00002064///
2065class DIModule : public DIScope {
2066 friend class LLVMContextImpl;
2067 friend class MDNode;
2068
2069 DIModule(LLVMContext &Context, StorageType Storage, ArrayRef<Metadata *> Ops)
2070 : DIScope(Context, DIModuleKind, Storage, dwarf::DW_TAG_module, Ops) {}
Eugene Zelenko1aa40f42016-11-23 22:25:16 +00002071 ~DIModule() = default;
Adrian Prantlab1243f2015-06-29 23:03:47 +00002072
2073 static DIModule *getImpl(LLVMContext &Context, DIScope *Scope,
2074 StringRef Name, StringRef ConfigurationMacros,
2075 StringRef IncludePath, StringRef ISysRoot,
2076 StorageType Storage, bool ShouldCreate = true) {
2077 return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
2078 getCanonicalMDString(Context, ConfigurationMacros),
NAKAMURA Takumiff35c332015-07-06 00:48:17 +00002079 getCanonicalMDString(Context, IncludePath),
2080 getCanonicalMDString(Context, ISysRoot),
Adrian Prantlab1243f2015-06-29 23:03:47 +00002081 Storage, ShouldCreate);
2082 }
2083 static DIModule *getImpl(LLVMContext &Context, Metadata *Scope,
2084 MDString *Name, MDString *ConfigurationMacros,
NAKAMURA Takumiff35c332015-07-06 00:48:17 +00002085 MDString *IncludePath, MDString *ISysRoot,
2086 StorageType Storage, bool ShouldCreate = true);
Adrian Prantlab1243f2015-06-29 23:03:47 +00002087
2088 TempDIModule cloneImpl() const {
2089 return getTemporary(getContext(), getScope(), getName(),
2090 getConfigurationMacros(), getIncludePath(),
2091 getISysRoot());
2092 }
2093
2094public:
2095 DEFINE_MDNODE_GET(DIModule, (DIScope *Scope, StringRef Name,
NAKAMURA Takumiff35c332015-07-06 00:48:17 +00002096 StringRef ConfigurationMacros, StringRef IncludePath,
2097 StringRef ISysRoot),
Adrian Prantlab1243f2015-06-29 23:03:47 +00002098 (Scope, Name, ConfigurationMacros, IncludePath, ISysRoot))
2099 DEFINE_MDNODE_GET(DIModule,
2100 (Metadata *Scope, MDString *Name, MDString *ConfigurationMacros,
NAKAMURA Takumiff35c332015-07-06 00:48:17 +00002101 MDString *IncludePath, MDString *ISysRoot),
Adrian Prantlab1243f2015-06-29 23:03:47 +00002102 (Scope, Name, ConfigurationMacros, IncludePath, ISysRoot))
2103
2104 TempDIModule clone() const { return cloneImpl(); }
2105
2106 DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
2107 StringRef getName() const { return getStringOperand(1); }
2108 StringRef getConfigurationMacros() const { return getStringOperand(2); }
2109 StringRef getIncludePath() const { return getStringOperand(3); }
2110 StringRef getISysRoot() const { return getStringOperand(4); }
2111
2112 Metadata *getRawScope() const { return getOperand(0); }
2113 MDString *getRawName() const { return getOperandAs<MDString>(1); }
2114 MDString *getRawConfigurationMacros() const { return getOperandAs<MDString>(2); }
2115 MDString *getRawIncludePath() const { return getOperandAs<MDString>(3); }
2116 MDString *getRawISysRoot() const { return getOperandAs<MDString>(4); }
2117
2118 static bool classof(const Metadata *MD) {
2119 return MD->getMetadataID() == DIModuleKind;
2120 }
2121};
2122
Adrian Prantl1687e012016-11-14 22:09:18 +00002123/// Base class for template parameters.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002124class DITemplateParameter : public DINode {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002125protected:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002126 DITemplateParameter(LLVMContext &Context, unsigned ID, StorageType Storage,
Duncan P. N. Exon Smithbd33d372015-02-10 01:59:57 +00002127 unsigned Tag, ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002128 : DINode(Context, ID, Storage, Tag, Ops) {}
2129 ~DITemplateParameter() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002130
2131public:
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002132 StringRef getName() const { return getStringOperand(0); }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002133 DITypeRef getType() const { return DITypeRef(getRawType()); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002134
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002135 MDString *getRawName() const { return getOperandAs<MDString>(0); }
Duncan P. N. Exon Smith3ec5fa62015-04-06 19:03:45 +00002136 Metadata *getRawType() const { return getOperand(1); }
Duncan P. N. Exon Smith2847f382015-02-13 01:34:32 +00002137
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002138 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002139 return MD->getMetadataID() == DITemplateTypeParameterKind ||
2140 MD->getMetadataID() == DITemplateValueParameterKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002141 }
2142};
2143
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002144class DITemplateTypeParameter : public DITemplateParameter {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002145 friend class LLVMContextImpl;
2146 friend class MDNode;
2147
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002148 DITemplateTypeParameter(LLVMContext &Context, StorageType Storage,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002149 ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002150 : DITemplateParameter(Context, DITemplateTypeParameterKind, Storage,
Duncan P. N. Exon Smithbd33d372015-02-10 01:59:57 +00002151 dwarf::DW_TAG_template_type_parameter, Ops) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002152 ~DITemplateTypeParameter() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002153
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002154 static DITemplateTypeParameter *getImpl(LLVMContext &Context, StringRef Name,
2155 DITypeRef Type, StorageType Storage,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002156 bool ShouldCreate = true) {
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002157 return getImpl(Context, getCanonicalMDString(Context, Name), Type, Storage,
2158 ShouldCreate);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002159 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002160 static DITemplateTypeParameter *getImpl(LLVMContext &Context, MDString *Name,
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002161 Metadata *Type, StorageType Storage,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002162 bool ShouldCreate = true);
2163
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002164 TempDITemplateTypeParameter cloneImpl() const {
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002165 return getTemporary(getContext(), getName(), getType());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002166 }
2167
2168public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002169 DEFINE_MDNODE_GET(DITemplateTypeParameter, (StringRef Name, DITypeRef Type),
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002170 (Name, Type))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002171 DEFINE_MDNODE_GET(DITemplateTypeParameter, (MDString * Name, Metadata *Type),
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002172 (Name, Type))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002173
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002174 TempDITemplateTypeParameter clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002175
2176 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002177 return MD->getMetadataID() == DITemplateTypeParameterKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002178 }
2179};
2180
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002181class DITemplateValueParameter : public DITemplateParameter {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002182 friend class LLVMContextImpl;
2183 friend class MDNode;
2184
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002185 DITemplateValueParameter(LLVMContext &Context, StorageType Storage,
Duncan P. N. Exon Smithbd33d372015-02-10 01:59:57 +00002186 unsigned Tag, ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002187 : DITemplateParameter(Context, DITemplateValueParameterKind, Storage, Tag,
Duncan P. N. Exon Smithbd33d372015-02-10 01:59:57 +00002188 Ops) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002189 ~DITemplateValueParameter() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002190
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002191 static DITemplateValueParameter *getImpl(LLVMContext &Context, unsigned Tag,
2192 StringRef Name, DITypeRef Type,
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002193 Metadata *Value, StorageType Storage,
Duncan P. N. Exon Smithbd33d372015-02-10 01:59:57 +00002194 bool ShouldCreate = true) {
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002195 return getImpl(Context, Tag, getCanonicalMDString(Context, Name), Type,
2196 Value, Storage, ShouldCreate);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002197 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002198 static DITemplateValueParameter *getImpl(LLVMContext &Context, unsigned Tag,
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002199 MDString *Name, Metadata *Type,
2200 Metadata *Value, StorageType Storage,
Duncan P. N. Exon Smithbd33d372015-02-10 01:59:57 +00002201 bool ShouldCreate = true);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002202
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002203 TempDITemplateValueParameter cloneImpl() const {
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002204 return getTemporary(getContext(), getTag(), getName(), getType(),
2205 getValue());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002206 }
2207
2208public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002209 DEFINE_MDNODE_GET(DITemplateValueParameter, (unsigned Tag, StringRef Name,
2210 DITypeRef Type, Metadata *Value),
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002211 (Tag, Name, Type, Value))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002212 DEFINE_MDNODE_GET(DITemplateValueParameter, (unsigned Tag, MDString *Name,
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002213 Metadata *Type, Metadata *Value),
2214 (Tag, Name, Type, Value))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002215
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002216 TempDITemplateValueParameter clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith6873fea2015-02-17 23:10:13 +00002217
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002218 Metadata *getValue() const { return getOperand(2); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002219
2220 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002221 return MD->getMetadataID() == DITemplateValueParameterKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002222 }
2223};
2224
Adrian Prantl1687e012016-11-14 22:09:18 +00002225/// Base class for variables.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002226class DIVariable : public DINode {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002227 unsigned Line;
Victor Leschuka37660c2016-10-26 21:32:29 +00002228 uint32_t AlignInBits;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002229
2230protected:
Duncan P. N. Exon Smithed013cd2015-07-31 18:58:39 +00002231 DIVariable(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Line,
Victor Leschuka37660c2016-10-26 21:32:29 +00002232 ArrayRef<Metadata *> Ops, uint32_t AlignInBits = 0)
Victor Leschuk2ede1262016-10-20 00:13:12 +00002233 : DINode(C, ID, Storage, dwarf::DW_TAG_variable, Ops), Line(Line),
NAKAMURA Takumi78029842017-02-19 06:51:46 +00002234 AlignInBits(AlignInBits) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002235 ~DIVariable() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002236
2237public:
2238 unsigned getLine() const { return Line; }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002239 DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002240 StringRef getName() const { return getStringOperand(1); }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002241 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
2242 DITypeRef getType() const { return DITypeRef(getRawType()); }
Victor Leschuk3c989982016-10-26 11:59:03 +00002243 uint32_t getAlignInBits() const { return AlignInBits; }
2244 uint32_t getAlignInBytes() const { return getAlignInBits() / CHAR_BIT; }
Adrian Prantl3e0e1d02017-11-28 00:57:51 +00002245 /// Determines the size of the variable's type.
2246 Optional<uint64_t> getSizeInBits() const;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002247
Vedant Kumar6379a622018-07-06 17:32:39 +00002248 /// Return the signedness of this variable's type, or None if this type is
2249 /// neither signed nor unsigned.
2250 Optional<DIBasicType::Signedness> getSignedness() const {
2251 if (auto *BT = dyn_cast<DIBasicType>(getType().resolve()))
2252 return BT->getSignedness();
2253 return None;
2254 }
2255
Duncan P. N. Exon Smith50c065b2015-04-11 00:39:43 +00002256 StringRef getFilename() const {
2257 if (auto *F = getFile())
2258 return F->getFilename();
2259 return "";
2260 }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +00002261
Duncan P. N. Exon Smith50c065b2015-04-11 00:39:43 +00002262 StringRef getDirectory() const {
2263 if (auto *F = getFile())
2264 return F->getDirectory();
2265 return "";
2266 }
2267
Scott Linder16c7bda2018-02-23 23:01:06 +00002268 Optional<StringRef> getSource() const {
2269 if (auto *F = getFile())
2270 return F->getSource();
2271 return None;
2272 }
2273
Duncan P. N. Exon Smith3d2afaa2015-03-27 17:29:58 +00002274 Metadata *getRawScope() const { return getOperand(0); }
Duncan P. N. Exon Smithc8f810a2015-02-13 01:35:40 +00002275 MDString *getRawName() const { return getOperandAs<MDString>(1); }
Duncan P. N. Exon Smith3d2afaa2015-03-27 17:29:58 +00002276 Metadata *getRawFile() const { return getOperand(2); }
2277 Metadata *getRawType() const { return getOperand(3); }
Duncan P. N. Exon Smithc8f810a2015-02-13 01:35:40 +00002278
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002279 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002280 return MD->getMetadataID() == DILocalVariableKind ||
2281 MD->getMetadataID() == DIGlobalVariableKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002282 }
2283};
2284
Adrian Prantl1687e012016-11-14 22:09:18 +00002285/// DWARF expression.
Peter Collingbourned4135bb2016-09-13 01:12:59 +00002286///
2287/// This is (almost) a DWARF expression that modifies the location of a
2288/// variable, or the location of a single piece of a variable, or (when using
2289/// DW_OP_stack_value) is the constant variable value.
2290///
Peter Collingbourned4135bb2016-09-13 01:12:59 +00002291/// TODO: Co-allocate the expression elements.
2292/// TODO: Separate from MDNode, or otherwise drop Distinct and Temporary
2293/// storage types.
2294class DIExpression : public MDNode {
2295 friend class LLVMContextImpl;
2296 friend class MDNode;
2297
2298 std::vector<uint64_t> Elements;
2299
2300 DIExpression(LLVMContext &C, StorageType Storage, ArrayRef<uint64_t> Elements)
2301 : MDNode(C, DIExpressionKind, Storage, None),
2302 Elements(Elements.begin(), Elements.end()) {}
2303 ~DIExpression() = default;
2304
2305 static DIExpression *getImpl(LLVMContext &Context,
2306 ArrayRef<uint64_t> Elements, StorageType Storage,
2307 bool ShouldCreate = true);
2308
2309 TempDIExpression cloneImpl() const {
2310 return getTemporary(getContext(), getElements());
2311 }
2312
2313public:
2314 DEFINE_MDNODE_GET(DIExpression, (ArrayRef<uint64_t> Elements), (Elements))
2315
2316 TempDIExpression clone() const { return cloneImpl(); }
2317
2318 ArrayRef<uint64_t> getElements() const { return Elements; }
2319
2320 unsigned getNumElements() const { return Elements.size(); }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +00002321
Peter Collingbourned4135bb2016-09-13 01:12:59 +00002322 uint64_t getElement(unsigned I) const {
2323 assert(I < Elements.size() && "Index out of range");
2324 return Elements[I];
2325 }
2326
Adrian Prantlbceaaa92016-12-20 02:09:43 +00002327 /// Determine whether this represents a standalone constant value.
2328 bool isConstant() const;
2329
Eugene Zelenkod761e2c2017-05-15 21:57:41 +00002330 using element_iterator = ArrayRef<uint64_t>::iterator;
2331
Peter Collingbourned4135bb2016-09-13 01:12:59 +00002332 element_iterator elements_begin() const { return getElements().begin(); }
2333 element_iterator elements_end() const { return getElements().end(); }
2334
2335 /// A lightweight wrapper around an expression operand.
2336 ///
2337 /// TODO: Store arguments directly and change \a DIExpression to store a
2338 /// range of these.
2339 class ExprOperand {
Adrian Prantl72845a52016-11-08 20:48:38 +00002340 const uint64_t *Op = nullptr;
Peter Collingbourned4135bb2016-09-13 01:12:59 +00002341
2342 public:
Adrian Prantl72845a52016-11-08 20:48:38 +00002343 ExprOperand() = default;
Peter Collingbourned4135bb2016-09-13 01:12:59 +00002344 explicit ExprOperand(const uint64_t *Op) : Op(Op) {}
2345
2346 const uint64_t *get() const { return Op; }
2347
2348 /// Get the operand code.
2349 uint64_t getOp() const { return *Op; }
2350
2351 /// Get an argument to the operand.
2352 ///
2353 /// Never returns the operand itself.
2354 uint64_t getArg(unsigned I) const { return Op[I + 1]; }
2355
2356 unsigned getNumArgs() const { return getSize() - 1; }
2357
2358 /// Return the size of the operand.
2359 ///
2360 /// Return the number of elements in the operand (1 + args).
2361 unsigned getSize() const;
Vedant Kumar6379a622018-07-06 17:32:39 +00002362
2363 /// Append the elements of this operand to \p V.
2364 void appendToVector(SmallVectorImpl<uint64_t> &V) const {
Vedant Kumar71c7c432018-07-06 21:06:21 +00002365 V.append(get(), get() + getSize());
Vedant Kumar6379a622018-07-06 17:32:39 +00002366 }
Peter Collingbourned4135bb2016-09-13 01:12:59 +00002367 };
2368
2369 /// An iterator for expression operands.
2370 class expr_op_iterator
2371 : public std::iterator<std::input_iterator_tag, ExprOperand> {
2372 ExprOperand Op;
2373
2374 public:
Adrian Prantl54286bd2016-11-02 16:12:20 +00002375 expr_op_iterator() = default;
Peter Collingbourned4135bb2016-09-13 01:12:59 +00002376 explicit expr_op_iterator(element_iterator I) : Op(I) {}
2377
2378 element_iterator getBase() const { return Op.get(); }
2379 const ExprOperand &operator*() const { return Op; }
2380 const ExprOperand *operator->() const { return &Op; }
2381
2382 expr_op_iterator &operator++() {
2383 increment();
2384 return *this;
2385 }
2386 expr_op_iterator operator++(int) {
2387 expr_op_iterator T(*this);
2388 increment();
2389 return T;
2390 }
2391
2392 /// Get the next iterator.
2393 ///
2394 /// \a std::next() doesn't work because this is technically an
2395 /// input_iterator, but it's a perfectly valid operation. This is an
2396 /// accessor to provide the same functionality.
2397 expr_op_iterator getNext() const { return ++expr_op_iterator(*this); }
2398
2399 bool operator==(const expr_op_iterator &X) const {
2400 return getBase() == X.getBase();
2401 }
2402 bool operator!=(const expr_op_iterator &X) const {
2403 return getBase() != X.getBase();
2404 }
2405
2406 private:
2407 void increment() { Op = ExprOperand(getBase() + Op.getSize()); }
2408 };
2409
2410 /// Visit the elements via ExprOperand wrappers.
2411 ///
2412 /// These range iterators visit elements through \a ExprOperand wrappers.
2413 /// This is not guaranteed to be a valid range unless \a isValid() gives \c
2414 /// true.
2415 ///
2416 /// \pre \a isValid() gives \c true.
2417 /// @{
2418 expr_op_iterator expr_op_begin() const {
2419 return expr_op_iterator(elements_begin());
2420 }
2421 expr_op_iterator expr_op_end() const {
2422 return expr_op_iterator(elements_end());
2423 }
Adrian Prantl6825fb62017-04-18 01:21:53 +00002424 iterator_range<expr_op_iterator> expr_ops() const {
2425 return {expr_op_begin(), expr_op_end()};
2426 }
Peter Collingbourned4135bb2016-09-13 01:12:59 +00002427 /// @}
2428
2429 bool isValid() const;
2430
2431 static bool classof(const Metadata *MD) {
2432 return MD->getMetadataID() == DIExpressionKind;
2433 }
2434
Adrian Prantl6825fb62017-04-18 01:21:53 +00002435 /// Return whether the first element a DW_OP_deref.
Peter Collingbourned4135bb2016-09-13 01:12:59 +00002436 bool startsWithDeref() const {
2437 return getNumElements() > 0 && getElement(0) == dwarf::DW_OP_deref;
2438 }
Adrian Prantl49797ca2016-12-22 05:27:12 +00002439
2440 /// Holds the characteristics of one fragment of a larger variable.
2441 struct FragmentInfo {
2442 uint64_t SizeInBits;
2443 uint64_t OffsetInBits;
2444 };
2445
2446 /// Retrieve the details of this fragment expression.
2447 static Optional<FragmentInfo> getFragmentInfo(expr_op_iterator Start,
NAKAMURA Takumi78029842017-02-19 06:51:46 +00002448 expr_op_iterator End);
Adrian Prantl49797ca2016-12-22 05:27:12 +00002449
2450 /// Retrieve the details of this fragment expression.
2451 Optional<FragmentInfo> getFragmentInfo() const {
2452 return getFragmentInfo(expr_op_begin(), expr_op_end());
2453 }
2454
2455 /// Return whether this is a piece of an aggregate variable.
2456 bool isFragment() const { return getFragmentInfo().hasValue(); }
Andrew Ng03e35b62017-04-28 08:44:30 +00002457
2458 /// Append \p Ops with operations to apply the \p Offset.
2459 static void appendOffset(SmallVectorImpl<uint64_t> &Ops, int64_t Offset);
2460
Reid Klecknerb5fced72017-05-09 19:59:29 +00002461 /// If this is a constant offset, extract it. If there is no expression,
2462 /// return true with an offset of zero.
2463 bool extractIfOffset(int64_t &Offset) const;
2464
Adrian Prantl109b2362017-04-28 17:51:05 +00002465 /// Constants for DIExpression::prepend.
2466 enum { NoDeref = false, WithDeref = true, WithStackValue = true };
2467
Andrew Ng03e35b62017-04-28 08:44:30 +00002468 /// Prepend \p DIExpr with a deref and offset operation and optionally turn it
2469 /// into a stack value.
Fangrui Song3c1b5db2018-07-06 19:26:00 +00002470 static DIExpression *prepend(const DIExpression *Expr, bool DerefBefore,
Adrian Prantld1317012017-12-08 21:58:18 +00002471 int64_t Offset = 0, bool DerefAfter = false,
2472 bool StackValue = false);
Adrian Prantlb192b542017-08-30 20:04:17 +00002473
Vedant Kumar04386d82018-02-09 19:19:55 +00002474 /// Prepend \p DIExpr with the given opcodes and optionally turn it into a
2475 /// stack value.
Fangrui Song3c1b5db2018-07-06 19:26:00 +00002476 static DIExpression *prependOpcodes(const DIExpression *Expr,
Adrian Prantl210a29d2018-04-27 21:41:36 +00002477 SmallVectorImpl<uint64_t> &Ops,
2478 bool StackValue = false);
Vedant Kumar04386d82018-02-09 19:19:55 +00002479
Vedant Kumarb572f642018-07-26 20:56:53 +00002480 /// Append the opcodes \p Ops to \p DIExpr. Unlike \ref appendToStack, the
2481 /// returned expression is a stack value only if \p DIExpr is a stack value.
2482 /// If \p DIExpr describes a fragment, the returned expression will describe
2483 /// the same fragment.
2484 static DIExpression *append(const DIExpression *Expr, ArrayRef<uint64_t> Ops);
2485
Vedant Kumar6379a622018-07-06 17:32:39 +00002486 /// Convert \p DIExpr into a stack value if it isn't one already by appending
Vedant Kumar47f28442018-07-13 22:39:29 +00002487 /// DW_OP_deref if needed, and appending \p Ops to the resulting expression.
2488 /// If \p DIExpr describes a fragment, the returned expression will describe
2489 /// the same fragment.
Fangrui Song3c1b5db2018-07-06 19:26:00 +00002490 static DIExpression *appendToStack(const DIExpression *Expr,
Vedant Kumar6379a622018-07-06 17:32:39 +00002491 ArrayRef<uint64_t> Ops);
2492
Adrian Prantlb192b542017-08-30 20:04:17 +00002493 /// Create a DIExpression to describe one part of an aggregate variable that
2494 /// is fragmented across multiple Values. The DW_OP_LLVM_fragment operation
2495 /// will be appended to the elements of \c Expr. If \c Expr already contains
2496 /// a \c DW_OP_LLVM_fragment \c OffsetInBits is interpreted as an offset
2497 /// into the existing fragment.
2498 ///
2499 /// \param OffsetInBits Offset of the piece in bits.
2500 /// \param SizeInBits Size of the piece in bits.
Adrian Prantl25a09dd2017-11-07 00:45:34 +00002501 /// \return Creating a fragment expression may fail if \c Expr
2502 /// contains arithmetic operations that would be truncated.
2503 static Optional<DIExpression *>
2504 createFragmentExpression(const DIExpression *Expr, unsigned OffsetInBits,
2505 unsigned SizeInBits);
Bjorn Petterssona223f8152018-03-12 18:02:39 +00002506
2507 /// Determine the relative position of the fragments described by this
2508 /// DIExpression and \p Other.
2509 /// Returns -1 if this is entirely before Other, 0 if this and Other overlap,
2510 /// 1 if this is entirely after Other.
2511 int fragmentCmp(const DIExpression *Other) const {
2512 auto Fragment1 = *getFragmentInfo();
2513 auto Fragment2 = *Other->getFragmentInfo();
2514 unsigned l1 = Fragment1.OffsetInBits;
2515 unsigned l2 = Fragment2.OffsetInBits;
2516 unsigned r1 = l1 + Fragment1.SizeInBits;
2517 unsigned r2 = l2 + Fragment2.SizeInBits;
2518 if (r1 <= l2)
2519 return -1;
2520 else if (r2 <= l1)
2521 return 1;
2522 else
2523 return 0;
2524 }
2525
2526 /// Check if fragments overlap between this DIExpression and \p Other.
2527 bool fragmentsOverlap(const DIExpression *Other) const {
2528 if (!isFragment() || !Other->isFragment())
2529 return true;
2530 return fragmentCmp(Other) == 0;
2531 }
Peter Collingbourned4135bb2016-09-13 01:12:59 +00002532};
2533
Adrian Prantl1687e012016-11-14 22:09:18 +00002534/// Global variables.
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002535///
2536/// TODO: Remove DisplayName. It's always equal to Name.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002537class DIGlobalVariable : public DIVariable {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002538 friend class LLVMContextImpl;
2539 friend class MDNode;
2540
2541 bool IsLocalToUnit;
2542 bool IsDefinition;
2543
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002544 DIGlobalVariable(LLVMContext &C, StorageType Storage, unsigned Line,
Victor Leschuka37660c2016-10-26 21:32:29 +00002545 bool IsLocalToUnit, bool IsDefinition, uint32_t AlignInBits,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002546 ArrayRef<Metadata *> Ops)
Victor Leschuk2ede1262016-10-20 00:13:12 +00002547 : DIVariable(C, DIGlobalVariableKind, Storage, Line, Ops, AlignInBits),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002548 IsLocalToUnit(IsLocalToUnit), IsDefinition(IsDefinition) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002549 ~DIGlobalVariable() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002550
Matthew Vossf8ab35a2018-10-03 18:44:53 +00002551 static DIGlobalVariable *
2552 getImpl(LLVMContext &Context, DIScope *Scope, StringRef Name,
2553 StringRef LinkageName, DIFile *File, unsigned Line, DITypeRef Type,
2554 bool IsLocalToUnit, bool IsDefinition,
2555 DIDerivedType *StaticDataMemberDeclaration, MDTuple *TemplateParams,
2556 uint32_t AlignInBits, StorageType Storage, bool ShouldCreate = true) {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002557 return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
2558 getCanonicalMDString(Context, LinkageName), File, Line, Type,
Adrian Prantlbceaaa92016-12-20 02:09:43 +00002559 IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration,
Matthew Vossf8ab35a2018-10-03 18:44:53 +00002560 cast_or_null<Metadata>(TemplateParams), AlignInBits, Storage,
2561 ShouldCreate);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002562 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002563 static DIGlobalVariable *
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002564 getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
2565 MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type,
Adrian Prantlbceaaa92016-12-20 02:09:43 +00002566 bool IsLocalToUnit, bool IsDefinition,
Matthew Vossf8ab35a2018-10-03 18:44:53 +00002567 Metadata *StaticDataMemberDeclaration, Metadata *TemplateParams,
2568 uint32_t AlignInBits, StorageType Storage, bool ShouldCreate = true);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002569
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002570 TempDIGlobalVariable cloneImpl() const {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002571 return getTemporary(getContext(), getScope(), getName(), getLinkageName(),
2572 getFile(), getLine(), getType(), isLocalToUnit(),
Adrian Prantlbceaaa92016-12-20 02:09:43 +00002573 isDefinition(), getStaticDataMemberDeclaration(),
Matthew Vossf8ab35a2018-10-03 18:44:53 +00002574 getTemplateParams(), getAlignInBits());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002575 }
2576
2577public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002578 DEFINE_MDNODE_GET(DIGlobalVariable,
2579 (DIScope * Scope, StringRef Name, StringRef LinkageName,
2580 DIFile *File, unsigned Line, DITypeRef Type,
Victor Leschuk2ede1262016-10-20 00:13:12 +00002581 bool IsLocalToUnit, bool IsDefinition,
Victor Leschuk2ede1262016-10-20 00:13:12 +00002582 DIDerivedType *StaticDataMemberDeclaration,
Matthew Vossf8ab35a2018-10-03 18:44:53 +00002583 MDTuple *TemplateParams, uint32_t AlignInBits),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002584 (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
Matthew Vossf8ab35a2018-10-03 18:44:53 +00002585 IsDefinition, StaticDataMemberDeclaration, TemplateParams,
2586 AlignInBits))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002587 DEFINE_MDNODE_GET(DIGlobalVariable,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002588 (Metadata * Scope, MDString *Name, MDString *LinkageName,
2589 Metadata *File, unsigned Line, Metadata *Type,
Victor Leschuk2ede1262016-10-20 00:13:12 +00002590 bool IsLocalToUnit, bool IsDefinition,
Adrian Prantlbceaaa92016-12-20 02:09:43 +00002591 Metadata *StaticDataMemberDeclaration,
Matthew Vossf8ab35a2018-10-03 18:44:53 +00002592 Metadata *TemplateParams, uint32_t AlignInBits),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002593 (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
Matthew Vossf8ab35a2018-10-03 18:44:53 +00002594 IsDefinition, StaticDataMemberDeclaration, TemplateParams,
2595 AlignInBits))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002596
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002597 TempDIGlobalVariable clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith6873fea2015-02-17 23:10:13 +00002598
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002599 bool isLocalToUnit() const { return IsLocalToUnit; }
2600 bool isDefinition() const { return IsDefinition; }
2601 StringRef getDisplayName() const { return getStringOperand(4); }
2602 StringRef getLinkageName() const { return getStringOperand(5); }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002603 DIDerivedType *getStaticDataMemberDeclaration() const {
2604 return cast_or_null<DIDerivedType>(getRawStaticDataMemberDeclaration());
Duncan P. N. Exon Smith3d2afaa2015-03-27 17:29:58 +00002605 }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002606
Duncan P. N. Exon Smithc8f810a2015-02-13 01:35:40 +00002607 MDString *getRawLinkageName() const { return getOperandAs<MDString>(5); }
Adrian Prantlbceaaa92016-12-20 02:09:43 +00002608 Metadata *getRawStaticDataMemberDeclaration() const { return getOperand(6); }
Matthew Vossf8ab35a2018-10-03 18:44:53 +00002609 Metadata *getRawTemplateParams() const { return getOperand(7); }
2610 MDTuple *getTemplateParams() const { return getOperandAs<MDTuple>(7); }
Duncan P. N. Exon Smithc8f810a2015-02-13 01:35:40 +00002611
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002612 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002613 return MD->getMetadataID() == DIGlobalVariableKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002614 }
2615};
2616
Adrian Prantl1687e012016-11-14 22:09:18 +00002617/// Local variable.
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002618///
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002619/// TODO: Split up flags.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002620class DILocalVariable : public DIVariable {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002621 friend class LLVMContextImpl;
2622 friend class MDNode;
2623
Davide Italianoeb6bb3e2016-04-16 02:27:56 +00002624 unsigned Arg : 16;
Leny Kholodov5fcc4182016-09-06 10:46:28 +00002625 DIFlags Flags;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002626
Duncan P. N. Exon Smithed013cd2015-07-31 18:58:39 +00002627 DILocalVariable(LLVMContext &C, StorageType Storage, unsigned Line,
Victor Leschuka37660c2016-10-26 21:32:29 +00002628 unsigned Arg, DIFlags Flags, uint32_t AlignInBits,
Victor Leschuk2ede1262016-10-20 00:13:12 +00002629 ArrayRef<Metadata *> Ops)
2630 : DIVariable(C, DILocalVariableKind, Storage, Line, Ops, AlignInBits),
2631 Arg(Arg), Flags(Flags) {
Davide Italiano0d2ef012016-04-16 03:23:48 +00002632 assert(Arg < (1 << 16) && "DILocalVariable: Arg out of range");
Davide Italianoeb6bb3e2016-04-16 02:27:56 +00002633 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002634 ~DILocalVariable() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002635
Duncan P. N. Exon Smithed013cd2015-07-31 18:58:39 +00002636 static DILocalVariable *getImpl(LLVMContext &Context, DIScope *Scope,
2637 StringRef Name, DIFile *File, unsigned Line,
Leny Kholodov5fcc4182016-09-06 10:46:28 +00002638 DITypeRef Type, unsigned Arg, DIFlags Flags,
Victor Leschuka37660c2016-10-26 21:32:29 +00002639 uint32_t AlignInBits, StorageType Storage,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002640 bool ShouldCreate = true) {
Duncan P. N. Exon Smithed013cd2015-07-31 18:58:39 +00002641 return getImpl(Context, Scope, getCanonicalMDString(Context, Name), File,
Victor Leschuk2ede1262016-10-20 00:13:12 +00002642 Line, Type, Arg, Flags, AlignInBits, Storage, ShouldCreate);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002643 }
Duncan P. N. Exon Smithed013cd2015-07-31 18:58:39 +00002644 static DILocalVariable *getImpl(LLVMContext &Context, Metadata *Scope,
2645 MDString *Name, Metadata *File, unsigned Line,
Leny Kholodov5fcc4182016-09-06 10:46:28 +00002646 Metadata *Type, unsigned Arg, DIFlags Flags,
Victor Leschuka37660c2016-10-26 21:32:29 +00002647 uint32_t AlignInBits, StorageType Storage,
Duncan P. N. Exon Smithed013cd2015-07-31 18:58:39 +00002648 bool ShouldCreate = true);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002649
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002650 TempDILocalVariable cloneImpl() const {
Duncan P. N. Exon Smithed013cd2015-07-31 18:58:39 +00002651 return getTemporary(getContext(), getScope(), getName(), getFile(),
Victor Leschuk2ede1262016-10-20 00:13:12 +00002652 getLine(), getType(), getArg(), getFlags(),
2653 getAlignInBits());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002654 }
2655
2656public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002657 DEFINE_MDNODE_GET(DILocalVariable,
Duncan P. N. Exon Smithed013cd2015-07-31 18:58:39 +00002658 (DILocalScope * Scope, StringRef Name, DIFile *File,
Leny Kholodov40c62352016-09-06 17:03:02 +00002659 unsigned Line, DITypeRef Type, unsigned Arg,
Victor Leschuka37660c2016-10-26 21:32:29 +00002660 DIFlags Flags, uint32_t AlignInBits),
Victor Leschuk2ede1262016-10-20 00:13:12 +00002661 (Scope, Name, File, Line, Type, Arg, Flags, AlignInBits))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002662 DEFINE_MDNODE_GET(DILocalVariable,
Duncan P. N. Exon Smithed013cd2015-07-31 18:58:39 +00002663 (Metadata * Scope, MDString *Name, Metadata *File,
Leny Kholodov40c62352016-09-06 17:03:02 +00002664 unsigned Line, Metadata *Type, unsigned Arg,
Victor Leschuka37660c2016-10-26 21:32:29 +00002665 DIFlags Flags, uint32_t AlignInBits),
Victor Leschuk2ede1262016-10-20 00:13:12 +00002666 (Scope, Name, File, Line, Type, Arg, Flags, AlignInBits))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002667
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002668 TempDILocalVariable clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith6873fea2015-02-17 23:10:13 +00002669
Adrian Prantl1687e012016-11-14 22:09:18 +00002670 /// Get the local scope for this variable.
Duncan P. N. Exon Smith3d2afaa2015-03-27 17:29:58 +00002671 ///
2672 /// Variables must be defined in a local scope.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002673 DILocalScope *getScope() const {
2674 return cast<DILocalScope>(DIVariable::getScope());
Duncan P. N. Exon Smith3d2afaa2015-03-27 17:29:58 +00002675 }
2676
Duncan P. N. Exon Smithed013cd2015-07-31 18:58:39 +00002677 bool isParameter() const { return Arg; }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002678 unsigned getArg() const { return Arg; }
Leny Kholodov5fcc4182016-09-06 10:46:28 +00002679 DIFlags getFlags() const { return Flags; }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002680
Duncan P. N. Exon Smithbd42d5d2015-04-07 03:55:30 +00002681 bool isArtificial() const { return getFlags() & FlagArtificial; }
2682 bool isObjectPointer() const { return getFlags() & FlagObjectPointer; }
2683
Adrian Prantl1687e012016-11-14 22:09:18 +00002684 /// Check that a location is valid for this variable.
Duncan P. N. Exon Smith3bef6a32015-04-03 19:20:26 +00002685 ///
Duncan P. N. Exon Smithf17f34e2015-04-15 22:15:46 +00002686 /// Check that \c DL exists, is in the same subprogram, and has the same
Benjamin Kramerdf005cb2015-08-08 18:27:36 +00002687 /// inlined-at location as \c this. (Otherwise, it's not a valid attachment
Duncan P. N. Exon Smithf17f34e2015-04-15 22:15:46 +00002688 /// to a \a DbgInfoIntrinsic.)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002689 bool isValidLocationForIntrinsic(const DILocation *DL) const {
Duncan P. N. Exon Smith62e0f452015-04-15 22:29:27 +00002690 return DL && getScope()->getSubprogram() == DL->getScope()->getSubprogram();
Duncan P. N. Exon Smith3bef6a32015-04-03 19:20:26 +00002691 }
2692
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002693 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002694 return MD->getMetadataID() == DILocalVariableKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002695 }
2696};
2697
Shiva Chen2c864552018-05-09 02:40:45 +00002698/// Label.
2699///
2700class DILabel : public DINode {
2701 friend class LLVMContextImpl;
2702 friend class MDNode;
2703
2704 unsigned Line;
2705
2706 DILabel(LLVMContext &C, StorageType Storage, unsigned Line,
2707 ArrayRef<Metadata *> Ops)
2708 : DINode(C, DILabelKind, Storage, dwarf::DW_TAG_label, Ops), Line(Line) {}
2709 ~DILabel() = default;
2710
2711 static DILabel *getImpl(LLVMContext &Context, DIScope *Scope,
2712 StringRef Name, DIFile *File, unsigned Line,
2713 StorageType Storage,
2714 bool ShouldCreate = true) {
2715 return getImpl(Context, Scope, getCanonicalMDString(Context, Name), File,
2716 Line, Storage, ShouldCreate);
2717 }
2718 static DILabel *getImpl(LLVMContext &Context, Metadata *Scope,
2719 MDString *Name, Metadata *File, unsigned Line,
2720 StorageType Storage,
2721 bool ShouldCreate = true);
2722
2723 TempDILabel cloneImpl() const {
2724 return getTemporary(getContext(), getScope(), getName(), getFile(),
2725 getLine());
2726 }
2727
2728public:
2729 DEFINE_MDNODE_GET(DILabel,
2730 (DILocalScope * Scope, StringRef Name, DIFile *File,
2731 unsigned Line),
2732 (Scope, Name, File, Line))
2733 DEFINE_MDNODE_GET(DILabel,
2734 (Metadata * Scope, MDString *Name, Metadata *File,
2735 unsigned Line),
2736 (Scope, Name, File, Line))
2737
2738 TempDILabel clone() const { return cloneImpl(); }
2739
2740 /// Get the local scope for this label.
2741 ///
2742 /// Labels must be defined in a local scope.
2743 DILocalScope *getScope() const {
2744 return cast_or_null<DILocalScope>(getRawScope());
2745 }
2746 unsigned getLine() const { return Line; }
2747 StringRef getName() const { return getStringOperand(1); }
2748 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
2749
2750 Metadata *getRawScope() const { return getOperand(0); }
2751 MDString *getRawName() const { return getOperandAs<MDString>(1); }
2752 Metadata *getRawFile() const { return getOperand(2); }
2753
2754 /// Check that a location is valid for this label.
2755 ///
2756 /// Check that \c DL exists, is in the same subprogram, and has the same
2757 /// inlined-at location as \c this. (Otherwise, it's not a valid attachment
2758 /// to a \a DbgInfoIntrinsic.)
2759 bool isValidLocationForIntrinsic(const DILocation *DL) const {
2760 return DL && getScope()->getSubprogram() == DL->getScope()->getSubprogram();
2761 }
2762
2763 static bool classof(const Metadata *MD) {
2764 return MD->getMetadataID() == DILabelKind;
2765 }
2766};
2767
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002768class DIObjCProperty : public DINode {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002769 friend class LLVMContextImpl;
2770 friend class MDNode;
2771
2772 unsigned Line;
2773 unsigned Attributes;
2774
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002775 DIObjCProperty(LLVMContext &C, StorageType Storage, unsigned Line,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002776 unsigned Attributes, ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002777 : DINode(C, DIObjCPropertyKind, Storage, dwarf::DW_TAG_APPLE_property,
2778 Ops),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002779 Line(Line), Attributes(Attributes) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002780 ~DIObjCProperty() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002781
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002782 static DIObjCProperty *
2783 getImpl(LLVMContext &Context, StringRef Name, DIFile *File, unsigned Line,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002784 StringRef GetterName, StringRef SetterName, unsigned Attributes,
Adrian Prantl8ff53b32015-06-15 23:18:03 +00002785 DITypeRef Type, StorageType Storage, bool ShouldCreate = true) {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002786 return getImpl(Context, getCanonicalMDString(Context, Name), File, Line,
2787 getCanonicalMDString(Context, GetterName),
2788 getCanonicalMDString(Context, SetterName), Attributes, Type,
2789 Storage, ShouldCreate);
2790 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002791 static DIObjCProperty *getImpl(LLVMContext &Context, MDString *Name,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002792 Metadata *File, unsigned Line,
2793 MDString *GetterName, MDString *SetterName,
2794 unsigned Attributes, Metadata *Type,
2795 StorageType Storage, bool ShouldCreate = true);
2796
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002797 TempDIObjCProperty cloneImpl() const {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002798 return getTemporary(getContext(), getName(), getFile(), getLine(),
2799 getGetterName(), getSetterName(), getAttributes(),
2800 getType());
2801 }
2802
2803public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002804 DEFINE_MDNODE_GET(DIObjCProperty,
2805 (StringRef Name, DIFile *File, unsigned Line,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002806 StringRef GetterName, StringRef SetterName,
Adrian Prantl8ff53b32015-06-15 23:18:03 +00002807 unsigned Attributes, DITypeRef Type),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002808 (Name, File, Line, GetterName, SetterName, Attributes,
2809 Type))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002810 DEFINE_MDNODE_GET(DIObjCProperty,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002811 (MDString * Name, Metadata *File, unsigned Line,
2812 MDString *GetterName, MDString *SetterName,
2813 unsigned Attributes, Metadata *Type),
2814 (Name, File, Line, GetterName, SetterName, Attributes,
2815 Type))
2816
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002817 TempDIObjCProperty clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith6873fea2015-02-17 23:10:13 +00002818
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002819 unsigned getLine() const { return Line; }
2820 unsigned getAttributes() const { return Attributes; }
2821 StringRef getName() const { return getStringOperand(0); }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002822 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002823 StringRef getGetterName() const { return getStringOperand(2); }
2824 StringRef getSetterName() const { return getStringOperand(3); }
Adrian Prantl8ff53b32015-06-15 23:18:03 +00002825 DITypeRef getType() const { return DITypeRef(getRawType()); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002826
Duncan P. N. Exon Smith50c065b2015-04-11 00:39:43 +00002827 StringRef getFilename() const {
2828 if (auto *F = getFile())
2829 return F->getFilename();
2830 return "";
2831 }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +00002832
Duncan P. N. Exon Smith50c065b2015-04-11 00:39:43 +00002833 StringRef getDirectory() const {
2834 if (auto *F = getFile())
2835 return F->getDirectory();
2836 return "";
2837 }
2838
Scott Linder16c7bda2018-02-23 23:01:06 +00002839 Optional<StringRef> getSource() const {
2840 if (auto *F = getFile())
2841 return F->getSource();
2842 return None;
2843 }
2844
Duncan P. N. Exon Smithd45ce962015-02-13 01:43:22 +00002845 MDString *getRawName() const { return getOperandAs<MDString>(0); }
Duncan P. N. Exon Smithf9b47752015-03-30 17:21:38 +00002846 Metadata *getRawFile() const { return getOperand(1); }
Duncan P. N. Exon Smithd45ce962015-02-13 01:43:22 +00002847 MDString *getRawGetterName() const { return getOperandAs<MDString>(2); }
2848 MDString *getRawSetterName() const { return getOperandAs<MDString>(3); }
Duncan P. N. Exon Smithf9b47752015-03-30 17:21:38 +00002849 Metadata *getRawType() const { return getOperand(4); }
Duncan P. N. Exon Smithd45ce962015-02-13 01:43:22 +00002850
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002851 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002852 return MD->getMetadataID() == DIObjCPropertyKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002853 }
2854};
2855
Adrian Prantl1687e012016-11-14 22:09:18 +00002856/// An imported module (C++ using directive or similar).
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002857class DIImportedEntity : public DINode {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002858 friend class LLVMContextImpl;
2859 friend class MDNode;
2860
2861 unsigned Line;
2862
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002863 DIImportedEntity(LLVMContext &C, StorageType Storage, unsigned Tag,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002864 unsigned Line, ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002865 : DINode(C, DIImportedEntityKind, Storage, Tag, Ops), Line(Line) {}
2866 ~DIImportedEntity() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002867
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002868 static DIImportedEntity *getImpl(LLVMContext &Context, unsigned Tag,
2869 DIScope *Scope, DINodeRef Entity,
Adrian Prantld63bfd22017-07-19 00:09:54 +00002870 DIFile *File, unsigned Line, StringRef Name,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002871 StorageType Storage,
2872 bool ShouldCreate = true) {
Adrian Prantld63bfd22017-07-19 00:09:54 +00002873 return getImpl(Context, Tag, Scope, Entity, File, Line,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002874 getCanonicalMDString(Context, Name), Storage, ShouldCreate);
2875 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002876 static DIImportedEntity *getImpl(LLVMContext &Context, unsigned Tag,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002877 Metadata *Scope, Metadata *Entity,
Adrian Prantld63bfd22017-07-19 00:09:54 +00002878 Metadata *File, unsigned Line,
2879 MDString *Name, StorageType Storage,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002880 bool ShouldCreate = true);
2881
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002882 TempDIImportedEntity cloneImpl() const {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002883 return getTemporary(getContext(), getTag(), getScope(), getEntity(),
Adrian Prantld63bfd22017-07-19 00:09:54 +00002884 getFile(), getLine(), getName());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002885 }
2886
2887public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002888 DEFINE_MDNODE_GET(DIImportedEntity,
2889 (unsigned Tag, DIScope *Scope, DINodeRef Entity,
Adrian Prantld63bfd22017-07-19 00:09:54 +00002890 DIFile *File, unsigned Line, StringRef Name = ""),
2891 (Tag, Scope, Entity, File, Line, Name))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002892 DEFINE_MDNODE_GET(DIImportedEntity,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002893 (unsigned Tag, Metadata *Scope, Metadata *Entity,
Adrian Prantld63bfd22017-07-19 00:09:54 +00002894 Metadata *File, unsigned Line, MDString *Name),
2895 (Tag, Scope, Entity, File, Line, Name))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002896
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002897 TempDIImportedEntity clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002898
2899 unsigned getLine() const { return Line; }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002900 DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
2901 DINodeRef getEntity() const { return DINodeRef(getRawEntity()); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002902 StringRef getName() const { return getStringOperand(2); }
Adrian Prantld63bfd22017-07-19 00:09:54 +00002903 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002904
Duncan P. N. Exon Smithf9b47752015-03-30 17:21:38 +00002905 Metadata *getRawScope() const { return getOperand(0); }
2906 Metadata *getRawEntity() const { return getOperand(1); }
Duncan P. N. Exon Smith1c931162015-02-13 01:46:02 +00002907 MDString *getRawName() const { return getOperandAs<MDString>(2); }
Adrian Prantld63bfd22017-07-19 00:09:54 +00002908 Metadata *getRawFile() const { return getOperand(3); }
Duncan P. N. Exon Smith1c931162015-02-13 01:46:02 +00002909
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002910 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002911 return MD->getMetadataID() == DIImportedEntityKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002912 }
2913};
2914
Adrian Prantlbceaaa92016-12-20 02:09:43 +00002915/// A pair of DIGlobalVariable and DIExpression.
2916class DIGlobalVariableExpression : public MDNode {
2917 friend class LLVMContextImpl;
2918 friend class MDNode;
2919
2920 DIGlobalVariableExpression(LLVMContext &C, StorageType Storage,
2921 ArrayRef<Metadata *> Ops)
2922 : MDNode(C, DIGlobalVariableExpressionKind, Storage, Ops) {}
2923 ~DIGlobalVariableExpression() = default;
2924
2925 static DIGlobalVariableExpression *
2926 getImpl(LLVMContext &Context, Metadata *Variable, Metadata *Expression,
2927 StorageType Storage, bool ShouldCreate = true);
2928
2929 TempDIGlobalVariableExpression cloneImpl() const {
2930 return getTemporary(getContext(), getVariable(), getExpression());
2931 }
2932
2933public:
2934 DEFINE_MDNODE_GET(DIGlobalVariableExpression,
2935 (Metadata * Variable, Metadata *Expression),
2936 (Variable, Expression))
2937
2938 TempDIGlobalVariableExpression clone() const { return cloneImpl(); }
2939
2940 Metadata *getRawVariable() const { return getOperand(0); }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +00002941
Adrian Prantlbceaaa92016-12-20 02:09:43 +00002942 DIGlobalVariable *getVariable() const {
2943 return cast_or_null<DIGlobalVariable>(getRawVariable());
2944 }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +00002945
Adrian Prantlbceaaa92016-12-20 02:09:43 +00002946 Metadata *getRawExpression() const { return getOperand(1); }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +00002947
Adrian Prantlbceaaa92016-12-20 02:09:43 +00002948 DIExpression *getExpression() const {
Adrian Prantl05782212017-08-30 18:06:51 +00002949 return cast<DIExpression>(getRawExpression());
Adrian Prantlbceaaa92016-12-20 02:09:43 +00002950 }
2951
2952 static bool classof(const Metadata *MD) {
2953 return MD->getMetadataID() == DIGlobalVariableExpressionKind;
2954 }
2955};
2956
Adrian Prantl1687e012016-11-14 22:09:18 +00002957/// Macro Info DWARF-like metadata node.
Amjad Abouda9bcf162015-12-10 12:56:35 +00002958///
2959/// A metadata node with a DWARF macro info (i.e., a constant named
Zachary Turner264b5d92017-06-07 03:48:56 +00002960/// \c DW_MACINFO_*, defined in llvm/BinaryFormat/Dwarf.h). Called \a
2961/// DIMacroNode
Amjad Abouda9bcf162015-12-10 12:56:35 +00002962/// because it's potentially used for non-DWARF output.
2963class DIMacroNode : public MDNode {
2964 friend class LLVMContextImpl;
2965 friend class MDNode;
2966
2967protected:
2968 DIMacroNode(LLVMContext &C, unsigned ID, StorageType Storage, unsigned MIType,
2969 ArrayRef<Metadata *> Ops1, ArrayRef<Metadata *> Ops2 = None)
2970 : MDNode(C, ID, Storage, Ops1, Ops2) {
2971 assert(MIType < 1u << 16);
2972 SubclassData16 = MIType;
2973 }
2974 ~DIMacroNode() = default;
2975
2976 template <class Ty> Ty *getOperandAs(unsigned I) const {
2977 return cast_or_null<Ty>(getOperand(I));
2978 }
2979
2980 StringRef getStringOperand(unsigned I) const {
2981 if (auto *S = getOperandAs<MDString>(I))
2982 return S->getString();
2983 return StringRef();
2984 }
2985
2986 static MDString *getCanonicalMDString(LLVMContext &Context, StringRef S) {
2987 if (S.empty())
2988 return nullptr;
2989 return MDString::get(Context, S);
2990 }
2991
2992public:
2993 unsigned getMacinfoType() const { return SubclassData16; }
2994
2995 static bool classof(const Metadata *MD) {
2996 switch (MD->getMetadataID()) {
2997 default:
2998 return false;
2999 case DIMacroKind:
3000 case DIMacroFileKind:
3001 return true;
3002 }
3003 }
3004};
3005
3006class DIMacro : public DIMacroNode {
3007 friend class LLVMContextImpl;
3008 friend class MDNode;
3009
3010 unsigned Line;
3011
3012 DIMacro(LLVMContext &C, StorageType Storage, unsigned MIType, unsigned Line,
3013 ArrayRef<Metadata *> Ops)
3014 : DIMacroNode(C, DIMacroKind, Storage, MIType, Ops), Line(Line) {}
3015 ~DIMacro() = default;
3016
3017 static DIMacro *getImpl(LLVMContext &Context, unsigned MIType, unsigned Line,
3018 StringRef Name, StringRef Value, StorageType Storage,
3019 bool ShouldCreate = true) {
3020 return getImpl(Context, MIType, Line, getCanonicalMDString(Context, Name),
3021 getCanonicalMDString(Context, Value), Storage, ShouldCreate);
3022 }
3023 static DIMacro *getImpl(LLVMContext &Context, unsigned MIType, unsigned Line,
3024 MDString *Name, MDString *Value, StorageType Storage,
3025 bool ShouldCreate = true);
3026
3027 TempDIMacro cloneImpl() const {
3028 return getTemporary(getContext(), getMacinfoType(), getLine(), getName(),
3029 getValue());
3030 }
3031
3032public:
3033 DEFINE_MDNODE_GET(DIMacro, (unsigned MIType, unsigned Line, StringRef Name,
3034 StringRef Value = ""),
3035 (MIType, Line, Name, Value))
3036 DEFINE_MDNODE_GET(DIMacro, (unsigned MIType, unsigned Line, MDString *Name,
3037 MDString *Value),
3038 (MIType, Line, Name, Value))
3039
3040 TempDIMacro clone() const { return cloneImpl(); }
3041
3042 unsigned getLine() const { return Line; }
3043
3044 StringRef getName() const { return getStringOperand(0); }
3045 StringRef getValue() const { return getStringOperand(1); }
3046
3047 MDString *getRawName() const { return getOperandAs<MDString>(0); }
3048 MDString *getRawValue() const { return getOperandAs<MDString>(1); }
3049
3050 static bool classof(const Metadata *MD) {
3051 return MD->getMetadataID() == DIMacroKind;
3052 }
3053};
3054
3055class DIMacroFile : public DIMacroNode {
3056 friend class LLVMContextImpl;
3057 friend class MDNode;
3058
3059 unsigned Line;
3060
3061 DIMacroFile(LLVMContext &C, StorageType Storage, unsigned MIType,
3062 unsigned Line, ArrayRef<Metadata *> Ops)
3063 : DIMacroNode(C, DIMacroFileKind, Storage, MIType, Ops), Line(Line) {}
3064 ~DIMacroFile() = default;
3065
3066 static DIMacroFile *getImpl(LLVMContext &Context, unsigned MIType,
3067 unsigned Line, DIFile *File,
3068 DIMacroNodeArray Elements, StorageType Storage,
3069 bool ShouldCreate = true) {
3070 return getImpl(Context, MIType, Line, static_cast<Metadata *>(File),
3071 Elements.get(), Storage, ShouldCreate);
3072 }
3073
3074 static DIMacroFile *getImpl(LLVMContext &Context, unsigned MIType,
3075 unsigned Line, Metadata *File, Metadata *Elements,
3076 StorageType Storage, bool ShouldCreate = true);
3077
3078 TempDIMacroFile cloneImpl() const {
3079 return getTemporary(getContext(), getMacinfoType(), getLine(), getFile(),
3080 getElements());
3081 }
3082
3083public:
3084 DEFINE_MDNODE_GET(DIMacroFile, (unsigned MIType, unsigned Line, DIFile *File,
3085 DIMacroNodeArray Elements),
3086 (MIType, Line, File, Elements))
3087 DEFINE_MDNODE_GET(DIMacroFile, (unsigned MIType, unsigned Line,
3088 Metadata *File, Metadata *Elements),
3089 (MIType, Line, File, Elements))
3090
3091 TempDIMacroFile clone() const { return cloneImpl(); }
3092
3093 void replaceElements(DIMacroNodeArray Elements) {
3094#ifndef NDEBUG
3095 for (DIMacroNode *Op : getElements())
David Majnemer42531262016-08-12 03:55:06 +00003096 assert(is_contained(Elements->operands(), Op) &&
Amjad Abouda9bcf162015-12-10 12:56:35 +00003097 "Lost a macro node during macro node list replacement");
3098#endif
3099 replaceOperandWith(1, Elements.get());
3100 }
3101
3102 unsigned getLine() const { return Line; }
3103 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
3104
3105 DIMacroNodeArray getElements() const {
3106 return cast_or_null<MDTuple>(getRawElements());
3107 }
3108
3109 Metadata *getRawFile() const { return getOperand(0); }
3110 Metadata *getRawElements() const { return getOperand(1); }
3111
3112 static bool classof(const Metadata *MD) {
3113 return MD->getMetadataID() == DIMacroFileKind;
3114 }
3115};
3116
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +00003117} // end namespace llvm
3118
Duncan P. N. Exon Smith61e62a52015-02-02 19:55:21 +00003119#undef DEFINE_MDNODE_GET_UNPACK_IMPL
3120#undef DEFINE_MDNODE_GET_UNPACK
3121#undef DEFINE_MDNODE_GET
3122
Eugene Zelenko1aa40f42016-11-23 22:25:16 +00003123#endif // LLVM_IR_DEBUGINFOMETADATA_H