this massive patch introduces a simple new abstraction: it makes
"FileID" a concept that is now enforced by the compiler's type checker
instead of yet-another-random-unsigned floating around.

This is an important distinction from the "FileID" currently tracked by
SourceLocation.  *That* FileID may refer to the start of a file or to a
chunk within it.  The new FileID *only* refers to the file (and its 
#include stack and eventually #line data), it cannot refer to a chunk.

FileID is a completely opaque datatype to all clients, only SourceManager
is allowed to poke and prod it.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62407 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Basic/SourceLocation.cpp b/lib/Basic/SourceLocation.cpp
index 2b7584e..84fac86 100644
--- a/lib/Basic/SourceLocation.cpp
+++ b/lib/Basic/SourceLocation.cpp
@@ -105,7 +105,7 @@
 
 const llvm::MemoryBuffer* FullSourceLoc::getBuffer() const {
   assert(isValid());
-  return SrcMgr->getBuffer(getFileID());
+  return SrcMgr->getBuffer(*this);
 }
 
 void FullSourceLoc::dump() const {
diff --git a/lib/Basic/SourceManager.cpp b/lib/Basic/SourceManager.cpp
index 1240262..b6c4ffa 100644
--- a/lib/Basic/SourceManager.cpp
+++ b/lib/Basic/SourceManager.cpp
@@ -111,7 +111,7 @@
 /// createFileID - Create a new fileID for the specified ContentCache and
 /// include position.  This works regardless of whether the ContentCache
 /// corresponds to a file or some other input source.
-unsigned SourceManager::createFileID(const ContentCache *File,
+FileID SourceManager::createFileID(const ContentCache *File,
                                      SourceLocation IncludePos,
                                      SrcMgr::CharacteristicKind FileCharacter) {
   // If FileEnt is really large (e.g. it's a large .i file), we may not be able
@@ -123,7 +123,7 @@
     FileIDs.push_back(FileIDInfo::get(IncludePos, 0, File, FileCharacter));
     assert(FileIDs.size() < (1 << SourceLocation::FileIDBits) &&
            "Ran out of file ID's!");
-    return FileIDs.size();
+    return FileID::Create(FileIDs.size());
   }
   
   // Create one FileID for each chunk of the file.
@@ -140,7 +140,7 @@
 
   assert(FileIDs.size() < (1 << SourceLocation::FileIDBits) &&
          "Ran out of file ID's!");
-  return Result;
+  return FileID::Create(Result);
 }
 
 /// getInstantiationLoc - Return a new SourceLocation that encodes the fact
@@ -181,13 +181,20 @@
 }
 
 /// getBufferData - Return a pointer to the start and end of the character
-/// data for the specified FileID.
+/// data for the specified location.
 std::pair<const char*, const char*> 
-SourceManager::getBufferData(unsigned FileID) const {
-  const llvm::MemoryBuffer *Buf = getBuffer(FileID);
+SourceManager::getBufferData(SourceLocation Loc) const {
+  const llvm::MemoryBuffer *Buf = getBuffer(Loc);
   return std::make_pair(Buf->getBufferStart(), Buf->getBufferEnd());
 }
 
+std::pair<const char*, const char*>
+SourceManager::getBufferData(FileID FID) const {
+  const llvm::MemoryBuffer *Buf = getBuffer(FID);
+  return std::make_pair(Buf->getBufferStart(), Buf->getBufferEnd());
+}
+
+
 
 /// getCharacterData - Return a pointer to the start of the specified location
 /// in the appropriate MemoryBuffer.
@@ -196,9 +203,11 @@
   // heavily used by -E mode.
   SL = getSpellingLoc(SL);
   
+  std::pair<FileID, unsigned> LocInfo = getDecomposedFileLoc(SL);
+  
   // Note that calling 'getBuffer()' may lazily page in a source file.
-  return getContentCache(SL.getFileID())->getBuffer()->getBufferStart() + 
-         getFullFilePos(SL);
+  return getContentCache(LocInfo.first)->getBuffer()->getBufferStart() + 
+         LocInfo.second;
 }
 
 
@@ -206,12 +215,12 @@
 /// this is significantly cheaper to compute than the line number.  This returns
 /// zero if the column number isn't known.
 unsigned SourceManager::getColumnNumber(SourceLocation Loc) const {
-  unsigned FileID = Loc.getFileID();
-  if (FileID == 0) return 0;
+  if (Loc.getFileID() == 0) return 0;
   
-  unsigned FilePos = getFullFilePos(Loc);
-  const MemoryBuffer *Buffer = getBuffer(FileID);
-  const char *Buf = Buffer->getBufferStart();
+  std::pair<FileID, unsigned> LocInfo = getDecomposedFileLoc(Loc);
+  unsigned FilePos = LocInfo.second;
+  
+  const char *Buf = getBuffer(LocInfo.first)->getBufferStart();
 
   unsigned LineStart = FilePos;
   while (LineStart && Buf[LineStart-1] != '\n' && Buf[LineStart-1] != '\r')
@@ -223,12 +232,11 @@
 /// the SourceLocation specifies.  This can be modified with #line directives,
 /// etc.
 const char *SourceManager::getSourceName(SourceLocation Loc) const {
-  unsigned FileID = Loc.getFileID();
-  if (FileID == 0) return "";
+  if (Loc.getFileID() == 0) return "";
   
   // To get the source name, first consult the FileEntry (if one exists) before
   // the MemBuffer as this will avoid unnecessarily paging in the MemBuffer.
-  const SrcMgr::ContentCache* C = getContentCache(FileID);
+  const SrcMgr::ContentCache *C = getContentCacheForLoc(Loc);
   return C->Entry ? C->Entry->getName() : C->getBuffer()->getBufferIdentifier();
 }
 
@@ -282,15 +290,16 @@
 /// line offsets for the MemoryBuffer, so this is not cheap: use only when
 /// about to emit a diagnostic.
 unsigned SourceManager::getLineNumber(SourceLocation Loc) const {
-  unsigned FileID = Loc.getFileID();
-  if (FileID == 0) return 0;
+  if (Loc.getFileID() == 0) return 0;
 
-  ContentCache* Content;
+  ContentCache *Content;
   
-  if (LastLineNoFileIDQuery == FileID)
+  std::pair<FileID, unsigned> LocInfo = getDecomposedFileLoc(Loc);
+  
+  if (LastLineNoFileIDQuery == LocInfo.first)
     Content = LastLineNoContentCache;
   else
-    Content = const_cast<ContentCache*>(getContentCache(FileID));
+    Content = const_cast<ContentCache*>(getContentCache(LocInfo.first));
   
   // If this is the first use of line information for this buffer, compute the
   /// SourceLineCache for it on demand.
@@ -303,12 +312,12 @@
   unsigned *SourceLineCacheStart = SourceLineCache;
   unsigned *SourceLineCacheEnd = SourceLineCache + Content->NumLines;
   
-  unsigned QueriedFilePos = getFullFilePos(Loc)+1;
+  unsigned QueriedFilePos = LocInfo.second+1;
 
   // If the previous query was to the same file, we know both the file pos from
   // that query and the line number returned.  This allows us to narrow the
   // search space from the entire file to something near the match.
-  if (LastLineNoFileIDQuery == FileID) {
+  if (LastLineNoFileIDQuery == LocInfo.first) {
     if (QueriedFilePos >= LastLineNoFilePos) {
       SourceLineCache = SourceLineCache+LastLineNoResult-1;
       
@@ -362,7 +371,7 @@
     = std::lower_bound(SourceLineCache, SourceLineCacheEnd, QueriedFilePos);
   unsigned LineNo = Pos-SourceLineCacheStart;
   
-  LastLineNoFileIDQuery = FileID;
+  LastLineNoFileIDQuery = LocInfo.first;
   LastLineNoContentCache = Content;
   LastLineNoFilePos = QueriedFilePos;
   LastLineNoResult = LineNo;
@@ -492,7 +501,7 @@
 void SourceManager::Emit(llvm::Serializer& S) const {
   S.EnterBlock();
   S.EmitPtr(this);
-  S.EmitInt(MainFileID);
+  S.EmitInt(MainFileID.getOpaqueValue());
   
   // Emit: FileInfos.  Just emit the file name.
   S.EnterBlock();    
@@ -527,7 +536,7 @@
   D.RegisterPtr(M);
   
   // Read: the FileID of the main source file of the translation unit.
-  M->MainFileID = D.ReadInt();
+  M->MainFileID = FileID::Create(D.ReadInt());
   
   std::vector<char> Buf;
     
diff --git a/lib/Driver/HTMLDiagnostics.cpp b/lib/Driver/HTMLDiagnostics.cpp
index f335396..81cedba 100644
--- a/lib/Driver/HTMLDiagnostics.cpp
+++ b/lib/Driver/HTMLDiagnostics.cpp
@@ -49,10 +49,10 @@
   
   virtual void HandlePathDiagnostic(const PathDiagnostic* D);
   
-  void HandlePiece(Rewriter& R, unsigned BugFileID,
+  void HandlePiece(Rewriter& R, FileID BugFileID,
                    const PathDiagnosticPiece& P, unsigned num, unsigned max);
   
-  void HighlightRange(Rewriter& R, unsigned BugFileID, SourceRange Range);
+  void HighlightRange(Rewriter& R, FileID BugFileID, SourceRange Range);
 
   void ReportDiag(const PathDiagnostic& D);
 };
@@ -125,17 +125,15 @@
     return;
   
   SourceManager &SMgr = D.begin()->getLocation().getManager();
-  unsigned FileID = 0;
-  bool FileIDInitialized = false;
+  FileID FID;
   
   // Verify that the entire path is from the same FileID.
   for (PathDiagnostic::const_iterator I = D.begin(), E = D.end(); I != E; ++I) {
     FullSourceLoc L = I->getLocation().getInstantiationLoc();
     
-    if (!FileIDInitialized) {
-      FileID = SMgr.getCanonicalFileID(L);
-      FileIDInitialized = true;
-    } else if (SMgr.getCanonicalFileID(L) != FileID)
+    if (FID.isInvalid()) {
+      FID = SMgr.getCanonicalFileID(L);
+    } else if (SMgr.getCanonicalFileID(L) != FID)
       return; // FIXME: Emit a warning?
     
     // Check the source ranges.
@@ -147,7 +145,7 @@
       if (!L.isFileID())
         return; // FIXME: Emit a warning?      
       
-      if (SMgr.getCanonicalFileID(L) != FileID)
+      if (SMgr.getCanonicalFileID(L) != FID)
         return; // FIXME: Emit a warning?
       
       L = SMgr.getInstantiationLoc(RI->getEnd());
@@ -155,12 +153,12 @@
       if (!L.isFileID())
         return; // FIXME: Emit a warning?      
       
-      if (SMgr.getCanonicalFileID(L) != FileID)
+      if (SMgr.getCanonicalFileID(L) != FID)
         return; // FIXME: Emit a warning?
     }
   }
   
-  if (!FileIDInitialized)
+  if (FID.isInvalid())
     return; // FIXME: Emit a warning?
   
   // Create a new rewriter to generate HTML.
@@ -174,31 +172,31 @@
   for (PathDiagnostic::const_reverse_iterator I=D.rbegin(), E=D.rend();
         I!=E; ++I, --n) {
     
-    HandlePiece(R, FileID, *I, n, max);
+    HandlePiece(R, FID, *I, n, max);
   }
   
   // Add line numbers, header, footer, etc.
   
-  // unsigned FileID = R.getSourceMgr().getMainFileID();
-  html::EscapeText(R, FileID);
-  html::AddLineNumbers(R, FileID);
+  // unsigned FID = R.getSourceMgr().getMainFileID();
+  html::EscapeText(R, FID);
+  html::AddLineNumbers(R, FID);
   
   // If we have a preprocessor, relex the file and syntax highlight.
   // We might not have a preprocessor if we come from a deserialized AST file,
   // for example.
   
-  if (PP) html::SyntaxHighlight(R, FileID, *PP);
+  if (PP) html::SyntaxHighlight(R, FID, *PP);
 
   // FIXME: We eventually want to use PPF to create a fresh Preprocessor,
   //  once we have worked out the bugs.
   //
-  // if (PPF) html::HighlightMacros(R, FileID, *PPF);
+  // if (PPF) html::HighlightMacros(R, FID, *PPF);
   //
-  if (PP) html::HighlightMacros(R, FileID, *PP);
+  if (PP) html::HighlightMacros(R, FID, *PP);
   
   // Get the full directory name of the analyzed file.
 
-  const FileEntry* Entry = SMgr.getFileEntryForID(FileID);
+  const FileEntry* Entry = SMgr.getFileEntryForID(FID);
   
   // This is a cludge; basically we want to append either the full
   // working directory if we have no directory information.  This is
@@ -241,7 +239,7 @@
     os << "</table>\n<!-- REPORTSUMMARYEXTRA -->\n"
           "<h3>Annotated Source Code</h3>\n";    
     
-    R.InsertStrBefore(SourceLocation::getFileLoc(FileID, 0), os.str());
+    R.InsertStrBefore(SMgr.getLocForStartOfFile(FID), os.str());
   }
   
   // Embed meta-data tags.
@@ -252,7 +250,7 @@
     std::string s;
     llvm::raw_string_ostream os(s);
     os << "\n<!-- BUGDESC " << BugDesc << " -->\n";
-    R.InsertStrBefore(SourceLocation::getFileLoc(FileID, 0), os.str());
+    R.InsertStrBefore(SMgr.getLocForStartOfFile(FID), os.str());
   }
   
   const std::string& BugCategory = D.getCategory();
@@ -261,14 +259,14 @@
     std::string s;
     llvm::raw_string_ostream os(s);
     os << "\n<!-- BUGCATEGORY " << BugCategory << " -->\n";
-    R.InsertStrBefore(SourceLocation::getFileLoc(FileID, 0), os.str());
+    R.InsertStrBefore(SMgr.getLocForStartOfFile(FID), os.str());
   }
   
   {
     std::string s;
     llvm::raw_string_ostream os(s);
     os << "\n<!-- BUGFILE " << DirName << Entry->getName() << " -->\n";
-    R.InsertStrBefore(SourceLocation::getFileLoc(FileID, 0), os.str());
+    R.InsertStrBefore(SMgr.getLocForStartOfFile(FID), os.str());
   }
   
   {
@@ -276,22 +274,22 @@
     llvm::raw_string_ostream os(s);
     os << "\n<!-- BUGLINE "
        << D.back()->getLocation().getInstantiationLineNumber() << " -->\n";
-    R.InsertStrBefore(SourceLocation::getFileLoc(FileID, 0), os.str());
+    R.InsertStrBefore(SMgr.getLocForStartOfFile(FID), os.str());
   }
   
   {
     std::string s;
     llvm::raw_string_ostream os(s);
     os << "\n<!-- BUGPATHLENGTH " << D.size() << " -->\n";
-    R.InsertStrBefore(SourceLocation::getFileLoc(FileID, 0), os.str());
+    R.InsertStrBefore(SMgr.getLocForStartOfFile(FID), os.str());
   }
 
   // Add CSS, header, and footer.
   
-  html::AddHeaderFooterInternalBuiltinCSS(R, FileID, Entry->getName());
+  html::AddHeaderFooterInternalBuiltinCSS(R, FID, Entry->getName());
   
   // Get the rewrite buffer.
-  const RewriteBuffer *Buf = R.getRewriteBufferFor(FileID);
+  const RewriteBuffer *Buf = R.getRewriteBufferFor(FID);
   
   if (!Buf) {
     llvm::cerr << "warning: no diagnostics generated for main file.\n";
@@ -325,28 +323,26 @@
       os << *I;
 }
 
-void HTMLDiagnostics::HandlePiece(Rewriter& R, unsigned BugFileID,
+void HTMLDiagnostics::HandlePiece(Rewriter& R, FileID BugFileID,
                                   const PathDiagnosticPiece& P,
                                   unsigned num, unsigned max) {
   
   // For now, just draw a box above the line in question, and emit the
   // warning.
-  
   FullSourceLoc Pos = P.getLocation();
   
   if (!Pos.isValid())
     return;  
   
-  SourceManager& SM = R.getSourceMgr();
+  SourceManager &SM = R.getSourceMgr();
   FullSourceLoc LPos = Pos.getInstantiationLoc();
-  unsigned FileID = SM.getCanonicalFileID(LPos);
-
-  assert (&LPos.getManager() == &SM && "SourceManagers are different!");
+  FileID FID = SM.getCanonicalFileID(LPos);
+  assert(&LPos.getManager() == &SM && "SourceManagers are different!");
   
   if (SM.getCanonicalFileID(LPos) != BugFileID)
     return;
   
-  const llvm::MemoryBuffer *Buf = SM.getBuffer(FileID);
+  const llvm::MemoryBuffer *Buf = SM.getBuffer(FID);
   const char* FileStart = Buf->getBufferStart();  
   
   // Compute the column number.  Rewind from the current position to the start
@@ -436,30 +432,30 @@
     os << html::EscapeText(Msg) << "</div></td></tr>";
 
     // Insert the new html.
-    unsigned DisplayPos = 0;
-    
+    unsigned DisplayPos;
     switch (P.getDisplayHint()) {
-      case PathDiagnosticPiece::Above:
-        DisplayPos = LineStart - FileStart;
-        break;
-      case PathDiagnosticPiece::Below:
-        DisplayPos = LineEnd - FileStart;
-        break;
-      default:
-        assert (false && "Unhandled hint.");
+    default: assert(0 && "Unhandled hint.");
+    case PathDiagnosticPiece::Above:
+      DisplayPos = LineStart - FileStart;
+      break;
+    case PathDiagnosticPiece::Below:
+      DisplayPos = LineEnd - FileStart;
+      break;
     }
-      
-    R.InsertStrBefore(SourceLocation::getFileLoc(FileID, DisplayPos), os.str());
+    
+    SourceLocation Loc = 
+      SM.getLocForStartOfFile(FID).getFileLocWithOffset(DisplayPos);
+    R.InsertStrBefore(Loc, os.str());
   }
   
   // Now highlight the ranges.
   
   for (const SourceRange *I = P.ranges_begin(), *E = P.ranges_end();
         I != E; ++I)
-    HighlightRange(R, FileID, *I);
+    HighlightRange(R, FID, *I);
 }
 
-void HTMLDiagnostics::HighlightRange(Rewriter& R, unsigned BugFileID,
+void HTMLDiagnostics::HighlightRange(Rewriter& R, FileID BugFileID,
                                      SourceRange Range) {
   
   SourceManager& SM = R.getSourceMgr();
diff --git a/lib/Driver/PlistDiagnostics.cpp b/lib/Driver/PlistDiagnostics.cpp
index 1428028..0b2ca52 100644
--- a/lib/Driver/PlistDiagnostics.cpp
+++ b/lib/Driver/PlistDiagnostics.cpp
@@ -20,9 +20,9 @@
 #include "llvm/System/Path.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SmallVector.h"
-
 using namespace clang;
-typedef llvm::DenseMap<unsigned,unsigned> FIDMap;
+
+typedef llvm::DenseMap<FileID, unsigned> FIDMap;
 
 namespace clang {
   class Preprocessor;
@@ -51,27 +51,28 @@
   return new PlistDiagnostics(s);
 }
 
-static void AddFID(FIDMap& FIDs,
-                   llvm::SmallVectorImpl<unsigned>& V,
+static void AddFID(FIDMap &FIDs,
+                   llvm::SmallVectorImpl<FileID> &V,
                    SourceManager& SM, SourceLocation L) {
 
-  unsigned fid = SM.getCanonicalFileID(SM.getInstantiationLoc(L));
-  FIDMap::iterator I = FIDs.find(fid);
+  FileID FID = SM.getCanonicalFileID(SM.getInstantiationLoc(L));
+  FIDMap::iterator I = FIDs.find(FID);
   if (I != FIDs.end()) return;
-  FIDs[fid] = V.size();
-  V.push_back(fid);
+  FIDs[FID] = V.size();
+  V.push_back(FID);
 }
 
 static unsigned GetFID(const FIDMap& FIDs,
                        SourceManager& SM, SourceLocation L) {
-  unsigned fid = SM.getCanonicalFileID(SM.getInstantiationLoc(L));
-  FIDMap::const_iterator I = FIDs.find(fid);
-  assert (I != FIDs.end());
+  FileID FID = SM.getCanonicalFileID(SM.getInstantiationLoc(L));
+  FIDMap::const_iterator I = FIDs.find(FID);
+  assert(I != FIDs.end());
   return I->second;
 }
 
 static llvm::raw_ostream& Indent(llvm::raw_ostream& o, const unsigned indent) {
-  for (unsigned i = 0; i < indent; ++i) o << ' ';
+  for (unsigned i = 0; i < indent; ++i)
+    o << ' ';
   return o;
 }
 
@@ -171,7 +172,7 @@
   // Build up a set of FIDs that we use by scanning the locations and
   // ranges of the diagnostics.
   FIDMap FM;
-  llvm::SmallVector<unsigned, 10> Fids;
+  llvm::SmallVector<FileID, 10> Fids;
   
   for (PathDiagnostic::const_iterator I=D->begin(), E=D->end(); I != E; ++I) {
     AddFID(FM, Fids, SM, I->getLocation());
@@ -214,7 +215,7 @@
        " <key>files</key>\n"
        " <array>\n";
   
-  for (llvm::SmallVectorImpl<unsigned>::iterator I=Fids.begin(), E=Fids.end();
+  for (llvm::SmallVectorImpl<FileID>::iterator I=Fids.begin(), E=Fids.end();
        I!=E; ++I)
     o << "  <string>" << SM.getFileEntryForID(*I)->getName() << "</string>\n";    
   
diff --git a/lib/Lex/Lexer.cpp b/lib/Lex/Lexer.cpp
index 5a14c13..d63c8cc 100644
--- a/lib/Lex/Lexer.cpp
+++ b/lib/Lex/Lexer.cpp
@@ -62,14 +62,18 @@
 /// with the specified preprocessor managing the lexing process.  This lexer
 /// assumes that the associated file buffer and Preprocessor objects will
 /// outlive it, so it doesn't take ownership of either of them.
-Lexer::Lexer(SourceLocation fileloc, Preprocessor &pp,
+Lexer::Lexer(SourceLocation fileloc, Preprocessor &PP,
              const char *BufStart, const char *BufEnd)
-  : PreprocessorLexer(&pp, fileloc), FileLoc(fileloc),
-    Features(pp.getLangOptions()) {
+// FIXME: This is really horrible and only needed for _Pragma lexers, split this
+// out of the main lexer path!
+  : PreprocessorLexer(&PP, 
+                      PP.getSourceManager().getCanonicalFileID(
+                      PP.getSourceManager().getSpellingLoc(fileloc))),
+                      FileLoc(fileloc),
+    Features(PP.getLangOptions()) {
       
-  SourceManager &SourceMgr = PP->getSourceManager();
-  unsigned InputFileID = SourceMgr.getSpellingLoc(FileLoc).getFileID();
-  const llvm::MemoryBuffer *InputFile = SourceMgr.getBuffer(InputFileID);
+  SourceManager &SourceMgr = PP.getSourceManager();
+  const llvm::MemoryBuffer *InputFile = SourceMgr.getBuffer(getFileID());
       
   Is_PragmaLexer = false;
   InitCharacterInfo();
@@ -103,7 +107,7 @@
   
   // Default to keeping comments if the preprocessor wants them.
   ExtendedTokenMode = 0;
-  SetCommentRetentionState(PP->getCommentRetentionState());
+  SetCommentRetentionState(PP.getCommentRetentionState());
 }
 
 /// Lexer constructor - Create a new raw lexer object.  This object is only
@@ -187,9 +191,7 @@
   // all obviously single-char tokens.  This could use 
   // Lexer::isObviouslySimpleCharacter for example to handle identifiers or
   // something.
-  
-  
-  const char *BufEnd = SM.getBufferData(Loc.getFileID()).second;
+  const char *BufEnd = SM.getBufferData(Loc).second;
   
   // Create a langops struct and enable trigraphs.  This is sufficient for
   // measuring tokens.
@@ -303,6 +305,8 @@
   if (FileLoc.isFileID())
     return SourceLocation::getFileLoc(FileLoc.getFileID(), CharNo);
   
+  // Otherwise, this is the _Pragma lexer case, which pretends that all of the
+  // tokens are lexed from where the _Pragma was defined.
   assert(PP && "This doesn't work on raw lexers");
   return GetMappedTokenLoc(*PP, FileLoc, CharNo);
 }
diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp
index 0566ec5..f7551a2 100644
--- a/lib/Lex/PPDirectives.cpp
+++ b/lib/Lex/PPDirectives.cpp
@@ -394,8 +394,8 @@
   // info about where the current file is.
   const FileEntry *CurFileEnt = 0;
   if (!FromDir) {
-    unsigned FileID = getCurrentFileLexer()->getFileID();
-    CurFileEnt = SourceMgr.getFileEntryForID(FileID);
+    FileID FID = getCurrentFileLexer()->getFileID();
+    CurFileEnt = SourceMgr.getFileEntryForID(FID);
   }
   
   // Do a standard file entry lookup.
@@ -786,16 +786,16 @@
           SourceMgr.getFileCharacteristic(getCurrentFileLexer()->getFileID()));
   
   // Look up the file, create a File ID for it.
-  unsigned FileID = SourceMgr.createFileID(File, FilenameTok.getLocation(),
-                                           FileCharacter);
-  if (FileID == 0) {
+  FileID FID = SourceMgr.createFileID(File, FilenameTok.getLocation(),
+                                      FileCharacter);
+  if (FID.isInvalid()) {
     Diag(FilenameTok, diag::err_pp_file_not_found)
       << std::string(FilenameStart, FilenameEnd);
     return;
   }
 
   // Finally, if all is good, enter the new file!
-  EnterSourceFile(FileID, CurDir);
+  EnterSourceFile(FID, CurDir);
 }
 
 /// HandleIncludeNextDirective - Implements #include_next.
diff --git a/lib/Lex/PPLexerChange.cpp b/lib/Lex/PPLexerChange.cpp
index 0ecca3a..cc8ccc4 100644
--- a/lib/Lex/PPLexerChange.cpp
+++ b/lib/Lex/PPLexerChange.cpp
@@ -66,8 +66,7 @@
 /// EnterSourceFile - Add a source file to the top of the include stack and
 /// start lexing tokens from it instead of the current buffer.  Return true
 /// on failure.
-void Preprocessor::EnterSourceFile(unsigned FileID,
-                                   const DirectoryLookup *CurDir) {
+void Preprocessor::EnterSourceFile(FileID FID, const DirectoryLookup *CurDir) {
   assert(CurTokenLexer == 0 && "Cannot #include a file inside a macro!");
   ++NumEnteredSourceFiles;
   
@@ -75,8 +74,7 @@
     MaxIncludeStackDepth = IncludeMacroStack.size();
 
   if (PTH) {
-    PTHLexer* PL =
-      PTH->CreateLexer(FileID, getSourceManager().getFileEntryForID(FileID));
+    PTHLexer *PL = PTH->CreateLexer(FID, SourceMgr.getFileEntryForID(FID));
 
     if (PL) {
       EnterSourceFileWithPTH(PL, CurDir);
@@ -84,7 +82,7 @@
     }
   }
   
-  Lexer *TheLexer = new Lexer(SourceLocation::getFileLoc(FileID, 0), *this);
+  Lexer *TheLexer = new Lexer(SourceMgr.getLocForStartOfFile(FID), *this);
   EnterSourceFileWithLexer(TheLexer, CurDir);
 }  
 
@@ -125,10 +123,9 @@
 
   // Notify the client, if desired, that we are in a new source file.
   if (Callbacks) {
-    unsigned FileID = CurPPLexer->getFileID();
-    SrcMgr::CharacteristicKind FileType =
-      SourceMgr.getFileCharacteristic(CurPPLexer->getFileID());    
-    Callbacks->FileChanged(SourceLocation::getFileLoc(FileID, 0),
+    FileID FID = CurPPLexer->getFileID();
+    SrcMgr::CharacteristicKind FileType = SourceMgr.getFileCharacteristic(FID);
+    Callbacks->FileChanged(SourceMgr.getLocForStartOfFile(FID),
                            PPCallbacks::EnterFile, FileType);
   }
 }
diff --git a/lib/Lex/PTHLexer.cpp b/lib/Lex/PTHLexer.cpp
index 6401b9a..b2870f4 100644
--- a/lib/Lex/PTHLexer.cpp
+++ b/lib/Lex/PTHLexer.cpp
@@ -23,7 +23,6 @@
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/OwningPtr.h"
-
 using namespace clang;
 
 #define DISK_TOKEN_SIZE (1+1+3+4+2)
@@ -48,15 +47,14 @@
 // PTHLexer methods.
 //===----------------------------------------------------------------------===//
 
-PTHLexer::PTHLexer(Preprocessor& pp, SourceLocation fileloc, const char* D,
-                   const char* ppcond,
-                   PTHSpellingSearch& mySpellingSrch,
-                   PTHManager& PM)
-  : PreprocessorLexer(&pp, fileloc), TokBuf(D), CurPtr(D), LastHashTokPtr(0),
+PTHLexer::PTHLexer(Preprocessor &PP, FileID FID, const char *D,
+                   const char *ppcond,
+                   PTHSpellingSearch &mySpellingSrch, PTHManager &PM)
+  : PreprocessorLexer(&PP, FID), TokBuf(D), CurPtr(D), LastHashTokPtr(0),
     PPCond(ppcond), CurPPCondPtr(ppcond), MySpellingSrch(mySpellingSrch),
-    PTHMgr(PM)
-{      
-  FileID = fileloc.getFileID();
+    PTHMgr(PM) {
+      
+  FileStartLoc = PP.getSourceManager().getLocForStartOfFile(FID);
 }
 
 void PTHLexer::Lex(Token& Tok) {
@@ -96,7 +94,7 @@
   Tok.setFlag(flags);
   assert(!LexingRawMode);
   Tok.setIdentifierInfo(perID ? PTHMgr.GetIdentifierInfo(perID-1) : 0);
-  Tok.setLocation(SourceLocation::getFileLoc(FileID, FileOffset));
+  Tok.setLocation(FileStartLoc.getFileLocWithOffset(FileOffset));
   Tok.setLength(Len);
 
   //===--------------------------------------==//
@@ -295,23 +293,27 @@
     | (((uint32_t) ((uint8_t) p[1])) << 8)
     | (((uint32_t) ((uint8_t) p[2])) << 16)
     | (((uint32_t) ((uint8_t) p[3])) << 24);
-  return SourceLocation::getFileLoc(FileID, offset);
+  return FileStartLoc.getFileLocWithOffset(offset);
 }
 
 //===----------------------------------------------------------------------===//
 // getSpelling() - Use cached data in PTH files for getSpelling().
 //===----------------------------------------------------------------------===//
 
-unsigned PTHManager::getSpelling(unsigned FileID, unsigned fpos,
-                                 const char *& Buffer) {
-  
-  llvm::DenseMap<unsigned,PTHSpellingSearch*>::iterator I =
-    SpellingMap.find(FileID);
+unsigned PTHManager::getSpelling(FileID FID, unsigned FPos,
+                                 const char *&Buffer) {
+  llvm::DenseMap<FileID, PTHSpellingSearch*>::iterator I =SpellingMap.find(FID);
 
   if (I == SpellingMap.end())
       return 0;
 
-  return I->second->getSpellingBinarySearch(fpos, Buffer);
+  return I->second->getSpellingBinarySearch(FPos, Buffer);
+}
+
+unsigned PTHManager::getSpelling(SourceLocation Loc, const char *&Buffer) {
+  std::pair<FileID, unsigned> LocInfo =
+    PP->getSourceManager().getDecomposedFileLoc(Loc);
+  return getSpelling(LocInfo.first, LocInfo.second, Buffer);
 }
 
 unsigned PTHManager::getSpellingAtPTHOffset(unsigned PTHOffset,
@@ -420,14 +422,17 @@
   return 0;
 }
 
-unsigned PTHLexer::getSpelling(SourceLocation sloc, const char *&Buffer) {
-  SourceManager& SM = PP->getSourceManager();
-  sloc = SM.getSpellingLoc(sloc);
-  unsigned fid = SM.getCanonicalFileID(sloc);
-  unsigned fpos = SM.getFullFilePos(sloc);
+unsigned PTHLexer::getSpelling(SourceLocation Loc, const char *&Buffer) {
+  SourceManager &SM = PP->getSourceManager();
+  Loc = SM.getSpellingLoc(Loc);
+  std::pair<FileID, unsigned> LocInfo = SM.getDecomposedFileLoc(Loc);
+
+  FileID FID = LocInfo.first;
+  unsigned FPos = LocInfo.second;
   
-  return (fid == FileID ) ? MySpellingSrch.getSpellingLinearSearch(fpos, Buffer)
-                          : PTHMgr.getSpelling(fid, fpos, Buffer);  
+  if (FID == getFileID())
+    return MySpellingSrch.getSpellingLinearSearch(FPos, Buffer);
+  return PTHMgr.getSpelling(FID, FPos, Buffer);  
 }
 
 //===----------------------------------------------------------------------===//
@@ -662,15 +667,14 @@
 }
 
 
-PTHLexer* PTHManager::CreateLexer(unsigned FileID, const FileEntry* FE) {
-  
+PTHLexer* PTHManager::CreateLexer(FileID FID, const FileEntry* FE) {
   if (!FE)
     return 0;
   
   // Lookup the FileEntry object in our file lookup data structure.  It will
   // return a variant that indicates whether or not there is an offset within
   // the PTH file that contains cached tokens.
-  PTHFileLookup::Val FileData = ((PTHFileLookup*) FileLookup)->Lookup(FE);
+  PTHFileLookup::Val FileData = ((PTHFileLookup*)FileLookup)->Lookup(FE);
   
   if (!FileData.isValid()) // No tokens available.
     return 0;
@@ -694,9 +698,8 @@
   
   // Create the SpellingSearch object for this FileID.
   PTHSpellingSearch* ss = new PTHSpellingSearch(*this, len, spellingTable);
-  SpellingMap[FileID] = ss;
+  SpellingMap[FID] = ss;
   
   assert(PP && "No preprocessor set yet!");
-  return new PTHLexer(*PP, SourceLocation::getFileLoc(FileID, 0), data, ppcond,
-                      *ss, *this); 
+  return new PTHLexer(*PP, FID, data, ppcond, *ss, *this); 
 }
diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp
index 667e436..8603016 100644
--- a/lib/Lex/Pragma.cpp
+++ b/lib/Lex/Pragma.cpp
@@ -191,10 +191,8 @@
   }
   
   // Get the current file lexer we're looking at.  Ignore _Pragma 'files' etc.
-  unsigned FileID = getCurrentFileLexer()->getFileID();
-  
   // Mark the file as a once-only file now.
-  HeaderInfo.MarkFileIncludeOnce(SourceMgr.getFileEntryForID(FileID));
+  HeaderInfo.MarkFileIncludeOnce(getCurrentFileLexer()->getFileEntry());
 }
 
 void Preprocessor::HandlePragmaMark() {
@@ -256,8 +254,7 @@
   PreprocessorLexer *TheLexer = getCurrentFileLexer();
   
   // Mark the file as a system header.
-  const FileEntry *File = SourceMgr.getFileEntryForID(TheLexer->getFileID());
-  HeaderInfo.MarkFileSystemHeader(File);
+  HeaderInfo.MarkFileSystemHeader(TheLexer->getFileEntry());
   
   // Notify the client, if desired, that we are in a new source file.
   if (Callbacks)
@@ -299,8 +296,7 @@
     return;
   }
   
-  unsigned FileID = getCurrentFileLexer()->getFileID();
-  const FileEntry *CurFile = SourceMgr.getFileEntryForID(FileID);
+  const FileEntry *CurFile = getCurrentFileLexer()->getFileEntry();
 
   // If this file is older than the file it depends on, emit a diagnostic.
   if (CurFile && CurFile->getModificationTime() < File->getModificationTime()) {
diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp
index bbe0f5c..976e1a2 100644
--- a/lib/Lex/Preprocessor.cpp
+++ b/lib/Lex/Preprocessor.cpp
@@ -200,9 +200,7 @@
   
   if (PTH) {
     SourceLocation SLoc = SourceMgr.getSpellingLoc(Tok.getLocation());
-    unsigned fid = SourceMgr.getCanonicalFileID(SLoc);
-    unsigned fpos = SourceMgr.getFullFilePos(SLoc);
-    if (unsigned Len = PTH->getSpelling(fid, fpos, TokStart)) {
+    if (unsigned Len = PTH->getSpelling(SLoc, TokStart)) {
       assert(!Tok.needsCleaning());
       return std::string(TokStart, TokStart+Len);
     }
@@ -256,10 +254,8 @@
     if (CurPTHLexer) {
       Len = CurPTHLexer.get()->getSpelling(Tok.getLocation(), Buffer);      
     } else {
-      SourceLocation SLoc = SourceMgr.getSpellingLoc(Tok.getLocation());
-      unsigned FID = SourceMgr.getCanonicalFileID(SLoc);
-      unsigned FPos = SourceMgr.getFullFilePos(SLoc);      
-      Len = PTH->getSpelling(FID, FPos, Buffer);      
+      Len = PTH->getSpelling(SourceMgr.getSpellingLoc(Tok.getLocation()),
+                             Buffer);      
     }
 
     // Did we find a spelling?  If so return its length.  Otherwise fall
@@ -656,15 +652,14 @@
 /// which implicitly adds the builtin defines etc.
 void Preprocessor::EnterMainSourceFile() {
   
-  unsigned MainFileID = SourceMgr.getMainFileID();
+  FileID MainFileID = SourceMgr.getMainFileID();
   
   // Enter the main file source buffer.
   EnterSourceFile(MainFileID, 0);
   
   // Tell the header info that the main file was entered.  If the file is later
   // #imported, it won't be re-entered.
-  if (const FileEntry *FE = 
-        SourceMgr.getFileEntryForLoc(SourceLocation::getFileLoc(MainFileID, 0)))
+  if (const FileEntry *FE = SourceMgr.getFileEntryForID(MainFileID))
     HeaderInfo.IncrementIncludeCount(FE);
     
   std::vector<char> PrologFile;
@@ -685,11 +680,11 @@
     llvm::MemoryBuffer::getMemBufferCopy(&PrologFile.front(),&PrologFile.back(),
                                          "<predefines>");
   assert(SB && "Cannot fail to create predefined source buffer");
-  unsigned FileID = SourceMgr.createFileIDForMemBuffer(SB);
-  assert(FileID && "Could not create FileID for predefines?");
+  FileID FID = SourceMgr.createFileIDForMemBuffer(SB);
+  assert(!FID.isInvalid() && "Could not create FileID for predefines?");
   
   // Start parsing the predefines.
-  EnterSourceFile(FileID, 0);
+  EnterSourceFile(FID, 0);
 }
 
 
diff --git a/lib/Lex/PreprocessorLexer.cpp b/lib/Lex/PreprocessorLexer.cpp
index 07329e0..e98afcc 100644
--- a/lib/Lex/PreprocessorLexer.cpp
+++ b/lib/Lex/PreprocessorLexer.cpp
@@ -17,14 +17,6 @@
 #include "clang/Basic/SourceManager.h"
 using namespace clang;
 
-PreprocessorLexer::PreprocessorLexer(Preprocessor* pp, SourceLocation L)
-  :  PP(pp), FileID(pp->getSourceManager().getSpellingLoc(L).getFileID()),
-     ParsingPreprocessorDirective(false),
-     ParsingFilename(false),
-     LexingRawMode(false) {}
-
-PreprocessorLexer::~PreprocessorLexer() {}
-
 /// LexIncludeFilename - After the preprocessor has parsed a #include, lex and
 /// (potentially) macro expand the filename.
 void PreprocessorLexer::LexIncludeFilename(Token &FilenameTok) {
@@ -45,3 +37,9 @@
   if (FilenameTok.is(tok::eom))
     PP->Diag(FilenameTok.getLocation(), diag::err_pp_expects_filename);
 }
+
+/// getFileEntry - Return the FileEntry corresponding to this FileID.  Like
+/// getFileID(), this only works for lexers with attached preprocessors.
+const FileEntry *PreprocessorLexer::getFileEntry() const {
+  return PP->getSourceManager().getFileEntryForID(getFileID());
+}
diff --git a/lib/Lex/ScratchBuffer.cpp b/lib/Lex/ScratchBuffer.cpp
index 99fbdf7..ec07a71 100644
--- a/lib/Lex/ScratchBuffer.cpp
+++ b/lib/Lex/ScratchBuffer.cpp
@@ -24,7 +24,6 @@
 ScratchBuffer::ScratchBuffer(SourceManager &SM) : SourceMgr(SM), CurBuffer(0) {
   // Set BytesUsed so that the first call to getToken will require an alloc.
   BytesUsed = ScratchBufSize;
-  FileID = 0;
 }
 
 /// getToken - Splat the specified text into a temporary MemoryBuffer and
@@ -44,7 +43,7 @@
   assert(BytesUsed-Len < (1 << SourceLocation::FilePosBits) &&
          "Out of range file position!");
   
-  return SourceLocation::getFileLoc(FileID, BytesUsed-Len);
+  return BufferStartLoc.getFileLocWithOffset(BytesUsed-Len);
 }
 
 
@@ -66,7 +65,8 @@
   
   llvm::MemoryBuffer *Buf = 
     llvm::MemoryBuffer::getNewMemBuffer(RequestLen, "<scratch space>");
-  FileID = SourceMgr.createFileIDForMemBuffer(Buf);
+  FileID FID = SourceMgr.createFileIDForMemBuffer(Buf);
+  BufferStartLoc = SourceMgr.getLocForStartOfFile(FID);
   CurBuffer = const_cast<char*>(Buf->getBufferStart());
   BytesUsed = 0;
 }
diff --git a/lib/Lex/TokenLexer.cpp b/lib/Lex/TokenLexer.cpp
index 6399e86..fde2935 100644
--- a/lib/Lex/TokenLexer.cpp
+++ b/lib/Lex/TokenLexer.cpp
@@ -392,8 +392,7 @@
       SourceManager &SourceMgr = PP.getSourceManager();
       const char *ResultStrData = SourceMgr.getCharacterData(ResultTokLoc);
       
-      const llvm::MemoryBuffer *Buffer = 
-        SourceMgr.getBuffer(ResultTokLoc.getFileID());
+      const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ResultTokLoc);
       
       // Make a lexer object so that we lex and expand the paste result.
       Lexer TL(ResultTokLoc, PP.getLangOptions(), ResultStrData, 
diff --git a/lib/Rewrite/HTMLRewrite.cpp b/lib/Rewrite/HTMLRewrite.cpp
index a605a1e..d61da40 100644
--- a/lib/Rewrite/HTMLRewrite.cpp
+++ b/lib/Rewrite/HTMLRewrite.cpp
@@ -33,8 +33,8 @@
   SourceManager &SM = R.getSourceMgr();
   B = SM.getInstantiationLoc(B);
   E = SM.getInstantiationLoc(E);
-  unsigned FileID = SM.getCanonicalFileID(B);
-  assert(SM.getCanonicalFileID(E) == FileID && "B/E not in the same file!");
+  FileID FID = SM.getCanonicalFileID(B);
+  assert(SM.getCanonicalFileID(E) == FID && "B/E not in the same file!");
 
   unsigned BOffset = SM.getFullFilePos(B);
   unsigned EOffset = SM.getFullFilePos(E);
@@ -42,8 +42,8 @@
   // Include the whole end token in the range.
   EOffset += Lexer::MeasureTokenLength(E, R.getSourceMgr());
   
-  HighlightRange(R.getEditBuffer(FileID), BOffset, EOffset,
-                 SM.getBufferData(FileID).first, StartTag, EndTag);
+  HighlightRange(R.getEditBuffer(FID), BOffset, EOffset,
+                 SM.getBufferData(FID).first, StartTag, EndTag);
 }
 
 /// HighlightRange - This is the same as the above method, but takes
@@ -97,16 +97,16 @@
   }
 }
 
-void html::EscapeText(Rewriter& R, unsigned FileID,
+void html::EscapeText(Rewriter &R, FileID FID,
                       bool EscapeSpaces, bool ReplaceTabs) {
   
-  const llvm::MemoryBuffer *Buf = R.getSourceMgr().getBuffer(FileID);
+  const llvm::MemoryBuffer *Buf = R.getSourceMgr().getBuffer(FID);
   const char* C = Buf->getBufferStart();
   const char* FileEnd = Buf->getBufferEnd();
   
   assert (C <= FileEnd);
   
-  RewriteBuffer &RB = R.getEditBuffer(FileID);
+  RewriteBuffer &RB = R.getEditBuffer(FID);
 
   unsigned ColNo = 0;
   for (unsigned FilePos = 0; C != FileEnd ; ++C, ++FilePos) {
@@ -217,13 +217,13 @@
   }
 }
 
-void html::AddLineNumbers(Rewriter& R, unsigned FileID) {
+void html::AddLineNumbers(Rewriter& R, FileID FID) {
 
-  const llvm::MemoryBuffer *Buf = R.getSourceMgr().getBuffer(FileID);
+  const llvm::MemoryBuffer *Buf = R.getSourceMgr().getBuffer(FID);
   const char* FileBeg = Buf->getBufferStart();
   const char* FileEnd = Buf->getBufferEnd();
   const char* C = FileBeg;
-  RewriteBuffer &RB = R.getEditBuffer(FileID);
+  RewriteBuffer &RB = R.getEditBuffer(FID);
   
   assert (C <= FileEnd);
   
@@ -263,15 +263,15 @@
   RB.InsertTextAfter(FileEnd - FileBeg, "</table>", strlen("</table>"));
 }
 
-void html::AddHeaderFooterInternalBuiltinCSS(Rewriter& R, unsigned FileID, 
+void html::AddHeaderFooterInternalBuiltinCSS(Rewriter& R, FileID FID, 
                                              const char *title) {
 
-  const llvm::MemoryBuffer *Buf = R.getSourceMgr().getBuffer(FileID);
+  const llvm::MemoryBuffer *Buf = R.getSourceMgr().getBuffer(FID);
   const char* FileStart = Buf->getBufferStart();
   const char* FileEnd = Buf->getBufferEnd();
 
-  SourceLocation StartLoc = SourceLocation::getFileLoc(FileID, 0);
-  SourceLocation EndLoc = SourceLocation::getFileLoc(FileID, FileEnd-FileStart);
+  SourceLocation StartLoc = R.getSourceMgr().getLocForStartOfFile(FID);
+  SourceLocation EndLoc = StartLoc.getFileLocWithOffset(FileEnd-FileStart);
 
   std::string s;
   llvm::raw_string_ostream os(s);
@@ -340,15 +340,15 @@
 /// information about keywords, macro expansions etc.  This uses the macro
 /// table state from the end of the file, so it won't be perfectly perfect,
 /// but it will be reasonably close.
-void html::SyntaxHighlight(Rewriter &R, unsigned FileID, Preprocessor &PP) {
-  RewriteBuffer &RB = R.getEditBuffer(FileID);
+void html::SyntaxHighlight(Rewriter &R, FileID FID, Preprocessor &PP) {
+  RewriteBuffer &RB = R.getEditBuffer(FID);
 
   const SourceManager &SourceMgr = PP.getSourceManager();
-  std::pair<const char*, const char*> File = SourceMgr.getBufferData(FileID);
+  std::pair<const char*, const char*> File = SourceMgr.getBufferData(FID);
   const char *BufferStart = File.first;
   
-  Lexer L(SourceLocation::getFileLoc(FileID, 0), PP.getLangOptions(),
-          File.first, File.second);
+  Lexer L(SourceMgr.getLocForStartOfFile(FID),
+          PP.getLangOptions(), File.first, File.second);
   
   // Inform the preprocessor that we want to retain comments as tokens, so we 
   // can highlight them.
@@ -421,9 +421,9 @@
 /// file, to reexpand macros and insert (into the HTML) information about the
 /// macro expansions.  This won't be perfectly perfect, but it will be
 /// reasonably close.
-void html::HighlightMacros(Rewriter &R, unsigned FileID, Preprocessor& PP) {
+void html::HighlightMacros(Rewriter &R, FileID FID, Preprocessor& PP) {
   
-  RewriteBuffer &RB = R.getEditBuffer(FileID);
+  RewriteBuffer &RB = R.getEditBuffer(FID);
   
   // Inform the preprocessor that we don't want comments.
   PP.SetCommentRetentionState(false, false);
@@ -444,10 +444,10 @@
     
     // Ignore tokens whose instantiation location was not the main file.
     SourceLocation LLoc = SourceMgr.getInstantiationLoc(Tok.getLocation());
-    std::pair<unsigned, unsigned> LLocInfo = 
+    std::pair<FileID, unsigned> LLocInfo = 
       SourceMgr.getDecomposedFileLoc(LLoc);
     
-    if (LLocInfo.first != FileID) {
+    if (LLocInfo.first != FID) {
       PP.Lex(Tok);
       continue;
     }
@@ -496,9 +496,9 @@
   }
 }
 
-void html::HighlightMacros(Rewriter &R, unsigned FileID,
+void html::HighlightMacros(Rewriter &R, FileID FID,
                            PreprocessorFactory &PPF) {
   
   llvm::OwningPtr<Preprocessor> PP(PPF.CreatePreprocessor());
-  HighlightMacros(R, FileID, *PP);
+  HighlightMacros(R, FID, *PP);
 }
diff --git a/lib/Rewrite/Rewriter.cpp b/lib/Rewrite/Rewriter.cpp
index ea8dcb9..e92bd7d 100644
--- a/lib/Rewrite/Rewriter.cpp
+++ b/lib/Rewrite/Rewriter.cpp
@@ -71,8 +71,8 @@
   if (!isRewritable(Range.getBegin()) ||
       !isRewritable(Range.getEnd())) return -1;
   
-  unsigned StartOff, StartFileID;
-  unsigned EndOff  , EndFileID;
+  FileID StartFileID, EndFileID;
+  unsigned StartOff, EndOff;
   
   StartOff = getLocationOffsetAndFileID(Range.getBegin(), StartFileID);
   EndOff   = getLocationOffsetAndFileID(Range.getEnd(), EndFileID);
@@ -82,7 +82,7 @@
   
   // If edits have been made to this buffer, the delta between the range may
   // have changed.
-  std::map<unsigned, RewriteBuffer>::const_iterator I =
+  std::map<FileID, RewriteBuffer>::const_iterator I =
     RewriteBuffers.find(StartFileID);
   if (I != RewriteBuffers.end()) {
     const RewriteBuffer &RB = I->second;
@@ -109,8 +109,8 @@
       !isRewritable(Range.getEnd()))
     return "";
   
-  unsigned StartOff, StartFileID;
-  unsigned EndOff  , EndFileID;
+  FileID StartFileID, EndFileID;
+  unsigned StartOff, EndOff;
   StartOff = getLocationOffsetAndFileID(Range.getBegin(), StartFileID);
   EndOff   = getLocationOffsetAndFileID(Range.getEnd(), EndFileID);
   
@@ -119,7 +119,7 @@
   
   // If edits have been made to this buffer, the delta between the range may
   // have changed.
-  std::map<unsigned, RewriteBuffer>::const_iterator I =
+  std::map<FileID, RewriteBuffer>::const_iterator I =
     RewriteBuffers.find(StartFileID);
   if (I == RewriteBuffers.end()) {
     // If the buffer hasn't been rewritten, just return the text from the input.
@@ -149,24 +149,24 @@
 }
 
 unsigned Rewriter::getLocationOffsetAndFileID(SourceLocation Loc,
-                                              unsigned &FileID) const {
+                                              FileID &FID) const {
   assert(Loc.isValid() && "Invalid location");
-  std::pair<unsigned,unsigned> V = SourceMgr->getDecomposedFileLoc(Loc);
-  FileID = V.first;
+  std::pair<FileID,unsigned> V = SourceMgr->getDecomposedFileLoc(Loc);
+  FID = V.first;
   return V.second;
 }
 
 
 /// getEditBuffer - Get or create a RewriteBuffer for the specified FileID.
 ///
-RewriteBuffer &Rewriter::getEditBuffer(unsigned FileID) {
-  std::map<unsigned, RewriteBuffer>::iterator I =
-    RewriteBuffers.lower_bound(FileID);
-  if (I != RewriteBuffers.end() && I->first == FileID) 
+RewriteBuffer &Rewriter::getEditBuffer(FileID FID) {
+  std::map<FileID, RewriteBuffer>::iterator I =
+    RewriteBuffers.lower_bound(FID);
+  if (I != RewriteBuffers.end() && I->first == FID) 
     return I->second;
-  I = RewriteBuffers.insert(I, std::make_pair(FileID, RewriteBuffer()));
+  I = RewriteBuffers.insert(I, std::make_pair(FID, RewriteBuffer()));
   
-  std::pair<const char*, const char*> MB = SourceMgr->getBufferData(FileID);
+  std::pair<const char*, const char*> MB = SourceMgr->getBufferData(FID);
   I->second.Initialize(MB.first, MB.second);
   
   return I->second;
@@ -177,18 +177,18 @@
 bool Rewriter::InsertText(SourceLocation Loc, const char *StrData,
                           unsigned StrLen, bool InsertAfter) {
   if (!isRewritable(Loc)) return true;
-  unsigned FileID;
-  unsigned StartOffs = getLocationOffsetAndFileID(Loc, FileID);
-  getEditBuffer(FileID).InsertText(StartOffs, StrData, StrLen, InsertAfter);
+  FileID FID;
+  unsigned StartOffs = getLocationOffsetAndFileID(Loc, FID);
+  getEditBuffer(FID).InsertText(StartOffs, StrData, StrLen, InsertAfter);
   return false;
 }
 
 /// RemoveText - Remove the specified text region.
 bool Rewriter::RemoveText(SourceLocation Start, unsigned Length) {
   if (!isRewritable(Start)) return true;
-  unsigned FileID;
-  unsigned StartOffs = getLocationOffsetAndFileID(Start, FileID);
-  getEditBuffer(FileID).RemoveText(StartOffs, Length);
+  FileID FID;
+  unsigned StartOffs = getLocationOffsetAndFileID(Start, FID);
+  getEditBuffer(FID).RemoveText(StartOffs, Length);
   return false;
 }
 
@@ -198,7 +198,7 @@
 bool Rewriter::ReplaceText(SourceLocation Start, unsigned OrigLength,
                            const char *NewStr, unsigned NewLength) {
   if (!isRewritable(Start)) return true;
-  unsigned StartFileID;
+  FileID StartFileID;
   unsigned StartOffs = getLocationOffsetAndFileID(Start, StartFileID);
   
   getEditBuffer(StartFileID).ReplaceText(StartOffs, OrigLength,
diff --git a/lib/Rewrite/TokenRewriter.cpp b/lib/Rewrite/TokenRewriter.cpp
index f288ac2..85d83c2 100644
--- a/lib/Rewrite/TokenRewriter.cpp
+++ b/lib/Rewrite/TokenRewriter.cpp
@@ -18,14 +18,14 @@
 #include "clang/Basic/SourceManager.h"
 using namespace clang;
 
-TokenRewriter::TokenRewriter(unsigned FileID, SourceManager &SM,
+TokenRewriter::TokenRewriter(FileID FID, SourceManager &SM,
                              const LangOptions &LangOpts) {
   ScratchBuf.reset(new ScratchBuffer(SM));
   
-  std::pair<const char*,const char*> File = SM.getBufferData(FileID);
+  std::pair<const char*,const char*> File = SM.getBufferData(FID);
   
   // Create a lexer to lex all the tokens of the main file in raw mode.
-  Lexer RawLex(SourceLocation::getFileLoc(FileID, 0),
+  Lexer RawLex(SM.getLocForStartOfFile(FID),
                LangOpts, File.first, File.second);
   
   // Return all comments and whitespace as tokens.