allow the HandlerComment callback to push tokens into the

preprocessor.  This could be used by an OpenMP implementation
or something.  Patch by Abramo Bagnara!


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@93795 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2010-01-18 22:35:47 +00:00
Родитель 2c6b193d57
Коммит 046c2277dc
4 изменённых файлов: 42 добавлений и 20 удалений

Просмотреть файл

@ -884,7 +884,9 @@ public:
void HandlePragmaSystemHeader(Token &SysHeaderTok); void HandlePragmaSystemHeader(Token &SysHeaderTok);
void HandlePragmaDependency(Token &DependencyTok); void HandlePragmaDependency(Token &DependencyTok);
void HandlePragmaComment(Token &CommentTok); void HandlePragmaComment(Token &CommentTok);
void HandleComment(SourceRange Comment); // Return true and store the first token only if any CommentHandler
// has inserted some tokens and getCommentRetentionState() is false.
bool HandleComment(Token &Token, SourceRange Comment);
}; };
/// \brief Abstract base class that describes a handler that will receive /// \brief Abstract base class that describes a handler that will receive
@ -893,7 +895,9 @@ class CommentHandler {
public: public:
virtual ~CommentHandler(); virtual ~CommentHandler();
virtual void HandleComment(Preprocessor &PP, SourceRange Comment) = 0; // The handler shall return true if it has pushed any tokens
// to be read using e.g. EnterToken or EnterTokenStream.
virtual bool HandleComment(Preprocessor &PP, SourceRange Comment) = 0;
}; };
} // end namespace clang } // end namespace clang

Просмотреть файл

@ -902,8 +902,10 @@ bool Lexer::SkipWhitespace(Token &Result, const char *CurPtr) {
// SkipBCPLComment - We have just read the // characters from input. Skip until // SkipBCPLComment - We have just read the // characters from input. Skip until
// we find the newline character thats terminate the comment. Then update // we find the newline character thats terminate the comment. Then update
/// BufferPtr and return. If we're in KeepCommentMode, this will form the token /// BufferPtr and return.
/// and return true. ///
/// If we're in KeepCommentMode or any CommentHandler has inserted
/// some tokens, this will store the first token and return true.
bool Lexer::SkipBCPLComment(Token &Result, const char *CurPtr) { bool Lexer::SkipBCPLComment(Token &Result, const char *CurPtr) {
// If BCPL comments aren't explicitly enabled for this language, emit an // If BCPL comments aren't explicitly enabled for this language, emit an
// extension warning. // extension warning.
@ -980,9 +982,12 @@ bool Lexer::SkipBCPLComment(Token &Result, const char *CurPtr) {
} while (C != '\n' && C != '\r'); } while (C != '\n' && C != '\r');
// Found but did not consume the newline. // Found but did not consume the newline.
if (PP) if (PP && PP->HandleComment(Result,
PP->HandleComment(SourceRange(getSourceLocation(BufferPtr), SourceRange(getSourceLocation(BufferPtr),
getSourceLocation(CurPtr))); getSourceLocation(CurPtr)))) {
BufferPtr = CurPtr;
return true; // A token has to be returned.
}
// If we are returning comments as tokens, return this comment as a token. // If we are returning comments as tokens, return this comment as a token.
if (inKeepCommentMode()) if (inKeepCommentMode())
@ -1108,8 +1113,8 @@ static bool isEndOfBlockCommentWithEscapedNewLine(const char *CurPtr,
/// happen is the comment could end with an escaped newline between the */ end /// happen is the comment could end with an escaped newline between the */ end
/// of comment. /// of comment.
/// ///
/// If KeepCommentMode is enabled, this forms a token from the comment and /// If we're in KeepCommentMode or any CommentHandler has inserted
/// returns true. /// some tokens, this will store the first token and return true.
bool Lexer::SkipBlockComment(Token &Result, const char *CurPtr) { bool Lexer::SkipBlockComment(Token &Result, const char *CurPtr) {
// Scan one character past where we should, looking for a '/' character. Once // Scan one character past where we should, looking for a '/' character. Once
// we find it, check to see if it was preceeded by a *. This common // we find it, check to see if it was preceeded by a *. This common
@ -1226,9 +1231,12 @@ bool Lexer::SkipBlockComment(Token &Result, const char *CurPtr) {
C = *CurPtr++; C = *CurPtr++;
} }
if (PP) if (PP && PP->HandleComment(Result,
PP->HandleComment(SourceRange(getSourceLocation(BufferPtr), SourceRange(getSourceLocation(BufferPtr),
getSourceLocation(CurPtr))); getSourceLocation(CurPtr)))) {
BufferPtr = CurPtr;
return true; // A token has to be returned.
}
// If we are returning comments as tokens, return this comment as a token. // If we are returning comments as tokens, return this comment as a token.
if (inKeepCommentMode()) { if (inKeepCommentMode()) {
@ -1606,10 +1614,12 @@ LexNextToken:
// too (without going through the big switch stmt). // too (without going through the big switch stmt).
if (CurPtr[0] == '/' && CurPtr[1] == '/' && !inKeepCommentMode() && if (CurPtr[0] == '/' && CurPtr[1] == '/' && !inKeepCommentMode() &&
Features.BCPLComment) { Features.BCPLComment) {
SkipBCPLComment(Result, CurPtr+2); if (SkipBCPLComment(Result, CurPtr+2))
return; // There is a token to return.
goto SkipIgnoredUnits; goto SkipIgnoredUnits;
} else if (CurPtr[0] == '/' && CurPtr[1] == '*' && !inKeepCommentMode()) { } else if (CurPtr[0] == '/' && CurPtr[1] == '*' && !inKeepCommentMode()) {
SkipBlockComment(Result, CurPtr+2); if (SkipBlockComment(Result, CurPtr+2))
return; // There is a token to return.
goto SkipIgnoredUnits; goto SkipIgnoredUnits;
} else if (isHorizontalWhitespace(*CurPtr)) { } else if (isHorizontalWhitespace(*CurPtr)) {
goto SkipHorizontalWhitespace; goto SkipHorizontalWhitespace;
@ -1795,7 +1805,7 @@ LexNextToken:
if (Features.BCPLComment || if (Features.BCPLComment ||
getCharAndSize(CurPtr+SizeTmp, SizeTmp2) != '*') { getCharAndSize(CurPtr+SizeTmp, SizeTmp2) != '*') {
if (SkipBCPLComment(Result, ConsumeChar(CurPtr, SizeTmp, Result))) if (SkipBCPLComment(Result, ConsumeChar(CurPtr, SizeTmp, Result)))
return; // KeepCommentMode return; // There is a token to return.
// It is common for the tokens immediately after a // comment to be // It is common for the tokens immediately after a // comment to be
// whitespace (indentation for the next line). Instead of going through // whitespace (indentation for the next line). Instead of going through
@ -1806,7 +1816,7 @@ LexNextToken:
if (Char == '*') { // /**/ comment. if (Char == '*') { // /**/ comment.
if (SkipBlockComment(Result, ConsumeChar(CurPtr, SizeTmp, Result))) if (SkipBlockComment(Result, ConsumeChar(CurPtr, SizeTmp, Result)))
return; // KeepCommentMode return; // There is a token to return.
goto LexNextToken; // GCC isn't tail call eliminating. goto LexNextToken; // GCC isn't tail call eliminating.
} }

Просмотреть файл

@ -583,11 +583,18 @@ void Preprocessor::RemoveCommentHandler(CommentHandler *Handler) {
CommentHandlers.erase(Pos); CommentHandlers.erase(Pos);
} }
void Preprocessor::HandleComment(SourceRange Comment) { bool Preprocessor::HandleComment(Token &result, SourceRange Comment) {
bool AnyPendingTokens = false;
for (std::vector<CommentHandler *>::iterator H = CommentHandlers.begin(), for (std::vector<CommentHandler *>::iterator H = CommentHandlers.begin(),
HEnd = CommentHandlers.end(); HEnd = CommentHandlers.end();
H != HEnd; ++H) H != HEnd; ++H) {
(*H)->HandleComment(*this, Comment); if ((*H)->HandleComment(*this, Comment))
AnyPendingTokens = true;
}
if (!AnyPendingTokens || getCommentRetentionState())
return false;
Lex(result);
return true;
} }
CommentHandler::~CommentHandler() { } CommentHandler::~CommentHandler() { }

Просмотреть файл

@ -29,8 +29,9 @@ class ActionCommentHandler : public CommentHandler {
public: public:
explicit ActionCommentHandler(Action &Actions) : Actions(Actions) { } explicit ActionCommentHandler(Action &Actions) : Actions(Actions) { }
virtual void HandleComment(Preprocessor &PP, SourceRange Comment) { virtual bool HandleComment(Preprocessor &PP, SourceRange Comment) {
Actions.ActOnComment(Comment); Actions.ActOnComment(Comment);
return false;
} }
}; };