[cfe-commits] r38569 - in /cfe/cfe/trunk: Driver/clang.cpp Lex/Preprocessor.cpp include/clang/Basic/DiagnosticKinds.def include/clang/Lex/Preprocessor.h

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


Author: sabre
Date: Wed Jul 11 11:22:46 2007
New Revision: 38569

URL: http://llvm.org/viewvc/llvm-project?rev=38569&view=rev
Log:
Implement #pragma GCC system_header

Modified:
    cfe/cfe/trunk/Driver/clang.cpp
    cfe/cfe/trunk/Lex/Preprocessor.cpp
    cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
    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=38569&r1=38568&r2=38569&view=diff

==============================================================================
--- cfe/cfe/trunk/Driver/clang.cpp (original)
+++ cfe/cfe/trunk/Driver/clang.cpp Wed Jul 11 11:22:46 2007
@@ -620,15 +620,23 @@
 
 /// 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,
+                             Preprocessor::FileChangeReason Reason,
                              DirectoryLookup::DirType FileType) {
   SourceManager &SourceMgr = EModePP->getSourceManager();
 
-  // If we are entering a new #include, make sure to skip ahead to the line the
+  // Unless we are exiting a #include, make sure to skip ahead to the line the
   // #include directive was at.
-  if (EnteringFile) {
+  if (Reason == Preprocessor::EnterFile) {
     SourceLocation IncludeLoc = SourceMgr.getIncludeLoc(Loc.getFileID());
     MoveToLine(SourceMgr.getLineNumber(IncludeLoc));
+  } else if (Reason == Preprocessor::SystemHeaderPragma) {
+    MoveToLine(SourceMgr.getLineNumber(Loc));
+    
+    // GCC emits the # directive for this directive on the line AFTER the
+    // directive and emits a bunch of spaces that aren't needed.  Emulate this
+    // strange behavior.
+    //std::cout << "       \n";
   }
   
   EModeCurLine = SourceMgr.getLineNumber(Loc);
@@ -641,10 +649,16 @@
     EmodeEmittedTokensOnThisLine = false;
   }
   std::cout << "# " << EModeCurLine << " " << EModeCurFilename;
-  if (EnteringFile) 
+  switch (Reason) {
+  case Preprocessor::EnterFile:
     std::cout << " 1";
-  else
+    break;
+  case Preprocessor::ExitFile:
     std::cout << " 2";
+    break;
+  case Preprocessor::SystemHeaderPragma: break;
+  case Preprocessor::RenameFile: break;
+  }
   
   if (FileType == DirectoryLookup::SystemHeaderDir)
     std::cout << " 3";

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

==============================================================================
--- cfe/cfe/trunk/Lex/Preprocessor.cpp (original)
+++ cfe/cfe/trunk/Lex/Preprocessor.cpp Wed Jul 11 11:22:46 2007
@@ -371,8 +371,8 @@
           SourceMgr.getFileEntryForFileID(CurLexer->getCurFileID()))
       FileType = getFileInfo(FE).DirInfo;
     
-    FileChangeHandler(CurLexer->getSourceLocation(CurLexer->BufferStart), true,
-                      FileType);
+    FileChangeHandler(CurLexer->getSourceLocation(CurLexer->BufferStart),
+                      EnterFile, FileType);
   }
 }
 
@@ -532,7 +532,7 @@
         FileType = getFileInfo(FE).DirInfo;
 
       FileChangeHandler(CurLexer->getSourceLocation(CurLexer->BufferPtr),
-                        false, FileType);
+                        ExitFile, FileType);
     }
     
     return Lex(Result);
@@ -1323,6 +1323,24 @@
   }
 }
 
+void Preprocessor::HandlePragmaSystemHeader(LexerToken &SysHeaderTok) {
+  if (IncludeStack.empty()) {
+    Diag(SysHeaderTok, diag::pp_pragma_sysheader_in_main_file);
+    return;
+  }
+  
+  // Mark the file as a system header.
+  const FileEntry *File = 
+    SourceMgr.getFileEntryForFileID(CurLexer->getCurFileID());
+  getFileInfo(File).DirInfo = DirectoryLookup::SystemHeaderDir;
+  
+  
+  // Notify the client, if desired, that we are in a new source file.
+  if (FileChangeHandler)
+    FileChangeHandler(CurLexer->getSourceLocation(CurLexer->BufferPtr),
+                      SystemHeaderPragma, DirectoryLookup::SystemHeaderDir);
+}
+
 /// AddPragmaHandler - Add the specified pragma handler to the preprocessor.
 /// If 'Namespace' is non-null, then it is a token required to exist on the
 /// pragma line before the pragma string starts, e.g. "STDC" or "GCC".
@@ -1356,8 +1374,7 @@
 }
 
 namespace {
-class PragmaOnceHandler : public PragmaHandler {
-public:
+struct PragmaOnceHandler : public PragmaHandler {
   PragmaOnceHandler(const IdentifierTokenInfo *OnceID) : PragmaHandler(OnceID){}
   virtual void HandlePragma(Preprocessor &PP, LexerToken &OnceTok) {
     PP.CheckEndOfDirective("#pragma once");
@@ -1365,13 +1382,20 @@
   }
 };
 
-class PragmaPoisonHandler : public PragmaHandler {
-public:
+struct PragmaPoisonHandler : public PragmaHandler {
   PragmaPoisonHandler(const IdentifierTokenInfo *ID) : PragmaHandler(ID) {}
   virtual void HandlePragma(Preprocessor &PP, LexerToken &PoisonTok) {
     PP.HandlePragmaPoison(PoisonTok);
   }
 };
+
+struct PragmaSystemHeaderHandler : public PragmaHandler {
+  PragmaSystemHeaderHandler(const IdentifierTokenInfo *ID) : PragmaHandler(ID){}
+  virtual void HandlePragma(Preprocessor &PP, LexerToken &SHToken) {
+    PP.HandlePragmaSystemHeader(SHToken);
+    PP.CheckEndOfDirective("#pragma");
+  }
+};
 }
 
 
@@ -1380,4 +1404,6 @@
 void Preprocessor::RegisterBuiltinPragmas() {
   AddPragmaHandler(0, new PragmaOnceHandler(getIdentifierInfo("once")));
   AddPragmaHandler("GCC", new PragmaPoisonHandler(getIdentifierInfo("poison")));
+  AddPragmaHandler("GCC", new PragmaSystemHeaderHandler(
+                                          getIdentifierInfo("system_header")));
 }

Modified: cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=38569&r1=38568&r2=38569&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:22:46 2007
@@ -88,6 +88,8 @@
      "ISO C99 requires whitespace after the macro name")
 DIAG(pp_pragma_once_in_main_file, WARNING,
      "#pragma once in main file")
+DIAG(pp_pragma_sysheader_in_main_file, WARNING,
+     "#pragma system_header ignored in main file")
 DIAG(pp_poisoning_existing_macro, WARNING,
      "poisoning existing macro")
 

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=38569&r1=38568&r2=38569&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Lex/Preprocessor.h (original)
+++ cfe/cfe/trunk/include/clang/Lex/Preprocessor.h Wed Jul 11 11:22:46 2007
@@ -89,13 +89,17 @@
   std::vector<DirectoryLookup> SearchDirs;
   unsigned SystemDirIdx;
   bool NoCurDirSearch;
-
+public:
+  enum FileChangeReason {
+    EnterFile, ExitFile, SystemHeaderPragma, RenameFile
+  };
+private:
   /// 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,
+  void (*FileChangeHandler)(SourceLocation Loc, FileChangeReason Reason,
                             DirectoryLookup::DirType FileType);
   
   enum {
@@ -210,7 +214,7 @@
   /// 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, FileChangeReason,
                                             DirectoryLookup::DirType)) {
     FileChangeHandler = Handler;
   }
@@ -428,6 +432,7 @@
 public:
   void HandlePragmaOnce(LexerToken &OnceTok);
   void HandlePragmaPoison(LexerToken &PoisonTok);
+  void HandlePragmaSystemHeader(LexerToken &SysHeaderTok);
 };
 
 }  // end namespace clang





More information about the cfe-commits mailing list