PTH:
- Added stub PTHLexer::getSpelling() that will be used for fetching cached
  spellings from the PTH file.  This doesn't do anything yet.
- Added a hook in Preprocessor::getSpelling() to call PTHLexer::getSpelling()
  when using a PTHLexer.
- Updated PTHLexer to read the offsets of spelling tables in the PTH file.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@61911 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Lex/PTHLexer.h b/include/clang/Lex/PTHLexer.h
index 2e7d0b9..8e23924 100644
--- a/include/clang/Lex/PTHLexer.h
+++ b/include/clang/Lex/PTHLexer.h
@@ -85,6 +85,16 @@
   /// IndirectLex - An indirect call to 'Lex' that can be invoked via
   ///  the PreprocessorLexer interface.
   void IndirectLex(Token &Result) { Lex(Result); }
+
+  /// Returns the cached spelling of a token.
+  /// \param[in] sloc The SourceLocation of the token.
+  /// \param[out] Buffer If a token's spelling is found in the PTH file then
+  ///   upon exit from this method \c Buffer will be set to the address of
+  ///   the character array representing that spelling.  No characters
+  ///   are copied.
+  /// \returns The number of characters for the spelling of the token.  This
+  ///   value is 0 if the spelling could not be found in the PTH file.
+  unsigned getSpelling(SourceLocation sloc, const char *&Buffer);
   
   /// getSourceLocation - Return a source location for the token in
   /// the current file.
diff --git a/lib/Lex/PTHLexer.cpp b/lib/Lex/PTHLexer.cpp
index 3924c9c..ef7cfb1 100644
--- a/lib/Lex/PTHLexer.cpp
+++ b/lib/Lex/PTHLexer.cpp
@@ -285,6 +285,10 @@
   return SourceLocation::getFileLoc(FileID, offset);
 }
 
+unsigned PTHLexer::getSpelling(SourceLocation sloc, const char *&Buffer) {
+  return 0;
+}
+
 //===----------------------------------------------------------------------===//
 // Internal Data Structures for PTH file lookup and resolving identifiers.
 //===----------------------------------------------------------------------===//
@@ -299,21 +303,28 @@
   class Val {
     uint32_t TokenOff;
     uint32_t PPCondOff;
+    uint32_t SpellingOff;
     
   public:
     Val() : TokenOff(~0) {}
-    Val(uint32_t toff, uint32_t poff) : TokenOff(toff), PPCondOff(poff) {}
+    Val(uint32_t toff, uint32_t poff, uint32_t soff)
+      : TokenOff(toff), PPCondOff(poff), SpellingOff(soff) {}
     
     uint32_t getTokenOffset() const {
       assert(TokenOff != ~((uint32_t)0) && "PTHFileLookup entry initialized.");
       return TokenOff;
     }
     
-    uint32_t gettPPCondOffset() const {
+    uint32_t getPPCondOffset() const {
       assert(TokenOff != ~((uint32_t)0) && "PTHFileLookup entry initialized.");
       return PPCondOff;
     }
     
+    uint32_t getSpellingOffset() const {
+      assert(TokenOff != ~((uint32_t)0) && "PTHFileLookup entry initialized.");
+      return SpellingOff;
+    }
+    
     bool isValid() const { return TokenOff != ~((uint32_t)0); }
   };
   
@@ -336,8 +347,13 @@
       uint32_t len = Read32(D);
       const char* s = D;
       D += len;
+
       uint32_t TokenOff = Read32(D);
-      FileMap.GetOrCreateValue(s, s+len).getValue() = Val(TokenOff, Read32(D));      
+      uint32_t PPCondOff = Read32(D);
+      uint32_t SpellingOff = Read32(D);
+
+      FileMap.GetOrCreateValue(s, s+len).getValue() =
+        Val(TokenOff, PPCondOff, SpellingOff);      
     }
   }
 };
@@ -459,10 +475,10 @@
   const char* data = Buf->getBufferStart() + FileData.getTokenOffset();
 
   // Get the location of pp-conditional table.
-  const char* ppcond = Buf->getBufferStart() + FileData.gettPPCondOffset();
-  uint32_t len = Read32(ppcond);  
+  const char* ppcond = Buf->getBufferStart() + FileData.getPPCondOffset();
+  uint32_t len = Read32(ppcond);
   if (len == 0) ppcond = 0;
-  
+
   assert(data < Buf->getBufferEnd());
   return new PTHLexer(PP, SourceLocation::getFileLoc(FileID, 0), data, ppcond,
                       *this); 
diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp
index 1fe2321..ee6b0f8 100644
--- a/lib/Lex/Preprocessor.cpp
+++ b/lib/Lex/Preprocessor.cpp
@@ -236,7 +236,25 @@
     Buffer = II->getName();
     return II->getLength();
   }
-  
+
+  // If using PTH, try and get the spelling from the PTH file.
+  if (CurPTHLexer) {
+    // We perform the const_cast<> here because we will only have a PTHLexer 
+    // when grabbing a stream of tokens from the PTH file (and thus the
+    // Preprocessor state is allowed to change).  The PTHLexer can assume we are
+    // getting token spellings in the order of tokens, and thus can update
+    // its internal state so that it can quickly fetch spellings from the PTH
+    // file.
+    unsigned len =
+      const_cast<PTHLexer*>(CurPTHLexer.get())->getSpelling(Tok.getLocation(),
+                                                            Buffer);
+    
+    // Did we find a spelling?  If so return its length.  Otherwise fall
+    // back to the default behavior for getting the spelling by looking at
+    // at the source code.
+    if (len) return len;
+  }
+
   // Otherwise, compute the start of the token in the input lexer buffer.
   const char *TokStart = SourceMgr.getCharacterData(Tok.getLocation());