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