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