PageRenderTime 111ms CodeModel.GetById 12ms app.highlight 91ms RepoModel.GetById 1ms app.codeStats 0ms

/3rd_party/llvm/include/llvm/Analysis/DebugInfo.h

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