blob: df689185ef8e85847a0e11dbc5d4d07919e45962 [file] [log] [blame]
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +00001//===- llvm/IR/DebugInfoMetadata.h - Debug info metadata --------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// Declarations for metadata specific to debug info.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_IR_DEBUGINFOMETADATA_H
15#define LLVM_IR_DEBUGINFOMETADATA_H
16
Eugene Zelenko1aa40f42016-11-23 22:25:16 +000017#include "llvm/ADT/ArrayRef.h"
Leny Kholodov40c62352016-09-06 17:03:02 +000018#include "llvm/ADT/BitmaskEnum.h"
Eugene Zelenko1aa40f42016-11-23 22:25:16 +000019#include "llvm/ADT/None.h"
Eugene Zelenkod761e2c2017-05-15 21:57:41 +000020#include "llvm/ADT/Optional.h"
Sander de Smalenfdf40912018-01-24 09:56:07 +000021#include "llvm/ADT/PointerUnion.h"
Eugene Zelenkod761e2c2017-05-15 21:57:41 +000022#include "llvm/ADT/STLExtras.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000023#include "llvm/ADT/SmallVector.h"
Eugene Zelenko1aa40f42016-11-23 22:25:16 +000024#include "llvm/ADT/StringRef.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000025#include "llvm/ADT/iterator_range.h"
Zachary Turner264b5d92017-06-07 03:48:56 +000026#include "llvm/BinaryFormat/Dwarf.h"
Sander de Smalenfdf40912018-01-24 09:56:07 +000027#include "llvm/IR/Constants.h"
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +000028#include "llvm/IR/Metadata.h"
Eugene Zelenko1aa40f42016-11-23 22:25:16 +000029#include "llvm/Support/Casting.h"
Eugene Zelenko1aa40f42016-11-23 22:25:16 +000030#include <cassert>
31#include <climits>
32#include <cstddef>
33#include <cstdint>
34#include <iterator>
35#include <type_traits>
36#include <vector>
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +000037
Duncan P. N. Exon Smith61e62a52015-02-02 19:55:21 +000038// Helper macros for defining get() overrides.
39#define DEFINE_MDNODE_GET_UNPACK_IMPL(...) __VA_ARGS__
40#define DEFINE_MDNODE_GET_UNPACK(ARGS) DEFINE_MDNODE_GET_UNPACK_IMPL ARGS
Duncan P. N. Exon Smith55ca9642015-08-03 17:26:41 +000041#define DEFINE_MDNODE_GET_DISTINCT_TEMPORARY(CLASS, FORMAL, ARGS) \
Duncan P. N. Exon Smith61e62a52015-02-02 19:55:21 +000042 static CLASS *getDistinct(LLVMContext &Context, \
43 DEFINE_MDNODE_GET_UNPACK(FORMAL)) { \
44 return getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Distinct); \
45 } \
46 static Temp##CLASS getTemporary(LLVMContext &Context, \
47 DEFINE_MDNODE_GET_UNPACK(FORMAL)) { \
48 return Temp##CLASS( \
49 getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Temporary)); \
50 }
Duncan P. N. Exon Smith55ca9642015-08-03 17:26:41 +000051#define DEFINE_MDNODE_GET(CLASS, FORMAL, ARGS) \
52 static CLASS *get(LLVMContext &Context, DEFINE_MDNODE_GET_UNPACK(FORMAL)) { \
53 return getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Uniqued); \
54 } \
55 static CLASS *getIfExists(LLVMContext &Context, \
56 DEFINE_MDNODE_GET_UNPACK(FORMAL)) { \
57 return getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Uniqued, \
58 /* ShouldCreate */ false); \
59 } \
60 DEFINE_MDNODE_GET_DISTINCT_TEMPORARY(CLASS, FORMAL, ARGS)
Duncan P. N. Exon Smith61e62a52015-02-02 19:55:21 +000061
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +000062namespace llvm {
63
Duncan P. N. Exon Smitha59d3e52016-04-23 21:08:00 +000064/// Holds a subclass of DINode.
Duncan P. N. Exon Smith930f3882015-04-06 18:02:43 +000065///
Duncan P. N. Exon Smitha59d3e52016-04-23 21:08:00 +000066/// FIXME: This class doesn't currently make much sense. Previously it was a
67/// union beteen MDString (for ODR-uniqued types) and things like DIType. To
68/// support CodeView work, it wasn't deleted outright when MDString-based type
69/// references were deleted; we'll soon need a similar concept for CodeView
70/// DITypeIndex.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +000071template <class T> class TypedDINodeRef {
Duncan P. N. Exon Smith930f3882015-04-06 18:02:43 +000072 const Metadata *MD = nullptr;
73
74public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +000075 TypedDINodeRef() = default;
76 TypedDINodeRef(std::nullptr_t) {}
Duncan P. N. Exon Smitha59d3e52016-04-23 21:08:00 +000077 TypedDINodeRef(const T *MD) : MD(MD) {}
Duncan P. N. Exon Smith930f3882015-04-06 18:02:43 +000078
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +000079 explicit TypedDINodeRef(const Metadata *MD) : MD(MD) {
Duncan P. N. Exon Smitha59d3e52016-04-23 21:08:00 +000080 assert((!MD || isa<T>(MD)) && "Expected valid type ref");
Duncan P. N. Exon Smith930f3882015-04-06 18:02:43 +000081 }
82
83 template <class U>
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +000084 TypedDINodeRef(
85 const TypedDINodeRef<U> &X,
Duncan P. N. Exon Smith930f3882015-04-06 18:02:43 +000086 typename std::enable_if<std::is_convertible<U *, T *>::value>::type * =
87 nullptr)
88 : MD(X) {}
89
90 operator Metadata *() const { return const_cast<Metadata *>(MD); }
91
Duncan P. N. Exon Smitha59d3e52016-04-23 21:08:00 +000092 T *resolve() const { return const_cast<T *>(cast_or_null<T>(MD)); }
93
Hans Wennborg13958b72015-07-22 20:46:11 +000094 bool operator==(const TypedDINodeRef<T> &X) const { return MD == X.MD; }
95 bool operator!=(const TypedDINodeRef<T> &X) const { return MD != X.MD; }
Duncan P. N. Exon Smith930f3882015-04-06 18:02:43 +000096};
97
Eugene Zelenkod761e2c2017-05-15 21:57:41 +000098using DINodeRef = TypedDINodeRef<DINode>;
99using DIScopeRef = TypedDINodeRef<DIScope>;
100using DITypeRef = TypedDINodeRef<DIType>;
Duncan P. N. Exon Smith930f3882015-04-06 18:02:43 +0000101
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000102class DITypeRefArray {
Duncan P. N. Exon Smith62e93622015-04-06 19:48:50 +0000103 const MDTuple *N = nullptr;
104
105public:
Duncan P. N. Exon Smith0660bcd2015-08-28 21:38:24 +0000106 DITypeRefArray() = default;
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000107 DITypeRefArray(const MDTuple *N) : N(N) {}
Duncan P. N. Exon Smith11344732015-04-07 16:50:39 +0000108
109 explicit operator bool() const { return get(); }
110 explicit operator MDTuple *() const { return get(); }
111
112 MDTuple *get() const { return const_cast<MDTuple *>(N); }
113 MDTuple *operator->() const { return get(); }
114 MDTuple &operator*() const { return *get(); }
Duncan P. N. Exon Smith62e93622015-04-06 19:48:50 +0000115
Duncan P. N. Exon Smith000fa2c2015-04-07 04:14:33 +0000116 // FIXME: Fix callers and remove condition on N.
117 unsigned size() const { return N ? N->getNumOperands() : 0u; }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000118 DITypeRef operator[](unsigned I) const { return DITypeRef(N->getOperand(I)); }
Duncan P. N. Exon Smith62e93622015-04-06 19:48:50 +0000119
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000120 class iterator : std::iterator<std::input_iterator_tag, DITypeRef,
121 std::ptrdiff_t, void, DITypeRef> {
Duncan P. N. Exon Smith000fa2c2015-04-07 04:14:33 +0000122 MDNode::op_iterator I = nullptr;
Duncan P. N. Exon Smith62e93622015-04-06 19:48:50 +0000123
124 public:
Duncan P. N. Exon Smith000fa2c2015-04-07 04:14:33 +0000125 iterator() = default;
Duncan P. N. Exon Smith62e93622015-04-06 19:48:50 +0000126 explicit iterator(MDNode::op_iterator I) : I(I) {}
Eugene Zelenko1aa40f42016-11-23 22:25:16 +0000127
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000128 DITypeRef operator*() const { return DITypeRef(*I); }
Eugene Zelenko1aa40f42016-11-23 22:25:16 +0000129
Duncan P. N. Exon Smith62e93622015-04-06 19:48:50 +0000130 iterator &operator++() {
131 ++I;
132 return *this;
133 }
Eugene Zelenko1aa40f42016-11-23 22:25:16 +0000134
Duncan P. N. Exon Smith62e93622015-04-06 19:48:50 +0000135 iterator operator++(int) {
136 iterator Temp(*this);
137 ++I;
138 return Temp;
139 }
Eugene Zelenko1aa40f42016-11-23 22:25:16 +0000140
Duncan P. N. Exon Smith62e93622015-04-06 19:48:50 +0000141 bool operator==(const iterator &X) const { return I == X.I; }
142 bool operator!=(const iterator &X) const { return I != X.I; }
143 };
144
Duncan P. N. Exon Smith000fa2c2015-04-07 04:14:33 +0000145 // FIXME: Fix callers and remove condition on N.
146 iterator begin() const { return N ? iterator(N->op_begin()) : iterator(); }
147 iterator end() const { return N ? iterator(N->op_end()) : iterator(); }
Duncan P. N. Exon Smith62e93622015-04-06 19:48:50 +0000148};
149
Adrian Prantl1687e012016-11-14 22:09:18 +0000150/// Tagged DWARF-like metadata node.
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000151///
152/// A metadata node with a DWARF tag (i.e., a constant named \c DW_TAG_*,
Zachary Turner264b5d92017-06-07 03:48:56 +0000153/// defined in llvm/BinaryFormat/Dwarf.h). Called \a DINode because it's
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000154/// potentially used for non-DWARF output.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000155class DINode : public MDNode {
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000156 friend class LLVMContextImpl;
157 friend class MDNode;
158
159protected:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000160 DINode(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
161 ArrayRef<Metadata *> Ops1, ArrayRef<Metadata *> Ops2 = None)
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000162 : MDNode(C, ID, Storage, Ops1, Ops2) {
163 assert(Tag < 1u << 16);
164 SubclassData16 = Tag;
165 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000166 ~DINode() = default;
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000167
Duncan P. N. Exon Smith252b62d2015-02-05 01:07:47 +0000168 template <class Ty> Ty *getOperandAs(unsigned I) const {
169 return cast_or_null<Ty>(getOperand(I));
170 }
171
Duncan P. N. Exon Smith442ec022015-02-02 19:54:05 +0000172 StringRef getStringOperand(unsigned I) const {
Duncan P. N. Exon Smith252b62d2015-02-05 01:07:47 +0000173 if (auto *S = getOperandAs<MDString>(I))
Duncan P. N. Exon Smith442ec022015-02-02 19:54:05 +0000174 return S->getString();
175 return StringRef();
176 }
177
Duncan P. N. Exon Smith9146fc82015-02-02 20:01:03 +0000178 static MDString *getCanonicalMDString(LLVMContext &Context, StringRef S) {
179 if (S.empty())
180 return nullptr;
181 return MDString::get(Context, S);
182 }
183
Duncan P. N. Exon Smith97386022016-04-19 18:00:19 +0000184 /// Allow subclasses to mutate the tag.
185 void setTag(unsigned Tag) { SubclassData16 = Tag; }
186
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000187public:
188 unsigned getTag() const { return SubclassData16; }
189
Adrian Prantl1687e012016-11-14 22:09:18 +0000190 /// Debug info flags.
Duncan P. N. Exon Smith3744fd02015-03-31 01:19:51 +0000191 ///
192 /// The three accessibility flags are mutually exclusive and rolled together
193 /// in the first two bits.
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000194 enum DIFlags : uint32_t {
Duncan P. N. Exon Smith3744fd02015-03-31 01:19:51 +0000195#define HANDLE_DI_FLAG(ID, NAME) Flag##NAME = ID,
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000196#define DI_FLAG_LARGEST_NEEDED
Duncan P. N. Exon Smith3744fd02015-03-31 01:19:51 +0000197#include "llvm/IR/DebugInfoFlags.def"
Reid Kleckner604105b2016-06-17 21:31:33 +0000198 FlagAccessibility = FlagPrivate | FlagProtected | FlagPublic,
199 FlagPtrToMemberRep = FlagSingleInheritance | FlagMultipleInheritance |
200 FlagVirtualInheritance,
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000201 LLVM_MARK_AS_BITMASK_ENUM(FlagLargest)
Duncan P. N. Exon Smith3744fd02015-03-31 01:19:51 +0000202 };
203
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000204 static DIFlags getFlag(StringRef Flag);
Mehdi Aminif42ec792016-10-01 05:57:50 +0000205 static StringRef getFlagString(DIFlags Flag);
Duncan P. N. Exon Smith5261e4b2015-04-07 01:21:40 +0000206
Adrian Prantl1687e012016-11-14 22:09:18 +0000207 /// Split up a flags bitfield.
Duncan P. N. Exon Smith5261e4b2015-04-07 01:21:40 +0000208 ///
209 /// Split \c Flags into \c SplitFlags, a vector of its components. Returns
210 /// any remaining (unrecognized) bits.
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000211 static DIFlags splitFlags(DIFlags Flags,
Leny Kholodov40c62352016-09-06 17:03:02 +0000212 SmallVectorImpl<DIFlags> &SplitFlags);
Duncan P. N. Exon Smith5261e4b2015-04-07 01:21:40 +0000213
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000214 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000215 switch (MD->getMetadataID()) {
216 default:
217 return false;
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000218 case GenericDINodeKind:
219 case DISubrangeKind:
220 case DIEnumeratorKind:
221 case DIBasicTypeKind:
222 case DIDerivedTypeKind:
223 case DICompositeTypeKind:
224 case DISubroutineTypeKind:
225 case DIFileKind:
226 case DICompileUnitKind:
227 case DISubprogramKind:
228 case DILexicalBlockKind:
229 case DILexicalBlockFileKind:
230 case DINamespaceKind:
231 case DITemplateTypeParameterKind:
232 case DITemplateValueParameterKind:
233 case DIGlobalVariableKind:
234 case DILocalVariableKind:
Shiva Chen2c864552018-05-09 02:40:45 +0000235 case DILabelKind:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000236 case DIObjCPropertyKind:
237 case DIImportedEntityKind:
Adrian Prantlab1243f2015-06-29 23:03:47 +0000238 case DIModuleKind:
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000239 return true;
240 }
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000241 }
242};
243
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000244template <class T> struct simplify_type<const TypedDINodeRef<T>> {
Eugene Zelenkod761e2c2017-05-15 21:57:41 +0000245 using SimpleType = Metadata *;
246
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000247 static SimpleType getSimplifiedValue(const TypedDINodeRef<T> &MD) {
Duncan P. N. Exon Smith930f3882015-04-06 18:02:43 +0000248 return MD;
249 }
250};
251
252template <class T>
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000253struct simplify_type<TypedDINodeRef<T>>
254 : simplify_type<const TypedDINodeRef<T>> {};
Duncan P. N. Exon Smith930f3882015-04-06 18:02:43 +0000255
Adrian Prantl1687e012016-11-14 22:09:18 +0000256/// Generic tagged DWARF-like metadata node.
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000257///
258/// An un-specialized DWARF-like metadata node. The first operand is a
259/// (possibly empty) null-separated \a MDString header that contains arbitrary
260/// fields. The remaining operands are \a dwarf_operands(), and are pointers
261/// to other metadata.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000262class GenericDINode : public DINode {
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000263 friend class LLVMContextImpl;
264 friend class MDNode;
265
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000266 GenericDINode(LLVMContext &C, StorageType Storage, unsigned Hash,
267 unsigned Tag, ArrayRef<Metadata *> Ops1,
268 ArrayRef<Metadata *> Ops2)
269 : DINode(C, GenericDINodeKind, Storage, Tag, Ops1, Ops2) {
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000270 setHash(Hash);
271 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000272 ~GenericDINode() { dropAllReferences(); }
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000273
274 void setHash(unsigned Hash) { SubclassData32 = Hash; }
275 void recalculateHash();
276
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000277 static GenericDINode *getImpl(LLVMContext &Context, unsigned Tag,
278 StringRef Header, ArrayRef<Metadata *> DwarfOps,
279 StorageType Storage, bool ShouldCreate = true) {
Duncan P. N. Exon Smith9146fc82015-02-02 20:01:03 +0000280 return getImpl(Context, Tag, getCanonicalMDString(Context, Header),
281 DwarfOps, Storage, ShouldCreate);
282 }
283
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000284 static GenericDINode *getImpl(LLVMContext &Context, unsigned Tag,
285 MDString *Header, ArrayRef<Metadata *> DwarfOps,
286 StorageType Storage, bool ShouldCreate = true);
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000287
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000288 TempGenericDINode cloneImpl() const {
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000289 return getTemporary(
290 getContext(), getTag(), getHeader(),
291 SmallVector<Metadata *, 4>(dwarf_op_begin(), dwarf_op_end()));
292 }
293
294public:
295 unsigned getHash() const { return SubclassData32; }
296
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000297 DEFINE_MDNODE_GET(GenericDINode, (unsigned Tag, StringRef Header,
298 ArrayRef<Metadata *> DwarfOps),
Duncan P. N. Exon Smith61e62a52015-02-02 19:55:21 +0000299 (Tag, Header, DwarfOps))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000300 DEFINE_MDNODE_GET(GenericDINode, (unsigned Tag, MDString *Header,
301 ArrayRef<Metadata *> DwarfOps),
Duncan P. N. Exon Smith9146fc82015-02-02 20:01:03 +0000302 (Tag, Header, DwarfOps))
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000303
Adrian Prantl1687e012016-11-14 22:09:18 +0000304 /// Return a (temporary) clone of this.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000305 TempGenericDINode clone() const { return cloneImpl(); }
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000306
307 unsigned getTag() const { return SubclassData16; }
Duncan P. N. Exon Smith442ec022015-02-02 19:54:05 +0000308 StringRef getHeader() const { return getStringOperand(0); }
Mehdi Amini5d99c4e2016-03-19 01:02:34 +0000309 MDString *getRawHeader() const { return getOperandAs<MDString>(0); }
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000310
311 op_iterator dwarf_op_begin() const { return op_begin() + 1; }
312 op_iterator dwarf_op_end() const { return op_end(); }
313 op_range dwarf_operands() const {
314 return op_range(dwarf_op_begin(), dwarf_op_end());
315 }
316
317 unsigned getNumDwarfOperands() const { return getNumOperands() - 1; }
318 const MDOperand &getDwarfOperand(unsigned I) const {
319 return getOperand(I + 1);
320 }
321 void replaceDwarfOperandWith(unsigned I, Metadata *New) {
322 replaceOperandWith(I + 1, New);
323 }
324
325 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000326 return MD->getMetadataID() == GenericDINodeKind;
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000327 }
328};
329
Adrian Prantl1687e012016-11-14 22:09:18 +0000330/// Array subrange.
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000331///
332/// TODO: Merge into node for DW_TAG_array_type, which should have a custom
333/// type.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000334class DISubrange : public DINode {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000335 friend class LLVMContextImpl;
336 friend class MDNode;
337
Duncan P. N. Exon Smith5dcf6212015-04-07 00:39:59 +0000338 int64_t LowerBound;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000339
Sander de Smalenfdf40912018-01-24 09:56:07 +0000340 DISubrange(LLVMContext &C, StorageType Storage, Metadata *Node,
341 int64_t LowerBound, ArrayRef<Metadata *> Ops)
342 : DINode(C, DISubrangeKind, Storage, dwarf::DW_TAG_subrange_type, Ops),
343 LowerBound(LowerBound) {}
344
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000345 ~DISubrange() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000346
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000347 static DISubrange *getImpl(LLVMContext &Context, int64_t Count,
Duncan P. N. Exon Smith5dcf6212015-04-07 00:39:59 +0000348 int64_t LowerBound, StorageType Storage,
349 bool ShouldCreate = true);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000350
Sander de Smalenfdf40912018-01-24 09:56:07 +0000351 static DISubrange *getImpl(LLVMContext &Context, Metadata *CountNode,
352 int64_t LowerBound, StorageType Storage,
353 bool ShouldCreate = true);
354
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000355 TempDISubrange cloneImpl() const {
Sander de Smalenfdf40912018-01-24 09:56:07 +0000356 return getTemporary(getContext(), getRawCountNode(), getLowerBound());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000357 }
358
359public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000360 DEFINE_MDNODE_GET(DISubrange, (int64_t Count, int64_t LowerBound = 0),
Duncan P. N. Exon Smith5dcf6212015-04-07 00:39:59 +0000361 (Count, LowerBound))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000362
Sander de Smalenfdf40912018-01-24 09:56:07 +0000363 DEFINE_MDNODE_GET(DISubrange, (Metadata *CountNode, int64_t LowerBound = 0),
364 (CountNode, LowerBound))
365
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000366 TempDISubrange clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000367
Duncan P. N. Exon Smith5dcf6212015-04-07 00:39:59 +0000368 int64_t getLowerBound() const { return LowerBound; }
Sander de Smalenfdf40912018-01-24 09:56:07 +0000369
370 Metadata *getRawCountNode() const {
371 return getOperand(0).get();
372 }
373
374 typedef PointerUnion<ConstantInt*, DIVariable*> CountType;
375
376 CountType getCount() const {
377 if (auto *MD = dyn_cast<ConstantAsMetadata>(getRawCountNode()))
378 return CountType(cast<ConstantInt>(MD->getValue()));
379
380 if (auto *DV = dyn_cast<DIVariable>(getRawCountNode()))
381 return CountType(DV);
382
383 return CountType();
384 }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000385
386 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000387 return MD->getMetadataID() == DISubrangeKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000388 }
389};
390
Adrian Prantl1687e012016-11-14 22:09:18 +0000391/// Enumeration value.
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000392///
393/// TODO: Add a pointer to the context (DW_TAG_enumeration_type) once that no
394/// longer creates a type cycle.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000395class DIEnumerator : public DINode {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000396 friend class LLVMContextImpl;
397 friend class MDNode;
398
399 int64_t Value;
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000400 DIEnumerator(LLVMContext &C, StorageType Storage, int64_t Value,
Momchil Velikov08dc66e2018-02-12 16:10:09 +0000401 bool IsUnsigned, ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000402 : DINode(C, DIEnumeratorKind, Storage, dwarf::DW_TAG_enumerator, Ops),
Momchil Velikov08dc66e2018-02-12 16:10:09 +0000403 Value(Value) {
404 SubclassData32 = IsUnsigned;
405 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000406 ~DIEnumerator() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000407
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000408 static DIEnumerator *getImpl(LLVMContext &Context, int64_t Value,
Momchil Velikov08dc66e2018-02-12 16:10:09 +0000409 bool IsUnsigned, StringRef Name,
410 StorageType Storage, bool ShouldCreate = true) {
411 return getImpl(Context, Value, IsUnsigned,
412 getCanonicalMDString(Context, Name), Storage, ShouldCreate);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000413 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000414 static DIEnumerator *getImpl(LLVMContext &Context, int64_t Value,
Momchil Velikov08dc66e2018-02-12 16:10:09 +0000415 bool IsUnsigned, MDString *Name,
416 StorageType Storage, bool ShouldCreate = true);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000417
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000418 TempDIEnumerator cloneImpl() const {
Momchil Velikov08dc66e2018-02-12 16:10:09 +0000419 return getTemporary(getContext(), getValue(), isUnsigned(), getName());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000420 }
421
422public:
Momchil Velikov08dc66e2018-02-12 16:10:09 +0000423 DEFINE_MDNODE_GET(DIEnumerator, (int64_t Value, bool IsUnsigned, StringRef Name),
424 (Value, IsUnsigned, Name))
425 DEFINE_MDNODE_GET(DIEnumerator, (int64_t Value, bool IsUnsigned, MDString *Name),
426 (Value, IsUnsigned, Name))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000427
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000428 TempDIEnumerator clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000429
430 int64_t getValue() const { return Value; }
Momchil Velikov08dc66e2018-02-12 16:10:09 +0000431 bool isUnsigned() const { return SubclassData32; }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000432 StringRef getName() const { return getStringOperand(0); }
433
Duncan P. N. Exon Smith87754762015-02-13 01:14:11 +0000434 MDString *getRawName() const { return getOperandAs<MDString>(0); }
435
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000436 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000437 return MD->getMetadataID() == DIEnumeratorKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000438 }
439};
440
Adrian Prantl1687e012016-11-14 22:09:18 +0000441/// Base class for scope-like contexts.
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000442///
443/// Base class for lexical scopes and types (which are also declaration
444/// contexts).
445///
446/// TODO: Separate the concepts of declaration contexts and lexical scopes.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000447class DIScope : public DINode {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000448protected:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000449 DIScope(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000450 ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000451 : DINode(C, ID, Storage, Tag, Ops) {}
452 ~DIScope() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000453
454public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000455 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
Duncan P. N. Exon Smith53855f02015-03-27 23:05:04 +0000456
Duncan P. N. Exon Smith50c065b2015-04-11 00:39:43 +0000457 inline StringRef getFilename() const;
458 inline StringRef getDirectory() const;
Scott Linder16c7bda2018-02-23 23:01:06 +0000459 inline Optional<StringRef> getSource() const;
Duncan P. N. Exon Smith50c065b2015-04-11 00:39:43 +0000460
Duncan P. N. Exon Smithf0d81a52015-04-11 17:37:23 +0000461 StringRef getName() const;
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000462 DIScopeRef getScope() const;
Duncan P. N. Exon Smithf0d81a52015-04-11 17:37:23 +0000463
Adrian Prantl1687e012016-11-14 22:09:18 +0000464 /// Return the raw underlying file.
Duncan P. N. Exon Smith2c6a0a92015-02-28 21:47:02 +0000465 ///
Adrian Prantlb9a8f7a2017-07-14 23:23:58 +0000466 /// A \a DIFile is a \a DIScope, but it doesn't point at a separate file (it
467 /// \em is the file). If \c this is an \a DIFile, we need to return \c this.
468 /// Otherwise, return the first operand, which is where all other subclasses
469 /// store their file pointer.
Duncan P. N. Exon Smith53855f02015-03-27 23:05:04 +0000470 Metadata *getRawFile() const {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000471 return isa<DIFile>(this) ? const_cast<DIScope *>(this)
Duncan P. N. Exon Smith3a46c142015-02-28 21:58:10 +0000472 : static_cast<Metadata *>(getOperand(0));
Duncan P. N. Exon Smith2c6a0a92015-02-28 21:47:02 +0000473 }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000474
475 static bool classof(const Metadata *MD) {
476 switch (MD->getMetadataID()) {
477 default:
478 return false;
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000479 case DIBasicTypeKind:
480 case DIDerivedTypeKind:
481 case DICompositeTypeKind:
482 case DISubroutineTypeKind:
483 case DIFileKind:
484 case DICompileUnitKind:
485 case DISubprogramKind:
486 case DILexicalBlockKind:
487 case DILexicalBlockFileKind:
488 case DINamespaceKind:
Adrian Prantlab1243f2015-06-29 23:03:47 +0000489 case DIModuleKind:
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000490 return true;
491 }
492 }
493};
494
Adrian Prantl1687e012016-11-14 22:09:18 +0000495/// File.
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +0000496///
497/// TODO: Merge with directory/file node (including users).
498/// TODO: Canonicalize paths on creation.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000499class DIFile : public DIScope {
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +0000500 friend class LLVMContextImpl;
501 friend class MDNode;
502
Amjad Aboud7faeecc2016-12-25 10:12:09 +0000503public:
Scott Linder71603842018-02-12 19:45:54 +0000504 /// Which algorithm (e.g. MD5) a checksum was generated with.
505 ///
506 /// The encoding is explicit because it is used directly in Bitcode. The
507 /// value 0 is reserved to indicate the absence of a checksum in Bitcode.
Amjad Aboud7faeecc2016-12-25 10:12:09 +0000508 enum ChecksumKind {
Scott Linder71603842018-02-12 19:45:54 +0000509 // The first variant was originally CSK_None, encoded as 0. The new
510 // internal representation removes the need for this by wrapping the
511 // ChecksumInfo in an Optional, but to preserve Bitcode compatibility the 0
512 // encoding is reserved.
Reid Kleckner26fa1bf2017-09-19 18:14:45 +0000513 CSK_MD5 = 1,
514 CSK_SHA1 = 2,
Amjad Aboud7faeecc2016-12-25 10:12:09 +0000515 CSK_Last = CSK_SHA1 // Should be last enumeration.
516 };
517
Scott Linder71603842018-02-12 19:45:54 +0000518 /// A single checksum, represented by a \a Kind and a \a Value (a string).
519 template <typename T>
520 struct ChecksumInfo {
521 /// The kind of checksum which \a Value encodes.
522 ChecksumKind Kind;
523 /// The string value of the checksum.
524 T Value;
Amjad Aboud7faeecc2016-12-25 10:12:09 +0000525
Scott Linder71603842018-02-12 19:45:54 +0000526 ChecksumInfo(ChecksumKind Kind, T Value) : Kind(Kind), Value(Value) { }
527 ~ChecksumInfo() = default;
528 bool operator==(const ChecksumInfo<T> &X) const {
529 return Kind == X.Kind && Value == X.Value;
530 }
531 bool operator!=(const ChecksumInfo<T> &X) const { return !(*this == X); }
532 StringRef getKindAsString() const { return getChecksumKindAsString(Kind); }
533 };
534
535private:
536 Optional<ChecksumInfo<MDString *>> Checksum;
Scott Linder16c7bda2018-02-23 23:01:06 +0000537 Optional<MDString *> Source;
Scott Linder71603842018-02-12 19:45:54 +0000538
539 DIFile(LLVMContext &C, StorageType Storage,
Scott Linder16c7bda2018-02-23 23:01:06 +0000540 Optional<ChecksumInfo<MDString *>> CS, Optional<MDString *> Src,
Amjad Aboud7faeecc2016-12-25 10:12:09 +0000541 ArrayRef<Metadata *> Ops)
542 : DIScope(C, DIFileKind, Storage, dwarf::DW_TAG_file_type, Ops),
Scott Linder16c7bda2018-02-23 23:01:06 +0000543 Checksum(CS), Source(Src) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000544 ~DIFile() = default;
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +0000545
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000546 static DIFile *getImpl(LLVMContext &Context, StringRef Filename,
Scott Linder71603842018-02-12 19:45:54 +0000547 StringRef Directory,
548 Optional<ChecksumInfo<StringRef>> CS,
Scott Linder16c7bda2018-02-23 23:01:06 +0000549 Optional<StringRef> Source,
Amjad Aboud7faeecc2016-12-25 10:12:09 +0000550 StorageType Storage, bool ShouldCreate = true) {
Scott Linder71603842018-02-12 19:45:54 +0000551 Optional<ChecksumInfo<MDString *>> MDChecksum;
552 if (CS)
553 MDChecksum.emplace(CS->Kind, getCanonicalMDString(Context, CS->Value));
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +0000554 return getImpl(Context, getCanonicalMDString(Context, Filename),
Scott Linder71603842018-02-12 19:45:54 +0000555 getCanonicalMDString(Context, Directory), MDChecksum,
Scott Linder16c7bda2018-02-23 23:01:06 +0000556 Source ? Optional<MDString *>(getCanonicalMDString(Context, *Source)) : None,
Scott Linder71603842018-02-12 19:45:54 +0000557 Storage, ShouldCreate);
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +0000558 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000559 static DIFile *getImpl(LLVMContext &Context, MDString *Filename,
Scott Linder71603842018-02-12 19:45:54 +0000560 MDString *Directory,
561 Optional<ChecksumInfo<MDString *>> CS,
Scott Linder16c7bda2018-02-23 23:01:06 +0000562 Optional<MDString *> Source, StorageType Storage,
563 bool ShouldCreate = true);
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +0000564
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000565 TempDIFile cloneImpl() const {
Amjad Aboud7faeecc2016-12-25 10:12:09 +0000566 return getTemporary(getContext(), getFilename(), getDirectory(),
Scott Linder16c7bda2018-02-23 23:01:06 +0000567 getChecksum(), getSource());
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +0000568 }
569
570public:
Amjad Aboud7faeecc2016-12-25 10:12:09 +0000571 DEFINE_MDNODE_GET(DIFile, (StringRef Filename, StringRef Directory,
Scott Linder16c7bda2018-02-23 23:01:06 +0000572 Optional<ChecksumInfo<StringRef>> CS = None,
573 Optional<StringRef> Source = None),
574 (Filename, Directory, CS, Source))
Reid Kleckner26fa1bf2017-09-19 18:14:45 +0000575 DEFINE_MDNODE_GET(DIFile, (MDString * Filename, MDString *Directory,
Scott Linder16c7bda2018-02-23 23:01:06 +0000576 Optional<ChecksumInfo<MDString *>> CS = None,
577 Optional<MDString *> Source = None),
578 (Filename, Directory, CS, Source))
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +0000579
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000580 TempDIFile clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +0000581
582 StringRef getFilename() const { return getStringOperand(0); }
583 StringRef getDirectory() const { return getStringOperand(1); }
Scott Linder71603842018-02-12 19:45:54 +0000584 Optional<ChecksumInfo<StringRef>> getChecksum() const {
585 Optional<ChecksumInfo<StringRef>> StringRefChecksum;
586 if (Checksum)
587 StringRefChecksum.emplace(Checksum->Kind, Checksum->Value->getString());
588 return StringRefChecksum;
589 }
Scott Linder16c7bda2018-02-23 23:01:06 +0000590 Optional<StringRef> getSource() const {
591 return Source ? Optional<StringRef>((*Source)->getString()) : None;
592 }
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +0000593
594 MDString *getRawFilename() const { return getOperandAs<MDString>(0); }
595 MDString *getRawDirectory() const { return getOperandAs<MDString>(1); }
Scott Linder71603842018-02-12 19:45:54 +0000596 Optional<ChecksumInfo<MDString *>> getRawChecksum() const { return Checksum; }
Scott Linder16c7bda2018-02-23 23:01:06 +0000597 Optional<MDString *> getRawSource() const { return Source; }
Amjad Aboud7faeecc2016-12-25 10:12:09 +0000598
Scott Linder71603842018-02-12 19:45:54 +0000599 static StringRef getChecksumKindAsString(ChecksumKind CSKind);
600 static Optional<ChecksumKind> getChecksumKind(StringRef CSKindStr);
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +0000601
602 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000603 return MD->getMetadataID() == DIFileKind;
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +0000604 }
605};
606
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000607StringRef DIScope::getFilename() const {
Duncan P. N. Exon Smith50c065b2015-04-11 00:39:43 +0000608 if (auto *F = getFile())
609 return F->getFilename();
610 return "";
611}
612
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000613StringRef DIScope::getDirectory() const {
Duncan P. N. Exon Smith50c065b2015-04-11 00:39:43 +0000614 if (auto *F = getFile())
615 return F->getDirectory();
616 return "";
617}
618
Scott Linder16c7bda2018-02-23 23:01:06 +0000619Optional<StringRef> DIScope::getSource() const {
620 if (auto *F = getFile())
621 return F->getSource();
622 return None;
623}
624
Adrian Prantl1687e012016-11-14 22:09:18 +0000625/// Base class for types.
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000626///
627/// TODO: Remove the hardcoded name and context, since many types don't use
628/// them.
629/// TODO: Split up flags.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000630class DIType : public DIScope {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000631 unsigned Line;
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000632 DIFlags Flags;
Duncan P. N. Exon Smithd34db172015-02-19 23:56:07 +0000633 uint64_t SizeInBits;
Duncan P. N. Exon Smithd34db172015-02-19 23:56:07 +0000634 uint64_t OffsetInBits;
Victor Leschuk197aa312016-10-18 14:31:22 +0000635 uint32_t AlignInBits;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000636
637protected:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000638 DIType(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
Victor Leschuk197aa312016-10-18 14:31:22 +0000639 unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits,
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000640 uint64_t OffsetInBits, DIFlags Flags, ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smith97386022016-04-19 18:00:19 +0000641 : DIScope(C, ID, Storage, Tag, Ops) {
642 init(Line, SizeInBits, AlignInBits, OffsetInBits, Flags);
643 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000644 ~DIType() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000645
Victor Leschuk197aa312016-10-18 14:31:22 +0000646 void init(unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits,
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000647 uint64_t OffsetInBits, DIFlags Flags) {
Duncan P. N. Exon Smith97386022016-04-19 18:00:19 +0000648 this->Line = Line;
649 this->Flags = Flags;
650 this->SizeInBits = SizeInBits;
651 this->AlignInBits = AlignInBits;
652 this->OffsetInBits = OffsetInBits;
653 }
654
655 /// Change fields in place.
656 void mutate(unsigned Tag, unsigned Line, uint64_t SizeInBits,
Victor Leschuk197aa312016-10-18 14:31:22 +0000657 uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags) {
Duncan P. N. Exon Smith97386022016-04-19 18:00:19 +0000658 assert(isDistinct() && "Only distinct nodes can mutate");
659 setTag(Tag);
660 init(Line, SizeInBits, AlignInBits, OffsetInBits, Flags);
661 }
662
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000663public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000664 TempDIType clone() const {
665 return TempDIType(cast<DIType>(MDNode::clone().release()));
Duncan P. N. Exon Smithb3538492015-03-03 16:45:34 +0000666 }
667
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000668 unsigned getLine() const { return Line; }
Duncan P. N. Exon Smithd34db172015-02-19 23:56:07 +0000669 uint64_t getSizeInBits() const { return SizeInBits; }
Victor Leschuk2ede1262016-10-20 00:13:12 +0000670 uint32_t getAlignInBits() const { return AlignInBits; }
671 uint32_t getAlignInBytes() const { return getAlignInBits() / CHAR_BIT; }
Duncan P. N. Exon Smithd34db172015-02-19 23:56:07 +0000672 uint64_t getOffsetInBits() const { return OffsetInBits; }
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000673 DIFlags getFlags() const { return Flags; }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000674
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000675 DIScopeRef getScope() const { return DIScopeRef(getRawScope()); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000676 StringRef getName() const { return getStringOperand(2); }
677
Duncan P. N. Exon Smith53855f02015-03-27 23:05:04 +0000678
679 Metadata *getRawScope() const { return getOperand(1); }
Duncan P. N. Exon Smith09e03f32015-02-13 01:14:58 +0000680 MDString *getRawName() const { return getOperandAs<MDString>(2); }
681
Roman Tereshincf88ffa2018-06-01 23:15:09 +0000682 /// Returns a new temporary DIType with updated Flags
683 TempDIType cloneWithFlags(DIFlags NewFlags) const {
684 auto NewTy = clone();
685 NewTy->Flags = NewFlags;
686 return NewTy;
Duncan P. N. Exon Smithb3538492015-03-03 16:45:34 +0000687 }
688
Duncan P. N. Exon Smithaecab7a2015-04-07 01:24:30 +0000689 bool isPrivate() const {
690 return (getFlags() & FlagAccessibility) == FlagPrivate;
691 }
692 bool isProtected() const {
693 return (getFlags() & FlagAccessibility) == FlagProtected;
694 }
695 bool isPublic() const {
696 return (getFlags() & FlagAccessibility) == FlagPublic;
697 }
698 bool isForwardDecl() const { return getFlags() & FlagFwdDecl; }
699 bool isAppleBlockExtension() const { return getFlags() & FlagAppleBlock; }
700 bool isBlockByrefStruct() const { return getFlags() & FlagBlockByrefStruct; }
701 bool isVirtual() const { return getFlags() & FlagVirtual; }
702 bool isArtificial() const { return getFlags() & FlagArtificial; }
703 bool isObjectPointer() const { return getFlags() & FlagObjectPointer; }
704 bool isObjcClassComplete() const {
705 return getFlags() & FlagObjcClassComplete;
706 }
707 bool isVector() const { return getFlags() & FlagVector; }
David Majnemer9319cbc2016-06-30 03:00:20 +0000708 bool isBitField() const { return getFlags() & FlagBitField; }
Duncan P. N. Exon Smithaecab7a2015-04-07 01:24:30 +0000709 bool isStaticMember() const { return getFlags() & FlagStaticMember; }
710 bool isLValueReference() const { return getFlags() & FlagLValueReference; }
711 bool isRValueReference() const { return getFlags() & FlagRValueReference; }
Adrian Prantla29aac72018-01-05 01:13:37 +0000712 bool isTypePassByValue() const { return getFlags() & FlagTypePassByValue; }
713 bool isTypePassByReference() const {
714 return getFlags() & FlagTypePassByReference;
715 }
Duncan P. N. Exon Smithaecab7a2015-04-07 01:24:30 +0000716
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000717 static bool classof(const Metadata *MD) {
718 switch (MD->getMetadataID()) {
719 default:
720 return false;
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000721 case DIBasicTypeKind:
722 case DIDerivedTypeKind:
723 case DICompositeTypeKind:
724 case DISubroutineTypeKind:
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000725 return true;
726 }
727 }
728};
729
Adrian Prantl1687e012016-11-14 22:09:18 +0000730/// Basic type, like 'int' or 'float'.
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000731///
732/// TODO: Split out DW_TAG_unspecified_type.
733/// TODO: Drop unused accessors.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000734class DIBasicType : public DIType {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000735 friend class LLVMContextImpl;
736 friend class MDNode;
737
738 unsigned Encoding;
739
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000740 DIBasicType(LLVMContext &C, StorageType Storage, unsigned Tag,
Victor Leschuk197aa312016-10-18 14:31:22 +0000741 uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000742 ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000743 : DIType(C, DIBasicTypeKind, Storage, Tag, 0, SizeInBits, AlignInBits, 0,
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000744 FlagZero, Ops),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000745 Encoding(Encoding) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000746 ~DIBasicType() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000747
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000748 static DIBasicType *getImpl(LLVMContext &Context, unsigned Tag,
Duncan P. N. Exon Smithd34db172015-02-19 23:56:07 +0000749 StringRef Name, uint64_t SizeInBits,
Victor Leschuk197aa312016-10-18 14:31:22 +0000750 uint32_t AlignInBits, unsigned Encoding,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000751 StorageType Storage, bool ShouldCreate = true) {
752 return getImpl(Context, Tag, getCanonicalMDString(Context, Name),
753 SizeInBits, AlignInBits, Encoding, Storage, ShouldCreate);
754 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000755 static DIBasicType *getImpl(LLVMContext &Context, unsigned Tag,
Duncan P. N. Exon Smithd34db172015-02-19 23:56:07 +0000756 MDString *Name, uint64_t SizeInBits,
Victor Leschuk197aa312016-10-18 14:31:22 +0000757 uint32_t AlignInBits, unsigned Encoding,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000758 StorageType Storage, bool ShouldCreate = true);
759
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000760 TempDIBasicType cloneImpl() const {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000761 return getTemporary(getContext(), getTag(), getName(), getSizeInBits(),
762 getAlignInBits(), getEncoding());
763 }
764
765public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000766 DEFINE_MDNODE_GET(DIBasicType, (unsigned Tag, StringRef Name),
Duncan P. N. Exon Smithb3538492015-03-03 16:45:34 +0000767 (Tag, Name, 0, 0, 0))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000768 DEFINE_MDNODE_GET(DIBasicType,
Duncan P. N. Exon Smithd34db172015-02-19 23:56:07 +0000769 (unsigned Tag, StringRef Name, uint64_t SizeInBits,
Victor Leschuk197aa312016-10-18 14:31:22 +0000770 uint32_t AlignInBits, unsigned Encoding),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000771 (Tag, Name, SizeInBits, AlignInBits, Encoding))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000772 DEFINE_MDNODE_GET(DIBasicType,
Duncan P. N. Exon Smithd34db172015-02-19 23:56:07 +0000773 (unsigned Tag, MDString *Name, uint64_t SizeInBits,
Victor Leschuk197aa312016-10-18 14:31:22 +0000774 uint32_t AlignInBits, unsigned Encoding),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000775 (Tag, Name, SizeInBits, AlignInBits, Encoding))
776
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000777 TempDIBasicType clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000778
779 unsigned getEncoding() const { return Encoding; }
780
Vedant Kumar6379a622018-07-06 17:32:39 +0000781 enum class Signedness { Signed, Unsigned };
782
783 /// Return the signedness of this type, or None if this type is neither
784 /// signed nor unsigned.
785 Optional<Signedness> getSignedness() const;
786
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000787 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000788 return MD->getMetadataID() == DIBasicTypeKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000789 }
790};
791
Adrian Prantl1687e012016-11-14 22:09:18 +0000792/// Derived types.
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000793///
794/// This includes qualified types, pointers, references, friends, typedefs, and
795/// class members.
796///
797/// TODO: Split out members (inheritance, fields, methods, etc.).
Duncan P. N. Exon Smith338aef02015-07-24 20:16:36 +0000798class DIDerivedType : public DIType {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000799 friend class LLVMContextImpl;
800 friend class MDNode;
801
Adrian Prantl5f8f34e42018-05-01 15:54:18 +0000802 /// The DWARF address space of the memory pointed to or referenced by a
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000803 /// pointer or reference type respectively.
804 Optional<unsigned> DWARFAddressSpace;
805
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000806 DIDerivedType(LLVMContext &C, StorageType Storage, unsigned Tag,
Victor Leschuk197aa312016-10-18 14:31:22 +0000807 unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits,
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000808 uint64_t OffsetInBits, Optional<unsigned> DWARFAddressSpace,
809 DIFlags Flags, ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smith338aef02015-07-24 20:16:36 +0000810 : DIType(C, DIDerivedTypeKind, Storage, Tag, Line, SizeInBits,
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000811 AlignInBits, OffsetInBits, Flags, Ops),
812 DWARFAddressSpace(DWARFAddressSpace) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000813 ~DIDerivedType() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000814
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000815 static DIDerivedType *getImpl(LLVMContext &Context, unsigned Tag,
816 StringRef Name, DIFile *File, unsigned Line,
817 DIScopeRef Scope, DITypeRef BaseType,
Victor Leschuk197aa312016-10-18 14:31:22 +0000818 uint64_t SizeInBits, uint32_t AlignInBits,
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000819 uint64_t OffsetInBits,
820 Optional<unsigned> DWARFAddressSpace,
821 DIFlags Flags, Metadata *ExtraData,
822 StorageType Storage, bool ShouldCreate = true) {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000823 return getImpl(Context, Tag, getCanonicalMDString(Context, Name), File,
824 Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits,
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000825 DWARFAddressSpace, Flags, ExtraData, Storage, ShouldCreate);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000826 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000827 static DIDerivedType *getImpl(LLVMContext &Context, unsigned Tag,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000828 MDString *Name, Metadata *File, unsigned Line,
829 Metadata *Scope, Metadata *BaseType,
Victor Leschuk197aa312016-10-18 14:31:22 +0000830 uint64_t SizeInBits, uint32_t AlignInBits,
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000831 uint64_t OffsetInBits,
832 Optional<unsigned> DWARFAddressSpace,
833 DIFlags Flags, Metadata *ExtraData,
834 StorageType Storage, bool ShouldCreate = true);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000835
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000836 TempDIDerivedType cloneImpl() const {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000837 return getTemporary(getContext(), getTag(), getName(), getFile(), getLine(),
838 getScope(), getBaseType(), getSizeInBits(),
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000839 getAlignInBits(), getOffsetInBits(),
840 getDWARFAddressSpace(), getFlags(), getExtraData());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000841 }
842
843public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000844 DEFINE_MDNODE_GET(DIDerivedType,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000845 (unsigned Tag, MDString *Name, Metadata *File,
846 unsigned Line, Metadata *Scope, Metadata *BaseType,
Victor Leschuk197aa312016-10-18 14:31:22 +0000847 uint64_t SizeInBits, uint32_t AlignInBits,
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000848 uint64_t OffsetInBits,
849 Optional<unsigned> DWARFAddressSpace, DIFlags Flags,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000850 Metadata *ExtraData = nullptr),
851 (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000852 AlignInBits, OffsetInBits, DWARFAddressSpace, Flags,
853 ExtraData))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000854 DEFINE_MDNODE_GET(DIDerivedType,
855 (unsigned Tag, StringRef Name, DIFile *File, unsigned Line,
856 DIScopeRef Scope, DITypeRef BaseType, uint64_t SizeInBits,
Victor Leschuk197aa312016-10-18 14:31:22 +0000857 uint32_t AlignInBits, uint64_t OffsetInBits,
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000858 Optional<unsigned> DWARFAddressSpace, DIFlags Flags,
859 Metadata *ExtraData = nullptr),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000860 (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000861 AlignInBits, OffsetInBits, DWARFAddressSpace, Flags,
862 ExtraData))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000863
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000864 TempDIDerivedType clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000865
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000866 /// Get the base type this is derived from.
Duncan P. N. Exon Smith338aef02015-07-24 20:16:36 +0000867 DITypeRef getBaseType() const { return DITypeRef(getRawBaseType()); }
868 Metadata *getRawBaseType() const { return getOperand(3); }
869
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000870 /// \returns The DWARF address space of the memory pointed to or referenced by
871 /// a pointer or reference type respectively.
872 Optional<unsigned> getDWARFAddressSpace() const { return DWARFAddressSpace; }
873
Adrian Prantl1687e012016-11-14 22:09:18 +0000874 /// Get extra data associated with this derived type.
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000875 ///
876 /// Class type for pointer-to-members, objective-c property node for ivars,
Brock Wyma3db2b102018-05-14 21:21:22 +0000877 /// global constant wrapper for static members, or virtual base pointer offset
878 /// for inheritance.
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000879 ///
880 /// TODO: Separate out types that need this extra operand: pointer-to-member
881 /// types and member fields (static members and ivars).
Duncan P. N. Exon Smith53855f02015-03-27 23:05:04 +0000882 Metadata *getExtraData() const { return getRawExtraData(); }
883 Metadata *getRawExtraData() const { return getOperand(4); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000884
Adrian Prantl1687e012016-11-14 22:09:18 +0000885 /// Get casted version of extra data.
Duncan P. N. Exon Smith0bf8d4c2015-04-13 23:36:36 +0000886 /// @{
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000887 DITypeRef getClassType() const {
Duncan P. N. Exon Smith0bf8d4c2015-04-13 23:36:36 +0000888 assert(getTag() == dwarf::DW_TAG_ptr_to_member_type);
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000889 return DITypeRef(getExtraData());
Duncan P. N. Exon Smith0bf8d4c2015-04-13 23:36:36 +0000890 }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +0000891
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000892 DIObjCProperty *getObjCProperty() const {
893 return dyn_cast_or_null<DIObjCProperty>(getExtraData());
Duncan P. N. Exon Smith0bf8d4c2015-04-13 23:36:36 +0000894 }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +0000895
Brock Wyma3db2b102018-05-14 21:21:22 +0000896 uint32_t getVBPtrOffset() const {
897 assert(getTag() == dwarf::DW_TAG_inheritance);
898 if (auto *CM = cast_or_null<ConstantAsMetadata>(getExtraData()))
899 if (auto *CI = dyn_cast_or_null<ConstantInt>(CM->getValue()))
900 return static_cast<uint32_t>(CI->getZExtValue());
901 return 0;
902 }
903
David Majnemer9319cbc2016-06-30 03:00:20 +0000904 Constant *getStorageOffsetInBits() const {
905 assert(getTag() == dwarf::DW_TAG_member && isBitField());
906 if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData()))
907 return C->getValue();
908 return nullptr;
909 }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +0000910
Duncan P. N. Exon Smith0bf8d4c2015-04-13 23:36:36 +0000911 Constant *getConstant() const {
912 assert(getTag() == dwarf::DW_TAG_member && isStaticMember());
913 if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData()))
914 return C->getValue();
915 return nullptr;
916 }
Adrian Prantl8c599212018-02-06 23:45:59 +0000917 Constant *getDiscriminantValue() const {
918 assert(getTag() == dwarf::DW_TAG_member && !isStaticMember());
919 if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData()))
920 return C->getValue();
921 return nullptr;
922 }
Duncan P. N. Exon Smith0bf8d4c2015-04-13 23:36:36 +0000923 /// @}
924
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000925 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000926 return MD->getMetadataID() == DIDerivedTypeKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000927 }
928};
929
Adrian Prantl1687e012016-11-14 22:09:18 +0000930/// Composite types.
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000931///
932/// TODO: Detach from DerivedTypeBase (split out MDEnumType?).
933/// TODO: Create a custom, unrelated node for DW_TAG_array_type.
Duncan P. N. Exon Smithb9e045a2015-07-24 20:56:36 +0000934class DICompositeType : public DIType {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000935 friend class LLVMContextImpl;
936 friend class MDNode;
937
Duncan P. N. Exon Smithb9e045a2015-07-24 20:56:36 +0000938 unsigned RuntimeLang;
939
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000940 DICompositeType(LLVMContext &C, StorageType Storage, unsigned Tag,
Duncan P. N. Exon Smithd34db172015-02-19 23:56:07 +0000941 unsigned Line, unsigned RuntimeLang, uint64_t SizeInBits,
Victor Leschuk197aa312016-10-18 14:31:22 +0000942 uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000943 ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smithb9e045a2015-07-24 20:56:36 +0000944 : DIType(C, DICompositeTypeKind, Storage, Tag, Line, SizeInBits,
945 AlignInBits, OffsetInBits, Flags, Ops),
946 RuntimeLang(RuntimeLang) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000947 ~DICompositeType() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000948
Duncan P. N. Exon Smith97386022016-04-19 18:00:19 +0000949 /// Change fields in place.
950 void mutate(unsigned Tag, unsigned Line, unsigned RuntimeLang,
Victor Leschuk197aa312016-10-18 14:31:22 +0000951 uint64_t SizeInBits, uint32_t AlignInBits,
952 uint64_t OffsetInBits, DIFlags Flags) {
Duncan P. N. Exon Smith97386022016-04-19 18:00:19 +0000953 assert(isDistinct() && "Only distinct nodes can mutate");
954 assert(getRawIdentifier() && "Only ODR-uniqued nodes should mutate");
955 this->RuntimeLang = RuntimeLang;
956 DIType::mutate(Tag, Line, SizeInBits, AlignInBits, OffsetInBits, Flags);
957 }
958
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000959 static DICompositeType *
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000960 getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, Metadata *File,
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000961 unsigned Line, DIScopeRef Scope, DITypeRef BaseType,
Victor Leschuk197aa312016-10-18 14:31:22 +0000962 uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000963 DIFlags Flags, DINodeArray Elements, unsigned RuntimeLang,
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000964 DITypeRef VTableHolder, DITemplateParameterArray TemplateParams,
Adrian Prantl8c599212018-02-06 23:45:59 +0000965 StringRef Identifier, DIDerivedType *Discriminator,
966 StorageType Storage, bool ShouldCreate = true) {
Duncan P. N. Exon Smith11344732015-04-07 16:50:39 +0000967 return getImpl(
968 Context, Tag, getCanonicalMDString(Context, Name), File, Line, Scope,
969 BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements.get(),
970 RuntimeLang, VTableHolder, TemplateParams.get(),
Adrian Prantl8c599212018-02-06 23:45:59 +0000971 getCanonicalMDString(Context, Identifier), Discriminator, Storage, ShouldCreate);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000972 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000973 static DICompositeType *
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000974 getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
975 unsigned Line, Metadata *Scope, Metadata *BaseType,
Victor Leschuk197aa312016-10-18 14:31:22 +0000976 uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000977 DIFlags Flags, Metadata *Elements, unsigned RuntimeLang,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000978 Metadata *VTableHolder, Metadata *TemplateParams,
Adrian Prantl8c599212018-02-06 23:45:59 +0000979 MDString *Identifier, Metadata *Discriminator,
980 StorageType Storage, bool ShouldCreate = true);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000981
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000982 TempDICompositeType cloneImpl() const {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000983 return getTemporary(getContext(), getTag(), getName(), getFile(), getLine(),
984 getScope(), getBaseType(), getSizeInBits(),
985 getAlignInBits(), getOffsetInBits(), getFlags(),
986 getElements(), getRuntimeLang(), getVTableHolder(),
Adrian Prantl8c599212018-02-06 23:45:59 +0000987 getTemplateParams(), getIdentifier(), getDiscriminator());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000988 }
989
990public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000991 DEFINE_MDNODE_GET(DICompositeType,
992 (unsigned Tag, StringRef Name, DIFile *File, unsigned Line,
993 DIScopeRef Scope, DITypeRef BaseType, uint64_t SizeInBits,
Victor Leschuk197aa312016-10-18 14:31:22 +0000994 uint32_t AlignInBits, uint64_t OffsetInBits,
995 DIFlags Flags, DINodeArray Elements, unsigned RuntimeLang,
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000996 DITypeRef VTableHolder,
997 DITemplateParameterArray TemplateParams = nullptr,
Adrian Prantl8c599212018-02-06 23:45:59 +0000998 StringRef Identifier = "", DIDerivedType *Discriminator = nullptr),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000999 (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
1000 AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
Adrian Prantl8c599212018-02-06 23:45:59 +00001001 VTableHolder, TemplateParams, Identifier, Discriminator))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001002 DEFINE_MDNODE_GET(DICompositeType,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001003 (unsigned Tag, MDString *Name, Metadata *File,
1004 unsigned Line, Metadata *Scope, Metadata *BaseType,
Victor Leschuk197aa312016-10-18 14:31:22 +00001005 uint64_t SizeInBits, uint32_t AlignInBits,
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001006 uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001007 unsigned RuntimeLang, Metadata *VTableHolder,
1008 Metadata *TemplateParams = nullptr,
Adrian Prantl8c599212018-02-06 23:45:59 +00001009 MDString *Identifier = nullptr,
1010 Metadata *Discriminator = nullptr),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001011 (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
1012 AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
Adrian Prantl8c599212018-02-06 23:45:59 +00001013 VTableHolder, TemplateParams, Identifier, Discriminator))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001014
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001015 TempDICompositeType clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001016
Duncan P. N. Exon Smith0b0271e2016-04-19 14:55:09 +00001017 /// Get a DICompositeType with the given ODR identifier.
1018 ///
1019 /// If \a LLVMContext::isODRUniquingDebugTypes(), gets the mapped
1020 /// DICompositeType for the given ODR \c Identifier. If none exists, creates
1021 /// a new node.
1022 ///
1023 /// Else, returns \c nullptr.
1024 static DICompositeType *
1025 getODRType(LLVMContext &Context, MDString &Identifier, unsigned Tag,
1026 MDString *Name, Metadata *File, unsigned Line, Metadata *Scope,
Victor Leschuk197aa312016-10-18 14:31:22 +00001027 Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits,
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001028 uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements,
Duncan P. N. Exon Smith0b0271e2016-04-19 14:55:09 +00001029 unsigned RuntimeLang, Metadata *VTableHolder,
Adrian Prantl8c599212018-02-06 23:45:59 +00001030 Metadata *TemplateParams, Metadata *Discriminator);
Duncan P. N. Exon Smith0b0271e2016-04-19 14:55:09 +00001031 static DICompositeType *getODRTypeIfExists(LLVMContext &Context,
1032 MDString &Identifier);
1033
Duncan P. N. Exon Smith97386022016-04-19 18:00:19 +00001034 /// Build a DICompositeType with the given ODR identifier.
1035 ///
1036 /// Looks up the mapped DICompositeType for the given ODR \c Identifier. If
1037 /// it doesn't exist, creates a new one. If it does exist and \a
1038 /// isForwardDecl(), and the new arguments would be a definition, mutates the
1039 /// the type in place. In either case, returns the type.
1040 ///
1041 /// If not \a LLVMContext::isODRUniquingDebugTypes(), this function returns
1042 /// nullptr.
1043 static DICompositeType *
1044 buildODRType(LLVMContext &Context, MDString &Identifier, unsigned Tag,
1045 MDString *Name, Metadata *File, unsigned Line, Metadata *Scope,
Victor Leschuk197aa312016-10-18 14:31:22 +00001046 Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits,
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001047 uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements,
Duncan P. N. Exon Smith97386022016-04-19 18:00:19 +00001048 unsigned RuntimeLang, Metadata *VTableHolder,
Adrian Prantl8c599212018-02-06 23:45:59 +00001049 Metadata *TemplateParams, Metadata *Discriminator);
Duncan P. N. Exon Smith97386022016-04-19 18:00:19 +00001050
Duncan P. N. Exon Smithb9e045a2015-07-24 20:56:36 +00001051 DITypeRef getBaseType() const { return DITypeRef(getRawBaseType()); }
1052 DINodeArray getElements() const {
1053 return cast_or_null<MDTuple>(getRawElements());
1054 }
1055 DITypeRef getVTableHolder() const { return DITypeRef(getRawVTableHolder()); }
1056 DITemplateParameterArray getTemplateParams() const {
1057 return cast_or_null<MDTuple>(getRawTemplateParams());
1058 }
1059 StringRef getIdentifier() const { return getStringOperand(7); }
1060 unsigned getRuntimeLang() const { return RuntimeLang; }
1061
1062 Metadata *getRawBaseType() const { return getOperand(3); }
1063 Metadata *getRawElements() const { return getOperand(4); }
1064 Metadata *getRawVTableHolder() const { return getOperand(5); }
1065 Metadata *getRawTemplateParams() const { return getOperand(6); }
1066 MDString *getRawIdentifier() const { return getOperandAs<MDString>(7); }
Adrian Prantl8c599212018-02-06 23:45:59 +00001067 Metadata *getRawDiscriminator() const { return getOperand(8); }
1068 DIDerivedType *getDiscriminator() const { return getOperandAs<DIDerivedType>(8); }
Duncan P. N. Exon Smithb9e045a2015-07-24 20:56:36 +00001069
Adrian Prantl1687e012016-11-14 22:09:18 +00001070 /// Replace operands.
Duncan P. N. Exon Smithb9e045a2015-07-24 20:56:36 +00001071 ///
1072 /// If this \a isUniqued() and not \a isResolved(), on a uniquing collision
1073 /// this will be RAUW'ed and deleted. Use a \a TrackingMDRef to keep track
1074 /// of its movement if necessary.
1075 /// @{
1076 void replaceElements(DINodeArray Elements) {
1077#ifndef NDEBUG
1078 for (DINode *Op : getElements())
David Majnemer42531262016-08-12 03:55:06 +00001079 assert(is_contained(Elements->operands(), Op) &&
Duncan P. N. Exon Smithb9e045a2015-07-24 20:56:36 +00001080 "Lost a member during member list replacement");
1081#endif
1082 replaceOperandWith(4, Elements.get());
1083 }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +00001084
Duncan P. N. Exon Smithb9e045a2015-07-24 20:56:36 +00001085 void replaceVTableHolder(DITypeRef VTableHolder) {
1086 replaceOperandWith(5, VTableHolder);
1087 }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +00001088
Duncan P. N. Exon Smithb9e045a2015-07-24 20:56:36 +00001089 void replaceTemplateParams(DITemplateParameterArray TemplateParams) {
1090 replaceOperandWith(6, TemplateParams.get());
1091 }
1092 /// @}
1093
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001094 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001095 return MD->getMetadataID() == DICompositeTypeKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001096 }
1097};
1098
Adrian Prantl1687e012016-11-14 22:09:18 +00001099/// Type array for a subprogram.
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001100///
Duncan P. N. Exon Smithb9e045a2015-07-24 20:56:36 +00001101/// TODO: Fold the array of types in directly as operands.
1102class DISubroutineType : public DIType {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001103 friend class LLVMContextImpl;
1104 friend class MDNode;
1105
Reid Klecknerde3d8b52016-06-08 20:34:29 +00001106 /// The calling convention used with DW_AT_calling_convention. Actually of
1107 /// type dwarf::CallingConvention.
1108 uint8_t CC;
1109
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001110 DISubroutineType(LLVMContext &C, StorageType Storage, DIFlags Flags,
Reid Klecknerde3d8b52016-06-08 20:34:29 +00001111 uint8_t CC, ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smithb9e045a2015-07-24 20:56:36 +00001112 : DIType(C, DISubroutineTypeKind, Storage, dwarf::DW_TAG_subroutine_type,
Reid Klecknerde3d8b52016-06-08 20:34:29 +00001113 0, 0, 0, 0, Flags, Ops),
1114 CC(CC) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001115 ~DISubroutineType() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001116
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001117 static DISubroutineType *getImpl(LLVMContext &Context, DIFlags Flags,
Reid Klecknerde3d8b52016-06-08 20:34:29 +00001118 uint8_t CC, DITypeRefArray TypeArray,
Duncan P. N. Exon Smith11344732015-04-07 16:50:39 +00001119 StorageType Storage,
1120 bool ShouldCreate = true) {
Reid Klecknerde3d8b52016-06-08 20:34:29 +00001121 return getImpl(Context, Flags, CC, TypeArray.get(), Storage, ShouldCreate);
Duncan P. N. Exon Smith11344732015-04-07 16:50:39 +00001122 }
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001123 static DISubroutineType *getImpl(LLVMContext &Context, DIFlags Flags,
Reid Klecknerde3d8b52016-06-08 20:34:29 +00001124 uint8_t CC, Metadata *TypeArray,
1125 StorageType Storage,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001126 bool ShouldCreate = true);
1127
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001128 TempDISubroutineType cloneImpl() const {
Reid Klecknerde3d8b52016-06-08 20:34:29 +00001129 return getTemporary(getContext(), getFlags(), getCC(), getTypeArray());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001130 }
1131
1132public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001133 DEFINE_MDNODE_GET(DISubroutineType,
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001134 (DIFlags Flags, uint8_t CC, DITypeRefArray TypeArray),
Reid Klecknerde3d8b52016-06-08 20:34:29 +00001135 (Flags, CC, TypeArray))
1136 DEFINE_MDNODE_GET(DISubroutineType,
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001137 (DIFlags Flags, uint8_t CC, Metadata *TypeArray),
Reid Klecknerde3d8b52016-06-08 20:34:29 +00001138 (Flags, CC, TypeArray))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001139
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001140 TempDISubroutineType clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001141
Reid Klecknerde3d8b52016-06-08 20:34:29 +00001142 uint8_t getCC() const { return CC; }
1143
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001144 DITypeRefArray getTypeArray() const {
Duncan P. N. Exon Smith11344732015-04-07 16:50:39 +00001145 return cast_or_null<MDTuple>(getRawTypeArray());
1146 }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +00001147
Duncan P. N. Exon Smithb9e045a2015-07-24 20:56:36 +00001148 Metadata *getRawTypeArray() const { return getOperand(3); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001149
1150 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001151 return MD->getMetadataID() == DISubroutineTypeKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001152 }
1153};
1154
Adrian Prantl1687e012016-11-14 22:09:18 +00001155/// Compile unit.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001156class DICompileUnit : public DIScope {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001157 friend class LLVMContextImpl;
1158 friend class MDNode;
Eugene Zelenko1aa40f42016-11-23 22:25:16 +00001159
Adrian Prantlb939a252016-03-31 23:56:58 +00001160public:
1161 enum DebugEmissionKind : unsigned {
1162 NoDebug = 0,
1163 FullDebug,
1164 LineTablesOnly,
1165 LastEmissionKind = LineTablesOnly
1166 };
Eugene Zelenko1aa40f42016-11-23 22:25:16 +00001167
Adrian Prantlb939a252016-03-31 23:56:58 +00001168 static Optional<DebugEmissionKind> getEmissionKind(StringRef Str);
1169 static const char *EmissionKindString(DebugEmissionKind EK);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001170
Adrian Prantlb939a252016-03-31 23:56:58 +00001171private:
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001172 unsigned SourceLanguage;
1173 bool IsOptimized;
1174 unsigned RuntimeVersion;
1175 unsigned EmissionKind;
Adrian Prantl1f599f92015-05-21 20:37:30 +00001176 uint64_t DWOId;
David Blaikiea01f2952016-08-24 18:29:49 +00001177 bool SplitDebugInlining;
Dehao Chen0944a8c2017-02-01 22:45:09 +00001178 bool DebugInfoForProfiling;
Peter Collingbourneb52e2362017-09-12 21:50:41 +00001179 bool GnuPubnames;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001180
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001181 DICompileUnit(LLVMContext &C, StorageType Storage, unsigned SourceLanguage,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001182 bool IsOptimized, unsigned RuntimeVersion,
David Blaikiea01f2952016-08-24 18:29:49 +00001183 unsigned EmissionKind, uint64_t DWOId, bool SplitDebugInlining,
Peter Collingbourneb52e2362017-09-12 21:50:41 +00001184 bool DebugInfoForProfiling, bool GnuPubnames, ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001185 : DIScope(C, DICompileUnitKind, Storage, dwarf::DW_TAG_compile_unit, Ops),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001186 SourceLanguage(SourceLanguage), IsOptimized(IsOptimized),
Adrian Prantl1f599f92015-05-21 20:37:30 +00001187 RuntimeVersion(RuntimeVersion), EmissionKind(EmissionKind),
Dehao Chen0944a8c2017-02-01 22:45:09 +00001188 DWOId(DWOId), SplitDebugInlining(SplitDebugInlining),
Peter Collingbourneb52e2362017-09-12 21:50:41 +00001189 DebugInfoForProfiling(DebugInfoForProfiling), GnuPubnames(GnuPubnames) {
Duncan P. N. Exon Smith55ca9642015-08-03 17:26:41 +00001190 assert(Storage != Uniqued);
1191 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001192 ~DICompileUnit() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001193
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001194 static DICompileUnit *
1195 getImpl(LLVMContext &Context, unsigned SourceLanguage, DIFile *File,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001196 StringRef Producer, bool IsOptimized, StringRef Flags,
1197 unsigned RuntimeVersion, StringRef SplitDebugFilename,
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001198 unsigned EmissionKind, DICompositeTypeArray EnumTypes,
Adrian Prantlbceaaa92016-12-20 02:09:43 +00001199 DIScopeArray RetainedTypes,
1200 DIGlobalVariableExpressionArray GlobalVariables,
Amjad Abouda9bcf162015-12-10 12:56:35 +00001201 DIImportedEntityArray ImportedEntities, DIMacroNodeArray Macros,
Dehao Chen0944a8c2017-02-01 22:45:09 +00001202 uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling,
Peter Collingbourneb52e2362017-09-12 21:50:41 +00001203 bool GnuPubnames, StorageType Storage, bool ShouldCreate = true) {
1204 return getImpl(
1205 Context, SourceLanguage, File, getCanonicalMDString(Context, Producer),
1206 IsOptimized, getCanonicalMDString(Context, Flags), RuntimeVersion,
1207 getCanonicalMDString(Context, SplitDebugFilename), EmissionKind,
1208 EnumTypes.get(), RetainedTypes.get(), GlobalVariables.get(),
1209 ImportedEntities.get(), Macros.get(), DWOId, SplitDebugInlining,
1210 DebugInfoForProfiling, GnuPubnames, Storage, ShouldCreate);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001211 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001212 static DICompileUnit *
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001213 getImpl(LLVMContext &Context, unsigned SourceLanguage, Metadata *File,
1214 MDString *Producer, bool IsOptimized, MDString *Flags,
1215 unsigned RuntimeVersion, MDString *SplitDebugFilename,
Adrian Prantl75819ae2016-04-15 15:57:41 +00001216 unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes,
Adrian Prantlb939a252016-03-31 23:56:58 +00001217 Metadata *GlobalVariables, Metadata *ImportedEntities,
David Blaikiea01f2952016-08-24 18:29:49 +00001218 Metadata *Macros, uint64_t DWOId, bool SplitDebugInlining,
Peter Collingbourneb52e2362017-09-12 21:50:41 +00001219 bool DebugInfoForProfiling, bool GnuPubnames, StorageType Storage,
Dehao Chen0944a8c2017-02-01 22:45:09 +00001220 bool ShouldCreate = true);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001221
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001222 TempDICompileUnit cloneImpl() const {
David Blaikiea01f2952016-08-24 18:29:49 +00001223 return getTemporary(getContext(), getSourceLanguage(), getFile(),
1224 getProducer(), isOptimized(), getFlags(),
1225 getRuntimeVersion(), getSplitDebugFilename(),
1226 getEmissionKind(), getEnumTypes(), getRetainedTypes(),
1227 getGlobalVariables(), getImportedEntities(),
Dehao Chen0944a8c2017-02-01 22:45:09 +00001228 getMacros(), DWOId, getSplitDebugInlining(),
Peter Collingbourneb52e2362017-09-12 21:50:41 +00001229 getDebugInfoForProfiling(), getGnuPubnames());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001230 }
1231
Eugene Zelenko1aa40f42016-11-23 22:25:16 +00001232public:
Duncan P. N. Exon Smith55ca9642015-08-03 17:26:41 +00001233 static void get() = delete;
1234 static void getIfExists() = delete;
1235
Duncan P. N. Exon Smith55ca9642015-08-03 17:26:41 +00001236 DEFINE_MDNODE_GET_DISTINCT_TEMPORARY(
1237 DICompileUnit,
1238 (unsigned SourceLanguage, DIFile *File, StringRef Producer,
1239 bool IsOptimized, StringRef Flags, unsigned RuntimeVersion,
Adrian Prantlb939a252016-03-31 23:56:58 +00001240 StringRef SplitDebugFilename, DebugEmissionKind EmissionKind,
Adrian Prantl75819ae2016-04-15 15:57:41 +00001241 DICompositeTypeArray EnumTypes, DIScopeArray RetainedTypes,
Adrian Prantlbceaaa92016-12-20 02:09:43 +00001242 DIGlobalVariableExpressionArray GlobalVariables,
Amjad Abouda9bcf162015-12-10 12:56:35 +00001243 DIImportedEntityArray ImportedEntities, DIMacroNodeArray Macros,
Peter Collingbourneb52e2362017-09-12 21:50:41 +00001244 uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling,
1245 bool GnuPubnames),
Duncan P. N. Exon Smith55ca9642015-08-03 17:26:41 +00001246 (SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion,
Adrian Prantl75819ae2016-04-15 15:57:41 +00001247 SplitDebugFilename, EmissionKind, EnumTypes, RetainedTypes,
Dehao Chen0944a8c2017-02-01 22:45:09 +00001248 GlobalVariables, ImportedEntities, Macros, DWOId, SplitDebugInlining,
Peter Collingbourneb52e2362017-09-12 21:50:41 +00001249 DebugInfoForProfiling, GnuPubnames))
Duncan P. N. Exon Smith55ca9642015-08-03 17:26:41 +00001250 DEFINE_MDNODE_GET_DISTINCT_TEMPORARY(
Adrian Prantl1f599f92015-05-21 20:37:30 +00001251 DICompileUnit,
1252 (unsigned SourceLanguage, Metadata *File, MDString *Producer,
1253 bool IsOptimized, MDString *Flags, unsigned RuntimeVersion,
1254 MDString *SplitDebugFilename, unsigned EmissionKind, Metadata *EnumTypes,
Adrian Prantl75819ae2016-04-15 15:57:41 +00001255 Metadata *RetainedTypes, Metadata *GlobalVariables,
David Blaikiea01f2952016-08-24 18:29:49 +00001256 Metadata *ImportedEntities, Metadata *Macros, uint64_t DWOId,
Peter Collingbourneb52e2362017-09-12 21:50:41 +00001257 bool SplitDebugInlining, bool DebugInfoForProfiling, bool GnuPubnames),
Adrian Prantl1f599f92015-05-21 20:37:30 +00001258 (SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion,
Adrian Prantl75819ae2016-04-15 15:57:41 +00001259 SplitDebugFilename, EmissionKind, EnumTypes, RetainedTypes,
Dehao Chen0944a8c2017-02-01 22:45:09 +00001260 GlobalVariables, ImportedEntities, Macros, DWOId, SplitDebugInlining,
Peter Collingbourneb52e2362017-09-12 21:50:41 +00001261 DebugInfoForProfiling, GnuPubnames))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001262
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001263 TempDICompileUnit clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001264
1265 unsigned getSourceLanguage() const { return SourceLanguage; }
1266 bool isOptimized() const { return IsOptimized; }
1267 unsigned getRuntimeVersion() const { return RuntimeVersion; }
Adrian Prantlb939a252016-03-31 23:56:58 +00001268 DebugEmissionKind getEmissionKind() const {
1269 return (DebugEmissionKind)EmissionKind;
1270 }
Dehao Chen0944a8c2017-02-01 22:45:09 +00001271 bool getDebugInfoForProfiling() const { return DebugInfoForProfiling; }
Peter Collingbourneb52e2362017-09-12 21:50:41 +00001272 bool getGnuPubnames() const { return GnuPubnames; }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001273 StringRef getProducer() const { return getStringOperand(1); }
1274 StringRef getFlags() const { return getStringOperand(2); }
1275 StringRef getSplitDebugFilename() const { return getStringOperand(3); }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001276 DICompositeTypeArray getEnumTypes() const {
Duncan P. N. Exon Smith53855f02015-03-27 23:05:04 +00001277 return cast_or_null<MDTuple>(getRawEnumTypes());
1278 }
Adrian Prantl75819ae2016-04-15 15:57:41 +00001279 DIScopeArray getRetainedTypes() const {
Duncan P. N. Exon Smith53855f02015-03-27 23:05:04 +00001280 return cast_or_null<MDTuple>(getRawRetainedTypes());
1281 }
Adrian Prantlbceaaa92016-12-20 02:09:43 +00001282 DIGlobalVariableExpressionArray getGlobalVariables() const {
Duncan P. N. Exon Smith53855f02015-03-27 23:05:04 +00001283 return cast_or_null<MDTuple>(getRawGlobalVariables());
1284 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001285 DIImportedEntityArray getImportedEntities() const {
Duncan P. N. Exon Smith53855f02015-03-27 23:05:04 +00001286 return cast_or_null<MDTuple>(getRawImportedEntities());
1287 }
Amjad Abouda9bcf162015-12-10 12:56:35 +00001288 DIMacroNodeArray getMacros() const {
1289 return cast_or_null<MDTuple>(getRawMacros());
1290 }
Adrian Prantlfbfc58e2015-09-22 23:21:03 +00001291 uint64_t getDWOId() const { return DWOId; }
Adrian Prantl44103922015-09-22 23:21:06 +00001292 void setDWOId(uint64_t DwoId) { DWOId = DwoId; }
David Blaikiea01f2952016-08-24 18:29:49 +00001293 bool getSplitDebugInlining() const { return SplitDebugInlining; }
1294 void setSplitDebugInlining(bool SplitDebugInlining) {
1295 this->SplitDebugInlining = SplitDebugInlining;
1296 }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001297
Duncan P. N. Exon Smithc1f1acc2015-02-13 01:25:10 +00001298 MDString *getRawProducer() const { return getOperandAs<MDString>(1); }
1299 MDString *getRawFlags() const { return getOperandAs<MDString>(2); }
1300 MDString *getRawSplitDebugFilename() const {
1301 return getOperandAs<MDString>(3);
1302 }
Duncan P. N. Exon Smith53855f02015-03-27 23:05:04 +00001303 Metadata *getRawEnumTypes() const { return getOperand(4); }
1304 Metadata *getRawRetainedTypes() const { return getOperand(5); }
Adrian Prantl75819ae2016-04-15 15:57:41 +00001305 Metadata *getRawGlobalVariables() const { return getOperand(6); }
1306 Metadata *getRawImportedEntities() const { return getOperand(7); }
1307 Metadata *getRawMacros() const { return getOperand(8); }
Duncan P. N. Exon Smithc1f1acc2015-02-13 01:25:10 +00001308
Adrian Prantl1687e012016-11-14 22:09:18 +00001309 /// Replace arrays.
Duncan P. N. Exon Smith94bbbf02015-02-18 20:36:09 +00001310 ///
1311 /// If this \a isUniqued() and not \a isResolved(), it will be RAUW'ed and
1312 /// deleted on a uniquing collision. In practice, uniquing collisions on \a
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001313 /// DICompileUnit should be fairly rare.
Duncan P. N. Exon Smith94bbbf02015-02-18 20:36:09 +00001314 /// @{
Adrian Prantl4afc1f42015-07-06 16:22:07 +00001315 void replaceEnumTypes(DICompositeTypeArray N) {
Adrian Prantl18c073a2015-07-02 22:32:52 +00001316 replaceOperandWith(4, N.get());
1317 }
Adrian Prantl4afc1f42015-07-06 16:22:07 +00001318 void replaceRetainedTypes(DITypeArray N) {
Adrian Prantl18c073a2015-07-02 22:32:52 +00001319 replaceOperandWith(5, N.get());
1320 }
Adrian Prantlbceaaa92016-12-20 02:09:43 +00001321 void replaceGlobalVariables(DIGlobalVariableExpressionArray N) {
Duncan P. N. Exon Smith11344732015-04-07 16:50:39 +00001322 replaceOperandWith(6, N.get());
1323 }
Adrian Prantl75819ae2016-04-15 15:57:41 +00001324 void replaceImportedEntities(DIImportedEntityArray N) {
Duncan P. N. Exon Smith11344732015-04-07 16:50:39 +00001325 replaceOperandWith(7, N.get());
1326 }
Adrian Prantl75819ae2016-04-15 15:57:41 +00001327 void replaceMacros(DIMacroNodeArray N) { replaceOperandWith(8, N.get()); }
Duncan P. N. Exon Smith94bbbf02015-02-18 20:36:09 +00001328 /// @}
1329
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001330 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001331 return MD->getMetadataID() == DICompileUnitKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001332 }
1333};
1334
Adrian Prantl1687e012016-11-14 22:09:18 +00001335/// A scope for locals.
Duncan P. N. Exon Smitha65159a2015-03-24 16:44:29 +00001336///
1337/// A legal scope for lexical blocks, local variables, and debug info
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001338/// locations. Subclasses are \a DISubprogram, \a DILexicalBlock, and \a
1339/// DILexicalBlockFile.
1340class DILocalScope : public DIScope {
Duncan P. N. Exon Smitha65159a2015-03-24 16:44:29 +00001341protected:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001342 DILocalScope(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
Duncan P. N. Exon Smitha65159a2015-03-24 16:44:29 +00001343 ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001344 : DIScope(C, ID, Storage, Tag, Ops) {}
1345 ~DILocalScope() = default;
Duncan P. N. Exon Smitha65159a2015-03-24 16:44:29 +00001346
1347public:
Adrian Prantl1687e012016-11-14 22:09:18 +00001348 /// Get the subprogram for this scope.
Duncan P. N. Exon Smithfd07a2a2015-03-30 21:32:28 +00001349 ///
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001350 /// Return this if it's an \a DISubprogram; otherwise, look up the scope
Duncan P. N. Exon Smithfd07a2a2015-03-30 21:32:28 +00001351 /// chain.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001352 DISubprogram *getSubprogram() const;
Duncan P. N. Exon Smithfd07a2a2015-03-30 21:32:28 +00001353
Amjad Abouda5ba9912016-04-21 16:58:49 +00001354 /// Get the first non DILexicalBlockFile scope of this scope.
1355 ///
1356 /// Return this if it's not a \a DILexicalBlockFIle; otherwise, look up the
1357 /// scope chain.
1358 DILocalScope *getNonLexicalBlockFileScope() const;
1359
Duncan P. N. Exon Smitha65159a2015-03-24 16:44:29 +00001360 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001361 return MD->getMetadataID() == DISubprogramKind ||
1362 MD->getMetadataID() == DILexicalBlockKind ||
1363 MD->getMetadataID() == DILexicalBlockFileKind;
Duncan P. N. Exon Smitha65159a2015-03-24 16:44:29 +00001364 }
1365};
1366
Adrian Prantl1687e012016-11-14 22:09:18 +00001367/// Debug location.
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001368///
1369/// A debug location in source code, used for debug info and otherwise.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001370class DILocation : public MDNode {
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001371 friend class LLVMContextImpl;
1372 friend class MDNode;
1373
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001374 DILocation(LLVMContext &C, StorageType Storage, unsigned Line,
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001375 unsigned Column, ArrayRef<Metadata *> MDs);
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001376 ~DILocation() { dropAllReferences(); }
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001377
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001378 static DILocation *getImpl(LLVMContext &Context, unsigned Line,
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001379 unsigned Column, Metadata *Scope,
1380 Metadata *InlinedAt, StorageType Storage,
1381 bool ShouldCreate = true);
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001382 static DILocation *getImpl(LLVMContext &Context, unsigned Line,
1383 unsigned Column, DILocalScope *Scope,
1384 DILocation *InlinedAt, StorageType Storage,
Duncan P. N. Exon Smith26489982015-03-26 22:05:04 +00001385 bool ShouldCreate = true) {
1386 return getImpl(Context, Line, Column, static_cast<Metadata *>(Scope),
1387 static_cast<Metadata *>(InlinedAt), Storage, ShouldCreate);
1388 }
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001389
Dehao Chen726da622017-02-15 17:54:39 +00001390 /// With a given unsigned int \p U, use up to 13 bits to represent it.
1391 /// old_bit 1~5 --> new_bit 1~5
1392 /// old_bit 6~12 --> new_bit 7~13
1393 /// new_bit_6 is 0 if higher bits (7~13) are all 0
1394 static unsigned getPrefixEncodingFromUnsigned(unsigned U) {
1395 U &= 0xfff;
1396 return U > 0x1f ? (((U & 0xfe0) << 1) | (U & 0x1f) | 0x20) : U;
1397 }
1398
1399 /// Reverse transformation as getPrefixEncodingFromUnsigned.
1400 static unsigned getUnsignedFromPrefixEncoding(unsigned U) {
1401 return (U & 0x20) ? (((U >> 1) & 0xfe0) | (U & 0x1f)) : (U & 0x1f);
1402 }
1403
1404 /// Returns the next component stored in discriminator.
1405 static unsigned getNextComponentInDiscriminator(unsigned D) {
1406 if ((D & 1) == 0)
1407 return D >> ((D & 0x40) ? 14 : 7);
1408 else
1409 return D >> 1;
1410 }
1411
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001412 TempDILocation cloneImpl() const {
Teresa Johnsond98152b62015-12-07 15:05:44 +00001413 // Get the raw scope/inlinedAt since it is possible to invoke this on
1414 // a DILocation containing temporary metadata.
1415 return getTemporary(getContext(), getLine(), getColumn(), getRawScope(),
1416 getRawInlinedAt());
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001417 }
1418
Eugene Zelenko1aa40f42016-11-23 22:25:16 +00001419public:
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001420 // Disallow replacing operands.
1421 void replaceOperandWith(unsigned I, Metadata *New) = delete;
1422
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001423 DEFINE_MDNODE_GET(DILocation,
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001424 (unsigned Line, unsigned Column, Metadata *Scope,
1425 Metadata *InlinedAt = nullptr),
1426 (Line, Column, Scope, InlinedAt))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001427 DEFINE_MDNODE_GET(DILocation,
1428 (unsigned Line, unsigned Column, DILocalScope *Scope,
1429 DILocation *InlinedAt = nullptr),
Duncan P. N. Exon Smith26489982015-03-26 22:05:04 +00001430 (Line, Column, Scope, InlinedAt))
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001431
Adrian Prantl1687e012016-11-14 22:09:18 +00001432 /// Return a (temporary) clone of this.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001433 TempDILocation clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001434
1435 unsigned getLine() const { return SubclassData32; }
1436 unsigned getColumn() const { return SubclassData16; }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001437 DILocalScope *getScope() const { return cast<DILocalScope>(getRawScope()); }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +00001438
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001439 DILocation *getInlinedAt() const {
1440 return cast_or_null<DILocation>(getRawInlinedAt());
Duncan P. N. Exon Smith26489982015-03-26 22:05:04 +00001441 }
1442
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001443 DIFile *getFile() const { return getScope()->getFile(); }
Duncan P. N. Exon Smith50c065b2015-04-11 00:39:43 +00001444 StringRef getFilename() const { return getScope()->getFilename(); }
1445 StringRef getDirectory() const { return getScope()->getDirectory(); }
Scott Linder16c7bda2018-02-23 23:01:06 +00001446 Optional<StringRef> getSource() const { return getScope()->getSource(); }
Duncan P. N. Exon Smith50c065b2015-04-11 00:39:43 +00001447
Adrian Prantl1687e012016-11-14 22:09:18 +00001448 /// Get the scope where this is inlined.
Duncan P. N. Exon Smith8f7bc792015-03-30 17:41:24 +00001449 ///
1450 /// Walk through \a getInlinedAt() and return \a getScope() from the deepest
1451 /// location.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001452 DILocalScope *getInlinedAtScope() const {
Duncan P. N. Exon Smith8f7bc792015-03-30 17:41:24 +00001453 if (auto *IA = getInlinedAt())
1454 return IA->getInlinedAtScope();
1455 return getScope();
1456 }
1457
Adrian Prantl1687e012016-11-14 22:09:18 +00001458 /// Check whether this can be discriminated from another location.
Duncan P. N. Exon Smith63ffa212015-04-11 01:00:47 +00001459 ///
1460 /// Check \c this can be discriminated from \c RHS in a linetable entry.
1461 /// Scope and inlined-at chains are not recorded in the linetable, so they
1462 /// cannot be used to distinguish basic blocks.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001463 bool canDiscriminate(const DILocation &RHS) const {
Robert Lougher426851e2017-01-12 20:34:35 +00001464 return getLine() != RHS.getLine() ||
1465 getColumn() != RHS.getColumn() ||
1466 getDiscriminator() != RHS.getDiscriminator() ||
1467 getFilename() != RHS.getFilename() ||
1468 getDirectory() != RHS.getDirectory();
Duncan P. N. Exon Smith63ffa212015-04-11 01:00:47 +00001469 }
1470
Adrian Prantl1687e012016-11-14 22:09:18 +00001471 /// Get the DWARF discriminator.
Duncan P. N. Exon Smith2c8291e2015-04-14 00:05:13 +00001472 ///
1473 /// DWARF discriminators distinguish identical file locations between
1474 /// instructions that are on different basic blocks.
Dehao Chenfb02f712017-02-10 21:09:07 +00001475 ///
1476 /// There are 3 components stored in discriminator, from lower bits:
1477 ///
1478 /// Base discriminator: assigned by AddDiscriminators pass to identify IRs
1479 /// that are defined by the same source line, but
1480 /// different basic blocks.
1481 /// Duplication factor: assigned by optimizations that will scale down
1482 /// the execution frequency of the original IR.
1483 /// Copy Identifier: assigned by optimizations that clones the IR.
1484 /// Each copy of the IR will be assigned an identifier.
1485 ///
1486 /// Encoding:
1487 ///
1488 /// The above 3 components are encoded into a 32bit unsigned integer in
1489 /// order. If the lowest bit is 1, the current component is empty, and the
Hiroshi Inoue4cf7b882018-01-23 05:49:30 +00001490 /// next component will start in the next bit. Otherwise, the current
Dehao Chenfb02f712017-02-10 21:09:07 +00001491 /// component is non-empty, and its content starts in the next bit. The
1492 /// length of each components is either 5 bit or 12 bit: if the 7th bit
1493 /// is 0, the bit 2~6 (5 bits) are used to represent the component; if the
1494 /// 7th bit is 1, the bit 2~6 (5 bits) and 8~14 (7 bits) are combined to
1495 /// represent the component.
1496
Duncan P. N. Exon Smith2c8291e2015-04-14 00:05:13 +00001497 inline unsigned getDiscriminator() const;
1498
Dehao Chene7130002016-10-26 15:48:45 +00001499 /// Returns a new DILocation with updated \p Discriminator.
Dehao Chenfb02f712017-02-10 21:09:07 +00001500 inline const DILocation *cloneWithDiscriminator(unsigned Discriminator) const;
1501
1502 /// Returns a new DILocation with updated base discriminator \p BD.
1503 inline const DILocation *setBaseDiscriminator(unsigned BD) const;
1504
1505 /// Returns the duplication factor stored in the discriminator.
1506 inline unsigned getDuplicationFactor() const;
1507
1508 /// Returns the copy identifier stored in the discriminator.
1509 inline unsigned getCopyIdentifier() const;
1510
1511 /// Returns the base discriminator stored in the discriminator.
1512 inline unsigned getBaseDiscriminator() const;
1513
1514 /// Returns a new DILocation with duplication factor \p DF encoded in the
1515 /// discriminator.
1516 inline const DILocation *cloneWithDuplicationFactor(unsigned DF) const;
Dehao Chene7130002016-10-26 15:48:45 +00001517
Vedant Kumar65b0d4d2018-04-12 20:58:24 +00001518 enum { NoGeneratedLocation = false, WithGeneratedLocation = true };
1519
Robert Lougher7bd04e32016-12-14 16:14:17 +00001520 /// When two instructions are combined into a single instruction we also
1521 /// need to combine the original locations into a single location.
1522 ///
1523 /// When the locations are the same we can use either location. When they
Vedant Kumar65b0d4d2018-04-12 20:58:24 +00001524 /// differ, we need a third location which is distinct from either. If they
1525 /// have the same file/line but have a different discriminator we could
1526 /// create a location with a new discriminator. If they are from different
1527 /// files/lines the location is ambiguous and can't be represented in a line
1528 /// entry. In this case, if \p GenerateLocation is true, we will set the
1529 /// merged debug location as line 0 of the nearest common scope where the two
1530 /// locations are inlined from.
Robert Lougher7bd04e32016-12-14 16:14:17 +00001531 ///
Vedant Kumar65b0d4d2018-04-12 20:58:24 +00001532 /// \p GenerateLocation: Whether the merged location can be generated when
1533 /// \p LocA and \p LocB differ.
Vedant Kumar2b881f52017-11-06 23:15:21 +00001534 static const DILocation *
1535 getMergedLocation(const DILocation *LocA, const DILocation *LocB,
Vedant Kumar65b0d4d2018-04-12 20:58:24 +00001536 bool GenerateLocation = NoGeneratedLocation);
Robert Lougher7bd04e32016-12-14 16:14:17 +00001537
Dehao Chen726da622017-02-15 17:54:39 +00001538 /// Returns the base discriminator for a given encoded discriminator \p D.
1539 static unsigned getBaseDiscriminatorFromDiscriminator(unsigned D) {
1540 if ((D & 1) == 0)
1541 return getUnsignedFromPrefixEncoding(D >> 1);
1542 else
1543 return 0;
1544 }
1545
1546 /// Returns the duplication factor for a given encoded discriminator \p D.
1547 static unsigned getDuplicationFactorFromDiscriminator(unsigned D) {
1548 D = getNextComponentInDiscriminator(D);
1549 if (D == 0 || (D & 1))
1550 return 1;
1551 else
1552 return getUnsignedFromPrefixEncoding(D >> 1);
1553 }
1554
1555 /// Returns the copy identifier for a given encoded discriminator \p D.
1556 static unsigned getCopyIdentifierFromDiscriminator(unsigned D) {
1557 return getUnsignedFromPrefixEncoding(getNextComponentInDiscriminator(
1558 getNextComponentInDiscriminator(D)));
1559 }
1560
1561
Duncan P. N. Exon Smith26489982015-03-26 22:05:04 +00001562 Metadata *getRawScope() const { return getOperand(0); }
1563 Metadata *getRawInlinedAt() const {
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001564 if (getNumOperands() == 2)
1565 return getOperand(1);
1566 return nullptr;
1567 }
1568
1569 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001570 return MD->getMetadataID() == DILocationKind;
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001571 }
1572};
1573
Adrian Prantl1687e012016-11-14 22:09:18 +00001574/// Subprogram description.
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001575///
1576/// TODO: Remove DisplayName. It's always equal to Name.
1577/// TODO: Split up flags.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001578class DISubprogram : public DILocalScope {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001579 friend class LLVMContextImpl;
1580 friend class MDNode;
1581
1582 unsigned Line;
1583 unsigned ScopeLine;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001584 unsigned VirtualIndex;
Davide Italiano236e7442016-04-13 20:17:42 +00001585
Reid Klecknerb5af11d2016-07-01 02:41:21 +00001586 /// In the MS ABI, the implicit 'this' parameter is adjusted in the prologue
1587 /// of method overrides from secondary bases by this amount. It may be
1588 /// negative.
1589 int ThisAdjustment;
1590
Davide Italiano236e7442016-04-13 20:17:42 +00001591 // Virtuality can only assume three values, so we can pack
1592 // in 2 bits (none/pure/pure_virtual).
1593 unsigned Virtuality : 2;
1594
Davide Italiano236e7442016-04-13 20:17:42 +00001595 // These are boolean flags so one bit is enough.
1596 // MSVC starts a new container field every time the base
1597 // type changes so we can't use 'bool' to ensure these bits
1598 // are packed.
1599 unsigned IsLocalToUnit : 1;
1600 unsigned IsDefinition : 1;
1601 unsigned IsOptimized : 1;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001602
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001603 unsigned Padding : 3;
1604
1605 DIFlags Flags;
1606
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001607 DISubprogram(LLVMContext &C, StorageType Storage, unsigned Line,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001608 unsigned ScopeLine, unsigned Virtuality, unsigned VirtualIndex,
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001609 int ThisAdjustment, DIFlags Flags, bool IsLocalToUnit,
Reid Klecknerb5af11d2016-07-01 02:41:21 +00001610 bool IsDefinition, bool IsOptimized, ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001611 : DILocalScope(C, DISubprogramKind, Storage, dwarf::DW_TAG_subprogram,
Duncan P. N. Exon Smitha65159a2015-03-24 16:44:29 +00001612 Ops),
Davide Italiano236e7442016-04-13 20:17:42 +00001613 Line(Line), ScopeLine(ScopeLine), VirtualIndex(VirtualIndex),
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001614 ThisAdjustment(ThisAdjustment), Virtuality(Virtuality),
Reid Klecknerb5af11d2016-07-01 02:41:21 +00001615 IsLocalToUnit(IsLocalToUnit), IsDefinition(IsDefinition),
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001616 IsOptimized(IsOptimized), Flags(Flags) {
Davide Italiano236e7442016-04-13 20:17:42 +00001617 static_assert(dwarf::DW_VIRTUALITY_max < 4, "Virtuality out of range");
1618 assert(Virtuality < 4 && "Virtuality out of range");
Davide Italiano236e7442016-04-13 20:17:42 +00001619 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001620 ~DISubprogram() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001621
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001622 static DISubprogram *
1623 getImpl(LLVMContext &Context, DIScopeRef Scope, StringRef Name,
1624 StringRef LinkageName, DIFile *File, unsigned Line,
1625 DISubroutineType *Type, bool IsLocalToUnit, bool IsDefinition,
1626 unsigned ScopeLine, DITypeRef ContainingType, unsigned Virtuality,
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001627 unsigned VirtualIndex, int ThisAdjustment, DIFlags Flags,
Reid Klecknerb5af11d2016-07-01 02:41:21 +00001628 bool IsOptimized, DICompileUnit *Unit,
1629 DITemplateParameterArray TemplateParams, DISubprogram *Declaration,
Shiva Chen2c864552018-05-09 02:40:45 +00001630 DINodeArray RetainedNodes, DITypeArray ThrownTypes,
Adrian Prantl1d12b882017-04-26 22:56:44 +00001631 StorageType Storage, bool ShouldCreate = true) {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001632 return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
1633 getCanonicalMDString(Context, LinkageName), File, Line, Type,
1634 IsLocalToUnit, IsDefinition, ScopeLine, ContainingType,
Reid Klecknerb5af11d2016-07-01 02:41:21 +00001635 Virtuality, VirtualIndex, ThisAdjustment, Flags, IsOptimized,
Shiva Chen2c864552018-05-09 02:40:45 +00001636 Unit, TemplateParams.get(), Declaration, RetainedNodes.get(),
Adrian Prantl1d12b882017-04-26 22:56:44 +00001637 ThrownTypes.get(), Storage, ShouldCreate);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001638 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001639 static DISubprogram *
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001640 getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
1641 MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type,
1642 bool IsLocalToUnit, bool IsDefinition, unsigned ScopeLine,
1643 Metadata *ContainingType, unsigned Virtuality, unsigned VirtualIndex,
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001644 int ThisAdjustment, DIFlags Flags, bool IsOptimized, Metadata *Unit,
Shiva Chen2c864552018-05-09 02:40:45 +00001645 Metadata *TemplateParams, Metadata *Declaration, Metadata *RetainedNodes,
Adrian Prantl1d12b882017-04-26 22:56:44 +00001646 Metadata *ThrownTypes, StorageType Storage, bool ShouldCreate = true);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001647
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001648 TempDISubprogram cloneImpl() const {
Adrian Prantl1d12b882017-04-26 22:56:44 +00001649 return getTemporary(getContext(), getScope(), getName(), getLinkageName(),
1650 getFile(), getLine(), getType(), isLocalToUnit(),
1651 isDefinition(), getScopeLine(), getContainingType(),
1652 getVirtuality(), getVirtualIndex(), getThisAdjustment(),
1653 getFlags(), isOptimized(), getUnit(),
Shiva Chen2c864552018-05-09 02:40:45 +00001654 getTemplateParams(), getDeclaration(), getRetainedNodes(),
Adrian Prantl1d12b882017-04-26 22:56:44 +00001655 getThrownTypes());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001656 }
1657
1658public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001659 DEFINE_MDNODE_GET(DISubprogram,
1660 (DIScopeRef Scope, StringRef Name, StringRef LinkageName,
1661 DIFile *File, unsigned Line, DISubroutineType *Type,
Duncan P. N. Exon Smith3ec5fa62015-04-06 19:03:45 +00001662 bool IsLocalToUnit, bool IsDefinition, unsigned ScopeLine,
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001663 DITypeRef ContainingType, unsigned Virtuality,
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001664 unsigned VirtualIndex, int ThisAdjustment, DIFlags Flags,
Reid Klecknerb5af11d2016-07-01 02:41:21 +00001665 bool IsOptimized, DICompileUnit *Unit,
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001666 DITemplateParameterArray TemplateParams = nullptr,
1667 DISubprogram *Declaration = nullptr,
Shiva Chen2c864552018-05-09 02:40:45 +00001668 DINodeArray RetainedNodes = nullptr,
Adrian Prantl1d12b882017-04-26 22:56:44 +00001669 DITypeArray ThrownTypes = nullptr),
Duncan P. N. Exon Smith3ec5fa62015-04-06 19:03:45 +00001670 (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
1671 IsDefinition, ScopeLine, ContainingType, Virtuality,
Reid Klecknerb5af11d2016-07-01 02:41:21 +00001672 VirtualIndex, ThisAdjustment, Flags, IsOptimized, Unit,
Shiva Chen2c864552018-05-09 02:40:45 +00001673 TemplateParams, Declaration, RetainedNodes, ThrownTypes))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001674 DEFINE_MDNODE_GET(
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001675 DISubprogram,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001676 (Metadata * Scope, MDString *Name, MDString *LinkageName, Metadata *File,
1677 unsigned Line, Metadata *Type, bool IsLocalToUnit, bool IsDefinition,
1678 unsigned ScopeLine, Metadata *ContainingType, unsigned Virtuality,
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001679 unsigned VirtualIndex, int ThisAdjustment, DIFlags Flags,
Reid Klecknerb5af11d2016-07-01 02:41:21 +00001680 bool IsOptimized, Metadata *Unit, Metadata *TemplateParams = nullptr,
Shiva Chen2c864552018-05-09 02:40:45 +00001681 Metadata *Declaration = nullptr, Metadata *RetainedNodes = nullptr,
Adrian Prantl1d12b882017-04-26 22:56:44 +00001682 Metadata *ThrownTypes = nullptr),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001683 (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition,
Reid Klecknerb5af11d2016-07-01 02:41:21 +00001684 ScopeLine, ContainingType, Virtuality, VirtualIndex, ThisAdjustment,
Shiva Chen2c864552018-05-09 02:40:45 +00001685 Flags, IsOptimized, Unit, TemplateParams, Declaration, RetainedNodes,
Adrian Prantl1d12b882017-04-26 22:56:44 +00001686 ThrownTypes))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001687
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001688 TempDISubprogram clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001689
Roman Tereshincf88ffa2018-06-01 23:15:09 +00001690 /// Returns a new temporary DISubprogram with updated Flags
1691 TempDISubprogram cloneWithFlags(DIFlags NewFlags) const {
1692 auto NewSP = clone();
1693 NewSP->Flags = NewFlags;
1694 return NewSP;
1695 }
1696
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001697public:
1698 unsigned getLine() const { return Line; }
1699 unsigned getVirtuality() const { return Virtuality; }
1700 unsigned getVirtualIndex() const { return VirtualIndex; }
Reid Klecknerb5af11d2016-07-01 02:41:21 +00001701 int getThisAdjustment() const { return ThisAdjustment; }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001702 unsigned getScopeLine() const { return ScopeLine; }
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001703 DIFlags getFlags() const { return Flags; }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001704 bool isLocalToUnit() const { return IsLocalToUnit; }
1705 bool isDefinition() const { return IsDefinition; }
1706 bool isOptimized() const { return IsOptimized; }
1707
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001708 bool isArtificial() const { return getFlags() & FlagArtificial; }
Duncan P. N. Exon Smitha1384912015-04-07 03:33:57 +00001709 bool isPrivate() const {
1710 return (getFlags() & FlagAccessibility) == FlagPrivate;
1711 }
1712 bool isProtected() const {
1713 return (getFlags() & FlagAccessibility) == FlagProtected;
1714 }
1715 bool isPublic() const {
1716 return (getFlags() & FlagAccessibility) == FlagPublic;
1717 }
1718 bool isExplicit() const { return getFlags() & FlagExplicit; }
1719 bool isPrototyped() const { return getFlags() & FlagPrototyped; }
David Blaikiece3c8ef2016-11-28 21:32:19 +00001720 bool isMainSubprogram() const { return getFlags() & FlagMainSubprogram; }
Duncan P. N. Exon Smitha1384912015-04-07 03:33:57 +00001721
Adrian Prantl1687e012016-11-14 22:09:18 +00001722 /// Check if this is reference-qualified.
Duncan P. N. Exon Smitha1384912015-04-07 03:33:57 +00001723 ///
1724 /// Return true if this subprogram is a C++11 reference-qualified non-static
1725 /// member function (void foo() &).
Leny Kholodov40c62352016-09-06 17:03:02 +00001726 bool isLValueReference() const { return getFlags() & FlagLValueReference; }
Duncan P. N. Exon Smitha1384912015-04-07 03:33:57 +00001727
Adrian Prantl1687e012016-11-14 22:09:18 +00001728 /// Check if this is rvalue-reference-qualified.
Duncan P. N. Exon Smitha1384912015-04-07 03:33:57 +00001729 ///
1730 /// Return true if this subprogram is a C++11 rvalue-reference-qualified
1731 /// non-static member function (void foo() &&).
Leny Kholodov40c62352016-09-06 17:03:02 +00001732 bool isRValueReference() const { return getFlags() & FlagRValueReference; }
Duncan P. N. Exon Smitha1384912015-04-07 03:33:57 +00001733
Adrian Prantl1687e012016-11-14 22:09:18 +00001734 /// Check if this is marked as noreturn.
Adrian Prantlc19dee72016-08-17 16:02:43 +00001735 ///
1736 /// Return true if this subprogram is C++11 noreturn or C11 _Noreturn
Leny Kholodov40c62352016-09-06 17:03:02 +00001737 bool isNoReturn() const { return getFlags() & FlagNoReturn; }
Adrian Prantlc19dee72016-08-17 16:02:43 +00001738
Brock Wyma94ece8f2018-04-16 16:53:57 +00001739 // Check if this routine is a compiler-generated thunk.
1740 //
1741 // Returns true if this subprogram is a thunk generated by the compiler.
1742 bool isThunk() const { return getFlags() & FlagThunk; }
1743
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001744 DIScopeRef getScope() const { return DIScopeRef(getRawScope()); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001745
1746 StringRef getName() const { return getStringOperand(2); }
Adrian Prantl9d2f0192017-04-26 23:59:52 +00001747 StringRef getLinkageName() const { return getStringOperand(3); }
Duncan P. N. Exon Smith19fc5ed2015-02-13 01:26:47 +00001748
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001749 DISubroutineType *getType() const {
1750 return cast_or_null<DISubroutineType>(getRawType());
Duncan P. N. Exon Smith869db502015-03-30 16:19:15 +00001751 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001752 DITypeRef getContainingType() const {
1753 return DITypeRef(getRawContainingType());
Duncan P. N. Exon Smith3ec5fa62015-04-06 19:03:45 +00001754 }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001755
Adrian Prantl75819ae2016-04-15 15:57:41 +00001756 DICompileUnit *getUnit() const {
1757 return cast_or_null<DICompileUnit>(getRawUnit());
1758 }
Adrian Prantl9d2f0192017-04-26 23:59:52 +00001759 void replaceUnit(DICompileUnit *CU) { replaceOperandWith(5, CU); }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001760 DITemplateParameterArray getTemplateParams() const {
Duncan P. N. Exon Smith869db502015-03-30 16:19:15 +00001761 return cast_or_null<MDTuple>(getRawTemplateParams());
1762 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001763 DISubprogram *getDeclaration() const {
1764 return cast_or_null<DISubprogram>(getRawDeclaration());
Duncan P. N. Exon Smith869db502015-03-30 16:19:15 +00001765 }
Shiva Chen2c864552018-05-09 02:40:45 +00001766 DINodeArray getRetainedNodes() const {
1767 return cast_or_null<MDTuple>(getRawRetainedNodes());
Duncan P. N. Exon Smith869db502015-03-30 16:19:15 +00001768 }
Adrian Prantl1d12b882017-04-26 22:56:44 +00001769 DITypeArray getThrownTypes() const {
1770 return cast_or_null<MDTuple>(getRawThrownTypes());
1771 }
Duncan P. N. Exon Smith869db502015-03-30 16:19:15 +00001772
1773 Metadata *getRawScope() const { return getOperand(1); }
Adrian Prantl9d2f0192017-04-26 23:59:52 +00001774 MDString *getRawName() const { return getOperandAs<MDString>(2); }
1775 MDString *getRawLinkageName() const { return getOperandAs<MDString>(3); }
1776 Metadata *getRawType() const { return getOperand(4); }
1777 Metadata *getRawUnit() const { return getOperand(5); }
1778 Metadata *getRawDeclaration() const { return getOperand(6); }
Shiva Chen2c864552018-05-09 02:40:45 +00001779 Metadata *getRawRetainedNodes() const { return getOperand(7); }
Adrian Prantl9d2f0192017-04-26 23:59:52 +00001780 Metadata *getRawContainingType() const {
1781 return getNumOperands() > 8 ? getOperandAs<Metadata>(8) : nullptr;
1782 }
1783 Metadata *getRawTemplateParams() const {
1784 return getNumOperands() > 9 ? getOperandAs<Metadata>(9) : nullptr;
1785 }
1786 Metadata *getRawThrownTypes() const {
1787 return getNumOperands() > 10 ? getOperandAs<Metadata>(10) : nullptr;
1788 }
Duncan P. N. Exon Smithdf523492015-02-18 20:32:57 +00001789
Adrian Prantl1687e012016-11-14 22:09:18 +00001790 /// Check if this subprogram describes the given function.
Duncan P. N. Exon Smith3c2d7042015-04-13 19:07:27 +00001791 ///
1792 /// FIXME: Should this be looking through bitcasts?
1793 bool describes(const Function *F) const;
1794
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001795 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001796 return MD->getMetadataID() == DISubprogramKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001797 }
1798};
1799
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001800class DILexicalBlockBase : public DILocalScope {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001801protected:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001802 DILexicalBlockBase(LLVMContext &C, unsigned ID, StorageType Storage,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001803 ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001804 : DILocalScope(C, ID, Storage, dwarf::DW_TAG_lexical_block, Ops) {}
1805 ~DILexicalBlockBase() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001806
1807public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001808 DILocalScope *getScope() const { return cast<DILocalScope>(getRawScope()); }
Duncan P. N. Exon Smith0e202b92015-03-30 16:37:48 +00001809
1810 Metadata *getRawScope() const { return getOperand(1); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001811
1812 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001813 return MD->getMetadataID() == DILexicalBlockKind ||
1814 MD->getMetadataID() == DILexicalBlockFileKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001815 }
1816};
1817
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001818class DILexicalBlock : public DILexicalBlockBase {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001819 friend class LLVMContextImpl;
1820 friend class MDNode;
1821
1822 unsigned Line;
Duncan P. N. Exon Smithb09eb9f2015-08-28 22:58:50 +00001823 uint16_t Column;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001824
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001825 DILexicalBlock(LLVMContext &C, StorageType Storage, unsigned Line,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001826 unsigned Column, ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001827 : DILexicalBlockBase(C, DILexicalBlockKind, Storage, Ops), Line(Line),
Duncan P. N. Exon Smithb09eb9f2015-08-28 22:58:50 +00001828 Column(Column) {
1829 assert(Column < (1u << 16) && "Expected 16-bit column");
1830 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001831 ~DILexicalBlock() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001832
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001833 static DILexicalBlock *getImpl(LLVMContext &Context, DILocalScope *Scope,
1834 DIFile *File, unsigned Line, unsigned Column,
Duncan P. N. Exon Smith0e202b92015-03-30 16:37:48 +00001835 StorageType Storage,
1836 bool ShouldCreate = true) {
1837 return getImpl(Context, static_cast<Metadata *>(Scope),
1838 static_cast<Metadata *>(File), Line, Column, Storage,
1839 ShouldCreate);
1840 }
1841
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001842 static DILexicalBlock *getImpl(LLVMContext &Context, Metadata *Scope,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001843 Metadata *File, unsigned Line, unsigned Column,
1844 StorageType Storage, bool ShouldCreate = true);
1845
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001846 TempDILexicalBlock cloneImpl() const {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001847 return getTemporary(getContext(), getScope(), getFile(), getLine(),
1848 getColumn());
1849 }
1850
1851public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001852 DEFINE_MDNODE_GET(DILexicalBlock, (DILocalScope * Scope, DIFile *File,
Duncan P. N. Exon Smith0e202b92015-03-30 16:37:48 +00001853 unsigned Line, unsigned Column),
1854 (Scope, File, Line, Column))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001855 DEFINE_MDNODE_GET(DILexicalBlock, (Metadata * Scope, Metadata *File,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001856 unsigned Line, unsigned Column),
1857 (Scope, File, Line, Column))
1858
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001859 TempDILexicalBlock clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001860
1861 unsigned getLine() const { return Line; }
1862 unsigned getColumn() const { return Column; }
1863
1864 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001865 return MD->getMetadataID() == DILexicalBlockKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001866 }
1867};
1868
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001869class DILexicalBlockFile : public DILexicalBlockBase {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001870 friend class LLVMContextImpl;
1871 friend class MDNode;
1872
1873 unsigned Discriminator;
1874
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001875 DILexicalBlockFile(LLVMContext &C, StorageType Storage,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001876 unsigned Discriminator, ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001877 : DILexicalBlockBase(C, DILexicalBlockFileKind, Storage, Ops),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001878 Discriminator(Discriminator) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001879 ~DILexicalBlockFile() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001880
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001881 static DILexicalBlockFile *getImpl(LLVMContext &Context, DILocalScope *Scope,
1882 DIFile *File, unsigned Discriminator,
Duncan P. N. Exon Smith0e202b92015-03-30 16:37:48 +00001883 StorageType Storage,
1884 bool ShouldCreate = true) {
1885 return getImpl(Context, static_cast<Metadata *>(Scope),
1886 static_cast<Metadata *>(File), Discriminator, Storage,
1887 ShouldCreate);
1888 }
1889
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001890 static DILexicalBlockFile *getImpl(LLVMContext &Context, Metadata *Scope,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001891 Metadata *File, unsigned Discriminator,
1892 StorageType Storage,
1893 bool ShouldCreate = true);
1894
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001895 TempDILexicalBlockFile cloneImpl() const {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001896 return getTemporary(getContext(), getScope(), getFile(),
1897 getDiscriminator());
1898 }
1899
1900public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001901 DEFINE_MDNODE_GET(DILexicalBlockFile, (DILocalScope * Scope, DIFile *File,
Duncan P. N. Exon Smith0e202b92015-03-30 16:37:48 +00001902 unsigned Discriminator),
1903 (Scope, File, Discriminator))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001904 DEFINE_MDNODE_GET(DILexicalBlockFile,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001905 (Metadata * Scope, Metadata *File, unsigned Discriminator),
1906 (Scope, File, Discriminator))
1907
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001908 TempDILexicalBlockFile clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001909
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001910 // TODO: Remove these once they're gone from DILexicalBlockBase.
Duncan P. N. Exon Smith5f88ba12015-04-14 02:50:07 +00001911 unsigned getLine() const = delete;
1912 unsigned getColumn() const = delete;
1913
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001914 unsigned getDiscriminator() const { return Discriminator; }
1915
1916 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001917 return MD->getMetadataID() == DILexicalBlockFileKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001918 }
1919};
1920
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001921unsigned DILocation::getDiscriminator() const {
1922 if (auto *F = dyn_cast<DILexicalBlockFile>(getScope()))
Duncan P. N. Exon Smith2c8291e2015-04-14 00:05:13 +00001923 return F->getDiscriminator();
1924 return 0;
1925}
1926
Dehao Chenfb02f712017-02-10 21:09:07 +00001927const DILocation *
1928DILocation::cloneWithDiscriminator(unsigned Discriminator) const {
Dehao Chene7130002016-10-26 15:48:45 +00001929 DIScope *Scope = getScope();
1930 // Skip all parent DILexicalBlockFile that already have a discriminator
1931 // assigned. We do not want to have nested DILexicalBlockFiles that have
1932 // mutliple discriminators because only the leaf DILexicalBlockFile's
1933 // dominator will be used.
1934 for (auto *LBF = dyn_cast<DILexicalBlockFile>(Scope);
1935 LBF && LBF->getDiscriminator() != 0;
1936 LBF = dyn_cast<DILexicalBlockFile>(Scope))
1937 Scope = LBF->getScope();
1938 DILexicalBlockFile *NewScope =
1939 DILexicalBlockFile::get(getContext(), Scope, getFile(), Discriminator);
1940 return DILocation::get(getContext(), getLine(), getColumn(), NewScope,
1941 getInlinedAt());
1942}
1943
Dehao Chenfb02f712017-02-10 21:09:07 +00001944unsigned DILocation::getBaseDiscriminator() const {
Dehao Chen726da622017-02-15 17:54:39 +00001945 return getBaseDiscriminatorFromDiscriminator(getDiscriminator());
Dehao Chenfb02f712017-02-10 21:09:07 +00001946}
1947
1948unsigned DILocation::getDuplicationFactor() const {
Dehao Chen726da622017-02-15 17:54:39 +00001949 return getDuplicationFactorFromDiscriminator(getDiscriminator());
Dehao Chenfb02f712017-02-10 21:09:07 +00001950}
1951
1952unsigned DILocation::getCopyIdentifier() const {
Dehao Chen726da622017-02-15 17:54:39 +00001953 return getCopyIdentifierFromDiscriminator(getDiscriminator());
Dehao Chenfb02f712017-02-10 21:09:07 +00001954}
1955
1956const DILocation *DILocation::setBaseDiscriminator(unsigned D) const {
1957 if (D == 0)
1958 return this;
1959 else
1960 return cloneWithDiscriminator(getPrefixEncodingFromUnsigned(D) << 1);
1961}
1962
1963const DILocation *DILocation::cloneWithDuplicationFactor(unsigned DF) const {
1964 DF *= getDuplicationFactor();
1965 if (DF <= 1)
1966 return this;
1967
1968 unsigned BD = getBaseDiscriminator();
1969 unsigned CI = getCopyIdentifier() << (DF > 0x1f ? 14 : 7);
1970 unsigned D = CI | (getPrefixEncodingFromUnsigned(DF) << 1);
1971
1972 if (BD == 0)
1973 D = (D << 1) | 1;
1974 else
1975 D = (D << (BD > 0x1f ? 14 : 7)) | (getPrefixEncodingFromUnsigned(BD) << 1);
1976
1977 return cloneWithDiscriminator(D);
1978}
1979
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001980class DINamespace : public DIScope {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001981 friend class LLVMContextImpl;
1982 friend class MDNode;
1983
Adrian Prantldbfda632016-11-03 19:42:02 +00001984 unsigned ExportSymbols : 1;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001985
Adrian Prantlfed4f392017-04-28 22:25:46 +00001986 DINamespace(LLVMContext &Context, StorageType Storage, bool ExportSymbols,
1987 ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001988 : DIScope(Context, DINamespaceKind, Storage, dwarf::DW_TAG_namespace,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001989 Ops),
Adrian Prantlfed4f392017-04-28 22:25:46 +00001990 ExportSymbols(ExportSymbols) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001991 ~DINamespace() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001992
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001993 static DINamespace *getImpl(LLVMContext &Context, DIScope *Scope,
Adrian Prantlfed4f392017-04-28 22:25:46 +00001994 StringRef Name, bool ExportSymbols,
1995 StorageType Storage, bool ShouldCreate = true) {
1996 return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
1997 ExportSymbols, Storage, ShouldCreate);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001998 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001999 static DINamespace *getImpl(LLVMContext &Context, Metadata *Scope,
Adrian Prantlfed4f392017-04-28 22:25:46 +00002000 MDString *Name, bool ExportSymbols,
2001 StorageType Storage, bool ShouldCreate = true);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002002
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002003 TempDINamespace cloneImpl() const {
Adrian Prantlfed4f392017-04-28 22:25:46 +00002004 return getTemporary(getContext(), getScope(), getName(),
2005 getExportSymbols());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002006 }
2007
2008public:
Adrian Prantldbfda632016-11-03 19:42:02 +00002009 DEFINE_MDNODE_GET(DINamespace,
Adrian Prantlfed4f392017-04-28 22:25:46 +00002010 (DIScope *Scope, StringRef Name, bool ExportSymbols),
2011 (Scope, Name, ExportSymbols))
2012 DEFINE_MDNODE_GET(DINamespace,
2013 (Metadata *Scope, MDString *Name, bool ExportSymbols),
2014 (Scope, Name, ExportSymbols))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002015
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002016 TempDINamespace clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002017
Adrian Prantldbfda632016-11-03 19:42:02 +00002018 bool getExportSymbols() const { return ExportSymbols; }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002019 DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002020 StringRef getName() const { return getStringOperand(2); }
2021
Duncan P. N. Exon Smithf9b47752015-03-30 17:21:38 +00002022 Metadata *getRawScope() const { return getOperand(1); }
Duncan P. N. Exon Smithe1460002015-02-13 01:32:09 +00002023 MDString *getRawName() const { return getOperandAs<MDString>(2); }
2024
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002025 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002026 return MD->getMetadataID() == DINamespaceKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002027 }
2028};
2029
Adrian Prantl1687e012016-11-14 22:09:18 +00002030/// A (clang) module that has been imported by the compile unit.
Adrian Prantlab1243f2015-06-29 23:03:47 +00002031///
2032class DIModule : public DIScope {
2033 friend class LLVMContextImpl;
2034 friend class MDNode;
2035
2036 DIModule(LLVMContext &Context, StorageType Storage, ArrayRef<Metadata *> Ops)
2037 : DIScope(Context, DIModuleKind, Storage, dwarf::DW_TAG_module, Ops) {}
Eugene Zelenko1aa40f42016-11-23 22:25:16 +00002038 ~DIModule() = default;
Adrian Prantlab1243f2015-06-29 23:03:47 +00002039
2040 static DIModule *getImpl(LLVMContext &Context, DIScope *Scope,
2041 StringRef Name, StringRef ConfigurationMacros,
2042 StringRef IncludePath, StringRef ISysRoot,
2043 StorageType Storage, bool ShouldCreate = true) {
2044 return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
2045 getCanonicalMDString(Context, ConfigurationMacros),
NAKAMURA Takumiff35c332015-07-06 00:48:17 +00002046 getCanonicalMDString(Context, IncludePath),
2047 getCanonicalMDString(Context, ISysRoot),
Adrian Prantlab1243f2015-06-29 23:03:47 +00002048 Storage, ShouldCreate);
2049 }
2050 static DIModule *getImpl(LLVMContext &Context, Metadata *Scope,
2051 MDString *Name, MDString *ConfigurationMacros,
NAKAMURA Takumiff35c332015-07-06 00:48:17 +00002052 MDString *IncludePath, MDString *ISysRoot,
2053 StorageType Storage, bool ShouldCreate = true);
Adrian Prantlab1243f2015-06-29 23:03:47 +00002054
2055 TempDIModule cloneImpl() const {
2056 return getTemporary(getContext(), getScope(), getName(),
2057 getConfigurationMacros(), getIncludePath(),
2058 getISysRoot());
2059 }
2060
2061public:
2062 DEFINE_MDNODE_GET(DIModule, (DIScope *Scope, StringRef Name,
NAKAMURA Takumiff35c332015-07-06 00:48:17 +00002063 StringRef ConfigurationMacros, StringRef IncludePath,
2064 StringRef ISysRoot),
Adrian Prantlab1243f2015-06-29 23:03:47 +00002065 (Scope, Name, ConfigurationMacros, IncludePath, ISysRoot))
2066 DEFINE_MDNODE_GET(DIModule,
2067 (Metadata *Scope, MDString *Name, MDString *ConfigurationMacros,
NAKAMURA Takumiff35c332015-07-06 00:48:17 +00002068 MDString *IncludePath, MDString *ISysRoot),
Adrian Prantlab1243f2015-06-29 23:03:47 +00002069 (Scope, Name, ConfigurationMacros, IncludePath, ISysRoot))
2070
2071 TempDIModule clone() const { return cloneImpl(); }
2072
2073 DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
2074 StringRef getName() const { return getStringOperand(1); }
2075 StringRef getConfigurationMacros() const { return getStringOperand(2); }
2076 StringRef getIncludePath() const { return getStringOperand(3); }
2077 StringRef getISysRoot() const { return getStringOperand(4); }
2078
2079 Metadata *getRawScope() const { return getOperand(0); }
2080 MDString *getRawName() const { return getOperandAs<MDString>(1); }
2081 MDString *getRawConfigurationMacros() const { return getOperandAs<MDString>(2); }
2082 MDString *getRawIncludePath() const { return getOperandAs<MDString>(3); }
2083 MDString *getRawISysRoot() const { return getOperandAs<MDString>(4); }
2084
2085 static bool classof(const Metadata *MD) {
2086 return MD->getMetadataID() == DIModuleKind;
2087 }
2088};
2089
Adrian Prantl1687e012016-11-14 22:09:18 +00002090/// Base class for template parameters.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002091class DITemplateParameter : public DINode {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002092protected:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002093 DITemplateParameter(LLVMContext &Context, unsigned ID, StorageType Storage,
Duncan P. N. Exon Smithbd33d372015-02-10 01:59:57 +00002094 unsigned Tag, ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002095 : DINode(Context, ID, Storage, Tag, Ops) {}
2096 ~DITemplateParameter() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002097
2098public:
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002099 StringRef getName() const { return getStringOperand(0); }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002100 DITypeRef getType() const { return DITypeRef(getRawType()); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002101
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002102 MDString *getRawName() const { return getOperandAs<MDString>(0); }
Duncan P. N. Exon Smith3ec5fa62015-04-06 19:03:45 +00002103 Metadata *getRawType() const { return getOperand(1); }
Duncan P. N. Exon Smith2847f382015-02-13 01:34:32 +00002104
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002105 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002106 return MD->getMetadataID() == DITemplateTypeParameterKind ||
2107 MD->getMetadataID() == DITemplateValueParameterKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002108 }
2109};
2110
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002111class DITemplateTypeParameter : public DITemplateParameter {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002112 friend class LLVMContextImpl;
2113 friend class MDNode;
2114
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002115 DITemplateTypeParameter(LLVMContext &Context, StorageType Storage,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002116 ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002117 : DITemplateParameter(Context, DITemplateTypeParameterKind, Storage,
Duncan P. N. Exon Smithbd33d372015-02-10 01:59:57 +00002118 dwarf::DW_TAG_template_type_parameter, Ops) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002119 ~DITemplateTypeParameter() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002120
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002121 static DITemplateTypeParameter *getImpl(LLVMContext &Context, StringRef Name,
2122 DITypeRef Type, StorageType Storage,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002123 bool ShouldCreate = true) {
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002124 return getImpl(Context, getCanonicalMDString(Context, Name), Type, Storage,
2125 ShouldCreate);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002126 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002127 static DITemplateTypeParameter *getImpl(LLVMContext &Context, MDString *Name,
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002128 Metadata *Type, StorageType Storage,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002129 bool ShouldCreate = true);
2130
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002131 TempDITemplateTypeParameter cloneImpl() const {
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002132 return getTemporary(getContext(), getName(), getType());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002133 }
2134
2135public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002136 DEFINE_MDNODE_GET(DITemplateTypeParameter, (StringRef Name, DITypeRef Type),
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002137 (Name, Type))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002138 DEFINE_MDNODE_GET(DITemplateTypeParameter, (MDString * Name, Metadata *Type),
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002139 (Name, Type))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002140
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002141 TempDITemplateTypeParameter clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002142
2143 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002144 return MD->getMetadataID() == DITemplateTypeParameterKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002145 }
2146};
2147
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002148class DITemplateValueParameter : public DITemplateParameter {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002149 friend class LLVMContextImpl;
2150 friend class MDNode;
2151
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002152 DITemplateValueParameter(LLVMContext &Context, StorageType Storage,
Duncan P. N. Exon Smithbd33d372015-02-10 01:59:57 +00002153 unsigned Tag, ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002154 : DITemplateParameter(Context, DITemplateValueParameterKind, Storage, Tag,
Duncan P. N. Exon Smithbd33d372015-02-10 01:59:57 +00002155 Ops) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002156 ~DITemplateValueParameter() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002157
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002158 static DITemplateValueParameter *getImpl(LLVMContext &Context, unsigned Tag,
2159 StringRef Name, DITypeRef Type,
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002160 Metadata *Value, StorageType Storage,
Duncan P. N. Exon Smithbd33d372015-02-10 01:59:57 +00002161 bool ShouldCreate = true) {
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002162 return getImpl(Context, Tag, getCanonicalMDString(Context, Name), Type,
2163 Value, Storage, ShouldCreate);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002164 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002165 static DITemplateValueParameter *getImpl(LLVMContext &Context, unsigned Tag,
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002166 MDString *Name, Metadata *Type,
2167 Metadata *Value, StorageType Storage,
Duncan P. N. Exon Smithbd33d372015-02-10 01:59:57 +00002168 bool ShouldCreate = true);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002169
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002170 TempDITemplateValueParameter cloneImpl() const {
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002171 return getTemporary(getContext(), getTag(), getName(), getType(),
2172 getValue());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002173 }
2174
2175public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002176 DEFINE_MDNODE_GET(DITemplateValueParameter, (unsigned Tag, StringRef Name,
2177 DITypeRef Type, Metadata *Value),
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002178 (Tag, Name, Type, Value))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002179 DEFINE_MDNODE_GET(DITemplateValueParameter, (unsigned Tag, MDString *Name,
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002180 Metadata *Type, Metadata *Value),
2181 (Tag, Name, Type, Value))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002182
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002183 TempDITemplateValueParameter clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith6873fea2015-02-17 23:10:13 +00002184
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002185 Metadata *getValue() const { return getOperand(2); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002186
2187 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002188 return MD->getMetadataID() == DITemplateValueParameterKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002189 }
2190};
2191
Adrian Prantl1687e012016-11-14 22:09:18 +00002192/// Base class for variables.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002193class DIVariable : public DINode {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002194 unsigned Line;
Victor Leschuka37660c2016-10-26 21:32:29 +00002195 uint32_t AlignInBits;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002196
2197protected:
Duncan P. N. Exon Smithed013cd2015-07-31 18:58:39 +00002198 DIVariable(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Line,
Victor Leschuka37660c2016-10-26 21:32:29 +00002199 ArrayRef<Metadata *> Ops, uint32_t AlignInBits = 0)
Victor Leschuk2ede1262016-10-20 00:13:12 +00002200 : DINode(C, ID, Storage, dwarf::DW_TAG_variable, Ops), Line(Line),
NAKAMURA Takumi78029842017-02-19 06:51:46 +00002201 AlignInBits(AlignInBits) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002202 ~DIVariable() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002203
2204public:
2205 unsigned getLine() const { return Line; }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002206 DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002207 StringRef getName() const { return getStringOperand(1); }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002208 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
2209 DITypeRef getType() const { return DITypeRef(getRawType()); }
Victor Leschuk3c989982016-10-26 11:59:03 +00002210 uint32_t getAlignInBits() const { return AlignInBits; }
2211 uint32_t getAlignInBytes() const { return getAlignInBits() / CHAR_BIT; }
Adrian Prantl3e0e1d02017-11-28 00:57:51 +00002212 /// Determines the size of the variable's type.
2213 Optional<uint64_t> getSizeInBits() const;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002214
Vedant Kumar6379a622018-07-06 17:32:39 +00002215 /// Return the signedness of this variable's type, or None if this type is
2216 /// neither signed nor unsigned.
2217 Optional<DIBasicType::Signedness> getSignedness() const {
2218 if (auto *BT = dyn_cast<DIBasicType>(getType().resolve()))
2219 return BT->getSignedness();
2220 return None;
2221 }
2222
Duncan P. N. Exon Smith50c065b2015-04-11 00:39:43 +00002223 StringRef getFilename() const {
2224 if (auto *F = getFile())
2225 return F->getFilename();
2226 return "";
2227 }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +00002228
Duncan P. N. Exon Smith50c065b2015-04-11 00:39:43 +00002229 StringRef getDirectory() const {
2230 if (auto *F = getFile())
2231 return F->getDirectory();
2232 return "";
2233 }
2234
Scott Linder16c7bda2018-02-23 23:01:06 +00002235 Optional<StringRef> getSource() const {
2236 if (auto *F = getFile())
2237 return F->getSource();
2238 return None;
2239 }
2240
Duncan P. N. Exon Smith3d2afaa2015-03-27 17:29:58 +00002241 Metadata *getRawScope() const { return getOperand(0); }
Duncan P. N. Exon Smithc8f810a2015-02-13 01:35:40 +00002242 MDString *getRawName() const { return getOperandAs<MDString>(1); }
Duncan P. N. Exon Smith3d2afaa2015-03-27 17:29:58 +00002243 Metadata *getRawFile() const { return getOperand(2); }
2244 Metadata *getRawType() const { return getOperand(3); }
Duncan P. N. Exon Smithc8f810a2015-02-13 01:35:40 +00002245
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002246 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002247 return MD->getMetadataID() == DILocalVariableKind ||
2248 MD->getMetadataID() == DIGlobalVariableKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002249 }
2250};
2251
Adrian Prantl1687e012016-11-14 22:09:18 +00002252/// DWARF expression.
Peter Collingbourned4135bb2016-09-13 01:12:59 +00002253///
2254/// This is (almost) a DWARF expression that modifies the location of a
2255/// variable, or the location of a single piece of a variable, or (when using
2256/// DW_OP_stack_value) is the constant variable value.
2257///
Peter Collingbourned4135bb2016-09-13 01:12:59 +00002258/// TODO: Co-allocate the expression elements.
2259/// TODO: Separate from MDNode, or otherwise drop Distinct and Temporary
2260/// storage types.
2261class DIExpression : public MDNode {
2262 friend class LLVMContextImpl;
2263 friend class MDNode;
2264
2265 std::vector<uint64_t> Elements;
2266
2267 DIExpression(LLVMContext &C, StorageType Storage, ArrayRef<uint64_t> Elements)
2268 : MDNode(C, DIExpressionKind, Storage, None),
2269 Elements(Elements.begin(), Elements.end()) {}
2270 ~DIExpression() = default;
2271
2272 static DIExpression *getImpl(LLVMContext &Context,
2273 ArrayRef<uint64_t> Elements, StorageType Storage,
2274 bool ShouldCreate = true);
2275
2276 TempDIExpression cloneImpl() const {
2277 return getTemporary(getContext(), getElements());
2278 }
2279
2280public:
2281 DEFINE_MDNODE_GET(DIExpression, (ArrayRef<uint64_t> Elements), (Elements))
2282
2283 TempDIExpression clone() const { return cloneImpl(); }
2284
2285 ArrayRef<uint64_t> getElements() const { return Elements; }
2286
2287 unsigned getNumElements() const { return Elements.size(); }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +00002288
Peter Collingbourned4135bb2016-09-13 01:12:59 +00002289 uint64_t getElement(unsigned I) const {
2290 assert(I < Elements.size() && "Index out of range");
2291 return Elements[I];
2292 }
2293
Adrian Prantlbceaaa92016-12-20 02:09:43 +00002294 /// Determine whether this represents a standalone constant value.
2295 bool isConstant() const;
2296
Eugene Zelenkod761e2c2017-05-15 21:57:41 +00002297 using element_iterator = ArrayRef<uint64_t>::iterator;
2298
Peter Collingbourned4135bb2016-09-13 01:12:59 +00002299 element_iterator elements_begin() const { return getElements().begin(); }
2300 element_iterator elements_end() const { return getElements().end(); }
2301
2302 /// A lightweight wrapper around an expression operand.
2303 ///
2304 /// TODO: Store arguments directly and change \a DIExpression to store a
2305 /// range of these.
2306 class ExprOperand {
Adrian Prantl72845a52016-11-08 20:48:38 +00002307 const uint64_t *Op = nullptr;
Peter Collingbourned4135bb2016-09-13 01:12:59 +00002308
2309 public:
Adrian Prantl72845a52016-11-08 20:48:38 +00002310 ExprOperand() = default;
Peter Collingbourned4135bb2016-09-13 01:12:59 +00002311 explicit ExprOperand(const uint64_t *Op) : Op(Op) {}
2312
2313 const uint64_t *get() const { return Op; }
2314
2315 /// Get the operand code.
2316 uint64_t getOp() const { return *Op; }
2317
2318 /// Get an argument to the operand.
2319 ///
2320 /// Never returns the operand itself.
2321 uint64_t getArg(unsigned I) const { return Op[I + 1]; }
2322
2323 unsigned getNumArgs() const { return getSize() - 1; }
2324
2325 /// Return the size of the operand.
2326 ///
2327 /// Return the number of elements in the operand (1 + args).
2328 unsigned getSize() const;
Vedant Kumar6379a622018-07-06 17:32:39 +00002329
2330 /// Append the elements of this operand to \p V.
2331 void appendToVector(SmallVectorImpl<uint64_t> &V) const {
2332 V.append(getSize(), *get());
2333 }
Peter Collingbourned4135bb2016-09-13 01:12:59 +00002334 };
2335
2336 /// An iterator for expression operands.
2337 class expr_op_iterator
2338 : public std::iterator<std::input_iterator_tag, ExprOperand> {
2339 ExprOperand Op;
2340
2341 public:
Adrian Prantl54286bd2016-11-02 16:12:20 +00002342 expr_op_iterator() = default;
Peter Collingbourned4135bb2016-09-13 01:12:59 +00002343 explicit expr_op_iterator(element_iterator I) : Op(I) {}
2344
2345 element_iterator getBase() const { return Op.get(); }
2346 const ExprOperand &operator*() const { return Op; }
2347 const ExprOperand *operator->() const { return &Op; }
2348
2349 expr_op_iterator &operator++() {
2350 increment();
2351 return *this;
2352 }
2353 expr_op_iterator operator++(int) {
2354 expr_op_iterator T(*this);
2355 increment();
2356 return T;
2357 }
2358
2359 /// Get the next iterator.
2360 ///
2361 /// \a std::next() doesn't work because this is technically an
2362 /// input_iterator, but it's a perfectly valid operation. This is an
2363 /// accessor to provide the same functionality.
2364 expr_op_iterator getNext() const { return ++expr_op_iterator(*this); }
2365
2366 bool operator==(const expr_op_iterator &X) const {
2367 return getBase() == X.getBase();
2368 }
2369 bool operator!=(const expr_op_iterator &X) const {
2370 return getBase() != X.getBase();
2371 }
2372
2373 private:
2374 void increment() { Op = ExprOperand(getBase() + Op.getSize()); }
2375 };
2376
2377 /// Visit the elements via ExprOperand wrappers.
2378 ///
2379 /// These range iterators visit elements through \a ExprOperand wrappers.
2380 /// This is not guaranteed to be a valid range unless \a isValid() gives \c
2381 /// true.
2382 ///
2383 /// \pre \a isValid() gives \c true.
2384 /// @{
2385 expr_op_iterator expr_op_begin() const {
2386 return expr_op_iterator(elements_begin());
2387 }
2388 expr_op_iterator expr_op_end() const {
2389 return expr_op_iterator(elements_end());
2390 }
Adrian Prantl6825fb62017-04-18 01:21:53 +00002391 iterator_range<expr_op_iterator> expr_ops() const {
2392 return {expr_op_begin(), expr_op_end()};
2393 }
Peter Collingbourned4135bb2016-09-13 01:12:59 +00002394 /// @}
2395
2396 bool isValid() const;
2397
2398 static bool classof(const Metadata *MD) {
2399 return MD->getMetadataID() == DIExpressionKind;
2400 }
2401
Adrian Prantl6825fb62017-04-18 01:21:53 +00002402 /// Return whether the first element a DW_OP_deref.
Peter Collingbourned4135bb2016-09-13 01:12:59 +00002403 bool startsWithDeref() const {
2404 return getNumElements() > 0 && getElement(0) == dwarf::DW_OP_deref;
2405 }
Adrian Prantl49797ca2016-12-22 05:27:12 +00002406
2407 /// Holds the characteristics of one fragment of a larger variable.
2408 struct FragmentInfo {
2409 uint64_t SizeInBits;
2410 uint64_t OffsetInBits;
2411 };
2412
2413 /// Retrieve the details of this fragment expression.
2414 static Optional<FragmentInfo> getFragmentInfo(expr_op_iterator Start,
NAKAMURA Takumi78029842017-02-19 06:51:46 +00002415 expr_op_iterator End);
Adrian Prantl49797ca2016-12-22 05:27:12 +00002416
2417 /// Retrieve the details of this fragment expression.
2418 Optional<FragmentInfo> getFragmentInfo() const {
2419 return getFragmentInfo(expr_op_begin(), expr_op_end());
2420 }
2421
2422 /// Return whether this is a piece of an aggregate variable.
2423 bool isFragment() const { return getFragmentInfo().hasValue(); }
Andrew Ng03e35b62017-04-28 08:44:30 +00002424
2425 /// Append \p Ops with operations to apply the \p Offset.
2426 static void appendOffset(SmallVectorImpl<uint64_t> &Ops, int64_t Offset);
2427
Reid Klecknerb5fced72017-05-09 19:59:29 +00002428 /// If this is a constant offset, extract it. If there is no expression,
2429 /// return true with an offset of zero.
2430 bool extractIfOffset(int64_t &Offset) const;
2431
Adrian Prantl109b2362017-04-28 17:51:05 +00002432 /// Constants for DIExpression::prepend.
2433 enum { NoDeref = false, WithDeref = true, WithStackValue = true };
2434
Andrew Ng03e35b62017-04-28 08:44:30 +00002435 /// Prepend \p DIExpr with a deref and offset operation and optionally turn it
2436 /// into a stack value.
Adrian Prantld1317012017-12-08 21:58:18 +00002437 static DIExpression *prepend(const DIExpression *DIExpr, bool DerefBefore,
2438 int64_t Offset = 0, bool DerefAfter = false,
2439 bool StackValue = false);
Adrian Prantlb192b542017-08-30 20:04:17 +00002440
Vedant Kumar04386d82018-02-09 19:19:55 +00002441 /// Prepend \p DIExpr with the given opcodes and optionally turn it into a
2442 /// stack value.
Adrian Prantl210a29d2018-04-27 21:41:36 +00002443 static DIExpression *prependOpcodes(const DIExpression *DIExpr,
2444 SmallVectorImpl<uint64_t> &Ops,
2445 bool StackValue = false);
Vedant Kumar04386d82018-02-09 19:19:55 +00002446
Vedant Kumar6379a622018-07-06 17:32:39 +00002447 /// Convert \p DIExpr into a stack value if it isn't one already by appending
2448 /// DW_OP_deref if needed, and applying \p Ops to the resulting expression.
2449 /// If \p DIExpr is a fragment, the returned expression will contain the same
2450 /// fragment.
2451 static DIExpression *appendToStack(const DIExpression *DIExpr,
2452 ArrayRef<uint64_t> Ops);
2453
Adrian Prantlb192b542017-08-30 20:04:17 +00002454 /// Create a DIExpression to describe one part of an aggregate variable that
2455 /// is fragmented across multiple Values. The DW_OP_LLVM_fragment operation
2456 /// will be appended to the elements of \c Expr. If \c Expr already contains
2457 /// a \c DW_OP_LLVM_fragment \c OffsetInBits is interpreted as an offset
2458 /// into the existing fragment.
2459 ///
2460 /// \param OffsetInBits Offset of the piece in bits.
2461 /// \param SizeInBits Size of the piece in bits.
Adrian Prantl25a09dd2017-11-07 00:45:34 +00002462 /// \return Creating a fragment expression may fail if \c Expr
2463 /// contains arithmetic operations that would be truncated.
2464 static Optional<DIExpression *>
2465 createFragmentExpression(const DIExpression *Expr, unsigned OffsetInBits,
2466 unsigned SizeInBits);
Bjorn Petterssona223f8152018-03-12 18:02:39 +00002467
2468 /// Determine the relative position of the fragments described by this
2469 /// DIExpression and \p Other.
2470 /// Returns -1 if this is entirely before Other, 0 if this and Other overlap,
2471 /// 1 if this is entirely after Other.
2472 int fragmentCmp(const DIExpression *Other) const {
2473 auto Fragment1 = *getFragmentInfo();
2474 auto Fragment2 = *Other->getFragmentInfo();
2475 unsigned l1 = Fragment1.OffsetInBits;
2476 unsigned l2 = Fragment2.OffsetInBits;
2477 unsigned r1 = l1 + Fragment1.SizeInBits;
2478 unsigned r2 = l2 + Fragment2.SizeInBits;
2479 if (r1 <= l2)
2480 return -1;
2481 else if (r2 <= l1)
2482 return 1;
2483 else
2484 return 0;
2485 }
2486
2487 /// Check if fragments overlap between this DIExpression and \p Other.
2488 bool fragmentsOverlap(const DIExpression *Other) const {
2489 if (!isFragment() || !Other->isFragment())
2490 return true;
2491 return fragmentCmp(Other) == 0;
2492 }
Peter Collingbourned4135bb2016-09-13 01:12:59 +00002493};
2494
Adrian Prantl1687e012016-11-14 22:09:18 +00002495/// Global variables.
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002496///
2497/// TODO: Remove DisplayName. It's always equal to Name.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002498class DIGlobalVariable : public DIVariable {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002499 friend class LLVMContextImpl;
2500 friend class MDNode;
2501
2502 bool IsLocalToUnit;
2503 bool IsDefinition;
2504
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002505 DIGlobalVariable(LLVMContext &C, StorageType Storage, unsigned Line,
Victor Leschuka37660c2016-10-26 21:32:29 +00002506 bool IsLocalToUnit, bool IsDefinition, uint32_t AlignInBits,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002507 ArrayRef<Metadata *> Ops)
Victor Leschuk2ede1262016-10-20 00:13:12 +00002508 : DIVariable(C, DIGlobalVariableKind, Storage, Line, Ops, AlignInBits),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002509 IsLocalToUnit(IsLocalToUnit), IsDefinition(IsDefinition) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002510 ~DIGlobalVariable() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002511
Adrian Prantlbceaaa92016-12-20 02:09:43 +00002512 static DIGlobalVariable *getImpl(LLVMContext &Context, DIScope *Scope,
2513 StringRef Name, StringRef LinkageName,
2514 DIFile *File, unsigned Line, DITypeRef Type,
2515 bool IsLocalToUnit, bool IsDefinition,
2516 DIDerivedType *StaticDataMemberDeclaration,
2517 uint32_t AlignInBits, StorageType Storage,
2518 bool ShouldCreate = true) {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002519 return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
2520 getCanonicalMDString(Context, LinkageName), File, Line, Type,
Adrian Prantlbceaaa92016-12-20 02:09:43 +00002521 IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration,
2522 AlignInBits, Storage, ShouldCreate);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002523 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002524 static DIGlobalVariable *
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002525 getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
2526 MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type,
Adrian Prantlbceaaa92016-12-20 02:09:43 +00002527 bool IsLocalToUnit, bool IsDefinition,
Victor Leschuka37660c2016-10-26 21:32:29 +00002528 Metadata *StaticDataMemberDeclaration, uint32_t AlignInBits,
Victor Leschuk2ede1262016-10-20 00:13:12 +00002529 StorageType Storage, bool ShouldCreate = true);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002530
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002531 TempDIGlobalVariable cloneImpl() const {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002532 return getTemporary(getContext(), getScope(), getName(), getLinkageName(),
2533 getFile(), getLine(), getType(), isLocalToUnit(),
Adrian Prantlbceaaa92016-12-20 02:09:43 +00002534 isDefinition(), getStaticDataMemberDeclaration(),
2535 getAlignInBits());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002536 }
2537
2538public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002539 DEFINE_MDNODE_GET(DIGlobalVariable,
2540 (DIScope * Scope, StringRef Name, StringRef LinkageName,
2541 DIFile *File, unsigned Line, DITypeRef Type,
Victor Leschuk2ede1262016-10-20 00:13:12 +00002542 bool IsLocalToUnit, bool IsDefinition,
Victor Leschuk2ede1262016-10-20 00:13:12 +00002543 DIDerivedType *StaticDataMemberDeclaration,
Victor Leschuka37660c2016-10-26 21:32:29 +00002544 uint32_t AlignInBits),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002545 (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
Adrian Prantlbceaaa92016-12-20 02:09:43 +00002546 IsDefinition, StaticDataMemberDeclaration, AlignInBits))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002547 DEFINE_MDNODE_GET(DIGlobalVariable,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002548 (Metadata * Scope, MDString *Name, MDString *LinkageName,
2549 Metadata *File, unsigned Line, Metadata *Type,
Victor Leschuk2ede1262016-10-20 00:13:12 +00002550 bool IsLocalToUnit, bool IsDefinition,
Adrian Prantlbceaaa92016-12-20 02:09:43 +00002551 Metadata *StaticDataMemberDeclaration,
Victor Leschuka37660c2016-10-26 21:32:29 +00002552 uint32_t AlignInBits),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002553 (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
Adrian Prantlbceaaa92016-12-20 02:09:43 +00002554 IsDefinition, StaticDataMemberDeclaration, AlignInBits))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002555
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002556 TempDIGlobalVariable clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith6873fea2015-02-17 23:10:13 +00002557
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002558 bool isLocalToUnit() const { return IsLocalToUnit; }
2559 bool isDefinition() const { return IsDefinition; }
2560 StringRef getDisplayName() const { return getStringOperand(4); }
2561 StringRef getLinkageName() const { return getStringOperand(5); }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002562 DIDerivedType *getStaticDataMemberDeclaration() const {
2563 return cast_or_null<DIDerivedType>(getRawStaticDataMemberDeclaration());
Duncan P. N. Exon Smith3d2afaa2015-03-27 17:29:58 +00002564 }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002565
Duncan P. N. Exon Smithc8f810a2015-02-13 01:35:40 +00002566 MDString *getRawLinkageName() const { return getOperandAs<MDString>(5); }
Adrian Prantlbceaaa92016-12-20 02:09:43 +00002567 Metadata *getRawStaticDataMemberDeclaration() const { return getOperand(6); }
Duncan P. N. Exon Smithc8f810a2015-02-13 01:35:40 +00002568
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002569 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002570 return MD->getMetadataID() == DIGlobalVariableKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002571 }
2572};
2573
Adrian Prantl1687e012016-11-14 22:09:18 +00002574/// Local variable.
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002575///
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002576/// TODO: Split up flags.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002577class DILocalVariable : public DIVariable {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002578 friend class LLVMContextImpl;
2579 friend class MDNode;
2580
Davide Italianoeb6bb3e2016-04-16 02:27:56 +00002581 unsigned Arg : 16;
Leny Kholodov5fcc4182016-09-06 10:46:28 +00002582 DIFlags Flags;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002583
Duncan P. N. Exon Smithed013cd2015-07-31 18:58:39 +00002584 DILocalVariable(LLVMContext &C, StorageType Storage, unsigned Line,
Victor Leschuka37660c2016-10-26 21:32:29 +00002585 unsigned Arg, DIFlags Flags, uint32_t AlignInBits,
Victor Leschuk2ede1262016-10-20 00:13:12 +00002586 ArrayRef<Metadata *> Ops)
2587 : DIVariable(C, DILocalVariableKind, Storage, Line, Ops, AlignInBits),
2588 Arg(Arg), Flags(Flags) {
Davide Italiano0d2ef012016-04-16 03:23:48 +00002589 assert(Arg < (1 << 16) && "DILocalVariable: Arg out of range");
Davide Italianoeb6bb3e2016-04-16 02:27:56 +00002590 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002591 ~DILocalVariable() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002592
Duncan P. N. Exon Smithed013cd2015-07-31 18:58:39 +00002593 static DILocalVariable *getImpl(LLVMContext &Context, DIScope *Scope,
2594 StringRef Name, DIFile *File, unsigned Line,
Leny Kholodov5fcc4182016-09-06 10:46:28 +00002595 DITypeRef Type, unsigned Arg, DIFlags Flags,
Victor Leschuka37660c2016-10-26 21:32:29 +00002596 uint32_t AlignInBits, StorageType Storage,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002597 bool ShouldCreate = true) {
Duncan P. N. Exon Smithed013cd2015-07-31 18:58:39 +00002598 return getImpl(Context, Scope, getCanonicalMDString(Context, Name), File,
Victor Leschuk2ede1262016-10-20 00:13:12 +00002599 Line, Type, Arg, Flags, AlignInBits, Storage, ShouldCreate);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002600 }
Duncan P. N. Exon Smithed013cd2015-07-31 18:58:39 +00002601 static DILocalVariable *getImpl(LLVMContext &Context, Metadata *Scope,
2602 MDString *Name, Metadata *File, unsigned Line,
Leny Kholodov5fcc4182016-09-06 10:46:28 +00002603 Metadata *Type, unsigned Arg, DIFlags Flags,
Victor Leschuka37660c2016-10-26 21:32:29 +00002604 uint32_t AlignInBits, StorageType Storage,
Duncan P. N. Exon Smithed013cd2015-07-31 18:58:39 +00002605 bool ShouldCreate = true);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002606
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002607 TempDILocalVariable cloneImpl() const {
Duncan P. N. Exon Smithed013cd2015-07-31 18:58:39 +00002608 return getTemporary(getContext(), getScope(), getName(), getFile(),
Victor Leschuk2ede1262016-10-20 00:13:12 +00002609 getLine(), getType(), getArg(), getFlags(),
2610 getAlignInBits());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002611 }
2612
2613public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002614 DEFINE_MDNODE_GET(DILocalVariable,
Duncan P. N. Exon Smithed013cd2015-07-31 18:58:39 +00002615 (DILocalScope * Scope, StringRef Name, DIFile *File,
Leny Kholodov40c62352016-09-06 17:03:02 +00002616 unsigned Line, DITypeRef Type, unsigned Arg,
Victor Leschuka37660c2016-10-26 21:32:29 +00002617 DIFlags Flags, uint32_t AlignInBits),
Victor Leschuk2ede1262016-10-20 00:13:12 +00002618 (Scope, Name, File, Line, Type, Arg, Flags, AlignInBits))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002619 DEFINE_MDNODE_GET(DILocalVariable,
Duncan P. N. Exon Smithed013cd2015-07-31 18:58:39 +00002620 (Metadata * Scope, MDString *Name, Metadata *File,
Leny Kholodov40c62352016-09-06 17:03:02 +00002621 unsigned Line, Metadata *Type, unsigned Arg,
Victor Leschuka37660c2016-10-26 21:32:29 +00002622 DIFlags Flags, uint32_t AlignInBits),
Victor Leschuk2ede1262016-10-20 00:13:12 +00002623 (Scope, Name, File, Line, Type, Arg, Flags, AlignInBits))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002624
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002625 TempDILocalVariable clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith6873fea2015-02-17 23:10:13 +00002626
Adrian Prantl1687e012016-11-14 22:09:18 +00002627 /// Get the local scope for this variable.
Duncan P. N. Exon Smith3d2afaa2015-03-27 17:29:58 +00002628 ///
2629 /// Variables must be defined in a local scope.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002630 DILocalScope *getScope() const {
2631 return cast<DILocalScope>(DIVariable::getScope());
Duncan P. N. Exon Smith3d2afaa2015-03-27 17:29:58 +00002632 }
2633
Duncan P. N. Exon Smithed013cd2015-07-31 18:58:39 +00002634 bool isParameter() const { return Arg; }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002635 unsigned getArg() const { return Arg; }
Leny Kholodov5fcc4182016-09-06 10:46:28 +00002636 DIFlags getFlags() const { return Flags; }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002637
Duncan P. N. Exon Smithbd42d5d2015-04-07 03:55:30 +00002638 bool isArtificial() const { return getFlags() & FlagArtificial; }
2639 bool isObjectPointer() const { return getFlags() & FlagObjectPointer; }
2640
Adrian Prantl1687e012016-11-14 22:09:18 +00002641 /// Check that a location is valid for this variable.
Duncan P. N. Exon Smith3bef6a32015-04-03 19:20:26 +00002642 ///
Duncan P. N. Exon Smithf17f34e2015-04-15 22:15:46 +00002643 /// Check that \c DL exists, is in the same subprogram, and has the same
Benjamin Kramerdf005cb2015-08-08 18:27:36 +00002644 /// inlined-at location as \c this. (Otherwise, it's not a valid attachment
Duncan P. N. Exon Smithf17f34e2015-04-15 22:15:46 +00002645 /// to a \a DbgInfoIntrinsic.)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002646 bool isValidLocationForIntrinsic(const DILocation *DL) const {
Duncan P. N. Exon Smith62e0f452015-04-15 22:29:27 +00002647 return DL && getScope()->getSubprogram() == DL->getScope()->getSubprogram();
Duncan P. N. Exon Smith3bef6a32015-04-03 19:20:26 +00002648 }
2649
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002650 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002651 return MD->getMetadataID() == DILocalVariableKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002652 }
2653};
2654
Shiva Chen2c864552018-05-09 02:40:45 +00002655/// Label.
2656///
2657class DILabel : public DINode {
2658 friend class LLVMContextImpl;
2659 friend class MDNode;
2660
2661 unsigned Line;
2662
2663 DILabel(LLVMContext &C, StorageType Storage, unsigned Line,
2664 ArrayRef<Metadata *> Ops)
2665 : DINode(C, DILabelKind, Storage, dwarf::DW_TAG_label, Ops), Line(Line) {}
2666 ~DILabel() = default;
2667
2668 static DILabel *getImpl(LLVMContext &Context, DIScope *Scope,
2669 StringRef Name, DIFile *File, unsigned Line,
2670 StorageType Storage,
2671 bool ShouldCreate = true) {
2672 return getImpl(Context, Scope, getCanonicalMDString(Context, Name), File,
2673 Line, Storage, ShouldCreate);
2674 }
2675 static DILabel *getImpl(LLVMContext &Context, Metadata *Scope,
2676 MDString *Name, Metadata *File, unsigned Line,
2677 StorageType Storage,
2678 bool ShouldCreate = true);
2679
2680 TempDILabel cloneImpl() const {
2681 return getTemporary(getContext(), getScope(), getName(), getFile(),
2682 getLine());
2683 }
2684
2685public:
2686 DEFINE_MDNODE_GET(DILabel,
2687 (DILocalScope * Scope, StringRef Name, DIFile *File,
2688 unsigned Line),
2689 (Scope, Name, File, Line))
2690 DEFINE_MDNODE_GET(DILabel,
2691 (Metadata * Scope, MDString *Name, Metadata *File,
2692 unsigned Line),
2693 (Scope, Name, File, Line))
2694
2695 TempDILabel clone() const { return cloneImpl(); }
2696
2697 /// Get the local scope for this label.
2698 ///
2699 /// Labels must be defined in a local scope.
2700 DILocalScope *getScope() const {
2701 return cast_or_null<DILocalScope>(getRawScope());
2702 }
2703 unsigned getLine() const { return Line; }
2704 StringRef getName() const { return getStringOperand(1); }
2705 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
2706
2707 Metadata *getRawScope() const { return getOperand(0); }
2708 MDString *getRawName() const { return getOperandAs<MDString>(1); }
2709 Metadata *getRawFile() const { return getOperand(2); }
2710
2711 /// Check that a location is valid for this label.
2712 ///
2713 /// Check that \c DL exists, is in the same subprogram, and has the same
2714 /// inlined-at location as \c this. (Otherwise, it's not a valid attachment
2715 /// to a \a DbgInfoIntrinsic.)
2716 bool isValidLocationForIntrinsic(const DILocation *DL) const {
2717 return DL && getScope()->getSubprogram() == DL->getScope()->getSubprogram();
2718 }
2719
2720 static bool classof(const Metadata *MD) {
2721 return MD->getMetadataID() == DILabelKind;
2722 }
2723};
2724
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002725class DIObjCProperty : public DINode {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002726 friend class LLVMContextImpl;
2727 friend class MDNode;
2728
2729 unsigned Line;
2730 unsigned Attributes;
2731
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002732 DIObjCProperty(LLVMContext &C, StorageType Storage, unsigned Line,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002733 unsigned Attributes, ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002734 : DINode(C, DIObjCPropertyKind, Storage, dwarf::DW_TAG_APPLE_property,
2735 Ops),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002736 Line(Line), Attributes(Attributes) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002737 ~DIObjCProperty() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002738
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002739 static DIObjCProperty *
2740 getImpl(LLVMContext &Context, StringRef Name, DIFile *File, unsigned Line,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002741 StringRef GetterName, StringRef SetterName, unsigned Attributes,
Adrian Prantl8ff53b32015-06-15 23:18:03 +00002742 DITypeRef Type, StorageType Storage, bool ShouldCreate = true) {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002743 return getImpl(Context, getCanonicalMDString(Context, Name), File, Line,
2744 getCanonicalMDString(Context, GetterName),
2745 getCanonicalMDString(Context, SetterName), Attributes, Type,
2746 Storage, ShouldCreate);
2747 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002748 static DIObjCProperty *getImpl(LLVMContext &Context, MDString *Name,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002749 Metadata *File, unsigned Line,
2750 MDString *GetterName, MDString *SetterName,
2751 unsigned Attributes, Metadata *Type,
2752 StorageType Storage, bool ShouldCreate = true);
2753
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002754 TempDIObjCProperty cloneImpl() const {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002755 return getTemporary(getContext(), getName(), getFile(), getLine(),
2756 getGetterName(), getSetterName(), getAttributes(),
2757 getType());
2758 }
2759
2760public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002761 DEFINE_MDNODE_GET(DIObjCProperty,
2762 (StringRef Name, DIFile *File, unsigned Line,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002763 StringRef GetterName, StringRef SetterName,
Adrian Prantl8ff53b32015-06-15 23:18:03 +00002764 unsigned Attributes, DITypeRef Type),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002765 (Name, File, Line, GetterName, SetterName, Attributes,
2766 Type))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002767 DEFINE_MDNODE_GET(DIObjCProperty,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002768 (MDString * Name, Metadata *File, unsigned Line,
2769 MDString *GetterName, MDString *SetterName,
2770 unsigned Attributes, Metadata *Type),
2771 (Name, File, Line, GetterName, SetterName, Attributes,
2772 Type))
2773
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002774 TempDIObjCProperty clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith6873fea2015-02-17 23:10:13 +00002775
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002776 unsigned getLine() const { return Line; }
2777 unsigned getAttributes() const { return Attributes; }
2778 StringRef getName() const { return getStringOperand(0); }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002779 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002780 StringRef getGetterName() const { return getStringOperand(2); }
2781 StringRef getSetterName() const { return getStringOperand(3); }
Adrian Prantl8ff53b32015-06-15 23:18:03 +00002782 DITypeRef getType() const { return DITypeRef(getRawType()); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002783
Duncan P. N. Exon Smith50c065b2015-04-11 00:39:43 +00002784 StringRef getFilename() const {
2785 if (auto *F = getFile())
2786 return F->getFilename();
2787 return "";
2788 }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +00002789
Duncan P. N. Exon Smith50c065b2015-04-11 00:39:43 +00002790 StringRef getDirectory() const {
2791 if (auto *F = getFile())
2792 return F->getDirectory();
2793 return "";
2794 }
2795
Scott Linder16c7bda2018-02-23 23:01:06 +00002796 Optional<StringRef> getSource() const {
2797 if (auto *F = getFile())
2798 return F->getSource();
2799 return None;
2800 }
2801
Duncan P. N. Exon Smithd45ce962015-02-13 01:43:22 +00002802 MDString *getRawName() const { return getOperandAs<MDString>(0); }
Duncan P. N. Exon Smithf9b47752015-03-30 17:21:38 +00002803 Metadata *getRawFile() const { return getOperand(1); }
Duncan P. N. Exon Smithd45ce962015-02-13 01:43:22 +00002804 MDString *getRawGetterName() const { return getOperandAs<MDString>(2); }
2805 MDString *getRawSetterName() const { return getOperandAs<MDString>(3); }
Duncan P. N. Exon Smithf9b47752015-03-30 17:21:38 +00002806 Metadata *getRawType() const { return getOperand(4); }
Duncan P. N. Exon Smithd45ce962015-02-13 01:43:22 +00002807
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002808 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002809 return MD->getMetadataID() == DIObjCPropertyKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002810 }
2811};
2812
Adrian Prantl1687e012016-11-14 22:09:18 +00002813/// An imported module (C++ using directive or similar).
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002814class DIImportedEntity : public DINode {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002815 friend class LLVMContextImpl;
2816 friend class MDNode;
2817
2818 unsigned Line;
2819
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002820 DIImportedEntity(LLVMContext &C, StorageType Storage, unsigned Tag,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002821 unsigned Line, ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002822 : DINode(C, DIImportedEntityKind, Storage, Tag, Ops), Line(Line) {}
2823 ~DIImportedEntity() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002824
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002825 static DIImportedEntity *getImpl(LLVMContext &Context, unsigned Tag,
2826 DIScope *Scope, DINodeRef Entity,
Adrian Prantld63bfd22017-07-19 00:09:54 +00002827 DIFile *File, unsigned Line, StringRef Name,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002828 StorageType Storage,
2829 bool ShouldCreate = true) {
Adrian Prantld63bfd22017-07-19 00:09:54 +00002830 return getImpl(Context, Tag, Scope, Entity, File, Line,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002831 getCanonicalMDString(Context, Name), Storage, ShouldCreate);
2832 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002833 static DIImportedEntity *getImpl(LLVMContext &Context, unsigned Tag,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002834 Metadata *Scope, Metadata *Entity,
Adrian Prantld63bfd22017-07-19 00:09:54 +00002835 Metadata *File, unsigned Line,
2836 MDString *Name, StorageType Storage,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002837 bool ShouldCreate = true);
2838
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002839 TempDIImportedEntity cloneImpl() const {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002840 return getTemporary(getContext(), getTag(), getScope(), getEntity(),
Adrian Prantld63bfd22017-07-19 00:09:54 +00002841 getFile(), getLine(), getName());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002842 }
2843
2844public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002845 DEFINE_MDNODE_GET(DIImportedEntity,
2846 (unsigned Tag, DIScope *Scope, DINodeRef Entity,
Adrian Prantld63bfd22017-07-19 00:09:54 +00002847 DIFile *File, unsigned Line, StringRef Name = ""),
2848 (Tag, Scope, Entity, File, Line, Name))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002849 DEFINE_MDNODE_GET(DIImportedEntity,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002850 (unsigned Tag, Metadata *Scope, Metadata *Entity,
Adrian Prantld63bfd22017-07-19 00:09:54 +00002851 Metadata *File, unsigned Line, MDString *Name),
2852 (Tag, Scope, Entity, File, Line, Name))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002853
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002854 TempDIImportedEntity clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002855
2856 unsigned getLine() const { return Line; }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002857 DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
2858 DINodeRef getEntity() const { return DINodeRef(getRawEntity()); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002859 StringRef getName() const { return getStringOperand(2); }
Adrian Prantld63bfd22017-07-19 00:09:54 +00002860 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002861
Duncan P. N. Exon Smithf9b47752015-03-30 17:21:38 +00002862 Metadata *getRawScope() const { return getOperand(0); }
2863 Metadata *getRawEntity() const { return getOperand(1); }
Duncan P. N. Exon Smith1c931162015-02-13 01:46:02 +00002864 MDString *getRawName() const { return getOperandAs<MDString>(2); }
Adrian Prantld63bfd22017-07-19 00:09:54 +00002865 Metadata *getRawFile() const { return getOperand(3); }
Duncan P. N. Exon Smith1c931162015-02-13 01:46:02 +00002866
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002867 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002868 return MD->getMetadataID() == DIImportedEntityKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002869 }
2870};
2871
Adrian Prantlbceaaa92016-12-20 02:09:43 +00002872/// A pair of DIGlobalVariable and DIExpression.
2873class DIGlobalVariableExpression : public MDNode {
2874 friend class LLVMContextImpl;
2875 friend class MDNode;
2876
2877 DIGlobalVariableExpression(LLVMContext &C, StorageType Storage,
2878 ArrayRef<Metadata *> Ops)
2879 : MDNode(C, DIGlobalVariableExpressionKind, Storage, Ops) {}
2880 ~DIGlobalVariableExpression() = default;
2881
2882 static DIGlobalVariableExpression *
2883 getImpl(LLVMContext &Context, Metadata *Variable, Metadata *Expression,
2884 StorageType Storage, bool ShouldCreate = true);
2885
2886 TempDIGlobalVariableExpression cloneImpl() const {
2887 return getTemporary(getContext(), getVariable(), getExpression());
2888 }
2889
2890public:
2891 DEFINE_MDNODE_GET(DIGlobalVariableExpression,
2892 (Metadata * Variable, Metadata *Expression),
2893 (Variable, Expression))
2894
2895 TempDIGlobalVariableExpression clone() const { return cloneImpl(); }
2896
2897 Metadata *getRawVariable() const { return getOperand(0); }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +00002898
Adrian Prantlbceaaa92016-12-20 02:09:43 +00002899 DIGlobalVariable *getVariable() const {
2900 return cast_or_null<DIGlobalVariable>(getRawVariable());
2901 }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +00002902
Adrian Prantlbceaaa92016-12-20 02:09:43 +00002903 Metadata *getRawExpression() const { return getOperand(1); }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +00002904
Adrian Prantlbceaaa92016-12-20 02:09:43 +00002905 DIExpression *getExpression() const {
Adrian Prantl05782212017-08-30 18:06:51 +00002906 return cast<DIExpression>(getRawExpression());
Adrian Prantlbceaaa92016-12-20 02:09:43 +00002907 }
2908
2909 static bool classof(const Metadata *MD) {
2910 return MD->getMetadataID() == DIGlobalVariableExpressionKind;
2911 }
2912};
2913
Adrian Prantl1687e012016-11-14 22:09:18 +00002914/// Macro Info DWARF-like metadata node.
Amjad Abouda9bcf162015-12-10 12:56:35 +00002915///
2916/// A metadata node with a DWARF macro info (i.e., a constant named
Zachary Turner264b5d92017-06-07 03:48:56 +00002917/// \c DW_MACINFO_*, defined in llvm/BinaryFormat/Dwarf.h). Called \a
2918/// DIMacroNode
Amjad Abouda9bcf162015-12-10 12:56:35 +00002919/// because it's potentially used for non-DWARF output.
2920class DIMacroNode : public MDNode {
2921 friend class LLVMContextImpl;
2922 friend class MDNode;
2923
2924protected:
2925 DIMacroNode(LLVMContext &C, unsigned ID, StorageType Storage, unsigned MIType,
2926 ArrayRef<Metadata *> Ops1, ArrayRef<Metadata *> Ops2 = None)
2927 : MDNode(C, ID, Storage, Ops1, Ops2) {
2928 assert(MIType < 1u << 16);
2929 SubclassData16 = MIType;
2930 }
2931 ~DIMacroNode() = default;
2932
2933 template <class Ty> Ty *getOperandAs(unsigned I) const {
2934 return cast_or_null<Ty>(getOperand(I));
2935 }
2936
2937 StringRef getStringOperand(unsigned I) const {
2938 if (auto *S = getOperandAs<MDString>(I))
2939 return S->getString();
2940 return StringRef();
2941 }
2942
2943 static MDString *getCanonicalMDString(LLVMContext &Context, StringRef S) {
2944 if (S.empty())
2945 return nullptr;
2946 return MDString::get(Context, S);
2947 }
2948
2949public:
2950 unsigned getMacinfoType() const { return SubclassData16; }
2951
2952 static bool classof(const Metadata *MD) {
2953 switch (MD->getMetadataID()) {
2954 default:
2955 return false;
2956 case DIMacroKind:
2957 case DIMacroFileKind:
2958 return true;
2959 }
2960 }
2961};
2962
2963class DIMacro : public DIMacroNode {
2964 friend class LLVMContextImpl;
2965 friend class MDNode;
2966
2967 unsigned Line;
2968
2969 DIMacro(LLVMContext &C, StorageType Storage, unsigned MIType, unsigned Line,
2970 ArrayRef<Metadata *> Ops)
2971 : DIMacroNode(C, DIMacroKind, Storage, MIType, Ops), Line(Line) {}
2972 ~DIMacro() = default;
2973
2974 static DIMacro *getImpl(LLVMContext &Context, unsigned MIType, unsigned Line,
2975 StringRef Name, StringRef Value, StorageType Storage,
2976 bool ShouldCreate = true) {
2977 return getImpl(Context, MIType, Line, getCanonicalMDString(Context, Name),
2978 getCanonicalMDString(Context, Value), Storage, ShouldCreate);
2979 }
2980 static DIMacro *getImpl(LLVMContext &Context, unsigned MIType, unsigned Line,
2981 MDString *Name, MDString *Value, StorageType Storage,
2982 bool ShouldCreate = true);
2983
2984 TempDIMacro cloneImpl() const {
2985 return getTemporary(getContext(), getMacinfoType(), getLine(), getName(),
2986 getValue());
2987 }
2988
2989public:
2990 DEFINE_MDNODE_GET(DIMacro, (unsigned MIType, unsigned Line, StringRef Name,
2991 StringRef Value = ""),
2992 (MIType, Line, Name, Value))
2993 DEFINE_MDNODE_GET(DIMacro, (unsigned MIType, unsigned Line, MDString *Name,
2994 MDString *Value),
2995 (MIType, Line, Name, Value))
2996
2997 TempDIMacro clone() const { return cloneImpl(); }
2998
2999 unsigned getLine() const { return Line; }
3000
3001 StringRef getName() const { return getStringOperand(0); }
3002 StringRef getValue() const { return getStringOperand(1); }
3003
3004 MDString *getRawName() const { return getOperandAs<MDString>(0); }
3005 MDString *getRawValue() const { return getOperandAs<MDString>(1); }
3006
3007 static bool classof(const Metadata *MD) {
3008 return MD->getMetadataID() == DIMacroKind;
3009 }
3010};
3011
3012class DIMacroFile : public DIMacroNode {
3013 friend class LLVMContextImpl;
3014 friend class MDNode;
3015
3016 unsigned Line;
3017
3018 DIMacroFile(LLVMContext &C, StorageType Storage, unsigned MIType,
3019 unsigned Line, ArrayRef<Metadata *> Ops)
3020 : DIMacroNode(C, DIMacroFileKind, Storage, MIType, Ops), Line(Line) {}
3021 ~DIMacroFile() = default;
3022
3023 static DIMacroFile *getImpl(LLVMContext &Context, unsigned MIType,
3024 unsigned Line, DIFile *File,
3025 DIMacroNodeArray Elements, StorageType Storage,
3026 bool ShouldCreate = true) {
3027 return getImpl(Context, MIType, Line, static_cast<Metadata *>(File),
3028 Elements.get(), Storage, ShouldCreate);
3029 }
3030
3031 static DIMacroFile *getImpl(LLVMContext &Context, unsigned MIType,
3032 unsigned Line, Metadata *File, Metadata *Elements,
3033 StorageType Storage, bool ShouldCreate = true);
3034
3035 TempDIMacroFile cloneImpl() const {
3036 return getTemporary(getContext(), getMacinfoType(), getLine(), getFile(),
3037 getElements());
3038 }
3039
3040public:
3041 DEFINE_MDNODE_GET(DIMacroFile, (unsigned MIType, unsigned Line, DIFile *File,
3042 DIMacroNodeArray Elements),
3043 (MIType, Line, File, Elements))
3044 DEFINE_MDNODE_GET(DIMacroFile, (unsigned MIType, unsigned Line,
3045 Metadata *File, Metadata *Elements),
3046 (MIType, Line, File, Elements))
3047
3048 TempDIMacroFile clone() const { return cloneImpl(); }
3049
3050 void replaceElements(DIMacroNodeArray Elements) {
3051#ifndef NDEBUG
3052 for (DIMacroNode *Op : getElements())
David Majnemer42531262016-08-12 03:55:06 +00003053 assert(is_contained(Elements->operands(), Op) &&
Amjad Abouda9bcf162015-12-10 12:56:35 +00003054 "Lost a macro node during macro node list replacement");
3055#endif
3056 replaceOperandWith(1, Elements.get());
3057 }
3058
3059 unsigned getLine() const { return Line; }
3060 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
3061
3062 DIMacroNodeArray getElements() const {
3063 return cast_or_null<MDTuple>(getRawElements());
3064 }
3065
3066 Metadata *getRawFile() const { return getOperand(0); }
3067 Metadata *getRawElements() const { return getOperand(1); }
3068
3069 static bool classof(const Metadata *MD) {
3070 return MD->getMetadataID() == DIMacroFileKind;
3071 }
3072};
3073
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +00003074} // end namespace llvm
3075
Duncan P. N. Exon Smith61e62a52015-02-02 19:55:21 +00003076#undef DEFINE_MDNODE_GET_UNPACK_IMPL
3077#undef DEFINE_MDNODE_GET_UNPACK
3078#undef DEFINE_MDNODE_GET
3079
Eugene Zelenko1aa40f42016-11-23 22:25:16 +00003080#endif // LLVM_IR_DEBUGINFOMETADATA_H