[cfe-commits] Patch for LineTableInfo to use FileID instead of int for file references

Tom Honermann thonermann at coverity.com
Fri May 25 09:17:19 PDT 2012


I recently needed to write code to iterate over preprocessing line 
control directives, identify the originating source file for the 
directive, and then lookup details for the originating source file.

LineTableInfo has begin() and end() methods to iterate over the set of 
source file IDs and retrieve the vector of line control directives in 
each.  The returned iterator (iter) is 'std::map<int, 
std::vector<LineEntry> >::iterator' where the int (iter->first) 
corresponds to FileID::ID.

The FileID class restricts creating instances with arbitrary IDs to a 
few friend classes (SourceManager, ASTWriter, ASTReader), so a user 
iterating over the map held by LineTableInfo is unable to create a 
FileID instance with an ID field corresponding to the 'int' key value 
from the map.  This prevents calling methods like 
SourceManager::getSLocEntry().  To work around this, I had to implement 
code to mimic the getSLocEntryByID() and getLoadedSLocEntryByID() 
private methods of SourceManager in order to retrieve the corresponding 
SLocEntry.

The attached patch modifies LineTableInfo to use FileID instead of an 
int corresponding to a FileID::ID as the key value for its map, modifies 
other methods similarly, and updates all users to pass FileID instances 
instead of int.  In all cases, users already had a FileID instance and 
were passing FileID.ID anyway.

The patch was produced with 'diff -rupN <orig> <modified>' where orig 
corresponds to the Clang 3.1 final release.  Apply the patch in the 
Clang root directory with 'patch -p1 ...'

Thank you!

Tom.
-------------- next part --------------
diff -rupN clang-3.1.src/include/clang/Basic/SourceManagerInternals.h clang/include/clang/Basic/SourceManagerInternals.h
--- clang-3.1.src/include/clang/Basic/SourceManagerInternals.h	2011-07-20 02:58:45.000000000 -0400
+++ clang/include/clang/Basic/SourceManagerInternals.h	2012-05-25 11:01:35.853962000 -0400
@@ -15,6 +15,7 @@
 #ifndef LLVM_CLANG_SOURCEMANAGER_INTERNALS_H
 #define LLVM_CLANG_SOURCEMANAGER_INTERNALS_H
 
+#include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/SourceManager.h"
 #include "llvm/ADT/StringMap.h"
 #include <map>
@@ -84,7 +85,7 @@ class LineTableInfo {
 
   /// LineEntries - This is a map from FileIDs to a list of line entries (sorted
   /// by the offset they occur in the file.
-  std::map<int, std::vector<LineEntry> > LineEntries;
+  std::map<FileID, std::vector<LineEntry> > LineEntries;
 public:
   LineTableInfo() {
   }
@@ -104,25 +105,25 @@ public:
   }
   unsigned getNumFilenames() const { return FilenamesByID.size(); }
 
-  void AddLineNote(int FID, unsigned Offset,
+  void AddLineNote(FileID FID, unsigned Offset,
                    unsigned LineNo, int FilenameID);
-  void AddLineNote(int FID, unsigned Offset,
+  void AddLineNote(FileID FID, unsigned Offset,
                    unsigned LineNo, int FilenameID,
                    unsigned EntryExit, SrcMgr::CharacteristicKind FileKind);
 
 
   /// FindNearestLineEntry - Find the line entry nearest to FID that is before
   /// it.  If there is no line entry before Offset in FID, return null.
-  const LineEntry *FindNearestLineEntry(int FID, unsigned Offset);
+  const LineEntry *FindNearestLineEntry(FileID FID, unsigned Offset);
 
   // Low-level access
-  typedef std::map<int, std::vector<LineEntry> >::iterator iterator;
+  typedef std::map<FileID, std::vector<LineEntry> >::iterator iterator;
   iterator begin() { return LineEntries.begin(); }
   iterator end() { return LineEntries.end(); }
 
   /// \brief Add a new line entry that has already been encoded into
   /// the internal representation of the line table.
-  void AddEntry(int FID, const std::vector<LineEntry> &Entries);
+  void AddEntry(FileID FID, const std::vector<LineEntry> &Entries);
 };
 
 } // end namespace clang
diff -rupN clang-3.1.src/lib/Basic/SourceManager.cpp clang/lib/Basic/SourceManager.cpp
--- clang-3.1.src/lib/Basic/SourceManager.cpp	2012-04-06 16:49:55.000000000 -0400
+++ clang/lib/Basic/SourceManager.cpp	2012-05-25 11:06:42.302494000 -0400
@@ -191,7 +191,7 @@ unsigned LineTableInfo::getLineTableFile
 /// AddLineNote - Add a line note to the line table that indicates that there
 /// is a #line at the specified FID/Offset location which changes the presumed
 /// location to LineNo/FilenameID.
-void LineTableInfo::AddLineNote(int FID, unsigned Offset,
+void LineTableInfo::AddLineNote(FileID FID, unsigned Offset,
                                 unsigned LineNo, int FilenameID) {
   std::vector<LineEntry> &Entries = LineEntries[FID];
 
@@ -222,7 +222,7 @@ void LineTableInfo::AddLineNote(int FID,
 /// presumed #include stack.  If it is 1, this is a file entry, if it is 2 then
 /// this is a file exit.  FileKind specifies whether this is a system header or
 /// extern C system header.
-void LineTableInfo::AddLineNote(int FID, unsigned Offset,
+void LineTableInfo::AddLineNote(FileID FID, unsigned Offset,
                                 unsigned LineNo, int FilenameID,
                                 unsigned EntryExit,
                                 SrcMgr::CharacteristicKind FileKind) {
@@ -256,7 +256,7 @@ void LineTableInfo::AddLineNote(int FID,
 
 /// FindNearestLineEntry - Find the line entry nearest to FID that is before
 /// it.  If there is no line entry before Offset in FID, return null.
-const LineEntry *LineTableInfo::FindNearestLineEntry(int FID,
+const LineEntry *LineTableInfo::FindNearestLineEntry(FileID FID,
                                                      unsigned Offset) {
   const std::vector<LineEntry> &Entries = LineEntries[FID];
   assert(!Entries.empty() && "No #line entries for this FID after all!");
@@ -275,7 +275,7 @@ const LineEntry *LineTableInfo::FindNear
 
 /// \brief Add a new line entry that has already been encoded into
 /// the internal representation of the line table.
-void LineTableInfo::AddEntry(int FID,
+void LineTableInfo::AddEntry(FileID FID,
                              const std::vector<LineEntry> &Entries) {
   LineEntries[FID] = Entries;
 }
@@ -308,7 +308,7 @@ void SourceManager::AddLineNote(SourceLo
 
   if (LineTable == 0)
     LineTable = new LineTableInfo();
-  LineTable->AddLineNote(LocInfo.first.ID, LocInfo.second, LineNo, FilenameID);
+  LineTable->AddLineNote(LocInfo.first, LocInfo.second, LineNo, FilenameID);
 }
 
 /// AddLineNote - Add a GNU line marker to the line table.
@@ -353,7 +353,7 @@ void SourceManager::AddLineNote(SourceLo
   else if (IsFileExit)
     EntryExit = 2;
 
-  LineTable->AddLineNote(LocInfo.first.ID, LocInfo.second, LineNo, FilenameID,
+  LineTable->AddLineNote(LocInfo.first, LocInfo.second, LineNo, FilenameID,
                          EntryExit, FileKind);
 }
 
@@ -1295,7 +1295,7 @@ SourceManager::getFileCharacteristic(Sou
   assert(LineTable && "Can't have linetable entries without a LineTable!");
   // See if there is a #line directive before the location.
   const LineEntry *Entry =
-    LineTable->FindNearestLineEntry(LocInfo.first.ID, LocInfo.second);
+    LineTable->FindNearestLineEntry(LocInfo.first, LocInfo.second);
 
   // If this is before the first line marker, use the file characteristic.
   if (!Entry)
@@ -1360,7 +1360,7 @@ PresumedLoc SourceManager::getPresumedLo
     assert(LineTable && "Can't have linetable entries without a LineTable!");
     // See if there is a #line directive before this.  If so, get it.
     if (const LineEntry *Entry =
-          LineTable->FindNearestLineEntry(LocInfo.first.ID, LocInfo.second)) {
+          LineTable->FindNearestLineEntry(LocInfo.first, LocInfo.second)) {
       // If the LineEntry indicates a filename, use it.
       if (Entry->FilenameID != -1)
         Filename = LineTable->getFilename(Entry->FilenameID);
diff -rupN clang-3.1.src/lib/Serialization/ASTReader.cpp clang/lib/Serialization/ASTReader.cpp
--- clang-3.1.src/lib/Serialization/ASTReader.cpp	2012-05-11 20:27:13.000000000 -0400
+++ clang/lib/Serialization/ASTReader.cpp	2012-05-25 11:11:10.435022000 -0400
@@ -829,7 +829,7 @@ bool ASTReader::ParseLineTable(ModuleFil
       Entries.push_back(LineEntry::get(FileOffset, LineNo, FilenameID,
                                        FileKind, IncludeOffset));
     }
-    LineTable.AddEntry(FID, Entries);
+    LineTable.AddEntry(FileID::get(FID), Entries);
   }
 
   return false;
diff -rupN clang-3.1.src/lib/Serialization/ASTWriter.cpp clang/lib/Serialization/ASTWriter.cpp
--- clang-3.1.src/lib/Serialization/ASTWriter.cpp	2012-05-11 20:27:13.000000000 -0400
+++ clang/lib/Serialization/ASTWriter.cpp	2012-05-25 11:14:26.533428000 -0400
@@ -1605,11 +1605,11 @@ void ASTWriter::WriteSourceManagerBlock(
     for (LineTableInfo::iterator L = LineTable.begin(), LEnd = LineTable.end();
          L != LEnd; ++L) {
       // Only emit entries for local files.
-      if (L->first < 0)
+      if (L->first.ID < 0)
         continue;
 
       // Emit the file ID
-      Record.push_back(L->first);
+      Record.push_back(L->first.ID);
 
       // Emit the line entries
       Record.push_back(L->second.size());


More information about the cfe-commits mailing list