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