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