1 // RUN: %clang_cc1 -std=c23 -E %s | FileCheck %s 2 3 /* WG14 N3033: Clang 12 4 * Comma ommission and deletion (__VA_OPT__) 5 */ 6 7 #define F(...) f(0 __VA_OPT__(,) __VA_ARGS__) 8 #define G(X, ...) f(0, X __VA_OPT__(,) __VA_ARGS__) 9 #define SDEF(sname, ...) S sname __VA_OPT__(= { __VA_ARGS__ }) 10 #define EMP 11 12 F(a, b, c) // replaced by f(0, a, b, c) 13 // CHECK: f(0 , a, b, c) 14 F() // replaced by f(0) 15 // CHECK: f(0 ) 16 F(EMP) // replaced by f(0) 17 // CHECK: f(0 ) 18 19 G(a, b, c) // replaced by f(0, a, b, c) 20 // CHECK: f(0, a , b, c) 21 G(a, ) // replaced by f(0, a) 22 // CHECK: f(0, a ) 23 G(a) // replaced by f(0, a) 24 // CHECK: f(0, a ) 25 26 SDEF(foo); // replaced by S foo; 27 // CHECK: S foo ; 28 SDEF(bar, 1, 2); // replaced by S bar = { 1, 2 }; 29 // CHECK: S bar = { 1, 2 }; 30 31 //#define H1(X, ...) X __VA_OPT__(##) __VA_ARGS__ // error: ## may not appear at the beginning of a replacement list (6.10.3.3) 32 33 #define H2(X, Y, ...) __VA_OPT__(X ## Y,) __VA_ARGS__ 34 H2(a, b, c, d) // replaced by ab, c, d 35 // CHECK: ab, c, d 36 37 #define H3(X, ...) #__VA_OPT__(X##X X##X) 38 H3(, 0) // replaced by "" 39 // CHECK: "" 40 41 #define H4(X, ...) __VA_OPT__(a X ## X) ## b 42 H4(, 1) // replaced by a b 43 // CHECK: a b 44 45 #define H5A(...) __VA_OPT__()/**/__VA_OPT__() 46 #define H5B(X) a ## X ## b 47 #define H5C(X) H5B(X) 48 H5C(H5A()) // replaced by ab 49 // CHECK: ab 50 51