[cfe-commits] r38561 - in /cfe/cfe/trunk: Driver/clang.cpp Lex/Preprocessor.cpp include/clang/Lex/Preprocessor.h

sabre at cs.uiuc.edu sabre at cs.uiuc.edu
Wed Jul 11 09:22:40 PDT 2007


Author: sabre
Date: Wed Jul 11 11:22:39 2007
New Revision: 38561

URL: http://llvm.org/viewvc/llvm-project?rev=38561&view=rev
Log:
Improve #line emission in -E mode to include file entry/exits.  This is
still pretty hacky because it doesn't compute the 3/4 markers correctly.

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

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

==============================================================================
--- cfe/cfe/trunk/Driver/clang.cpp (original)
+++ cfe/cfe/trunk/Driver/clang.cpp Wed Jul 11 11:22:39 2007
@@ -588,24 +588,76 @@
 // Preprocessed output mode.
 //===----------------------------------------------------------------------===//
 
+static unsigned EModeCurLine;
+static std::string EModeCurFilename;
+static Preprocessor *EModePP;
+static bool EmodeEmittedTokensOnThisLine;
+
+static void MoveToLine(unsigned LineNo) {
+  // If this line is "close enough" to the original line, just print newlines,
+  // otherwise print a #line directive.
+  if (LineNo-EModeCurLine < 8) {
+    for (; EModeCurLine != LineNo; ++EModeCurLine)
+      std::cout << "\n";
+  } else {
+    if (EmodeEmittedTokensOnThisLine) {
+      std::cout << "\n";
+      EmodeEmittedTokensOnThisLine = false;
+    }
+    
+    std::cout << "# " << LineNo << " " << EModeCurFilename;
+
+    // FIXME: calculate system file right.
+    std::cout << " 3";
+
+    std::cout << "\n";
+    EModeCurLine = LineNo;
+  } 
+}
+
+/// HandleFileChange - Whenever the preprocessor enters or exits a #include file
+/// it invokes this handler.  Update our conception of the current 
+static void HandleFileChange(SourceLocation Loc, bool EnteringFile) {
+  SourceManager &SourceMgr = EModePP->getSourceManager();
+
+  // If we are entering a new #include, make sure to skip ahead to the line the
+  // #include directive was at.
+  if (EnteringFile) {
+    SourceLocation IncludeLoc = SourceMgr.getIncludeLoc(Loc.getFileID());
+    MoveToLine(SourceMgr.getLineNumber(IncludeLoc));
+  }
+  
+  EModeCurLine = SourceMgr.getLineNumber(Loc);
+  // FIXME: escape filename right.
+  EModeCurFilename = '"' + SourceMgr.getSourceName(Loc) + '"';
+  
+  if (EmodeEmittedTokensOnThisLine) {
+    std::cout << "\n";
+    EmodeEmittedTokensOnThisLine = false;
+  }
+  std::cout << "# " << EModeCurLine << " " << EModeCurFilename;
+  if (EnteringFile) 
+    std::cout << " 1";
+  else
+    std::cout << " 2";
+  
+  // FIXME: calculate system file right.
+  std::cout << " 3";
+    
+  std::cout << "\n";
+}
+
+
 /// HandleFirstTokOnLine - When emitting a preprocessed file in -E mode, this
 /// is called for the first token on each new line.
-static void HandleFirstTokOnLine(LexerToken &Tok, Preprocessor &PP,
-                                 unsigned &CurLine) {
+static void HandleFirstTokOnLine(LexerToken &Tok, Preprocessor &PP) {
   // Figure out what line we went to and insert the appropriate number of
   // newline characters.
   unsigned LineNo = PP.getSourceManager().getLineNumber(Tok.getLocation());
   
-  // If this line is "close enough" to the original line, just print newlines,
-  // otherwise print a #line directive.
-  if (LineNo-CurLine < 8) {
-    for (; CurLine != LineNo; ++CurLine)
-      std::cout << "\n";
-  } else {
-    // FIXME: filename too.
-    std::cout << "\n# " << LineNo << "\n";
-    CurLine = LineNo;
-  }
+  // Move to the specified line.
+  MoveToLine(LineNo);
+
   
   // Print out space characters so that the first token on a line is
   // indented for easy reading.
@@ -630,7 +682,12 @@
 void DoPrintPreprocessedInput(Preprocessor &PP) {
   LexerToken Tok;
   char Buffer[256];
-  unsigned CurLine = 1;
+  EModeCurLine = 0;
+  EModeCurFilename = "\"<uninit>\"";
+  PP.setFileChangeHandler(HandleFileChange);
+  EModePP = &PP;
+  EmodeEmittedTokensOnThisLine = false;
+  
   do {
     PP.Lex(Tok);
 
@@ -640,7 +697,7 @@
     // FIXME: For some tests, this fails just because there is no col# info from
     // macro expansions!
     if (Tok.isAtStartOfLine()) {
-      HandleFirstTokOnLine(Tok, PP, CurLine);
+      HandleFirstTokOnLine(Tok, PP);
     } else if (Tok.hasLeadingSpace()) {
       std::cout << ' ';
     }
@@ -652,6 +709,7 @@
     } else {
       std::cout << PP.getSpelling(Tok);
     }
+    EmodeEmittedTokensOnThisLine = true;
   } while (Tok.getKind() != tok::eof);
   std::cout << "\n";
 }

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

==============================================================================
--- cfe/cfe/trunk/Lex/Preprocessor.cpp (original)
+++ cfe/cfe/trunk/Lex/Preprocessor.cpp Wed Jul 11 11:22:39 2007
@@ -55,10 +55,13 @@
   NumEnteredSourceFiles = NumMacroExpanded = NumFastMacroExpanded = 0;
   MaxIncludeStackDepth = MaxMacroStackDepth = 0;
   NumSkipped = 0;
-      
+    
   // Macro expansion is enabled.
   DisableMacroExpansion = false;
   SkippingContents = false;
+
+  // There is no file-change handler yet.
+  FileChangeHandler = 0;
 }
 
 Preprocessor::~Preprocessor() {
@@ -342,6 +345,10 @@
   
   CurLexer         = new Lexer(Buffer, FileID, *this);
   CurNextDirLookup = NextDir;
+  
+  // Notify the client, if desired, that we are in a new source file.
+  if (FileChangeHandler)
+    FileChangeHandler(CurLexer->getSourceLocation(CurLexer->BufferStart), true);
 }
 
 /// EnterMacro - Add a Macro to the top of the include stack and start lexing
@@ -464,7 +471,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) {
+void Preprocessor::HandleEndOfFile(LexerToken &Result, bool isEndOfMacro) {
   assert(!CurMacroExpander &&
          "Ending a file when currently in a macro!");
   
@@ -488,6 +495,12 @@
     CurLexer         = IncludeStack.back().TheLexer;
     CurNextDirLookup = IncludeStack.back().TheDirLookup;
     IncludeStack.pop_back();
+
+    // Notify the client, if desired, that we are in a new source file.
+    if (FileChangeHandler && !isEndOfMacro)
+      FileChangeHandler(CurLexer->getSourceLocation(CurLexer->BufferPtr),
+                        false);
+    
     return Lex(Result);
   }
   
@@ -519,7 +532,7 @@
   } else {
     CurMacroExpander = 0;
     // Handle this like a #include file being popped off the stack.
-    return HandleEndOfFile(Result);
+    return HandleEndOfFile(Result, true);
   }
 }
 

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=38561&r1=38560&r2=38561&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Lex/Preprocessor.h (original)
+++ cfe/cfe/trunk/include/clang/Lex/Preprocessor.h Wed Jul 11 11:22:39 2007
@@ -87,6 +87,13 @@
   std::vector<DirectoryLookup> SearchDirs;
   unsigned SystemDirIdx;
   bool NoCurDirSearch;
+
+  /// FileChangeHandler - This callback is invoked whenever a source file is
+  /// entered or exited.  The SourceLocation indicates the new location, and
+  /// EnteringFile indicates whether this is because we are entering a new
+  /// #include'd file (when true) or whether we're exiting one because we ran
+  /// off the end (when false).
+  void (*FileChangeHandler)(SourceLocation Loc, bool EnteringFile);
   
   enum {
     /// MaxIncludeStackDepth - Maximum depth of #includes.
@@ -103,7 +110,6 @@
   
   /// CurLexer - This is the current top of the stack that we're lexing from if
   /// not expanding a macro.  One of CurLexer and CurMacroExpander must be null.
-  ///
   Lexer *CurLexer;
   
   /// CurDirLookup - The next DirectoryLookup structure to search for a file if
@@ -185,6 +191,16 @@
     NoCurDirSearch = noCurDirSearch;
   }
   
+  /// setFileChangeHandler - Set the callback invoked whenever a source file is
+  /// entered or exited.  The SourceLocation indicates the new location, and
+  /// EnteringFile indicates whether this is because we are entering a new
+  /// #include'd file (when true) or whether we're exiting one because we ran
+  /// off the end (when false).
+  void setFileChangeHandler(void (*Handler)(SourceLocation, bool)) {
+    FileChangeHandler = Handler;
+  }
+  
+  
   /// getIdentifierInfo - Return information about the specified preprocessor
   /// identifier token.  The version of this method that takes two character
   /// pointers is preferred unless the identifier is already available as a
@@ -302,7 +318,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 HandleEndOfFile(LexerToken &Result);
+  void HandleEndOfFile(LexerToken &Result, bool isEndOfMacro = false);
   
   /// HandleEndOfMacro - This callback is invoked when the lexer hits the end of
   /// the current macro line.





More information about the cfe-commits mailing list