diff options
Diffstat (limited to 'clang')
-rw-r--r-- | clang/lib/Lex/TokenLexer.cpp | 29 | ||||
-rw-r--r-- | clang/test/Preprocessor/macro_paste_commaext.c | 4 | ||||
-rw-r--r-- | clang/test/Preprocessor/macro_paste_spacing.c | 16 |
3 files changed, 33 insertions, 16 deletions
diff --git a/clang/lib/Lex/TokenLexer.cpp b/clang/lib/Lex/TokenLexer.cpp index 7d80cdc2f13..d41af3f41a9 100644 --- a/clang/lib/Lex/TokenLexer.cpp +++ b/clang/lib/Lex/TokenLexer.cpp @@ -223,6 +223,13 @@ void TokenLexer::ExpandFunctionArguments() { continue; } + // Find out if there is a paste (##) operator before or after the token. + bool NonEmptyPasteBefore = + !ResultToks.empty() && ResultToks.back().is(tok::hashhash); + bool PasteBefore = i != 0 && Tokens[i-1].is(tok::hashhash); + bool PasteAfter = i+1 != e && Tokens[i+1].is(tok::hashhash); + assert(!NonEmptyPasteBefore || PasteBefore); + // Otherwise, if this is not an argument token, just add the token to the // output buffer. IdentifierInfo *II = CurTok.getIdentifierInfo(); @@ -234,7 +241,9 @@ void TokenLexer::ExpandFunctionArguments() { if (NextTokGetsSpace) { ResultToks.back().setFlag(Token::LeadingSpace); NextTokGetsSpace = false; - } + } else if (PasteBefore && !NonEmptyPasteBefore) + ResultToks.back().clearFlag(Token::LeadingSpace); + continue; } @@ -242,13 +251,7 @@ void TokenLexer::ExpandFunctionArguments() { // input. MadeChange = true; - // Otherwise, this is a use of the argument. Find out if there is a paste - // (##) operator before or after the argument. - bool NonEmptyPasteBefore = - !ResultToks.empty() && ResultToks.back().is(tok::hashhash); - bool PasteBefore = i != 0 && Tokens[i-1].is(tok::hashhash); - bool PasteAfter = i+1 != e && Tokens[i+1].is(tok::hashhash); - assert(!NonEmptyPasteBefore || PasteBefore); + // Otherwise, this is a use of the argument. // In Microsoft mode, remove the comma before __VA_ARGS__ to ensure there // are no trailing commas if __VA_ARGS__ is empty. @@ -358,8 +361,8 @@ void TokenLexer::ExpandFunctionArguments() { // assembler-with-cpp mode, invalid pastes are allowed through: in this // case, we do not want the extra whitespace to be added. For example, // we want ". ## foo" -> ".foo" not ". foo". - if ((CurTok.hasLeadingSpace() || NextTokGetsSpace) && - !NonEmptyPasteBefore) + if ((CurTok.hasLeadingSpace() && !PasteBefore) || + (NextTokGetsSpace && !NonEmptyPasteBefore)) ResultToks[ResultToks.size()-NumToks].setFlag(Token::LeadingSpace); NextTokGetsSpace = false; @@ -370,11 +373,11 @@ void TokenLexer::ExpandFunctionArguments() { // 6.10.3.3p2,3) calls for a bunch of placemarker stuff to occur. We // implement this by eating ## operators when a LHS or RHS expands to // empty. - NextTokGetsSpace |= CurTok.hasLeadingSpace(); + if (!PasteBefore) + NextTokGetsSpace |= i != 0 && CurTok.hasLeadingSpace(); if (PasteAfter) { // Discard the argument token and skip (don't copy to the expansion // buffer) the paste operator after it. - NextTokGetsSpace |= Tokens[i+1].hasLeadingSpace(); ++i; continue; } @@ -385,7 +388,7 @@ void TokenLexer::ExpandFunctionArguments() { assert(PasteBefore); if (NonEmptyPasteBefore) { assert(ResultToks.back().is(tok::hashhash)); - NextTokGetsSpace |= ResultToks.pop_back_val().hasLeadingSpace(); + ResultToks.pop_back(); } // If this is the __VA_ARGS__ token, and if the argument wasn't provided, diff --git a/clang/test/Preprocessor/macro_paste_commaext.c b/clang/test/Preprocessor/macro_paste_commaext.c index 7cfe43d077b..fdb8f982a92 100644 --- a/clang/test/Preprocessor/macro_paste_commaext.c +++ b/clang/test/Preprocessor/macro_paste_commaext.c @@ -1,8 +1,8 @@ // RUN: %clang_cc1 %s -E | grep 'V);' // RUN: %clang_cc1 %s -E | grep 'W, 1, 2);' // RUN: %clang_cc1 %s -E | grep 'X, 1, 2);' -// RUN: %clang_cc1 %s -E | grep 'Y, );' -// RUN: %clang_cc1 %s -E | grep 'Z, );' +// RUN: %clang_cc1 %s -E | grep 'Y,);' +// RUN: %clang_cc1 %s -E | grep 'Z,);' #define debug(format, ...) format, ## __VA_ARGS__) debug(V); diff --git a/clang/test/Preprocessor/macro_paste_spacing.c b/clang/test/Preprocessor/macro_paste_spacing.c index 6498ffc9814..481d457e66a 100644 --- a/clang/test/Preprocessor/macro_paste_spacing.c +++ b/clang/test/Preprocessor/macro_paste_spacing.c @@ -1,7 +1,21 @@ -// RUN: %clang_cc1 %s -E | grep "^xy$" +// RUN: %clang_cc1 -E %s | FileCheck --strict-whitespace %s #define A x ## y blah A +// CHECK: {{^}}xy{{$}} +#define B(x, y) [v ## w] [ v##w] [v##w ] [w ## x] [ w##x] [w##x ] [x ## y] [ x##y] [x##y ] [y ## z] [ y##z] [y##z ] +B(x,y) +// CHECK: [vw] [ vw] [vw ] [wx] [ wx] [wx ] [xy] [ xy] [xy ] [yz] [ yz] [yz ] +B(x,) +// CHECK: [vw] [ vw] [vw ] [wx] [ wx] [wx ] [x] [ x] [x ] [z] [ z] [z ] +B(,y) +// CHECK: [vw] [ vw] [vw ] [w] [ w] [w ] [y] [ y] [y ] [yz] [ yz] [yz ] +B(,) +// CHECK: [vw] [ vw] [vw ] [w] [ w] [w ] [] [ ] [ ] [z] [ z] [z ] + +#define C(x, y, z) [x ## y ## z] +C(,,) C(a,,) C(,b,) C(,,c) C(a,b,) C(a,,c) C(,b,c) C(a,b,c) +// CHECK: [] [a] [b] [c] [ab] [ac] [bc] [abc] |