lsym_lparen_or_lbracket.c revision 1.19 1 /* $NetBSD: lsym_lparen_or_lbracket.c,v 1.19 2023/06/17 22:09:24 rillig Exp $ */
2
3 /*
4 * Tests for the token lsym_lparen_or_lbracket, which represents a '(' or '['
5 * in these contexts:
6 *
7 * In a type name, '(' constructs a function type.
8 *
9 * In an expression, '(' starts an inner expression to override the usual
10 * operator precedence.
11 *
12 * In a function call expression, '(' marks the beginning of the function
13 * arguments.
14 *
15 * In a 'sizeof' expression, '(' is required if the argument is a type name.
16 *
17 * In an expression, '(' followed by a type name starts a cast expression or
18 * a compound literal.
19 *
20 * In a type declaration, '(' marks the beginning of the function parameters.
21 *
22 * After one of the keywords 'for', 'if', 'switch' or 'while', the controlling
23 * expression must be enclosed in '(' and ')'; see lsym_for.c, lsym_if.c,
24 * lsym_switch.c, lsym_while.c.
25 *
26 * In a declaration, '[' derives an array type.
27 *
28 * In an expression, '[' starts an array subscript.
29 */
30
31 /* The '(' in a type name derives a function type. */
32 //indent input
33 typedef void signal_handler(int);
34 void (*signal(void (*)(int)))(int);
35 //indent end
36
37 //indent run
38 typedef void signal_handler(int);
39 void (*signal(void (*)(int)))(int);
40 //indent end
41
42
43 //indent input
44 #define macro(arg) ((arg) + 1)
45 //indent end
46
47 //indent run-equals-input -di0
48
49
50 /*
51 * The '(' in an expression overrides operator precedence. In multi-line
52 * expressions, the continuation lines are aligned on the parentheses.
53 */
54 //indent input
55 int nested = (
56 (
57 (
58 (
59 1 + 4
60 )
61 )
62 )
63 );
64 //indent end
65
66 //indent run
67 int nested = (
68 (
69 (
70 (
71 1 + 4
72 )
73 )
74 )
75 );
76 //indent end
77
78
79 /* The '(' in a function call expression starts the argument list. */
80 //indent input
81 int var = macro_call ( arg1, arg2 ,arg3);
82 //indent end
83
84 //indent run
85 int var = macro_call(arg1, arg2, arg3);
86 //indent end
87
88
89 /*
90 * The '(' in a sizeof expression is required for type names and optional for
91 * expressions.
92 */
93 //indent input
94 size_t sizeof_typename = sizeof ( int );
95 size_t sizeof_expr = sizeof ( 12345 ) ;
96 //indent end
97
98 //indent run
99 size_t sizeof_typename = sizeof(int);
100 size_t sizeof_expr = sizeof(12345);
101 //indent end
102
103
104 /* The '[' in a type name derives an array type. */
105 //indent input
106 int array_of_numbers[100];
107 //indent end
108
109 //indent run
110 int array_of_numbers[100];
111 //indent end
112
113
114 /* The '[' in an expression accesses an array element. */
115 //indent input
116 int second_prime = &primes[1];
117 //indent end
118
119 //indent run
120 int second_prime = &primes[1];
121 //indent end
122
123
124 //indent input
125 void
126 function(void)
127 {
128 /* Type casts */
129 a = (int)b;
130 a = (struct tag)b;
131 /* TODO: The '(int)' is not a type cast, it is a prototype list. */
132 a = (int (*)(int))fn;
133
134 /* Not type casts */
135 a = sizeof(int) * 2;
136 a = sizeof(5) * 2;
137 a = offsetof(struct stat, st_mtime);
138
139 /* Grouping subexpressions */
140 a = ((((b + c)))) * d;
141 }
142 //indent end
143
144 //indent run-equals-input
145
146
147 //indent input
148 int zero = (((((((((((((((((((0)))))))))))))))))));
149 int many = ((((((((((((((((((((((((((((((((0))))))))))))))))))))))))))))))));
150 //indent end
151
152 //indent run-equals-input -di0
153
154
155 //indent input
156 void (*action)(void);
157 //indent end
158
159 //indent run-equals-input -di0
160
161
162 //indent input
163 void
164 function(void)
165 {
166 other_function();
167 other_function("first", 2, "last argument"[4]);
168
169 if (false)(void)x;
170 if (false)(func)(arg);
171 if (false)(cond)?123:456;
172
173 /* C99 compound literal */
174 origin = (struct point){0,0};
175
176 /* GCC statement expression */
177 /* expr = ({if(expr)debug();expr;}); */
178 /* $ XXX: Generates 'error: Standard Input:36: Unbalanced parentheses'. */
179 }
180 //indent end
181
182 //indent run
183 void
184 function(void)
185 {
186 other_function();
187 other_function("first", 2, "last argument"[4]);
188
189 if (false)
190 (void)x;
191 if (false)
192 (func)(arg);
193 if (false)
194 (cond) ? 123 : 456;
195
196 /* C99 compound literal */
197 origin = (struct point){0, 0};
198
199 /* GCC statement expression */
200 /* expr = ({if(expr)debug();expr;}); */
201 }
202 //indent end
203
204
205 /*
206 * Test a few variants of C99 compound expressions, as the '{' and '}' must not
207 * be treated as block delimiters.
208 */
209 //indent input
210 {
211 return (struct point){0, 0};
212 return (struct point){
213 0, 0
214 };
215 return (struct point){.x = 0, .y = 0};
216 return (struct point){
217 .x = 0,
218 .y = 0,
219 };
220 }
221 //indent end
222
223 //indent run-equals-input
224
225
226 /*
227 * C99 designator initializers are the rare situation where there is a space
228 * before a '['.
229 */
230 //indent input
231 int array[] = {
232 1, 2, [2] = 3, [3] = 4,
233 };
234 //indent end
235
236 //indent run-equals-input -di0
237
238
239 /*
240 * Test want_blank_before_lparen for all possible token types.
241 */
242 //indent input
243 void cover_want_blank_before_lparen(void)
244 {
245 /* ps.prev_lsym can never be 'newline'. */
246 int newline =
247 (3);
248
249 int lparen_or_lbracket = a[(3)];
250 int rparen_or_rbracket = a[3](5);
251 +(unary_op);
252 3 + (binary_op);
253 a++(postfix_op); /* unlikely to be seen in practice */
254 cond ? (question) : (5);
255 switch (expr) {
256 case (case_label):;
257 }
258 a ? 3 : (colon);
259 (semicolon) = 3;
260 int lbrace[] = {(3)};
261 int rbrace_in_decl = {{3}(4)}; /* syntax error */
262 {}
263 (rbrace_in_stmt)();
264 ident(3);
265 int(decl);
266 a++, (comma)();
267 int comment = /* comment */ (3); /* comment is skipped */
268 switch (expr) {}
269 #define preprocessing
270 (preprocessing)();
271 (lsym_form_feed)();
273 for(;;);
274 do(lsym_do)=3;while(0);
275 if(cond);else(lsym_else)();
276 do(lsym_do);while(0);
277 str.(member); /* syntax error */
278 L("string_prefix"); /* impossible */
279 static (int)storage_class; /* syntax error */
280 funcname(3);
281 typedef (type_def) new_type;
282 // $ TODO: is keyword_struct_union_enum possible?
283 struct (keyword_struct_union_enum); /* syntax error */
284 }
285 //indent end
286
287 //indent run -ldi0
288 void
289 cover_want_blank_before_lparen(void)
290 {
291 /* ps.prev_lsym can never be 'newline'. */
292 int newline =
293 (3);
294
295 int lparen_or_lbracket = a[(3)];
296 int rparen_or_rbracket = a[3](5);
297 +(unary_op);
298 3 + (binary_op);
299 a++(postfix_op); /* unlikely to be seen in practice */
300 cond ? (question) : (5);
301 switch (expr) {
302 case (case_label): ;
303 }
304 a ? 3 : (colon);
305 (semicolon) = 3;
306 int lbrace[] = {(3)};
307 int rbrace_in_decl = {{3} (4)}; /* syntax error */
308 {
309 }
310 (rbrace_in_stmt)();
311 ident(3);
312 int (decl);
313 a++, (comma)();
314 int comment = /* comment */ (3); /* comment is skipped */
315 switch (expr) {
316 }
317 #define preprocessing
318 (preprocessing)();
319 (lsym_form_feed)();
321 for (;;);
322 do
323 (lsym_do) = 3;
324 while (0);
325 if (cond);
326 else
327 (lsym_else)();
328 do
329 (lsym_do);
330 while (0);
331 str.(member); /* syntax error */
332 L("string_prefix"); /* impossible */
333 static (int)storage_class; /* syntax error */
334 funcname(3);
335 typedef (type_def) new_type;
336 struct (keyword_struct_union_enum); /* syntax error */
337 }
338 //indent end
339
340 /* See t_errors.sh, test case 'compound_literal'. */
341
342
343 /*
344 * Ensure that a designated initializer after a comma is not indented further
345 * than necessary, as in most other contexts, there is no space before a '['.
346 */
347 //indent input
348 int arr[] = {
349 ['0'] = 1,
350 ['1'] = 2,
351 };
352 //indent end
353
354 //indent run -di0
355 int arr[] = {
356 ['0'] = 1,
357 ['1'] = 2,
358 };
359 //indent end
360
361
362 /* In an initializer, a '(' does not start a function definition. */
363 //indent input
364 {
365 type var = {
366 .CONCAT(a, b)
367 = init,
368 };
369 }
370
371 //indent end
372
373 //indent run
374 {
375 type var = {
376 .CONCAT(a, b)
377 = init,
378 };
379 }
380 //indent end
381