1 //===- llvm/IR/DebugInfoMetadata.h - Debug info metadata --------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // Declarations for metadata specific to debug info.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_IR_DEBUGINFOMETADATA_H
15 #define LLVM_IR_DEBUGINFOMETADATA_H
17 #include "llvm/IR/Metadata.h"
19 // Helper macros for defining get() overrides.
20 #define DEFINE_MDNODE_GET_UNPACK_IMPL(...) __VA_ARGS__
21 #define DEFINE_MDNODE_GET_UNPACK(ARGS) DEFINE_MDNODE_GET_UNPACK_IMPL ARGS
22 #define DEFINE_MDNODE_GET(CLASS, FORMAL, ARGS) \
23 static CLASS *get(LLVMContext &Context, DEFINE_MDNODE_GET_UNPACK(FORMAL)) { \
24 return getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Uniqued); \
26 static CLASS *getIfExists(LLVMContext &Context, \
27 DEFINE_MDNODE_GET_UNPACK(FORMAL)) { \
28 return getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Uniqued, \
29 /* ShouldCreate */ false); \
31 static CLASS *getDistinct(LLVMContext &Context, \
32 DEFINE_MDNODE_GET_UNPACK(FORMAL)) { \
33 return getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Distinct); \
35 static Temp##CLASS getTemporary(LLVMContext &Context, \
36 DEFINE_MDNODE_GET_UNPACK(FORMAL)) { \
38 getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Temporary)); \
43 /// \brief Debug location.
45 /// A debug location in source code, used for debug info and otherwise.
46 class MDLocation : public MDNode {
47 friend class LLVMContextImpl;
50 MDLocation(LLVMContext &C, StorageType Storage, unsigned Line,
51 unsigned Column, ArrayRef<Metadata *> MDs);
52 ~MDLocation() { dropAllReferences(); }
54 static MDLocation *getImpl(LLVMContext &Context, unsigned Line,
55 unsigned Column, Metadata *Scope,
56 Metadata *InlinedAt, StorageType Storage,
57 bool ShouldCreate = true);
59 TempMDLocation cloneImpl() const {
60 return getTemporary(getContext(), getLine(), getColumn(), getScope(),
64 // Disallow replacing operands.
65 void replaceOperandWith(unsigned I, Metadata *New) LLVM_DELETED_FUNCTION;
68 DEFINE_MDNODE_GET(MDLocation,
69 (unsigned Line, unsigned Column, Metadata *Scope,
70 Metadata *InlinedAt = nullptr),
71 (Line, Column, Scope, InlinedAt))
73 /// \brief Return a (temporary) clone of this.
74 TempMDLocation clone() const { return cloneImpl(); }
76 unsigned getLine() const { return SubclassData32; }
77 unsigned getColumn() const { return SubclassData16; }
78 Metadata *getScope() const { return getOperand(0); }
79 Metadata *getInlinedAt() const {
80 if (getNumOperands() == 2)
85 static bool classof(const Metadata *MD) {
86 return MD->getMetadataID() == MDLocationKind;
90 /// \brief Tagged DWARF-like metadata node.
92 /// A metadata node with a DWARF tag (i.e., a constant named \c DW_TAG_*,
93 /// defined in llvm/Support/Dwarf.h). Called \a DebugNode because it's
94 /// potentially used for non-DWARF output.
95 class DebugNode : public MDNode {
96 friend class LLVMContextImpl;
100 DebugNode(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
101 ArrayRef<Metadata *> Ops1, ArrayRef<Metadata *> Ops2 = None)
102 : MDNode(C, ID, Storage, Ops1, Ops2) {
103 assert(Tag < 1u << 16);
104 SubclassData16 = Tag;
108 StringRef getStringOperand(unsigned I) const {
109 if (auto *S = cast_or_null<MDString>(getOperand(I)))
110 return S->getString();
115 unsigned getTag() const { return SubclassData16; }
117 static bool classof(const Metadata *MD) {
118 return MD->getMetadataID() == GenericDebugNodeKind;
122 /// \brief Generic tagged DWARF-like metadata node.
124 /// An un-specialized DWARF-like metadata node. The first operand is a
125 /// (possibly empty) null-separated \a MDString header that contains arbitrary
126 /// fields. The remaining operands are \a dwarf_operands(), and are pointers
127 /// to other metadata.
128 class GenericDebugNode : public DebugNode {
129 friend class LLVMContextImpl;
132 GenericDebugNode(LLVMContext &C, StorageType Storage, unsigned Hash,
133 unsigned Tag, ArrayRef<Metadata *> Ops1,
134 ArrayRef<Metadata *> Ops2)
135 : DebugNode(C, GenericDebugNodeKind, Storage, Tag, Ops1, Ops2) {
138 ~GenericDebugNode() { dropAllReferences(); }
140 void setHash(unsigned Hash) { SubclassData32 = Hash; }
141 void recalculateHash();
143 static GenericDebugNode *getImpl(LLVMContext &Context, unsigned Tag,
145 ArrayRef<Metadata *> DwarfOps,
147 bool ShouldCreate = true);
149 TempGenericDebugNode cloneImpl() const {
151 getContext(), getTag(), getHeader(),
152 SmallVector<Metadata *, 4>(dwarf_op_begin(), dwarf_op_end()));
156 unsigned getHash() const { return SubclassData32; }
158 DEFINE_MDNODE_GET(GenericDebugNode, (unsigned Tag, StringRef Header,
159 ArrayRef<Metadata *> DwarfOps),
160 (Tag, Header, DwarfOps))
162 /// \brief Return a (temporary) clone of this.
163 TempGenericDebugNode clone() const { return cloneImpl(); }
165 unsigned getTag() const { return SubclassData16; }
166 StringRef getHeader() const { return getStringOperand(0); }
168 op_iterator dwarf_op_begin() const { return op_begin() + 1; }
169 op_iterator dwarf_op_end() const { return op_end(); }
170 op_range dwarf_operands() const {
171 return op_range(dwarf_op_begin(), dwarf_op_end());
174 unsigned getNumDwarfOperands() const { return getNumOperands() - 1; }
175 const MDOperand &getDwarfOperand(unsigned I) const {
176 return getOperand(I + 1);
178 void replaceDwarfOperandWith(unsigned I, Metadata *New) {
179 replaceOperandWith(I + 1, New);
182 static bool classof(const Metadata *MD) {
183 return MD->getMetadataID() == GenericDebugNodeKind;
187 } // end namespace llvm
189 #undef DEFINE_MDNODE_GET_UNPACK_IMPL
190 #undef DEFINE_MDNODE_GET_UNPACK
191 #undef DEFINE_MDNODE_GET