xref: /netbsd-src/external/bsd/pcc/dist/pcc/cc/ccom/cgram.y (revision 41b9722a1abf231082724f766574d77aa46a5bdd)
1 /*	Id: cgram.y,v 1.411 2016/01/10 18:08:13 ragge Exp 	*/
2 /*	$NetBSD: cgram.y,v 1.3 2016/02/09 20:37:32 plunky Exp $	*/
3 
4 /*
5  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 /*
30  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
31  *
32  * Redistribution and use in source and binary forms, with or without
33  * modification, are permitted provided that the following conditions
34  * are met:
35  *
36  * Redistributions of source code and documentation must retain the above
37  * copyright notice, this list of conditions and the following disclaimer.
38  * Redistributions in binary form must reproduce the above copyright
39  * notice, this list of conditions and the following disclaimer in the
40  * documentation and/or other materials provided with the distribution.
41  * All advertising materials mentioning features or use of this software
42  * must display the following acknowledgement:
43  * 	This product includes software developed or owned by Caldera
44  *	International, Inc.
45  * Neither the name of Caldera International, Inc. nor the names of other
46  * contributors may be used to endorse or promote products derived from
47  * this software without specific prior written permission.
48  *
49  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
50  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
51  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
52  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
53  * DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
54  * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
55  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
56  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
57  * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
58  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
59  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
60  * POSSIBILITY OF SUCH DAMAGE.
61  */
62 
63 /*
64  * Comments for this grammar file. Ragge 021123
65  *
66  * ANSI support required rewrite of the function header and declaration
67  * rules almost totally.
68  *
69  * The lex/yacc shared keywords are now split from the keywords used
70  * in the rest of the compiler, to simplify use of other frontends.
71  */
72 
73 /*
74  * At last count, there were 5 shift/reduce and no reduce/reduce conflicts
75  * All are accounted for;
76  * One is "dangling else"
77  * Two is in attribute parsing
78  * Two is in ({ }) parsing
79  */
80 
81 /*
82  * Token used in C lex/yacc communications.
83  */
84 %token	C_STRING	/* a string constant */
85 %token	C_ICON		/* an integer constant */
86 %token	C_FCON		/* a floating point constant */
87 %token	C_NAME		/* an identifier */
88 %token	C_TYPENAME	/* a typedef'd name */
89 %token	C_ANDAND	/* && */
90 %token	C_OROR		/* || */
91 %token	C_GOTO		/* unconditional goto */
92 %token	C_RETURN	/* return from function */
93 %token	C_TYPE		/* a type */
94 %token	C_CLASS		/* a storage class */
95 %token	C_ASOP		/* assignment ops */
96 %token	C_RELOP		/* <=, <, >=, > */
97 %token	C_EQUOP		/* ==, != */
98 %token	C_DIVOP		/* /, % */
99 %token	C_SHIFTOP	/* <<, >> */
100 %token	C_INCOP		/* ++, -- */
101 %token	C_UNOP		/* !, ~ */
102 %token	C_STROP		/* ., -> */
103 %token	C_STRUCT
104 %token	C_IF
105 %token	C_ELSE
106 %token	C_SWITCH
107 %token	C_BREAK
108 %token	C_CONTINUE
109 %token	C_WHILE
110 %token	C_DO
111 %token	C_FOR
112 %token	C_DEFAULT
113 %token	C_CASE
114 %token	C_SIZEOF
115 %token	C_ENUM
116 %token	C_ELLIPSIS
117 %token	C_QUALIFIER
118 %token	C_FUNSPEC
119 %token	C_ASM
120 %token	NOMATCH
121 %token	C_TYPEOF	/* COMPAT_GCC */
122 %token	C_ATTRIBUTE	/* COMPAT_GCC */
123 %token	PCC_OFFSETOF
124 %token	GCC_DESIG
125 
126 /* C11 keywords */
127 %token	C_STATICASSERT
128 %token	C_ALIGNAS
129 %token	C_ALIGNOF
130 %token	C_GENERIC
131 %token	C_ATOMIC
132 
133 /*
134  * Precedence
135  */
136 %left ','
137 %right '=' C_ASOP
138 %right '?' ':'
139 %left C_OROR
140 %left C_ANDAND
141 %left '|'
142 %left '^'
143 %left '&'
144 %left C_EQUOP
145 %left C_RELOP
146 %left C_SHIFTOP
147 %left '+' '-'
148 %left '*' C_DIVOP
149 %right C_UNOP
150 %right C_INCOP C_SIZEOF
151 %left '[' '(' C_STROP
152 %{
153 # include "pass1.h"
154 # include <stdarg.h>
155 # include <string.h>
156 # include <stdlib.h>
157 
158 int fun_inline;	/* Reading an inline function */
159 int oldstyle;	/* Current function being defined */
160 static struct symtab *xnf;
161 extern int enummer, tvaloff, inattr;
162 extern struct rstack *rpole;
163 static int alwinl;
164 P1ND *cftnod;
165 static int attrwarn = 1;
166 
167 #define	NORETYP	SNOCREAT /* no return type, save in unused field in symtab */
168 
169 struct genlist {
170 	struct genlist *next;
171 	P1ND *p;
172 	TWORD t;
173 };
174 
175        P1ND *bdty(int op, ...);
176 static void fend(void);
177 static void fundef(P1ND *tp, P1ND *p);
178 static void olddecl(P1ND *p, P1ND *a);
179 static struct symtab *init_declarator(P1ND *tn, P1ND *p, int assign, P1ND *a,
180 	char *as);
181 static void resetbc(int mask);
182 static void swend(void);
183 static void addcase(P1ND *p);
184 #ifdef GCC_COMPAT
185 static void gcccase(P1ND *p, P1ND *);
186 #endif
187 static struct attr *gcc_attr_wrapper(P1ND *p);
188 static void adddef(void);
189 static void savebc(void);
190 static void swstart(int, TWORD);
191 static void genswitch(int, TWORD, struct swents **, int);
192 static char *mkpstr(char *str);
193 static struct symtab *clbrace(P1ND *);
194 static P1ND *cmop(P1ND *l, P1ND *r);
195 static P1ND *xcmop(P1ND *out, P1ND *in, P1ND *str);
196 static void mkxasm(char *str, P1ND *p);
197 static P1ND *xasmop(char *str, P1ND *p);
198 static P1ND *biop(int op, P1ND *l, P1ND *r);
199 static void flend(void);
200 static P1ND *gccexpr(int bn, P1ND *q);
201 static char * simname(char *s);
202 static P1ND *tyof(P1ND *);	/* COMPAT_GCC */
203 static P1ND *voidcon(void);
204 static P1ND *funargs(P1ND *p);
205 static void oldargs(P1ND *p);
206 static void uawarn(P1ND *p, char *s);
207 static int con_e(P1ND *p);
208 static void dainit(P1ND *d, P1ND *a);
209 static P1ND *tymfix(P1ND *p);
210 static P1ND *namekill(P1ND *p, int clr);
211 static P1ND *aryfix(P1ND *p);
212 static P1ND *dogen(struct genlist *g, P1ND *e);
213 static struct genlist *newgen(P1ND *p, P1ND *q);
214 static struct genlist *addgen(struct genlist *g, struct genlist *h);
215 
216 static void savlab(int);
217 static void xcbranch(P1ND *, int);
218 extern int *mkclabs(void);
219 
220 #define	TYMFIX(inp) { \
221 	P1ND *pp = inp; \
222 	inp = tymerge(pp->n_left, pp->n_right); \
223 	p1nfree(pp->n_left); p1nfree(pp); }
224 
225 struct xalloc;
226 extern struct xalloc *bkpole, *sapole;
227 extern int cbkp, cstp;
228 extern int usdnodes;
229 struct bks {
230 	struct xalloc *ptr;
231 	int off;
232 };
233 
234 /*
235  * State for saving current switch state (when nested switches).
236  */
237 struct savbc {
238 	struct savbc *next;
239 	int brklab;
240 	int contlab;
241 	int flostat;
242 	int swx;
243 	struct xalloc *bkptr;
244 	int bkoff;
245 	struct xalloc *stptr;
246 	int stoff;
247 	int numnode;
248 } *savbc, *savctx;
249 
250 %}
251 
252 %union {
253 	TWORD type;
254 	int intval;
255 	P1ND *nodep;
256 	struct symtab *symp;
257 	struct rstack *rp;
258 	char *strp;
259 	struct bks *bkp;
260 	union flt *flt;
261 	struct genlist *g;
262 }
263 
264 	/* define types */
265 %start ext_def_list
266 
267 %type <intval> ifelprefix ifprefix whprefix forprefix doprefix switchpart
268 		xbegin
269 %type <nodep> e .e term enum_dcl struct_dcl cast_type declarator
270 		elist type_sq cf_spec merge_attribs e2 ecq
271 		parameter_declaration abstract_declarator initializer
272 		parameter_type_list parameter_list
273 		declaration_specifiers designation
274 		specifier_qualifier_list merge_specifiers
275 		identifier_list arg_param_list type_qualifier_list
276 		designator_list designator xasm oplist oper cnstr funtype
277 		typeof attribute attribute_specifier /* COMPAT_GCC */
278 		attribute_list attr_spec_list attr_var /* COMPAT_GCC */
279 
280 %type <g>	gen_ass_list gen_assoc
281 %type <strp>	string C_STRING GCC_DESIG svstr
282 %type <rp>	str_head
283 %type <symp>	xnfdeclarator clbrace enum_head
284 
285 %type <intval>  C_STRUCT C_RELOP C_DIVOP C_SHIFTOP
286 		C_ANDAND C_OROR C_STROP C_INCOP C_UNOP C_ASOP C_EQUOP
287 
288 %type <type>	C_TYPE C_QUALIFIER C_CLASS C_FUNSPEC
289 
290 %type <nodep>   C_ICON
291 
292 %type <flt>	C_FCON
293 
294 %type <strp>	C_NAME C_TYPENAME
295 %%
296 
297 ext_def_list:	   ext_def_list external_def
298 		| { ftnend(); }
299 		;
300 
301 external_def:	   funtype kr_args compoundstmt { fend(); }
302 		|  declaration  { blevel = 0; symclear(0); }
303 		|  asmstatement ';'
304 		|  ';'
305 		|  error { blevel = 0; }
306 		;
307 
308 funtype:	  /* no type given */ declarator {
309 		    fundef(mkty(INT, 0, 0), $1);
310 		    cftnsp->sflags |= NORETYP;
311 		}
312 		| declaration_specifiers declarator { fundef($1,$2); }
313 		;
314 
315 kr_args:	  /* empty */
316 		| arg_dcl_list
317 		;
318 
319 /*
320  * Returns a node pointer or NULL, if no types at all given.
321  * Type trees are checked for correctness and merged into one
322  * type node in typenode().
323  */
324 declaration_specifiers:
325 		   merge_attribs { $$ = typenode($1); }
326 		;
327 
328 merge_attribs:	   type_sq { $$ = $1; }
329 		|  type_sq merge_attribs { $$ = cmop($2, $1); }
330 		|  cf_spec { $$ = $1; }
331 		|  cf_spec merge_attribs { $$ = cmop($2, $1); }
332 		;
333 
334 type_sq:	   C_TYPE { $$ = mkty($1, 0, 0); }
335 		|  C_TYPENAME {
336 			struct symtab *sp = lookup($1, 0);
337 			if (sp->stype == ENUMTY) {
338 				sp->stype = strmemb(sp->sap)->stype;
339 			}
340 			$$ = mkty(sp->stype, sp->sdf, sp->sap);
341 			$$->n_sp = sp;
342 		}
343 		|  struct_dcl { $$ = $1; }
344 		|  enum_dcl { $$ = $1; }
345 		|  C_QUALIFIER { $$ = block(QUALIFIER, NULL, NULL, 0, 0, 0); $$->n_qual = $1; }
346 		|  attribute_specifier { $$ = biop(ATTRIB, $1, 0); }
347 		|  C_ALIGNAS '(' e ')' {
348 			$$ = biop(ALIGN, NULL, NULL);
349 			slval($$, con_e($3));
350 		}
351 		|  C_ALIGNAS '(' cast_type ')' {
352 			TYMFIX($3);
353 			$$ = biop(ALIGN, NULL, NULL);
354 			slval($$, talign($3->n_type, $3->n_ap)/SZCHAR);
355 			p1tfree($3);
356 		}
357 		|  C_ATOMIC { uerror("_Atomic not supported"); $$ = bcon(0); }
358 		|  C_ATOMIC '(' cast_type ')' {
359 			uerror("_Atomic not supported"); $$ = $3;
360 		}
361 		|  typeof { $$ = $1; }
362 		;
363 
364 cf_spec:	   C_CLASS { $$ = block(CLASS, NULL, NULL, $1, 0, 0); }
365 		|  C_FUNSPEC { $$ = block(FUNSPEC, NULL, NULL, $1, 0, 0); }
366 		;
367 
368 typeof:		   C_TYPEOF '(' e ')' { $$ = tyof(eve($3)); }
369 		|  C_TYPEOF '(' cast_type ')' { TYMFIX($3); $$ = tyof($3); }
370 		;
371 
372 attribute_specifier :
373 		   C_ATTRIBUTE '(' '(' attribute_list ')' ')' { $$ = $4; }
374  /*COMPAT_GCC*/	;
375 
376 attribute_list:	   attribute
377 		|  attribute ',' attribute_list { $$ = cmop($3, $1); }
378 		;
379 
380 attribute:	   {
381 #ifdef GCC_COMPAT
382 			 $$ = voidcon();
383 #endif
384 		}
385 		|  C_NAME { $$ = bdty(NAME, $1); }
386 		|  C_NAME '(' elist ')' {
387 			$$ = bdty($3 == NULL ? UCALL : CALL, bdty(NAME, $1), $3);
388 		}
389 		;
390 
391 /*
392  * Adds a pointer list to front of the declarators.
393  */
394 declarator:	   '*' declarator { $$ = bdty(UMUL, $2); }
395 		|  '*' type_qualifier_list declarator {
396 			$$ = $2;
397 			$$->n_left = $3;
398 		}
399 		|  C_NAME { $$ = bdty(NAME, $1); }
400 		|  '(' attr_spec_list declarator ')' {
401 			$$ = $3;
402 			$$->n_ap = attr_add($$->n_ap, gcc_attr_wrapper($2));
403 		}
404 		|  '(' declarator ')' { $$ = $2; }
405 		|  declarator '[' ecq ']' { $$ = biop(LB, $1, $3); }
406 		|  declarator '(' parameter_type_list ')' {
407 			$$ = bdty(CALL, $1, $3);
408 		}
409 		|  declarator '(' identifier_list ')' {
410 			$$ = bdty(CALL, $1, $3);
411 			oldstyle = 1;
412 		}
413 		|  declarator '(' ')' { $$ = bdty(UCALL, $1); }
414 		;
415 
416 ecq:		   maybe_r { $$ = bcon(NOOFFSET); }
417 		|  e  { $$ = $1; }
418 		|  r e { $$ = $2; }
419 		|  c maybe_r e { $$ = $3; }
420 		|  r c e { $$ = $3; }
421 		|  '*' { $$ = bcon(NOOFFSET); }
422 		|  r '*' { $$ = bcon(NOOFFSET); }
423 		;
424 
425 r:		  C_QUALIFIER {
426 			if ($1 != 0)
427 				uerror("bad qualifier");
428 		}
429 		;
430 
431 c:		  C_CLASS {
432 			if ($1 != STATIC)
433 				uerror("bad class keyword");
434 		}
435 		;
436 
437 type_qualifier_list:
438 		   C_QUALIFIER { $$ = biop(UMUL, 0, 0); $$->n_qual = $1; }
439 		|  type_qualifier_list C_QUALIFIER {
440 			$$ = $1;
441 			$$->n_qual |= $2;
442 		}
443 		|  attribute_specifier {
444 			$$ = block(UMUL, NULL, NULL, 0, 0, gcc_attr_wrapper($1));
445 		}
446 		|  type_qualifier_list attribute_specifier {
447 			$1->n_ap = attr_add($1->n_ap, gcc_attr_wrapper($2));
448 		}
449 		;
450 
451 identifier_list:   C_NAME { $$ = bdty(NAME, $1); oldargs($$); }
452 		|  identifier_list ',' C_NAME {
453 			$$ = cmop($1, bdty(NAME, $3));
454 			oldargs($$->n_right);
455 		}
456 		;
457 
458 /*
459  * Returns as parameter_list, but can add an additional ELLIPSIS node.
460  */
461 parameter_type_list:
462 		   parameter_list { $$ = $1; }
463 		|  parameter_list ',' C_ELLIPSIS {
464 			$$ = cmop($1, biop(ELLIPSIS, NULL, NULL));
465 		}
466 		;
467 
468 /*
469  * Returns a linked lists of nodes of op CM with parameters on
470  * its right and additional CM nodes of its left pointer.
471  * No CM nodes if only one parameter.
472  */
473 parameter_list:	   parameter_declaration { $$ = $1; }
474 		|  parameter_list ',' parameter_declaration {
475 			$$ = cmop($1, $3);
476 		}
477 		;
478 
479 /*
480  * Returns a node pointer to the declaration.
481  */
482 parameter_declaration:
483 		   declaration_specifiers declarator attr_var {
484 			if (glval($1) != SNULL && glval($1) != REGISTER)
485 				uerror("illegal parameter class");
486 			$$ = block(TYMERGE, $1, $2, INT, 0,
487 			    gcc_attr_wrapper($3));
488 		}
489 		|  declaration_specifiers abstract_declarator {
490 			$1->n_ap = attr_add($1->n_ap, $2->n_ap);
491 			$$ = block(TYMERGE, $1, $2, INT, 0, 0);
492 		}
493 		|  declaration_specifiers {
494 			$$ = block(TYMERGE, $1, bdty(NAME, NULL), INT, 0, 0);
495 		}
496 		;
497 
498 abstract_declarator:
499 		   '*' { $$ = bdty(UMUL, bdty(NAME, NULL)); }
500 		|  '*' type_qualifier_list {
501 			$$ = $2;
502 			$$->n_left = bdty(NAME, NULL);
503 		}
504 		|  '*' abstract_declarator { $$ = bdty(UMUL, $2); }
505 		|  '*' type_qualifier_list abstract_declarator {
506 			$$ = $2;
507 			$$->n_left = $3;
508 		}
509 		|  '(' abstract_declarator ')' { $$ = $2; }
510 		|  '[' maybe_r ']' attr_var {
511 			$$ = block(LB, bdty(NAME, NULL), bcon(NOOFFSET),
512 			    INT, 0, gcc_attr_wrapper($4));
513 		}
514 		|  '[' e ']' attr_var {
515 			$$ = block(LB, bdty(NAME, NULL), $2,
516 			    INT, 0, gcc_attr_wrapper($4));
517 		}
518 		|  abstract_declarator '[' maybe_r ']' attr_var {
519 			$$ = block(LB, $1, bcon(NOOFFSET),
520 			    INT, 0, gcc_attr_wrapper($5));
521 		}
522 		|  abstract_declarator '[' e ']' attr_var {
523 			$$ = block(LB, $1, $3, INT, 0, gcc_attr_wrapper($5));
524 		}
525 		|  '(' ')' attr_var {
526 			$$ = bdty(UCALL, bdty(NAME, NULL));
527 			$$->n_ap = gcc_attr_wrapper($3);
528 		}
529 		|  '(' ib2 parameter_type_list ')' attr_var {
530 			$$ = block(CALL, bdty(NAME, NULL), $3, INT, 0,
531 			    gcc_attr_wrapper($5));
532 		}
533 		|  abstract_declarator '(' ')' attr_var {
534 			$$ = block(UCALL, $1, NULL, INT, 0, gcc_attr_wrapper($4));
535 		}
536 		|  abstract_declarator '(' ib2 parameter_type_list ')' attr_var {
537 			$$ = block(CALL, $1, $4, INT, 0, gcc_attr_wrapper($6));
538 		}
539 		;
540 
541 ib2:		   { }
542 		;
543 
544 maybe_r:	   { }
545 		|  C_QUALIFIER { }
546 		;
547 
548 /*
549  * K&R arg declaration, between ) and {
550  */
551 arg_dcl_list:	   arg_declaration
552 		|  arg_dcl_list arg_declaration
553 		;
554 
555 
556 arg_declaration:   declaration_specifiers arg_param_list ';' {
557 			p1nfree($1);
558 		}
559 		;
560 
561 arg_param_list:	   declarator attr_var {
562 			olddecl(block(TYMERGE, p1tcopy($<nodep>0), $1,
563 			    INT, 0, 0), $2);
564 		}
565 		|  arg_param_list ',' declarator attr_var {
566 			olddecl(block(TYMERGE, p1tcopy($<nodep>0), $3,
567 			    INT, 0, 0), $4);
568 		}
569 		;
570 
571 /*
572  * Declarations in beginning of blocks.
573  */
574 block_item_list:   block_item
575 		|  block_item_list block_item
576 		;
577 
578 block_item:	   declaration
579 		|  statement { stmtfree(); }
580 		;
581 
582 /*
583  * Here starts the old YACC code.
584  */
585 
586 /*
587  * Variables are declared in init_declarator.
588  */
589 declaration:	   declaration_specifiers ';' { p1tfree($1); fun_inline = 0; }
590 		|  declaration_specifiers init_declarator_list ';' {
591 			p1tfree($1);
592 			fun_inline = 0;
593 		}
594 		|  C_STATICASSERT '(' e ',' string ')' ';' {
595 			int r = con_e($3);
596 			if (r == 0) /* false */
597 				uerror($5);
598 		}
599 		;
600 
601 /*
602  * Normal declaration of variables. curtype contains the current type node.
603  * Returns nothing, variables are declared in init_declarator.
604  */
605 init_declarator_list:
606 		   init_declarator { symclear(blevel); }
607 		|  init_declarator_list ',' attr_var { $<nodep>$ = $<nodep>0; } init_declarator {
608 			uawarn($3, "init_declarator");
609 			symclear(blevel);
610 		}
611 		;
612 
613 enum_dcl:	   enum_head '{' moe_list optcomma '}' { $$ = enumdcl($1); }
614 		|  C_ENUM C_NAME {  $$ = enumref($2); }
615 		;
616 
617 enum_head:	   C_ENUM { $$ = enumhd(NULL); }
618 		|  C_ENUM C_NAME {  $$ = enumhd($2); }
619 		;
620 
621 moe_list:	   moe
622 		|  moe_list ',' moe
623 		;
624 
625 moe:		   C_NAME {  moedef($1); }
626 		|  C_TYPENAME {  moedef($1); }
627 		|  C_NAME '=' e { enummer = con_e($3); moedef($1); }
628 		|  C_TYPENAME '=' e { enummer = con_e($3); moedef($1); }
629 		;
630 
631 struct_dcl:	   str_head '{' struct_dcl_list '}' {
632 			P1ND *p;
633 
634 			$$ = dclstruct($1);
635 			if (pragma_allpacked) {
636 				p = bdty(CALL, bdty(NAME, "packed"),
637 				    bcon(pragma_allpacked));
638 				$$->n_ap = attr_add($$->n_ap,gcc_attr_wrapper(p)); }
639 		}
640 		|  C_STRUCT attr_var C_NAME {
641 			$$ = rstruct($3,$1);
642 			uawarn($2, "struct_dcl");
643 		}
644  /*COMPAT_GCC*/	|  str_head '{' '}' { $$ = dclstruct($1); }
645 		;
646 
647 attr_var:	   {
648 			P1ND *q, *p;
649 
650 			p = pragma_aligned ? bdty(CALL, bdty(NAME, "aligned"),
651 			    bcon(pragma_aligned)) : NULL;
652 			if (pragma_packed) {
653 				q = bdty(NAME, "packed");
654 				p = (p == NULL ? q : cmop(p, q));
655 			}
656 			pragma_aligned = pragma_packed = 0;
657 			$$ = p;
658 		}
659  /*COMPAT_GCC*/	|  attr_spec_list
660 		;
661 
662 attr_spec_list:	   attribute_specifier
663 		|  attr_spec_list attribute_specifier { $$ = cmop($1, $2); }
664 		;
665 
666 str_head:	   C_STRUCT attr_var {  $$ = bstruct(NULL, $1, $2);  }
667 		|  C_STRUCT attr_var C_NAME {  $$ = bstruct($3, $1, $2);  }
668 		;
669 
670 struct_dcl_list:   struct_declaration
671 		|  struct_dcl_list struct_declaration
672 		;
673 
674 struct_declaration:
675 		   specifier_qualifier_list struct_declarator_list optsemi {
676 			p1tfree($1);
677 		}
678 		;
679 
680 optsemi:	   ';' { }
681 		|  optsemi ';' { werror("extra ; in struct"); }
682 		;
683 
684 specifier_qualifier_list:
685 		   merge_specifiers { $$ = typenode($1); }
686 		;
687 
688 merge_specifiers:  type_sq merge_specifiers { $$ = cmop($2, $1); }
689 		|  type_sq { $$ = $1; }
690 		;
691 
692 struct_declarator_list:
693 		   struct_declarator { symclear(blevel); }
694 		|  struct_declarator_list ',' { $<nodep>$=$<nodep>0; }
695 			struct_declarator { symclear(blevel); }
696 		;
697 
698 struct_declarator: declarator attr_var {
699 			P1ND *p;
700 
701 			$1 = aryfix($1);
702 			p = tymerge($<nodep>0, tymfix($1));
703 			if ($2)
704 				p->n_ap = attr_add(p->n_ap, gcc_attr_wrapper($2));
705 			soumemb(p, (char *)$1->n_sp, 0);
706 			p1tfree(p);
707 		}
708 		|  ':' e {
709 			int ie = con_e($2);
710 			if (fldchk(ie))
711 				ie = 1;
712 			falloc(NULL, ie, $<nodep>0);
713 		}
714 		|  declarator ':' e {
715 			int ie = con_e($3);
716 			if (fldchk(ie))
717 				ie = 1;
718 			if ($1->n_op == NAME) {
719 				/* XXX - tymfix() may alter $1 */
720 				tymerge($<nodep>0, tymfix($1));
721 				soumemb($1, (char *)$1->n_sp, FIELD | ie);
722 				p1nfree($1);
723 			} else
724 				uerror("illegal declarator");
725 		}
726 		|  declarator ':' e attr_spec_list {
727 			int ie = con_e($3);
728 			if (fldchk(ie))
729 				ie = 1;
730 			if ($1->n_op == NAME) {
731 				/* XXX - tymfix() may alter $1 */
732 				tymerge($<nodep>0, tymfix($1));
733 				if ($4)
734 					$1->n_ap = attr_add($1->n_ap,
735 					    gcc_attr_wrapper($4));
736 				soumemb($1, (char *)$1->n_sp, FIELD | ie);
737 				p1nfree($1);
738 			} else
739 				uerror("illegal declarator");
740 		}
741 		| /* unnamed member */ {
742 			P1ND *p = $<nodep>0;
743 			char *c = permalloc(10);
744 
745 			if (p->n_type != STRTY && p->n_type != UNIONTY)
746 				uerror("bad unnamed member type");
747 			snprintf(c, 10, "*%dFAKE", getlab());
748 			soumemb(p, c, 0);
749 		}
750 		;
751 
752 		/* always preceeded by attributes */
753 xnfdeclarator:	   declarator attr_var {
754 			$$ = xnf = init_declarator($<nodep>0, $1, 1, $2, 0);
755 		}
756 		|  declarator C_ASM '(' svstr ')' {
757 			$$ = xnf = init_declarator($<nodep>0, $1, 1, NULL, $4);
758 		}
759 		;
760 
761 /*
762  * Handles declarations and assignments.
763  * Returns nothing.
764  */
765 init_declarator:   declarator attr_var {
766 			init_declarator($<nodep>0, $1, 0, $2, 0);
767 		}
768 		|  declarator C_ASM '(' svstr ')' attr_var {
769 			init_declarator($<nodep>0, $1, 0, $6, $4);
770 		}
771 		|  xnfdeclarator '=' e {
772 			if ($1->sclass == STATIC || $1->sclass == EXTDEF)
773 				statinit++;
774 			simpleinit($1, eve($3));
775 			if ($1->sclass == STATIC || $1->sclass == EXTDEF)
776 				statinit--;
777 			xnf = NULL;
778 		}
779 		|  xnfdeclarator '=' begbr init_list optcomma '}' {
780 			endinit(0);
781 			xnf = NULL;
782 		}
783  /*COMPAT_GCC*/	|  xnfdeclarator '=' begbr '}' { endinit(0); xnf = NULL; }
784 		;
785 
786 begbr:		   '{' { beginit($<symp>-1); }
787 		;
788 
789 initializer:	   e %prec ',' {  $$ = eve($1); }
790 		|  ibrace init_list optcomma '}' { $$ = NULL; }
791 		|  ibrace '}' { asginit(bcon(0)); $$ = NULL; }
792 		;
793 
794 init_list:	   designation initializer { dainit($1, $2); }
795 		|  init_list ','  designation initializer { dainit($3, $4); }
796 		;
797 
798 designation:	   designator_list '=' { desinit($1); $$ = NULL; }
799 		|  GCC_DESIG { desinit(bdty(NAME, $1)); $$ = NULL; }
800 		|  '[' e C_ELLIPSIS e ']' '=' { $$ = biop(CM, $2, $4); }
801 		|  { $$ = NULL; }
802 		;
803 
804 designator_list:   designator { $$ = $1; }
805 		|  designator_list designator { $$ = $2; $$->n_left = $1; }
806 		;
807 
808 designator:	   '[' e ']' {
809 			int ie = con_e($2);
810 			if (ie < 0) {
811 				uerror("designator must be non-negative");
812 				ie = 0;
813 			}
814 			$$ = biop(LB, NULL, bcon(ie));
815 		}
816 		|  C_STROP C_TYPENAME {
817 			if ($1 != DOT)
818 				uerror("invalid designator");
819 			$$ = bdty(NAME, $2);
820 		}
821 		|  C_STROP C_NAME {
822 			if ($1 != DOT)
823 				uerror("invalid designator");
824 			$$ = bdty(NAME, $2);
825 		}
826 		;
827 
828 optcomma	:	/* VOID */
829 		|  ','
830 		;
831 
832 ibrace:		   '{' {  ilbrace(); }
833 		;
834 
835 /*	STATEMENTS	*/
836 
837 compoundstmt:	   begin block_item_list '}' { flend(); }
838 		|  begin '}' { flend(); }
839 		;
840 
841 begin:		  '{' {
842 			struct savbc *bc = malloc(sizeof(struct savbc));
843 			if (blevel == 1) {
844 #ifdef STABS
845 				if (gflag)
846 					stabs_line(lineno);
847 #endif
848 				dclargs();
849 			}
850 #ifdef STABS
851 			if (gflag && blevel > 1)
852 				stabs_lbrac(blevel+1);
853 #endif
854 			++blevel;
855 			oldstyle = 0;
856 			bc->contlab = autooff;
857 			bc->next = savctx;
858 			bc->bkptr = bkpole;
859 			bc->bkoff = cbkp;
860 			bc->stptr = sapole;
861 			bc->stoff = cstp;
862 			bc->numnode = usdnodes;
863 			usdnodes = 0;
864 			bkpole = sapole = NULL;
865 			cbkp = cstp = 0;
866 			savctx = bc;
867 			if (!isinlining && sspflag && blevel == 2)
868 				sspstart();
869 		}
870 		;
871 
872 statement:	   e ';' { ecomp(eve($1)); symclear(blevel); }
873 		|  compoundstmt
874 		|  ifprefix statement { plabel($1); reached = 1; }
875 		|  ifelprefix statement {
876 			if ($1 != NOLAB) {
877 				plabel( $1);
878 				reached = 1;
879 			}
880 		}
881 		|  whprefix statement {
882 			branch(contlab);
883 			plabel( brklab );
884 			if( (flostat&FBRK) || !(flostat&FLOOP))
885 				reached = 1;
886 			else
887 				reached = 0;
888 			resetbc(0);
889 		}
890 		|  doprefix statement C_WHILE '(' e ')' ';' {
891 			plabel(contlab);
892 			if (flostat & FCONT)
893 				reached = 1;
894 			if (reached)
895 				cbranch(buildtree(NE, eve($5), bcon(0)),
896 				    bcon($1));
897 			else
898 				p1tfree(eve($5));
899 			plabel( brklab);
900 			reached = 1;
901 			resetbc(0);
902 		}
903 		|  forprefix .e ')' statement
904 			{  plabel( contlab );
905 			    if( flostat&FCONT ) reached = 1;
906 			    if( $2 ) ecomp( $2 );
907 			    branch($1);
908 			    plabel( brklab );
909 			    if( (flostat&FBRK) || !(flostat&FLOOP) ) reached = 1;
910 			    else reached = 0;
911 			    resetbc(0);
912 			    blevel--;
913 			    symclear(blevel);
914 			    }
915 		| switchpart statement
916 			{ if( reached ) branch( brklab );
917 			    plabel( $1 );
918 			    swend();
919 			    plabel( brklab);
920 			    if( (flostat&FBRK) || !(flostat&FDEF) ) reached = 1;
921 			    resetbc(FCONT);
922 			    }
923 		|  C_BREAK  ';' {
924 			if (brklab == NOLAB)
925 				uerror("illegal break");
926 			else if (reached)
927 				branch(brklab);
928 			flostat |= FBRK;
929 			reached = 0;
930 		}
931 		|  C_CONTINUE  ';' {
932 			if (contlab == NOLAB)
933 				uerror("illegal continue");
934 			else
935 				branch(contlab);
936 			flostat |= FCONT;
937 			goto rch;
938 		}
939 		|  C_RETURN  ';' {
940 			branch(retlab);
941 			if (cftnsp->stype != VOID &&
942 			    (cftnsp->sflags & NORETYP) == 0 &&
943 			    cftnsp->stype != VOID+FTN)
944 				uerror("return value required");
945 			rch:
946 			if (!reached)
947 				warner(Wunreachable_code);
948 			reached = 0;
949 		}
950 		|  C_RETURN e  ';' {
951 			P1ND *p, *q;
952 
953 			p = nametree(cftnsp);
954 			p->n_type = DECREF(p->n_type);
955 			q = eve($2);
956 #ifdef TARGET_TIMODE
957 			P1ND *r;
958 			if ((r = gcc_eval_ticast(RETURN, p, q)) != NULL)
959 				q = r;
960 #endif
961 #ifndef NO_COMPLEX
962 			if (ANYCX(q) || ANYCX(p))
963 				q = cxret(q, p);
964 			else if (ISITY(p->n_type) || ISITY(q->n_type)) {
965 				q = imret(q, p);
966 				if (ISITY(p->n_type))
967 					p->n_type -= (FIMAG-FLOAT);
968 				if (ISITY(q->n_type))
969 					q->n_type -= (FIMAG-FLOAT);
970 			}
971 #endif
972 			p = buildtree(RETURN, p, q);
973 			if (p->n_type == VOID) {
974 				ecomp(p->n_right);
975 			} else {
976 				if (cftnod == NULL) {
977 					P1ND *r = tempnode(0, p->n_type,
978 					    p->n_df, p->n_ap);
979 					cftnod = tmpalloc(sizeof(P1ND));
980 					*cftnod = *r;
981 					p1tfree(r);
982 				}
983 				ecomp(buildtree(ASSIGN,
984 				    p1tcopy(cftnod), p->n_right));
985 			}
986 			p1tfree(p->n_left);
987 			p1nfree(p);
988 			branch(retlab);
989 			reached = 0;
990 		}
991 		|  C_GOTO C_NAME ';' { gotolabel($2); goto rch; }
992 		|  C_GOTO '*' e ';' { ecomp(biop(GOTO, eve($3), NULL)); }
993 		|  asmstatement ';'
994 		|   ';'
995 		|  error  ';'
996 		|  error '}'
997 		|  label statement
998 		;
999 
1000 asmstatement:	   C_ASM mvol '(' svstr ')' { send_passt(IP_ASM, mkpstr($4)); }
1001 		|  C_ASM mvol '(' svstr xasm ')' { mkxasm($4, $5); }
1002 		;
1003 
1004 svstr:		  string { $$ = addstring($1); }
1005 		;
1006 
1007 mvol:		   /* empty */
1008 		|  C_QUALIFIER { }
1009 		;
1010 
1011 xasm:		   ':' oplist { $$ = xcmop($2, NULL, NULL); }
1012 		|  ':' oplist ':' oplist { $$ = xcmop($2, $4, NULL); }
1013 		|  ':' oplist ':' oplist ':' cnstr { $$ = xcmop($2, $4, $6); }
1014 		;
1015 
1016 oplist:		   /* nothing */ { $$ = NULL; }
1017 		|  oper { $$ = $1; }
1018 		;
1019 
1020 oper:		   svstr '(' e ')' { $$ = xasmop($1, pconvert(eve($3))); }
1021 		|  oper ',' svstr '(' e ')' {
1022 			$$ = cmop($1, xasmop($3, pconvert(eve($5))));
1023 		}
1024 		;
1025 
1026 cnstr:		   svstr { $$ = xasmop($1, bcon(0)); }
1027 		|  cnstr ',' svstr { $$ = cmop($1, xasmop($3, bcon(0))); }
1028                 ;
1029 
1030 label:		   C_NAME ':' attr_var { deflabel($1, $3); reached = 1; }
1031 		|  C_TYPENAME ':' attr_var { deflabel($1, $3); reached = 1; }
1032 		|  C_CASE e ':' { addcase(eve($2)); reached = 1; }
1033 /* COMPAT_GCC */|  C_CASE e C_ELLIPSIS e ':' {
1034 #ifdef GCC_COMPAT
1035 			gcccase(eve($2), eve($4)); reached = 1;
1036 #endif
1037 		}
1038 		|  C_DEFAULT ':' { reached = 1; adddef(); flostat |= FDEF; }
1039 		;
1040 
1041 doprefix:	C_DO {
1042 			savebc();
1043 			brklab = getlab();
1044 			contlab = getlab();
1045 			plabel(  $$ = getlab());
1046 			reached = 1;
1047 		}
1048 		;
1049 ifprefix:	C_IF '(' e ')' {
1050 			xcbranch(eve($3), $$ = getlab());
1051 			reached = 1;
1052 		}
1053 		;
1054 ifelprefix:	  ifprefix statement C_ELSE {
1055 			if (reached)
1056 				branch($$ = getlab());
1057 			else
1058 				$$ = NOLAB;
1059 			plabel( $1);
1060 			reached = 1;
1061 		}
1062 		;
1063 
1064 whprefix:	  C_WHILE  '('  e  ')' {
1065 			savebc();
1066 			$3 = eve($3);
1067 			if ($3->n_op == ICON && glval($3) != 0)
1068 				flostat = FLOOP;
1069 			plabel( contlab = getlab());
1070 			reached = 1;
1071 			brklab = getlab();
1072 			if (flostat == FLOOP)
1073 				p1tfree($3);
1074 			else
1075 				xcbranch($3, brklab);
1076 		}
1077 		;
1078 forprefix:	  C_FOR  '('  .e  ';' .e  ';' {
1079 			++blevel;
1080 			if ($3)
1081 				ecomp($3);
1082 			savebc();
1083 			contlab = getlab();
1084 			brklab = getlab();
1085 			plabel( $$ = getlab());
1086 			reached = 1;
1087 			if ($5)
1088 				xcbranch($5, brklab);
1089 			else
1090 				flostat |= FLOOP;
1091 		}
1092 		|  C_FOR '(' { ++blevel; } declaration .e ';' {
1093 			savebc();
1094 			contlab = getlab();
1095 			brklab = getlab();
1096 			plabel( $$ = getlab());
1097 			reached = 1;
1098 			if ($5)
1099 				xcbranch($5, brklab);
1100 			else
1101 				flostat |= FLOOP;
1102 		}
1103 		;
1104 
1105 switchpart:	   C_SWITCH  '('  e ')' {
1106 			P1ND *p;
1107 			int num;
1108 			TWORD t;
1109 
1110 			savebc();
1111 			brklab = getlab();
1112 			$3 = eve($3);
1113 			if (!ISINTEGER($3->n_type)) {
1114 				uerror("switch expression must have integer "
1115 				       "type");
1116 				t = INT;
1117 			} else {
1118 				$3 = intprom($3);
1119 				t = $3->n_type;
1120 			}
1121 			p = tempnode(0, t, 0, 0);
1122 			num = regno(p);
1123 			ecomp(buildtree(ASSIGN, p, $3));
1124 			branch( $$ = getlab());
1125 			swstart(num, t);
1126 			reached = 0;
1127 		}
1128 		;
1129 /*	EXPRESSIONS	*/
1130 .e:		   e { $$ = eve($1); }
1131 		| 	{ $$=0; }
1132 		;
1133 
1134 elist:		   { $$ = NULL; }
1135 		|  e2 { $$ = $1; }
1136 		;
1137 
1138 e2:		   e %prec ','
1139 		|  e2  ','  e { $$ = biop(CM, $1, $3); }
1140 		|  e2  ','  cast_type { /* hack for stdarg */
1141 			TYMFIX($3);
1142 			$3->n_op = TYPE;
1143 			$$ = biop(CM, $1, $3);
1144 		}
1145 		|  cast_type { TYMFIX($1); $1->n_op = TYPE; $$ = $1; }
1146 		;
1147 
1148 /*
1149  * Precedence order of operators.
1150  */
1151 e:		   e ',' e { $$ = biop(COMOP, $1, $3); }
1152 		|  e '=' e {  $$ = biop(ASSIGN, $1, $3); }
1153 		|  e C_ASOP e {  $$ = biop($2, $1, $3); }
1154 		|  e '?' e ':' e { $$=biop(QUEST, $1, biop(COLON, $3, $5)); }
1155 /* COMPAT_GCC */|  e '?' ':' e { $$ = biop(BIQUEST, $1, $4); }
1156 		|  e C_OROR e { $$ = biop($2, $1, $3); }
1157 		|  e C_ANDAND e { $$ = biop($2, $1, $3); }
1158 		|  e '|' e { $$ = biop(OR, $1, $3); }
1159 		|  e '^' e { $$ = biop(ER, $1, $3); }
1160 		|  e '&' e { $$ = biop(AND, $1, $3); }
1161 		|  e C_EQUOP  e { $$ = biop($2, $1, $3); }
1162 		|  e C_RELOP e { $$ = biop($2, $1, $3); }
1163 		|  e C_SHIFTOP e { $$ = biop($2, $1, $3); }
1164 		|  e '+' e { $$ = biop(PLUS, $1, $3); }
1165 		|  e '-' e { $$ = biop(MINUS, $1, $3); }
1166 		|  e C_DIVOP e { $$ = biop($2, $1, $3); }
1167 		|  e '*' e { $$ = biop(MUL, $1, $3); }
1168 		|  term
1169 		;
1170 
1171 xbegin:		   begin {
1172 			$$ = getlab(); getlab(); getlab();
1173 			branch($$); plabel(($$)+2);
1174 		}
1175 		;
1176 
1177 term:		   term C_INCOP {  $$ = biop($2, $1, bcon(1)); }
1178 		|  '*' term { $$ = biop(UMUL, $2, NULL); }
1179 		|  '&' term { $$ = biop(ADDROF, $2, NULL); }
1180 		|  '-' term { $$ = biop(UMINUS, $2, NULL ); }
1181 		|  '+' term { $$ = biop(UPLUS, $2, NULL ); }
1182 		|  C_UNOP term { $$ = biop($1, $2, NULL); }
1183 		|  C_INCOP term {
1184 			$$ = biop($1 == INCR ? PLUSEQ : MINUSEQ, $2, bcon(1));
1185 		}
1186 		|  C_SIZEOF xa term { $$ = biop(SZOF, $3, bcon(0)); inattr = $<intval>2; }
1187 		|  '(' cast_type ')' term  %prec C_INCOP {
1188 			TYMFIX($2);
1189 			$$ = biop(CAST, $2, $4);
1190 		}
1191 		|  C_SIZEOF xa '(' cast_type ')'  %prec C_SIZEOF {
1192 			$$ = biop(SZOF, $4, bcon(1));
1193 			inattr = $<intval>2;
1194 		}
1195 		|  C_ALIGNOF xa '(' cast_type ')' {
1196 			int al;
1197 			TYMFIX($4);
1198 			al = talign($4->n_type, $4->n_ap);
1199 			$$ = bcon(al/SZCHAR);
1200 			inattr = $<intval>2;
1201 			p1tfree($4);
1202 		}
1203 		| '(' cast_type ')' clbrace init_list optcomma '}' {
1204 			endinit(0);
1205 			$$ = bdty(NAME, $4);
1206 			$$->n_op = CLOP;
1207 		}
1208 		| '(' cast_type ')' clbrace '}' {
1209 			endinit(0);
1210 			$$ = bdty(NAME, $4);
1211 			$$->n_op = CLOP;
1212 		}
1213 		|  term '[' e ']' { $$ = biop(LB, $1, $3); }
1214 		|  C_NAME  '(' elist ')' {
1215 			$$ = biop($3 ? CALL : UCALL, bdty(NAME, $1), $3);
1216 		}
1217 		|  term  '(' elist ')' { $$ = biop($3 ? CALL : UCALL, $1, $3); }
1218 		|  term C_STROP C_NAME { $$ = biop($2, $1, bdty(NAME, $3)); }
1219 		|  term C_STROP C_TYPENAME { $$ = biop($2, $1, bdty(NAME, $3));}
1220 		|  C_NAME %prec C_SIZEOF /* below ( */{ $$ = bdty(NAME, $1); }
1221 		|  PCC_OFFSETOF  '(' cast_type ',' term ')' {
1222 			TYMFIX($3);
1223 			$3->n_type = INCREF($3->n_type);
1224 			$3 = biop(CAST, $3, bcon(0));
1225 			if ($5->n_op == NAME) {
1226 				$$ = biop(STREF, $3, $5);
1227 			} else {
1228 				P1ND *p = $5;
1229 				while (p->n_left->n_op != NAME)
1230 					p = p->n_left;
1231 				p->n_left = biop(STREF, $3, p->n_left);
1232 				$$ = $5;
1233 			}
1234 			$$ = biop(ADDROF, $$, NULL);
1235 			$3 = block(NAME, NULL, NULL, ENUNSIGN(INTPTR), 0, 0);
1236 			$$ = biop(CAST, $3, $$);
1237 		}
1238 		|  C_ICON { $$ = $1; }
1239 		|  C_FCON { $$ = bdty(FCON, $1); }
1240 		|  svstr { $$ = bdty(STRING, $1, styp()); }
1241 		|  '(' e ')' { $$=$2; }
1242 		|  '(' xbegin e ';' '}' ')' { $$ = gccexpr($2, eve($3)); }
1243 		|  '(' xbegin block_item_list e ';' '}' ')' {
1244 			$$ = gccexpr($2, eve($4));
1245 		}
1246 		|  '(' xbegin block_item_list '}' ')' {
1247 			$$ = gccexpr($2, voidcon());
1248 		}
1249 		| C_ANDAND C_NAME {
1250 			struct symtab *s = lookup($2, SLBLNAME|STEMP);
1251 			if (s->soffset == 0) {
1252 				s->soffset = -getlab();
1253 				s->sclass = STATIC;
1254 			}
1255 			savlab(s->soffset);
1256 			$$ = biop(ADDROF, bdty(GOTO, $2), NULL);
1257 		}
1258 		| C_GENERIC '(' e ',' gen_ass_list ')' { $$ = dogen($5, $3); }
1259 		;
1260 
1261 gen_ass_list:	  gen_assoc { $$ = $1; }
1262 		| gen_ass_list ',' gen_assoc { $$ = addgen($1, $3); }
1263 		;
1264 
1265 gen_assoc:	  cast_type ':' e { TYMFIX($1); $$ = newgen($1, $3); }
1266 		| C_DEFAULT ':' e { $$ = newgen(0, $3); }
1267 		;
1268 
1269 xa:		  { $<intval>$ = inattr; inattr = 0; }
1270 		;
1271 
1272 clbrace:	   '{'	{ P1ND *q = $<nodep>-1; TYMFIX(q); $$ = clbrace(q); }
1273 		;
1274 
1275 string:		   C_STRING { $$ = stradd(NULL, $1); }
1276 		|  string C_STRING { $$ = stradd($1, $2); }
1277 		;
1278 
1279 cast_type:	   specifier_qualifier_list {
1280 			$$ = biop(TYMERGE, $1, bdty(NAME, NULL));
1281 		}
1282 		|  specifier_qualifier_list abstract_declarator {
1283 			$$ = biop(TYMERGE, $1, aryfix($2));
1284 		}
1285 		;
1286 
1287 %%
1288 
1289 P1ND *
1290 mkty(TWORD t, union dimfun *d, struct attr *sue)
1291 {
1292 	return block(TYPE, NULL, NULL, t, d, sue);
1293 }
1294 
1295 P1ND *
bdty(int op,...)1296 bdty(int op, ...)
1297 {
1298 	CONSZ c;
1299 	va_list ap;
1300 	int val;
1301 	register P1ND *q;
1302 
1303 	va_start(ap, op);
1304 	q = biop(op, NULL, NULL);
1305 
1306 	switch (op) {
1307 	case UMUL:
1308 	case UCALL:
1309 		q->n_left = va_arg(ap, P1ND *);
1310 		q->n_rval = 0;
1311 		break;
1312 
1313 	case FCON:
1314 		q->n_dcon = va_arg(ap, union flt *);
1315 		q->n_type = q->n_dcon->fa[FP_TOP];
1316 		break;
1317 
1318 	case CALL:
1319 		q->n_left = va_arg(ap, P1ND *);
1320 		q->n_right = va_arg(ap, P1ND *);
1321 		break;
1322 
1323 	case LB:
1324 		q->n_left = va_arg(ap, P1ND *);
1325 		if ((val = va_arg(ap, int)) <= 0) {
1326 			uerror("array size must be positive");
1327 			val = 1;
1328 		}
1329 		q->n_right = bcon(val);
1330 		break;
1331 
1332 	case GOTO: /* for named labels */
1333 		q->n_ap = attr_add(q->n_ap, attr_new(ATTR_P1LABELS, 1));
1334 		/* FALLTHROUGH */
1335 	case NAME:
1336 		q->n_op = NAME;
1337 		q->n_sp = va_arg(ap, struct symtab *); /* XXX survive tymerge */
1338 		break;
1339 
1340 	case STRING:
1341 		q->n_type = PTR|CHAR;
1342 		q->n_name = va_arg(ap, char *);
1343 		c = va_arg(ap, TWORD);
1344 		slval(q, c);
1345 		break;
1346 
1347 	default:
1348 		cerror("bad bdty");
1349 	}
1350 	va_end(ap);
1351 
1352 	return q;
1353 }
1354 
1355 static void
flend(void)1356 flend(void)
1357 {
1358 	struct savbc *sc;
1359 
1360 	if (!isinlining && sspflag && blevel == 2)
1361 		sspend();
1362 #ifdef STABS
1363 	if (gflag && blevel > 2)
1364 		stabs_rbrac(blevel);
1365 #endif
1366 	--blevel;
1367 	if( blevel == 1 )
1368 		blevel = 0;
1369 	symclear(blevel); /* Clean ut the symbol table */
1370 	if (autooff > maxautooff)
1371 		maxautooff = autooff;
1372 	autooff = savctx->contlab;
1373 	blkfree();
1374 	stmtfree();
1375 	bkpole = savctx->bkptr;
1376 	cbkp = savctx->bkoff;
1377 	sapole = savctx->stptr;
1378 	cstp = savctx->stoff;
1379 	usdnodes = savctx->numnode;
1380 	sc = savctx->next;
1381 	free(savctx);
1382 	savctx = sc;
1383 }
1384 
1385 /*
1386  * XXX workaround routines for block level cleansing in gcc compat mode.
1387  * Temporary should be re reserved for this value before.
1388  */
1389 static P1ND *
p1mcopy(P1ND * p)1390 p1mcopy(P1ND *p)
1391 {
1392 	P1ND *q;
1393 
1394 	q = xmalloc(sizeof(P1ND));
1395 	*q = *p;
1396 
1397 	switch (coptype(q->n_op)) {
1398 	case BITYPE:
1399 		q->n_right = p1mcopy(p->n_right);
1400 		/* FALLTHROUGH */
1401 	case UTYPE:
1402 		q->n_left = p1mcopy(p->n_left);
1403 	}
1404 
1405 	return(q);
1406 }
1407 
1408 static void
p1mfree(P1ND * p)1409 p1mfree(P1ND *p)
1410 {
1411 	int o = coptype(p->n_op);
1412 	if (o == BITYPE)
1413 		p1mfree(p->n_right);
1414 	if (o != LTYPE)
1415 		p1mfree(p->n_left);
1416 	free(p);
1417 }
1418 
1419 
1420 static P1ND *
gccexpr(int bn,P1ND * q)1421 gccexpr(int bn, P1ND *q)
1422 {
1423 	P1ND *r, *p, *s;
1424 
1425 	branch(bn+4);
1426 	plabel(bn);
1427 	r = buildtree(COMOP, biop(GOTO, bcon(bn+2), NULL), q);
1428 	/* XXX hack to survive flend() */
1429 	s = p1mcopy(r);
1430 	p1tfree(r);
1431 	flend();
1432 	r = p1tcopy(s);
1433 	p1mfree(s);
1434 	q = r->n_right;
1435 	/* XXX end hack */
1436 	if (q->n_op != ICON && q->n_type != STRTY) {
1437 		p = tempnode(0, q->n_type, q->n_df, q->n_ap);
1438 		r = buildtree(ASSIGN, p1tcopy(p), r);
1439 		r = buildtree(COMOP, r, p);
1440 	}
1441 	return r;
1442 }
1443 
1444 static void
savebc(void)1445 savebc(void)
1446 {
1447 	struct savbc *bc = malloc(sizeof(struct savbc));
1448 
1449 	bc->brklab = brklab;
1450 	bc->contlab = contlab;
1451 	bc->flostat = flostat;
1452 	bc->next = savbc;
1453 	savbc = bc;
1454 	flostat = 0;
1455 }
1456 
1457 static void
resetbc(int mask)1458 resetbc(int mask)
1459 {
1460 	struct savbc *bc;
1461 
1462 	flostat = savbc->flostat | (flostat&mask);
1463 	contlab = savbc->contlab;
1464 	brklab = savbc->brklab;
1465 	bc = savbc->next;
1466 	free(savbc);
1467 	savbc = bc;
1468 }
1469 
1470 struct swdef {
1471 	struct swdef *next;	/* Next in list */
1472 	int deflbl;		/* Label for "default" */
1473 	struct swents *ents;	/* Linked sorted list of case entries */
1474 	int nents;		/* # of entries in list */
1475 	int num;		/* Node value will end up in */
1476 	TWORD type;		/* Type of switch expression */
1477 } *swpole;
1478 
1479 /*
1480  * add case to switch
1481  */
1482 static void
addcase(P1ND * p)1483 addcase(P1ND *p)
1484 {
1485 	struct swents **put, *w, *sw = malloc(sizeof(struct swents));
1486 	CONSZ val;
1487 
1488 	p = optloop(p);  /* change enum to ints */
1489 	if (p->n_op != ICON || p->n_sp != NULL) {
1490 		uerror( "non-constant case expression");
1491 		return;
1492 	}
1493 	if (swpole == NULL) {
1494 		uerror("case not in switch");
1495 		return;
1496 	}
1497 
1498 	if (DEUNSIGN(swpole->type) != DEUNSIGN(p->n_type)) {
1499 		val = glval(p);
1500 		p = makety(p, swpole->type, 0, 0, 0);
1501 		if (p->n_op != ICON)
1502 			cerror("could not cast case value to type of switch "
1503 			       "expression");
1504 		if (glval(p) != val)
1505 			werror("case expression truncated");
1506 	}
1507 	sw->sval = glval(p);
1508 	p1tfree(p);
1509 	put = &swpole->ents;
1510 	if (ISUNSIGNED(swpole->type)) {
1511 		for (w = swpole->ents;
1512 		     w != NULL && (U_CONSZ)w->sval < (U_CONSZ)sw->sval;
1513 		     w = w->next)
1514 			put = &w->next;
1515 	} else {
1516 		for (w = swpole->ents; w != NULL && w->sval < sw->sval;
1517 		     w = w->next)
1518 			put = &w->next;
1519 	}
1520 	if (w != NULL && w->sval == sw->sval) {
1521 		uerror("duplicate case in switch");
1522 		return;
1523 	}
1524 	plabel(sw->slab = getlab());
1525 	*put = sw;
1526 	sw->next = w;
1527 	swpole->nents++;
1528 }
1529 
1530 #ifdef GCC_COMPAT
1531 void
gcccase(P1ND * ln,P1ND * hn)1532 gcccase(P1ND *ln, P1ND *hn)
1533 {
1534 	CONSZ i, l, h;
1535 
1536 	l = icons(optim(ln));
1537 	h = icons(optim(hn));
1538 
1539 	if (h < l)
1540 		i = l, l = h, h = i;
1541 
1542 	for (i = l; i <= h; i++)
1543 		addcase(xbcon(i, NULL, hn->n_type));
1544 }
1545 #endif
1546 
1547 /*
1548  * add default case to switch
1549  */
1550 static void
adddef(void)1551 adddef(void)
1552 {
1553 	if (swpole == NULL)
1554 		uerror("default not inside switch");
1555 	else if (swpole->deflbl != 0)
1556 		uerror("duplicate default in switch");
1557 	else
1558 		plabel( swpole->deflbl = getlab());
1559 }
1560 
1561 static void
swstart(int num,TWORD type)1562 swstart(int num, TWORD type)
1563 {
1564 	struct swdef *sw = malloc(sizeof(struct swdef));
1565 
1566 	sw->deflbl = sw->nents = 0;
1567 	sw->ents = NULL;
1568 	sw->next = swpole;
1569 	sw->num = num;
1570 	sw->type = type;
1571 	swpole = sw;
1572 }
1573 
1574 /*
1575  * end a switch block
1576  */
1577 static void
swend(void)1578 swend(void)
1579 {
1580 	struct swents *sw, **swp;
1581 	struct swdef *sp;
1582 	int i;
1583 
1584 	sw = FUNALLO(sizeof(struct swents));
1585 	swp = FUNALLO(sizeof(struct swents *) * (swpole->nents+1));
1586 
1587 	sw->slab = swpole->deflbl;
1588 	swp[0] = sw;
1589 
1590 	for (i = 1; i <= swpole->nents; i++) {
1591 		swp[i] = swpole->ents;
1592 		swpole->ents = swpole->ents->next;
1593 	}
1594 	genswitch(swpole->num, swpole->type, swp, swpole->nents);
1595 
1596 	FUNFREE(sw);
1597 	FUNFREE(swp);
1598 	while (swpole->ents) {
1599 		sw = swpole->ents;
1600 		swpole->ents = sw->next;
1601 		free(sw);
1602 	}
1603 	sp = swpole->next;
1604 	free(swpole);
1605 	swpole = sp;
1606 }
1607 
1608 /*
1609  * num: tempnode the value of the switch expression is in
1610  * type: type of the switch expression
1611  *
1612  * p points to an array of structures, each consisting
1613  * of a constant value and a label.
1614  * The first is >=0 if there is a default label;
1615  * its value is the label number
1616  * The entries p[1] to p[n] are the nontrivial cases
1617  * n is the number of case statements (length of list)
1618  */
1619 static void
genswitch(int num,TWORD type,struct swents ** p,int n)1620 genswitch(int num, TWORD type, struct swents **p, int n)
1621 {
1622 	P1ND *r, *q;
1623 	int i;
1624 
1625 	if (mygenswitch(num, type, p, n))
1626 		return;
1627 
1628 	/* simple switch code */
1629 	for (i = 1; i <= n; ++i) {
1630 		/* already in 1 */
1631 		r = tempnode(num, type, 0, 0);
1632 		q = xbcon(p[i]->sval, NULL, type);
1633 		r = buildtree(NE, r, clocal(q));
1634 		xcbranch(r, p[i]->slab);
1635 	}
1636 	if (p[0]->slab > 0)
1637 		branch(p[0]->slab);
1638 }
1639 
1640 /*
1641  * Declare a variable or prototype.
1642  */
1643 static struct symtab *
init_declarator(P1ND * tn,P1ND * p,int assign,P1ND * a,char * as)1644 init_declarator(P1ND *tn, P1ND *p, int assign, P1ND *a, char *as)
1645 {
1646 	int class = glval(tn);
1647 	struct symtab *sp;
1648 
1649 	p = aryfix(p);
1650 	p = tymerge(tn, p);
1651 	if (a) {
1652 		struct attr *ap = gcc_attr_wrapper(a);
1653 		p->n_ap = attr_add(p->n_ap, ap);
1654 	}
1655 
1656 	p->n_sp = sp = lookup((char *)p->n_sp, 0); /* XXX */
1657 
1658 	if (fun_inline && ISFTN(p->n_type))
1659 		sp->sflags |= SINLINE;
1660 
1661 	if (!ISFTN(p->n_type)) {
1662 		if (assign) {
1663 			defid2(p, class, as);
1664 			sp = p->n_sp;
1665 			sp->sflags |= SASG;
1666 			if (sp->sflags & SDYNARRAY)
1667 				uerror("can't initialize dynamic arrays");
1668 			lcommdel(sp);
1669 		} else
1670 			nidcl2(p, class, as);
1671 	} else {
1672 		extern P1ND *parlink;
1673 		if (assign)
1674 			uerror("cannot initialise function");
1675 		defid2(p, uclass(class), as);
1676 		sp = p->n_sp;
1677 		if (sp->sdf->dfun == 0 && !issyshdr)
1678 			warner(Wstrict_prototypes);
1679 		if (parlink) {
1680 			/* dynamic sized arrays in prototypes */
1681 			p1tfree(parlink); /* Free delayed tree */
1682 			parlink = NULL;
1683 		}
1684 	}
1685 	p1tfree(p);
1686 	if (issyshdr)
1687 		sp->sflags |= SINSYS; /* declared in system header */
1688 	return sp;
1689 }
1690 
1691 /*
1692  * Declare old-stype function arguments.
1693  */
1694 static void
oldargs(P1ND * p)1695 oldargs(P1ND *p)
1696 {
1697 	blevel++;
1698 	p->n_op = TYPE;
1699 	p->n_type = FARG;
1700 	p->n_sp = lookup((char *)p->n_sp, 0);/* XXX */
1701 	defid(p, PARAM);
1702 	blevel--;
1703 }
1704 
1705 /*
1706  * Set NAME nodes to a null name and index of LB nodes to NOOFFSET
1707  * unless clr is one, in that case preserve variable name.
1708  */
1709 static P1ND *
namekill(P1ND * p,int clr)1710 namekill(P1ND *p, int clr)
1711 {
1712 	P1ND *q;
1713 	int o = p->n_op;
1714 
1715 	switch (coptype(o)) {
1716 	case LTYPE:
1717 		if (o == NAME) {
1718 			if (clr)
1719 				p->n_sp = NULL;
1720 			else
1721 				p->n_sp = lookup((char *)p->n_sp, 0);/* XXX */
1722 		}
1723 		break;
1724 
1725 	case UTYPE:
1726 		p->n_left = namekill(p->n_left, clr);
1727 		break;
1728 
1729         case BITYPE:
1730                 p->n_left = namekill(p->n_left, clr);
1731 		if (o == LB) {
1732 			if (clr) {
1733 				p1tfree(p->n_right);
1734 				p->n_right = bcon(NOOFFSET);
1735 			} else
1736 				p->n_right = eve(p->n_right);
1737 		} else if (o == CALL)
1738 			p->n_right = namekill(p->n_right, 1);
1739 		else
1740 			p->n_right = namekill(p->n_right, clr);
1741 		if (o == TYMERGE) {
1742 			q = tymerge(p->n_left, p->n_right);
1743 			q->n_ap = attr_add(q->n_ap, p->n_ap);
1744 			p1tfree(p->n_left);
1745 			p1nfree(p);
1746 			p = q;
1747 		}
1748 		break;
1749 	}
1750 	return p;
1751 }
1752 
1753 /*
1754  * Declare function arguments.
1755  */
1756 static P1ND *
funargs(P1ND * p)1757 funargs(P1ND *p)
1758 {
1759 	extern P1ND *arrstk[10];
1760 
1761 	if (p->n_op == ELLIPSIS)
1762 		return p;
1763 
1764 	p = namekill(p, 0);
1765 	if (ISFTN(p->n_type))
1766 		p->n_type = INCREF(p->n_type);
1767 	if (ISARY(p->n_type)) {
1768 		p->n_type += (PTR-ARY);
1769 		if (p->n_df->ddim == -1)
1770 			p1tfree(arrstk[0]), arrstk[0] = NULL;
1771 		p->n_df++;
1772 	}
1773 	if (p->n_type == VOID && p->n_sp->sname == NULL)
1774 		return p; /* sanitycheck later */
1775 	else if (p->n_sp->sname == NULL)
1776 		uerror("argument missing");
1777 	else
1778 		defid(p, PARAM);
1779 	return p;
1780 }
1781 
1782 static P1ND *
listfw(P1ND * p,P1ND * (* f)(P1ND *))1783 listfw(P1ND *p, P1ND * (*f)(P1ND *))
1784 {
1785         if (p->n_op == CM) {
1786                 p->n_left = listfw(p->n_left, f);
1787                 p->n_right = (*f)(p->n_right);
1788         } else
1789                 p = (*f)(p);
1790 	return p;
1791 }
1792 
1793 
1794 /*
1795  * Declare a function.
1796  */
1797 static void
fundef(P1ND * tp,P1ND * p)1798 fundef(P1ND *tp, P1ND *p)
1799 {
1800 	extern int prolab;
1801 	struct symtab *s;
1802 	P1ND *q, *typ;
1803 	int class = glval(tp), oclass, ctval;
1804 
1805 	/*
1806 	 * We discard all names except for those needed for
1807 	 * parameter declaration. While doing that, also change
1808 	 * non-constant array sizes to unknown.
1809 	 */
1810 	ctval = tvaloff;
1811 	for (q = p; coptype(q->n_op) != LTYPE &&
1812 	    q->n_left->n_op != NAME; q = q->n_left) {
1813 		if (q->n_op == CALL)
1814 			q->n_right = namekill(q->n_right, 1);
1815 	}
1816 	if (q->n_op != CALL && q->n_op != UCALL) {
1817 		uerror("invalid function definition");
1818 		p = bdty(UCALL, p);
1819 	} else if (q->n_op == CALL) {
1820 		blevel = 1;
1821 		argoff = ARGINIT;
1822 		if (oldstyle == 0)
1823 			q->n_right = listfw(q->n_right, funargs);
1824 		ftnarg(q);
1825 		blevel = 0;
1826 	}
1827 
1828 	p = typ = tymerge(tp, p);
1829 #ifdef GCC_COMPAT
1830 	/* gcc seems to discard __builtin_ when declaring functions */
1831 	if (strncmp("__builtin_", (char *)typ->n_sp, 10) == 0)
1832 		typ->n_sp = (struct symtab *)((char *)typ->n_sp + 10);
1833 #endif
1834 	s = typ->n_sp = lookup((char *)typ->n_sp, 0); /* XXX */
1835 
1836 	oclass = s->sclass;
1837 	if (class == STATIC && oclass == EXTERN)
1838 		werror("%s was first declared extern, then static", s->sname);
1839 
1840 	if (fun_inline) {
1841 		/* special syntax for inline functions */
1842 		if (! strcmp(s->sname,"main"))
1843 			uerror("cannot inline main()");
1844 
1845 		s->sflags |= SINLINE;
1846 		inline_start(s, class);
1847 		if (class == EXTERN)
1848 			class = EXTDEF;
1849 	} else if (class == EXTERN)
1850 		class = SNULL; /* same result */
1851 
1852 	cftnsp = s;
1853 	defid(p, class);
1854 	if (s->sdf->dfun == 0 && !issyshdr)
1855 		warner(Wstrict_prototypes);
1856 #ifdef GCC_COMPAT
1857 	if (attr_find(p->n_ap, GCC_ATYP_ALW_INL)) {
1858 		/* Temporary turn on temps to make always_inline work */
1859 		alwinl = 1;
1860 		if (xtemps == 0) alwinl |= 2;
1861 		xtemps = 1;
1862 	}
1863 #endif
1864 	prolab = getlab();
1865 	send_passt(IP_PROLOG, -1, getexname(cftnsp), cftnsp->stype,
1866 	    cftnsp->sclass == EXTDEF, prolab, ctval);
1867 	blevel++;
1868 #ifdef STABS
1869 	if (gflag)
1870 		stabs_func(s);
1871 #endif
1872 	p1tfree(tp);
1873 	p1tfree(p);
1874 
1875 }
1876 
1877 static void
fend(void)1878 fend(void)
1879 {
1880 	if (blevel)
1881 		cerror("function level error");
1882 	ftnend();
1883 	fun_inline = 0;
1884 	if (alwinl & 2) xtemps = 0;
1885 	alwinl = 0;
1886 	cftnsp = NULL;
1887 }
1888 
1889 P1ND *
structref(P1ND * p,int f,char * name)1890 structref(P1ND *p, int f, char *name)
1891 {
1892 	P1ND *r;
1893 
1894 	if (f == DOT)
1895 		p = buildtree(ADDROF, p, NULL);
1896 	r = biop(NAME, NULL, NULL);
1897 	r->n_name = name;
1898 	r = buildtree(STREF, p, r);
1899 	return r;
1900 }
1901 
1902 static void
olddecl(P1ND * p,P1ND * a)1903 olddecl(P1ND *p, P1ND *a)
1904 {
1905 	struct symtab *s;
1906 
1907 	p = namekill(p, 0);
1908 	s = p->n_sp;
1909 	if (s->slevel != 1 || s->stype == UNDEF)
1910 		uerror("parameter '%s' not defined", s->sname);
1911 	else if (s->stype != FARG)
1912 		uerror("parameter '%s' redefined", s->sname);
1913 
1914 	s->stype = p->n_type;
1915 	s->sdf = p->n_df;
1916 	s->sap = p->n_ap;
1917 	if (ISARY(s->stype)) {
1918 		s->stype += (PTR-ARY);
1919 		s->sdf++;
1920 	} else if (s->stype == FLOAT)
1921 		s->stype = DOUBLE;
1922 	if (a)
1923 		attr_add(s->sap, gcc_attr_wrapper(a));
1924 	p1nfree(p);
1925 }
1926 
1927 void
branch(int lbl)1928 branch(int lbl)
1929 {
1930 	int r = reached++;
1931 	ecomp(biop(GOTO, bcon(lbl), NULL));
1932 	reached = r;
1933 }
1934 
1935 /*
1936  * Create a printable string based on an encoded string.
1937  */
1938 static char *
mkpstr(char * str)1939 mkpstr(char *str)
1940 {
1941 	char *os, *s;
1942 	int l = strlen(str) + 3; /* \t + \n + \0 */
1943 
1944 	os = s = stmtalloc(l);
1945 	*s++ = '\t';
1946 	while (*str) {
1947 		if (*str == '\\')
1948 			*s++ = esccon(&str);
1949 		else
1950 			*s++ = *str++;
1951 	}
1952 	*s++ = '\n';
1953 	*s = 0;
1954 
1955 	return os;
1956 }
1957 
1958 /*
1959  * Fake a symtab entry for compound literals.
1960  */
1961 static struct symtab *
clbrace(P1ND * p)1962 clbrace(P1ND *p)
1963 {
1964 	struct symtab *sp;
1965 
1966 	sp = getsymtab(simname("cl"), STEMP);
1967 	sp->stype = p->n_type;
1968 	sp->squal = p->n_qual;
1969 	sp->sdf = p->n_df;
1970 	sp->sap = p->n_ap;
1971 	p1tfree(p);
1972 	if (blevel == 0 && xnf != NULL) {
1973 		sp->sclass = STATIC;
1974 		sp->slevel = 2;
1975 		sp->soffset = getlab();
1976 	} else {
1977 		sp->sclass = blevel ? AUTO : STATIC;
1978 		if (!ISARY(sp->stype) || sp->sdf->ddim != NOOFFSET) {
1979 			sp->soffset = NOOFFSET;
1980 			oalloc(sp, &autooff);
1981 		}
1982 	}
1983 	beginit(sp);
1984 	return sp;
1985 }
1986 
1987 char *
simname(char * s)1988 simname(char *s)
1989 {
1990 	int len = strlen(s) + 10 + 1;
1991 	char *w = tmpalloc(len); /* uncommon */
1992 
1993 	snprintf(w, len, "%s%d", s, getlab());
1994 	return w;
1995 }
1996 
1997 P1ND *
biop(int op,P1ND * l,P1ND * r)1998 biop(int op, P1ND *l, P1ND *r)
1999 {
2000 	return block(op, l, r, INT, 0, 0);
2001 }
2002 
2003 static P1ND *
cmop(P1ND * l,P1ND * r)2004 cmop(P1ND *l, P1ND *r)
2005 {
2006 	return biop(CM, l, r);
2007 }
2008 
2009 static P1ND *
voidcon(void)2010 voidcon(void)
2011 {
2012 	return block(ICON, NULL, NULL, STRTY, 0, 0);
2013 }
2014 
2015 /* Support for extended assembler a' la' gcc style follows below */
2016 
2017 static P1ND *
xmrg(P1ND * out,P1ND * in)2018 xmrg(P1ND *out, P1ND *in)
2019 {
2020 	P1ND *p = in;
2021 
2022 	if (p->n_op == XARG) {
2023 		in = cmop(out, p);
2024 	} else {
2025 		while (p->n_left->n_op == CM)
2026 			p = p->n_left;
2027 		p->n_left = cmop(out, p->n_left);
2028 	}
2029 	return in;
2030 }
2031 
2032 /*
2033  * Put together in and out node lists in one list, and balance it with
2034  * the constraints on the right side of a CM node.
2035  */
2036 static P1ND *
xcmop(P1ND * out,P1ND * in,P1ND * str)2037 xcmop(P1ND *out, P1ND *in, P1ND *str)
2038 {
2039 	P1ND *p, *q;
2040 
2041 	if (out) {
2042 		/* D out-list sanity check */
2043 		for (p = out; p->n_op == CM; p = p->n_left) {
2044 			q = p->n_right;
2045 			if (q->n_name[0] != '=' && q->n_name[0] != '+')
2046 				uerror("output missing =");
2047 		}
2048 		if (p->n_name[0] != '=' && p->n_name[0] != '+')
2049 			uerror("output missing =");
2050 		if (in == NULL)
2051 			p = out;
2052 		else
2053 			p = xmrg(out, in);
2054 	} else if (in) {
2055 		p = in;
2056 	} else
2057 		p = voidcon();
2058 
2059 	if (str == NULL)
2060 		str = voidcon();
2061 	return cmop(p, str);
2062 }
2063 
2064 /*
2065  * Generate a XARG node based on a string and an expression.
2066  */
2067 static P1ND *
xasmop(char * str,P1ND * p)2068 xasmop(char *str, P1ND *p)
2069 {
2070 
2071 	p = biop(XARG, p, NULL);
2072 	p->n_name = str;
2073 	return p;
2074 }
2075 
2076 /*
2077  * Generate a XASM node based on a string and an expression.
2078  */
2079 static void
mkxasm(char * str,P1ND * p)2080 mkxasm(char *str, P1ND *p)
2081 {
2082 	P1ND *q;
2083 
2084 	q = biop(XASM, p->n_left, p->n_right);
2085 	q->n_name = str;
2086 	p1nfree(p);
2087 	ecomp(optloop(q));
2088 }
2089 
2090 static struct attr *
gcc_attr_wrapper(P1ND * p)2091 gcc_attr_wrapper(P1ND *p)
2092 {
2093 #ifdef GCC_COMPAT
2094 	return gcc_attr_parse(p);
2095 #else
2096 	if (p != NULL)
2097 		uerror("gcc attribute used");
2098 	return NULL;
2099 #endif
2100 }
2101 
2102 #ifdef GCC_COMPAT
2103 static P1ND *
tyof(P1ND * p)2104 tyof(P1ND *p)
2105 {
2106 	static struct symtab spp;
2107 	P1ND *q = block(TYPE, NULL, NULL, p->n_type, p->n_df, p->n_ap);
2108 	q->n_qual = p->n_qual;
2109 	q->n_sp = &spp; /* for typenode */
2110 	p1tfree(p);
2111 	return q;
2112 }
2113 
2114 #else
2115 static P1ND *
tyof(P1ND * p)2116 tyof(P1ND *p)
2117 {
2118 	uerror("typeof gcc extension");
2119 	return bcon(0);
2120 }
2121 #endif
2122 
2123 /*
2124  * Traverse an unhandled expression tree bottom-up and call buildtree()
2125  * or equivalent as needed.
2126  */
2127 P1ND *
eve(P1ND * p)2128 eve(P1ND *p)
2129 {
2130 	struct symtab *sp;
2131 	P1ND *r, *p1, *p2;
2132 	int x;
2133 
2134 	p1 = p->n_left;
2135 	p2 = p->n_right;
2136 	switch (p->n_op) {
2137 	case NAME:
2138 		sp = lookup((char *)p->n_sp,
2139 		    attr_find(p->n_ap, ATTR_P1LABELS) ? SLBLNAME|STEMP : 0);
2140 		if (sp->sflags & SINLINE)
2141 			inline_ref(sp);
2142 		r = nametree(sp);
2143 		if (sp->sflags & SDYNARRAY)
2144 			r = buildtree(UMUL, r, NULL);
2145 #ifdef GCC_COMPAT
2146 		if (attr_find(sp->sap, GCC_ATYP_DEPRECATED))
2147 			warner(Wdeprecated_declarations, sp->sname);
2148 #endif
2149 		break;
2150 
2151 	case DOT:
2152 	case STREF:
2153 		r = structref(eve(p1), p->n_op, (char *)p2->n_sp);
2154 		p1nfree(p2);
2155 		break;
2156 
2157 	case CAST:
2158 		p2 = eve(p2);
2159 #ifndef NO_COMPLEX
2160 		if (ANYCX(p1) || ANYCX(p2)) {
2161 			r = cxcast(p1, p2);
2162 			break;
2163 		}
2164 #endif
2165 #ifdef TARGET_TIMODE
2166 		if ((r = gcc_eval_ticast(CAST, p1, p2)) != NULL)
2167 			break;
2168 #endif
2169 		p1 = buildtree(CAST, p1, p2);
2170 		p1nfree(p1->n_left);
2171 		r = p1->n_right;
2172 		p1nfree(p1);
2173 		break;
2174 
2175 
2176 	case SZOF:
2177 		x = xinline; xinline = 0; /* XXX hack */
2178 		if (glval(p2) == 0)
2179 			p1 = eve(p1);
2180 		else
2181 			TYMFIX(p1);
2182 		p1nfree(p2);
2183 		r = doszof(p1);
2184 		xinline = x;
2185 		break;
2186 
2187 	case LB:
2188 		p1 = eve(p1);
2189 		p2 = eve(p2);
2190 #ifdef TARGET_TIMODE
2191 		if (isti(p2)) {
2192 			P1ND *s = block(NAME, NULL, NULL, LONG, 0, 0);
2193 			if ((r = gcc_eval_ticast(CAST, s, p2)) != NULL)
2194 				p2 = r;
2195 			p1nfree(s);
2196 		}
2197 #endif
2198 		r = buildtree(UMUL, buildtree(PLUS, p1, p2), NULL);
2199 		break;
2200 
2201 	case COMPL:
2202 #ifndef NO_COMPLEX
2203 		p1 = eve(p1);
2204 		if (ANYCX(p1))
2205 			r = cxconj(p1);
2206 		else
2207 			r = buildtree(COMPL, p1, NULL);
2208 		break;
2209 #endif
2210 	case UPLUS:
2211 		r = eve(p1);
2212 		if (r->n_op == FLD || r->n_type < INT)
2213 			r = buildtree(PLUS, r, bcon(0)); /* must be size int */
2214 		break;
2215 
2216 	case UMINUS:
2217 #ifndef NO_COMPLEX
2218 		p1 = eve(p1);
2219 		if (ANYCX(p1))
2220 			r = cxop(UMINUS, p1, p1);
2221 		else
2222 			r = buildtree(UMINUS, p1, NULL);
2223 		break;
2224 #endif
2225 	case NOT:
2226 	case UMUL:
2227 		p1 = eve(p1);
2228 #ifdef TARGET_TIMODE
2229 		if ((r = gcc_eval_tiuni(p->n_op, p1)) != NULL)
2230 			break;
2231 #endif
2232 #ifndef NO_COMPLEX
2233 		if (p->n_op == NOT && ANYCX(p1))
2234 			p1 = cxop(NE, p1, bcon(0));
2235 #endif
2236 		r = buildtree(p->n_op, p1, NULL);
2237 		break;
2238 
2239 	case ADDROF:
2240 		r = eve(p1);
2241 		if (ISFTN(p->n_type)/* || ISARY(p->n_type) */){
2242 #ifdef notdef
2243 			werror( "& before array or function: ignored" );
2244 #endif
2245 		} else
2246 			r = buildtree(ADDROF, r, NULL);
2247 		break;
2248 
2249 	case UCALL:
2250 		p2 = NULL;
2251 		/* FALLTHROUGH */
2252 	case CALL:
2253 		if (p1->n_op == NAME) {
2254 			sp = lookup((char *)p1->n_sp, 0);
2255 #ifndef NO_C_BUILTINS
2256 			if (sp->sflags & SBUILTIN) {
2257 				p1nfree(p1);
2258 				r = builtin_check(sp, p2);
2259 				break;
2260 			}
2261 #endif
2262 			if (sp->stype == UNDEF) {
2263 				p1->n_type = FTN|INT;
2264 				p1->n_sp = sp;
2265 				p1->n_ap = NULL;
2266 				defid(p1, EXTERN);
2267 			}
2268 			p1nfree(p1);
2269 #ifdef GCC_COMPAT
2270 			if (attr_find(sp->sap, GCC_ATYP_DEPRECATED))
2271 				warner(Wdeprecated_declarations, sp->sname);
2272 #endif
2273 			if (p->n_op == CALL)
2274 				p2 = eve(p2);
2275 			r = doacall(sp, nametree(sp), p2);
2276 		} else {
2277 			if (p->n_op == CALL)
2278 				p2 = eve(p2);
2279 			r = doacall(NULL, eve(p1), p2);
2280 		}
2281 		break;
2282 
2283 #ifndef NO_COMPLEX
2284 	case XREAL:
2285 	case XIMAG:
2286 		p1 = eve(p1);
2287 		r = cxelem(p->n_op, p1);
2288 		break;
2289 #endif
2290 
2291 	case COLON:
2292 	case MUL:
2293 	case DIV:
2294 	case PLUS:
2295 	case MINUS:
2296 	case ASSIGN:
2297 	case EQ:
2298 	case NE:
2299 	case OROR:
2300 	case ANDAND:
2301 #ifndef NO_COMPLEX
2302 		p1 = eve(p1);
2303 		p2 = eve(p2);
2304 #ifdef TARGET_TIMODE
2305 		if ((r = gcc_eval_timode(p->n_op, p1, p2)) != NULL)
2306 			break;
2307 #endif
2308 		if (ANYCX(p1) || ANYCX(p2)) {
2309 			r = cxop(p->n_op, p1, p2);
2310 		} else if (ISITY(p1->n_type) || ISITY(p2->n_type)) {
2311 			r = imop(p->n_op, p1, p2);
2312 		} else
2313 			r = buildtree(p->n_op, p1, p2);
2314 		break;
2315 #endif
2316 	case MOD:
2317 	case CM:
2318 	case GT:
2319 	case GE:
2320 	case LT:
2321 	case LE:
2322 	case RS:
2323 	case LS:
2324 	case RSEQ:
2325 	case LSEQ:
2326 	case AND:
2327 	case OR:
2328 	case ER:
2329 	case EREQ:
2330 	case OREQ:
2331 	case ANDEQ:
2332 	case QUEST:
2333 		p1 = eve(p1);
2334 		p2 = eve(p2);
2335 #ifdef TARGET_TIMODE
2336 		if ((r = gcc_eval_timode(p->n_op, p1, p2)) != NULL)
2337 			break;
2338 #endif
2339 		r = buildtree(p->n_op, p1, p2);
2340 		break;
2341 
2342 	case BIQUEST: /* gcc e ?: e op */
2343 		p1 = eve(p1);
2344 		r = tempnode(0, p1->n_type, p1->n_df, p1->n_ap);
2345 		p2 = eve(biop(COLON, p1tcopy(r), p2));
2346 		r = buildtree(QUEST, buildtree(ASSIGN, r, p1), p2);
2347 		break;
2348 
2349 	case INCR:
2350 	case DECR:
2351 	case MODEQ:
2352 	case MINUSEQ:
2353 	case PLUSEQ:
2354 	case MULEQ:
2355 	case DIVEQ:
2356 		p1 = eve(p1);
2357 		p2 = eve(p2);
2358 #ifdef TARGET_TIMODE
2359 		if ((r = gcc_eval_timode(p->n_op, p1, p2)) != NULL)
2360 			break;
2361 #endif
2362 #ifndef NO_COMPLEX
2363 		if (ANYCX(p1) || ANYCX(p2)) {
2364 			r = cxop(UNASG p->n_op, p1tcopy(p1), p2);
2365 			r = cxop(ASSIGN, p1, r);
2366 			break;
2367 		} else if (ISITY(p1->n_type) || ISITY(p2->n_type)) {
2368 			r = imop(UNASG p->n_op, p1tcopy(p1), p2);
2369 			r = cxop(ASSIGN, p1, r);
2370 			break;
2371 		}
2372 		/* FALLTHROUGH */
2373 #endif
2374 		r = buildtree(p->n_op, p1, p2);
2375 		break;
2376 
2377 	case STRING:
2378 		r = strend(p->n_name, (TWORD)glval(p));
2379 		break;
2380 
2381 	case COMOP:
2382 		if (p1->n_op == GOTO) {
2383 			/* inside ({ }), eve already called */
2384 			r = buildtree(p->n_op, p1, p2);
2385 		} else {
2386 			p1 = eve(p1);
2387 			r = buildtree(p->n_op, p1, eve(p2));
2388 		}
2389 		break;
2390 
2391 	case TYPE:
2392 	case ICON:
2393 	case FCON:
2394 	case TEMP:
2395 		return p;
2396 
2397 	case CLOP:
2398 		r = nametree(p->n_sp);
2399 		break;
2400 
2401 	default:
2402 #ifdef PCC_DEBUG
2403 		p1fwalk(p, eprint, 0);
2404 #endif
2405 		cerror("eve");
2406 		r = NULL;
2407 	}
2408 	p1nfree(p);
2409 	return r;
2410 }
2411 
2412 int
con_e(P1ND * p)2413 con_e(P1ND *p)
2414 {
2415 	return icons(optloop(eve(p)));
2416 }
2417 
2418 void
uawarn(P1ND * p,char * s)2419 uawarn(P1ND *p, char *s)
2420 {
2421 	if (p == 0)
2422 		return;
2423 	if (attrwarn)
2424 		werror("unhandled %s attribute", s);
2425 	p1tfree(p);
2426 }
2427 
2428 static void
dainit(P1ND * d,P1ND * a)2429 dainit(P1ND *d, P1ND *a)
2430 {
2431 	if (d == NULL) {
2432 		asginit(a);
2433 	} else if (d->n_op == CM) {
2434 		int is = con_e(d->n_left);
2435 		int ie = con_e(d->n_right);
2436 		int i;
2437 
2438 		p1nfree(d);
2439 		if (ie < is)
2440 			uerror("negative initializer range");
2441 		desinit(biop(LB, NULL, bcon(is)));
2442 		for (i = is; i < ie; i++)
2443 			asginit(p1tcopy(a));
2444 		asginit(a);
2445 	} else {
2446 		cerror("dainit");
2447 	}
2448 }
2449 
2450 /*
2451  * Traverse down and tymerge() where appropriate.
2452  */
2453 static P1ND *
tymfix(P1ND * p)2454 tymfix(P1ND *p)
2455 {
2456 	P1ND *q;
2457 	int o = coptype(p->n_op);
2458 
2459 	switch (o) {
2460 	case LTYPE:
2461 		break;
2462 	case UTYPE:
2463 		p->n_left = tymfix(p->n_left);
2464 		break;
2465 	case BITYPE:
2466 		p->n_left = tymfix(p->n_left);
2467 		p->n_right = tymfix(p->n_right);
2468 		if (p->n_op == TYMERGE) {
2469 			q = tymerge(p->n_left, p->n_right);
2470 			q->n_ap = attr_add(q->n_ap, p->n_ap);
2471 			p1tfree(p->n_left);
2472 			p1nfree(p);
2473 			p = q;
2474 		}
2475 		break;
2476 	}
2477 	return p;
2478 }
2479 
2480 static P1ND *
aryfix(P1ND * p)2481 aryfix(P1ND *p)
2482 {
2483 	P1ND *q;
2484 
2485 	for (q = p; q->n_op != NAME; q = q->n_left) {
2486 		if (q->n_op == LB) {
2487 			q->n_right = optloop(eve(q->n_right));
2488 			if ((blevel == 0 || rpole != NULL) &&
2489 			    !nncon(q->n_right))
2490 				uerror("array size not constant");
2491 			/*
2492 			 * Checks according to 6.7.5.2 clause 1:
2493 			 * "...the expression shall have an integer type."
2494 			 * "If the expression is a constant expression,
2495 			 * it shall have a value greater than zero."
2496 			 */
2497 			if (!ISINTEGER(q->n_right->n_type))
2498 				werror("array size is not an integer");
2499 			else if (q->n_right->n_op == ICON &&
2500 			    glval(q->n_right) < 0 &&
2501 			    glval(q->n_right) != NOOFFSET) {
2502 					uerror("array size cannot be negative");
2503 					slval(q->n_right, 1);
2504 			}
2505 		} else if (q->n_op == CALL)
2506 			q->n_right = namekill(q->n_right, 1);
2507 	}
2508 	return p;
2509 }
2510 
2511 struct labs {
2512 	struct labs *next;
2513 	int lab;
2514 } *labp;
2515 
2516 static void
savlab(int lab)2517 savlab(int lab)
2518 {
2519 	struct labs *l = tmpalloc(sizeof(struct labs)); /* uncommon */
2520 	l->lab = lab < 0 ? -lab : lab;
2521 	l->next = labp;
2522 	labp = l;
2523 }
2524 
2525 int *
mkclabs(void)2526 mkclabs(void)
2527 {
2528 	struct labs *l;
2529 	int i, *rv;
2530 
2531 	for (i = 0, l = labp; l; l = l->next, i++)
2532 		;
2533 	rv = tmpalloc((i+1)*sizeof(int));	/* uncommon */
2534 	for (i = 0, l = labp; l; l = l->next, i++)
2535 		rv[i] = l->lab;
2536 	rv[i] = 0;
2537 	labp = 0;
2538 	return rv;
2539 }
2540 
2541 void
xcbranch(P1ND * p,int lab)2542 xcbranch(P1ND *p, int lab)
2543 {
2544 #ifndef NO_COMPLEX
2545 	if (ANYCX(p))
2546 		p = cxop(NE, p, bcon(0));
2547 #endif
2548 	cbranch(buildtree(NOT, p, NULL), bcon(lab));
2549 }
2550 
2551 /*
2552  * New a case entry to genlist.
2553  * tn is type, e is expression.
2554  */
2555 static struct genlist *
newgen(P1ND * tn,P1ND * e)2556 newgen(P1ND *tn, P1ND *e)
2557 {
2558 	struct genlist *ng;
2559 	TWORD t;
2560 
2561 	if (tn) {
2562 		t = tn->n_type;
2563 		p1tfree(tn);
2564 	} else
2565 		t = 0;
2566 
2567 	/* add new entry */
2568 	ng = malloc(sizeof(struct genlist));
2569 	ng->next = NULL;
2570 	ng->t = t;
2571 	ng->p = e;
2572 	return ng;
2573 }
2574 
2575 /*
2576  * Add a case entry to genlist.
2577  * g is list, ng is new entry.
2578  */
2579 static struct genlist *
addgen(struct genlist * g,struct genlist * ng)2580 addgen(struct genlist *g, struct genlist *ng)
2581 {
2582 	struct genlist *w;
2583 
2584 	/* search for duplicate type */
2585 	for (w = g; w; w = w->next) {
2586 		if (w->t == ng->t)
2587 			uerror("duplicate type in _Generic");
2588 	}
2589 	ng->next = g;
2590 	return ng;
2591 }
2592 
2593 static P1ND *
dogen(struct genlist * g,P1ND * e)2594 dogen(struct genlist *g, P1ND *e)
2595 {
2596 	struct genlist *ng;
2597 	P1ND *w, *p;
2598 
2599 	e = eve(e);
2600 
2601 	/* search for direct match */
2602 	for (ng = g, w = p = NULL; ng; ng = ng->next) {
2603 		if (ng->t == 0)
2604 			p = ng->p; /* save default */
2605 		if (e->n_type == ng->t)
2606 			w = ng->p;
2607 	}
2608 
2609 	/* if no match, use generic */
2610 	if (w == NULL) {
2611 		if (p == NULL) {
2612 			uerror("_Generic: no default found");
2613 			p = bcon(0);
2614 		}
2615 		w = p;
2616 	}
2617 
2618 	/* free tree */
2619 	while (g) {
2620 		if (g->p != w)
2621 			p1tfree(g->p);
2622 		ng = g->next;
2623 		free(g);
2624 		g = ng;
2625 	}
2626 
2627 	p1tfree(e);
2628 	return w;
2629 }
2630