[cfe-commits] r62273 - in /cfe/trunk: Driver/CacheTokens.cpp Driver/clang.cpp include/clang/Basic/IdentifierTable.h include/clang/Lex/PTHManager.h include/clang/Lex/Preprocessor.h lib/Basic/IdentifierTable.cpp lib/Lex/PTHLexer.cpp lib/Lex/Preprocessor.cpp

Ted Kremenek kremenek at apple.com
Thu Jan 15 10:47:46 PST 2009


Author: kremenek
Date: Thu Jan 15 12:47:46 2009
New Revision: 62273

URL: http://llvm.org/viewvc/llvm-project?rev=62273&view=rev
Log:
IdentifierInfo:
- IdentifierInfo can now (optionally) have its string data not be
  co-located with itself.  This is for use with PTH.  This aspect is a
  little gross, as getName() and getLength() now make assumptions
  about a possible alternate representation of IdentifierInfo.
  Perhaps we should make IdentifierInfo have virtual methods?

IdentifierTable:
- Added class "IdentifierInfoLookup" that can be used by
  IdentifierTable to perform "string -> IdentifierInfo" lookups using
  an auxilliary data structure.  This is used by PTH.
- Perform tests show that IdentifierTable::get() does not slow down
  because of the extra check for the IdentiferInfoLookup object (the
  regular StringMap lookup does enough work to mitigate the impact of
  an extra null pointer check).
- The upshot is that now that some IdentifierInfo objects might be
  owned by the IdentiferInfoLookup object.  This should be reviewed.

PTH:
- Modified PTHManager::GetIdentifierInfo to *not* insert entries in
  IdentifierTable's string map, and instead create IdentifierInfo
  objects on the fly when mapping from persistent IDs to
  IdentifierInfos.  This saves a ton of work with string copies,
  hashing, and StringMap lookup and resizing.  This change was
  motivated because when processing source files in the PTH cache we
  don't need to do any string -> IdentifierInfo lookups.
- PTHManager now subclasses IdentifierInfoLookup, allowing clients of
  IdentifierTable to transparently use IdentifierInfo objects managed
  by the PTH file.  PTHManager resolves "string -> IdentifierInfo"
  queries by doing a binary search over a sorted table of identifier
  strings in the PTH file (the exact algorithm we use can be changed
  as needed).

These changes lead to the following performance changes when using PTH on Cocoa.h:
- fsyntax-only: 10% performance improvement
- Eonly: 30% performance improvement

Modified:
    cfe/trunk/Driver/CacheTokens.cpp
    cfe/trunk/Driver/clang.cpp
    cfe/trunk/include/clang/Basic/IdentifierTable.h
    cfe/trunk/include/clang/Lex/PTHManager.h
    cfe/trunk/include/clang/Lex/Preprocessor.h
    cfe/trunk/lib/Basic/IdentifierTable.cpp
    cfe/trunk/lib/Lex/PTHLexer.cpp
    cfe/trunk/lib/Lex/Preprocessor.cpp

Modified: cfe/trunk/Driver/CacheTokens.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/CacheTokens.cpp?rev=62273&r1=62272&r2=62273&view=diff

==============================================================================
--- cfe/trunk/Driver/CacheTokens.cpp (original)
+++ cfe/trunk/Driver/CacheTokens.cpp Thu Jan 15 12:47:46 2009
@@ -24,6 +24,7 @@
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/System/Path.h"
 #include "llvm/Support/Compiler.h"
+#include "llvm/Support/Streams.h"
 
 using namespace clang;
 
@@ -179,8 +180,20 @@
   CompareIDDataIndex(IDData* table) : Table(table) {}
 
   bool operator()(unsigned i, unsigned j) const {
-    // Assume that IdentifierInfo::getName() returns a '\0' terminated string.
-    return strcmp(Table[i].II->getName(), Table[j].II->getName()) < 0;    
+    const IdentifierInfo* II_i = Table[i].II;
+    const IdentifierInfo* II_j = Table[j].II;
+
+    unsigned i_len = II_i->getLength();
+    unsigned j_len = II_j->getLength();
+    
+    if (i_len > j_len)
+      return false;
+    
+    if (i_len < j_len)
+      return true;
+
+    // Otherwise, compare the strings themselves!
+    return strncmp(II_i->getName(), II_j->getName(), i_len) < 0;    
   }
 };
 }
@@ -221,7 +234,10 @@
     unsigned len = d.II->getLength(); // Write out the string length.
     Emit32(len);
     const char* buf = d.II->getName(); // Write out the string data.
-    EmitBuf(buf, buf+len);  
+    EmitBuf(buf, buf+len);
+    // Emit a null character for those clients expecting that IdentifierInfo
+    // strings are null terminated.
+    Emit8('\0');
   }
   
   // Now emit the table mapping from persistent IDs to PTH file offsets.  
@@ -229,7 +245,6 @@
   Emit32(idcount);  // Emit the number of identifiers.
   for (unsigned i = 0 ; i < idcount; ++i) Emit32(IIDMap[i].FileOffset);
 
-
   return std::make_pair(DataOff, std::make_pair(IDOff, LexicalOff));
 }
 

Modified: cfe/trunk/Driver/clang.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/clang.cpp?rev=62273&r1=62272&r2=62273&view=diff

==============================================================================
--- cfe/trunk/Driver/clang.cpp (original)
+++ cfe/trunk/Driver/clang.cpp Thu Jan 15 12:47:46 2009
@@ -955,12 +955,6 @@
   PredefineBuffer.push_back(0);
   PP.setPredefines(&PredefineBuffer[0]);
   
-  // Use PTH.
-  if (!TokenCache.empty()) {
-    PTHManager* PM = PTHManager::Create(TokenCache, PP);
-    if (PM) PP.setPTHManager(PM);    
-  }
-  
   // Once we've read this, we're done.
   return false;
 }
@@ -1142,18 +1136,33 @@
   virtual ~DriverPreprocessorFactory() {}
   
   virtual Preprocessor* CreatePreprocessor() {
-    Preprocessor* PP = new Preprocessor(Diags, LangInfo, Target,
-                                        SourceMgr, HeaderInfo);
+    llvm::OwningPtr<PTHManager> PTHMgr;
+
+    // Use PTH?
+    if (!TokenCache.empty())
+      PTHMgr.reset(PTHManager::Create(TokenCache));
+    
+    // Create the Preprocessor.
+    llvm::OwningPtr<Preprocessor> PP(new Preprocessor(Diags, LangInfo, Target,
+                                                      SourceMgr, HeaderInfo,
+                                                      PTHMgr.get()));
+    
+    // Note that this is different then passing PTHMgr to Preprocessor's ctor.
+    // That argument is used as the IdentifierInfoLookup argument to
+    // IdentifierTable's ctor.
+    if (PTHMgr) {
+      PTHMgr->setPreprocessor(PP.get());
+      PP->setPTHManager(PTHMgr.take());
+    }
     
     if (InitializePreprocessor(*PP, InitializeSourceMgr, InFile)) {
-      delete PP;
       return NULL;
     }
     
     /// FIXME: PP can only handle one callback
     if (ProgAction != PrintPreprocessedInput) {    
       const char* ErrStr;
-      bool DFG = CreateDependencyFileGen(PP, OutputFile, InFile, ErrStr);
+      bool DFG = CreateDependencyFileGen(PP.get(), OutputFile, InFile, ErrStr);
        if (!DFG && ErrStr) {
         fprintf(stderr, "%s", ErrStr);
         return NULL;
@@ -1161,7 +1170,7 @@
     }
 
     InitializeSourceMgr = false;
-    return PP;
+    return PP.take();
   }
 };
 }

Modified: cfe/trunk/include/clang/Basic/IdentifierTable.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/IdentifierTable.h?rev=62273&r1=62272&r2=62273&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/IdentifierTable.h (original)
+++ cfe/trunk/include/clang/Basic/IdentifierTable.h Thu Jan 15 12:47:46 2009
@@ -19,6 +19,7 @@
 #include "clang/Basic/TokenKinds.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/OwningPtr.h"
 #include "llvm/Bitcode/SerializationFwd.h"
 #include <string> 
 #include <cassert> 
@@ -55,12 +56,13 @@
   bool IsExtension            : 1; // True if identifier is a lang extension.
   bool IsPoisoned             : 1; // True if identifier is poisoned.
   bool IsCPPOperatorKeyword   : 1; // True if ident is a C++ operator keyword.
-  // 10 bits left in 32-bit word.
+  bool IndirectString         : 1; // True if the string is stored indirectly.
+  // 9 bits left in 32-bit word.
   void *FETokenInfo;               // Managed by the language front-end.
   IdentifierInfo(const IdentifierInfo&);  // NONCOPYABLE.
   void operator=(const IdentifierInfo&);  // NONASSIGNABLE.
 public:
-  IdentifierInfo();
+  IdentifierInfo(bool usesIndirectString = false);
 
   /// isStr - Return true if this is the identifier for the specified string.
   /// This is intended to be used for string literals only: II->isStr("foo").
@@ -73,6 +75,13 @@
   /// string is properly null terminated.
   ///
   const char *getName() const {
+    if (IndirectString) {
+      // The 'this' pointer really points to a 
+      // std::pair<IdentifierInfo, const char*>, where internal pointer
+      // points to the external string data.
+      return ((std::pair<IdentifierInfo, const char*>*) this)->second + 4;
+    }
+
     // We know that this is embedded into a StringMapEntry, and it knows how to
     // efficiently find the string.
     return llvm::StringMapEntry<IdentifierInfo>::
@@ -82,6 +91,17 @@
   /// getLength - Efficiently return the length of this identifier info.
   ///
   unsigned getLength() const {
+    if (IndirectString) {
+      // The 'this' pointer really points to a 
+      // std::pair<IdentifierInfo, const char*>, where internal pointer
+      // points to the external string data.
+      const char* p = ((std::pair<IdentifierInfo, const char*>*) this)->second;
+      return ((unsigned) p[0])
+        | (((unsigned) p[1]) << 8)
+        | (((unsigned) p[2]) << 16)
+        | (((unsigned) p[3]) << 24);      
+    }
+    
     return llvm::StringMapEntry<IdentifierInfo>::
                     GetStringMapEntryFromValue(*this).getKeyLength();
   }
@@ -161,6 +181,20 @@
   void Read(llvm::Deserializer& D);  
 };
 
+/// IdentifierInfoLookup - An abstract class used by IdentifierTable that
+///  provides an interface for for performing lookups from strings
+/// (const char *) to IdentiferInfo objects.
+class IdentifierInfoLookup {
+public:
+  virtual ~IdentifierInfoLookup();
+  
+  /// get - Return the identifier token info for the specified named identifier.
+  ///  Unlike the version in IdentifierTable, this returns a pointer instead
+  ///  of a reference.  If the pointer is NULL then the IdentifierInfo cannot
+  ///  be found.
+  virtual IdentifierInfo* get(const char *NameStart, const char *NameEnd) = 0;
+};  
+  
 /// IdentifierTable - This table implements an efficient mapping from strings to
 /// IdentifierInfo nodes.  It has no other purpose, but this is an
 /// extremely performance-critical piece of the code, as each occurrance of
@@ -170,15 +204,27 @@
   // BumpPtrAllocator!
   typedef llvm::StringMap<IdentifierInfo, llvm::BumpPtrAllocator> HashTableTy;
   HashTableTy HashTable;
+  
+  IdentifierInfoLookup* ExternalLookup;
 
 public:
   /// IdentifierTable ctor - Create the identifier table, populating it with
   /// info about the language keywords for the language specified by LangOpts.
-  IdentifierTable(const LangOptions &LangOpts);
+  IdentifierTable(const LangOptions &LangOpts,
+                  IdentifierInfoLookup* externalLookup = 0);
+  
+  llvm::BumpPtrAllocator& getAllocator() {
+    return HashTable.getAllocator();
+  }
   
   /// get - Return the identifier token info for the specified named identifier.
   ///
   IdentifierInfo &get(const char *NameStart, const char *NameEnd) {
+    if (ExternalLookup) {
+      IdentifierInfo* II = ExternalLookup->get(NameStart, NameEnd);
+      if (II) return *II;
+    }
+
     return HashTable.GetOrCreateValue(NameStart, NameEnd).getValue();
   }
   

Modified: cfe/trunk/include/clang/Lex/PTHManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/PTHManager.h?rev=62273&r1=62272&r2=62273&view=diff

==============================================================================
--- cfe/trunk/include/clang/Lex/PTHManager.h (original)
+++ cfe/trunk/include/clang/Lex/PTHManager.h Thu Jan 15 12:47:46 2009
@@ -16,7 +16,9 @@
 
 #include "clang/Lex/PTHLexer.h"
 #include "clang/Basic/LangOptions.h"
+#include "clang/Basic/IdentifierTable.h"
 #include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/Allocator.h"
 #include <string>
 
 namespace llvm {
@@ -26,8 +28,6 @@
 namespace clang {
 
 class FileEntry;
-class IdentifierInfo;
-class IdentifierTable;
 class PTHLexer;
 class PTHManager;
 
@@ -54,7 +54,7 @@
       LinearItr(tableBeg) {}
 };  
   
-class PTHManager {
+class PTHManager : public IdentifierInfoLookup {
   friend class PTHLexer;
   friend class PTHSpellingSearch;
   
@@ -64,6 +64,9 @@
   /// A map from FileIDs to SpellingSearch objects.
   llvm::DenseMap<unsigned,PTHSpellingSearch*> SpellingMap;
   
+  /// Alloc - Allocator used for IdentifierInfo objects.
+  llvm::BumpPtrAllocator Alloc;
+  
   /// IdMap - A lazily generated cache mapping from persistent identifiers to
   ///  IdentifierInfo*.
   IdentifierInfo** PerIDCache;
@@ -75,47 +78,59 @@
   /// IdDataTable - Array representing the mapping from persistent IDs to the
   ///  data offset within the PTH file containing the information to
   ///  reconsitute an IdentifierInfo.
-  const char* IdDataTable;
+  const char* const IdDataTable;
+  
+  /// SortedIdTable - Array ordering persistent identifier IDs by the lexical
+  ///  order of their corresponding strings.  This is used by get().
+  const char* const SortedIdTable;
   
-  /// ITable - The IdentifierTable used for the translation unit being lexed.
-  IdentifierTable& ITable;
+  /// NumIds - The number of identifiers in the PTH file.
+  const unsigned NumIds;
 
   /// PP - The Preprocessor object that will use this PTHManager to create
   ///  PTHLexer objects.
-  Preprocessor& PP;
+  Preprocessor* PP;
   
   /// This constructor is intended to only be called by the static 'Create'
   /// method.
   PTHManager(const llvm::MemoryBuffer* buf, void* fileLookup,
              const char* idDataTable, IdentifierInfo** perIDCache,
-             Preprocessor& pp);
+             const char* sortedIdTable, unsigned numIds);
 
   // Do not implement.
   PTHManager();
   void operator=(const PTHManager&);
   
-  /// GetIdentifierInfo - Used by PTHManager to reconstruct IdentifierInfo
-  ///  objects from the PTH file.
-  IdentifierInfo* GetIdentifierInfo(unsigned);
-  
   /// getSpellingAtPTHOffset - Used by PTHLexer classes to get the cached 
   ///  spelling for a token.
   unsigned getSpellingAtPTHOffset(unsigned PTHOffset, const char*& Buffer);
   
-public:
   
+  /// GetIdentifierInfo - Used to reconstruct IdentifierInfo objects from the
+  ///  PTH file.
+  IdentifierInfo* GetIdentifierInfo(unsigned);
+  
+public:  
   ~PTHManager();
   
+  /// get - Return the identifier token info for the specified named identifier.
+  ///  Unlike the version in IdentifierTable, this returns a pointer instead
+  ///  of a reference.  If the pointer is NULL then the IdentifierInfo cannot
+  ///  be found.
+  IdentifierInfo* get(const char *NameStart, const char *NameEnd);
+  
   /// Create - This method creates PTHManager objects.  The 'file' argument
   ///  is the name of the PTH file.  This method returns NULL upon failure.
-  static PTHManager* Create(const std::string& file, Preprocessor& PP);
+  static PTHManager* Create(const std::string& file);
 
+  void setPreprocessor(Preprocessor* pp) { PP = pp; }    
+  
   /// CreateLexer - Return a PTHLexer that "lexes" the cached tokens for the
   ///  specified file.  This method returns NULL if no cached tokens exist.
   ///  It is the responsibility of the caller to 'delete' the returned object.
   PTHLexer* CreateLexer(unsigned FileID, const FileEntry* FE);
   
-  unsigned getSpelling(unsigned FileID, unsigned fpos, const char *& Buffer);
+  unsigned getSpelling(unsigned FileID, unsigned fpos, const char *& Buffer);  
 };
   
 }  // end namespace clang

Modified: cfe/trunk/include/clang/Lex/Preprocessor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Preprocessor.h?rev=62273&r1=62272&r2=62273&view=diff

==============================================================================
--- cfe/trunk/include/clang/Lex/Preprocessor.h (original)
+++ cfe/trunk/include/clang/Lex/Preprocessor.h Thu Jan 15 12:47:46 2009
@@ -191,7 +191,9 @@
 
 public:
   Preprocessor(Diagnostic &diags, const LangOptions &opts, TargetInfo &target,
-               SourceManager &SM, HeaderSearch &Headers);
+               SourceManager &SM, HeaderSearch &Headers,
+               IdentifierInfoLookup* IILookup);
+
   ~Preprocessor();
 
   Diagnostic &getDiagnostics() const { return Diags; }

Modified: cfe/trunk/lib/Basic/IdentifierTable.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/IdentifierTable.cpp?rev=62273&r1=62272&r2=62273&view=diff

==============================================================================
--- cfe/trunk/lib/Basic/IdentifierTable.cpp (original)
+++ cfe/trunk/lib/Basic/IdentifierTable.cpp Thu Jan 15 12:47:46 2009
@@ -25,7 +25,7 @@
 // IdentifierInfo Implementation
 //===----------------------------------------------------------------------===//
 
-IdentifierInfo::IdentifierInfo() {
+IdentifierInfo::IdentifierInfo(bool usesIndirectString) {
   TokenID = tok::identifier;
   ObjCOrBuiltinID = 0;
   HasMacro = false;
@@ -33,15 +33,19 @@
   IsPoisoned = false;
   IsCPPOperatorKeyword = false;
   FETokenInfo = 0;
+  IndirectString = usesIndirectString;
 }
 
 //===----------------------------------------------------------------------===//
 // IdentifierTable Implementation
 //===----------------------------------------------------------------------===//
 
-IdentifierTable::IdentifierTable(const LangOptions &LangOpts)
-  // Start with space for 8K identifiers.
-  : HashTable(8192) {
+IdentifierInfoLookup::~IdentifierInfoLookup() {}
+
+IdentifierTable::IdentifierTable(const LangOptions &LangOpts,
+                                 IdentifierInfoLookup* externalLookup)
+  : HashTable(8192), // Start with space for 8K identifiers.
+    ExternalLookup(externalLookup) {
 
   // Populate the identifier table with info about keywords for the current
   // language.
@@ -50,7 +54,7 @@
 
 // This cstor is intended to be used only for serialization.
 IdentifierTable::IdentifierTable() 
-  : HashTable(8192) { }
+  : HashTable(8192), ExternalLookup(0) { }
 
 //===----------------------------------------------------------------------===//
 // Language Keyword Implementation

Modified: cfe/trunk/lib/Lex/PTHLexer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PTHLexer.cpp?rev=62273&r1=62272&r2=62273&view=diff

==============================================================================
--- cfe/trunk/lib/Lex/PTHLexer.cpp (original)
+++ cfe/trunk/lib/Lex/PTHLexer.cpp Thu Jan 15 12:47:46 2009
@@ -506,9 +506,10 @@
 
 PTHManager::PTHManager(const llvm::MemoryBuffer* buf, void* fileLookup,
                        const char* idDataTable, IdentifierInfo** perIDCache, 
-                       Preprocessor& pp)
+                       const char* sortedIdTable, unsigned numIds)
 : Buf(buf), PerIDCache(perIDCache), FileLookup(fileLookup),
-  IdDataTable(idDataTable), ITable(pp.getIdentifierTable()), PP(pp) {}
+  IdDataTable(idDataTable), SortedIdTable(sortedIdTable),
+  NumIds(numIds), PP(0) {}
 
 PTHManager::~PTHManager() {
   delete Buf;
@@ -516,7 +517,7 @@
   free(PerIDCache);
 }
 
-PTHManager* PTHManager::Create(const std::string& file, Preprocessor& PP) {
+PTHManager* PTHManager::Create(const std::string& file) {
   
   // Memory map the PTH file.
   llvm::OwningPtr<llvm::MemoryBuffer>
@@ -563,6 +564,14 @@
     return 0; // FIXME: Proper error diagnostic?
   }
   
+  // Get the location of the lexigraphically-sorted table of persistent IDs.
+  const char* SortedIdTableOffset = EndTable + sizeof(uint32_t)*2;
+  const char* SortedIdTable = BufBeg + Read32(SortedIdTableOffset);
+  if (!(SortedIdTable > BufBeg && SortedIdTable < BufEnd)) {
+    assert(false && "Invalid PTH file.");
+    return 0; // FIXME: Proper error diagnostic?
+  }
+  
   // Get the number of IdentifierInfos and pre-allocate the identifier cache.
   uint32_t NumIds = Read32(IData);
 
@@ -577,14 +586,15 @@
     return 0;
   }
   
-  // Create the new lexer.
-  return new PTHManager(File.take(), FL.take(), IData, PerIDCache, PP);
+  // Create the new PTHManager.
+  return new PTHManager(File.take(), FL.take(), IData, PerIDCache,
+                        SortedIdTable, NumIds);
 }
 
 IdentifierInfo* PTHManager::GetIdentifierInfo(unsigned persistentID) {
     
   // Check if the IdentifierInfo has already been resolved.
-  IdentifierInfo*& II = PerIDCache[persistentID];
+  IdentifierInfo* II = PerIDCache[persistentID];
   if (II) return II;
   
   // Look in the PTH file for the string data for the IdentifierInfo object.
@@ -592,14 +602,66 @@
   const char* IDData = Buf->getBufferStart() + Read32(TableEntry);
   assert(IDData < Buf->getBufferEnd());
   
-  // Read the length of the string.
-  uint32_t len = Read32(IDData);  
+  // Allocate the object.
+  std::pair<IdentifierInfo,const char*> *Mem =
+    Alloc.Allocate<std::pair<IdentifierInfo,const char*> >();
+
+  Mem->second = IDData;
+  II = new ((void*) Mem) IdentifierInfo(true);
   
-  // Get the IdentifierInfo* with the specified string.
-  II = &ITable.get(IDData, IDData+len);
+  // Store the new IdentifierInfo in the cache.
+  PerIDCache[persistentID] = II;
   return II;
 }
 
+IdentifierInfo* PTHManager::get(const char *NameStart, const char *NameEnd) {
+  unsigned min = 0;
+  unsigned max = NumIds;
+  unsigned len = NameEnd - NameStart;
+  
+  do {
+    unsigned i = (max - min) / 2 + min;
+    const char* p = SortedIdTable + (i * 4);
+    
+    // Read the persistentID.
+    unsigned perID = 
+      ((unsigned) ((uint8_t) p[0]))
+      | (((unsigned) ((uint8_t) p[1])) << 8)
+      | (((unsigned) ((uint8_t) p[2])) << 16)
+      | (((unsigned) ((uint8_t) p[3])) << 24);
+    
+    // Get the IdentifierInfo.
+    IdentifierInfo* II = GetIdentifierInfo(perID);
+    
+    // First compare the lengths.
+    unsigned IILen = II->getLength();
+    if (len < IILen) goto IsLess;
+    if (len > IILen) goto IsGreater;
+    
+    // Now compare the strings!
+    {
+      signed comp = strncmp(NameStart, II->getName(), len);
+      if (comp < 0) goto IsLess;
+      if (comp > 0) goto IsGreater;
+    }    
+    // We found a match!
+    return II;
+    
+  IsGreater:
+    if (i == min) break;
+    min = i;
+    continue;
+    
+  IsLess:
+    max = i;
+    assert(!(max == min) || (min == i));
+  }
+  while (1);
+  
+  return 0;
+}
+
+
 PTHLexer* PTHManager::CreateLexer(unsigned FileID, const FileEntry* FE) {
   
   if (!FE)
@@ -634,6 +696,7 @@
   PTHSpellingSearch* ss = new PTHSpellingSearch(*this, len, spellingTable);
   SpellingMap[FileID] = ss;
   
-  return new PTHLexer(PP, SourceLocation::getFileLoc(FileID, 0), data, ppcond,
+  assert(PP && "No preprocessor set yet!");
+  return new PTHLexer(*PP, SourceLocation::getFileLoc(FileID, 0), data, ppcond,
                       *ss, *this); 
 }

Modified: cfe/trunk/lib/Lex/Preprocessor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Preprocessor.cpp?rev=62273&r1=62272&r2=62273&view=diff

==============================================================================
--- cfe/trunk/lib/Lex/Preprocessor.cpp (original)
+++ cfe/trunk/lib/Lex/Preprocessor.cpp Thu Jan 15 12:47:46 2009
@@ -45,9 +45,10 @@
 
 Preprocessor::Preprocessor(Diagnostic &diags, const LangOptions &opts,
                            TargetInfo &target, SourceManager &SM, 
-                           HeaderSearch &Headers) 
+                           HeaderSearch &Headers,
+                           IdentifierInfoLookup* IILookup)
   : Diags(diags), Features(opts), Target(target), FileMgr(Headers.getFileMgr()),
-    SourceMgr(SM), HeaderInfo(Headers), Identifiers(opts),
+    SourceMgr(SM), HeaderInfo(Headers), Identifiers(opts, IILookup),
     CurPPLexer(0), CurDirLookup(0), Callbacks(0) {
   ScratchBuf = new ScratchBuffer(SourceMgr);
 





More information about the cfe-commits mailing list