From b70e3dafb9618f34017061400dc19ac5e3539a6d Mon Sep 17 00:00:00 2001
From: Ted Kremenek <kremenek@apple.com>
Date: Thu, 8 Jan 2009 02:47:16 +0000
Subject: [PATCH] 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
---
 include/clang/Lex/PTHLexer.h | 10 ++++++++++
 lib/Lex/PTHLexer.cpp         | 28 ++++++++++++++++++++++------
 lib/Lex/Preprocessor.cpp     | 20 +++++++++++++++++++-
 3 files changed, 51 insertions(+), 7 deletions(-)

diff --git a/include/clang/Lex/PTHLexer.h b/include/clang/Lex/PTHLexer.h
index 2e7d0b95cd2..8e23924abc8 100644
--- a/include/clang/Lex/PTHLexer.h
+++ b/include/clang/Lex/PTHLexer.h
@@ -85,6 +85,16 @@ public:
   /// 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 3924c9cd2d3..ef7cfb18d61 100644
--- a/lib/Lex/PTHLexer.cpp
+++ b/lib/Lex/PTHLexer.cpp
@@ -285,6 +285,10 @@ SourceLocation PTHLexer::getSourceLocation() {
   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 @@ public:
   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 @@ public:
       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 @@ PTHLexer* PTHManager::CreateLexer(unsigned FileID, const FileEntry* FE) {
   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 1fe23216e71..ee6b0f888cf 100644
--- a/lib/Lex/Preprocessor.cpp
+++ b/lib/Lex/Preprocessor.cpp
@@ -236,7 +236,25 @@ unsigned Preprocessor::getSpelling(const Token &Tok,
     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());
 
-- 
GitLab