• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===--- llvm/Analysis/DebugInfo.h - Debug Information Helpers --*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // 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
13 // DWARF information.
14 //
15 //===----------------------------------------------------------------------===//
16 
17 #ifndef LLVM_ANALYSIS_DEBUGINFO_H
18 #define LLVM_ANALYSIS_DEBUGINFO_H
19 
20 #include "llvm/ADT/SmallVector.h"
21 #include "llvm/ADT/SmallPtrSet.h"
22 #include "llvm/ADT/StringRef.h"
23 #include "llvm/Support/Dwarf.h"
24 
25 namespace llvm {
26   class BasicBlock;
27   class Constant;
28   class Function;
29   class GlobalVariable;
30   class Module;
31   class Type;
32   class Value;
33   class DbgDeclareInst;
34   class Instruction;
35   class MDNode;
36   class NamedMDNode;
37   class LLVMContext;
38   class raw_ostream;
39 
40   class DIFile;
41   class DISubprogram;
42   class DILexicalBlock;
43   class DILexicalBlockFile;
44   class DIVariable;
45   class DIType;
46   class DIObjCProperty;
47 
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.
51   class DIDescriptor {
52   public:
53     enum {
54       FlagPrivate            = 1 << 0,
55       FlagProtected          = 1 << 1,
56       FlagFwdDecl            = 1 << 2,
57       FlagAppleBlock         = 1 << 3,
58       FlagBlockByrefStruct   = 1 << 4,
59       FlagVirtual            = 1 << 5,
60       FlagArtificial         = 1 << 6,
61       FlagExplicit           = 1 << 7,
62       FlagPrototyped         = 1 << 8,
63       FlagObjcClassComplete  = 1 << 9
64     };
65   protected:
66     const MDNode *DbgNode;
67 
68     StringRef getStringField(unsigned Elt) const;
getUnsignedField(unsigned Elt)69     unsigned getUnsignedField(unsigned Elt) const {
70       return (unsigned)getUInt64Field(Elt);
71     }
72     uint64_t getUInt64Field(unsigned Elt) const;
73     DIDescriptor getDescriptorField(unsigned Elt) const;
74 
75     template <typename DescTy>
getFieldAs(unsigned Elt)76     DescTy getFieldAs(unsigned Elt) const {
77       return DescTy(getDescriptorField(Elt));
78     }
79 
80     GlobalVariable *getGlobalVariableField(unsigned Elt) const;
81     Constant *getConstantField(unsigned Elt) const;
82     Function *getFunctionField(unsigned Elt) const;
83 
84   public:
DIDescriptor()85     explicit DIDescriptor() : DbgNode(0) {}
DIDescriptor(const MDNode * N)86     explicit DIDescriptor(const MDNode *N) : DbgNode(N) {}
87     explicit DIDescriptor(const DIFile F);
88     explicit DIDescriptor(const DISubprogram F);
89     explicit DIDescriptor(const DILexicalBlockFile F);
90     explicit DIDescriptor(const DILexicalBlock F);
91     explicit DIDescriptor(const DIVariable F);
92     explicit DIDescriptor(const DIType F);
93 
Verify()94     bool Verify() const { return DbgNode != 0; }
95 
96     operator MDNode *() const { return const_cast<MDNode*>(DbgNode); }
97     MDNode *operator ->() const { return const_cast<MDNode*>(DbgNode); }
98 
getVersion()99     unsigned getVersion() const {
100       return getUnsignedField(0) & LLVMDebugVersionMask;
101     }
102 
getTag()103     unsigned getTag() const {
104       return getUnsignedField(0) & ~LLVMDebugVersionMask;
105     }
106 
107     bool isDerivedType() const;
108     bool isCompositeType() const;
109     bool isBasicType() const;
110     bool isVariable() const;
111     bool isSubprogram() const;
112     bool isGlobalVariable() const;
113     bool isScope() const;
114     bool isFile() const;
115     bool isCompileUnit() const;
116     bool isNameSpace() const;
117     bool isLexicalBlockFile() const;
118     bool isLexicalBlock() const;
119     bool isSubrange() const;
120     bool isEnumerator() const;
121     bool isType() const;
122     bool isGlobal() const;
123     bool isUnspecifiedParameter() const;
124     bool isTemplateTypeParameter() const;
125     bool isTemplateValueParameter() const;
126     bool isObjCProperty() const;
127 
128     /// print - print descriptor.
129     void print(raw_ostream &OS) const;
130 
131     /// dump - print descriptor to dbgs() with a newline.
132     void dump() const;
133   };
134 
135   /// DISubrange - This is used to represent ranges, for array bounds.
136   class DISubrange : public DIDescriptor {
137     friend class DIDescriptor;
138     void printInternal(raw_ostream &OS) const;
139   public:
DIDescriptor(N)140     explicit DISubrange(const MDNode *N = 0) : DIDescriptor(N) {}
141 
getLo()142     uint64_t getLo() const { return getUInt64Field(1); }
getHi()143     uint64_t getHi() const { return getUInt64Field(2); }
144   };
145 
146   /// DIArray - This descriptor holds an array of descriptors.
147   class DIArray : public DIDescriptor {
148   public:
149     explicit DIArray(const MDNode *N = 0)
DIDescriptor(N)150       : DIDescriptor(N) {}
151 
152     unsigned getNumElements() const;
getElement(unsigned Idx)153     DIDescriptor getElement(unsigned Idx) const {
154       return getDescriptorField(Idx);
155     }
156   };
157 
158   /// DIScope - A base class for various scopes.
159   class DIScope : public DIDescriptor {
160   protected:
161     friend class DIDescriptor;
162     void printInternal(raw_ostream &OS) const;
163   public:
DIDescriptor(N)164     explicit DIScope(const MDNode *N = 0) : DIDescriptor (N) {}
165 
166     StringRef getFilename() const;
167     StringRef getDirectory() const;
168   };
169 
170   /// DICompileUnit - A wrapper for a compile unit.
171   class DICompileUnit : public DIScope {
172     friend class DIDescriptor;
173     void printInternal(raw_ostream &OS) const;
174   public:
DIScope(N)175     explicit DICompileUnit(const MDNode *N = 0) : DIScope(N) {}
176 
getLanguage()177     unsigned getLanguage() const   { return getUnsignedField(2); }
getFilename()178     StringRef getFilename() const  { return getStringField(3);   }
getDirectory()179     StringRef getDirectory() const { return getStringField(4);   }
getProducer()180     StringRef getProducer() const  { return getStringField(5);   }
181 
182     /// isMain - Each input file is encoded as a separate compile unit in LLVM
183     /// debugging information output. However, many target specific tool chains
184     /// prefer to encode only one compile unit in an object file. In this
185     /// situation, the LLVM code generator will include  debugging information
186     /// entities in the compile unit that is marked as main compile unit. The
187     /// code generator accepts maximum one main compile unit per module. If a
188     /// module does not contain any main compile unit then the code generator
189     /// will emit multiple compile units in the output object file.
190 
isMain()191     bool isMain() const                { return getUnsignedField(6) != 0; }
isOptimized()192     bool isOptimized() const           { return getUnsignedField(7) != 0; }
getFlags()193     StringRef getFlags() const       { return getStringField(8);   }
getRunTimeVersion()194     unsigned getRunTimeVersion() const { return getUnsignedField(9); }
195 
196     DIArray getEnumTypes() const;
197     DIArray getRetainedTypes() const;
198     DIArray getSubprograms() const;
199     DIArray getGlobalVariables() const;
200 
201     /// Verify - Verify that a compile unit is well formed.
202     bool Verify() const;
203   };
204 
205   /// DIFile - This is a wrapper for a file.
206   class DIFile : public DIScope {
207     friend class DIDescriptor;
printInternal(raw_ostream & OS)208     void printInternal(raw_ostream &OS) const {} // FIXME: Output something?
209   public:
DIScope(N)210     explicit DIFile(const MDNode *N = 0) : DIScope(N) {
211       if (DbgNode && !isFile())
212         DbgNode = 0;
213     }
getFilename()214     StringRef getFilename() const  { return getStringField(1);   }
getDirectory()215     StringRef getDirectory() const { return getStringField(2);   }
getCompileUnit()216     DICompileUnit getCompileUnit() const{
217       assert (getVersion() <= LLVMDebugVersion10  && "Invalid CompileUnit!");
218       return getFieldAs<DICompileUnit>(3);
219     }
220   };
221 
222   /// DIEnumerator - A wrapper for an enumerator (e.g. X and Y in 'enum {X,Y}').
223   /// FIXME: it seems strange that this doesn't have either a reference to the
224   /// type/precision or a file/line pair for location info.
225   class DIEnumerator : public DIDescriptor {
226     friend class DIDescriptor;
227     void printInternal(raw_ostream &OS) const;
228   public:
DIDescriptor(N)229     explicit DIEnumerator(const MDNode *N = 0) : DIDescriptor(N) {}
230 
getName()231     StringRef getName() const        { return getStringField(1); }
getEnumValue()232     uint64_t getEnumValue() const      { return getUInt64Field(2); }
233   };
234 
235   /// DIType - This is a wrapper for a type.
236   /// FIXME: Types should be factored much better so that CV qualifiers and
237   /// others do not require a huge and empty descriptor full of zeros.
238   class DIType : public DIScope {
239   protected:
240     friend class DIDescriptor;
241     void printInternal(raw_ostream &OS) const;
242     // This ctor is used when the Tag has already been validated by a derived
243     // ctor.
DIType(const MDNode * N,bool,bool)244     DIType(const MDNode *N, bool, bool) : DIScope(N) {}
245   public:
246     /// Verify - Verify that a type descriptor is well formed.
247     bool Verify() const;
248     explicit DIType(const MDNode *N);
DIType()249     explicit DIType() {}
250 
getContext()251     DIScope getContext() const          { return getFieldAs<DIScope>(1); }
getName()252     StringRef getName() const           { return getStringField(2);     }
getCompileUnit()253     DICompileUnit getCompileUnit() const{
254       assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!");
255      if (getVersion() == llvm::LLVMDebugVersion7)
256        return getFieldAs<DICompileUnit>(3);
257 
258      return getFieldAs<DIFile>(3).getCompileUnit();
259     }
getFile()260     DIFile getFile() const              { return getFieldAs<DIFile>(3); }
getLineNumber()261     unsigned getLineNumber() const      { return getUnsignedField(4); }
getSizeInBits()262     uint64_t getSizeInBits() const      { return getUInt64Field(5); }
getAlignInBits()263     uint64_t getAlignInBits() const     { return getUInt64Field(6); }
264     // FIXME: Offset is only used for DW_TAG_member nodes.  Making every type
265     // carry this is just plain insane.
getOffsetInBits()266     uint64_t getOffsetInBits() const    { return getUInt64Field(7); }
getFlags()267     unsigned getFlags() const           { return getUnsignedField(8); }
isPrivate()268     bool isPrivate() const {
269       return (getFlags() & FlagPrivate) != 0;
270     }
isProtected()271     bool isProtected() const {
272       return (getFlags() & FlagProtected) != 0;
273     }
isForwardDecl()274     bool isForwardDecl() const {
275       return (getFlags() & FlagFwdDecl) != 0;
276     }
277     // isAppleBlock - Return true if this is the Apple Blocks extension.
isAppleBlockExtension()278     bool isAppleBlockExtension() const {
279       return (getFlags() & FlagAppleBlock) != 0;
280     }
isBlockByrefStruct()281     bool isBlockByrefStruct() const {
282       return (getFlags() & FlagBlockByrefStruct) != 0;
283     }
isVirtual()284     bool isVirtual() const {
285       return (getFlags() & FlagVirtual) != 0;
286     }
isArtificial()287     bool isArtificial() const {
288       return (getFlags() & FlagArtificial) != 0;
289     }
isObjcClassComplete()290     bool isObjcClassComplete() const {
291       return (getFlags() & FlagObjcClassComplete) != 0;
292     }
isValid()293     bool isValid() const {
294       return DbgNode && (isBasicType() || isDerivedType() || isCompositeType());
295     }
getDirectory()296     StringRef getDirectory() const  {
297       if (getVersion() == llvm::LLVMDebugVersion7)
298         return getCompileUnit().getDirectory();
299 
300       return getFieldAs<DIFile>(3).getDirectory();
301     }
getFilename()302     StringRef getFilename() const  {
303       if (getVersion() == llvm::LLVMDebugVersion7)
304         return getCompileUnit().getFilename();
305 
306       return getFieldAs<DIFile>(3).getFilename();
307     }
308 
309     /// isUnsignedDIType - Return true if type encoding is unsigned.
310     bool isUnsignedDIType();
311 
312     /// replaceAllUsesWith - Replace all uses of debug info referenced by
313     /// this descriptor.
314     void replaceAllUsesWith(DIDescriptor &D);
315     void replaceAllUsesWith(MDNode *D);
316   };
317 
318   /// DIBasicType - A basic type, like 'int' or 'float'.
319   class DIBasicType : public DIType {
320   public:
DIType(N)321     explicit DIBasicType(const MDNode *N = 0) : DIType(N) {}
322 
getEncoding()323     unsigned getEncoding() const { return getUnsignedField(9); }
324 
325     /// Verify - Verify that a basic type descriptor is well formed.
326     bool Verify() const;
327   };
328 
329   /// DIDerivedType - A simple derived type, like a const qualified type,
330   /// a typedef, a pointer or reference, etc.
331   class DIDerivedType : public DIType {
332     friend class DIDescriptor;
333     void printInternal(raw_ostream &OS) const;
334   protected:
DIDerivedType(const MDNode * N,bool,bool)335     explicit DIDerivedType(const MDNode *N, bool, bool)
336       : DIType(N, true, true) {}
337   public:
338     explicit DIDerivedType(const MDNode *N = 0)
DIType(N,true,true)339       : DIType(N, true, true) {}
340 
getTypeDerivedFrom()341     DIType getTypeDerivedFrom() const { return getFieldAs<DIType>(9); }
342 
343     /// getOriginalTypeSize - If this type is derived from a base type then
344     /// return base type size.
345     uint64_t getOriginalTypeSize() const;
346 
347     /// getObjCProperty - Return property node, if this ivar is
348     /// associated with one.
349     MDNode *getObjCProperty() const;
350 
getObjCPropertyName()351     StringRef getObjCPropertyName() const {
352       if (getVersion() > LLVMDebugVersion11)
353         return StringRef();
354       return getStringField(10);
355     }
getObjCPropertyGetterName()356     StringRef getObjCPropertyGetterName() const {
357       assert (getVersion() <= LLVMDebugVersion11  && "Invalid Request");
358       return getStringField(11);
359     }
getObjCPropertySetterName()360     StringRef getObjCPropertySetterName() const {
361       assert (getVersion() <= LLVMDebugVersion11  && "Invalid Request");
362       return getStringField(12);
363     }
isReadOnlyObjCProperty()364     bool isReadOnlyObjCProperty() {
365       assert (getVersion() <= LLVMDebugVersion11  && "Invalid Request");
366       return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_readonly) != 0;
367     }
isReadWriteObjCProperty()368     bool isReadWriteObjCProperty() {
369       assert (getVersion() <= LLVMDebugVersion11  && "Invalid Request");
370       return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_readwrite) != 0;
371     }
isAssignObjCProperty()372     bool isAssignObjCProperty() {
373       assert (getVersion() <= LLVMDebugVersion11  && "Invalid Request");
374       return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_assign) != 0;
375     }
isRetainObjCProperty()376     bool isRetainObjCProperty() {
377       assert (getVersion() <= LLVMDebugVersion11  && "Invalid Request");
378       return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_retain) != 0;
379     }
isCopyObjCProperty()380     bool isCopyObjCProperty() {
381       assert (getVersion() <= LLVMDebugVersion11  && "Invalid Request");
382       return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_copy) != 0;
383     }
isNonAtomicObjCProperty()384     bool isNonAtomicObjCProperty() {
385       assert (getVersion() <= LLVMDebugVersion11  && "Invalid Request");
386       return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_nonatomic) != 0;
387     }
388 
389     /// Verify - Verify that a derived type descriptor is well formed.
390     bool Verify() const;
391   };
392 
393   /// DICompositeType - This descriptor holds a type that can refer to multiple
394   /// other types, like a function or struct.
395   /// FIXME: Why is this a DIDerivedType??
396   class DICompositeType : public DIDerivedType {
397     friend class DIDescriptor;
398     void printInternal(raw_ostream &OS) const;
399   public:
400     explicit DICompositeType(const MDNode *N = 0)
DIDerivedType(N,true,true)401       : DIDerivedType(N, true, true) {
402       if (N && !isCompositeType())
403         DbgNode = 0;
404     }
405 
getTypeArray()406     DIArray getTypeArray() const { return getFieldAs<DIArray>(10); }
getRunTimeLang()407     unsigned getRunTimeLang() const { return getUnsignedField(11); }
getContainingType()408     DICompositeType getContainingType() const {
409       return getFieldAs<DICompositeType>(12);
410     }
getTemplateParams()411     DIArray getTemplateParams() const { return getFieldAs<DIArray>(13); }
412 
413     /// Verify - Verify that a composite type descriptor is well formed.
414     bool Verify() const;
415   };
416 
417   /// DITemplateTypeParameter - This is a wrapper for template type parameter.
418   class DITemplateTypeParameter : public DIDescriptor {
419   public:
DIDescriptor(N)420     explicit DITemplateTypeParameter(const MDNode *N = 0) : DIDescriptor(N) {}
421 
getContext()422     DIScope getContext() const       { return getFieldAs<DIScope>(1); }
getName()423     StringRef getName() const        { return getStringField(2); }
getType()424     DIType getType() const           { return getFieldAs<DIType>(3); }
getFilename()425     StringRef getFilename() const    {
426       return getFieldAs<DIFile>(4).getFilename();
427     }
getDirectory()428     StringRef getDirectory() const   {
429       return getFieldAs<DIFile>(4).getDirectory();
430     }
getLineNumber()431     unsigned getLineNumber() const   { return getUnsignedField(5); }
getColumnNumber()432     unsigned getColumnNumber() const { return getUnsignedField(6); }
433   };
434 
435   /// DITemplateValueParameter - This is a wrapper for template value parameter.
436   class DITemplateValueParameter : public DIDescriptor {
437   public:
DIDescriptor(N)438     explicit DITemplateValueParameter(const MDNode *N = 0) : DIDescriptor(N) {}
439 
getContext()440     DIScope getContext() const       { return getFieldAs<DIScope>(1); }
getName()441     StringRef getName() const        { return getStringField(2); }
getType()442     DIType getType() const           { return getFieldAs<DIType>(3); }
getValue()443     uint64_t getValue() const         { return getUInt64Field(4); }
getFilename()444     StringRef getFilename() const    {
445       return getFieldAs<DIFile>(5).getFilename();
446     }
getDirectory()447     StringRef getDirectory() const   {
448       return getFieldAs<DIFile>(5).getDirectory();
449     }
getLineNumber()450     unsigned getLineNumber() const   { return getUnsignedField(6); }
getColumnNumber()451     unsigned getColumnNumber() const { return getUnsignedField(7); }
452   };
453 
454   /// DISubprogram - This is a wrapper for a subprogram (e.g. a function).
455   class DISubprogram : public DIScope {
456     friend class DIDescriptor;
457     void printInternal(raw_ostream &OS) const;
458   public:
DIScope(N)459     explicit DISubprogram(const MDNode *N = 0) : DIScope(N) {}
460 
getContext()461     DIScope getContext() const          { return getFieldAs<DIScope>(2); }
getName()462     StringRef getName() const         { return getStringField(3); }
getDisplayName()463     StringRef getDisplayName() const  { return getStringField(4); }
getLinkageName()464     StringRef getLinkageName() const  { return getStringField(5); }
getCompileUnit()465     DICompileUnit getCompileUnit() const{
466       assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!");
467       if (getVersion() == llvm::LLVMDebugVersion7)
468         return getFieldAs<DICompileUnit>(6);
469 
470       return getFieldAs<DIFile>(6).getCompileUnit();
471     }
getLineNumber()472     unsigned getLineNumber() const      { return getUnsignedField(7); }
getType()473     DICompositeType getType() const { return getFieldAs<DICompositeType>(8); }
474 
475     /// getReturnTypeName - Subprogram return types are encoded either as
476     /// DIType or as DICompositeType.
getReturnTypeName()477     StringRef getReturnTypeName() const {
478       DICompositeType DCT(getFieldAs<DICompositeType>(8));
479       if (DCT.Verify()) {
480         DIArray A = DCT.getTypeArray();
481         DIType T(A.getElement(0));
482         return T.getName();
483       }
484       DIType T(getFieldAs<DIType>(8));
485       return T.getName();
486     }
487 
488     /// isLocalToUnit - Return true if this subprogram is local to the current
489     /// compile unit, like 'static' in C.
isLocalToUnit()490     unsigned isLocalToUnit() const     { return getUnsignedField(9); }
isDefinition()491     unsigned isDefinition() const      { return getUnsignedField(10); }
492 
getVirtuality()493     unsigned getVirtuality() const { return getUnsignedField(11); }
getVirtualIndex()494     unsigned getVirtualIndex() const { return getUnsignedField(12); }
495 
getContainingType()496     DICompositeType getContainingType() const {
497       return getFieldAs<DICompositeType>(13);
498     }
499 
isArtificial()500     unsigned isArtificial() const    {
501       if (getVersion() <= llvm::LLVMDebugVersion8)
502         return getUnsignedField(14);
503       return (getUnsignedField(14) & FlagArtificial) != 0;
504     }
505     /// isPrivate - Return true if this subprogram has "private"
506     /// access specifier.
isPrivate()507     bool isPrivate() const    {
508       if (getVersion() <= llvm::LLVMDebugVersion8)
509         return false;
510       return (getUnsignedField(14) & FlagPrivate) != 0;
511     }
512     /// isProtected - Return true if this subprogram has "protected"
513     /// access specifier.
isProtected()514     bool isProtected() const    {
515       if (getVersion() <= llvm::LLVMDebugVersion8)
516         return false;
517       return (getUnsignedField(14) & FlagProtected) != 0;
518     }
519     /// isExplicit - Return true if this subprogram is marked as explicit.
isExplicit()520     bool isExplicit() const    {
521       if (getVersion() <= llvm::LLVMDebugVersion8)
522         return false;
523       return (getUnsignedField(14) & FlagExplicit) != 0;
524     }
525     /// isPrototyped - Return true if this subprogram is prototyped.
isPrototyped()526     bool isPrototyped() const    {
527       if (getVersion() <= llvm::LLVMDebugVersion8)
528         return false;
529       return (getUnsignedField(14) & FlagPrototyped) != 0;
530     }
531 
532     unsigned isOptimized() const;
533 
getFilename()534     StringRef getFilename() const    {
535       if (getVersion() == llvm::LLVMDebugVersion7)
536         return getCompileUnit().getFilename();
537 
538       return getFieldAs<DIFile>(6).getFilename();
539     }
540 
getDirectory()541     StringRef getDirectory() const   {
542       if (getVersion() == llvm::LLVMDebugVersion7)
543         return getCompileUnit().getFilename();
544 
545       return getFieldAs<DIFile>(6).getDirectory();
546     }
547 
548     /// getScopeLineNumber - Get the beginning of the scope of the
549     /// function, not necessarily where the name of the program
550     /// starts.
getScopeLineNumber()551     unsigned getScopeLineNumber() const { return getUnsignedField(20); }
552 
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 
getFunction()560     Function *getFunction() const { return getFunctionField(16); }
getTemplateParams()561     DIArray getTemplateParams() const { return getFieldAs<DIArray>(17); }
getFunctionDeclaration()562     DISubprogram getFunctionDeclaration() const {
563       return getFieldAs<DISubprogram>(18);
564     }
565     MDNode *getVariablesNodes() const;
566     DIArray getVariables() const;
567   };
568 
569   /// DIGlobalVariable - This is a wrapper for a global variable.
570   class DIGlobalVariable : public DIDescriptor {
571     friend class DIDescriptor;
572     void printInternal(raw_ostream &OS) const;
573   public:
DIDescriptor(N)574     explicit DIGlobalVariable(const MDNode *N = 0) : DIDescriptor(N) {}
575 
getContext()576     DIScope getContext() const          { return getFieldAs<DIScope>(2); }
getName()577     StringRef getName() const         { return getStringField(3); }
getDisplayName()578     StringRef getDisplayName() const  { return getStringField(4); }
getLinkageName()579     StringRef getLinkageName() const  { return getStringField(5); }
getCompileUnit()580     DICompileUnit getCompileUnit() const{
581       assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!");
582       if (getVersion() == llvm::LLVMDebugVersion7)
583         return getFieldAs<DICompileUnit>(6);
584 
585       DIFile F = getFieldAs<DIFile>(6);
586       return F.getCompileUnit();
587     }
getFilename()588     StringRef getFilename() const {
589       if (getVersion() <= llvm::LLVMDebugVersion10)
590         return getContext().getFilename();
591       return getFieldAs<DIFile>(6).getFilename();
592     }
getDirectory()593     StringRef getDirectory() const {
594       if (getVersion() <= llvm::LLVMDebugVersion10)
595         return getContext().getDirectory();
596       return getFieldAs<DIFile>(6).getDirectory();
597 
598     }
599 
getLineNumber()600     unsigned getLineNumber() const      { return getUnsignedField(7); }
getType()601     DIType getType() const              { return getFieldAs<DIType>(8); }
isLocalToUnit()602     unsigned isLocalToUnit() const      { return getUnsignedField(9); }
isDefinition()603     unsigned isDefinition() const       { return getUnsignedField(10); }
604 
getGlobal()605     GlobalVariable *getGlobal() const { return getGlobalVariableField(11); }
getConstant()606     Constant *getConstant() const   { return getConstantField(11); }
607 
608     /// Verify - Verify that a global variable descriptor is well formed.
609     bool Verify() const;
610   };
611 
612   /// DIVariable - This is a wrapper for a variable (e.g. parameter, local,
613   /// global etc).
614   class DIVariable : public DIDescriptor {
615     friend class DIDescriptor;
616     void printInternal(raw_ostream &OS) const;
617   public:
618     explicit DIVariable(const MDNode *N = 0)
DIDescriptor(N)619       : DIDescriptor(N) {}
620 
getContext()621     DIScope getContext() const          { return getFieldAs<DIScope>(1); }
getName()622     StringRef getName() const           { return getStringField(2);     }
getCompileUnit()623     DICompileUnit getCompileUnit() const {
624       assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!");
625       if (getVersion() == llvm::LLVMDebugVersion7)
626         return getFieldAs<DICompileUnit>(3);
627 
628       DIFile F = getFieldAs<DIFile>(3);
629       return F.getCompileUnit();
630     }
getLineNumber()631     unsigned getLineNumber() const      {
632       return (getUnsignedField(4) << 8) >> 8;
633     }
getArgNumber()634     unsigned getArgNumber() const       {
635       unsigned L = getUnsignedField(4);
636       return L >> 24;
637     }
getType()638     DIType getType() const              { return getFieldAs<DIType>(5); }
639 
640     /// isArtificial - Return true if this variable is marked as "artificial".
isArtificial()641     bool isArtificial() const    {
642       if (getVersion() <= llvm::LLVMDebugVersion8)
643         return false;
644       return (getUnsignedField(6) & FlagArtificial) != 0;
645     }
646 
647     /// getInlinedAt - If this variable is inlined then return inline location.
648     MDNode *getInlinedAt() const;
649 
650     /// Verify - Verify that a variable descriptor is well formed.
651     bool Verify() const;
652 
653     /// HasComplexAddr - Return true if the variable has a complex address.
hasComplexAddress()654     bool hasComplexAddress() const {
655       return getNumAddrElements() > 0;
656     }
657 
658     unsigned getNumAddrElements() const;
659 
getAddrElement(unsigned Idx)660     uint64_t getAddrElement(unsigned Idx) const {
661       if (getVersion() <= llvm::LLVMDebugVersion8)
662         return getUInt64Field(Idx+6);
663       if (getVersion() == llvm::LLVMDebugVersion9)
664         return getUInt64Field(Idx+7);
665       return getUInt64Field(Idx+8);
666     }
667 
668     /// isBlockByrefVariable - Return true if the variable was declared as
669     /// a "__block" variable (Apple Blocks).
isBlockByrefVariable()670     bool isBlockByrefVariable() const {
671       return getType().isBlockByrefStruct();
672     }
673 
674     /// isInlinedFnArgument - Return trule if this variable provides debugging
675     /// information for an inlined function arguments.
676     bool isInlinedFnArgument(const Function *CurFn);
677 
678     void printExtendedName(raw_ostream &OS) const;
679   };
680 
681   /// DILexicalBlock - This is a wrapper for a lexical block.
682   class DILexicalBlock : public DIScope {
683   public:
DIScope(N)684     explicit DILexicalBlock(const MDNode *N = 0) : DIScope(N) {}
getContext()685     DIScope getContext() const       { return getFieldAs<DIScope>(1);      }
getLineNumber()686     unsigned getLineNumber() const   { return getUnsignedField(2);         }
getColumnNumber()687     unsigned getColumnNumber() const { return getUnsignedField(3);         }
getDirectory()688     StringRef getDirectory() const {
689       StringRef dir = getFieldAs<DIFile>(4).getDirectory();
690       return !dir.empty() ? dir : getContext().getDirectory();
691     }
getFilename()692     StringRef getFilename() const {
693       StringRef filename = getFieldAs<DIFile>(4).getFilename();
694       return !filename.empty() ? filename : getContext().getFilename();
695     }
696   };
697 
698   /// DILexicalBlockFile - This is a wrapper for a lexical block with
699   /// a filename change.
700   class DILexicalBlockFile : public DIScope {
701   public:
DIScope(N)702     explicit DILexicalBlockFile(const MDNode *N = 0) : DIScope(N) {}
getContext()703     DIScope getContext() const { return getScope().getContext(); }
getLineNumber()704     unsigned getLineNumber() const { return getScope().getLineNumber(); }
getColumnNumber()705     unsigned getColumnNumber() const { return getScope().getColumnNumber(); }
getDirectory()706     StringRef getDirectory() const {
707       StringRef dir = getFieldAs<DIFile>(2).getDirectory();
708       return !dir.empty() ? dir : getContext().getDirectory();
709     }
getFilename()710     StringRef getFilename() const {
711       StringRef filename = getFieldAs<DIFile>(2).getFilename();
712       assert(!filename.empty() && "Why'd you create this then?");
713       return filename;
714     }
getScope()715     DILexicalBlock getScope() const { return getFieldAs<DILexicalBlock>(1); }
716   };
717 
718   /// DINameSpace - A wrapper for a C++ style name space.
719   class DINameSpace : public DIScope {
720   public:
DIScope(N)721     explicit DINameSpace(const MDNode *N = 0) : DIScope(N) {}
getContext()722     DIScope getContext() const     { return getFieldAs<DIScope>(1);      }
getName()723     StringRef getName() const      { return getStringField(2);           }
getDirectory()724     StringRef getDirectory() const  {
725       return getFieldAs<DIFile>(3).getDirectory();
726     }
getFilename()727     StringRef getFilename() const  {
728       return getFieldAs<DIFile>(3).getFilename();
729     }
getCompileUnit()730     DICompileUnit getCompileUnit() const{
731       assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!");
732       if (getVersion() == llvm::LLVMDebugVersion7)
733         return getFieldAs<DICompileUnit>(3);
734 
735       return getFieldAs<DIFile>(3).getCompileUnit();
736     }
getLineNumber()737     unsigned getLineNumber() const { return getUnsignedField(4);         }
738     bool Verify() const;
739   };
740 
741   /// DILocation - This object holds location information. This object
742   /// is not associated with any DWARF tag.
743   class DILocation : public DIDescriptor {
744   public:
DILocation(const MDNode * N)745     explicit DILocation(const MDNode *N) : DIDescriptor(N) { }
746 
getLineNumber()747     unsigned getLineNumber() const     { return getUnsignedField(0); }
getColumnNumber()748     unsigned getColumnNumber() const   { return getUnsignedField(1); }
getScope()749     DIScope  getScope() const          { return getFieldAs<DIScope>(2); }
getOrigLocation()750     DILocation getOrigLocation() const { return getFieldAs<DILocation>(3); }
getFilename()751     StringRef getFilename() const    { return getScope().getFilename(); }
getDirectory()752     StringRef getDirectory() const   { return getScope().getDirectory(); }
753     bool Verify() const;
754   };
755 
756   class DIObjCProperty : public DIDescriptor {
757     friend class DIDescriptor;
758     void printInternal(raw_ostream &OS) const;
759   public:
DIObjCProperty(const MDNode * N)760     explicit DIObjCProperty(const MDNode *N) : DIDescriptor(N) { }
761 
getObjCPropertyName()762     StringRef getObjCPropertyName() const { return getStringField(1); }
getFile()763     DIFile getFile() const { return getFieldAs<DIFile>(2); }
getLineNumber()764     unsigned getLineNumber() const { return getUnsignedField(3); }
765 
getObjCPropertyGetterName()766     StringRef getObjCPropertyGetterName() const {
767       return getStringField(4);
768     }
getObjCPropertySetterName()769     StringRef getObjCPropertySetterName() const {
770       return getStringField(5);
771     }
isReadOnlyObjCProperty()772     bool isReadOnlyObjCProperty() {
773       return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_readonly) != 0;
774     }
isReadWriteObjCProperty()775     bool isReadWriteObjCProperty() {
776       return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_readwrite) != 0;
777     }
isAssignObjCProperty()778     bool isAssignObjCProperty() {
779       return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_assign) != 0;
780     }
isRetainObjCProperty()781     bool isRetainObjCProperty() {
782       return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_retain) != 0;
783     }
isCopyObjCProperty()784     bool isCopyObjCProperty() {
785       return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_copy) != 0;
786     }
isNonAtomicObjCProperty()787     bool isNonAtomicObjCProperty() {
788       return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_nonatomic) != 0;
789     }
790 
getType()791     DIType getType() const { return getFieldAs<DIType>(7); }
792 
793     /// Verify - Verify that a derived type descriptor is well formed.
794     bool Verify() const;
795   };
796 
797   /// getDISubprogram - Find subprogram that is enclosing this scope.
798   DISubprogram getDISubprogram(const MDNode *Scope);
799 
800   /// getDICompositeType - Find underlying composite type.
801   DICompositeType getDICompositeType(DIType T);
802 
803   /// isSubprogramContext - Return true if Context is either a subprogram
804   /// or another context nested inside a subprogram.
805   bool isSubprogramContext(const MDNode *Context);
806 
807   /// getOrInsertFnSpecificMDNode - Return a NameMDNode that is suitable
808   /// to hold function specific information.
809   NamedMDNode *getOrInsertFnSpecificMDNode(Module &M, DISubprogram SP);
810 
811   /// getFnSpecificMDNode - Return a NameMDNode, if available, that is
812   /// suitable to hold function specific information.
813   NamedMDNode *getFnSpecificMDNode(const Module &M, DISubprogram SP);
814 
815   /// createInlinedVariable - Create a new inlined variable based on current
816   /// variable.
817   /// @param DV            Current Variable.
818   /// @param InlinedScope  Location at current variable is inlined.
819   DIVariable createInlinedVariable(MDNode *DV, MDNode *InlinedScope,
820                                    LLVMContext &VMContext);
821 
822   /// cleanseInlinedVariable - Remove inlined scope from the variable.
823   DIVariable cleanseInlinedVariable(MDNode *DV, LLVMContext &VMContext);
824 
825   class DebugInfoFinder {
826   public:
827     /// processModule - Process entire module and collect debug info
828     /// anchors.
829     void processModule(Module &M);
830 
831   private:
832     /// processType - Process DIType.
833     void processType(DIType DT);
834 
835     /// processLexicalBlock - Process DILexicalBlock.
836     void processLexicalBlock(DILexicalBlock LB);
837 
838     /// processSubprogram - Process DISubprogram.
839     void processSubprogram(DISubprogram SP);
840 
841     /// processDeclare - Process DbgDeclareInst.
842     void processDeclare(DbgDeclareInst *DDI);
843 
844     /// processLocation - Process DILocation.
845     void processLocation(DILocation Loc);
846 
847     /// addCompileUnit - Add compile unit into CUs.
848     bool addCompileUnit(DICompileUnit CU);
849 
850     /// addGlobalVariable - Add global variable into GVs.
851     bool addGlobalVariable(DIGlobalVariable DIG);
852 
853     // addSubprogram - Add subprogram into SPs.
854     bool addSubprogram(DISubprogram SP);
855 
856     /// addType - Add type into Tys.
857     bool addType(DIType DT);
858 
859   public:
860     typedef SmallVector<MDNode *, 8>::const_iterator iterator;
compile_unit_begin()861     iterator compile_unit_begin()    const { return CUs.begin(); }
compile_unit_end()862     iterator compile_unit_end()      const { return CUs.end(); }
subprogram_begin()863     iterator subprogram_begin()      const { return SPs.begin(); }
subprogram_end()864     iterator subprogram_end()        const { return SPs.end(); }
global_variable_begin()865     iterator global_variable_begin() const { return GVs.begin(); }
global_variable_end()866     iterator global_variable_end()   const { return GVs.end(); }
type_begin()867     iterator type_begin()            const { return TYs.begin(); }
type_end()868     iterator type_end()              const { return TYs.end(); }
869 
compile_unit_count()870     unsigned compile_unit_count()    const { return CUs.size(); }
global_variable_count()871     unsigned global_variable_count() const { return GVs.size(); }
subprogram_count()872     unsigned subprogram_count()      const { return SPs.size(); }
type_count()873     unsigned type_count()            const { return TYs.size(); }
874 
875   private:
876     SmallVector<MDNode *, 8> CUs;  // Compile Units
877     SmallVector<MDNode *, 8> SPs;  // Subprograms
878     SmallVector<MDNode *, 8> GVs;  // Global Variables;
879     SmallVector<MDNode *, 8> TYs;  // Types
880     SmallPtrSet<MDNode *, 64> NodesSeen;
881   };
882 } // end namespace llvm
883 
884 #endif
885