Hi,
Here is a small patch which add an callback on comment. This mechanism
could be used to implement -verify and tools like a documentation generator.
This patch is by no means production ready, but I would like to know
what you think about it. In particular, I didn't really know how should
the callback interact with the comment retention mode. In this patch,
they are exclusive alternative, but it would be as easy to make them
complementary. Also, the function naming is pretty bad I think...
There is no test included. I started to wrote a small consumer but it
isn't ready yet (I have just tested take the comment callback work for
simple cases).
regards,
Cédric
Index: include/clang/Lex/Lexer.h
===================================================================
--- include/clang/Lex/Lexer.h (revision 58184)
+++ include/clang/Lex/Lexer.h (working copy)
@@ -71,10 +71,12 @@
/// whitespace preservation can be useful for some clients that want to lex
/// the file in raw mode and get every character from the file.
///
- /// When this is set to 2 it returns comments and whitespace. When set to 1
- /// it returns comments, when it is set to 0 it returns normal tokens only.
+ /// When this is set to 3 it returns comments and whitespace. When set to 2
+ /// it returns comments. When set to 1 it call the PP callback on comment but
+ /// only return normal tokens. When it is set to 0 it returns normal tokens
+ /// only.
unsigned char ExtendedTokenMode;
-
+
//===--------------------------------------------------------------------===//
// Context that changes as the file is lexed.
// NOTE: any state that mutates when in raw mode must have save/restore code
@@ -161,7 +163,7 @@
/// should only be used in raw mode, as the preprocessor is not prepared to
/// deal with the excess tokens.
bool isKeepWhitespaceMode() const {
- return ExtendedTokenMode > 1;
+ return ExtendedTokenMode > 2;
}
/// SetKeepWhitespaceMode - This method lets clients enable or disable
@@ -169,13 +171,13 @@
void SetKeepWhitespaceMode(bool Val) {
assert((!Val || LexingRawMode) &&
"Can only enable whitespace retention in raw mode");
- ExtendedTokenMode = Val ? 2 : 0;
+ ExtendedTokenMode = Val ? 3 : 0;
}
/// inKeepCommentMode - Return true if the lexer should return comments as
/// tokens.
bool inKeepCommentMode() const {
- return ExtendedTokenMode > 0;
+ return ExtendedTokenMode > 1;
}
/// SetCommentRetentionMode - Change the comment retention mode of the lexer
@@ -184,10 +186,28 @@
void SetCommentRetentionState(bool Mode) {
assert(!isKeepWhitespaceMode() &&
"Can't play with comment retention state when retaining
whitespace");
+ ExtendedTokenMode = Mode ? 2 : 0;
+ }
+
+ /// inLexCommentMode - Return true if the lexer should process comments as
+ /// tokens.
+ bool inLexCommentMode() const {
+ return ExtendedTokenMode > 0;
+ }
+ /// isCommentCallbackMode - Return true if the lexer should call the callback
+ /// on comments.
+ bool isCommentCallbackMode() const {
+ return ExtendedTokenMode == 1;
+ }
+
+ /// SetCommentCallbackState - Change the comment callback mode of the lexer
+ /// to the specified mode.
+ void SetCommentCallbackState(bool Mode) {
+ assert(!inKeepCommentMode() &&
+ "Can't play with comment callback state when retaining comment");
ExtendedTokenMode = Mode ? 1 : 0;
}
-
/// ReadToEndOfLine - Read the rest of the current preprocessor line as an
/// uninterpreted string. This switches the lexer out of directive mode.
std::string ReadToEndOfLine();
Index: include/clang/Lex/PPCallbacks.h
===================================================================
--- include/clang/Lex/PPCallbacks.h (revision 58184)
+++ include/clang/Lex/PPCallbacks.h (working copy)
@@ -46,6 +46,11 @@
virtual void Ident(SourceLocation Loc, const std::string &str) {
}
+ /// Comment - This callback is invoked when a comment is encountered
+ /// only when ...
+ virtual void Comment(SourceLocation Loc, unsigned Length) {
+ }
+
};
} // end namespace clang
Index: include/clang/Lex/Preprocessor.h
===================================================================
--- include/clang/Lex/Preprocessor.h (revision 58184)
+++ include/clang/Lex/Preprocessor.h (working copy)
@@ -66,6 +66,7 @@
// State that is set before the preprocessor begins.
bool KeepComments : 1;
bool KeepMacroComments : 1;
+ bool CallbackOnComment : 1;
// State that changes while the preprocessor runs:
bool DisableMacroExpansion : 1; // True if macro expansion is disabled.
@@ -187,6 +188,9 @@
}
bool getCommentRetentionState() const { return KeepComments; }
+
+ void SetCommentCallbackState(bool state) { CallbackOnComment = state; }
+ bool getCommentCallbackState() const { return CallbackOnComment; }
/// isCurrentLexer - Return true if we are lexing directly from the specified
/// lexer.
Index: lib/Lex/Lexer.cpp
===================================================================
--- lib/Lex/Lexer.cpp (revision 58184)
+++ lib/Lex/Lexer.cpp (working copy)
@@ -102,6 +102,7 @@
// Default to keeping comments if the preprocessor wants them.
ExtendedTokenMode = 0;
SetCommentRetentionState(PP->getCommentRetentionState());
+ SetCommentCallbackState(PP->getCommentCallbackState());
}
/// Lexer constructor - Create a new raw lexer object. This object is only
@@ -804,8 +805,13 @@
// Found but did not consume the newline.
// If we are returning comments as tokens, return this comment as a token.
- if (inKeepCommentMode())
- return SaveBCPLComment(Result, CurPtr);
+ if (inLexCommentMode()) {
+ // This always return true.
+ SaveBCPLComment(Result, CurPtr);
+ if (inKeepCommentMode()) return true;
+ // We are in CallbackComment mode here
+ PP->getPPCallbacks()->Comment(Result.getLocation(), Result.getLength());
+ }
// If we are inside a preprocessor directive and we see the end of line,
// return immediately, so that the lexer can return this as an EOM token.
@@ -1041,7 +1047,9 @@
}
// If we are returning comments as tokens, return this comment as a token.
- if (inKeepCommentMode()) {
+ if(isCommentCallbackMode()) {
+ PP->getPPCallbacks()->Comment(getSourceLocation(BufferPtr),
CurPtr-BufferPtr);
+ } else if (inKeepCommentMode()) {
FormTokenWithChars(Result, CurPtr, tok::comment);
return true;
}
@@ -1303,10 +1311,10 @@
// If the next token is obviously a // or /* */ comment, skip it
efficiently
// too (without going through the big switch stmt).
- if (CurPtr[0] == '/' && CurPtr[1] == '/' && !inKeepCommentMode()) {
+ if (CurPtr[0] == '/' && CurPtr[1] == '/' && !inLexCommentMode()) {
SkipBCPLComment(Result, CurPtr+2);
goto SkipIgnoredUnits;
- } else if (CurPtr[0] == '/' && CurPtr[1] == '*' && !inKeepCommentMode()) {
+ } else if (CurPtr[0] == '/' && CurPtr[1] == '*' && !inLexCommentMode()) {
SkipBlockComment(Result, CurPtr+2);
goto SkipIgnoredUnits;
} else if (isHorizontalWhitespace(*CurPtr)) {
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits