28f29ec8353e1320f4b4d13ccd30b50f0a6a12b6
[oota-llvm.git] / include / llvm / IR / DebugInfoMetadata.h
1 //===- llvm/IR/DebugInfoMetadata.h - Debug info metadata --------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // Declarations for metadata specific to debug info.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_IR_DEBUGINFOMETADATA_H
15 #define LLVM_IR_DEBUGINFOMETADATA_H
16
17 #include "llvm/IR/Metadata.h"
18
19 namespace llvm {
20
21 /// \brief Debug location.
22 ///
23 /// A debug location in source code, used for debug info and otherwise.
24 class MDLocation : public MDNode {
25   friend class LLVMContextImpl;
26   friend class MDNode;
27
28   MDLocation(LLVMContext &C, StorageType Storage, unsigned Line,
29              unsigned Column, ArrayRef<Metadata *> MDs);
30   ~MDLocation() { dropAllReferences(); }
31
32   static MDLocation *getImpl(LLVMContext &Context, unsigned Line,
33                              unsigned Column, Metadata *Scope,
34                              Metadata *InlinedAt, StorageType Storage,
35                              bool ShouldCreate = true);
36
37   TempMDLocation cloneImpl() const {
38     return getTemporary(getContext(), getLine(), getColumn(), getScope(),
39                         getInlinedAt());
40   }
41
42   // Disallow replacing operands.
43   void replaceOperandWith(unsigned I, Metadata *New) LLVM_DELETED_FUNCTION;
44
45 public:
46   static MDLocation *get(LLVMContext &Context, unsigned Line, unsigned Column,
47                          Metadata *Scope, Metadata *InlinedAt = nullptr) {
48     return getImpl(Context, Line, Column, Scope, InlinedAt, Uniqued);
49   }
50   static MDLocation *getIfExists(LLVMContext &Context, unsigned Line,
51                                  unsigned Column, Metadata *Scope,
52                                  Metadata *InlinedAt = nullptr) {
53     return getImpl(Context, Line, Column, Scope, InlinedAt, Uniqued,
54                    /* ShouldCreate */ false);
55   }
56   static MDLocation *getDistinct(LLVMContext &Context, unsigned Line,
57                                  unsigned Column, Metadata *Scope,
58                                  Metadata *InlinedAt = nullptr) {
59     return getImpl(Context, Line, Column, Scope, InlinedAt, Distinct);
60   }
61   static TempMDLocation getTemporary(LLVMContext &Context, unsigned Line,
62                                      unsigned Column, Metadata *Scope,
63                                      Metadata *InlinedAt = nullptr) {
64     return TempMDLocation(
65         getImpl(Context, Line, Column, Scope, InlinedAt, Temporary));
66   }
67
68   /// \brief Return a (temporary) clone of this.
69   TempMDLocation clone() const { return cloneImpl(); }
70
71   unsigned getLine() const { return SubclassData32; }
72   unsigned getColumn() const { return SubclassData16; }
73   Metadata *getScope() const { return getOperand(0); }
74   Metadata *getInlinedAt() const {
75     if (getNumOperands() == 2)
76       return getOperand(1);
77     return nullptr;
78   }
79
80   static bool classof(const Metadata *MD) {
81     return MD->getMetadataID() == MDLocationKind;
82   }
83 };
84
85 /// \brief Tagged DWARF-like metadata node.
86 ///
87 /// A metadata node with a DWARF tag (i.e., a constant named \c DW_TAG_*,
88 /// defined in llvm/Support/Dwarf.h).  Called \a DebugNode because it's
89 /// potentially used for non-DWARF output.
90 class DebugNode : public MDNode {
91   friend class LLVMContextImpl;
92   friend class MDNode;
93
94 protected:
95   DebugNode(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
96             ArrayRef<Metadata *> Ops1, ArrayRef<Metadata *> Ops2 = None)
97       : MDNode(C, ID, Storage, Ops1, Ops2) {
98     assert(Tag < 1u << 16);
99     SubclassData16 = Tag;
100   }
101   ~DebugNode() {}
102
103 public:
104   unsigned getTag() const { return SubclassData16; }
105
106   static bool classof(const Metadata *MD) {
107     return MD->getMetadataID() == GenericDebugNodeKind;
108   }
109 };
110
111 /// \brief Generic tagged DWARF-like metadata node.
112 ///
113 /// An un-specialized DWARF-like metadata node.  The first operand is a
114 /// (possibly empty) null-separated \a MDString header that contains arbitrary
115 /// fields.  The remaining operands are \a dwarf_operands(), and are pointers
116 /// to other metadata.
117 class GenericDebugNode : public DebugNode {
118   friend class LLVMContextImpl;
119   friend class MDNode;
120
121   GenericDebugNode(LLVMContext &C, StorageType Storage, unsigned Hash,
122                    unsigned Tag, ArrayRef<Metadata *> Ops1,
123                    ArrayRef<Metadata *> Ops2)
124       : DebugNode(C, GenericDebugNodeKind, Storage, Tag, Ops1, Ops2) {
125     setHash(Hash);
126   }
127   ~GenericDebugNode() { dropAllReferences(); }
128
129   void setHash(unsigned Hash) { SubclassData32 = Hash; }
130   void recalculateHash();
131
132   static GenericDebugNode *getImpl(LLVMContext &Context, unsigned Tag,
133                                    StringRef Header,
134                                    ArrayRef<Metadata *> DwarfOps,
135                                    StorageType Storage,
136                                    bool ShouldCreate = true);
137
138   TempGenericDebugNode cloneImpl() const {
139     return getTemporary(
140         getContext(), getTag(), getHeader(),
141         SmallVector<Metadata *, 4>(dwarf_op_begin(), dwarf_op_end()));
142   }
143
144 public:
145   unsigned getHash() const { return SubclassData32; }
146
147   static GenericDebugNode *get(LLVMContext &Context, unsigned Tag,
148                                StringRef Header,
149                                ArrayRef<Metadata *> DwarfOps) {
150     return getImpl(Context, Tag, Header, DwarfOps, Uniqued);
151   }
152   static GenericDebugNode *getIfExists(LLVMContext &Context, unsigned Tag,
153                                        StringRef Header,
154                                        ArrayRef<Metadata *> DwarfOps) {
155     return getImpl(Context, Tag, Header, DwarfOps, Uniqued,
156                    /* ShouldCreate */ false);
157   }
158   static GenericDebugNode *getDistinct(LLVMContext &Context, unsigned Tag,
159                                        StringRef Header,
160                                        ArrayRef<Metadata *> DwarfOps) {
161     return getImpl(Context, Tag, Header, DwarfOps, Distinct);
162   }
163   static TempGenericDebugNode getTemporary(LLVMContext &Context, unsigned Tag,
164                                            StringRef Header,
165                                            ArrayRef<Metadata *> DwarfOps) {
166     return TempGenericDebugNode(
167         getImpl(Context, Tag, Header, DwarfOps, Temporary));
168   }
169
170   /// \brief Return a (temporary) clone of this.
171   TempGenericDebugNode clone() const { return cloneImpl(); }
172
173   unsigned getTag() const { return SubclassData16; }
174   StringRef getHeader() const {
175     if (auto *S = cast_or_null<MDString>(getOperand(0)))
176       return S->getString();
177     return StringRef();
178   }
179
180   op_iterator dwarf_op_begin() const { return op_begin() + 1; }
181   op_iterator dwarf_op_end() const { return op_end(); }
182   op_range dwarf_operands() const {
183     return op_range(dwarf_op_begin(), dwarf_op_end());
184   }
185
186   unsigned getNumDwarfOperands() const { return getNumOperands() - 1; }
187   const MDOperand &getDwarfOperand(unsigned I) const {
188     return getOperand(I + 1);
189   }
190   void replaceDwarfOperandWith(unsigned I, Metadata *New) {
191     replaceOperandWith(I + 1, New);
192   }
193
194   static bool classof(const Metadata *MD) {
195     return MD->getMetadataID() == GenericDebugNodeKind;
196   }
197 };
198
199 } // end namespace llvm
200
201 #endif