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