[cfe-commits] r38643 - 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:23:27 PDT 2007
Author: sabre
Date: Wed Jul 11 11:23:27 2007
New Revision: 38643
URL: http://llvm.org/viewvc/llvm-project?rev=38643&view=rev
Log:
Implement #ident and #sccs
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=38643&r1=38642&r2=38643&view=diff
==============================================================================
--- cfe/cfe/trunk/Driver/clang.cpp (original)
+++ cfe/cfe/trunk/Driver/clang.cpp Wed Jul 11 11:23:27 2007
@@ -674,6 +674,13 @@
std::cout << "\n";
}
+static void HandleIdent(SourceLocation Loc, const std::string &Val) {
+ SourceManager &SourceMgr = EModePP->getSourceManager();
+ MoveToLine(SourceMgr.getLineNumber(Loc));
+
+ std::cout << "#ident " << Val;
+ EmodeEmittedTokensOnThisLine = true;
+}
/// HandleFirstTokOnLine - When emitting a preprocessed file in -E mode, this
/// is called for the first token on each new line.
@@ -733,6 +740,7 @@
EModeCurLine = 0;
EModeCurFilename = "\"<uninit>\"";
PP.setFileChangeHandler(HandleFileChange);
+ PP.setIdentHandler(HandleIdent);
EModePP = &PP;
EmodeEmittedTokensOnThisLine = false;
Modified: cfe/cfe/trunk/Lex/Preprocessor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Lex/Preprocessor.cpp?rev=38643&r1=38642&r2=38643&view=diff
==============================================================================
--- cfe/cfe/trunk/Lex/Preprocessor.cpp (original)
+++ cfe/cfe/trunk/Lex/Preprocessor.cpp Wed Jul 11 11:23:27 2007
@@ -65,6 +65,7 @@
// There is no file-change handler yet.
FileChangeHandler = 0;
+ IdentHandler = 0;
// Initialize the pragma handlers.
PragmaHandlers = new PragmaNamespace(0);
@@ -1082,10 +1083,8 @@
; // FIXME: implement #line
if (Directive[0] == 'e' && !strcmp(Directive, "elif"))
return HandleElifDirective(Result);
- if (Directive[0] == 's' && !strcmp(Directive, "sccs")) {
- isExtension = true; // FIXME: implement #sccs
- // SCCS is the same as #ident.
- }
+ if (Directive[0] == 's' && !strcmp(Directive, "sccs"))
+ return HandleIdentSCCSDirective(Result);
break;
case 5:
if (Directive[0] == 'e' && !strcmp(Directive, "endif"))
@@ -1097,7 +1096,7 @@
if (Directive[0] == 'e' && !strcmp(Directive, "error"))
return HandleUserDiagnosticDirective(Result, false);
if (Directive[0] == 'i' && !strcmp(Directive, "ident"))
- isExtension = true; // FIXME: implement #ident
+ return HandleIdentSCCSDirective(Result);
break;
case 6:
if (Directive[0] == 'd' && !strcmp(Directive, "define"))
@@ -1143,7 +1142,7 @@
// Okay, we're done parsing the directive.
}
-void Preprocessor::HandleUserDiagnosticDirective(LexerToken &Result,
+void Preprocessor::HandleUserDiagnosticDirective(LexerToken &Tok,
bool isWarning) {
// Read the rest of the line raw. We do this because we don't want macros
// to be expanded and we don't require that the tokens be valid preprocessing
@@ -1153,7 +1152,26 @@
std::string Message = CurLexer->ReadToEndOfLine();
unsigned DiagID = isWarning ? diag::pp_hash_warning : diag::err_pp_hash_error;
- return Diag(Result, DiagID, Message);
+ return Diag(Tok, DiagID, Message);
+}
+
+/// HandleIdentSCCSDirective - Handle a #ident/#sccs directive.
+///
+void Preprocessor::HandleIdentSCCSDirective(LexerToken &Tok) {
+ Diag(Tok, diag::ext_pp_ident_directive);
+
+ LexerToken StrTok;
+ Lex(StrTok);
+
+ // If the token kind isn't a string, it's a malformed directive.
+ if (StrTok.getKind() != tok::string_literal)
+ return Diag(StrTok, diag::err_pp_malformed_ident);
+
+ // Verify that there is nothing after the string, other than EOM.
+ CheckEndOfDirective("#ident");
+
+ if (IdentHandler)
+ IdentHandler(Tok.getLocation(), getSpelling(StrTok));
}
//===----------------------------------------------------------------------===//
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=38643&r1=38642&r2=38643&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:23:27 2007
@@ -103,6 +103,8 @@
DIAG(ext_pp_import_directive, EXTENSION,
"#import is a language extension")
+DIAG(ext_pp_ident_directive, EXTENSION,
+ "#ident is a language extension")
DIAG(ext_pp_include_next_directive, EXTENSION,
"#include_next is a language extension")
DIAG(ext_pp_warning_directive, EXTENSION,
@@ -135,6 +137,8 @@
"macro names must be identifiers")
DIAG(err_pp_missing_macro_name, ERROR,
"macro name missing")
+DIAG(err_pp_malformed_ident, ERROR,
+ "invalid #ident directive")
DIAG(err_pp_unterminated_conditional, ERROR,
"unterminated conditional directive")
DIAG(pp_err_else_after_else, ERROR,
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=38643&r1=38642&r2=38643&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Lex/Preprocessor.h (original)
+++ cfe/cfe/trunk/include/clang/Lex/Preprocessor.h Wed Jul 11 11:23:27 2007
@@ -105,14 +105,22 @@
enum FileChangeReason {
EnterFile, ExitFile, SystemHeaderPragma, RenameFile
};
+ typedef void (*FileChangeHandler_t)(SourceLocation Loc,
+ FileChangeReason Reason,
+ DirectoryLookup::DirType FileType);
+ typedef void (*IdentHandler_t)(SourceLocation Loc, const std::string &str);
+
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, FileChangeReason Reason,
- DirectoryLookup::DirType FileType);
+ FileChangeHandler_t FileChangeHandler;
+
+ /// IdentHandler - This is called whenever a #ident or #sccs directive is
+ /// found.
+ IdentHandler_t IdentHandler;
enum {
/// MaxIncludeStackDepth - Maximum depth of #includes.
@@ -234,11 +242,15 @@
/// 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, FileChangeReason,
- DirectoryLookup::DirType)) {
+ void setFileChangeHandler(FileChangeHandler_t Handler) {
FileChangeHandler = Handler;
}
-
+
+ /// setIdentHandler - Set the callback invoked whenever a #ident/#sccs
+ /// directive is found.
+ void setIdentHandler(IdentHandler_t Handler) {
+ IdentHandler = Handler;
+ }
/// getIdentifierInfo - Return information about the specified preprocessor
/// identifier token. The version of this method that takes two character
@@ -453,7 +465,8 @@
/// should side-effect the current preprocessor object so that the next call
/// to Lex() will return the appropriate token next.
- void HandleUserDiagnosticDirective(LexerToken &Result, bool isWarning);
+ void HandleUserDiagnosticDirective(LexerToken &Tok, bool isWarning);
+ void HandleIdentSCCSDirective(LexerToken &Tok);
// File inclusion.
void HandleIncludeDirective(LexerToken &Tok,
More information about the cfe-commits
mailing list