112099Sjoerg%{
291592Smarkm/* $NetBSD: cgram.y,v 1.23 2002/01/31 19:36:53 tv Exp $ */
312099Sjoerg
412099Sjoerg/*
591592Smarkm * Copyright (c) 1996 Christopher G. Demetriou.  All Rights Reserved.
612099Sjoerg * Copyright (c) 1994, 1995 Jochen Pohl
712099Sjoerg * All Rights Reserved.
812099Sjoerg *
912099Sjoerg * Redistribution and use in source and binary forms, with or without
1012099Sjoerg * modification, are permitted provided that the following conditions
1112099Sjoerg * are met:
1212099Sjoerg * 1. Redistributions of source code must retain the above copyright
1312099Sjoerg *    notice, this list of conditions and the following disclaimer.
1412099Sjoerg * 2. Redistributions in binary form must reproduce the above copyright
1512099Sjoerg *    notice, this list of conditions and the following disclaimer in the
1612099Sjoerg *    documentation and/or other materials provided with the distribution.
1712099Sjoerg * 3. All advertising materials mentioning features or use of this software
1812099Sjoerg *    must display the following acknowledgement:
1912099Sjoerg *      This product includes software developed by Jochen Pohl for
2012099Sjoerg *	The NetBSD Project.
2112099Sjoerg * 4. The name of the author may not be used to endorse or promote products
2212099Sjoerg *    derived from this software without specific prior written permission.
2312099Sjoerg *
2412099Sjoerg * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
2512099Sjoerg * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2612099Sjoerg * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2712099Sjoerg * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2812099Sjoerg * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2912099Sjoerg * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3012099Sjoerg * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3112099Sjoerg * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3212099Sjoerg * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
3312099Sjoerg * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3412099Sjoerg */
3512099Sjoerg
3691592Smarkm#include <sys/cdefs.h>
3791592Smarkm#if defined(__RCSID) && !defined(lint)
3891592Smarkm__RCSID("$NetBSD: cgram.y,v 1.23 2002/01/31 19:36:53 tv Exp $");
3912099Sjoerg#endif
4091592Smarkm__FBSDID("$FreeBSD$");
4112099Sjoerg
4212099Sjoerg#include <stdlib.h>
4391592Smarkm#include <string.h>
4412099Sjoerg#include <limits.h>
4512099Sjoerg
4612099Sjoerg#include "lint1.h"
4712099Sjoerg
4812099Sjoerg/*
4912099Sjoerg * Contains the level of current declaration. 0 is extern.
5012099Sjoerg * Used for symbol table entries.
5112099Sjoerg */
5212099Sjoergint	blklev;
5312099Sjoerg
5412099Sjoerg/*
5512099Sjoerg * level for memory allocation. Normaly the same as blklev.
5612099Sjoerg * An exeption is the declaration of arguments in prototypes. Memory
5712099Sjoerg * for these can't be freed after the declaration, but symbols must
5812099Sjoerg * be removed from the symbol table after the declaration.
5912099Sjoerg */
6012099Sjoergint	mblklev;
6112099Sjoerg
6291592Smarkm/*
6391592Smarkm * Save the no-warns state and restore it to avoid the problem where
6491592Smarkm * if (expr) { stmt } / * NOLINT * / stmt;
6591592Smarkm */
6691592Smarkmstatic int onowarn = -1;
6712099Sjoerg
6891592Smarkmstatic	int	toicon(tnode_t *);
6991592Smarkmstatic	void	idecl(sym_t *, int, sbuf_t *);
7091592Smarkmstatic	void	ignuptorp(void);
7191592Smarkm
7291592Smarkm#ifdef DEBUG
7391592Smarkmstatic __inline void CLRWFLGS(void);
7491592Smarkmstatic __inline void CLRWFLGS(void)
7591592Smarkm{
7691592Smarkm	printf("%s, %d: clear flags %s %d\n", curr_pos.p_file,
7791592Smarkm	    curr_pos.p_line, __FILE__, __LINE__);
7891592Smarkm	clrwflgs();
7991592Smarkm	onowarn = -1;
8091592Smarkm}
8191592Smarkm
8291592Smarkmstatic __inline void SAVE(void);
8391592Smarkmstatic __inline void SAVE(void)
8491592Smarkm{
8591592Smarkm	if (onowarn != -1)
8691592Smarkm		abort();
8791592Smarkm	printf("%s, %d: save flags %s %d = %d\n", curr_pos.p_file,
8891592Smarkm	    curr_pos.p_line, __FILE__, __LINE__, nowarn);
8991592Smarkm	onowarn = nowarn;
9091592Smarkm}
9191592Smarkm
9291592Smarkmstatic __inline void RESTORE(void);
9391592Smarkmstatic __inline void RESTORE(void)
9491592Smarkm{
9591592Smarkm	if (onowarn != -1) {
9691592Smarkm		nowarn = onowarn;
9791592Smarkm		printf("%s, %d: restore flags %s %d = %d\n", curr_pos.p_file,
9891592Smarkm		    curr_pos.p_line, __FILE__, __LINE__, nowarn);
9991592Smarkm		onowarn = -1;
10091592Smarkm	} else
10191592Smarkm		CLRWFLGS();
10291592Smarkm}
10391592Smarkm#else
10491592Smarkm#define CLRWFLGS() clrwflgs(), onowarn = -1
10591592Smarkm#define SAVE()	onowarn = nowarn
10691592Smarkm#define RESTORE() (void)(onowarn == -1 ? (clrwflgs(), 0) : (nowarn = onowarn))
10791592Smarkm#endif
10812099Sjoerg%}
10912099Sjoerg
11012099Sjoerg%union {
11112099Sjoerg	int	y_int;
11212099Sjoerg	val_t	*y_val;
11312099Sjoerg	sbuf_t	*y_sb;
11412099Sjoerg	sym_t	*y_sym;
11512099Sjoerg	op_t	y_op;
11612099Sjoerg	scl_t	y_scl;
11712099Sjoerg	tspec_t	y_tspec;
11812099Sjoerg	tqual_t	y_tqual;
11912099Sjoerg	type_t	*y_type;
12012099Sjoerg	tnode_t	*y_tnode;
12112099Sjoerg	strg_t	*y_strg;
12212099Sjoerg	pqinf_t	*y_pqinf;
12312099Sjoerg};
12412099Sjoerg
12512099Sjoerg%token			T_LBRACE T_RBRACE T_LBRACK T_RBRACK T_LPARN T_RPARN
12612099Sjoerg%token	<y_op>		T_STROP
12712099Sjoerg%token	<y_op>		T_UNOP
12812099Sjoerg%token	<y_op>		T_INCDEC
12912099Sjoerg%token			T_SIZEOF
13012099Sjoerg%token	<y_op>		T_MULT
13112099Sjoerg%token	<y_op>		T_DIVOP
13212099Sjoerg%token	<y_op>		T_ADDOP
13312099Sjoerg%token	<y_op>		T_SHFTOP
13412099Sjoerg%token	<y_op>		T_RELOP
13512099Sjoerg%token	<y_op>		T_EQOP
13612099Sjoerg%token	<y_op>		T_AND
13712099Sjoerg%token	<y_op>		T_XOR
13812099Sjoerg%token	<y_op>		T_OR
13912099Sjoerg%token	<y_op>		T_LOGAND
14012099Sjoerg%token	<y_op>		T_LOGOR
14112099Sjoerg%token			T_QUEST
14212099Sjoerg%token			T_COLON
14312099Sjoerg%token	<y_op>		T_ASSIGN
14412099Sjoerg%token	<y_op>		T_OPASS
14512099Sjoerg%token			T_COMMA
14612099Sjoerg%token			T_SEMI
14712099Sjoerg%token			T_ELLIPSE
14812099Sjoerg
14912099Sjoerg/* storage classes (extern, static, auto, register and typedef) */
15012099Sjoerg%token	<y_scl>		T_SCLASS
15112099Sjoerg
15212099Sjoerg/* types (char, int, short, long, unsigned, signed, float, double, void) */
15312099Sjoerg%token	<y_tspec>	T_TYPE
15412099Sjoerg
15512099Sjoerg/* qualifiers (const, volatile) */
15612099Sjoerg%token	<y_tqual>	T_QUAL
15712099Sjoerg
15812099Sjoerg/* struct or union */
15912099Sjoerg%token	<y_tspec>	T_SOU
16012099Sjoerg
16112099Sjoerg/* enum */
16212099Sjoerg%token			T_ENUM
16312099Sjoerg
16412099Sjoerg/* remaining keywords */
16512099Sjoerg%token			T_CASE
16612099Sjoerg%token			T_DEFAULT
16712099Sjoerg%token			T_IF
16812099Sjoerg%token			T_ELSE
16912099Sjoerg%token			T_SWITCH
17012099Sjoerg%token			T_DO
17112099Sjoerg%token			T_WHILE
17212099Sjoerg%token			T_FOR
17312099Sjoerg%token			T_GOTO
17412099Sjoerg%token			T_CONTINUE
17512099Sjoerg%token			T_BREAK
17612099Sjoerg%token			T_RETURN
17712099Sjoerg%token			T_ASM
17891592Smarkm%token			T_SYMBOLRENAME
17912099Sjoerg
18012099Sjoerg%left	T_COMMA
18112099Sjoerg%right	T_ASSIGN T_OPASS
18212099Sjoerg%right	T_QUEST T_COLON
18312099Sjoerg%left	T_LOGOR
18412099Sjoerg%left	T_LOGAND
18512099Sjoerg%left	T_OR
18612099Sjoerg%left	T_XOR
18712099Sjoerg%left	T_AND
18812099Sjoerg%left	T_EQOP
18912099Sjoerg%left	T_RELOP
19012099Sjoerg%left	T_SHFTOP
19112099Sjoerg%left	T_ADDOP
19212099Sjoerg%left	T_MULT T_DIVOP
19312099Sjoerg%right	T_UNOP T_INCDEC T_SIZEOF
19412099Sjoerg%left	T_LPARN T_LBRACK T_STROP
19512099Sjoerg
19612099Sjoerg%token	<y_sb>		T_NAME
19712099Sjoerg%token	<y_sb>		T_TYPENAME
19812099Sjoerg%token	<y_val>		T_CON
19912099Sjoerg%token	<y_strg>	T_STRING
20012099Sjoerg
20112099Sjoerg%type	<y_sym>		func_decl
20212099Sjoerg%type	<y_sym>		notype_decl
20312099Sjoerg%type	<y_sym>		type_decl
20412099Sjoerg%type	<y_type>	typespec
20512099Sjoerg%type	<y_type>	clrtyp_typespec
20612099Sjoerg%type	<y_type>	notype_typespec
20712099Sjoerg%type	<y_type>	struct_spec
20812099Sjoerg%type	<y_type>	enum_spec
20912099Sjoerg%type	<y_sym>		struct_tag
21012099Sjoerg%type	<y_sym>		enum_tag
21112099Sjoerg%type	<y_tspec>	struct
21212099Sjoerg%type	<y_sym>		struct_declaration
21312099Sjoerg%type	<y_sb>		identifier
21412099Sjoerg%type	<y_sym>		member_declaration_list_with_rbrace
21512099Sjoerg%type	<y_sym>		member_declaration_list
21612099Sjoerg%type	<y_sym>		member_declaration
21712099Sjoerg%type	<y_sym>		notype_member_decls
21812099Sjoerg%type	<y_sym>		type_member_decls
21912099Sjoerg%type	<y_sym>		notype_member_decl
22012099Sjoerg%type	<y_sym>		type_member_decl
22112099Sjoerg%type	<y_tnode>	constant
22212099Sjoerg%type	<y_sym>		enum_declaration
22312099Sjoerg%type	<y_sym>		enums_with_opt_comma
22412099Sjoerg%type	<y_sym>		enums
22512099Sjoerg%type	<y_sym>		enumerator
22612099Sjoerg%type	<y_sym>		ename
22712099Sjoerg%type	<y_sym>		notype_direct_decl
22812099Sjoerg%type	<y_sym>		type_direct_decl
22912099Sjoerg%type	<y_pqinf>	pointer
23012099Sjoerg%type	<y_pqinf>	asterisk
23112099Sjoerg%type	<y_sym>		param_decl
23212099Sjoerg%type	<y_sym>		param_list
23312099Sjoerg%type	<y_sym>		abs_decl_param_list
23412099Sjoerg%type	<y_sym>		direct_param_decl
23512099Sjoerg%type	<y_sym>		notype_param_decl
23612099Sjoerg%type	<y_sym>		direct_notype_param_decl
23712099Sjoerg%type	<y_pqinf>	type_qualifier_list
23812099Sjoerg%type	<y_pqinf>	type_qualifier
23912099Sjoerg%type	<y_sym>		identifier_list
24012099Sjoerg%type	<y_sym>		abs_decl
24112099Sjoerg%type	<y_sym>		direct_abs_decl
24212099Sjoerg%type	<y_sym>		vararg_parameter_type_list
24312099Sjoerg%type	<y_sym>		parameter_type_list
24412099Sjoerg%type	<y_sym>		parameter_declaration
24512099Sjoerg%type	<y_tnode>	expr
24612099Sjoerg%type	<y_tnode>	term
24712099Sjoerg%type	<y_tnode>	func_arg_list
24812099Sjoerg%type	<y_op>		point_or_arrow
24912099Sjoerg%type	<y_type>	type_name
25012099Sjoerg%type	<y_sym>		abstract_declaration
25112099Sjoerg%type	<y_tnode>	do_while_expr
25212099Sjoerg%type	<y_tnode>	opt_expr
25312099Sjoerg%type	<y_strg>	string
25412099Sjoerg%type	<y_strg>	string2
25591592Smarkm%type	<y_sb>		opt_asm_or_symbolrename
25612099Sjoerg
25712099Sjoerg
25812099Sjoerg%%
25912099Sjoerg
26012099Sjoergprogram:
26112099Sjoerg	  /* empty */ {
26212099Sjoerg		if (sflag) {
26312099Sjoerg			/* empty translation unit */
26412099Sjoerg			error(272);
26512099Sjoerg		} else if (!tflag) {
26612099Sjoerg			/* empty translation unit */
26712099Sjoerg			warning(272);
26812099Sjoerg		}
26912099Sjoerg	  }
27012099Sjoerg	| translation_unit
27112099Sjoerg	;
27212099Sjoerg
27312099Sjoergtranslation_unit:
27412099Sjoerg	  ext_decl
27512099Sjoerg	| translation_unit ext_decl
27612099Sjoerg	;
27712099Sjoerg
27812099Sjoergext_decl:
27991592Smarkm	  asm_stmnt
28091592Smarkm	| func_def {
28112099Sjoerg		glclup(0);
28291592Smarkm		CLRWFLGS();
28312099Sjoerg	  }
28412099Sjoerg	| data_def {
28512099Sjoerg		glclup(0);
28691592Smarkm		CLRWFLGS();
28712099Sjoerg	  }
28812099Sjoerg	;
28912099Sjoerg
29012099Sjoergdata_def:
29112099Sjoerg	  T_SEMI {
29212099Sjoerg		if (sflag) {
29312099Sjoerg			/* syntax error: empty declaration */
29412099Sjoerg			error(0);
29512099Sjoerg		} else if (!tflag) {
29612099Sjoerg			/* syntax error: empty declaration */
29712099Sjoerg			warning(0);
29812099Sjoerg		}
29912099Sjoerg	  }
30012099Sjoerg	| clrtyp deftyp notype_init_decls T_SEMI {
30112099Sjoerg		if (sflag) {
30212099Sjoerg			/* old style declaration; add "int" */
30312099Sjoerg			error(1);
30412099Sjoerg		} else if (!tflag) {
30512099Sjoerg			/* old style declaration; add "int" */
30612099Sjoerg			warning(1);
30712099Sjoerg		}
30812099Sjoerg	  }
30912099Sjoerg	| declmods deftyp T_SEMI {
31012099Sjoerg		if (dcs->d_scl == TYPEDEF) {
31112099Sjoerg			/* typedef declares no type name */
31212099Sjoerg			warning(72);
31312099Sjoerg		} else {
31412099Sjoerg			/* empty declaration */
31512099Sjoerg			warning(2);
31612099Sjoerg		}
31712099Sjoerg	  }
31812099Sjoerg	| declmods deftyp notype_init_decls T_SEMI
31912099Sjoerg	| declspecs deftyp T_SEMI {
32012099Sjoerg		if (dcs->d_scl == TYPEDEF) {
32112099Sjoerg			/* typedef declares no type name */
32212099Sjoerg			warning(72);
32312099Sjoerg		} else if (!dcs->d_nedecl) {
32412099Sjoerg			/* empty declaration */
32512099Sjoerg			warning(2);
32612099Sjoerg		}
32712099Sjoerg	  }
32812099Sjoerg	| declspecs deftyp type_init_decls T_SEMI
32912099Sjoerg	| error T_SEMI {
33091592Smarkm		globclup();
33112099Sjoerg	  }
33212099Sjoerg	| error T_RBRACE {
33312099Sjoerg		globclup();
33412099Sjoerg	  }
33512099Sjoerg	;
33612099Sjoerg
33712099Sjoergfunc_def:
33812099Sjoerg	  func_decl {
33912099Sjoerg		if ($1->s_type->t_tspec != FUNC) {
34012099Sjoerg			/* syntax error */
34112099Sjoerg			error(249);
34212099Sjoerg			YYERROR;
34312099Sjoerg		}
34412099Sjoerg		if ($1->s_type->t_typedef) {
34512099Sjoerg			/* ()-less function definition */
34612099Sjoerg			error(64);
34712099Sjoerg			YYERROR;
34812099Sjoerg		}
34912099Sjoerg		funcdef($1);
35012099Sjoerg		blklev++;
35112099Sjoerg		pushdecl(ARG);
35212099Sjoerg	  } opt_arg_declaration_list {
35312099Sjoerg		popdecl();
35412099Sjoerg		blklev--;
35512099Sjoerg		cluparg();
35612099Sjoerg		pushctrl(0);
35712099Sjoerg	  } comp_stmnt {
35812099Sjoerg		funcend();
35912099Sjoerg		popctrl(0);
36012099Sjoerg	  }
36112099Sjoerg	;
36212099Sjoerg
36312099Sjoergfunc_decl:
36412099Sjoerg	  clrtyp deftyp notype_decl {
36512099Sjoerg		$$ = $3;
36612099Sjoerg	  }
36712099Sjoerg	| declmods deftyp notype_decl {
36812099Sjoerg		$$ = $3;
36912099Sjoerg	  }
37012099Sjoerg	| declspecs deftyp type_decl {
37112099Sjoerg		$$ = $3;
37212099Sjoerg	  }
37312099Sjoerg	;
37412099Sjoerg
37512099Sjoergopt_arg_declaration_list:
37612099Sjoerg	  /* empty */
37712099Sjoerg	| arg_declaration_list
37812099Sjoerg	;
37912099Sjoerg
38012099Sjoergarg_declaration_list:
38112099Sjoerg	  arg_declaration
38212099Sjoerg	| arg_declaration_list arg_declaration
38312099Sjoerg	/* XXX or better "arg_declaration error" ? */
38412099Sjoerg	| error
38512099Sjoerg	;
38612099Sjoerg
38712099Sjoerg/*
38812099Sjoerg * "arg_declaration" is separated from "declaration" because it
38912099Sjoerg * needs other error handling.
39012099Sjoerg */
39112099Sjoerg
39212099Sjoergarg_declaration:
39312099Sjoerg	  declmods deftyp T_SEMI {
39412099Sjoerg		/* empty declaration */
39512099Sjoerg		warning(2);
39612099Sjoerg	  }
39712099Sjoerg	| declmods deftyp notype_init_decls T_SEMI
39812099Sjoerg	| declspecs deftyp T_SEMI {
39912099Sjoerg		if (!dcs->d_nedecl) {
40012099Sjoerg			/* empty declaration */
40112099Sjoerg			warning(2);
40212099Sjoerg		} else {
40312099Sjoerg			tspec_t	ts = dcs->d_type->t_tspec;
40412099Sjoerg			/* %s declared in argument declaration list */
40512099Sjoerg			warning(3, ts == STRUCT ? "struct" :
40612099Sjoerg				(ts == UNION ? "union" : "enum"));
40712099Sjoerg		}
40812099Sjoerg	  }
40912099Sjoerg	| declspecs deftyp type_init_decls T_SEMI {
41012099Sjoerg		if (dcs->d_nedecl) {
41112099Sjoerg			tspec_t	ts = dcs->d_type->t_tspec;
41212099Sjoerg			/* %s declared in argument declaration list */
41312099Sjoerg			warning(3, ts == STRUCT ? "struct" :
41412099Sjoerg				(ts == UNION ? "union" : "enum"));
41512099Sjoerg		}
41612099Sjoerg	  }
41712099Sjoerg	| declmods error
41812099Sjoerg	| declspecs error
41912099Sjoerg	;
42012099Sjoerg
42112099Sjoergdeclaration:
42212099Sjoerg	  declmods deftyp T_SEMI {
42312099Sjoerg		if (dcs->d_scl == TYPEDEF) {
42412099Sjoerg			/* typedef declares no type name */
42512099Sjoerg			warning(72);
42612099Sjoerg		} else {
42712099Sjoerg			/* empty declaration */
42812099Sjoerg			warning(2);
42912099Sjoerg		}
43012099Sjoerg	  }
43112099Sjoerg	| declmods deftyp notype_init_decls T_SEMI
43212099Sjoerg	| declspecs deftyp T_SEMI {
43312099Sjoerg		if (dcs->d_scl == TYPEDEF) {
43412099Sjoerg			/* typedef declares no type name */
43512099Sjoerg			warning(72);
43612099Sjoerg		} else if (!dcs->d_nedecl) {
43712099Sjoerg			/* empty declaration */
43812099Sjoerg			warning(2);
43912099Sjoerg		}
44012099Sjoerg	  }
44112099Sjoerg	| declspecs deftyp type_init_decls T_SEMI
44212099Sjoerg	| error T_SEMI
44312099Sjoerg	;
44412099Sjoerg
44512099Sjoergclrtyp:
44612099Sjoerg	  {
44712099Sjoerg		clrtyp();
44812099Sjoerg	  }
44912099Sjoerg	;
45012099Sjoerg
45112099Sjoergdeftyp:
45212099Sjoerg	  /* empty */ {
45312099Sjoerg		deftyp();
45412099Sjoerg	  }
45512099Sjoerg	;
45612099Sjoerg
45712099Sjoergdeclspecs:
45812099Sjoerg	  clrtyp_typespec {
45912099Sjoerg		addtype($1);
46012099Sjoerg	  }
46112099Sjoerg	| declmods typespec {
46212099Sjoerg		addtype($2);
46312099Sjoerg	  }
46412099Sjoerg	| declspecs declmod
46512099Sjoerg	| declspecs notype_typespec {
46612099Sjoerg		addtype($2);
46712099Sjoerg	  }
46812099Sjoerg	;
46912099Sjoerg
47012099Sjoergdeclmods:
47112099Sjoerg	  clrtyp T_QUAL {
47212099Sjoerg		addqual($2);
47312099Sjoerg	  }
47412099Sjoerg	| clrtyp T_SCLASS {
47512099Sjoerg		addscl($2);
47612099Sjoerg	  }
47712099Sjoerg	| declmods declmod
47812099Sjoerg	;
47912099Sjoerg
48012099Sjoergdeclmod:
48112099Sjoerg	  T_QUAL {
48212099Sjoerg		addqual($1);
48312099Sjoerg	  }
48412099Sjoerg	| T_SCLASS {
48512099Sjoerg		addscl($1);
48612099Sjoerg	  }
48712099Sjoerg	;
48812099Sjoerg
48912099Sjoergclrtyp_typespec:
49012099Sjoerg	  clrtyp notype_typespec {
49112099Sjoerg		$$ = $2;
49212099Sjoerg	  }
49312099Sjoerg	| T_TYPENAME clrtyp {
49412099Sjoerg		$$ = getsym($1)->s_type;
49512099Sjoerg	  }
49612099Sjoerg	;
49712099Sjoerg
49812099Sjoergtypespec:
49912099Sjoerg	  notype_typespec {
50012099Sjoerg		$$ = $1;
50112099Sjoerg	  }
50212099Sjoerg	| T_TYPENAME {
50312099Sjoerg		$$ = getsym($1)->s_type;
50412099Sjoerg	  }
50512099Sjoerg	;
50612099Sjoerg
50712099Sjoergnotype_typespec:
50812099Sjoerg	  T_TYPE {
50912099Sjoerg		$$ = gettyp($1);
51012099Sjoerg	  }
51112099Sjoerg	| struct_spec {
51212099Sjoerg		popdecl();
51312099Sjoerg		$$ = $1;
51412099Sjoerg	  }
51512099Sjoerg	| enum_spec {
51612099Sjoerg		popdecl();
51712099Sjoerg		$$ = $1;
51812099Sjoerg	  }
51912099Sjoerg	;
52012099Sjoerg
52112099Sjoergstruct_spec:
52212099Sjoerg	  struct struct_tag {
52312099Sjoerg		/*
52412099Sjoerg		 * STDC requires that "struct a;" always introduces
52512099Sjoerg		 * a new tag if "a" is not declared at current level
52612099Sjoerg		 *
52712099Sjoerg		 * yychar is valid because otherwise the parser would
52812099Sjoerg		 * not been able to deceide if he must shift or reduce
52912099Sjoerg		 */
53012099Sjoerg		$$ = mktag($2, $1, 0, yychar == T_SEMI);
53112099Sjoerg	  }
53212099Sjoerg	| struct struct_tag {
53312099Sjoerg		dcs->d_tagtyp = mktag($2, $1, 1, 0);
53412099Sjoerg	  } struct_declaration {
53512099Sjoerg		$$ = compltag(dcs->d_tagtyp, $4);
53612099Sjoerg	  }
53712099Sjoerg	| struct {
53812099Sjoerg		dcs->d_tagtyp = mktag(NULL, $1, 1, 0);
53912099Sjoerg	  } struct_declaration {
54012099Sjoerg		$$ = compltag(dcs->d_tagtyp, $3);
54112099Sjoerg	  }
54212099Sjoerg	| struct error {
54312099Sjoerg		symtyp = FVFT;
54412099Sjoerg		$$ = gettyp(INT);
54512099Sjoerg	  }
54612099Sjoerg	;
54712099Sjoerg
54812099Sjoergstruct:
54912099Sjoerg	  T_SOU {
55012099Sjoerg		symtyp = FTAG;
55112099Sjoerg		pushdecl($1 == STRUCT ? MOS : MOU);
55212099Sjoerg		dcs->d_offset = 0;
55312099Sjoerg		dcs->d_stralign = CHAR_BIT;
55412099Sjoerg		$$ = $1;
55512099Sjoerg	  }
55612099Sjoerg	;
55712099Sjoerg
55812099Sjoergstruct_tag:
55912099Sjoerg	  identifier {
56012099Sjoerg		$$ = getsym($1);
56112099Sjoerg	  }
56212099Sjoerg	;
56312099Sjoerg
56412099Sjoergstruct_declaration:
56512099Sjoerg	  struct_decl_lbrace member_declaration_list_with_rbrace {
56612099Sjoerg		$$ = $2;
56712099Sjoerg	  }
56812099Sjoerg	;
56912099Sjoerg
57012099Sjoergstruct_decl_lbrace:
57112099Sjoerg	  T_LBRACE {
57212099Sjoerg		symtyp = FVFT;
57312099Sjoerg	  }
57412099Sjoerg	;
57512099Sjoerg
57612099Sjoergmember_declaration_list_with_rbrace:
57712099Sjoerg	  member_declaration_list T_SEMI T_RBRACE {
57812099Sjoerg		$$ = $1;
57912099Sjoerg	  }
58012099Sjoerg	| member_declaration_list T_RBRACE {
58112099Sjoerg		if (sflag) {
58212099Sjoerg			/* syntax req. ";" after last struct/union member */
58312099Sjoerg			error(66);
58412099Sjoerg		} else {
58512099Sjoerg			/* syntax req. ";" after last struct/union member */
58612099Sjoerg			warning(66);
58712099Sjoerg		}
58812099Sjoerg		$$ = $1;
58912099Sjoerg	  }
59012099Sjoerg	| T_RBRACE {
59112099Sjoerg		$$ = NULL;
59212099Sjoerg	  }
59312099Sjoerg	;
59412099Sjoerg
59512099Sjoergmember_declaration_list:
59612099Sjoerg	  member_declaration {
59712099Sjoerg		$$ = $1;
59812099Sjoerg	  }
59912099Sjoerg	| member_declaration_list T_SEMI member_declaration {
60012099Sjoerg		$$ = lnklst($1, $3);
60112099Sjoerg	  }
60212099Sjoerg	;
60312099Sjoerg
60412099Sjoergmember_declaration:
60512099Sjoerg	  noclass_declmods deftyp {
60612099Sjoerg		/* too late, i know, but getsym() compensates it */
60712099Sjoerg		symtyp = FMOS;
60812099Sjoerg	  } notype_member_decls {
60912099Sjoerg		symtyp = FVFT;
61012099Sjoerg		$$ = $4;
61112099Sjoerg	  }
61212099Sjoerg	| noclass_declspecs deftyp {
61312099Sjoerg		symtyp = FMOS;
61412099Sjoerg	  } type_member_decls {
61512099Sjoerg		symtyp = FVFT;
61612099Sjoerg		$$ = $4;
61712099Sjoerg	  }
61812099Sjoerg	| noclass_declmods deftyp {
61912099Sjoerg		/* struct or union member must be named */
62012099Sjoerg		warning(49);
62112099Sjoerg		$$ = NULL;
62212099Sjoerg	  }
62312099Sjoerg	| noclass_declspecs deftyp {
62412099Sjoerg		/* struct or union member must be named */
62512099Sjoerg		warning(49);
62612099Sjoerg		$$ = NULL;
62712099Sjoerg	  }
62812099Sjoerg	| error {
62912099Sjoerg		symtyp = FVFT;
63012099Sjoerg		$$ = NULL;
63112099Sjoerg	  }
63212099Sjoerg	;
63312099Sjoerg
63412099Sjoergnoclass_declspecs:
63512099Sjoerg	  clrtyp_typespec {
63612099Sjoerg		addtype($1);
63712099Sjoerg	  }
63812099Sjoerg	| noclass_declmods typespec {
63912099Sjoerg		addtype($2);
64012099Sjoerg	  }
64112099Sjoerg	| noclass_declspecs T_QUAL {
64212099Sjoerg		addqual($2);
64312099Sjoerg	  }
64412099Sjoerg	| noclass_declspecs notype_typespec {
64512099Sjoerg		addtype($2);
64612099Sjoerg	  }
64712099Sjoerg	;
64812099Sjoerg
64912099Sjoergnoclass_declmods:
65012099Sjoerg	  clrtyp T_QUAL {
65112099Sjoerg		addqual($2);
65212099Sjoerg	  }
65312099Sjoerg	| noclass_declmods T_QUAL {
65412099Sjoerg		addqual($2);
65512099Sjoerg	  }
65612099Sjoerg	;
65712099Sjoerg
65812099Sjoergnotype_member_decls:
65912099Sjoerg	  notype_member_decl {
66012099Sjoerg		$$ = decl1str($1);
66112099Sjoerg	  }
66212099Sjoerg	| notype_member_decls {
66312099Sjoerg		symtyp = FMOS;
66412099Sjoerg	  } T_COMMA type_member_decl {
66512099Sjoerg		$$ = lnklst($1, decl1str($4));
66612099Sjoerg	  }
66712099Sjoerg	;
66812099Sjoerg
66912099Sjoergtype_member_decls:
67012099Sjoerg	  type_member_decl {
67112099Sjoerg		$$ = decl1str($1);
67212099Sjoerg	  }
67312099Sjoerg	| type_member_decls {
67412099Sjoerg		symtyp = FMOS;
67512099Sjoerg	  } T_COMMA type_member_decl {
67612099Sjoerg		$$ = lnklst($1, decl1str($4));
67712099Sjoerg	  }
67812099Sjoerg	;
67912099Sjoerg
68012099Sjoergnotype_member_decl:
68112099Sjoerg	  notype_decl {
68212099Sjoerg		$$ = $1;
68312099Sjoerg	  }
68412099Sjoerg	| notype_decl T_COLON constant {
68512099Sjoerg		$$ = bitfield($1, toicon($3));
68612099Sjoerg	  }
68712099Sjoerg	| {
68812099Sjoerg		symtyp = FVFT;
68912099Sjoerg	  } T_COLON constant {
69012099Sjoerg		$$ = bitfield(NULL, toicon($3));
69112099Sjoerg	  }
69212099Sjoerg	;
69312099Sjoerg
69412099Sjoergtype_member_decl:
69512099Sjoerg	  type_decl {
69612099Sjoerg		$$ = $1;
69712099Sjoerg	  }
69812099Sjoerg	| type_decl T_COLON constant {
69912099Sjoerg		$$ = bitfield($1, toicon($3));
70012099Sjoerg	  }
70112099Sjoerg	| {
70212099Sjoerg		symtyp = FVFT;
70312099Sjoerg	  } T_COLON constant {
70412099Sjoerg		$$ = bitfield(NULL, toicon($3));
70512099Sjoerg	  }
70612099Sjoerg	;
70712099Sjoerg
70812099Sjoergenum_spec:
70912099Sjoerg	  enum enum_tag {
71012099Sjoerg		$$ = mktag($2, ENUM, 0, 0);
71112099Sjoerg	  }
71212099Sjoerg	| enum enum_tag {
71312099Sjoerg		dcs->d_tagtyp = mktag($2, ENUM, 1, 0);
71412099Sjoerg	  } enum_declaration {
71512099Sjoerg		$$ = compltag(dcs->d_tagtyp, $4);
71612099Sjoerg	  }
71712099Sjoerg	| enum {
71812099Sjoerg		dcs->d_tagtyp = mktag(NULL, ENUM, 1, 0);
71912099Sjoerg	  } enum_declaration {
72012099Sjoerg		$$ = compltag(dcs->d_tagtyp, $3);
72112099Sjoerg	  }
72212099Sjoerg	| enum error {
72312099Sjoerg		symtyp = FVFT;
72412099Sjoerg		$$ = gettyp(INT);
72512099Sjoerg	  }
72612099Sjoerg	;
72712099Sjoerg
72812099Sjoergenum:
72912099Sjoerg	  T_ENUM {
73012099Sjoerg		symtyp = FTAG;
73112099Sjoerg		pushdecl(ENUMCON);
73212099Sjoerg	  }
73312099Sjoerg	;
73412099Sjoerg
73512099Sjoergenum_tag:
73612099Sjoerg	  identifier {
73712099Sjoerg		$$ = getsym($1);
73812099Sjoerg	  }
73912099Sjoerg	;
74012099Sjoerg
74112099Sjoergenum_declaration:
74212099Sjoerg	  enum_decl_lbrace enums_with_opt_comma T_RBRACE {
74312099Sjoerg		$$ = $2;
74412099Sjoerg	  }
74512099Sjoerg	;
74612099Sjoerg
74712099Sjoergenum_decl_lbrace:
74812099Sjoerg	  T_LBRACE {
74912099Sjoerg		symtyp = FVFT;
75012099Sjoerg		enumval = 0;
75112099Sjoerg	  }
75212099Sjoerg	;
75312099Sjoerg
75412099Sjoergenums_with_opt_comma:
75512099Sjoerg	  enums {
75612099Sjoerg		$$ = $1;
75712099Sjoerg	  }
75812099Sjoerg	| enums T_COMMA {
75912099Sjoerg		if (sflag) {
76012099Sjoerg			/* trailing "," prohibited in enum declaration */
76112099Sjoerg			error(54);
76212099Sjoerg		} else {
76312099Sjoerg			/* trailing "," prohibited in enum declaration */
76491592Smarkm			(void)gnuism(54);
76512099Sjoerg		}
76612099Sjoerg		$$ = $1;
76712099Sjoerg	  }
76812099Sjoerg	;
76912099Sjoerg
77012099Sjoergenums:
77112099Sjoerg	  enumerator {
77212099Sjoerg		$$ = $1;
77312099Sjoerg	  }
77412099Sjoerg	| enums T_COMMA enumerator {
77512099Sjoerg		$$ = lnklst($1, $3);
77612099Sjoerg	  }
77712099Sjoerg	| error {
77812099Sjoerg		$$ = NULL;
77912099Sjoerg	  }
78012099Sjoerg	;
78112099Sjoerg
78212099Sjoergenumerator:
78312099Sjoerg	  ename {
78412099Sjoerg		$$ = ename($1, enumval, 1);
78512099Sjoerg	  }
78612099Sjoerg	| ename T_ASSIGN constant {
78712099Sjoerg		$$ = ename($1, toicon($3), 0);
78812099Sjoerg	  }
78912099Sjoerg	;
79012099Sjoerg
79112099Sjoergename:
79212099Sjoerg	  identifier {
79312099Sjoerg		$$ = getsym($1);
79412099Sjoerg	  }
79512099Sjoerg	;
79612099Sjoerg
79712099Sjoerg
79812099Sjoergnotype_init_decls:
79912099Sjoerg	  notype_init_decl
80012099Sjoerg	| notype_init_decls T_COMMA type_init_decl
80112099Sjoerg	;
80212099Sjoerg
80312099Sjoergtype_init_decls:
80412099Sjoerg	  type_init_decl
80512099Sjoerg	| type_init_decls T_COMMA type_init_decl
80612099Sjoerg	;
80712099Sjoerg
80812099Sjoergnotype_init_decl:
80991592Smarkm	  notype_decl opt_asm_or_symbolrename {
81091592Smarkm		idecl($1, 0, $2);
81112099Sjoerg		chksz($1);
81212099Sjoerg	  }
81391592Smarkm	| notype_decl opt_asm_or_symbolrename {
81491592Smarkm		idecl($1, 1, $2);
81512099Sjoerg	  } T_ASSIGN initializer {
81612099Sjoerg		chksz($1);
81712099Sjoerg	  }
81812099Sjoerg	;
81912099Sjoerg
82012099Sjoergtype_init_decl:
82191592Smarkm	  type_decl opt_asm_or_symbolrename {
82291592Smarkm		idecl($1, 0, $2);
82312099Sjoerg		chksz($1);
82412099Sjoerg	  }
82591592Smarkm	| type_decl opt_asm_or_symbolrename {
82691592Smarkm		idecl($1, 1, $2);
82712099Sjoerg	  } T_ASSIGN initializer {
82812099Sjoerg		chksz($1);
82912099Sjoerg	  }
83012099Sjoerg	;
83112099Sjoerg
83212099Sjoergnotype_decl:
83312099Sjoerg	  notype_direct_decl {
83412099Sjoerg		$$ = $1;
83512099Sjoerg	  }
83612099Sjoerg	| pointer notype_direct_decl {
83712099Sjoerg		$$ = addptr($2, $1);
83812099Sjoerg	  }
83912099Sjoerg	;
84012099Sjoerg
84112099Sjoergnotype_direct_decl:
84212099Sjoerg	  T_NAME {
84312099Sjoerg		$$ = dname(getsym($1));
84412099Sjoerg	  }
84512099Sjoerg	| T_LPARN type_decl T_RPARN {
84612099Sjoerg		$$ = $2;
84712099Sjoerg	  }
84812099Sjoerg	| notype_direct_decl T_LBRACK T_RBRACK {
84912099Sjoerg		$$ = addarray($1, 0, 0);
85012099Sjoerg	  }
85112099Sjoerg	| notype_direct_decl T_LBRACK constant T_RBRACK {
85212099Sjoerg		$$ = addarray($1, 1, toicon($3));
85312099Sjoerg	  }
85412099Sjoerg	| notype_direct_decl param_list {
85512099Sjoerg		$$ = addfunc($1, $2);
85612099Sjoerg		popdecl();
85712099Sjoerg		blklev--;
85812099Sjoerg	  }
85912099Sjoerg	;
86012099Sjoerg
86112099Sjoergtype_decl:
86212099Sjoerg	  type_direct_decl {
86312099Sjoerg		$$ = $1;
86412099Sjoerg	  }
86512099Sjoerg	| pointer type_direct_decl {
86612099Sjoerg		$$ = addptr($2, $1);
86712099Sjoerg	  }
86812099Sjoerg	;
86912099Sjoerg
87012099Sjoergtype_direct_decl:
87112099Sjoerg	  identifier {
87212099Sjoerg		$$ = dname(getsym($1));
87312099Sjoerg	  }
87412099Sjoerg	| T_LPARN type_decl T_RPARN {
87512099Sjoerg		$$ = $2;
87612099Sjoerg	  }
87712099Sjoerg	| type_direct_decl T_LBRACK T_RBRACK {
87812099Sjoerg		$$ = addarray($1, 0, 0);
87912099Sjoerg	  }
88012099Sjoerg	| type_direct_decl T_LBRACK constant T_RBRACK {
88112099Sjoerg		$$ = addarray($1, 1, toicon($3));
88212099Sjoerg	  }
88312099Sjoerg	| type_direct_decl param_list {
88412099Sjoerg		$$ = addfunc($1, $2);
88512099Sjoerg		popdecl();
88612099Sjoerg		blklev--;
88712099Sjoerg	  }
88812099Sjoerg	;
88912099Sjoerg
89012099Sjoerg/*
89112099Sjoerg * param_decl and notype_param_decl exist to avoid a conflict in
89212099Sjoerg * argument lists. A typename enclosed in parens should always be
89312099Sjoerg * treated as a typename, not an argument.
89412099Sjoerg * "typedef int a; f(int (a));" is  "typedef int a; f(int foo(a));"
89512099Sjoerg *				not "typedef int a; f(int a);"
89612099Sjoerg */
89712099Sjoergparam_decl:
89812099Sjoerg	  direct_param_decl {
89912099Sjoerg		$$ = $1;
90012099Sjoerg	  }
90112099Sjoerg	| pointer direct_param_decl {
90212099Sjoerg		$$ = addptr($2, $1);
90312099Sjoerg	  }
90412099Sjoerg	;
90512099Sjoerg
90612099Sjoergdirect_param_decl:
90712099Sjoerg	  identifier {
90812099Sjoerg		$$ = dname(getsym($1));
90912099Sjoerg	  }
91012099Sjoerg	| T_LPARN notype_param_decl T_RPARN {
91112099Sjoerg		$$ = $2;
91212099Sjoerg	  }
91312099Sjoerg	| direct_param_decl T_LBRACK T_RBRACK {
91412099Sjoerg		$$ = addarray($1, 0, 0);
91512099Sjoerg	  }
91612099Sjoerg	| direct_param_decl T_LBRACK constant T_RBRACK {
91712099Sjoerg		$$ = addarray($1, 1, toicon($3));
91812099Sjoerg	  }
91912099Sjoerg	| direct_param_decl param_list {
92012099Sjoerg		$$ = addfunc($1, $2);
92112099Sjoerg		popdecl();
92212099Sjoerg		blklev--;
92312099Sjoerg	  }
92412099Sjoerg	;
92512099Sjoerg
92612099Sjoergnotype_param_decl:
92712099Sjoerg	  direct_notype_param_decl {
92812099Sjoerg		$$ = $1;
92912099Sjoerg	  }
93012099Sjoerg	| pointer direct_notype_param_decl {
93112099Sjoerg		$$ = addptr($2, $1);
93212099Sjoerg	  }
93312099Sjoerg	;
93412099Sjoerg
93512099Sjoergdirect_notype_param_decl:
93612099Sjoerg	  T_NAME {
93712099Sjoerg		$$ = dname(getsym($1));
93812099Sjoerg	  }
93912099Sjoerg	| T_LPARN notype_param_decl T_RPARN {
94012099Sjoerg		$$ = $2;
94112099Sjoerg	  }
94212099Sjoerg	| direct_notype_param_decl T_LBRACK T_RBRACK {
94312099Sjoerg		$$ = addarray($1, 0, 0);
94412099Sjoerg	  }
94512099Sjoerg	| direct_notype_param_decl T_LBRACK constant T_RBRACK {
94612099Sjoerg		$$ = addarray($1, 1, toicon($3));
94712099Sjoerg	  }
94812099Sjoerg	| direct_notype_param_decl param_list {
94912099Sjoerg		$$ = addfunc($1, $2);
95012099Sjoerg		popdecl();
95112099Sjoerg		blklev--;
95212099Sjoerg	  }
95312099Sjoerg	;
95412099Sjoerg
95512099Sjoergpointer:
95612099Sjoerg	  asterisk {
95712099Sjoerg		$$ = $1;
95812099Sjoerg	  }
95912099Sjoerg	| asterisk type_qualifier_list {
96012099Sjoerg		$$ = mergepq($1, $2);
96112099Sjoerg	  }
96212099Sjoerg	| asterisk pointer {
96312099Sjoerg		$$ = mergepq($1, $2);
96412099Sjoerg	  }
96512099Sjoerg	| asterisk type_qualifier_list pointer {
96612099Sjoerg		$$ = mergepq(mergepq($1, $2), $3);
96712099Sjoerg	  }
96812099Sjoerg	;
96912099Sjoerg
97012099Sjoergasterisk:
97112099Sjoerg	  T_MULT {
97291592Smarkm		$$ = xcalloc(1, sizeof (pqinf_t));
97312099Sjoerg		$$->p_pcnt = 1;
97412099Sjoerg	  }
97512099Sjoerg	;
97612099Sjoerg
97712099Sjoergtype_qualifier_list:
97812099Sjoerg	  type_qualifier {
97912099Sjoerg		$$ = $1;
98012099Sjoerg	  }
98112099Sjoerg	| type_qualifier_list type_qualifier {
98212099Sjoerg		$$ = mergepq($1, $2);
98312099Sjoerg	  }
98412099Sjoerg	;
98512099Sjoerg
98612099Sjoergtype_qualifier:
98712099Sjoerg	  T_QUAL {
98891592Smarkm		$$ = xcalloc(1, sizeof (pqinf_t));
98912099Sjoerg		if ($1 == CONST) {
99012099Sjoerg			$$->p_const = 1;
99112099Sjoerg		} else {
99212099Sjoerg			$$->p_volatile = 1;
99312099Sjoerg		}
99412099Sjoerg	  }
99512099Sjoerg	;
99612099Sjoerg
99712099Sjoergparam_list:
99812099Sjoerg	  id_list_lparn identifier_list T_RPARN {
99912099Sjoerg		$$ = $2;
100012099Sjoerg	  }
100112099Sjoerg	| abs_decl_param_list {
100212099Sjoerg		$$ = $1;
100312099Sjoerg	  }
100412099Sjoerg	;
100512099Sjoerg
100612099Sjoergid_list_lparn:
100712099Sjoerg	  T_LPARN {
100812099Sjoerg		blklev++;
100912099Sjoerg		pushdecl(PARG);
101012099Sjoerg	  }
101112099Sjoerg	;
101212099Sjoerg
101312099Sjoergidentifier_list:
101412099Sjoerg	  T_NAME {
101512099Sjoerg		$$ = iname(getsym($1));
101612099Sjoerg	  }
101712099Sjoerg	| identifier_list T_COMMA T_NAME {
101812099Sjoerg		$$ = lnklst($1, iname(getsym($3)));
101912099Sjoerg	  }
102012099Sjoerg	| identifier_list error {
102112099Sjoerg		$$ = $1;
102212099Sjoerg	  }
102312099Sjoerg	;
102412099Sjoerg
102512099Sjoergabs_decl_param_list:
102612099Sjoerg	  abs_decl_lparn T_RPARN {
102712099Sjoerg		$$ = NULL;
102812099Sjoerg	  }
102912099Sjoerg	| abs_decl_lparn vararg_parameter_type_list T_RPARN {
103012099Sjoerg		dcs->d_proto = 1;
103112099Sjoerg		$$ = $2;
103212099Sjoerg	  }
103312099Sjoerg	| abs_decl_lparn error T_RPARN {
103412099Sjoerg		$$ = NULL;
103512099Sjoerg	  }
103612099Sjoerg	;
103712099Sjoerg
103812099Sjoergabs_decl_lparn:
103912099Sjoerg	  T_LPARN {
104012099Sjoerg		blklev++;
104112099Sjoerg		pushdecl(PARG);
104212099Sjoerg	  }
104312099Sjoerg	;
104412099Sjoerg
104512099Sjoergvararg_parameter_type_list:
104612099Sjoerg	  parameter_type_list {
104712099Sjoerg		$$ = $1;
104812099Sjoerg	  }
104912099Sjoerg	| parameter_type_list T_COMMA T_ELLIPSE {
105012099Sjoerg		dcs->d_vararg = 1;
105112099Sjoerg		$$ = $1;
105212099Sjoerg	  }
105312099Sjoerg	| T_ELLIPSE {
105412099Sjoerg		if (sflag) {
105512099Sjoerg			/* ANSI C requires formal parameter before "..." */
105612099Sjoerg			error(84);
105712099Sjoerg		} else if (!tflag) {
105812099Sjoerg			/* ANSI C requires formal parameter before "..." */
105912099Sjoerg			warning(84);
106012099Sjoerg		}
106112099Sjoerg		dcs->d_vararg = 1;
106212099Sjoerg		$$ = NULL;
106312099Sjoerg	  }
106412099Sjoerg	;
106512099Sjoerg
106612099Sjoergparameter_type_list:
106791592Smarkm	  parameter_declaration {
106812099Sjoerg		$$ = $1;
106912099Sjoerg	  }
107091592Smarkm	| parameter_type_list T_COMMA parameter_declaration {
107112099Sjoerg		$$ = lnklst($1, $3);
107212099Sjoerg	  }
107312099Sjoerg	;
107412099Sjoerg
107512099Sjoergparameter_declaration:
107612099Sjoerg	  declmods deftyp {
107712099Sjoerg		$$ = decl1arg(aname(), 0);
107812099Sjoerg	  }
107912099Sjoerg	| declspecs deftyp {
108012099Sjoerg		$$ = decl1arg(aname(), 0);
108112099Sjoerg	  }
108212099Sjoerg	| declmods deftyp notype_param_decl {
108312099Sjoerg		$$ = decl1arg($3, 0);
108412099Sjoerg	  }
108512099Sjoerg	/*
108612099Sjoerg	 * param_decl is needed because of following conflict:
108712099Sjoerg	 * "typedef int a; f(int (a));" could be parsed as
108812099Sjoerg	 * "function with argument a of type int", or
108912099Sjoerg	 * "function with an abstract argument of type function".
109012099Sjoerg	 * This grammar realizes the second case.
109112099Sjoerg	 */
109212099Sjoerg	| declspecs deftyp param_decl {
109312099Sjoerg		$$ = decl1arg($3, 0);
109412099Sjoerg	  }
109512099Sjoerg	| declmods deftyp abs_decl {
109612099Sjoerg		$$ = decl1arg($3, 0);
109712099Sjoerg	  }
109812099Sjoerg	| declspecs deftyp abs_decl {
109912099Sjoerg		$$ = decl1arg($3, 0);
110012099Sjoerg	  }
110112099Sjoerg	;
110212099Sjoerg
110391592Smarkmopt_asm_or_symbolrename:		/* expect only one */
110491592Smarkm	  /* empty */ {
110591592Smarkm		$$ = NULL;
110691592Smarkm	  }
110712099Sjoerg	| T_ASM T_LPARN T_STRING T_RPARN {
110812099Sjoerg		freeyyv(&$3, T_STRING);
110991592Smarkm		$$ = NULL;
111012099Sjoerg	  }
111191592Smarkm	| T_SYMBOLRENAME T_LPARN T_NAME T_RPARN {
111291592Smarkm		$$ = $3;
111391592Smarkm	  }
111412099Sjoerg	;
111512099Sjoerg
111612099Sjoerginitializer:
111712099Sjoerg	  init_expr
111812099Sjoerg	;
111912099Sjoerg
112012099Sjoerginit_expr:
112112099Sjoerg	  expr				%prec T_COMMA {
112212099Sjoerg		mkinit($1);
112312099Sjoerg	  }
112412099Sjoerg	| init_lbrace init_expr_list init_rbrace
112512099Sjoerg	| init_lbrace init_expr_list T_COMMA init_rbrace
112612099Sjoerg	| error
112712099Sjoerg	;
112812099Sjoerg
112912099Sjoerginit_expr_list:
113012099Sjoerg	  init_expr			%prec T_COMMA
113112099Sjoerg	| init_expr_list T_COMMA init_expr
113212099Sjoerg	;
113312099Sjoerg
113412099Sjoerginit_lbrace:
113512099Sjoerg	  T_LBRACE {
113612099Sjoerg		initlbr();
113712099Sjoerg	  }
113812099Sjoerg	;
113912099Sjoerg
114012099Sjoerginit_rbrace:
114112099Sjoerg	  T_RBRACE {
114212099Sjoerg		initrbr();
114312099Sjoerg	  }
114412099Sjoerg	;
114512099Sjoerg
114612099Sjoergtype_name:
114712099Sjoerg	  {
114812099Sjoerg		pushdecl(ABSTRACT);
114912099Sjoerg	  } abstract_declaration {
115012099Sjoerg		popdecl();
115112099Sjoerg		$$ = $2->s_type;
115212099Sjoerg	  }
115312099Sjoerg	;
115412099Sjoerg
115512099Sjoergabstract_declaration:
115612099Sjoerg	  noclass_declmods deftyp {
115712099Sjoerg		$$ = decl1abs(aname());
115812099Sjoerg	  }
115912099Sjoerg	| noclass_declspecs deftyp {
116012099Sjoerg		$$ = decl1abs(aname());
116112099Sjoerg	  }
116212099Sjoerg	| noclass_declmods deftyp abs_decl {
116312099Sjoerg		$$ = decl1abs($3);
116412099Sjoerg	  }
116512099Sjoerg	| noclass_declspecs deftyp abs_decl {
116612099Sjoerg		$$ = decl1abs($3);
116712099Sjoerg	  }
116812099Sjoerg	;
116912099Sjoerg
117012099Sjoergabs_decl:
117112099Sjoerg	  pointer {
117212099Sjoerg		$$ = addptr(aname(), $1);
117312099Sjoerg	  }
117412099Sjoerg	| direct_abs_decl {
117512099Sjoerg		$$ = $1;
117612099Sjoerg	  }
117712099Sjoerg	| pointer direct_abs_decl {
117812099Sjoerg		$$ = addptr($2, $1);
117912099Sjoerg	  }
118012099Sjoerg	;
118112099Sjoerg
118212099Sjoergdirect_abs_decl:
118312099Sjoerg	  T_LPARN abs_decl T_RPARN {
118412099Sjoerg		$$ = $2;
118512099Sjoerg	  }
118612099Sjoerg	| T_LBRACK T_RBRACK {
118712099Sjoerg		$$ = addarray(aname(), 0, 0);
118812099Sjoerg	  }
118912099Sjoerg	| T_LBRACK constant T_RBRACK {
119012099Sjoerg		$$ = addarray(aname(), 1, toicon($2));
119112099Sjoerg	  }
119212099Sjoerg	| direct_abs_decl T_LBRACK T_RBRACK {
119312099Sjoerg		$$ = addarray($1, 0, 0);
119412099Sjoerg	  }
119512099Sjoerg	| direct_abs_decl T_LBRACK constant T_RBRACK {
119612099Sjoerg		$$ = addarray($1, 1, toicon($3));
119712099Sjoerg	  }
119812099Sjoerg	| abs_decl_param_list {
119912099Sjoerg		$$ = addfunc(aname(), $1);
120012099Sjoerg		popdecl();
120112099Sjoerg		blklev--;
120212099Sjoerg	  }
120312099Sjoerg	| direct_abs_decl abs_decl_param_list {
120412099Sjoerg		$$ = addfunc($1, $2);
120512099Sjoerg		popdecl();
120612099Sjoerg		blklev--;
120712099Sjoerg	  }
120812099Sjoerg	;
120912099Sjoerg
121012099Sjoergstmnt:
121112099Sjoerg	  labeled_stmnt
121212099Sjoerg	| expr_stmnt
121312099Sjoerg	| comp_stmnt
121412099Sjoerg	| selection_stmnt
121512099Sjoerg	| iteration_stmnt
121612099Sjoerg	| jump_stmnt {
121712099Sjoerg		ftflg = 0;
121812099Sjoerg	  }
121912099Sjoerg	| asm_stmnt
122012099Sjoerg	;
122112099Sjoerg
122212099Sjoerglabeled_stmnt:
122312099Sjoerg	  label stmnt
122412099Sjoerg	;
122512099Sjoerg
122612099Sjoerglabel:
122712099Sjoerg	  identifier T_COLON {
122812099Sjoerg		symtyp = FLAB;
122912099Sjoerg		label(T_NAME, getsym($1), NULL);
123012099Sjoerg	  }
123112099Sjoerg	| T_CASE constant T_COLON {
123212099Sjoerg		label(T_CASE, NULL, $2);
123312099Sjoerg		ftflg = 1;
123412099Sjoerg	  }
123512099Sjoerg	| T_DEFAULT T_COLON {
123612099Sjoerg		label(T_DEFAULT, NULL, NULL);
123712099Sjoerg		ftflg = 1;
123812099Sjoerg	  }
123912099Sjoerg	;
124012099Sjoerg
124112099Sjoergcomp_stmnt:
124212099Sjoerg	  compstmnt_lbrace declaration_list opt_stmnt_list compstmnt_rbrace
124312099Sjoerg	| compstmnt_lbrace opt_stmnt_list compstmnt_rbrace
124412099Sjoerg	;
124512099Sjoerg
124612099Sjoergcompstmnt_lbrace:
124712099Sjoerg	  T_LBRACE {
124812099Sjoerg		blklev++;
124912099Sjoerg		mblklev++;
125012099Sjoerg		pushdecl(AUTO);
125112099Sjoerg	  }
125212099Sjoerg	;
125312099Sjoerg
125412099Sjoergcompstmnt_rbrace:
125512099Sjoerg	  T_RBRACE {
125612099Sjoerg		popdecl();
125712099Sjoerg		freeblk();
125812099Sjoerg		mblklev--;
125912099Sjoerg		blklev--;
126012099Sjoerg		ftflg = 0;
126112099Sjoerg	  }
126212099Sjoerg	;
126312099Sjoerg
126412099Sjoergopt_stmnt_list:
126512099Sjoerg	  /* empty */
126612099Sjoerg	| stmnt_list
126712099Sjoerg	;
126812099Sjoerg
126912099Sjoergstmnt_list:
127091592Smarkm	  stmnt
127112099Sjoerg	| stmnt_list stmnt {
127291592Smarkm		RESTORE();
127312099Sjoerg	  }
127491592Smarkm	| stmnt_list error T_SEMI
127512099Sjoerg	;
127612099Sjoerg
127712099Sjoergexpr_stmnt:
127812099Sjoerg	  expr T_SEMI {
127912099Sjoerg		expr($1, 0, 0);
128012099Sjoerg		ftflg = 0;
128112099Sjoerg	  }
128212099Sjoerg	| T_SEMI {
128312099Sjoerg		ftflg = 0;
128412099Sjoerg	  }
128512099Sjoerg	;
128612099Sjoerg
128712099Sjoergselection_stmnt:
128812099Sjoerg	  if_without_else {
128991592Smarkm		SAVE();
129012099Sjoerg		if2();
129112099Sjoerg		if3(0);
129212099Sjoerg	  }
129312099Sjoerg	| if_without_else T_ELSE {
129491592Smarkm		SAVE();
129512099Sjoerg		if2();
129612099Sjoerg	  } stmnt {
129791592Smarkm		CLRWFLGS();
129812099Sjoerg		if3(1);
129912099Sjoerg	  }
130012099Sjoerg	| if_without_else T_ELSE error {
130191592Smarkm		CLRWFLGS();
130212099Sjoerg		if3(0);
130312099Sjoerg	  }
130412099Sjoerg	| switch_expr stmnt {
130591592Smarkm		CLRWFLGS();
130612099Sjoerg		switch2();
130712099Sjoerg	  }
130812099Sjoerg	| switch_expr error {
130991592Smarkm		CLRWFLGS();
131012099Sjoerg		switch2();
131112099Sjoerg	  }
131212099Sjoerg	;
131312099Sjoerg
131412099Sjoergif_without_else:
131512099Sjoerg	  if_expr stmnt
131612099Sjoerg	| if_expr error
131712099Sjoerg	;
131812099Sjoerg
131912099Sjoergif_expr:
132012099Sjoerg	  T_IF T_LPARN expr T_RPARN {
132112099Sjoerg		if1($3);
132291592Smarkm		CLRWFLGS();
132312099Sjoerg	  }
132412099Sjoerg	;
132512099Sjoerg
132612099Sjoergswitch_expr:
132712099Sjoerg	  T_SWITCH T_LPARN expr T_RPARN {
132812099Sjoerg		switch1($3);
132991592Smarkm		CLRWFLGS();
133012099Sjoerg	  }
133112099Sjoerg	;
133212099Sjoerg
133391592Smarkmdo_stmnt:
133491592Smarkm	  do stmnt {
133591592Smarkm		CLRWFLGS();
133691592Smarkm	  }
133791592Smarkm	;
133891592Smarkm
133912099Sjoergiteration_stmnt:
134012099Sjoerg	  while_expr stmnt {
134191592Smarkm		CLRWFLGS();
134212099Sjoerg		while2();
134312099Sjoerg	  }
134412099Sjoerg	| while_expr error {
134591592Smarkm		CLRWFLGS();
134612099Sjoerg		while2();
134712099Sjoerg	  }
134891592Smarkm	| do_stmnt do_while_expr {
134991592Smarkm		do2($2);
135012099Sjoerg		ftflg = 0;
135112099Sjoerg	  }
135212099Sjoerg	| do error {
135391592Smarkm		CLRWFLGS();
135412099Sjoerg		do2(NULL);
135512099Sjoerg	  }
135612099Sjoerg	| for_exprs stmnt {
135791592Smarkm		CLRWFLGS();
135812099Sjoerg		for2();
135912099Sjoerg	  }
136012099Sjoerg	| for_exprs error {
136191592Smarkm		CLRWFLGS();
136212099Sjoerg		for2();
136312099Sjoerg	  }
136412099Sjoerg	;
136512099Sjoerg
136612099Sjoergwhile_expr:
136712099Sjoerg	  T_WHILE T_LPARN expr T_RPARN {
136812099Sjoerg		while1($3);
136991592Smarkm		CLRWFLGS();
137012099Sjoerg	  }
137112099Sjoerg	;
137212099Sjoerg
137312099Sjoergdo:
137412099Sjoerg	  T_DO {
137512099Sjoerg		do1();
137612099Sjoerg	  }
137712099Sjoerg	;
137812099Sjoerg
137912099Sjoergdo_while_expr:
138012099Sjoerg	  T_WHILE T_LPARN expr T_RPARN T_SEMI {
138112099Sjoerg		$$ = $3;
138212099Sjoerg	  }
138312099Sjoerg	;
138412099Sjoerg
138512099Sjoergfor_exprs:
138612099Sjoerg	  T_FOR T_LPARN opt_expr T_SEMI opt_expr T_SEMI opt_expr T_RPARN {
138712099Sjoerg		for1($3, $5, $7);
138891592Smarkm		CLRWFLGS();
138912099Sjoerg	  }
139012099Sjoerg	;
139112099Sjoerg
139212099Sjoergopt_expr:
139312099Sjoerg	  /* empty */ {
139412099Sjoerg		$$ = NULL;
139512099Sjoerg	  }
139612099Sjoerg	| expr {
139712099Sjoerg		$$ = $1;
139812099Sjoerg	  }
139912099Sjoerg	;
140012099Sjoerg
140112099Sjoergjump_stmnt:
140212099Sjoerg	  goto identifier T_SEMI {
140312099Sjoerg		dogoto(getsym($2));
140412099Sjoerg	  }
140512099Sjoerg	| goto error T_SEMI {
140612099Sjoerg		symtyp = FVFT;
140712099Sjoerg	  }
140812099Sjoerg	| T_CONTINUE T_SEMI {
140912099Sjoerg		docont();
141012099Sjoerg	  }
141112099Sjoerg	| T_BREAK T_SEMI {
141212099Sjoerg		dobreak();
141312099Sjoerg	  }
141412099Sjoerg	| T_RETURN T_SEMI {
141512099Sjoerg		doreturn(NULL);
141612099Sjoerg	  }
141712099Sjoerg	| T_RETURN expr T_SEMI {
141812099Sjoerg		doreturn($2);
141912099Sjoerg	  }
142012099Sjoerg	;
142112099Sjoerg
142212099Sjoerggoto:
142312099Sjoerg	  T_GOTO {
142412099Sjoerg		symtyp = FLAB;
142512099Sjoerg	  }
142612099Sjoerg	;
142712099Sjoerg
142812099Sjoergasm_stmnt:
142912099Sjoerg	  T_ASM T_LPARN read_until_rparn T_SEMI {
143012099Sjoerg		setasm();
143112099Sjoerg	  }
143212099Sjoerg	| T_ASM T_QUAL T_LPARN read_until_rparn T_SEMI {
143312099Sjoerg		setasm();
143412099Sjoerg	  }
143512099Sjoerg	| T_ASM error
143612099Sjoerg	;
143712099Sjoerg
143812099Sjoergread_until_rparn:
143912099Sjoerg	  /* empty */ {
144012099Sjoerg		ignuptorp();
144112099Sjoerg	  }
144212099Sjoerg	;
144312099Sjoerg
144412099Sjoergdeclaration_list:
144512099Sjoerg	  declaration {
144691592Smarkm		CLRWFLGS();
144712099Sjoerg	  }
144812099Sjoerg	| declaration_list declaration {
144991592Smarkm		CLRWFLGS();
145012099Sjoerg	  }
145112099Sjoerg	;
145212099Sjoerg
145312099Sjoergconstant:
145412099Sjoerg	  expr				%prec T_COMMA {
145512099Sjoerg		  $$ = $1;
145612099Sjoerg	  }
145712099Sjoerg	;
145812099Sjoerg
145912099Sjoergexpr:
146012099Sjoerg	  expr T_MULT expr {
146112099Sjoerg		$$ = build(MULT, $1, $3);
146212099Sjoerg	  }
146312099Sjoerg	| expr T_DIVOP expr {
146412099Sjoerg		$$ = build($2, $1, $3);
146512099Sjoerg	  }
146612099Sjoerg	| expr T_ADDOP expr {
146712099Sjoerg		$$ = build($2, $1, $3);
146812099Sjoerg	  }
146912099Sjoerg	| expr T_SHFTOP expr {
147012099Sjoerg		$$ = build($2, $1, $3);
147112099Sjoerg	  }
147212099Sjoerg	| expr T_RELOP expr {
147312099Sjoerg		$$ = build($2, $1, $3);
147412099Sjoerg	  }
147512099Sjoerg	| expr T_EQOP expr {
147612099Sjoerg		$$ = build($2, $1, $3);
147712099Sjoerg	  }
147812099Sjoerg	| expr T_AND expr {
147912099Sjoerg		$$ = build(AND, $1, $3);
148012099Sjoerg	  }
148112099Sjoerg	| expr T_XOR expr {
148212099Sjoerg		$$ = build(XOR, $1, $3);
148312099Sjoerg	  }
148412099Sjoerg	| expr T_OR expr {
148512099Sjoerg		$$ = build(OR, $1, $3);
148612099Sjoerg	  }
148712099Sjoerg	| expr T_LOGAND expr {
148812099Sjoerg		$$ = build(LOGAND, $1, $3);
148912099Sjoerg	  }
149012099Sjoerg	| expr T_LOGOR expr {
149112099Sjoerg		$$ = build(LOGOR, $1, $3);
149212099Sjoerg	  }
149312099Sjoerg	| expr T_QUEST expr T_COLON expr {
149412099Sjoerg		$$ = build(QUEST, $1, build(COLON, $3, $5));
149512099Sjoerg	  }
149612099Sjoerg	| expr T_ASSIGN expr {
149712099Sjoerg		$$ = build(ASSIGN, $1, $3);
149812099Sjoerg	  }
149912099Sjoerg	| expr T_OPASS expr {
150012099Sjoerg		$$ = build($2, $1, $3);
150112099Sjoerg	  }
150212099Sjoerg	| expr T_COMMA expr {
150312099Sjoerg		$$ = build(COMMA, $1, $3);
150412099Sjoerg	  }
150512099Sjoerg	| term {
150612099Sjoerg		$$ = $1;
150712099Sjoerg	  }
150812099Sjoerg	;
150912099Sjoerg
151012099Sjoergterm:
151112099Sjoerg	  T_NAME {
151291592Smarkm		/* XXX really necessary? */
151312099Sjoerg		if (yychar < 0)
151412099Sjoerg			yychar = yylex();
151512099Sjoerg		$$ = getnnode(getsym($1), yychar);
151612099Sjoerg	  }
151712099Sjoerg	| string {
151812099Sjoerg		$$ = getsnode($1);
151912099Sjoerg	  }
152012099Sjoerg	| T_CON {
152112099Sjoerg		$$ = getcnode(gettyp($1->v_tspec), $1);
152212099Sjoerg	  }
152312099Sjoerg	| T_LPARN expr T_RPARN {
152412099Sjoerg		if ($2 != NULL)
152512099Sjoerg			$2->tn_parn = 1;
152612099Sjoerg		$$ = $2;
152712099Sjoerg	  }
152812099Sjoerg	| term T_INCDEC {
152912099Sjoerg		$$ = build($2 == INC ? INCAFT : DECAFT, $1, NULL);
153012099Sjoerg	  }
153112099Sjoerg	| T_INCDEC term {
153212099Sjoerg		$$ = build($1 == INC ? INCBEF : DECBEF, $2, NULL);
153312099Sjoerg	  }
153412099Sjoerg	| T_MULT term {
153512099Sjoerg		$$ = build(STAR, $2, NULL);
153612099Sjoerg	  }
153712099Sjoerg	| T_AND term {
153812099Sjoerg		$$ = build(AMPER, $2, NULL);
153912099Sjoerg	  }
154012099Sjoerg	| T_UNOP term {
154112099Sjoerg		$$ = build($1, $2, NULL);
154212099Sjoerg	  }
154312099Sjoerg	| T_ADDOP term {
154412099Sjoerg		if (tflag && $1 == PLUS) {
154512099Sjoerg			/* unary + is illegal in traditional C */
154612099Sjoerg			warning(100);
154712099Sjoerg		}
154812099Sjoerg		$$ = build($1 == PLUS ? UPLUS : UMINUS, $2, NULL);
154912099Sjoerg	  }
155012099Sjoerg	| term T_LBRACK expr T_RBRACK {
155112099Sjoerg		$$ = build(STAR, build(PLUS, $1, $3), NULL);
155212099Sjoerg	  }
155312099Sjoerg	| term T_LPARN T_RPARN {
155412099Sjoerg		$$ = funccall($1, NULL);
155512099Sjoerg	  }
155612099Sjoerg	| term T_LPARN func_arg_list T_RPARN {
155712099Sjoerg		$$ = funccall($1, $3);
155812099Sjoerg	  }
155912099Sjoerg	| term point_or_arrow T_NAME {
156012099Sjoerg		if ($1 != NULL) {
156112099Sjoerg			sym_t	*msym;
156212099Sjoerg			/* XXX strmemb should be integrated in build() */
156312099Sjoerg			if ($2 == ARROW) {
156412099Sjoerg				/* must to this before strmemb is called */
156512099Sjoerg				$1 = cconv($1);
156612099Sjoerg			}
156712099Sjoerg			msym = strmemb($1, $2, getsym($3));
156812099Sjoerg			$$ = build($2, $1, getnnode(msym, 0));
156912099Sjoerg		} else {
157012099Sjoerg			$$ = NULL;
157112099Sjoerg		}
157212099Sjoerg	  }
157312099Sjoerg	| T_SIZEOF term					%prec T_SIZEOF {
157412099Sjoerg		if (($$ = $2 == NULL ? NULL : bldszof($2->tn_type)) != NULL)
157512099Sjoerg			chkmisc($2, 0, 0, 0, 0, 0, 1);
157612099Sjoerg	  }
157712099Sjoerg	| T_SIZEOF T_LPARN type_name T_RPARN		%prec T_SIZEOF {
157812099Sjoerg		$$ = bldszof($3);
157912099Sjoerg	  }
158012099Sjoerg	| T_LPARN type_name T_RPARN term		%prec T_UNOP {
158112099Sjoerg		$$ = cast($4, $2);
158212099Sjoerg	  }
158312099Sjoerg	;
158412099Sjoerg
158512099Sjoergstring:
158612099Sjoerg	  T_STRING {
158712099Sjoerg		$$ = $1;
158812099Sjoerg	  }
158912099Sjoerg	| T_STRING string2 {
159012099Sjoerg		$$ = catstrg($1, $2);
159112099Sjoerg	  }
159212099Sjoerg	;
159312099Sjoerg
159412099Sjoergstring2:
159512099Sjoerg	 T_STRING {
159612099Sjoerg		if (tflag) {
159712099Sjoerg			/* concatenated strings are illegal in traditional C */
159812099Sjoerg			warning(219);
159912099Sjoerg		}
160012099Sjoerg		$$ = $1;
160112099Sjoerg	  }
160212099Sjoerg	| string2 T_STRING {
160312099Sjoerg		$$ = catstrg($1, $2);
160412099Sjoerg	  }
160512099Sjoerg	;
160612099Sjoerg
160712099Sjoergfunc_arg_list:
160812099Sjoerg	  expr						%prec T_COMMA {
160912099Sjoerg		$$ = funcarg(NULL, $1);
161012099Sjoerg	  }
161112099Sjoerg	| func_arg_list T_COMMA expr {
161212099Sjoerg		$$ = funcarg($1, $3);
161312099Sjoerg	  }
161412099Sjoerg	;
161512099Sjoerg
161612099Sjoergpoint_or_arrow:
161712099Sjoerg	  T_STROP {
161812099Sjoerg		symtyp = FMOS;
161912099Sjoerg		$$ = $1;
162012099Sjoerg	  }
162112099Sjoerg	;
162212099Sjoerg
162312099Sjoergidentifier:
162412099Sjoerg	  T_NAME {
162512099Sjoerg		$$ = $1;
162612099Sjoerg	  }
162712099Sjoerg	| T_TYPENAME {
162812099Sjoerg		$$ = $1;
162912099Sjoerg	  }
163012099Sjoerg	;
163112099Sjoerg
163212099Sjoerg%%
163312099Sjoerg
163412099Sjoerg/* ARGSUSED */
163512099Sjoergint
163691592Smarkmyyerror(char *msg)
163712099Sjoerg{
163891592Smarkm
163912099Sjoerg	error(249);
164012099Sjoerg	if (++sytxerr >= 5)
164112099Sjoerg		norecover();
164212099Sjoerg	return (0);
164312099Sjoerg}
164412099Sjoerg
1645115967Sobrienstatic __inline int uq_gt(uint64_t, uint64_t);
1646115967Sobrienstatic __inline int
164791592Smarkmuq_gt(uint64_t a, uint64_t b)
164891592Smarkm{
164991592Smarkm
165091592Smarkm	return (a > b);
165191592Smarkm}
165291592Smarkm
1653115967Sobrienstatic __inline int q_gt(int64_t, int64_t);
1654115967Sobrienstatic __inline int
165591592Smarkmq_gt(int64_t a, int64_t b)
165691592Smarkm{
165791592Smarkm
165891592Smarkm	return (a > b);
165991592Smarkm}
166091592Smarkm
166191592Smarkm#define	q_lt(a, b)	q_gt(b, a)
166291592Smarkm
166312099Sjoerg/*
166412099Sjoerg * Gets a node for a constant and returns the value of this constant
166512099Sjoerg * as integer.
166612099Sjoerg * Is the node not constant or too large for int or of type float,
166712099Sjoerg * a warning will be printed.
166812099Sjoerg *
166912099Sjoerg * toicon() should be used only inside declarations. If it is used in
167012099Sjoerg * expressions, it frees the memory used for the expression.
167112099Sjoerg */
167212099Sjoergstatic int
167391592Smarkmtoicon(tnode_t *tn)
167412099Sjoerg{
167512099Sjoerg	int	i;
167612099Sjoerg	tspec_t	t;
167712099Sjoerg	val_t	*v;
167812099Sjoerg
167912099Sjoerg	v = constant(tn);
168012099Sjoerg
168112099Sjoerg	/*
168212099Sjoerg	 * Abstract declarations are used inside expression. To free
168312099Sjoerg	 * the memory would be a fatal error.
168412099Sjoerg	 */
168512099Sjoerg	if (dcs->d_ctx != ABSTRACT)
168612099Sjoerg		tfreeblk();
168712099Sjoerg
168812099Sjoerg	if ((t = v->v_tspec) == FLOAT || t == DOUBLE || t == LDOUBLE) {
168912099Sjoerg		i = (int)v->v_ldbl;
169012099Sjoerg		/* integral constant expression expected */
169112099Sjoerg		error(55);
169212099Sjoerg	} else {
169312099Sjoerg		i = (int)v->v_quad;
169412099Sjoerg		if (isutyp(t)) {
169591592Smarkm			if (uq_gt((uint64_t)v->v_quad,
169691592Smarkm				  (uint64_t)INT_MAX)) {
169712099Sjoerg				/* integral constant too large */
169812099Sjoerg				warning(56);
169912099Sjoerg			}
170012099Sjoerg		} else {
170191592Smarkm			if (q_gt(v->v_quad, (int64_t)INT_MAX) ||
170291592Smarkm			    q_lt(v->v_quad, (int64_t)INT_MIN)) {
170326582Stegge				/* integral constant too large */
170426582Stegge				warning(56);
170526582Stegge			}
170612099Sjoerg		}
170712099Sjoerg	}
170812099Sjoerg	free(v);
170912099Sjoerg	return (i);
171012099Sjoerg}
171112099Sjoerg
171212099Sjoergstatic void
171391592Smarkmidecl(sym_t *decl, int initflg, sbuf_t *rename)
171412099Sjoerg{
171591592Smarkm	char *s;
171691592Smarkm
171712099Sjoerg	initerr = 0;
171812099Sjoerg	initsym = decl;
171912099Sjoerg
172012099Sjoerg	switch (dcs->d_ctx) {
172112099Sjoerg	case EXTERN:
172291592Smarkm		if (rename != NULL) {
172391592Smarkm			if (decl->s_rename != NULL)
172491592Smarkm				lerror("idecl() 1");
172591592Smarkm
172691592Smarkm			s = getlblk(1, rename->sb_len + 1);
172791592Smarkm	                (void)memcpy(s, rename->sb_name, rename->sb_len + 1);
172891592Smarkm			decl->s_rename = s;
172991592Smarkm			freeyyv(&rename, T_NAME);
173091592Smarkm		}
173112099Sjoerg		decl1ext(decl, initflg);
173212099Sjoerg		break;
173312099Sjoerg	case ARG:
173491592Smarkm		if (rename != NULL) {
173591592Smarkm			/* symbol renaming can't be used on function arguments */
173691592Smarkm			error(310);
173791592Smarkm			freeyyv(&rename, T_NAME);
173891592Smarkm			break;
173991592Smarkm		}
174012099Sjoerg		(void)decl1arg(decl, initflg);
174112099Sjoerg		break;
174212099Sjoerg	case AUTO:
174391592Smarkm		if (rename != NULL) {
174491592Smarkm			/* symbol renaming can't be used on automatic variables */
174591592Smarkm			error(311);
174691592Smarkm			freeyyv(&rename, T_NAME);
174791592Smarkm			break;
174891592Smarkm		}
174912099Sjoerg		decl1loc(decl, initflg);
175012099Sjoerg		break;
175112099Sjoerg	default:
175291592Smarkm		lerror("idecl() 2");
175312099Sjoerg	}
175412099Sjoerg
175512099Sjoerg	if (initflg && !initerr)
175612099Sjoerg		prepinit();
175712099Sjoerg}
175812099Sjoerg
175912099Sjoerg/*
176012099Sjoerg * Discard all input tokens up to and including the next
176112099Sjoerg * unmatched right paren
176212099Sjoerg */
176391592Smarkmstatic void
176491592Smarkmignuptorp(void)
176512099Sjoerg{
176612099Sjoerg	int	level;
176712099Sjoerg
176812099Sjoerg	if (yychar < 0)
176912099Sjoerg		yychar = yylex();
177012099Sjoerg	freeyyv(&yylval, yychar);
177112099Sjoerg
177212099Sjoerg	level = 1;
177312099Sjoerg	while (yychar != T_RPARN || --level > 0) {
177412099Sjoerg		if (yychar == T_LPARN) {
177512099Sjoerg			level++;
177612099Sjoerg		} else if (yychar <= 0) {
177712099Sjoerg			break;
177812099Sjoerg		}
177912099Sjoerg		freeyyv(&yylval, yychar = yylex());
178012099Sjoerg	}
178112099Sjoerg
178212099Sjoerg	yyclearin;
178312099Sjoerg}
1784