blob: 2ec8de14d66f3c70362e523a24989346c9f39661 [file] [log] [blame]
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +00001//===- llvm/IR/DebugInfoMetadata.h - Debug info metadata --------*- C++ -*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +00006//
7//===----------------------------------------------------------------------===//
8//
9// Declarations for metadata specific to debug info.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_IR_DEBUGINFOMETADATA_H
14#define LLVM_IR_DEBUGINFOMETADATA_H
15
Eugene Zelenko1aa40f42016-11-23 22:25:16 +000016#include "llvm/ADT/ArrayRef.h"
Leny Kholodov40c62352016-09-06 17:03:02 +000017#include "llvm/ADT/BitmaskEnum.h"
Eugene Zelenko1aa40f42016-11-23 22:25:16 +000018#include "llvm/ADT/None.h"
Eugene Zelenkod761e2c2017-05-15 21:57:41 +000019#include "llvm/ADT/Optional.h"
Sander de Smalenfdf40912018-01-24 09:56:07 +000020#include "llvm/ADT/PointerUnion.h"
Eugene Zelenkod761e2c2017-05-15 21:57:41 +000021#include "llvm/ADT/STLExtras.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000022#include "llvm/ADT/SmallVector.h"
Eugene Zelenko1aa40f42016-11-23 22:25:16 +000023#include "llvm/ADT/StringRef.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000024#include "llvm/ADT/iterator_range.h"
Zachary Turner264b5d92017-06-07 03:48:56 +000025#include "llvm/BinaryFormat/Dwarf.h"
Sander de Smalenfdf40912018-01-24 09:56:07 +000026#include "llvm/IR/Constants.h"
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +000027#include "llvm/IR/Metadata.h"
Eugene Zelenko1aa40f42016-11-23 22:25:16 +000028#include "llvm/Support/Casting.h"
Eugene Zelenko1aa40f42016-11-23 22:25:16 +000029#include <cassert>
30#include <climits>
31#include <cstddef>
32#include <cstdint>
33#include <iterator>
34#include <type_traits>
35#include <vector>
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +000036
Duncan P. N. Exon Smith61e62a52015-02-02 19:55:21 +000037// Helper macros for defining get() overrides.
38#define DEFINE_MDNODE_GET_UNPACK_IMPL(...) __VA_ARGS__
39#define DEFINE_MDNODE_GET_UNPACK(ARGS) DEFINE_MDNODE_GET_UNPACK_IMPL ARGS
Duncan P. N. Exon Smith55ca9642015-08-03 17:26:41 +000040#define DEFINE_MDNODE_GET_DISTINCT_TEMPORARY(CLASS, FORMAL, ARGS) \
Duncan P. N. Exon Smith61e62a52015-02-02 19:55:21 +000041 static CLASS *getDistinct(LLVMContext &Context, \
42 DEFINE_MDNODE_GET_UNPACK(FORMAL)) { \
43 return getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Distinct); \
44 } \
45 static Temp##CLASS getTemporary(LLVMContext &Context, \
46 DEFINE_MDNODE_GET_UNPACK(FORMAL)) { \
47 return Temp##CLASS( \
48 getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Temporary)); \
49 }
Duncan P. N. Exon Smith55ca9642015-08-03 17:26:41 +000050#define DEFINE_MDNODE_GET(CLASS, FORMAL, ARGS) \
51 static CLASS *get(LLVMContext &Context, DEFINE_MDNODE_GET_UNPACK(FORMAL)) { \
52 return getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Uniqued); \
53 } \
54 static CLASS *getIfExists(LLVMContext &Context, \
55 DEFINE_MDNODE_GET_UNPACK(FORMAL)) { \
56 return getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Uniqued, \
57 /* ShouldCreate */ false); \
58 } \
59 DEFINE_MDNODE_GET_DISTINCT_TEMPORARY(CLASS, FORMAL, ARGS)
Duncan P. N. Exon Smith61e62a52015-02-02 19:55:21 +000060
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +000061namespace llvm {
62
Duncan P. N. Exon Smitha59d3e52016-04-23 21:08:00 +000063/// Holds a subclass of DINode.
Duncan P. N. Exon Smith930f3882015-04-06 18:02:43 +000064///
Duncan P. N. Exon Smitha59d3e52016-04-23 21:08:00 +000065/// FIXME: This class doesn't currently make much sense. Previously it was a
66/// union beteen MDString (for ODR-uniqued types) and things like DIType. To
67/// support CodeView work, it wasn't deleted outright when MDString-based type
68/// references were deleted; we'll soon need a similar concept for CodeView
69/// DITypeIndex.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +000070template <class T> class TypedDINodeRef {
Duncan P. N. Exon Smith930f3882015-04-06 18:02:43 +000071 const Metadata *MD = nullptr;
72
73public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +000074 TypedDINodeRef() = default;
75 TypedDINodeRef(std::nullptr_t) {}
Duncan P. N. Exon Smitha59d3e52016-04-23 21:08:00 +000076 TypedDINodeRef(const T *MD) : MD(MD) {}
Duncan P. N. Exon Smith930f3882015-04-06 18:02:43 +000077
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +000078 explicit TypedDINodeRef(const Metadata *MD) : MD(MD) {
Duncan P. N. Exon Smitha59d3e52016-04-23 21:08:00 +000079 assert((!MD || isa<T>(MD)) && "Expected valid type ref");
Duncan P. N. Exon Smith930f3882015-04-06 18:02:43 +000080 }
81
82 template <class U>
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +000083 TypedDINodeRef(
84 const TypedDINodeRef<U> &X,
Duncan P. N. Exon Smith930f3882015-04-06 18:02:43 +000085 typename std::enable_if<std::is_convertible<U *, T *>::value>::type * =
86 nullptr)
87 : MD(X) {}
88
89 operator Metadata *() const { return const_cast<Metadata *>(MD); }
90
Duncan P. N. Exon Smitha59d3e52016-04-23 21:08:00 +000091 T *resolve() const { return const_cast<T *>(cast_or_null<T>(MD)); }
92
Hans Wennborg13958b72015-07-22 20:46:11 +000093 bool operator==(const TypedDINodeRef<T> &X) const { return MD == X.MD; }
94 bool operator!=(const TypedDINodeRef<T> &X) const { return MD != X.MD; }
Duncan P. N. Exon Smith930f3882015-04-06 18:02:43 +000095};
96
Eugene Zelenkod761e2c2017-05-15 21:57:41 +000097using DINodeRef = TypedDINodeRef<DINode>;
98using DIScopeRef = TypedDINodeRef<DIScope>;
99using DITypeRef = TypedDINodeRef<DIType>;
Duncan P. N. Exon Smith930f3882015-04-06 18:02:43 +0000100
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000101class DITypeRefArray {
Duncan P. N. Exon Smith62e93622015-04-06 19:48:50 +0000102 const MDTuple *N = nullptr;
103
104public:
Duncan P. N. Exon Smith0660bcd2015-08-28 21:38:24 +0000105 DITypeRefArray() = default;
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000106 DITypeRefArray(const MDTuple *N) : N(N) {}
Duncan P. N. Exon Smith11344732015-04-07 16:50:39 +0000107
108 explicit operator bool() const { return get(); }
109 explicit operator MDTuple *() const { return get(); }
110
111 MDTuple *get() const { return const_cast<MDTuple *>(N); }
112 MDTuple *operator->() const { return get(); }
113 MDTuple &operator*() const { return *get(); }
Duncan P. N. Exon Smith62e93622015-04-06 19:48:50 +0000114
Duncan P. N. Exon Smith000fa2c2015-04-07 04:14:33 +0000115 // FIXME: Fix callers and remove condition on N.
116 unsigned size() const { return N ? N->getNumOperands() : 0u; }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000117 DITypeRef operator[](unsigned I) const { return DITypeRef(N->getOperand(I)); }
Duncan P. N. Exon Smith62e93622015-04-06 19:48:50 +0000118
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000119 class iterator : std::iterator<std::input_iterator_tag, DITypeRef,
120 std::ptrdiff_t, void, DITypeRef> {
Duncan P. N. Exon Smith000fa2c2015-04-07 04:14:33 +0000121 MDNode::op_iterator I = nullptr;
Duncan P. N. Exon Smith62e93622015-04-06 19:48:50 +0000122
123 public:
Duncan P. N. Exon Smith000fa2c2015-04-07 04:14:33 +0000124 iterator() = default;
Duncan P. N. Exon Smith62e93622015-04-06 19:48:50 +0000125 explicit iterator(MDNode::op_iterator I) : I(I) {}
Eugene Zelenko1aa40f42016-11-23 22:25:16 +0000126
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000127 DITypeRef operator*() const { return DITypeRef(*I); }
Eugene Zelenko1aa40f42016-11-23 22:25:16 +0000128
Duncan P. N. Exon Smith62e93622015-04-06 19:48:50 +0000129 iterator &operator++() {
130 ++I;
131 return *this;
132 }
Eugene Zelenko1aa40f42016-11-23 22:25:16 +0000133
Duncan P. N. Exon Smith62e93622015-04-06 19:48:50 +0000134 iterator operator++(int) {
135 iterator Temp(*this);
136 ++I;
137 return Temp;
138 }
Eugene Zelenko1aa40f42016-11-23 22:25:16 +0000139
Duncan P. N. Exon Smith62e93622015-04-06 19:48:50 +0000140 bool operator==(const iterator &X) const { return I == X.I; }
141 bool operator!=(const iterator &X) const { return I != X.I; }
142 };
143
Duncan P. N. Exon Smith000fa2c2015-04-07 04:14:33 +0000144 // FIXME: Fix callers and remove condition on N.
145 iterator begin() const { return N ? iterator(N->op_begin()) : iterator(); }
146 iterator end() const { return N ? iterator(N->op_end()) : iterator(); }
Duncan P. N. Exon Smith62e93622015-04-06 19:48:50 +0000147};
148
Adrian Prantl1687e012016-11-14 22:09:18 +0000149/// Tagged DWARF-like metadata node.
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000150///
151/// A metadata node with a DWARF tag (i.e., a constant named \c DW_TAG_*,
Zachary Turner264b5d92017-06-07 03:48:56 +0000152/// defined in llvm/BinaryFormat/Dwarf.h). Called \a DINode because it's
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000153/// potentially used for non-DWARF output.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000154class DINode : public MDNode {
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000155 friend class LLVMContextImpl;
156 friend class MDNode;
157
158protected:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000159 DINode(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
160 ArrayRef<Metadata *> Ops1, ArrayRef<Metadata *> Ops2 = None)
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000161 : MDNode(C, ID, Storage, Ops1, Ops2) {
162 assert(Tag < 1u << 16);
163 SubclassData16 = Tag;
164 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000165 ~DINode() = default;
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000166
Duncan P. N. Exon Smith252b62d2015-02-05 01:07:47 +0000167 template <class Ty> Ty *getOperandAs(unsigned I) const {
168 return cast_or_null<Ty>(getOperand(I));
169 }
170
Duncan P. N. Exon Smith442ec022015-02-02 19:54:05 +0000171 StringRef getStringOperand(unsigned I) const {
Duncan P. N. Exon Smith252b62d2015-02-05 01:07:47 +0000172 if (auto *S = getOperandAs<MDString>(I))
Duncan P. N. Exon Smith442ec022015-02-02 19:54:05 +0000173 return S->getString();
174 return StringRef();
175 }
176
Duncan P. N. Exon Smith9146fc82015-02-02 20:01:03 +0000177 static MDString *getCanonicalMDString(LLVMContext &Context, StringRef S) {
178 if (S.empty())
179 return nullptr;
180 return MDString::get(Context, S);
181 }
182
Duncan P. N. Exon Smith97386022016-04-19 18:00:19 +0000183 /// Allow subclasses to mutate the tag.
184 void setTag(unsigned Tag) { SubclassData16 = Tag; }
185
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000186public:
187 unsigned getTag() const { return SubclassData16; }
188
Adrian Prantl1687e012016-11-14 22:09:18 +0000189 /// Debug info flags.
Duncan P. N. Exon Smith3744fd02015-03-31 01:19:51 +0000190 ///
191 /// The three accessibility flags are mutually exclusive and rolled together
192 /// in the first two bits.
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000193 enum DIFlags : uint32_t {
Duncan P. N. Exon Smith3744fd02015-03-31 01:19:51 +0000194#define HANDLE_DI_FLAG(ID, NAME) Flag##NAME = ID,
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000195#define DI_FLAG_LARGEST_NEEDED
Duncan P. N. Exon Smith3744fd02015-03-31 01:19:51 +0000196#include "llvm/IR/DebugInfoFlags.def"
Reid Kleckner604105b2016-06-17 21:31:33 +0000197 FlagAccessibility = FlagPrivate | FlagProtected | FlagPublic,
198 FlagPtrToMemberRep = FlagSingleInheritance | FlagMultipleInheritance |
199 FlagVirtualInheritance,
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000200 LLVM_MARK_AS_BITMASK_ENUM(FlagLargest)
Duncan P. N. Exon Smith3744fd02015-03-31 01:19:51 +0000201 };
202
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000203 static DIFlags getFlag(StringRef Flag);
Mehdi Aminif42ec792016-10-01 05:57:50 +0000204 static StringRef getFlagString(DIFlags Flag);
Duncan P. N. Exon Smith5261e4b2015-04-07 01:21:40 +0000205
Adrian Prantl1687e012016-11-14 22:09:18 +0000206 /// Split up a flags bitfield.
Duncan P. N. Exon Smith5261e4b2015-04-07 01:21:40 +0000207 ///
208 /// Split \c Flags into \c SplitFlags, a vector of its components. Returns
209 /// any remaining (unrecognized) bits.
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000210 static DIFlags splitFlags(DIFlags Flags,
Leny Kholodov40c62352016-09-06 17:03:02 +0000211 SmallVectorImpl<DIFlags> &SplitFlags);
Duncan P. N. Exon Smith5261e4b2015-04-07 01:21:40 +0000212
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +0000213 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000214 switch (MD->getMetadataID()) {
215 default:
216 return false;
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000217 case GenericDINodeKind:
218 case DISubrangeKind:
219 case DIEnumeratorKind:
220 case DIBasicTypeKind:
221 case DIDerivedTypeKind:
222 case DICompositeTypeKind:
223 case DISubroutineTypeKind:
224 case DIFileKind:
225 case DICompileUnitKind:
226 case DISubprogramKind:
227 case DILexicalBlockKind:
228 case DILexicalBlockFileKind:
229 case DINamespaceKind:
Adrian Prantl6ed57062019-04-08 19:13:55 +0000230 case DICommonBlockKind:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000231 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 Prantl6ed57062019-04-08 19:13:55 +0000489 case DICommonBlockKind:
Adrian Prantlab1243f2015-06-29 23:03:47 +0000490 case DIModuleKind:
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000491 return true;
492 }
493 }
494};
495
Adrian Prantl1687e012016-11-14 22:09:18 +0000496/// File.
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +0000497///
498/// TODO: Merge with directory/file node (including users).
499/// TODO: Canonicalize paths on creation.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000500class DIFile : public DIScope {
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +0000501 friend class LLVMContextImpl;
502 friend class MDNode;
503
Amjad Aboud7faeecc2016-12-25 10:12:09 +0000504public:
Scott Linder71603842018-02-12 19:45:54 +0000505 /// Which algorithm (e.g. MD5) a checksum was generated with.
506 ///
507 /// The encoding is explicit because it is used directly in Bitcode. The
508 /// value 0 is reserved to indicate the absence of a checksum in Bitcode.
Amjad Aboud7faeecc2016-12-25 10:12:09 +0000509 enum ChecksumKind {
Scott Linder71603842018-02-12 19:45:54 +0000510 // The first variant was originally CSK_None, encoded as 0. The new
511 // internal representation removes the need for this by wrapping the
512 // ChecksumInfo in an Optional, but to preserve Bitcode compatibility the 0
513 // encoding is reserved.
Reid Kleckner26fa1bf2017-09-19 18:14:45 +0000514 CSK_MD5 = 1,
515 CSK_SHA1 = 2,
Amjad Aboud7faeecc2016-12-25 10:12:09 +0000516 CSK_Last = CSK_SHA1 // Should be last enumeration.
517 };
518
Scott Linder71603842018-02-12 19:45:54 +0000519 /// A single checksum, represented by a \a Kind and a \a Value (a string).
520 template <typename T>
521 struct ChecksumInfo {
522 /// The kind of checksum which \a Value encodes.
523 ChecksumKind Kind;
524 /// The string value of the checksum.
525 T Value;
Amjad Aboud7faeecc2016-12-25 10:12:09 +0000526
Scott Linder71603842018-02-12 19:45:54 +0000527 ChecksumInfo(ChecksumKind Kind, T Value) : Kind(Kind), Value(Value) { }
528 ~ChecksumInfo() = default;
529 bool operator==(const ChecksumInfo<T> &X) const {
530 return Kind == X.Kind && Value == X.Value;
531 }
532 bool operator!=(const ChecksumInfo<T> &X) const { return !(*this == X); }
533 StringRef getKindAsString() const { return getChecksumKindAsString(Kind); }
534 };
535
536private:
537 Optional<ChecksumInfo<MDString *>> Checksum;
Scott Linder16c7bda2018-02-23 23:01:06 +0000538 Optional<MDString *> Source;
Scott Linder71603842018-02-12 19:45:54 +0000539
540 DIFile(LLVMContext &C, StorageType Storage,
Scott Linder16c7bda2018-02-23 23:01:06 +0000541 Optional<ChecksumInfo<MDString *>> CS, Optional<MDString *> Src,
Amjad Aboud7faeecc2016-12-25 10:12:09 +0000542 ArrayRef<Metadata *> Ops)
543 : DIScope(C, DIFileKind, Storage, dwarf::DW_TAG_file_type, Ops),
Scott Linder16c7bda2018-02-23 23:01:06 +0000544 Checksum(CS), Source(Src) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000545 ~DIFile() = default;
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +0000546
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000547 static DIFile *getImpl(LLVMContext &Context, StringRef Filename,
Scott Linder71603842018-02-12 19:45:54 +0000548 StringRef Directory,
549 Optional<ChecksumInfo<StringRef>> CS,
Scott Linder16c7bda2018-02-23 23:01:06 +0000550 Optional<StringRef> Source,
Amjad Aboud7faeecc2016-12-25 10:12:09 +0000551 StorageType Storage, bool ShouldCreate = true) {
Scott Linder71603842018-02-12 19:45:54 +0000552 Optional<ChecksumInfo<MDString *>> MDChecksum;
553 if (CS)
554 MDChecksum.emplace(CS->Kind, getCanonicalMDString(Context, CS->Value));
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +0000555 return getImpl(Context, getCanonicalMDString(Context, Filename),
Scott Linder71603842018-02-12 19:45:54 +0000556 getCanonicalMDString(Context, Directory), MDChecksum,
Scott Linder16c7bda2018-02-23 23:01:06 +0000557 Source ? Optional<MDString *>(getCanonicalMDString(Context, *Source)) : None,
Scott Linder71603842018-02-12 19:45:54 +0000558 Storage, ShouldCreate);
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +0000559 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000560 static DIFile *getImpl(LLVMContext &Context, MDString *Filename,
Scott Linder71603842018-02-12 19:45:54 +0000561 MDString *Directory,
562 Optional<ChecksumInfo<MDString *>> CS,
Scott Linder16c7bda2018-02-23 23:01:06 +0000563 Optional<MDString *> Source, StorageType Storage,
564 bool ShouldCreate = true);
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +0000565
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000566 TempDIFile cloneImpl() const {
Amjad Aboud7faeecc2016-12-25 10:12:09 +0000567 return getTemporary(getContext(), getFilename(), getDirectory(),
Scott Linder16c7bda2018-02-23 23:01:06 +0000568 getChecksum(), getSource());
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +0000569 }
570
571public:
Amjad Aboud7faeecc2016-12-25 10:12:09 +0000572 DEFINE_MDNODE_GET(DIFile, (StringRef Filename, StringRef Directory,
Scott Linder16c7bda2018-02-23 23:01:06 +0000573 Optional<ChecksumInfo<StringRef>> CS = None,
574 Optional<StringRef> Source = None),
575 (Filename, Directory, CS, Source))
Reid Kleckner26fa1bf2017-09-19 18:14:45 +0000576 DEFINE_MDNODE_GET(DIFile, (MDString * Filename, MDString *Directory,
Scott Linder16c7bda2018-02-23 23:01:06 +0000577 Optional<ChecksumInfo<MDString *>> CS = None,
578 Optional<MDString *> Source = None),
579 (Filename, Directory, CS, Source))
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +0000580
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000581 TempDIFile clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +0000582
583 StringRef getFilename() const { return getStringOperand(0); }
584 StringRef getDirectory() const { return getStringOperand(1); }
Scott Linder71603842018-02-12 19:45:54 +0000585 Optional<ChecksumInfo<StringRef>> getChecksum() const {
586 Optional<ChecksumInfo<StringRef>> StringRefChecksum;
587 if (Checksum)
588 StringRefChecksum.emplace(Checksum->Kind, Checksum->Value->getString());
589 return StringRefChecksum;
590 }
Scott Linder16c7bda2018-02-23 23:01:06 +0000591 Optional<StringRef> getSource() const {
592 return Source ? Optional<StringRef>((*Source)->getString()) : None;
593 }
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +0000594
595 MDString *getRawFilename() const { return getOperandAs<MDString>(0); }
596 MDString *getRawDirectory() const { return getOperandAs<MDString>(1); }
Scott Linder71603842018-02-12 19:45:54 +0000597 Optional<ChecksumInfo<MDString *>> getRawChecksum() const { return Checksum; }
Scott Linder16c7bda2018-02-23 23:01:06 +0000598 Optional<MDString *> getRawSource() const { return Source; }
Amjad Aboud7faeecc2016-12-25 10:12:09 +0000599
Scott Linder71603842018-02-12 19:45:54 +0000600 static StringRef getChecksumKindAsString(ChecksumKind CSKind);
601 static Optional<ChecksumKind> getChecksumKind(StringRef CSKindStr);
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +0000602
603 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000604 return MD->getMetadataID() == DIFileKind;
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +0000605 }
606};
607
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000608StringRef DIScope::getFilename() const {
Duncan P. N. Exon Smith50c065b2015-04-11 00:39:43 +0000609 if (auto *F = getFile())
610 return F->getFilename();
611 return "";
612}
613
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000614StringRef DIScope::getDirectory() const {
Duncan P. N. Exon Smith50c065b2015-04-11 00:39:43 +0000615 if (auto *F = getFile())
616 return F->getDirectory();
617 return "";
618}
619
Scott Linder16c7bda2018-02-23 23:01:06 +0000620Optional<StringRef> DIScope::getSource() const {
621 if (auto *F = getFile())
622 return F->getSource();
623 return None;
624}
625
Adrian Prantl1687e012016-11-14 22:09:18 +0000626/// Base class for types.
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000627///
628/// TODO: Remove the hardcoded name and context, since many types don't use
629/// them.
630/// TODO: Split up flags.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000631class DIType : public DIScope {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000632 unsigned Line;
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000633 DIFlags Flags;
Duncan P. N. Exon Smithd34db172015-02-19 23:56:07 +0000634 uint64_t SizeInBits;
Duncan P. N. Exon Smithd34db172015-02-19 23:56:07 +0000635 uint64_t OffsetInBits;
Victor Leschuk197aa312016-10-18 14:31:22 +0000636 uint32_t AlignInBits;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000637
638protected:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000639 DIType(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
Victor Leschuk197aa312016-10-18 14:31:22 +0000640 unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits,
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000641 uint64_t OffsetInBits, DIFlags Flags, ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smith97386022016-04-19 18:00:19 +0000642 : DIScope(C, ID, Storage, Tag, Ops) {
643 init(Line, SizeInBits, AlignInBits, OffsetInBits, Flags);
644 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000645 ~DIType() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000646
Victor Leschuk197aa312016-10-18 14:31:22 +0000647 void init(unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits,
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000648 uint64_t OffsetInBits, DIFlags Flags) {
Duncan P. N. Exon Smith97386022016-04-19 18:00:19 +0000649 this->Line = Line;
650 this->Flags = Flags;
651 this->SizeInBits = SizeInBits;
652 this->AlignInBits = AlignInBits;
653 this->OffsetInBits = OffsetInBits;
654 }
655
656 /// Change fields in place.
657 void mutate(unsigned Tag, unsigned Line, uint64_t SizeInBits,
Victor Leschuk197aa312016-10-18 14:31:22 +0000658 uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags) {
Duncan P. N. Exon Smith97386022016-04-19 18:00:19 +0000659 assert(isDistinct() && "Only distinct nodes can mutate");
660 setTag(Tag);
661 init(Line, SizeInBits, AlignInBits, OffsetInBits, Flags);
662 }
663
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000664public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000665 TempDIType clone() const {
666 return TempDIType(cast<DIType>(MDNode::clone().release()));
Duncan P. N. Exon Smithb3538492015-03-03 16:45:34 +0000667 }
668
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000669 unsigned getLine() const { return Line; }
Duncan P. N. Exon Smithd34db172015-02-19 23:56:07 +0000670 uint64_t getSizeInBits() const { return SizeInBits; }
Victor Leschuk2ede1262016-10-20 00:13:12 +0000671 uint32_t getAlignInBits() const { return AlignInBits; }
672 uint32_t getAlignInBytes() const { return getAlignInBits() / CHAR_BIT; }
Duncan P. N. Exon Smithd34db172015-02-19 23:56:07 +0000673 uint64_t getOffsetInBits() const { return OffsetInBits; }
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000674 DIFlags getFlags() const { return Flags; }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000675
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000676 DIScopeRef getScope() const { return DIScopeRef(getRawScope()); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000677 StringRef getName() const { return getStringOperand(2); }
678
Duncan P. N. Exon Smith53855f02015-03-27 23:05:04 +0000679
680 Metadata *getRawScope() const { return getOperand(1); }
Duncan P. N. Exon Smith09e03f32015-02-13 01:14:58 +0000681 MDString *getRawName() const { return getOperandAs<MDString>(2); }
682
Roman Tereshincf88ffa2018-06-01 23:15:09 +0000683 /// Returns a new temporary DIType with updated Flags
684 TempDIType cloneWithFlags(DIFlags NewFlags) const {
685 auto NewTy = clone();
686 NewTy->Flags = NewFlags;
687 return NewTy;
Duncan P. N. Exon Smithb3538492015-03-03 16:45:34 +0000688 }
689
Duncan P. N. Exon Smithaecab7a2015-04-07 01:24:30 +0000690 bool isPrivate() const {
691 return (getFlags() & FlagAccessibility) == FlagPrivate;
692 }
693 bool isProtected() const {
694 return (getFlags() & FlagAccessibility) == FlagProtected;
695 }
696 bool isPublic() const {
697 return (getFlags() & FlagAccessibility) == FlagPublic;
698 }
699 bool isForwardDecl() const { return getFlags() & FlagFwdDecl; }
700 bool isAppleBlockExtension() const { return getFlags() & FlagAppleBlock; }
701 bool isBlockByrefStruct() const { return getFlags() & FlagBlockByrefStruct; }
702 bool isVirtual() const { return getFlags() & FlagVirtual; }
703 bool isArtificial() const { return getFlags() & FlagArtificial; }
704 bool isObjectPointer() const { return getFlags() & FlagObjectPointer; }
705 bool isObjcClassComplete() const {
706 return getFlags() & FlagObjcClassComplete;
707 }
708 bool isVector() const { return getFlags() & FlagVector; }
David Majnemer9319cbc2016-06-30 03:00:20 +0000709 bool isBitField() const { return getFlags() & FlagBitField; }
Duncan P. N. Exon Smithaecab7a2015-04-07 01:24:30 +0000710 bool isStaticMember() const { return getFlags() & FlagStaticMember; }
711 bool isLValueReference() const { return getFlags() & FlagLValueReference; }
712 bool isRValueReference() const { return getFlags() & FlagRValueReference; }
Adrian Prantla29aac72018-01-05 01:13:37 +0000713 bool isTypePassByValue() const { return getFlags() & FlagTypePassByValue; }
714 bool isTypePassByReference() const {
715 return getFlags() & FlagTypePassByReference;
716 }
Adrian Prantl55f42622018-08-14 19:35:34 +0000717 bool isBigEndian() const { return getFlags() & FlagBigEndian; }
718 bool isLittleEndian() const { return getFlags() & FlagLittleEndian; }
Duncan P. N. Exon Smithaecab7a2015-04-07 01:24:30 +0000719
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000720 static bool classof(const Metadata *MD) {
721 switch (MD->getMetadataID()) {
722 default:
723 return false;
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000724 case DIBasicTypeKind:
725 case DIDerivedTypeKind:
726 case DICompositeTypeKind:
727 case DISubroutineTypeKind:
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000728 return true;
729 }
730 }
731};
732
Adrian Prantl1687e012016-11-14 22:09:18 +0000733/// Basic type, like 'int' or 'float'.
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000734///
735/// TODO: Split out DW_TAG_unspecified_type.
736/// TODO: Drop unused accessors.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000737class DIBasicType : public DIType {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000738 friend class LLVMContextImpl;
739 friend class MDNode;
740
741 unsigned Encoding;
742
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000743 DIBasicType(LLVMContext &C, StorageType Storage, unsigned Tag,
Victor Leschuk197aa312016-10-18 14:31:22 +0000744 uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding,
Adrian Prantl55f42622018-08-14 19:35:34 +0000745 DIFlags Flags, ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000746 : DIType(C, DIBasicTypeKind, Storage, Tag, 0, SizeInBits, AlignInBits, 0,
Adrian Prantl55f42622018-08-14 19:35:34 +0000747 Flags, Ops),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000748 Encoding(Encoding) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000749 ~DIBasicType() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000750
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000751 static DIBasicType *getImpl(LLVMContext &Context, unsigned Tag,
Duncan P. N. Exon Smithd34db172015-02-19 23:56:07 +0000752 StringRef Name, uint64_t SizeInBits,
Victor Leschuk197aa312016-10-18 14:31:22 +0000753 uint32_t AlignInBits, unsigned Encoding,
Adrian Prantl55f42622018-08-14 19:35:34 +0000754 DIFlags Flags, StorageType Storage,
755 bool ShouldCreate = true) {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000756 return getImpl(Context, Tag, getCanonicalMDString(Context, Name),
Adrian Prantl55f42622018-08-14 19:35:34 +0000757 SizeInBits, AlignInBits, Encoding, Flags, Storage,
758 ShouldCreate);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000759 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000760 static DIBasicType *getImpl(LLVMContext &Context, unsigned Tag,
Duncan P. N. Exon Smithd34db172015-02-19 23:56:07 +0000761 MDString *Name, uint64_t SizeInBits,
Victor Leschuk197aa312016-10-18 14:31:22 +0000762 uint32_t AlignInBits, unsigned Encoding,
Adrian Prantl55f42622018-08-14 19:35:34 +0000763 DIFlags Flags, StorageType Storage,
764 bool ShouldCreate = true);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000765
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000766 TempDIBasicType cloneImpl() const {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000767 return getTemporary(getContext(), getTag(), getName(), getSizeInBits(),
Adrian Prantl55f42622018-08-14 19:35:34 +0000768 getAlignInBits(), getEncoding(), getFlags());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000769 }
770
771public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000772 DEFINE_MDNODE_GET(DIBasicType, (unsigned Tag, StringRef Name),
Adrian Prantl55f42622018-08-14 19:35:34 +0000773 (Tag, Name, 0, 0, 0, FlagZero))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000774 DEFINE_MDNODE_GET(DIBasicType,
Duncan P. N. Exon Smithd34db172015-02-19 23:56:07 +0000775 (unsigned Tag, StringRef Name, uint64_t SizeInBits,
Adrian Prantl55f42622018-08-14 19:35:34 +0000776 uint32_t AlignInBits, unsigned Encoding, DIFlags Flags),
777 (Tag, Name, SizeInBits, AlignInBits, Encoding, Flags))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000778 DEFINE_MDNODE_GET(DIBasicType,
Duncan P. N. Exon Smithd34db172015-02-19 23:56:07 +0000779 (unsigned Tag, MDString *Name, uint64_t SizeInBits,
Adrian Prantl55f42622018-08-14 19:35:34 +0000780 uint32_t AlignInBits, unsigned Encoding, DIFlags Flags),
781 (Tag, Name, SizeInBits, AlignInBits, Encoding, Flags))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000782
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000783 TempDIBasicType clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000784
785 unsigned getEncoding() const { return Encoding; }
786
Vedant Kumar6379a622018-07-06 17:32:39 +0000787 enum class Signedness { Signed, Unsigned };
788
789 /// Return the signedness of this type, or None if this type is neither
790 /// signed nor unsigned.
791 Optional<Signedness> getSignedness() const;
792
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000793 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000794 return MD->getMetadataID() == DIBasicTypeKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000795 }
796};
797
Adrian Prantl1687e012016-11-14 22:09:18 +0000798/// Derived types.
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000799///
800/// This includes qualified types, pointers, references, friends, typedefs, and
801/// class members.
802///
803/// TODO: Split out members (inheritance, fields, methods, etc.).
Duncan P. N. Exon Smith338aef02015-07-24 20:16:36 +0000804class DIDerivedType : public DIType {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000805 friend class LLVMContextImpl;
806 friend class MDNode;
807
Adrian Prantl5f8f34e42018-05-01 15:54:18 +0000808 /// The DWARF address space of the memory pointed to or referenced by a
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000809 /// pointer or reference type respectively.
810 Optional<unsigned> DWARFAddressSpace;
811
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000812 DIDerivedType(LLVMContext &C, StorageType Storage, unsigned Tag,
Victor Leschuk197aa312016-10-18 14:31:22 +0000813 unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits,
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000814 uint64_t OffsetInBits, Optional<unsigned> DWARFAddressSpace,
815 DIFlags Flags, ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smith338aef02015-07-24 20:16:36 +0000816 : DIType(C, DIDerivedTypeKind, Storage, Tag, Line, SizeInBits,
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000817 AlignInBits, OffsetInBits, Flags, Ops),
818 DWARFAddressSpace(DWARFAddressSpace) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000819 ~DIDerivedType() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000820
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000821 static DIDerivedType *getImpl(LLVMContext &Context, unsigned Tag,
822 StringRef Name, DIFile *File, unsigned Line,
823 DIScopeRef Scope, DITypeRef BaseType,
Victor Leschuk197aa312016-10-18 14:31:22 +0000824 uint64_t SizeInBits, uint32_t AlignInBits,
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000825 uint64_t OffsetInBits,
826 Optional<unsigned> DWARFAddressSpace,
827 DIFlags Flags, Metadata *ExtraData,
828 StorageType Storage, bool ShouldCreate = true) {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000829 return getImpl(Context, Tag, getCanonicalMDString(Context, Name), File,
830 Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits,
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000831 DWARFAddressSpace, Flags, ExtraData, Storage, ShouldCreate);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000832 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000833 static DIDerivedType *getImpl(LLVMContext &Context, unsigned Tag,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000834 MDString *Name, Metadata *File, unsigned Line,
835 Metadata *Scope, Metadata *BaseType,
Victor Leschuk197aa312016-10-18 14:31:22 +0000836 uint64_t SizeInBits, uint32_t AlignInBits,
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000837 uint64_t OffsetInBits,
838 Optional<unsigned> DWARFAddressSpace,
839 DIFlags Flags, Metadata *ExtraData,
840 StorageType Storage, bool ShouldCreate = true);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000841
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000842 TempDIDerivedType cloneImpl() const {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000843 return getTemporary(getContext(), getTag(), getName(), getFile(), getLine(),
844 getScope(), getBaseType(), getSizeInBits(),
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000845 getAlignInBits(), getOffsetInBits(),
846 getDWARFAddressSpace(), getFlags(), getExtraData());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000847 }
848
849public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000850 DEFINE_MDNODE_GET(DIDerivedType,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000851 (unsigned Tag, MDString *Name, Metadata *File,
852 unsigned Line, Metadata *Scope, Metadata *BaseType,
Victor Leschuk197aa312016-10-18 14:31:22 +0000853 uint64_t SizeInBits, uint32_t AlignInBits,
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000854 uint64_t OffsetInBits,
855 Optional<unsigned> DWARFAddressSpace, DIFlags Flags,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000856 Metadata *ExtraData = nullptr),
857 (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000858 AlignInBits, OffsetInBits, DWARFAddressSpace, Flags,
859 ExtraData))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000860 DEFINE_MDNODE_GET(DIDerivedType,
861 (unsigned Tag, StringRef Name, DIFile *File, unsigned Line,
862 DIScopeRef Scope, DITypeRef BaseType, uint64_t SizeInBits,
Victor Leschuk197aa312016-10-18 14:31:22 +0000863 uint32_t AlignInBits, uint64_t OffsetInBits,
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000864 Optional<unsigned> DWARFAddressSpace, DIFlags Flags,
865 Metadata *ExtraData = nullptr),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000866 (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000867 AlignInBits, OffsetInBits, DWARFAddressSpace, Flags,
868 ExtraData))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000869
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000870 TempDIDerivedType clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000871
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000872 /// Get the base type this is derived from.
Duncan P. N. Exon Smith338aef02015-07-24 20:16:36 +0000873 DITypeRef getBaseType() const { return DITypeRef(getRawBaseType()); }
874 Metadata *getRawBaseType() const { return getOperand(3); }
875
Konstantin Zhuravlyovd5561e02017-03-08 23:55:44 +0000876 /// \returns The DWARF address space of the memory pointed to or referenced by
877 /// a pointer or reference type respectively.
878 Optional<unsigned> getDWARFAddressSpace() const { return DWARFAddressSpace; }
879
Adrian Prantl1687e012016-11-14 22:09:18 +0000880 /// Get extra data associated with this derived type.
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000881 ///
882 /// Class type for pointer-to-members, objective-c property node for ivars,
Brock Wyma3db2b102018-05-14 21:21:22 +0000883 /// global constant wrapper for static members, or virtual base pointer offset
884 /// for inheritance.
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000885 ///
886 /// TODO: Separate out types that need this extra operand: pointer-to-member
887 /// types and member fields (static members and ivars).
Duncan P. N. Exon Smith53855f02015-03-27 23:05:04 +0000888 Metadata *getExtraData() const { return getRawExtraData(); }
889 Metadata *getRawExtraData() const { return getOperand(4); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000890
Adrian Prantl1687e012016-11-14 22:09:18 +0000891 /// Get casted version of extra data.
Duncan P. N. Exon Smith0bf8d4c2015-04-13 23:36:36 +0000892 /// @{
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000893 DITypeRef getClassType() const {
Duncan P. N. Exon Smith0bf8d4c2015-04-13 23:36:36 +0000894 assert(getTag() == dwarf::DW_TAG_ptr_to_member_type);
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000895 return DITypeRef(getExtraData());
Duncan P. N. Exon Smith0bf8d4c2015-04-13 23:36:36 +0000896 }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +0000897
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000898 DIObjCProperty *getObjCProperty() const {
899 return dyn_cast_or_null<DIObjCProperty>(getExtraData());
Duncan P. N. Exon Smith0bf8d4c2015-04-13 23:36:36 +0000900 }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +0000901
Brock Wyma3db2b102018-05-14 21:21:22 +0000902 uint32_t getVBPtrOffset() const {
903 assert(getTag() == dwarf::DW_TAG_inheritance);
904 if (auto *CM = cast_or_null<ConstantAsMetadata>(getExtraData()))
905 if (auto *CI = dyn_cast_or_null<ConstantInt>(CM->getValue()))
906 return static_cast<uint32_t>(CI->getZExtValue());
907 return 0;
908 }
909
David Majnemer9319cbc2016-06-30 03:00:20 +0000910 Constant *getStorageOffsetInBits() const {
911 assert(getTag() == dwarf::DW_TAG_member && isBitField());
912 if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData()))
913 return C->getValue();
914 return nullptr;
915 }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +0000916
Duncan P. N. Exon Smith0bf8d4c2015-04-13 23:36:36 +0000917 Constant *getConstant() 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 }
Adrian Prantl8c599212018-02-06 23:45:59 +0000923 Constant *getDiscriminantValue() const {
924 assert(getTag() == dwarf::DW_TAG_member && !isStaticMember());
925 if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData()))
926 return C->getValue();
927 return nullptr;
928 }
Duncan P. N. Exon Smith0bf8d4c2015-04-13 23:36:36 +0000929 /// @}
930
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000931 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000932 return MD->getMetadataID() == DIDerivedTypeKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000933 }
934};
935
Adrian Prantl1687e012016-11-14 22:09:18 +0000936/// Composite types.
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000937///
938/// TODO: Detach from DerivedTypeBase (split out MDEnumType?).
939/// TODO: Create a custom, unrelated node for DW_TAG_array_type.
Duncan P. N. Exon Smithb9e045a2015-07-24 20:56:36 +0000940class DICompositeType : public DIType {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000941 friend class LLVMContextImpl;
942 friend class MDNode;
943
Duncan P. N. Exon Smithb9e045a2015-07-24 20:56:36 +0000944 unsigned RuntimeLang;
945
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000946 DICompositeType(LLVMContext &C, StorageType Storage, unsigned Tag,
Duncan P. N. Exon Smithd34db172015-02-19 23:56:07 +0000947 unsigned Line, unsigned RuntimeLang, uint64_t SizeInBits,
Victor Leschuk197aa312016-10-18 14:31:22 +0000948 uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000949 ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smithb9e045a2015-07-24 20:56:36 +0000950 : DIType(C, DICompositeTypeKind, Storage, Tag, Line, SizeInBits,
951 AlignInBits, OffsetInBits, Flags, Ops),
952 RuntimeLang(RuntimeLang) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000953 ~DICompositeType() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000954
Duncan P. N. Exon Smith97386022016-04-19 18:00:19 +0000955 /// Change fields in place.
956 void mutate(unsigned Tag, unsigned Line, unsigned RuntimeLang,
Victor Leschuk197aa312016-10-18 14:31:22 +0000957 uint64_t SizeInBits, uint32_t AlignInBits,
958 uint64_t OffsetInBits, DIFlags Flags) {
Duncan P. N. Exon Smith97386022016-04-19 18:00:19 +0000959 assert(isDistinct() && "Only distinct nodes can mutate");
960 assert(getRawIdentifier() && "Only ODR-uniqued nodes should mutate");
961 this->RuntimeLang = RuntimeLang;
962 DIType::mutate(Tag, Line, SizeInBits, AlignInBits, OffsetInBits, Flags);
963 }
964
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000965 static DICompositeType *
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000966 getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, Metadata *File,
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000967 unsigned Line, DIScopeRef Scope, DITypeRef BaseType,
Victor Leschuk197aa312016-10-18 14:31:22 +0000968 uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000969 DIFlags Flags, DINodeArray Elements, unsigned RuntimeLang,
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000970 DITypeRef VTableHolder, DITemplateParameterArray TemplateParams,
Adrian Prantl8c599212018-02-06 23:45:59 +0000971 StringRef Identifier, DIDerivedType *Discriminator,
972 StorageType Storage, bool ShouldCreate = true) {
Duncan P. N. Exon Smith11344732015-04-07 16:50:39 +0000973 return getImpl(
974 Context, Tag, getCanonicalMDString(Context, Name), File, Line, Scope,
975 BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements.get(),
976 RuntimeLang, VTableHolder, TemplateParams.get(),
Adrian Prantl8c599212018-02-06 23:45:59 +0000977 getCanonicalMDString(Context, Identifier), Discriminator, Storage, ShouldCreate);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000978 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000979 static DICompositeType *
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000980 getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
981 unsigned Line, Metadata *Scope, Metadata *BaseType,
Victor Leschuk197aa312016-10-18 14:31:22 +0000982 uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
Leny Kholodov5fcc4182016-09-06 10:46:28 +0000983 DIFlags Flags, Metadata *Elements, unsigned RuntimeLang,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000984 Metadata *VTableHolder, Metadata *TemplateParams,
Adrian Prantl8c599212018-02-06 23:45:59 +0000985 MDString *Identifier, Metadata *Discriminator,
986 StorageType Storage, bool ShouldCreate = true);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000987
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000988 TempDICompositeType cloneImpl() const {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000989 return getTemporary(getContext(), getTag(), getName(), getFile(), getLine(),
990 getScope(), getBaseType(), getSizeInBits(),
991 getAlignInBits(), getOffsetInBits(), getFlags(),
992 getElements(), getRuntimeLang(), getVTableHolder(),
Adrian Prantl8c599212018-02-06 23:45:59 +0000993 getTemplateParams(), getIdentifier(), getDiscriminator());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +0000994 }
995
996public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +0000997 DEFINE_MDNODE_GET(DICompositeType,
998 (unsigned Tag, StringRef Name, DIFile *File, unsigned Line,
999 DIScopeRef Scope, DITypeRef BaseType, uint64_t SizeInBits,
Victor Leschuk197aa312016-10-18 14:31:22 +00001000 uint32_t AlignInBits, uint64_t OffsetInBits,
1001 DIFlags Flags, DINodeArray Elements, unsigned RuntimeLang,
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001002 DITypeRef VTableHolder,
1003 DITemplateParameterArray TemplateParams = nullptr,
Adrian Prantl8c599212018-02-06 23:45:59 +00001004 StringRef Identifier = "", DIDerivedType *Discriminator = nullptr),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001005 (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
1006 AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
Adrian Prantl8c599212018-02-06 23:45:59 +00001007 VTableHolder, TemplateParams, Identifier, Discriminator))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001008 DEFINE_MDNODE_GET(DICompositeType,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001009 (unsigned Tag, MDString *Name, Metadata *File,
1010 unsigned Line, Metadata *Scope, Metadata *BaseType,
Victor Leschuk197aa312016-10-18 14:31:22 +00001011 uint64_t SizeInBits, uint32_t AlignInBits,
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001012 uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001013 unsigned RuntimeLang, Metadata *VTableHolder,
1014 Metadata *TemplateParams = nullptr,
Adrian Prantl8c599212018-02-06 23:45:59 +00001015 MDString *Identifier = nullptr,
1016 Metadata *Discriminator = nullptr),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001017 (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
1018 AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
Adrian Prantl8c599212018-02-06 23:45:59 +00001019 VTableHolder, TemplateParams, Identifier, Discriminator))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001020
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001021 TempDICompositeType clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001022
Duncan P. N. Exon Smith0b0271e2016-04-19 14:55:09 +00001023 /// Get a DICompositeType with the given ODR identifier.
1024 ///
1025 /// If \a LLVMContext::isODRUniquingDebugTypes(), gets the mapped
1026 /// DICompositeType for the given ODR \c Identifier. If none exists, creates
1027 /// a new node.
1028 ///
1029 /// Else, returns \c nullptr.
1030 static DICompositeType *
1031 getODRType(LLVMContext &Context, MDString &Identifier, unsigned Tag,
1032 MDString *Name, Metadata *File, unsigned Line, Metadata *Scope,
Victor Leschuk197aa312016-10-18 14:31:22 +00001033 Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits,
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001034 uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements,
Duncan P. N. Exon Smith0b0271e2016-04-19 14:55:09 +00001035 unsigned RuntimeLang, Metadata *VTableHolder,
Adrian Prantl8c599212018-02-06 23:45:59 +00001036 Metadata *TemplateParams, Metadata *Discriminator);
Duncan P. N. Exon Smith0b0271e2016-04-19 14:55:09 +00001037 static DICompositeType *getODRTypeIfExists(LLVMContext &Context,
1038 MDString &Identifier);
1039
Duncan P. N. Exon Smith97386022016-04-19 18:00:19 +00001040 /// Build a DICompositeType with the given ODR identifier.
1041 ///
1042 /// Looks up the mapped DICompositeType for the given ODR \c Identifier. If
1043 /// it doesn't exist, creates a new one. If it does exist and \a
1044 /// isForwardDecl(), and the new arguments would be a definition, mutates the
1045 /// the type in place. In either case, returns the type.
1046 ///
1047 /// If not \a LLVMContext::isODRUniquingDebugTypes(), this function returns
1048 /// nullptr.
1049 static DICompositeType *
1050 buildODRType(LLVMContext &Context, MDString &Identifier, unsigned Tag,
1051 MDString *Name, Metadata *File, unsigned Line, Metadata *Scope,
Victor Leschuk197aa312016-10-18 14:31:22 +00001052 Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits,
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001053 uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements,
Duncan P. N. Exon Smith97386022016-04-19 18:00:19 +00001054 unsigned RuntimeLang, Metadata *VTableHolder,
Adrian Prantl8c599212018-02-06 23:45:59 +00001055 Metadata *TemplateParams, Metadata *Discriminator);
Duncan P. N. Exon Smith97386022016-04-19 18:00:19 +00001056
Duncan P. N. Exon Smithb9e045a2015-07-24 20:56:36 +00001057 DITypeRef getBaseType() const { return DITypeRef(getRawBaseType()); }
1058 DINodeArray getElements() const {
1059 return cast_or_null<MDTuple>(getRawElements());
1060 }
1061 DITypeRef getVTableHolder() const { return DITypeRef(getRawVTableHolder()); }
1062 DITemplateParameterArray getTemplateParams() const {
1063 return cast_or_null<MDTuple>(getRawTemplateParams());
1064 }
1065 StringRef getIdentifier() const { return getStringOperand(7); }
1066 unsigned getRuntimeLang() const { return RuntimeLang; }
1067
1068 Metadata *getRawBaseType() const { return getOperand(3); }
1069 Metadata *getRawElements() const { return getOperand(4); }
1070 Metadata *getRawVTableHolder() const { return getOperand(5); }
1071 Metadata *getRawTemplateParams() const { return getOperand(6); }
1072 MDString *getRawIdentifier() const { return getOperandAs<MDString>(7); }
Adrian Prantl8c599212018-02-06 23:45:59 +00001073 Metadata *getRawDiscriminator() const { return getOperand(8); }
1074 DIDerivedType *getDiscriminator() const { return getOperandAs<DIDerivedType>(8); }
Duncan P. N. Exon Smithb9e045a2015-07-24 20:56:36 +00001075
Adrian Prantl1687e012016-11-14 22:09:18 +00001076 /// Replace operands.
Duncan P. N. Exon Smithb9e045a2015-07-24 20:56:36 +00001077 ///
1078 /// If this \a isUniqued() and not \a isResolved(), on a uniquing collision
1079 /// this will be RAUW'ed and deleted. Use a \a TrackingMDRef to keep track
1080 /// of its movement if necessary.
1081 /// @{
1082 void replaceElements(DINodeArray Elements) {
1083#ifndef NDEBUG
1084 for (DINode *Op : getElements())
David Majnemer42531262016-08-12 03:55:06 +00001085 assert(is_contained(Elements->operands(), Op) &&
Duncan P. N. Exon Smithb9e045a2015-07-24 20:56:36 +00001086 "Lost a member during member list replacement");
1087#endif
1088 replaceOperandWith(4, Elements.get());
1089 }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +00001090
Duncan P. N. Exon Smithb9e045a2015-07-24 20:56:36 +00001091 void replaceVTableHolder(DITypeRef VTableHolder) {
1092 replaceOperandWith(5, VTableHolder);
1093 }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +00001094
Duncan P. N. Exon Smithb9e045a2015-07-24 20:56:36 +00001095 void replaceTemplateParams(DITemplateParameterArray TemplateParams) {
1096 replaceOperandWith(6, TemplateParams.get());
1097 }
1098 /// @}
1099
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001100 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001101 return MD->getMetadataID() == DICompositeTypeKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001102 }
1103};
1104
Adrian Prantl1687e012016-11-14 22:09:18 +00001105/// Type array for a subprogram.
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001106///
Duncan P. N. Exon Smithb9e045a2015-07-24 20:56:36 +00001107/// TODO: Fold the array of types in directly as operands.
1108class DISubroutineType : public DIType {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001109 friend class LLVMContextImpl;
1110 friend class MDNode;
1111
Reid Klecknerde3d8b52016-06-08 20:34:29 +00001112 /// The calling convention used with DW_AT_calling_convention. Actually of
1113 /// type dwarf::CallingConvention.
1114 uint8_t CC;
1115
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001116 DISubroutineType(LLVMContext &C, StorageType Storage, DIFlags Flags,
Reid Klecknerde3d8b52016-06-08 20:34:29 +00001117 uint8_t CC, ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smithb9e045a2015-07-24 20:56:36 +00001118 : DIType(C, DISubroutineTypeKind, Storage, dwarf::DW_TAG_subroutine_type,
Reid Klecknerde3d8b52016-06-08 20:34:29 +00001119 0, 0, 0, 0, Flags, Ops),
1120 CC(CC) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001121 ~DISubroutineType() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +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, DITypeRefArray TypeArray,
Duncan P. N. Exon Smith11344732015-04-07 16:50:39 +00001125 StorageType Storage,
1126 bool ShouldCreate = true) {
Reid Klecknerde3d8b52016-06-08 20:34:29 +00001127 return getImpl(Context, Flags, CC, TypeArray.get(), Storage, ShouldCreate);
Duncan P. N. Exon Smith11344732015-04-07 16:50:39 +00001128 }
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001129 static DISubroutineType *getImpl(LLVMContext &Context, DIFlags Flags,
Reid Klecknerde3d8b52016-06-08 20:34:29 +00001130 uint8_t CC, Metadata *TypeArray,
1131 StorageType Storage,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001132 bool ShouldCreate = true);
1133
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001134 TempDISubroutineType cloneImpl() const {
Reid Klecknerde3d8b52016-06-08 20:34:29 +00001135 return getTemporary(getContext(), getFlags(), getCC(), getTypeArray());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001136 }
1137
1138public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001139 DEFINE_MDNODE_GET(DISubroutineType,
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001140 (DIFlags Flags, uint8_t CC, DITypeRefArray TypeArray),
Reid Klecknerde3d8b52016-06-08 20:34:29 +00001141 (Flags, CC, TypeArray))
1142 DEFINE_MDNODE_GET(DISubroutineType,
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001143 (DIFlags Flags, uint8_t CC, Metadata *TypeArray),
Reid Klecknerde3d8b52016-06-08 20:34:29 +00001144 (Flags, CC, TypeArray))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001145
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001146 TempDISubroutineType clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001147
Reid Klecknerde3d8b52016-06-08 20:34:29 +00001148 uint8_t getCC() const { return CC; }
1149
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001150 DITypeRefArray getTypeArray() const {
Duncan P. N. Exon Smith11344732015-04-07 16:50:39 +00001151 return cast_or_null<MDTuple>(getRawTypeArray());
1152 }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +00001153
Duncan P. N. Exon Smithb9e045a2015-07-24 20:56:36 +00001154 Metadata *getRawTypeArray() const { return getOperand(3); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001155
1156 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001157 return MD->getMetadataID() == DISubroutineTypeKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001158 }
1159};
1160
Adrian Prantl1687e012016-11-14 22:09:18 +00001161/// Compile unit.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001162class DICompileUnit : public DIScope {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001163 friend class LLVMContextImpl;
1164 friend class MDNode;
Eugene Zelenko1aa40f42016-11-23 22:25:16 +00001165
Adrian Prantlb939a252016-03-31 23:56:58 +00001166public:
1167 enum DebugEmissionKind : unsigned {
1168 NoDebug = 0,
1169 FullDebug,
1170 LineTablesOnly,
Alexey Bataevd4dd7212018-08-01 19:38:20 +00001171 DebugDirectivesOnly,
1172 LastEmissionKind = DebugDirectivesOnly
Adrian Prantlb939a252016-03-31 23:56:58 +00001173 };
Eugene Zelenko1aa40f42016-11-23 22:25:16 +00001174
David Blaikie66cf14d2018-08-16 21:29:55 +00001175 enum class DebugNameTableKind : unsigned {
1176 Default = 0,
1177 GNU = 1,
1178 None = 2,
1179 LastDebugNameTableKind = None
1180 };
1181
Adrian Prantlb939a252016-03-31 23:56:58 +00001182 static Optional<DebugEmissionKind> getEmissionKind(StringRef Str);
Fangrui Song3c1b5db2018-07-06 19:26:00 +00001183 static const char *emissionKindString(DebugEmissionKind EK);
David Blaikie66cf14d2018-08-16 21:29:55 +00001184 static Optional<DebugNameTableKind> getNameTableKind(StringRef Str);
1185 static const char *nameTableKindString(DebugNameTableKind PK);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001186
Adrian Prantlb939a252016-03-31 23:56:58 +00001187private:
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001188 unsigned SourceLanguage;
1189 bool IsOptimized;
1190 unsigned RuntimeVersion;
1191 unsigned EmissionKind;
Adrian Prantl1f599f92015-05-21 20:37:30 +00001192 uint64_t DWOId;
David Blaikiea01f2952016-08-24 18:29:49 +00001193 bool SplitDebugInlining;
Dehao Chen0944a8c2017-02-01 22:45:09 +00001194 bool DebugInfoForProfiling;
David Blaikie66cf14d2018-08-16 21:29:55 +00001195 unsigned NameTableKind;
David Blaikiebb279112018-11-13 20:08:10 +00001196 bool RangesBaseAddress;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001197
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001198 DICompileUnit(LLVMContext &C, StorageType Storage, unsigned SourceLanguage,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001199 bool IsOptimized, unsigned RuntimeVersion,
David Blaikiea01f2952016-08-24 18:29:49 +00001200 unsigned EmissionKind, uint64_t DWOId, bool SplitDebugInlining,
David Blaikie66cf14d2018-08-16 21:29:55 +00001201 bool DebugInfoForProfiling, unsigned NameTableKind,
David Blaikiebb279112018-11-13 20:08:10 +00001202 bool RangesBaseAddress, ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001203 : DIScope(C, DICompileUnitKind, Storage, dwarf::DW_TAG_compile_unit, Ops),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001204 SourceLanguage(SourceLanguage), IsOptimized(IsOptimized),
Adrian Prantl1f599f92015-05-21 20:37:30 +00001205 RuntimeVersion(RuntimeVersion), EmissionKind(EmissionKind),
Dehao Chen0944a8c2017-02-01 22:45:09 +00001206 DWOId(DWOId), SplitDebugInlining(SplitDebugInlining),
David Blaikie66cf14d2018-08-16 21:29:55 +00001207 DebugInfoForProfiling(DebugInfoForProfiling),
David Blaikiebb279112018-11-13 20:08:10 +00001208 NameTableKind(NameTableKind), RangesBaseAddress(RangesBaseAddress) {
Duncan P. N. Exon Smith55ca9642015-08-03 17:26:41 +00001209 assert(Storage != Uniqued);
1210 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001211 ~DICompileUnit() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001212
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001213 static DICompileUnit *
1214 getImpl(LLVMContext &Context, unsigned SourceLanguage, DIFile *File,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001215 StringRef Producer, bool IsOptimized, StringRef Flags,
1216 unsigned RuntimeVersion, StringRef SplitDebugFilename,
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001217 unsigned EmissionKind, DICompositeTypeArray EnumTypes,
Adrian Prantlbceaaa92016-12-20 02:09:43 +00001218 DIScopeArray RetainedTypes,
1219 DIGlobalVariableExpressionArray GlobalVariables,
Amjad Abouda9bcf162015-12-10 12:56:35 +00001220 DIImportedEntityArray ImportedEntities, DIMacroNodeArray Macros,
Dehao Chen0944a8c2017-02-01 22:45:09 +00001221 uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling,
David Blaikiebb279112018-11-13 20:08:10 +00001222 unsigned NameTableKind, bool RangesBaseAddress, StorageType Storage,
David Blaikie66cf14d2018-08-16 21:29:55 +00001223 bool ShouldCreate = true) {
David Blaikiebb279112018-11-13 20:08:10 +00001224 return getImpl(Context, SourceLanguage, File,
1225 getCanonicalMDString(Context, Producer), IsOptimized,
1226 getCanonicalMDString(Context, Flags), RuntimeVersion,
1227 getCanonicalMDString(Context, SplitDebugFilename),
1228 EmissionKind, EnumTypes.get(), RetainedTypes.get(),
1229 GlobalVariables.get(), ImportedEntities.get(), Macros.get(),
1230 DWOId, SplitDebugInlining, DebugInfoForProfiling,
1231 NameTableKind, RangesBaseAddress, Storage, ShouldCreate);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001232 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001233 static DICompileUnit *
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001234 getImpl(LLVMContext &Context, unsigned SourceLanguage, Metadata *File,
1235 MDString *Producer, bool IsOptimized, MDString *Flags,
1236 unsigned RuntimeVersion, MDString *SplitDebugFilename,
Adrian Prantl75819ae2016-04-15 15:57:41 +00001237 unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes,
Adrian Prantlb939a252016-03-31 23:56:58 +00001238 Metadata *GlobalVariables, Metadata *ImportedEntities,
David Blaikiea01f2952016-08-24 18:29:49 +00001239 Metadata *Macros, uint64_t DWOId, bool SplitDebugInlining,
David Blaikie66cf14d2018-08-16 21:29:55 +00001240 bool DebugInfoForProfiling, unsigned NameTableKind,
David Blaikiebb279112018-11-13 20:08:10 +00001241 bool RangesBaseAddress, StorageType Storage, bool ShouldCreate = true);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001242
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001243 TempDICompileUnit cloneImpl() const {
David Blaikiebb279112018-11-13 20:08:10 +00001244 return getTemporary(
1245 getContext(), getSourceLanguage(), getFile(), getProducer(),
1246 isOptimized(), getFlags(), getRuntimeVersion(), getSplitDebugFilename(),
1247 getEmissionKind(), getEnumTypes(), getRetainedTypes(),
1248 getGlobalVariables(), getImportedEntities(), getMacros(), DWOId,
1249 getSplitDebugInlining(), getDebugInfoForProfiling(), getNameTableKind(),
1250 getRangesBaseAddress());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001251 }
1252
Eugene Zelenko1aa40f42016-11-23 22:25:16 +00001253public:
Duncan P. N. Exon Smith55ca9642015-08-03 17:26:41 +00001254 static void get() = delete;
1255 static void getIfExists() = delete;
1256
Duncan P. N. Exon Smith55ca9642015-08-03 17:26:41 +00001257 DEFINE_MDNODE_GET_DISTINCT_TEMPORARY(
1258 DICompileUnit,
1259 (unsigned SourceLanguage, DIFile *File, StringRef Producer,
1260 bool IsOptimized, StringRef Flags, unsigned RuntimeVersion,
Adrian Prantlb939a252016-03-31 23:56:58 +00001261 StringRef SplitDebugFilename, DebugEmissionKind EmissionKind,
Adrian Prantl75819ae2016-04-15 15:57:41 +00001262 DICompositeTypeArray EnumTypes, DIScopeArray RetainedTypes,
Adrian Prantlbceaaa92016-12-20 02:09:43 +00001263 DIGlobalVariableExpressionArray GlobalVariables,
Amjad Abouda9bcf162015-12-10 12:56:35 +00001264 DIImportedEntityArray ImportedEntities, DIMacroNodeArray Macros,
Peter Collingbourneb52e2362017-09-12 21:50:41 +00001265 uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling,
David Blaikiebb279112018-11-13 20:08:10 +00001266 DebugNameTableKind NameTableKind, bool RangesBaseAddress),
Duncan P. N. Exon Smith55ca9642015-08-03 17:26:41 +00001267 (SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion,
Adrian Prantl75819ae2016-04-15 15:57:41 +00001268 SplitDebugFilename, EmissionKind, EnumTypes, RetainedTypes,
Dehao Chen0944a8c2017-02-01 22:45:09 +00001269 GlobalVariables, ImportedEntities, Macros, DWOId, SplitDebugInlining,
David Blaikiebb279112018-11-13 20:08:10 +00001270 DebugInfoForProfiling, (unsigned)NameTableKind, RangesBaseAddress))
Duncan P. N. Exon Smith55ca9642015-08-03 17:26:41 +00001271 DEFINE_MDNODE_GET_DISTINCT_TEMPORARY(
Adrian Prantl1f599f92015-05-21 20:37:30 +00001272 DICompileUnit,
1273 (unsigned SourceLanguage, Metadata *File, MDString *Producer,
1274 bool IsOptimized, MDString *Flags, unsigned RuntimeVersion,
1275 MDString *SplitDebugFilename, unsigned EmissionKind, Metadata *EnumTypes,
Adrian Prantl75819ae2016-04-15 15:57:41 +00001276 Metadata *RetainedTypes, Metadata *GlobalVariables,
David Blaikiea01f2952016-08-24 18:29:49 +00001277 Metadata *ImportedEntities, Metadata *Macros, uint64_t DWOId,
David Blaikie66cf14d2018-08-16 21:29:55 +00001278 bool SplitDebugInlining, bool DebugInfoForProfiling,
David Blaikiebb279112018-11-13 20:08:10 +00001279 unsigned NameTableKind, bool RangesBaseAddress),
Adrian Prantl1f599f92015-05-21 20:37:30 +00001280 (SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion,
Adrian Prantl75819ae2016-04-15 15:57:41 +00001281 SplitDebugFilename, EmissionKind, EnumTypes, RetainedTypes,
Dehao Chen0944a8c2017-02-01 22:45:09 +00001282 GlobalVariables, ImportedEntities, Macros, DWOId, SplitDebugInlining,
David Blaikiebb279112018-11-13 20:08:10 +00001283 DebugInfoForProfiling, NameTableKind, RangesBaseAddress))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001284
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001285 TempDICompileUnit clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001286
1287 unsigned getSourceLanguage() const { return SourceLanguage; }
1288 bool isOptimized() const { return IsOptimized; }
1289 unsigned getRuntimeVersion() const { return RuntimeVersion; }
Adrian Prantlb939a252016-03-31 23:56:58 +00001290 DebugEmissionKind getEmissionKind() const {
1291 return (DebugEmissionKind)EmissionKind;
1292 }
Alexey Bataevd4dd7212018-08-01 19:38:20 +00001293 bool isDebugDirectivesOnly() const {
1294 return EmissionKind == DebugDirectivesOnly;
1295 }
Dehao Chen0944a8c2017-02-01 22:45:09 +00001296 bool getDebugInfoForProfiling() const { return DebugInfoForProfiling; }
David Blaikie66cf14d2018-08-16 21:29:55 +00001297 DebugNameTableKind getNameTableKind() const {
1298 return (DebugNameTableKind)NameTableKind;
1299 }
David Blaikiebb279112018-11-13 20:08:10 +00001300 bool getRangesBaseAddress() const {
1301 return RangesBaseAddress; }
1302 StringRef getProducer() const {
1303 return getStringOperand(1); }
1304 StringRef getFlags() const {
1305 return getStringOperand(2); }
1306 StringRef getSplitDebugFilename() const {
1307 return getStringOperand(3); }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001308 DICompositeTypeArray getEnumTypes() const {
Duncan P. N. Exon Smith53855f02015-03-27 23:05:04 +00001309 return cast_or_null<MDTuple>(getRawEnumTypes());
1310 }
Adrian Prantl75819ae2016-04-15 15:57:41 +00001311 DIScopeArray getRetainedTypes() const {
Duncan P. N. Exon Smith53855f02015-03-27 23:05:04 +00001312 return cast_or_null<MDTuple>(getRawRetainedTypes());
1313 }
Adrian Prantlbceaaa92016-12-20 02:09:43 +00001314 DIGlobalVariableExpressionArray getGlobalVariables() const {
Duncan P. N. Exon Smith53855f02015-03-27 23:05:04 +00001315 return cast_or_null<MDTuple>(getRawGlobalVariables());
1316 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001317 DIImportedEntityArray getImportedEntities() const {
Duncan P. N. Exon Smith53855f02015-03-27 23:05:04 +00001318 return cast_or_null<MDTuple>(getRawImportedEntities());
1319 }
Amjad Abouda9bcf162015-12-10 12:56:35 +00001320 DIMacroNodeArray getMacros() const {
1321 return cast_or_null<MDTuple>(getRawMacros());
1322 }
Adrian Prantlfbfc58e2015-09-22 23:21:03 +00001323 uint64_t getDWOId() const { return DWOId; }
Adrian Prantl44103922015-09-22 23:21:06 +00001324 void setDWOId(uint64_t DwoId) { DWOId = DwoId; }
David Blaikiea01f2952016-08-24 18:29:49 +00001325 bool getSplitDebugInlining() const { return SplitDebugInlining; }
1326 void setSplitDebugInlining(bool SplitDebugInlining) {
1327 this->SplitDebugInlining = SplitDebugInlining;
1328 }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001329
Duncan P. N. Exon Smithc1f1acc2015-02-13 01:25:10 +00001330 MDString *getRawProducer() const { return getOperandAs<MDString>(1); }
1331 MDString *getRawFlags() const { return getOperandAs<MDString>(2); }
1332 MDString *getRawSplitDebugFilename() const {
1333 return getOperandAs<MDString>(3);
1334 }
Duncan P. N. Exon Smith53855f02015-03-27 23:05:04 +00001335 Metadata *getRawEnumTypes() const { return getOperand(4); }
1336 Metadata *getRawRetainedTypes() const { return getOperand(5); }
Adrian Prantl75819ae2016-04-15 15:57:41 +00001337 Metadata *getRawGlobalVariables() const { return getOperand(6); }
1338 Metadata *getRawImportedEntities() const { return getOperand(7); }
1339 Metadata *getRawMacros() const { return getOperand(8); }
Duncan P. N. Exon Smithc1f1acc2015-02-13 01:25:10 +00001340
Adrian Prantl1687e012016-11-14 22:09:18 +00001341 /// Replace arrays.
Duncan P. N. Exon Smith94bbbf02015-02-18 20:36:09 +00001342 ///
1343 /// If this \a isUniqued() and not \a isResolved(), it will be RAUW'ed and
1344 /// deleted on a uniquing collision. In practice, uniquing collisions on \a
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001345 /// DICompileUnit should be fairly rare.
Duncan P. N. Exon Smith94bbbf02015-02-18 20:36:09 +00001346 /// @{
Adrian Prantl4afc1f42015-07-06 16:22:07 +00001347 void replaceEnumTypes(DICompositeTypeArray N) {
Adrian Prantl18c073a2015-07-02 22:32:52 +00001348 replaceOperandWith(4, N.get());
1349 }
Adrian Prantl4afc1f42015-07-06 16:22:07 +00001350 void replaceRetainedTypes(DITypeArray N) {
Adrian Prantl18c073a2015-07-02 22:32:52 +00001351 replaceOperandWith(5, N.get());
1352 }
Adrian Prantlbceaaa92016-12-20 02:09:43 +00001353 void replaceGlobalVariables(DIGlobalVariableExpressionArray N) {
Duncan P. N. Exon Smith11344732015-04-07 16:50:39 +00001354 replaceOperandWith(6, N.get());
1355 }
Adrian Prantl75819ae2016-04-15 15:57:41 +00001356 void replaceImportedEntities(DIImportedEntityArray N) {
Duncan P. N. Exon Smith11344732015-04-07 16:50:39 +00001357 replaceOperandWith(7, N.get());
1358 }
Adrian Prantl75819ae2016-04-15 15:57:41 +00001359 void replaceMacros(DIMacroNodeArray N) { replaceOperandWith(8, N.get()); }
Duncan P. N. Exon Smith94bbbf02015-02-18 20:36:09 +00001360 /// @}
1361
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001362 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001363 return MD->getMetadataID() == DICompileUnitKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001364 }
1365};
1366
Adrian Prantl1687e012016-11-14 22:09:18 +00001367/// A scope for locals.
Duncan P. N. Exon Smitha65159a2015-03-24 16:44:29 +00001368///
1369/// A legal scope for lexical blocks, local variables, and debug info
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001370/// locations. Subclasses are \a DISubprogram, \a DILexicalBlock, and \a
1371/// DILexicalBlockFile.
1372class DILocalScope : public DIScope {
Duncan P. N. Exon Smitha65159a2015-03-24 16:44:29 +00001373protected:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001374 DILocalScope(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
Duncan P. N. Exon Smitha65159a2015-03-24 16:44:29 +00001375 ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001376 : DIScope(C, ID, Storage, Tag, Ops) {}
1377 ~DILocalScope() = default;
Duncan P. N. Exon Smitha65159a2015-03-24 16:44:29 +00001378
1379public:
Adrian Prantl1687e012016-11-14 22:09:18 +00001380 /// Get the subprogram for this scope.
Duncan P. N. Exon Smithfd07a2a2015-03-30 21:32:28 +00001381 ///
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001382 /// Return this if it's an \a DISubprogram; otherwise, look up the scope
Duncan P. N. Exon Smithfd07a2a2015-03-30 21:32:28 +00001383 /// chain.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001384 DISubprogram *getSubprogram() const;
Duncan P. N. Exon Smithfd07a2a2015-03-30 21:32:28 +00001385
Amjad Abouda5ba9912016-04-21 16:58:49 +00001386 /// Get the first non DILexicalBlockFile scope of this scope.
1387 ///
1388 /// Return this if it's not a \a DILexicalBlockFIle; otherwise, look up the
1389 /// scope chain.
1390 DILocalScope *getNonLexicalBlockFileScope() const;
1391
Duncan P. N. Exon Smitha65159a2015-03-24 16:44:29 +00001392 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001393 return MD->getMetadataID() == DISubprogramKind ||
1394 MD->getMetadataID() == DILexicalBlockKind ||
1395 MD->getMetadataID() == DILexicalBlockFileKind;
Duncan P. N. Exon Smitha65159a2015-03-24 16:44:29 +00001396 }
1397};
1398
Adrian Prantl1687e012016-11-14 22:09:18 +00001399/// Debug location.
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001400///
1401/// A debug location in source code, used for debug info and otherwise.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001402class DILocation : public MDNode {
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001403 friend class LLVMContextImpl;
1404 friend class MDNode;
1405
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001406 DILocation(LLVMContext &C, StorageType Storage, unsigned Line,
Calixte Denizeteb7f6022018-09-20 08:53:06 +00001407 unsigned Column, ArrayRef<Metadata *> MDs, bool ImplicitCode);
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001408 ~DILocation() { dropAllReferences(); }
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001409
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001410 static DILocation *getImpl(LLVMContext &Context, unsigned Line,
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001411 unsigned Column, Metadata *Scope,
Calixte Denizeteb7f6022018-09-20 08:53:06 +00001412 Metadata *InlinedAt, bool ImplicitCode,
1413 StorageType Storage, bool ShouldCreate = true);
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001414 static DILocation *getImpl(LLVMContext &Context, unsigned Line,
1415 unsigned Column, DILocalScope *Scope,
Calixte Denizeteb7f6022018-09-20 08:53:06 +00001416 DILocation *InlinedAt, bool ImplicitCode,
1417 StorageType Storage, bool ShouldCreate = true) {
Duncan P. N. Exon Smith26489982015-03-26 22:05:04 +00001418 return getImpl(Context, Line, Column, static_cast<Metadata *>(Scope),
Calixte Denizeteb7f6022018-09-20 08:53:06 +00001419 static_cast<Metadata *>(InlinedAt), ImplicitCode, Storage,
1420 ShouldCreate);
Duncan P. N. Exon Smith26489982015-03-26 22:05:04 +00001421 }
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001422
Dehao Chen726da622017-02-15 17:54:39 +00001423 /// With a given unsigned int \p U, use up to 13 bits to represent it.
1424 /// old_bit 1~5 --> new_bit 1~5
1425 /// old_bit 6~12 --> new_bit 7~13
1426 /// new_bit_6 is 0 if higher bits (7~13) are all 0
1427 static unsigned getPrefixEncodingFromUnsigned(unsigned U) {
1428 U &= 0xfff;
1429 return U > 0x1f ? (((U & 0xfe0) << 1) | (U & 0x1f) | 0x20) : U;
1430 }
1431
1432 /// Reverse transformation as getPrefixEncodingFromUnsigned.
1433 static unsigned getUnsignedFromPrefixEncoding(unsigned U) {
Mircea Trofinb53eeb62018-12-21 22:48:50 +00001434 if (U & 1)
1435 return 0;
1436 U >>= 1;
Dehao Chen726da622017-02-15 17:54:39 +00001437 return (U & 0x20) ? (((U >> 1) & 0xfe0) | (U & 0x1f)) : (U & 0x1f);
1438 }
1439
1440 /// Returns the next component stored in discriminator.
1441 static unsigned getNextComponentInDiscriminator(unsigned D) {
1442 if ((D & 1) == 0)
1443 return D >> ((D & 0x40) ? 14 : 7);
1444 else
1445 return D >> 1;
1446 }
1447
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001448 TempDILocation cloneImpl() const {
Teresa Johnsond98152b62015-12-07 15:05:44 +00001449 // Get the raw scope/inlinedAt since it is possible to invoke this on
1450 // a DILocation containing temporary metadata.
1451 return getTemporary(getContext(), getLine(), getColumn(), getRawScope(),
Calixte Denizeteb7f6022018-09-20 08:53:06 +00001452 getRawInlinedAt(), isImplicitCode());
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001453 }
1454
Mircea Trofinb53eeb62018-12-21 22:48:50 +00001455 static unsigned encodeComponent(unsigned C) {
1456 return (C == 0) ? 1U : (getPrefixEncodingFromUnsigned(C) << 1);
1457 }
1458
1459 static unsigned encodingBits(unsigned C) {
1460 return (C == 0) ? 1 : (C > 0x1f ? 14 : 7);
1461 }
1462
Eugene Zelenko1aa40f42016-11-23 22:25:16 +00001463public:
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001464 // Disallow replacing operands.
1465 void replaceOperandWith(unsigned I, Metadata *New) = delete;
1466
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001467 DEFINE_MDNODE_GET(DILocation,
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001468 (unsigned Line, unsigned Column, Metadata *Scope,
Calixte Denizeteb7f6022018-09-20 08:53:06 +00001469 Metadata *InlinedAt = nullptr, bool ImplicitCode = false),
1470 (Line, Column, Scope, InlinedAt, ImplicitCode))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001471 DEFINE_MDNODE_GET(DILocation,
1472 (unsigned Line, unsigned Column, DILocalScope *Scope,
Calixte Denizeteb7f6022018-09-20 08:53:06 +00001473 DILocation *InlinedAt = nullptr,
1474 bool ImplicitCode = false),
1475 (Line, Column, Scope, InlinedAt, ImplicitCode))
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001476
Adrian Prantl1687e012016-11-14 22:09:18 +00001477 /// Return a (temporary) clone of this.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001478 TempDILocation clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001479
1480 unsigned getLine() const { return SubclassData32; }
1481 unsigned getColumn() const { return SubclassData16; }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001482 DILocalScope *getScope() const { return cast<DILocalScope>(getRawScope()); }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +00001483
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001484 DILocation *getInlinedAt() const {
1485 return cast_or_null<DILocation>(getRawInlinedAt());
Duncan P. N. Exon Smith26489982015-03-26 22:05:04 +00001486 }
1487
Calixte Denizeteb7f6022018-09-20 08:53:06 +00001488 /// Check if the location corresponds to an implicit code.
1489 /// When the ImplicitCode flag is true, it means that the Instruction
1490 /// with this DILocation has been added by the front-end but it hasn't been
1491 /// written explicitly by the user (e.g. cleanup stuff in C++ put on a closing
1492 /// bracket). It's useful for code coverage to not show a counter on "empty"
1493 /// lines.
1494 bool isImplicitCode() const { return ImplicitCode; }
1495 void setImplicitCode(bool ImplicitCode) { this->ImplicitCode = ImplicitCode; }
1496
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001497 DIFile *getFile() const { return getScope()->getFile(); }
Duncan P. N. Exon Smith50c065b2015-04-11 00:39:43 +00001498 StringRef getFilename() const { return getScope()->getFilename(); }
1499 StringRef getDirectory() const { return getScope()->getDirectory(); }
Scott Linder16c7bda2018-02-23 23:01:06 +00001500 Optional<StringRef> getSource() const { return getScope()->getSource(); }
Duncan P. N. Exon Smith50c065b2015-04-11 00:39:43 +00001501
Adrian Prantl1687e012016-11-14 22:09:18 +00001502 /// Get the scope where this is inlined.
Duncan P. N. Exon Smith8f7bc792015-03-30 17:41:24 +00001503 ///
1504 /// Walk through \a getInlinedAt() and return \a getScope() from the deepest
1505 /// location.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001506 DILocalScope *getInlinedAtScope() const {
Duncan P. N. Exon Smith8f7bc792015-03-30 17:41:24 +00001507 if (auto *IA = getInlinedAt())
1508 return IA->getInlinedAtScope();
1509 return getScope();
1510 }
1511
Adrian Prantl1687e012016-11-14 22:09:18 +00001512 /// Get the DWARF discriminator.
Duncan P. N. Exon Smith2c8291e2015-04-14 00:05:13 +00001513 ///
1514 /// DWARF discriminators distinguish identical file locations between
1515 /// instructions that are on different basic blocks.
Dehao Chenfb02f712017-02-10 21:09:07 +00001516 ///
1517 /// There are 3 components stored in discriminator, from lower bits:
1518 ///
1519 /// Base discriminator: assigned by AddDiscriminators pass to identify IRs
1520 /// that are defined by the same source line, but
1521 /// different basic blocks.
1522 /// Duplication factor: assigned by optimizations that will scale down
1523 /// the execution frequency of the original IR.
1524 /// Copy Identifier: assigned by optimizations that clones the IR.
1525 /// Each copy of the IR will be assigned an identifier.
1526 ///
1527 /// Encoding:
1528 ///
1529 /// The above 3 components are encoded into a 32bit unsigned integer in
1530 /// order. If the lowest bit is 1, the current component is empty, and the
Hiroshi Inoue4cf7b882018-01-23 05:49:30 +00001531 /// next component will start in the next bit. Otherwise, the current
Dehao Chenfb02f712017-02-10 21:09:07 +00001532 /// component is non-empty, and its content starts in the next bit. The
Mircea Trofinb53eeb62018-12-21 22:48:50 +00001533 /// value of each components is either 5 bit or 12 bit: if the 7th bit
Dehao Chenfb02f712017-02-10 21:09:07 +00001534 /// is 0, the bit 2~6 (5 bits) are used to represent the component; if the
1535 /// 7th bit is 1, the bit 2~6 (5 bits) and 8~14 (7 bits) are combined to
Mircea Trofinb53eeb62018-12-21 22:48:50 +00001536 /// represent the component. Thus, the number of bits used for a component
1537 /// is either 0 (if it and all the next components are empty); 1 - if it is
1538 /// empty; 7 - if its value is up to and including 0x1f (lsb and msb are both
1539 /// 0); or 14, if its value is up to and including 0x1ff. Note that the last
1540 /// component is also capped at 0x1ff, even in the case when both first
1541 /// components are 0, and we'd technically have 29 bits available.
1542 ///
1543 /// For precise control over the data being encoded in the discriminator,
1544 /// use encodeDiscriminator/decodeDiscriminator.
Dehao Chenfb02f712017-02-10 21:09:07 +00001545
Duncan P. N. Exon Smith2c8291e2015-04-14 00:05:13 +00001546 inline unsigned getDiscriminator() const;
1547
Dehao Chene7130002016-10-26 15:48:45 +00001548 /// Returns a new DILocation with updated \p Discriminator.
Dehao Chenfb02f712017-02-10 21:09:07 +00001549 inline const DILocation *cloneWithDiscriminator(unsigned Discriminator) const;
1550
Mircea Trofinb53eeb62018-12-21 22:48:50 +00001551 /// Returns a new DILocation with updated base discriminator \p BD. Only the
1552 /// base discriminator is set in the new DILocation, the other encoded values
1553 /// are elided.
1554 /// If the discriminator cannot be encoded, the function returns None.
Mircea Trofinec026302019-01-24 00:10:25 +00001555 inline Optional<const DILocation *> cloneWithBaseDiscriminator(unsigned BD) const;
Dehao Chenfb02f712017-02-10 21:09:07 +00001556
Mircea Trofinb53eeb62018-12-21 22:48:50 +00001557 /// Returns the duplication factor stored in the discriminator, or 1 if no
1558 /// duplication factor (or 0) is encoded.
Dehao Chenfb02f712017-02-10 21:09:07 +00001559 inline unsigned getDuplicationFactor() const;
1560
1561 /// Returns the copy identifier stored in the discriminator.
1562 inline unsigned getCopyIdentifier() const;
1563
1564 /// Returns the base discriminator stored in the discriminator.
1565 inline unsigned getBaseDiscriminator() const;
1566
Mircea Trofinb53eeb62018-12-21 22:48:50 +00001567 /// Returns a new DILocation with duplication factor \p DF * current
1568 /// duplication factor encoded in the discriminator. The current duplication
1569 /// factor is as defined by getDuplicationFactor().
1570 /// Returns None if encoding failed.
Mircea Trofinec026302019-01-24 00:10:25 +00001571 inline Optional<const DILocation *> cloneByMultiplyingDuplicationFactor(unsigned DF) const;
Dehao Chene7130002016-10-26 15:48:45 +00001572
Robert Lougher7bd04e32016-12-14 16:14:17 +00001573 /// When two instructions are combined into a single instruction we also
1574 /// need to combine the original locations into a single location.
1575 ///
1576 /// When the locations are the same we can use either location. When they
Vedant Kumar65b0d4d2018-04-12 20:58:24 +00001577 /// differ, we need a third location which is distinct from either. If they
1578 /// have the same file/line but have a different discriminator we could
1579 /// create a location with a new discriminator. If they are from different
1580 /// files/lines the location is ambiguous and can't be represented in a line
1581 /// entry. In this case, if \p GenerateLocation is true, we will set the
1582 /// merged debug location as line 0 of the nearest common scope where the two
1583 /// locations are inlined from.
Robert Lougher7bd04e32016-12-14 16:14:17 +00001584 ///
Vedant Kumar65b0d4d2018-04-12 20:58:24 +00001585 /// \p GenerateLocation: Whether the merged location can be generated when
1586 /// \p LocA and \p LocB differ.
David Blaikie2a813ef2018-08-23 22:35:58 +00001587 static const DILocation *getMergedLocation(const DILocation *LocA,
1588 const DILocation *LocB);
Robert Lougher7bd04e32016-12-14 16:14:17 +00001589
Dehao Chen726da622017-02-15 17:54:39 +00001590 /// Returns the base discriminator for a given encoded discriminator \p D.
1591 static unsigned getBaseDiscriminatorFromDiscriminator(unsigned D) {
Mircea Trofinb53eeb62018-12-21 22:48:50 +00001592 return getUnsignedFromPrefixEncoding(D);
Dehao Chen726da622017-02-15 17:54:39 +00001593 }
1594
Mircea Trofinec026302019-01-24 00:10:25 +00001595 /// Raw encoding of the discriminator. APIs such as cloneWithDuplicationFactor
1596 /// have certain special case behavior (e.g. treating empty duplication factor
1597 /// as the value '1').
1598 /// This API, in conjunction with cloneWithDiscriminator, may be used to encode
1599 /// the raw values provided. \p BD: base discriminator \p DF: duplication factor
Mircea Trofinb53eeb62018-12-21 22:48:50 +00001600 /// \p CI: copy index
1601 /// The return is None if the values cannot be encoded in 32 bits - for
1602 /// example, values for BD or DF larger than 12 bits. Otherwise, the return
1603 /// is the encoded value.
1604 static Optional<unsigned> encodeDiscriminator(unsigned BD, unsigned DF, unsigned CI);
1605
1606 /// Raw decoder for values in an encoded discriminator D.
1607 static void decodeDiscriminator(unsigned D, unsigned &BD, unsigned &DF,
1608 unsigned &CI);
1609
1610 /// Returns the duplication factor for a given encoded discriminator \p D, or
1611 /// 1 if no value or 0 is encoded.
Dehao Chen726da622017-02-15 17:54:39 +00001612 static unsigned getDuplicationFactorFromDiscriminator(unsigned D) {
1613 D = getNextComponentInDiscriminator(D);
Mircea Trofinb53eeb62018-12-21 22:48:50 +00001614 unsigned Ret = getUnsignedFromPrefixEncoding(D);
1615 if (Ret == 0)
Dehao Chen726da622017-02-15 17:54:39 +00001616 return 1;
Mircea Trofinb53eeb62018-12-21 22:48:50 +00001617 return Ret;
Dehao Chen726da622017-02-15 17:54:39 +00001618 }
1619
1620 /// Returns the copy identifier for a given encoded discriminator \p D.
1621 static unsigned getCopyIdentifierFromDiscriminator(unsigned D) {
1622 return getUnsignedFromPrefixEncoding(getNextComponentInDiscriminator(
1623 getNextComponentInDiscriminator(D)));
1624 }
1625
1626
Duncan P. N. Exon Smith26489982015-03-26 22:05:04 +00001627 Metadata *getRawScope() const { return getOperand(0); }
1628 Metadata *getRawInlinedAt() const {
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001629 if (getNumOperands() == 2)
1630 return getOperand(1);
1631 return nullptr;
1632 }
1633
1634 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001635 return MD->getMetadataID() == DILocationKind;
Duncan P. N. Exon Smith7f9f7c82015-03-24 17:34:33 +00001636 }
1637};
1638
Adrian Prantl1687e012016-11-14 22:09:18 +00001639/// Subprogram description.
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001640///
1641/// TODO: Remove DisplayName. It's always equal to Name.
1642/// TODO: Split up flags.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001643class DISubprogram : public DILocalScope {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001644 friend class LLVMContextImpl;
1645 friend class MDNode;
1646
1647 unsigned Line;
1648 unsigned ScopeLine;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001649 unsigned VirtualIndex;
Davide Italiano236e7442016-04-13 20:17:42 +00001650
Reid Klecknerb5af11d2016-07-01 02:41:21 +00001651 /// In the MS ABI, the implicit 'this' parameter is adjusted in the prologue
1652 /// of method overrides from secondary bases by this amount. It may be
1653 /// negative.
1654 int ThisAdjustment;
1655
Paul Robinsoncda54212018-11-19 18:29:28 +00001656public:
1657 /// Debug info subprogram flags.
1658 enum DISPFlags : uint32_t {
1659#define HANDLE_DISP_FLAG(ID, NAME) SPFlag##NAME = ID,
1660#define DISP_FLAG_LARGEST_NEEDED
1661#include "llvm/IR/DebugInfoFlags.def"
Paul Robinsonadcdc1b2018-11-28 21:14:32 +00001662 SPFlagNonvirtual = SPFlagZero,
1663 SPFlagVirtuality = SPFlagVirtual | SPFlagPureVirtual,
Paul Robinsoncda54212018-11-19 18:29:28 +00001664 LLVM_MARK_AS_BITMASK_ENUM(SPFlagLargest)
1665 };
Paul Robinsonadcdc1b2018-11-28 21:14:32 +00001666
1667 static DISPFlags getFlag(StringRef Flag);
1668 static StringRef getFlagString(DISPFlags Flag);
1669
1670 /// Split up a flags bitfield for easier printing.
1671 ///
1672 /// Split \c Flags into \c SplitFlags, a vector of its components. Returns
1673 /// any remaining (unrecognized) bits.
1674 static DISPFlags splitFlags(DISPFlags Flags,
1675 SmallVectorImpl<DISPFlags> &SplitFlags);
1676
Paul Robinsoncda54212018-11-19 18:29:28 +00001677 // Helper for converting old bitfields to new flags word.
1678 static DISPFlags toSPFlags(bool IsLocalToUnit, bool IsDefinition,
1679 bool IsOptimized,
Petar Jovanovic38a61872019-03-19 13:49:03 +00001680 unsigned Virtuality = SPFlagNonvirtual,
1681 bool IsMainSubprogram = false) {
Paul Robinsoncda54212018-11-19 18:29:28 +00001682 // We're assuming virtuality is the low-order field.
Paul Robinsonfdaeb0c2018-11-19 18:51:11 +00001683 static_assert(
Simon Pilgrim0a1cb712018-11-19 18:54:34 +00001684 int(SPFlagVirtual) == int(dwarf::DW_VIRTUALITY_virtual) &&
Paul Robinsonfdaeb0c2018-11-19 18:51:11 +00001685 int(SPFlagPureVirtual) == int(dwarf::DW_VIRTUALITY_pure_virtual),
1686 "Virtuality constant mismatch");
Roman Lebedevf2848032018-11-19 19:07:03 +00001687 return static_cast<DISPFlags>(
1688 (Virtuality & SPFlagVirtuality) |
1689 (IsLocalToUnit ? SPFlagLocalToUnit : SPFlagZero) |
1690 (IsDefinition ? SPFlagDefinition : SPFlagZero) |
Petar Jovanovic38a61872019-03-19 13:49:03 +00001691 (IsOptimized ? SPFlagOptimized : SPFlagZero) |
1692 (IsMainSubprogram ? SPFlagMainSubprogram : SPFlagZero));
Paul Robinsoncda54212018-11-19 18:29:28 +00001693 }
Davide Italiano236e7442016-04-13 20:17:42 +00001694
Paul Robinsoncda54212018-11-19 18:29:28 +00001695private:
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001696 DIFlags Flags;
Paul Robinsoncda54212018-11-19 18:29:28 +00001697 DISPFlags SPFlags;
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001698
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001699 DISubprogram(LLVMContext &C, StorageType Storage, unsigned Line,
Paul Robinsoncda54212018-11-19 18:29:28 +00001700 unsigned ScopeLine, unsigned VirtualIndex, int ThisAdjustment,
1701 DIFlags Flags, DISPFlags SPFlags, ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001702 : DILocalScope(C, DISubprogramKind, Storage, dwarf::DW_TAG_subprogram,
Duncan P. N. Exon Smitha65159a2015-03-24 16:44:29 +00001703 Ops),
Davide Italiano236e7442016-04-13 20:17:42 +00001704 Line(Line), ScopeLine(ScopeLine), VirtualIndex(VirtualIndex),
Paul Robinsoncda54212018-11-19 18:29:28 +00001705 ThisAdjustment(ThisAdjustment), Flags(Flags), SPFlags(SPFlags) {
Davide Italiano236e7442016-04-13 20:17:42 +00001706 static_assert(dwarf::DW_VIRTUALITY_max < 4, "Virtuality out of range");
Davide Italiano236e7442016-04-13 20:17:42 +00001707 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001708 ~DISubprogram() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001709
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001710 static DISubprogram *
1711 getImpl(LLVMContext &Context, DIScopeRef Scope, StringRef Name,
1712 StringRef LinkageName, DIFile *File, unsigned Line,
Paul Robinsoncda54212018-11-19 18:29:28 +00001713 DISubroutineType *Type, unsigned ScopeLine, DITypeRef ContainingType,
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001714 unsigned VirtualIndex, int ThisAdjustment, DIFlags Flags,
Paul Robinsoncda54212018-11-19 18:29:28 +00001715 DISPFlags SPFlags, DICompileUnit *Unit,
Reid Klecknerb5af11d2016-07-01 02:41:21 +00001716 DITemplateParameterArray TemplateParams, DISubprogram *Declaration,
Shiva Chen2c864552018-05-09 02:40:45 +00001717 DINodeArray RetainedNodes, DITypeArray ThrownTypes,
Adrian Prantl1d12b882017-04-26 22:56:44 +00001718 StorageType Storage, bool ShouldCreate = true) {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001719 return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
1720 getCanonicalMDString(Context, LinkageName), File, Line, Type,
Paul Robinsoncda54212018-11-19 18:29:28 +00001721 ScopeLine, ContainingType, VirtualIndex, ThisAdjustment,
1722 Flags, SPFlags, Unit, TemplateParams.get(), Declaration,
1723 RetainedNodes.get(), ThrownTypes.get(), Storage,
1724 ShouldCreate);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001725 }
Paul Robinsoncda54212018-11-19 18:29:28 +00001726 static DISubprogram *getImpl(LLVMContext &Context, Metadata *Scope,
1727 MDString *Name, MDString *LinkageName,
1728 Metadata *File, unsigned Line, Metadata *Type,
1729 unsigned ScopeLine, Metadata *ContainingType,
1730 unsigned VirtualIndex, int ThisAdjustment,
1731 DIFlags Flags, DISPFlags SPFlags, Metadata *Unit,
1732 Metadata *TemplateParams, Metadata *Declaration,
1733 Metadata *RetainedNodes, Metadata *ThrownTypes,
1734 StorageType Storage, bool ShouldCreate = true);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001735
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001736 TempDISubprogram cloneImpl() const {
Adrian Prantl1d12b882017-04-26 22:56:44 +00001737 return getTemporary(getContext(), getScope(), getName(), getLinkageName(),
Paul Robinsoncda54212018-11-19 18:29:28 +00001738 getFile(), getLine(), getType(), getScopeLine(),
1739 getContainingType(), getVirtualIndex(),
1740 getThisAdjustment(), getFlags(), getSPFlags(),
1741 getUnit(), getTemplateParams(), getDeclaration(),
1742 getRetainedNodes(), getThrownTypes());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001743 }
1744
1745public:
Paul Robinsoncda54212018-11-19 18:29:28 +00001746 DEFINE_MDNODE_GET(
1747 DISubprogram,
1748 (DIScopeRef Scope, StringRef Name, StringRef LinkageName, DIFile *File,
1749 unsigned Line, DISubroutineType *Type, unsigned ScopeLine,
1750 DITypeRef ContainingType, unsigned VirtualIndex, int ThisAdjustment,
1751 DIFlags Flags, DISPFlags SPFlags, DICompileUnit *Unit,
1752 DITemplateParameterArray TemplateParams = nullptr,
1753 DISubprogram *Declaration = nullptr, DINodeArray RetainedNodes = nullptr,
1754 DITypeArray ThrownTypes = nullptr),
1755 (Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType,
1756 VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams,
1757 Declaration, RetainedNodes, ThrownTypes))
1758
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001759 DEFINE_MDNODE_GET(
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001760 DISubprogram,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001761 (Metadata * Scope, MDString *Name, MDString *LinkageName, Metadata *File,
Paul Robinsoncda54212018-11-19 18:29:28 +00001762 unsigned Line, Metadata *Type, unsigned ScopeLine,
1763 Metadata *ContainingType, unsigned VirtualIndex, int ThisAdjustment,
1764 DIFlags Flags, DISPFlags SPFlags, Metadata *Unit,
1765 Metadata *TemplateParams = nullptr, Metadata *Declaration = nullptr,
1766 Metadata *RetainedNodes = nullptr, Metadata *ThrownTypes = nullptr),
1767 (Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType,
1768 VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams,
1769 Declaration, RetainedNodes, ThrownTypes))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001770
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001771 TempDISubprogram clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001772
Roman Tereshincf88ffa2018-06-01 23:15:09 +00001773 /// Returns a new temporary DISubprogram with updated Flags
1774 TempDISubprogram cloneWithFlags(DIFlags NewFlags) const {
1775 auto NewSP = clone();
1776 NewSP->Flags = NewFlags;
1777 return NewSP;
1778 }
1779
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001780public:
1781 unsigned getLine() const { return Line; }
Paul Robinsoncda54212018-11-19 18:29:28 +00001782 unsigned getVirtuality() const { return getSPFlags() & SPFlagVirtuality; }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001783 unsigned getVirtualIndex() const { return VirtualIndex; }
Reid Klecknerb5af11d2016-07-01 02:41:21 +00001784 int getThisAdjustment() const { return ThisAdjustment; }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001785 unsigned getScopeLine() const { return ScopeLine; }
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001786 DIFlags getFlags() const { return Flags; }
Paul Robinsoncda54212018-11-19 18:29:28 +00001787 DISPFlags getSPFlags() const { return SPFlags; }
1788 bool isLocalToUnit() const { return getSPFlags() & SPFlagLocalToUnit; }
1789 bool isDefinition() const { return getSPFlags() & SPFlagDefinition; }
1790 bool isOptimized() const { return getSPFlags() & SPFlagOptimized; }
Petar Jovanovic38a61872019-03-19 13:49:03 +00001791 bool isMainSubprogram() const { return getSPFlags() & SPFlagMainSubprogram; }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001792
Leny Kholodov5fcc4182016-09-06 10:46:28 +00001793 bool isArtificial() const { return getFlags() & FlagArtificial; }
Duncan P. N. Exon Smitha1384912015-04-07 03:33:57 +00001794 bool isPrivate() const {
1795 return (getFlags() & FlagAccessibility) == FlagPrivate;
1796 }
1797 bool isProtected() const {
1798 return (getFlags() & FlagAccessibility) == FlagProtected;
1799 }
1800 bool isPublic() const {
1801 return (getFlags() & FlagAccessibility) == FlagPublic;
1802 }
1803 bool isExplicit() const { return getFlags() & FlagExplicit; }
1804 bool isPrototyped() const { return getFlags() & FlagPrototyped; }
Vedant Kumar5931b4e2018-10-05 20:37:17 +00001805 bool areAllCallsDescribed() const {
1806 return getFlags() & FlagAllCallsDescribed;
1807 }
Adrian Prantle69917f2019-03-14 16:29:54 +00001808 bool isPure() const { return getSPFlags() & SPFlagPure; }
1809 bool isElemental() const { return getSPFlags() & SPFlagElemental; }
1810 bool isRecursive() const { return getSPFlags() & SPFlagRecursive; }
Duncan P. N. Exon Smitha1384912015-04-07 03:33:57 +00001811
Adrian Prantl1687e012016-11-14 22:09:18 +00001812 /// Check if this is reference-qualified.
Duncan P. N. Exon Smitha1384912015-04-07 03:33:57 +00001813 ///
1814 /// Return true if this subprogram is a C++11 reference-qualified non-static
1815 /// member function (void foo() &).
Leny Kholodov40c62352016-09-06 17:03:02 +00001816 bool isLValueReference() const { return getFlags() & FlagLValueReference; }
Duncan P. N. Exon Smitha1384912015-04-07 03:33:57 +00001817
Adrian Prantl1687e012016-11-14 22:09:18 +00001818 /// Check if this is rvalue-reference-qualified.
Duncan P. N. Exon Smitha1384912015-04-07 03:33:57 +00001819 ///
1820 /// Return true if this subprogram is a C++11 rvalue-reference-qualified
1821 /// non-static member function (void foo() &&).
Leny Kholodov40c62352016-09-06 17:03:02 +00001822 bool isRValueReference() const { return getFlags() & FlagRValueReference; }
Duncan P. N. Exon Smitha1384912015-04-07 03:33:57 +00001823
Adrian Prantl1687e012016-11-14 22:09:18 +00001824 /// Check if this is marked as noreturn.
Adrian Prantlc19dee72016-08-17 16:02:43 +00001825 ///
1826 /// Return true if this subprogram is C++11 noreturn or C11 _Noreturn
Leny Kholodov40c62352016-09-06 17:03:02 +00001827 bool isNoReturn() const { return getFlags() & FlagNoReturn; }
Adrian Prantlc19dee72016-08-17 16:02:43 +00001828
Brock Wyma94ece8f2018-04-16 16:53:57 +00001829 // Check if this routine is a compiler-generated thunk.
1830 //
1831 // Returns true if this subprogram is a thunk generated by the compiler.
1832 bool isThunk() const { return getFlags() & FlagThunk; }
1833
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001834 DIScopeRef getScope() const { return DIScopeRef(getRawScope()); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001835
1836 StringRef getName() const { return getStringOperand(2); }
Adrian Prantl9d2f0192017-04-26 23:59:52 +00001837 StringRef getLinkageName() const { return getStringOperand(3); }
Duncan P. N. Exon Smith19fc5ed2015-02-13 01:26:47 +00001838
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001839 DISubroutineType *getType() const {
1840 return cast_or_null<DISubroutineType>(getRawType());
Duncan P. N. Exon Smith869db502015-03-30 16:19:15 +00001841 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001842 DITypeRef getContainingType() const {
1843 return DITypeRef(getRawContainingType());
Duncan P. N. Exon Smith3ec5fa62015-04-06 19:03:45 +00001844 }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001845
Adrian Prantl75819ae2016-04-15 15:57:41 +00001846 DICompileUnit *getUnit() const {
1847 return cast_or_null<DICompileUnit>(getRawUnit());
1848 }
Adrian Prantl9d2f0192017-04-26 23:59:52 +00001849 void replaceUnit(DICompileUnit *CU) { replaceOperandWith(5, CU); }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001850 DITemplateParameterArray getTemplateParams() const {
Duncan P. N. Exon Smith869db502015-03-30 16:19:15 +00001851 return cast_or_null<MDTuple>(getRawTemplateParams());
1852 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001853 DISubprogram *getDeclaration() const {
1854 return cast_or_null<DISubprogram>(getRawDeclaration());
Duncan P. N. Exon Smith869db502015-03-30 16:19:15 +00001855 }
Shiva Chen2c864552018-05-09 02:40:45 +00001856 DINodeArray getRetainedNodes() const {
1857 return cast_or_null<MDTuple>(getRawRetainedNodes());
Duncan P. N. Exon Smith869db502015-03-30 16:19:15 +00001858 }
Adrian Prantl1d12b882017-04-26 22:56:44 +00001859 DITypeArray getThrownTypes() const {
1860 return cast_or_null<MDTuple>(getRawThrownTypes());
1861 }
Duncan P. N. Exon Smith869db502015-03-30 16:19:15 +00001862
1863 Metadata *getRawScope() const { return getOperand(1); }
Adrian Prantl9d2f0192017-04-26 23:59:52 +00001864 MDString *getRawName() const { return getOperandAs<MDString>(2); }
1865 MDString *getRawLinkageName() const { return getOperandAs<MDString>(3); }
1866 Metadata *getRawType() const { return getOperand(4); }
1867 Metadata *getRawUnit() const { return getOperand(5); }
1868 Metadata *getRawDeclaration() const { return getOperand(6); }
Shiva Chen2c864552018-05-09 02:40:45 +00001869 Metadata *getRawRetainedNodes() const { return getOperand(7); }
Adrian Prantl9d2f0192017-04-26 23:59:52 +00001870 Metadata *getRawContainingType() const {
1871 return getNumOperands() > 8 ? getOperandAs<Metadata>(8) : nullptr;
1872 }
1873 Metadata *getRawTemplateParams() const {
1874 return getNumOperands() > 9 ? getOperandAs<Metadata>(9) : nullptr;
1875 }
1876 Metadata *getRawThrownTypes() const {
1877 return getNumOperands() > 10 ? getOperandAs<Metadata>(10) : nullptr;
1878 }
Duncan P. N. Exon Smithdf523492015-02-18 20:32:57 +00001879
Adrian Prantl1687e012016-11-14 22:09:18 +00001880 /// Check if this subprogram describes the given function.
Duncan P. N. Exon Smith3c2d7042015-04-13 19:07:27 +00001881 ///
1882 /// FIXME: Should this be looking through bitcasts?
1883 bool describes(const Function *F) const;
1884
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001885 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001886 return MD->getMetadataID() == DISubprogramKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001887 }
1888};
1889
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001890class DILexicalBlockBase : public DILocalScope {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001891protected:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001892 DILexicalBlockBase(LLVMContext &C, unsigned ID, StorageType Storage,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001893 ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001894 : DILocalScope(C, ID, Storage, dwarf::DW_TAG_lexical_block, Ops) {}
1895 ~DILexicalBlockBase() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001896
1897public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001898 DILocalScope *getScope() const { return cast<DILocalScope>(getRawScope()); }
Duncan P. N. Exon Smith0e202b92015-03-30 16:37:48 +00001899
1900 Metadata *getRawScope() const { return getOperand(1); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001901
1902 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001903 return MD->getMetadataID() == DILexicalBlockKind ||
1904 MD->getMetadataID() == DILexicalBlockFileKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001905 }
1906};
1907
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001908class DILexicalBlock : public DILexicalBlockBase {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001909 friend class LLVMContextImpl;
1910 friend class MDNode;
1911
1912 unsigned Line;
Duncan P. N. Exon Smithb09eb9f2015-08-28 22:58:50 +00001913 uint16_t Column;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001914
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001915 DILexicalBlock(LLVMContext &C, StorageType Storage, unsigned Line,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001916 unsigned Column, ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001917 : DILexicalBlockBase(C, DILexicalBlockKind, Storage, Ops), Line(Line),
Duncan P. N. Exon Smithb09eb9f2015-08-28 22:58:50 +00001918 Column(Column) {
1919 assert(Column < (1u << 16) && "Expected 16-bit column");
1920 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001921 ~DILexicalBlock() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001922
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001923 static DILexicalBlock *getImpl(LLVMContext &Context, DILocalScope *Scope,
1924 DIFile *File, unsigned Line, unsigned Column,
Duncan P. N. Exon Smith0e202b92015-03-30 16:37:48 +00001925 StorageType Storage,
1926 bool ShouldCreate = true) {
1927 return getImpl(Context, static_cast<Metadata *>(Scope),
1928 static_cast<Metadata *>(File), Line, Column, Storage,
1929 ShouldCreate);
1930 }
1931
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001932 static DILexicalBlock *getImpl(LLVMContext &Context, Metadata *Scope,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001933 Metadata *File, unsigned Line, unsigned Column,
1934 StorageType Storage, bool ShouldCreate = true);
1935
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001936 TempDILexicalBlock cloneImpl() const {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001937 return getTemporary(getContext(), getScope(), getFile(), getLine(),
1938 getColumn());
1939 }
1940
1941public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001942 DEFINE_MDNODE_GET(DILexicalBlock, (DILocalScope * Scope, DIFile *File,
Duncan P. N. Exon Smith0e202b92015-03-30 16:37:48 +00001943 unsigned Line, unsigned Column),
1944 (Scope, File, Line, Column))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001945 DEFINE_MDNODE_GET(DILexicalBlock, (Metadata * Scope, Metadata *File,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001946 unsigned Line, unsigned Column),
1947 (Scope, File, Line, Column))
1948
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001949 TempDILexicalBlock clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001950
1951 unsigned getLine() const { return Line; }
1952 unsigned getColumn() const { return Column; }
1953
1954 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001955 return MD->getMetadataID() == DILexicalBlockKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001956 }
1957};
1958
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001959class DILexicalBlockFile : public DILexicalBlockBase {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001960 friend class LLVMContextImpl;
1961 friend class MDNode;
1962
1963 unsigned Discriminator;
1964
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001965 DILexicalBlockFile(LLVMContext &C, StorageType Storage,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001966 unsigned Discriminator, ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001967 : DILexicalBlockBase(C, DILexicalBlockFileKind, Storage, Ops),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001968 Discriminator(Discriminator) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001969 ~DILexicalBlockFile() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001970
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001971 static DILexicalBlockFile *getImpl(LLVMContext &Context, DILocalScope *Scope,
1972 DIFile *File, unsigned Discriminator,
Duncan P. N. Exon Smith0e202b92015-03-30 16:37:48 +00001973 StorageType Storage,
1974 bool ShouldCreate = true) {
1975 return getImpl(Context, static_cast<Metadata *>(Scope),
1976 static_cast<Metadata *>(File), Discriminator, Storage,
1977 ShouldCreate);
1978 }
1979
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001980 static DILexicalBlockFile *getImpl(LLVMContext &Context, Metadata *Scope,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001981 Metadata *File, unsigned Discriminator,
1982 StorageType Storage,
1983 bool ShouldCreate = true);
1984
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001985 TempDILexicalBlockFile cloneImpl() const {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001986 return getTemporary(getContext(), getScope(), getFile(),
1987 getDiscriminator());
1988 }
1989
1990public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001991 DEFINE_MDNODE_GET(DILexicalBlockFile, (DILocalScope * Scope, DIFile *File,
Duncan P. N. Exon Smith0e202b92015-03-30 16:37:48 +00001992 unsigned Discriminator),
1993 (Scope, File, Discriminator))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001994 DEFINE_MDNODE_GET(DILexicalBlockFile,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001995 (Metadata * Scope, Metadata *File, unsigned Discriminator),
1996 (Scope, File, Discriminator))
1997
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00001998 TempDILexicalBlockFile clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00001999
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002000 // TODO: Remove these once they're gone from DILexicalBlockBase.
Duncan P. N. Exon Smith5f88ba12015-04-14 02:50:07 +00002001 unsigned getLine() const = delete;
2002 unsigned getColumn() const = delete;
2003
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002004 unsigned getDiscriminator() const { return Discriminator; }
2005
2006 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002007 return MD->getMetadataID() == DILexicalBlockFileKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002008 }
2009};
2010
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002011unsigned DILocation::getDiscriminator() const {
2012 if (auto *F = dyn_cast<DILexicalBlockFile>(getScope()))
Duncan P. N. Exon Smith2c8291e2015-04-14 00:05:13 +00002013 return F->getDiscriminator();
2014 return 0;
2015}
2016
Dehao Chenfb02f712017-02-10 21:09:07 +00002017const DILocation *
2018DILocation::cloneWithDiscriminator(unsigned Discriminator) const {
Dehao Chene7130002016-10-26 15:48:45 +00002019 DIScope *Scope = getScope();
2020 // Skip all parent DILexicalBlockFile that already have a discriminator
2021 // assigned. We do not want to have nested DILexicalBlockFiles that have
2022 // mutliple discriminators because only the leaf DILexicalBlockFile's
2023 // dominator will be used.
2024 for (auto *LBF = dyn_cast<DILexicalBlockFile>(Scope);
2025 LBF && LBF->getDiscriminator() != 0;
2026 LBF = dyn_cast<DILexicalBlockFile>(Scope))
2027 Scope = LBF->getScope();
2028 DILexicalBlockFile *NewScope =
2029 DILexicalBlockFile::get(getContext(), Scope, getFile(), Discriminator);
2030 return DILocation::get(getContext(), getLine(), getColumn(), NewScope,
2031 getInlinedAt());
2032}
2033
Dehao Chenfb02f712017-02-10 21:09:07 +00002034unsigned DILocation::getBaseDiscriminator() const {
Dehao Chen726da622017-02-15 17:54:39 +00002035 return getBaseDiscriminatorFromDiscriminator(getDiscriminator());
Dehao Chenfb02f712017-02-10 21:09:07 +00002036}
2037
2038unsigned DILocation::getDuplicationFactor() const {
Dehao Chen726da622017-02-15 17:54:39 +00002039 return getDuplicationFactorFromDiscriminator(getDiscriminator());
Dehao Chenfb02f712017-02-10 21:09:07 +00002040}
2041
2042unsigned DILocation::getCopyIdentifier() const {
Dehao Chen726da622017-02-15 17:54:39 +00002043 return getCopyIdentifierFromDiscriminator(getDiscriminator());
Dehao Chenfb02f712017-02-10 21:09:07 +00002044}
2045
Mircea Trofinec026302019-01-24 00:10:25 +00002046Optional<const DILocation *> DILocation::cloneWithBaseDiscriminator(unsigned D) const {
2047 unsigned BD, DF, CI;
2048 decodeDiscriminator(getDiscriminator(), BD, DF, CI);
2049 if (D == BD)
Dehao Chenfb02f712017-02-10 21:09:07 +00002050 return this;
Mircea Trofinec026302019-01-24 00:10:25 +00002051 if (Optional<unsigned> Encoded = encodeDiscriminator(D, DF, CI))
2052 return cloneWithDiscriminator(*Encoded);
2053 return None;
Dehao Chenfb02f712017-02-10 21:09:07 +00002054}
2055
Mircea Trofinec026302019-01-24 00:10:25 +00002056Optional<const DILocation *> DILocation::cloneByMultiplyingDuplicationFactor(unsigned DF) const {
Dehao Chenfb02f712017-02-10 21:09:07 +00002057 DF *= getDuplicationFactor();
2058 if (DF <= 1)
2059 return this;
2060
2061 unsigned BD = getBaseDiscriminator();
Mircea Trofinb53eeb62018-12-21 22:48:50 +00002062 unsigned CI = getCopyIdentifier();
2063 if (Optional<unsigned> D = encodeDiscriminator(BD, DF, CI))
2064 return cloneWithDiscriminator(*D);
2065 return None;
Dehao Chenfb02f712017-02-10 21:09:07 +00002066}
2067
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002068class DINamespace : public DIScope {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002069 friend class LLVMContextImpl;
2070 friend class MDNode;
2071
Adrian Prantldbfda632016-11-03 19:42:02 +00002072 unsigned ExportSymbols : 1;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002073
Adrian Prantlfed4f392017-04-28 22:25:46 +00002074 DINamespace(LLVMContext &Context, StorageType Storage, bool ExportSymbols,
2075 ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002076 : DIScope(Context, DINamespaceKind, Storage, dwarf::DW_TAG_namespace,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002077 Ops),
Adrian Prantlfed4f392017-04-28 22:25:46 +00002078 ExportSymbols(ExportSymbols) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002079 ~DINamespace() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002080
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002081 static DINamespace *getImpl(LLVMContext &Context, DIScope *Scope,
Adrian Prantlfed4f392017-04-28 22:25:46 +00002082 StringRef Name, bool ExportSymbols,
2083 StorageType Storage, bool ShouldCreate = true) {
2084 return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
2085 ExportSymbols, Storage, ShouldCreate);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002086 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002087 static DINamespace *getImpl(LLVMContext &Context, Metadata *Scope,
Adrian Prantlfed4f392017-04-28 22:25:46 +00002088 MDString *Name, bool ExportSymbols,
2089 StorageType Storage, bool ShouldCreate = true);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002090
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002091 TempDINamespace cloneImpl() const {
Adrian Prantlfed4f392017-04-28 22:25:46 +00002092 return getTemporary(getContext(), getScope(), getName(),
2093 getExportSymbols());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002094 }
2095
2096public:
Adrian Prantldbfda632016-11-03 19:42:02 +00002097 DEFINE_MDNODE_GET(DINamespace,
Adrian Prantlfed4f392017-04-28 22:25:46 +00002098 (DIScope *Scope, StringRef Name, bool ExportSymbols),
2099 (Scope, Name, ExportSymbols))
2100 DEFINE_MDNODE_GET(DINamespace,
2101 (Metadata *Scope, MDString *Name, bool ExportSymbols),
2102 (Scope, Name, ExportSymbols))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002103
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002104 TempDINamespace clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002105
Adrian Prantldbfda632016-11-03 19:42:02 +00002106 bool getExportSymbols() const { return ExportSymbols; }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002107 DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002108 StringRef getName() const { return getStringOperand(2); }
2109
Duncan P. N. Exon Smithf9b47752015-03-30 17:21:38 +00002110 Metadata *getRawScope() const { return getOperand(1); }
Duncan P. N. Exon Smithe1460002015-02-13 01:32:09 +00002111 MDString *getRawName() const { return getOperandAs<MDString>(2); }
2112
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002113 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002114 return MD->getMetadataID() == DINamespaceKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002115 }
2116};
2117
Adrian Prantl1687e012016-11-14 22:09:18 +00002118/// A (clang) module that has been imported by the compile unit.
Adrian Prantlab1243f2015-06-29 23:03:47 +00002119///
2120class DIModule : public DIScope {
2121 friend class LLVMContextImpl;
2122 friend class MDNode;
2123
2124 DIModule(LLVMContext &Context, StorageType Storage, ArrayRef<Metadata *> Ops)
2125 : DIScope(Context, DIModuleKind, Storage, dwarf::DW_TAG_module, Ops) {}
Eugene Zelenko1aa40f42016-11-23 22:25:16 +00002126 ~DIModule() = default;
Adrian Prantlab1243f2015-06-29 23:03:47 +00002127
2128 static DIModule *getImpl(LLVMContext &Context, DIScope *Scope,
2129 StringRef Name, StringRef ConfigurationMacros,
2130 StringRef IncludePath, StringRef ISysRoot,
2131 StorageType Storage, bool ShouldCreate = true) {
2132 return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
2133 getCanonicalMDString(Context, ConfigurationMacros),
NAKAMURA Takumiff35c332015-07-06 00:48:17 +00002134 getCanonicalMDString(Context, IncludePath),
2135 getCanonicalMDString(Context, ISysRoot),
Adrian Prantlab1243f2015-06-29 23:03:47 +00002136 Storage, ShouldCreate);
2137 }
2138 static DIModule *getImpl(LLVMContext &Context, Metadata *Scope,
2139 MDString *Name, MDString *ConfigurationMacros,
NAKAMURA Takumiff35c332015-07-06 00:48:17 +00002140 MDString *IncludePath, MDString *ISysRoot,
2141 StorageType Storage, bool ShouldCreate = true);
Adrian Prantlab1243f2015-06-29 23:03:47 +00002142
2143 TempDIModule cloneImpl() const {
2144 return getTemporary(getContext(), getScope(), getName(),
2145 getConfigurationMacros(), getIncludePath(),
2146 getISysRoot());
2147 }
2148
2149public:
2150 DEFINE_MDNODE_GET(DIModule, (DIScope *Scope, StringRef Name,
NAKAMURA Takumiff35c332015-07-06 00:48:17 +00002151 StringRef ConfigurationMacros, StringRef IncludePath,
2152 StringRef ISysRoot),
Adrian Prantlab1243f2015-06-29 23:03:47 +00002153 (Scope, Name, ConfigurationMacros, IncludePath, ISysRoot))
2154 DEFINE_MDNODE_GET(DIModule,
2155 (Metadata *Scope, MDString *Name, MDString *ConfigurationMacros,
NAKAMURA Takumiff35c332015-07-06 00:48:17 +00002156 MDString *IncludePath, MDString *ISysRoot),
Adrian Prantlab1243f2015-06-29 23:03:47 +00002157 (Scope, Name, ConfigurationMacros, IncludePath, ISysRoot))
2158
2159 TempDIModule clone() const { return cloneImpl(); }
2160
2161 DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
2162 StringRef getName() const { return getStringOperand(1); }
2163 StringRef getConfigurationMacros() const { return getStringOperand(2); }
2164 StringRef getIncludePath() const { return getStringOperand(3); }
2165 StringRef getISysRoot() const { return getStringOperand(4); }
2166
2167 Metadata *getRawScope() const { return getOperand(0); }
2168 MDString *getRawName() const { return getOperandAs<MDString>(1); }
2169 MDString *getRawConfigurationMacros() const { return getOperandAs<MDString>(2); }
2170 MDString *getRawIncludePath() const { return getOperandAs<MDString>(3); }
2171 MDString *getRawISysRoot() const { return getOperandAs<MDString>(4); }
2172
2173 static bool classof(const Metadata *MD) {
2174 return MD->getMetadataID() == DIModuleKind;
2175 }
2176};
2177
Adrian Prantl1687e012016-11-14 22:09:18 +00002178/// Base class for template parameters.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002179class DITemplateParameter : public DINode {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002180protected:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002181 DITemplateParameter(LLVMContext &Context, unsigned ID, StorageType Storage,
Duncan P. N. Exon Smithbd33d372015-02-10 01:59:57 +00002182 unsigned Tag, ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002183 : DINode(Context, ID, Storage, Tag, Ops) {}
2184 ~DITemplateParameter() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002185
2186public:
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002187 StringRef getName() const { return getStringOperand(0); }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002188 DITypeRef getType() const { return DITypeRef(getRawType()); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002189
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002190 MDString *getRawName() const { return getOperandAs<MDString>(0); }
Duncan P. N. Exon Smith3ec5fa62015-04-06 19:03:45 +00002191 Metadata *getRawType() const { return getOperand(1); }
Duncan P. N. Exon Smith2847f382015-02-13 01:34:32 +00002192
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002193 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002194 return MD->getMetadataID() == DITemplateTypeParameterKind ||
2195 MD->getMetadataID() == DITemplateValueParameterKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002196 }
2197};
2198
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002199class DITemplateTypeParameter : public DITemplateParameter {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002200 friend class LLVMContextImpl;
2201 friend class MDNode;
2202
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002203 DITemplateTypeParameter(LLVMContext &Context, StorageType Storage,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002204 ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002205 : DITemplateParameter(Context, DITemplateTypeParameterKind, Storage,
Duncan P. N. Exon Smithbd33d372015-02-10 01:59:57 +00002206 dwarf::DW_TAG_template_type_parameter, Ops) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002207 ~DITemplateTypeParameter() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002208
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002209 static DITemplateTypeParameter *getImpl(LLVMContext &Context, StringRef Name,
2210 DITypeRef Type, StorageType Storage,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002211 bool ShouldCreate = true) {
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002212 return getImpl(Context, getCanonicalMDString(Context, Name), Type, Storage,
2213 ShouldCreate);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002214 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002215 static DITemplateTypeParameter *getImpl(LLVMContext &Context, MDString *Name,
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002216 Metadata *Type, StorageType Storage,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002217 bool ShouldCreate = true);
2218
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002219 TempDITemplateTypeParameter cloneImpl() const {
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002220 return getTemporary(getContext(), getName(), getType());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002221 }
2222
2223public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002224 DEFINE_MDNODE_GET(DITemplateTypeParameter, (StringRef Name, DITypeRef Type),
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002225 (Name, Type))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002226 DEFINE_MDNODE_GET(DITemplateTypeParameter, (MDString * Name, Metadata *Type),
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002227 (Name, Type))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002228
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002229 TempDITemplateTypeParameter clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002230
2231 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002232 return MD->getMetadataID() == DITemplateTypeParameterKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002233 }
2234};
2235
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002236class DITemplateValueParameter : public DITemplateParameter {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002237 friend class LLVMContextImpl;
2238 friend class MDNode;
2239
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002240 DITemplateValueParameter(LLVMContext &Context, StorageType Storage,
Duncan P. N. Exon Smithbd33d372015-02-10 01:59:57 +00002241 unsigned Tag, ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002242 : DITemplateParameter(Context, DITemplateValueParameterKind, Storage, Tag,
Duncan P. N. Exon Smithbd33d372015-02-10 01:59:57 +00002243 Ops) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002244 ~DITemplateValueParameter() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002245
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002246 static DITemplateValueParameter *getImpl(LLVMContext &Context, unsigned Tag,
2247 StringRef Name, DITypeRef Type,
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002248 Metadata *Value, StorageType Storage,
Duncan P. N. Exon Smithbd33d372015-02-10 01:59:57 +00002249 bool ShouldCreate = true) {
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002250 return getImpl(Context, Tag, getCanonicalMDString(Context, Name), Type,
2251 Value, Storage, ShouldCreate);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002252 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002253 static DITemplateValueParameter *getImpl(LLVMContext &Context, unsigned Tag,
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002254 MDString *Name, Metadata *Type,
2255 Metadata *Value, StorageType Storage,
Duncan P. N. Exon Smithbd33d372015-02-10 01:59:57 +00002256 bool ShouldCreate = true);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002257
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002258 TempDITemplateValueParameter cloneImpl() const {
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002259 return getTemporary(getContext(), getTag(), getName(), getType(),
2260 getValue());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002261 }
2262
2263public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002264 DEFINE_MDNODE_GET(DITemplateValueParameter, (unsigned Tag, StringRef Name,
2265 DITypeRef Type, Metadata *Value),
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002266 (Tag, Name, Type, Value))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002267 DEFINE_MDNODE_GET(DITemplateValueParameter, (unsigned Tag, MDString *Name,
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002268 Metadata *Type, Metadata *Value),
2269 (Tag, Name, Type, Value))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002270
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002271 TempDITemplateValueParameter clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith6873fea2015-02-17 23:10:13 +00002272
Duncan P. N. Exon Smith3d62bba2015-02-19 00:37:21 +00002273 Metadata *getValue() const { return getOperand(2); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002274
2275 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002276 return MD->getMetadataID() == DITemplateValueParameterKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002277 }
2278};
2279
Adrian Prantl1687e012016-11-14 22:09:18 +00002280/// Base class for variables.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002281class DIVariable : public DINode {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002282 unsigned Line;
Victor Leschuka37660c2016-10-26 21:32:29 +00002283 uint32_t AlignInBits;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002284
2285protected:
Duncan P. N. Exon Smithed013cd2015-07-31 18:58:39 +00002286 DIVariable(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Line,
Victor Leschuka37660c2016-10-26 21:32:29 +00002287 ArrayRef<Metadata *> Ops, uint32_t AlignInBits = 0)
Victor Leschuk2ede1262016-10-20 00:13:12 +00002288 : DINode(C, ID, Storage, dwarf::DW_TAG_variable, Ops), Line(Line),
NAKAMURA Takumi78029842017-02-19 06:51:46 +00002289 AlignInBits(AlignInBits) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002290 ~DIVariable() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002291
2292public:
2293 unsigned getLine() const { return Line; }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002294 DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002295 StringRef getName() const { return getStringOperand(1); }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002296 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
2297 DITypeRef getType() const { return DITypeRef(getRawType()); }
Victor Leschuk3c989982016-10-26 11:59:03 +00002298 uint32_t getAlignInBits() const { return AlignInBits; }
2299 uint32_t getAlignInBytes() const { return getAlignInBits() / CHAR_BIT; }
Adrian Prantl3e0e1d02017-11-28 00:57:51 +00002300 /// Determines the size of the variable's type.
2301 Optional<uint64_t> getSizeInBits() const;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002302
Vedant Kumar6379a622018-07-06 17:32:39 +00002303 /// Return the signedness of this variable's type, or None if this type is
2304 /// neither signed nor unsigned.
2305 Optional<DIBasicType::Signedness> getSignedness() const {
2306 if (auto *BT = dyn_cast<DIBasicType>(getType().resolve()))
2307 return BT->getSignedness();
2308 return None;
2309 }
2310
Duncan P. N. Exon Smith50c065b2015-04-11 00:39:43 +00002311 StringRef getFilename() const {
2312 if (auto *F = getFile())
2313 return F->getFilename();
2314 return "";
2315 }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +00002316
Duncan P. N. Exon Smith50c065b2015-04-11 00:39:43 +00002317 StringRef getDirectory() const {
2318 if (auto *F = getFile())
2319 return F->getDirectory();
2320 return "";
2321 }
2322
Scott Linder16c7bda2018-02-23 23:01:06 +00002323 Optional<StringRef> getSource() const {
2324 if (auto *F = getFile())
2325 return F->getSource();
2326 return None;
2327 }
2328
Duncan P. N. Exon Smith3d2afaa2015-03-27 17:29:58 +00002329 Metadata *getRawScope() const { return getOperand(0); }
Duncan P. N. Exon Smithc8f810a2015-02-13 01:35:40 +00002330 MDString *getRawName() const { return getOperandAs<MDString>(1); }
Duncan P. N. Exon Smith3d2afaa2015-03-27 17:29:58 +00002331 Metadata *getRawFile() const { return getOperand(2); }
2332 Metadata *getRawType() const { return getOperand(3); }
Duncan P. N. Exon Smithc8f810a2015-02-13 01:35:40 +00002333
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002334 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002335 return MD->getMetadataID() == DILocalVariableKind ||
2336 MD->getMetadataID() == DIGlobalVariableKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002337 }
2338};
2339
Adrian Prantl1687e012016-11-14 22:09:18 +00002340/// DWARF expression.
Peter Collingbourned4135bb2016-09-13 01:12:59 +00002341///
2342/// This is (almost) a DWARF expression that modifies the location of a
2343/// variable, or the location of a single piece of a variable, or (when using
2344/// DW_OP_stack_value) is the constant variable value.
2345///
Peter Collingbourned4135bb2016-09-13 01:12:59 +00002346/// TODO: Co-allocate the expression elements.
2347/// TODO: Separate from MDNode, or otherwise drop Distinct and Temporary
2348/// storage types.
2349class DIExpression : public MDNode {
2350 friend class LLVMContextImpl;
2351 friend class MDNode;
2352
2353 std::vector<uint64_t> Elements;
2354
2355 DIExpression(LLVMContext &C, StorageType Storage, ArrayRef<uint64_t> Elements)
2356 : MDNode(C, DIExpressionKind, Storage, None),
2357 Elements(Elements.begin(), Elements.end()) {}
2358 ~DIExpression() = default;
2359
2360 static DIExpression *getImpl(LLVMContext &Context,
2361 ArrayRef<uint64_t> Elements, StorageType Storage,
2362 bool ShouldCreate = true);
2363
2364 TempDIExpression cloneImpl() const {
2365 return getTemporary(getContext(), getElements());
2366 }
2367
2368public:
2369 DEFINE_MDNODE_GET(DIExpression, (ArrayRef<uint64_t> Elements), (Elements))
2370
2371 TempDIExpression clone() const { return cloneImpl(); }
2372
2373 ArrayRef<uint64_t> getElements() const { return Elements; }
2374
2375 unsigned getNumElements() const { return Elements.size(); }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +00002376
Peter Collingbourned4135bb2016-09-13 01:12:59 +00002377 uint64_t getElement(unsigned I) const {
2378 assert(I < Elements.size() && "Index out of range");
2379 return Elements[I];
2380 }
2381
Adrian Prantlbceaaa92016-12-20 02:09:43 +00002382 /// Determine whether this represents a standalone constant value.
2383 bool isConstant() const;
2384
Eugene Zelenkod761e2c2017-05-15 21:57:41 +00002385 using element_iterator = ArrayRef<uint64_t>::iterator;
2386
Peter Collingbourned4135bb2016-09-13 01:12:59 +00002387 element_iterator elements_begin() const { return getElements().begin(); }
2388 element_iterator elements_end() const { return getElements().end(); }
2389
2390 /// A lightweight wrapper around an expression operand.
2391 ///
2392 /// TODO: Store arguments directly and change \a DIExpression to store a
2393 /// range of these.
2394 class ExprOperand {
Adrian Prantl72845a52016-11-08 20:48:38 +00002395 const uint64_t *Op = nullptr;
Peter Collingbourned4135bb2016-09-13 01:12:59 +00002396
2397 public:
Adrian Prantl72845a52016-11-08 20:48:38 +00002398 ExprOperand() = default;
Peter Collingbourned4135bb2016-09-13 01:12:59 +00002399 explicit ExprOperand(const uint64_t *Op) : Op(Op) {}
2400
2401 const uint64_t *get() const { return Op; }
2402
2403 /// Get the operand code.
2404 uint64_t getOp() const { return *Op; }
2405
2406 /// Get an argument to the operand.
2407 ///
2408 /// Never returns the operand itself.
2409 uint64_t getArg(unsigned I) const { return Op[I + 1]; }
2410
2411 unsigned getNumArgs() const { return getSize() - 1; }
2412
2413 /// Return the size of the operand.
2414 ///
2415 /// Return the number of elements in the operand (1 + args).
2416 unsigned getSize() const;
Vedant Kumar6379a622018-07-06 17:32:39 +00002417
2418 /// Append the elements of this operand to \p V.
2419 void appendToVector(SmallVectorImpl<uint64_t> &V) const {
Vedant Kumar71c7c432018-07-06 21:06:21 +00002420 V.append(get(), get() + getSize());
Vedant Kumar6379a622018-07-06 17:32:39 +00002421 }
Peter Collingbourned4135bb2016-09-13 01:12:59 +00002422 };
2423
2424 /// An iterator for expression operands.
2425 class expr_op_iterator
2426 : public std::iterator<std::input_iterator_tag, ExprOperand> {
2427 ExprOperand Op;
2428
2429 public:
Adrian Prantl54286bd2016-11-02 16:12:20 +00002430 expr_op_iterator() = default;
Peter Collingbourned4135bb2016-09-13 01:12:59 +00002431 explicit expr_op_iterator(element_iterator I) : Op(I) {}
2432
2433 element_iterator getBase() const { return Op.get(); }
2434 const ExprOperand &operator*() const { return Op; }
2435 const ExprOperand *operator->() const { return &Op; }
2436
2437 expr_op_iterator &operator++() {
2438 increment();
2439 return *this;
2440 }
2441 expr_op_iterator operator++(int) {
2442 expr_op_iterator T(*this);
2443 increment();
2444 return T;
2445 }
2446
2447 /// Get the next iterator.
2448 ///
2449 /// \a std::next() doesn't work because this is technically an
2450 /// input_iterator, but it's a perfectly valid operation. This is an
2451 /// accessor to provide the same functionality.
2452 expr_op_iterator getNext() const { return ++expr_op_iterator(*this); }
2453
2454 bool operator==(const expr_op_iterator &X) const {
2455 return getBase() == X.getBase();
2456 }
2457 bool operator!=(const expr_op_iterator &X) const {
2458 return getBase() != X.getBase();
2459 }
2460
2461 private:
2462 void increment() { Op = ExprOperand(getBase() + Op.getSize()); }
2463 };
2464
2465 /// Visit the elements via ExprOperand wrappers.
2466 ///
2467 /// These range iterators visit elements through \a ExprOperand wrappers.
2468 /// This is not guaranteed to be a valid range unless \a isValid() gives \c
2469 /// true.
2470 ///
2471 /// \pre \a isValid() gives \c true.
2472 /// @{
2473 expr_op_iterator expr_op_begin() const {
2474 return expr_op_iterator(elements_begin());
2475 }
2476 expr_op_iterator expr_op_end() const {
2477 return expr_op_iterator(elements_end());
2478 }
Adrian Prantl6825fb62017-04-18 01:21:53 +00002479 iterator_range<expr_op_iterator> expr_ops() const {
2480 return {expr_op_begin(), expr_op_end()};
2481 }
Peter Collingbourned4135bb2016-09-13 01:12:59 +00002482 /// @}
2483
2484 bool isValid() const;
2485
2486 static bool classof(const Metadata *MD) {
2487 return MD->getMetadataID() == DIExpressionKind;
2488 }
2489
Adrian Prantl6825fb62017-04-18 01:21:53 +00002490 /// Return whether the first element a DW_OP_deref.
Peter Collingbourned4135bb2016-09-13 01:12:59 +00002491 bool startsWithDeref() const {
2492 return getNumElements() > 0 && getElement(0) == dwarf::DW_OP_deref;
2493 }
Adrian Prantl49797ca2016-12-22 05:27:12 +00002494
2495 /// Holds the characteristics of one fragment of a larger variable.
2496 struct FragmentInfo {
2497 uint64_t SizeInBits;
2498 uint64_t OffsetInBits;
2499 };
2500
2501 /// Retrieve the details of this fragment expression.
2502 static Optional<FragmentInfo> getFragmentInfo(expr_op_iterator Start,
NAKAMURA Takumi78029842017-02-19 06:51:46 +00002503 expr_op_iterator End);
Adrian Prantl49797ca2016-12-22 05:27:12 +00002504
2505 /// Retrieve the details of this fragment expression.
2506 Optional<FragmentInfo> getFragmentInfo() const {
2507 return getFragmentInfo(expr_op_begin(), expr_op_end());
2508 }
2509
2510 /// Return whether this is a piece of an aggregate variable.
2511 bool isFragment() const { return getFragmentInfo().hasValue(); }
Andrew Ng03e35b62017-04-28 08:44:30 +00002512
2513 /// Append \p Ops with operations to apply the \p Offset.
2514 static void appendOffset(SmallVectorImpl<uint64_t> &Ops, int64_t Offset);
2515
Reid Klecknerb5fced72017-05-09 19:59:29 +00002516 /// If this is a constant offset, extract it. If there is no expression,
2517 /// return true with an offset of zero.
2518 bool extractIfOffset(int64_t &Offset) const;
2519
Alexey Bataevf3a91502019-02-05 19:33:47 +00002520 /// Checks if the last 4 elements of the expression are DW_OP_constu <DWARF
2521 /// Address Space> DW_OP_swap DW_OP_xderef and extracts the <DWARF Address
2522 /// Space>.
2523 static const DIExpression *extractAddressClass(const DIExpression *Expr,
2524 unsigned &AddrClass);
2525
Adrian Prantl109b2362017-04-28 17:51:05 +00002526 /// Constants for DIExpression::prepend.
2527 enum { NoDeref = false, WithDeref = true, WithStackValue = true };
2528
Andrew Ng03e35b62017-04-28 08:44:30 +00002529 /// Prepend \p DIExpr with a deref and offset operation and optionally turn it
2530 /// into a stack value.
Fangrui Song3c1b5db2018-07-06 19:26:00 +00002531 static DIExpression *prepend(const DIExpression *Expr, bool DerefBefore,
Adrian Prantld1317012017-12-08 21:58:18 +00002532 int64_t Offset = 0, bool DerefAfter = false,
2533 bool StackValue = false);
Adrian Prantlb192b542017-08-30 20:04:17 +00002534
Vedant Kumar04386d82018-02-09 19:19:55 +00002535 /// Prepend \p DIExpr with the given opcodes and optionally turn it into a
2536 /// stack value.
Fangrui Song3c1b5db2018-07-06 19:26:00 +00002537 static DIExpression *prependOpcodes(const DIExpression *Expr,
Adrian Prantl210a29d2018-04-27 21:41:36 +00002538 SmallVectorImpl<uint64_t> &Ops,
2539 bool StackValue = false);
Vedant Kumar04386d82018-02-09 19:19:55 +00002540
Vedant Kumarb572f642018-07-26 20:56:53 +00002541 /// Append the opcodes \p Ops to \p DIExpr. Unlike \ref appendToStack, the
2542 /// returned expression is a stack value only if \p DIExpr is a stack value.
2543 /// If \p DIExpr describes a fragment, the returned expression will describe
2544 /// the same fragment.
2545 static DIExpression *append(const DIExpression *Expr, ArrayRef<uint64_t> Ops);
2546
Vedant Kumar6379a622018-07-06 17:32:39 +00002547 /// Convert \p DIExpr into a stack value if it isn't one already by appending
Vedant Kumar47f28442018-07-13 22:39:29 +00002548 /// DW_OP_deref if needed, and appending \p Ops to the resulting expression.
2549 /// If \p DIExpr describes a fragment, the returned expression will describe
2550 /// the same fragment.
Fangrui Song3c1b5db2018-07-06 19:26:00 +00002551 static DIExpression *appendToStack(const DIExpression *Expr,
Vedant Kumar6379a622018-07-06 17:32:39 +00002552 ArrayRef<uint64_t> Ops);
2553
Adrian Prantlb192b542017-08-30 20:04:17 +00002554 /// Create a DIExpression to describe one part of an aggregate variable that
2555 /// is fragmented across multiple Values. The DW_OP_LLVM_fragment operation
2556 /// will be appended to the elements of \c Expr. If \c Expr already contains
2557 /// a \c DW_OP_LLVM_fragment \c OffsetInBits is interpreted as an offset
2558 /// into the existing fragment.
2559 ///
2560 /// \param OffsetInBits Offset of the piece in bits.
2561 /// \param SizeInBits Size of the piece in bits.
Adrian Prantl25a09dd2017-11-07 00:45:34 +00002562 /// \return Creating a fragment expression may fail if \c Expr
2563 /// contains arithmetic operations that would be truncated.
2564 static Optional<DIExpression *>
2565 createFragmentExpression(const DIExpression *Expr, unsigned OffsetInBits,
2566 unsigned SizeInBits);
Bjorn Petterssona223f8152018-03-12 18:02:39 +00002567
2568 /// Determine the relative position of the fragments described by this
2569 /// DIExpression and \p Other.
2570 /// Returns -1 if this is entirely before Other, 0 if this and Other overlap,
2571 /// 1 if this is entirely after Other.
2572 int fragmentCmp(const DIExpression *Other) const {
2573 auto Fragment1 = *getFragmentInfo();
2574 auto Fragment2 = *Other->getFragmentInfo();
2575 unsigned l1 = Fragment1.OffsetInBits;
2576 unsigned l2 = Fragment2.OffsetInBits;
2577 unsigned r1 = l1 + Fragment1.SizeInBits;
2578 unsigned r2 = l2 + Fragment2.SizeInBits;
2579 if (r1 <= l2)
2580 return -1;
2581 else if (r2 <= l1)
2582 return 1;
2583 else
2584 return 0;
2585 }
2586
2587 /// Check if fragments overlap between this DIExpression and \p Other.
2588 bool fragmentsOverlap(const DIExpression *Other) const {
2589 if (!isFragment() || !Other->isFragment())
2590 return true;
2591 return fragmentCmp(Other) == 0;
2592 }
Peter Collingbourned4135bb2016-09-13 01:12:59 +00002593};
2594
Adrian Prantl1687e012016-11-14 22:09:18 +00002595/// Global variables.
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002596///
2597/// TODO: Remove DisplayName. It's always equal to Name.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002598class DIGlobalVariable : public DIVariable {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002599 friend class LLVMContextImpl;
2600 friend class MDNode;
2601
2602 bool IsLocalToUnit;
2603 bool IsDefinition;
2604
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002605 DIGlobalVariable(LLVMContext &C, StorageType Storage, unsigned Line,
Victor Leschuka37660c2016-10-26 21:32:29 +00002606 bool IsLocalToUnit, bool IsDefinition, uint32_t AlignInBits,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002607 ArrayRef<Metadata *> Ops)
Victor Leschuk2ede1262016-10-20 00:13:12 +00002608 : DIVariable(C, DIGlobalVariableKind, Storage, Line, Ops, AlignInBits),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002609 IsLocalToUnit(IsLocalToUnit), IsDefinition(IsDefinition) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002610 ~DIGlobalVariable() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002611
Matthew Vossf8ab35a2018-10-03 18:44:53 +00002612 static DIGlobalVariable *
2613 getImpl(LLVMContext &Context, DIScope *Scope, StringRef Name,
2614 StringRef LinkageName, DIFile *File, unsigned Line, DITypeRef Type,
2615 bool IsLocalToUnit, bool IsDefinition,
2616 DIDerivedType *StaticDataMemberDeclaration, MDTuple *TemplateParams,
2617 uint32_t AlignInBits, StorageType Storage, bool ShouldCreate = true) {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002618 return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
2619 getCanonicalMDString(Context, LinkageName), File, Line, Type,
Adrian Prantlbceaaa92016-12-20 02:09:43 +00002620 IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration,
Matthew Vossf8ab35a2018-10-03 18:44:53 +00002621 cast_or_null<Metadata>(TemplateParams), AlignInBits, Storage,
2622 ShouldCreate);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002623 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002624 static DIGlobalVariable *
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002625 getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
2626 MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type,
Adrian Prantlbceaaa92016-12-20 02:09:43 +00002627 bool IsLocalToUnit, bool IsDefinition,
Matthew Vossf8ab35a2018-10-03 18:44:53 +00002628 Metadata *StaticDataMemberDeclaration, Metadata *TemplateParams,
2629 uint32_t AlignInBits, StorageType Storage, bool ShouldCreate = true);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002630
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002631 TempDIGlobalVariable cloneImpl() const {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002632 return getTemporary(getContext(), getScope(), getName(), getLinkageName(),
2633 getFile(), getLine(), getType(), isLocalToUnit(),
Adrian Prantlbceaaa92016-12-20 02:09:43 +00002634 isDefinition(), getStaticDataMemberDeclaration(),
Matthew Vossf8ab35a2018-10-03 18:44:53 +00002635 getTemplateParams(), getAlignInBits());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002636 }
2637
2638public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002639 DEFINE_MDNODE_GET(DIGlobalVariable,
2640 (DIScope * Scope, StringRef Name, StringRef LinkageName,
2641 DIFile *File, unsigned Line, DITypeRef Type,
Victor Leschuk2ede1262016-10-20 00:13:12 +00002642 bool IsLocalToUnit, bool IsDefinition,
Victor Leschuk2ede1262016-10-20 00:13:12 +00002643 DIDerivedType *StaticDataMemberDeclaration,
Matthew Vossf8ab35a2018-10-03 18:44:53 +00002644 MDTuple *TemplateParams, uint32_t AlignInBits),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002645 (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
Matthew Vossf8ab35a2018-10-03 18:44:53 +00002646 IsDefinition, StaticDataMemberDeclaration, TemplateParams,
2647 AlignInBits))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002648 DEFINE_MDNODE_GET(DIGlobalVariable,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002649 (Metadata * Scope, MDString *Name, MDString *LinkageName,
2650 Metadata *File, unsigned Line, Metadata *Type,
Victor Leschuk2ede1262016-10-20 00:13:12 +00002651 bool IsLocalToUnit, bool IsDefinition,
Adrian Prantlbceaaa92016-12-20 02:09:43 +00002652 Metadata *StaticDataMemberDeclaration,
Matthew Vossf8ab35a2018-10-03 18:44:53 +00002653 Metadata *TemplateParams, uint32_t AlignInBits),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002654 (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
Matthew Vossf8ab35a2018-10-03 18:44:53 +00002655 IsDefinition, StaticDataMemberDeclaration, TemplateParams,
2656 AlignInBits))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002657
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002658 TempDIGlobalVariable clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith6873fea2015-02-17 23:10:13 +00002659
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002660 bool isLocalToUnit() const { return IsLocalToUnit; }
2661 bool isDefinition() const { return IsDefinition; }
2662 StringRef getDisplayName() const { return getStringOperand(4); }
2663 StringRef getLinkageName() const { return getStringOperand(5); }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002664 DIDerivedType *getStaticDataMemberDeclaration() const {
2665 return cast_or_null<DIDerivedType>(getRawStaticDataMemberDeclaration());
Duncan P. N. Exon Smith3d2afaa2015-03-27 17:29:58 +00002666 }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002667
Duncan P. N. Exon Smithc8f810a2015-02-13 01:35:40 +00002668 MDString *getRawLinkageName() const { return getOperandAs<MDString>(5); }
Adrian Prantlbceaaa92016-12-20 02:09:43 +00002669 Metadata *getRawStaticDataMemberDeclaration() const { return getOperand(6); }
Matthew Vossf8ab35a2018-10-03 18:44:53 +00002670 Metadata *getRawTemplateParams() const { return getOperand(7); }
2671 MDTuple *getTemplateParams() const { return getOperandAs<MDTuple>(7); }
Duncan P. N. Exon Smithc8f810a2015-02-13 01:35:40 +00002672
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002673 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002674 return MD->getMetadataID() == DIGlobalVariableKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002675 }
2676};
2677
Adrian Prantl6ed57062019-04-08 19:13:55 +00002678class DICommonBlock : public DIScope {
2679 unsigned LineNo;
2680
2681 friend class LLVMContextImpl;
2682 friend class MDNode;
2683
2684 DICommonBlock(LLVMContext &Context, StorageType Storage, unsigned LineNo,
2685 ArrayRef<Metadata *> Ops)
2686 : DIScope(Context, DICommonBlockKind, Storage, dwarf::DW_TAG_common_block,
2687 Ops), LineNo(LineNo) {}
2688
2689 static DICommonBlock *getImpl(LLVMContext &Context, DIScope *Scope,
2690 DIGlobalVariable *Decl, StringRef Name,
2691 DIFile *File, unsigned LineNo,
2692 StorageType Storage,
2693 bool ShouldCreate = true) {
2694 return getImpl(Context, Scope, Decl, getCanonicalMDString(Context, Name),
2695 File, LineNo, Storage, ShouldCreate);
2696 }
2697 static DICommonBlock *getImpl(LLVMContext &Context, Metadata *Scope,
2698 Metadata *Decl, MDString *Name, Metadata *File,
2699 unsigned LineNo,
2700 StorageType Storage, bool ShouldCreate = true);
2701
2702 TempDICommonBlock cloneImpl() const {
2703 return getTemporary(getContext(), getScope(), getDecl(), getName(),
2704 getFile(), getLineNo());
2705 }
2706
2707public:
2708 DEFINE_MDNODE_GET(DICommonBlock,
2709 (DIScope *Scope, DIGlobalVariable *Decl, StringRef Name,
2710 DIFile *File, unsigned LineNo),
2711 (Scope, Decl, Name, File, LineNo))
2712 DEFINE_MDNODE_GET(DICommonBlock,
2713 (Metadata *Scope, Metadata *Decl, MDString *Name,
2714 Metadata *File, unsigned LineNo),
2715 (Scope, Decl, Name, File, LineNo))
2716
2717 TempDICommonBlock clone() const { return cloneImpl(); }
2718
2719 DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
2720 DIGlobalVariable *getDecl() const {
2721 return cast_or_null<DIGlobalVariable>(getRawDecl());
2722 }
2723 StringRef getName() const { return getStringOperand(2); }
2724 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
2725 unsigned getLineNo() const { return LineNo; }
2726
2727 Metadata *getRawScope() const { return getOperand(0); }
2728 Metadata *getRawDecl() const { return getOperand(1); }
2729 MDString *getRawName() const { return getOperandAs<MDString>(2); }
2730 Metadata *getRawFile() const { return getOperand(3); }
2731
2732 static bool classof(const Metadata *MD) {
2733 return MD->getMetadataID() == DICommonBlockKind;
2734 }
2735};
2736
Adrian Prantl1687e012016-11-14 22:09:18 +00002737/// Local variable.
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002738///
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002739/// TODO: Split up flags.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002740class DILocalVariable : public DIVariable {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002741 friend class LLVMContextImpl;
2742 friend class MDNode;
2743
Davide Italianoeb6bb3e2016-04-16 02:27:56 +00002744 unsigned Arg : 16;
Leny Kholodov5fcc4182016-09-06 10:46:28 +00002745 DIFlags Flags;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002746
Duncan P. N. Exon Smithed013cd2015-07-31 18:58:39 +00002747 DILocalVariable(LLVMContext &C, StorageType Storage, unsigned Line,
Victor Leschuka37660c2016-10-26 21:32:29 +00002748 unsigned Arg, DIFlags Flags, uint32_t AlignInBits,
Victor Leschuk2ede1262016-10-20 00:13:12 +00002749 ArrayRef<Metadata *> Ops)
2750 : DIVariable(C, DILocalVariableKind, Storage, Line, Ops, AlignInBits),
2751 Arg(Arg), Flags(Flags) {
Davide Italiano0d2ef012016-04-16 03:23:48 +00002752 assert(Arg < (1 << 16) && "DILocalVariable: Arg out of range");
Davide Italianoeb6bb3e2016-04-16 02:27:56 +00002753 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002754 ~DILocalVariable() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002755
Duncan P. N. Exon Smithed013cd2015-07-31 18:58:39 +00002756 static DILocalVariable *getImpl(LLVMContext &Context, DIScope *Scope,
2757 StringRef Name, DIFile *File, unsigned Line,
Leny Kholodov5fcc4182016-09-06 10:46:28 +00002758 DITypeRef Type, unsigned Arg, DIFlags Flags,
Victor Leschuka37660c2016-10-26 21:32:29 +00002759 uint32_t AlignInBits, StorageType Storage,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002760 bool ShouldCreate = true) {
Duncan P. N. Exon Smithed013cd2015-07-31 18:58:39 +00002761 return getImpl(Context, Scope, getCanonicalMDString(Context, Name), File,
Victor Leschuk2ede1262016-10-20 00:13:12 +00002762 Line, Type, Arg, Flags, AlignInBits, Storage, ShouldCreate);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002763 }
Duncan P. N. Exon Smithed013cd2015-07-31 18:58:39 +00002764 static DILocalVariable *getImpl(LLVMContext &Context, Metadata *Scope,
2765 MDString *Name, Metadata *File, unsigned Line,
Leny Kholodov5fcc4182016-09-06 10:46:28 +00002766 Metadata *Type, unsigned Arg, DIFlags Flags,
Victor Leschuka37660c2016-10-26 21:32:29 +00002767 uint32_t AlignInBits, StorageType Storage,
Duncan P. N. Exon Smithed013cd2015-07-31 18:58:39 +00002768 bool ShouldCreate = true);
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002769
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002770 TempDILocalVariable cloneImpl() const {
Duncan P. N. Exon Smithed013cd2015-07-31 18:58:39 +00002771 return getTemporary(getContext(), getScope(), getName(), getFile(),
Victor Leschuk2ede1262016-10-20 00:13:12 +00002772 getLine(), getType(), getArg(), getFlags(),
2773 getAlignInBits());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002774 }
2775
2776public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002777 DEFINE_MDNODE_GET(DILocalVariable,
Duncan P. N. Exon Smithed013cd2015-07-31 18:58:39 +00002778 (DILocalScope * Scope, StringRef Name, DIFile *File,
Leny Kholodov40c62352016-09-06 17:03:02 +00002779 unsigned Line, DITypeRef Type, unsigned Arg,
Victor Leschuka37660c2016-10-26 21:32:29 +00002780 DIFlags Flags, uint32_t AlignInBits),
Victor Leschuk2ede1262016-10-20 00:13:12 +00002781 (Scope, Name, File, Line, Type, Arg, Flags, AlignInBits))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002782 DEFINE_MDNODE_GET(DILocalVariable,
Duncan P. N. Exon Smithed013cd2015-07-31 18:58:39 +00002783 (Metadata * Scope, MDString *Name, Metadata *File,
Leny Kholodov40c62352016-09-06 17:03:02 +00002784 unsigned Line, Metadata *Type, unsigned Arg,
Victor Leschuka37660c2016-10-26 21:32:29 +00002785 DIFlags Flags, uint32_t AlignInBits),
Victor Leschuk2ede1262016-10-20 00:13:12 +00002786 (Scope, Name, File, Line, Type, Arg, Flags, AlignInBits))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002787
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002788 TempDILocalVariable clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith6873fea2015-02-17 23:10:13 +00002789
Adrian Prantl1687e012016-11-14 22:09:18 +00002790 /// Get the local scope for this variable.
Duncan P. N. Exon Smith3d2afaa2015-03-27 17:29:58 +00002791 ///
2792 /// Variables must be defined in a local scope.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002793 DILocalScope *getScope() const {
2794 return cast<DILocalScope>(DIVariable::getScope());
Duncan P. N. Exon Smith3d2afaa2015-03-27 17:29:58 +00002795 }
2796
Duncan P. N. Exon Smithed013cd2015-07-31 18:58:39 +00002797 bool isParameter() const { return Arg; }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002798 unsigned getArg() const { return Arg; }
Leny Kholodov5fcc4182016-09-06 10:46:28 +00002799 DIFlags getFlags() const { return Flags; }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002800
Duncan P. N. Exon Smithbd42d5d2015-04-07 03:55:30 +00002801 bool isArtificial() const { return getFlags() & FlagArtificial; }
2802 bool isObjectPointer() const { return getFlags() & FlagObjectPointer; }
2803
Adrian Prantl1687e012016-11-14 22:09:18 +00002804 /// Check that a location is valid for this variable.
Duncan P. N. Exon Smith3bef6a32015-04-03 19:20:26 +00002805 ///
Duncan P. N. Exon Smithf17f34e2015-04-15 22:15:46 +00002806 /// Check that \c DL exists, is in the same subprogram, and has the same
Benjamin Kramerdf005cb2015-08-08 18:27:36 +00002807 /// inlined-at location as \c this. (Otherwise, it's not a valid attachment
Duncan P. N. Exon Smithf17f34e2015-04-15 22:15:46 +00002808 /// to a \a DbgInfoIntrinsic.)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002809 bool isValidLocationForIntrinsic(const DILocation *DL) const {
Duncan P. N. Exon Smith62e0f452015-04-15 22:29:27 +00002810 return DL && getScope()->getSubprogram() == DL->getScope()->getSubprogram();
Duncan P. N. Exon Smith3bef6a32015-04-03 19:20:26 +00002811 }
2812
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002813 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002814 return MD->getMetadataID() == DILocalVariableKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002815 }
2816};
2817
Shiva Chen2c864552018-05-09 02:40:45 +00002818/// Label.
2819///
2820class DILabel : public DINode {
2821 friend class LLVMContextImpl;
2822 friend class MDNode;
2823
2824 unsigned Line;
2825
2826 DILabel(LLVMContext &C, StorageType Storage, unsigned Line,
2827 ArrayRef<Metadata *> Ops)
2828 : DINode(C, DILabelKind, Storage, dwarf::DW_TAG_label, Ops), Line(Line) {}
2829 ~DILabel() = default;
2830
2831 static DILabel *getImpl(LLVMContext &Context, DIScope *Scope,
2832 StringRef Name, DIFile *File, unsigned Line,
2833 StorageType Storage,
2834 bool ShouldCreate = true) {
2835 return getImpl(Context, Scope, getCanonicalMDString(Context, Name), File,
2836 Line, Storage, ShouldCreate);
2837 }
2838 static DILabel *getImpl(LLVMContext &Context, Metadata *Scope,
2839 MDString *Name, Metadata *File, unsigned Line,
2840 StorageType Storage,
2841 bool ShouldCreate = true);
2842
2843 TempDILabel cloneImpl() const {
2844 return getTemporary(getContext(), getScope(), getName(), getFile(),
2845 getLine());
2846 }
2847
2848public:
2849 DEFINE_MDNODE_GET(DILabel,
2850 (DILocalScope * Scope, StringRef Name, DIFile *File,
2851 unsigned Line),
2852 (Scope, Name, File, Line))
2853 DEFINE_MDNODE_GET(DILabel,
2854 (Metadata * Scope, MDString *Name, Metadata *File,
2855 unsigned Line),
2856 (Scope, Name, File, Line))
2857
2858 TempDILabel clone() const { return cloneImpl(); }
2859
2860 /// Get the local scope for this label.
2861 ///
2862 /// Labels must be defined in a local scope.
2863 DILocalScope *getScope() const {
2864 return cast_or_null<DILocalScope>(getRawScope());
2865 }
2866 unsigned getLine() const { return Line; }
2867 StringRef getName() const { return getStringOperand(1); }
2868 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
2869
2870 Metadata *getRawScope() const { return getOperand(0); }
2871 MDString *getRawName() const { return getOperandAs<MDString>(1); }
2872 Metadata *getRawFile() const { return getOperand(2); }
2873
2874 /// Check that a location is valid for this label.
2875 ///
2876 /// Check that \c DL exists, is in the same subprogram, and has the same
2877 /// inlined-at location as \c this. (Otherwise, it's not a valid attachment
2878 /// to a \a DbgInfoIntrinsic.)
2879 bool isValidLocationForIntrinsic(const DILocation *DL) const {
2880 return DL && getScope()->getSubprogram() == DL->getScope()->getSubprogram();
2881 }
2882
2883 static bool classof(const Metadata *MD) {
2884 return MD->getMetadataID() == DILabelKind;
2885 }
2886};
2887
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002888class DIObjCProperty : public DINode {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002889 friend class LLVMContextImpl;
2890 friend class MDNode;
2891
2892 unsigned Line;
2893 unsigned Attributes;
2894
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002895 DIObjCProperty(LLVMContext &C, StorageType Storage, unsigned Line,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002896 unsigned Attributes, ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002897 : DINode(C, DIObjCPropertyKind, Storage, dwarf::DW_TAG_APPLE_property,
2898 Ops),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002899 Line(Line), Attributes(Attributes) {}
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002900 ~DIObjCProperty() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002901
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002902 static DIObjCProperty *
2903 getImpl(LLVMContext &Context, StringRef Name, DIFile *File, unsigned Line,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002904 StringRef GetterName, StringRef SetterName, unsigned Attributes,
Adrian Prantl8ff53b32015-06-15 23:18:03 +00002905 DITypeRef Type, StorageType Storage, bool ShouldCreate = true) {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002906 return getImpl(Context, getCanonicalMDString(Context, Name), File, Line,
2907 getCanonicalMDString(Context, GetterName),
2908 getCanonicalMDString(Context, SetterName), Attributes, Type,
2909 Storage, ShouldCreate);
2910 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002911 static DIObjCProperty *getImpl(LLVMContext &Context, MDString *Name,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002912 Metadata *File, unsigned Line,
2913 MDString *GetterName, MDString *SetterName,
2914 unsigned Attributes, Metadata *Type,
2915 StorageType Storage, bool ShouldCreate = true);
2916
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002917 TempDIObjCProperty cloneImpl() const {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002918 return getTemporary(getContext(), getName(), getFile(), getLine(),
2919 getGetterName(), getSetterName(), getAttributes(),
2920 getType());
2921 }
2922
2923public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002924 DEFINE_MDNODE_GET(DIObjCProperty,
2925 (StringRef Name, DIFile *File, unsigned Line,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002926 StringRef GetterName, StringRef SetterName,
Adrian Prantl8ff53b32015-06-15 23:18:03 +00002927 unsigned Attributes, DITypeRef Type),
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002928 (Name, File, Line, GetterName, SetterName, Attributes,
2929 Type))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002930 DEFINE_MDNODE_GET(DIObjCProperty,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002931 (MDString * Name, Metadata *File, unsigned Line,
2932 MDString *GetterName, MDString *SetterName,
2933 unsigned Attributes, Metadata *Type),
2934 (Name, File, Line, GetterName, SetterName, Attributes,
2935 Type))
2936
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002937 TempDIObjCProperty clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith6873fea2015-02-17 23:10:13 +00002938
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002939 unsigned getLine() const { return Line; }
2940 unsigned getAttributes() const { return Attributes; }
2941 StringRef getName() const { return getStringOperand(0); }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002942 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002943 StringRef getGetterName() const { return getStringOperand(2); }
2944 StringRef getSetterName() const { return getStringOperand(3); }
Adrian Prantl8ff53b32015-06-15 23:18:03 +00002945 DITypeRef getType() const { return DITypeRef(getRawType()); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002946
Duncan P. N. Exon Smith50c065b2015-04-11 00:39:43 +00002947 StringRef getFilename() const {
2948 if (auto *F = getFile())
2949 return F->getFilename();
2950 return "";
2951 }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +00002952
Duncan P. N. Exon Smith50c065b2015-04-11 00:39:43 +00002953 StringRef getDirectory() const {
2954 if (auto *F = getFile())
2955 return F->getDirectory();
2956 return "";
2957 }
2958
Scott Linder16c7bda2018-02-23 23:01:06 +00002959 Optional<StringRef> getSource() const {
2960 if (auto *F = getFile())
2961 return F->getSource();
2962 return None;
2963 }
2964
Duncan P. N. Exon Smithd45ce962015-02-13 01:43:22 +00002965 MDString *getRawName() const { return getOperandAs<MDString>(0); }
Duncan P. N. Exon Smithf9b47752015-03-30 17:21:38 +00002966 Metadata *getRawFile() const { return getOperand(1); }
Duncan P. N. Exon Smithd45ce962015-02-13 01:43:22 +00002967 MDString *getRawGetterName() const { return getOperandAs<MDString>(2); }
2968 MDString *getRawSetterName() const { return getOperandAs<MDString>(3); }
Duncan P. N. Exon Smithf9b47752015-03-30 17:21:38 +00002969 Metadata *getRawType() const { return getOperand(4); }
Duncan P. N. Exon Smithd45ce962015-02-13 01:43:22 +00002970
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002971 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002972 return MD->getMetadataID() == DIObjCPropertyKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002973 }
2974};
2975
Adrian Prantl1687e012016-11-14 22:09:18 +00002976/// An imported module (C++ using directive or similar).
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002977class DIImportedEntity : public DINode {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002978 friend class LLVMContextImpl;
2979 friend class MDNode;
2980
2981 unsigned Line;
2982
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002983 DIImportedEntity(LLVMContext &C, StorageType Storage, unsigned Tag,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002984 unsigned Line, ArrayRef<Metadata *> Ops)
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002985 : DINode(C, DIImportedEntityKind, Storage, Tag, Ops), Line(Line) {}
2986 ~DIImportedEntity() = default;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002987
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002988 static DIImportedEntity *getImpl(LLVMContext &Context, unsigned Tag,
2989 DIScope *Scope, DINodeRef Entity,
Adrian Prantld63bfd22017-07-19 00:09:54 +00002990 DIFile *File, unsigned Line, StringRef Name,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002991 StorageType Storage,
2992 bool ShouldCreate = true) {
Adrian Prantld63bfd22017-07-19 00:09:54 +00002993 return getImpl(Context, Tag, Scope, Entity, File, Line,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002994 getCanonicalMDString(Context, Name), Storage, ShouldCreate);
2995 }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00002996 static DIImportedEntity *getImpl(LLVMContext &Context, unsigned Tag,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00002997 Metadata *Scope, Metadata *Entity,
Adrian Prantld63bfd22017-07-19 00:09:54 +00002998 Metadata *File, unsigned Line,
2999 MDString *Name, StorageType Storage,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00003000 bool ShouldCreate = true);
3001
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00003002 TempDIImportedEntity cloneImpl() const {
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00003003 return getTemporary(getContext(), getTag(), getScope(), getEntity(),
Adrian Prantld63bfd22017-07-19 00:09:54 +00003004 getFile(), getLine(), getName());
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00003005 }
3006
3007public:
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00003008 DEFINE_MDNODE_GET(DIImportedEntity,
3009 (unsigned Tag, DIScope *Scope, DINodeRef Entity,
Adrian Prantld63bfd22017-07-19 00:09:54 +00003010 DIFile *File, unsigned Line, StringRef Name = ""),
3011 (Tag, Scope, Entity, File, Line, Name))
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00003012 DEFINE_MDNODE_GET(DIImportedEntity,
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00003013 (unsigned Tag, Metadata *Scope, Metadata *Entity,
Adrian Prantld63bfd22017-07-19 00:09:54 +00003014 Metadata *File, unsigned Line, MDString *Name),
3015 (Tag, Scope, Entity, File, Line, Name))
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00003016
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00003017 TempDIImportedEntity clone() const { return cloneImpl(); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00003018
3019 unsigned getLine() const { return Line; }
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00003020 DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
3021 DINodeRef getEntity() const { return DINodeRef(getRawEntity()); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00003022 StringRef getName() const { return getStringOperand(2); }
Adrian Prantld63bfd22017-07-19 00:09:54 +00003023 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00003024
Duncan P. N. Exon Smithf9b47752015-03-30 17:21:38 +00003025 Metadata *getRawScope() const { return getOperand(0); }
3026 Metadata *getRawEntity() const { return getOperand(1); }
Duncan P. N. Exon Smith1c931162015-02-13 01:46:02 +00003027 MDString *getRawName() const { return getOperandAs<MDString>(2); }
Adrian Prantld63bfd22017-07-19 00:09:54 +00003028 Metadata *getRawFile() const { return getOperand(3); }
Duncan P. N. Exon Smith1c931162015-02-13 01:46:02 +00003029
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00003030 static bool classof(const Metadata *MD) {
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +00003031 return MD->getMetadataID() == DIImportedEntityKind;
Duncan P. N. Exon Smith01fc1762015-02-10 00:52:32 +00003032 }
3033};
3034
Adrian Prantlbceaaa92016-12-20 02:09:43 +00003035/// A pair of DIGlobalVariable and DIExpression.
3036class DIGlobalVariableExpression : public MDNode {
3037 friend class LLVMContextImpl;
3038 friend class MDNode;
3039
3040 DIGlobalVariableExpression(LLVMContext &C, StorageType Storage,
3041 ArrayRef<Metadata *> Ops)
3042 : MDNode(C, DIGlobalVariableExpressionKind, Storage, Ops) {}
3043 ~DIGlobalVariableExpression() = default;
3044
3045 static DIGlobalVariableExpression *
3046 getImpl(LLVMContext &Context, Metadata *Variable, Metadata *Expression,
3047 StorageType Storage, bool ShouldCreate = true);
3048
3049 TempDIGlobalVariableExpression cloneImpl() const {
3050 return getTemporary(getContext(), getVariable(), getExpression());
3051 }
3052
3053public:
3054 DEFINE_MDNODE_GET(DIGlobalVariableExpression,
3055 (Metadata * Variable, Metadata *Expression),
3056 (Variable, Expression))
3057
3058 TempDIGlobalVariableExpression clone() const { return cloneImpl(); }
3059
3060 Metadata *getRawVariable() const { return getOperand(0); }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +00003061
Adrian Prantlbceaaa92016-12-20 02:09:43 +00003062 DIGlobalVariable *getVariable() const {
3063 return cast_or_null<DIGlobalVariable>(getRawVariable());
3064 }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +00003065
Adrian Prantlbceaaa92016-12-20 02:09:43 +00003066 Metadata *getRawExpression() const { return getOperand(1); }
Eugene Zelenkod761e2c2017-05-15 21:57:41 +00003067
Adrian Prantlbceaaa92016-12-20 02:09:43 +00003068 DIExpression *getExpression() const {
Adrian Prantl05782212017-08-30 18:06:51 +00003069 return cast<DIExpression>(getRawExpression());
Adrian Prantlbceaaa92016-12-20 02:09:43 +00003070 }
3071
3072 static bool classof(const Metadata *MD) {
3073 return MD->getMetadataID() == DIGlobalVariableExpressionKind;
3074 }
3075};
3076
Adrian Prantl1687e012016-11-14 22:09:18 +00003077/// Macro Info DWARF-like metadata node.
Amjad Abouda9bcf162015-12-10 12:56:35 +00003078///
3079/// A metadata node with a DWARF macro info (i.e., a constant named
Zachary Turner264b5d92017-06-07 03:48:56 +00003080/// \c DW_MACINFO_*, defined in llvm/BinaryFormat/Dwarf.h). Called \a
3081/// DIMacroNode
Amjad Abouda9bcf162015-12-10 12:56:35 +00003082/// because it's potentially used for non-DWARF output.
3083class DIMacroNode : public MDNode {
3084 friend class LLVMContextImpl;
3085 friend class MDNode;
3086
3087protected:
3088 DIMacroNode(LLVMContext &C, unsigned ID, StorageType Storage, unsigned MIType,
3089 ArrayRef<Metadata *> Ops1, ArrayRef<Metadata *> Ops2 = None)
3090 : MDNode(C, ID, Storage, Ops1, Ops2) {
3091 assert(MIType < 1u << 16);
3092 SubclassData16 = MIType;
3093 }
3094 ~DIMacroNode() = default;
3095
3096 template <class Ty> Ty *getOperandAs(unsigned I) const {
3097 return cast_or_null<Ty>(getOperand(I));
3098 }
3099
3100 StringRef getStringOperand(unsigned I) const {
3101 if (auto *S = getOperandAs<MDString>(I))
3102 return S->getString();
3103 return StringRef();
3104 }
3105
3106 static MDString *getCanonicalMDString(LLVMContext &Context, StringRef S) {
3107 if (S.empty())
3108 return nullptr;
3109 return MDString::get(Context, S);
3110 }
3111
3112public:
3113 unsigned getMacinfoType() const { return SubclassData16; }
3114
3115 static bool classof(const Metadata *MD) {
3116 switch (MD->getMetadataID()) {
3117 default:
3118 return false;
3119 case DIMacroKind:
3120 case DIMacroFileKind:
3121 return true;
3122 }
3123 }
3124};
3125
3126class DIMacro : public DIMacroNode {
3127 friend class LLVMContextImpl;
3128 friend class MDNode;
3129
3130 unsigned Line;
3131
3132 DIMacro(LLVMContext &C, StorageType Storage, unsigned MIType, unsigned Line,
3133 ArrayRef<Metadata *> Ops)
3134 : DIMacroNode(C, DIMacroKind, Storage, MIType, Ops), Line(Line) {}
3135 ~DIMacro() = default;
3136
3137 static DIMacro *getImpl(LLVMContext &Context, unsigned MIType, unsigned Line,
3138 StringRef Name, StringRef Value, StorageType Storage,
3139 bool ShouldCreate = true) {
3140 return getImpl(Context, MIType, Line, getCanonicalMDString(Context, Name),
3141 getCanonicalMDString(Context, Value), Storage, ShouldCreate);
3142 }
3143 static DIMacro *getImpl(LLVMContext &Context, unsigned MIType, unsigned Line,
3144 MDString *Name, MDString *Value, StorageType Storage,
3145 bool ShouldCreate = true);
3146
3147 TempDIMacro cloneImpl() const {
3148 return getTemporary(getContext(), getMacinfoType(), getLine(), getName(),
3149 getValue());
3150 }
3151
3152public:
3153 DEFINE_MDNODE_GET(DIMacro, (unsigned MIType, unsigned Line, StringRef Name,
3154 StringRef Value = ""),
3155 (MIType, Line, Name, Value))
3156 DEFINE_MDNODE_GET(DIMacro, (unsigned MIType, unsigned Line, MDString *Name,
3157 MDString *Value),
3158 (MIType, Line, Name, Value))
3159
3160 TempDIMacro clone() const { return cloneImpl(); }
3161
3162 unsigned getLine() const { return Line; }
3163
3164 StringRef getName() const { return getStringOperand(0); }
3165 StringRef getValue() const { return getStringOperand(1); }
3166
3167 MDString *getRawName() const { return getOperandAs<MDString>(0); }
3168 MDString *getRawValue() const { return getOperandAs<MDString>(1); }
3169
3170 static bool classof(const Metadata *MD) {
3171 return MD->getMetadataID() == DIMacroKind;
3172 }
3173};
3174
3175class DIMacroFile : public DIMacroNode {
3176 friend class LLVMContextImpl;
3177 friend class MDNode;
3178
3179 unsigned Line;
3180
3181 DIMacroFile(LLVMContext &C, StorageType Storage, unsigned MIType,
3182 unsigned Line, ArrayRef<Metadata *> Ops)
3183 : DIMacroNode(C, DIMacroFileKind, Storage, MIType, Ops), Line(Line) {}
3184 ~DIMacroFile() = default;
3185
3186 static DIMacroFile *getImpl(LLVMContext &Context, unsigned MIType,
3187 unsigned Line, DIFile *File,
3188 DIMacroNodeArray Elements, StorageType Storage,
3189 bool ShouldCreate = true) {
3190 return getImpl(Context, MIType, Line, static_cast<Metadata *>(File),
3191 Elements.get(), Storage, ShouldCreate);
3192 }
3193
3194 static DIMacroFile *getImpl(LLVMContext &Context, unsigned MIType,
3195 unsigned Line, Metadata *File, Metadata *Elements,
3196 StorageType Storage, bool ShouldCreate = true);
3197
3198 TempDIMacroFile cloneImpl() const {
3199 return getTemporary(getContext(), getMacinfoType(), getLine(), getFile(),
3200 getElements());
3201 }
3202
3203public:
3204 DEFINE_MDNODE_GET(DIMacroFile, (unsigned MIType, unsigned Line, DIFile *File,
3205 DIMacroNodeArray Elements),
3206 (MIType, Line, File, Elements))
3207 DEFINE_MDNODE_GET(DIMacroFile, (unsigned MIType, unsigned Line,
3208 Metadata *File, Metadata *Elements),
3209 (MIType, Line, File, Elements))
3210
3211 TempDIMacroFile clone() const { return cloneImpl(); }
3212
3213 void replaceElements(DIMacroNodeArray Elements) {
3214#ifndef NDEBUG
3215 for (DIMacroNode *Op : getElements())
David Majnemer42531262016-08-12 03:55:06 +00003216 assert(is_contained(Elements->operands(), Op) &&
Amjad Abouda9bcf162015-12-10 12:56:35 +00003217 "Lost a macro node during macro node list replacement");
3218#endif
3219 replaceOperandWith(1, Elements.get());
3220 }
3221
3222 unsigned getLine() const { return Line; }
3223 DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
3224
3225 DIMacroNodeArray getElements() const {
3226 return cast_or_null<MDTuple>(getRawElements());
3227 }
3228
3229 Metadata *getRawFile() const { return getOperand(0); }
3230 Metadata *getRawElements() const { return getOperand(1); }
3231
3232 static bool classof(const Metadata *MD) {
3233 return MD->getMetadataID() == DIMacroFileKind;
3234 }
3235};
3236
Duncan P. N. Exon Smithd9901ff2015-02-02 18:53:21 +00003237} // end namespace llvm
3238
Duncan P. N. Exon Smith61e62a52015-02-02 19:55:21 +00003239#undef DEFINE_MDNODE_GET_UNPACK_IMPL
3240#undef DEFINE_MDNODE_GET_UNPACK
3241#undef DEFINE_MDNODE_GET
3242
Eugene Zelenko1aa40f42016-11-23 22:25:16 +00003243#endif // LLVM_IR_DEBUGINFOMETADATA_H