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