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