1 /*============================================================================= 2 Boost.Wave: A Standard compliant C++ preprocessor library 3 http://www.boost.org/ 4 5 Copyright (c) 2020 Jeff Trull. Distributed under the Boost 6 Software License, Version 1.0. (See accompanying file 7 LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 8 =============================================================================*/ 9 10 //O --c++20 11 //O -Werror 12 13 // __VA_OPT__ examples from the proposal doc P00306 14 // Those examples have a few weird typos. I've tried to match the 15 // behavior of gcc in the expected results - JET 16 17 #define LOG(msg, ...) printf(msg __VA_OPT__(,) __VA_ARGS__) 18 #define SDEF(sname, ...) S sname __VA_OPT__(= { __VA_ARGS__ }) 19 #define LOG2(...) \ 20 printf("at line=%d" __VA_OPT__(": "), __LINE__); \ 21 __VA_OPT__(printf(__VA_ARGS__);) \ 22 printf("\n") 23 24 //R #line 28 "t_8_001.cpp" 25 //R printf("hello world\n" ); 26 //R printf("hello world\n" ); 27 //R printf("hello %d\n" , n); 28 LOG("hello world\n"); 29 LOG("hello world\n", ); 30 LOG("hello %d\n", n); 31 32 //R #line 35 "t_8_001.cpp" 33 //R S foo; 34 //R S bar = { 1, 2, 3 }; 35 SDEF(foo); 36 SDEF(bar, 1, 2, 3); 37 38 //R #line 43 "t_8_001.cpp" 39 //R printf("at line=%d" , 43); printf("\n"); 40 // P00306 example suggests the adjacent string literals are concatenated in 41 // this test case but that's the *compiler's* job: 42 //R printf("at line=%d" ": ", 44); printf("All well in zone %d", n); printf("\n"); 43 LOG2(); 44 LOG2("All well in zone %d", n); 45 46 //H 10: t_8_001.cpp(17): #define 47 //H 08: t_8_001.cpp(17): LOG(msg, ...)=printf(msg __VA_OPT__(,) __VA_ARGS__) 48 //H 10: t_8_001.cpp(18): #define 49 //H 08: t_8_001.cpp(18): SDEF(sname, ...)=S sname __VA_OPT__(= { __VA_ARGS__ }) 50 //H 10: t_8_001.cpp(19): #define 51 //H 08: t_8_001.cpp(19): LOG2(...)=printf("at line=%d" __VA_OPT__(": "), __LINE__); __VA_OPT__(printf(__VA_ARGS__);) printf("\n") 52 //H 00: t_8_001.cpp(28): LOG("hello world\n"), [t_8_001.cpp(17): LOG(msg, ...)=printf(msg __VA_OPT__(,) __VA_ARGS__)] 53 //H 00: t_8_001.cpp(17): __VA_OPT__(,), [<built-in>(1): __VA_OPT__(...)=] 54 // no variadic args supplied, placemarker produced: 55 //H 02: � 56 //H 02: printf("hello world\n" � ) 57 //H 03: printf("hello world\n" ) 58 //H 00: t_8_001.cpp(29): LOG("hello world\n", �), [t_8_001.cpp(17): LOG(msg, ...)=printf(msg __VA_OPT__(,) __VA_ARGS__)] 59 //H 00: t_8_001.cpp(17): __VA_OPT__(,), [<built-in>(1): __VA_OPT__(...)=] 60 // a variadic arg, but it contains a placemarker 61 // it's a kind of third case - no visible tokens, but not exclusively "whitespace" 62 //H 02: 63 //H 02: printf("hello world\n" ) 64 //H 03: printf("hello world\n" ) 65 //H 00: t_8_001.cpp(30): LOG("hello %d\n", n), [t_8_001.cpp(17): LOG(msg, ...)=printf(msg __VA_OPT__(,) __VA_ARGS__)] 66 //H 00: t_8_001.cpp(17): __VA_OPT__(,), [<built-in>(1): __VA_OPT__(...)=] 67 // a single token for variadic args: 68 //H 02: , 69 //H 02: printf("hello %d\n" , n) 70 //H 03: printf("hello %d\n" , n) 71 //H 00: t_8_001.cpp(35): SDEF(foo), [t_8_001.cpp(18): SDEF(sname, ...)=S sname __VA_OPT__(= { __VA_ARGS__ })] 72 //H 00: t_8_001.cpp(18): __VA_OPT__(= { __VA_ARGS__ }), [<built-in>(1): __VA_OPT__(...)=] 73 // no varargs, emit placeholder: 74 //H 02: � 75 //H 02: S foo � 76 //H 03: S foo 77 //H 00: t_8_001.cpp(36): SDEF(bar, 1, 2, 3), [t_8_001.cpp(18): SDEF(sname, ...)=S sname __VA_OPT__(= { __VA_ARGS__ })] 78 //H 00: t_8_001.cpp(18): __VA_OPT__(= { __VA_ARGS__ }), [<built-in>(1): __VA_OPT__(...)=] 79 //H 02: = { 1, 2, 3 } 80 //H 02: S bar = { 1, 2, 3 } 81 //H 03: S bar = { 1, 2, 3 } 82 //H 00: t_8_001.cpp(43): LOG2(�), [t_8_001.cpp(19): LOG2(...)=printf("at line=%d" __VA_OPT__(": "), __LINE__); __VA_OPT__(printf(__VA_ARGS__);) printf("\n")] 83 //H 00: t_8_001.cpp(20): __VA_OPT__(": "), [<built-in>(1): __VA_OPT__(...)=] 84 //H 02: 85 //H 00: t_8_001.cpp(21): __VA_OPT__(printf(__VA_ARGS__);), [<built-in>(1): __VA_OPT__(...)=] 86 //H 02: 87 //H 02: printf("at line=%d" , __LINE__); printf("\n") 88 //H 01: <built-in>(1): __LINE__ 89 //H 02: 43 90 //H 03: 43 91 //H 03: printf("at line=%d" , 43); printf("\n") 92 //H 00: t_8_001.cpp(44): LOG2("All well in zone %d", n), [t_8_001.cpp(19): LOG2(...)=printf("at line=%d" __VA_OPT__(": "), __LINE__); __VA_OPT__(printf(__VA_ARGS__);) printf("\n")] 93 //H 00: t_8_001.cpp(20): __VA_OPT__(": "), [<built-in>(1): __VA_OPT__(...)=] 94 //H 02: ": " 95 //H 00: t_8_001.cpp(21): __VA_OPT__(printf(__VA_ARGS__);), [<built-in>(1): __VA_OPT__(...)=] 96 //H 02: printf("All well in zone %d", n); 97 //H 02: printf("at line=%d" ": ", __LINE__); printf("All well in zone %d", n); printf("\n") 98 //H 01: <built-in>(1): __LINE__ 99 //H 02: 44 100 //H 03: 44 101 //H 03: printf("at line=%d" ": ", 44); printf("All well in zone %d", n); printf("\n") 102