]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - include/llvm/DebugInfo.h
Vendor import of llvm trunk r161861:
[FreeBSD/FreeBSD.git] / include / llvm / DebugInfo.h
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;
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>
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:
85     explicit DIDescriptor() : DbgNode(0) {}
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
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
99     unsigned getVersion() const {
100       return getUnsignedField(0) & LLVMDebugVersionMask;
101     }
102
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:
140     explicit DISubrange(const MDNode *N = 0) : DIDescriptor(N) {}
141
142     uint64_t getLo() const { return getUInt64Field(1); }
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)
150       : DIDescriptor(N) {}
151
152     unsigned getNumElements() const;
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:
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:
175     explicit DICompileUnit(const MDNode *N = 0) : DIScope(N) {}
176
177     unsigned getLanguage() const   { return getUnsignedField(2); }
178     StringRef getFilename() const  { return getStringField(3);   }
179     StringRef getDirectory() const { return getStringField(4);   }
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
191     bool isMain() const                { return getUnsignedField(6) != 0; }
192     bool isOptimized() const           { return getUnsignedField(7) != 0; }
193     StringRef getFlags() const       { return getStringField(8);   }
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;
208     void printInternal(raw_ostream &OS) const {} // FIXME: Output something?
209   public:
210     explicit DIFile(const MDNode *N = 0) : DIScope(N) {
211       if (DbgNode && !isFile())
212         DbgNode = 0;
213     }
214     StringRef getFilename() const  { return getStringField(1);   }
215     StringRef getDirectory() const { return getStringField(2);   }
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:
229     explicit DIEnumerator(const MDNode *N = 0) : DIDescriptor(N) {}
230
231     StringRef getName() const        { return getStringField(1); }
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.
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);
249     explicit DIType() {}
250
251     DIScope getContext() const          { return getFieldAs<DIScope>(1); }
252     StringRef getName() const           { return getStringField(2);     }
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     }
260     DIFile getFile() const              { return getFieldAs<DIFile>(3); }
261     unsigned getLineNumber() const      { return getUnsignedField(4); }
262     uint64_t getSizeInBits() const      { return getUInt64Field(5); }
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.
266     uint64_t getOffsetInBits() const    { return getUInt64Field(7); }
267     unsigned getFlags() const           { return getUnsignedField(8); }
268     bool isPrivate() const {
269       return (getFlags() & FlagPrivate) != 0;
270     }
271     bool isProtected() const {
272       return (getFlags() & FlagProtected) != 0;
273     }
274     bool isForwardDecl() const {
275       return (getFlags() & FlagFwdDecl) != 0;
276     }
277     // isAppleBlock - Return true if this is the Apple Blocks extension.
278     bool isAppleBlockExtension() const {
279       return (getFlags() & FlagAppleBlock) != 0;
280     }
281     bool isBlockByrefStruct() const {
282       return (getFlags() & FlagBlockByrefStruct) != 0;
283     }
284     bool isVirtual() const {
285       return (getFlags() & FlagVirtual) != 0;
286     }
287     bool isArtificial() const {
288       return (getFlags() & FlagArtificial) != 0;
289     }
290     bool isObjcClassComplete() const {
291       return (getFlags() & FlagObjcClassComplete) != 0;
292     }
293     bool isValid() const {
294       return DbgNode && (isBasicType() || isDerivedType() || isCompositeType());
295     }
296     StringRef getDirectory() const  { 
297       if (getVersion() == llvm::LLVMDebugVersion7)
298         return getCompileUnit().getDirectory();
299
300       return getFieldAs<DIFile>(3).getDirectory();
301     }
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:
321     explicit DIBasicType(const MDNode *N = 0) : DIType(N) {}
322
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:
335     explicit DIDerivedType(const MDNode *N, bool, bool)
336       : DIType(N, true, true) {}
337   public:
338     explicit DIDerivedType(const MDNode *N = 0)
339       : DIType(N, true, true) {}
340
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
351     StringRef getObjCPropertyName() const { 
352       if (getVersion() > LLVMDebugVersion11)
353         return StringRef();
354       return getStringField(10); 
355     }
356     StringRef getObjCPropertyGetterName() const {
357       assert (getVersion() <= LLVMDebugVersion11  && "Invalid Request");
358       return getStringField(11);
359     }
360     StringRef getObjCPropertySetterName() const {
361       assert (getVersion() <= LLVMDebugVersion11  && "Invalid Request");
362       return getStringField(12);
363     }
364     bool isReadOnlyObjCProperty() {
365       assert (getVersion() <= LLVMDebugVersion11  && "Invalid Request");
366       return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_readonly) != 0;
367     }
368     bool isReadWriteObjCProperty() {
369       assert (getVersion() <= LLVMDebugVersion11  && "Invalid Request");
370       return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_readwrite) != 0;
371     }
372     bool isAssignObjCProperty() {
373       assert (getVersion() <= LLVMDebugVersion11  && "Invalid Request");
374       return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_assign) != 0;
375     }
376     bool isRetainObjCProperty() {
377       assert (getVersion() <= LLVMDebugVersion11  && "Invalid Request");
378       return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_retain) != 0;
379     }
380     bool isCopyObjCProperty() {
381       assert (getVersion() <= LLVMDebugVersion11  && "Invalid Request");
382       return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_copy) != 0;
383     }
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)
401       : DIDerivedType(N, true, true) {
402       if (N && !isCompositeType())
403         DbgNode = 0;
404     }
405
406     DIArray getTypeArray() const { return getFieldAs<DIArray>(10); }
407     unsigned getRunTimeLang() const { return getUnsignedField(11); }
408     DICompositeType getContainingType() const {
409       return getFieldAs<DICompositeType>(12);
410     }
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:
420     explicit DITemplateTypeParameter(const MDNode *N = 0) : DIDescriptor(N) {}
421
422     DIScope getContext() const       { return getFieldAs<DIScope>(1); }
423     StringRef getName() const        { return getStringField(2); }
424     DIType getType() const           { return getFieldAs<DIType>(3); }
425     StringRef getFilename() const    { 
426       return getFieldAs<DIFile>(4).getFilename();
427     }
428     StringRef getDirectory() const   { 
429       return getFieldAs<DIFile>(4).getDirectory();
430     }
431     unsigned getLineNumber() const   { return getUnsignedField(5); }
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:
438     explicit DITemplateValueParameter(const MDNode *N = 0) : DIDescriptor(N) {}
439
440     DIScope getContext() const       { return getFieldAs<DIScope>(1); }
441     StringRef getName() const        { return getStringField(2); }
442     DIType getType() const           { return getFieldAs<DIType>(3); }
443     uint64_t getValue() const         { return getUInt64Field(4); }
444     StringRef getFilename() const    { 
445       return getFieldAs<DIFile>(5).getFilename();
446     }
447     StringRef getDirectory() const   { 
448       return getFieldAs<DIFile>(5).getDirectory();
449     }
450     unsigned getLineNumber() const   { return getUnsignedField(6); }
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:
459     explicit DISubprogram(const MDNode *N = 0) : DIScope(N) {}
460
461     DIScope getContext() const          { return getFieldAs<DIScope>(2); }
462     StringRef getName() const         { return getStringField(3); }
463     StringRef getDisplayName() const  { return getStringField(4); }
464     StringRef getLinkageName() const  { return getStringField(5); }
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     }
472     unsigned getLineNumber() const      { return getUnsignedField(7); }
473     DICompositeType getType() const { return getFieldAs<DICompositeType>(8); }
474
475     /// getReturnTypeName - Subprogram return types are encoded either as
476     /// DIType or as DICompositeType.
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.
490     unsigned isLocalToUnit() const     { return getUnsignedField(9); }
491     unsigned isDefinition() const      { return getUnsignedField(10); }
492
493     unsigned getVirtuality() const { return getUnsignedField(11); }
494     unsigned getVirtualIndex() const { return getUnsignedField(12); }
495
496     DICompositeType getContainingType() const {
497       return getFieldAs<DICompositeType>(13);
498     }
499
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.
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.
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.
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.
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
534     StringRef getFilename() const    { 
535       if (getVersion() == llvm::LLVMDebugVersion7)
536         return getCompileUnit().getFilename();
537
538       return getFieldAs<DIFile>(6).getFilename(); 
539     }
540
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.
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
560     Function *getFunction() const { return getFunctionField(16); }
561     DIArray getTemplateParams() const { return getFieldAs<DIArray>(17); }
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:
574     explicit DIGlobalVariable(const MDNode *N = 0) : DIDescriptor(N) {}
575
576     DIScope getContext() const          { return getFieldAs<DIScope>(2); }
577     StringRef getName() const         { return getStringField(3); }
578     StringRef getDisplayName() const  { return getStringField(4); }
579     StringRef getLinkageName() const  { return getStringField(5); }
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     }
588     StringRef getFilename() const {
589       if (getVersion() <= llvm::LLVMDebugVersion10)
590         return getContext().getFilename();
591       return getFieldAs<DIFile>(6).getFilename();
592     } 
593     StringRef getDirectory() const {
594       if (getVersion() <= llvm::LLVMDebugVersion10)
595         return getContext().getDirectory();
596       return getFieldAs<DIFile>(6).getDirectory();
597
598     } 
599
600     unsigned getLineNumber() const      { return getUnsignedField(7); }
601     DIType getType() const              { return getFieldAs<DIType>(8); }
602     unsigned isLocalToUnit() const      { return getUnsignedField(9); }
603     unsigned isDefinition() const       { return getUnsignedField(10); }
604
605     GlobalVariable *getGlobal() const { return getGlobalVariableField(11); }
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)
619       : DIDescriptor(N) {}
620
621     DIScope getContext() const          { return getFieldAs<DIScope>(1); }
622     StringRef getName() const           { return getStringField(2);     }
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     }
631     unsigned getLineNumber() const      { 
632       return (getUnsignedField(4) << 8) >> 8; 
633     }
634     unsigned getArgNumber() const       {
635       unsigned L = getUnsignedField(4); 
636       return L >> 24;
637     }
638     DIType getType() const              { return getFieldAs<DIType>(5); }
639     
640     /// isArtificial - Return true if this variable is marked as "artificial".
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.
654     bool hasComplexAddress() const {
655       return getNumAddrElements() > 0;
656     }
657
658     unsigned getNumAddrElements() const;
659     
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).
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:
684     explicit DILexicalBlock(const MDNode *N = 0) : DIScope(N) {}
685     DIScope getContext() const       { return getFieldAs<DIScope>(1);      }
686     unsigned getLineNumber() const   { return getUnsignedField(2);         }
687     unsigned getColumnNumber() const { return getUnsignedField(3);         }
688     StringRef getDirectory() const {
689       StringRef dir = getFieldAs<DIFile>(4).getDirectory();
690       return !dir.empty() ? dir : getContext().getDirectory();
691     }
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:
702     explicit DILexicalBlockFile(const MDNode *N = 0) : DIScope(N) {}
703     DIScope getContext() const { return getScope().getContext(); }
704     unsigned getLineNumber() const { return getScope().getLineNumber(); }
705     unsigned getColumnNumber() const { return getScope().getColumnNumber(); }
706     StringRef getDirectory() const {
707       StringRef dir = getFieldAs<DIFile>(2).getDirectory();
708       return !dir.empty() ? dir : getContext().getDirectory();
709     }
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     }
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:
721     explicit DINameSpace(const MDNode *N = 0) : DIScope(N) {}
722     DIScope getContext() const     { return getFieldAs<DIScope>(1);      }
723     StringRef getName() const      { return getStringField(2);           }
724     StringRef getDirectory() const  { 
725       return getFieldAs<DIFile>(3).getDirectory();
726     }
727     StringRef getFilename() const  { 
728       return getFieldAs<DIFile>(3).getFilename();
729     }
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     }
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:
745     explicit DILocation(const MDNode *N) : DIDescriptor(N) { }
746
747     unsigned getLineNumber() const     { return getUnsignedField(0); }
748     unsigned getColumnNumber() const   { return getUnsignedField(1); }
749     DIScope  getScope() const          { return getFieldAs<DIScope>(2); }
750     DILocation getOrigLocation() const { return getFieldAs<DILocation>(3); }
751     StringRef getFilename() const    { return getScope().getFilename(); }
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:
760     explicit DIObjCProperty(const MDNode *N) : DIDescriptor(N) { }
761
762     StringRef getObjCPropertyName() const { return getStringField(1); }
763     DIFile getFile() const { return getFieldAs<DIFile>(2); }
764     unsigned getLineNumber() const { return getUnsignedField(3); }
765
766     StringRef getObjCPropertyGetterName() const {
767       return getStringField(4);
768     }
769     StringRef getObjCPropertySetterName() const {
770       return getStringField(5);
771     }
772     bool isReadOnlyObjCProperty() {
773       return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_readonly) != 0;
774     }
775     bool isReadWriteObjCProperty() {
776       return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_readwrite) != 0;
777     }
778     bool isAssignObjCProperty() {
779       return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_assign) != 0;
780     }
781     bool isRetainObjCProperty() {
782       return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_retain) != 0;
783     }
784     bool isCopyObjCProperty() {
785       return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_copy) != 0;
786     }
787     bool isNonAtomicObjCProperty() {
788       return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_nonatomic) != 0;
789     }
790
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;
861     iterator compile_unit_begin()    const { return CUs.begin(); }
862     iterator compile_unit_end()      const { return CUs.end(); }
863     iterator subprogram_begin()      const { return SPs.begin(); }
864     iterator subprogram_end()        const { return SPs.end(); }
865     iterator global_variable_begin() const { return GVs.begin(); }
866     iterator global_variable_end()   const { return GVs.end(); }
867     iterator type_begin()            const { return TYs.begin(); }
868     iterator type_end()              const { return TYs.end(); }
869
870     unsigned compile_unit_count()    const { return CUs.size(); }
871     unsigned global_variable_count() const { return GVs.size(); }
872     unsigned subprogram_count()      const { return SPs.size(); }
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