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