Home | History | Annotate | Download | only in llvm
      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
    885