xref: /netbsd/external/bsd/pcc/dist/pcc/cc/ccom/cgram.y (revision c555ae24)
1*c555ae24Splunky /*	Id: cgram.y,v 1.411 2016/01/10 18:08:13 ragge Exp 	*/
2*c555ae24Splunky /*	$NetBSD: cgram.y,v 1.3 2016/02/09 20:37:32 plunky Exp $	*/
36e0bca22Sgmcgarry 
46e0bca22Sgmcgarry /*
56e0bca22Sgmcgarry  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
66e0bca22Sgmcgarry  * All rights reserved.
76e0bca22Sgmcgarry  *
86e0bca22Sgmcgarry  * Redistribution and use in source and binary forms, with or without
96e0bca22Sgmcgarry  * modification, are permitted provided that the following conditions
106e0bca22Sgmcgarry  * are met:
116e0bca22Sgmcgarry  * 1. Redistributions of source code must retain the above copyright
126e0bca22Sgmcgarry  *    notice, this list of conditions and the following disclaimer.
136e0bca22Sgmcgarry  * 2. Redistributions in binary form must reproduce the above copyright
146e0bca22Sgmcgarry  *    notice, this list of conditions and the following disclaimer in the
156e0bca22Sgmcgarry  *    documentation and/or other materials provided with the distribution.
166e0bca22Sgmcgarry  *
176e0bca22Sgmcgarry  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
186e0bca22Sgmcgarry  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
196e0bca22Sgmcgarry  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
206e0bca22Sgmcgarry  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
216e0bca22Sgmcgarry  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
226e0bca22Sgmcgarry  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
236e0bca22Sgmcgarry  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
246e0bca22Sgmcgarry  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
256e0bca22Sgmcgarry  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
266e0bca22Sgmcgarry  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
276e0bca22Sgmcgarry  */
286e0bca22Sgmcgarry 
296e0bca22Sgmcgarry /*
306e0bca22Sgmcgarry  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
316e0bca22Sgmcgarry  *
326e0bca22Sgmcgarry  * Redistribution and use in source and binary forms, with or without
336e0bca22Sgmcgarry  * modification, are permitted provided that the following conditions
346e0bca22Sgmcgarry  * are met:
356e0bca22Sgmcgarry  *
366e0bca22Sgmcgarry  * Redistributions of source code and documentation must retain the above
376e0bca22Sgmcgarry  * copyright notice, this list of conditions and the following disclaimer.
386e0bca22Sgmcgarry  * Redistributions in binary form must reproduce the above copyright
396e0bca22Sgmcgarry  * notice, this list of conditions and the following disclaimer in the
406e0bca22Sgmcgarry  * documentation and/or other materials provided with the distribution.
416e0bca22Sgmcgarry  * All advertising materials mentioning features or use of this software
426e0bca22Sgmcgarry  * must display the following acknowledgement:
436e0bca22Sgmcgarry  * 	This product includes software developed or owned by Caldera
446e0bca22Sgmcgarry  *	International, Inc.
456e0bca22Sgmcgarry  * Neither the name of Caldera International, Inc. nor the names of other
466e0bca22Sgmcgarry  * contributors may be used to endorse or promote products derived from
476e0bca22Sgmcgarry  * this software without specific prior written permission.
486e0bca22Sgmcgarry  *
496e0bca22Sgmcgarry  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
506e0bca22Sgmcgarry  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
516e0bca22Sgmcgarry  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
526e0bca22Sgmcgarry  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
536e0bca22Sgmcgarry  * DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
546e0bca22Sgmcgarry  * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
556e0bca22Sgmcgarry  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
566e0bca22Sgmcgarry  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
576e0bca22Sgmcgarry  * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
586e0bca22Sgmcgarry  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
596e0bca22Sgmcgarry  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
606e0bca22Sgmcgarry  * POSSIBILITY OF SUCH DAMAGE.
616e0bca22Sgmcgarry  */
626e0bca22Sgmcgarry 
636e0bca22Sgmcgarry /*
646e0bca22Sgmcgarry  * Comments for this grammar file. Ragge 021123
656e0bca22Sgmcgarry  *
666e0bca22Sgmcgarry  * ANSI support required rewrite of the function header and declaration
676e0bca22Sgmcgarry  * rules almost totally.
686e0bca22Sgmcgarry  *
696e0bca22Sgmcgarry  * The lex/yacc shared keywords are now split from the keywords used
706e0bca22Sgmcgarry  * in the rest of the compiler, to simplify use of other frontends.
716e0bca22Sgmcgarry  */
726e0bca22Sgmcgarry 
736e0bca22Sgmcgarry /*
74a301e773Splunky  * At last count, there were 5 shift/reduce and no reduce/reduce conflicts
75*c555ae24Splunky  * All are accounted for;
76a301e773Splunky  * One is "dangling else"
77a301e773Splunky  * Two is in attribute parsing
78*c555ae24Splunky  * Two is in ({ }) parsing
796e0bca22Sgmcgarry  */
806e0bca22Sgmcgarry 
816e0bca22Sgmcgarry /*
826e0bca22Sgmcgarry  * Token used in C lex/yacc communications.
836e0bca22Sgmcgarry  */
846e0bca22Sgmcgarry %token	C_STRING	/* a string constant */
856e0bca22Sgmcgarry %token	C_ICON		/* an integer constant */
866e0bca22Sgmcgarry %token	C_FCON		/* a floating point constant */
876e0bca22Sgmcgarry %token	C_NAME		/* an identifier */
886e0bca22Sgmcgarry %token	C_TYPENAME	/* a typedef'd name */
896e0bca22Sgmcgarry %token	C_ANDAND	/* && */
906e0bca22Sgmcgarry %token	C_OROR		/* || */
916e0bca22Sgmcgarry %token	C_GOTO		/* unconditional goto */
926e0bca22Sgmcgarry %token	C_RETURN	/* return from function */
936e0bca22Sgmcgarry %token	C_TYPE		/* a type */
946e0bca22Sgmcgarry %token	C_CLASS		/* a storage class */
956e0bca22Sgmcgarry %token	C_ASOP		/* assignment ops */
966e0bca22Sgmcgarry %token	C_RELOP		/* <=, <, >=, > */
976e0bca22Sgmcgarry %token	C_EQUOP		/* ==, != */
986e0bca22Sgmcgarry %token	C_DIVOP		/* /, % */
996e0bca22Sgmcgarry %token	C_SHIFTOP	/* <<, >> */
1006e0bca22Sgmcgarry %token	C_INCOP		/* ++, -- */
1016e0bca22Sgmcgarry %token	C_UNOP		/* !, ~ */
1026e0bca22Sgmcgarry %token	C_STROP		/* ., -> */
1036e0bca22Sgmcgarry %token	C_STRUCT
1046e0bca22Sgmcgarry %token	C_IF
1056e0bca22Sgmcgarry %token	C_ELSE
1066e0bca22Sgmcgarry %token	C_SWITCH
1076e0bca22Sgmcgarry %token	C_BREAK
1086e0bca22Sgmcgarry %token	C_CONTINUE
1096e0bca22Sgmcgarry %token	C_WHILE
1106e0bca22Sgmcgarry %token	C_DO
1116e0bca22Sgmcgarry %token	C_FOR
1126e0bca22Sgmcgarry %token	C_DEFAULT
1136e0bca22Sgmcgarry %token	C_CASE
1146e0bca22Sgmcgarry %token	C_SIZEOF
1156e0bca22Sgmcgarry %token	C_ENUM
1166e0bca22Sgmcgarry %token	C_ELLIPSIS
1176e0bca22Sgmcgarry %token	C_QUALIFIER
1186e0bca22Sgmcgarry %token	C_FUNSPEC
1196e0bca22Sgmcgarry %token	C_ASM
1206e0bca22Sgmcgarry %token	NOMATCH
121c4627bc7Sgmcgarry %token	C_TYPEOF	/* COMPAT_GCC */
122c4627bc7Sgmcgarry %token	C_ATTRIBUTE	/* COMPAT_GCC */
1233eb51a41Splunky %token	PCC_OFFSETOF
124a301e773Splunky %token	GCC_DESIG
1256e0bca22Sgmcgarry 
126*c555ae24Splunky /* C11 keywords */
127*c555ae24Splunky %token	C_STATICASSERT
128*c555ae24Splunky %token	C_ALIGNAS
129*c555ae24Splunky %token	C_ALIGNOF
130*c555ae24Splunky %token	C_GENERIC
131*c555ae24Splunky %token	C_ATOMIC
132*c555ae24Splunky 
1336e0bca22Sgmcgarry /*
1346e0bca22Sgmcgarry  * Precedence
1356e0bca22Sgmcgarry  */
1366e0bca22Sgmcgarry %left ','
1376e0bca22Sgmcgarry %right '=' C_ASOP
1386e0bca22Sgmcgarry %right '?' ':'
1396e0bca22Sgmcgarry %left C_OROR
1406e0bca22Sgmcgarry %left C_ANDAND
1416e0bca22Sgmcgarry %left '|'
1426e0bca22Sgmcgarry %left '^'
1436e0bca22Sgmcgarry %left '&'
1446e0bca22Sgmcgarry %left C_EQUOP
1456e0bca22Sgmcgarry %left C_RELOP
1466e0bca22Sgmcgarry %left C_SHIFTOP
1476e0bca22Sgmcgarry %left '+' '-'
1486e0bca22Sgmcgarry %left '*' C_DIVOP
1496e0bca22Sgmcgarry %right C_UNOP
1506e0bca22Sgmcgarry %right C_INCOP C_SIZEOF
1516e0bca22Sgmcgarry %left '[' '(' C_STROP
1526e0bca22Sgmcgarry %{
1536e0bca22Sgmcgarry # include "pass1.h"
1546e0bca22Sgmcgarry # include <stdarg.h>
1556e0bca22Sgmcgarry # include <string.h>
1566e0bca22Sgmcgarry # include <stdlib.h>
1576e0bca22Sgmcgarry 
1586e0bca22Sgmcgarry int fun_inline;	/* Reading an inline function */
1596e0bca22Sgmcgarry int oldstyle;	/* Current function being defined */
1606e0bca22Sgmcgarry static struct symtab *xnf;
161c4627bc7Sgmcgarry extern int enummer, tvaloff, inattr;
1626e0bca22Sgmcgarry extern struct rstack *rpole;
163*c555ae24Splunky static int alwinl;
164*c555ae24Splunky P1ND *cftnod;
165a301e773Splunky static int attrwarn = 1;
1666e0bca22Sgmcgarry 
1676e0bca22Sgmcgarry #define	NORETYP	SNOCREAT /* no return type, save in unused field in symtab */
1686e0bca22Sgmcgarry 
169*c555ae24Splunky struct genlist {
170*c555ae24Splunky 	struct genlist *next;
171*c555ae24Splunky 	P1ND *p;
172*c555ae24Splunky 	TWORD t;
173*c555ae24Splunky };
174*c555ae24Splunky 
175*c555ae24Splunky        P1ND *bdty(int op, ...);
1766e0bca22Sgmcgarry static void fend(void);
177*c555ae24Splunky static void fundef(P1ND *tp, P1ND *p);
178*c555ae24Splunky static void olddecl(P1ND *p, P1ND *a);
179*c555ae24Splunky static struct symtab *init_declarator(P1ND *tn, P1ND *p, int assign, P1ND *a,
1802d03e475Splunky 	char *as);
1816e0bca22Sgmcgarry static void resetbc(int mask);
1826e0bca22Sgmcgarry static void swend(void);
183*c555ae24Splunky static void addcase(P1ND *p);
184c4627bc7Sgmcgarry #ifdef GCC_COMPAT
185*c555ae24Splunky static void gcccase(P1ND *p, P1ND *);
186c4627bc7Sgmcgarry #endif
187*c555ae24Splunky static struct attr *gcc_attr_wrapper(P1ND *p);
1886e0bca22Sgmcgarry static void adddef(void);
1896e0bca22Sgmcgarry static void savebc(void);
1906e0bca22Sgmcgarry static void swstart(int, TWORD);
1916e0bca22Sgmcgarry static void genswitch(int, TWORD, struct swents **, int);
1926e0bca22Sgmcgarry static char *mkpstr(char *str);
193*c555ae24Splunky static struct symtab *clbrace(P1ND *);
194*c555ae24Splunky static P1ND *cmop(P1ND *l, P1ND *r);
195*c555ae24Splunky static P1ND *xcmop(P1ND *out, P1ND *in, P1ND *str);
196*c555ae24Splunky static void mkxasm(char *str, P1ND *p);
197*c555ae24Splunky static P1ND *xasmop(char *str, P1ND *p);
198*c555ae24Splunky static P1ND *biop(int op, P1ND *l, P1ND *r);
1996e0bca22Sgmcgarry static void flend(void);
200*c555ae24Splunky static P1ND *gccexpr(int bn, P1ND *q);
201c4627bc7Sgmcgarry static char * simname(char *s);
202*c555ae24Splunky static P1ND *tyof(P1ND *);	/* COMPAT_GCC */
203*c555ae24Splunky static P1ND *voidcon(void);
204*c555ae24Splunky static P1ND *funargs(P1ND *p);
205*c555ae24Splunky static void oldargs(P1ND *p);
206*c555ae24Splunky static void uawarn(P1ND *p, char *s);
207*c555ae24Splunky static int con_e(P1ND *p);
208*c555ae24Splunky static void dainit(P1ND *d, P1ND *a);
209*c555ae24Splunky static P1ND *tymfix(P1ND *p);
210*c555ae24Splunky static P1ND *namekill(P1ND *p, int clr);
211*c555ae24Splunky static P1ND *aryfix(P1ND *p);
212*c555ae24Splunky static P1ND *dogen(struct genlist *g, P1ND *e);
213*c555ae24Splunky static struct genlist *newgen(P1ND *p, P1ND *q);
214*c555ae24Splunky static struct genlist *addgen(struct genlist *g, struct genlist *h);
215*c555ae24Splunky 
2162d03e475Splunky static void savlab(int);
217*c555ae24Splunky static void xcbranch(P1ND *, int);
2182d03e475Splunky extern int *mkclabs(void);
2193eb51a41Splunky 
220a301e773Splunky #define	TYMFIX(inp) { \
221*c555ae24Splunky 	P1ND *pp = inp; \
222a301e773Splunky 	inp = tymerge(pp->n_left, pp->n_right); \
223*c555ae24Splunky 	p1nfree(pp->n_left); p1nfree(pp); }
224*c555ae24Splunky 
225*c555ae24Splunky struct xalloc;
226*c555ae24Splunky extern struct xalloc *bkpole, *sapole;
227*c555ae24Splunky extern int cbkp, cstp;
228*c555ae24Splunky extern int usdnodes;
229*c555ae24Splunky struct bks {
230*c555ae24Splunky 	struct xalloc *ptr;
231*c555ae24Splunky 	int off;
232*c555ae24Splunky };
233*c555ae24Splunky 
2346e0bca22Sgmcgarry /*
2356e0bca22Sgmcgarry  * State for saving current switch state (when nested switches).
2366e0bca22Sgmcgarry  */
2376e0bca22Sgmcgarry struct savbc {
2386e0bca22Sgmcgarry 	struct savbc *next;
2396e0bca22Sgmcgarry 	int brklab;
2406e0bca22Sgmcgarry 	int contlab;
2416e0bca22Sgmcgarry 	int flostat;
2426e0bca22Sgmcgarry 	int swx;
243*c555ae24Splunky 	struct xalloc *bkptr;
244*c555ae24Splunky 	int bkoff;
245*c555ae24Splunky 	struct xalloc *stptr;
246*c555ae24Splunky 	int stoff;
247*c555ae24Splunky 	int numnode;
2486e0bca22Sgmcgarry } *savbc, *savctx;
2496e0bca22Sgmcgarry 
2506e0bca22Sgmcgarry %}
2516e0bca22Sgmcgarry 
2526e0bca22Sgmcgarry %union {
253*c555ae24Splunky 	TWORD type;
2546e0bca22Sgmcgarry 	int intval;
255*c555ae24Splunky 	P1ND *nodep;
2566e0bca22Sgmcgarry 	struct symtab *symp;
2576e0bca22Sgmcgarry 	struct rstack *rp;
2586e0bca22Sgmcgarry 	char *strp;
259*c555ae24Splunky 	struct bks *bkp;
260*c555ae24Splunky 	union flt *flt;
261*c555ae24Splunky 	struct genlist *g;
2626e0bca22Sgmcgarry }
2636e0bca22Sgmcgarry 
2646e0bca22Sgmcgarry 	/* define types */
2656e0bca22Sgmcgarry %start ext_def_list
2666e0bca22Sgmcgarry 
2673eb51a41Splunky %type <intval> ifelprefix ifprefix whprefix forprefix doprefix switchpart
268a301e773Splunky 		xbegin
269a301e773Splunky %type <nodep> e .e term enum_dcl struct_dcl cast_type declarator
270*c555ae24Splunky 		elist type_sq cf_spec merge_attribs e2 ecq
2716e0bca22Sgmcgarry 		parameter_declaration abstract_declarator initializer
2722d03e475Splunky 		parameter_type_list parameter_list
2733eb51a41Splunky 		declaration_specifiers designation
2743eb51a41Splunky 		specifier_qualifier_list merge_specifiers
275c4627bc7Sgmcgarry 		identifier_list arg_param_list type_qualifier_list
2766e0bca22Sgmcgarry 		designator_list designator xasm oplist oper cnstr funtype
277c4627bc7Sgmcgarry 		typeof attribute attribute_specifier /* COMPAT_GCC */
278c4627bc7Sgmcgarry 		attribute_list attr_spec_list attr_var /* COMPAT_GCC */
279*c555ae24Splunky 
280*c555ae24Splunky %type <g>	gen_ass_list gen_assoc
281*c555ae24Splunky %type <strp>	string C_STRING GCC_DESIG svstr
2826e0bca22Sgmcgarry %type <rp>	str_head
2836e0bca22Sgmcgarry %type <symp>	xnfdeclarator clbrace enum_head
2846e0bca22Sgmcgarry 
285c4627bc7Sgmcgarry %type <intval>  C_STRUCT C_RELOP C_DIVOP C_SHIFTOP
2866e0bca22Sgmcgarry 		C_ANDAND C_OROR C_STROP C_INCOP C_UNOP C_ASOP C_EQUOP
2876e0bca22Sgmcgarry 
288*c555ae24Splunky %type <type>	C_TYPE C_QUALIFIER C_CLASS C_FUNSPEC
289*c555ae24Splunky 
290*c555ae24Splunky %type <nodep>   C_ICON
291*c555ae24Splunky 
292*c555ae24Splunky %type <flt>	C_FCON
293*c555ae24Splunky 
2946e0bca22Sgmcgarry %type <strp>	C_NAME C_TYPENAME
2956e0bca22Sgmcgarry %%
2966e0bca22Sgmcgarry 
2976e0bca22Sgmcgarry ext_def_list:	   ext_def_list external_def
2986e0bca22Sgmcgarry 		| { ftnend(); }
2996e0bca22Sgmcgarry 		;
3006e0bca22Sgmcgarry 
3016e0bca22Sgmcgarry external_def:	   funtype kr_args compoundstmt { fend(); }
3026e0bca22Sgmcgarry 		|  declaration  { blevel = 0; symclear(0); }
3036e0bca22Sgmcgarry 		|  asmstatement ';'
3046e0bca22Sgmcgarry 		|  ';'
3056e0bca22Sgmcgarry 		|  error { blevel = 0; }
3066e0bca22Sgmcgarry 		;
3076e0bca22Sgmcgarry 
3086e0bca22Sgmcgarry funtype:	  /* no type given */ declarator {
309a301e773Splunky 		    fundef(mkty(INT, 0, 0), $1);
3106e0bca22Sgmcgarry 		    cftnsp->sflags |= NORETYP;
3116e0bca22Sgmcgarry 		}
3126e0bca22Sgmcgarry 		| declaration_specifiers declarator { fundef($1,$2); }
3136e0bca22Sgmcgarry 		;
3146e0bca22Sgmcgarry 
3156e0bca22Sgmcgarry kr_args:	  /* empty */
3166e0bca22Sgmcgarry 		| arg_dcl_list
3176e0bca22Sgmcgarry 		;
3186e0bca22Sgmcgarry 
3196e0bca22Sgmcgarry /*
3206e0bca22Sgmcgarry  * Returns a node pointer or NULL, if no types at all given.
3216e0bca22Sgmcgarry  * Type trees are checked for correctness and merged into one
3226e0bca22Sgmcgarry  * type node in typenode().
3236e0bca22Sgmcgarry  */
3246e0bca22Sgmcgarry declaration_specifiers:
3256e0bca22Sgmcgarry 		   merge_attribs { $$ = typenode($1); }
3266e0bca22Sgmcgarry 		;
3276e0bca22Sgmcgarry 
328c4627bc7Sgmcgarry merge_attribs:	   type_sq { $$ = $1; }
329c4627bc7Sgmcgarry 		|  type_sq merge_attribs { $$ = cmop($2, $1); }
330c4627bc7Sgmcgarry 		|  cf_spec { $$ = $1; }
331c4627bc7Sgmcgarry 		|  cf_spec merge_attribs { $$ = cmop($2, $1); }
3326e0bca22Sgmcgarry 		;
3336e0bca22Sgmcgarry 
334*c555ae24Splunky type_sq:	   C_TYPE { $$ = mkty($1, 0, 0); }
3356e0bca22Sgmcgarry 		|  C_TYPENAME {
3366e0bca22Sgmcgarry 			struct symtab *sp = lookup($1, 0);
337a301e773Splunky 			if (sp->stype == ENUMTY) {
338a301e773Splunky 				sp->stype = strmemb(sp->sap)->stype;
339a301e773Splunky 			}
340a301e773Splunky 			$$ = mkty(sp->stype, sp->sdf, sp->sap);
3416e0bca22Sgmcgarry 			$$->n_sp = sp;
3426e0bca22Sgmcgarry 		}
3436e0bca22Sgmcgarry 		|  struct_dcl { $$ = $1; }
3446e0bca22Sgmcgarry 		|  enum_dcl { $$ = $1; }
345*c555ae24Splunky 		|  C_QUALIFIER { $$ = block(QUALIFIER, NULL, NULL, 0, 0, 0); $$->n_qual = $1; }
346c4627bc7Sgmcgarry 		|  attribute_specifier { $$ = biop(ATTRIB, $1, 0); }
347*c555ae24Splunky 		|  C_ALIGNAS '(' e ')' {
348*c555ae24Splunky 			$$ = biop(ALIGN, NULL, NULL);
349*c555ae24Splunky 			slval($$, con_e($3));
350*c555ae24Splunky 		}
351*c555ae24Splunky 		|  C_ALIGNAS '(' cast_type ')' {
352*c555ae24Splunky 			TYMFIX($3);
353*c555ae24Splunky 			$$ = biop(ALIGN, NULL, NULL);
354*c555ae24Splunky 			slval($$, talign($3->n_type, $3->n_ap)/SZCHAR);
355*c555ae24Splunky 			p1tfree($3);
356*c555ae24Splunky 		}
357*c555ae24Splunky 		|  C_ATOMIC { uerror("_Atomic not supported"); $$ = bcon(0); }
358*c555ae24Splunky 		|  C_ATOMIC '(' cast_type ')' {
359*c555ae24Splunky 			uerror("_Atomic not supported"); $$ = $3;
360*c555ae24Splunky 		}
361c4627bc7Sgmcgarry 		|  typeof { $$ = $1; }
362c4627bc7Sgmcgarry 		;
363c4627bc7Sgmcgarry 
364*c555ae24Splunky cf_spec:	   C_CLASS { $$ = block(CLASS, NULL, NULL, $1, 0, 0); }
365*c555ae24Splunky 		|  C_FUNSPEC { $$ = block(FUNSPEC, NULL, NULL, $1, 0, 0); }
366c4627bc7Sgmcgarry 		;
367c4627bc7Sgmcgarry 
368a301e773Splunky typeof:		   C_TYPEOF '(' e ')' { $$ = tyof(eve($3)); }
369a301e773Splunky 		|  C_TYPEOF '(' cast_type ')' { TYMFIX($3); $$ = tyof($3); }
370a301e773Splunky 		;
371c4627bc7Sgmcgarry 
372c4627bc7Sgmcgarry attribute_specifier :
373c4627bc7Sgmcgarry 		   C_ATTRIBUTE '(' '(' attribute_list ')' ')' { $$ = $4; }
374c4627bc7Sgmcgarry  /*COMPAT_GCC*/	;
375c4627bc7Sgmcgarry 
376c4627bc7Sgmcgarry attribute_list:	   attribute
377c4627bc7Sgmcgarry 		|  attribute ',' attribute_list { $$ = cmop($3, $1); }
378c4627bc7Sgmcgarry 		;
379c4627bc7Sgmcgarry 
380c4627bc7Sgmcgarry attribute:	   {
381c4627bc7Sgmcgarry #ifdef GCC_COMPAT
382c4627bc7Sgmcgarry 			 $$ = voidcon();
383c4627bc7Sgmcgarry #endif
384c4627bc7Sgmcgarry 		}
385c4627bc7Sgmcgarry 		|  C_NAME { $$ = bdty(NAME, $1); }
386c4627bc7Sgmcgarry 		|  C_NAME '(' elist ')' {
387*c555ae24Splunky 			$$ = bdty($3 == NULL ? UCALL : CALL, bdty(NAME, $1), $3);
388c4627bc7Sgmcgarry 		}
3896e0bca22Sgmcgarry 		;
3906e0bca22Sgmcgarry 
3916e0bca22Sgmcgarry /*
3926e0bca22Sgmcgarry  * Adds a pointer list to front of the declarators.
3936e0bca22Sgmcgarry  */
394c4627bc7Sgmcgarry declarator:	   '*' declarator { $$ = bdty(UMUL, $2); }
395c4627bc7Sgmcgarry 		|  '*' type_qualifier_list declarator {
396a301e773Splunky 			$$ = $2;
397a301e773Splunky 			$$->n_left = $3;
3986e0bca22Sgmcgarry 		}
399c4627bc7Sgmcgarry 		|  C_NAME { $$ = bdty(NAME, $1); }
4003eb51a41Splunky 		|  '(' attr_spec_list declarator ')' {
4013eb51a41Splunky 			$$ = $3;
4022d03e475Splunky 			$$->n_ap = attr_add($$->n_ap, gcc_attr_wrapper($2));
4033eb51a41Splunky 		}
4046e0bca22Sgmcgarry 		|  '(' declarator ')' { $$ = $2; }
405*c555ae24Splunky 		|  declarator '[' ecq ']' { $$ = biop(LB, $1, $3); }
406a301e773Splunky 		|  declarator '(' parameter_type_list ')' {
407a301e773Splunky 			$$ = bdty(CALL, $1, $3);
4086e0bca22Sgmcgarry 		}
409a301e773Splunky 		|  declarator '(' identifier_list ')' {
410a301e773Splunky 			$$ = bdty(CALL, $1, $3);
4116e0bca22Sgmcgarry 			oldstyle = 1;
4126e0bca22Sgmcgarry 		}
413a301e773Splunky 		|  declarator '(' ')' { $$ = bdty(UCALL, $1); }
414c4627bc7Sgmcgarry 		;
415c4627bc7Sgmcgarry 
416*c555ae24Splunky ecq:		   maybe_r { $$ = bcon(NOOFFSET); }
417*c555ae24Splunky 		|  e  { $$ = $1; }
418*c555ae24Splunky 		|  r e { $$ = $2; }
419*c555ae24Splunky 		|  c maybe_r e { $$ = $3; }
420*c555ae24Splunky 		|  r c e { $$ = $3; }
421*c555ae24Splunky 		|  '*' { $$ = bcon(NOOFFSET); }
422*c555ae24Splunky 		|  r '*' { $$ = bcon(NOOFFSET); }
423*c555ae24Splunky 		;
424*c555ae24Splunky 
425*c555ae24Splunky r:		  C_QUALIFIER {
426*c555ae24Splunky 			if ($1 != 0)
427*c555ae24Splunky 				uerror("bad qualifier");
428*c555ae24Splunky 		}
429*c555ae24Splunky 		;
430*c555ae24Splunky 
431*c555ae24Splunky c:		  C_CLASS {
432*c555ae24Splunky 			if ($1 != STATIC)
433*c555ae24Splunky 				uerror("bad class keyword");
434*c555ae24Splunky 		}
435*c555ae24Splunky 		;
436*c555ae24Splunky 
437c4627bc7Sgmcgarry type_qualifier_list:
438*c555ae24Splunky 		   C_QUALIFIER { $$ = biop(UMUL, 0, 0); $$->n_qual = $1; }
439c4627bc7Sgmcgarry 		|  type_qualifier_list C_QUALIFIER {
440c4627bc7Sgmcgarry 			$$ = $1;
441*c555ae24Splunky 			$$->n_qual |= $2;
442c4627bc7Sgmcgarry 		}
443a301e773Splunky 		|  attribute_specifier {
444*c555ae24Splunky 			$$ = block(UMUL, NULL, NULL, 0, 0, gcc_attr_wrapper($1));
445c4627bc7Sgmcgarry 		}
446a301e773Splunky 		|  type_qualifier_list attribute_specifier {
4472d03e475Splunky 			$1->n_ap = attr_add($1->n_ap, gcc_attr_wrapper($2));
448c4627bc7Sgmcgarry 		}
449c4627bc7Sgmcgarry 		;
450c4627bc7Sgmcgarry 
451c4627bc7Sgmcgarry identifier_list:   C_NAME { $$ = bdty(NAME, $1); oldargs($$); }
452a301e773Splunky 		|  identifier_list ',' C_NAME {
453a301e773Splunky 			$$ = cmop($1, bdty(NAME, $3));
454a301e773Splunky 			oldargs($$->n_right);
455a301e773Splunky 		}
4566e0bca22Sgmcgarry 		;
4576e0bca22Sgmcgarry 
4586e0bca22Sgmcgarry /*
4596e0bca22Sgmcgarry  * Returns as parameter_list, but can add an additional ELLIPSIS node.
4606e0bca22Sgmcgarry  */
4616e0bca22Sgmcgarry parameter_type_list:
4626e0bca22Sgmcgarry 		   parameter_list { $$ = $1; }
4636e0bca22Sgmcgarry 		|  parameter_list ',' C_ELLIPSIS {
464*c555ae24Splunky 			$$ = cmop($1, biop(ELLIPSIS, NULL, NULL));
4656e0bca22Sgmcgarry 		}
4666e0bca22Sgmcgarry 		;
4676e0bca22Sgmcgarry 
4686e0bca22Sgmcgarry /*
4696e0bca22Sgmcgarry  * Returns a linked lists of nodes of op CM with parameters on
4706e0bca22Sgmcgarry  * its right and additional CM nodes of its left pointer.
4716e0bca22Sgmcgarry  * No CM nodes if only one parameter.
4726e0bca22Sgmcgarry  */
4736e0bca22Sgmcgarry parameter_list:	   parameter_declaration { $$ = $1; }
4746e0bca22Sgmcgarry 		|  parameter_list ',' parameter_declaration {
4756e0bca22Sgmcgarry 			$$ = cmop($1, $3);
4766e0bca22Sgmcgarry 		}
4776e0bca22Sgmcgarry 		;
4786e0bca22Sgmcgarry 
4796e0bca22Sgmcgarry /*
4806e0bca22Sgmcgarry  * Returns a node pointer to the declaration.
4816e0bca22Sgmcgarry  */
4826e0bca22Sgmcgarry parameter_declaration:
483c4627bc7Sgmcgarry 		   declaration_specifiers declarator attr_var {
484*c555ae24Splunky 			if (glval($1) != SNULL && glval($1) != REGISTER)
4856e0bca22Sgmcgarry 				uerror("illegal parameter class");
4862d03e475Splunky 			$$ = block(TYMERGE, $1, $2, INT, 0,
4872d03e475Splunky 			    gcc_attr_wrapper($3));
4886e0bca22Sgmcgarry 		}
4896e0bca22Sgmcgarry 		|  declaration_specifiers abstract_declarator {
4905eacabfdSplunky 			$1->n_ap = attr_add($1->n_ap, $2->n_ap);
491a301e773Splunky 			$$ = block(TYMERGE, $1, $2, INT, 0, 0);
4926e0bca22Sgmcgarry 		}
4936e0bca22Sgmcgarry 		|  declaration_specifiers {
494a301e773Splunky 			$$ = block(TYMERGE, $1, bdty(NAME, NULL), INT, 0, 0);
4956e0bca22Sgmcgarry 		}
4966e0bca22Sgmcgarry 		;
4976e0bca22Sgmcgarry 
4986e0bca22Sgmcgarry abstract_declarator:
499c4627bc7Sgmcgarry 		   '*' { $$ = bdty(UMUL, bdty(NAME, NULL)); }
500c4627bc7Sgmcgarry 		|  '*' type_qualifier_list {
501a301e773Splunky 			$$ = $2;
502a301e773Splunky 			$$->n_left = bdty(NAME, NULL);
5036e0bca22Sgmcgarry 		}
504c4627bc7Sgmcgarry 		|  '*' abstract_declarator { $$ = bdty(UMUL, $2); }
505c4627bc7Sgmcgarry 		|  '*' type_qualifier_list abstract_declarator {
506a301e773Splunky 			$$ = $2;
507a301e773Splunky 			$$->n_left = $3;
508c4627bc7Sgmcgarry 		}
509c4627bc7Sgmcgarry 		|  '(' abstract_declarator ')' { $$ = $2; }
5109a43ec58Splunky 		|  '[' maybe_r ']' attr_var {
511a301e773Splunky 			$$ = block(LB, bdty(NAME, NULL), bcon(NOOFFSET),
5129a43ec58Splunky 			    INT, 0, gcc_attr_wrapper($4));
513c4627bc7Sgmcgarry 		}
5143eb51a41Splunky 		|  '[' e ']' attr_var {
515a301e773Splunky 			$$ = block(LB, bdty(NAME, NULL), $2,
5162d03e475Splunky 			    INT, 0, gcc_attr_wrapper($4));
517c4627bc7Sgmcgarry 		}
5189a43ec58Splunky 		|  abstract_declarator '[' maybe_r ']' attr_var {
519a301e773Splunky 			$$ = block(LB, $1, bcon(NOOFFSET),
5209a43ec58Splunky 			    INT, 0, gcc_attr_wrapper($5));
5216e0bca22Sgmcgarry 		}
5223eb51a41Splunky 		|  abstract_declarator '[' e ']' attr_var {
5232d03e475Splunky 			$$ = block(LB, $1, $3, INT, 0, gcc_attr_wrapper($5));
5246e0bca22Sgmcgarry 		}
5255eacabfdSplunky 		|  '(' ')' attr_var {
5265eacabfdSplunky 			$$ = bdty(UCALL, bdty(NAME, NULL));
5272d03e475Splunky 			$$->n_ap = gcc_attr_wrapper($3);
5286e0bca22Sgmcgarry 		}
5295eacabfdSplunky 		|  '(' ib2 parameter_type_list ')' attr_var {
5305eacabfdSplunky 			$$ = block(CALL, bdty(NAME, NULL), $3, INT, 0,
5312d03e475Splunky 			    gcc_attr_wrapper($5));
5326e0bca22Sgmcgarry 		}
5335eacabfdSplunky 		|  abstract_declarator '(' ')' attr_var {
534*c555ae24Splunky 			$$ = block(UCALL, $1, NULL, INT, 0, gcc_attr_wrapper($4));
5355eacabfdSplunky 		}
5365eacabfdSplunky 		|  abstract_declarator '(' ib2 parameter_type_list ')' attr_var {
5372d03e475Splunky 			$$ = block(CALL, $1, $4, INT, 0, gcc_attr_wrapper($6));
5386e0bca22Sgmcgarry 		}
5396e0bca22Sgmcgarry 		;
5406e0bca22Sgmcgarry 
541a301e773Splunky ib2:		   { }
542c4627bc7Sgmcgarry 		;
5439a43ec58Splunky 
5449a43ec58Splunky maybe_r:	   { }
545*c555ae24Splunky 		|  C_QUALIFIER { }
5469a43ec58Splunky 		;
5479a43ec58Splunky 
5486e0bca22Sgmcgarry /*
5496e0bca22Sgmcgarry  * K&R arg declaration, between ) and {
5506e0bca22Sgmcgarry  */
5516e0bca22Sgmcgarry arg_dcl_list:	   arg_declaration
5526e0bca22Sgmcgarry 		|  arg_dcl_list arg_declaration
5536e0bca22Sgmcgarry 		;
5546e0bca22Sgmcgarry 
5556e0bca22Sgmcgarry 
5566e0bca22Sgmcgarry arg_declaration:   declaration_specifiers arg_param_list ';' {
557*c555ae24Splunky 			p1nfree($1);
5586e0bca22Sgmcgarry 		}
5596e0bca22Sgmcgarry 		;
5606e0bca22Sgmcgarry 
561a301e773Splunky arg_param_list:	   declarator attr_var {
562*c555ae24Splunky 			olddecl(block(TYMERGE, p1tcopy($<nodep>0), $1,
563a301e773Splunky 			    INT, 0, 0), $2);
564a301e773Splunky 		}
565c4627bc7Sgmcgarry 		|  arg_param_list ',' declarator attr_var {
566*c555ae24Splunky 			olddecl(block(TYMERGE, p1tcopy($<nodep>0), $3,
567a301e773Splunky 			    INT, 0, 0), $4);
5686e0bca22Sgmcgarry 		}
5696e0bca22Sgmcgarry 		;
5706e0bca22Sgmcgarry 
5716e0bca22Sgmcgarry /*
5726e0bca22Sgmcgarry  * Declarations in beginning of blocks.
5736e0bca22Sgmcgarry  */
5746e0bca22Sgmcgarry block_item_list:   block_item
5756e0bca22Sgmcgarry 		|  block_item_list block_item
5766e0bca22Sgmcgarry 		;
5776e0bca22Sgmcgarry 
5786e0bca22Sgmcgarry block_item:	   declaration
579*c555ae24Splunky 		|  statement { stmtfree(); }
5806e0bca22Sgmcgarry 		;
5816e0bca22Sgmcgarry 
5826e0bca22Sgmcgarry /*
5836e0bca22Sgmcgarry  * Here starts the old YACC code.
5846e0bca22Sgmcgarry  */
5856e0bca22Sgmcgarry 
5866e0bca22Sgmcgarry /*
5876e0bca22Sgmcgarry  * Variables are declared in init_declarator.
5886e0bca22Sgmcgarry  */
589*c555ae24Splunky declaration:	   declaration_specifiers ';' { p1tfree($1); fun_inline = 0; }
5906e0bca22Sgmcgarry 		|  declaration_specifiers init_declarator_list ';' {
591*c555ae24Splunky 			p1tfree($1);
5926e0bca22Sgmcgarry 			fun_inline = 0;
5936e0bca22Sgmcgarry 		}
594*c555ae24Splunky 		|  C_STATICASSERT '(' e ',' string ')' ';' {
595*c555ae24Splunky 			int r = con_e($3);
596*c555ae24Splunky 			if (r == 0) /* false */
597*c555ae24Splunky 				uerror($5);
598*c555ae24Splunky 		}
5996e0bca22Sgmcgarry 		;
6006e0bca22Sgmcgarry 
6016e0bca22Sgmcgarry /*
6026e0bca22Sgmcgarry  * Normal declaration of variables. curtype contains the current type node.
6036e0bca22Sgmcgarry  * Returns nothing, variables are declared in init_declarator.
6046e0bca22Sgmcgarry  */
6056e0bca22Sgmcgarry init_declarator_list:
606a301e773Splunky 		   init_declarator { symclear(blevel); }
607c4627bc7Sgmcgarry 		|  init_declarator_list ',' attr_var { $<nodep>$ = $<nodep>0; } init_declarator {
608a301e773Splunky 			uawarn($3, "init_declarator");
609a301e773Splunky 			symclear(blevel);
610c4627bc7Sgmcgarry 		}
6116e0bca22Sgmcgarry 		;
6126e0bca22Sgmcgarry 
6136e0bca22Sgmcgarry enum_dcl:	   enum_head '{' moe_list optcomma '}' { $$ = enumdcl($1); }
6146e0bca22Sgmcgarry 		|  C_ENUM C_NAME {  $$ = enumref($2); }
6156e0bca22Sgmcgarry 		;
6166e0bca22Sgmcgarry 
6176e0bca22Sgmcgarry enum_head:	   C_ENUM { $$ = enumhd(NULL); }
6186e0bca22Sgmcgarry 		|  C_ENUM C_NAME {  $$ = enumhd($2); }
6196e0bca22Sgmcgarry 		;
6206e0bca22Sgmcgarry 
6216e0bca22Sgmcgarry moe_list:	   moe
6226e0bca22Sgmcgarry 		|  moe_list ',' moe
6236e0bca22Sgmcgarry 		;
6246e0bca22Sgmcgarry 
6256e0bca22Sgmcgarry moe:		   C_NAME {  moedef($1); }
6266e0bca22Sgmcgarry 		|  C_TYPENAME {  moedef($1); }
6273eb51a41Splunky 		|  C_NAME '=' e { enummer = con_e($3); moedef($1); }
6283eb51a41Splunky 		|  C_TYPENAME '=' e { enummer = con_e($3); moedef($1); }
6296e0bca22Sgmcgarry 		;
6306e0bca22Sgmcgarry 
631a301e773Splunky struct_dcl:	   str_head '{' struct_dcl_list '}' {
632*c555ae24Splunky 			P1ND *p;
633a301e773Splunky 
634a301e773Splunky 			$$ = dclstruct($1);
635a301e773Splunky 			if (pragma_allpacked) {
636a301e773Splunky 				p = bdty(CALL, bdty(NAME, "packed"),
637a301e773Splunky 				    bcon(pragma_allpacked));
6382d03e475Splunky 				$$->n_ap = attr_add($$->n_ap,gcc_attr_wrapper(p)); }
6396e0bca22Sgmcgarry 		}
640a301e773Splunky 		|  C_STRUCT attr_var C_NAME {
641a301e773Splunky 			$$ = rstruct($3,$1);
642a301e773Splunky 			uawarn($2, "struct_dcl");
6436e0bca22Sgmcgarry 		}
644c4627bc7Sgmcgarry  /*COMPAT_GCC*/	|  str_head '{' '}' { $$ = dclstruct($1); }
6456e0bca22Sgmcgarry 		;
6466e0bca22Sgmcgarry 
647c4627bc7Sgmcgarry attr_var:	   {
648*c555ae24Splunky 			P1ND *q, *p;
649c4627bc7Sgmcgarry 
650c4627bc7Sgmcgarry 			p = pragma_aligned ? bdty(CALL, bdty(NAME, "aligned"),
651*c555ae24Splunky 			    bcon(pragma_aligned)) : NULL;
652c4627bc7Sgmcgarry 			if (pragma_packed) {
653c4627bc7Sgmcgarry 				q = bdty(NAME, "packed");
654*c555ae24Splunky 				p = (p == NULL ? q : cmop(p, q));
655c4627bc7Sgmcgarry 			}
656c4627bc7Sgmcgarry 			pragma_aligned = pragma_packed = 0;
657c4627bc7Sgmcgarry 			$$ = p;
658c4627bc7Sgmcgarry 		}
659c4627bc7Sgmcgarry  /*COMPAT_GCC*/	|  attr_spec_list
6606e0bca22Sgmcgarry 		;
6616e0bca22Sgmcgarry 
662c4627bc7Sgmcgarry attr_spec_list:	   attribute_specifier
663c4627bc7Sgmcgarry 		|  attr_spec_list attribute_specifier { $$ = cmop($1, $2); }
664c4627bc7Sgmcgarry 		;
665c4627bc7Sgmcgarry 
666c4627bc7Sgmcgarry str_head:	   C_STRUCT attr_var {  $$ = bstruct(NULL, $1, $2);  }
667c4627bc7Sgmcgarry 		|  C_STRUCT attr_var C_NAME {  $$ = bstruct($3, $1, $2);  }
6686e0bca22Sgmcgarry 		;
6696e0bca22Sgmcgarry 
6706e0bca22Sgmcgarry struct_dcl_list:   struct_declaration
6716e0bca22Sgmcgarry 		|  struct_dcl_list struct_declaration
6726e0bca22Sgmcgarry 		;
6736e0bca22Sgmcgarry 
6746e0bca22Sgmcgarry struct_declaration:
675c4627bc7Sgmcgarry 		   specifier_qualifier_list struct_declarator_list optsemi {
676*c555ae24Splunky 			p1tfree($1);
6776e0bca22Sgmcgarry 		}
6786e0bca22Sgmcgarry 		;
6796e0bca22Sgmcgarry 
680c4627bc7Sgmcgarry optsemi:	   ';' { }
681c4627bc7Sgmcgarry 		|  optsemi ';' { werror("extra ; in struct"); }
682c4627bc7Sgmcgarry 		;
683c4627bc7Sgmcgarry 
6846e0bca22Sgmcgarry specifier_qualifier_list:
6856e0bca22Sgmcgarry 		   merge_specifiers { $$ = typenode($1); }
6866e0bca22Sgmcgarry 		;
6876e0bca22Sgmcgarry 
688c4627bc7Sgmcgarry merge_specifiers:  type_sq merge_specifiers { $$ = cmop($2, $1); }
689c4627bc7Sgmcgarry 		|  type_sq { $$ = $1; }
6906e0bca22Sgmcgarry 		;
6916e0bca22Sgmcgarry 
6926e0bca22Sgmcgarry struct_declarator_list:
693a301e773Splunky 		   struct_declarator { symclear(blevel); }
6946e0bca22Sgmcgarry 		|  struct_declarator_list ',' { $<nodep>$=$<nodep>0; }
695a301e773Splunky 			struct_declarator { symclear(blevel); }
6966e0bca22Sgmcgarry 		;
6976e0bca22Sgmcgarry 
698c4627bc7Sgmcgarry struct_declarator: declarator attr_var {
699*c555ae24Splunky 			P1ND *p;
700a301e773Splunky 
701a301e773Splunky 			$1 = aryfix($1);
702a301e773Splunky 			p = tymerge($<nodep>0, tymfix($1));
703a301e773Splunky 			if ($2)
7042d03e475Splunky 				p->n_ap = attr_add(p->n_ap, gcc_attr_wrapper($2));
705a301e773Splunky 			soumemb(p, (char *)$1->n_sp, 0);
706*c555ae24Splunky 			p1tfree(p);
7076e0bca22Sgmcgarry 		}
7083eb51a41Splunky 		|  ':' e {
7093eb51a41Splunky 			int ie = con_e($2);
7103eb51a41Splunky 			if (fldchk(ie))
7113eb51a41Splunky 				ie = 1;
7123eb51a41Splunky 			falloc(NULL, ie, $<nodep>0);
7136e0bca22Sgmcgarry 		}
7143eb51a41Splunky 		|  declarator ':' e {
7153eb51a41Splunky 			int ie = con_e($3);
7163eb51a41Splunky 			if (fldchk(ie))
7173eb51a41Splunky 				ie = 1;
7186e0bca22Sgmcgarry 			if ($1->n_op == NAME) {
719a301e773Splunky 				/* XXX - tymfix() may alter $1 */
720a301e773Splunky 				tymerge($<nodep>0, tymfix($1));
721a301e773Splunky 				soumemb($1, (char *)$1->n_sp, FIELD | ie);
722*c555ae24Splunky 				p1nfree($1);
723a301e773Splunky 			} else
724a301e773Splunky 				uerror("illegal declarator");
725a301e773Splunky 		}
726a301e773Splunky 		|  declarator ':' e attr_spec_list {
727a301e773Splunky 			int ie = con_e($3);
728a301e773Splunky 			if (fldchk(ie))
729a301e773Splunky 				ie = 1;
730a301e773Splunky 			if ($1->n_op == NAME) {
731a301e773Splunky 				/* XXX - tymfix() may alter $1 */
732a301e773Splunky 				tymerge($<nodep>0, tymfix($1));
733a301e773Splunky 				if ($4)
734a301e773Splunky 					$1->n_ap = attr_add($1->n_ap,
7352d03e475Splunky 					    gcc_attr_wrapper($4));
7363eb51a41Splunky 				soumemb($1, (char *)$1->n_sp, FIELD | ie);
737*c555ae24Splunky 				p1nfree($1);
7386e0bca22Sgmcgarry 			} else
7396e0bca22Sgmcgarry 				uerror("illegal declarator");
7406e0bca22Sgmcgarry 		}
741c4627bc7Sgmcgarry 		| /* unnamed member */ {
742*c555ae24Splunky 			P1ND *p = $<nodep>0;
743c4627bc7Sgmcgarry 			char *c = permalloc(10);
744c4627bc7Sgmcgarry 
745c4627bc7Sgmcgarry 			if (p->n_type != STRTY && p->n_type != UNIONTY)
746c4627bc7Sgmcgarry 				uerror("bad unnamed member type");
747c4627bc7Sgmcgarry 			snprintf(c, 10, "*%dFAKE", getlab());
748c4627bc7Sgmcgarry 			soumemb(p, c, 0);
749c4627bc7Sgmcgarry 		}
7506e0bca22Sgmcgarry 		;
7516e0bca22Sgmcgarry 
7526e0bca22Sgmcgarry 		/* always preceeded by attributes */
753c4627bc7Sgmcgarry xnfdeclarator:	   declarator attr_var {
7542d03e475Splunky 			$$ = xnf = init_declarator($<nodep>0, $1, 1, $2, 0);
755c4627bc7Sgmcgarry 		}
756*c555ae24Splunky 		|  declarator C_ASM '(' svstr ')' {
757*c555ae24Splunky 			$$ = xnf = init_declarator($<nodep>0, $1, 1, NULL, $4);
7583eb51a41Splunky 		}
7596e0bca22Sgmcgarry 		;
7606e0bca22Sgmcgarry 
7616e0bca22Sgmcgarry /*
7626e0bca22Sgmcgarry  * Handles declarations and assignments.
7636e0bca22Sgmcgarry  * Returns nothing.
7646e0bca22Sgmcgarry  */
7652d03e475Splunky init_declarator:   declarator attr_var {
7662d03e475Splunky 			init_declarator($<nodep>0, $1, 0, $2, 0);
7672d03e475Splunky 		}
768*c555ae24Splunky 		|  declarator C_ASM '(' svstr ')' attr_var {
769*c555ae24Splunky 			init_declarator($<nodep>0, $1, 0, $6, $4);
7706e0bca22Sgmcgarry 		}
771a301e773Splunky 		|  xnfdeclarator '=' e {
772a301e773Splunky 			if ($1->sclass == STATIC || $1->sclass == EXTDEF)
773a301e773Splunky 				statinit++;
774a301e773Splunky 			simpleinit($1, eve($3));
775a301e773Splunky 			if ($1->sclass == STATIC || $1->sclass == EXTDEF)
776a301e773Splunky 				statinit--;
7776e0bca22Sgmcgarry 			xnf = NULL;
7786e0bca22Sgmcgarry 		}
779a301e773Splunky 		|  xnfdeclarator '=' begbr init_list optcomma '}' {
780a301e773Splunky 			endinit(0);
781a301e773Splunky 			xnf = NULL;
782a301e773Splunky 		}
783a301e773Splunky  /*COMPAT_GCC*/	|  xnfdeclarator '=' begbr '}' { endinit(0); xnf = NULL; }
7846e0bca22Sgmcgarry 		;
7856e0bca22Sgmcgarry 
7866e0bca22Sgmcgarry begbr:		   '{' { beginit($<symp>-1); }
7876e0bca22Sgmcgarry 		;
7886e0bca22Sgmcgarry 
789c4627bc7Sgmcgarry initializer:	   e %prec ',' {  $$ = eve($1); }
7906e0bca22Sgmcgarry 		|  ibrace init_list optcomma '}' { $$ = NULL; }
791c4627bc7Sgmcgarry 		|  ibrace '}' { asginit(bcon(0)); $$ = NULL; }
7926e0bca22Sgmcgarry 		;
7936e0bca22Sgmcgarry 
7943eb51a41Splunky init_list:	   designation initializer { dainit($1, $2); }
7953eb51a41Splunky 		|  init_list ','  designation initializer { dainit($3, $4); }
7966e0bca22Sgmcgarry 		;
7976e0bca22Sgmcgarry 
798*c555ae24Splunky designation:	   designator_list '=' { desinit($1); $$ = NULL; }
799*c555ae24Splunky 		|  GCC_DESIG { desinit(bdty(NAME, $1)); $$ = NULL; }
8003eb51a41Splunky 		|  '[' e C_ELLIPSIS e ']' '=' { $$ = biop(CM, $2, $4); }
801*c555ae24Splunky 		|  { $$ = NULL; }
8026e0bca22Sgmcgarry 		;
8036e0bca22Sgmcgarry 
8046e0bca22Sgmcgarry designator_list:   designator { $$ = $1; }
8056e0bca22Sgmcgarry 		|  designator_list designator { $$ = $2; $$->n_left = $1; }
8066e0bca22Sgmcgarry 		;
8076e0bca22Sgmcgarry 
8083eb51a41Splunky designator:	   '[' e ']' {
8093eb51a41Splunky 			int ie = con_e($2);
8103eb51a41Splunky 			if (ie < 0) {
8116e0bca22Sgmcgarry 				uerror("designator must be non-negative");
8123eb51a41Splunky 				ie = 0;
8136e0bca22Sgmcgarry 			}
814*c555ae24Splunky 			$$ = biop(LB, NULL, bcon(ie));
8156e0bca22Sgmcgarry 		}
816a301e773Splunky 		|  C_STROP C_TYPENAME {
817a301e773Splunky 			if ($1 != DOT)
818a301e773Splunky 				uerror("invalid designator");
819a301e773Splunky 			$$ = bdty(NAME, $2);
820a301e773Splunky 		}
8216e0bca22Sgmcgarry 		|  C_STROP C_NAME {
8226e0bca22Sgmcgarry 			if ($1 != DOT)
8236e0bca22Sgmcgarry 				uerror("invalid designator");
8246e0bca22Sgmcgarry 			$$ = bdty(NAME, $2);
8256e0bca22Sgmcgarry 		}
8266e0bca22Sgmcgarry 		;
8276e0bca22Sgmcgarry 
8286e0bca22Sgmcgarry optcomma	:	/* VOID */
8296e0bca22Sgmcgarry 		|  ','
8306e0bca22Sgmcgarry 		;
8316e0bca22Sgmcgarry 
8326e0bca22Sgmcgarry ibrace:		   '{' {  ilbrace(); }
8336e0bca22Sgmcgarry 		;
8346e0bca22Sgmcgarry 
8356e0bca22Sgmcgarry /*	STATEMENTS	*/
8366e0bca22Sgmcgarry 
8376e0bca22Sgmcgarry compoundstmt:	   begin block_item_list '}' { flend(); }
8386e0bca22Sgmcgarry 		|  begin '}' { flend(); }
8396e0bca22Sgmcgarry 		;
8406e0bca22Sgmcgarry 
8416e0bca22Sgmcgarry begin:		  '{' {
842*c555ae24Splunky 			struct savbc *bc = malloc(sizeof(struct savbc));
8436e0bca22Sgmcgarry 			if (blevel == 1) {
8446e0bca22Sgmcgarry #ifdef STABS
8456e0bca22Sgmcgarry 				if (gflag)
8466e0bca22Sgmcgarry 					stabs_line(lineno);
8476e0bca22Sgmcgarry #endif
8486e0bca22Sgmcgarry 				dclargs();
8496e0bca22Sgmcgarry 			}
8506e0bca22Sgmcgarry #ifdef STABS
8516e0bca22Sgmcgarry 			if (gflag && blevel > 1)
8526e0bca22Sgmcgarry 				stabs_lbrac(blevel+1);
8536e0bca22Sgmcgarry #endif
8546e0bca22Sgmcgarry 			++blevel;
8556e0bca22Sgmcgarry 			oldstyle = 0;
8566e0bca22Sgmcgarry 			bc->contlab = autooff;
8576e0bca22Sgmcgarry 			bc->next = savctx;
858*c555ae24Splunky 			bc->bkptr = bkpole;
859*c555ae24Splunky 			bc->bkoff = cbkp;
860*c555ae24Splunky 			bc->stptr = sapole;
861*c555ae24Splunky 			bc->stoff = cstp;
862*c555ae24Splunky 			bc->numnode = usdnodes;
863*c555ae24Splunky 			usdnodes = 0;
864*c555ae24Splunky 			bkpole = sapole = NULL;
865*c555ae24Splunky 			cbkp = cstp = 0;
8666e0bca22Sgmcgarry 			savctx = bc;
867a301e773Splunky 			if (!isinlining && sspflag && blevel == 2)
8686e0bca22Sgmcgarry 				sspstart();
8696e0bca22Sgmcgarry 		}
8706e0bca22Sgmcgarry 		;
8716e0bca22Sgmcgarry 
872c4627bc7Sgmcgarry statement:	   e ';' { ecomp(eve($1)); symclear(blevel); }
8736e0bca22Sgmcgarry 		|  compoundstmt
8746e0bca22Sgmcgarry 		|  ifprefix statement { plabel($1); reached = 1; }
8756e0bca22Sgmcgarry 		|  ifelprefix statement {
8766e0bca22Sgmcgarry 			if ($1 != NOLAB) {
8776e0bca22Sgmcgarry 				plabel( $1);
8786e0bca22Sgmcgarry 				reached = 1;
8796e0bca22Sgmcgarry 			}
8806e0bca22Sgmcgarry 		}
8816e0bca22Sgmcgarry 		|  whprefix statement {
8826e0bca22Sgmcgarry 			branch(contlab);
8836e0bca22Sgmcgarry 			plabel( brklab );
8846e0bca22Sgmcgarry 			if( (flostat&FBRK) || !(flostat&FLOOP))
8856e0bca22Sgmcgarry 				reached = 1;
8866e0bca22Sgmcgarry 			else
8876e0bca22Sgmcgarry 				reached = 0;
8886e0bca22Sgmcgarry 			resetbc(0);
8896e0bca22Sgmcgarry 		}
8906e0bca22Sgmcgarry 		|  doprefix statement C_WHILE '(' e ')' ';' {
8916e0bca22Sgmcgarry 			plabel(contlab);
8926e0bca22Sgmcgarry 			if (flostat & FCONT)
8936e0bca22Sgmcgarry 				reached = 1;
8946e0bca22Sgmcgarry 			if (reached)
895a301e773Splunky 				cbranch(buildtree(NE, eve($5), bcon(0)),
896a301e773Splunky 				    bcon($1));
8976e0bca22Sgmcgarry 			else
898*c555ae24Splunky 				p1tfree(eve($5));
8996e0bca22Sgmcgarry 			plabel( brklab);
9006e0bca22Sgmcgarry 			reached = 1;
9016e0bca22Sgmcgarry 			resetbc(0);
9026e0bca22Sgmcgarry 		}
9036e0bca22Sgmcgarry 		|  forprefix .e ')' statement
9046e0bca22Sgmcgarry 			{  plabel( contlab );
9056e0bca22Sgmcgarry 			    if( flostat&FCONT ) reached = 1;
9066e0bca22Sgmcgarry 			    if( $2 ) ecomp( $2 );
9076e0bca22Sgmcgarry 			    branch($1);
9086e0bca22Sgmcgarry 			    plabel( brklab );
9096e0bca22Sgmcgarry 			    if( (flostat&FBRK) || !(flostat&FLOOP) ) reached = 1;
9106e0bca22Sgmcgarry 			    else reached = 0;
9116e0bca22Sgmcgarry 			    resetbc(0);
9122d03e475Splunky 			    blevel--;
9132d03e475Splunky 			    symclear(blevel);
9146e0bca22Sgmcgarry 			    }
9156e0bca22Sgmcgarry 		| switchpart statement
9166e0bca22Sgmcgarry 			{ if( reached ) branch( brklab );
9176e0bca22Sgmcgarry 			    plabel( $1 );
9186e0bca22Sgmcgarry 			    swend();
9196e0bca22Sgmcgarry 			    plabel( brklab);
9206e0bca22Sgmcgarry 			    if( (flostat&FBRK) || !(flostat&FDEF) ) reached = 1;
9216e0bca22Sgmcgarry 			    resetbc(FCONT);
9226e0bca22Sgmcgarry 			    }
9236e0bca22Sgmcgarry 		|  C_BREAK  ';' {
9246e0bca22Sgmcgarry 			if (brklab == NOLAB)
9256e0bca22Sgmcgarry 				uerror("illegal break");
9266e0bca22Sgmcgarry 			else if (reached)
9276e0bca22Sgmcgarry 				branch(brklab);
9286e0bca22Sgmcgarry 			flostat |= FBRK;
9296e0bca22Sgmcgarry 			reached = 0;
9306e0bca22Sgmcgarry 		}
9316e0bca22Sgmcgarry 		|  C_CONTINUE  ';' {
9326e0bca22Sgmcgarry 			if (contlab == NOLAB)
9336e0bca22Sgmcgarry 				uerror("illegal continue");
9346e0bca22Sgmcgarry 			else
9356e0bca22Sgmcgarry 				branch(contlab);
9366e0bca22Sgmcgarry 			flostat |= FCONT;
9376e0bca22Sgmcgarry 			goto rch;
9386e0bca22Sgmcgarry 		}
9396e0bca22Sgmcgarry 		|  C_RETURN  ';' {
9406e0bca22Sgmcgarry 			branch(retlab);
9416e0bca22Sgmcgarry 			if (cftnsp->stype != VOID &&
9426e0bca22Sgmcgarry 			    (cftnsp->sflags & NORETYP) == 0 &&
9436e0bca22Sgmcgarry 			    cftnsp->stype != VOID+FTN)
9446e0bca22Sgmcgarry 				uerror("return value required");
9456e0bca22Sgmcgarry 			rch:
946a301e773Splunky 			if (!reached)
947*c555ae24Splunky 				warner(Wunreachable_code);
9486e0bca22Sgmcgarry 			reached = 0;
9496e0bca22Sgmcgarry 		}
9506e0bca22Sgmcgarry 		|  C_RETURN e  ';' {
951*c555ae24Splunky 			P1ND *p, *q;
9526e0bca22Sgmcgarry 
953c4627bc7Sgmcgarry 			p = nametree(cftnsp);
954c4627bc7Sgmcgarry 			p->n_type = DECREF(p->n_type);
955c4627bc7Sgmcgarry 			q = eve($2);
9562d03e475Splunky #ifdef TARGET_TIMODE
957*c555ae24Splunky 			P1ND *r;
9582d03e475Splunky 			if ((r = gcc_eval_ticast(RETURN, p, q)) != NULL)
9592d03e475Splunky 				q = r;
9602d03e475Splunky #endif
961c4627bc7Sgmcgarry #ifndef NO_COMPLEX
962c4627bc7Sgmcgarry 			if (ANYCX(q) || ANYCX(p))
963c4627bc7Sgmcgarry 				q = cxret(q, p);
964*c555ae24Splunky 			else if (ISITY(p->n_type) || ISITY(q->n_type)) {
965*c555ae24Splunky 				q = imret(q, p);
966*c555ae24Splunky 				if (ISITY(p->n_type))
967*c555ae24Splunky 					p->n_type -= (FIMAG-FLOAT);
968*c555ae24Splunky 				if (ISITY(q->n_type))
969*c555ae24Splunky 					q->n_type -= (FIMAG-FLOAT);
970*c555ae24Splunky 			}
971c4627bc7Sgmcgarry #endif
972c4627bc7Sgmcgarry 			p = buildtree(RETURN, p, q);
973c4627bc7Sgmcgarry 			if (p->n_type == VOID) {
974c4627bc7Sgmcgarry 				ecomp(p->n_right);
975c4627bc7Sgmcgarry 			} else {
976*c555ae24Splunky 				if (cftnod == NULL) {
977*c555ae24Splunky 					P1ND *r = tempnode(0, p->n_type,
978a301e773Splunky 					    p->n_df, p->n_ap);
979*c555ae24Splunky 					cftnod = tmpalloc(sizeof(P1ND));
980*c555ae24Splunky 					*cftnod = *r;
981*c555ae24Splunky 					p1tfree(r);
982c4627bc7Sgmcgarry 				}
983*c555ae24Splunky 				ecomp(buildtree(ASSIGN,
984*c555ae24Splunky 				    p1tcopy(cftnod), p->n_right));
985*c555ae24Splunky 			}
986*c555ae24Splunky 			p1tfree(p->n_left);
987*c555ae24Splunky 			p1nfree(p);
9886e0bca22Sgmcgarry 			branch(retlab);
9896e0bca22Sgmcgarry 			reached = 0;
9906e0bca22Sgmcgarry 		}
9916e0bca22Sgmcgarry 		|  C_GOTO C_NAME ';' { gotolabel($2); goto rch; }
992*c555ae24Splunky 		|  C_GOTO '*' e ';' { ecomp(biop(GOTO, eve($3), NULL)); }
9936e0bca22Sgmcgarry 		|  asmstatement ';'
9946e0bca22Sgmcgarry 		|   ';'
9956e0bca22Sgmcgarry 		|  error  ';'
9966e0bca22Sgmcgarry 		|  error '}'
9976e0bca22Sgmcgarry 		|  label statement
9986e0bca22Sgmcgarry 		;
9996e0bca22Sgmcgarry 
1000*c555ae24Splunky asmstatement:	   C_ASM mvol '(' svstr ')' { send_passt(IP_ASM, mkpstr($4)); }
1001*c555ae24Splunky 		|  C_ASM mvol '(' svstr xasm ')' { mkxasm($4, $5); }
1002*c555ae24Splunky 		;
1003*c555ae24Splunky 
1004*c555ae24Splunky svstr:		  string { $$ = addstring($1); }
10056e0bca22Sgmcgarry 		;
10066e0bca22Sgmcgarry 
10076e0bca22Sgmcgarry mvol:		   /* empty */
1008*c555ae24Splunky 		|  C_QUALIFIER { }
10096e0bca22Sgmcgarry 		;
10106e0bca22Sgmcgarry 
1011*c555ae24Splunky xasm:		   ':' oplist { $$ = xcmop($2, NULL, NULL); }
1012*c555ae24Splunky 		|  ':' oplist ':' oplist { $$ = xcmop($2, $4, NULL); }
10136e0bca22Sgmcgarry 		|  ':' oplist ':' oplist ':' cnstr { $$ = xcmop($2, $4, $6); }
10146e0bca22Sgmcgarry 		;
10156e0bca22Sgmcgarry 
1016*c555ae24Splunky oplist:		   /* nothing */ { $$ = NULL; }
10176e0bca22Sgmcgarry 		|  oper { $$ = $1; }
10186e0bca22Sgmcgarry 		;
10196e0bca22Sgmcgarry 
1020*c555ae24Splunky oper:		   svstr '(' e ')' { $$ = xasmop($1, pconvert(eve($3))); }
1021*c555ae24Splunky 		|  oper ',' svstr '(' e ')' {
10222d03e475Splunky 			$$ = cmop($1, xasmop($3, pconvert(eve($5))));
1023c4627bc7Sgmcgarry 		}
10246e0bca22Sgmcgarry 		;
10256e0bca22Sgmcgarry 
1026*c555ae24Splunky cnstr:		   svstr { $$ = xasmop($1, bcon(0)); }
1027*c555ae24Splunky 		|  cnstr ',' svstr { $$ = cmop($1, xasmop($3, bcon(0))); }
10286e0bca22Sgmcgarry                 ;
10296e0bca22Sgmcgarry 
1030a301e773Splunky label:		   C_NAME ':' attr_var { deflabel($1, $3); reached = 1; }
1031a301e773Splunky 		|  C_TYPENAME ':' attr_var { deflabel($1, $3); reached = 1; }
1032c4627bc7Sgmcgarry 		|  C_CASE e ':' { addcase(eve($2)); reached = 1; }
1033c4627bc7Sgmcgarry /* COMPAT_GCC */|  C_CASE e C_ELLIPSIS e ':' {
1034c4627bc7Sgmcgarry #ifdef GCC_COMPAT
1035c4627bc7Sgmcgarry 			gcccase(eve($2), eve($4)); reached = 1;
1036c4627bc7Sgmcgarry #endif
1037c4627bc7Sgmcgarry 		}
10386e0bca22Sgmcgarry 		|  C_DEFAULT ':' { reached = 1; adddef(); flostat |= FDEF; }
10396e0bca22Sgmcgarry 		;
10406e0bca22Sgmcgarry 
10416e0bca22Sgmcgarry doprefix:	C_DO {
10426e0bca22Sgmcgarry 			savebc();
10436e0bca22Sgmcgarry 			brklab = getlab();
10446e0bca22Sgmcgarry 			contlab = getlab();
10456e0bca22Sgmcgarry 			plabel(  $$ = getlab());
10466e0bca22Sgmcgarry 			reached = 1;
10476e0bca22Sgmcgarry 		}
10486e0bca22Sgmcgarry 		;
10496e0bca22Sgmcgarry ifprefix:	C_IF '(' e ')' {
10502d03e475Splunky 			xcbranch(eve($3), $$ = getlab());
10516e0bca22Sgmcgarry 			reached = 1;
10526e0bca22Sgmcgarry 		}
10536e0bca22Sgmcgarry 		;
10546e0bca22Sgmcgarry ifelprefix:	  ifprefix statement C_ELSE {
10556e0bca22Sgmcgarry 			if (reached)
10566e0bca22Sgmcgarry 				branch($$ = getlab());
10576e0bca22Sgmcgarry 			else
10586e0bca22Sgmcgarry 				$$ = NOLAB;
10596e0bca22Sgmcgarry 			plabel( $1);
10606e0bca22Sgmcgarry 			reached = 1;
10616e0bca22Sgmcgarry 		}
10626e0bca22Sgmcgarry 		;
10636e0bca22Sgmcgarry 
10646e0bca22Sgmcgarry whprefix:	  C_WHILE  '('  e  ')' {
10656e0bca22Sgmcgarry 			savebc();
1066c4627bc7Sgmcgarry 			$3 = eve($3);
1067*c555ae24Splunky 			if ($3->n_op == ICON && glval($3) != 0)
10686e0bca22Sgmcgarry 				flostat = FLOOP;
10696e0bca22Sgmcgarry 			plabel( contlab = getlab());
10706e0bca22Sgmcgarry 			reached = 1;
10716e0bca22Sgmcgarry 			brklab = getlab();
10726e0bca22Sgmcgarry 			if (flostat == FLOOP)
1073*c555ae24Splunky 				p1tfree($3);
10746e0bca22Sgmcgarry 			else
10752d03e475Splunky 				xcbranch($3, brklab);
10766e0bca22Sgmcgarry 		}
10776e0bca22Sgmcgarry 		;
10786e0bca22Sgmcgarry forprefix:	  C_FOR  '('  .e  ';' .e  ';' {
10792d03e475Splunky 			++blevel;
10806e0bca22Sgmcgarry 			if ($3)
10816e0bca22Sgmcgarry 				ecomp($3);
10826e0bca22Sgmcgarry 			savebc();
10836e0bca22Sgmcgarry 			contlab = getlab();
10846e0bca22Sgmcgarry 			brklab = getlab();
10856e0bca22Sgmcgarry 			plabel( $$ = getlab());
10866e0bca22Sgmcgarry 			reached = 1;
10876e0bca22Sgmcgarry 			if ($5)
10882d03e475Splunky 				xcbranch($5, brklab);
10896e0bca22Sgmcgarry 			else
10906e0bca22Sgmcgarry 				flostat |= FLOOP;
10916e0bca22Sgmcgarry 		}
1092c4627bc7Sgmcgarry 		|  C_FOR '(' { ++blevel; } declaration .e ';' {
10936e0bca22Sgmcgarry 			savebc();
10946e0bca22Sgmcgarry 			contlab = getlab();
10956e0bca22Sgmcgarry 			brklab = getlab();
10966e0bca22Sgmcgarry 			plabel( $$ = getlab());
10976e0bca22Sgmcgarry 			reached = 1;
10986e0bca22Sgmcgarry 			if ($5)
10992d03e475Splunky 				xcbranch($5, brklab);
11006e0bca22Sgmcgarry 			else
11016e0bca22Sgmcgarry 				flostat |= FLOOP;
11026e0bca22Sgmcgarry 		}
11036e0bca22Sgmcgarry 		;
11046e0bca22Sgmcgarry 
11056e0bca22Sgmcgarry switchpart:	   C_SWITCH  '('  e ')' {
1106*c555ae24Splunky 			P1ND *p;
11076e0bca22Sgmcgarry 			int num;
11086e0bca22Sgmcgarry 			TWORD t;
11096e0bca22Sgmcgarry 
11106e0bca22Sgmcgarry 			savebc();
11116e0bca22Sgmcgarry 			brklab = getlab();
1112c4627bc7Sgmcgarry 			$3 = eve($3);
1113a301e773Splunky 			if (!ISINTEGER($3->n_type)) {
11146e0bca22Sgmcgarry 				uerror("switch expression must have integer "
11156e0bca22Sgmcgarry 				       "type");
11166e0bca22Sgmcgarry 				t = INT;
11176e0bca22Sgmcgarry 			} else {
11186e0bca22Sgmcgarry 				$3 = intprom($3);
11196e0bca22Sgmcgarry 				t = $3->n_type;
11206e0bca22Sgmcgarry 			}
1121a301e773Splunky 			p = tempnode(0, t, 0, 0);
11226e0bca22Sgmcgarry 			num = regno(p);
11236e0bca22Sgmcgarry 			ecomp(buildtree(ASSIGN, p, $3));
11246e0bca22Sgmcgarry 			branch( $$ = getlab());
11256e0bca22Sgmcgarry 			swstart(num, t);
11266e0bca22Sgmcgarry 			reached = 0;
11276e0bca22Sgmcgarry 		}
11286e0bca22Sgmcgarry 		;
11296e0bca22Sgmcgarry /*	EXPRESSIONS	*/
1130c4627bc7Sgmcgarry .e:		   e { $$ = eve($1); }
11316e0bca22Sgmcgarry 		| 	{ $$=0; }
11326e0bca22Sgmcgarry 		;
11336e0bca22Sgmcgarry 
1134*c555ae24Splunky elist:		   { $$ = NULL; }
11352d03e475Splunky 		|  e2 { $$ = $1; }
11362d03e475Splunky 		;
11372d03e475Splunky 
11382d03e475Splunky e2:		   e %prec ','
11392d03e475Splunky 		|  e2  ','  e { $$ = biop(CM, $1, $3); }
11402d03e475Splunky 		|  e2  ','  cast_type { /* hack for stdarg */
1141a301e773Splunky 			TYMFIX($3);
11426e0bca22Sgmcgarry 			$3->n_op = TYPE;
1143c4627bc7Sgmcgarry 			$$ = biop(CM, $1, $3);
11446e0bca22Sgmcgarry 		}
1145*c555ae24Splunky 		|  cast_type { TYMFIX($1); $1->n_op = TYPE; $$ = $1; }
11466e0bca22Sgmcgarry 		;
11476e0bca22Sgmcgarry 
11486e0bca22Sgmcgarry /*
11496e0bca22Sgmcgarry  * Precedence order of operators.
11506e0bca22Sgmcgarry  */
1151c4627bc7Sgmcgarry e:		   e ',' e { $$ = biop(COMOP, $1, $3); }
1152c4627bc7Sgmcgarry 		|  e '=' e {  $$ = biop(ASSIGN, $1, $3); }
1153c4627bc7Sgmcgarry 		|  e C_ASOP e {  $$ = biop($2, $1, $3); }
11542d03e475Splunky 		|  e '?' e ':' e { $$=biop(QUEST, $1, biop(COLON, $3, $5)); }
11552d03e475Splunky /* COMPAT_GCC */|  e '?' ':' e { $$ = biop(BIQUEST, $1, $4); }
1156c4627bc7Sgmcgarry 		|  e C_OROR e { $$ = biop($2, $1, $3); }
1157c4627bc7Sgmcgarry 		|  e C_ANDAND e { $$ = biop($2, $1, $3); }
1158c4627bc7Sgmcgarry 		|  e '|' e { $$ = biop(OR, $1, $3); }
1159c4627bc7Sgmcgarry 		|  e '^' e { $$ = biop(ER, $1, $3); }
1160c4627bc7Sgmcgarry 		|  e '&' e { $$ = biop(AND, $1, $3); }
1161c4627bc7Sgmcgarry 		|  e C_EQUOP  e { $$ = biop($2, $1, $3); }
1162c4627bc7Sgmcgarry 		|  e C_RELOP e { $$ = biop($2, $1, $3); }
1163c4627bc7Sgmcgarry 		|  e C_SHIFTOP e { $$ = biop($2, $1, $3); }
1164c4627bc7Sgmcgarry 		|  e '+' e { $$ = biop(PLUS, $1, $3); }
1165c4627bc7Sgmcgarry 		|  e '-' e { $$ = biop(MINUS, $1, $3); }
1166c4627bc7Sgmcgarry 		|  e C_DIVOP e { $$ = biop($2, $1, $3); }
1167c4627bc7Sgmcgarry 		|  e '*' e { $$ = biop(MUL, $1, $3); }
11686e0bca22Sgmcgarry 		|  term
11696e0bca22Sgmcgarry 		;
11706e0bca22Sgmcgarry 
1171c4627bc7Sgmcgarry xbegin:		   begin {
1172c4627bc7Sgmcgarry 			$$ = getlab(); getlab(); getlab();
1173*c555ae24Splunky 			branch($$); plabel(($$)+2);
1174*c555ae24Splunky 		}
1175c4627bc7Sgmcgarry 		;
1176c4627bc7Sgmcgarry 
1177c4627bc7Sgmcgarry term:		   term C_INCOP {  $$ = biop($2, $1, bcon(1)); }
1178*c555ae24Splunky 		|  '*' term { $$ = biop(UMUL, $2, NULL); }
1179*c555ae24Splunky 		|  '&' term { $$ = biop(ADDROF, $2, NULL); }
1180*c555ae24Splunky 		|  '-' term { $$ = biop(UMINUS, $2, NULL ); }
1181*c555ae24Splunky 		|  '+' term { $$ = biop(UPLUS, $2, NULL ); }
1182*c555ae24Splunky 		|  C_UNOP term { $$ = biop($1, $2, NULL); }
11836e0bca22Sgmcgarry 		|  C_INCOP term {
1184c4627bc7Sgmcgarry 			$$ = biop($1 == INCR ? PLUSEQ : MINUSEQ, $2, bcon(1));
11856e0bca22Sgmcgarry 		}
1186c4627bc7Sgmcgarry 		|  C_SIZEOF xa term { $$ = biop(SZOF, $3, bcon(0)); inattr = $<intval>2; }
11876e0bca22Sgmcgarry 		|  '(' cast_type ')' term  %prec C_INCOP {
1188a301e773Splunky 			TYMFIX($2);
1189c4627bc7Sgmcgarry 			$$ = biop(CAST, $2, $4);
11906e0bca22Sgmcgarry 		}
1191c4627bc7Sgmcgarry 		|  C_SIZEOF xa '(' cast_type ')'  %prec C_SIZEOF {
1192c4627bc7Sgmcgarry 			$$ = biop(SZOF, $4, bcon(1));
1193c4627bc7Sgmcgarry 			inattr = $<intval>2;
11946e0bca22Sgmcgarry 		}
1195a301e773Splunky 		|  C_ALIGNOF xa '(' cast_type ')' {
1196a301e773Splunky 			int al;
1197a301e773Splunky 			TYMFIX($4);
1198a301e773Splunky 			al = talign($4->n_type, $4->n_ap);
1199a301e773Splunky 			$$ = bcon(al/SZCHAR);
1200a301e773Splunky 			inattr = $<intval>2;
1201*c555ae24Splunky 			p1tfree($4);
1202a301e773Splunky 		}
12036e0bca22Sgmcgarry 		| '(' cast_type ')' clbrace init_list optcomma '}' {
1204a301e773Splunky 			endinit(0);
1205a301e773Splunky 			$$ = bdty(NAME, $4);
1206a301e773Splunky 			$$->n_op = CLOP;
1207a301e773Splunky 		}
1208a301e773Splunky 		| '(' cast_type ')' clbrace '}' {
1209a301e773Splunky 			endinit(0);
1210c4627bc7Sgmcgarry 			$$ = bdty(NAME, $4);
1211c4627bc7Sgmcgarry 			$$->n_op = CLOP;
12126e0bca22Sgmcgarry 		}
1213c4627bc7Sgmcgarry 		|  term '[' e ']' { $$ = biop(LB, $1, $3); }
1214c4627bc7Sgmcgarry 		|  C_NAME  '(' elist ')' {
1215c4627bc7Sgmcgarry 			$$ = biop($3 ? CALL : UCALL, bdty(NAME, $1), $3);
12166e0bca22Sgmcgarry 		}
1217c4627bc7Sgmcgarry 		|  term  '(' elist ')' { $$ = biop($3 ? CALL : UCALL, $1, $3); }
1218c4627bc7Sgmcgarry 		|  term C_STROP C_NAME { $$ = biop($2, $1, bdty(NAME, $3)); }
1219c4627bc7Sgmcgarry 		|  term C_STROP C_TYPENAME { $$ = biop($2, $1, bdty(NAME, $3));}
1220c4627bc7Sgmcgarry 		|  C_NAME %prec C_SIZEOF /* below ( */{ $$ = bdty(NAME, $1); }
12213eb51a41Splunky 		|  PCC_OFFSETOF  '(' cast_type ',' term ')' {
1222a301e773Splunky 			TYMFIX($3);
12233eb51a41Splunky 			$3->n_type = INCREF($3->n_type);
12243eb51a41Splunky 			$3 = biop(CAST, $3, bcon(0));
12253eb51a41Splunky 			if ($5->n_op == NAME) {
12263eb51a41Splunky 				$$ = biop(STREF, $3, $5);
12273eb51a41Splunky 			} else {
1228*c555ae24Splunky 				P1ND *p = $5;
12293eb51a41Splunky 				while (p->n_left->n_op != NAME)
12303eb51a41Splunky 					p = p->n_left;
12313eb51a41Splunky 				p->n_left = biop(STREF, $3, p->n_left);
12323eb51a41Splunky 				$$ = $5;
12333eb51a41Splunky 			}
1234*c555ae24Splunky 			$$ = biop(ADDROF, $$, NULL);
1235*c555ae24Splunky 			$3 = block(NAME, NULL, NULL, ENUNSIGN(INTPTR), 0, 0);
12363eb51a41Splunky 			$$ = biop(CAST, $3, $$);
12373eb51a41Splunky 		}
12386e0bca22Sgmcgarry 		|  C_ICON { $$ = $1; }
1239*c555ae24Splunky 		|  C_FCON { $$ = bdty(FCON, $1); }
1240*c555ae24Splunky 		|  svstr { $$ = bdty(STRING, $1, styp()); }
12416e0bca22Sgmcgarry 		|  '(' e ')' { $$=$2; }
1242*c555ae24Splunky 		|  '(' xbegin e ';' '}' ')' { $$ = gccexpr($2, eve($3)); }
1243c4627bc7Sgmcgarry 		|  '(' xbegin block_item_list e ';' '}' ')' {
1244*c555ae24Splunky 			$$ = gccexpr($2, eve($4));
1245c4627bc7Sgmcgarry 		}
1246a301e773Splunky 		|  '(' xbegin block_item_list '}' ')' {
1247*c555ae24Splunky 			$$ = gccexpr($2, voidcon());
1248a301e773Splunky 		}
12492d03e475Splunky 		| C_ANDAND C_NAME {
1250*c555ae24Splunky 			struct symtab *s = lookup($2, SLBLNAME|STEMP);
12512d03e475Splunky 			if (s->soffset == 0) {
12522d03e475Splunky 				s->soffset = -getlab();
12532d03e475Splunky 				s->sclass = STATIC;
12542d03e475Splunky 			}
12552d03e475Splunky 			savlab(s->soffset);
1256*c555ae24Splunky 			$$ = biop(ADDROF, bdty(GOTO, $2), NULL);
12572d03e475Splunky 		}
1258*c555ae24Splunky 		| C_GENERIC '(' e ',' gen_ass_list ')' { $$ = dogen($5, $3); }
1259*c555ae24Splunky 		;
1260*c555ae24Splunky 
1261*c555ae24Splunky gen_ass_list:	  gen_assoc { $$ = $1; }
1262*c555ae24Splunky 		| gen_ass_list ',' gen_assoc { $$ = addgen($1, $3); }
1263*c555ae24Splunky 		;
1264*c555ae24Splunky 
1265*c555ae24Splunky gen_assoc:	  cast_type ':' e { TYMFIX($1); $$ = newgen($1, $3); }
1266*c555ae24Splunky 		| C_DEFAULT ':' e { $$ = newgen(0, $3); }
1267c4627bc7Sgmcgarry 		;
1268c4627bc7Sgmcgarry 
1269c4627bc7Sgmcgarry xa:		  { $<intval>$ = inattr; inattr = 0; }
12706e0bca22Sgmcgarry 		;
12716e0bca22Sgmcgarry 
1272*c555ae24Splunky clbrace:	   '{'	{ P1ND *q = $<nodep>-1; TYMFIX(q); $$ = clbrace(q); }
12736e0bca22Sgmcgarry 		;
12746e0bca22Sgmcgarry 
1275*c555ae24Splunky string:		   C_STRING { $$ = stradd(NULL, $1); }
12766e0bca22Sgmcgarry 		|  string C_STRING { $$ = stradd($1, $2); }
12776e0bca22Sgmcgarry 		;
12786e0bca22Sgmcgarry 
12796e0bca22Sgmcgarry cast_type:	   specifier_qualifier_list {
1280a301e773Splunky 			$$ = biop(TYMERGE, $1, bdty(NAME, NULL));
12816e0bca22Sgmcgarry 		}
12826e0bca22Sgmcgarry 		|  specifier_qualifier_list abstract_declarator {
1283a301e773Splunky 			$$ = biop(TYMERGE, $1, aryfix($2));
12846e0bca22Sgmcgarry 		}
12856e0bca22Sgmcgarry 		;
12866e0bca22Sgmcgarry 
12876e0bca22Sgmcgarry %%
12886e0bca22Sgmcgarry 
1289*c555ae24Splunky P1ND *
1290a301e773Splunky mkty(TWORD t, union dimfun *d, struct attr *sue)
12916e0bca22Sgmcgarry {
1292*c555ae24Splunky 	return block(TYPE, NULL, NULL, t, d, sue);
12936e0bca22Sgmcgarry }
12946e0bca22Sgmcgarry 
1295*c555ae24Splunky P1ND *
bdty(int op,...)12966e0bca22Sgmcgarry bdty(int op, ...)
12976e0bca22Sgmcgarry {
1298*c555ae24Splunky 	CONSZ c;
12996e0bca22Sgmcgarry 	va_list ap;
13006e0bca22Sgmcgarry 	int val;
1301*c555ae24Splunky 	register P1ND *q;
13026e0bca22Sgmcgarry 
13036e0bca22Sgmcgarry 	va_start(ap, op);
1304*c555ae24Splunky 	q = biop(op, NULL, NULL);
13056e0bca22Sgmcgarry 
13066e0bca22Sgmcgarry 	switch (op) {
13076e0bca22Sgmcgarry 	case UMUL:
13086e0bca22Sgmcgarry 	case UCALL:
1309*c555ae24Splunky 		q->n_left = va_arg(ap, P1ND *);
13106e0bca22Sgmcgarry 		q->n_rval = 0;
13116e0bca22Sgmcgarry 		break;
13126e0bca22Sgmcgarry 
1313*c555ae24Splunky 	case FCON:
1314*c555ae24Splunky 		q->n_dcon = va_arg(ap, union flt *);
1315*c555ae24Splunky 		q->n_type = q->n_dcon->fa[FP_TOP];
1316*c555ae24Splunky 		break;
1317*c555ae24Splunky 
13186e0bca22Sgmcgarry 	case CALL:
1319*c555ae24Splunky 		q->n_left = va_arg(ap, P1ND *);
1320*c555ae24Splunky 		q->n_right = va_arg(ap, P1ND *);
13216e0bca22Sgmcgarry 		break;
13226e0bca22Sgmcgarry 
13236e0bca22Sgmcgarry 	case LB:
1324*c555ae24Splunky 		q->n_left = va_arg(ap, P1ND *);
13256e0bca22Sgmcgarry 		if ((val = va_arg(ap, int)) <= 0) {
13266e0bca22Sgmcgarry 			uerror("array size must be positive");
13276e0bca22Sgmcgarry 			val = 1;
13286e0bca22Sgmcgarry 		}
13296e0bca22Sgmcgarry 		q->n_right = bcon(val);
13306e0bca22Sgmcgarry 		break;
13316e0bca22Sgmcgarry 
13322d03e475Splunky 	case GOTO: /* for named labels */
1333*c555ae24Splunky 		q->n_ap = attr_add(q->n_ap, attr_new(ATTR_P1LABELS, 1));
13342d03e475Splunky 		/* FALLTHROUGH */
13356e0bca22Sgmcgarry 	case NAME:
13362d03e475Splunky 		q->n_op = NAME;
13376e0bca22Sgmcgarry 		q->n_sp = va_arg(ap, struct symtab *); /* XXX survive tymerge */
13386e0bca22Sgmcgarry 		break;
13396e0bca22Sgmcgarry 
1340c4627bc7Sgmcgarry 	case STRING:
13412d03e475Splunky 		q->n_type = PTR|CHAR;
1342c4627bc7Sgmcgarry 		q->n_name = va_arg(ap, char *);
1343*c555ae24Splunky 		c = va_arg(ap, TWORD);
1344*c555ae24Splunky 		slval(q, c);
1345c4627bc7Sgmcgarry 		break;
1346c4627bc7Sgmcgarry 
13476e0bca22Sgmcgarry 	default:
13486e0bca22Sgmcgarry 		cerror("bad bdty");
13496e0bca22Sgmcgarry 	}
13506e0bca22Sgmcgarry 	va_end(ap);
13516e0bca22Sgmcgarry 
13526e0bca22Sgmcgarry 	return q;
13536e0bca22Sgmcgarry }
13546e0bca22Sgmcgarry 
13556e0bca22Sgmcgarry static void
flend(void)13566e0bca22Sgmcgarry flend(void)
13576e0bca22Sgmcgarry {
1358*c555ae24Splunky 	struct savbc *sc;
1359*c555ae24Splunky 
1360a301e773Splunky 	if (!isinlining && sspflag && blevel == 2)
13616e0bca22Sgmcgarry 		sspend();
13626e0bca22Sgmcgarry #ifdef STABS
13636e0bca22Sgmcgarry 	if (gflag && blevel > 2)
13646e0bca22Sgmcgarry 		stabs_rbrac(blevel);
13656e0bca22Sgmcgarry #endif
13666e0bca22Sgmcgarry 	--blevel;
13676e0bca22Sgmcgarry 	if( blevel == 1 )
13686e0bca22Sgmcgarry 		blevel = 0;
13696e0bca22Sgmcgarry 	symclear(blevel); /* Clean ut the symbol table */
13706e0bca22Sgmcgarry 	if (autooff > maxautooff)
13716e0bca22Sgmcgarry 		maxautooff = autooff;
13726e0bca22Sgmcgarry 	autooff = savctx->contlab;
1373*c555ae24Splunky 	blkfree();
1374*c555ae24Splunky 	stmtfree();
1375*c555ae24Splunky 	bkpole = savctx->bkptr;
1376*c555ae24Splunky 	cbkp = savctx->bkoff;
1377*c555ae24Splunky 	sapole = savctx->stptr;
1378*c555ae24Splunky 	cstp = savctx->stoff;
1379*c555ae24Splunky 	usdnodes = savctx->numnode;
1380*c555ae24Splunky 	sc = savctx->next;
1381*c555ae24Splunky 	free(savctx);
1382*c555ae24Splunky 	savctx = sc;
1383*c555ae24Splunky }
1384*c555ae24Splunky 
1385*c555ae24Splunky /*
1386*c555ae24Splunky  * XXX workaround routines for block level cleansing in gcc compat mode.
1387*c555ae24Splunky  * Temporary should be re reserved for this value before.
1388*c555ae24Splunky  */
1389*c555ae24Splunky static P1ND *
p1mcopy(P1ND * p)1390*c555ae24Splunky p1mcopy(P1ND *p)
1391*c555ae24Splunky {
1392*c555ae24Splunky 	P1ND *q;
1393*c555ae24Splunky 
1394*c555ae24Splunky 	q = xmalloc(sizeof(P1ND));
1395*c555ae24Splunky 	*q = *p;
1396*c555ae24Splunky 
1397*c555ae24Splunky 	switch (coptype(q->n_op)) {
1398*c555ae24Splunky 	case BITYPE:
1399*c555ae24Splunky 		q->n_right = p1mcopy(p->n_right);
1400*c555ae24Splunky 		/* FALLTHROUGH */
1401*c555ae24Splunky 	case UTYPE:
1402*c555ae24Splunky 		q->n_left = p1mcopy(p->n_left);
1403*c555ae24Splunky 	}
1404*c555ae24Splunky 
1405*c555ae24Splunky 	return(q);
1406*c555ae24Splunky }
1407*c555ae24Splunky 
1408*c555ae24Splunky static void
p1mfree(P1ND * p)1409*c555ae24Splunky p1mfree(P1ND *p)
1410*c555ae24Splunky {
1411*c555ae24Splunky 	int o = coptype(p->n_op);
1412*c555ae24Splunky 	if (o == BITYPE)
1413*c555ae24Splunky 		p1mfree(p->n_right);
1414*c555ae24Splunky 	if (o != LTYPE)
1415*c555ae24Splunky 		p1mfree(p->n_left);
1416*c555ae24Splunky 	free(p);
1417*c555ae24Splunky }
1418*c555ae24Splunky 
1419*c555ae24Splunky 
1420*c555ae24Splunky static P1ND *
gccexpr(int bn,P1ND * q)1421*c555ae24Splunky gccexpr(int bn, P1ND *q)
1422*c555ae24Splunky {
1423*c555ae24Splunky 	P1ND *r, *p, *s;
1424*c555ae24Splunky 
1425*c555ae24Splunky 	branch(bn+4);
1426*c555ae24Splunky 	plabel(bn);
1427*c555ae24Splunky 	r = buildtree(COMOP, biop(GOTO, bcon(bn+2), NULL), q);
1428*c555ae24Splunky 	/* XXX hack to survive flend() */
1429*c555ae24Splunky 	s = p1mcopy(r);
1430*c555ae24Splunky 	p1tfree(r);
1431*c555ae24Splunky 	flend();
1432*c555ae24Splunky 	r = p1tcopy(s);
1433*c555ae24Splunky 	p1mfree(s);
1434*c555ae24Splunky 	q = r->n_right;
1435*c555ae24Splunky 	/* XXX end hack */
1436*c555ae24Splunky 	if (q->n_op != ICON && q->n_type != STRTY) {
1437*c555ae24Splunky 		p = tempnode(0, q->n_type, q->n_df, q->n_ap);
1438*c555ae24Splunky 		r = buildtree(ASSIGN, p1tcopy(p), r);
1439*c555ae24Splunky 		r = buildtree(COMOP, r, p);
1440*c555ae24Splunky 	}
1441*c555ae24Splunky 	return r;
14426e0bca22Sgmcgarry }
14436e0bca22Sgmcgarry 
14446e0bca22Sgmcgarry static void
savebc(void)14456e0bca22Sgmcgarry savebc(void)
14466e0bca22Sgmcgarry {
1447*c555ae24Splunky 	struct savbc *bc = malloc(sizeof(struct savbc));
14486e0bca22Sgmcgarry 
14496e0bca22Sgmcgarry 	bc->brklab = brklab;
14506e0bca22Sgmcgarry 	bc->contlab = contlab;
14516e0bca22Sgmcgarry 	bc->flostat = flostat;
14526e0bca22Sgmcgarry 	bc->next = savbc;
14536e0bca22Sgmcgarry 	savbc = bc;
14546e0bca22Sgmcgarry 	flostat = 0;
14556e0bca22Sgmcgarry }
14566e0bca22Sgmcgarry 
14576e0bca22Sgmcgarry static void
resetbc(int mask)14586e0bca22Sgmcgarry resetbc(int mask)
14596e0bca22Sgmcgarry {
1460*c555ae24Splunky 	struct savbc *bc;
1461*c555ae24Splunky 
14626e0bca22Sgmcgarry 	flostat = savbc->flostat | (flostat&mask);
14636e0bca22Sgmcgarry 	contlab = savbc->contlab;
14646e0bca22Sgmcgarry 	brklab = savbc->brklab;
1465*c555ae24Splunky 	bc = savbc->next;
1466*c555ae24Splunky 	free(savbc);
1467*c555ae24Splunky 	savbc = bc;
14686e0bca22Sgmcgarry }
14696e0bca22Sgmcgarry 
14706e0bca22Sgmcgarry struct swdef {
14716e0bca22Sgmcgarry 	struct swdef *next;	/* Next in list */
14726e0bca22Sgmcgarry 	int deflbl;		/* Label for "default" */
14736e0bca22Sgmcgarry 	struct swents *ents;	/* Linked sorted list of case entries */
14746e0bca22Sgmcgarry 	int nents;		/* # of entries in list */
14756e0bca22Sgmcgarry 	int num;		/* Node value will end up in */
14766e0bca22Sgmcgarry 	TWORD type;		/* Type of switch expression */
14776e0bca22Sgmcgarry } *swpole;
14786e0bca22Sgmcgarry 
14796e0bca22Sgmcgarry /*
14806e0bca22Sgmcgarry  * add case to switch
14816e0bca22Sgmcgarry  */
14826e0bca22Sgmcgarry static void
addcase(P1ND * p)1483*c555ae24Splunky addcase(P1ND *p)
14846e0bca22Sgmcgarry {
1485*c555ae24Splunky 	struct swents **put, *w, *sw = malloc(sizeof(struct swents));
14866e0bca22Sgmcgarry 	CONSZ val;
14876e0bca22Sgmcgarry 
14882d03e475Splunky 	p = optloop(p);  /* change enum to ints */
14896e0bca22Sgmcgarry 	if (p->n_op != ICON || p->n_sp != NULL) {
14906e0bca22Sgmcgarry 		uerror( "non-constant case expression");
14916e0bca22Sgmcgarry 		return;
14926e0bca22Sgmcgarry 	}
14936e0bca22Sgmcgarry 	if (swpole == NULL) {
14946e0bca22Sgmcgarry 		uerror("case not in switch");
14956e0bca22Sgmcgarry 		return;
14966e0bca22Sgmcgarry 	}
14976e0bca22Sgmcgarry 
14986e0bca22Sgmcgarry 	if (DEUNSIGN(swpole->type) != DEUNSIGN(p->n_type)) {
1499*c555ae24Splunky 		val = glval(p);
1500a301e773Splunky 		p = makety(p, swpole->type, 0, 0, 0);
15016e0bca22Sgmcgarry 		if (p->n_op != ICON)
15026e0bca22Sgmcgarry 			cerror("could not cast case value to type of switch "
15036e0bca22Sgmcgarry 			       "expression");
1504*c555ae24Splunky 		if (glval(p) != val)
15056e0bca22Sgmcgarry 			werror("case expression truncated");
15066e0bca22Sgmcgarry 	}
1507*c555ae24Splunky 	sw->sval = glval(p);
1508*c555ae24Splunky 	p1tfree(p);
15096e0bca22Sgmcgarry 	put = &swpole->ents;
15106e0bca22Sgmcgarry 	if (ISUNSIGNED(swpole->type)) {
15116e0bca22Sgmcgarry 		for (w = swpole->ents;
15126e0bca22Sgmcgarry 		     w != NULL && (U_CONSZ)w->sval < (U_CONSZ)sw->sval;
15136e0bca22Sgmcgarry 		     w = w->next)
15146e0bca22Sgmcgarry 			put = &w->next;
15156e0bca22Sgmcgarry 	} else {
15166e0bca22Sgmcgarry 		for (w = swpole->ents; w != NULL && w->sval < sw->sval;
15176e0bca22Sgmcgarry 		     w = w->next)
15186e0bca22Sgmcgarry 			put = &w->next;
15196e0bca22Sgmcgarry 	}
15206e0bca22Sgmcgarry 	if (w != NULL && w->sval == sw->sval) {
15216e0bca22Sgmcgarry 		uerror("duplicate case in switch");
15226e0bca22Sgmcgarry 		return;
15236e0bca22Sgmcgarry 	}
15246e0bca22Sgmcgarry 	plabel(sw->slab = getlab());
15256e0bca22Sgmcgarry 	*put = sw;
15266e0bca22Sgmcgarry 	sw->next = w;
15276e0bca22Sgmcgarry 	swpole->nents++;
15286e0bca22Sgmcgarry }
15296e0bca22Sgmcgarry 
1530c4627bc7Sgmcgarry #ifdef GCC_COMPAT
1531c4627bc7Sgmcgarry void
gcccase(P1ND * ln,P1ND * hn)1532*c555ae24Splunky gcccase(P1ND *ln, P1ND *hn)
1533c4627bc7Sgmcgarry {
1534c4627bc7Sgmcgarry 	CONSZ i, l, h;
1535c4627bc7Sgmcgarry 
1536c4627bc7Sgmcgarry 	l = icons(optim(ln));
1537c4627bc7Sgmcgarry 	h = icons(optim(hn));
1538c4627bc7Sgmcgarry 
1539c4627bc7Sgmcgarry 	if (h < l)
1540c4627bc7Sgmcgarry 		i = l, l = h, h = i;
1541c4627bc7Sgmcgarry 
1542c4627bc7Sgmcgarry 	for (i = l; i <= h; i++)
1543c4627bc7Sgmcgarry 		addcase(xbcon(i, NULL, hn->n_type));
1544c4627bc7Sgmcgarry }
1545c4627bc7Sgmcgarry #endif
1546c4627bc7Sgmcgarry 
15476e0bca22Sgmcgarry /*
15486e0bca22Sgmcgarry  * add default case to switch
15496e0bca22Sgmcgarry  */
15506e0bca22Sgmcgarry static void
adddef(void)15516e0bca22Sgmcgarry adddef(void)
15526e0bca22Sgmcgarry {
15536e0bca22Sgmcgarry 	if (swpole == NULL)
15546e0bca22Sgmcgarry 		uerror("default not inside switch");
15556e0bca22Sgmcgarry 	else if (swpole->deflbl != 0)
15566e0bca22Sgmcgarry 		uerror("duplicate default in switch");
15576e0bca22Sgmcgarry 	else
15586e0bca22Sgmcgarry 		plabel( swpole->deflbl = getlab());
15596e0bca22Sgmcgarry }
15606e0bca22Sgmcgarry 
15616e0bca22Sgmcgarry static void
swstart(int num,TWORD type)15626e0bca22Sgmcgarry swstart(int num, TWORD type)
15636e0bca22Sgmcgarry {
1564*c555ae24Splunky 	struct swdef *sw = malloc(sizeof(struct swdef));
15656e0bca22Sgmcgarry 
15666e0bca22Sgmcgarry 	sw->deflbl = sw->nents = 0;
15676e0bca22Sgmcgarry 	sw->ents = NULL;
15686e0bca22Sgmcgarry 	sw->next = swpole;
15696e0bca22Sgmcgarry 	sw->num = num;
15706e0bca22Sgmcgarry 	sw->type = type;
15716e0bca22Sgmcgarry 	swpole = sw;
15726e0bca22Sgmcgarry }
15736e0bca22Sgmcgarry 
15746e0bca22Sgmcgarry /*
15756e0bca22Sgmcgarry  * end a switch block
15766e0bca22Sgmcgarry  */
15776e0bca22Sgmcgarry static void
swend(void)15786e0bca22Sgmcgarry swend(void)
15796e0bca22Sgmcgarry {
15806e0bca22Sgmcgarry 	struct swents *sw, **swp;
1581*c555ae24Splunky 	struct swdef *sp;
15826e0bca22Sgmcgarry 	int i;
15836e0bca22Sgmcgarry 
1584*c555ae24Splunky 	sw = FUNALLO(sizeof(struct swents));
1585*c555ae24Splunky 	swp = FUNALLO(sizeof(struct swents *) * (swpole->nents+1));
15866e0bca22Sgmcgarry 
15876e0bca22Sgmcgarry 	sw->slab = swpole->deflbl;
15886e0bca22Sgmcgarry 	swp[0] = sw;
15896e0bca22Sgmcgarry 
15906e0bca22Sgmcgarry 	for (i = 1; i <= swpole->nents; i++) {
15916e0bca22Sgmcgarry 		swp[i] = swpole->ents;
15926e0bca22Sgmcgarry 		swpole->ents = swpole->ents->next;
15936e0bca22Sgmcgarry 	}
15946e0bca22Sgmcgarry 	genswitch(swpole->num, swpole->type, swp, swpole->nents);
15956e0bca22Sgmcgarry 
1596*c555ae24Splunky 	FUNFREE(sw);
1597*c555ae24Splunky 	FUNFREE(swp);
1598*c555ae24Splunky 	while (swpole->ents) {
1599*c555ae24Splunky 		sw = swpole->ents;
1600*c555ae24Splunky 		swpole->ents = sw->next;
1601*c555ae24Splunky 		free(sw);
1602*c555ae24Splunky 	}
1603*c555ae24Splunky 	sp = swpole->next;
1604*c555ae24Splunky 	free(swpole);
1605*c555ae24Splunky 	swpole = sp;
16066e0bca22Sgmcgarry }
16076e0bca22Sgmcgarry 
16086e0bca22Sgmcgarry /*
16096e0bca22Sgmcgarry  * num: tempnode the value of the switch expression is in
16106e0bca22Sgmcgarry  * type: type of the switch expression
16116e0bca22Sgmcgarry  *
16126e0bca22Sgmcgarry  * p points to an array of structures, each consisting
16136e0bca22Sgmcgarry  * of a constant value and a label.
16146e0bca22Sgmcgarry  * The first is >=0 if there is a default label;
16156e0bca22Sgmcgarry  * its value is the label number
16166e0bca22Sgmcgarry  * The entries p[1] to p[n] are the nontrivial cases
16176e0bca22Sgmcgarry  * n is the number of case statements (length of list)
16186e0bca22Sgmcgarry  */
16196e0bca22Sgmcgarry static void
genswitch(int num,TWORD type,struct swents ** p,int n)16206e0bca22Sgmcgarry genswitch(int num, TWORD type, struct swents **p, int n)
16216e0bca22Sgmcgarry {
1622*c555ae24Splunky 	P1ND *r, *q;
16236e0bca22Sgmcgarry 	int i;
16246e0bca22Sgmcgarry 
16256e0bca22Sgmcgarry 	if (mygenswitch(num, type, p, n))
16266e0bca22Sgmcgarry 		return;
16276e0bca22Sgmcgarry 
16286e0bca22Sgmcgarry 	/* simple switch code */
16296e0bca22Sgmcgarry 	for (i = 1; i <= n; ++i) {
16306e0bca22Sgmcgarry 		/* already in 1 */
1631a301e773Splunky 		r = tempnode(num, type, 0, 0);
16326e0bca22Sgmcgarry 		q = xbcon(p[i]->sval, NULL, type);
16336e0bca22Sgmcgarry 		r = buildtree(NE, r, clocal(q));
16342d03e475Splunky 		xcbranch(r, p[i]->slab);
16356e0bca22Sgmcgarry 	}
16366e0bca22Sgmcgarry 	if (p[0]->slab > 0)
16376e0bca22Sgmcgarry 		branch(p[0]->slab);
16386e0bca22Sgmcgarry }
16396e0bca22Sgmcgarry 
16406e0bca22Sgmcgarry /*
16416e0bca22Sgmcgarry  * Declare a variable or prototype.
16426e0bca22Sgmcgarry  */
16436e0bca22Sgmcgarry static struct symtab *
init_declarator(P1ND * tn,P1ND * p,int assign,P1ND * a,char * as)1644*c555ae24Splunky init_declarator(P1ND *tn, P1ND *p, int assign, P1ND *a, char *as)
16456e0bca22Sgmcgarry {
1646*c555ae24Splunky 	int class = glval(tn);
1647a301e773Splunky 	struct symtab *sp;
16486e0bca22Sgmcgarry 
1649a301e773Splunky 	p = aryfix(p);
1650a301e773Splunky 	p = tymerge(tn, p);
1651a301e773Splunky 	if (a) {
16522d03e475Splunky 		struct attr *ap = gcc_attr_wrapper(a);
1653a301e773Splunky 		p->n_ap = attr_add(p->n_ap, ap);
1654a301e773Splunky 	}
1655c4627bc7Sgmcgarry 
1656a301e773Splunky 	p->n_sp = sp = lookup((char *)p->n_sp, 0); /* XXX */
1657c4627bc7Sgmcgarry 
1658a301e773Splunky 	if (fun_inline && ISFTN(p->n_type))
1659a301e773Splunky 		sp->sflags |= SINLINE;
16606e0bca22Sgmcgarry 
16612d03e475Splunky 	if (!ISFTN(p->n_type)) {
16626e0bca22Sgmcgarry 		if (assign) {
16632d03e475Splunky 			defid2(p, class, as);
1664a301e773Splunky 			sp = p->n_sp;
1665a301e773Splunky 			sp->sflags |= SASG;
1666a301e773Splunky 			if (sp->sflags & SDYNARRAY)
16676e0bca22Sgmcgarry 				uerror("can't initialize dynamic arrays");
1668a301e773Splunky 			lcommdel(sp);
1669c4627bc7Sgmcgarry 		} else
16702d03e475Splunky 			nidcl2(p, class, as);
16716e0bca22Sgmcgarry 	} else {
1672*c555ae24Splunky 		extern P1ND *parlink;
16736e0bca22Sgmcgarry 		if (assign)
16746e0bca22Sgmcgarry 			uerror("cannot initialise function");
16752d03e475Splunky 		defid2(p, uclass(class), as);
1676a301e773Splunky 		sp = p->n_sp;
16772d03e475Splunky 		if (sp->sdf->dfun == 0 && !issyshdr)
16782d03e475Splunky 			warner(Wstrict_prototypes);
16793eb51a41Splunky 		if (parlink) {
16803eb51a41Splunky 			/* dynamic sized arrays in prototypes */
1681*c555ae24Splunky 			p1tfree(parlink); /* Free delayed tree */
1682*c555ae24Splunky 			parlink = NULL;
16833eb51a41Splunky 		}
16846e0bca22Sgmcgarry 	}
1685*c555ae24Splunky 	p1tfree(p);
16862d03e475Splunky 	if (issyshdr)
16872d03e475Splunky 		sp->sflags |= SINSYS; /* declared in system header */
1688a301e773Splunky 	return sp;
16896e0bca22Sgmcgarry }
16906e0bca22Sgmcgarry 
16916e0bca22Sgmcgarry /*
1692c4627bc7Sgmcgarry  * Declare old-stype function arguments.
1693c4627bc7Sgmcgarry  */
1694c4627bc7Sgmcgarry static void
oldargs(P1ND * p)1695*c555ae24Splunky oldargs(P1ND *p)
1696c4627bc7Sgmcgarry {
1697a301e773Splunky 	blevel++;
1698c4627bc7Sgmcgarry 	p->n_op = TYPE;
1699c4627bc7Sgmcgarry 	p->n_type = FARG;
1700c4627bc7Sgmcgarry 	p->n_sp = lookup((char *)p->n_sp, 0);/* XXX */
1701c4627bc7Sgmcgarry 	defid(p, PARAM);
1702a301e773Splunky 	blevel--;
1703c4627bc7Sgmcgarry }
1704c4627bc7Sgmcgarry 
1705c4627bc7Sgmcgarry /*
1706a301e773Splunky  * Set NAME nodes to a null name and index of LB nodes to NOOFFSET
1707a301e773Splunky  * unless clr is one, in that case preserve variable name.
1708a301e773Splunky  */
1709*c555ae24Splunky static P1ND *
namekill(P1ND * p,int clr)1710*c555ae24Splunky namekill(P1ND *p, int clr)
1711a301e773Splunky {
1712*c555ae24Splunky 	P1ND *q;
1713a301e773Splunky 	int o = p->n_op;
1714a301e773Splunky 
1715a301e773Splunky 	switch (coptype(o)) {
1716a301e773Splunky 	case LTYPE:
1717a301e773Splunky 		if (o == NAME) {
1718a301e773Splunky 			if (clr)
1719a301e773Splunky 				p->n_sp = NULL;
1720a301e773Splunky 			else
1721a301e773Splunky 				p->n_sp = lookup((char *)p->n_sp, 0);/* XXX */
1722a301e773Splunky 		}
1723a301e773Splunky 		break;
1724a301e773Splunky 
1725a301e773Splunky 	case UTYPE:
1726a301e773Splunky 		p->n_left = namekill(p->n_left, clr);
1727a301e773Splunky 		break;
1728a301e773Splunky 
1729a301e773Splunky         case BITYPE:
1730a301e773Splunky                 p->n_left = namekill(p->n_left, clr);
1731a301e773Splunky 		if (o == LB) {
1732a301e773Splunky 			if (clr) {
1733*c555ae24Splunky 				p1tfree(p->n_right);
1734a301e773Splunky 				p->n_right = bcon(NOOFFSET);
1735a301e773Splunky 			} else
1736a301e773Splunky 				p->n_right = eve(p->n_right);
1737a301e773Splunky 		} else if (o == CALL)
1738a301e773Splunky 			p->n_right = namekill(p->n_right, 1);
1739a301e773Splunky 		else
1740a301e773Splunky 			p->n_right = namekill(p->n_right, clr);
1741a301e773Splunky 		if (o == TYMERGE) {
1742a301e773Splunky 			q = tymerge(p->n_left, p->n_right);
1743a301e773Splunky 			q->n_ap = attr_add(q->n_ap, p->n_ap);
1744*c555ae24Splunky 			p1tfree(p->n_left);
1745*c555ae24Splunky 			p1nfree(p);
1746a301e773Splunky 			p = q;
1747a301e773Splunky 		}
1748a301e773Splunky 		break;
1749a301e773Splunky 	}
1750a301e773Splunky 	return p;
1751a301e773Splunky }
1752a301e773Splunky 
1753a301e773Splunky /*
1754a301e773Splunky  * Declare function arguments.
1755a301e773Splunky  */
1756*c555ae24Splunky static P1ND *
funargs(P1ND * p)1757*c555ae24Splunky funargs(P1ND *p)
1758a301e773Splunky {
1759*c555ae24Splunky 	extern P1ND *arrstk[10];
1760a301e773Splunky 
1761a301e773Splunky 	if (p->n_op == ELLIPSIS)
1762a301e773Splunky 		return p;
1763a301e773Splunky 
1764a301e773Splunky 	p = namekill(p, 0);
1765a301e773Splunky 	if (ISFTN(p->n_type))
1766a301e773Splunky 		p->n_type = INCREF(p->n_type);
1767a301e773Splunky 	if (ISARY(p->n_type)) {
1768a301e773Splunky 		p->n_type += (PTR-ARY);
1769a301e773Splunky 		if (p->n_df->ddim == -1)
1770*c555ae24Splunky 			p1tfree(arrstk[0]), arrstk[0] = NULL;
1771a301e773Splunky 		p->n_df++;
1772a301e773Splunky 	}
1773a301e773Splunky 	if (p->n_type == VOID && p->n_sp->sname == NULL)
1774a301e773Splunky 		return p; /* sanitycheck later */
1775a301e773Splunky 	else if (p->n_sp->sname == NULL)
1776a301e773Splunky 		uerror("argument missing");
1777a301e773Splunky 	else
1778a301e773Splunky 		defid(p, PARAM);
1779a301e773Splunky 	return p;
1780a301e773Splunky }
1781a301e773Splunky 
1782*c555ae24Splunky static P1ND *
listfw(P1ND * p,P1ND * (* f)(P1ND *))1783*c555ae24Splunky listfw(P1ND *p, P1ND * (*f)(P1ND *))
1784a301e773Splunky {
1785a301e773Splunky         if (p->n_op == CM) {
1786a301e773Splunky                 p->n_left = listfw(p->n_left, f);
1787a301e773Splunky                 p->n_right = (*f)(p->n_right);
1788a301e773Splunky         } else
1789a301e773Splunky                 p = (*f)(p);
1790a301e773Splunky 	return p;
1791a301e773Splunky }
1792a301e773Splunky 
1793a301e773Splunky 
1794a301e773Splunky /*
17956e0bca22Sgmcgarry  * Declare a function.
17966e0bca22Sgmcgarry  */
17976e0bca22Sgmcgarry static void
fundef(P1ND * tp,P1ND * p)1798*c555ae24Splunky fundef(P1ND *tp, P1ND *p)
17996e0bca22Sgmcgarry {
18006e0bca22Sgmcgarry 	extern int prolab;
18016e0bca22Sgmcgarry 	struct symtab *s;
1802*c555ae24Splunky 	P1ND *q, *typ;
1803*c555ae24Splunky 	int class = glval(tp), oclass, ctval;
18046e0bca22Sgmcgarry 
1805a301e773Splunky 	/*
1806a301e773Splunky 	 * We discard all names except for those needed for
1807a301e773Splunky 	 * parameter declaration. While doing that, also change
1808a301e773Splunky 	 * non-constant array sizes to unknown.
1809a301e773Splunky 	 */
1810a301e773Splunky 	ctval = tvaloff;
1811a301e773Splunky 	for (q = p; coptype(q->n_op) != LTYPE &&
1812a301e773Splunky 	    q->n_left->n_op != NAME; q = q->n_left) {
1813a301e773Splunky 		if (q->n_op == CALL)
1814a301e773Splunky 			q->n_right = namekill(q->n_right, 1);
1815a301e773Splunky 	}
18166e0bca22Sgmcgarry 	if (q->n_op != CALL && q->n_op != UCALL) {
18176e0bca22Sgmcgarry 		uerror("invalid function definition");
18186e0bca22Sgmcgarry 		p = bdty(UCALL, p);
1819a301e773Splunky 	} else if (q->n_op == CALL) {
1820a301e773Splunky 		blevel = 1;
1821a301e773Splunky 		argoff = ARGINIT;
1822a301e773Splunky 		if (oldstyle == 0)
1823a301e773Splunky 			q->n_right = listfw(q->n_right, funargs);
18246e0bca22Sgmcgarry 		ftnarg(q);
1825a301e773Splunky 		blevel = 0;
18266e0bca22Sgmcgarry 	}
18276e0bca22Sgmcgarry 
1828c4627bc7Sgmcgarry 	p = typ = tymerge(tp, p);
1829c4627bc7Sgmcgarry #ifdef GCC_COMPAT
1830a301e773Splunky 	/* gcc seems to discard __builtin_ when declaring functions */
1831a301e773Splunky 	if (strncmp("__builtin_", (char *)typ->n_sp, 10) == 0)
1832a301e773Splunky 		typ->n_sp = (struct symtab *)((char *)typ->n_sp + 10);
1833c4627bc7Sgmcgarry #endif
1834c4627bc7Sgmcgarry 	s = typ->n_sp = lookup((char *)typ->n_sp, 0); /* XXX */
18356e0bca22Sgmcgarry 
18366e0bca22Sgmcgarry 	oclass = s->sclass;
18376e0bca22Sgmcgarry 	if (class == STATIC && oclass == EXTERN)
18386e0bca22Sgmcgarry 		werror("%s was first declared extern, then static", s->sname);
18396e0bca22Sgmcgarry 
18406e0bca22Sgmcgarry 	if (fun_inline) {
18416e0bca22Sgmcgarry 		/* special syntax for inline functions */
1842a301e773Splunky 		if (! strcmp(s->sname,"main"))
1843a301e773Splunky 			uerror("cannot inline main()");
1844a301e773Splunky 
18456e0bca22Sgmcgarry 		s->sflags |= SINLINE;
18462d03e475Splunky 		inline_start(s, class);
1847c4627bc7Sgmcgarry 		if (class == EXTERN)
18486e0bca22Sgmcgarry 			class = EXTDEF;
18496e0bca22Sgmcgarry 	} else if (class == EXTERN)
18506e0bca22Sgmcgarry 		class = SNULL; /* same result */
18516e0bca22Sgmcgarry 
18526e0bca22Sgmcgarry 	cftnsp = s;
18536e0bca22Sgmcgarry 	defid(p, class);
18542d03e475Splunky 	if (s->sdf->dfun == 0 && !issyshdr)
18552d03e475Splunky 		warner(Wstrict_prototypes);
1856a301e773Splunky #ifdef GCC_COMPAT
1857a301e773Splunky 	if (attr_find(p->n_ap, GCC_ATYP_ALW_INL)) {
1858a301e773Splunky 		/* Temporary turn on temps to make always_inline work */
1859a301e773Splunky 		alwinl = 1;
1860a301e773Splunky 		if (xtemps == 0) alwinl |= 2;
1861a301e773Splunky 		xtemps = 1;
1862a301e773Splunky 	}
1863a301e773Splunky #endif
18646e0bca22Sgmcgarry 	prolab = getlab();
1865*c555ae24Splunky 	send_passt(IP_PROLOG, -1, getexname(cftnsp), cftnsp->stype,
18666e0bca22Sgmcgarry 	    cftnsp->sclass == EXTDEF, prolab, ctval);
18676e0bca22Sgmcgarry 	blevel++;
18686e0bca22Sgmcgarry #ifdef STABS
18696e0bca22Sgmcgarry 	if (gflag)
18706e0bca22Sgmcgarry 		stabs_func(s);
18716e0bca22Sgmcgarry #endif
1872*c555ae24Splunky 	p1tfree(tp);
1873*c555ae24Splunky 	p1tfree(p);
18746e0bca22Sgmcgarry 
18756e0bca22Sgmcgarry }
18766e0bca22Sgmcgarry 
18776e0bca22Sgmcgarry static void
fend(void)18786e0bca22Sgmcgarry fend(void)
18796e0bca22Sgmcgarry {
18806e0bca22Sgmcgarry 	if (blevel)
18816e0bca22Sgmcgarry 		cerror("function level error");
18826e0bca22Sgmcgarry 	ftnend();
18836e0bca22Sgmcgarry 	fun_inline = 0;
1884a301e773Splunky 	if (alwinl & 2) xtemps = 0;
1885a301e773Splunky 	alwinl = 0;
18866e0bca22Sgmcgarry 	cftnsp = NULL;
18876e0bca22Sgmcgarry }
18886e0bca22Sgmcgarry 
1889*c555ae24Splunky P1ND *
structref(P1ND * p,int f,char * name)1890*c555ae24Splunky structref(P1ND *p, int f, char *name)
18916e0bca22Sgmcgarry {
1892*c555ae24Splunky 	P1ND *r;
18936e0bca22Sgmcgarry 
18946e0bca22Sgmcgarry 	if (f == DOT)
1895*c555ae24Splunky 		p = buildtree(ADDROF, p, NULL);
1896*c555ae24Splunky 	r = biop(NAME, NULL, NULL);
18976e0bca22Sgmcgarry 	r->n_name = name;
18986e0bca22Sgmcgarry 	r = buildtree(STREF, p, r);
18996e0bca22Sgmcgarry 	return r;
19006e0bca22Sgmcgarry }
19016e0bca22Sgmcgarry 
19026e0bca22Sgmcgarry static void
olddecl(P1ND * p,P1ND * a)1903*c555ae24Splunky olddecl(P1ND *p, P1ND *a)
19046e0bca22Sgmcgarry {
19056e0bca22Sgmcgarry 	struct symtab *s;
19066e0bca22Sgmcgarry 
1907a301e773Splunky 	p = namekill(p, 0);
1908a301e773Splunky 	s = p->n_sp;
19096e0bca22Sgmcgarry 	if (s->slevel != 1 || s->stype == UNDEF)
19106e0bca22Sgmcgarry 		uerror("parameter '%s' not defined", s->sname);
19116e0bca22Sgmcgarry 	else if (s->stype != FARG)
19126e0bca22Sgmcgarry 		uerror("parameter '%s' redefined", s->sname);
1913a301e773Splunky 
19146e0bca22Sgmcgarry 	s->stype = p->n_type;
19156e0bca22Sgmcgarry 	s->sdf = p->n_df;
1916a301e773Splunky 	s->sap = p->n_ap;
1917a301e773Splunky 	if (ISARY(s->stype)) {
1918a301e773Splunky 		s->stype += (PTR-ARY);
1919a301e773Splunky 		s->sdf++;
1920a301e773Splunky 	} else if (s->stype == FLOAT)
1921a301e773Splunky 		s->stype = DOUBLE;
1922a301e773Splunky 	if (a)
19232d03e475Splunky 		attr_add(s->sap, gcc_attr_wrapper(a));
1924*c555ae24Splunky 	p1nfree(p);
19256e0bca22Sgmcgarry }
19266e0bca22Sgmcgarry 
19276e0bca22Sgmcgarry void
branch(int lbl)19286e0bca22Sgmcgarry branch(int lbl)
19296e0bca22Sgmcgarry {
19306e0bca22Sgmcgarry 	int r = reached++;
1931*c555ae24Splunky 	ecomp(biop(GOTO, bcon(lbl), NULL));
19326e0bca22Sgmcgarry 	reached = r;
19336e0bca22Sgmcgarry }
19346e0bca22Sgmcgarry 
19356e0bca22Sgmcgarry /*
19366e0bca22Sgmcgarry  * Create a printable string based on an encoded string.
19376e0bca22Sgmcgarry  */
19386e0bca22Sgmcgarry static char *
mkpstr(char * str)19396e0bca22Sgmcgarry mkpstr(char *str)
19406e0bca22Sgmcgarry {
1941*c555ae24Splunky 	char *os, *s;
19422d03e475Splunky 	int l = strlen(str) + 3; /* \t + \n + \0 */
19436e0bca22Sgmcgarry 
1944*c555ae24Splunky 	os = s = stmtalloc(l);
1945*c555ae24Splunky 	*s++ = '\t';
1946*c555ae24Splunky 	while (*str) {
1947*c555ae24Splunky 		if (*str == '\\')
1948*c555ae24Splunky 			*s++ = esccon(&str);
1949*c555ae24Splunky 		else
1950*c555ae24Splunky 			*s++ = *str++;
19516e0bca22Sgmcgarry 	}
1952*c555ae24Splunky 	*s++ = '\n';
1953*c555ae24Splunky 	*s = 0;
19546e0bca22Sgmcgarry 
1955*c555ae24Splunky 	return os;
19566e0bca22Sgmcgarry }
19576e0bca22Sgmcgarry 
1958c4627bc7Sgmcgarry /*
1959c4627bc7Sgmcgarry  * Fake a symtab entry for compound literals.
1960c4627bc7Sgmcgarry  */
19616e0bca22Sgmcgarry static struct symtab *
clbrace(P1ND * p)1962*c555ae24Splunky clbrace(P1ND *p)
19636e0bca22Sgmcgarry {
19646e0bca22Sgmcgarry 	struct symtab *sp;
19656e0bca22Sgmcgarry 
1966c4627bc7Sgmcgarry 	sp = getsymtab(simname("cl"), STEMP);
19676e0bca22Sgmcgarry 	sp->stype = p->n_type;
19686e0bca22Sgmcgarry 	sp->squal = p->n_qual;
19696e0bca22Sgmcgarry 	sp->sdf = p->n_df;
1970a301e773Splunky 	sp->sap = p->n_ap;
1971*c555ae24Splunky 	p1tfree(p);
1972c4627bc7Sgmcgarry 	if (blevel == 0 && xnf != NULL) {
1973c4627bc7Sgmcgarry 		sp->sclass = STATIC;
1974c4627bc7Sgmcgarry 		sp->slevel = 2;
1975c4627bc7Sgmcgarry 		sp->soffset = getlab();
1976c4627bc7Sgmcgarry 	} else {
19776e0bca22Sgmcgarry 		sp->sclass = blevel ? AUTO : STATIC;
19786e0bca22Sgmcgarry 		if (!ISARY(sp->stype) || sp->sdf->ddim != NOOFFSET) {
19796e0bca22Sgmcgarry 			sp->soffset = NOOFFSET;
19806e0bca22Sgmcgarry 			oalloc(sp, &autooff);
19816e0bca22Sgmcgarry 		}
1982c4627bc7Sgmcgarry 	}
19836e0bca22Sgmcgarry 	beginit(sp);
19846e0bca22Sgmcgarry 	return sp;
19856e0bca22Sgmcgarry }
19866e0bca22Sgmcgarry 
1987c4627bc7Sgmcgarry char *
simname(char * s)1988c4627bc7Sgmcgarry simname(char *s)
1989c4627bc7Sgmcgarry {
1990c4627bc7Sgmcgarry 	int len = strlen(s) + 10 + 1;
1991*c555ae24Splunky 	char *w = tmpalloc(len); /* uncommon */
1992c4627bc7Sgmcgarry 
1993c4627bc7Sgmcgarry 	snprintf(w, len, "%s%d", s, getlab());
1994c4627bc7Sgmcgarry 	return w;
1995c4627bc7Sgmcgarry }
1996c4627bc7Sgmcgarry 
1997*c555ae24Splunky P1ND *
biop(int op,P1ND * l,P1ND * r)1998*c555ae24Splunky biop(int op, P1ND *l, P1ND *r)
19996e0bca22Sgmcgarry {
2000a301e773Splunky 	return block(op, l, r, INT, 0, 0);
20016e0bca22Sgmcgarry }
20026e0bca22Sgmcgarry 
2003*c555ae24Splunky static P1ND *
cmop(P1ND * l,P1ND * r)2004*c555ae24Splunky cmop(P1ND *l, P1ND *r)
20056e0bca22Sgmcgarry {
20066e0bca22Sgmcgarry 	return biop(CM, l, r);
20076e0bca22Sgmcgarry }
20086e0bca22Sgmcgarry 
2009*c555ae24Splunky static P1ND *
voidcon(void)20106e0bca22Sgmcgarry voidcon(void)
20116e0bca22Sgmcgarry {
2012*c555ae24Splunky 	return block(ICON, NULL, NULL, STRTY, 0, 0);
20136e0bca22Sgmcgarry }
20146e0bca22Sgmcgarry 
20156e0bca22Sgmcgarry /* Support for extended assembler a' la' gcc style follows below */
20166e0bca22Sgmcgarry 
2017*c555ae24Splunky static P1ND *
xmrg(P1ND * out,P1ND * in)2018*c555ae24Splunky xmrg(P1ND *out, P1ND *in)
20196e0bca22Sgmcgarry {
2020*c555ae24Splunky 	P1ND *p = in;
20216e0bca22Sgmcgarry 
20226e0bca22Sgmcgarry 	if (p->n_op == XARG) {
20236e0bca22Sgmcgarry 		in = cmop(out, p);
20246e0bca22Sgmcgarry 	} else {
20256e0bca22Sgmcgarry 		while (p->n_left->n_op == CM)
20266e0bca22Sgmcgarry 			p = p->n_left;
20276e0bca22Sgmcgarry 		p->n_left = cmop(out, p->n_left);
20286e0bca22Sgmcgarry 	}
20296e0bca22Sgmcgarry 	return in;
20306e0bca22Sgmcgarry }
20316e0bca22Sgmcgarry 
20326e0bca22Sgmcgarry /*
20336e0bca22Sgmcgarry  * Put together in and out node lists in one list, and balance it with
20346e0bca22Sgmcgarry  * the constraints on the right side of a CM node.
20356e0bca22Sgmcgarry  */
2036*c555ae24Splunky static P1ND *
xcmop(P1ND * out,P1ND * in,P1ND * str)2037*c555ae24Splunky xcmop(P1ND *out, P1ND *in, P1ND *str)
20386e0bca22Sgmcgarry {
2039*c555ae24Splunky 	P1ND *p, *q;
20406e0bca22Sgmcgarry 
20416e0bca22Sgmcgarry 	if (out) {
20426e0bca22Sgmcgarry 		/* D out-list sanity check */
20436e0bca22Sgmcgarry 		for (p = out; p->n_op == CM; p = p->n_left) {
20446e0bca22Sgmcgarry 			q = p->n_right;
20456e0bca22Sgmcgarry 			if (q->n_name[0] != '=' && q->n_name[0] != '+')
20466e0bca22Sgmcgarry 				uerror("output missing =");
20476e0bca22Sgmcgarry 		}
20486e0bca22Sgmcgarry 		if (p->n_name[0] != '=' && p->n_name[0] != '+')
20496e0bca22Sgmcgarry 			uerror("output missing =");
2050*c555ae24Splunky 		if (in == NULL)
20516e0bca22Sgmcgarry 			p = out;
20526e0bca22Sgmcgarry 		else
20536e0bca22Sgmcgarry 			p = xmrg(out, in);
20546e0bca22Sgmcgarry 	} else if (in) {
20556e0bca22Sgmcgarry 		p = in;
20566e0bca22Sgmcgarry 	} else
20576e0bca22Sgmcgarry 		p = voidcon();
20586e0bca22Sgmcgarry 
2059*c555ae24Splunky 	if (str == NULL)
20606e0bca22Sgmcgarry 		str = voidcon();
20616e0bca22Sgmcgarry 	return cmop(p, str);
20626e0bca22Sgmcgarry }
20636e0bca22Sgmcgarry 
20646e0bca22Sgmcgarry /*
20656e0bca22Sgmcgarry  * Generate a XARG node based on a string and an expression.
20666e0bca22Sgmcgarry  */
2067*c555ae24Splunky static P1ND *
xasmop(char * str,P1ND * p)2068*c555ae24Splunky xasmop(char *str, P1ND *p)
20696e0bca22Sgmcgarry {
20706e0bca22Sgmcgarry 
2071*c555ae24Splunky 	p = biop(XARG, p, NULL);
2072*c555ae24Splunky 	p->n_name = str;
20736e0bca22Sgmcgarry 	return p;
20746e0bca22Sgmcgarry }
20756e0bca22Sgmcgarry 
20766e0bca22Sgmcgarry /*
20776e0bca22Sgmcgarry  * Generate a XASM node based on a string and an expression.
20786e0bca22Sgmcgarry  */
20796e0bca22Sgmcgarry static void
mkxasm(char * str,P1ND * p)2080*c555ae24Splunky mkxasm(char *str, P1ND *p)
20816e0bca22Sgmcgarry {
2082*c555ae24Splunky 	P1ND *q;
20836e0bca22Sgmcgarry 
20846e0bca22Sgmcgarry 	q = biop(XASM, p->n_left, p->n_right);
2085*c555ae24Splunky 	q->n_name = str;
2086*c555ae24Splunky 	p1nfree(p);
20872d03e475Splunky 	ecomp(optloop(q));
20882d03e475Splunky }
20892d03e475Splunky 
20902d03e475Splunky static struct attr *
gcc_attr_wrapper(P1ND * p)2091*c555ae24Splunky gcc_attr_wrapper(P1ND *p)
20922d03e475Splunky {
20932d03e475Splunky #ifdef GCC_COMPAT
20942d03e475Splunky 	return gcc_attr_parse(p);
20952d03e475Splunky #else
2096*c555ae24Splunky 	if (p != NULL)
20972d03e475Splunky 		uerror("gcc attribute used");
20982d03e475Splunky 	return NULL;
20992d03e475Splunky #endif
21006e0bca22Sgmcgarry }
2101c4627bc7Sgmcgarry 
2102c4627bc7Sgmcgarry #ifdef GCC_COMPAT
2103*c555ae24Splunky static P1ND *
tyof(P1ND * p)2104*c555ae24Splunky tyof(P1ND *p)
2105c4627bc7Sgmcgarry {
2106c4627bc7Sgmcgarry 	static struct symtab spp;
2107*c555ae24Splunky 	P1ND *q = block(TYPE, NULL, NULL, p->n_type, p->n_df, p->n_ap);
2108c4627bc7Sgmcgarry 	q->n_qual = p->n_qual;
2109c4627bc7Sgmcgarry 	q->n_sp = &spp; /* for typenode */
2110*c555ae24Splunky 	p1tfree(p);
2111c4627bc7Sgmcgarry 	return q;
2112c4627bc7Sgmcgarry }
2113c4627bc7Sgmcgarry 
21142d03e475Splunky #else
2115*c555ae24Splunky static P1ND *
tyof(P1ND * p)2116*c555ae24Splunky tyof(P1ND *p)
2117a301e773Splunky {
21182d03e475Splunky 	uerror("typeof gcc extension");
21192d03e475Splunky 	return bcon(0);
2120a301e773Splunky }
21212d03e475Splunky #endif
2122a301e773Splunky 
2123a301e773Splunky /*
2124c4627bc7Sgmcgarry  * Traverse an unhandled expression tree bottom-up and call buildtree()
2125c4627bc7Sgmcgarry  * or equivalent as needed.
2126c4627bc7Sgmcgarry  */
2127*c555ae24Splunky P1ND *
eve(P1ND * p)2128*c555ae24Splunky eve(P1ND *p)
2129c4627bc7Sgmcgarry {
2130c4627bc7Sgmcgarry 	struct symtab *sp;
2131*c555ae24Splunky 	P1ND *r, *p1, *p2;
2132c4627bc7Sgmcgarry 	int x;
2133c4627bc7Sgmcgarry 
2134c4627bc7Sgmcgarry 	p1 = p->n_left;
2135c4627bc7Sgmcgarry 	p2 = p->n_right;
2136c4627bc7Sgmcgarry 	switch (p->n_op) {
2137c4627bc7Sgmcgarry 	case NAME:
2138*c555ae24Splunky 		sp = lookup((char *)p->n_sp,
2139*c555ae24Splunky 		    attr_find(p->n_ap, ATTR_P1LABELS) ? SLBLNAME|STEMP : 0);
2140c4627bc7Sgmcgarry 		if (sp->sflags & SINLINE)
2141c4627bc7Sgmcgarry 			inline_ref(sp);
2142c4627bc7Sgmcgarry 		r = nametree(sp);
2143c4627bc7Sgmcgarry 		if (sp->sflags & SDYNARRAY)
2144*c555ae24Splunky 			r = buildtree(UMUL, r, NULL);
2145a301e773Splunky #ifdef GCC_COMPAT
2146a301e773Splunky 		if (attr_find(sp->sap, GCC_ATYP_DEPRECATED))
21472d03e475Splunky 			warner(Wdeprecated_declarations, sp->sname);
2148a301e773Splunky #endif
2149c4627bc7Sgmcgarry 		break;
2150c4627bc7Sgmcgarry 
2151c4627bc7Sgmcgarry 	case DOT:
2152c4627bc7Sgmcgarry 	case STREF:
2153c4627bc7Sgmcgarry 		r = structref(eve(p1), p->n_op, (char *)p2->n_sp);
2154*c555ae24Splunky 		p1nfree(p2);
2155c4627bc7Sgmcgarry 		break;
2156c4627bc7Sgmcgarry 
2157c4627bc7Sgmcgarry 	case CAST:
21582d03e475Splunky 		p2 = eve(p2);
21592d03e475Splunky #ifndef NO_COMPLEX
21602d03e475Splunky 		if (ANYCX(p1) || ANYCX(p2)) {
21612d03e475Splunky 			r = cxcast(p1, p2);
21622d03e475Splunky 			break;
21632d03e475Splunky 		}
21642d03e475Splunky #endif
21652d03e475Splunky #ifdef TARGET_TIMODE
21662d03e475Splunky 		if ((r = gcc_eval_ticast(CAST, p1, p2)) != NULL)
21672d03e475Splunky 			break;
21682d03e475Splunky #endif
21692d03e475Splunky 		p1 = buildtree(CAST, p1, p2);
2170*c555ae24Splunky 		p1nfree(p1->n_left);
2171c4627bc7Sgmcgarry 		r = p1->n_right;
2172*c555ae24Splunky 		p1nfree(p1);
2173c4627bc7Sgmcgarry 		break;
2174c4627bc7Sgmcgarry 
2175c4627bc7Sgmcgarry 
2176c4627bc7Sgmcgarry 	case SZOF:
2177c4627bc7Sgmcgarry 		x = xinline; xinline = 0; /* XXX hack */
2178*c555ae24Splunky 		if (glval(p2) == 0)
2179c4627bc7Sgmcgarry 			p1 = eve(p1);
2180a301e773Splunky 		else
2181a301e773Splunky 			TYMFIX(p1);
2182*c555ae24Splunky 		p1nfree(p2);
2183c4627bc7Sgmcgarry 		r = doszof(p1);
2184c4627bc7Sgmcgarry 		xinline = x;
2185c4627bc7Sgmcgarry 		break;
2186c4627bc7Sgmcgarry 
2187c4627bc7Sgmcgarry 	case LB:
21882d03e475Splunky 		p1 = eve(p1);
21892d03e475Splunky 		p2 = eve(p2);
21902d03e475Splunky #ifdef TARGET_TIMODE
21912d03e475Splunky 		if (isti(p2)) {
2192*c555ae24Splunky 			P1ND *s = block(NAME, NULL, NULL, LONG, 0, 0);
21932d03e475Splunky 			if ((r = gcc_eval_ticast(CAST, s, p2)) != NULL)
21942d03e475Splunky 				p2 = r;
2195*c555ae24Splunky 			p1nfree(s);
21962d03e475Splunky 		}
21972d03e475Splunky #endif
2198*c555ae24Splunky 		r = buildtree(UMUL, buildtree(PLUS, p1, p2), NULL);
2199c4627bc7Sgmcgarry 		break;
2200c4627bc7Sgmcgarry 
2201c4627bc7Sgmcgarry 	case COMPL:
2202c4627bc7Sgmcgarry #ifndef NO_COMPLEX
2203c4627bc7Sgmcgarry 		p1 = eve(p1);
2204c4627bc7Sgmcgarry 		if (ANYCX(p1))
2205c4627bc7Sgmcgarry 			r = cxconj(p1);
2206c4627bc7Sgmcgarry 		else
2207*c555ae24Splunky 			r = buildtree(COMPL, p1, NULL);
2208c4627bc7Sgmcgarry 		break;
2209c4627bc7Sgmcgarry #endif
22102d03e475Splunky 	case UPLUS:
22112d03e475Splunky 		r = eve(p1);
22122d03e475Splunky 		if (r->n_op == FLD || r->n_type < INT)
2213*c555ae24Splunky 			r = buildtree(PLUS, r, bcon(0)); /* must be size int */
22142d03e475Splunky 		break;
22152d03e475Splunky 
2216c4627bc7Sgmcgarry 	case UMINUS:
22172d03e475Splunky #ifndef NO_COMPLEX
22182d03e475Splunky 		p1 = eve(p1);
22192d03e475Splunky 		if (ANYCX(p1))
22202d03e475Splunky 			r = cxop(UMINUS, p1, p1);
22212d03e475Splunky 		else
2222*c555ae24Splunky 			r = buildtree(UMINUS, p1, NULL);
22232d03e475Splunky 		break;
22242d03e475Splunky #endif
2225c4627bc7Sgmcgarry 	case NOT:
2226c4627bc7Sgmcgarry 	case UMUL:
22272d03e475Splunky 		p1 = eve(p1);
22282d03e475Splunky #ifdef TARGET_TIMODE
22292d03e475Splunky 		if ((r = gcc_eval_tiuni(p->n_op, p1)) != NULL)
22302d03e475Splunky 			break;
22312d03e475Splunky #endif
2232*c555ae24Splunky #ifndef NO_COMPLEX
2233*c555ae24Splunky 		if (p->n_op == NOT && ANYCX(p1))
2234*c555ae24Splunky 			p1 = cxop(NE, p1, bcon(0));
2235*c555ae24Splunky #endif
2236*c555ae24Splunky 		r = buildtree(p->n_op, p1, NULL);
2237c4627bc7Sgmcgarry 		break;
2238c4627bc7Sgmcgarry 
2239c4627bc7Sgmcgarry 	case ADDROF:
2240c4627bc7Sgmcgarry 		r = eve(p1);
2241c4627bc7Sgmcgarry 		if (ISFTN(p->n_type)/* || ISARY(p->n_type) */){
2242c4627bc7Sgmcgarry #ifdef notdef
2243c4627bc7Sgmcgarry 			werror( "& before array or function: ignored" );
2244c4627bc7Sgmcgarry #endif
2245c4627bc7Sgmcgarry 		} else
2246*c555ae24Splunky 			r = buildtree(ADDROF, r, NULL);
2247c4627bc7Sgmcgarry 		break;
2248c4627bc7Sgmcgarry 
2249c4627bc7Sgmcgarry 	case UCALL:
2250*c555ae24Splunky 		p2 = NULL;
22512d03e475Splunky 		/* FALLTHROUGH */
22522d03e475Splunky 	case CALL:
2253c4627bc7Sgmcgarry 		if (p1->n_op == NAME) {
2254c4627bc7Sgmcgarry 			sp = lookup((char *)p1->n_sp, 0);
22552d03e475Splunky #ifndef NO_C_BUILTINS
22562d03e475Splunky 			if (sp->sflags & SBUILTIN) {
2257*c555ae24Splunky 				p1nfree(p1);
22582d03e475Splunky 				r = builtin_check(sp, p2);
22592d03e475Splunky 				break;
22602d03e475Splunky 			}
22612d03e475Splunky #endif
2262c4627bc7Sgmcgarry 			if (sp->stype == UNDEF) {
2263c4627bc7Sgmcgarry 				p1->n_type = FTN|INT;
2264c4627bc7Sgmcgarry 				p1->n_sp = sp;
2265a301e773Splunky 				p1->n_ap = NULL;
2266c4627bc7Sgmcgarry 				defid(p1, EXTERN);
2267c4627bc7Sgmcgarry 			}
2268*c555ae24Splunky 			p1nfree(p1);
2269a301e773Splunky #ifdef GCC_COMPAT
2270a301e773Splunky 			if (attr_find(sp->sap, GCC_ATYP_DEPRECATED))
22712d03e475Splunky 				warner(Wdeprecated_declarations, sp->sname);
2272a301e773Splunky #endif
22732d03e475Splunky 			if (p->n_op == CALL)
22742d03e475Splunky 				p2 = eve(p2);
2275c4627bc7Sgmcgarry 			r = doacall(sp, nametree(sp), p2);
22762d03e475Splunky 		} else {
22772d03e475Splunky 			if (p->n_op == CALL)
22782d03e475Splunky 				p2 = eve(p2);
2279c4627bc7Sgmcgarry 			r = doacall(NULL, eve(p1), p2);
22802d03e475Splunky 		}
2281c4627bc7Sgmcgarry 		break;
2282c4627bc7Sgmcgarry 
2283c4627bc7Sgmcgarry #ifndef NO_COMPLEX
2284c4627bc7Sgmcgarry 	case XREAL:
2285c4627bc7Sgmcgarry 	case XIMAG:
2286c4627bc7Sgmcgarry 		p1 = eve(p1);
2287c4627bc7Sgmcgarry 		r = cxelem(p->n_op, p1);
2288c4627bc7Sgmcgarry 		break;
2289c4627bc7Sgmcgarry #endif
2290c4627bc7Sgmcgarry 
2291*c555ae24Splunky 	case COLON:
2292c4627bc7Sgmcgarry 	case MUL:
2293c4627bc7Sgmcgarry 	case DIV:
2294c4627bc7Sgmcgarry 	case PLUS:
2295c4627bc7Sgmcgarry 	case MINUS:
2296c4627bc7Sgmcgarry 	case ASSIGN:
2297a301e773Splunky 	case EQ:
2298a301e773Splunky 	case NE:
22992d03e475Splunky 	case OROR:
23002d03e475Splunky 	case ANDAND:
2301c4627bc7Sgmcgarry #ifndef NO_COMPLEX
2302c4627bc7Sgmcgarry 		p1 = eve(p1);
2303c4627bc7Sgmcgarry 		p2 = eve(p2);
23042d03e475Splunky #ifdef TARGET_TIMODE
23052d03e475Splunky 		if ((r = gcc_eval_timode(p->n_op, p1, p2)) != NULL)
23062d03e475Splunky 			break;
23072d03e475Splunky #endif
2308c4627bc7Sgmcgarry 		if (ANYCX(p1) || ANYCX(p2)) {
2309c4627bc7Sgmcgarry 			r = cxop(p->n_op, p1, p2);
2310c4627bc7Sgmcgarry 		} else if (ISITY(p1->n_type) || ISITY(p2->n_type)) {
2311c4627bc7Sgmcgarry 			r = imop(p->n_op, p1, p2);
2312c4627bc7Sgmcgarry 		} else
2313c4627bc7Sgmcgarry 			r = buildtree(p->n_op, p1, p2);
2314c4627bc7Sgmcgarry 		break;
2315c4627bc7Sgmcgarry #endif
2316c4627bc7Sgmcgarry 	case MOD:
2317c4627bc7Sgmcgarry 	case CM:
2318c4627bc7Sgmcgarry 	case GT:
2319c4627bc7Sgmcgarry 	case GE:
2320c4627bc7Sgmcgarry 	case LT:
2321c4627bc7Sgmcgarry 	case LE:
2322c4627bc7Sgmcgarry 	case RS:
2323c4627bc7Sgmcgarry 	case LS:
2324c4627bc7Sgmcgarry 	case RSEQ:
2325c4627bc7Sgmcgarry 	case LSEQ:
2326c4627bc7Sgmcgarry 	case AND:
2327c4627bc7Sgmcgarry 	case OR:
2328c4627bc7Sgmcgarry 	case ER:
2329c4627bc7Sgmcgarry 	case EREQ:
2330c4627bc7Sgmcgarry 	case OREQ:
2331c4627bc7Sgmcgarry 	case ANDEQ:
23322d03e475Splunky 	case QUEST:
2333a301e773Splunky 		p1 = eve(p1);
23342d03e475Splunky 		p2 = eve(p2);
23352d03e475Splunky #ifdef TARGET_TIMODE
23362d03e475Splunky 		if ((r = gcc_eval_timode(p->n_op, p1, p2)) != NULL)
23372d03e475Splunky 			break;
23382d03e475Splunky #endif
23392d03e475Splunky 		r = buildtree(p->n_op, p1, p2);
23402d03e475Splunky 		break;
23412d03e475Splunky 
23422d03e475Splunky 	case BIQUEST: /* gcc e ?: e op */
23432d03e475Splunky 		p1 = eve(p1);
23442d03e475Splunky 		r = tempnode(0, p1->n_type, p1->n_df, p1->n_ap);
2345*c555ae24Splunky 		p2 = eve(biop(COLON, p1tcopy(r), p2));
23462d03e475Splunky 		r = buildtree(QUEST, buildtree(ASSIGN, r, p1), p2);
2347a301e773Splunky 		break;
2348a301e773Splunky 
2349a301e773Splunky 	case INCR:
2350a301e773Splunky 	case DECR:
2351a301e773Splunky 	case MODEQ:
2352c4627bc7Sgmcgarry 	case MINUSEQ:
2353c4627bc7Sgmcgarry 	case PLUSEQ:
2354c4627bc7Sgmcgarry 	case MULEQ:
2355c4627bc7Sgmcgarry 	case DIVEQ:
2356c4627bc7Sgmcgarry 		p1 = eve(p1);
2357a301e773Splunky 		p2 = eve(p2);
23582d03e475Splunky #ifdef TARGET_TIMODE
23592d03e475Splunky 		if ((r = gcc_eval_timode(p->n_op, p1, p2)) != NULL)
23602d03e475Splunky 			break;
23612d03e475Splunky #endif
2362a301e773Splunky #ifndef NO_COMPLEX
2363a301e773Splunky 		if (ANYCX(p1) || ANYCX(p2)) {
2364*c555ae24Splunky 			r = cxop(UNASG p->n_op, p1tcopy(p1), p2);
2365a301e773Splunky 			r = cxop(ASSIGN, p1, r);
2366a301e773Splunky 			break;
2367a301e773Splunky 		} else if (ISITY(p1->n_type) || ISITY(p2->n_type)) {
2368*c555ae24Splunky 			r = imop(UNASG p->n_op, p1tcopy(p1), p2);
2369a301e773Splunky 			r = cxop(ASSIGN, p1, r);
2370a301e773Splunky 			break;
2371a301e773Splunky 		}
2372a301e773Splunky 		/* FALLTHROUGH */
2373a301e773Splunky #endif
2374a301e773Splunky 		r = buildtree(p->n_op, p1, p2);
2375c4627bc7Sgmcgarry 		break;
2376c4627bc7Sgmcgarry 
2377c4627bc7Sgmcgarry 	case STRING:
2378*c555ae24Splunky 		r = strend(p->n_name, (TWORD)glval(p));
2379c4627bc7Sgmcgarry 		break;
2380c4627bc7Sgmcgarry 
2381c4627bc7Sgmcgarry 	case COMOP:
2382c4627bc7Sgmcgarry 		if (p1->n_op == GOTO) {
2383c4627bc7Sgmcgarry 			/* inside ({ }), eve already called */
2384c4627bc7Sgmcgarry 			r = buildtree(p->n_op, p1, p2);
2385c4627bc7Sgmcgarry 		} else {
2386c4627bc7Sgmcgarry 			p1 = eve(p1);
2387c4627bc7Sgmcgarry 			r = buildtree(p->n_op, p1, eve(p2));
2388c4627bc7Sgmcgarry 		}
2389c4627bc7Sgmcgarry 		break;
2390c4627bc7Sgmcgarry 
2391c4627bc7Sgmcgarry 	case TYPE:
2392c4627bc7Sgmcgarry 	case ICON:
2393c4627bc7Sgmcgarry 	case FCON:
23943eb51a41Splunky 	case TEMP:
2395c4627bc7Sgmcgarry 		return p;
2396c4627bc7Sgmcgarry 
2397c4627bc7Sgmcgarry 	case CLOP:
2398c4627bc7Sgmcgarry 		r = nametree(p->n_sp);
2399c4627bc7Sgmcgarry 		break;
2400c4627bc7Sgmcgarry 
2401c4627bc7Sgmcgarry 	default:
2402c4627bc7Sgmcgarry #ifdef PCC_DEBUG
2403*c555ae24Splunky 		p1fwalk(p, eprint, 0);
2404c4627bc7Sgmcgarry #endif
2405c4627bc7Sgmcgarry 		cerror("eve");
2406*c555ae24Splunky 		r = NULL;
2407c4627bc7Sgmcgarry 	}
2408*c555ae24Splunky 	p1nfree(p);
2409c4627bc7Sgmcgarry 	return r;
2410c4627bc7Sgmcgarry }
2411c4627bc7Sgmcgarry 
24123eb51a41Splunky int
con_e(P1ND * p)2413*c555ae24Splunky con_e(P1ND *p)
24143eb51a41Splunky {
24152d03e475Splunky 	return icons(optloop(eve(p)));
24163eb51a41Splunky }
24173eb51a41Splunky 
24183eb51a41Splunky void
uawarn(P1ND * p,char * s)2419*c555ae24Splunky uawarn(P1ND *p, char *s)
24203eb51a41Splunky {
24213eb51a41Splunky 	if (p == 0)
24223eb51a41Splunky 		return;
24233eb51a41Splunky 	if (attrwarn)
24243eb51a41Splunky 		werror("unhandled %s attribute", s);
2425*c555ae24Splunky 	p1tfree(p);
24263eb51a41Splunky }
24273eb51a41Splunky 
24283eb51a41Splunky static void
dainit(P1ND * d,P1ND * a)2429*c555ae24Splunky dainit(P1ND *d, P1ND *a)
24303eb51a41Splunky {
24313eb51a41Splunky 	if (d == NULL) {
24323eb51a41Splunky 		asginit(a);
24333eb51a41Splunky 	} else if (d->n_op == CM) {
24343eb51a41Splunky 		int is = con_e(d->n_left);
24353eb51a41Splunky 		int ie = con_e(d->n_right);
24363eb51a41Splunky 		int i;
24373eb51a41Splunky 
2438*c555ae24Splunky 		p1nfree(d);
24393eb51a41Splunky 		if (ie < is)
24403eb51a41Splunky 			uerror("negative initializer range");
2441*c555ae24Splunky 		desinit(biop(LB, NULL, bcon(is)));
24423eb51a41Splunky 		for (i = is; i < ie; i++)
2443*c555ae24Splunky 			asginit(p1tcopy(a));
24443eb51a41Splunky 		asginit(a);
24453eb51a41Splunky 	} else {
24463eb51a41Splunky 		cerror("dainit");
24473eb51a41Splunky 	}
24483eb51a41Splunky }
2449a301e773Splunky 
2450a301e773Splunky /*
2451a301e773Splunky  * Traverse down and tymerge() where appropriate.
2452a301e773Splunky  */
2453*c555ae24Splunky static P1ND *
tymfix(P1ND * p)2454*c555ae24Splunky tymfix(P1ND *p)
2455a301e773Splunky {
2456*c555ae24Splunky 	P1ND *q;
2457a301e773Splunky 	int o = coptype(p->n_op);
2458a301e773Splunky 
2459a301e773Splunky 	switch (o) {
2460a301e773Splunky 	case LTYPE:
2461a301e773Splunky 		break;
2462a301e773Splunky 	case UTYPE:
2463a301e773Splunky 		p->n_left = tymfix(p->n_left);
2464a301e773Splunky 		break;
2465a301e773Splunky 	case BITYPE:
2466a301e773Splunky 		p->n_left = tymfix(p->n_left);
2467a301e773Splunky 		p->n_right = tymfix(p->n_right);
2468a301e773Splunky 		if (p->n_op == TYMERGE) {
2469a301e773Splunky 			q = tymerge(p->n_left, p->n_right);
2470a301e773Splunky 			q->n_ap = attr_add(q->n_ap, p->n_ap);
2471*c555ae24Splunky 			p1tfree(p->n_left);
2472*c555ae24Splunky 			p1nfree(p);
2473a301e773Splunky 			p = q;
2474a301e773Splunky 		}
2475a301e773Splunky 		break;
2476a301e773Splunky 	}
2477a301e773Splunky 	return p;
2478a301e773Splunky }
2479a301e773Splunky 
2480*c555ae24Splunky static P1ND *
aryfix(P1ND * p)2481*c555ae24Splunky aryfix(P1ND *p)
2482a301e773Splunky {
2483*c555ae24Splunky 	P1ND *q;
2484a301e773Splunky 
2485a301e773Splunky 	for (q = p; q->n_op != NAME; q = q->n_left) {
2486a301e773Splunky 		if (q->n_op == LB) {
24872d03e475Splunky 			q->n_right = optloop(eve(q->n_right));
2488a301e773Splunky 			if ((blevel == 0 || rpole != NULL) &&
2489a301e773Splunky 			    !nncon(q->n_right))
2490a301e773Splunky 				uerror("array size not constant");
2491a301e773Splunky 			/*
2492a301e773Splunky 			 * Checks according to 6.7.5.2 clause 1:
2493a301e773Splunky 			 * "...the expression shall have an integer type."
2494a301e773Splunky 			 * "If the expression is a constant expression,
2495a301e773Splunky 			 * it shall have a value greater than zero."
2496a301e773Splunky 			 */
2497a301e773Splunky 			if (!ISINTEGER(q->n_right->n_type))
2498a301e773Splunky 				werror("array size is not an integer");
2499a301e773Splunky 			else if (q->n_right->n_op == ICON &&
2500*c555ae24Splunky 			    glval(q->n_right) < 0 &&
2501*c555ae24Splunky 			    glval(q->n_right) != NOOFFSET) {
2502a301e773Splunky 					uerror("array size cannot be negative");
2503*c555ae24Splunky 					slval(q->n_right, 1);
2504a301e773Splunky 			}
2505a301e773Splunky 		} else if (q->n_op == CALL)
2506a301e773Splunky 			q->n_right = namekill(q->n_right, 1);
2507a301e773Splunky 	}
2508a301e773Splunky 	return p;
2509a301e773Splunky }
25102d03e475Splunky 
25112d03e475Splunky struct labs {
25122d03e475Splunky 	struct labs *next;
25132d03e475Splunky 	int lab;
25142d03e475Splunky } *labp;
25152d03e475Splunky 
25162d03e475Splunky static void
savlab(int lab)25172d03e475Splunky savlab(int lab)
25182d03e475Splunky {
2519*c555ae24Splunky 	struct labs *l = tmpalloc(sizeof(struct labs)); /* uncommon */
25202d03e475Splunky 	l->lab = lab < 0 ? -lab : lab;
25212d03e475Splunky 	l->next = labp;
25222d03e475Splunky 	labp = l;
25232d03e475Splunky }
25242d03e475Splunky 
25252d03e475Splunky int *
mkclabs(void)25262d03e475Splunky mkclabs(void)
25272d03e475Splunky {
25282d03e475Splunky 	struct labs *l;
25292d03e475Splunky 	int i, *rv;
25302d03e475Splunky 
25312d03e475Splunky 	for (i = 0, l = labp; l; l = l->next, i++)
25322d03e475Splunky 		;
2533*c555ae24Splunky 	rv = tmpalloc((i+1)*sizeof(int));	/* uncommon */
25342d03e475Splunky 	for (i = 0, l = labp; l; l = l->next, i++)
25352d03e475Splunky 		rv[i] = l->lab;
25362d03e475Splunky 	rv[i] = 0;
25372d03e475Splunky 	labp = 0;
25382d03e475Splunky 	return rv;
25392d03e475Splunky }
25402d03e475Splunky 
25412d03e475Splunky void
xcbranch(P1ND * p,int lab)2542*c555ae24Splunky xcbranch(P1ND *p, int lab)
25432d03e475Splunky {
25442d03e475Splunky #ifndef NO_COMPLEX
25452d03e475Splunky 	if (ANYCX(p))
25462d03e475Splunky 		p = cxop(NE, p, bcon(0));
25472d03e475Splunky #endif
2548*c555ae24Splunky 	cbranch(buildtree(NOT, p, NULL), bcon(lab));
2549*c555ae24Splunky }
2550*c555ae24Splunky 
2551*c555ae24Splunky /*
2552*c555ae24Splunky  * New a case entry to genlist.
2553*c555ae24Splunky  * tn is type, e is expression.
2554*c555ae24Splunky  */
2555*c555ae24Splunky static struct genlist *
newgen(P1ND * tn,P1ND * e)2556*c555ae24Splunky newgen(P1ND *tn, P1ND *e)
2557*c555ae24Splunky {
2558*c555ae24Splunky 	struct genlist *ng;
2559*c555ae24Splunky 	TWORD t;
2560*c555ae24Splunky 
2561*c555ae24Splunky 	if (tn) {
2562*c555ae24Splunky 		t = tn->n_type;
2563*c555ae24Splunky 		p1tfree(tn);
2564*c555ae24Splunky 	} else
2565*c555ae24Splunky 		t = 0;
2566*c555ae24Splunky 
2567*c555ae24Splunky 	/* add new entry */
2568*c555ae24Splunky 	ng = malloc(sizeof(struct genlist));
2569*c555ae24Splunky 	ng->next = NULL;
2570*c555ae24Splunky 	ng->t = t;
2571*c555ae24Splunky 	ng->p = e;
2572*c555ae24Splunky 	return ng;
2573*c555ae24Splunky }
2574*c555ae24Splunky 
2575*c555ae24Splunky /*
2576*c555ae24Splunky  * Add a case entry to genlist.
2577*c555ae24Splunky  * g is list, ng is new entry.
2578*c555ae24Splunky  */
2579*c555ae24Splunky static struct genlist *
addgen(struct genlist * g,struct genlist * ng)2580*c555ae24Splunky addgen(struct genlist *g, struct genlist *ng)
2581*c555ae24Splunky {
2582*c555ae24Splunky 	struct genlist *w;
2583*c555ae24Splunky 
2584*c555ae24Splunky 	/* search for duplicate type */
2585*c555ae24Splunky 	for (w = g; w; w = w->next) {
2586*c555ae24Splunky 		if (w->t == ng->t)
2587*c555ae24Splunky 			uerror("duplicate type in _Generic");
2588*c555ae24Splunky 	}
2589*c555ae24Splunky 	ng->next = g;
2590*c555ae24Splunky 	return ng;
2591*c555ae24Splunky }
2592*c555ae24Splunky 
2593*c555ae24Splunky static P1ND *
dogen(struct genlist * g,P1ND * e)2594*c555ae24Splunky dogen(struct genlist *g, P1ND *e)
2595*c555ae24Splunky {
2596*c555ae24Splunky 	struct genlist *ng;
2597*c555ae24Splunky 	P1ND *w, *p;
2598*c555ae24Splunky 
2599*c555ae24Splunky 	e = eve(e);
2600*c555ae24Splunky 
2601*c555ae24Splunky 	/* search for direct match */
2602*c555ae24Splunky 	for (ng = g, w = p = NULL; ng; ng = ng->next) {
2603*c555ae24Splunky 		if (ng->t == 0)
2604*c555ae24Splunky 			p = ng->p; /* save default */
2605*c555ae24Splunky 		if (e->n_type == ng->t)
2606*c555ae24Splunky 			w = ng->p;
2607*c555ae24Splunky 	}
2608*c555ae24Splunky 
2609*c555ae24Splunky 	/* if no match, use generic */
2610*c555ae24Splunky 	if (w == NULL) {
2611*c555ae24Splunky 		if (p == NULL) {
2612*c555ae24Splunky 			uerror("_Generic: no default found");
2613*c555ae24Splunky 			p = bcon(0);
2614*c555ae24Splunky 		}
2615*c555ae24Splunky 		w = p;
2616*c555ae24Splunky 	}
2617*c555ae24Splunky 
2618*c555ae24Splunky 	/* free tree */
2619*c555ae24Splunky 	while (g) {
2620*c555ae24Splunky 		if (g->p != w)
2621*c555ae24Splunky 			p1tfree(g->p);
2622*c555ae24Splunky 		ng = g->next;
2623*c555ae24Splunky 		free(g);
2624*c555ae24Splunky 		g = ng;
2625*c555ae24Splunky 	}
2626*c555ae24Splunky 
2627*c555ae24Splunky 	p1tfree(e);
2628*c555ae24Splunky 	return w;
26292d03e475Splunky }
2630