Extract source location info from DebugInfo.
authorDevang Patel <dpatel@apple.com>
Mon, 5 Jan 2009 22:35:52 +0000 (22:35 +0000)
committerDevang Patel <dpatel@apple.com>
Mon, 5 Jan 2009 22:35:52 +0000 (22:35 +0000)
Add methods to add source location info in a DIE.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@61761 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Analysis/DebugInfo.h
lib/CodeGen/AsmPrinter/DwarfWriter.cpp

index fae9a4422535608b53c17caaf2bba6de844cb645..ea11b8de2363f40667b12a6caab73f30049192ef 100644 (file)
@@ -48,10 +48,6 @@ namespace llvm {
     /// not, the debug info is corrupt and we ignore it.
     DIDescriptor(GlobalVariable *GV, unsigned RequiredTag);
     
-    unsigned getVersion() const {
-      return getUnsignedField(0) & VersionMask;
-    }
-    
     std::string getStringField(unsigned Elt) const;
     unsigned getUnsignedField(unsigned Elt) const {
       return (unsigned)getUInt64Field(Elt);
@@ -74,6 +70,10 @@ namespace llvm {
 
     GlobalVariable *getGV() const { return GV; }
 
+    unsigned getVersion() const {
+      return getUnsignedField(0) & VersionMask;
+    }
+    
     unsigned getTag() const {
       return getUnsignedField(0) & ~VersionMask;
     }
@@ -147,7 +147,8 @@ namespace llvm {
   public:
     explicit DIType(GlobalVariable *GV);
     explicit DIType() {}
-    
+    virtual ~DIType() {}
+
     DIDescriptor getContext() const     { return getDescriptorField(1); }
     std::string getName() const         { return getStringField(2); }
     DICompileUnit getCompileUnit() const{ return getFieldAs<DICompileUnit>(3); }
@@ -158,6 +159,16 @@ namespace llvm {
     // carry this is just plain insane.
     uint64_t getOffsetInBits() const    { return getUInt64Field(7); }
     unsigned getFlags() const           { return getUnsignedField(8); }
+
+    virtual std::string getFilename() const { 
+      assert (0 && "Invalid DIDescriptor");
+      return "";
+    }
+
+    virtual std::string getDirectory() const { 
+      assert (0 && "Invalid DIDescriptor");
+      return "";
+    }
   };
   
   /// DIBasicType - A basic type, like 'int' or 'float'.
@@ -166,7 +177,7 @@ namespace llvm {
     explicit DIBasicType(GlobalVariable *GV);
     
     unsigned getEncoding() const { return getUnsignedField(9); }
-    std::string getFileName() const { return getStringField(10); }
+    std::string getFilename() const { return getStringField(10); }
     std::string getDirectory() const { return getStringField(11); }
   };
   
@@ -180,7 +191,7 @@ namespace llvm {
     explicit DIDerivedType(GlobalVariable *GV);
     
     DIType getTypeDerivedFrom() const { return getFieldAs<DIType>(9); }
-    std::string getFileName() const { return getStringField(10); }
+    std::string getFilename() const { return getStringField(10); }
     std::string getDirectory() const { return getStringField(11); }
 
     /// isDerivedType - Return true if the specified tag is legal for
@@ -202,7 +213,7 @@ namespace llvm {
     explicit DICompositeType(GlobalVariable *GV);
     
     DIArray getTypeArray() const { return getFieldAs<DIArray>(10); }
-    std::string getFileName() const { return getStringField(11); }
+    std::string getFilename() const { return getStringField(11); }
     std::string getDirectory() const { return getStringField(12); }
     
     /// isCompositeType - Return true if the specified tag is legal for
@@ -220,7 +231,8 @@ namespace llvm {
     explicit DIGlobal(GlobalVariable *GV, unsigned RequiredTag)
       : DIDescriptor(GV, RequiredTag) {}
   public:
-    
+    virtual ~DIGlobal() {}
+
     DIDescriptor getContext() const     { return getDescriptorField(2); }
     std::string getName() const         { return getStringField(3); }
     std::string getDisplayName() const  { return getStringField(4); }
@@ -234,6 +246,16 @@ namespace llvm {
     /// compile unit, like 'static' in C.
     unsigned isLocalToUnit() const      { return getUnsignedField(9); }
     unsigned isDefinition() const       { return getUnsignedField(10); }
+
+    virtual std::string getFilename() const { 
+      assert (0 && "Invalid DIDescriptor");
+      return "";
+    }
+
+    virtual std::string getDirectory() const { 
+      assert (0 && "Invalid DIDescriptor");
+      return "";
+    }
   };
   
   
index 56d9ec371ea409e3197d1847ff3beb239443b18e..d5ae56efeb7bde95c297f7ba676f039c714d016a 100644 (file)
@@ -1123,6 +1123,33 @@ public:
 
 };
 
+//===----------------------------------------------------------------------===//
+/// SrcFileInfo - This class is used to track source information.
+///
+class SrcFileInfo {
+  unsigned DirectoryID;                 // Directory ID number.
+  std::string Name;                     // File name (not including directory.)
+public:
+  SrcFileInfo(unsigned D, const std::string &N) : DirectoryID(D), Name(N) {}
+            
+  // Accessors
+  unsigned getDirectoryID()    const { return DirectoryID; }
+  const std::string &getName() const { return Name; }
+
+  /// operator== - Used by UniqueVector to locate entry.
+  ///
+  bool operator==(const SourceFileInfo &SI) const {
+    return getDirectoryID() == SI.getDirectoryID() && getName() == SI.getName();
+  }
+
+  /// operator< - Used by UniqueVector to locate entry.
+  ///
+  bool operator<(const SrcFileInfo &SI) const {
+    return getDirectoryID() < SI.getDirectoryID() ||
+          (getDirectoryID() == SI.getDirectoryID() && getName() < SI.getName());
+  }
+};
+
 //===----------------------------------------------------------------------===//
 /// DwarfDebug - Emits Dwarf debug directives.
 ///
@@ -1136,6 +1163,7 @@ private:
   /// CompileUnits - All the compile units involved in this build.  The index
   /// of each entry in this vector corresponds to the sources in MMI.
   std::vector<CompileUnit *> CompileUnits;
+  DenseMap<GlobalVariable *, CompileUnit *> DW_CUs;
 
   /// AbbreviationsSet - Used to uniquely define abbreviations.
   ///
@@ -1147,6 +1175,12 @@ private:
 
   /// ValuesSet - Used to uniquely define values.
   ///
+  // Directories - Uniquing vector for directories.                                       
+  UniqueVector<std::string> Directories;
+
+  // SourceFiles - Uniquing vector for source files.                                      
+  UniqueVector<SrcFileInfo> SrcFiles;
+
   FoldingSet<DIEValue> ValuesSet;
 
   /// Values - A list of all the unique values in use.
@@ -1416,6 +1450,42 @@ private:
     }
   }
 
+  /// AddSourceLine - Add location information to specified debug information
+  /// entry.
+  void AddSourceLine(DIE *Die, DIGlobal *G) {
+    unsigned FileID = 0;
+    unsigned Line = G->getLineNumber();
+    if (G->getVersion() < DIDescriptor::Version7) {
+      // Version6 or earlier. Use compile unit info to get file id.
+      CompileUnit *Unit = FindCompileUnit(G->getCompileUnit());
+      FileID = Unit->getID();
+    } else {
+      // Version7 or newer, use filename and directory info from DIGlobal
+      // directly.
+      unsigned DID = Directories.idFor(G->getDirectory());
+      FileID = SrcFiles.idFor(SrcFileInfo(DID, G->getFilename()));
+    }
+    AddUInt(Die, DW_AT_decl_file, 0, FileID);
+    AddUInt(Die, DW_AT_decl_line, 0, Line);
+  }
+
+  void AddSourceLine(DIE *Die, DIType *G) {
+    unsigned FileID = 0;
+    unsigned Line = G->getLineNumber();
+    if (G->getVersion() < DIDescriptor::Version7) {
+      // Version6 or earlier. Use compile unit info to get file id.
+      CompileUnit *Unit = FindCompileUnit(G->getCompileUnit());
+      FileID = Unit->getID();
+    } else {
+      // Version7 or newer, use filename and directory info from DIGlobal
+      // directly.
+      unsigned DID = Directories.idFor(G->getDirectory());
+      FileID = SrcFiles.idFor(SrcFileInfo(DID, G->getFilename()));
+    }
+    AddUInt(Die, DW_AT_decl_file, 0, FileID);
+    AddUInt(Die, DW_AT_decl_line, 0, Line);
+  }
+
   /// AddAddress - Add an address attribute to a die based on the location
   /// provided.
   void AddAddress(DIE *Die, unsigned Attribute,
@@ -2144,6 +2214,14 @@ private:
     return Unit;
   }
 
+  /// FindCompileUnit - Get the compile unit for the given descriptor.                    
+  ///                                                                                     
+  CompileUnit *FindCompileUnit(DICompileUnit Unit) {
+    CompileUnit *DW_Unit = DW_CUs[Unit.getGV()];
+    assert(DW_Unit && "Missing compile unit.");
+    return DW_Unit;
+  }
+
   /// NewGlobalVariable - Add a new global variable DIE.
   ///
   DIE *NewGlobalVariable(GlobalVariableDesc *GVD) {