Generalize isSafeToSpeculativelyExecute to work on arbitrary
[oota-llvm.git] / include / llvm / Analysis / DebugInfo.h
index a5252aaab54f435baca116e47c3f8e03aee7b632..f62dddd669356d5a568848d593add2139044f5af 100644 (file)
@@ -40,6 +40,7 @@ namespace llvm {
   class DIFile;
   class DISubprogram;
   class DILexicalBlock;
+  class DILexicalBlockFile;
   class DIVariable;
   class DIType;
 
@@ -49,15 +50,16 @@ namespace llvm {
   class DIDescriptor {
   public:
     enum {
-      FlagPrivate          = 1 << 0,
-      FlagProtected        = 1 << 1,
-      FlagFwdDecl          = 1 << 2,
-      FlagAppleBlock       = 1 << 3,
-      FlagBlockByrefStruct = 1 << 4,
-      FlagVirtual          = 1 << 5,
-      FlagArtificial       = 1 << 6,
-      FlagExplicit         = 1 << 7,
-      FlagPrototyped       = 1 << 8
+      FlagPrivate            = 1 << 0,
+      FlagProtected          = 1 << 1,
+      FlagFwdDecl            = 1 << 2,
+      FlagAppleBlock         = 1 << 3,
+      FlagBlockByrefStruct   = 1 << 4,
+      FlagVirtual            = 1 << 5,
+      FlagArtificial         = 1 << 6,
+      FlagExplicit           = 1 << 7,
+      FlagPrototyped         = 1 << 8,
+      FlagObjcClassComplete  = 1 << 9
     };
   protected:
     const MDNode *DbgNode;
@@ -83,6 +85,7 @@ namespace llvm {
     explicit DIDescriptor(const MDNode *N) : DbgNode(N) {}
     explicit DIDescriptor(const DIFile F);
     explicit DIDescriptor(const DISubprogram F);
+    explicit DIDescriptor(const DILexicalBlockFile F);
     explicit DIDescriptor(const DILexicalBlock F);
     explicit DIDescriptor(const DIVariable F);
     explicit DIDescriptor(const DIType F);
@@ -116,6 +119,7 @@ namespace llvm {
     bool isFile() const;
     bool isCompileUnit() const;
     bool isNameSpace() const;
+    bool isLexicalBlockFile() const;
     bool isLexicalBlock() const;
     bool isSubrange() const;
     bool isEnumerator() const;
@@ -131,8 +135,8 @@ namespace llvm {
   public:
     explicit DISubrange(const MDNode *N = 0) : DIDescriptor(N) {}
 
-    int64_t getLo() const { return (int64_t)getUInt64Field(1); }
-    int64_t getHi() const { return (int64_t)getUInt64Field(2); }
+    uint64_t getLo() const { return getUInt64Field(1); }
+    uint64_t getHi() const { return getUInt64Field(2); }
   };
 
   /// DIArray - This descriptor holds an array of descriptors.
@@ -149,6 +153,7 @@ namespace llvm {
 
   /// DIScope - A base class for various scopes.
   class DIScope : public DIDescriptor {
+    virtual void anchor();
   public:
     explicit DIScope(const MDNode *N = 0) : DIDescriptor (N) {}
     virtual ~DIScope() {}
@@ -159,6 +164,7 @@ namespace llvm {
 
   /// DICompileUnit - A wrapper for a compile unit.
   class DICompileUnit : public DIScope {
+    virtual void anchor();
   public:
     explicit DICompileUnit(const MDNode *N = 0) : DIScope(N) {}
 
@@ -181,6 +187,11 @@ namespace llvm {
     StringRef getFlags() const       { return getStringField(8);   }
     unsigned getRunTimeVersion() const { return getUnsignedField(9); }
 
+    DIArray getEnumTypes() const;
+    DIArray getRetainedTypes() const;
+    DIArray getSubprograms() const;
+    DIArray getGlobalVariables() const;
+
     /// Verify - Verify that a compile unit is well formed.
     bool Verify() const;
 
@@ -193,6 +204,7 @@ namespace llvm {
 
   /// DIFile - This is a wrapper for a file.
   class DIFile : public DIScope {
+    virtual void anchor();
   public:
     explicit DIFile(const MDNode *N = 0) : DIScope(N) {
       if (DbgNode && !isFile())
@@ -200,7 +212,10 @@ namespace llvm {
     }
     StringRef getFilename() const  { return getStringField(1);   }
     StringRef getDirectory() const { return getStringField(2);   }
-    DICompileUnit getCompileUnit() const{ return getFieldAs<DICompileUnit>(3); }
+    DICompileUnit getCompileUnit() const{ 
+      assert (getVersion() <= LLVMDebugVersion10  && "Invalid CompileUnit!");
+      return getFieldAs<DICompileUnit>(3); 
+    }
   };
 
   /// DIEnumerator - A wrapper for an enumerator (e.g. X and Y in 'enum {X,Y}').
@@ -218,7 +233,7 @@ namespace llvm {
   /// FIXME: Types should be factored much better so that CV qualifiers and
   /// others do not require a huge and empty descriptor full of zeros.
   class DIType : public DIScope {
-  public:
+    virtual void anchor();
   protected:
     // This ctor is used when the Tag has already been validated by a derived
     // ctor.
@@ -228,7 +243,6 @@ namespace llvm {
 
     /// Verify - Verify that a type descriptor is well formed.
     bool Verify() const;
-  public:
     explicit DIType(const MDNode *N);
     explicit DIType() {}
     virtual ~DIType() {}
@@ -236,6 +250,7 @@ namespace llvm {
     DIScope getContext() const          { return getFieldAs<DIScope>(1); }
     StringRef getName() const           { return getStringField(2);     }
     DICompileUnit getCompileUnit() const{ 
+      assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!");
      if (getVersion() == llvm::LLVMDebugVersion7)
        return getFieldAs<DICompileUnit>(3);
      
@@ -271,6 +286,9 @@ namespace llvm {
     bool isArtificial() const {
       return (getFlags() & FlagArtificial) != 0;
     }
+    bool isObjcClassComplete() const {
+      return (getFlags() & FlagObjcClassComplete) != 0;
+    }
     bool isValid() const {
       return DbgNode && (isBasicType() || isDerivedType() || isCompositeType());
     }
@@ -287,6 +305,9 @@ namespace llvm {
       return getFieldAs<DIFile>(3).getFilename();
     }
 
+    /// isUnsignedDIType - Return true if type encoding is unsigned.
+    bool isUnsignedDIType();
+
     /// replaceAllUsesWith - Replace all uses of debug info referenced by
     /// this descriptor.
     void replaceAllUsesWith(DIDescriptor &D);
@@ -301,6 +322,7 @@ namespace llvm {
 
   /// DIBasicType - A basic type, like 'int' or 'float'.
   class DIBasicType : public DIType {
+    virtual void anchor();
   public:
     explicit DIBasicType(const MDNode *N = 0) : DIType(N) {}
 
@@ -319,6 +341,7 @@ namespace llvm {
   /// DIDerivedType - A simple derived type, like a const qualified type,
   /// a typedef, a pointer or reference, etc.
   class DIDerivedType : public DIType {
+    virtual void anchor();
   protected:
     explicit DIDerivedType(const MDNode *N, bool, bool)
       : DIType(N, true, true) {}
@@ -372,6 +395,7 @@ namespace llvm {
   /// other types, like a function or struct.
   /// FIXME: Why is this a DIDerivedType??
   class DICompositeType : public DIDerivedType {
+    virtual void anchor();
   public:
     explicit DICompositeType(const MDNode *N = 0)
       : DIDerivedType(N, true, true) {
@@ -435,6 +459,7 @@ namespace llvm {
 
   /// DISubprogram - This is a wrapper for a subprogram (e.g. a function).
   class DISubprogram : public DIScope {
+    virtual void anchor();
   public:
     explicit DISubprogram(const MDNode *N = 0) : DIScope(N) {}
 
@@ -443,6 +468,7 @@ namespace llvm {
     StringRef getDisplayName() const  { return getStringField(4); }
     StringRef getLinkageName() const  { return getStringField(5); }
     DICompileUnit getCompileUnit() const{ 
+      assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!");
       if (getVersion() == llvm::LLVMDebugVersion7)
         return getFieldAs<DICompileUnit>(6);
 
@@ -541,6 +567,8 @@ namespace llvm {
     DISubprogram getFunctionDeclaration() const {
       return getFieldAs<DISubprogram>(18);
     }
+    MDNode *getVariablesNodes() const;
+    DIArray getVariables() const;
   };
 
   /// DIGlobalVariable - This is a wrapper for a global variable.
@@ -553,12 +581,24 @@ namespace llvm {
     StringRef getDisplayName() const  { return getStringField(4); }
     StringRef getLinkageName() const  { return getStringField(5); }
     DICompileUnit getCompileUnit() const{ 
+      assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!");
       if (getVersion() == llvm::LLVMDebugVersion7)
         return getFieldAs<DICompileUnit>(6);
 
       DIFile F = getFieldAs<DIFile>(6); 
       return F.getCompileUnit();
     }
+    StringRef getFilename() const {
+      if (getVersion() <= llvm::LLVMDebugVersion10)
+        return getContext().getFilename();
+      return getFieldAs<DIFile>(6).getFilename();
+    } 
+    StringRef getDirectory() const {
+      if (getVersion() <= llvm::LLVMDebugVersion10)
+        return getContext().getDirectory();
+      return getFieldAs<DIFile>(6).getDirectory();
+
+    } 
 
     unsigned getLineNumber() const      { return getUnsignedField(7); }
     DIType getType() const              { return getFieldAs<DIType>(8); }
@@ -587,7 +627,8 @@ namespace llvm {
 
     DIScope getContext() const          { return getFieldAs<DIScope>(1); }
     StringRef getName() const           { return getStringField(2);     }
-    DICompileUnit getCompileUnit() const{ 
+    DICompileUnit getCompileUnit() const { 
+      assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!");
       if (getVersion() == llvm::LLVMDebugVersion7)
         return getFieldAs<DICompileUnit>(3);
 
@@ -610,6 +651,8 @@ namespace llvm {
       return (getUnsignedField(6) & FlagArtificial) != 0;
     }
 
+    /// getInlinedAt - If this variable is inlined then return inline location.
+    MDNode *getInlinedAt() const;
 
     /// Verify - Verify that a variable descriptor is well formed.
     bool Verify() const;
@@ -622,7 +665,11 @@ namespace llvm {
     unsigned getNumAddrElements() const;
     
     uint64_t getAddrElement(unsigned Idx) const {
-      return getUInt64Field(Idx+6);
+      if (getVersion() <= llvm::LLVMDebugVersion8)
+        return getUInt64Field(Idx+6);
+      if (getVersion() == llvm::LLVMDebugVersion9)
+        return getUInt64Field(Idx+7);
+      return getUInt64Field(Idx+8);
     }
 
     /// isBlockByrefVariable - Return true if the variable was declared as
@@ -638,12 +685,15 @@ namespace llvm {
     /// print - print variable.
     void print(raw_ostream &OS) const;
 
+    void printExtendedName(raw_ostream &OS) const;
+
     /// dump - print variable to dbgs() with a newline.
     void dump() const;
   };
 
   /// DILexicalBlock - This is a wrapper for a lexical block.
   class DILexicalBlock : public DIScope {
+    virtual void anchor();
   public:
     explicit DILexicalBlock(const MDNode *N = 0) : DIScope(N) {}
     DIScope getContext() const       { return getFieldAs<DIScope>(1);      }
@@ -659,8 +709,30 @@ namespace llvm {
     }
   };
 
+  /// DILexicalBlockFile - This is a wrapper for a lexical block with
+  /// a filename change.
+  class DILexicalBlockFile : public DIScope {
+    virtual void anchor();
+  public:
+    explicit DILexicalBlockFile(const MDNode *N = 0) : DIScope(N) {}
+    DIScope getContext() const { return getScope().getContext(); }
+    unsigned getLineNumber() const { return getScope().getLineNumber(); }
+    unsigned getColumnNumber() const { return getScope().getColumnNumber(); }
+    StringRef getDirectory() const {
+      StringRef dir = getFieldAs<DIFile>(2).getDirectory();
+      return !dir.empty() ? dir : getContext().getDirectory();
+    }
+    StringRef getFilename() const {
+      StringRef filename = getFieldAs<DIFile>(2).getFilename();
+      assert(!filename.empty() && "Why'd you create this then?");
+      return filename;
+    }
+    DILexicalBlock getScope() const { return getFieldAs<DILexicalBlock>(1); }
+  };
+
   /// DINameSpace - A wrapper for a C++ style name space.
   class DINameSpace : public DIScope { 
+    virtual void anchor();
   public:
     explicit DINameSpace(const MDNode *N = 0) : DIScope(N) {}
     DIScope getContext() const     { return getFieldAs<DIScope>(1);      }
@@ -672,6 +744,7 @@ namespace llvm {
       return getFieldAs<DIFile>(3).getFilename();
     }
     DICompileUnit getCompileUnit() const{ 
+      assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!");
       if (getVersion() == llvm::LLVMDebugVersion7)
         return getFieldAs<DICompileUnit>(3);
 
@@ -702,13 +775,27 @@ namespace llvm {
   /// getDICompositeType - Find underlying composite type.
   DICompositeType getDICompositeType(DIType T);
 
+  /// isSubprogramContext - Return true if Context is either a subprogram
+  /// or another context nested inside a subprogram.
+  bool isSubprogramContext(const MDNode *Context);
+
   /// getOrInsertFnSpecificMDNode - Return a NameMDNode that is suitable
   /// to hold function specific information.
-  NamedMDNode *getOrInsertFnSpecificMDNode(Module &M, StringRef Name);
+  NamedMDNode *getOrInsertFnSpecificMDNode(Module &M, DISubprogram SP);
 
   /// getFnSpecificMDNode - Return a NameMDNode, if available, that is 
   /// suitable to hold function specific information.
-  NamedMDNode *getFnSpecificMDNode(const Module &M, StringRef Name);
+  NamedMDNode *getFnSpecificMDNode(const Module &M, DISubprogram SP);
+
+  /// createInlinedVariable - Create a new inlined variable based on current
+  /// variable.
+  /// @param DV            Current Variable.
+  /// @param InlinedScope  Location at current variable is inlined.
+  DIVariable createInlinedVariable(MDNode *DV, MDNode *InlinedScope,
+                                   LLVMContext &VMContext);
+
+  /// cleanseInlinedVariable - Remove inlined scope from the variable.
+  DIVariable cleanseInlinedVariable(MDNode *DV, LLVMContext &VMContext);
 
   class DebugInfoFinder {
   public:
@@ -738,7 +825,7 @@ namespace llvm {
     /// addGlobalVariable - Add global variable into GVs.
     bool addGlobalVariable(DIGlobalVariable DIG);
 
-    // addSubprogram - Add subprgoram into SPs.
+    // addSubprogram - Add subprogram into SPs.
     bool addSubprogram(DISubprogram SP);
 
     /// addType - Add type into Tys.