]> granicus.if.org Git - clang/commitdiff
Fix whitespace handling in empty macro expansions
authorJustin Bogner <mail@justinbogner.com>
Tue, 4 Feb 2014 19:18:35 +0000 (19:18 +0000)
committerJustin Bogner <mail@justinbogner.com>
Tue, 4 Feb 2014 19:18:35 +0000 (19:18 +0000)
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!

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@200787 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Lex/TokenLexer.cpp
test/Preprocessor/macro_space.c

index 2f29f7c9c8cd57ff62f4be8658fa7ba6edb4d6b7..307e781cae8a7d2d5683d9fce8d2f218377899df 100644 (file)
@@ -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);
   }
+  AtStartOfLine = false;
+  HasLeadingSpace = false;
 
   // Handle recursive expansion!
   if (!Tok.isAnnotation() && Tok.getIdentifierInfo() != 0) {
index 8a47a3b08f688561f7325238a5b275e9110d8843..13e531fff1511237ab5aa9323a1b45414c503587 100644 (file)
@@ -1,6 +1,36 @@
 // RUN: %clang_cc1 -E %s | FileCheck --strict-whitespace %s
 
-#define XX
-! XX,
+#define FOO1()
+#define FOO2(x)x
+#define FOO3(x) x
+#define FOO4(x)x x
+#define FOO5(x) x x
+#define FOO6(x) [x]
+#define FOO7(x) [ x]
+#define FOO8(x) [x ]
 
-// CHECK: {{^}}! ,{{$}}
+#define TEST(FOO,x) FOO <FOO()> < FOO()> <FOO ()> <FOO( )> <FOO() > <FOO()x> <FOO() x> < FOO()x>
+
+TEST(FOO1,)
+// CHECK: FOO1 <> < > <> <> < > <> < > < >
+
+TEST(FOO2,)
+// CHECK: FOO2 <> < > <> <> < > <> < > < >
+
+TEST(FOO3,)
+// CHECK: FOO3 <> < > <> <> < > <> < > < >
+
+TEST(FOO4,)
+// CHECK: FOO4 < > < > < > < > < > < > < > < >
+
+TEST(FOO5,)
+// CHECK: FOO5 < > < > < > < > < > < > < > < >
+
+TEST(FOO6,)
+// CHECK: FOO6 <[]> < []> <[]> <[]> <[] > <[]> <[] > < []>
+
+TEST(FOO7,)
+// CHECK: FOO7 <[ ]> < [ ]> <[ ]> <[ ]> <[ ] > <[ ]> <[ ] > < [ ]>
+
+TEST(FOO8,)
+// CHECK: FOO8 <[ ]> < [ ]> <[ ]> <[ ]> <[ ] > <[ ]> <[ ] > < [ ]>