Mercurial > hg > CbC > CbC_llvm
comparison include/llvm/IR/DebugInfo.h @ 83:60c9769439b8 LLVM3.7
LLVM 3.7
author | Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 18 Feb 2015 14:55:36 +0900 |
parents | 54457678186b |
children | afa8332a0e37 |
comparison
equal
deleted
inserted
replaced
78:af83660cff7b | 83:60c9769439b8 |
---|---|
16 | 16 |
17 #ifndef LLVM_IR_DEBUGINFO_H | 17 #ifndef LLVM_IR_DEBUGINFO_H |
18 #define LLVM_IR_DEBUGINFO_H | 18 #define LLVM_IR_DEBUGINFO_H |
19 | 19 |
20 #include "llvm/ADT/DenseMap.h" | 20 #include "llvm/ADT/DenseMap.h" |
21 #include "llvm/ADT/iterator_range.h" | |
22 #include "llvm/ADT/SmallPtrSet.h" | 21 #include "llvm/ADT/SmallPtrSet.h" |
23 #include "llvm/ADT/SmallVector.h" | 22 #include "llvm/ADT/SmallVector.h" |
24 #include "llvm/ADT/StringRef.h" | 23 #include "llvm/ADT/StringRef.h" |
25 #include "llvm/IR/Metadata.h" | 24 #include "llvm/ADT/iterator_range.h" |
25 #include "llvm/IR/DebugInfoMetadata.h" | |
26 #include "llvm/Support/Casting.h" | 26 #include "llvm/Support/Casting.h" |
27 #include "llvm/Support/Dwarf.h" | 27 #include "llvm/Support/Dwarf.h" |
28 #include "llvm/Support/ErrorHandling.h" | |
29 #include <iterator> | |
28 | 30 |
29 namespace llvm { | 31 namespace llvm { |
30 class BasicBlock; | 32 class BasicBlock; |
31 class Constant; | 33 class Constant; |
32 class Function; | 34 class Function; |
35 class Type; | 37 class Type; |
36 class Value; | 38 class Value; |
37 class DbgDeclareInst; | 39 class DbgDeclareInst; |
38 class DbgValueInst; | 40 class DbgValueInst; |
39 class Instruction; | 41 class Instruction; |
42 class Metadata; | |
40 class MDNode; | 43 class MDNode; |
41 class MDString; | 44 class MDString; |
42 class NamedMDNode; | 45 class NamedMDNode; |
43 class LLVMContext; | 46 class LLVMContext; |
44 class raw_ostream; | 47 class raw_ostream; |
50 class DIVariable; | 53 class DIVariable; |
51 class DIType; | 54 class DIType; |
52 class DIScope; | 55 class DIScope; |
53 class DIObjCProperty; | 56 class DIObjCProperty; |
54 | 57 |
55 /// Maps from type identifier to the actual MDNode. | 58 /// \brief Maps from type identifier to the actual MDNode. |
56 typedef DenseMap<const MDString *, MDNode *> DITypeIdentifierMap; | 59 typedef DenseMap<const MDString *, MDNode *> DITypeIdentifierMap; |
57 | 60 |
58 /// DIDescriptor - A thin wraper around MDNode to access encoded debug info. | 61 class DIHeaderFieldIterator |
59 /// This should not be stored in a container, because the underlying MDNode | 62 : public std::iterator<std::input_iterator_tag, StringRef, std::ptrdiff_t, |
60 /// may change in certain situations. | 63 const StringRef *, StringRef> { |
64 StringRef Header; | |
65 StringRef Current; | |
66 | |
67 public: | |
68 DIHeaderFieldIterator() {} | |
69 explicit DIHeaderFieldIterator(StringRef Header) | |
70 : Header(Header), Current(Header.slice(0, Header.find('\0'))) {} | |
71 StringRef operator*() const { return Current; } | |
72 const StringRef *operator->() const { return &Current; } | |
73 DIHeaderFieldIterator &operator++() { | |
74 increment(); | |
75 return *this; | |
76 } | |
77 DIHeaderFieldIterator operator++(int) { | |
78 DIHeaderFieldIterator X(*this); | |
79 increment(); | |
80 return X; | |
81 } | |
82 bool operator==(const DIHeaderFieldIterator &X) const { | |
83 return Current.data() == X.Current.data(); | |
84 } | |
85 bool operator!=(const DIHeaderFieldIterator &X) const { | |
86 return !(*this == X); | |
87 } | |
88 | |
89 StringRef getHeader() const { return Header; } | |
90 StringRef getCurrent() const { return Current; } | |
91 StringRef getPrefix() const { | |
92 if (Current.begin() == Header.begin()) | |
93 return StringRef(); | |
94 return Header.slice(0, Current.begin() - Header.begin() - 1); | |
95 } | |
96 StringRef getSuffix() const { | |
97 if (Current.end() == Header.end()) | |
98 return StringRef(); | |
99 return Header.slice(Current.end() - Header.begin() + 1, StringRef::npos); | |
100 } | |
101 | |
102 /// \brief Get the current field as a number. | |
103 /// | |
104 /// Convert the current field into a number. Return \c 0 on error. | |
105 template <class T> T getNumber() const { | |
106 T Int; | |
107 if (getCurrent().getAsInteger(0, Int)) | |
108 return 0; | |
109 return Int; | |
110 } | |
111 | |
112 private: | |
113 void increment() { | |
114 assert(Current.data() != nullptr && "Cannot increment past the end"); | |
115 StringRef Suffix = getSuffix(); | |
116 Current = Suffix.slice(0, Suffix.find('\0')); | |
117 } | |
118 }; | |
119 | |
120 /// \brief A thin wraper around MDNode to access encoded debug info. | |
121 /// | |
122 /// This should not be stored in a container, because the underlying MDNode may | |
123 /// change in certain situations. | |
61 class DIDescriptor { | 124 class DIDescriptor { |
62 // Befriends DIRef so DIRef can befriend the protected member | 125 // Befriends DIRef so DIRef can befriend the protected member |
63 // function: getFieldAs<DIRef>. | 126 // function: getFieldAs<DIRef>. |
64 template <typename T> friend class DIRef; | 127 template <typename T> friend class DIRef; |
65 | 128 |
66 public: | 129 public: |
67 /// The three accessibility flags are mutually exclusive and rolled | 130 /// \brief Accessibility flags. |
68 /// together in the first two bits. | 131 /// |
132 /// The three accessibility flags are mutually exclusive and rolled together | |
133 /// in the first two bits. | |
69 enum { | 134 enum { |
70 FlagAccessibility = 1 << 0 | 1 << 1, | 135 FlagAccessibility = 1 << 0 | 1 << 1, |
71 FlagPrivate = 1, | 136 FlagPrivate = 1, |
72 FlagProtected = 2, | 137 FlagProtected = 2, |
73 FlagPublic = 3, | 138 FlagPublic = 3, |
81 FlagPrototyped = 1 << 8, | 146 FlagPrototyped = 1 << 8, |
82 FlagObjcClassComplete = 1 << 9, | 147 FlagObjcClassComplete = 1 << 9, |
83 FlagObjectPointer = 1 << 10, | 148 FlagObjectPointer = 1 << 10, |
84 FlagVector = 1 << 11, | 149 FlagVector = 1 << 11, |
85 FlagStaticMember = 1 << 12, | 150 FlagStaticMember = 1 << 12, |
86 FlagIndirectVariable = 1 << 13, | 151 FlagLValueReference = 1 << 13, |
87 FlagLValueReference = 1 << 14, | 152 FlagRValueReference = 1 << 14 |
88 FlagRValueReference = 1 << 15 | |
89 }; | 153 }; |
90 | 154 |
91 protected: | 155 protected: |
92 const MDNode *DbgNode; | 156 const MDNode *DbgNode; |
93 | 157 |
111 public: | 175 public: |
112 explicit DIDescriptor(const MDNode *N = nullptr) : DbgNode(N) {} | 176 explicit DIDescriptor(const MDNode *N = nullptr) : DbgNode(N) {} |
113 | 177 |
114 bool Verify() const; | 178 bool Verify() const; |
115 | 179 |
116 operator MDNode *() const { return const_cast<MDNode *>(DbgNode); } | 180 MDNode *get() const { return const_cast<MDNode *>(DbgNode); } |
117 MDNode *operator->() const { return const_cast<MDNode *>(DbgNode); } | 181 operator MDNode *() const { return get(); } |
182 MDNode *operator->() const { return get(); } | |
118 | 183 |
119 // An explicit operator bool so that we can do testing of DI values | 184 // An explicit operator bool so that we can do testing of DI values |
120 // easily. | 185 // easily. |
121 // FIXME: This operator bool isn't actually protecting anything at the | 186 // FIXME: This operator bool isn't actually protecting anything at the |
122 // moment due to the conversion operator above making DIDescriptor nodes | 187 // moment due to the conversion operator above making DIDescriptor nodes |
123 // implicitly convertable to bool. | 188 // implicitly convertable to bool. |
124 LLVM_EXPLICIT operator bool() const { return DbgNode != nullptr; } | 189 explicit operator bool() const { return DbgNode != nullptr; } |
125 | 190 |
126 bool operator==(DIDescriptor Other) const { return DbgNode == Other.DbgNode; } | 191 bool operator==(DIDescriptor Other) const { return DbgNode == Other.DbgNode; } |
127 bool operator!=(DIDescriptor Other) const { return !operator==(Other); } | 192 bool operator!=(DIDescriptor Other) const { return !operator==(Other); } |
128 | 193 |
129 uint16_t getTag() const { | 194 StringRef getHeader() const { return getStringField(0); } |
130 return getUnsignedField(0) & ~LLVMDebugVersionMask; | 195 |
131 } | 196 size_t getNumHeaderFields() const { |
197 return std::distance(DIHeaderFieldIterator(getHeader()), | |
198 DIHeaderFieldIterator()); | |
199 } | |
200 | |
201 DIHeaderFieldIterator header_begin() const { | |
202 return DIHeaderFieldIterator(getHeader()); | |
203 } | |
204 DIHeaderFieldIterator header_end() const { return DIHeaderFieldIterator(); } | |
205 | |
206 DIHeaderFieldIterator getHeaderIterator(unsigned Index) const { | |
207 // Since callers expect an empty string for out-of-range accesses, we can't | |
208 // use std::advance() here. | |
209 for (auto I = header_begin(), E = header_end(); I != E; ++I, --Index) | |
210 if (!Index) | |
211 return I; | |
212 return header_end(); | |
213 } | |
214 | |
215 StringRef getHeaderField(unsigned Index) const { | |
216 return *getHeaderIterator(Index); | |
217 } | |
218 | |
219 template <class T> T getHeaderFieldAs(unsigned Index) const { | |
220 return getHeaderIterator(Index).getNumber<T>(); | |
221 } | |
222 | |
223 uint16_t getTag() const { return getHeaderFieldAs<uint16_t>(0); } | |
132 | 224 |
133 bool isDerivedType() const; | 225 bool isDerivedType() const; |
134 bool isCompositeType() const; | 226 bool isCompositeType() const; |
135 bool isSubroutineType() const; | 227 bool isSubroutineType() const; |
136 bool isBasicType() const; | 228 bool isBasicType() const; |
148 bool isType() const; | 240 bool isType() const; |
149 bool isTemplateTypeParameter() const; | 241 bool isTemplateTypeParameter() const; |
150 bool isTemplateValueParameter() const; | 242 bool isTemplateValueParameter() const; |
151 bool isObjCProperty() const; | 243 bool isObjCProperty() const; |
152 bool isImportedEntity() const; | 244 bool isImportedEntity() const; |
153 | 245 bool isExpression() const; |
154 /// print - print descriptor. | 246 |
155 void print(raw_ostream &OS) const; | 247 void print(raw_ostream &OS) const; |
156 | |
157 /// dump - print descriptor to dbgs() with a newline. | |
158 void dump() const; | 248 void dump() const; |
159 }; | 249 |
160 | 250 /// \brief Replace all uses of debug info referenced by this descriptor. |
161 /// DISubrange - This is used to represent ranges, for array bounds. | 251 void replaceAllUsesWith(LLVMContext &VMContext, DIDescriptor D); |
252 void replaceAllUsesWith(MDNode *D); | |
253 }; | |
254 | |
255 /// \brief This is used to represent ranges, for array bounds. | |
162 class DISubrange : public DIDescriptor { | 256 class DISubrange : public DIDescriptor { |
163 friend class DIDescriptor; | 257 friend class DIDescriptor; |
164 void printInternal(raw_ostream &OS) const; | 258 void printInternal(raw_ostream &OS) const; |
165 | 259 |
166 public: | 260 public: |
167 explicit DISubrange(const MDNode *N = nullptr) : DIDescriptor(N) {} | 261 explicit DISubrange(const MDNode *N = nullptr) : DIDescriptor(N) {} |
168 | 262 |
169 int64_t getLo() const { return getInt64Field(1); } | 263 int64_t getLo() const { return getHeaderFieldAs<int64_t>(1); } |
170 int64_t getCount() const { return getInt64Field(2); } | 264 int64_t getCount() const { return getHeaderFieldAs<int64_t>(2); } |
171 bool Verify() const; | 265 bool Verify() const; |
172 }; | 266 }; |
173 | 267 |
174 /// DITypedArray - This descriptor holds an array of nodes with type T. | 268 /// \brief This descriptor holds an array of nodes with type T. |
175 template <typename T> class DITypedArray : public DIDescriptor { | 269 template <typename T> class DITypedArray : public DIDescriptor { |
176 public: | 270 public: |
177 explicit DITypedArray(const MDNode *N = nullptr) : DIDescriptor(N) {} | 271 explicit DITypedArray(const MDNode *N = nullptr) : DIDescriptor(N) {} |
178 unsigned getNumElements() const { | 272 unsigned getNumElements() const { |
179 return DbgNode ? DbgNode->getNumOperands() : 0; | 273 return DbgNode ? DbgNode->getNumOperands() : 0; |
180 } | 274 } |
181 T getElement(unsigned Idx) const { | 275 T getElement(unsigned Idx) const { return getFieldAs<T>(Idx); } |
182 return getFieldAs<T>(Idx); | |
183 } | |
184 }; | 276 }; |
185 | 277 |
186 typedef DITypedArray<DIDescriptor> DIArray; | 278 typedef DITypedArray<DIDescriptor> DIArray; |
187 | 279 |
188 /// DIEnumerator - A wrapper for an enumerator (e.g. X and Y in 'enum {X,Y}'). | 280 /// \brief A wrapper for an enumerator (e.g. X and Y in 'enum {X,Y}'). |
281 /// | |
189 /// FIXME: it seems strange that this doesn't have either a reference to the | 282 /// FIXME: it seems strange that this doesn't have either a reference to the |
190 /// type/precision or a file/line pair for location info. | 283 /// type/precision or a file/line pair for location info. |
191 class DIEnumerator : public DIDescriptor { | 284 class DIEnumerator : public DIDescriptor { |
192 friend class DIDescriptor; | 285 friend class DIDescriptor; |
193 void printInternal(raw_ostream &OS) const; | 286 void printInternal(raw_ostream &OS) const; |
194 | 287 |
195 public: | 288 public: |
196 explicit DIEnumerator(const MDNode *N = nullptr) : DIDescriptor(N) {} | 289 explicit DIEnumerator(const MDNode *N = nullptr) : DIDescriptor(N) {} |
197 | 290 |
198 StringRef getName() const { return getStringField(1); } | 291 StringRef getName() const { return getHeaderField(1); } |
199 int64_t getEnumValue() const { return getInt64Field(2); } | 292 int64_t getEnumValue() const { return getHeaderFieldAs<int64_t>(2); } |
200 bool Verify() const; | 293 bool Verify() const; |
201 }; | 294 }; |
202 | 295 |
203 template <typename T> class DIRef; | 296 template <typename T> class DIRef; |
204 typedef DIRef<DIScope> DIScopeRef; | 297 typedef DIRef<DIScope> DIScopeRef; |
205 typedef DIRef<DIType> DITypeRef; | 298 typedef DIRef<DIType> DITypeRef; |
206 typedef DITypedArray<DITypeRef> DITypeArray; | 299 typedef DITypedArray<DITypeRef> DITypeArray; |
207 | 300 |
208 /// DIScope - A base class for various scopes. | 301 /// \brief A base class for various scopes. |
209 /// | 302 /// |
210 /// Although, implementation-wise, DIScope is the parent class of most | 303 /// Although, implementation-wise, DIScope is the parent class of most |
211 /// other DIxxx classes, including DIType and its descendants, most of | 304 /// other DIxxx classes, including DIType and its descendants, most of |
212 /// DIScope's descendants are not a substitutable subtype of | 305 /// DIScope's descendants are not a substitutable subtype of |
213 /// DIScope. The DIDescriptor::isScope() method only is true for | 306 /// DIScope. The DIDescriptor::isScope() method only is true for |
219 void printInternal(raw_ostream &OS) const; | 312 void printInternal(raw_ostream &OS) const; |
220 | 313 |
221 public: | 314 public: |
222 explicit DIScope(const MDNode *N = nullptr) : DIDescriptor(N) {} | 315 explicit DIScope(const MDNode *N = nullptr) : DIDescriptor(N) {} |
223 | 316 |
224 /// Gets the parent scope for this scope node or returns a | 317 /// \brief Get the parent scope. |
225 /// default constructed scope. | 318 /// |
319 /// Gets the parent scope for this scope node or returns a default | |
320 /// constructed scope. | |
226 DIScopeRef getContext() const; | 321 DIScopeRef getContext() const; |
322 /// \brief Get the scope name. | |
323 /// | |
227 /// If the scope node has a name, return that, else return an empty string. | 324 /// If the scope node has a name, return that, else return an empty string. |
228 StringRef getName() const; | 325 StringRef getName() const; |
229 StringRef getFilename() const; | 326 StringRef getFilename() const; |
230 StringRef getDirectory() const; | 327 StringRef getDirectory() const; |
231 | 328 |
232 /// Generate a reference to this DIScope. Uses the type identifier instead | 329 /// \brief Generate a reference to this DIScope. |
233 /// of the actual MDNode if possible, to help type uniquing. | 330 /// |
331 /// Uses the type identifier instead of the actual MDNode if possible, to | |
332 /// help type uniquing. | |
234 DIScopeRef getRef() const; | 333 DIScopeRef getRef() const; |
235 }; | 334 }; |
236 | 335 |
237 /// Represents reference to a DIDescriptor, abstracts over direct and | 336 /// \brief Represents reference to a DIDescriptor. |
238 /// identifier-based metadata references. | 337 /// |
338 /// Abstracts over direct and identifier-based metadata references. | |
239 template <typename T> class DIRef { | 339 template <typename T> class DIRef { |
240 template <typename DescTy> | 340 template <typename DescTy> |
241 friend DescTy DIDescriptor::getFieldAs(unsigned Elt) const; | 341 friend DescTy DIDescriptor::getFieldAs(unsigned Elt) const; |
242 friend DIScopeRef DIScope::getContext() const; | 342 friend DIScopeRef DIScope::getContext() const; |
243 friend DIScopeRef DIScope::getRef() const; | 343 friend DIScopeRef DIScope::getRef() const; |
244 friend class DIType; | 344 friend class DIType; |
245 | 345 |
246 /// Val can be either a MDNode or a MDString, in the latter, | 346 /// \brief Val can be either a MDNode or a MDString. |
247 /// MDString specifies the type identifier. | 347 /// |
248 const Value *Val; | 348 /// In the latter, MDString specifies the type identifier. |
249 explicit DIRef(const Value *V); | 349 const Metadata *Val; |
350 explicit DIRef(const Metadata *V); | |
250 | 351 |
251 public: | 352 public: |
252 T resolve(const DITypeIdentifierMap &Map) const; | 353 T resolve(const DITypeIdentifierMap &Map) const; |
253 StringRef getName() const; | 354 StringRef getName() const; |
254 operator Value *() const { return const_cast<Value *>(Val); } | 355 operator Metadata *() const { return const_cast<Metadata *>(Val); } |
255 }; | 356 }; |
256 | 357 |
257 template <typename T> | 358 template <typename T> |
258 T DIRef<T>::resolve(const DITypeIdentifierMap &Map) const { | 359 T DIRef<T>::resolve(const DITypeIdentifierMap &Map) const { |
259 if (!Val) | 360 if (!Val) |
280 | 381 |
281 const MDString *MS = cast<MDString>(Val); | 382 const MDString *MS = cast<MDString>(Val); |
282 return MS->getString(); | 383 return MS->getString(); |
283 } | 384 } |
284 | 385 |
285 /// Specialize getFieldAs to handle fields that are references to DIScopes. | 386 /// \brief Handle fields that are references to DIScopes. |
286 template <> DIScopeRef DIDescriptor::getFieldAs<DIScopeRef>(unsigned Elt) const; | 387 template <> DIScopeRef DIDescriptor::getFieldAs<DIScopeRef>(unsigned Elt) const; |
287 /// Specialize DIRef constructor for DIScopeRef. | 388 /// \brief Specialize DIRef constructor for DIScopeRef. |
288 template <> DIRef<DIScope>::DIRef(const Value *V); | 389 template <> DIRef<DIScope>::DIRef(const Metadata *V); |
289 | 390 |
290 /// Specialize getFieldAs to handle fields that are references to DITypes. | 391 /// \brief Handle fields that are references to DITypes. |
291 template <> DITypeRef DIDescriptor::getFieldAs<DITypeRef>(unsigned Elt) const; | 392 template <> DITypeRef DIDescriptor::getFieldAs<DITypeRef>(unsigned Elt) const; |
292 /// Specialize DIRef constructor for DITypeRef. | 393 /// \brief Specialize DIRef constructor for DITypeRef. |
293 template <> DIRef<DIType>::DIRef(const Value *V); | 394 template <> DIRef<DIType>::DIRef(const Metadata *V); |
294 | 395 |
295 /// DIType - This is a wrapper for a type. | 396 /// \brief This is a wrapper for a type. |
397 /// | |
296 /// FIXME: Types should be factored much better so that CV qualifiers and | 398 /// FIXME: Types should be factored much better so that CV qualifiers and |
297 /// others do not require a huge and empty descriptor full of zeros. | 399 /// others do not require a huge and empty descriptor full of zeros. |
298 class DIType : public DIScope { | 400 class DIType : public DIScope { |
299 protected: | 401 protected: |
300 friend class DIDescriptor; | 402 friend class DIDescriptor; |
301 void printInternal(raw_ostream &OS) const; | 403 void printInternal(raw_ostream &OS) const; |
302 | 404 |
303 public: | 405 public: |
304 explicit DIType(const MDNode *N = nullptr) : DIScope(N) {} | 406 explicit DIType(const MDNode *N = nullptr) : DIScope(N) {} |
305 operator DITypeRef () const { | 407 operator DITypeRef() const { |
306 assert(isType() && | 408 assert(isType() && |
307 "constructing DITypeRef from an MDNode that is not a type"); | 409 "constructing DITypeRef from an MDNode that is not a type"); |
308 return DITypeRef(&*getRef()); | 410 return DITypeRef(&*getRef()); |
309 } | 411 } |
310 | 412 |
311 /// Verify - Verify that a type descriptor is well formed. | |
312 bool Verify() const; | 413 bool Verify() const; |
313 | 414 |
314 DIScopeRef getContext() const { return getFieldAs<DIScopeRef>(2); } | 415 DIScopeRef getContext() const { return getFieldAs<DIScopeRef>(2); } |
315 StringRef getName() const { return getStringField(3); } | 416 StringRef getName() const { return getHeaderField(1); } |
316 unsigned getLineNumber() const { return getUnsignedField(4); } | 417 unsigned getLineNumber() const { return getHeaderFieldAs<unsigned>(2); } |
317 uint64_t getSizeInBits() const { return getUInt64Field(5); } | 418 uint64_t getSizeInBits() const { return getHeaderFieldAs<unsigned>(3); } |
318 uint64_t getAlignInBits() const { return getUInt64Field(6); } | 419 uint64_t getAlignInBits() const { return getHeaderFieldAs<unsigned>(4); } |
319 // FIXME: Offset is only used for DW_TAG_member nodes. Making every type | 420 // FIXME: Offset is only used for DW_TAG_member nodes. Making every type |
320 // carry this is just plain insane. | 421 // carry this is just plain insane. |
321 uint64_t getOffsetInBits() const { return getUInt64Field(7); } | 422 uint64_t getOffsetInBits() const { return getHeaderFieldAs<unsigned>(5); } |
322 unsigned getFlags() const { return getUnsignedField(8); } | 423 unsigned getFlags() const { return getHeaderFieldAs<unsigned>(6); } |
323 bool isPrivate() const { | 424 bool isPrivate() const { |
324 return (getFlags() & FlagAccessibility) == FlagPrivate; | 425 return (getFlags() & FlagAccessibility) == FlagPrivate; |
325 } | 426 } |
326 bool isProtected() const { | 427 bool isProtected() const { |
327 return (getFlags() & FlagAccessibility) == FlagProtected; | 428 return (getFlags() & FlagAccessibility) == FlagProtected; |
328 } | 429 } |
329 bool isPublic() const { | 430 bool isPublic() const { |
330 return (getFlags() & FlagAccessibility) == FlagPublic; | 431 return (getFlags() & FlagAccessibility) == FlagPublic; |
331 } | 432 } |
332 bool isForwardDecl() const { return (getFlags() & FlagFwdDecl) != 0; } | 433 bool isForwardDecl() const { return (getFlags() & FlagFwdDecl) != 0; } |
333 // isAppleBlock - Return true if this is the Apple Blocks extension. | |
334 bool isAppleBlockExtension() const { | 434 bool isAppleBlockExtension() const { |
335 return (getFlags() & FlagAppleBlock) != 0; | 435 return (getFlags() & FlagAppleBlock) != 0; |
336 } | 436 } |
337 bool isBlockByrefStruct() const { | 437 bool isBlockByrefStruct() const { |
338 return (getFlags() & FlagBlockByrefStruct) != 0; | 438 return (getFlags() & FlagBlockByrefStruct) != 0; |
350 } | 450 } |
351 bool isRValueReference() const { | 451 bool isRValueReference() const { |
352 return (getFlags() & FlagRValueReference) != 0; | 452 return (getFlags() & FlagRValueReference) != 0; |
353 } | 453 } |
354 bool isValid() const { return DbgNode && isType(); } | 454 bool isValid() const { return DbgNode && isType(); } |
355 | 455 }; |
356 /// replaceAllUsesWith - Replace all uses of debug info referenced by | 456 |
357 /// this descriptor. | 457 /// \brief A basic type, like 'int' or 'float'. |
358 void replaceAllUsesWith(LLVMContext &VMContext, DIDescriptor D); | |
359 void replaceAllUsesWith(MDNode *D); | |
360 }; | |
361 | |
362 /// DIBasicType - A basic type, like 'int' or 'float'. | |
363 class DIBasicType : public DIType { | 458 class DIBasicType : public DIType { |
364 public: | 459 public: |
365 explicit DIBasicType(const MDNode *N = nullptr) : DIType(N) {} | 460 explicit DIBasicType(const MDNode *N = nullptr) : DIType(N) {} |
366 | 461 |
367 unsigned getEncoding() const { return getUnsignedField(9); } | 462 unsigned getEncoding() const { return getHeaderFieldAs<unsigned>(7); } |
368 | 463 |
369 /// Verify - Verify that a basic type descriptor is well formed. | 464 bool Verify() const; |
370 bool Verify() const; | 465 }; |
371 }; | 466 |
372 | 467 /// \brief A simple derived type |
373 /// DIDerivedType - A simple derived type, like a const qualified type, | 468 /// |
374 /// a typedef, a pointer or reference, et cetera. Or, a data member of | 469 /// Like a const qualified type, a typedef, a pointer or reference, et cetera. |
375 /// a class/struct/union. | 470 /// Or, a data member of a class/struct/union. |
376 class DIDerivedType : public DIType { | 471 class DIDerivedType : public DIType { |
377 friend class DIDescriptor; | 472 friend class DIDescriptor; |
378 void printInternal(raw_ostream &OS) const; | 473 void printInternal(raw_ostream &OS) const; |
379 | 474 |
380 public: | 475 public: |
381 explicit DIDerivedType(const MDNode *N = nullptr) : DIType(N) {} | 476 explicit DIDerivedType(const MDNode *N = nullptr) : DIType(N) {} |
382 | 477 |
383 DITypeRef getTypeDerivedFrom() const { return getFieldAs<DITypeRef>(9); } | 478 DITypeRef getTypeDerivedFrom() const { return getFieldAs<DITypeRef>(3); } |
384 | 479 |
385 /// getObjCProperty - Return property node, if this ivar is | 480 /// \brief Return property node, if this ivar is associated with one. |
386 /// associated with one. | |
387 MDNode *getObjCProperty() const; | 481 MDNode *getObjCProperty() const; |
388 | 482 |
389 DITypeRef getClassType() const { | 483 DITypeRef getClassType() const { |
390 assert(getTag() == dwarf::DW_TAG_ptr_to_member_type); | 484 assert(getTag() == dwarf::DW_TAG_ptr_to_member_type); |
391 return getFieldAs<DITypeRef>(10); | 485 return getFieldAs<DITypeRef>(4); |
392 } | 486 } |
393 | 487 |
394 Constant *getConstant() const { | 488 Constant *getConstant() const { |
395 assert((getTag() == dwarf::DW_TAG_member) && isStaticMember()); | 489 assert((getTag() == dwarf::DW_TAG_member) && isStaticMember()); |
396 return getConstantField(10); | 490 return getConstantField(4); |
397 } | 491 } |
398 | 492 |
399 /// Verify - Verify that a derived type descriptor is well formed. | 493 bool Verify() const; |
400 bool Verify() const; | 494 }; |
401 }; | 495 |
402 | 496 /// \brief Types that refer to multiple other types. |
403 /// DICompositeType - This descriptor holds a type that can refer to multiple | 497 /// |
404 /// other types, like a function or struct. | 498 /// This descriptor holds a type that can refer to multiple other types, like a |
499 /// function or struct. | |
500 /// | |
405 /// DICompositeType is derived from DIDerivedType because some | 501 /// DICompositeType is derived from DIDerivedType because some |
406 /// composite types (such as enums) can be derived from basic types | 502 /// composite types (such as enums) can be derived from basic types |
407 // FIXME: Make this derive from DIType directly & just store the | 503 // FIXME: Make this derive from DIType directly & just store the |
408 // base type in a single DIType field. | 504 // base type in a single DIType field. |
409 class DICompositeType : public DIDerivedType { | 505 class DICompositeType : public DIDerivedType { |
410 friend class DIDescriptor; | 506 friend class DIBuilder; |
411 void printInternal(raw_ostream &OS) const; | 507 friend class DIDescriptor; |
508 void printInternal(raw_ostream &OS) const; | |
509 | |
510 /// \brief Set the array of member DITypes. | |
412 void setArraysHelper(MDNode *Elements, MDNode *TParams); | 511 void setArraysHelper(MDNode *Elements, MDNode *TParams); |
413 | 512 |
414 public: | 513 public: |
415 explicit DICompositeType(const MDNode *N = nullptr) : DIDerivedType(N) {} | 514 explicit DICompositeType(const MDNode *N = nullptr) : DIDerivedType(N) {} |
416 | 515 |
417 DIArray getElements() const { | 516 DIArray getElements() const { |
418 assert(!isSubroutineType() && "no elements for DISubroutineType"); | 517 assert(!isSubroutineType() && "no elements for DISubroutineType"); |
419 return getFieldAs<DIArray>(10); | 518 return getFieldAs<DIArray>(4); |
420 } | 519 } |
520 | |
521 private: | |
421 template <typename T> | 522 template <typename T> |
422 void setArrays(DITypedArray<T> Elements, DIArray TParams = DIArray()) { | 523 void setArrays(DITypedArray<T> Elements, DIArray TParams = DIArray()) { |
423 assert((!TParams || DbgNode->getNumOperands() == 15) && | 524 assert( |
424 "If you're setting the template parameters this should include a slot " | 525 (!TParams || DbgNode->getNumOperands() == 8) && |
425 "for that!"); | 526 "If you're setting the template parameters this should include a slot " |
527 "for that!"); | |
426 setArraysHelper(Elements, TParams); | 528 setArraysHelper(Elements, TParams); |
427 } | 529 } |
428 unsigned getRunTimeLang() const { return getUnsignedField(11); } | 530 |
429 DITypeRef getContainingType() const { return getFieldAs<DITypeRef>(12); } | 531 public: |
532 unsigned getRunTimeLang() const { return getHeaderFieldAs<unsigned>(7); } | |
533 DITypeRef getContainingType() const { return getFieldAs<DITypeRef>(5); } | |
534 | |
535 private: | |
536 /// \brief Set the containing type. | |
430 void setContainingType(DICompositeType ContainingType); | 537 void setContainingType(DICompositeType ContainingType); |
431 DIArray getTemplateParams() const { return getFieldAs<DIArray>(13); } | 538 |
539 public: | |
540 DIArray getTemplateParams() const { return getFieldAs<DIArray>(6); } | |
432 MDString *getIdentifier() const; | 541 MDString *getIdentifier() const; |
433 | 542 |
434 /// Verify - Verify that a composite type descriptor is well formed. | |
435 bool Verify() const; | 543 bool Verify() const; |
436 }; | 544 }; |
437 | 545 |
438 class DISubroutineType : public DICompositeType { | 546 class DISubroutineType : public DICompositeType { |
439 public: | 547 public: |
440 explicit DISubroutineType(const MDNode *N = nullptr) : DICompositeType(N) {} | 548 explicit DISubroutineType(const MDNode *N = nullptr) : DICompositeType(N) {} |
441 DITypedArray<DITypeRef> getTypeArray() const { | 549 DITypedArray<DITypeRef> getTypeArray() const { |
442 return getFieldAs<DITypedArray<DITypeRef>>(10); | 550 return getFieldAs<DITypedArray<DITypeRef>>(4); |
443 } | 551 } |
444 }; | 552 }; |
445 | 553 |
446 /// DIFile - This is a wrapper for a file. | 554 /// \brief This is a wrapper for a file. |
447 class DIFile : public DIScope { | 555 class DIFile : public DIScope { |
448 friend class DIDescriptor; | 556 friend class DIDescriptor; |
449 | 557 |
450 public: | 558 public: |
451 explicit DIFile(const MDNode *N = nullptr) : DIScope(N) {} | 559 explicit DIFile(const MDNode *N = nullptr) : DIScope(N) {} |
560 | |
561 /// \brief Retrieve the MDNode for the directory/file pair. | |
452 MDNode *getFileNode() const; | 562 MDNode *getFileNode() const; |
453 bool Verify() const; | 563 bool Verify() const; |
454 }; | 564 }; |
455 | 565 |
456 /// DICompileUnit - A wrapper for a compile unit. | 566 /// \brief A wrapper for a compile unit. |
457 class DICompileUnit : public DIScope { | 567 class DICompileUnit : public DIScope { |
458 friend class DIDescriptor; | 568 friend class DIDescriptor; |
459 void printInternal(raw_ostream &OS) const; | 569 void printInternal(raw_ostream &OS) const; |
460 | 570 |
461 public: | 571 public: |
462 explicit DICompileUnit(const MDNode *N = nullptr) : DIScope(N) {} | 572 explicit DICompileUnit(const MDNode *N = nullptr) : DIScope(N) {} |
463 | 573 |
464 dwarf::SourceLanguage getLanguage() const { | 574 dwarf::SourceLanguage getLanguage() const { |
465 return static_cast<dwarf::SourceLanguage>(getUnsignedField(2)); | 575 return static_cast<dwarf::SourceLanguage>(getHeaderFieldAs<unsigned>(1)); |
466 } | 576 } |
467 StringRef getProducer() const { return getStringField(3); } | 577 StringRef getProducer() const { return getHeaderField(2); } |
468 | 578 |
469 bool isOptimized() const { return getUnsignedField(4) != 0; } | 579 bool isOptimized() const { return getHeaderFieldAs<bool>(3) != 0; } |
470 StringRef getFlags() const { return getStringField(5); } | 580 StringRef getFlags() const { return getHeaderField(4); } |
471 unsigned getRunTimeVersion() const { return getUnsignedField(6); } | 581 unsigned getRunTimeVersion() const { return getHeaderFieldAs<unsigned>(5); } |
472 | 582 |
473 DIArray getEnumTypes() const; | 583 DIArray getEnumTypes() const; |
474 DIArray getRetainedTypes() const; | 584 DIArray getRetainedTypes() const; |
475 DIArray getSubprograms() const; | 585 DIArray getSubprograms() const; |
476 DIArray getGlobalVariables() const; | 586 DIArray getGlobalVariables() const; |
477 DIArray getImportedEntities() const; | 587 DIArray getImportedEntities() const; |
478 | 588 |
479 StringRef getSplitDebugFilename() const { return getStringField(12); } | 589 void replaceSubprograms(DIArray Subprograms); |
480 unsigned getEmissionKind() const { return getUnsignedField(13); } | 590 void replaceGlobalVariables(DIArray GlobalVariables); |
481 | 591 |
482 /// Verify - Verify that a compile unit is well formed. | 592 StringRef getSplitDebugFilename() const { return getHeaderField(6); } |
483 bool Verify() const; | 593 unsigned getEmissionKind() const { return getHeaderFieldAs<unsigned>(7); } |
484 }; | 594 |
485 | 595 bool Verify() const; |
486 /// DISubprogram - This is a wrapper for a subprogram (e.g. a function). | 596 }; |
597 | |
598 /// \brief This is a wrapper for a subprogram (e.g. a function). | |
487 class DISubprogram : public DIScope { | 599 class DISubprogram : public DIScope { |
488 friend class DIDescriptor; | 600 friend class DIDescriptor; |
489 void printInternal(raw_ostream &OS) const; | 601 void printInternal(raw_ostream &OS) const; |
490 | 602 |
491 public: | 603 public: |
492 explicit DISubprogram(const MDNode *N = nullptr) : DIScope(N) {} | 604 explicit DISubprogram(const MDNode *N = nullptr) : DIScope(N) {} |
493 | 605 |
606 StringRef getName() const { return getHeaderField(1); } | |
607 StringRef getDisplayName() const { return getHeaderField(2); } | |
608 StringRef getLinkageName() const { return getHeaderField(3); } | |
609 unsigned getLineNumber() const { return getHeaderFieldAs<unsigned>(4); } | |
610 | |
611 /// \brief Check if this is local (like 'static' in C). | |
612 unsigned isLocalToUnit() const { return getHeaderFieldAs<unsigned>(5); } | |
613 unsigned isDefinition() const { return getHeaderFieldAs<unsigned>(6); } | |
614 | |
615 unsigned getVirtuality() const { return getHeaderFieldAs<unsigned>(7); } | |
616 unsigned getVirtualIndex() const { return getHeaderFieldAs<unsigned>(8); } | |
617 | |
618 unsigned getFlags() const { return getHeaderFieldAs<unsigned>(9); } | |
619 | |
620 unsigned isOptimized() const { return getHeaderFieldAs<bool>(10); } | |
621 | |
622 /// \brief Get the beginning of the scope of the function (not the name). | |
623 unsigned getScopeLineNumber() const { return getHeaderFieldAs<unsigned>(11); } | |
624 | |
494 DIScopeRef getContext() const { return getFieldAs<DIScopeRef>(2); } | 625 DIScopeRef getContext() const { return getFieldAs<DIScopeRef>(2); } |
495 StringRef getName() const { return getStringField(3); } | 626 DISubroutineType getType() const { return getFieldAs<DISubroutineType>(3); } |
496 StringRef getDisplayName() const { return getStringField(4); } | 627 |
497 StringRef getLinkageName() const { return getStringField(5); } | 628 DITypeRef getContainingType() const { return getFieldAs<DITypeRef>(4); } |
498 unsigned getLineNumber() const { return getUnsignedField(6); } | 629 |
499 DISubroutineType getType() const { return getFieldAs<DISubroutineType>(7); } | 630 bool Verify() const; |
500 | 631 |
501 /// isLocalToUnit - Return true if this subprogram is local to the current | 632 /// \brief Check if this provides debugging information for the function F. |
502 /// compile unit, like 'static' in C. | 633 bool describes(const Function *F); |
503 unsigned isLocalToUnit() const { return getUnsignedField(8); } | 634 |
504 unsigned isDefinition() const { return getUnsignedField(9); } | 635 Function *getFunction() const { return getFunctionField(5); } |
505 | 636 void replaceFunction(Function *F) { replaceFunctionField(5, F); } |
506 unsigned getVirtuality() const { return getUnsignedField(10); } | 637 DIArray getTemplateParams() const { return getFieldAs<DIArray>(6); } |
507 unsigned getVirtualIndex() const { return getUnsignedField(11); } | 638 DISubprogram getFunctionDeclaration() const { |
508 | 639 return getFieldAs<DISubprogram>(7); |
509 DITypeRef getContainingType() const { return getFieldAs<DITypeRef>(12); } | 640 } |
510 | 641 MDNode *getVariablesNodes() const; |
511 unsigned getFlags() const { return getUnsignedField(13); } | 642 DIArray getVariables() const; |
512 | 643 |
513 unsigned isArtificial() const { | 644 unsigned isArtificial() const { return (getFlags() & FlagArtificial) != 0; } |
514 return (getUnsignedField(13) & FlagArtificial) != 0; | 645 /// \brief Check for the "private" access specifier. |
515 } | |
516 /// isPrivate - Return true if this subprogram has "private" | |
517 /// access specifier. | |
518 bool isPrivate() const { | 646 bool isPrivate() const { |
519 return (getFlags() & FlagAccessibility) == FlagPrivate; | 647 return (getFlags() & FlagAccessibility) == FlagPrivate; |
520 } | 648 } |
521 /// isProtected - Return true if this subprogram has "protected" | 649 /// \brief Check for the "protected" access specifier. |
522 /// access specifier. | |
523 bool isProtected() const { | 650 bool isProtected() const { |
524 return (getFlags() & FlagAccessibility) == FlagProtected; | 651 return (getFlags() & FlagAccessibility) == FlagProtected; |
525 } | 652 } |
526 /// isPublic - Return true if this subprogram has "public" | 653 /// \brief Check for the "public" access specifier. |
527 /// access specifier. | |
528 bool isPublic() const { | 654 bool isPublic() const { |
529 return (getFlags() & FlagAccessibility) == FlagPublic; | 655 return (getFlags() & FlagAccessibility) == FlagPublic; |
530 } | 656 } |
531 /// isExplicit - Return true if this subprogram is marked as explicit. | 657 /// \brief Check for "explicit". |
532 bool isExplicit() const { return (getUnsignedField(13) & FlagExplicit) != 0; } | 658 bool isExplicit() const { return (getFlags() & FlagExplicit) != 0; } |
533 /// isPrototyped - Return true if this subprogram is prototyped. | 659 /// \brief Check if this is prototyped. |
534 bool isPrototyped() const { | 660 bool isPrototyped() const { return (getFlags() & FlagPrototyped) != 0; } |
535 return (getUnsignedField(13) & FlagPrototyped) != 0; | 661 |
536 } | 662 /// \brief Check if this is reference-qualified. |
537 | 663 /// |
538 /// Return true if this subprogram is a C++11 reference-qualified | 664 /// Return true if this subprogram is a C++11 reference-qualified non-static |
539 /// non-static member function (void foo() &). | 665 /// member function (void foo() &). |
540 unsigned isLValueReference() const { | 666 unsigned isLValueReference() const { |
541 return (getUnsignedField(13) & FlagLValueReference) != 0; | 667 return (getFlags() & FlagLValueReference) != 0; |
542 } | 668 } |
543 | 669 |
544 /// Return true if this subprogram is a C++11 | 670 /// \brief Check if this is rvalue-reference-qualified. |
545 /// rvalue-reference-qualified non-static member function | 671 /// |
546 /// (void foo() &&). | 672 /// Return true if this subprogram is a C++11 rvalue-reference-qualified |
673 /// non-static member function (void foo() &&). | |
547 unsigned isRValueReference() const { | 674 unsigned isRValueReference() const { |
548 return (getUnsignedField(13) & FlagRValueReference) != 0; | 675 return (getFlags() & FlagRValueReference) != 0; |
549 } | 676 } |
550 | 677 }; |
551 unsigned isOptimized() const; | 678 |
552 | 679 /// \brief This is a wrapper for a lexical block. |
553 /// Verify - Verify that a subprogram descriptor is well formed. | |
554 bool Verify() const; | |
555 | |
556 /// describes - Return true if this subprogram provides debugging | |
557 /// information for the function F. | |
558 bool describes(const Function *F); | |
559 | |
560 Function *getFunction() const { return getFunctionField(15); } | |
561 void replaceFunction(Function *F) { replaceFunctionField(15, F); } | |
562 DIArray getTemplateParams() const { return getFieldAs<DIArray>(16); } | |
563 DISubprogram getFunctionDeclaration() const { | |
564 return getFieldAs<DISubprogram>(17); | |
565 } | |
566 MDNode *getVariablesNodes() const; | |
567 DIArray getVariables() const; | |
568 | |
569 /// getScopeLineNumber - Get the beginning of the scope of the | |
570 /// function, not necessarily where the name of the program | |
571 /// starts. | |
572 unsigned getScopeLineNumber() const { return getUnsignedField(19); } | |
573 }; | |
574 | |
575 /// DILexicalBlock - This is a wrapper for a lexical block. | |
576 class DILexicalBlock : public DIScope { | 680 class DILexicalBlock : public DIScope { |
577 public: | 681 public: |
578 explicit DILexicalBlock(const MDNode *N = nullptr) : DIScope(N) {} | 682 explicit DILexicalBlock(const MDNode *N = nullptr) : DIScope(N) {} |
579 DIScope getContext() const { return getFieldAs<DIScope>(2); } | 683 DIScope getContext() const { return getFieldAs<DIScope>(2); } |
580 unsigned getLineNumber() const { return getUnsignedField(3); } | 684 unsigned getLineNumber() const { return getHeaderFieldAs<unsigned>(1); } |
581 unsigned getColumnNumber() const { return getUnsignedField(4); } | 685 unsigned getColumnNumber() const { return getHeaderFieldAs<unsigned>(2); } |
582 bool Verify() const; | 686 bool Verify() const; |
583 }; | 687 }; |
584 | 688 |
585 /// DILexicalBlockFile - This is a wrapper for a lexical block with | 689 /// \brief This is a wrapper for a lexical block with a filename change. |
586 /// a filename change. | |
587 class DILexicalBlockFile : public DIScope { | 690 class DILexicalBlockFile : public DIScope { |
588 public: | 691 public: |
589 explicit DILexicalBlockFile(const MDNode *N = nullptr) : DIScope(N) {} | 692 explicit DILexicalBlockFile(const MDNode *N = nullptr) : DIScope(N) {} |
590 DIScope getContext() const { | 693 DIScope getContext() const { |
694 // FIXME: This logic is horrible. getScope() returns a DILexicalBlock, but | |
695 // then we check if it's a subprogram? WHAT?!? | |
591 if (getScope().isSubprogram()) | 696 if (getScope().isSubprogram()) |
592 return getScope(); | 697 return getScope(); |
593 return getScope().getContext(); | 698 return getScope().getContext(); |
594 } | 699 } |
595 unsigned getLineNumber() const { return getScope().getLineNumber(); } | 700 unsigned getLineNumber() const { return getScope().getLineNumber(); } |
596 unsigned getColumnNumber() const { return getScope().getColumnNumber(); } | 701 unsigned getColumnNumber() const { return getScope().getColumnNumber(); } |
597 DILexicalBlock getScope() const { return getFieldAs<DILexicalBlock>(2); } | 702 DILexicalBlock getScope() const { return getFieldAs<DILexicalBlock>(2); } |
598 unsigned getDiscriminator() const { return getUnsignedField(3); } | 703 unsigned getDiscriminator() const { return getHeaderFieldAs<unsigned>(1); } |
599 bool Verify() const; | 704 bool Verify() const; |
600 }; | 705 }; |
601 | 706 |
602 /// DINameSpace - A wrapper for a C++ style name space. | 707 /// \brief A wrapper for a C++ style name space. |
603 class DINameSpace : public DIScope { | 708 class DINameSpace : public DIScope { |
604 friend class DIDescriptor; | 709 friend class DIDescriptor; |
605 void printInternal(raw_ostream &OS) const; | 710 void printInternal(raw_ostream &OS) const; |
606 | 711 |
607 public: | 712 public: |
608 explicit DINameSpace(const MDNode *N = nullptr) : DIScope(N) {} | 713 explicit DINameSpace(const MDNode *N = nullptr) : DIScope(N) {} |
714 StringRef getName() const { return getHeaderField(1); } | |
715 unsigned getLineNumber() const { return getHeaderFieldAs<unsigned>(2); } | |
609 DIScope getContext() const { return getFieldAs<DIScope>(2); } | 716 DIScope getContext() const { return getFieldAs<DIScope>(2); } |
610 StringRef getName() const { return getStringField(3); } | 717 bool Verify() const; |
611 unsigned getLineNumber() const { return getUnsignedField(4); } | 718 }; |
612 bool Verify() const; | 719 |
613 }; | 720 /// \brief This is a wrapper for template type parameter. |
614 | |
615 /// DITemplateTypeParameter - This is a wrapper for template type parameter. | |
616 class DITemplateTypeParameter : public DIDescriptor { | 721 class DITemplateTypeParameter : public DIDescriptor { |
617 public: | 722 public: |
618 explicit DITemplateTypeParameter(const MDNode *N = nullptr) | 723 explicit DITemplateTypeParameter(const MDNode *N = nullptr) |
619 : DIDescriptor(N) {} | 724 : DIDescriptor(N) {} |
725 | |
726 StringRef getName() const { return getHeaderField(1); } | |
620 | 727 |
621 DIScopeRef getContext() const { return getFieldAs<DIScopeRef>(1); } | 728 DIScopeRef getContext() const { return getFieldAs<DIScopeRef>(1); } |
622 StringRef getName() const { return getStringField(2); } | 729 DITypeRef getType() const { return getFieldAs<DITypeRef>(2); } |
730 bool Verify() const; | |
731 }; | |
732 | |
733 /// \brief This is a wrapper for template value parameter. | |
734 class DITemplateValueParameter : public DIDescriptor { | |
735 public: | |
736 explicit DITemplateValueParameter(const MDNode *N = nullptr) | |
737 : DIDescriptor(N) {} | |
738 | |
739 StringRef getName() const { return getHeaderField(1); } | |
740 | |
741 DIScopeRef getContext() const { return getFieldAs<DIScopeRef>(1); } | |
742 DITypeRef getType() const { return getFieldAs<DITypeRef>(2); } | |
743 Metadata *getValue() const; | |
744 bool Verify() const; | |
745 }; | |
746 | |
747 /// \brief This is a wrapper for a global variable. | |
748 class DIGlobalVariable : public DIDescriptor { | |
749 friend class DIDescriptor; | |
750 void printInternal(raw_ostream &OS) const; | |
751 | |
752 public: | |
753 explicit DIGlobalVariable(const MDNode *N = nullptr) : DIDescriptor(N) {} | |
754 | |
755 StringRef getName() const { return getHeaderField(1); } | |
756 StringRef getDisplayName() const { return getHeaderField(2); } | |
757 StringRef getLinkageName() const { return getHeaderField(3); } | |
758 unsigned getLineNumber() const { return getHeaderFieldAs<unsigned>(4); } | |
759 unsigned isLocalToUnit() const { return getHeaderFieldAs<bool>(5); } | |
760 unsigned isDefinition() const { return getHeaderFieldAs<bool>(6); } | |
761 | |
762 DIScope getContext() const { return getFieldAs<DIScope>(1); } | |
763 StringRef getFilename() const { return getFieldAs<DIFile>(2).getFilename(); } | |
764 StringRef getDirectory() const { | |
765 return getFieldAs<DIFile>(2).getDirectory(); | |
766 } | |
623 DITypeRef getType() const { return getFieldAs<DITypeRef>(3); } | 767 DITypeRef getType() const { return getFieldAs<DITypeRef>(3); } |
624 StringRef getFilename() const { return getFieldAs<DIFile>(4).getFilename(); } | 768 |
625 StringRef getDirectory() const { | 769 GlobalVariable *getGlobal() const { return getGlobalVariableField(4); } |
626 return getFieldAs<DIFile>(4).getDirectory(); | 770 Constant *getConstant() const { return getConstantField(4); } |
627 } | 771 DIDerivedType getStaticDataMemberDeclaration() const { |
628 unsigned getLineNumber() const { return getUnsignedField(5); } | 772 return getFieldAs<DIDerivedType>(5); |
629 unsigned getColumnNumber() const { return getUnsignedField(6); } | 773 } |
630 bool Verify() const; | 774 |
631 }; | 775 bool Verify() const; |
632 | 776 }; |
633 /// DITemplateValueParameter - This is a wrapper for template value parameter. | 777 |
634 class DITemplateValueParameter : public DIDescriptor { | 778 /// \brief This is a wrapper for a variable (e.g. parameter, local, global etc). |
635 public: | 779 class DIVariable : public DIDescriptor { |
636 explicit DITemplateValueParameter(const MDNode *N = nullptr) | 780 friend class DIDescriptor; |
637 : DIDescriptor(N) {} | 781 void printInternal(raw_ostream &OS) const; |
638 | 782 |
639 DIScopeRef getContext() const { return getFieldAs<DIScopeRef>(1); } | 783 public: |
640 StringRef getName() const { return getStringField(2); } | 784 explicit DIVariable(const MDNode *N = nullptr) : DIDescriptor(N) {} |
785 | |
786 StringRef getName() const { return getHeaderField(1); } | |
787 unsigned getLineNumber() const { | |
788 // FIXME: Line number and arg number shouldn't be merged together like this. | |
789 return (getHeaderFieldAs<unsigned>(2) << 8) >> 8; | |
790 } | |
791 unsigned getArgNumber() const { return getHeaderFieldAs<unsigned>(2) >> 24; } | |
792 | |
793 DIScope getContext() const { return getFieldAs<DIScope>(1); } | |
794 DIFile getFile() const { return getFieldAs<DIFile>(2); } | |
641 DITypeRef getType() const { return getFieldAs<DITypeRef>(3); } | 795 DITypeRef getType() const { return getFieldAs<DITypeRef>(3); } |
642 Value *getValue() const; | 796 |
643 StringRef getFilename() const { return getFieldAs<DIFile>(5).getFilename(); } | 797 /// \brief Return true if this variable is marked as "artificial". |
644 StringRef getDirectory() const { | |
645 return getFieldAs<DIFile>(5).getDirectory(); | |
646 } | |
647 unsigned getLineNumber() const { return getUnsignedField(6); } | |
648 unsigned getColumnNumber() const { return getUnsignedField(7); } | |
649 bool Verify() const; | |
650 }; | |
651 | |
652 /// DIGlobalVariable - This is a wrapper for a global variable. | |
653 class DIGlobalVariable : public DIDescriptor { | |
654 friend class DIDescriptor; | |
655 void printInternal(raw_ostream &OS) const; | |
656 | |
657 public: | |
658 explicit DIGlobalVariable(const MDNode *N = nullptr) : DIDescriptor(N) {} | |
659 | |
660 DIScope getContext() const { return getFieldAs<DIScope>(2); } | |
661 StringRef getName() const { return getStringField(3); } | |
662 StringRef getDisplayName() const { return getStringField(4); } | |
663 StringRef getLinkageName() const { return getStringField(5); } | |
664 StringRef getFilename() const { return getFieldAs<DIFile>(6).getFilename(); } | |
665 StringRef getDirectory() const { | |
666 return getFieldAs<DIFile>(6).getDirectory(); | |
667 } | |
668 | |
669 unsigned getLineNumber() const { return getUnsignedField(7); } | |
670 DITypeRef getType() const { return getFieldAs<DITypeRef>(8); } | |
671 unsigned isLocalToUnit() const { return getUnsignedField(9); } | |
672 unsigned isDefinition() const { return getUnsignedField(10); } | |
673 | |
674 GlobalVariable *getGlobal() const { return getGlobalVariableField(11); } | |
675 Constant *getConstant() const { return getConstantField(11); } | |
676 DIDerivedType getStaticDataMemberDeclaration() const { | |
677 return getFieldAs<DIDerivedType>(12); | |
678 } | |
679 | |
680 /// Verify - Verify that a global variable descriptor is well formed. | |
681 bool Verify() const; | |
682 }; | |
683 | |
684 /// DIVariable - This is a wrapper for a variable (e.g. parameter, local, | |
685 /// global etc). | |
686 class DIVariable : public DIDescriptor { | |
687 friend class DIDescriptor; | |
688 void printInternal(raw_ostream &OS) const; | |
689 | |
690 public: | |
691 explicit DIVariable(const MDNode *N = nullptr) : DIDescriptor(N) {} | |
692 | |
693 DIScope getContext() const { return getFieldAs<DIScope>(1); } | |
694 StringRef getName() const { return getStringField(2); } | |
695 DIFile getFile() const { return getFieldAs<DIFile>(3); } | |
696 unsigned getLineNumber() const { return (getUnsignedField(4) << 8) >> 8; } | |
697 unsigned getArgNumber() const { | |
698 unsigned L = getUnsignedField(4); | |
699 return L >> 24; | |
700 } | |
701 DITypeRef getType() const { return getFieldAs<DITypeRef>(5); } | |
702 | |
703 /// isArtificial - Return true if this variable is marked as "artificial". | |
704 bool isArtificial() const { | 798 bool isArtificial() const { |
705 return (getUnsignedField(6) & FlagArtificial) != 0; | 799 return (getHeaderFieldAs<unsigned>(3) & FlagArtificial) != 0; |
706 } | 800 } |
707 | 801 |
708 bool isObjectPointer() const { | 802 bool isObjectPointer() const { |
709 return (getUnsignedField(6) & FlagObjectPointer) != 0; | 803 return (getHeaderFieldAs<unsigned>(3) & FlagObjectPointer) != 0; |
710 } | 804 } |
711 | 805 |
712 /// \brief Return true if this variable is represented as a pointer. | 806 /// \brief If this variable is inlined then return inline location. |
713 bool isIndirect() const { | |
714 return (getUnsignedField(6) & FlagIndirectVariable) != 0; | |
715 } | |
716 | |
717 /// getInlinedAt - If this variable is inlined then return inline location. | |
718 MDNode *getInlinedAt() const; | 807 MDNode *getInlinedAt() const; |
719 | 808 |
720 /// Verify - Verify that a variable descriptor is well formed. | 809 bool Verify() const; |
721 bool Verify() const; | 810 |
722 | 811 /// \brief Check if this is a "__block" variable (Apple Blocks). |
723 /// HasComplexAddr - Return true if the variable has a complex address. | |
724 bool hasComplexAddress() const { return getNumAddrElements() > 0; } | |
725 | |
726 /// \brief Return the size of this variable's complex address or | |
727 /// zero if there is none. | |
728 unsigned getNumAddrElements() const { | |
729 if (DbgNode->getNumOperands() < 9) | |
730 return 0; | |
731 return getDescriptorField(8)->getNumOperands(); | |
732 } | |
733 | |
734 /// \brief return the Idx'th complex address element. | |
735 uint64_t getAddrElement(unsigned Idx) const; | |
736 | |
737 /// isBlockByrefVariable - Return true if the variable was declared as | |
738 /// a "__block" variable (Apple Blocks). | |
739 bool isBlockByrefVariable(const DITypeIdentifierMap &Map) const { | 812 bool isBlockByrefVariable(const DITypeIdentifierMap &Map) const { |
740 return (getType().resolve(Map)).isBlockByrefStruct(); | 813 return (getType().resolve(Map)).isBlockByrefStruct(); |
741 } | 814 } |
742 | 815 |
743 /// isInlinedFnArgument - Return true if this variable provides debugging | 816 /// \brief Check if this is an inlined function argument. |
744 /// information for an inlined function arguments. | |
745 bool isInlinedFnArgument(const Function *CurFn); | 817 bool isInlinedFnArgument(const Function *CurFn); |
746 | 818 |
747 /// isVariablePiece - Return whether this is a piece of an aggregate | 819 /// \brief Return the size reported by the variable's type. |
748 /// variable. | |
749 bool isVariablePiece() const; | |
750 /// getPieceOffset - Return the offset of this piece in bytes. | |
751 uint64_t getPieceOffset() const; | |
752 /// getPieceSize - Return the size of this piece in bytes. | |
753 uint64_t getPieceSize() const; | |
754 | |
755 /// Return the size reported by the variable's type. | |
756 unsigned getSizeInBits(const DITypeIdentifierMap &Map); | 820 unsigned getSizeInBits(const DITypeIdentifierMap &Map); |
757 | 821 |
758 void printExtendedName(raw_ostream &OS) const; | 822 void printExtendedName(raw_ostream &OS) const; |
759 }; | 823 }; |
760 | 824 |
761 /// DILocation - This object holds location information. This object | 825 /// \brief A complex location expression in postfix notation. |
762 /// is not associated with any DWARF tag. | 826 /// |
827 /// This is (almost) a DWARF expression that modifies the location of a | |
828 /// variable or (or the location of a single piece of a variable). | |
829 /// | |
830 /// FIXME: Instead of DW_OP_plus taking an argument, this should use DW_OP_const | |
831 /// and have DW_OP_plus consume the topmost elements on the stack. | |
832 class DIExpression : public DIDescriptor { | |
833 friend class DIDescriptor; | |
834 void printInternal(raw_ostream &OS) const; | |
835 | |
836 public: | |
837 explicit DIExpression(const MDNode *N = nullptr) : DIDescriptor(N) {} | |
838 | |
839 bool Verify() const; | |
840 | |
841 /// \brief Return the number of elements in the complex expression. | |
842 unsigned getNumElements() const { | |
843 if (!DbgNode) | |
844 return 0; | |
845 unsigned N = getNumHeaderFields(); | |
846 assert(N > 0 && "missing tag"); | |
847 return N - 1; | |
848 } | |
849 | |
850 /// \brief return the Idx'th complex address element. | |
851 uint64_t getElement(unsigned Idx) const; | |
852 | |
853 /// \brief Return whether this is a piece of an aggregate variable. | |
854 bool isBitPiece() const; | |
855 /// \brief Return the offset of this piece in bits. | |
856 uint64_t getBitPieceOffset() const; | |
857 /// \brief Return the size of this piece in bits. | |
858 uint64_t getBitPieceSize() const; | |
859 | |
860 class iterator; | |
861 /// \brief A lightweight wrapper around an element of a DIExpression. | |
862 class Operand { | |
863 friend class iterator; | |
864 DIHeaderFieldIterator I; | |
865 Operand() {} | |
866 Operand(DIHeaderFieldIterator I) : I(I) {} | |
867 public: | |
868 /// \brief Operands such as DW_OP_piece have explicit (non-stack) arguments. | |
869 /// Argument 0 is the operand itself. | |
870 uint64_t getArg(unsigned N) const { | |
871 DIHeaderFieldIterator In = I; | |
872 std::advance(In, N); | |
873 return In.getNumber<uint64_t>(); | |
874 } | |
875 operator uint64_t () const { return I.getNumber<uint64_t>(); } | |
876 /// \brief Returns underlying DIHeaderFieldIterator. | |
877 const DIHeaderFieldIterator &getBase() const { return I; } | |
878 /// \brief Returns the next operand. | |
879 Operand getNext() const; | |
880 }; | |
881 | |
882 /// \brief An iterator for DIExpression elements. | |
883 class iterator : public std::iterator<std::input_iterator_tag, StringRef, | |
884 unsigned, const Operand*, Operand> { | |
885 friend class Operand; | |
886 DIHeaderFieldIterator I; | |
887 Operand Tmp; | |
888 iterator(DIHeaderFieldIterator I) : I(I) {} | |
889 public: | |
890 iterator() {} | |
891 iterator(const DIExpression &Expr) : I(++Expr.header_begin()) {} | |
892 const Operand &operator*() { return Tmp = Operand(I); } | |
893 const Operand *operator->() { return &(Tmp = Operand(I)); } | |
894 iterator &operator++() { | |
895 increment(); | |
896 return *this; | |
897 } | |
898 iterator operator++(int) { | |
899 iterator X(*this); | |
900 increment(); | |
901 return X; | |
902 } | |
903 bool operator==(const iterator &X) const { return I == X.I; } | |
904 bool operator!=(const iterator &X) const { return !(*this == X); } | |
905 | |
906 private: | |
907 void increment() { | |
908 switch (**this) { | |
909 case dwarf::DW_OP_bit_piece: std::advance(I, 3); break; | |
910 case dwarf::DW_OP_plus: std::advance(I, 2); break; | |
911 case dwarf::DW_OP_deref: std::advance(I, 1); break; | |
912 default: | |
913 llvm_unreachable("unsupported operand"); | |
914 } | |
915 } | |
916 }; | |
917 | |
918 iterator begin() const; | |
919 iterator end() const; | |
920 }; | |
921 | |
922 /// \brief This object holds location information. | |
923 /// | |
924 /// This object is not associated with any DWARF tag. | |
763 class DILocation : public DIDescriptor { | 925 class DILocation : public DIDescriptor { |
764 public: | 926 public: |
765 explicit DILocation(const MDNode *N) : DIDescriptor(N) {} | 927 explicit DILocation(const MDNode *N) : DIDescriptor(N) {} |
766 | 928 |
767 unsigned getLineNumber() const { return getUnsignedField(0); } | 929 unsigned getLineNumber() const { |
768 unsigned getColumnNumber() const { return getUnsignedField(1); } | 930 if (auto *L = dyn_cast_or_null<MDLocation>(DbgNode)) |
769 DIScope getScope() const { return getFieldAs<DIScope>(2); } | 931 return L->getLine(); |
770 DILocation getOrigLocation() const { return getFieldAs<DILocation>(3); } | 932 return 0; |
933 } | |
934 unsigned getColumnNumber() const { | |
935 if (auto *L = dyn_cast_or_null<MDLocation>(DbgNode)) | |
936 return L->getColumn(); | |
937 return 0; | |
938 } | |
939 DIScope getScope() const { | |
940 if (auto *L = dyn_cast_or_null<MDLocation>(DbgNode)) | |
941 return DIScope(dyn_cast_or_null<MDNode>(L->getScope())); | |
942 return DIScope(nullptr); | |
943 } | |
944 DILocation getOrigLocation() const { | |
945 if (auto *L = dyn_cast_or_null<MDLocation>(DbgNode)) | |
946 return DILocation(dyn_cast_or_null<MDNode>(L->getInlinedAt())); | |
947 return DILocation(nullptr); | |
948 } | |
771 StringRef getFilename() const { return getScope().getFilename(); } | 949 StringRef getFilename() const { return getScope().getFilename(); } |
772 StringRef getDirectory() const { return getScope().getDirectory(); } | 950 StringRef getDirectory() const { return getScope().getDirectory(); } |
773 bool Verify() const; | 951 bool Verify() const; |
774 bool atSameLineAs(const DILocation &Other) const { | 952 bool atSameLineAs(const DILocation &Other) const { |
775 return (getLineNumber() == Other.getLineNumber() && | 953 return (getLineNumber() == Other.getLineNumber() && |
776 getFilename() == Other.getFilename()); | 954 getFilename() == Other.getFilename()); |
777 } | 955 } |
778 /// getDiscriminator - DWARF discriminators are used to distinguish | 956 /// \brief Get the DWAF discriminator. |
779 /// identical file locations for instructions that are on different | 957 /// |
780 /// basic blocks. If two instructions are inside the same lexical block | 958 /// DWARF discriminators are used to distinguish identical file locations for |
781 /// and are in different basic blocks, we create a new lexical block | 959 /// instructions that are on different basic blocks. If two instructions are |
782 /// with identical location as the original but with a different | 960 /// inside the same lexical block and are in different basic blocks, we |
783 /// discriminator value (lib/Transforms/Util/AddDiscriminators.cpp | 961 /// create a new lexical block with identical location as the original but |
784 /// for details). | 962 /// with a different discriminator value |
963 /// (lib/Transforms/Util/AddDiscriminators.cpp for details). | |
785 unsigned getDiscriminator() const { | 964 unsigned getDiscriminator() const { |
786 // Since discriminators are associated with lexical blocks, make | 965 // Since discriminators are associated with lexical blocks, make |
787 // sure this location is a lexical block before retrieving its | 966 // sure this location is a lexical block before retrieving its |
788 // value. | 967 // value. |
789 return getScope().isLexicalBlockFile() | 968 return getScope().isLexicalBlockFile() |
790 ? getFieldAs<DILexicalBlockFile>(2).getDiscriminator() | 969 ? DILexicalBlockFile( |
970 cast<MDNode>(cast<MDLocation>(DbgNode)->getScope())) | |
971 .getDiscriminator() | |
791 : 0; | 972 : 0; |
792 } | 973 } |
974 | |
975 /// \brief Generate a new discriminator value for this location. | |
793 unsigned computeNewDiscriminator(LLVMContext &Ctx); | 976 unsigned computeNewDiscriminator(LLVMContext &Ctx); |
977 | |
978 /// \brief Return a copy of this location with a different scope. | |
794 DILocation copyWithNewScope(LLVMContext &Ctx, DILexicalBlockFile NewScope); | 979 DILocation copyWithNewScope(LLVMContext &Ctx, DILexicalBlockFile NewScope); |
795 }; | 980 }; |
796 | 981 |
797 class DIObjCProperty : public DIDescriptor { | 982 class DIObjCProperty : public DIDescriptor { |
798 friend class DIDescriptor; | 983 friend class DIDescriptor; |
799 void printInternal(raw_ostream &OS) const; | 984 void printInternal(raw_ostream &OS) const; |
800 | 985 |
801 public: | 986 public: |
802 explicit DIObjCProperty(const MDNode *N) : DIDescriptor(N) {} | 987 explicit DIObjCProperty(const MDNode *N) : DIDescriptor(N) {} |
803 | 988 |
804 StringRef getObjCPropertyName() const { return getStringField(1); } | 989 StringRef getObjCPropertyName() const { return getHeaderField(1); } |
805 DIFile getFile() const { return getFieldAs<DIFile>(2); } | 990 DIFile getFile() const { return getFieldAs<DIFile>(1); } |
806 unsigned getLineNumber() const { return getUnsignedField(3); } | 991 unsigned getLineNumber() const { return getHeaderFieldAs<unsigned>(2); } |
807 | 992 |
808 StringRef getObjCPropertyGetterName() const { return getStringField(4); } | 993 StringRef getObjCPropertyGetterName() const { return getHeaderField(3); } |
809 StringRef getObjCPropertySetterName() const { return getStringField(5); } | 994 StringRef getObjCPropertySetterName() const { return getHeaderField(4); } |
995 unsigned getAttributes() const { return getHeaderFieldAs<unsigned>(5); } | |
810 bool isReadOnlyObjCProperty() const { | 996 bool isReadOnlyObjCProperty() const { |
811 return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_readonly) != 0; | 997 return (getAttributes() & dwarf::DW_APPLE_PROPERTY_readonly) != 0; |
812 } | 998 } |
813 bool isReadWriteObjCProperty() const { | 999 bool isReadWriteObjCProperty() const { |
814 return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_readwrite) != 0; | 1000 return (getAttributes() & dwarf::DW_APPLE_PROPERTY_readwrite) != 0; |
815 } | 1001 } |
816 bool isAssignObjCProperty() const { | 1002 bool isAssignObjCProperty() const { |
817 return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_assign) != 0; | 1003 return (getAttributes() & dwarf::DW_APPLE_PROPERTY_assign) != 0; |
818 } | 1004 } |
819 bool isRetainObjCProperty() const { | 1005 bool isRetainObjCProperty() const { |
820 return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_retain) != 0; | 1006 return (getAttributes() & dwarf::DW_APPLE_PROPERTY_retain) != 0; |
821 } | 1007 } |
822 bool isCopyObjCProperty() const { | 1008 bool isCopyObjCProperty() const { |
823 return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_copy) != 0; | 1009 return (getAttributes() & dwarf::DW_APPLE_PROPERTY_copy) != 0; |
824 } | 1010 } |
825 bool isNonAtomicObjCProperty() const { | 1011 bool isNonAtomicObjCProperty() const { |
826 return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_nonatomic) != 0; | 1012 return (getAttributes() & dwarf::DW_APPLE_PROPERTY_nonatomic) != 0; |
827 } | 1013 } |
828 | 1014 |
829 /// Objective-C doesn't have an ODR, so there is no benefit in storing | 1015 /// \brief Get the type. |
1016 /// | |
1017 /// \note Objective-C doesn't have an ODR, so there is no benefit in storing | |
830 /// the type as a DITypeRef here. | 1018 /// the type as a DITypeRef here. |
831 DIType getType() const { return getFieldAs<DIType>(7); } | 1019 DIType getType() const { return getFieldAs<DIType>(2); } |
832 | 1020 |
833 /// Verify - Verify that a derived type descriptor is well formed. | |
834 bool Verify() const; | 1021 bool Verify() const; |
835 }; | 1022 }; |
836 | 1023 |
837 /// \brief An imported module (C++ using directive or similar). | 1024 /// \brief An imported module (C++ using directive or similar). |
838 class DIImportedEntity : public DIDescriptor { | 1025 class DIImportedEntity : public DIDescriptor { |
841 | 1028 |
842 public: | 1029 public: |
843 explicit DIImportedEntity(const MDNode *N) : DIDescriptor(N) {} | 1030 explicit DIImportedEntity(const MDNode *N) : DIDescriptor(N) {} |
844 DIScope getContext() const { return getFieldAs<DIScope>(1); } | 1031 DIScope getContext() const { return getFieldAs<DIScope>(1); } |
845 DIScopeRef getEntity() const { return getFieldAs<DIScopeRef>(2); } | 1032 DIScopeRef getEntity() const { return getFieldAs<DIScopeRef>(2); } |
846 unsigned getLineNumber() const { return getUnsignedField(3); } | 1033 unsigned getLineNumber() const { return getHeaderFieldAs<unsigned>(1); } |
847 StringRef getName() const { return getStringField(4); } | 1034 StringRef getName() const { return getHeaderField(2); } |
848 bool Verify() const; | 1035 bool Verify() const; |
849 }; | 1036 }; |
850 | 1037 |
851 /// getDISubprogram - Find subprogram that is enclosing this scope. | 1038 /// \brief Find subprogram that is enclosing this scope. |
852 DISubprogram getDISubprogram(const MDNode *Scope); | 1039 DISubprogram getDISubprogram(const MDNode *Scope); |
853 | 1040 |
854 /// getDICompositeType - Find underlying composite type. | 1041 /// \brief Find debug info for a given function. |
1042 /// \returns a valid DISubprogram, if found. Otherwise, it returns an empty | |
1043 /// DISubprogram. | |
1044 DISubprogram getDISubprogram(const Function *F); | |
1045 | |
1046 /// \brief Find underlying composite type. | |
855 DICompositeType getDICompositeType(DIType T); | 1047 DICompositeType getDICompositeType(DIType T); |
856 | 1048 |
857 /// getOrInsertFnSpecificMDNode - Return a NameMDNode that is suitable | 1049 /// \brief Create a new inlined variable based on current variable. |
858 /// to hold function specific information. | 1050 /// |
859 NamedMDNode *getOrInsertFnSpecificMDNode(Module &M, DISubprogram SP); | |
860 | |
861 /// getFnSpecificMDNode - Return a NameMDNode, if available, that is | |
862 /// suitable to hold function specific information. | |
863 NamedMDNode *getFnSpecificMDNode(const Module &M, DISubprogram SP); | |
864 | |
865 /// createInlinedVariable - Create a new inlined variable based on current | |
866 /// variable. | |
867 /// @param DV Current Variable. | 1051 /// @param DV Current Variable. |
868 /// @param InlinedScope Location at current variable is inlined. | 1052 /// @param InlinedScope Location at current variable is inlined. |
869 DIVariable createInlinedVariable(MDNode *DV, MDNode *InlinedScope, | 1053 DIVariable createInlinedVariable(MDNode *DV, MDNode *InlinedScope, |
870 LLVMContext &VMContext); | 1054 LLVMContext &VMContext); |
871 | 1055 |
872 /// cleanseInlinedVariable - Remove inlined scope from the variable. | 1056 /// \brief Remove inlined scope from the variable. |
873 DIVariable cleanseInlinedVariable(MDNode *DV, LLVMContext &VMContext); | 1057 DIVariable cleanseInlinedVariable(MDNode *DV, LLVMContext &VMContext); |
874 | 1058 |
875 /// getEntireVariable - Remove OpPiece exprs from the variable. | 1059 /// \brief Generate map by visiting all retained types. |
876 DIVariable getEntireVariable(DIVariable DV); | |
877 | |
878 /// Construct DITypeIdentifierMap by going through retained types of each CU. | |
879 DITypeIdentifierMap generateDITypeIdentifierMap(const NamedMDNode *CU_Nodes); | 1060 DITypeIdentifierMap generateDITypeIdentifierMap(const NamedMDNode *CU_Nodes); |
880 | 1061 |
881 /// Strip debug info in the module if it exists. | 1062 /// \brief Strip debug info in the module if it exists. |
1063 /// | |
882 /// To do this, we remove all calls to the debugger intrinsics and any named | 1064 /// To do this, we remove all calls to the debugger intrinsics and any named |
883 /// metadata for debugging. We also remove debug locations for instructions. | 1065 /// metadata for debugging. We also remove debug locations for instructions. |
884 /// Return true if module is modified. | 1066 /// Return true if module is modified. |
885 bool StripDebugInfo(Module &M); | 1067 bool StripDebugInfo(Module &M); |
886 | 1068 |
887 /// Return Debug Info Metadata Version by checking module flags. | 1069 /// \brief Return Debug Info Metadata Version by checking module flags. |
888 unsigned getDebugMetadataVersionFromModule(const Module &M); | 1070 unsigned getDebugMetadataVersionFromModule(const Module &M); |
889 | 1071 |
1072 /// \brief Utility to find all debug info in a module. | |
1073 /// | |
890 /// DebugInfoFinder tries to list all debug info MDNodes used in a module. To | 1074 /// DebugInfoFinder tries to list all debug info MDNodes used in a module. To |
891 /// list debug info MDNodes used by an instruction, DebugInfoFinder uses | 1075 /// list debug info MDNodes used by an instruction, DebugInfoFinder uses |
892 /// processDeclare, processValue and processLocation to handle DbgDeclareInst, | 1076 /// processDeclare, processValue and processLocation to handle DbgDeclareInst, |
893 /// DbgValueInst and DbgLoc attached to instructions. processModule will go | 1077 /// DbgValueInst and DbgLoc attached to instructions. processModule will go |
894 /// through all DICompileUnits in llvm.dbg.cu and list debug info MDNodes | 1078 /// through all DICompileUnits in llvm.dbg.cu and list debug info MDNodes |
895 /// used by the CUs. | 1079 /// used by the CUs. |
896 class DebugInfoFinder { | 1080 class DebugInfoFinder { |
897 public: | 1081 public: |
898 DebugInfoFinder() : TypeMapInitialized(false) {} | 1082 DebugInfoFinder() : TypeMapInitialized(false) {} |
899 | 1083 |
900 /// processModule - Process entire module and collect debug info | 1084 /// \brief Process entire module and collect debug info anchors. |
901 /// anchors. | |
902 void processModule(const Module &M); | 1085 void processModule(const Module &M); |
903 | 1086 |
904 /// processDeclare - Process DbgDeclareInst. | 1087 /// \brief Process DbgDeclareInst. |
905 void processDeclare(const Module &M, const DbgDeclareInst *DDI); | 1088 void processDeclare(const Module &M, const DbgDeclareInst *DDI); |
906 /// Process DbgValueInst. | 1089 /// \brief Process DbgValueInst. |
907 void processValue(const Module &M, const DbgValueInst *DVI); | 1090 void processValue(const Module &M, const DbgValueInst *DVI); |
908 /// processLocation - Process DILocation. | 1091 /// \brief Process DILocation. |
909 void processLocation(const Module &M, DILocation Loc); | 1092 void processLocation(const Module &M, DILocation Loc); |
910 | 1093 |
911 /// Clear all lists. | 1094 /// \brief Process DIExpression. |
1095 void processExpression(DIExpression Expr); | |
1096 | |
1097 /// \brief Clear all lists. | |
912 void reset(); | 1098 void reset(); |
913 | 1099 |
914 private: | 1100 private: |
915 /// Initialize TypeIdentifierMap. | |
916 void InitializeTypeMap(const Module &M); | 1101 void InitializeTypeMap(const Module &M); |
917 | 1102 |
918 /// processType - Process DIType. | |
919 void processType(DIType DT); | 1103 void processType(DIType DT); |
920 | |
921 /// processSubprogram - Process DISubprogram. | |
922 void processSubprogram(DISubprogram SP); | 1104 void processSubprogram(DISubprogram SP); |
923 | |
924 void processScope(DIScope Scope); | 1105 void processScope(DIScope Scope); |
925 | |
926 /// addCompileUnit - Add compile unit into CUs. | |
927 bool addCompileUnit(DICompileUnit CU); | 1106 bool addCompileUnit(DICompileUnit CU); |
928 | |
929 /// addGlobalVariable - Add global variable into GVs. | |
930 bool addGlobalVariable(DIGlobalVariable DIG); | 1107 bool addGlobalVariable(DIGlobalVariable DIG); |
931 | |
932 // addSubprogram - Add subprogram into SPs. | |
933 bool addSubprogram(DISubprogram SP); | 1108 bool addSubprogram(DISubprogram SP); |
934 | |
935 /// addType - Add type into Tys. | |
936 bool addType(DIType DT); | 1109 bool addType(DIType DT); |
937 | |
938 bool addScope(DIScope Scope); | 1110 bool addScope(DIScope Scope); |
939 | 1111 |
940 public: | 1112 public: |
941 typedef SmallVectorImpl<DICompileUnit>::const_iterator compile_unit_iterator; | 1113 typedef SmallVectorImpl<DICompileUnit>::const_iterator compile_unit_iterator; |
942 typedef SmallVectorImpl<DISubprogram>::const_iterator subprogram_iterator; | 1114 typedef SmallVectorImpl<DISubprogram>::const_iterator subprogram_iterator; |
943 typedef SmallVectorImpl<DIGlobalVariable>::const_iterator global_variable_iterator; | 1115 typedef SmallVectorImpl<DIGlobalVariable>::const_iterator |
1116 global_variable_iterator; | |
944 typedef SmallVectorImpl<DIType>::const_iterator type_iterator; | 1117 typedef SmallVectorImpl<DIType>::const_iterator type_iterator; |
945 typedef SmallVectorImpl<DIScope>::const_iterator scope_iterator; | 1118 typedef SmallVectorImpl<DIScope>::const_iterator scope_iterator; |
946 | 1119 |
947 iterator_range<compile_unit_iterator> compile_units() const { | 1120 iterator_range<compile_unit_iterator> compile_units() const { |
948 return iterator_range<compile_unit_iterator>(CUs.begin(), CUs.end()); | 1121 return iterator_range<compile_unit_iterator>(CUs.begin(), CUs.end()); |
969 unsigned subprogram_count() const { return SPs.size(); } | 1142 unsigned subprogram_count() const { return SPs.size(); } |
970 unsigned type_count() const { return TYs.size(); } | 1143 unsigned type_count() const { return TYs.size(); } |
971 unsigned scope_count() const { return Scopes.size(); } | 1144 unsigned scope_count() const { return Scopes.size(); } |
972 | 1145 |
973 private: | 1146 private: |
974 SmallVector<DICompileUnit, 8> CUs; // Compile Units | 1147 SmallVector<DICompileUnit, 8> CUs; |
975 SmallVector<DISubprogram, 8> SPs; // Subprograms | 1148 SmallVector<DISubprogram, 8> SPs; |
976 SmallVector<DIGlobalVariable, 8> GVs; // Global Variables; | 1149 SmallVector<DIGlobalVariable, 8> GVs; |
977 SmallVector<DIType, 8> TYs; // Types | 1150 SmallVector<DIType, 8> TYs; |
978 SmallVector<DIScope, 8> Scopes; // Scopes | 1151 SmallVector<DIScope, 8> Scopes; |
979 SmallPtrSet<MDNode *, 64> NodesSeen; | 1152 SmallPtrSet<MDNode *, 64> NodesSeen; |
980 DITypeIdentifierMap TypeIdentifierMap; | 1153 DITypeIdentifierMap TypeIdentifierMap; |
981 /// Specify if TypeIdentifierMap is initialized. | 1154 |
1155 /// \brief Specify if TypeIdentifierMap is initialized. | |
982 bool TypeMapInitialized; | 1156 bool TypeMapInitialized; |
983 }; | 1157 }; |
984 | 1158 |
985 DenseMap<const Function *, DISubprogram> makeSubprogramMap(const Module &M); | 1159 DenseMap<const Function *, DISubprogram> makeSubprogramMap(const Module &M); |
986 | 1160 |