1 /* $NetBSD: lsym_lparen_or_lbracket.c,v 1.20 2025/01/03 23:37:18 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)(); 272 for(;;); 273 do(lsym_do)=3;while(0); 274 if(cond);else(lsym_else)(); 275 do(lsym_do);while(0); 276 str.(member); /* syntax error */ 277 L("string_prefix"); /* impossible */ 278 static (int)storage_class; /* syntax error */ 279 funcname(3); 280 typedef (type_def) new_type; 281 // $ TODO: is keyword_struct_union_enum possible? 282 struct (keyword_struct_union_enum); /* syntax error */ 283 } 284 //indent end 285 286 //indent run -ldi0 287 void 288 cover_want_blank_before_lparen(void) 289 { 290 /* ps.prev_lsym can never be 'newline'. */ 291 int newline = 292 (3); 293 294 int lparen_or_lbracket = a[(3)]; 295 int rparen_or_rbracket = a[3](5); 296 +(unary_op); 297 3 + (binary_op); 298 a++(postfix_op); /* unlikely to be seen in practice */ 299 cond ? (question) : (5); 300 switch (expr) { 301 case (case_label): ; 302 } 303 a ? 3 : (colon); 304 (semicolon) = 3; 305 int lbrace[] = {(3)}; 306 int rbrace_in_decl = {{3} (4)}; /* syntax error */ 307 { 308 } 309 (rbrace_in_stmt)(); 310 ident(3); 311 int (decl); 312 a++, (comma)(); 313 int comment = /* comment */ (3); /* comment is skipped */ 314 switch (expr) { 315 } 316 #define preprocessing 317 (preprocessing)(); 318 (lsym_form_feed)(); 319 for (;;) 320 ; 321 do 322 (lsym_do) = 3; 323 while (0); 324 if (cond) 325 ; 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