[cfe-commits] r38726 - in /cfe/cfe/trunk: Lex/Lexer.cpp Lex/MacroExpander.cpp Lex/Preprocessor.cpp include/clang/Lex/Lexer.h include/clang/Lex/Preprocessor.h

sabre at cs.uiuc.edu sabre at cs.uiuc.edu
Wed Jul 11 09:24:08 PDT 2007


Author: sabre
Date: Wed Jul 11 11:24:08 2007
New Revision: 38726

URL: http://llvm.org/viewvc/llvm-project?rev=38726&view=rev
Log:
Make end-of-file handling much less recursive.  This reduces the worst case
stack depth sampled by shark from ~34 to ~17 frames when preprocessing <iostream>.

Modified:
    cfe/cfe/trunk/Lex/Lexer.cpp
    cfe/cfe/trunk/Lex/MacroExpander.cpp
    cfe/cfe/trunk/Lex/Preprocessor.cpp
    cfe/cfe/trunk/include/clang/Lex/Lexer.h
    cfe/cfe/trunk/include/clang/Lex/Preprocessor.h

Modified: cfe/cfe/trunk/Lex/Lexer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Lex/Lexer.cpp?rev=38726&r1=38725&r2=38726&view=diff

==============================================================================
--- cfe/cfe/trunk/Lex/Lexer.cpp (original)
+++ cfe/cfe/trunk/Lex/Lexer.cpp Wed Jul 11 11:24:08 2007
@@ -889,7 +889,9 @@
 
 /// LexEndOfFile - CurPtr points to the end of this file.  Handle this
 /// condition, reporting diagnostics and handling other edge cases as required.
-void Lexer::LexEndOfFile(LexerToken &Result, const char *CurPtr) {
+/// This returns true if Result contains a token, false if PP.Lex should be
+/// called again.
+bool Lexer::LexEndOfFile(LexerToken &Result, const char *CurPtr) {
   // If we hit the end of the file while parsing a preprocessor directive,
   // end the preprocessor directive first.  The next token returned will
   // then be the end of file.
@@ -899,7 +901,7 @@
     Result.SetKind(tok::eom);
     // Update the location of token as well as BufferPtr.
     FormTokenWithChars(Result, CurPtr);
-    return;
+    return true;  // Have a token.
   }        
 
   // If we aren't in raw mode, issue diagnostics. If we are in raw mode, let the
@@ -919,7 +921,7 @@
   }
   
   BufferPtr = CurPtr;
-  PP.HandleEndOfFile(Result);
+  return PP.HandleEndOfFile(Result);
 }
 
 /// isNextPPTokenLParen - Return 1 if the next unexpanded token lexed from
@@ -985,8 +987,14 @@
   switch (Char) {
   case 0:  // Null.
     // Found end of file?
-    if (CurPtr-1 == BufferEnd)
-      return LexEndOfFile(Result, CurPtr-1);  // Retreat back into the file.
+    if (CurPtr-1 == BufferEnd) {
+      // Read the PP instance variable into an automatic variable, because
+      // LexEndOfFile will often delete 'this'.
+      Preprocessor &PPCache = PP;
+      if (LexEndOfFile(Result, CurPtr-1))  // Retreat back into the file.
+        return;   // Got a token to return.
+      return PPCache.Lex(Result);
+    }
     
     Diag(CurPtr-1, diag::null_in_file);
     Result.SetFlag(LexerToken::LeadingSpace);

Modified: cfe/cfe/trunk/Lex/MacroExpander.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Lex/MacroExpander.cpp?rev=38726&r1=38725&r2=38726&view=diff

==============================================================================
--- cfe/cfe/trunk/Lex/MacroExpander.cpp (original)
+++ cfe/cfe/trunk/Lex/MacroExpander.cpp Wed Jul 11 11:24:08 2007
@@ -326,9 +326,6 @@
         continue;
       }
       
-      // Okay, we have a token that is either the LHS or RHS of a paste (##)
-      // argument.
-      
       // FIXME: Handle comma swallowing GNU extension.
       
       // FIXME: handle pasted args.  Handle 'placemarker' stuff.
@@ -355,8 +352,14 @@
     if (Macro) Macro->EnableMacro();
 
     // Pop this context off the preprocessors lexer stack and get the next
-    // token.
-    return PP.HandleEndOfMacro(Tok);
+    // token.  This will delete "this" so remember the PP instance var.
+    Preprocessor &PPCache = PP;
+    if (PP.HandleEndOfMacro(Tok))
+      return;
+
+    // HandleEndOfMacro may not return a token.  If it doesn't, lex whatever is
+    // next.
+    return PPCache.Lex(Tok);
   }
   
   // Get the next token to return.

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

==============================================================================
--- cfe/cfe/trunk/Lex/Preprocessor.cpp (original)
+++ cfe/cfe/trunk/Lex/Preprocessor.cpp Wed Jul 11 11:24:08 2007
@@ -1005,7 +1005,7 @@
 /// HandleEndOfFile - This callback is invoked when the lexer hits the end of
 /// the current file.  This either returns the EOF token or pops a level off
 /// the include stack and keeps going.
-void Preprocessor::HandleEndOfFile(LexerToken &Result, bool isEndOfMacro) {
+bool Preprocessor::HandleEndOfFile(LexerToken &Result, bool isEndOfMacro) {
   assert(!CurMacroExpander &&
          "Ending a file when currently in a macro!");
   
@@ -1019,7 +1019,7 @@
     CurLexer->BufferPtr = CurLexer->BufferEnd;
     CurLexer->FormTokenWithChars(Result, CurLexer->BufferEnd);
     Result.SetKind(tok::eof);
-    return;
+    return true;
   }
   
   // See if this file had a controlling macro.
@@ -1051,8 +1051,9 @@
       FileChangeHandler(CurLexer->getSourceLocation(CurLexer->BufferPtr),
                         ExitFile, FileType);
     }
-    
-    return Lex(Result);
+
+    // Client should lex another token.
+    return false;
   }
   
   Result.StartToken();
@@ -1069,11 +1070,13 @@
   // have not been used.
   if (Diags.getDiagnosticLevel(diag::pp_macro_not_used) != Diagnostic::Ignored)
     Identifiers.VisitIdentifiers(UnusedIdentifierReporter(*this));
+  
+  return true;
 }
 
 /// HandleEndOfMacro - This callback is invoked when the lexer hits the end of
 /// the current macro expansion or token stream expansion.
-void Preprocessor::HandleEndOfMacro(LexerToken &Result) {
+bool Preprocessor::HandleEndOfMacro(LexerToken &Result) {
   assert(CurMacroExpander && !CurLexer &&
          "Ending a macro when currently in a #include file!");
 

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

==============================================================================
--- cfe/cfe/trunk/include/clang/Lex/Lexer.h (original)
+++ cfe/cfe/trunk/include/clang/Lex/Lexer.h Wed Jul 11 11:24:08 2007
@@ -336,7 +336,7 @@
   void LexStringLiteral      (LexerToken &Result, const char *CurPtr);
   void LexAngledStringLiteral(LexerToken &Result, const char *CurPtr);
   void LexCharConstant       (LexerToken &Result, const char *CurPtr);
-  void LexEndOfFile          (LexerToken &Result, const char *CurPtr);
+  bool LexEndOfFile          (LexerToken &Result, const char *CurPtr);
   
   void SkipWhitespace        (LexerToken &Result, const char *CurPtr);
   void SkipBCPLComment       (LexerToken &Result, const char *CurPtr);

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

==============================================================================
--- cfe/cfe/trunk/include/clang/Lex/Preprocessor.h (original)
+++ cfe/cfe/trunk/include/clang/Lex/Preprocessor.h Wed Jul 11 11:24:08 2007
@@ -417,13 +417,15 @@
 
   
   /// HandleEndOfFile - This callback is invoked when the lexer hits the end of
-  /// the current file.  This either returns the EOF token or pops a level off
-  /// the include stack and keeps going.
-  void HandleEndOfFile(LexerToken &Result, bool isEndOfMacro = false);
+  /// the current file.  This either returns the EOF token and returns true, or
+  /// pops a level off the include stack and returns false, at which point the
+  /// client should call lex again.
+  bool HandleEndOfFile(LexerToken &Result, bool isEndOfMacro = false);
   
   /// HandleEndOfMacro - This callback is invoked when the lexer hits the end of
-  /// the current macro line.
-  void HandleEndOfMacro(LexerToken &Result);
+  /// the current macro line.  It returns true if Result is filled in with a
+  /// token, or false if Lex should be called again.
+  bool HandleEndOfMacro(LexerToken &Result);
   
   /// HandleDirective - This callback is invoked when the lexer sees a # token
   /// at the start of a line.  This consumes the directive, modifies the 





More information about the cfe-commits mailing list