[cfe-commits] r38562 - 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:41 PDT 2007


Author: sabre
Date: Wed Jul 11 11:22:40 2007
New Revision: 38562

URL: http://llvm.org/viewvc/llvm-project?rev=38562&view=rev
Log:
Track which headers are system and non-C++-clean-system headers. Use this
information to print the 3/4 flags correctly on #line directives emitted
in -E mode.

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

==============================================================================
--- cfe/cfe/trunk/Driver/clang.cpp (original)
+++ cfe/cfe/trunk/Driver/clang.cpp Wed Jul 11 11:22:40 2007
@@ -592,6 +592,7 @@
 static std::string EModeCurFilename;
 static Preprocessor *EModePP;
 static bool EmodeEmittedTokensOnThisLine;
+static DirectoryLookup::DirType EmodeFileType =DirectoryLookup::NormalHeaderDir;
 
 static void MoveToLine(unsigned LineNo) {
   // If this line is "close enough" to the original line, just print newlines,
@@ -607,9 +608,11 @@
     
     std::cout << "# " << LineNo << " " << EModeCurFilename;
 
-    // FIXME: calculate system file right.
-    std::cout << " 3";
-
+    if (EmodeFileType == DirectoryLookup::SystemHeaderDir)
+      std::cout << " 3";
+    else if (EmodeFileType == DirectoryLookup::ExternCSystemHeaderDir)
+      std::cout << " 3 4";
+    
     std::cout << "\n";
     EModeCurLine = LineNo;
   } 
@@ -617,7 +620,8 @@
 
 /// 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) {
+static void HandleFileChange(SourceLocation Loc, bool EnteringFile,
+                             DirectoryLookup::DirType FileType) {
   SourceManager &SourceMgr = EModePP->getSourceManager();
 
   // If we are entering a new #include, make sure to skip ahead to the line the
@@ -630,6 +634,7 @@
   EModeCurLine = SourceMgr.getLineNumber(Loc);
   // FIXME: escape filename right.
   EModeCurFilename = '"' + SourceMgr.getSourceName(Loc) + '"';
+  EmodeFileType = FileType;
   
   if (EmodeEmittedTokensOnThisLine) {
     std::cout << "\n";
@@ -641,8 +646,10 @@
   else
     std::cout << " 2";
   
-  // FIXME: calculate system file right.
-  std::cout << " 3";
+  if (FileType == DirectoryLookup::SystemHeaderDir)
+    std::cout << " 3";
+  else if (FileType == DirectoryLookup::ExternCSystemHeaderDir)
+    std::cout << " 3 4";
     
   std::cout << "\n";
 }

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

==============================================================================
--- cfe/cfe/trunk/Lex/Preprocessor.cpp (original)
+++ cfe/cfe/trunk/Lex/Preprocessor.cpp Wed Jul 11 11:22:40 2007
@@ -48,7 +48,7 @@
                            FileManager &FM, SourceManager &SM) 
   : Diags(diags), Features(opts), FileMgr(FM), SourceMgr(SM),
     SystemDirIdx(0), NoCurDirSearch(false),
-    CurLexer(0), CurNextDirLookup(0), CurMacroExpander(0) {
+    CurLexer(0), CurDirLookup(0), CurMacroExpander(0) {
   // Clear stats.
   NumDirectives = NumIncluded = NumDefined = NumUndefined = NumPragma = 0;
   NumIf = NumElse = NumEndif = 0;
@@ -267,11 +267,11 @@
 /// return null on failure.  isAngled indicates whether the file reference is
 /// for system #include's or not (i.e. using <> instead of "").
 const FileEntry *Preprocessor::LookupFile(const std::string &Filename, 
-                                          bool isSystem,
+                                          bool isAngled,
                                           const DirectoryLookup *FromDir,
-                                          const DirectoryLookup *&NextDir) {
+                                          const DirectoryLookup *&CurDir) {
   assert(CurLexer && "Cannot enter a #include inside a macro expansion!");
-  NextDir = 0;
+  CurDir = 0;
   
   // If 'Filename' is absolute, check to see if it exists and no searching.
   // FIXME: this should be a sys::Path interface, this doesn't handle things
@@ -286,23 +286,28 @@
   
   // Step #0, unless disabled, check to see if the file is in the #includer's
   // directory.  This search is not done for <> headers.
-  if (!isSystem && !FromDir && !NoCurDirSearch) {
+  if (!isAngled && !FromDir && !NoCurDirSearch) {
     const FileEntry *CurFE = 
       SourceMgr.getFileEntryForFileID(CurLexer->getCurFileID());
     if (CurFE) {
+      // Concatenate the requested file onto the directory.
+      // FIXME: should be in sys::Path.
       if (const FileEntry *FE = 
             FileMgr.getFile(CurFE->getDir()->getName()+"/"+Filename)) {
-        if (CurNextDirLookup)
-          NextDir = CurNextDirLookup;
+        if (CurDirLookup)
+          CurDir = CurDirLookup;
         else
-          NextDir = &SearchDirs[0];
+          CurDir = 0;
+        
+        // This file is a system header or C++ unfriendly if the old file is.
+        getFileInfo(FE).DirInfo = getFileInfo(CurFE).DirInfo;
         return FE;
       }
     }
   }
   
   // If this is a system #include, ignore the user #include locs.
-  unsigned i = isSystem ? SystemDirIdx : 0;
+  unsigned i = isAngled ? SystemDirIdx : 0;
 
   // If this is a #include_next request, start searching after the directory the
   // file was found in.
@@ -315,7 +320,10 @@
     // FIXME: should be in sys::Path.
     if (const FileEntry *FE = 
           FileMgr.getFile(SearchDirs[i].getDir()->getName()+"/"+Filename)) {
-      NextDir = &SearchDirs[i+1];
+      CurDir = &SearchDirs[i];
+      
+      // This file is a system header or C++ unfriendly if the dir is.
+      getFileInfo(FE).DirInfo = CurDir->getDirCharacteristic();
       return FE;
     }
   }
@@ -328,12 +336,12 @@
 /// start lexing tokens from it instead of the current buffer.  Return true
 /// on failure.
 void Preprocessor::EnterSourceFile(unsigned FileID,
-                                   const DirectoryLookup *NextDir) {
+                                   const DirectoryLookup *CurDir) {
   ++NumEnteredSourceFiles;
   
   // Add the current lexer to the include stack.
   if (CurLexer) {
-    IncludeStack.push_back(IncludeStackInfo(CurLexer, CurNextDirLookup));
+    IncludeStack.push_back(IncludeStackInfo(CurLexer, CurDirLookup));
   } else {
     assert(CurMacroExpander == 0 && "Cannot #include a file inside a macro!");
   }
@@ -343,12 +351,21 @@
   
   const SourceBuffer *Buffer = SourceMgr.getBuffer(FileID);
   
-  CurLexer         = new Lexer(Buffer, FileID, *this);
-  CurNextDirLookup = NextDir;
+  CurLexer     = new Lexer(Buffer, FileID, *this);
+  CurDirLookup = CurDir;
   
   // Notify the client, if desired, that we are in a new source file.
-  if (FileChangeHandler)
-    FileChangeHandler(CurLexer->getSourceLocation(CurLexer->BufferStart), true);
+  if (FileChangeHandler) {
+    DirectoryLookup::DirType FileType = DirectoryLookup::NormalHeaderDir;
+    
+    // Get the file entry for the current file.
+    if (const FileEntry *FE = 
+          SourceMgr.getFileEntryForFileID(CurLexer->getCurFileID()))
+      FileType = getFileInfo(FE).DirInfo;
+    
+    FileChangeHandler(CurLexer->getSourceLocation(CurLexer->BufferStart), true,
+                      FileType);
+  }
 }
 
 /// EnterMacro - Add a Macro to the top of the include stack and start lexing
@@ -357,9 +374,9 @@
   IdentifierTokenInfo *Identifier = Tok.getIdentifierInfo();
   MacroInfo &MI = *Identifier->getMacroInfo();
   if (CurLexer) {
-    IncludeStack.push_back(IncludeStackInfo(CurLexer, CurNextDirLookup));
-    CurLexer         = 0;
-    CurNextDirLookup = 0;
+    IncludeStack.push_back(IncludeStackInfo(CurLexer, CurDirLookup));
+    CurLexer     = 0;
+    CurDirLookup = 0;
   } else if (CurMacroExpander) {
     MacroStack.push_back(CurMacroExpander);
   }
@@ -492,14 +509,22 @@
   if (!IncludeStack.empty()) {
     // We're done with the #included file.
     delete CurLexer;
-    CurLexer         = IncludeStack.back().TheLexer;
-    CurNextDirLookup = IncludeStack.back().TheDirLookup;
+    CurLexer     = IncludeStack.back().TheLexer;
+    CurDirLookup = IncludeStack.back().TheDirLookup;
     IncludeStack.pop_back();
 
     // Notify the client, if desired, that we are in a new source file.
-    if (FileChangeHandler && !isEndOfMacro)
+    if (FileChangeHandler && !isEndOfMacro) {
+      DirectoryLookup::DirType FileType = DirectoryLookup::NormalHeaderDir;
+      
+      // Get the file entry for the current file.
+      if (const FileEntry *FE = 
+            SourceMgr.getFileEntryForFileID(CurLexer->getCurFileID()))
+        FileType = getFileInfo(FE).DirInfo;
+
       FileChangeHandler(CurLexer->getSourceLocation(CurLexer->BufferPtr),
-                        false);
+                        false, FileType);
+    }
     
     return Lex(Result);
   }
@@ -923,8 +948,8 @@
     return Diag(FilenameTok, diag::err_pp_empty_filename);
   
   // Search include directories.
-  const DirectoryLookup *NextDir;
-  const FileEntry *File = LookupFile(Filename, isAngled, LookupFrom, NextDir);
+  const DirectoryLookup *CurDir;
+  const FileEntry *File = LookupFile(Filename, isAngled, LookupFrom, CurDir);
   if (File == 0)
     return Diag(FilenameTok, diag::err_pp_file_not_found);
   
@@ -953,7 +978,7 @@
     return Diag(FilenameTok, diag::err_pp_file_not_found);
 
   // Finally, if all is good, enter the new file!
-  EnterSourceFile(FileID, NextDir);
+  EnterSourceFile(FileID, CurDir);
 
   // Increment the number of times this file has been included.
   ++FileInfo.NumIncludes;
@@ -967,12 +992,15 @@
   // #include_next is like #include, except that we start searching after
   // the current found directory.  If we can't do this, issue a
   // diagnostic.
-  const DirectoryLookup *Lookup = CurNextDirLookup;
+  const DirectoryLookup *Lookup = CurDirLookup;
   if (IncludeStack.empty()) {
     Lookup = 0;
     Diag(IncludeNextTok, diag::pp_include_next_in_primary);
   } else if (Lookup == 0) {
     Diag(IncludeNextTok, diag::pp_include_next_absolute_path);
+  } else {
+    // Start looking up in the next directory.
+    ++Lookup;
   }
   
   return HandleIncludeDirective(IncludeNextTok, Lookup);

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

==============================================================================
--- cfe/cfe/trunk/include/clang/Lex/Preprocessor.h (original)
+++ cfe/cfe/trunk/include/clang/Lex/Preprocessor.h Wed Jul 11 11:22:40 2007
@@ -93,7 +93,8 @@
   /// 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);
+  void (*FileChangeHandler)(SourceLocation Loc, bool EnteringFile,
+                            DirectoryLookup::DirType FileType);
   
   enum {
     /// MaxIncludeStackDepth - Maximum depth of #includes.
@@ -112,9 +113,10 @@
   /// 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
-  /// CurLexer is non-null.  This allows us to implement #include_next.
-  const DirectoryLookup *CurNextDirLookup;
+  /// CurLookup - The DirectoryLookup structure used to find the current
+  /// FileEntry, if CurLexer is non-null and if applicable.  This allows us to
+  /// implement #include_next and find directory-specific properties.
+  const DirectoryLookup *CurDirLookup;
   
   /// IncludeStack - This keeps track of the stack of files currently #included,
   /// not counting CurLexer.
@@ -139,14 +141,20 @@
   /// PreFileInfo - The preprocessor keeps track of this information for each
   /// file that is #included.
   struct PerFileInfo {
-    // isImport - True if this is a #import'd or #pragma once file.
-    bool isImport;
+    /// isImport - True if this is a #import'd or #pragma once file.
+    bool isImport : 1;
     
-    // NumIncludes - This is the number of times the file has been included
-    // already.
+    /// DirInfo - Keep track of whether this is a system header, and if so,
+    /// whether it is C++ clean or not.  This can be set by the include paths or
+    /// by #pragma gcc system_header.
+    DirectoryLookup::DirType DirInfo : 2;
+    
+    /// NumIncludes - This is the number of times the file has been included
+    /// already.
     unsigned short NumIncludes;
     
-    PerFileInfo() : isImport(false), NumIncludes(0) {}
+    PerFileInfo() : isImport(false), DirInfo(DirectoryLookup::NormalHeaderDir),
+                    NumIncludes(0) {}
   };
   
   /// FileInfo - This contains all of the preprocessor-specific data about files
@@ -196,7 +204,8 @@
   /// 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)) {
+  void setFileChangeHandler(void (*Handler)(SourceLocation, bool,
+                                            DirectoryLookup::DirType)) {
     FileChangeHandler = Handler;
   }
   
@@ -239,14 +248,14 @@
   void AddKeywords();
 
   /// LookupFile - Given a "foo" or <foo> reference, look up the indicated file,
-  /// return null on failure.  isSystem indicates whether the file reference is
-  /// for system #include's or not.  If successful, this returns 'UsedDir', the
+  /// return null on failure.  isAngled indicates whether the file reference is
+  /// a <> reference.  If successful, this returns 'UsedDir', the
   /// DirectoryLookup member the file was found in, or null if not applicable.
-  /// If FromDir is non-null, the directory search should start with the entry
-  /// after the indicated lookup.  This is used to implement #include_next.
-  const FileEntry *LookupFile(const std::string &Filename, bool isSystem,
+  /// If CurDir is non-null, the file was found in the specified directory
+  /// search location.  This is used to implement #include_next.
+  const FileEntry *LookupFile(const std::string &Filename, bool isAngled,
                               const DirectoryLookup *FromDir,
-                              const DirectoryLookup *&NextDir);
+                              const DirectoryLookup *&CurDir);
   
   /// EnterSourceFile - Add a source file to the top of the include stack and
   /// start lexing tokens from it instead of the current buffer.





More information about the cfe-commits mailing list