blob: 652c90c7a90b9c3a1d579fa4d166983d7cd0a609 [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"
Eugene Zelenkod761e2c2017-05-15 21:57:41 +000021#include "llvm/ADT/STLExtras.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000022#include "llvm/ADT/SmallVector.h"
Eugene Zelenko1aa40f42016-11-23 22:25:16 +000023#include "llvm/ADT/StringRef.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000024#include "llvm/ADT/iterator_range.h"
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +000025#include "llvm/IR/Metadata.h"
Eugene Zelenko1aa40f42016-11-23 22:25:16 +000026#include "llvm/Support/Casting.h"
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +000027#include "llvm/Support/Dwarf.h"
Eugene Zelenko1aa40f42016-11-23 22:25:16 +000028#include <cassert>
29#include <climits>
30#include <cstddef>
31#include <cstdint>
32#include <iterator>
33#include <type_traits>
34#include <vector>
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +000035
Duncan P. N. Exon Smith61e62a52015-02-02 19:55:21 +000036// Helper macros for defining get() overrides.
37#define DEFINE_MDNODE_GET_UNPACK_IMPL(...) __VA_ARGS__
38#define DEFINE_MDNODE_GET_UNPACK(ARGS) DEFINE_MDNODE_GET_UNPACK_IMPL ARGS
Duncan P. N. Exon Smith55ca9642015-08-03 17:26:41 +000039#define DEFINE_MDNODE_GET_DISTINCT_TEMPORARY(CLASS, FORMAL, ARGS) \
Duncan P. N. Exon Smith61e62a52015-02-02 19:55:21 +000040 static CLASS *getDistinct(LLVMContext &Context, \
41 DEFINE_MDNODE_GET_UNPACK(FORMAL)) { \
42 return getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Distinct); \
43 } \
44 static Temp##CLASS getTemporary(LLVMContext &Context, \
45 DEFINE_MDNODE_GET_UNPACK(FORMAL)) { \
46 return Temp##CLASS( \
47 getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Temporary)); \
48 }
Duncan P. N. Exon Smith55ca9642015-08-03 17:26:41 +000049#define DEFINE_MDNODE_GET(CLASS, FORMAL, ARGS) \
50 static CLASS *get(LLVMContext &Context, DEFINE_MDNODE_GET_UNPACK(FORMAL)) { \
51 return getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Uniqued); \
52 } \
53 static CLASS *getIfExists(LLVMContext &Context, \
54 DEFINE_MDNODE_GET_UNPACK(FORMAL)) { \
55 return getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Uniqued, \
56 /* ShouldCreate */ false); \
57 } \
58 DEFINE_MDNODE_GET_DISTINCT_TEMPORARY(CLASS, FORMAL, ARGS)
Duncan P. N. Exon Smith61e62a52015-02-02 19:55:21 +000059
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +000060namespace llvm {
61
Duncan P. N. Exon Smitha59d3e52016-04-23 21:08:00 +000062/// Holds a subclass of DINode.
Duncan P. N. Exon Smith930f3882015-04-06 18:02:43 +000063///
Duncan P. N. Exon Smitha59d3e52016-04-23 21:08:00 +000064/// FIXME: This class doesn't currently make much sense. Previously it was a
65/// union beteen MDString (for ODR-uniqued types) and things like DIType. To
66/// support CodeView work, it wasn't deleted outright when MDString-based type
67/// references were deleted; we'll soon need a similar concept for CodeView
68/// DITypeIndex.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +000069template <class T> class TypedDINodeRef {
Duncan P. N. Exon Smith930f3882015-04-06 18:02:43 +000070 const Metadata *MD = nullptr;
71
72public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +000073 TypedDINodeRef() = default;
74 TypedDINodeRef(std::nullptr_t) {}
Duncan P. N. Exon Smitha59d3e52016-04-23 21:08:00 +000075 TypedDINodeRef(const T *MD) : MD(MD) {}
Duncan P. N. Exon Smith930f3882015-04-06 18:02:43 +000076
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +000077 explicit TypedDINodeRef(const Metadata *MD) : MD(MD) {
Duncan P. N. Exon Smitha59d3e52016-04-23 21:08:00 +000078 assert((!MD || isa<T>(MD)) && "Expected valid type ref");
Duncan P. N. Exon Smith930f3882015-04-06 18:02:43 +000079 }
80
81 template <class U>
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +000082 TypedDINodeRef(
83 const TypedDINodeRef<U> &X,
Duncan P. N. Exon Smith930f3882015-04-06 18:02:43 +000084 typename std::enable_if<std::is_convertible<U *, T *>::value>::type * =
85 nullptr)
86 : MD(X) {}
87
88 operator Metadata *() const { return const_cast<Metadata *>(MD); }
89
Duncan P. N. Exon Smitha59d3e52016-04-23 21:08:00 +000090 T *resolve() const { return const_cast<T *>(cast_or_null<T>(MD)); }
91
Hans Wennborg13958b72015-07-22 20:46:11 +000092 bool operator==(const TypedDINodeRef<T> &X) const { return MD == X.MD; }
93 bool operator!=(const TypedDINodeRef<T> &X) const { return MD != X.MD; }
Duncan P. N. Exon Smith930f3882015-04-06 18:02:43 +000094};
95
Eugene Zelenkod761e2c2017-05-15 21:57:41 +000096using DINodeRef = TypedDINodeRef<DINode>;
97using DIScopeRef = TypedDINodeRef<DIScope>;
98using DITypeRef = TypedDINodeRef<DIType>;
Duncan P. N. Exon Smith930f3882015-04-06 18:02:43 +000099
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000100class DITypeRefArray {
Duncan P. N. Exon Smith62e93622015-04-06 19:48:50 +0000101 const MDTuple *N = nullptr;
102
103public:
Duncan P. N. Exon Smith0660bcd2015-08-28 21:38:24 +0000104 DITypeRefArray() = default;
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000105 DITypeRefArray(const MDTuple *N) : N(N) {}
Duncan P. N. Exon Smith11344732015-04-07 16:50:39 +0000106
107 explicit operator bool() const { return get(); }
108 explicit operator MDTuple *() const { return get(); }
109
110 MDTuple *get() const { return const_cast<MDTuple *>(N); }
111 MDTuple *operator->() const { return get(); }
112 MDTuple &operator*() const { return *get(); }
Duncan P. N. Exon Smith62e93622015-04-06 19:48:50 +0000113
Duncan P. N. Exon Smith000fa2c2015-04-07 04:14:33 +0000114 // FIXME: Fix callers and remove condition on N.
115 unsigned size() const { return N ? N->getNumOperands() : 0u; }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000116 DITypeRef operator[](unsigned I) const { return DITypeRef(N->getOperand(I)); }
Duncan P. N. Exon Smith62e93622015-04-06 19:48:50 +0000117
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000118 class iterator : std::iterator<std::input_iterator_tag, DITypeRef,
119 std::ptrdiff_t, void, DITypeRef> {
Duncan P. N. Exon Smith000fa2c2015-04-07 04:14:33 +0000120 MDNode::op_iterator I = nullptr;
Duncan P. N. Exon Smith62e93622015-04-06 19:48:50 +0000121
122 public:
Duncan P. N. Exon Smith000fa2c2015-04-07 04:14:33 +0000123 iterator() = default;
Duncan P. N. Exon Smith62e93622015-04-06 19:48:50 +0000124 explicit iterator(MDNode::op_iterator I) : I(I) {}
Eugene Zelenko1aa40f42016-11-23 22:25:16 +0000125
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000126 DITypeRef operator*() const { return DITypeRef(*I); }
Eugene Zelenko1aa40f42016-11-23 22:25:16 +0000127
Duncan P. N. Exon Smith62e93622015-04-06 19:48:50 +0000128 iterator &operator++() {
129 ++I;
130 return *this;
131 }
Eugene Zelenko1aa40f42016-11-23 22:25:16 +0000132
Duncan P. N. Exon Smith62e93622015-04-06 19:48:50 +0000133 iterator operator++(int) {
134 iterator Temp(*this);
135 ++I;
136 return Temp;
137 }
Eugene Zelenko1aa40f42016-11-23 22:25:16 +0000138
Duncan P. N. Exon Smith62e93622015-04-06 19:48:50 +0000139 bool operator==(const iterator &X) const { return I == X.I; }
140 bool operator!=(const iterator &X) const { return I != X.I; }
141 };
142
Duncan P. N. Exon Smith000fa2c2015-04-07 04:14:33 +0000143 // FIXME: Fix callers and remove condition on N.
144 iterator begin() const { return N ? iterator(N->op_begin()) : iterator(); }
145 iterator end() const { return N ? iterator(N->op_end()) : iterator(); }
Duncan P. N. Exon Smith62e93622015-04-06 19:48:50 +0000146};
147
Adrian Prantl1687e012016-11-14 22:09:18 +0000148/// Tagged DWARF-like metadata node.
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000149///
150/// A metadata node with a DWARF tag (i.e., a constant named \c DW_TAG_*,
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000151/// defined in llvm/Support/Dwarf.h). Called \a DINode because it's
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000152/// potentially used for non-DWARF output.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000153class DINode : public MDNode {
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000154 friend class LLVMContextImpl;
155 friend class MDNode;
156
157protected:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000158 DINode(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
159 ArrayRef<Metadata *> Ops1, ArrayRef<Metadata *> Ops2 = None)
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000160 : MDNode(C, ID, Storage, Ops1, Ops2) {
161 assert(Tag < 1u << 16);
162 SubclassData16 = Tag;
163 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000164 ~DINode() = default;
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000165
Duncan P. N. Exon Smith252b62d2015-02-05 01:07:47 +0000166 template <class Ty> Ty *getOperandAs(unsigned I) const {
167 return cast_or_null<Ty>(getOperand(I));
168 }
169
Duncan P. N. Exon Smith442ec022015-02-02 19:54:05 +0000170 StringRef getStringOperand(unsigned I) const {
Duncan P. N. Exon Smith252b62d2015-02-05 01:07:47 +0000171 if (auto *S = getOperandAs<MDString>(I))
Duncan P. N. Exon Smith442ec022015-02-02 19:54:05 +0000172 return S->getString();
173 return StringRef();
174 }
175
Duncan P. N. Exon Smith9146fc82015-02-02 20:01:03 +0000176 static MDString *getCanonicalMDString(LLVMContext &Context, StringRef S) {
177 if (S.empty())
178 return nullptr;
179 return MDString::get(Context, S);
180 }
181
Duncan P. N. Exon Smith97386022016-04-19 18:00:19 +0000182 /// Allow subclasses to mutate the tag.
183 void setTag(unsigned Tag) { SubclassData16 = Tag; }
184
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000185public:
186 unsigned getTag() const { return SubclassData16; }
187
Adrian Prantl1687e012016-11-14 22:09:18 +0000188 /// Debug info flags.
Duncan P. N. Exon Smith3744fd02015-03-31 01:19:51 +0000189 ///
190 /// The three accessibility flags are mutually exclusive and rolled together
191 /// in the first two bits.
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000192 enum DIFlags : uint32_t {
Duncan P. N. Exon Smith3744fd02015-03-31 01:19:51 +0000193#define HANDLE_DI_FLAG(ID, NAME) Flag##NAME = ID,
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000194#define DI_FLAG_LARGEST_NEEDED
Duncan P. N. Exon Smith3744fd02015-03-31 01:19:51 +0000195#include "llvm/IR/DebugInfoFlags.def"
Reid Kleckner604105b2016-06-17 21:31:33 +0000196 FlagAccessibility = FlagPrivate | FlagProtected | FlagPublic,
197 FlagPtrToMemberRep = FlagSingleInheritance | FlagMultipleInheritance |
198 FlagVirtualInheritance,
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000199 LLVM_MARK_AS_BITMASK_ENUM(FlagLargest)
Duncan P. N. Exon Smith3744fd02015-03-31 01:19:51 +0000200 };
201
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000202 static DIFlags getFlag(StringRef Flag);
Mehdi Aminif42ec792016-10-01 05:57:50 +0000203 static StringRef getFlagString(DIFlags Flag);
Duncan P. N. Exon Smith5261e4b2015-04-07 01:21:40 +0000204
Adrian Prantl1687e012016-11-14 22:09:18 +0000205 /// Split up a flags bitfield.
Duncan P. N. Exon Smith5261e4b2015-04-07 01:21:40 +0000206 ///
207 /// Split \c Flags into \c SplitFlags, a vector of its components. Returns
208 /// any remaining (unrecognized) bits.
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000209 static DIFlags splitFlags(DIFlags Flags,
Leny Kholodov40c62352016-09-06 17:03:02 +0000210 SmallVectorImpl<DIFlags> &SplitFlags);
Duncan P. N. Exon Smith5261e4b2015-04-07 01:21:40 +0000211
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000212 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000213 switch (MD->getMetadataID()) {
214 default:
215 return false;
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000216 case GenericDINodeKind:
217 case DISubrangeKind:
218 case DIEnumeratorKind:
219 case DIBasicTypeKind:
220 case DIDerivedTypeKind:
221 case DICompositeTypeKind:
222 case DISubroutineTypeKind:
223 case DIFileKind:
224 case DICompileUnitKind:
225 case DISubprogramKind:
226 case DILexicalBlockKind:
227 case DILexicalBlockFileKind:
228 case DINamespaceKind:
229 case DITemplateTypeParameterKind:
230 case DITemplateValueParameterKind:
231 case DIGlobalVariableKind:
232 case DILocalVariableKind:
233 case DIObjCPropertyKind:
234 case DIImportedEntityKind:
Adrian Prantlab1243f2015-06-29 23:03:47 +0000235 case DIModuleKind:
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000236 return true;
237 }
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000238 }
239};
240
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000241template <class T> struct simplify_type<const TypedDINodeRef<T>> {
Eugene Zelenkod761e2c2017-05-15 21:57:41 +0000242 using SimpleType = Metadata *;
243
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000244 static SimpleType getSimplifiedValue(const TypedDINodeRef<T> &MD) {
Duncan P. N. Exon Smith930f3882015-04-06 18:02:43 +0000245 return MD;
246 }
247};
248
249template <class T>
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000250struct simplify_type<TypedDINodeRef<T>>
251 : simplify_type<const TypedDINodeRef<T>> {};
Duncan P. N. Exon Smith930f3882015-04-06 18:02:43 +0000252
Adrian Prantl1687e012016-11-14 22:09:18 +0000253/// Generic tagged DWARF-like metadata node.
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000254///
255/// An un-specialized DWARF-like metadata node. The first operand is a
256/// (possibly empty) null-separated \a MDString header that contains arbitrary
257/// fields. The remaining operands are \a dwarf_operands(), and are pointers
258/// to other metadata.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000259class GenericDINode : public DINode {
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000260 friend class LLVMContextImpl;
261 friend class MDNode;
262
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000263 GenericDINode(LLVMContext &C, StorageType Storage, unsigned Hash,
264 unsigned Tag, ArrayRef<Metadata *> Ops1,
265 ArrayRef<Metadata *> Ops2)
266 : DINode(C, GenericDINodeKind, Storage, Tag, Ops1, Ops2) {
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000267 setHash(Hash);
268 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000269 ~GenericDINode() { dropAllReferences(); }
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000270
271 void setHash(unsigned Hash) { SubclassData32 = Hash; }
272 void recalculateHash();
273
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000274 static GenericDINode *getImpl(LLVMContext &Context, unsigned Tag,
275 StringRef Header, ArrayRef<Metadata *> DwarfOps,
276 StorageType Storage, bool ShouldCreate = true) {
Duncan P. N. Exon Smith9146fc82015-02-02 20:01:03 +0000277 return getImpl(Context, Tag, getCanonicalMDString(Context, Header),
278 DwarfOps, Storage, ShouldCreate);
279 }
280
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000281 static GenericDINode *getImpl(LLVMContext &Context, unsigned Tag,
282 MDString *Header, ArrayRef<Metadata *> DwarfOps,
283 StorageType Storage, bool ShouldCreate = true);
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000284
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000285 TempGenericDINode cloneImpl() const {
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000286 return getTemporary(
287 getContext(), getTag(), getHeader(),
288 SmallVector<Metadata *, 4>(dwarf_op_begin(), dwarf_op_end()));
289 }
290
291public:
292 unsigned getHash() const { return SubclassData32; }
293
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000294 DEFINE_MDNODE_GET(GenericDINode, (unsigned Tag, StringRef Header,
295 ArrayRef<Metadata *> DwarfOps),
Duncan P. N. Exon Smith61e62a52015-02-02 19:55:21 +0000296 (Tag, Header, DwarfOps))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000297 DEFINE_MDNODE_GET(GenericDINode, (unsigned Tag, MDString *Header,
298 ArrayRef<Metadata *> DwarfOps),
Duncan P. N. Exon Smith9146fc82015-02-02 20:01:03 +0000299 (Tag, Header, DwarfOps))
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000300
Adrian Prantl1687e012016-11-14 22:09:18 +0000301 /// Return a (temporary) clone of this.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000302 TempGenericDINode clone() const { return cloneImpl(); }
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000303
304 unsigned getTag() const { return SubclassData16; }
Duncan P. N. Exon Smith442ec022015-02-02 19:54:05 +0000305 StringRef getHeader() const { return getStringOperand(0); }
Mehdi Amini5d99c4e2016-03-19 01:02:34 +0000306 MDString *getRawHeader() const { return getOperandAs<MDString>(0); }
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000307
308 op_iterator dwarf_op_begin() const { return op_begin() + 1; }
309 op_iterator dwarf_op_end() const { return op_end(); }
310 op_range dwarf_operands() const {
311 return op_range(dwarf_op_begin(), dwarf_op_end());
312 }
313
314 unsigned getNumDwarfOperands() const { return getNumOperands() - 1; }
315 const MDOperand &getDwarfOperand(unsigned I) const {
316 return getOperand(I + 1);
317 }
318 void replaceDwarfOperandWith(unsigned I, Metadata *New) {
319 replaceOperandWith(I + 1, New);
320 }
321
322 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000323 return MD->getMetadataID() == GenericDINodeKind;
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000324 }
325};
326
Adrian Prantl1687e012016-11-14 22:09:18 +0000327/// Array subrange.
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000328///
329/// TODO: Merge into node for DW_TAG_array_type, which should have a custom
330/// type.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000331class DISubrange : public DINode {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000332 friend class LLVMContextImpl;
333 friend class MDNode;
334
335 int64_t Count;
Duncan P. N. Exon Smith5dcf6212015-04-07 00:39:59 +0000336 int64_t LowerBound;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000337
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000338 DISubrange(LLVMContext &C, StorageType Storage, int64_t Count,
Duncan P. N. Exon Smith5dcf6212015-04-07 00:39:59 +0000339 int64_t LowerBound)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000340 : DINode(C, DISubrangeKind, Storage, dwarf::DW_TAG_subrange_type, None),
Duncan P. N. Exon Smith5dcf6212015-04-07 00:39:59 +0000341 Count(Count), LowerBound(LowerBound) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000342 ~DISubrange() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000343
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000344 static DISubrange *getImpl(LLVMContext &Context, int64_t Count,
Duncan P. N. Exon Smith5dcf6212015-04-07 00:39:59 +0000345 int64_t LowerBound, StorageType Storage,
346 bool ShouldCreate = true);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000347
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000348 TempDISubrange cloneImpl() const {
Duncan P. N. Exon Smith5dcf6212015-04-07 00:39:59 +0000349 return getTemporary(getContext(), getCount(), getLowerBound());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000350 }
351
352public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000353 DEFINE_MDNODE_GET(DISubrange, (int64_t Count, int64_t LowerBound = 0),
Duncan P. N. Exon Smith5dcf6212015-04-07 00:39:59 +0000354 (Count, LowerBound))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000355
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000356 TempDISubrange clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000357
Duncan P. N. Exon Smith5dcf6212015-04-07 00:39:59 +0000358 int64_t getLowerBound() const { return LowerBound; }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000359 int64_t getCount() const { return Count; }
360
361 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000362 return MD->getMetadataID() == DISubrangeKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000363 }
364};
365
Adrian Prantl1687e012016-11-14 22:09:18 +0000366/// Enumeration value.
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000367///
368/// TODO: Add a pointer to the context (DW_TAG_enumeration_type) once that no
369/// longer creates a type cycle.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000370class DIEnumerator : public DINode {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000371 friend class LLVMContextImpl;
372 friend class MDNode;
373
374 int64_t Value;
375
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000376 DIEnumerator(LLVMContext &C, StorageType Storage, int64_t Value,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000377 ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000378 : DINode(C, DIEnumeratorKind, Storage, dwarf::DW_TAG_enumerator, Ops),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000379 Value(Value) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000380 ~DIEnumerator() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000381
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000382 static DIEnumerator *getImpl(LLVMContext &Context, int64_t Value,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000383 StringRef Name, StorageType Storage,
384 bool ShouldCreate = true) {
385 return getImpl(Context, Value, getCanonicalMDString(Context, Name), Storage,
386 ShouldCreate);
387 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000388 static DIEnumerator *getImpl(LLVMContext &Context, int64_t Value,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000389 MDString *Name, StorageType Storage,
390 bool ShouldCreate = true);
391
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000392 TempDIEnumerator cloneImpl() const {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000393 return getTemporary(getContext(), getValue(), getName());
394 }
395
396public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000397 DEFINE_MDNODE_GET(DIEnumerator, (int64_t Value, StringRef Name),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000398 (Value, Name))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000399 DEFINE_MDNODE_GET(DIEnumerator, (int64_t Value, MDString *Name),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000400 (Value, Name))
401
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000402 TempDIEnumerator clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000403
404 int64_t getValue() const { return Value; }
405 StringRef getName() const { return getStringOperand(0); }
406
Duncan P. N. Exon Smith87754762015-02-13 01:14:11 +0000407 MDString *getRawName() const { return getOperandAs<MDString>(0); }
408
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000409 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000410 return MD->getMetadataID() == DIEnumeratorKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000411 }
412};
413
Adrian Prantl1687e012016-11-14 22:09:18 +0000414/// Base class for scope-like contexts.
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000415///
416/// Base class for lexical scopes and types (which are also declaration
417/// contexts).
418///
419/// TODO: Separate the concepts of declaration contexts and lexical scopes.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000420class DIScope : public DINode {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000421protected:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000422 DIScope(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000423 ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000424 : DINode(C, ID, Storage, Tag, Ops) {}
425 ~DIScope() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000426
427public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000428 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
Duncan P. N. Exon Smith53855f02015-03-27 23:05:04 +0000429
Duncan P. N. Exon Smith50c065b2015-04-11 00:39:43 +0000430 inline StringRef getFilename() const;
431 inline StringRef getDirectory() const;
432
Duncan P. N. Exon Smithf0d81a52015-04-11 17:37:23 +0000433 StringRef getName() const;
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000434 DIScopeRef getScope() const;
Duncan P. N. Exon Smithf0d81a52015-04-11 17:37:23 +0000435
Adrian Prantl1687e012016-11-14 22:09:18 +0000436 /// Return the raw underlying file.
Duncan P. N. Exon Smith2c6a0a92015-02-28 21:47:02 +0000437 ///
Saleem Abdulrasool2dc8cb92017-04-28 17:18:28 +0000438 /// A \a DIFile is a \a DIScope, but it doesn't point at a separate file
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000439 /// (it\em is the file). If \c this is an \a DIFile, we need to return \c
Duncan P. N. Exon Smith2c6a0a92015-02-28 21:47:02 +0000440 /// this. Otherwise, return the first operand, which is where all other
441 /// subclasses store their file pointer.
Duncan P. N. Exon Smith53855f02015-03-27 23:05:04 +0000442 Metadata *getRawFile() const {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000443 return isa<DIFile>(this) ? const_cast<DIScope *>(this)
Duncan P. N. Exon Smith3a46c142015-02-28 21:58:10 +0000444 : static_cast<Metadata *>(getOperand(0));
Duncan P. N. Exon Smith2c6a0a92015-02-28 21:47:02 +0000445 }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000446
447 static bool classof(const Metadata *MD) {
448 switch (MD->getMetadataID()) {
449 default:
450 return false;
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000451 case DIBasicTypeKind:
452 case DIDerivedTypeKind:
453 case DICompositeTypeKind:
454 case DISubroutineTypeKind:
455 case DIFileKind:
456 case DICompileUnitKind:
457 case DISubprogramKind:
458 case DILexicalBlockKind:
459 case DILexicalBlockFileKind:
460 case DINamespaceKind:
Adrian Prantlab1243f2015-06-29 23:03:47 +0000461 case DIModuleKind:
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000462 return true;
463 }
464 }
465};
466
Adrian Prantl1687e012016-11-14 22:09:18 +0000467/// File.
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +0000468///
469/// TODO: Merge with directory/file node (including users).
470/// TODO: Canonicalize paths on creation.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000471class DIFile : public DIScope {
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +0000472 friend class LLVMContextImpl;
473 friend class MDNode;
474
Amjad Aboud7faeecc2016-12-25 10:12:09 +0000475public:
476 enum ChecksumKind {
477 CSK_None,
478 CSK_MD5,
479 CSK_SHA1,
480 CSK_Last = CSK_SHA1 // Should be last enumeration.
481 };
482
483private:
484 ChecksumKind CSKind;
485
486 DIFile(LLVMContext &C, StorageType Storage, ChecksumKind CSK,
487 ArrayRef<Metadata *> Ops)
488 : DIScope(C, DIFileKind, Storage, dwarf::DW_TAG_file_type, Ops),
489 CSKind(CSK) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000490 ~DIFile() = default;
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +0000491
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000492 static DIFile *getImpl(LLVMContext &Context, StringRef Filename,
Amjad Aboud7faeecc2016-12-25 10:12:09 +0000493 StringRef Directory, ChecksumKind CSK, StringRef CS,
494 StorageType Storage, bool ShouldCreate = true) {
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +0000495 return getImpl(Context, getCanonicalMDString(Context, Filename),
Amjad Aboud7faeecc2016-12-25 10:12:09 +0000496 getCanonicalMDString(Context, Directory), CSK,
497 getCanonicalMDString(Context, CS), Storage, ShouldCreate);
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +0000498 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000499 static DIFile *getImpl(LLVMContext &Context, MDString *Filename,
Amjad Aboud7faeecc2016-12-25 10:12:09 +0000500 MDString *Directory, ChecksumKind CSK, MDString *CS,
501 StorageType Storage, bool ShouldCreate = true);
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +0000502
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000503 TempDIFile cloneImpl() const {
Amjad Aboud7faeecc2016-12-25 10:12:09 +0000504 return getTemporary(getContext(), getFilename(), getDirectory(),
505 getChecksumKind(), getChecksum());
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +0000506 }
507
508public:
Amjad Aboud7faeecc2016-12-25 10:12:09 +0000509 DEFINE_MDNODE_GET(DIFile, (StringRef Filename, StringRef Directory,
510 ChecksumKind CSK = CSK_None,
511 StringRef CS = StringRef()),
512 (Filename, Directory, CSK, CS))
513 DEFINE_MDNODE_GET(DIFile, (MDString *Filename, MDString *Directory,
514 ChecksumKind CSK = CSK_None,
515 MDString *CS = nullptr),
516 (Filename, Directory, CSK, CS))
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +0000517
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000518 TempDIFile clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +0000519
520 StringRef getFilename() const { return getStringOperand(0); }
521 StringRef getDirectory() const { return getStringOperand(1); }
Amjad Aboud7faeecc2016-12-25 10:12:09 +0000522 StringRef getChecksum() const { return getStringOperand(2); }
523 ChecksumKind getChecksumKind() const { return CSKind; }
524 StringRef getChecksumKindAsString() const;
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +0000525
526 MDString *getRawFilename() const { return getOperandAs<MDString>(0); }
527 MDString *getRawDirectory() const { return getOperandAs<MDString>(1); }
Amjad Aboud7faeecc2016-12-25 10:12:09 +0000528 MDString *getRawChecksum() const { return getOperandAs<MDString>(2); }
529
530 static ChecksumKind getChecksumKind(StringRef CSKindStr);
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +0000531
532 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000533 return MD->getMetadataID() == DIFileKind;
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +0000534 }
535};
536
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000537StringRef DIScope::getFilename() const {
Duncan P. N. Exon Smith50c065b2015-04-11 00:39:43 +0000538 if (auto *F = getFile())
539 return F->getFilename();
540 return "";
541}
542
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000543StringRef DIScope::getDirectory() const {
Duncan P. N. Exon Smith50c065b2015-04-11 00:39:43 +0000544 if (auto *F = getFile())
545 return F->getDirectory();
546 return "";
547}
548
Adrian Prantl1687e012016-11-14 22:09:18 +0000549/// Base class for types.
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000550///
551/// TODO: Remove the hardcoded name and context, since many types don't use
552/// them.
553/// TODO: Split up flags.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000554class DIType : public DIScope {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000555 unsigned Line;
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000556 DIFlags Flags;
Duncan P. N. Exon Smithd34db172015-02-19 23:56:07 +0000557 uint64_t SizeInBits;
Duncan P. N. Exon Smithd34db172015-02-19 23:56:07 +0000558 uint64_t OffsetInBits;
Victor Leschuk197aa312016-10-18 14:31:22 +0000559 uint32_t AlignInBits;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000560
561protected:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000562 DIType(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
Victor Leschuk197aa312016-10-18 14:31:22 +0000563 unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits,
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000564 uint64_t OffsetInBits, DIFlags Flags, ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smith97386022016-04-19 18:00:19 +0000565 : DIScope(C, ID, Storage, Tag, Ops) {
566 init(Line, SizeInBits, AlignInBits, OffsetInBits, Flags);
567 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000568 ~DIType() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000569
Victor Leschuk197aa312016-10-18 14:31:22 +0000570 void init(unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits,
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000571 uint64_t OffsetInBits, DIFlags Flags) {
Duncan P. N. Exon Smith97386022016-04-19 18:00:19 +0000572 this->Line = Line;
573 this->Flags = Flags;
574 this->SizeInBits = SizeInBits;
575 this->AlignInBits = AlignInBits;
576 this->OffsetInBits = OffsetInBits;
577 }
578
579 /// Change fields in place.
580 void mutate(unsigned Tag, unsigned Line, uint64_t SizeInBits,
Victor Leschuk197aa312016-10-18 14:31:22 +0000581 uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags) {
Duncan P. N. Exon Smith97386022016-04-19 18:00:19 +0000582 assert(isDistinct() && "Only distinct nodes can mutate");
583 setTag(Tag);
584 init(Line, SizeInBits, AlignInBits, OffsetInBits, Flags);
585 }
586
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000587public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000588 TempDIType clone() const {
589 return TempDIType(cast<DIType>(MDNode::clone().release()));
Duncan P. N. Exon Smithb3538492015-03-03 16:45:34 +0000590 }
591
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000592 unsigned getLine() const { return Line; }
Duncan P. N. Exon Smithd34db172015-02-19 23:56:07 +0000593 uint64_t getSizeInBits() const { return SizeInBits; }
Victor Leschuk2ede1262016-10-20 00:13:12 +0000594 uint32_t getAlignInBits() const { return AlignInBits; }
595 uint32_t getAlignInBytes() const { return getAlignInBits() / CHAR_BIT; }
Duncan P. N. Exon Smithd34db172015-02-19 23:56:07 +0000596 uint64_t getOffsetInBits() const { return OffsetInBits; }
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000597 DIFlags getFlags() const { return Flags; }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000598
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000599 DIScopeRef getScope() const { return DIScopeRef(getRawScope()); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000600 StringRef getName() const { return getStringOperand(2); }
601
Duncan P. N. Exon Smith53855f02015-03-27 23:05:04 +0000602
603 Metadata *getRawScope() const { return getOperand(1); }
Duncan P. N. Exon Smith09e03f32015-02-13 01:14:58 +0000604 MDString *getRawName() const { return getOperandAs<MDString>(2); }
605
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000606 void setFlags(DIFlags NewFlags) {
Duncan P. N. Exon Smithb3538492015-03-03 16:45:34 +0000607 assert(!isUniqued() && "Cannot set flags on uniqued nodes");
608 Flags = NewFlags;
609 }
610
Duncan P. N. Exon Smithaecab7a2015-04-07 01:24:30 +0000611 bool isPrivate() const {
612 return (getFlags() & FlagAccessibility) == FlagPrivate;
613 }
614 bool isProtected() const {
615 return (getFlags() & FlagAccessibility) == FlagProtected;
616 }
617 bool isPublic() const {
618 return (getFlags() & FlagAccessibility) == FlagPublic;
619 }
620 bool isForwardDecl() const { return getFlags() & FlagFwdDecl; }
621 bool isAppleBlockExtension() const { return getFlags() & FlagAppleBlock; }
622 bool isBlockByrefStruct() const { return getFlags() & FlagBlockByrefStruct; }
623 bool isVirtual() const { return getFlags() & FlagVirtual; }
624 bool isArtificial() const { return getFlags() & FlagArtificial; }
625 bool isObjectPointer() const { return getFlags() & FlagObjectPointer; }
626 bool isObjcClassComplete() const {
627 return getFlags() & FlagObjcClassComplete;
628 }
629 bool isVector() const { return getFlags() & FlagVector; }
David Majnemer9319cbc2016-06-30 03:00:20 +0000630 bool isBitField() const { return getFlags() & FlagBitField; }
Duncan P. N. Exon Smithaecab7a2015-04-07 01:24:30 +0000631 bool isStaticMember() const { return getFlags() & FlagStaticMember; }
632 bool isLValueReference() const { return getFlags() & FlagLValueReference; }
633 bool isRValueReference() const { return getFlags() & FlagRValueReference; }
634
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000635 static bool classof(const Metadata *MD) {
636 switch (MD->getMetadataID()) {
637 default:
638 return false;
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000639 case DIBasicTypeKind:
640 case DIDerivedTypeKind:
641 case DICompositeTypeKind:
642 case DISubroutineTypeKind:
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000643 return true;
644 }
645 }
646};
647
Adrian Prantl1687e012016-11-14 22:09:18 +0000648/// Basic type, like 'int' or 'float'.
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000649///
650/// TODO: Split out DW_TAG_unspecified_type.
651/// TODO: Drop unused accessors.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000652class DIBasicType : public DIType {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000653 friend class LLVMContextImpl;
654 friend class MDNode;
655
656 unsigned Encoding;
657
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000658 DIBasicType(LLVMContext &C, StorageType Storage, unsigned Tag,
Victor Leschuk197aa312016-10-18 14:31:22 +0000659 uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000660 ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000661 : DIType(C, DIBasicTypeKind, Storage, Tag, 0, SizeInBits, AlignInBits, 0,
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000662 FlagZero, Ops),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000663 Encoding(Encoding) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000664 ~DIBasicType() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000665
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000666 static DIBasicType *getImpl(LLVMContext &Context, unsigned Tag,
Duncan P. N. Exon Smithd34db172015-02-19 23:56:07 +0000667 StringRef Name, uint64_t SizeInBits,
Victor Leschuk197aa312016-10-18 14:31:22 +0000668 uint32_t AlignInBits, unsigned Encoding,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000669 StorageType Storage, bool ShouldCreate = true) {
670 return getImpl(Context, Tag, getCanonicalMDString(Context, Name),
671 SizeInBits, AlignInBits, Encoding, Storage, ShouldCreate);
672 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000673 static DIBasicType *getImpl(LLVMContext &Context, unsigned Tag,
Duncan P. N. Exon Smithd34db172015-02-19 23:56:07 +0000674 MDString *Name, uint64_t SizeInBits,
Victor Leschuk197aa312016-10-18 14:31:22 +0000675 uint32_t AlignInBits, unsigned Encoding,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000676 StorageType Storage, bool ShouldCreate = true);
677
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000678 TempDIBasicType cloneImpl() const {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000679 return getTemporary(getContext(), getTag(), getName(), getSizeInBits(),
680 getAlignInBits(), getEncoding());
681 }
682
683public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000684 DEFINE_MDNODE_GET(DIBasicType, (unsigned Tag, StringRef Name),
Duncan P. N. Exon Smithb3538492015-03-03 16:45:34 +0000685 (Tag, Name, 0, 0, 0))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000686 DEFINE_MDNODE_GET(DIBasicType,
Duncan P. N. Exon Smithd34db172015-02-19 23:56:07 +0000687 (unsigned Tag, StringRef Name, uint64_t SizeInBits,
Victor Leschuk197aa312016-10-18 14:31:22 +0000688 uint32_t AlignInBits, unsigned Encoding),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000689 (Tag, Name, SizeInBits, AlignInBits, Encoding))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000690 DEFINE_MDNODE_GET(DIBasicType,
Duncan P. N. Exon Smithd34db172015-02-19 23:56:07 +0000691 (unsigned Tag, MDString *Name, uint64_t SizeInBits,
Victor Leschuk197aa312016-10-18 14:31:22 +0000692 uint32_t AlignInBits, unsigned Encoding),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000693 (Tag, Name, SizeInBits, AlignInBits, Encoding))
694
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000695 TempDIBasicType clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000696
697 unsigned getEncoding() const { return Encoding; }
698
699 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000700 return MD->getMetadataID() == DIBasicTypeKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000701 }
702};
703
Adrian Prantl1687e012016-11-14 22:09:18 +0000704/// Derived types.
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000705///
706/// This includes qualified types, pointers, references, friends, typedefs, and
707/// class members.
708///
709/// TODO: Split out members (inheritance, fields, methods, etc.).
Duncan P. N. Exon Smith338aef02015-07-24 20:16:36 +0000710class DIDerivedType : public DIType {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000711 friend class LLVMContextImpl;
712 friend class MDNode;
713
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000714 /// \brief The DWARF address space of the memory pointed to or referenced by a
715 /// pointer or reference type respectively.
716 Optional<unsigned> DWARFAddressSpace;
717
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000718 DIDerivedType(LLVMContext &C, StorageType Storage, unsigned Tag,
Victor Leschuk197aa312016-10-18 14:31:22 +0000719 unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits,
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000720 uint64_t OffsetInBits, Optional<unsigned> DWARFAddressSpace,
721 DIFlags Flags, ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smith338aef02015-07-24 20:16:36 +0000722 : DIType(C, DIDerivedTypeKind, Storage, Tag, Line, SizeInBits,
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000723 AlignInBits, OffsetInBits, Flags, Ops),
724 DWARFAddressSpace(DWARFAddressSpace) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000725 ~DIDerivedType() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000726
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000727 static DIDerivedType *getImpl(LLVMContext &Context, unsigned Tag,
728 StringRef Name, DIFile *File, unsigned Line,
729 DIScopeRef Scope, DITypeRef BaseType,
Victor Leschuk197aa312016-10-18 14:31:22 +0000730 uint64_t SizeInBits, uint32_t AlignInBits,
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000731 uint64_t OffsetInBits,
732 Optional<unsigned> DWARFAddressSpace,
733 DIFlags Flags, Metadata *ExtraData,
734 StorageType Storage, bool ShouldCreate = true) {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000735 return getImpl(Context, Tag, getCanonicalMDString(Context, Name), File,
736 Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits,
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000737 DWARFAddressSpace, Flags, ExtraData, Storage, ShouldCreate);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000738 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000739 static DIDerivedType *getImpl(LLVMContext &Context, unsigned Tag,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000740 MDString *Name, Metadata *File, unsigned Line,
741 Metadata *Scope, Metadata *BaseType,
Victor Leschuk197aa312016-10-18 14:31:22 +0000742 uint64_t SizeInBits, uint32_t AlignInBits,
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000743 uint64_t OffsetInBits,
744 Optional<unsigned> DWARFAddressSpace,
745 DIFlags Flags, Metadata *ExtraData,
746 StorageType Storage, bool ShouldCreate = true);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000747
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000748 TempDIDerivedType cloneImpl() const {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000749 return getTemporary(getContext(), getTag(), getName(), getFile(), getLine(),
750 getScope(), getBaseType(), getSizeInBits(),
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000751 getAlignInBits(), getOffsetInBits(),
752 getDWARFAddressSpace(), getFlags(), getExtraData());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000753 }
754
755public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000756 DEFINE_MDNODE_GET(DIDerivedType,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000757 (unsigned Tag, MDString *Name, Metadata *File,
758 unsigned Line, Metadata *Scope, Metadata *BaseType,
Victor Leschuk197aa312016-10-18 14:31:22 +0000759 uint64_t SizeInBits, uint32_t AlignInBits,
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000760 uint64_t OffsetInBits,
761 Optional<unsigned> DWARFAddressSpace, DIFlags Flags,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000762 Metadata *ExtraData = nullptr),
763 (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000764 AlignInBits, OffsetInBits, DWARFAddressSpace, Flags,
765 ExtraData))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000766 DEFINE_MDNODE_GET(DIDerivedType,
767 (unsigned Tag, StringRef Name, DIFile *File, unsigned Line,
768 DIScopeRef Scope, DITypeRef BaseType, uint64_t SizeInBits,
Victor Leschuk197aa312016-10-18 14:31:22 +0000769 uint32_t AlignInBits, uint64_t OffsetInBits,
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000770 Optional<unsigned> DWARFAddressSpace, DIFlags Flags,
771 Metadata *ExtraData = nullptr),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000772 (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000773 AlignInBits, OffsetInBits, DWARFAddressSpace, Flags,
774 ExtraData))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000775
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000776 TempDIDerivedType clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000777
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000778 /// Get the base type this is derived from.
Duncan P. N. Exon Smith338aef02015-07-24 20:16:36 +0000779 DITypeRef getBaseType() const { return DITypeRef(getRawBaseType()); }
780 Metadata *getRawBaseType() const { return getOperand(3); }
781
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000782 /// \returns The DWARF address space of the memory pointed to or referenced by
783 /// a pointer or reference type respectively.
784 Optional<unsigned> getDWARFAddressSpace() const { return DWARFAddressSpace; }
785
Adrian Prantl1687e012016-11-14 22:09:18 +0000786 /// Get extra data associated with this derived type.
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000787 ///
788 /// Class type for pointer-to-members, objective-c property node for ivars,
789 /// or global constant wrapper for static members.
790 ///
791 /// TODO: Separate out types that need this extra operand: pointer-to-member
792 /// types and member fields (static members and ivars).
Duncan P. N. Exon Smith53855f02015-03-27 23:05:04 +0000793 Metadata *getExtraData() const { return getRawExtraData(); }
794 Metadata *getRawExtraData() const { return getOperand(4); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000795
Adrian Prantl1687e012016-11-14 22:09:18 +0000796 /// Get casted version of extra data.
Duncan P. N. Exon Smith0bf8d4c2015-04-13 23:36:36 +0000797 /// @{
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000798 DITypeRef getClassType() const {
Duncan P. N. Exon Smith0bf8d4c2015-04-13 23:36:36 +0000799 assert(getTag() == dwarf::DW_TAG_ptr_to_member_type);
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000800 return DITypeRef(getExtraData());
Duncan P. N. Exon Smith0bf8d4c2015-04-13 23:36:36 +0000801 }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +0000802
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000803 DIObjCProperty *getObjCProperty() const {
804 return dyn_cast_or_null<DIObjCProperty>(getExtraData());
Duncan P. N. Exon Smith0bf8d4c2015-04-13 23:36:36 +0000805 }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +0000806
David Majnemer9319cbc2016-06-30 03:00:20 +0000807 Constant *getStorageOffsetInBits() const {
808 assert(getTag() == dwarf::DW_TAG_member && isBitField());
809 if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData()))
810 return C->getValue();
811 return nullptr;
812 }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +0000813
Duncan P. N. Exon Smith0bf8d4c2015-04-13 23:36:36 +0000814 Constant *getConstant() const {
815 assert(getTag() == dwarf::DW_TAG_member && isStaticMember());
816 if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData()))
817 return C->getValue();
818 return nullptr;
819 }
820 /// @}
821
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000822 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000823 return MD->getMetadataID() == DIDerivedTypeKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000824 }
825};
826
Adrian Prantl1687e012016-11-14 22:09:18 +0000827/// Composite types.
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000828///
829/// TODO: Detach from DerivedTypeBase (split out MDEnumType?).
830/// TODO: Create a custom, unrelated node for DW_TAG_array_type.
Duncan P. N. Exon Smithb9e045a2015-07-24 20:56:36 +0000831class DICompositeType : public DIType {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000832 friend class LLVMContextImpl;
833 friend class MDNode;
834
Duncan P. N. Exon Smithb9e045a2015-07-24 20:56:36 +0000835 unsigned RuntimeLang;
836
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000837 DICompositeType(LLVMContext &C, StorageType Storage, unsigned Tag,
Duncan P. N. Exon Smithd34db172015-02-19 23:56:07 +0000838 unsigned Line, unsigned RuntimeLang, uint64_t SizeInBits,
Victor Leschuk197aa312016-10-18 14:31:22 +0000839 uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000840 ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smithb9e045a2015-07-24 20:56:36 +0000841 : DIType(C, DICompositeTypeKind, Storage, Tag, Line, SizeInBits,
842 AlignInBits, OffsetInBits, Flags, Ops),
843 RuntimeLang(RuntimeLang) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000844 ~DICompositeType() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000845
Duncan P. N. Exon Smith97386022016-04-19 18:00:19 +0000846 /// Change fields in place.
847 void mutate(unsigned Tag, unsigned Line, unsigned RuntimeLang,
Victor Leschuk197aa312016-10-18 14:31:22 +0000848 uint64_t SizeInBits, uint32_t AlignInBits,
849 uint64_t OffsetInBits, DIFlags Flags) {
Duncan P. N. Exon Smith97386022016-04-19 18:00:19 +0000850 assert(isDistinct() && "Only distinct nodes can mutate");
851 assert(getRawIdentifier() && "Only ODR-uniqued nodes should mutate");
852 this->RuntimeLang = RuntimeLang;
853 DIType::mutate(Tag, Line, SizeInBits, AlignInBits, OffsetInBits, Flags);
854 }
855
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000856 static DICompositeType *
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000857 getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, Metadata *File,
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000858 unsigned Line, DIScopeRef Scope, DITypeRef BaseType,
Victor Leschuk197aa312016-10-18 14:31:22 +0000859 uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000860 DIFlags Flags, DINodeArray Elements, unsigned RuntimeLang,
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000861 DITypeRef VTableHolder, DITemplateParameterArray TemplateParams,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000862 StringRef Identifier, StorageType Storage, bool ShouldCreate = true) {
Duncan P. N. Exon Smith11344732015-04-07 16:50:39 +0000863 return getImpl(
864 Context, Tag, getCanonicalMDString(Context, Name), File, Line, Scope,
865 BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements.get(),
866 RuntimeLang, VTableHolder, TemplateParams.get(),
867 getCanonicalMDString(Context, Identifier), Storage, ShouldCreate);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000868 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000869 static DICompositeType *
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000870 getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
871 unsigned Line, Metadata *Scope, Metadata *BaseType,
Victor Leschuk197aa312016-10-18 14:31:22 +0000872 uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000873 DIFlags Flags, Metadata *Elements, unsigned RuntimeLang,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000874 Metadata *VTableHolder, Metadata *TemplateParams,
875 MDString *Identifier, StorageType Storage, bool ShouldCreate = true);
876
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000877 TempDICompositeType cloneImpl() const {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000878 return getTemporary(getContext(), getTag(), getName(), getFile(), getLine(),
879 getScope(), getBaseType(), getSizeInBits(),
880 getAlignInBits(), getOffsetInBits(), getFlags(),
881 getElements(), getRuntimeLang(), getVTableHolder(),
882 getTemplateParams(), getIdentifier());
883 }
884
885public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000886 DEFINE_MDNODE_GET(DICompositeType,
887 (unsigned Tag, StringRef Name, DIFile *File, unsigned Line,
888 DIScopeRef Scope, DITypeRef BaseType, uint64_t SizeInBits,
Victor Leschuk197aa312016-10-18 14:31:22 +0000889 uint32_t AlignInBits, uint64_t OffsetInBits,
890 DIFlags Flags, DINodeArray Elements, unsigned RuntimeLang,
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000891 DITypeRef VTableHolder,
892 DITemplateParameterArray TemplateParams = nullptr,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000893 StringRef Identifier = ""),
894 (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
895 AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
896 VTableHolder, TemplateParams, Identifier))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000897 DEFINE_MDNODE_GET(DICompositeType,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000898 (unsigned Tag, MDString *Name, Metadata *File,
899 unsigned Line, Metadata *Scope, Metadata *BaseType,
Victor Leschuk197aa312016-10-18 14:31:22 +0000900 uint64_t SizeInBits, uint32_t AlignInBits,
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000901 uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000902 unsigned RuntimeLang, Metadata *VTableHolder,
903 Metadata *TemplateParams = nullptr,
904 MDString *Identifier = nullptr),
905 (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
906 AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
907 VTableHolder, TemplateParams, Identifier))
908
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000909 TempDICompositeType clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000910
Duncan P. N. Exon Smith0b0271e2016-04-19 14:55:09 +0000911 /// Get a DICompositeType with the given ODR identifier.
912 ///
913 /// If \a LLVMContext::isODRUniquingDebugTypes(), gets the mapped
914 /// DICompositeType for the given ODR \c Identifier. If none exists, creates
915 /// a new node.
916 ///
917 /// Else, returns \c nullptr.
918 static DICompositeType *
919 getODRType(LLVMContext &Context, MDString &Identifier, unsigned Tag,
920 MDString *Name, Metadata *File, unsigned Line, Metadata *Scope,
Victor Leschuk197aa312016-10-18 14:31:22 +0000921 Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits,
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000922 uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements,
Duncan P. N. Exon Smith0b0271e2016-04-19 14:55:09 +0000923 unsigned RuntimeLang, Metadata *VTableHolder,
924 Metadata *TemplateParams);
925 static DICompositeType *getODRTypeIfExists(LLVMContext &Context,
926 MDString &Identifier);
927
Duncan P. N. Exon Smith97386022016-04-19 18:00:19 +0000928 /// Build a DICompositeType with the given ODR identifier.
929 ///
930 /// Looks up the mapped DICompositeType for the given ODR \c Identifier. If
931 /// it doesn't exist, creates a new one. If it does exist and \a
932 /// isForwardDecl(), and the new arguments would be a definition, mutates the
933 /// the type in place. In either case, returns the type.
934 ///
935 /// If not \a LLVMContext::isODRUniquingDebugTypes(), this function returns
936 /// nullptr.
937 static DICompositeType *
938 buildODRType(LLVMContext &Context, MDString &Identifier, unsigned Tag,
939 MDString *Name, Metadata *File, unsigned Line, Metadata *Scope,
Victor Leschuk197aa312016-10-18 14:31:22 +0000940 Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits,
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000941 uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements,
Duncan P. N. Exon Smith97386022016-04-19 18:00:19 +0000942 unsigned RuntimeLang, Metadata *VTableHolder,
943 Metadata *TemplateParams);
944
Duncan P. N. Exon Smithb9e045a2015-07-24 20:56:36 +0000945 DITypeRef getBaseType() const { return DITypeRef(getRawBaseType()); }
946 DINodeArray getElements() const {
947 return cast_or_null<MDTuple>(getRawElements());
948 }
949 DITypeRef getVTableHolder() const { return DITypeRef(getRawVTableHolder()); }
950 DITemplateParameterArray getTemplateParams() const {
951 return cast_or_null<MDTuple>(getRawTemplateParams());
952 }
953 StringRef getIdentifier() const { return getStringOperand(7); }
954 unsigned getRuntimeLang() const { return RuntimeLang; }
955
956 Metadata *getRawBaseType() const { return getOperand(3); }
957 Metadata *getRawElements() const { return getOperand(4); }
958 Metadata *getRawVTableHolder() const { return getOperand(5); }
959 Metadata *getRawTemplateParams() const { return getOperand(6); }
960 MDString *getRawIdentifier() const { return getOperandAs<MDString>(7); }
961
Adrian Prantl1687e012016-11-14 22:09:18 +0000962 /// Replace operands.
Duncan P. N. Exon Smithb9e045a2015-07-24 20:56:36 +0000963 ///
964 /// If this \a isUniqued() and not \a isResolved(), on a uniquing collision
965 /// this will be RAUW'ed and deleted. Use a \a TrackingMDRef to keep track
966 /// of its movement if necessary.
967 /// @{
968 void replaceElements(DINodeArray Elements) {
969#ifndef NDEBUG
970 for (DINode *Op : getElements())
David Majnemer42531262016-08-12 03:55:06 +0000971 assert(is_contained(Elements->operands(), Op) &&
Duncan P. N. Exon Smithb9e045a2015-07-24 20:56:36 +0000972 "Lost a member during member list replacement");
973#endif
974 replaceOperandWith(4, Elements.get());
975 }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +0000976
Duncan P. N. Exon Smithb9e045a2015-07-24 20:56:36 +0000977 void replaceVTableHolder(DITypeRef VTableHolder) {
978 replaceOperandWith(5, VTableHolder);
979 }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +0000980
Duncan P. N. Exon Smithb9e045a2015-07-24 20:56:36 +0000981 void replaceTemplateParams(DITemplateParameterArray TemplateParams) {
982 replaceOperandWith(6, TemplateParams.get());
983 }
984 /// @}
985
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000986 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000987 return MD->getMetadataID() == DICompositeTypeKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000988 }
989};
990
Adrian Prantl1687e012016-11-14 22:09:18 +0000991/// Type array for a subprogram.
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000992///
Duncan P. N. Exon Smithb9e045a2015-07-24 20:56:36 +0000993/// TODO: Fold the array of types in directly as operands.
994class DISubroutineType : public DIType {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000995 friend class LLVMContextImpl;
996 friend class MDNode;
997
Reid Klecknerde3d8b52016-06-08 20:34:29 +0000998 /// The calling convention used with DW_AT_calling_convention. Actually of
999 /// type dwarf::CallingConvention.
1000 uint8_t CC;
1001
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001002 DISubroutineType(LLVMContext &C, StorageType Storage, DIFlags Flags,
Reid Klecknerde3d8b52016-06-08 20:34:29 +00001003 uint8_t CC, ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smithb9e045a2015-07-24 20:56:36 +00001004 : DIType(C, DISubroutineTypeKind, Storage, dwarf::DW_TAG_subroutine_type,
Reid Klecknerde3d8b52016-06-08 20:34:29 +00001005 0, 0, 0, 0, Flags, Ops),
1006 CC(CC) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001007 ~DISubroutineType() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001008
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001009 static DISubroutineType *getImpl(LLVMContext &Context, DIFlags Flags,
Reid Klecknerde3d8b52016-06-08 20:34:29 +00001010 uint8_t CC, DITypeRefArray TypeArray,
Duncan P. N. Exon Smith11344732015-04-07 16:50:39 +00001011 StorageType Storage,
1012 bool ShouldCreate = true) {
Reid Klecknerde3d8b52016-06-08 20:34:29 +00001013 return getImpl(Context, Flags, CC, TypeArray.get(), Storage, ShouldCreate);
Duncan P. N. Exon Smith11344732015-04-07 16:50:39 +00001014 }
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001015 static DISubroutineType *getImpl(LLVMContext &Context, DIFlags Flags,
Reid Klecknerde3d8b52016-06-08 20:34:29 +00001016 uint8_t CC, Metadata *TypeArray,
1017 StorageType Storage,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001018 bool ShouldCreate = true);
1019
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001020 TempDISubroutineType cloneImpl() const {
Reid Klecknerde3d8b52016-06-08 20:34:29 +00001021 return getTemporary(getContext(), getFlags(), getCC(), getTypeArray());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001022 }
1023
1024public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001025 DEFINE_MDNODE_GET(DISubroutineType,
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001026 (DIFlags Flags, uint8_t CC, DITypeRefArray TypeArray),
Reid Klecknerde3d8b52016-06-08 20:34:29 +00001027 (Flags, CC, TypeArray))
1028 DEFINE_MDNODE_GET(DISubroutineType,
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001029 (DIFlags Flags, uint8_t CC, Metadata *TypeArray),
Reid Klecknerde3d8b52016-06-08 20:34:29 +00001030 (Flags, CC, TypeArray))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001031
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001032 TempDISubroutineType clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001033
Reid Klecknerde3d8b52016-06-08 20:34:29 +00001034 uint8_t getCC() const { return CC; }
1035
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001036 DITypeRefArray getTypeArray() const {
Duncan P. N. Exon Smith11344732015-04-07 16:50:39 +00001037 return cast_or_null<MDTuple>(getRawTypeArray());
1038 }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +00001039
Duncan P. N. Exon Smithb9e045a2015-07-24 20:56:36 +00001040 Metadata *getRawTypeArray() const { return getOperand(3); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001041
1042 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001043 return MD->getMetadataID() == DISubroutineTypeKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001044 }
1045};
1046
Adrian Prantl1687e012016-11-14 22:09:18 +00001047/// Compile unit.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001048class DICompileUnit : public DIScope {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001049 friend class LLVMContextImpl;
1050 friend class MDNode;
Eugene Zelenko1aa40f42016-11-23 22:25:16 +00001051
Adrian Prantlb939a252016-03-31 23:56:58 +00001052public:
1053 enum DebugEmissionKind : unsigned {
1054 NoDebug = 0,
1055 FullDebug,
1056 LineTablesOnly,
1057 LastEmissionKind = LineTablesOnly
1058 };
Eugene Zelenko1aa40f42016-11-23 22:25:16 +00001059
Adrian Prantlb939a252016-03-31 23:56:58 +00001060 static Optional<DebugEmissionKind> getEmissionKind(StringRef Str);
1061 static const char *EmissionKindString(DebugEmissionKind EK);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001062
Adrian Prantlb939a252016-03-31 23:56:58 +00001063private:
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001064 unsigned SourceLanguage;
1065 bool IsOptimized;
1066 unsigned RuntimeVersion;
1067 unsigned EmissionKind;
Adrian Prantl1f599f92015-05-21 20:37:30 +00001068 uint64_t DWOId;
David Blaikiea01f2952016-08-24 18:29:49 +00001069 bool SplitDebugInlining;
Dehao Chen0944a8c2017-02-01 22:45:09 +00001070 bool DebugInfoForProfiling;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001071
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001072 DICompileUnit(LLVMContext &C, StorageType Storage, unsigned SourceLanguage,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001073 bool IsOptimized, unsigned RuntimeVersion,
David Blaikiea01f2952016-08-24 18:29:49 +00001074 unsigned EmissionKind, uint64_t DWOId, bool SplitDebugInlining,
Dehao Chen0944a8c2017-02-01 22:45:09 +00001075 bool DebugInfoForProfiling, ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001076 : DIScope(C, DICompileUnitKind, Storage, dwarf::DW_TAG_compile_unit, Ops),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001077 SourceLanguage(SourceLanguage), IsOptimized(IsOptimized),
Adrian Prantl1f599f92015-05-21 20:37:30 +00001078 RuntimeVersion(RuntimeVersion), EmissionKind(EmissionKind),
Dehao Chen0944a8c2017-02-01 22:45:09 +00001079 DWOId(DWOId), SplitDebugInlining(SplitDebugInlining),
1080 DebugInfoForProfiling(DebugInfoForProfiling) {
Duncan P. N. Exon Smith55ca9642015-08-03 17:26:41 +00001081 assert(Storage != Uniqued);
1082 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001083 ~DICompileUnit() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001084
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001085 static DICompileUnit *
1086 getImpl(LLVMContext &Context, unsigned SourceLanguage, DIFile *File,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001087 StringRef Producer, bool IsOptimized, StringRef Flags,
1088 unsigned RuntimeVersion, StringRef SplitDebugFilename,
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001089 unsigned EmissionKind, DICompositeTypeArray EnumTypes,
Adrian Prantlbceaaa92016-12-20 02:09:43 +00001090 DIScopeArray RetainedTypes,
1091 DIGlobalVariableExpressionArray GlobalVariables,
Amjad Abouda9bcf162015-12-10 12:56:35 +00001092 DIImportedEntityArray ImportedEntities, DIMacroNodeArray Macros,
Dehao Chen0944a8c2017-02-01 22:45:09 +00001093 uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling,
1094 StorageType Storage, bool ShouldCreate = true) {
David Blaikiea01f2952016-08-24 18:29:49 +00001095 return getImpl(Context, SourceLanguage, File,
1096 getCanonicalMDString(Context, Producer), IsOptimized,
1097 getCanonicalMDString(Context, Flags), RuntimeVersion,
1098 getCanonicalMDString(Context, SplitDebugFilename),
1099 EmissionKind, EnumTypes.get(), RetainedTypes.get(),
1100 GlobalVariables.get(), ImportedEntities.get(), Macros.get(),
Dehao Chen0944a8c2017-02-01 22:45:09 +00001101 DWOId, SplitDebugInlining, DebugInfoForProfiling, Storage,
1102 ShouldCreate);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001103 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001104 static DICompileUnit *
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001105 getImpl(LLVMContext &Context, unsigned SourceLanguage, Metadata *File,
1106 MDString *Producer, bool IsOptimized, MDString *Flags,
1107 unsigned RuntimeVersion, MDString *SplitDebugFilename,
Adrian Prantl75819ae2016-04-15 15:57:41 +00001108 unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes,
Adrian Prantlb939a252016-03-31 23:56:58 +00001109 Metadata *GlobalVariables, Metadata *ImportedEntities,
David Blaikiea01f2952016-08-24 18:29:49 +00001110 Metadata *Macros, uint64_t DWOId, bool SplitDebugInlining,
Dehao Chen0944a8c2017-02-01 22:45:09 +00001111 bool DebugInfoForProfiling, StorageType Storage,
1112 bool ShouldCreate = true);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001113
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001114 TempDICompileUnit cloneImpl() const {
David Blaikiea01f2952016-08-24 18:29:49 +00001115 return getTemporary(getContext(), getSourceLanguage(), getFile(),
1116 getProducer(), isOptimized(), getFlags(),
1117 getRuntimeVersion(), getSplitDebugFilename(),
1118 getEmissionKind(), getEnumTypes(), getRetainedTypes(),
1119 getGlobalVariables(), getImportedEntities(),
Dehao Chen0944a8c2017-02-01 22:45:09 +00001120 getMacros(), DWOId, getSplitDebugInlining(),
1121 getDebugInfoForProfiling());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001122 }
1123
Eugene Zelenko1aa40f42016-11-23 22:25:16 +00001124public:
Duncan P. N. Exon Smith55ca9642015-08-03 17:26:41 +00001125 static void get() = delete;
1126 static void getIfExists() = delete;
1127
Duncan P. N. Exon Smith55ca9642015-08-03 17:26:41 +00001128 DEFINE_MDNODE_GET_DISTINCT_TEMPORARY(
1129 DICompileUnit,
1130 (unsigned SourceLanguage, DIFile *File, StringRef Producer,
1131 bool IsOptimized, StringRef Flags, unsigned RuntimeVersion,
Adrian Prantlb939a252016-03-31 23:56:58 +00001132 StringRef SplitDebugFilename, DebugEmissionKind EmissionKind,
Adrian Prantl75819ae2016-04-15 15:57:41 +00001133 DICompositeTypeArray EnumTypes, DIScopeArray RetainedTypes,
Adrian Prantlbceaaa92016-12-20 02:09:43 +00001134 DIGlobalVariableExpressionArray GlobalVariables,
Amjad Abouda9bcf162015-12-10 12:56:35 +00001135 DIImportedEntityArray ImportedEntities, DIMacroNodeArray Macros,
Dehao Chen0944a8c2017-02-01 22:45:09 +00001136 uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling),
Duncan P. N. Exon Smith55ca9642015-08-03 17:26:41 +00001137 (SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion,
Adrian Prantl75819ae2016-04-15 15:57:41 +00001138 SplitDebugFilename, EmissionKind, EnumTypes, RetainedTypes,
Dehao Chen0944a8c2017-02-01 22:45:09 +00001139 GlobalVariables, ImportedEntities, Macros, DWOId, SplitDebugInlining,
1140 DebugInfoForProfiling))
Duncan P. N. Exon Smith55ca9642015-08-03 17:26:41 +00001141 DEFINE_MDNODE_GET_DISTINCT_TEMPORARY(
Adrian Prantl1f599f92015-05-21 20:37:30 +00001142 DICompileUnit,
1143 (unsigned SourceLanguage, Metadata *File, MDString *Producer,
1144 bool IsOptimized, MDString *Flags, unsigned RuntimeVersion,
1145 MDString *SplitDebugFilename, unsigned EmissionKind, Metadata *EnumTypes,
Adrian Prantl75819ae2016-04-15 15:57:41 +00001146 Metadata *RetainedTypes, Metadata *GlobalVariables,
David Blaikiea01f2952016-08-24 18:29:49 +00001147 Metadata *ImportedEntities, Metadata *Macros, uint64_t DWOId,
Dehao Chen0944a8c2017-02-01 22:45:09 +00001148 bool SplitDebugInlining, bool DebugInfoForProfiling),
Adrian Prantl1f599f92015-05-21 20:37:30 +00001149 (SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion,
Adrian Prantl75819ae2016-04-15 15:57:41 +00001150 SplitDebugFilename, EmissionKind, EnumTypes, RetainedTypes,
Dehao Chen0944a8c2017-02-01 22:45:09 +00001151 GlobalVariables, ImportedEntities, Macros, DWOId, SplitDebugInlining,
1152 DebugInfoForProfiling))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001153
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001154 TempDICompileUnit clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001155
1156 unsigned getSourceLanguage() const { return SourceLanguage; }
1157 bool isOptimized() const { return IsOptimized; }
1158 unsigned getRuntimeVersion() const { return RuntimeVersion; }
Adrian Prantlb939a252016-03-31 23:56:58 +00001159 DebugEmissionKind getEmissionKind() const {
1160 return (DebugEmissionKind)EmissionKind;
1161 }
Dehao Chen0944a8c2017-02-01 22:45:09 +00001162 bool getDebugInfoForProfiling() const { return DebugInfoForProfiling; }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001163 StringRef getProducer() const { return getStringOperand(1); }
1164 StringRef getFlags() const { return getStringOperand(2); }
1165 StringRef getSplitDebugFilename() const { return getStringOperand(3); }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001166 DICompositeTypeArray getEnumTypes() const {
Duncan P. N. Exon Smith53855f02015-03-27 23:05:04 +00001167 return cast_or_null<MDTuple>(getRawEnumTypes());
1168 }
Adrian Prantl75819ae2016-04-15 15:57:41 +00001169 DIScopeArray getRetainedTypes() const {
Duncan P. N. Exon Smith53855f02015-03-27 23:05:04 +00001170 return cast_or_null<MDTuple>(getRawRetainedTypes());
1171 }
Adrian Prantlbceaaa92016-12-20 02:09:43 +00001172 DIGlobalVariableExpressionArray getGlobalVariables() const {
Duncan P. N. Exon Smith53855f02015-03-27 23:05:04 +00001173 return cast_or_null<MDTuple>(getRawGlobalVariables());
1174 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001175 DIImportedEntityArray getImportedEntities() const {
Duncan P. N. Exon Smith53855f02015-03-27 23:05:04 +00001176 return cast_or_null<MDTuple>(getRawImportedEntities());
1177 }
Amjad Abouda9bcf162015-12-10 12:56:35 +00001178 DIMacroNodeArray getMacros() const {
1179 return cast_or_null<MDTuple>(getRawMacros());
1180 }
Adrian Prantlfbfc58e2015-09-22 23:21:03 +00001181 uint64_t getDWOId() const { return DWOId; }
Adrian Prantl44103922015-09-22 23:21:06 +00001182 void setDWOId(uint64_t DwoId) { DWOId = DwoId; }
David Blaikiea01f2952016-08-24 18:29:49 +00001183 bool getSplitDebugInlining() const { return SplitDebugInlining; }
1184 void setSplitDebugInlining(bool SplitDebugInlining) {
1185 this->SplitDebugInlining = SplitDebugInlining;
1186 }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001187
Duncan P. N. Exon Smithc1f1acc2015-02-13 01:25:10 +00001188 MDString *getRawProducer() const { return getOperandAs<MDString>(1); }
1189 MDString *getRawFlags() const { return getOperandAs<MDString>(2); }
1190 MDString *getRawSplitDebugFilename() const {
1191 return getOperandAs<MDString>(3);
1192 }
Duncan P. N. Exon Smith53855f02015-03-27 23:05:04 +00001193 Metadata *getRawEnumTypes() const { return getOperand(4); }
1194 Metadata *getRawRetainedTypes() const { return getOperand(5); }
Adrian Prantl75819ae2016-04-15 15:57:41 +00001195 Metadata *getRawGlobalVariables() const { return getOperand(6); }
1196 Metadata *getRawImportedEntities() const { return getOperand(7); }
1197 Metadata *getRawMacros() const { return getOperand(8); }
Duncan P. N. Exon Smithc1f1acc2015-02-13 01:25:10 +00001198
Adrian Prantl1687e012016-11-14 22:09:18 +00001199 /// Replace arrays.
Duncan P. N. Exon Smith94bbbf02015-02-18 20:36:09 +00001200 ///
1201 /// If this \a isUniqued() and not \a isResolved(), it will be RAUW'ed and
1202 /// deleted on a uniquing collision. In practice, uniquing collisions on \a
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001203 /// DICompileUnit should be fairly rare.
Duncan P. N. Exon Smith94bbbf02015-02-18 20:36:09 +00001204 /// @{
Adrian Prantl4afc1f42015-07-06 16:22:07 +00001205 void replaceEnumTypes(DICompositeTypeArray N) {
Adrian Prantl18c073a2015-07-02 22:32:52 +00001206 replaceOperandWith(4, N.get());
1207 }
Adrian Prantl4afc1f42015-07-06 16:22:07 +00001208 void replaceRetainedTypes(DITypeArray N) {
Adrian Prantl18c073a2015-07-02 22:32:52 +00001209 replaceOperandWith(5, N.get());
1210 }
Adrian Prantlbceaaa92016-12-20 02:09:43 +00001211 void replaceGlobalVariables(DIGlobalVariableExpressionArray N) {
Duncan P. N. Exon Smith11344732015-04-07 16:50:39 +00001212 replaceOperandWith(6, N.get());
1213 }
Adrian Prantl75819ae2016-04-15 15:57:41 +00001214 void replaceImportedEntities(DIImportedEntityArray N) {
Duncan P. N. Exon Smith11344732015-04-07 16:50:39 +00001215 replaceOperandWith(7, N.get());
1216 }
Adrian Prantl75819ae2016-04-15 15:57:41 +00001217 void replaceMacros(DIMacroNodeArray N) { replaceOperandWith(8, N.get()); }
Duncan P. N. Exon Smith94bbbf02015-02-18 20:36:09 +00001218 /// @}
1219
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001220 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001221 return MD->getMetadataID() == DICompileUnitKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001222 }
1223};
1224
Adrian Prantl1687e012016-11-14 22:09:18 +00001225/// A scope for locals.
Duncan P. N. Exon Smitha65159a2015-03-24 16:44:29 +00001226///
1227/// A legal scope for lexical blocks, local variables, and debug info
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001228/// locations. Subclasses are \a DISubprogram, \a DILexicalBlock, and \a
1229/// DILexicalBlockFile.
1230class DILocalScope : public DIScope {
Duncan P. N. Exon Smitha65159a2015-03-24 16:44:29 +00001231protected:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001232 DILocalScope(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
Duncan P. N. Exon Smitha65159a2015-03-24 16:44:29 +00001233 ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001234 : DIScope(C, ID, Storage, Tag, Ops) {}
1235 ~DILocalScope() = default;
Duncan P. N. Exon Smitha65159a2015-03-24 16:44:29 +00001236
1237public:
Adrian Prantl1687e012016-11-14 22:09:18 +00001238 /// Get the subprogram for this scope.
Duncan P. N. Exon Smithfd07a2a2015-03-30 21:32:28 +00001239 ///
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001240 /// Return this if it's an \a DISubprogram; otherwise, look up the scope
Duncan P. N. Exon Smithfd07a2a2015-03-30 21:32:28 +00001241 /// chain.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001242 DISubprogram *getSubprogram() const;
Duncan P. N. Exon Smithfd07a2a2015-03-30 21:32:28 +00001243
Amjad Abouda5ba9912016-04-21 16:58:49 +00001244 /// Get the first non DILexicalBlockFile scope of this scope.
1245 ///
1246 /// Return this if it's not a \a DILexicalBlockFIle; otherwise, look up the
1247 /// scope chain.
1248 DILocalScope *getNonLexicalBlockFileScope() const;
1249
Duncan P. N. Exon Smitha65159a2015-03-24 16:44:29 +00001250 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001251 return MD->getMetadataID() == DISubprogramKind ||
1252 MD->getMetadataID() == DILexicalBlockKind ||
1253 MD->getMetadataID() == DILexicalBlockFileKind;
Duncan P. N. Exon Smitha65159a2015-03-24 16:44:29 +00001254 }
1255};
1256
Adrian Prantl1687e012016-11-14 22:09:18 +00001257/// Debug location.
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001258///
1259/// A debug location in source code, used for debug info and otherwise.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001260class DILocation : public MDNode {
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001261 friend class LLVMContextImpl;
1262 friend class MDNode;
1263
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001264 DILocation(LLVMContext &C, StorageType Storage, unsigned Line,
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001265 unsigned Column, ArrayRef<Metadata *> MDs);
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001266 ~DILocation() { dropAllReferences(); }
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001267
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001268 static DILocation *getImpl(LLVMContext &Context, unsigned Line,
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001269 unsigned Column, Metadata *Scope,
1270 Metadata *InlinedAt, StorageType Storage,
1271 bool ShouldCreate = true);
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001272 static DILocation *getImpl(LLVMContext &Context, unsigned Line,
1273 unsigned Column, DILocalScope *Scope,
1274 DILocation *InlinedAt, StorageType Storage,
Duncan P. N. Exon Smith26489982015-03-26 22:05:04 +00001275 bool ShouldCreate = true) {
1276 return getImpl(Context, Line, Column, static_cast<Metadata *>(Scope),
1277 static_cast<Metadata *>(InlinedAt), Storage, ShouldCreate);
1278 }
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001279
Dehao Chen726da622017-02-15 17:54:39 +00001280 /// With a given unsigned int \p U, use up to 13 bits to represent it.
1281 /// old_bit 1~5 --> new_bit 1~5
1282 /// old_bit 6~12 --> new_bit 7~13
1283 /// new_bit_6 is 0 if higher bits (7~13) are all 0
1284 static unsigned getPrefixEncodingFromUnsigned(unsigned U) {
1285 U &= 0xfff;
1286 return U > 0x1f ? (((U & 0xfe0) << 1) | (U & 0x1f) | 0x20) : U;
1287 }
1288
1289 /// Reverse transformation as getPrefixEncodingFromUnsigned.
1290 static unsigned getUnsignedFromPrefixEncoding(unsigned U) {
1291 return (U & 0x20) ? (((U >> 1) & 0xfe0) | (U & 0x1f)) : (U & 0x1f);
1292 }
1293
1294 /// Returns the next component stored in discriminator.
1295 static unsigned getNextComponentInDiscriminator(unsigned D) {
1296 if ((D & 1) == 0)
1297 return D >> ((D & 0x40) ? 14 : 7);
1298 else
1299 return D >> 1;
1300 }
1301
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001302 TempDILocation cloneImpl() const {
Teresa Johnsond98152b62015-12-07 15:05:44 +00001303 // Get the raw scope/inlinedAt since it is possible to invoke this on
1304 // a DILocation containing temporary metadata.
1305 return getTemporary(getContext(), getLine(), getColumn(), getRawScope(),
1306 getRawInlinedAt());
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001307 }
1308
Eugene Zelenko1aa40f42016-11-23 22:25:16 +00001309public:
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001310 // Disallow replacing operands.
1311 void replaceOperandWith(unsigned I, Metadata *New) = delete;
1312
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001313 DEFINE_MDNODE_GET(DILocation,
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001314 (unsigned Line, unsigned Column, Metadata *Scope,
1315 Metadata *InlinedAt = nullptr),
1316 (Line, Column, Scope, InlinedAt))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001317 DEFINE_MDNODE_GET(DILocation,
1318 (unsigned Line, unsigned Column, DILocalScope *Scope,
1319 DILocation *InlinedAt = nullptr),
Duncan P. N. Exon Smith26489982015-03-26 22:05:04 +00001320 (Line, Column, Scope, InlinedAt))
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001321
Adrian Prantl1687e012016-11-14 22:09:18 +00001322 /// Return a (temporary) clone of this.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001323 TempDILocation clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001324
1325 unsigned getLine() const { return SubclassData32; }
1326 unsigned getColumn() const { return SubclassData16; }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001327 DILocalScope *getScope() const { return cast<DILocalScope>(getRawScope()); }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +00001328
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001329 DILocation *getInlinedAt() const {
1330 return cast_or_null<DILocation>(getRawInlinedAt());
Duncan P. N. Exon Smith26489982015-03-26 22:05:04 +00001331 }
1332
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001333 DIFile *getFile() const { return getScope()->getFile(); }
Duncan P. N. Exon Smith50c065b2015-04-11 00:39:43 +00001334 StringRef getFilename() const { return getScope()->getFilename(); }
1335 StringRef getDirectory() const { return getScope()->getDirectory(); }
1336
Adrian Prantl1687e012016-11-14 22:09:18 +00001337 /// Get the scope where this is inlined.
Duncan P. N. Exon Smith8f7bc792015-03-30 17:41:24 +00001338 ///
1339 /// Walk through \a getInlinedAt() and return \a getScope() from the deepest
1340 /// location.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001341 DILocalScope *getInlinedAtScope() const {
Duncan P. N. Exon Smith8f7bc792015-03-30 17:41:24 +00001342 if (auto *IA = getInlinedAt())
1343 return IA->getInlinedAtScope();
1344 return getScope();
1345 }
1346
Adrian Prantl1687e012016-11-14 22:09:18 +00001347 /// Check whether this can be discriminated from another location.
Duncan P. N. Exon Smith63ffa212015-04-11 01:00:47 +00001348 ///
1349 /// Check \c this can be discriminated from \c RHS in a linetable entry.
1350 /// Scope and inlined-at chains are not recorded in the linetable, so they
1351 /// cannot be used to distinguish basic blocks.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001352 bool canDiscriminate(const DILocation &RHS) const {
Robert Lougher426851e2017-01-12 20:34:35 +00001353 return getLine() != RHS.getLine() ||
1354 getColumn() != RHS.getColumn() ||
1355 getDiscriminator() != RHS.getDiscriminator() ||
1356 getFilename() != RHS.getFilename() ||
1357 getDirectory() != RHS.getDirectory();
Duncan P. N. Exon Smith63ffa212015-04-11 01:00:47 +00001358 }
1359
Adrian Prantl1687e012016-11-14 22:09:18 +00001360 /// Get the DWARF discriminator.
Duncan P. N. Exon Smith2c8291e2015-04-14 00:05:13 +00001361 ///
1362 /// DWARF discriminators distinguish identical file locations between
1363 /// instructions that are on different basic blocks.
Dehao Chenfb02f712017-02-10 21:09:07 +00001364 ///
1365 /// There are 3 components stored in discriminator, from lower bits:
1366 ///
1367 /// Base discriminator: assigned by AddDiscriminators pass to identify IRs
1368 /// that are defined by the same source line, but
1369 /// different basic blocks.
1370 /// Duplication factor: assigned by optimizations that will scale down
1371 /// the execution frequency of the original IR.
1372 /// Copy Identifier: assigned by optimizations that clones the IR.
1373 /// Each copy of the IR will be assigned an identifier.
1374 ///
1375 /// Encoding:
1376 ///
1377 /// The above 3 components are encoded into a 32bit unsigned integer in
1378 /// order. If the lowest bit is 1, the current component is empty, and the
1379 /// next component will start in the next bit. Otherwise, the the current
1380 /// component is non-empty, and its content starts in the next bit. The
1381 /// length of each components is either 5 bit or 12 bit: if the 7th bit
1382 /// is 0, the bit 2~6 (5 bits) are used to represent the component; if the
1383 /// 7th bit is 1, the bit 2~6 (5 bits) and 8~14 (7 bits) are combined to
1384 /// represent the component.
1385
Duncan P. N. Exon Smith2c8291e2015-04-14 00:05:13 +00001386 inline unsigned getDiscriminator() const;
1387
Dehao Chene7130002016-10-26 15:48:45 +00001388 /// Returns a new DILocation with updated \p Discriminator.
Dehao Chenfb02f712017-02-10 21:09:07 +00001389 inline const DILocation *cloneWithDiscriminator(unsigned Discriminator) const;
1390
1391 /// Returns a new DILocation with updated base discriminator \p BD.
1392 inline const DILocation *setBaseDiscriminator(unsigned BD) const;
1393
1394 /// Returns the duplication factor stored in the discriminator.
1395 inline unsigned getDuplicationFactor() const;
1396
1397 /// Returns the copy identifier stored in the discriminator.
1398 inline unsigned getCopyIdentifier() const;
1399
1400 /// Returns the base discriminator stored in the discriminator.
1401 inline unsigned getBaseDiscriminator() const;
1402
1403 /// Returns a new DILocation with duplication factor \p DF encoded in the
1404 /// discriminator.
1405 inline const DILocation *cloneWithDuplicationFactor(unsigned DF) const;
Dehao Chene7130002016-10-26 15:48:45 +00001406
Robert Lougher7bd04e32016-12-14 16:14:17 +00001407 /// When two instructions are combined into a single instruction we also
1408 /// need to combine the original locations into a single location.
1409 ///
1410 /// When the locations are the same we can use either location. When they
1411 /// differ, we need a third location which is distinct from either. If
1412 /// they have the same file/line but have a different discriminator we
1413 /// could create a location with a new discriminator. If they are from
1414 /// different files/lines the location is ambiguous and can't be
1415 /// represented in a single line entry. In this case, no location
1416 /// should be set.
1417 ///
Robert Lougher426851e2017-01-12 20:34:35 +00001418 /// Currently the function does not create a new location. If the locations
1419 /// are the same, or cannot be discriminated, the first location is returned.
1420 /// Otherwise an empty location will be used.
1421 static const DILocation *getMergedLocation(const DILocation *LocA,
1422 const DILocation *LocB) {
1423 if (LocA && LocB && (LocA == LocB || !LocA->canDiscriminate(*LocB)))
1424 return LocA;
Robert Lougher7bd04e32016-12-14 16:14:17 +00001425 return nullptr;
1426 }
1427
Dehao Chen726da622017-02-15 17:54:39 +00001428 /// Returns the base discriminator for a given encoded discriminator \p D.
1429 static unsigned getBaseDiscriminatorFromDiscriminator(unsigned D) {
1430 if ((D & 1) == 0)
1431 return getUnsignedFromPrefixEncoding(D >> 1);
1432 else
1433 return 0;
1434 }
1435
1436 /// Returns the duplication factor for a given encoded discriminator \p D.
1437 static unsigned getDuplicationFactorFromDiscriminator(unsigned D) {
1438 D = getNextComponentInDiscriminator(D);
1439 if (D == 0 || (D & 1))
1440 return 1;
1441 else
1442 return getUnsignedFromPrefixEncoding(D >> 1);
1443 }
1444
1445 /// Returns the copy identifier for a given encoded discriminator \p D.
1446 static unsigned getCopyIdentifierFromDiscriminator(unsigned D) {
1447 return getUnsignedFromPrefixEncoding(getNextComponentInDiscriminator(
1448 getNextComponentInDiscriminator(D)));
1449 }
1450
1451
Duncan P. N. Exon Smith26489982015-03-26 22:05:04 +00001452 Metadata *getRawScope() const { return getOperand(0); }
1453 Metadata *getRawInlinedAt() const {
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001454 if (getNumOperands() == 2)
1455 return getOperand(1);
1456 return nullptr;
1457 }
1458
1459 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001460 return MD->getMetadataID() == DILocationKind;
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001461 }
1462};
1463
Adrian Prantl1687e012016-11-14 22:09:18 +00001464/// Subprogram description.
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001465///
1466/// TODO: Remove DisplayName. It's always equal to Name.
1467/// TODO: Split up flags.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001468class DISubprogram : public DILocalScope {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001469 friend class LLVMContextImpl;
1470 friend class MDNode;
1471
1472 unsigned Line;
1473 unsigned ScopeLine;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001474 unsigned VirtualIndex;
Davide Italiano236e7442016-04-13 20:17:42 +00001475
Reid Klecknerb5af11d2016-07-01 02:41:21 +00001476 /// In the MS ABI, the implicit 'this' parameter is adjusted in the prologue
1477 /// of method overrides from secondary bases by this amount. It may be
1478 /// negative.
1479 int ThisAdjustment;
1480
Davide Italiano236e7442016-04-13 20:17:42 +00001481 // Virtuality can only assume three values, so we can pack
1482 // in 2 bits (none/pure/pure_virtual).
1483 unsigned Virtuality : 2;
1484
Davide Italiano236e7442016-04-13 20:17:42 +00001485 // These are boolean flags so one bit is enough.
1486 // MSVC starts a new container field every time the base
1487 // type changes so we can't use 'bool' to ensure these bits
1488 // are packed.
1489 unsigned IsLocalToUnit : 1;
1490 unsigned IsDefinition : 1;
1491 unsigned IsOptimized : 1;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001492
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001493 unsigned Padding : 3;
1494
1495 DIFlags Flags;
1496
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001497 DISubprogram(LLVMContext &C, StorageType Storage, unsigned Line,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001498 unsigned ScopeLine, unsigned Virtuality, unsigned VirtualIndex,
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001499 int ThisAdjustment, DIFlags Flags, bool IsLocalToUnit,
Reid Klecknerb5af11d2016-07-01 02:41:21 +00001500 bool IsDefinition, bool IsOptimized, ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001501 : DILocalScope(C, DISubprogramKind, Storage, dwarf::DW_TAG_subprogram,
Duncan P. N. Exon Smitha65159a2015-03-24 16:44:29 +00001502 Ops),
Davide Italiano236e7442016-04-13 20:17:42 +00001503 Line(Line), ScopeLine(ScopeLine), VirtualIndex(VirtualIndex),
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001504 ThisAdjustment(ThisAdjustment), Virtuality(Virtuality),
Reid Klecknerb5af11d2016-07-01 02:41:21 +00001505 IsLocalToUnit(IsLocalToUnit), IsDefinition(IsDefinition),
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001506 IsOptimized(IsOptimized), Flags(Flags) {
Davide Italiano236e7442016-04-13 20:17:42 +00001507 static_assert(dwarf::DW_VIRTUALITY_max < 4, "Virtuality out of range");
1508 assert(Virtuality < 4 && "Virtuality out of range");
Davide Italiano236e7442016-04-13 20:17:42 +00001509 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001510 ~DISubprogram() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001511
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001512 static DISubprogram *
1513 getImpl(LLVMContext &Context, DIScopeRef Scope, StringRef Name,
1514 StringRef LinkageName, DIFile *File, unsigned Line,
1515 DISubroutineType *Type, bool IsLocalToUnit, bool IsDefinition,
1516 unsigned ScopeLine, DITypeRef ContainingType, unsigned Virtuality,
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001517 unsigned VirtualIndex, int ThisAdjustment, DIFlags Flags,
Reid Klecknerb5af11d2016-07-01 02:41:21 +00001518 bool IsOptimized, DICompileUnit *Unit,
1519 DITemplateParameterArray TemplateParams, DISubprogram *Declaration,
Adrian Prantl1d12b882017-04-26 22:56:44 +00001520 DILocalVariableArray Variables, DITypeArray ThrownTypes,
1521 StorageType Storage, bool ShouldCreate = true) {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001522 return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
1523 getCanonicalMDString(Context, LinkageName), File, Line, Type,
1524 IsLocalToUnit, IsDefinition, ScopeLine, ContainingType,
Reid Klecknerb5af11d2016-07-01 02:41:21 +00001525 Virtuality, VirtualIndex, ThisAdjustment, Flags, IsOptimized,
1526 Unit, TemplateParams.get(), Declaration, Variables.get(),
Adrian Prantl1d12b882017-04-26 22:56:44 +00001527 ThrownTypes.get(), Storage, ShouldCreate);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001528 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001529 static DISubprogram *
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001530 getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
1531 MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type,
1532 bool IsLocalToUnit, bool IsDefinition, unsigned ScopeLine,
1533 Metadata *ContainingType, unsigned Virtuality, unsigned VirtualIndex,
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001534 int ThisAdjustment, DIFlags Flags, bool IsOptimized, Metadata *Unit,
Adrian Prantl75819ae2016-04-15 15:57:41 +00001535 Metadata *TemplateParams, Metadata *Declaration, Metadata *Variables,
Adrian Prantl1d12b882017-04-26 22:56:44 +00001536 Metadata *ThrownTypes, StorageType Storage, bool ShouldCreate = true);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001537
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001538 TempDISubprogram cloneImpl() const {
Adrian Prantl1d12b882017-04-26 22:56:44 +00001539 return getTemporary(getContext(), getScope(), getName(), getLinkageName(),
1540 getFile(), getLine(), getType(), isLocalToUnit(),
1541 isDefinition(), getScopeLine(), getContainingType(),
1542 getVirtuality(), getVirtualIndex(), getThisAdjustment(),
1543 getFlags(), isOptimized(), getUnit(),
1544 getTemplateParams(), getDeclaration(), getVariables(),
1545 getThrownTypes());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001546 }
1547
1548public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001549 DEFINE_MDNODE_GET(DISubprogram,
1550 (DIScopeRef Scope, StringRef Name, StringRef LinkageName,
1551 DIFile *File, unsigned Line, DISubroutineType *Type,
Duncan P. N. Exon Smith3ec5fa62015-04-06 19:03:45 +00001552 bool IsLocalToUnit, bool IsDefinition, unsigned ScopeLine,
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001553 DITypeRef ContainingType, unsigned Virtuality,
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001554 unsigned VirtualIndex, int ThisAdjustment, DIFlags Flags,
Reid Klecknerb5af11d2016-07-01 02:41:21 +00001555 bool IsOptimized, DICompileUnit *Unit,
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001556 DITemplateParameterArray TemplateParams = nullptr,
1557 DISubprogram *Declaration = nullptr,
Adrian Prantl1d12b882017-04-26 22:56:44 +00001558 DILocalVariableArray Variables = nullptr,
1559 DITypeArray ThrownTypes = nullptr),
Duncan P. N. Exon Smith3ec5fa62015-04-06 19:03:45 +00001560 (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
1561 IsDefinition, ScopeLine, ContainingType, Virtuality,
Reid Klecknerb5af11d2016-07-01 02:41:21 +00001562 VirtualIndex, ThisAdjustment, Flags, IsOptimized, Unit,
Adrian Prantl1d12b882017-04-26 22:56:44 +00001563 TemplateParams, Declaration, Variables, ThrownTypes))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001564 DEFINE_MDNODE_GET(
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001565 DISubprogram,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001566 (Metadata * Scope, MDString *Name, MDString *LinkageName, Metadata *File,
1567 unsigned Line, Metadata *Type, bool IsLocalToUnit, bool IsDefinition,
1568 unsigned ScopeLine, Metadata *ContainingType, unsigned Virtuality,
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001569 unsigned VirtualIndex, int ThisAdjustment, DIFlags Flags,
Reid Klecknerb5af11d2016-07-01 02:41:21 +00001570 bool IsOptimized, Metadata *Unit, Metadata *TemplateParams = nullptr,
Adrian Prantl1d12b882017-04-26 22:56:44 +00001571 Metadata *Declaration = nullptr, Metadata *Variables = nullptr,
1572 Metadata *ThrownTypes = nullptr),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001573 (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition,
Reid Klecknerb5af11d2016-07-01 02:41:21 +00001574 ScopeLine, ContainingType, Virtuality, VirtualIndex, ThisAdjustment,
Adrian Prantl1d12b882017-04-26 22:56:44 +00001575 Flags, IsOptimized, Unit, TemplateParams, Declaration, Variables,
1576 ThrownTypes))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001577
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001578 TempDISubprogram clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001579
1580public:
1581 unsigned getLine() const { return Line; }
1582 unsigned getVirtuality() const { return Virtuality; }
1583 unsigned getVirtualIndex() const { return VirtualIndex; }
Reid Klecknerb5af11d2016-07-01 02:41:21 +00001584 int getThisAdjustment() const { return ThisAdjustment; }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001585 unsigned getScopeLine() const { return ScopeLine; }
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001586 DIFlags getFlags() const { return Flags; }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001587 bool isLocalToUnit() const { return IsLocalToUnit; }
1588 bool isDefinition() const { return IsDefinition; }
1589 bool isOptimized() const { return IsOptimized; }
1590
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001591 bool isArtificial() const { return getFlags() & FlagArtificial; }
Duncan P. N. Exon Smitha1384912015-04-07 03:33:57 +00001592 bool isPrivate() const {
1593 return (getFlags() & FlagAccessibility) == FlagPrivate;
1594 }
1595 bool isProtected() const {
1596 return (getFlags() & FlagAccessibility) == FlagProtected;
1597 }
1598 bool isPublic() const {
1599 return (getFlags() & FlagAccessibility) == FlagPublic;
1600 }
1601 bool isExplicit() const { return getFlags() & FlagExplicit; }
1602 bool isPrototyped() const { return getFlags() & FlagPrototyped; }
David Blaikiece3c8ef2016-11-28 21:32:19 +00001603 bool isMainSubprogram() const { return getFlags() & FlagMainSubprogram; }
Duncan P. N. Exon Smitha1384912015-04-07 03:33:57 +00001604
Adrian Prantl1687e012016-11-14 22:09:18 +00001605 /// Check if this is reference-qualified.
Duncan P. N. Exon Smitha1384912015-04-07 03:33:57 +00001606 ///
1607 /// Return true if this subprogram is a C++11 reference-qualified non-static
1608 /// member function (void foo() &).
Leny Kholodov40c62352016-09-06 17:03:02 +00001609 bool isLValueReference() const { return getFlags() & FlagLValueReference; }
Duncan P. N. Exon Smitha1384912015-04-07 03:33:57 +00001610
Adrian Prantl1687e012016-11-14 22:09:18 +00001611 /// Check if this is rvalue-reference-qualified.
Duncan P. N. Exon Smitha1384912015-04-07 03:33:57 +00001612 ///
1613 /// Return true if this subprogram is a C++11 rvalue-reference-qualified
1614 /// non-static member function (void foo() &&).
Leny Kholodov40c62352016-09-06 17:03:02 +00001615 bool isRValueReference() const { return getFlags() & FlagRValueReference; }
Duncan P. N. Exon Smitha1384912015-04-07 03:33:57 +00001616
Adrian Prantl1687e012016-11-14 22:09:18 +00001617 /// Check if this is marked as noreturn.
Adrian Prantlc19dee72016-08-17 16:02:43 +00001618 ///
1619 /// Return true if this subprogram is C++11 noreturn or C11 _Noreturn
Leny Kholodov40c62352016-09-06 17:03:02 +00001620 bool isNoReturn() const { return getFlags() & FlagNoReturn; }
Adrian Prantlc19dee72016-08-17 16:02:43 +00001621
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001622 DIScopeRef getScope() const { return DIScopeRef(getRawScope()); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001623
1624 StringRef getName() const { return getStringOperand(2); }
Adrian Prantl9d2f0192017-04-26 23:59:52 +00001625 StringRef getLinkageName() const { return getStringOperand(3); }
Duncan P. N. Exon Smith19fc5ed2015-02-13 01:26:47 +00001626
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001627 DISubroutineType *getType() const {
1628 return cast_or_null<DISubroutineType>(getRawType());
Duncan P. N. Exon Smith869db502015-03-30 16:19:15 +00001629 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001630 DITypeRef getContainingType() const {
1631 return DITypeRef(getRawContainingType());
Duncan P. N. Exon Smith3ec5fa62015-04-06 19:03:45 +00001632 }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001633
Adrian Prantl75819ae2016-04-15 15:57:41 +00001634 DICompileUnit *getUnit() const {
1635 return cast_or_null<DICompileUnit>(getRawUnit());
1636 }
Adrian Prantl9d2f0192017-04-26 23:59:52 +00001637 void replaceUnit(DICompileUnit *CU) { replaceOperandWith(5, CU); }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001638 DITemplateParameterArray getTemplateParams() const {
Duncan P. N. Exon Smith869db502015-03-30 16:19:15 +00001639 return cast_or_null<MDTuple>(getRawTemplateParams());
1640 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001641 DISubprogram *getDeclaration() const {
1642 return cast_or_null<DISubprogram>(getRawDeclaration());
Duncan P. N. Exon Smith869db502015-03-30 16:19:15 +00001643 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001644 DILocalVariableArray getVariables() const {
Duncan P. N. Exon Smith869db502015-03-30 16:19:15 +00001645 return cast_or_null<MDTuple>(getRawVariables());
1646 }
Adrian Prantl1d12b882017-04-26 22:56:44 +00001647 DITypeArray getThrownTypes() const {
1648 return cast_or_null<MDTuple>(getRawThrownTypes());
1649 }
Duncan P. N. Exon Smith869db502015-03-30 16:19:15 +00001650
1651 Metadata *getRawScope() const { return getOperand(1); }
Adrian Prantl9d2f0192017-04-26 23:59:52 +00001652 MDString *getRawName() const { return getOperandAs<MDString>(2); }
1653 MDString *getRawLinkageName() const { return getOperandAs<MDString>(3); }
1654 Metadata *getRawType() const { return getOperand(4); }
1655 Metadata *getRawUnit() const { return getOperand(5); }
1656 Metadata *getRawDeclaration() const { return getOperand(6); }
1657 Metadata *getRawVariables() const { return getOperand(7); }
1658 Metadata *getRawContainingType() const {
1659 return getNumOperands() > 8 ? getOperandAs<Metadata>(8) : nullptr;
1660 }
1661 Metadata *getRawTemplateParams() const {
1662 return getNumOperands() > 9 ? getOperandAs<Metadata>(9) : nullptr;
1663 }
1664 Metadata *getRawThrownTypes() const {
1665 return getNumOperands() > 10 ? getOperandAs<Metadata>(10) : nullptr;
1666 }
Duncan P. N. Exon Smithdf523492015-02-18 20:32:57 +00001667
Adrian Prantl1687e012016-11-14 22:09:18 +00001668 /// Check if this subprogram describes the given function.
Duncan P. N. Exon Smith3c2d7042015-04-13 19:07:27 +00001669 ///
1670 /// FIXME: Should this be looking through bitcasts?
1671 bool describes(const Function *F) const;
1672
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001673 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001674 return MD->getMetadataID() == DISubprogramKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001675 }
1676};
1677
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001678class DILexicalBlockBase : public DILocalScope {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001679protected:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001680 DILexicalBlockBase(LLVMContext &C, unsigned ID, StorageType Storage,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001681 ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001682 : DILocalScope(C, ID, Storage, dwarf::DW_TAG_lexical_block, Ops) {}
1683 ~DILexicalBlockBase() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001684
1685public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001686 DILocalScope *getScope() const { return cast<DILocalScope>(getRawScope()); }
Duncan P. N. Exon Smith0e202b92015-03-30 16:37:48 +00001687
1688 Metadata *getRawScope() const { return getOperand(1); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001689
1690 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001691 return MD->getMetadataID() == DILexicalBlockKind ||
1692 MD->getMetadataID() == DILexicalBlockFileKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001693 }
1694};
1695
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001696class DILexicalBlock : public DILexicalBlockBase {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001697 friend class LLVMContextImpl;
1698 friend class MDNode;
1699
1700 unsigned Line;
Duncan P. N. Exon Smithb09eb9f2015-08-28 22:58:50 +00001701 uint16_t Column;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001702
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001703 DILexicalBlock(LLVMContext &C, StorageType Storage, unsigned Line,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001704 unsigned Column, ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001705 : DILexicalBlockBase(C, DILexicalBlockKind, Storage, Ops), Line(Line),
Duncan P. N. Exon Smithb09eb9f2015-08-28 22:58:50 +00001706 Column(Column) {
1707 assert(Column < (1u << 16) && "Expected 16-bit column");
1708 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001709 ~DILexicalBlock() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001710
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001711 static DILexicalBlock *getImpl(LLVMContext &Context, DILocalScope *Scope,
1712 DIFile *File, unsigned Line, unsigned Column,
Duncan P. N. Exon Smith0e202b92015-03-30 16:37:48 +00001713 StorageType Storage,
1714 bool ShouldCreate = true) {
1715 return getImpl(Context, static_cast<Metadata *>(Scope),
1716 static_cast<Metadata *>(File), Line, Column, Storage,
1717 ShouldCreate);
1718 }
1719
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001720 static DILexicalBlock *getImpl(LLVMContext &Context, Metadata *Scope,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001721 Metadata *File, unsigned Line, unsigned Column,
1722 StorageType Storage, bool ShouldCreate = true);
1723
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001724 TempDILexicalBlock cloneImpl() const {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001725 return getTemporary(getContext(), getScope(), getFile(), getLine(),
1726 getColumn());
1727 }
1728
1729public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001730 DEFINE_MDNODE_GET(DILexicalBlock, (DILocalScope * Scope, DIFile *File,
Duncan P. N. Exon Smith0e202b92015-03-30 16:37:48 +00001731 unsigned Line, unsigned Column),
1732 (Scope, File, Line, Column))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001733 DEFINE_MDNODE_GET(DILexicalBlock, (Metadata * Scope, Metadata *File,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001734 unsigned Line, unsigned Column),
1735 (Scope, File, Line, Column))
1736
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001737 TempDILexicalBlock clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001738
1739 unsigned getLine() const { return Line; }
1740 unsigned getColumn() const { return Column; }
1741
1742 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001743 return MD->getMetadataID() == DILexicalBlockKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001744 }
1745};
1746
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001747class DILexicalBlockFile : public DILexicalBlockBase {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001748 friend class LLVMContextImpl;
1749 friend class MDNode;
1750
1751 unsigned Discriminator;
1752
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001753 DILexicalBlockFile(LLVMContext &C, StorageType Storage,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001754 unsigned Discriminator, ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001755 : DILexicalBlockBase(C, DILexicalBlockFileKind, Storage, Ops),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001756 Discriminator(Discriminator) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001757 ~DILexicalBlockFile() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001758
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001759 static DILexicalBlockFile *getImpl(LLVMContext &Context, DILocalScope *Scope,
1760 DIFile *File, unsigned Discriminator,
Duncan P. N. Exon Smith0e202b92015-03-30 16:37:48 +00001761 StorageType Storage,
1762 bool ShouldCreate = true) {
1763 return getImpl(Context, static_cast<Metadata *>(Scope),
1764 static_cast<Metadata *>(File), Discriminator, Storage,
1765 ShouldCreate);
1766 }
1767
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001768 static DILexicalBlockFile *getImpl(LLVMContext &Context, Metadata *Scope,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001769 Metadata *File, unsigned Discriminator,
1770 StorageType Storage,
1771 bool ShouldCreate = true);
1772
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001773 TempDILexicalBlockFile cloneImpl() const {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001774 return getTemporary(getContext(), getScope(), getFile(),
1775 getDiscriminator());
1776 }
1777
1778public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001779 DEFINE_MDNODE_GET(DILexicalBlockFile, (DILocalScope * Scope, DIFile *File,
Duncan P. N. Exon Smith0e202b92015-03-30 16:37:48 +00001780 unsigned Discriminator),
1781 (Scope, File, Discriminator))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001782 DEFINE_MDNODE_GET(DILexicalBlockFile,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001783 (Metadata * Scope, Metadata *File, unsigned Discriminator),
1784 (Scope, File, Discriminator))
1785
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001786 TempDILexicalBlockFile clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001787
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001788 // TODO: Remove these once they're gone from DILexicalBlockBase.
Duncan P. N. Exon Smith5f88ba12015-04-14 02:50:07 +00001789 unsigned getLine() const = delete;
1790 unsigned getColumn() const = delete;
1791
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001792 unsigned getDiscriminator() const { return Discriminator; }
1793
1794 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001795 return MD->getMetadataID() == DILexicalBlockFileKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001796 }
1797};
1798
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001799unsigned DILocation::getDiscriminator() const {
1800 if (auto *F = dyn_cast<DILexicalBlockFile>(getScope()))
Duncan P. N. Exon Smith2c8291e2015-04-14 00:05:13 +00001801 return F->getDiscriminator();
1802 return 0;
1803}
1804
Dehao Chenfb02f712017-02-10 21:09:07 +00001805const DILocation *
1806DILocation::cloneWithDiscriminator(unsigned Discriminator) const {
Dehao Chene7130002016-10-26 15:48:45 +00001807 DIScope *Scope = getScope();
1808 // Skip all parent DILexicalBlockFile that already have a discriminator
1809 // assigned. We do not want to have nested DILexicalBlockFiles that have
1810 // mutliple discriminators because only the leaf DILexicalBlockFile's
1811 // dominator will be used.
1812 for (auto *LBF = dyn_cast<DILexicalBlockFile>(Scope);
1813 LBF && LBF->getDiscriminator() != 0;
1814 LBF = dyn_cast<DILexicalBlockFile>(Scope))
1815 Scope = LBF->getScope();
1816 DILexicalBlockFile *NewScope =
1817 DILexicalBlockFile::get(getContext(), Scope, getFile(), Discriminator);
1818 return DILocation::get(getContext(), getLine(), getColumn(), NewScope,
1819 getInlinedAt());
1820}
1821
Dehao Chenfb02f712017-02-10 21:09:07 +00001822unsigned DILocation::getBaseDiscriminator() const {
Dehao Chen726da622017-02-15 17:54:39 +00001823 return getBaseDiscriminatorFromDiscriminator(getDiscriminator());
Dehao Chenfb02f712017-02-10 21:09:07 +00001824}
1825
1826unsigned DILocation::getDuplicationFactor() const {
Dehao Chen726da622017-02-15 17:54:39 +00001827 return getDuplicationFactorFromDiscriminator(getDiscriminator());
Dehao Chenfb02f712017-02-10 21:09:07 +00001828}
1829
1830unsigned DILocation::getCopyIdentifier() const {
Dehao Chen726da622017-02-15 17:54:39 +00001831 return getCopyIdentifierFromDiscriminator(getDiscriminator());
Dehao Chenfb02f712017-02-10 21:09:07 +00001832}
1833
1834const DILocation *DILocation::setBaseDiscriminator(unsigned D) const {
1835 if (D == 0)
1836 return this;
1837 else
1838 return cloneWithDiscriminator(getPrefixEncodingFromUnsigned(D) << 1);
1839}
1840
1841const DILocation *DILocation::cloneWithDuplicationFactor(unsigned DF) const {
1842 DF *= getDuplicationFactor();
1843 if (DF <= 1)
1844 return this;
1845
1846 unsigned BD = getBaseDiscriminator();
1847 unsigned CI = getCopyIdentifier() << (DF > 0x1f ? 14 : 7);
1848 unsigned D = CI | (getPrefixEncodingFromUnsigned(DF) << 1);
1849
1850 if (BD == 0)
1851 D = (D << 1) | 1;
1852 else
1853 D = (D << (BD > 0x1f ? 14 : 7)) | (getPrefixEncodingFromUnsigned(BD) << 1);
1854
1855 return cloneWithDiscriminator(D);
1856}
1857
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001858class DINamespace : public DIScope {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001859 friend class LLVMContextImpl;
1860 friend class MDNode;
1861
Adrian Prantldbfda632016-11-03 19:42:02 +00001862 unsigned ExportSymbols : 1;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001863
Adrian Prantlfed4f392017-04-28 22:25:46 +00001864 DINamespace(LLVMContext &Context, StorageType Storage, bool ExportSymbols,
1865 ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001866 : DIScope(Context, DINamespaceKind, Storage, dwarf::DW_TAG_namespace,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001867 Ops),
Adrian Prantlfed4f392017-04-28 22:25:46 +00001868 ExportSymbols(ExportSymbols) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001869 ~DINamespace() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001870
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001871 static DINamespace *getImpl(LLVMContext &Context, DIScope *Scope,
Adrian Prantlfed4f392017-04-28 22:25:46 +00001872 StringRef Name, bool ExportSymbols,
1873 StorageType Storage, bool ShouldCreate = true) {
1874 return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
1875 ExportSymbols, Storage, ShouldCreate);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001876 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001877 static DINamespace *getImpl(LLVMContext &Context, Metadata *Scope,
Adrian Prantlfed4f392017-04-28 22:25:46 +00001878 MDString *Name, bool ExportSymbols,
1879 StorageType Storage, bool ShouldCreate = true);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001880
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001881 TempDINamespace cloneImpl() const {
Adrian Prantlfed4f392017-04-28 22:25:46 +00001882 return getTemporary(getContext(), getScope(), getName(),
1883 getExportSymbols());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001884 }
1885
1886public:
Adrian Prantldbfda632016-11-03 19:42:02 +00001887 DEFINE_MDNODE_GET(DINamespace,
Adrian Prantlfed4f392017-04-28 22:25:46 +00001888 (DIScope *Scope, StringRef Name, bool ExportSymbols),
1889 (Scope, Name, ExportSymbols))
1890 DEFINE_MDNODE_GET(DINamespace,
1891 (Metadata *Scope, MDString *Name, bool ExportSymbols),
1892 (Scope, Name, ExportSymbols))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001893
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001894 TempDINamespace clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001895
Adrian Prantldbfda632016-11-03 19:42:02 +00001896 bool getExportSymbols() const { return ExportSymbols; }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001897 DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001898 StringRef getName() const { return getStringOperand(2); }
1899
Duncan P. N. Exon Smithf9b47752015-03-30 17:21:38 +00001900 Metadata *getRawScope() const { return getOperand(1); }
Duncan P. N. Exon Smithe1460002015-02-13 01:32:09 +00001901 MDString *getRawName() const { return getOperandAs<MDString>(2); }
1902
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001903 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001904 return MD->getMetadataID() == DINamespaceKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001905 }
1906};
1907
Adrian Prantl1687e012016-11-14 22:09:18 +00001908/// A (clang) module that has been imported by the compile unit.
Adrian Prantlab1243f2015-06-29 23:03:47 +00001909///
1910class DIModule : public DIScope {
1911 friend class LLVMContextImpl;
1912 friend class MDNode;
1913
1914 DIModule(LLVMContext &Context, StorageType Storage, ArrayRef<Metadata *> Ops)
1915 : DIScope(Context, DIModuleKind, Storage, dwarf::DW_TAG_module, Ops) {}
Eugene Zelenko1aa40f42016-11-23 22:25:16 +00001916 ~DIModule() = default;
Adrian Prantlab1243f2015-06-29 23:03:47 +00001917
1918 static DIModule *getImpl(LLVMContext &Context, DIScope *Scope,
1919 StringRef Name, StringRef ConfigurationMacros,
1920 StringRef IncludePath, StringRef ISysRoot,
1921 StorageType Storage, bool ShouldCreate = true) {
1922 return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
1923 getCanonicalMDString(Context, ConfigurationMacros),
NAKAMURA Takumiff35c332015-07-06 00:48:17 +00001924 getCanonicalMDString(Context, IncludePath),
1925 getCanonicalMDString(Context, ISysRoot),
Adrian Prantlab1243f2015-06-29 23:03:47 +00001926 Storage, ShouldCreate);
1927 }
1928 static DIModule *getImpl(LLVMContext &Context, Metadata *Scope,
1929 MDString *Name, MDString *ConfigurationMacros,
NAKAMURA Takumiff35c332015-07-06 00:48:17 +00001930 MDString *IncludePath, MDString *ISysRoot,
1931 StorageType Storage, bool ShouldCreate = true);
Adrian Prantlab1243f2015-06-29 23:03:47 +00001932
1933 TempDIModule cloneImpl() const {
1934 return getTemporary(getContext(), getScope(), getName(),
1935 getConfigurationMacros(), getIncludePath(),
1936 getISysRoot());
1937 }
1938
1939public:
1940 DEFINE_MDNODE_GET(DIModule, (DIScope *Scope, StringRef Name,
NAKAMURA Takumiff35c332015-07-06 00:48:17 +00001941 StringRef ConfigurationMacros, StringRef IncludePath,
1942 StringRef ISysRoot),
Adrian Prantlab1243f2015-06-29 23:03:47 +00001943 (Scope, Name, ConfigurationMacros, IncludePath, ISysRoot))
1944 DEFINE_MDNODE_GET(DIModule,
1945 (Metadata *Scope, MDString *Name, MDString *ConfigurationMacros,
NAKAMURA Takumiff35c332015-07-06 00:48:17 +00001946 MDString *IncludePath, MDString *ISysRoot),
Adrian Prantlab1243f2015-06-29 23:03:47 +00001947 (Scope, Name, ConfigurationMacros, IncludePath, ISysRoot))
1948
1949 TempDIModule clone() const { return cloneImpl(); }
1950
1951 DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
1952 StringRef getName() const { return getStringOperand(1); }
1953 StringRef getConfigurationMacros() const { return getStringOperand(2); }
1954 StringRef getIncludePath() const { return getStringOperand(3); }
1955 StringRef getISysRoot() const { return getStringOperand(4); }
1956
1957 Metadata *getRawScope() const { return getOperand(0); }
1958 MDString *getRawName() const { return getOperandAs<MDString>(1); }
1959 MDString *getRawConfigurationMacros() const { return getOperandAs<MDString>(2); }
1960 MDString *getRawIncludePath() const { return getOperandAs<MDString>(3); }
1961 MDString *getRawISysRoot() const { return getOperandAs<MDString>(4); }
1962
1963 static bool classof(const Metadata *MD) {
1964 return MD->getMetadataID() == DIModuleKind;
1965 }
1966};
1967
Adrian Prantl1687e012016-11-14 22:09:18 +00001968/// Base class for template parameters.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001969class DITemplateParameter : public DINode {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001970protected:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001971 DITemplateParameter(LLVMContext &Context, unsigned ID, StorageType Storage,
Duncan P. N. Exon Smithbd33d372015-02-10 01:59:57 +00001972 unsigned Tag, ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001973 : DINode(Context, ID, Storage, Tag, Ops) {}
1974 ~DITemplateParameter() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001975
1976public:
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00001977 StringRef getName() const { return getStringOperand(0); }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001978 DITypeRef getType() const { return DITypeRef(getRawType()); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001979
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00001980 MDString *getRawName() const { return getOperandAs<MDString>(0); }
Duncan P. N. Exon Smith3ec5fa62015-04-06 19:03:45 +00001981 Metadata *getRawType() const { return getOperand(1); }
Duncan P. N. Exon Smith2847f382015-02-13 01:34:32 +00001982
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001983 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001984 return MD->getMetadataID() == DITemplateTypeParameterKind ||
1985 MD->getMetadataID() == DITemplateValueParameterKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001986 }
1987};
1988
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001989class DITemplateTypeParameter : public DITemplateParameter {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001990 friend class LLVMContextImpl;
1991 friend class MDNode;
1992
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001993 DITemplateTypeParameter(LLVMContext &Context, StorageType Storage,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001994 ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001995 : DITemplateParameter(Context, DITemplateTypeParameterKind, Storage,
Duncan P. N. Exon Smithbd33d372015-02-10 01:59:57 +00001996 dwarf::DW_TAG_template_type_parameter, Ops) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001997 ~DITemplateTypeParameter() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001998
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001999 static DITemplateTypeParameter *getImpl(LLVMContext &Context, StringRef Name,
2000 DITypeRef Type, StorageType Storage,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002001 bool ShouldCreate = true) {
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002002 return getImpl(Context, getCanonicalMDString(Context, Name), Type, Storage,
2003 ShouldCreate);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002004 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002005 static DITemplateTypeParameter *getImpl(LLVMContext &Context, MDString *Name,
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002006 Metadata *Type, StorageType Storage,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002007 bool ShouldCreate = true);
2008
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002009 TempDITemplateTypeParameter cloneImpl() const {
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002010 return getTemporary(getContext(), getName(), getType());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002011 }
2012
2013public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002014 DEFINE_MDNODE_GET(DITemplateTypeParameter, (StringRef Name, DITypeRef Type),
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002015 (Name, Type))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002016 DEFINE_MDNODE_GET(DITemplateTypeParameter, (MDString * Name, Metadata *Type),
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002017 (Name, Type))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002018
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002019 TempDITemplateTypeParameter clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002020
2021 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002022 return MD->getMetadataID() == DITemplateTypeParameterKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002023 }
2024};
2025
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002026class DITemplateValueParameter : public DITemplateParameter {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002027 friend class LLVMContextImpl;
2028 friend class MDNode;
2029
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002030 DITemplateValueParameter(LLVMContext &Context, StorageType Storage,
Duncan P. N. Exon Smithbd33d372015-02-10 01:59:57 +00002031 unsigned Tag, ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002032 : DITemplateParameter(Context, DITemplateValueParameterKind, Storage, Tag,
Duncan P. N. Exon Smithbd33d372015-02-10 01:59:57 +00002033 Ops) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002034 ~DITemplateValueParameter() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002035
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002036 static DITemplateValueParameter *getImpl(LLVMContext &Context, unsigned Tag,
2037 StringRef Name, DITypeRef Type,
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002038 Metadata *Value, StorageType Storage,
Duncan P. N. Exon Smithbd33d372015-02-10 01:59:57 +00002039 bool ShouldCreate = true) {
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002040 return getImpl(Context, Tag, getCanonicalMDString(Context, Name), Type,
2041 Value, Storage, ShouldCreate);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002042 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002043 static DITemplateValueParameter *getImpl(LLVMContext &Context, unsigned Tag,
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002044 MDString *Name, Metadata *Type,
2045 Metadata *Value, StorageType Storage,
Duncan P. N. Exon Smithbd33d372015-02-10 01:59:57 +00002046 bool ShouldCreate = true);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002047
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002048 TempDITemplateValueParameter cloneImpl() const {
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002049 return getTemporary(getContext(), getTag(), getName(), getType(),
2050 getValue());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002051 }
2052
2053public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002054 DEFINE_MDNODE_GET(DITemplateValueParameter, (unsigned Tag, StringRef Name,
2055 DITypeRef Type, Metadata *Value),
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002056 (Tag, Name, Type, Value))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002057 DEFINE_MDNODE_GET(DITemplateValueParameter, (unsigned Tag, MDString *Name,
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002058 Metadata *Type, Metadata *Value),
2059 (Tag, Name, Type, Value))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002060
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002061 TempDITemplateValueParameter clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith6873fea2015-02-17 23:10:13 +00002062
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002063 Metadata *getValue() const { return getOperand(2); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002064
2065 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002066 return MD->getMetadataID() == DITemplateValueParameterKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002067 }
2068};
2069
Adrian Prantl1687e012016-11-14 22:09:18 +00002070/// Base class for variables.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002071class DIVariable : public DINode {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002072 unsigned Line;
Victor Leschuka37660c2016-10-26 21:32:29 +00002073 uint32_t AlignInBits;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002074
2075protected:
Duncan P. N. Exon Smithed013cd2015-07-31 18:58:39 +00002076 DIVariable(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Line,
Victor Leschuka37660c2016-10-26 21:32:29 +00002077 ArrayRef<Metadata *> Ops, uint32_t AlignInBits = 0)
Victor Leschuk2ede1262016-10-20 00:13:12 +00002078 : DINode(C, ID, Storage, dwarf::DW_TAG_variable, Ops), Line(Line),
NAKAMURA Takumi78029842017-02-19 06:51:46 +00002079 AlignInBits(AlignInBits) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002080 ~DIVariable() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002081
2082public:
2083 unsigned getLine() const { return Line; }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002084 DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002085 StringRef getName() const { return getStringOperand(1); }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002086 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
2087 DITypeRef getType() const { return DITypeRef(getRawType()); }
Victor Leschuk3c989982016-10-26 11:59:03 +00002088 uint32_t getAlignInBits() const { return AlignInBits; }
2089 uint32_t getAlignInBytes() const { return getAlignInBits() / CHAR_BIT; }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002090
Duncan P. N. Exon Smith50c065b2015-04-11 00:39:43 +00002091 StringRef getFilename() const {
2092 if (auto *F = getFile())
2093 return F->getFilename();
2094 return "";
2095 }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +00002096
Duncan P. N. Exon Smith50c065b2015-04-11 00:39:43 +00002097 StringRef getDirectory() const {
2098 if (auto *F = getFile())
2099 return F->getDirectory();
2100 return "";
2101 }
2102
Duncan P. N. Exon Smith3d2afaa2015-03-27 17:29:58 +00002103 Metadata *getRawScope() const { return getOperand(0); }
Duncan P. N. Exon Smithc8f810a2015-02-13 01:35:40 +00002104 MDString *getRawName() const { return getOperandAs<MDString>(1); }
Duncan P. N. Exon Smith3d2afaa2015-03-27 17:29:58 +00002105 Metadata *getRawFile() const { return getOperand(2); }
2106 Metadata *getRawType() const { return getOperand(3); }
Duncan P. N. Exon Smithc8f810a2015-02-13 01:35:40 +00002107
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002108 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002109 return MD->getMetadataID() == DILocalVariableKind ||
2110 MD->getMetadataID() == DIGlobalVariableKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002111 }
2112};
2113
Adrian Prantl1687e012016-11-14 22:09:18 +00002114/// DWARF expression.
Peter Collingbourned4135bb2016-09-13 01:12:59 +00002115///
2116/// This is (almost) a DWARF expression that modifies the location of a
2117/// variable, or the location of a single piece of a variable, or (when using
2118/// DW_OP_stack_value) is the constant variable value.
2119///
2120/// FIXME: Instead of DW_OP_plus taking an argument, this should use DW_OP_const
2121/// and have DW_OP_plus consume the topmost elements on the stack.
2122///
2123/// TODO: Co-allocate the expression elements.
2124/// TODO: Separate from MDNode, or otherwise drop Distinct and Temporary
2125/// storage types.
2126class DIExpression : public MDNode {
2127 friend class LLVMContextImpl;
2128 friend class MDNode;
2129
2130 std::vector<uint64_t> Elements;
2131
2132 DIExpression(LLVMContext &C, StorageType Storage, ArrayRef<uint64_t> Elements)
2133 : MDNode(C, DIExpressionKind, Storage, None),
2134 Elements(Elements.begin(), Elements.end()) {}
2135 ~DIExpression() = default;
2136
2137 static DIExpression *getImpl(LLVMContext &Context,
2138 ArrayRef<uint64_t> Elements, StorageType Storage,
2139 bool ShouldCreate = true);
2140
2141 TempDIExpression cloneImpl() const {
2142 return getTemporary(getContext(), getElements());
2143 }
2144
2145public:
2146 DEFINE_MDNODE_GET(DIExpression, (ArrayRef<uint64_t> Elements), (Elements))
2147
2148 TempDIExpression clone() const { return cloneImpl(); }
2149
2150 ArrayRef<uint64_t> getElements() const { return Elements; }
2151
2152 unsigned getNumElements() const { return Elements.size(); }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +00002153
Peter Collingbourned4135bb2016-09-13 01:12:59 +00002154 uint64_t getElement(unsigned I) const {
2155 assert(I < Elements.size() && "Index out of range");
2156 return Elements[I];
2157 }
2158
Adrian Prantlbceaaa92016-12-20 02:09:43 +00002159 /// Determine whether this represents a standalone constant value.
2160 bool isConstant() const;
2161
Eugene Zelenkod761e2c2017-05-15 21:57:41 +00002162 using element_iterator = ArrayRef<uint64_t>::iterator;
2163
Peter Collingbourned4135bb2016-09-13 01:12:59 +00002164 element_iterator elements_begin() const { return getElements().begin(); }
2165 element_iterator elements_end() const { return getElements().end(); }
2166
2167 /// A lightweight wrapper around an expression operand.
2168 ///
2169 /// TODO: Store arguments directly and change \a DIExpression to store a
2170 /// range of these.
2171 class ExprOperand {
Adrian Prantl72845a52016-11-08 20:48:38 +00002172 const uint64_t *Op = nullptr;
Peter Collingbourned4135bb2016-09-13 01:12:59 +00002173
2174 public:
Adrian Prantl72845a52016-11-08 20:48:38 +00002175 ExprOperand() = default;
Peter Collingbourned4135bb2016-09-13 01:12:59 +00002176 explicit ExprOperand(const uint64_t *Op) : Op(Op) {}
2177
2178 const uint64_t *get() const { return Op; }
2179
2180 /// Get the operand code.
2181 uint64_t getOp() const { return *Op; }
2182
2183 /// Get an argument to the operand.
2184 ///
2185 /// Never returns the operand itself.
2186 uint64_t getArg(unsigned I) const { return Op[I + 1]; }
2187
2188 unsigned getNumArgs() const { return getSize() - 1; }
2189
2190 /// Return the size of the operand.
2191 ///
2192 /// Return the number of elements in the operand (1 + args).
2193 unsigned getSize() const;
2194 };
2195
2196 /// An iterator for expression operands.
2197 class expr_op_iterator
2198 : public std::iterator<std::input_iterator_tag, ExprOperand> {
2199 ExprOperand Op;
2200
2201 public:
Adrian Prantl54286bd2016-11-02 16:12:20 +00002202 expr_op_iterator() = default;
Peter Collingbourned4135bb2016-09-13 01:12:59 +00002203 explicit expr_op_iterator(element_iterator I) : Op(I) {}
2204
2205 element_iterator getBase() const { return Op.get(); }
2206 const ExprOperand &operator*() const { return Op; }
2207 const ExprOperand *operator->() const { return &Op; }
2208
2209 expr_op_iterator &operator++() {
2210 increment();
2211 return *this;
2212 }
2213 expr_op_iterator operator++(int) {
2214 expr_op_iterator T(*this);
2215 increment();
2216 return T;
2217 }
2218
2219 /// Get the next iterator.
2220 ///
2221 /// \a std::next() doesn't work because this is technically an
2222 /// input_iterator, but it's a perfectly valid operation. This is an
2223 /// accessor to provide the same functionality.
2224 expr_op_iterator getNext() const { return ++expr_op_iterator(*this); }
2225
2226 bool operator==(const expr_op_iterator &X) const {
2227 return getBase() == X.getBase();
2228 }
2229 bool operator!=(const expr_op_iterator &X) const {
2230 return getBase() != X.getBase();
2231 }
2232
2233 private:
2234 void increment() { Op = ExprOperand(getBase() + Op.getSize()); }
2235 };
2236
2237 /// Visit the elements via ExprOperand wrappers.
2238 ///
2239 /// These range iterators visit elements through \a ExprOperand wrappers.
2240 /// This is not guaranteed to be a valid range unless \a isValid() gives \c
2241 /// true.
2242 ///
2243 /// \pre \a isValid() gives \c true.
2244 /// @{
2245 expr_op_iterator expr_op_begin() const {
2246 return expr_op_iterator(elements_begin());
2247 }
2248 expr_op_iterator expr_op_end() const {
2249 return expr_op_iterator(elements_end());
2250 }
Adrian Prantl6825fb62017-04-18 01:21:53 +00002251 iterator_range<expr_op_iterator> expr_ops() const {
2252 return {expr_op_begin(), expr_op_end()};
2253 }
Peter Collingbourned4135bb2016-09-13 01:12:59 +00002254 /// @}
2255
2256 bool isValid() const;
2257
2258 static bool classof(const Metadata *MD) {
2259 return MD->getMetadataID() == DIExpressionKind;
2260 }
2261
Adrian Prantl6825fb62017-04-18 01:21:53 +00002262 /// Return whether the first element a DW_OP_deref.
Peter Collingbourned4135bb2016-09-13 01:12:59 +00002263 bool startsWithDeref() const {
2264 return getNumElements() > 0 && getElement(0) == dwarf::DW_OP_deref;
2265 }
Adrian Prantl49797ca2016-12-22 05:27:12 +00002266
2267 /// Holds the characteristics of one fragment of a larger variable.
2268 struct FragmentInfo {
2269 uint64_t SizeInBits;
2270 uint64_t OffsetInBits;
2271 };
2272
2273 /// Retrieve the details of this fragment expression.
2274 static Optional<FragmentInfo> getFragmentInfo(expr_op_iterator Start,
NAKAMURA Takumi78029842017-02-19 06:51:46 +00002275 expr_op_iterator End);
Adrian Prantl49797ca2016-12-22 05:27:12 +00002276
2277 /// Retrieve the details of this fragment expression.
2278 Optional<FragmentInfo> getFragmentInfo() const {
2279 return getFragmentInfo(expr_op_begin(), expr_op_end());
2280 }
2281
2282 /// Return whether this is a piece of an aggregate variable.
2283 bool isFragment() const { return getFragmentInfo().hasValue(); }
Andrew Ng03e35b62017-04-28 08:44:30 +00002284
2285 /// Append \p Ops with operations to apply the \p Offset.
2286 static void appendOffset(SmallVectorImpl<uint64_t> &Ops, int64_t Offset);
2287
Reid Klecknerb5fced72017-05-09 19:59:29 +00002288 /// If this is a constant offset, extract it. If there is no expression,
2289 /// return true with an offset of zero.
2290 bool extractIfOffset(int64_t &Offset) const;
2291
Adrian Prantl109b2362017-04-28 17:51:05 +00002292 /// Constants for DIExpression::prepend.
2293 enum { NoDeref = false, WithDeref = true, WithStackValue = true };
2294
Andrew Ng03e35b62017-04-28 08:44:30 +00002295 /// Prepend \p DIExpr with a deref and offset operation and optionally turn it
2296 /// into a stack value.
Adrian Prantl06d60962017-04-28 18:30:36 +00002297 static DIExpression *prepend(const DIExpression *DIExpr, bool Deref,
Adrian Prantl109b2362017-04-28 17:51:05 +00002298 int64_t Offset = 0, bool StackValue = false);
Peter Collingbourned4135bb2016-09-13 01:12:59 +00002299};
2300
Adrian Prantl1687e012016-11-14 22:09:18 +00002301/// Global variables.
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002302///
2303/// TODO: Remove DisplayName. It's always equal to Name.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002304class DIGlobalVariable : public DIVariable {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002305 friend class LLVMContextImpl;
2306 friend class MDNode;
2307
2308 bool IsLocalToUnit;
2309 bool IsDefinition;
2310
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002311 DIGlobalVariable(LLVMContext &C, StorageType Storage, unsigned Line,
Victor Leschuka37660c2016-10-26 21:32:29 +00002312 bool IsLocalToUnit, bool IsDefinition, uint32_t AlignInBits,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002313 ArrayRef<Metadata *> Ops)
Victor Leschuk2ede1262016-10-20 00:13:12 +00002314 : DIVariable(C, DIGlobalVariableKind, Storage, Line, Ops, AlignInBits),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002315 IsLocalToUnit(IsLocalToUnit), IsDefinition(IsDefinition) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002316 ~DIGlobalVariable() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002317
Adrian Prantlbceaaa92016-12-20 02:09:43 +00002318 static DIGlobalVariable *getImpl(LLVMContext &Context, DIScope *Scope,
2319 StringRef Name, StringRef LinkageName,
2320 DIFile *File, unsigned Line, DITypeRef Type,
2321 bool IsLocalToUnit, bool IsDefinition,
2322 DIDerivedType *StaticDataMemberDeclaration,
2323 uint32_t AlignInBits, StorageType Storage,
2324 bool ShouldCreate = true) {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002325 return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
2326 getCanonicalMDString(Context, LinkageName), File, Line, Type,
Adrian Prantlbceaaa92016-12-20 02:09:43 +00002327 IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration,
2328 AlignInBits, Storage, ShouldCreate);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002329 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002330 static DIGlobalVariable *
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002331 getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
2332 MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type,
Adrian Prantlbceaaa92016-12-20 02:09:43 +00002333 bool IsLocalToUnit, bool IsDefinition,
Victor Leschuka37660c2016-10-26 21:32:29 +00002334 Metadata *StaticDataMemberDeclaration, uint32_t AlignInBits,
Victor Leschuk2ede1262016-10-20 00:13:12 +00002335 StorageType Storage, bool ShouldCreate = true);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002336
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002337 TempDIGlobalVariable cloneImpl() const {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002338 return getTemporary(getContext(), getScope(), getName(), getLinkageName(),
2339 getFile(), getLine(), getType(), isLocalToUnit(),
Adrian Prantlbceaaa92016-12-20 02:09:43 +00002340 isDefinition(), getStaticDataMemberDeclaration(),
2341 getAlignInBits());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002342 }
2343
2344public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002345 DEFINE_MDNODE_GET(DIGlobalVariable,
2346 (DIScope * Scope, StringRef Name, StringRef LinkageName,
2347 DIFile *File, unsigned Line, DITypeRef Type,
Victor Leschuk2ede1262016-10-20 00:13:12 +00002348 bool IsLocalToUnit, bool IsDefinition,
Victor Leschuk2ede1262016-10-20 00:13:12 +00002349 DIDerivedType *StaticDataMemberDeclaration,
Victor Leschuka37660c2016-10-26 21:32:29 +00002350 uint32_t AlignInBits),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002351 (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
Adrian Prantlbceaaa92016-12-20 02:09:43 +00002352 IsDefinition, StaticDataMemberDeclaration, AlignInBits))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002353 DEFINE_MDNODE_GET(DIGlobalVariable,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002354 (Metadata * Scope, MDString *Name, MDString *LinkageName,
2355 Metadata *File, unsigned Line, Metadata *Type,
Victor Leschuk2ede1262016-10-20 00:13:12 +00002356 bool IsLocalToUnit, bool IsDefinition,
Adrian Prantlbceaaa92016-12-20 02:09:43 +00002357 Metadata *StaticDataMemberDeclaration,
Victor Leschuka37660c2016-10-26 21:32:29 +00002358 uint32_t AlignInBits),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002359 (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
Adrian Prantlbceaaa92016-12-20 02:09:43 +00002360 IsDefinition, StaticDataMemberDeclaration, AlignInBits))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002361
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002362 TempDIGlobalVariable clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith6873fea2015-02-17 23:10:13 +00002363
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002364 bool isLocalToUnit() const { return IsLocalToUnit; }
2365 bool isDefinition() const { return IsDefinition; }
2366 StringRef getDisplayName() const { return getStringOperand(4); }
2367 StringRef getLinkageName() const { return getStringOperand(5); }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002368 DIDerivedType *getStaticDataMemberDeclaration() const {
2369 return cast_or_null<DIDerivedType>(getRawStaticDataMemberDeclaration());
Duncan P. N. Exon Smith3d2afaa2015-03-27 17:29:58 +00002370 }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002371
Duncan P. N. Exon Smithc8f810a2015-02-13 01:35:40 +00002372 MDString *getRawLinkageName() const { return getOperandAs<MDString>(5); }
Adrian Prantlbceaaa92016-12-20 02:09:43 +00002373 Metadata *getRawStaticDataMemberDeclaration() const { return getOperand(6); }
Duncan P. N. Exon Smithc8f810a2015-02-13 01:35:40 +00002374
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002375 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002376 return MD->getMetadataID() == DIGlobalVariableKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002377 }
2378};
2379
Adrian Prantl1687e012016-11-14 22:09:18 +00002380/// Local variable.
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002381///
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002382/// TODO: Split up flags.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002383class DILocalVariable : public DIVariable {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002384 friend class LLVMContextImpl;
2385 friend class MDNode;
2386
Davide Italianoeb6bb3e2016-04-16 02:27:56 +00002387 unsigned Arg : 16;
Leny Kholodov5fcc4182016-09-06 10:46:28 +00002388 DIFlags Flags;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002389
Duncan P. N. Exon Smithed013cd2015-07-31 18:58:39 +00002390 DILocalVariable(LLVMContext &C, StorageType Storage, unsigned Line,
Victor Leschuka37660c2016-10-26 21:32:29 +00002391 unsigned Arg, DIFlags Flags, uint32_t AlignInBits,
Victor Leschuk2ede1262016-10-20 00:13:12 +00002392 ArrayRef<Metadata *> Ops)
2393 : DIVariable(C, DILocalVariableKind, Storage, Line, Ops, AlignInBits),
2394 Arg(Arg), Flags(Flags) {
Davide Italiano0d2ef012016-04-16 03:23:48 +00002395 assert(Arg < (1 << 16) && "DILocalVariable: Arg out of range");
Davide Italianoeb6bb3e2016-04-16 02:27:56 +00002396 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002397 ~DILocalVariable() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002398
Duncan P. N. Exon Smithed013cd2015-07-31 18:58:39 +00002399 static DILocalVariable *getImpl(LLVMContext &Context, DIScope *Scope,
2400 StringRef Name, DIFile *File, unsigned Line,
Leny Kholodov5fcc4182016-09-06 10:46:28 +00002401 DITypeRef Type, unsigned Arg, DIFlags Flags,
Victor Leschuka37660c2016-10-26 21:32:29 +00002402 uint32_t AlignInBits, StorageType Storage,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002403 bool ShouldCreate = true) {
Duncan P. N. Exon Smithed013cd2015-07-31 18:58:39 +00002404 return getImpl(Context, Scope, getCanonicalMDString(Context, Name), File,
Victor Leschuk2ede1262016-10-20 00:13:12 +00002405 Line, Type, Arg, Flags, AlignInBits, Storage, ShouldCreate);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002406 }
Duncan P. N. Exon Smithed013cd2015-07-31 18:58:39 +00002407 static DILocalVariable *getImpl(LLVMContext &Context, Metadata *Scope,
2408 MDString *Name, Metadata *File, unsigned Line,
Leny Kholodov5fcc4182016-09-06 10:46:28 +00002409 Metadata *Type, unsigned Arg, DIFlags Flags,
Victor Leschuka37660c2016-10-26 21:32:29 +00002410 uint32_t AlignInBits, StorageType Storage,
Duncan P. N. Exon Smithed013cd2015-07-31 18:58:39 +00002411 bool ShouldCreate = true);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002412
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002413 TempDILocalVariable cloneImpl() const {
Duncan P. N. Exon Smithed013cd2015-07-31 18:58:39 +00002414 return getTemporary(getContext(), getScope(), getName(), getFile(),
Victor Leschuk2ede1262016-10-20 00:13:12 +00002415 getLine(), getType(), getArg(), getFlags(),
2416 getAlignInBits());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002417 }
2418
2419public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002420 DEFINE_MDNODE_GET(DILocalVariable,
Duncan P. N. Exon Smithed013cd2015-07-31 18:58:39 +00002421 (DILocalScope * Scope, StringRef Name, DIFile *File,
Leny Kholodov40c62352016-09-06 17:03:02 +00002422 unsigned Line, DITypeRef Type, unsigned Arg,
Victor Leschuka37660c2016-10-26 21:32:29 +00002423 DIFlags Flags, uint32_t AlignInBits),
Victor Leschuk2ede1262016-10-20 00:13:12 +00002424 (Scope, Name, File, Line, Type, Arg, Flags, AlignInBits))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002425 DEFINE_MDNODE_GET(DILocalVariable,
Duncan P. N. Exon Smithed013cd2015-07-31 18:58:39 +00002426 (Metadata * Scope, MDString *Name, Metadata *File,
Leny Kholodov40c62352016-09-06 17:03:02 +00002427 unsigned Line, Metadata *Type, unsigned Arg,
Victor Leschuka37660c2016-10-26 21:32:29 +00002428 DIFlags Flags, uint32_t AlignInBits),
Victor Leschuk2ede1262016-10-20 00:13:12 +00002429 (Scope, Name, File, Line, Type, Arg, Flags, AlignInBits))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002430
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002431 TempDILocalVariable clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith6873fea2015-02-17 23:10:13 +00002432
Adrian Prantl1687e012016-11-14 22:09:18 +00002433 /// Get the local scope for this variable.
Duncan P. N. Exon Smith3d2afaa2015-03-27 17:29:58 +00002434 ///
2435 /// Variables must be defined in a local scope.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002436 DILocalScope *getScope() const {
2437 return cast<DILocalScope>(DIVariable::getScope());
Duncan P. N. Exon Smith3d2afaa2015-03-27 17:29:58 +00002438 }
2439
Duncan P. N. Exon Smithed013cd2015-07-31 18:58:39 +00002440 bool isParameter() const { return Arg; }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002441 unsigned getArg() const { return Arg; }
Leny Kholodov5fcc4182016-09-06 10:46:28 +00002442 DIFlags getFlags() const { return Flags; }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002443
Duncan P. N. Exon Smithbd42d5d2015-04-07 03:55:30 +00002444 bool isArtificial() const { return getFlags() & FlagArtificial; }
2445 bool isObjectPointer() const { return getFlags() & FlagObjectPointer; }
2446
Adrian Prantl1687e012016-11-14 22:09:18 +00002447 /// Check that a location is valid for this variable.
Duncan P. N. Exon Smith3bef6a32015-04-03 19:20:26 +00002448 ///
Duncan P. N. Exon Smithf17f34e2015-04-15 22:15:46 +00002449 /// Check that \c DL exists, is in the same subprogram, and has the same
Benjamin Kramerdf005cb2015-08-08 18:27:36 +00002450 /// inlined-at location as \c this. (Otherwise, it's not a valid attachment
Duncan P. N. Exon Smithf17f34e2015-04-15 22:15:46 +00002451 /// to a \a DbgInfoIntrinsic.)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002452 bool isValidLocationForIntrinsic(const DILocation *DL) const {
Duncan P. N. Exon Smith62e0f452015-04-15 22:29:27 +00002453 return DL && getScope()->getSubprogram() == DL->getScope()->getSubprogram();
Duncan P. N. Exon Smith3bef6a32015-04-03 19:20:26 +00002454 }
2455
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002456 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002457 return MD->getMetadataID() == DILocalVariableKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002458 }
2459};
2460
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002461class DIObjCProperty : public DINode {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002462 friend class LLVMContextImpl;
2463 friend class MDNode;
2464
2465 unsigned Line;
2466 unsigned Attributes;
2467
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002468 DIObjCProperty(LLVMContext &C, StorageType Storage, unsigned Line,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002469 unsigned Attributes, ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002470 : DINode(C, DIObjCPropertyKind, Storage, dwarf::DW_TAG_APPLE_property,
2471 Ops),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002472 Line(Line), Attributes(Attributes) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002473 ~DIObjCProperty() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002474
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002475 static DIObjCProperty *
2476 getImpl(LLVMContext &Context, StringRef Name, DIFile *File, unsigned Line,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002477 StringRef GetterName, StringRef SetterName, unsigned Attributes,
Adrian Prantl8ff53b32015-06-15 23:18:03 +00002478 DITypeRef Type, StorageType Storage, bool ShouldCreate = true) {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002479 return getImpl(Context, getCanonicalMDString(Context, Name), File, Line,
2480 getCanonicalMDString(Context, GetterName),
2481 getCanonicalMDString(Context, SetterName), Attributes, Type,
2482 Storage, ShouldCreate);
2483 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002484 static DIObjCProperty *getImpl(LLVMContext &Context, MDString *Name,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002485 Metadata *File, unsigned Line,
2486 MDString *GetterName, MDString *SetterName,
2487 unsigned Attributes, Metadata *Type,
2488 StorageType Storage, bool ShouldCreate = true);
2489
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002490 TempDIObjCProperty cloneImpl() const {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002491 return getTemporary(getContext(), getName(), getFile(), getLine(),
2492 getGetterName(), getSetterName(), getAttributes(),
2493 getType());
2494 }
2495
2496public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002497 DEFINE_MDNODE_GET(DIObjCProperty,
2498 (StringRef Name, DIFile *File, unsigned Line,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002499 StringRef GetterName, StringRef SetterName,
Adrian Prantl8ff53b32015-06-15 23:18:03 +00002500 unsigned Attributes, DITypeRef Type),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002501 (Name, File, Line, GetterName, SetterName, Attributes,
2502 Type))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002503 DEFINE_MDNODE_GET(DIObjCProperty,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002504 (MDString * Name, Metadata *File, unsigned Line,
2505 MDString *GetterName, MDString *SetterName,
2506 unsigned Attributes, Metadata *Type),
2507 (Name, File, Line, GetterName, SetterName, Attributes,
2508 Type))
2509
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002510 TempDIObjCProperty clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith6873fea2015-02-17 23:10:13 +00002511
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002512 unsigned getLine() const { return Line; }
2513 unsigned getAttributes() const { return Attributes; }
2514 StringRef getName() const { return getStringOperand(0); }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002515 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002516 StringRef getGetterName() const { return getStringOperand(2); }
2517 StringRef getSetterName() const { return getStringOperand(3); }
Adrian Prantl8ff53b32015-06-15 23:18:03 +00002518 DITypeRef getType() const { return DITypeRef(getRawType()); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002519
Duncan P. N. Exon Smith50c065b2015-04-11 00:39:43 +00002520 StringRef getFilename() const {
2521 if (auto *F = getFile())
2522 return F->getFilename();
2523 return "";
2524 }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +00002525
Duncan P. N. Exon Smith50c065b2015-04-11 00:39:43 +00002526 StringRef getDirectory() const {
2527 if (auto *F = getFile())
2528 return F->getDirectory();
2529 return "";
2530 }
2531
Duncan P. N. Exon Smithd45ce962015-02-13 01:43:22 +00002532 MDString *getRawName() const { return getOperandAs<MDString>(0); }
Duncan P. N. Exon Smithf9b47752015-03-30 17:21:38 +00002533 Metadata *getRawFile() const { return getOperand(1); }
Duncan P. N. Exon Smithd45ce962015-02-13 01:43:22 +00002534 MDString *getRawGetterName() const { return getOperandAs<MDString>(2); }
2535 MDString *getRawSetterName() const { return getOperandAs<MDString>(3); }
Duncan P. N. Exon Smithf9b47752015-03-30 17:21:38 +00002536 Metadata *getRawType() const { return getOperand(4); }
Duncan P. N. Exon Smithd45ce962015-02-13 01:43:22 +00002537
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002538 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002539 return MD->getMetadataID() == DIObjCPropertyKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002540 }
2541};
2542
Adrian Prantl1687e012016-11-14 22:09:18 +00002543/// An imported module (C++ using directive or similar).
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002544class DIImportedEntity : public DINode {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002545 friend class LLVMContextImpl;
2546 friend class MDNode;
2547
2548 unsigned Line;
2549
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002550 DIImportedEntity(LLVMContext &C, StorageType Storage, unsigned Tag,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002551 unsigned Line, ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002552 : DINode(C, DIImportedEntityKind, Storage, Tag, Ops), Line(Line) {}
2553 ~DIImportedEntity() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002554
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002555 static DIImportedEntity *getImpl(LLVMContext &Context, unsigned Tag,
2556 DIScope *Scope, DINodeRef Entity,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002557 unsigned Line, StringRef Name,
2558 StorageType Storage,
2559 bool ShouldCreate = true) {
2560 return getImpl(Context, Tag, Scope, Entity, Line,
2561 getCanonicalMDString(Context, Name), Storage, ShouldCreate);
2562 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002563 static DIImportedEntity *getImpl(LLVMContext &Context, unsigned Tag,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002564 Metadata *Scope, Metadata *Entity,
2565 unsigned Line, MDString *Name,
2566 StorageType Storage,
2567 bool ShouldCreate = true);
2568
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002569 TempDIImportedEntity cloneImpl() const {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002570 return getTemporary(getContext(), getTag(), getScope(), getEntity(),
2571 getLine(), getName());
2572 }
2573
2574public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002575 DEFINE_MDNODE_GET(DIImportedEntity,
2576 (unsigned Tag, DIScope *Scope, DINodeRef Entity,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002577 unsigned Line, StringRef Name = ""),
2578 (Tag, Scope, Entity, Line, Name))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002579 DEFINE_MDNODE_GET(DIImportedEntity,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002580 (unsigned Tag, Metadata *Scope, Metadata *Entity,
2581 unsigned Line, MDString *Name),
2582 (Tag, Scope, Entity, Line, Name))
2583
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002584 TempDIImportedEntity clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002585
2586 unsigned getLine() const { return Line; }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002587 DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
2588 DINodeRef getEntity() const { return DINodeRef(getRawEntity()); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002589 StringRef getName() const { return getStringOperand(2); }
2590
Duncan P. N. Exon Smithf9b47752015-03-30 17:21:38 +00002591 Metadata *getRawScope() const { return getOperand(0); }
2592 Metadata *getRawEntity() const { return getOperand(1); }
Duncan P. N. Exon Smith1c931162015-02-13 01:46:02 +00002593 MDString *getRawName() const { return getOperandAs<MDString>(2); }
2594
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002595 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002596 return MD->getMetadataID() == DIImportedEntityKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002597 }
2598};
2599
Adrian Prantlbceaaa92016-12-20 02:09:43 +00002600/// A pair of DIGlobalVariable and DIExpression.
2601class DIGlobalVariableExpression : public MDNode {
2602 friend class LLVMContextImpl;
2603 friend class MDNode;
2604
2605 DIGlobalVariableExpression(LLVMContext &C, StorageType Storage,
2606 ArrayRef<Metadata *> Ops)
2607 : MDNode(C, DIGlobalVariableExpressionKind, Storage, Ops) {}
2608 ~DIGlobalVariableExpression() = default;
2609
2610 static DIGlobalVariableExpression *
2611 getImpl(LLVMContext &Context, Metadata *Variable, Metadata *Expression,
2612 StorageType Storage, bool ShouldCreate = true);
2613
2614 TempDIGlobalVariableExpression cloneImpl() const {
2615 return getTemporary(getContext(), getVariable(), getExpression());
2616 }
2617
2618public:
2619 DEFINE_MDNODE_GET(DIGlobalVariableExpression,
2620 (Metadata * Variable, Metadata *Expression),
2621 (Variable, Expression))
2622
2623 TempDIGlobalVariableExpression clone() const { return cloneImpl(); }
2624
2625 Metadata *getRawVariable() const { return getOperand(0); }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +00002626
Adrian Prantlbceaaa92016-12-20 02:09:43 +00002627 DIGlobalVariable *getVariable() const {
2628 return cast_or_null<DIGlobalVariable>(getRawVariable());
2629 }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +00002630
Adrian Prantlbceaaa92016-12-20 02:09:43 +00002631 Metadata *getRawExpression() const { return getOperand(1); }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +00002632
Adrian Prantlbceaaa92016-12-20 02:09:43 +00002633 DIExpression *getExpression() const {
2634 return cast_or_null<DIExpression>(getRawExpression());
2635 }
2636
2637 static bool classof(const Metadata *MD) {
2638 return MD->getMetadataID() == DIGlobalVariableExpressionKind;
2639 }
2640};
2641
Adrian Prantl1687e012016-11-14 22:09:18 +00002642/// Macro Info DWARF-like metadata node.
Amjad Abouda9bcf162015-12-10 12:56:35 +00002643///
2644/// A metadata node with a DWARF macro info (i.e., a constant named
2645/// \c DW_MACINFO_*, defined in llvm/Support/Dwarf.h). Called \a DIMacroNode
2646/// because it's potentially used for non-DWARF output.
2647class DIMacroNode : public MDNode {
2648 friend class LLVMContextImpl;
2649 friend class MDNode;
2650
2651protected:
2652 DIMacroNode(LLVMContext &C, unsigned ID, StorageType Storage, unsigned MIType,
2653 ArrayRef<Metadata *> Ops1, ArrayRef<Metadata *> Ops2 = None)
2654 : MDNode(C, ID, Storage, Ops1, Ops2) {
2655 assert(MIType < 1u << 16);
2656 SubclassData16 = MIType;
2657 }
2658 ~DIMacroNode() = default;
2659
2660 template <class Ty> Ty *getOperandAs(unsigned I) const {
2661 return cast_or_null<Ty>(getOperand(I));
2662 }
2663
2664 StringRef getStringOperand(unsigned I) const {
2665 if (auto *S = getOperandAs<MDString>(I))
2666 return S->getString();
2667 return StringRef();
2668 }
2669
2670 static MDString *getCanonicalMDString(LLVMContext &Context, StringRef S) {
2671 if (S.empty())
2672 return nullptr;
2673 return MDString::get(Context, S);
2674 }
2675
2676public:
2677 unsigned getMacinfoType() const { return SubclassData16; }
2678
2679 static bool classof(const Metadata *MD) {
2680 switch (MD->getMetadataID()) {
2681 default:
2682 return false;
2683 case DIMacroKind:
2684 case DIMacroFileKind:
2685 return true;
2686 }
2687 }
2688};
2689
2690class DIMacro : public DIMacroNode {
2691 friend class LLVMContextImpl;
2692 friend class MDNode;
2693
2694 unsigned Line;
2695
2696 DIMacro(LLVMContext &C, StorageType Storage, unsigned MIType, unsigned Line,
2697 ArrayRef<Metadata *> Ops)
2698 : DIMacroNode(C, DIMacroKind, Storage, MIType, Ops), Line(Line) {}
2699 ~DIMacro() = default;
2700
2701 static DIMacro *getImpl(LLVMContext &Context, unsigned MIType, unsigned Line,
2702 StringRef Name, StringRef Value, StorageType Storage,
2703 bool ShouldCreate = true) {
2704 return getImpl(Context, MIType, Line, getCanonicalMDString(Context, Name),
2705 getCanonicalMDString(Context, Value), Storage, ShouldCreate);
2706 }
2707 static DIMacro *getImpl(LLVMContext &Context, unsigned MIType, unsigned Line,
2708 MDString *Name, MDString *Value, StorageType Storage,
2709 bool ShouldCreate = true);
2710
2711 TempDIMacro cloneImpl() const {
2712 return getTemporary(getContext(), getMacinfoType(), getLine(), getName(),
2713 getValue());
2714 }
2715
2716public:
2717 DEFINE_MDNODE_GET(DIMacro, (unsigned MIType, unsigned Line, StringRef Name,
2718 StringRef Value = ""),
2719 (MIType, Line, Name, Value))
2720 DEFINE_MDNODE_GET(DIMacro, (unsigned MIType, unsigned Line, MDString *Name,
2721 MDString *Value),
2722 (MIType, Line, Name, Value))
2723
2724 TempDIMacro clone() const { return cloneImpl(); }
2725
2726 unsigned getLine() const { return Line; }
2727
2728 StringRef getName() const { return getStringOperand(0); }
2729 StringRef getValue() const { return getStringOperand(1); }
2730
2731 MDString *getRawName() const { return getOperandAs<MDString>(0); }
2732 MDString *getRawValue() const { return getOperandAs<MDString>(1); }
2733
2734 static bool classof(const Metadata *MD) {
2735 return MD->getMetadataID() == DIMacroKind;
2736 }
2737};
2738
2739class DIMacroFile : public DIMacroNode {
2740 friend class LLVMContextImpl;
2741 friend class MDNode;
2742
2743 unsigned Line;
2744
2745 DIMacroFile(LLVMContext &C, StorageType Storage, unsigned MIType,
2746 unsigned Line, ArrayRef<Metadata *> Ops)
2747 : DIMacroNode(C, DIMacroFileKind, Storage, MIType, Ops), Line(Line) {}
2748 ~DIMacroFile() = default;
2749
2750 static DIMacroFile *getImpl(LLVMContext &Context, unsigned MIType,
2751 unsigned Line, DIFile *File,
2752 DIMacroNodeArray Elements, StorageType Storage,
2753 bool ShouldCreate = true) {
2754 return getImpl(Context, MIType, Line, static_cast<Metadata *>(File),
2755 Elements.get(), Storage, ShouldCreate);
2756 }
2757
2758 static DIMacroFile *getImpl(LLVMContext &Context, unsigned MIType,
2759 unsigned Line, Metadata *File, Metadata *Elements,
2760 StorageType Storage, bool ShouldCreate = true);
2761
2762 TempDIMacroFile cloneImpl() const {
2763 return getTemporary(getContext(), getMacinfoType(), getLine(), getFile(),
2764 getElements());
2765 }
2766
2767public:
2768 DEFINE_MDNODE_GET(DIMacroFile, (unsigned MIType, unsigned Line, DIFile *File,
2769 DIMacroNodeArray Elements),
2770 (MIType, Line, File, Elements))
2771 DEFINE_MDNODE_GET(DIMacroFile, (unsigned MIType, unsigned Line,
2772 Metadata *File, Metadata *Elements),
2773 (MIType, Line, File, Elements))
2774
2775 TempDIMacroFile clone() const { return cloneImpl(); }
2776
2777 void replaceElements(DIMacroNodeArray Elements) {
2778#ifndef NDEBUG
2779 for (DIMacroNode *Op : getElements())
David Majnemer42531262016-08-12 03:55:06 +00002780 assert(is_contained(Elements->operands(), Op) &&
Amjad Abouda9bcf162015-12-10 12:56:35 +00002781 "Lost a macro node during macro node list replacement");
2782#endif
2783 replaceOperandWith(1, Elements.get());
2784 }
2785
2786 unsigned getLine() const { return Line; }
2787 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
2788
2789 DIMacroNodeArray getElements() const {
2790 return cast_or_null<MDTuple>(getRawElements());
2791 }
2792
2793 Metadata *getRawFile() const { return getOperand(0); }
2794 Metadata *getRawElements() const { return getOperand(1); }
2795
2796 static bool classof(const Metadata *MD) {
2797 return MD->getMetadataID() == DIMacroFileKind;
2798 }
2799};
2800
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +00002801} // end namespace llvm
2802
Duncan P. N. Exon Smith61e62a52015-02-02 19:55:21 +00002803#undef DEFINE_MDNODE_GET_UNPACK_IMPL
2804#undef DEFINE_MDNODE_GET_UNPACK
2805#undef DEFINE_MDNODE_GET
2806
Eugene Zelenko1aa40f42016-11-23 22:25:16 +00002807#endif // LLVM_IR_DEBUGINFOMETADATA_H