[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