Introduce a callback to PPCallbacks for lines skipped by the preprocessor.

Patch by Jason Haslam!

llvm-svn: 140612
This commit is contained in:
Argyrios Kyrtzidis 2011-09-27 17:32:05 +00:00
parent e241bad92b
commit 18bcfd5595
3 changed files with 23 additions and 4 deletions

View File

@ -158,6 +158,12 @@ public:
/// MI is released immediately following this callback. /// MI is released immediately following this callback.
virtual void MacroUndefined(const Token &MacroNameTok, const MacroInfo *MI) { virtual void MacroUndefined(const Token &MacroNameTok, const MacroInfo *MI) {
} }
/// SourceRangeSkipped - This hook is called when a source range is skipped.
/// \param Range The SourceRange that was skipped. The range begins at the
/// #if/#else directive and ends after the #endif/#else directive.
virtual void SourceRangeSkipped(SourceRange Range) {
}
/// If -- This hook is called whenever an #if is seen. /// If -- This hook is called whenever an #if is seen.
/// \param Range The SourceRange of the expression being tested. /// \param Range The SourceRange of the expression being tested.
@ -286,6 +292,11 @@ public:
Second->MacroUndefined(MacroNameTok, MI); Second->MacroUndefined(MacroNameTok, MI);
} }
virtual void SourceRangeSkipped(SourceRange Range) {
First->SourceRangeSkipped(Range);
Second->SourceRangeSkipped(Range);
}
/// If -- This hook is called whenever an #if is seen. /// If -- This hook is called whenever an #if is seen.
virtual void If(SourceRange Range) { virtual void If(SourceRange Range) {
First->If(Range); First->If(Range);

View File

@ -1057,7 +1057,8 @@ private:
/// already seen one so a #else directive is a duplicate. When this returns, /// already seen one so a #else directive is a duplicate. When this returns,
/// the caller can lex the first valid token. /// the caller can lex the first valid token.
void SkipExcludedConditionalBlock(SourceLocation IfTokenLoc, void SkipExcludedConditionalBlock(SourceLocation IfTokenLoc,
bool FoundNonSkipPortion, bool FoundElse); bool FoundNonSkipPortion, bool FoundElse,
SourceLocation ElseLoc = SourceLocation());
/// PTHSkipExcludedConditionalBlock - A fast PTH version of /// PTHSkipExcludedConditionalBlock - A fast PTH version of
/// SkipExcludedConditionalBlock. /// SkipExcludedConditionalBlock.

View File

@ -193,7 +193,8 @@ void Preprocessor::CheckEndOfDirective(const char *DirType, bool EnableMacros) {
/// the first valid token. /// the first valid token.
void Preprocessor::SkipExcludedConditionalBlock(SourceLocation IfTokenLoc, void Preprocessor::SkipExcludedConditionalBlock(SourceLocation IfTokenLoc,
bool FoundNonSkipPortion, bool FoundNonSkipPortion,
bool FoundElse) { bool FoundElse,
SourceLocation ElseLoc) {
++NumSkipped; ++NumSkipped;
assert(CurTokenLexer == 0 && CurPPLexer && "Lexing a macro, not a file?"); assert(CurTokenLexer == 0 && CurPPLexer && "Lexing a macro, not a file?");
@ -389,6 +390,11 @@ void Preprocessor::SkipExcludedConditionalBlock(SourceLocation IfTokenLoc,
// of the file, just stop skipping and return to lexing whatever came after // of the file, just stop skipping and return to lexing whatever came after
// the #if block. // the #if block.
CurPPLexer->LexingRawMode = false; CurPPLexer->LexingRawMode = false;
if (Callbacks) {
SourceLocation BeginLoc = ElseLoc.isValid() ? ElseLoc : IfTokenLoc;
Callbacks->SourceRangeSkipped(SourceRange(BeginLoc, Tok.getLocation()));
}
} }
void Preprocessor::PTHSkipExcludedConditionalBlock() { void Preprocessor::PTHSkipExcludedConditionalBlock() {
@ -1817,7 +1823,7 @@ void Preprocessor::HandleElseDirective(Token &Result) {
// Finally, skip the rest of the contents of this block. // Finally, skip the rest of the contents of this block.
SkipExcludedConditionalBlock(CI.IfLoc, /*Foundnonskip*/true, SkipExcludedConditionalBlock(CI.IfLoc, /*Foundnonskip*/true,
/*FoundElse*/true); /*FoundElse*/true, Result.getLocation());
if (Callbacks) if (Callbacks)
Callbacks->Else(); Callbacks->Else();
@ -1850,7 +1856,8 @@ void Preprocessor::HandleElifDirective(Token &ElifToken) {
// Finally, skip the rest of the contents of this block. // Finally, skip the rest of the contents of this block.
SkipExcludedConditionalBlock(CI.IfLoc, /*Foundnonskip*/true, SkipExcludedConditionalBlock(CI.IfLoc, /*Foundnonskip*/true,
/*FoundElse*/CI.FoundElse); /*FoundElse*/CI.FoundElse,
ElifToken.getLocation());
if (Callbacks) if (Callbacks)
Callbacks->Elif(SourceRange(ConditionalBegin, ConditionalEnd)); Callbacks->Elif(SourceRange(ConditionalBegin, ConditionalEnd));