r200787 - Fix whitespace handling in empty macro expansions
Harald van Dijk
harald at gigawatt.nl
Tue Feb 4 14:33:50 PST 2014
On 04/02/14 22:48, Justin Bogner wrote:
> Richard Smith <richard at metafoo.co.uk> writes:
>> On Tue, Feb 4, 2014 at 11:18 AM, Justin Bogner <mail at justinbogner.com> wrote:
>> Fix whitespace handling in empty macro expansions
>>
>> When a macro expansion does not result in any tokens, and the macro name
>> is preceded by whitespace, the whitespace should be passed to the first
>> token that follows the macro expansion. Similarly when a macro expansion
>> ends with a placemarker token, and that placemarker token is preceded by
>> whitespace. This worked already for top-level macro expansions, but is
>> now extended to also work for nested macro expansions.
>>
>> Patch by Harald van Dijk!
>>
>> Modified:
>> cfe/trunk/lib/Lex/TokenLexer.cpp
>> cfe/trunk/test/Preprocessor/macro_space.c
>>
>> Modified: cfe/trunk/lib/Lex/TokenLexer.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/TokenLexer.cpp?
>> rev=200787&r1=200786&r2=200787&view=diff
>> ==========================================================================
>> ====
>> --- cfe/trunk/lib/Lex/TokenLexer.cpp (original)
>> +++ cfe/trunk/lib/Lex/TokenLexer.cpp Tue Feb 4 13:18:35 2014
>> @@ -477,9 +477,13 @@ bool TokenLexer::Lex(Token &Tok) {
>> if (isFirstToken) {
>> Tok.setFlagValue(Token::StartOfLine , AtStartOfLine);
>> Tok.setFlagValue(Token::LeadingSpace, HasLeadingSpace);
>> - AtStartOfLine = false;
>> - HasLeadingSpace = false;
>> + } else {
>> + // If this is not the first token, we may still need to pass through
>> + // leading whitespace if we've expanded a macro.
>> + if (HasLeadingSpace) Tok.setFlag(Token::LeadingSpace);
>>
>> Do we need to do this for AtStartOfLine too? What happens if we have a macro
>> at the start of a line that expands to no tokens, within a TokenLexer? (I
>> guess this can't happen within a macro expansion, since no tokens there are
>> ever at the start of a line after line-splicing, but we use TokenLexers in
>> other cases too).
>
> CCing Harald.
>
> Handling AtStartOfLine as well does sound pretty reasonable to me, but
> it's difficult to come up with a case where this actually applies.
> Without a concrete example, I don't have a good way to judge this.
It can happen even in a macro expansion:
#define foo() bar() .
#define bar()
foo()
The question is whether the resulting . should be treated as at the
start of the line. I was initially unable to come up with a test case
where it mattered, but am able to come up with one now, because error
handling is different depending on whether certain tokens start on the
next line:
int a, int b; // expected-error {{expected identifier or '('}}
// expected-error at -1 {{expected ';' after top level declarator}}
int c, // expected-error {{expected ';' at end of declaration}}
int d;
#define foo() bar() int f;
#define bar()
int e, // expected-error {{expected ';' at end of declaration}}
foo()
This fails, should pass, and setting Token::StartOfLine is indeed enough
to make it pass, like so:
diff --git a/lib/Lex/TokenLexer.cpp b/lib/Lex/TokenLexer.cpp
index 9913f30..543ca92 100644
--- a/lib/Lex/TokenLexer.cpp
+++ b/lib/Lex/TokenLexer.cpp
@@ -474,6 +474,7 @@ bool TokenLexer::Lex(Token &Tok) {
} else {
// If this is not the first token, we may still need to pass through
// leading whitespace if we've expanded a macro.
+ if (AtStartOfLine) Tok.setFlag(Token::StartOfLine);
if (HasLeadingSpace) Tok.setFlag(Token::LeadingSpace);
}
AtStartOfLine = false;
I am not happy with my test case, though. Is there an easier way to
verify that this works as intended?
Cheers,
Harald van Dijk
More information about the cfe-commits
mailing list