1 //===--- llvm/Analysis/DebugInfo.h - Debug Information Helpers --*- 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 // This file defines a bunch of datatypes that are useful for creating and
11 // walking debug info in LLVM IR form. They essentially provide wrappers around
12 // the information in the global variables that's needed when constructing the
15 //===----------------------------------------------------------------------===//
17 #ifndef LLVM_ANALYSIS_DEBUGINFO_H
18 #define LLVM_ANALYSIS_DEBUGINFO_H
20 #include "llvm/ADT/SmallVector.h"
21 #include "llvm/ADT/SmallPtrSet.h"
22 #include "llvm/ADT/StringRef.h"
23 #include "llvm/Support/Dwarf.h"
43 class DILexicalBlockFile;
48 /// DIDescriptor - A thin wraper around MDNode to access encoded debug info.
49 /// This should not be stored in a container, because the underlying MDNode
50 /// may change in certain situations.
55 FlagProtected = 1 << 1,
57 FlagAppleBlock = 1 << 3,
58 FlagBlockByrefStruct = 1 << 4,
60 FlagArtificial = 1 << 6,
61 FlagExplicit = 1 << 7,
62 FlagPrototyped = 1 << 8,
63 FlagObjcClassComplete = 1 << 9,
64 FlagObjectPointer = 1 << 10
67 const MDNode *DbgNode;
69 StringRef getStringField(unsigned Elt) const;
70 unsigned getUnsignedField(unsigned Elt) const {
71 return (unsigned)getUInt64Field(Elt);
73 uint64_t getUInt64Field(unsigned Elt) const;
74 DIDescriptor getDescriptorField(unsigned Elt) const;
76 template <typename DescTy>
77 DescTy getFieldAs(unsigned Elt) const {
78 return DescTy(getDescriptorField(Elt));
81 GlobalVariable *getGlobalVariableField(unsigned Elt) const;
82 Constant *getConstantField(unsigned Elt) const;
83 Function *getFunctionField(unsigned Elt) const;
86 explicit DIDescriptor() : DbgNode(0) {}
87 explicit DIDescriptor(const MDNode *N) : DbgNode(N) {}
88 explicit DIDescriptor(const DIFile F);
89 explicit DIDescriptor(const DISubprogram F);
90 explicit DIDescriptor(const DILexicalBlockFile F);
91 explicit DIDescriptor(const DILexicalBlock F);
92 explicit DIDescriptor(const DIVariable F);
93 explicit DIDescriptor(const DIType F);
95 bool Verify() const { return DbgNode != 0; }
97 operator MDNode *() const { return const_cast<MDNode*>(DbgNode); }
98 MDNode *operator ->() const { return const_cast<MDNode*>(DbgNode); }
100 unsigned getVersion() const {
101 return getUnsignedField(0) & LLVMDebugVersionMask;
104 unsigned getTag() const {
105 return getUnsignedField(0) & ~LLVMDebugVersionMask;
108 bool isDerivedType() const;
109 bool isCompositeType() const;
110 bool isBasicType() const;
111 bool isVariable() const;
112 bool isSubprogram() const;
113 bool isGlobalVariable() const;
114 bool isScope() const;
116 bool isCompileUnit() const;
117 bool isNameSpace() const;
118 bool isLexicalBlockFile() const;
119 bool isLexicalBlock() const;
120 bool isSubrange() const;
121 bool isEnumerator() const;
123 bool isGlobal() const;
124 bool isUnspecifiedParameter() const;
125 bool isTemplateTypeParameter() const;
126 bool isTemplateValueParameter() const;
127 bool isObjCProperty() const;
129 /// print - print descriptor.
130 void print(raw_ostream &OS) const;
132 /// dump - print descriptor to dbgs() with a newline.
136 /// DISubrange - This is used to represent ranges, for array bounds.
137 class DISubrange : public DIDescriptor {
138 friend class DIDescriptor;
139 void printInternal(raw_ostream &OS) const;
141 explicit DISubrange(const MDNode *N = 0) : DIDescriptor(N) {}
143 uint64_t getLo() const { return getUInt64Field(1); }
144 uint64_t getHi() const { return getUInt64Field(2); }
147 /// DIArray - This descriptor holds an array of descriptors.
148 class DIArray : public DIDescriptor {
150 explicit DIArray(const MDNode *N = 0)
153 unsigned getNumElements() const;
154 DIDescriptor getElement(unsigned Idx) const {
155 return getDescriptorField(Idx);
159 /// DIScope - A base class for various scopes.
160 class DIScope : public DIDescriptor {
162 friend class DIDescriptor;
163 void printInternal(raw_ostream &OS) const;
165 explicit DIScope(const MDNode *N = 0) : DIDescriptor (N) {}
167 StringRef getFilename() const;
168 StringRef getDirectory() const;
171 /// DICompileUnit - A wrapper for a compile unit.
172 class DICompileUnit : public DIScope {
173 friend class DIDescriptor;
174 void printInternal(raw_ostream &OS) const;
176 explicit DICompileUnit(const MDNode *N = 0) : DIScope(N) {}
178 unsigned getLanguage() const { return getUnsignedField(2); }
179 StringRef getFilename() const { return getStringField(3); }
180 StringRef getDirectory() const { return getStringField(4); }
181 StringRef getProducer() const { return getStringField(5); }
183 /// isMain - Each input file is encoded as a separate compile unit in LLVM
184 /// debugging information output. However, many target specific tool chains
185 /// prefer to encode only one compile unit in an object file. In this
186 /// situation, the LLVM code generator will include debugging information
187 /// entities in the compile unit that is marked as main compile unit. The
188 /// code generator accepts maximum one main compile unit per module. If a
189 /// module does not contain any main compile unit then the code generator
190 /// will emit multiple compile units in the output object file.
192 bool isMain() const { return getUnsignedField(6) != 0; }
193 bool isOptimized() const { return getUnsignedField(7) != 0; }
194 StringRef getFlags() const { return getStringField(8); }
195 unsigned getRunTimeVersion() const { return getUnsignedField(9); }
197 DIArray getEnumTypes() const;
198 DIArray getRetainedTypes() const;
199 DIArray getSubprograms() const;
200 DIArray getGlobalVariables() const;
202 /// Verify - Verify that a compile unit is well formed.
206 /// DIFile - This is a wrapper for a file.
207 class DIFile : public DIScope {
208 friend class DIDescriptor;
209 void printInternal(raw_ostream &OS) const {} // FIXME: Output something?
211 explicit DIFile(const MDNode *N = 0) : DIScope(N) {
212 if (DbgNode && !isFile())
215 StringRef getFilename() const { return getStringField(1); }
216 StringRef getDirectory() const { return getStringField(2); }
217 DICompileUnit getCompileUnit() const{
218 assert (getVersion() <= LLVMDebugVersion10 && "Invalid CompileUnit!");
219 return getFieldAs<DICompileUnit>(3);
223 /// DIEnumerator - A wrapper for an enumerator (e.g. X and Y in 'enum {X,Y}').
224 /// FIXME: it seems strange that this doesn't have either a reference to the
225 /// type/precision or a file/line pair for location info.
226 class DIEnumerator : public DIDescriptor {
227 friend class DIDescriptor;
228 void printInternal(raw_ostream &OS) const;
230 explicit DIEnumerator(const MDNode *N = 0) : DIDescriptor(N) {}
232 StringRef getName() const { return getStringField(1); }
233 uint64_t getEnumValue() const { return getUInt64Field(2); }
236 /// DIType - This is a wrapper for a type.
237 /// FIXME: Types should be factored much better so that CV qualifiers and
238 /// others do not require a huge and empty descriptor full of zeros.
239 class DIType : public DIScope {
241 friend class DIDescriptor;
242 void printInternal(raw_ostream &OS) const;
243 // This ctor is used when the Tag has already been validated by a derived
245 DIType(const MDNode *N, bool, bool) : DIScope(N) {}
247 /// Verify - Verify that a type descriptor is well formed.
249 explicit DIType(const MDNode *N);
252 DIScope getContext() const { return getFieldAs<DIScope>(1); }
253 StringRef getName() const { return getStringField(2); }
254 DICompileUnit getCompileUnit() const{
255 assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!");
256 if (getVersion() == llvm::LLVMDebugVersion7)
257 return getFieldAs<DICompileUnit>(3);
259 return getFieldAs<DIFile>(3).getCompileUnit();
261 DIFile getFile() const { return getFieldAs<DIFile>(3); }
262 unsigned getLineNumber() const { return getUnsignedField(4); }
263 uint64_t getSizeInBits() const { return getUInt64Field(5); }
264 uint64_t getAlignInBits() const { return getUInt64Field(6); }
265 // FIXME: Offset is only used for DW_TAG_member nodes. Making every type
266 // carry this is just plain insane.
267 uint64_t getOffsetInBits() const { return getUInt64Field(7); }
268 unsigned getFlags() const { return getUnsignedField(8); }
269 bool isPrivate() const {
270 return (getFlags() & FlagPrivate) != 0;
272 bool isProtected() const {
273 return (getFlags() & FlagProtected) != 0;
275 bool isForwardDecl() const {
276 return (getFlags() & FlagFwdDecl) != 0;
278 // isAppleBlock - Return true if this is the Apple Blocks extension.
279 bool isAppleBlockExtension() const {
280 return (getFlags() & FlagAppleBlock) != 0;
282 bool isBlockByrefStruct() const {
283 return (getFlags() & FlagBlockByrefStruct) != 0;
285 bool isVirtual() const {
286 return (getFlags() & FlagVirtual) != 0;
288 bool isArtificial() const {
289 return (getFlags() & FlagArtificial) != 0;
291 bool isObjectPointer() const {
292 return (getFlags() & FlagObjectPointer) != 0;
294 bool isObjcClassComplete() const {
295 return (getFlags() & FlagObjcClassComplete) != 0;
297 bool isValid() const {
298 return DbgNode && (isBasicType() || isDerivedType() || isCompositeType());
300 StringRef getDirectory() const {
301 if (getVersion() == llvm::LLVMDebugVersion7)
302 return getCompileUnit().getDirectory();
304 return getFieldAs<DIFile>(3).getDirectory();
306 StringRef getFilename() const {
307 if (getVersion() == llvm::LLVMDebugVersion7)
308 return getCompileUnit().getFilename();
310 return getFieldAs<DIFile>(3).getFilename();
313 /// isUnsignedDIType - Return true if type encoding is unsigned.
314 bool isUnsignedDIType();
316 /// replaceAllUsesWith - Replace all uses of debug info referenced by
318 void replaceAllUsesWith(DIDescriptor &D);
319 void replaceAllUsesWith(MDNode *D);
322 /// DIBasicType - A basic type, like 'int' or 'float'.
323 class DIBasicType : public DIType {
325 explicit DIBasicType(const MDNode *N = 0) : DIType(N) {}
327 unsigned getEncoding() const { return getUnsignedField(9); }
329 /// Verify - Verify that a basic type descriptor is well formed.
333 /// DIDerivedType - A simple derived type, like a const qualified type,
334 /// a typedef, a pointer or reference, etc.
335 class DIDerivedType : public DIType {
336 friend class DIDescriptor;
337 void printInternal(raw_ostream &OS) const;
339 explicit DIDerivedType(const MDNode *N, bool, bool)
340 : DIType(N, true, true) {}
342 explicit DIDerivedType(const MDNode *N = 0)
343 : DIType(N, true, true) {}
345 DIType getTypeDerivedFrom() const { return getFieldAs<DIType>(9); }
347 /// getOriginalTypeSize - If this type is derived from a base type then
348 /// return base type size.
349 uint64_t getOriginalTypeSize() const;
351 /// getObjCProperty - Return property node, if this ivar is
352 /// associated with one.
353 MDNode *getObjCProperty() const;
355 StringRef getObjCPropertyName() const {
356 if (getVersion() > LLVMDebugVersion11)
358 return getStringField(10);
360 StringRef getObjCPropertyGetterName() const {
361 assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request");
362 return getStringField(11);
364 StringRef getObjCPropertySetterName() const {
365 assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request");
366 return getStringField(12);
368 bool isReadOnlyObjCProperty() {
369 assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request");
370 return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_readonly) != 0;
372 bool isReadWriteObjCProperty() {
373 assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request");
374 return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_readwrite) != 0;
376 bool isAssignObjCProperty() {
377 assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request");
378 return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_assign) != 0;
380 bool isRetainObjCProperty() {
381 assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request");
382 return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_retain) != 0;
384 bool isCopyObjCProperty() {
385 assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request");
386 return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_copy) != 0;
388 bool isNonAtomicObjCProperty() {
389 assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request");
390 return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_nonatomic) != 0;
393 /// Verify - Verify that a derived type descriptor is well formed.
397 /// DICompositeType - This descriptor holds a type that can refer to multiple
398 /// other types, like a function or struct.
399 /// FIXME: Why is this a DIDerivedType??
400 class DICompositeType : public DIDerivedType {
401 friend class DIDescriptor;
402 void printInternal(raw_ostream &OS) const;
404 explicit DICompositeType(const MDNode *N = 0)
405 : DIDerivedType(N, true, true) {
406 if (N && !isCompositeType())
410 DIArray getTypeArray() const { return getFieldAs<DIArray>(10); }
411 unsigned getRunTimeLang() const { return getUnsignedField(11); }
412 DICompositeType getContainingType() const {
413 return getFieldAs<DICompositeType>(12);
415 DIArray getTemplateParams() const { return getFieldAs<DIArray>(13); }
417 /// Verify - Verify that a composite type descriptor is well formed.
421 /// DITemplateTypeParameter - This is a wrapper for template type parameter.
422 class DITemplateTypeParameter : public DIDescriptor {
424 explicit DITemplateTypeParameter(const MDNode *N = 0) : DIDescriptor(N) {}
426 DIScope getContext() const { return getFieldAs<DIScope>(1); }
427 StringRef getName() const { return getStringField(2); }
428 DIType getType() const { return getFieldAs<DIType>(3); }
429 StringRef getFilename() const {
430 return getFieldAs<DIFile>(4).getFilename();
432 StringRef getDirectory() const {
433 return getFieldAs<DIFile>(4).getDirectory();
435 unsigned getLineNumber() const { return getUnsignedField(5); }
436 unsigned getColumnNumber() const { return getUnsignedField(6); }
439 /// DITemplateValueParameter - This is a wrapper for template value parameter.
440 class DITemplateValueParameter : public DIDescriptor {
442 explicit DITemplateValueParameter(const MDNode *N = 0) : DIDescriptor(N) {}
444 DIScope getContext() const { return getFieldAs<DIScope>(1); }
445 StringRef getName() const { return getStringField(2); }
446 DIType getType() const { return getFieldAs<DIType>(3); }
447 uint64_t getValue() const { return getUInt64Field(4); }
448 StringRef getFilename() const {
449 return getFieldAs<DIFile>(5).getFilename();
451 StringRef getDirectory() const {
452 return getFieldAs<DIFile>(5).getDirectory();
454 unsigned getLineNumber() const { return getUnsignedField(6); }
455 unsigned getColumnNumber() const { return getUnsignedField(7); }
458 /// DISubprogram - This is a wrapper for a subprogram (e.g. a function).
459 class DISubprogram : public DIScope {
460 friend class DIDescriptor;
461 void printInternal(raw_ostream &OS) const;
463 explicit DISubprogram(const MDNode *N = 0) : DIScope(N) {}
465 DIScope getContext() const { return getFieldAs<DIScope>(2); }
466 StringRef getName() const { return getStringField(3); }
467 StringRef getDisplayName() const { return getStringField(4); }
468 StringRef getLinkageName() const { return getStringField(5); }
469 DICompileUnit getCompileUnit() const{
470 assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!");
471 if (getVersion() == llvm::LLVMDebugVersion7)
472 return getFieldAs<DICompileUnit>(6);
474 return getFieldAs<DIFile>(6).getCompileUnit();
476 unsigned getLineNumber() const { return getUnsignedField(7); }
477 DICompositeType getType() const { return getFieldAs<DICompositeType>(8); }
479 /// getReturnTypeName - Subprogram return types are encoded either as
480 /// DIType or as DICompositeType.
481 StringRef getReturnTypeName() const {
482 DICompositeType DCT(getFieldAs<DICompositeType>(8));
484 DIArray A = DCT.getTypeArray();
485 DIType T(A.getElement(0));
488 DIType T(getFieldAs<DIType>(8));
492 /// isLocalToUnit - Return true if this subprogram is local to the current
493 /// compile unit, like 'static' in C.
494 unsigned isLocalToUnit() const { return getUnsignedField(9); }
495 unsigned isDefinition() const { return getUnsignedField(10); }
497 unsigned getVirtuality() const { return getUnsignedField(11); }
498 unsigned getVirtualIndex() const { return getUnsignedField(12); }
500 DICompositeType getContainingType() const {
501 return getFieldAs<DICompositeType>(13);
504 unsigned isArtificial() const {
505 if (getVersion() <= llvm::LLVMDebugVersion8)
506 return getUnsignedField(14);
507 return (getUnsignedField(14) & FlagArtificial) != 0;
509 /// isPrivate - Return true if this subprogram has "private"
510 /// access specifier.
511 bool isPrivate() const {
512 if (getVersion() <= llvm::LLVMDebugVersion8)
514 return (getUnsignedField(14) & FlagPrivate) != 0;
516 /// isProtected - Return true if this subprogram has "protected"
517 /// access specifier.
518 bool isProtected() const {
519 if (getVersion() <= llvm::LLVMDebugVersion8)
521 return (getUnsignedField(14) & FlagProtected) != 0;
523 /// isExplicit - Return true if this subprogram is marked as explicit.
524 bool isExplicit() const {
525 if (getVersion() <= llvm::LLVMDebugVersion8)
527 return (getUnsignedField(14) & FlagExplicit) != 0;
529 /// isPrototyped - Return true if this subprogram is prototyped.
530 bool isPrototyped() const {
531 if (getVersion() <= llvm::LLVMDebugVersion8)
533 return (getUnsignedField(14) & FlagPrototyped) != 0;
536 unsigned isOptimized() const;
538 StringRef getFilename() const {
539 if (getVersion() == llvm::LLVMDebugVersion7)
540 return getCompileUnit().getFilename();
542 return getFieldAs<DIFile>(6).getFilename();
545 StringRef getDirectory() const {
546 if (getVersion() == llvm::LLVMDebugVersion7)
547 return getCompileUnit().getFilename();
549 return getFieldAs<DIFile>(6).getDirectory();
552 /// getScopeLineNumber - Get the beginning of the scope of the
553 /// function, not necessarily where the name of the program
555 unsigned getScopeLineNumber() const { return getUnsignedField(20); }
557 /// Verify - Verify that a subprogram descriptor is well formed.
560 /// describes - Return true if this subprogram provides debugging
561 /// information for the function F.
562 bool describes(const Function *F);
564 Function *getFunction() const { return getFunctionField(16); }
565 DIArray getTemplateParams() const { return getFieldAs<DIArray>(17); }
566 DISubprogram getFunctionDeclaration() const {
567 return getFieldAs<DISubprogram>(18);
569 MDNode *getVariablesNodes() const;
570 DIArray getVariables() const;
573 /// DIGlobalVariable - This is a wrapper for a global variable.
574 class DIGlobalVariable : public DIDescriptor {
575 friend class DIDescriptor;
576 void printInternal(raw_ostream &OS) const;
578 explicit DIGlobalVariable(const MDNode *N = 0) : DIDescriptor(N) {}
580 DIScope getContext() const { return getFieldAs<DIScope>(2); }
581 StringRef getName() const { return getStringField(3); }
582 StringRef getDisplayName() const { return getStringField(4); }
583 StringRef getLinkageName() const { return getStringField(5); }
584 DICompileUnit getCompileUnit() const{
585 assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!");
586 if (getVersion() == llvm::LLVMDebugVersion7)
587 return getFieldAs<DICompileUnit>(6);
589 DIFile F = getFieldAs<DIFile>(6);
590 return F.getCompileUnit();
592 StringRef getFilename() const {
593 if (getVersion() <= llvm::LLVMDebugVersion10)
594 return getContext().getFilename();
595 return getFieldAs<DIFile>(6).getFilename();
597 StringRef getDirectory() const {
598 if (getVersion() <= llvm::LLVMDebugVersion10)
599 return getContext().getDirectory();
600 return getFieldAs<DIFile>(6).getDirectory();
604 unsigned getLineNumber() const { return getUnsignedField(7); }
605 DIType getType() const { return getFieldAs<DIType>(8); }
606 unsigned isLocalToUnit() const { return getUnsignedField(9); }
607 unsigned isDefinition() const { return getUnsignedField(10); }
609 GlobalVariable *getGlobal() const { return getGlobalVariableField(11); }
610 Constant *getConstant() const { return getConstantField(11); }
612 /// Verify - Verify that a global variable descriptor is well formed.
616 /// DIVariable - This is a wrapper for a variable (e.g. parameter, local,
618 class DIVariable : public DIDescriptor {
619 friend class DIDescriptor;
620 void printInternal(raw_ostream &OS) const;
622 explicit DIVariable(const MDNode *N = 0)
625 DIScope getContext() const { return getFieldAs<DIScope>(1); }
626 StringRef getName() const { return getStringField(2); }
627 DICompileUnit getCompileUnit() const {
628 assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!");
629 if (getVersion() == llvm::LLVMDebugVersion7)
630 return getFieldAs<DICompileUnit>(3);
632 DIFile F = getFieldAs<DIFile>(3);
633 return F.getCompileUnit();
635 unsigned getLineNumber() const {
636 return (getUnsignedField(4) << 8) >> 8;
638 unsigned getArgNumber() const {
639 unsigned L = getUnsignedField(4);
642 DIType getType() const { return getFieldAs<DIType>(5); }
644 /// isArtificial - Return true if this variable is marked as "artificial".
645 bool isArtificial() const {
646 if (getVersion() <= llvm::LLVMDebugVersion8)
648 return (getUnsignedField(6) & FlagArtificial) != 0;
651 bool isObjectPointer() const {
652 return (getUnsignedField(6) & FlagObjectPointer) != 0;
655 /// getInlinedAt - If this variable is inlined then return inline location.
656 MDNode *getInlinedAt() const;
658 /// Verify - Verify that a variable descriptor is well formed.
661 /// HasComplexAddr - Return true if the variable has a complex address.
662 bool hasComplexAddress() const {
663 return getNumAddrElements() > 0;
666 unsigned getNumAddrElements() const;
668 uint64_t getAddrElement(unsigned Idx) const {
669 if (getVersion() <= llvm::LLVMDebugVersion8)
670 return getUInt64Field(Idx+6);
671 if (getVersion() == llvm::LLVMDebugVersion9)
672 return getUInt64Field(Idx+7);
673 return getUInt64Field(Idx+8);
676 /// isBlockByrefVariable - Return true if the variable was declared as
677 /// a "__block" variable (Apple Blocks).
678 bool isBlockByrefVariable() const {
679 return getType().isBlockByrefStruct();
682 /// isInlinedFnArgument - Return trule if this variable provides debugging
683 /// information for an inlined function arguments.
684 bool isInlinedFnArgument(const Function *CurFn);
686 void printExtendedName(raw_ostream &OS) const;
689 /// DILexicalBlock - This is a wrapper for a lexical block.
690 class DILexicalBlock : public DIScope {
692 explicit DILexicalBlock(const MDNode *N = 0) : DIScope(N) {}
693 DIScope getContext() const { return getFieldAs<DIScope>(1); }
694 unsigned getLineNumber() const { return getUnsignedField(2); }
695 unsigned getColumnNumber() const { return getUnsignedField(3); }
696 StringRef getDirectory() const {
697 StringRef dir = getFieldAs<DIFile>(4).getDirectory();
698 return !dir.empty() ? dir : getContext().getDirectory();
700 StringRef getFilename() const {
701 StringRef filename = getFieldAs<DIFile>(4).getFilename();
702 return !filename.empty() ? filename : getContext().getFilename();
706 /// DILexicalBlockFile - This is a wrapper for a lexical block with
707 /// a filename change.
708 class DILexicalBlockFile : public DIScope {
710 explicit DILexicalBlockFile(const MDNode *N = 0) : DIScope(N) {}
711 DIScope getContext() const { return getScope().getContext(); }
712 unsigned getLineNumber() const { return getScope().getLineNumber(); }
713 unsigned getColumnNumber() const { return getScope().getColumnNumber(); }
714 StringRef getDirectory() const {
715 StringRef dir = getFieldAs<DIFile>(2).getDirectory();
716 return !dir.empty() ? dir : getContext().getDirectory();
718 StringRef getFilename() const {
719 StringRef filename = getFieldAs<DIFile>(2).getFilename();
720 assert(!filename.empty() && "Why'd you create this then?");
723 DILexicalBlock getScope() const { return getFieldAs<DILexicalBlock>(1); }
726 /// DINameSpace - A wrapper for a C++ style name space.
727 class DINameSpace : public DIScope {
729 explicit DINameSpace(const MDNode *N = 0) : DIScope(N) {}
730 DIScope getContext() const { return getFieldAs<DIScope>(1); }
731 StringRef getName() const { return getStringField(2); }
732 StringRef getDirectory() const {
733 return getFieldAs<DIFile>(3).getDirectory();
735 StringRef getFilename() const {
736 return getFieldAs<DIFile>(3).getFilename();
738 DICompileUnit getCompileUnit() const{
739 assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!");
740 if (getVersion() == llvm::LLVMDebugVersion7)
741 return getFieldAs<DICompileUnit>(3);
743 return getFieldAs<DIFile>(3).getCompileUnit();
745 unsigned getLineNumber() const { return getUnsignedField(4); }
749 /// DILocation - This object holds location information. This object
750 /// is not associated with any DWARF tag.
751 class DILocation : public DIDescriptor {
753 explicit DILocation(const MDNode *N) : DIDescriptor(N) { }
755 unsigned getLineNumber() const { return getUnsignedField(0); }
756 unsigned getColumnNumber() const { return getUnsignedField(1); }
757 DIScope getScope() const { return getFieldAs<DIScope>(2); }
758 DILocation getOrigLocation() const { return getFieldAs<DILocation>(3); }
759 StringRef getFilename() const { return getScope().getFilename(); }
760 StringRef getDirectory() const { return getScope().getDirectory(); }
764 class DIObjCProperty : public DIDescriptor {
765 friend class DIDescriptor;
766 void printInternal(raw_ostream &OS) const;
768 explicit DIObjCProperty(const MDNode *N) : DIDescriptor(N) { }
770 StringRef getObjCPropertyName() const { return getStringField(1); }
771 DIFile getFile() const { return getFieldAs<DIFile>(2); }
772 unsigned getLineNumber() const { return getUnsignedField(3); }
774 StringRef getObjCPropertyGetterName() const {
775 return getStringField(4);
777 StringRef getObjCPropertySetterName() const {
778 return getStringField(5);
780 bool isReadOnlyObjCProperty() {
781 return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_readonly) != 0;
783 bool isReadWriteObjCProperty() {
784 return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_readwrite) != 0;
786 bool isAssignObjCProperty() {
787 return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_assign) != 0;
789 bool isRetainObjCProperty() {
790 return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_retain) != 0;
792 bool isCopyObjCProperty() {
793 return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_copy) != 0;
795 bool isNonAtomicObjCProperty() {
796 return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_nonatomic) != 0;
799 DIType getType() const { return getFieldAs<DIType>(7); }
801 /// Verify - Verify that a derived type descriptor is well formed.
805 /// getDISubprogram - Find subprogram that is enclosing this scope.
806 DISubprogram getDISubprogram(const MDNode *Scope);
808 /// getDICompositeType - Find underlying composite type.
809 DICompositeType getDICompositeType(DIType T);
811 /// isSubprogramContext - Return true if Context is either a subprogram
812 /// or another context nested inside a subprogram.
813 bool isSubprogramContext(const MDNode *Context);
815 /// getOrInsertFnSpecificMDNode - Return a NameMDNode that is suitable
816 /// to hold function specific information.
817 NamedMDNode *getOrInsertFnSpecificMDNode(Module &M, DISubprogram SP);
819 /// getFnSpecificMDNode - Return a NameMDNode, if available, that is
820 /// suitable to hold function specific information.
821 NamedMDNode *getFnSpecificMDNode(const Module &M, DISubprogram SP);
823 /// createInlinedVariable - Create a new inlined variable based on current
825 /// @param DV Current Variable.
826 /// @param InlinedScope Location at current variable is inlined.
827 DIVariable createInlinedVariable(MDNode *DV, MDNode *InlinedScope,
828 LLVMContext &VMContext);
830 /// cleanseInlinedVariable - Remove inlined scope from the variable.
831 DIVariable cleanseInlinedVariable(MDNode *DV, LLVMContext &VMContext);
833 class DebugInfoFinder {
835 /// processModule - Process entire module and collect debug info
837 void processModule(Module &M);
840 /// processType - Process DIType.
841 void processType(DIType DT);
843 /// processLexicalBlock - Process DILexicalBlock.
844 void processLexicalBlock(DILexicalBlock LB);
846 /// processSubprogram - Process DISubprogram.
847 void processSubprogram(DISubprogram SP);
849 /// processDeclare - Process DbgDeclareInst.
850 void processDeclare(DbgDeclareInst *DDI);
852 /// processLocation - Process DILocation.
853 void processLocation(DILocation Loc);
855 /// addCompileUnit - Add compile unit into CUs.
856 bool addCompileUnit(DICompileUnit CU);
858 /// addGlobalVariable - Add global variable into GVs.
859 bool addGlobalVariable(DIGlobalVariable DIG);
861 // addSubprogram - Add subprogram into SPs.
862 bool addSubprogram(DISubprogram SP);
864 /// addType - Add type into Tys.
865 bool addType(DIType DT);
868 typedef SmallVector<MDNode *, 8>::const_iterator iterator;
869 iterator compile_unit_begin() const { return CUs.begin(); }
870 iterator compile_unit_end() const { return CUs.end(); }
871 iterator subprogram_begin() const { return SPs.begin(); }
872 iterator subprogram_end() const { return SPs.end(); }
873 iterator global_variable_begin() const { return GVs.begin(); }
874 iterator global_variable_end() const { return GVs.end(); }
875 iterator type_begin() const { return TYs.begin(); }
876 iterator type_end() const { return TYs.end(); }
878 unsigned compile_unit_count() const { return CUs.size(); }
879 unsigned global_variable_count() const { return GVs.size(); }
880 unsigned subprogram_count() const { return SPs.size(); }
881 unsigned type_count() const { return TYs.size(); }
884 SmallVector<MDNode *, 8> CUs; // Compile Units
885 SmallVector<MDNode *, 8> SPs; // Subprograms
886 SmallVector<MDNode *, 8> GVs; // Global Variables;
887 SmallVector<MDNode *, 8> TYs; // Types
888 SmallPtrSet<MDNode *, 64> NodesSeen;
890 } // end namespace llvm