xref: /netbsd-src/usr.bin/xlint/lint1/cgram.y (revision 1580a27b92f58fcdcb23fdfbc04a7c2b54a0b7c8)
1 %{
2 /* $NetBSD: cgram.y,v 1.94 2017/03/06 21:01:39 christos Exp $ */
3 
4 /*
5  * Copyright (c) 1996 Christopher G. Demetriou.  All Rights Reserved.
6  * Copyright (c) 1994, 1995 Jochen Pohl
7  * All Rights Reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. All advertising materials mentioning features or use of this software
18  *    must display the following acknowledgement:
19  *      This product includes software developed by Jochen Pohl for
20  *	The NetBSD Project.
21  * 4. The name of the author may not be used to endorse or promote products
22  *    derived from this software without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
25  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
28  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 #include <sys/cdefs.h>
37 #if defined(__RCSID) && !defined(lint)
38 __RCSID("$NetBSD: cgram.y,v 1.94 2017/03/06 21:01:39 christos Exp $");
39 #endif
40 
41 #include <stdlib.h>
42 #include <string.h>
43 #include <limits.h>
44 
45 #include "lint1.h"
46 
47 extern char *yytext;
48 /*
49  * Contains the level of current declaration. 0 is extern.
50  * Used for symbol table entries.
51  */
52 int	blklev;
53 
54 /*
55  * level for memory allocation. Normaly the same as blklev.
56  * An exception is the declaration of arguments in prototypes. Memory
57  * for these can't be freed after the declaration, but symbols must
58  * be removed from the symbol table after the declaration.
59  */
60 int	mblklev;
61 
62 /*
63  * Save the no-warns state and restore it to avoid the problem where
64  * if (expr) { stmt } / * NOLINT * / stmt;
65  */
66 static int olwarn = LWARN_BAD;
67 
68 static	int	toicon(tnode_t *, int);
69 static	void	idecl(sym_t *, int, sbuf_t *);
70 static	void	ignuptorp(void);
71 static	sym_t	*symbolrename(sym_t *, sbuf_t *);
72 
73 
74 #ifdef DEBUG
75 static inline void CLRWFLGS(const char *file, size_t line);
76 static inline void CLRWFLGS(const char *file, size_t line)
77 {
78 	printf("%s, %d: clear flags %s %zu\n", curr_pos.p_file,
79 	    curr_pos.p_line, file, line);
80 	clrwflgs();
81 	olwarn = LWARN_BAD;
82 }
83 
84 static inline void SAVE(const char *file, size_t line);
85 static inline void SAVE(const char *file, size_t line)
86 {
87 	if (olwarn != LWARN_BAD)
88 		abort();
89 	printf("%s, %d: save flags %s %zu = %d\n", curr_pos.p_file,
90 	    curr_pos.p_line, file, line, lwarn);
91 	olwarn = lwarn;
92 }
93 
94 static inline void RESTORE(const char *file, size_t line);
95 static inline void RESTORE(const char *file, size_t line)
96 {
97 	if (olwarn != LWARN_BAD) {
98 		lwarn = olwarn;
99 		printf("%s, %d: restore flags %s %zu = %d\n", curr_pos.p_file,
100 		    curr_pos.p_line, file, line, lwarn);
101 		olwarn = LWARN_BAD;
102 	} else
103 		CLRWFLGS(file, line);
104 }
105 #else
106 #define CLRWFLGS(f, l) clrwflgs(), olwarn = LWARN_BAD
107 #define SAVE(f, l)	olwarn = lwarn
108 #define RESTORE(f, l) (void)(olwarn == LWARN_BAD ? (clrwflgs(), 0) : (lwarn = olwarn))
109 #endif
110 
111 /* unbind the anonymous struct members from the struct */
112 static void
113 anonymize(sym_t *s)
114 {
115 	for ( ; s; s = s->s_nxt)
116 		s->s_styp = NULL;
117 }
118 %}
119 
120 %expect 107
121 
122 %union {
123 	int	y_int;
124 	val_t	*y_val;
125 	sbuf_t	*y_sb;
126 	sym_t	*y_sym;
127 	op_t	y_op;
128 	scl_t	y_scl;
129 	tspec_t	y_tspec;
130 	tqual_t	y_tqual;
131 	type_t	*y_type;
132 	tnode_t	*y_tnode;
133 	range_t	y_range;
134 	strg_t	*y_strg;
135 	pqinf_t	*y_pqinf;
136 };
137 
138 %token			T_LBRACE T_RBRACE T_LBRACK T_RBRACK T_LPARN T_RPARN
139 %token	<y_op>		T_STROP
140 %token	<y_op>		T_UNOP
141 %token	<y_op>		T_INCDEC
142 %token			T_SIZEOF
143 %token			T_BUILTIN_OFFSETOF
144 %token			T_TYPEOF
145 %token			T_EXTENSION
146 %token			T_ALIGNOF
147 %token	<y_op>		T_MULT
148 %token	<y_op>		T_DIVOP
149 %token	<y_op>		T_ADDOP
150 %token	<y_op>		T_SHFTOP
151 %token	<y_op>		T_RELOP
152 %token	<y_op>		T_EQOP
153 %token	<y_op>		T_AND
154 %token	<y_op>		T_XOR
155 %token	<y_op>		T_OR
156 %token	<y_op>		T_LOGAND
157 %token	<y_op>		T_LOGOR
158 %token			T_QUEST
159 %token			T_COLON
160 %token	<y_op>		T_ASSIGN
161 %token	<y_op>		T_OPASS
162 %token			T_COMMA
163 %token			T_SEMI
164 %token			T_ELLIPSE
165 %token			T_REAL
166 %token			T_IMAG
167 %token			T_GENERIC
168 
169 /* storage classes (extern, static, auto, register and typedef) */
170 %token	<y_scl>		T_SCLASS
171 
172 /* types (char, int, short, long, unsigned, signed, float, double, void) */
173 %token	<y_tspec>	T_TYPE
174 
175 /* qualifiers (const, volatile) */
176 %token	<y_tqual>	T_QUAL
177 
178 /* struct or union */
179 %token	<y_tspec>	T_SOU
180 
181 /* enum */
182 %token			T_ENUM
183 
184 /* remaining keywords */
185 %token			T_CASE
186 %token			T_DEFAULT
187 %token			T_IF
188 %token			T_ELSE
189 %token			T_SWITCH
190 %token			T_DO
191 %token			T_WHILE
192 %token			T_FOR
193 %token			T_GOTO
194 %token			T_CONTINUE
195 %token			T_BREAK
196 %token			T_RETURN
197 %token			T_ASM
198 %token			T_SYMBOLRENAME
199 %token			T_PACKED
200 /* Type Attributes */
201 %token <y_type>		T_ATTRIBUTE
202 %token <y_type>		T_AT_ALIAS
203 %token <y_type>		T_AT_ALIGNED
204 %token <y_type>		T_AT_ALWAYS_INLINE
205 %token <y_type>		T_AT_BOUNDED
206 %token <y_type>		T_AT_BUFFER
207 %token <y_type>		T_AT_COLD
208 %token <y_type>		T_AT_CONSTRUCTOR
209 %token <y_type>		T_AT_DEPRECATED
210 %token <y_type>		T_AT_FORMAT
211 %token <y_type>		T_AT_FORMAT_ARG
212 %token <y_type>		T_AT_FORMAT_PRINTF
213 %token <y_type>		T_AT_FORMAT_SCANF
214 %token <y_type>		T_AT_FORMAT_STRFMON
215 %token <y_type>		T_AT_FORMAT_STRFTIME
216 %token <y_type>		T_AT_GNU_INLINE
217 %token <y_type>		T_AT_MAY_ALIAS
218 %token <y_type>		T_AT_MINBYTES
219 %token <y_type>		T_AT_MODE
220 %token <y_type>		T_AT_NONNULL
221 %token <y_type>		T_AT_NORETURN
222 %token <y_type>		T_AT_NO_INSTRUMENT_FUNCTION
223 %token <y_type>		T_AT_PACKED
224 %token <y_type>		T_AT_PCS
225 %token <y_type>		T_AT_PURE
226 %token <y_type>		T_AT_RETURNS_TWICE
227 %token <y_type>		T_AT_SECTION
228 %token <y_type>		T_AT_SENTINEL
229 %token <y_type>		T_AT_STRING
230 %token <y_type>		T_AT_TUNION
231 %token <y_type>		T_AT_UNUSED
232 %token <y_type>		T_AT_USED
233 %token <y_type>		T_AT_VISIBILITY
234 %token <y_type>		T_AT_WEAK
235 
236 %left	T_COMMA
237 %right	T_ASSIGN T_OPASS
238 %right	T_QUEST T_COLON
239 %left	T_LOGOR
240 %left	T_LOGAND
241 %left	T_OR
242 %left	T_XOR
243 %left	T_AND
244 %left	T_EQOP
245 %left	T_RELOP
246 %left	T_SHFTOP
247 %left	T_ADDOP
248 %left	T_MULT T_DIVOP
249 %right	T_UNOP T_INCDEC T_SIZEOF TBUILTIN_SIZEOF T_ALIGNOF T_REAL T_IMAG
250 %left	T_LPARN T_LBRACK T_STROP
251 
252 %token	<y_sb>		T_NAME
253 %token	<y_sb>		T_TYPENAME
254 %token	<y_val>		T_CON
255 %token	<y_strg>	T_STRING
256 
257 %type	<y_sym>		func_decl
258 %type	<y_sym>		notype_decl
259 %type	<y_sym>		type_decl
260 %type	<y_type>	typespec
261 %type	<y_type>	clrtyp_typespec
262 %type	<y_type>	notype_typespec
263 %type	<y_type>	struct_spec
264 %type	<y_type>	enum_spec
265 %type	<y_type>	type_attribute
266 %type	<y_sym>		struct_tag
267 %type	<y_sym>		enum_tag
268 %type	<y_tspec>	struct
269 %type	<y_sym>		struct_declaration
270 %type	<y_sb>		identifier
271 %type	<y_sym>		member_declaration_list_with_rbrace
272 %type	<y_sym>		member_declaration_list
273 %type	<y_sym>		member_declaration
274 %type	<y_sym>		notype_member_decls
275 %type	<y_sym>		type_member_decls
276 %type	<y_sym>		notype_member_decl
277 %type	<y_sym>		type_member_decl
278 %type	<y_tnode>	constant
279 %type	<y_sym>		enum_declaration
280 %type	<y_sym>		enums_with_opt_comma
281 %type	<y_sym>		enums
282 %type	<y_sym>		enumerator
283 %type	<y_sym>		ename
284 %type	<y_sym>		notype_direct_decl
285 %type	<y_sym>		type_direct_decl
286 %type	<y_pqinf>	pointer
287 %type	<y_pqinf>	asterisk
288 %type	<y_sym>		param_decl
289 %type	<y_sym>		param_list
290 %type	<y_sym>		abs_decl_param_list
291 %type	<y_sym>		direct_param_decl
292 %type	<y_sym>		notype_param_decl
293 %type	<y_sym>		direct_notype_param_decl
294 %type	<y_pqinf>	type_qualifier_list
295 %type	<y_pqinf>	type_qualifier
296 %type	<y_sym>		identifier_list
297 %type	<y_sym>		abs_decl
298 %type	<y_sym>		direct_abs_decl
299 %type	<y_sym>		vararg_parameter_type_list
300 %type	<y_sym>		parameter_type_list
301 %type	<y_sym>		parameter_declaration
302 %type	<y_tnode>	expr
303 %type	<y_tnode>	expr_stmnt_val
304 %type	<y_tnode>	expr_stmnt_list
305 %type	<y_tnode>	term
306 %type	<y_tnode>	generic_expr
307 %type	<y_tnode>	func_arg_list
308 %type	<y_op>		point_or_arrow
309 %type	<y_type>	type_name
310 %type	<y_sym>		abstract_declaration
311 %type	<y_tnode>	do_while_expr
312 %type	<y_tnode>	opt_expr
313 %type	<y_strg>	string
314 %type	<y_strg>	string2
315 %type	<y_sb>		opt_asm_or_symbolrename
316 %type	<y_range>	range
317 %type	<y_range>	lorange
318 
319 
320 %%
321 
322 program:
323 	  /* empty */ {
324 		if (sflag) {
325 			/* empty translation unit */
326 			error(272);
327 		} else if (!tflag) {
328 			/* empty translation unit */
329 			warning(272);
330 		}
331 	  }
332 	| translation_unit
333 	;
334 
335 translation_unit:
336 	  ext_decl
337 	| translation_unit ext_decl
338 	;
339 
340 ext_decl:
341 	  asm_stmnt
342 	| func_def {
343 		glclup(0);
344 		CLRWFLGS(__FILE__, __LINE__);
345 	  }
346 	| data_def {
347 		glclup(0);
348 		CLRWFLGS(__FILE__, __LINE__);
349 	  }
350 	;
351 
352 data_def:
353 	  T_SEMI {
354 		if (sflag) {
355 			/* syntax error: empty declaration */
356 			error(0);
357 		} else if (!tflag) {
358 			/* syntax error: empty declaration */
359 			warning(0);
360 		}
361 	  }
362 	| clrtyp deftyp notype_init_decls T_SEMI {
363 		if (sflag) {
364 			/* old style declaration; add "int" */
365 			error(1);
366 		} else if (!tflag) {
367 			/* old style declaration; add "int" */
368 			warning(1);
369 		}
370 	  }
371 	| declmods deftyp T_SEMI {
372 		if (dcs->d_scl == TYPEDEF) {
373 			/* typedef declares no type name */
374 			warning(72);
375 		} else {
376 			/* empty declaration */
377 			warning(2);
378 		}
379 	  }
380 	| declmods deftyp notype_init_decls T_SEMI
381 	| declspecs deftyp T_SEMI {
382 		if (dcs->d_scl == TYPEDEF) {
383 			/* typedef declares no type name */
384 			warning(72);
385 		} else if (!dcs->d_nedecl) {
386 			/* empty declaration */
387 			warning(2);
388 		}
389 	  }
390 	| declspecs deftyp type_init_decls T_SEMI
391 	| error T_SEMI {
392 		globclup();
393 	  }
394 	| error T_RBRACE {
395 		globclup();
396 	  }
397 	;
398 
399 func_def:
400 	  func_decl {
401 		if ($1->s_type->t_tspec != FUNC) {
402 			/* syntax error */
403 			error(249, yytext);
404 			YYERROR;
405 		}
406 		if ($1->s_type->t_typedef) {
407 			/* ()-less function definition */
408 			error(64);
409 			YYERROR;
410 		}
411 		funcdef($1);
412 		blklev++;
413 		pushdecl(ARG);
414 		if (lwarn == LWARN_NONE)
415 			$1->s_used = 1;
416 	  } opt_arg_declaration_list {
417 		popdecl();
418 		blklev--;
419 		cluparg();
420 		pushctrl(0);
421 	  } comp_stmnt {
422 		funcend();
423 		popctrl(0);
424 	  }
425 	;
426 
427 func_decl:
428 	  clrtyp deftyp notype_decl {
429 		$$ = $3;
430 	  }
431 	| declmods deftyp notype_decl {
432 		$$ = $3;
433 	  }
434 	| declspecs deftyp type_decl {
435 		$$ = $3;
436 	  }
437 	;
438 
439 opt_arg_declaration_list:
440 	  /* empty */
441 	| arg_declaration_list
442 	;
443 
444 arg_declaration_list:
445 	  arg_declaration
446 	| arg_declaration_list arg_declaration
447 	/* XXX or better "arg_declaration error" ? */
448 	| error
449 	;
450 
451 /*
452  * "arg_declaration" is separated from "declaration" because it
453  * needs other error handling.
454  */
455 
456 arg_declaration:
457 	  declmods deftyp T_SEMI {
458 		/* empty declaration */
459 		warning(2);
460 	  }
461 	| declmods deftyp notype_init_decls T_SEMI
462 	| declspecs deftyp T_SEMI {
463 		if (!dcs->d_nedecl) {
464 			/* empty declaration */
465 			warning(2);
466 		} else {
467 			tspec_t	ts = dcs->d_type->t_tspec;
468 			/* %s declared in argument declaration list */
469 			warning(3, ts == STRUCT ? "struct" :
470 				(ts == UNION ? "union" : "enum"));
471 		}
472 	  }
473 	| declspecs deftyp type_init_decls T_SEMI {
474 		if (dcs->d_nedecl) {
475 			tspec_t	ts = dcs->d_type->t_tspec;
476 			/* %s declared in argument declaration list */
477 			warning(3, ts == STRUCT ? "struct" :
478 				(ts == UNION ? "union" : "enum"));
479 		}
480 	  }
481 	| declmods error
482 	| declspecs error
483 	;
484 
485 declaration:
486 	  declmods deftyp T_SEMI {
487 		if (dcs->d_scl == TYPEDEF) {
488 			/* typedef declares no type name */
489 			warning(72);
490 		} else {
491 			/* empty declaration */
492 			warning(2);
493 		}
494 	  }
495 	| declmods deftyp notype_init_decls T_SEMI
496 	| declspecs deftyp T_SEMI {
497 		if (dcs->d_scl == TYPEDEF) {
498 			/* typedef declares no type name */
499 			warning(72);
500 		} else if (!dcs->d_nedecl) {
501 			/* empty declaration */
502 			warning(2);
503 		}
504 	  }
505 	| declspecs deftyp type_init_decls T_SEMI
506 	| error T_SEMI
507 	;
508 
509 type_attribute_format_type:
510 	  T_AT_FORMAT_PRINTF
511 	| T_AT_FORMAT_SCANF
512 	| T_AT_FORMAT_STRFMON
513 	| T_AT_FORMAT_STRFTIME
514 	;
515 
516 type_attribute_bounded_type:
517 	  T_AT_MINBYTES
518 	| T_AT_STRING
519 	| T_AT_BUFFER
520 	;
521 
522 type_attribute_spec:
523 	  /* empty */
524 	| T_AT_DEPRECATED
525 	| T_AT_ALIGNED T_LPARN constant T_RPARN
526 	| T_AT_BOUNDED T_LPARN type_attribute_bounded_type
527 	  T_COMMA constant T_COMMA constant T_RPARN
528 	| T_AT_SENTINEL T_LPARN constant T_RPARN
529 	| T_AT_FORMAT_ARG T_LPARN constant T_RPARN
530 	| T_AT_NONNULL T_LPARN constant T_RPARN
531 	| T_AT_MODE T_LPARN T_NAME T_RPARN
532 	| T_AT_ALIAS T_LPARN string T_RPARN
533 	| T_AT_PCS T_LPARN string T_RPARN
534 	| T_AT_SECTION T_LPARN string T_RPARN
535 	| T_AT_ALIGNED
536 	| T_AT_CONSTRUCTOR
537 	| T_AT_MAY_ALIAS
538 	| T_AT_NO_INSTRUMENT_FUNCTION
539 	| T_AT_NORETURN
540 	| T_AT_COLD
541 	| T_AT_RETURNS_TWICE
542 	| T_AT_PACKED {
543 		addpacked();
544 	}
545 	| T_AT_PURE
546 	| T_AT_TUNION
547 	| T_AT_GNU_INLINE
548 	| T_AT_ALWAYS_INLINE
549 	| T_AT_FORMAT T_LPARN type_attribute_format_type T_COMMA
550 	    constant T_COMMA constant T_RPARN
551 	| T_AT_USED {
552 		addused();
553 	}
554 	| T_AT_UNUSED {
555 		addused();
556 	}
557 	| T_AT_WEAK
558 	| T_AT_VISIBILITY T_LPARN constant T_RPARN
559 	| T_QUAL {
560 		if ($1 != CONST)
561 			yyerror("Bad attribute");
562 	}
563 	;
564 
565 type_attribute_spec_list:
566 	  type_attribute_spec
567 	| type_attribute_spec_list T_COMMA type_attribute_spec
568 	;
569 
570 type_attribute:
571 	  T_ATTRIBUTE T_LPARN T_LPARN {
572 	    attron = 1;
573 	} type_attribute_spec_list {
574 	    attron = 0;
575 	} T_RPARN T_RPARN
576 	| T_PACKED {
577 		addpacked();
578 	}
579 	;
580 
581 type_attribute_list:
582 	  type_attribute
583 	| type_attribute_list type_attribute
584 	;
585 
586 clrtyp:
587 	  {
588 		clrtyp();
589 	  }
590 	;
591 
592 deftyp:
593 	  /* empty */ {
594 		deftyp();
595 	  }
596 	;
597 
598 declspecs:
599 	  clrtyp_typespec {
600 		addtype($1);
601 	  }
602 	| declmods typespec {
603 		addtype($2);
604 	  }
605 	| type_attribute declspecs
606 	| declspecs declmod
607 	| declspecs notype_typespec {
608 		addtype($2);
609 	  }
610 	;
611 
612 declmods:
613 	  clrtyp T_QUAL {
614 		addqual($2);
615 	  }
616 	| clrtyp T_SCLASS {
617 		addscl($2);
618 	  }
619 	| declmods declmod
620 	;
621 
622 declmod:
623 	  T_QUAL {
624 		addqual($1);
625 	  }
626 	| T_SCLASS {
627 		addscl($1);
628 	  }
629 	| type_attribute_list
630 	;
631 
632 clrtyp_typespec:
633 	  clrtyp notype_typespec {
634 		$$ = $2;
635 	  }
636 	| T_TYPENAME clrtyp {
637 		$$ = getsym($1)->s_type;
638 	  }
639 	;
640 
641 typespec:
642 	  notype_typespec {
643 		$$ = $1;
644 	  }
645 	| T_TYPENAME {
646 		$$ = getsym($1)->s_type;
647 	  }
648 	;
649 
650 notype_typespec:
651 	  T_TYPE {
652 		$$ = gettyp($1);
653 	  }
654 	| T_TYPEOF term {
655 		$$ = $2->tn_type;
656 	  }
657 	| struct_spec {
658 		popdecl();
659 		$$ = $1;
660 	  }
661 	| enum_spec {
662 		popdecl();
663 		$$ = $1;
664 	  }
665 	;
666 
667 struct_spec:
668 	  struct struct_tag {
669 		/*
670 		 * STDC requires that "struct a;" always introduces
671 		 * a new tag if "a" is not declared at current level
672 		 *
673 		 * yychar is valid because otherwise the parser would
674 		 * not been able to decide if he must shift or reduce
675 		 */
676 		$$ = mktag($2, $1, 0, yychar == T_SEMI);
677 	  }
678 	| struct struct_tag {
679 		dcs->d_tagtyp = mktag($2, $1, 1, 0);
680 	  } struct_declaration {
681 		$$ = compltag(dcs->d_tagtyp, $4);
682 	  }
683 	| struct {
684 		dcs->d_tagtyp = mktag(NULL, $1, 1, 0);
685 	  } struct_declaration {
686 		$$ = compltag(dcs->d_tagtyp, $3);
687 	  }
688 	| struct error {
689 		symtyp = FVFT;
690 		$$ = gettyp(INT);
691 	  }
692 	;
693 
694 struct:
695 	  struct type_attribute
696 	| T_SOU {
697 		symtyp = FTAG;
698 		pushdecl($1 == STRUCT ? MOS : MOU);
699 		dcs->d_offset = 0;
700 		dcs->d_stralign = CHAR_BIT;
701 		$$ = $1;
702 	  }
703 	;
704 
705 struct_tag:
706 	  identifier {
707 		$$ = getsym($1);
708 	  }
709 	;
710 
711 struct_declaration:
712 	  struct_decl_lbrace member_declaration_list_with_rbrace {
713 		$$ = $2;
714 	  }
715 	;
716 
717 struct_decl_lbrace:
718 	  T_LBRACE {
719 		symtyp = FVFT;
720 	  }
721 	;
722 
723 member_declaration_list_with_rbrace:
724 	  member_declaration_list T_SEMI T_RBRACE {
725 		$$ = $1;
726 	  }
727 	| member_declaration_list T_RBRACE {
728 		if (sflag) {
729 			/* syntax req. ";" after last struct/union member */
730 			error(66);
731 		} else {
732 			/* syntax req. ";" after last struct/union member */
733 			warning(66);
734 		}
735 		$$ = $1;
736 	  }
737 	| T_RBRACE {
738 		$$ = NULL;
739 	  }
740 	;
741 
742 opt_type_attribute:
743 	  /* empty */
744 	| type_attribute
745 	;
746 
747 member_declaration_list:
748 	  member_declaration {
749 		$$ = $1;
750 	  }
751 	| member_declaration_list T_SEMI member_declaration {
752 		$$ = lnklst($1, $3);
753 	  }
754 	;
755 
756 member_declaration:
757 	  noclass_declmods deftyp {
758 		/* too late, i know, but getsym() compensates it */
759 		symtyp = FMOS;
760 	  } notype_member_decls opt_type_attribute {
761 		symtyp = FVFT;
762 		$$ = $4;
763 	  }
764 	| noclass_declspecs deftyp {
765 		symtyp = FMOS;
766 	  } type_member_decls opt_type_attribute {
767 		symtyp = FVFT;
768 		$$ = $4;
769 	  }
770 	| noclass_declmods deftyp opt_type_attribute {
771 		symtyp = FVFT;
772 		/* struct or union member must be named */
773 		if (!Sflag)
774 			warning(49);
775 		/* add all the members of the anonymous struct/union */
776 		$$ = dcs->d_type->t_str->memb;
777 		anonymize($$);
778 	  }
779 	| noclass_declspecs deftyp opt_type_attribute {
780 		symtyp = FVFT;
781 		/* struct or union member must be named */
782 		if (!Sflag)
783 			warning(49);
784 		$$ = dcs->d_type->t_str->memb;
785 		/* add all the members of the anonymous struct/union */
786 		anonymize($$);
787 	  }
788 	| error {
789 		symtyp = FVFT;
790 		$$ = NULL;
791 	  }
792 	;
793 
794 noclass_declspecs:
795 	  clrtyp_typespec {
796 		addtype($1);
797 	  }
798 	| type_attribute noclass_declspecs
799 	| noclass_declmods typespec {
800 		addtype($2);
801 	  }
802 	| noclass_declspecs T_QUAL {
803 		addqual($2);
804 	  }
805 	| noclass_declspecs notype_typespec {
806 		addtype($2);
807 	  }
808 	| noclass_declspecs type_attribute
809 	;
810 
811 noclass_declmods:
812 	  clrtyp T_QUAL {
813 		addqual($2);
814 	  }
815 	| noclass_declmods T_QUAL {
816 		addqual($2);
817 	  }
818 	;
819 
820 notype_member_decls:
821 	  notype_member_decl {
822 		$$ = decl1str($1);
823 	  }
824 	| notype_member_decls {
825 		symtyp = FMOS;
826 	  } T_COMMA type_member_decl {
827 		$$ = lnklst($1, decl1str($4));
828 	  }
829 	;
830 
831 type_member_decls:
832 	  type_member_decl {
833 		$$ = decl1str($1);
834 	  }
835 	| type_member_decls {
836 		symtyp = FMOS;
837 	  } T_COMMA type_member_decl {
838 		$$ = lnklst($1, decl1str($4));
839 	  }
840 	;
841 
842 notype_member_decl:
843 	  notype_decl {
844 		$$ = $1;
845 	  }
846 	| notype_decl T_COLON constant {
847 		$$ = bitfield($1, toicon($3, 1));
848 	  }
849 	| {
850 		symtyp = FVFT;
851 	  } T_COLON constant {
852 		$$ = bitfield(NULL, toicon($3, 1));
853 	  }
854 	;
855 
856 type_member_decl:
857 	  type_decl {
858 		$$ = $1;
859 	  }
860 	| type_decl T_COLON constant {
861 		$$ = bitfield($1, toicon($3, 1));
862 	  }
863 	| {
864 		symtyp = FVFT;
865 	  } T_COLON constant {
866 		$$ = bitfield(NULL, toicon($3, 1));
867 	  }
868 	;
869 
870 enum_spec:
871 	  enum enum_tag {
872 		$$ = mktag($2, ENUM, 0, 0);
873 	  }
874 	| enum enum_tag {
875 		dcs->d_tagtyp = mktag($2, ENUM, 1, 0);
876 	  } enum_declaration {
877 		$$ = compltag(dcs->d_tagtyp, $4);
878 	  }
879 	| enum {
880 		dcs->d_tagtyp = mktag(NULL, ENUM, 1, 0);
881 	  } enum_declaration {
882 		$$ = compltag(dcs->d_tagtyp, $3);
883 	  }
884 	| enum error {
885 		symtyp = FVFT;
886 		$$ = gettyp(INT);
887 	  }
888 	;
889 
890 enum:
891 	  T_ENUM {
892 		symtyp = FTAG;
893 		pushdecl(ENUMCON);
894 	  }
895 	;
896 
897 enum_tag:
898 	  identifier {
899 		$$ = getsym($1);
900 	  }
901 	;
902 
903 enum_declaration:
904 	  enum_decl_lbrace enums_with_opt_comma T_RBRACE {
905 		$$ = $2;
906 	  }
907 	;
908 
909 enum_decl_lbrace:
910 	  T_LBRACE {
911 		symtyp = FVFT;
912 		enumval = 0;
913 	  }
914 	;
915 
916 enums_with_opt_comma:
917 	  enums {
918 		$$ = $1;
919 	  }
920 	| enums T_COMMA {
921 		if (sflag) {
922 			/* trailing "," prohibited in enum declaration */
923 			error(54);
924 		} else {
925 			/* trailing "," prohibited in enum declaration */
926 			c99ism(54);
927 		}
928 		$$ = $1;
929 	  }
930 	;
931 
932 enums:
933 	  enumerator {
934 		$$ = $1;
935 	  }
936 	| enums T_COMMA enumerator {
937 		$$ = lnklst($1, $3);
938 	  }
939 	| error {
940 		$$ = NULL;
941 	  }
942 	;
943 
944 enumerator:
945 	  ename {
946 		$$ = ename($1, enumval, 1);
947 	  }
948 	| ename T_ASSIGN constant {
949 		$$ = ename($1, toicon($3, 1), 0);
950 	  }
951 	;
952 
953 ename:
954 	  identifier {
955 		$$ = getsym($1);
956 	  }
957 	;
958 
959 
960 notype_init_decls:
961 	  notype_init_decl
962 	| notype_init_decls T_COMMA type_init_decl
963 	;
964 
965 type_init_decls:
966 	  type_init_decl
967 	| type_init_decls T_COMMA type_init_decl
968 	;
969 
970 notype_init_decl:
971 	notype_decl opt_asm_or_symbolrename {
972 		idecl($1, 0, $2);
973 		chksz($1);
974 	  }
975 	| notype_decl opt_asm_or_symbolrename {
976 		idecl($1, 1, $2);
977 	  } T_ASSIGN initializer {
978 		chksz($1);
979 	  }
980 	;
981 
982 type_init_decl:
983 	type_decl opt_asm_or_symbolrename {
984 		idecl($1, 0, $2);
985 		chksz($1);
986 	  }
987 	| type_decl opt_asm_or_symbolrename {
988 		idecl($1, 1, $2);
989 	  } T_ASSIGN initializer {
990 		chksz($1);
991 	  }
992 	;
993 
994 notype_decl:
995 	  notype_direct_decl {
996 		$$ = $1;
997 	  }
998 	| pointer notype_direct_decl {
999 		$$ = addptr($2, $1);
1000 	  }
1001 	;
1002 
1003 notype_direct_decl:
1004 	  T_NAME {
1005 		$$ = dname(getsym($1));
1006 	  }
1007 	| T_LPARN type_decl T_RPARN {
1008 		$$ = $2;
1009 	  }
1010 	| type_attribute notype_direct_decl {
1011 		$$ = $2;
1012 	}
1013 	| notype_direct_decl T_LBRACK T_RBRACK {
1014 		$$ = addarray($1, 0, 0);
1015 	  }
1016 	| notype_direct_decl T_LBRACK constant T_RBRACK {
1017 		$$ = addarray($1, 1, toicon($3, 0));
1018 	  }
1019 	| notype_direct_decl param_list opt_asm_or_symbolrename {
1020 		$$ = addfunc(symbolrename($1, $3), $2);
1021 		popdecl();
1022 		blklev--;
1023 	  }
1024 	| notype_direct_decl type_attribute_list
1025 	;
1026 
1027 type_decl:
1028 	  type_direct_decl {
1029 		$$ = $1;
1030 	  }
1031 	| pointer type_direct_decl {
1032 		$$ = addptr($2, $1);
1033 	  }
1034 	;
1035 
1036 type_direct_decl:
1037 	  identifier {
1038 		$$ = dname(getsym($1));
1039 	  }
1040 	| T_LPARN type_decl T_RPARN {
1041 		$$ = $2;
1042 	  }
1043 	| type_attribute type_direct_decl {
1044 		$$ = $2;
1045 	}
1046 	| type_direct_decl T_LBRACK T_RBRACK {
1047 		$$ = addarray($1, 0, 0);
1048 	  }
1049 	| type_direct_decl T_LBRACK constant T_RBRACK {
1050 		$$ = addarray($1, 1, toicon($3, 0));
1051 	  }
1052 	| type_direct_decl param_list opt_asm_or_symbolrename {
1053 		$$ = addfunc(symbolrename($1, $3), $2);
1054 		popdecl();
1055 		blklev--;
1056 	  }
1057 	| type_direct_decl type_attribute_list
1058 	;
1059 
1060 /*
1061  * param_decl and notype_param_decl exist to avoid a conflict in
1062  * argument lists. A typename enclosed in parens should always be
1063  * treated as a typename, not an argument.
1064  * "typedef int a; f(int (a));" is  "typedef int a; f(int foo(a));"
1065  *				not "typedef int a; f(int a);"
1066  */
1067 param_decl:
1068 	  direct_param_decl {
1069 		$$ = $1;
1070 	  }
1071 	| pointer direct_param_decl {
1072 		$$ = addptr($2, $1);
1073 	  }
1074 	;
1075 
1076 direct_param_decl:
1077 	  identifier type_attribute_list {
1078 		$$ = dname(getsym($1));
1079 	  }
1080 	| identifier {
1081 		$$ = dname(getsym($1));
1082 	  }
1083 	| T_LPARN notype_param_decl T_RPARN {
1084 		$$ = $2;
1085 	  }
1086 	| direct_param_decl T_LBRACK T_RBRACK {
1087 		$$ = addarray($1, 0, 0);
1088 	  }
1089 	| direct_param_decl T_LBRACK constant T_RBRACK {
1090 		$$ = addarray($1, 1, toicon($3, 0));
1091 	  }
1092 	| direct_param_decl param_list opt_asm_or_symbolrename {
1093 		$$ = addfunc(symbolrename($1, $3), $2);
1094 		popdecl();
1095 		blklev--;
1096 	  }
1097 	;
1098 
1099 notype_param_decl:
1100 	  direct_notype_param_decl {
1101 		$$ = $1;
1102 	  }
1103 	| pointer direct_notype_param_decl {
1104 		$$ = addptr($2, $1);
1105 	  }
1106 	;
1107 
1108 direct_notype_param_decl:
1109 	  identifier {
1110 		$$ = dname(getsym($1));
1111 	  }
1112 	| T_LPARN notype_param_decl T_RPARN {
1113 		$$ = $2;
1114 	  }
1115 	| direct_notype_param_decl T_LBRACK T_RBRACK {
1116 		$$ = addarray($1, 0, 0);
1117 	  }
1118 	| direct_notype_param_decl T_LBRACK constant T_RBRACK {
1119 		$$ = addarray($1, 1, toicon($3, 0));
1120 	  }
1121 	| direct_notype_param_decl param_list opt_asm_or_symbolrename {
1122 		$$ = addfunc(symbolrename($1, $3), $2);
1123 		popdecl();
1124 		blklev--;
1125 	  }
1126 	;
1127 
1128 pointer:
1129 	  asterisk {
1130 		$$ = $1;
1131 	  }
1132 	| asterisk type_qualifier_list {
1133 		$$ = mergepq($1, $2);
1134 	  }
1135 	| asterisk pointer {
1136 		$$ = mergepq($1, $2);
1137 	  }
1138 	| asterisk type_qualifier_list pointer {
1139 		$$ = mergepq(mergepq($1, $2), $3);
1140 	  }
1141 	;
1142 
1143 asterisk:
1144 	  T_MULT {
1145 		$$ = xcalloc(1, sizeof (pqinf_t));
1146 		$$->p_pcnt = 1;
1147 	  }
1148 	;
1149 
1150 type_qualifier_list:
1151 	  type_qualifier {
1152 		$$ = $1;
1153 	  }
1154 	| type_qualifier_list type_qualifier {
1155 		$$ = mergepq($1, $2);
1156 	  }
1157 	;
1158 
1159 type_qualifier:
1160 	  T_QUAL {
1161 		$$ = xcalloc(1, sizeof (pqinf_t));
1162 		if ($1 == CONST) {
1163 			$$->p_const = 1;
1164 		} else {
1165 			$$->p_volatile = 1;
1166 		}
1167 	  }
1168 	;
1169 
1170 param_list:
1171 	  id_list_lparn identifier_list T_RPARN {
1172 		$$ = $2;
1173 	  }
1174 	| abs_decl_param_list {
1175 		$$ = $1;
1176 	  }
1177 	;
1178 
1179 id_list_lparn:
1180 	  T_LPARN {
1181 		blklev++;
1182 		pushdecl(PARG);
1183 	  }
1184 	;
1185 
1186 identifier_list:
1187 	  T_NAME {
1188 		$$ = iname(getsym($1));
1189 	  }
1190 	| identifier_list T_COMMA T_NAME {
1191 		$$ = lnklst($1, iname(getsym($3)));
1192 	  }
1193 	| identifier_list error {
1194 		$$ = $1;
1195 	  }
1196 	;
1197 
1198 abs_decl_param_list:
1199 	  abs_decl_lparn T_RPARN {
1200 		$$ = NULL;
1201 	  }
1202 	| abs_decl_lparn vararg_parameter_type_list T_RPARN {
1203 		dcs->d_proto = 1;
1204 		$$ = $2;
1205 	  }
1206 	| abs_decl_lparn error T_RPARN {
1207 		$$ = NULL;
1208 	  }
1209 	;
1210 
1211 abs_decl_lparn:
1212 	  T_LPARN {
1213 		blklev++;
1214 		pushdecl(PARG);
1215 	  }
1216 	;
1217 
1218 vararg_parameter_type_list:
1219 	  parameter_type_list {
1220 		$$ = $1;
1221 	  }
1222 	| parameter_type_list T_COMMA T_ELLIPSE {
1223 		dcs->d_vararg = 1;
1224 		$$ = $1;
1225 	  }
1226 	| T_ELLIPSE {
1227 		if (sflag) {
1228 			/* ANSI C requires formal parameter before "..." */
1229 			error(84);
1230 		} else if (!tflag) {
1231 			/* ANSI C requires formal parameter before "..." */
1232 			warning(84);
1233 		}
1234 		dcs->d_vararg = 1;
1235 		$$ = NULL;
1236 	  }
1237 	;
1238 
1239 parameter_type_list:
1240 	  parameter_declaration {
1241 		$$ = $1;
1242 	  }
1243 	| parameter_type_list T_COMMA parameter_declaration {
1244 		$$ = lnklst($1, $3);
1245 	  }
1246 	;
1247 
1248 parameter_declaration:
1249 	  declmods deftyp {
1250 		$$ = decl1arg(aname(), 0);
1251 	  }
1252 	| declspecs deftyp {
1253 		$$ = decl1arg(aname(), 0);
1254 	  }
1255 	| declmods deftyp notype_param_decl {
1256 		$$ = decl1arg($3, 0);
1257 	  }
1258 	/*
1259 	 * param_decl is needed because of following conflict:
1260 	 * "typedef int a; f(int (a));" could be parsed as
1261 	 * "function with argument a of type int", or
1262 	 * "function with an abstract argument of type function".
1263 	 * This grammar realizes the second case.
1264 	 */
1265 	| declspecs deftyp param_decl {
1266 		$$ = decl1arg($3, 0);
1267 	  }
1268 	| declmods deftyp abs_decl {
1269 		$$ = decl1arg($3, 0);
1270 	  }
1271 	| declspecs deftyp abs_decl {
1272 		$$ = decl1arg($3, 0);
1273 	  }
1274 	;
1275 
1276 opt_asm_or_symbolrename:		/* expect only one */
1277 	  /* empty */ {
1278 		$$ = NULL;
1279 	  }
1280 	| T_ASM T_LPARN T_STRING T_RPARN {
1281 		freeyyv(&$3, T_STRING);
1282 		$$ = NULL;
1283 	  }
1284 	| T_SYMBOLRENAME T_LPARN T_NAME T_RPARN {
1285 		$$ = $3;
1286 	  }
1287 	;
1288 
1289 initializer:
1290 	  init_assign_expr
1291 	;
1292 
1293 init_assign_expr:
1294 	| init_by_name init_base_expr	%prec T_COMMA
1295 	| init_base_expr
1296 
1297 init_base_expr:
1298 	  expr				%prec T_COMMA {
1299 		mkinit($1);
1300 	  }
1301 	| init_lbrace init_rbrace
1302 	| init_lbrace init_expr_list init_rbrace
1303 	| init_lbrace init_expr_list T_COMMA init_rbrace
1304 	| error
1305 	;
1306 
1307 init_expr_list:
1308 	  init_assign_expr		%prec T_COMMA
1309 	| init_expr_list T_COMMA init_assign_expr
1310 	;
1311 
1312 lorange:
1313 	  constant T_ELLIPSE {
1314 		$$.lo = toicon($1, 1);
1315 	  }
1316 	;
1317 range:
1318 	constant {
1319 		$$.lo = toicon($1, 1);
1320 		$$.hi = $$.lo + 1;
1321 	  }
1322 	| lorange constant {
1323 		$$.lo = $1.lo;
1324 		$$.hi = toicon($2, 1);
1325 	  }
1326 	;
1327 
1328 init_field:
1329 	  T_LBRACK range T_RBRACK {
1330 		if (!Sflag)
1331 			warning(321);
1332 	  }
1333 	| point identifier {
1334 		if (!Sflag)
1335 			warning(313);
1336 		memberpush($2);
1337 	  }
1338 	;
1339 
1340 init_field_list:
1341 	  init_field
1342 	| init_field_list init_field
1343 	;
1344 
1345 init_by_name:
1346 	  init_field_list T_ASSIGN
1347 	| identifier T_COLON {
1348 		gnuism(315);
1349 		memberpush($1);
1350 	  }
1351 	;
1352 
1353 init_lbrace:
1354 	  T_LBRACE {
1355 		initlbr();
1356 	  }
1357 	;
1358 
1359 init_rbrace:
1360 	  T_RBRACE {
1361 		initrbr();
1362 	  }
1363 	;
1364 
1365 type_name:
1366   	  {
1367 		pushdecl(ABSTRACT);
1368 	  } abstract_declaration {
1369 		popdecl();
1370 		$$ = $2->s_type;
1371 	  }
1372 	;
1373 
1374 abstract_declaration:
1375 	  noclass_declmods deftyp {
1376 		$$ = decl1abs(aname());
1377 	  }
1378 	| noclass_declspecs deftyp {
1379 		$$ = decl1abs(aname());
1380 	  }
1381 	| noclass_declmods deftyp abs_decl {
1382 		$$ = decl1abs($3);
1383 	  }
1384 	| noclass_declspecs deftyp abs_decl {
1385 		$$ = decl1abs($3);
1386 	  }
1387 	;
1388 
1389 abs_decl:
1390 	  pointer {
1391 		$$ = addptr(aname(), $1);
1392 	  }
1393 	| direct_abs_decl {
1394 		$$ = $1;
1395 	  }
1396 	| pointer direct_abs_decl {
1397 		$$ = addptr($2, $1);
1398 	  }
1399 	| T_TYPEOF term {
1400 		$$ = mktempsym($2->tn_type);
1401 	  }
1402 	;
1403 
1404 direct_abs_decl:
1405 	  T_LPARN abs_decl T_RPARN {
1406 		$$ = $2;
1407 	  }
1408 	| T_LBRACK T_RBRACK {
1409 		$$ = addarray(aname(), 0, 0);
1410 	  }
1411 	| T_LBRACK constant T_RBRACK {
1412 		$$ = addarray(aname(), 1, toicon($2, 0));
1413 	  }
1414 	| type_attribute direct_abs_decl {
1415 		$$ = $2;
1416 	}
1417 	| direct_abs_decl T_LBRACK T_RBRACK {
1418 		$$ = addarray($1, 0, 0);
1419 	  }
1420 	| direct_abs_decl T_LBRACK constant T_RBRACK {
1421 		$$ = addarray($1, 1, toicon($3, 0));
1422 	  }
1423 	| abs_decl_param_list opt_asm_or_symbolrename {
1424 		$$ = addfunc(symbolrename(aname(), $2), $1);
1425 		popdecl();
1426 		blklev--;
1427 	  }
1428 	| direct_abs_decl abs_decl_param_list opt_asm_or_symbolrename {
1429 		$$ = addfunc(symbolrename($1, $3), $2);
1430 		popdecl();
1431 		blklev--;
1432 	  }
1433 	| direct_abs_decl type_attribute_list
1434 	;
1435 
1436 non_expr_stmnt:
1437 	  labeled_stmnt
1438 	| comp_stmnt
1439 	| selection_stmnt
1440 	| iteration_stmnt
1441 	| jump_stmnt {
1442 		ftflg = 0;
1443 	  }
1444 	| asm_stmnt
1445 
1446 stmnt:
1447 	  expr_stmnt
1448 	| non_expr_stmnt
1449 	;
1450 
1451 labeled_stmnt:
1452 	  label stmnt
1453 	;
1454 
1455 label:
1456 	  T_NAME T_COLON {
1457 		symtyp = FLAB;
1458 		label(T_NAME, getsym($1), NULL);
1459 	  }
1460 	| T_CASE constant T_COLON {
1461 		label(T_CASE, NULL, $2);
1462 		ftflg = 1;
1463 	}
1464 	| T_CASE constant T_ELLIPSE constant T_COLON {
1465 		/* XXX: We don't fill all cases */
1466 		label(T_CASE, NULL, $2);
1467 		ftflg = 1;
1468 	}
1469 	| T_DEFAULT T_COLON {
1470 		label(T_DEFAULT, NULL, NULL);
1471 		ftflg = 1;
1472 	  }
1473 	;
1474 
1475 stmnt_d_list:
1476 	  stmnt_list
1477 	| stmnt_d_list declaration_list stmnt_list {
1478 		if (!Sflag)
1479 			c99ism(327);
1480 	}
1481 	;
1482 
1483 comp_stmnt:
1484 	  comp_stmnt_lbrace comp_stmnt_rbrace
1485 	| comp_stmnt_lbrace stmnt_d_list comp_stmnt_rbrace
1486 	| comp_stmnt_lbrace declaration_list comp_stmnt_rbrace
1487 	| comp_stmnt_lbrace declaration_list stmnt_d_list comp_stmnt_rbrace
1488 	;
1489 
1490 comp_stmnt_lbrace:
1491 	  T_LBRACE {
1492 		blklev++;
1493 		mblklev++;
1494 		pushdecl(AUTO);
1495 	  }
1496 	;
1497 
1498 comp_stmnt_rbrace:
1499 	  T_RBRACE {
1500 		popdecl();
1501 		freeblk();
1502 		mblklev--;
1503 		blklev--;
1504 		ftflg = 0;
1505 	  }
1506 	;
1507 
1508 stmnt_list:
1509 	  stmnt
1510 	| stmnt_list stmnt {
1511 		RESTORE(__FILE__, __LINE__);
1512 	  }
1513 	| stmnt_list error T_SEMI
1514 	;
1515 
1516 expr_stmnt:
1517 	  expr T_SEMI {
1518 		expr($1, 0, 0, 0);
1519 		ftflg = 0;
1520 	  }
1521 	| T_SEMI {
1522 		ftflg = 0;
1523 	  }
1524 	;
1525 
1526 /*
1527  * The following two productions are used to implement
1528  * ({ [[decl-list] stmt-list] }).
1529  * XXX: This is not well tested.
1530  */
1531 expr_stmnt_val:
1532 	  expr T_SEMI {
1533 		/* XXX: We should really do that only on the last name */
1534 		if ($1->tn_op == NAME)
1535 			$1->tn_sym->s_used = 1;
1536 		$$ = $1;
1537 		expr($1, 0, 0, 0);
1538 		ftflg = 0;
1539 	  }
1540 	| non_expr_stmnt {
1541 		$$ = getnode();
1542 		$$->tn_type = gettyp(VOID);
1543 	}
1544 	;
1545 
1546 expr_stmnt_list:
1547 	  expr_stmnt_val
1548 	| expr_stmnt_list expr_stmnt_val {
1549 		$$ = $2;
1550 	}
1551 	;
1552 
1553 selection_stmnt:
1554 	  if_without_else {
1555 		SAVE(__FILE__, __LINE__);
1556 		if2();
1557 		if3(0);
1558 	  }
1559 	| if_without_else T_ELSE {
1560 		SAVE(__FILE__, __LINE__);
1561 		if2();
1562 	  } stmnt {
1563 		CLRWFLGS(__FILE__, __LINE__);
1564 		if3(1);
1565 	  }
1566 	| if_without_else T_ELSE error {
1567 		CLRWFLGS(__FILE__, __LINE__);
1568 		if3(0);
1569 	  }
1570 	| switch_expr stmnt {
1571 		CLRWFLGS(__FILE__, __LINE__);
1572 		switch2();
1573 	  }
1574 	| switch_expr error {
1575 		CLRWFLGS(__FILE__, __LINE__);
1576 		switch2();
1577 	  }
1578 	;
1579 
1580 if_without_else:
1581 	  if_expr stmnt
1582 	| if_expr error
1583 	;
1584 
1585 if_expr:
1586 	  T_IF T_LPARN expr T_RPARN {
1587 		if1($3);
1588 		CLRWFLGS(__FILE__, __LINE__);
1589 	  }
1590 	;
1591 
1592 switch_expr:
1593 	  T_SWITCH T_LPARN expr T_RPARN {
1594 		switch1($3);
1595 		CLRWFLGS(__FILE__, __LINE__);
1596 	  }
1597 	;
1598 
1599 association:
1600 	  type_name T_COLON expr
1601 	| T_DEFAULT T_COLON expr
1602 	;
1603 
1604 association_list:
1605 	  association
1606 	| association_list T_COMMA association
1607 	;
1608 
1609 generic_expr:
1610 	  T_GENERIC T_LPARN expr T_COMMA association_list T_RPARN {
1611 		$$ = $3;
1612 	  }
1613 	;
1614 
1615 do_stmnt:
1616 	  do stmnt {
1617 		CLRWFLGS(__FILE__, __LINE__);
1618 	  }
1619 	;
1620 
1621 iteration_stmnt:
1622 	  while_expr stmnt {
1623 		CLRWFLGS(__FILE__, __LINE__);
1624 		while2();
1625 	  }
1626 	| while_expr error {
1627 		CLRWFLGS(__FILE__, __LINE__);
1628 		while2();
1629 	  }
1630 	| do_stmnt do_while_expr {
1631 		do2($2);
1632 		ftflg = 0;
1633 	  }
1634 	| do error {
1635 		CLRWFLGS(__FILE__, __LINE__);
1636 		do2(NULL);
1637 	  }
1638 	| for_exprs stmnt {
1639 		CLRWFLGS(__FILE__, __LINE__);
1640 		for2();
1641 		popdecl();
1642 		blklev--;
1643 	  }
1644 	| for_exprs error {
1645 		CLRWFLGS(__FILE__, __LINE__);
1646 		for2();
1647 		popdecl();
1648 		blklev--;
1649 	  }
1650 	;
1651 
1652 while_expr:
1653 	  T_WHILE T_LPARN expr T_RPARN {
1654 		while1($3);
1655 		CLRWFLGS(__FILE__, __LINE__);
1656 	  }
1657 	;
1658 
1659 do:
1660 	  T_DO {
1661 		do1();
1662 	  }
1663 	;
1664 
1665 do_while_expr:
1666 	  T_WHILE T_LPARN expr T_RPARN T_SEMI {
1667 		$$ = $3;
1668 	  }
1669 	;
1670 
1671 for_start:
1672 	  T_FOR T_LPARN {
1673 		pushdecl(AUTO);
1674 		blklev++;
1675 	  }
1676 	;
1677 for_exprs:
1678 	    for_start declspecs deftyp notype_init_decls T_SEMI opt_expr
1679 	    T_SEMI opt_expr T_RPARN {
1680 		c99ism(325);
1681 		for1(NULL, $6, $8);
1682 		CLRWFLGS(__FILE__, __LINE__);
1683 	    }
1684 	  | for_start opt_expr T_SEMI opt_expr T_SEMI opt_expr T_RPARN {
1685 		for1($2, $4, $6);
1686 		CLRWFLGS(__FILE__, __LINE__);
1687 	  }
1688 	;
1689 
1690 opt_expr:
1691 	  /* empty */ {
1692 		$$ = NULL;
1693 	  }
1694 	| expr {
1695 		$$ = $1;
1696 	  }
1697 	;
1698 
1699 jump_stmnt:
1700 	  goto identifier T_SEMI {
1701 		dogoto(getsym($2));
1702 	  }
1703 	| goto error T_SEMI {
1704 		symtyp = FVFT;
1705 	  }
1706 	| T_CONTINUE T_SEMI {
1707 		docont();
1708 	  }
1709 	| T_BREAK T_SEMI {
1710 		dobreak();
1711 	  }
1712 	| T_RETURN T_SEMI {
1713 		doreturn(NULL);
1714 	  }
1715 	| T_RETURN expr T_SEMI {
1716 		doreturn($2);
1717 	  }
1718 	;
1719 
1720 goto:
1721 	  T_GOTO {
1722 		symtyp = FLAB;
1723 	  }
1724 	;
1725 
1726 asm_stmnt:
1727 	  T_ASM T_LPARN read_until_rparn T_SEMI {
1728 		setasm();
1729 	  }
1730 	| T_ASM T_QUAL T_LPARN read_until_rparn T_SEMI {
1731 		setasm();
1732 	  }
1733 	| T_ASM error
1734 	;
1735 
1736 read_until_rparn:
1737 	  /* empty */ {
1738 		ignuptorp();
1739 	  }
1740 	;
1741 
1742 declaration_list:
1743 	  declaration {
1744 		CLRWFLGS(__FILE__, __LINE__);
1745 	  }
1746 	| declaration_list declaration {
1747 		CLRWFLGS(__FILE__, __LINE__);
1748 	  }
1749 	;
1750 
1751 constant:
1752 	  expr				%prec T_COMMA {
1753 		  $$ = $1;
1754 	  }
1755 	;
1756 
1757 expr:
1758 	  expr T_MULT expr {
1759 		$$ = build(MULT, $1, $3);
1760 	  }
1761 	| expr T_DIVOP expr {
1762 		$$ = build($2, $1, $3);
1763 	  }
1764 	| expr T_ADDOP expr {
1765 		$$ = build($2, $1, $3);
1766 	  }
1767 	| expr T_SHFTOP expr {
1768 		$$ = build($2, $1, $3);
1769 	  }
1770 	| expr T_RELOP expr {
1771 		$$ = build($2, $1, $3);
1772 	  }
1773 	| expr T_EQOP expr {
1774 		$$ = build($2, $1, $3);
1775 	  }
1776 	| expr T_AND expr {
1777 		$$ = build(AND, $1, $3);
1778 	  }
1779 	| expr T_XOR expr {
1780 		$$ = build(XOR, $1, $3);
1781 	  }
1782 	| expr T_OR expr {
1783 		$$ = build(OR, $1, $3);
1784 	  }
1785 	| expr T_LOGAND expr {
1786 		$$ = build(LOGAND, $1, $3);
1787 	  }
1788 	| expr T_LOGOR expr {
1789 		$$ = build(LOGOR, $1, $3);
1790 	  }
1791 	| expr T_QUEST expr T_COLON expr {
1792 		$$ = build(QUEST, $1, build(COLON, $3, $5));
1793 	  }
1794 	| expr T_ASSIGN expr {
1795 		$$ = build(ASSIGN, $1, $3);
1796 	  }
1797 	| expr T_OPASS expr {
1798 		$$ = build($2, $1, $3);
1799 	  }
1800 	| expr T_COMMA expr {
1801 		$$ = build(COMMA, $1, $3);
1802 	  }
1803 	| term {
1804 		$$ = $1;
1805 	  }
1806 	| generic_expr {
1807 		$$ = $1;
1808 	  }
1809 	;
1810 
1811 term:
1812 	  T_NAME {
1813 		/* XXX really necessary? */
1814 		if (yychar < 0)
1815 			yychar = yylex();
1816 		$$ = getnnode(getsym($1), yychar);
1817 	  }
1818 	| string {
1819 		$$ = getsnode($1);
1820 	  }
1821 	| T_CON {
1822 		$$ = getcnode(gettyp($1->v_tspec), $1);
1823 	  }
1824 	| T_LPARN expr T_RPARN {
1825 		if ($2 != NULL)
1826 			$2->tn_parn = 1;
1827 		$$ = $2;
1828 	  }
1829 	| T_LPARN comp_stmnt_lbrace declaration_list expr_stmnt_list {
1830 		blklev--;
1831 		mblklev--;
1832 		initsym = mktempsym(duptyp($4->tn_type));
1833 		mblklev++;
1834 		blklev++;
1835 		gnuism(320);
1836 	} comp_stmnt_rbrace T_RPARN {
1837 		$$ = getnnode(initsym, 0);
1838 	}
1839 	| T_LPARN comp_stmnt_lbrace expr_stmnt_list {
1840 		blklev--;
1841 		mblklev--;
1842 		initsym = mktempsym($3->tn_type);
1843 		mblklev++;
1844 		blklev++;
1845 		gnuism(320);
1846 	} comp_stmnt_rbrace T_RPARN {
1847 		$$ = getnnode(initsym, 0);
1848 	}
1849 	| term T_INCDEC {
1850 		$$ = build($2 == INC ? INCAFT : DECAFT, $1, NULL);
1851 	  }
1852 	| T_INCDEC term {
1853 		$$ = build($1 == INC ? INCBEF : DECBEF, $2, NULL);
1854 	  }
1855 	| T_MULT term {
1856 		$$ = build(STAR, $2, NULL);
1857 	  }
1858 	| T_AND term {
1859 		$$ = build(AMPER, $2, NULL);
1860 	  }
1861 	| T_UNOP term {
1862 		$$ = build($1, $2, NULL);
1863 	  }
1864 	| T_ADDOP term {
1865 		if (tflag && $1 == PLUS) {
1866 			/* unary + is illegal in traditional C */
1867 			warning(100);
1868 		}
1869 		$$ = build($1 == PLUS ? UPLUS : UMINUS, $2, NULL);
1870 	  }
1871 	| term T_LBRACK expr T_RBRACK {
1872 		$$ = build(STAR, build(PLUS, $1, $3), NULL);
1873 	  }
1874 	| term T_LPARN T_RPARN {
1875 		$$ = funccall($1, NULL);
1876 	  }
1877 	| term T_LPARN func_arg_list T_RPARN {
1878 		$$ = funccall($1, $3);
1879 	  }
1880 	| term point_or_arrow T_NAME {
1881 		if ($1 != NULL) {
1882 			sym_t	*msym;
1883 			/* XXX strmemb should be integrated in build() */
1884 			if ($2 == ARROW) {
1885 				/* must to this before strmemb is called */
1886 				$1 = cconv($1);
1887 			}
1888 			msym = strmemb($1, $2, getsym($3));
1889 			$$ = build($2, $1, getnnode(msym, 0));
1890 		} else {
1891 			$$ = NULL;
1892 		}
1893 	  }
1894 	| T_REAL term {
1895 		$$ = build(REAL, $2, NULL);
1896 	  }
1897 	| T_IMAG term {
1898 		$$ = build(IMAG, $2, NULL);
1899 	  }
1900 	| T_EXTENSION term {
1901 		$$ = $2;
1902 	  }
1903 	| T_REAL T_LPARN term T_RPARN {
1904 		$$ = build(REAL, $3, NULL);
1905 	  }
1906 	| T_IMAG T_LPARN term T_RPARN {
1907 		$$ = build(IMAG, $3, NULL);
1908 	  }
1909 	| T_BUILTIN_OFFSETOF T_LPARN type_name T_COMMA identifier T_RPARN
1910 						    %prec T_BUILTIN_OFFSETOF {
1911 		symtyp = FMOS;
1912 		$$ = bldoffsetof($3, getsym($5));
1913 	  }
1914 	| T_SIZEOF term					%prec T_SIZEOF {
1915 		if (($$ = $2 == NULL ? NULL : bldszof($2->tn_type)) != NULL)
1916 			chkmisc($2, 0, 0, 0, 0, 0, 1);
1917 	  }
1918 	| T_SIZEOF T_LPARN type_name T_RPARN		%prec T_SIZEOF {
1919 		$$ = bldszof($3);
1920 	  }
1921 	| T_ALIGNOF T_LPARN type_name T_RPARN		%prec T_ALIGNOF {
1922 		$$ = bldalof($3);
1923 	  }
1924 	| T_LPARN type_name T_RPARN term		%prec T_UNOP {
1925 		$$ = cast($4, $2);
1926 	  }
1927 	| T_LPARN type_name T_RPARN 			%prec T_UNOP {
1928 		sym_t *tmp = mktempsym($2);
1929 		idecl(tmp, 1, NULL);
1930 	  } init_lbrace init_expr_list init_rbrace {
1931 		if (!Sflag)
1932 			gnuism(319);
1933 		$$ = getnnode(initsym, 0);
1934 	  }
1935 	;
1936 
1937 string:
1938 	  T_STRING {
1939 		$$ = $1;
1940 	  }
1941 	| T_STRING string2 {
1942 		$$ = catstrg($1, $2);
1943 	  }
1944 	;
1945 
1946 string2:
1947 	 T_STRING {
1948 		if (tflag) {
1949 			/* concatenated strings are illegal in traditional C */
1950 			warning(219);
1951 		}
1952 		$$ = $1;
1953 	  }
1954 	| string2 T_STRING {
1955 		$$ = catstrg($1, $2);
1956 	  }
1957 	;
1958 
1959 func_arg_list:
1960 	  expr						%prec T_COMMA {
1961 		$$ = funcarg(NULL, $1);
1962 	  }
1963 	| func_arg_list T_COMMA expr {
1964 		$$ = funcarg($1, $3);
1965 	  }
1966 	;
1967 
1968 point_or_arrow:
1969 	  T_STROP {
1970 		symtyp = FMOS;
1971 		$$ = $1;
1972 	  }
1973 	;
1974 
1975 point:
1976 	  T_STROP {
1977 		if ($1 != POINT) {
1978 			error(249, yytext);
1979 		}
1980 	  }
1981 	;
1982 
1983 identifier:
1984 	  T_NAME {
1985 		$$ = $1;
1986 	  }
1987 	| T_TYPENAME {
1988 		$$ = $1;
1989 	  }
1990 	;
1991 
1992 %%
1993 
1994 /* ARGSUSED */
1995 int
1996 yyerror(const char *msg)
1997 {
1998 	error(249, yytext);
1999 	if (++sytxerr >= 5)
2000 		norecover();
2001 	return (0);
2002 }
2003 
2004 static __inline int uq_gt(uint64_t, uint64_t);
2005 static __inline int q_gt(int64_t, int64_t);
2006 
2007 static __inline int
2008 uq_gt(uint64_t a, uint64_t b)
2009 {
2010 
2011 	return (a > b);
2012 }
2013 
2014 static __inline int
2015 q_gt(int64_t a, int64_t b)
2016 {
2017 
2018 	return (a > b);
2019 }
2020 
2021 #define	q_lt(a, b)	q_gt(b, a)
2022 
2023 /*
2024  * Gets a node for a constant and returns the value of this constant
2025  * as integer.
2026  * Is the node not constant or too large for int or of type float,
2027  * a warning will be printed.
2028  *
2029  * toicon() should be used only inside declarations. If it is used in
2030  * expressions, it frees the memory used for the expression.
2031  */
2032 static int
2033 toicon(tnode_t *tn, int required)
2034 {
2035 	int	i;
2036 	tspec_t	t;
2037 	val_t	*v;
2038 
2039 	v = constant(tn, required);
2040 
2041 	/*
2042 	 * Abstract declarations are used inside expression. To free
2043 	 * the memory would be a fatal error.
2044 	 * We don't free blocks that are inside casts because these
2045 	 * will be used later to match types.
2046 	 */
2047 	if (tn->tn_op != CON && dcs->d_ctx != ABSTRACT)
2048 		tfreeblk();
2049 
2050 	if ((t = v->v_tspec) == FLOAT || t == DOUBLE || t == LDOUBLE) {
2051 		i = (int)v->v_ldbl;
2052 		/* integral constant expression expected */
2053 		error(55);
2054 	} else {
2055 		i = (int)v->v_quad;
2056 		if (isutyp(t)) {
2057 			if (uq_gt((uint64_t)v->v_quad,
2058 				  (uint64_t)TARG_INT_MAX)) {
2059 				/* integral constant too large */
2060 				warning(56);
2061 			}
2062 		} else {
2063 			if (q_gt(v->v_quad, (int64_t)TARG_INT_MAX) ||
2064 			    q_lt(v->v_quad, (int64_t)TARG_INT_MIN)) {
2065 				/* integral constant too large */
2066 				warning(56);
2067 			}
2068 		}
2069 	}
2070 	free(v);
2071 	return (i);
2072 }
2073 
2074 static void
2075 idecl(sym_t *decl, int initflg, sbuf_t *renaming)
2076 {
2077 	char *s;
2078 
2079 	initerr = 0;
2080 	initsym = decl;
2081 
2082 	switch (dcs->d_ctx) {
2083 	case EXTERN:
2084 		if (renaming != NULL) {
2085 			if (decl->s_rename != NULL)
2086 				LERROR("idecl(rename)");
2087 
2088 			s = getlblk(1, renaming->sb_len + 1);
2089 	                (void)memcpy(s, renaming->sb_name, renaming->sb_len + 1);
2090 			decl->s_rename = s;
2091 			freeyyv(&renaming, T_NAME);
2092 		}
2093 		decl1ext(decl, initflg);
2094 		break;
2095 	case ARG:
2096 		if (renaming != NULL) {
2097 			/* symbol renaming can't be used on function arguments */
2098 			error(310);
2099 			freeyyv(&renaming, T_NAME);
2100 			break;
2101 		}
2102 		(void)decl1arg(decl, initflg);
2103 		break;
2104 	case AUTO:
2105 		if (renaming != NULL) {
2106 			/* symbol renaming can't be used on automatic variables */
2107 			error(311);
2108 			freeyyv(&renaming, T_NAME);
2109 			break;
2110 		}
2111 		decl1loc(decl, initflg);
2112 		break;
2113 	default:
2114 		LERROR("idecl(%d)", dcs->d_ctx);
2115 	}
2116 
2117 	if (initflg && !initerr)
2118 		prepinit();
2119 }
2120 
2121 /*
2122  * Discard all input tokens up to and including the next
2123  * unmatched right paren
2124  */
2125 static void
2126 ignuptorp(void)
2127 {
2128 	int	level;
2129 
2130 	if (yychar < 0)
2131 		yychar = yylex();
2132 	freeyyv(&yylval, yychar);
2133 
2134 	level = 1;
2135 	while (yychar != T_RPARN || --level > 0) {
2136 		if (yychar == T_LPARN) {
2137 			level++;
2138 		} else if (yychar <= 0) {
2139 			break;
2140 		}
2141 		freeyyv(&yylval, yychar = yylex());
2142 	}
2143 
2144 	yyclearin;
2145 }
2146 
2147 static	sym_t *
2148 symbolrename(sym_t *s, sbuf_t *sb)
2149 {
2150 	if (sb)
2151 		s->s_rename = sb->sb_name;
2152 	return s;
2153 }
2154