* add p cc
[mascara-docs.git] / compilers / pcc / pcc-1.0.0 / cc / ccom / cgram.y
blobef489d366e720d1184fd7a7269d63fd1f8caf684
1 /* $Id: cgram.y,v 1.319 2011/01/27 18:00:32 ragge Exp $ */
3 /*
4 * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
5 * All rights reserved.
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 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
33 * Redistribution and use in source and binary forms, with or without
34 * modification, are permitted provided that the following conditions
35 * are met:
37 * Redistributions of source code and documentation must retain the above
38 * copyright notice, this list of conditions and the following disclaimer.
39 * Redistributions in binary form must reproduce the above copyright
40 * notice, this list of conditions and the following disclaimer in the
41 * documentation and/or other materials provided with the distribution.
42 * All advertising materials mentioning features or use of this software
43 * must display the following acknowledgement:
44 * This product includes software developed or owned by Caldera
45 * International, Inc.
46 * Neither the name of Caldera International, Inc. nor the names of other
47 * contributors may be used to endorse or promote products derived from
48 * this software without specific prior written permission.
50 * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
51 * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
52 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
53 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
54 * DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
55 * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
56 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
57 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
58 * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
59 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
60 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
61 * POSSIBILITY OF SUCH DAMAGE.
65 * Comments for this grammar file. Ragge 021123
67 * ANSI support required rewrite of the function header and declaration
68 * rules almost totally.
70 * The lex/yacc shared keywords are now split from the keywords used
71 * in the rest of the compiler, to simplify use of other frontends.
75 * At last count, there were 5 shift/reduce and no reduce/reduce conflicts
76 * Four are accounted for;
77 * One is "dangling else"
78 * Two is in attribute parsing
79 * One is in ({ }) parsing
83 * Token used in C lex/yacc communications.
85 %token C_STRING /* a string constant */
86 %token C_ICON /* an integer constant */
87 %token C_FCON /* a floating point constant */
88 %token C_NAME /* an identifier */
89 %token C_TYPENAME /* a typedef'd name */
90 %token C_ANDAND /* && */
91 %token C_OROR /* || */
92 %token C_GOTO /* unconditional goto */
93 %token C_RETURN /* return from function */
94 %token C_TYPE /* a type */
95 %token C_CLASS /* a storage class */
96 %token C_ASOP /* assignment ops */
97 %token C_RELOP /* <=, <, >=, > */
98 %token C_EQUOP /* ==, != */
99 %token C_DIVOP /* /, % */
100 %token C_SHIFTOP /* <<, >> */
101 %token C_INCOP /* ++, -- */
102 %token C_UNOP /* !, ~ */
103 %token C_STROP /* ., -> */
104 %token C_STRUCT
105 %token C_IF
106 %token C_ELSE
107 %token C_SWITCH
108 %token C_BREAK
109 %token C_CONTINUE
110 %token C_WHILE
111 %token C_DO
112 %token C_FOR
113 %token C_DEFAULT
114 %token C_CASE
115 %token C_SIZEOF
116 %token C_ALIGNOF
117 %token C_ENUM
118 %token C_ELLIPSIS
119 %token C_QUALIFIER
120 %token C_FUNSPEC
121 %token C_ASM
122 %token NOMATCH
123 %token C_TYPEOF /* COMPAT_GCC */
124 %token C_ATTRIBUTE /* COMPAT_GCC */
125 %token PCC_OFFSETOF
128 * Precedence
130 %left ','
131 %right '=' C_ASOP
132 %right '?' ':'
133 %left C_OROR
134 %left C_ANDAND
135 %left '|'
136 %left '^'
137 %left '&'
138 %left C_EQUOP
139 %left C_RELOP
140 %left C_SHIFTOP
141 %left '+' '-'
142 %left '*' C_DIVOP
143 %right C_UNOP
144 %right C_INCOP C_SIZEOF
145 %left '[' '(' C_STROP
147 # include "pass1.h"
148 # include <stdarg.h>
149 # include <string.h>
150 # include <stdlib.h>
152 int fun_inline; /* Reading an inline function */
153 int oldstyle; /* Current function being defined */
154 static struct symtab *xnf;
155 extern int enummer, tvaloff, inattr;
156 extern struct rstack *rpole;
157 static int widestr, alwinl;
158 NODE *cftnod;
159 static int attrwarn = 1;
161 #define NORETYP SNOCREAT /* no return type, save in unused field in symtab */
163 NODE *bdty(int op, ...);
164 static void fend(void);
165 static void fundef(NODE *tp, NODE *p);
166 static void olddecl(NODE *p, NODE *a);
167 static struct symtab *init_declarator(NODE *tn, NODE *p, int assign, NODE *a);
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 void adddef(void);
175 static void savebc(void);
176 static void swstart(int, TWORD);
177 static void genswitch(int, TWORD, struct swents **, int);
178 static char *mkpstr(char *str);
179 static struct symtab *clbrace(NODE *);
180 static NODE *cmop(NODE *l, NODE *r);
181 static NODE *xcmop(NODE *out, NODE *in, NODE *str);
182 static void mkxasm(char *str, NODE *p);
183 static NODE *xasmop(char *str, NODE *p);
184 static int maxstlen(char *str);
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 #ifdef GCC_COMPAT
190 static NODE *tyof(NODE *); /* COMPAT_GCC */
191 static NODE *voidcon(void); /* COMPAT_GCC */
192 #endif
193 static NODE *funargs(NODE *p);
194 static void oldargs(NODE *p);
195 static void uawarn(NODE *p, char *s);
196 static int con_e(NODE *p);
197 static void dainit(NODE *d, NODE *a);
198 static NODE *tymfix(NODE *p);
199 static NODE *namekill(NODE *p, int clr);
200 static NODE *aryfix(NODE *p);
202 #define TYMFIX(inp) { \
203 NODE *pp = inp; \
204 inp = tymerge(pp->n_left, pp->n_right); \
205 nfree(pp->n_left); nfree(pp); }
207 * State for saving current switch state (when nested switches).
209 struct savbc {
210 struct savbc *next;
211 int brklab;
212 int contlab;
213 int flostat;
214 int swx;
215 } *savbc, *savctx;
219 %union {
220 int intval;
221 NODE *nodep;
222 struct symtab *symp;
223 struct rstack *rp;
224 char *strp;
227 /* define types */
228 %start ext_def_list
230 %type <intval> ifelprefix ifprefix whprefix forprefix doprefix switchpart
231 xbegin
232 %type <nodep> e .e term enum_dcl struct_dcl cast_type declarator
233 elist type_sq cf_spec merge_attribs
234 parameter_declaration abstract_declarator initializer
235 parameter_type_list parameter_list addrlbl
236 declaration_specifiers designation
237 specifier_qualifier_list merge_specifiers
238 identifier_list arg_param_list type_qualifier_list
239 designator_list designator xasm oplist oper cnstr funtype
240 typeof attribute attribute_specifier /* COMPAT_GCC */
241 attribute_list attr_spec_list attr_var /* COMPAT_GCC */
242 %type <strp> string C_STRING
243 %type <rp> str_head
244 %type <symp> xnfdeclarator clbrace enum_head
246 %type <intval> C_STRUCT C_RELOP C_DIVOP C_SHIFTOP
247 C_ANDAND C_OROR C_STROP C_INCOP C_UNOP C_ASOP C_EQUOP
249 %type <nodep> C_TYPE C_QUALIFIER C_ICON C_FCON C_CLASS
250 %type <strp> C_NAME C_TYPENAME
253 ext_def_list: ext_def_list external_def
254 | { ftnend(); }
257 external_def: funtype kr_args compoundstmt { fend(); }
258 | declaration { blevel = 0; symclear(0); }
259 | asmstatement ';'
260 | ';'
261 | error { blevel = 0; }
264 funtype: /* no type given */ declarator {
265 fundef(mkty(INT, 0, MKAP(INT)), $1);
266 cftnsp->sflags |= NORETYP;
268 | declaration_specifiers declarator { fundef($1,$2); }
271 kr_args: /* empty */
272 | arg_dcl_list
276 * Returns a node pointer or NULL, if no types at all given.
277 * Type trees are checked for correctness and merged into one
278 * type node in typenode().
280 declaration_specifiers:
281 merge_attribs { $$ = typenode($1); }
284 merge_attribs: type_sq { $$ = $1; }
285 | type_sq merge_attribs { $$ = cmop($2, $1); }
286 | cf_spec { $$ = $1; }
287 | cf_spec merge_attribs { $$ = cmop($2, $1); }
290 type_sq: C_TYPE { $$ = $1; }
291 | C_TYPENAME {
292 struct symtab *sp = lookup($1, 0);
293 if (sp->stype == ENUMTY) {
294 sp->stype = strmemb(sp->sap)->stype;
296 $$ = mkty(sp->stype, sp->sdf, sp->sap);
297 $$->n_sp = sp;
299 | struct_dcl { $$ = $1; }
300 | enum_dcl { $$ = $1; }
301 | C_QUALIFIER { $$ = $1; }
302 | attribute_specifier { $$ = biop(ATTRIB, $1, 0); }
303 | typeof { $$ = $1; }
306 cf_spec: C_CLASS { $$ = $1; }
307 | C_FUNSPEC { fun_inline = 1; /* XXX - hack */
308 $$ = block(QUALIFIER, NIL, NIL, 0, 0, 0); }
311 typeof: C_TYPEOF '(' term ')' { $$ = tyof(eve($3)); }
312 | C_TYPEOF '(' cast_type ')' { TYMFIX($3); $$ = tyof($3); }
315 attribute_specifier :
316 C_ATTRIBUTE '(' '(' attribute_list ')' ')' { $$ = $4; }
317 /*COMPAT_GCC*/ ;
319 attribute_list: attribute
320 | attribute ',' attribute_list { $$ = cmop($3, $1); }
323 attribute: {
324 #ifdef GCC_COMPAT
325 $$ = voidcon();
326 #endif
328 | C_NAME { $$ = bdty(NAME, $1); }
329 | C_NAME '(' elist ')' {
330 $$ = bdty($3 == NIL ? UCALL : CALL, bdty(NAME, $1), $3);
335 * Adds a pointer list to front of the declarators.
337 declarator: '*' declarator { $$ = bdty(UMUL, $2); }
338 | '*' type_qualifier_list declarator {
339 $$ = $2;
340 $$->n_left = $3;
342 | C_NAME { $$ = bdty(NAME, $1); }
343 | '(' attr_spec_list declarator ')' {
344 $$ = $3;
345 $$->n_ap = attr_add($$->n_ap, gcc_attr_parse($2));
347 | '(' declarator ')' { $$ = $2; }
348 | declarator '[' e ']' { $$ = biop(LB, $1, $3); }
349 | declarator '[' C_CLASS e ']' {
350 if ($3->n_type != STATIC)
351 uerror("bad class keyword");
352 tfree($3); /* XXX - handle */
353 $$ = biop(LB, $1, $4);
355 | declarator '[' ']' { $$ = biop(LB, $1, bcon(NOOFFSET)); }
356 | declarator '[' '*' ']' { $$ = biop(LB, $1, bcon(NOOFFSET)); }
357 | declarator '(' parameter_type_list ')' {
358 $$ = bdty(CALL, $1, $3);
360 | declarator '(' identifier_list ')' {
361 $$ = bdty(CALL, $1, $3);
362 oldstyle = 1;
364 | declarator '(' ')' { $$ = bdty(UCALL, $1); }
367 type_qualifier_list:
368 C_QUALIFIER { $$ = $1; $$->n_op = UMUL; }
369 | type_qualifier_list C_QUALIFIER {
370 $$ = $1;
371 $$->n_qual |= $2->n_qual;
372 nfree($2);
374 | attribute_specifier {
375 $$ = block(UMUL, NIL, NIL, 0, 0, gcc_attr_parse($1));
377 | type_qualifier_list attribute_specifier {
378 $1->n_ap = attr_add($1->n_ap, gcc_attr_parse($2));
382 identifier_list: C_NAME { $$ = bdty(NAME, $1); oldargs($$); }
383 | identifier_list ',' C_NAME {
384 $$ = cmop($1, bdty(NAME, $3));
385 oldargs($$->n_right);
390 * Returns as parameter_list, but can add an additional ELLIPSIS node.
392 parameter_type_list:
393 parameter_list { $$ = $1; }
394 | parameter_list ',' C_ELLIPSIS {
395 $$ = cmop($1, biop(ELLIPSIS, NIL, NIL));
400 * Returns a linked lists of nodes of op CM with parameters on
401 * its right and additional CM nodes of its left pointer.
402 * No CM nodes if only one parameter.
404 parameter_list: parameter_declaration { $$ = $1; }
405 | parameter_list ',' parameter_declaration {
406 $$ = cmop($1, $3);
411 * Returns a node pointer to the declaration.
413 parameter_declaration:
414 declaration_specifiers declarator attr_var {
415 if ($1->n_lval != SNULL && $1->n_lval != REGISTER)
416 uerror("illegal parameter class");
417 $$ = block(TYMERGE, $1, $2, INT, 0, gcc_attr_parse($3));
419 | declaration_specifiers abstract_declarator {
420 $$ = block(TYMERGE, $1, $2, INT, 0, 0);
422 | declaration_specifiers {
423 $$ = block(TYMERGE, $1, bdty(NAME, NULL), INT, 0, 0);
427 abstract_declarator:
428 '*' { $$ = bdty(UMUL, bdty(NAME, NULL)); }
429 | '*' type_qualifier_list {
430 $$ = $2;
431 $$->n_left = bdty(NAME, NULL);
433 | '*' abstract_declarator { $$ = bdty(UMUL, $2); }
434 | '*' type_qualifier_list abstract_declarator {
435 $$ = $2;
436 $$->n_left = $3;
438 | '(' abstract_declarator ')' { $$ = $2; }
439 | '[' ']' attr_var {
440 $$ = block(LB, bdty(NAME, NULL), bcon(NOOFFSET),
441 INT, 0, gcc_attr_parse($3));
443 | '[' e ']' attr_var {
444 $$ = block(LB, bdty(NAME, NULL), $2,
445 INT, 0, gcc_attr_parse($4));
447 | abstract_declarator '[' ']' attr_var {
448 $$ = block(LB, $1, bcon(NOOFFSET),
449 INT, 0, gcc_attr_parse($4));
451 | abstract_declarator '[' e ']' attr_var {
452 $$ = block(LB, $1, $3, INT, 0, gcc_attr_parse($5));
454 | '(' ')' { $$ = bdty(UCALL, bdty(NAME, NULL)); }
455 | '(' ib2 parameter_type_list ')' {
456 $$ = bdty(CALL, bdty(NAME, NULL), $3);
458 | abstract_declarator '(' ')' {
459 $$ = bdty(UCALL, $1);
461 | abstract_declarator '(' ib2 parameter_type_list ')' {
462 $$ = bdty(CALL, $1, $4);
466 ib2: { }
469 * K&R arg declaration, between ) and {
471 arg_dcl_list: arg_declaration
472 | arg_dcl_list arg_declaration
476 arg_declaration: declaration_specifiers arg_param_list ';' {
477 nfree($1);
481 arg_param_list: declarator attr_var {
482 olddecl(block(TYMERGE, ccopy($<nodep>0), $1,
483 INT, 0, 0), $2);
485 | arg_param_list ',' declarator attr_var {
486 olddecl(block(TYMERGE, ccopy($<nodep>0), $3,
487 INT, 0, 0), $4);
492 * Declarations in beginning of blocks.
494 block_item_list: block_item
495 | block_item_list block_item
498 block_item: declaration
499 | statement
503 * Here starts the old YACC code.
507 * Variables are declared in init_declarator.
509 declaration: declaration_specifiers ';' { tfree($1); fun_inline = 0; }
510 | declaration_specifiers init_declarator_list ';' {
511 tfree($1);
512 fun_inline = 0;
517 * Normal declaration of variables. curtype contains the current type node.
518 * Returns nothing, variables are declared in init_declarator.
520 init_declarator_list:
521 init_declarator { symclear(blevel); }
522 | init_declarator_list ',' attr_var { $<nodep>$ = $<nodep>0; } init_declarator {
523 uawarn($3, "init_declarator");
524 symclear(blevel);
528 enum_dcl: enum_head '{' moe_list optcomma '}' { $$ = enumdcl($1); }
529 | C_ENUM C_NAME { $$ = enumref($2); }
532 enum_head: C_ENUM { $$ = enumhd(NULL); }
533 | C_ENUM C_NAME { $$ = enumhd($2); }
536 moe_list: moe
537 | moe_list ',' moe
540 moe: C_NAME { moedef($1); }
541 | C_TYPENAME { moedef($1); }
542 | C_NAME '=' e { enummer = con_e($3); moedef($1); }
543 | C_TYPENAME '=' e { enummer = con_e($3); moedef($1); }
546 struct_dcl: str_head '{' struct_dcl_list '}' {
547 NODE *p;
549 $$ = dclstruct($1);
550 if (pragma_allpacked) {
551 p = bdty(CALL, bdty(NAME, "packed"),
552 bcon(pragma_allpacked));
553 $$ = cmop(biop(ATTRIB, p, 0), $$);
556 | C_STRUCT attr_var C_NAME {
557 $$ = rstruct($3,$1);
558 uawarn($2, "struct_dcl");
560 /*COMPAT_GCC*/ | str_head '{' '}' { $$ = dclstruct($1); }
563 attr_var: {
564 NODE *q, *p;
566 p = pragma_aligned ? bdty(CALL, bdty(NAME, "aligned"),
567 bcon(pragma_aligned)) : NIL;
568 if (pragma_packed) {
569 q = bdty(NAME, "packed");
570 p = (p == NIL ? q : cmop(p, q));
572 pragma_aligned = pragma_packed = 0;
573 $$ = p;
575 /*COMPAT_GCC*/ | attr_spec_list
578 attr_spec_list: attribute_specifier
579 | attr_spec_list attribute_specifier { $$ = cmop($1, $2); }
582 str_head: C_STRUCT attr_var { $$ = bstruct(NULL, $1, $2); }
583 | C_STRUCT attr_var C_NAME { $$ = bstruct($3, $1, $2); }
586 struct_dcl_list: struct_declaration
587 | struct_dcl_list struct_declaration
590 struct_declaration:
591 specifier_qualifier_list struct_declarator_list optsemi {
592 tfree($1);
596 optsemi: ';' { }
597 | optsemi ';' { werror("extra ; in struct"); }
600 specifier_qualifier_list:
601 merge_specifiers { $$ = typenode($1); }
604 merge_specifiers: type_sq merge_specifiers { $$ = cmop($2, $1); }
605 | type_sq { $$ = $1; }
608 struct_declarator_list:
609 struct_declarator { symclear(blevel); }
610 | struct_declarator_list ',' { $<nodep>$=$<nodep>0; }
611 struct_declarator { symclear(blevel); }
614 struct_declarator: declarator attr_var {
615 NODE *p;
617 $1 = aryfix($1);
618 p = tymerge($<nodep>0, tymfix($1));
619 if ($2)
620 p->n_ap = attr_add(p->n_ap, gcc_attr_parse($2));
621 soumemb(p, (char *)$1->n_sp, 0);
622 tfree(p);
624 | ':' e {
625 int ie = con_e($2);
626 if (fldchk(ie))
627 ie = 1;
628 falloc(NULL, ie, $<nodep>0);
630 | declarator ':' e {
631 int ie = con_e($3);
632 if (fldchk(ie))
633 ie = 1;
634 if ($1->n_op == NAME) {
635 /* XXX - tymfix() may alter $1 */
636 tymerge($<nodep>0, tymfix($1));
637 soumemb($1, (char *)$1->n_sp, FIELD | ie);
638 nfree($1);
639 } else
640 uerror("illegal declarator");
642 | declarator ':' e attr_spec_list {
643 int ie = con_e($3);
644 if (fldchk(ie))
645 ie = 1;
646 if ($1->n_op == NAME) {
647 /* XXX - tymfix() may alter $1 */
648 tymerge($<nodep>0, tymfix($1));
649 if ($4)
650 $1->n_ap = attr_add($1->n_ap,
651 gcc_attr_parse($4));
652 soumemb($1, (char *)$1->n_sp, FIELD | ie);
653 nfree($1);
654 } else
655 uerror("illegal declarator");
657 | /* unnamed member */ {
658 NODE *p = $<nodep>0;
659 char *c = permalloc(10);
661 if (p->n_type != STRTY && p->n_type != UNIONTY)
662 uerror("bad unnamed member type");
663 snprintf(c, 10, "*%dFAKE", getlab());
664 soumemb(p, c, 0);
668 /* always preceeded by attributes */
669 xnfdeclarator: declarator attr_var {
670 $$ = xnf = init_declarator($<nodep>0, $1, 1, $2);
672 | declarator C_ASM '(' string ')' {
673 pragma_renamed = newstring($4, strlen($4));
674 $$ = xnf = init_declarator($<nodep>0, $1, 1, NULL);
679 * Handles declarations and assignments.
680 * Returns nothing.
682 init_declarator: declarator attr_var { init_declarator($<nodep>0, $1, 0, $2);}
683 | declarator C_ASM '(' string ')' attr_var {
684 #ifdef GCC_COMPAT
685 pragma_renamed = newstring($4, strlen($4));
686 init_declarator($<nodep>0, $1, 0, $6);
687 #else
688 werror("gcc extension");
689 init_declarator($<nodep>0, $1, 0, $6);
690 #endif
692 | xnfdeclarator '=' e { simpleinit($1, eve($3)); xnf = NULL; }
693 | xnfdeclarator '=' begbr init_list optcomma '}' {
694 endinit();
695 xnf = NULL;
697 /*COMPAT_GCC*/ | xnfdeclarator '=' begbr '}' { endinit(); xnf = NULL; }
698 | xnfdeclarator '=' addrlbl { simpleinit($1, $3); xnf = NULL; }
701 begbr: '{' { beginit($<symp>-1); }
704 initializer: e %prec ',' { $$ = eve($1); }
705 | addrlbl { $$ = $1; }
706 | ibrace init_list optcomma '}' { $$ = NULL; }
707 | ibrace '}' { asginit(bcon(0)); $$ = NULL; }
710 init_list: designation initializer { dainit($1, $2); }
711 | init_list ',' designation initializer { dainit($3, $4); }
714 designation: designator_list '=' { desinit($1); $$ = NIL; }
715 | '[' e C_ELLIPSIS e ']' '=' { $$ = biop(CM, $2, $4); }
716 | { $$ = NIL; }
719 designator_list: designator { $$ = $1; }
720 | designator_list designator { $$ = $2; $$->n_left = $1; }
723 designator: '[' e ']' {
724 int ie = con_e($2);
725 if (ie < 0) {
726 uerror("designator must be non-negative");
727 ie = 0;
729 $$ = biop(LB, NIL, bcon(ie));
731 | C_STROP C_TYPENAME {
732 if ($1 != DOT)
733 uerror("invalid designator");
734 $$ = bdty(NAME, $2);
736 | C_STROP C_NAME {
737 if ($1 != DOT)
738 uerror("invalid designator");
739 $$ = bdty(NAME, $2);
743 optcomma : /* VOID */
744 | ','
747 ibrace: '{' { ilbrace(); }
750 /* STATEMENTS */
752 compoundstmt: begin block_item_list '}' { flend(); }
753 | begin '}' { flend(); }
756 begin: '{' {
757 struct savbc *bc = tmpalloc(sizeof(struct savbc));
758 if (blevel == 1) {
759 #ifdef STABS
760 if (gflag)
761 stabs_line(lineno);
762 #endif
763 dclargs();
765 #ifdef STABS
766 if (gflag && blevel > 1)
767 stabs_lbrac(blevel+1);
768 #endif
769 ++blevel;
770 oldstyle = 0;
771 bc->contlab = autooff;
772 bc->next = savctx;
773 savctx = bc;
774 bccode();
775 if (!isinlining && sspflag && blevel == 2)
776 sspstart();
780 statement: e ';' { ecomp(eve($1)); symclear(blevel); }
781 | compoundstmt
782 | ifprefix statement { plabel($1); reached = 1; }
783 | ifelprefix statement {
784 if ($1 != NOLAB) {
785 plabel( $1);
786 reached = 1;
789 | whprefix statement {
790 branch(contlab);
791 plabel( brklab );
792 if( (flostat&FBRK) || !(flostat&FLOOP))
793 reached = 1;
794 else
795 reached = 0;
796 resetbc(0);
798 | doprefix statement C_WHILE '(' e ')' ';' {
799 plabel(contlab);
800 if (flostat & FCONT)
801 reached = 1;
802 if (reached)
803 cbranch(buildtree(NE, eve($5), bcon(0)),
804 bcon($1));
805 else
806 tfree(eve($5));
807 plabel( brklab);
808 reached = 1;
809 resetbc(0);
811 | forprefix .e ')' statement
812 { plabel( contlab );
813 if( flostat&FCONT ) reached = 1;
814 if( $2 ) ecomp( $2 );
815 branch($1);
816 plabel( brklab );
817 if( (flostat&FBRK) || !(flostat&FLOOP) ) reached = 1;
818 else reached = 0;
819 resetbc(0);
821 | switchpart statement
822 { if( reached ) branch( brklab );
823 plabel( $1 );
824 swend();
825 plabel( brklab);
826 if( (flostat&FBRK) || !(flostat&FDEF) ) reached = 1;
827 resetbc(FCONT);
829 | C_BREAK ';' {
830 if (brklab == NOLAB)
831 uerror("illegal break");
832 else if (reached)
833 branch(brklab);
834 flostat |= FBRK;
835 reached = 0;
837 | C_CONTINUE ';' {
838 if (contlab == NOLAB)
839 uerror("illegal continue");
840 else
841 branch(contlab);
842 flostat |= FCONT;
843 goto rch;
845 | C_RETURN ';' {
846 branch(retlab);
847 if (cftnsp->stype != VOID &&
848 (cftnsp->sflags & NORETYP) == 0 &&
849 cftnsp->stype != VOID+FTN)
850 uerror("return value required");
851 rch:
852 if (!reached)
853 warner(Wunreachable_code, NULL);
854 reached = 0;
856 | C_RETURN e ';' {
857 NODE *p, *q;
859 p = nametree(cftnsp);
860 p->n_type = DECREF(p->n_type);
861 q = eve($2);
862 #ifndef NO_COMPLEX
863 if (ANYCX(q) || ANYCX(p))
864 q = cxret(q, p);
865 #endif
866 p = buildtree(RETURN, p, q);
867 if (p->n_type == VOID) {
868 ecomp(p->n_right);
869 } else {
870 if (cftnod == NIL)
871 cftnod = tempnode(0, p->n_type,
872 p->n_df, p->n_ap);
873 ecomp(buildtree(ASSIGN,
874 ccopy(cftnod), p->n_right));
876 tfree(p->n_left);
877 nfree(p);
878 branch(retlab);
879 reached = 0;
881 | C_GOTO C_NAME ';' { gotolabel($2); goto rch; }
882 | C_GOTO '*' e ';' { ecomp(biop(GOTO, eve($3), NIL)); }
883 | asmstatement ';'
884 | ';'
885 | error ';'
886 | error '}'
887 | label statement
890 asmstatement: C_ASM mvol '(' string ')' { send_passt(IP_ASM, mkpstr($4)); }
891 | C_ASM mvol '(' string xasm ')' { mkxasm($4, $5); }
894 mvol: /* empty */
895 | C_QUALIFIER { nfree($1); }
898 xasm: ':' oplist { $$ = xcmop($2, NIL, NIL); }
899 | ':' oplist ':' oplist { $$ = xcmop($2, $4, NIL); }
900 | ':' oplist ':' oplist ':' cnstr { $$ = xcmop($2, $4, $6); }
903 oplist: /* nothing */ { $$ = NIL; }
904 | oper { $$ = $1; }
907 oper: string '(' e ')' { $$ = xasmop($1, eve($3)); }
908 | oper ',' string '(' e ')' {
909 $$ = cmop($1, xasmop($3, eve($5)));
913 cnstr: string { $$ = xasmop($1, bcon(0)); }
914 | cnstr ',' string { $$ = cmop($1, xasmop($3, bcon(0))); }
917 label: C_NAME ':' attr_var { deflabel($1, $3); reached = 1; }
918 | C_TYPENAME ':' attr_var { deflabel($1, $3); reached = 1; }
919 | C_CASE e ':' { addcase(eve($2)); reached = 1; }
920 /* COMPAT_GCC */| C_CASE e C_ELLIPSIS e ':' {
921 #ifdef GCC_COMPAT
922 gcccase(eve($2), eve($4)); reached = 1;
923 #endif
925 | C_DEFAULT ':' { reached = 1; adddef(); flostat |= FDEF; }
928 doprefix: C_DO {
929 savebc();
930 brklab = getlab();
931 contlab = getlab();
932 plabel( $$ = getlab());
933 reached = 1;
936 ifprefix: C_IF '(' e ')' {
937 cbranch(buildtree(NOT, eve($3), NIL), bcon($$ = getlab()));
938 reached = 1;
941 ifelprefix: ifprefix statement C_ELSE {
942 if (reached)
943 branch($$ = getlab());
944 else
945 $$ = NOLAB;
946 plabel( $1);
947 reached = 1;
951 whprefix: C_WHILE '(' e ')' {
952 savebc();
953 $3 = eve($3);
954 if ($3->n_op == ICON && $3->n_lval != 0)
955 flostat = FLOOP;
956 plabel( contlab = getlab());
957 reached = 1;
958 brklab = getlab();
959 if (flostat == FLOOP)
960 tfree($3);
961 else
962 cbranch(buildtree(NOT, $3, NIL), bcon(brklab));
965 forprefix: C_FOR '(' .e ';' .e ';' {
966 if ($3)
967 ecomp($3);
968 savebc();
969 contlab = getlab();
970 brklab = getlab();
971 plabel( $$ = getlab());
972 reached = 1;
973 if ($5)
974 cbranch(buildtree(NOT, $5, NIL), bcon(brklab));
975 else
976 flostat |= FLOOP;
978 | C_FOR '(' { ++blevel; } declaration .e ';' {
979 blevel--;
980 savebc();
981 contlab = getlab();
982 brklab = getlab();
983 plabel( $$ = getlab());
984 reached = 1;
985 if ($5)
986 cbranch(buildtree(NOT, $5, NIL), bcon(brklab));
987 else
988 flostat |= FLOOP;
992 switchpart: C_SWITCH '(' e ')' {
993 NODE *p;
994 int num;
995 TWORD t;
997 savebc();
998 brklab = getlab();
999 $3 = eve($3);
1000 if (($3->n_type != BOOL && $3->n_type > ULONGLONG) ||
1001 $3->n_type < CHAR) {
1002 uerror("switch expression must have integer "
1003 "type");
1004 t = INT;
1005 } else {
1006 $3 = intprom($3);
1007 t = $3->n_type;
1009 p = tempnode(0, t, 0, MKAP(t));
1010 num = regno(p);
1011 ecomp(buildtree(ASSIGN, p, $3));
1012 branch( $$ = getlab());
1013 swstart(num, t);
1014 reached = 0;
1017 /* EXPRESSIONS */
1018 .e: e { $$ = eve($1); }
1019 | { $$=0; }
1022 elist: { $$ = NIL; }
1023 | e %prec ','
1024 | elist ',' e { $$ = biop(CM, $1, $3); }
1025 | elist ',' cast_type { /* hack for stdarg */
1026 TYMFIX($3);
1027 $3->n_op = TYPE;
1028 $$ = biop(CM, $1, $3);
1033 * Precedence order of operators.
1035 e: e ',' e { $$ = biop(COMOP, $1, $3); }
1036 | e '=' e { $$ = biop(ASSIGN, $1, $3); }
1037 | e C_ASOP e { $$ = biop($2, $1, $3); }
1038 | e '?' e ':' e {
1039 $$=biop(QUEST, $1, biop(COLON, $3, $5));
1041 | e '?' ':' e {
1042 NODE *p = tempnode(0, $1->n_type, $1->n_df, $1->n_ap);
1043 $$ = biop(COLON, ccopy(p), $4);
1044 $$=biop(QUEST, biop(ASSIGN, p, $1), $$);
1046 | e C_OROR e { $$ = biop($2, $1, $3); }
1047 | e C_ANDAND e { $$ = biop($2, $1, $3); }
1048 | e '|' e { $$ = biop(OR, $1, $3); }
1049 | e '^' e { $$ = biop(ER, $1, $3); }
1050 | e '&' e { $$ = biop(AND, $1, $3); }
1051 | e C_EQUOP e { $$ = biop($2, $1, $3); }
1052 | e C_RELOP e { $$ = biop($2, $1, $3); }
1053 | e C_SHIFTOP e { $$ = biop($2, $1, $3); }
1054 | e '+' e { $$ = biop(PLUS, $1, $3); }
1055 | e '-' e { $$ = biop(MINUS, $1, $3); }
1056 | e C_DIVOP e { $$ = biop($2, $1, $3); }
1057 | e '*' e { $$ = biop(MUL, $1, $3); }
1058 | e '=' addrlbl { $$ = biop(ASSIGN, $1, $3); }
1059 | term
1062 xbegin: begin {
1063 $$ = getlab(); getlab(); getlab();
1064 branch($$); plabel(($$)+1); }
1067 addrlbl: C_ANDAND C_NAME {
1068 #ifdef GCC_COMPAT
1069 struct symtab *s = lookup($2, SLBLNAME);
1070 if (s->soffset == 0)
1071 s->soffset = -getlab();
1072 $$ = buildtree(ADDROF, nametree(s), NIL);
1073 #else
1074 uerror("gcc extension");
1075 #endif
1079 term: term C_INCOP { $$ = biop($2, $1, bcon(1)); }
1080 | '*' term { $$ = biop(UMUL, $2, NIL); }
1081 | '&' term { $$ = biop(ADDROF, $2, NIL); }
1082 | '-' term { $$ = biop(UMINUS, $2, NIL ); }
1083 | '+' term { $$ = biop(PLUS, $2, bcon(0)); }
1084 | C_UNOP term { $$ = biop($1, $2, NIL); }
1085 | C_INCOP term {
1086 $$ = biop($1 == INCR ? PLUSEQ : MINUSEQ, $2, bcon(1));
1088 | C_SIZEOF xa term { $$ = biop(SZOF, $3, bcon(0)); inattr = $<intval>2; }
1089 | '(' cast_type ')' term %prec C_INCOP {
1090 TYMFIX($2);
1091 $$ = biop(CAST, $2, $4);
1093 | C_SIZEOF xa '(' cast_type ')' %prec C_SIZEOF {
1094 $$ = biop(SZOF, $4, bcon(1));
1095 inattr = $<intval>2;
1097 | C_ALIGNOF xa '(' cast_type ')' {
1098 TYMFIX($4);
1099 int al = talign($4->n_type, $4->n_ap);
1100 $$ = bcon(al/SZCHAR);
1101 inattr = $<intval>2;
1102 tfree($4);
1104 | '(' cast_type ')' clbrace init_list optcomma '}' {
1105 endinit();
1106 $$ = bdty(NAME, $4);
1107 $$->n_op = CLOP;
1109 | '(' cast_type ')' clbrace '}' {
1110 endinit();
1111 $$ = bdty(NAME, $4);
1112 $$->n_op = CLOP;
1114 | term '[' e ']' { $$ = biop(LB, $1, $3); }
1115 | C_NAME '(' elist ')' {
1116 $$ = biop($3 ? CALL : UCALL, bdty(NAME, $1), $3);
1118 | term '(' elist ')' { $$ = biop($3 ? CALL : UCALL, $1, $3); }
1119 | term C_STROP C_NAME { $$ = biop($2, $1, bdty(NAME, $3)); }
1120 | term C_STROP C_TYPENAME { $$ = biop($2, $1, bdty(NAME, $3));}
1121 | C_NAME %prec C_SIZEOF /* below ( */{ $$ = bdty(NAME, $1); }
1122 | PCC_OFFSETOF '(' cast_type ',' term ')' {
1123 TYMFIX($3);
1124 $3->n_type = INCREF($3->n_type);
1125 $3 = biop(CAST, $3, bcon(0));
1126 if ($5->n_op == NAME) {
1127 $$ = biop(STREF, $3, $5);
1128 } else {
1129 NODE *p = $5;
1130 while (p->n_left->n_op != NAME)
1131 p = p->n_left;
1132 p->n_left = biop(STREF, $3, p->n_left);
1133 $$ = $5;
1135 $$ = biop(ADDROF, $$, NIL);
1136 $3 = block(NAME, NIL, NIL, ENUNSIGN(INTPTR), 0,
1137 MKAP(ENUNSIGN(INTPTR)));
1138 $$ = biop(CAST, $3, $$);
1140 | C_ICON { $$ = $1; }
1141 | C_FCON { $$ = $1; }
1142 | string { $$ = bdty(STRING, $1, widestr); }
1143 | '(' e ')' { $$=$2; }
1144 | '(' xbegin block_item_list e ';' '}' ')' {
1145 /* XXX - check recursive ({ }) statements */
1146 branch(($2)+2);
1147 plabel($2);
1148 $$ = buildtree(COMOP,
1149 biop(GOTO, bcon(($2)+1), NIL), eve($4));
1150 flend();
1152 | '(' xbegin block_item_list '}' ')' {
1153 /* XXX - check recursive ({ }) statements */
1154 branch(($2)+2);
1155 plabel($2);
1156 $$ = buildtree(COMOP,
1157 biop(GOTO, bcon(($2)+1), NIL), voidcon());
1158 flend();
1162 xa: { $<intval>$ = inattr; inattr = 0; }
1165 clbrace: '{' { NODE *q = $<nodep>-1; TYMFIX(q); $$ = clbrace(q); }
1168 string: C_STRING { widestr = 0; $$ = stradd("", $1); }
1169 | string C_STRING { $$ = stradd($1, $2); }
1172 cast_type: specifier_qualifier_list {
1173 $$ = biop(TYMERGE, $1, bdty(NAME, NULL));
1175 | specifier_qualifier_list abstract_declarator {
1176 $$ = biop(TYMERGE, $1, aryfix($2));
1182 NODE *
1183 mkty(TWORD t, union dimfun *d, struct attr *sue)
1185 return block(TYPE, NIL, NIL, t, d, sue);
1188 NODE *
1189 bdty(int op, ...)
1191 va_list ap;
1192 int val;
1193 register NODE *q;
1195 va_start(ap, op);
1196 q = biop(op, NIL, NIL);
1198 switch (op) {
1199 case UMUL:
1200 case UCALL:
1201 q->n_left = va_arg(ap, NODE *);
1202 q->n_rval = 0;
1203 break;
1205 case CALL:
1206 q->n_left = va_arg(ap, NODE *);
1207 q->n_right = va_arg(ap, NODE *);
1208 break;
1210 case LB:
1211 q->n_left = va_arg(ap, NODE *);
1212 if ((val = va_arg(ap, int)) <= 0) {
1213 uerror("array size must be positive");
1214 val = 1;
1216 q->n_right = bcon(val);
1217 break;
1219 case NAME:
1220 q->n_sp = va_arg(ap, struct symtab *); /* XXX survive tymerge */
1221 break;
1223 case STRING:
1224 q->n_name = va_arg(ap, char *);
1225 q->n_lval = va_arg(ap, int);
1226 break;
1228 default:
1229 cerror("bad bdty");
1231 va_end(ap);
1233 return q;
1236 static void
1237 flend(void)
1239 if (!isinlining && sspflag && blevel == 2)
1240 sspend();
1241 #ifdef STABS
1242 if (gflag && blevel > 2)
1243 stabs_rbrac(blevel);
1244 #endif
1245 --blevel;
1246 if( blevel == 1 )
1247 blevel = 0;
1248 symclear(blevel); /* Clean ut the symbol table */
1249 if (autooff > maxautooff)
1250 maxautooff = autooff;
1251 autooff = savctx->contlab;
1252 savctx = savctx->next;
1255 static void
1256 savebc(void)
1258 struct savbc *bc = tmpalloc(sizeof(struct savbc));
1260 bc->brklab = brklab;
1261 bc->contlab = contlab;
1262 bc->flostat = flostat;
1263 bc->next = savbc;
1264 savbc = bc;
1265 flostat = 0;
1268 static void
1269 resetbc(int mask)
1271 flostat = savbc->flostat | (flostat&mask);
1272 contlab = savbc->contlab;
1273 brklab = savbc->brklab;
1274 savbc = savbc->next;
1277 struct swdef {
1278 struct swdef *next; /* Next in list */
1279 int deflbl; /* Label for "default" */
1280 struct swents *ents; /* Linked sorted list of case entries */
1281 int nents; /* # of entries in list */
1282 int num; /* Node value will end up in */
1283 TWORD type; /* Type of switch expression */
1284 } *swpole;
1287 * add case to switch
1289 static void
1290 addcase(NODE *p)
1292 struct swents **put, *w, *sw = tmpalloc(sizeof(struct swents));
1293 CONSZ val;
1295 p = optim(p); /* change enum to ints */
1296 if (p->n_op != ICON || p->n_sp != NULL) {
1297 uerror( "non-constant case expression");
1298 return;
1300 if (swpole == NULL) {
1301 uerror("case not in switch");
1302 return;
1305 if (DEUNSIGN(swpole->type) != DEUNSIGN(p->n_type)) {
1306 val = p->n_lval;
1307 p = makety(p, swpole->type, 0, 0, MKAP(swpole->type));
1308 if (p->n_op != ICON)
1309 cerror("could not cast case value to type of switch "
1310 "expression");
1311 if (p->n_lval != val)
1312 werror("case expression truncated");
1314 sw->sval = p->n_lval;
1315 tfree(p);
1316 put = &swpole->ents;
1317 if (ISUNSIGNED(swpole->type)) {
1318 for (w = swpole->ents;
1319 w != NULL && (U_CONSZ)w->sval < (U_CONSZ)sw->sval;
1320 w = w->next)
1321 put = &w->next;
1322 } else {
1323 for (w = swpole->ents; w != NULL && w->sval < sw->sval;
1324 w = w->next)
1325 put = &w->next;
1327 if (w != NULL && w->sval == sw->sval) {
1328 uerror("duplicate case in switch");
1329 return;
1331 plabel(sw->slab = getlab());
1332 *put = sw;
1333 sw->next = w;
1334 swpole->nents++;
1337 #ifdef GCC_COMPAT
1338 void
1339 gcccase(NODE *ln, NODE *hn)
1341 CONSZ i, l, h;
1343 l = icons(optim(ln));
1344 h = icons(optim(hn));
1346 if (h < l)
1347 i = l, l = h, h = i;
1349 for (i = l; i <= h; i++)
1350 addcase(xbcon(i, NULL, hn->n_type));
1352 #endif
1355 * add default case to switch
1357 static void
1358 adddef(void)
1360 if (swpole == NULL)
1361 uerror("default not inside switch");
1362 else if (swpole->deflbl != 0)
1363 uerror("duplicate default in switch");
1364 else
1365 plabel( swpole->deflbl = getlab());
1368 static void
1369 swstart(int num, TWORD type)
1371 struct swdef *sw = tmpalloc(sizeof(struct swdef));
1373 sw->deflbl = sw->nents = 0;
1374 sw->ents = NULL;
1375 sw->next = swpole;
1376 sw->num = num;
1377 sw->type = type;
1378 swpole = sw;
1382 * end a switch block
1384 static void
1385 swend(void)
1387 struct swents *sw, **swp;
1388 int i;
1390 sw = tmpalloc(sizeof(struct swents));
1391 swp = tmpalloc(sizeof(struct swents *) * (swpole->nents+1));
1393 sw->slab = swpole->deflbl;
1394 swp[0] = sw;
1396 for (i = 1; i <= swpole->nents; i++) {
1397 swp[i] = swpole->ents;
1398 swpole->ents = swpole->ents->next;
1400 genswitch(swpole->num, swpole->type, swp, swpole->nents);
1402 swpole = swpole->next;
1406 * num: tempnode the value of the switch expression is in
1407 * type: type of the switch expression
1409 * p points to an array of structures, each consisting
1410 * of a constant value and a label.
1411 * The first is >=0 if there is a default label;
1412 * its value is the label number
1413 * The entries p[1] to p[n] are the nontrivial cases
1414 * n is the number of case statements (length of list)
1416 static void
1417 genswitch(int num, TWORD type, struct swents **p, int n)
1419 NODE *r, *q;
1420 int i;
1422 if (mygenswitch(num, type, p, n))
1423 return;
1425 /* simple switch code */
1426 for (i = 1; i <= n; ++i) {
1427 /* already in 1 */
1428 r = tempnode(num, type, 0, MKAP(type));
1429 q = xbcon(p[i]->sval, NULL, type);
1430 r = buildtree(NE, r, clocal(q));
1431 cbranch(buildtree(NOT, r, NIL), bcon(p[i]->slab));
1433 if (p[0]->slab > 0)
1434 branch(p[0]->slab);
1438 * Declare a variable or prototype.
1440 static struct symtab *
1441 init_declarator(NODE *tn, NODE *p, int assign, NODE *a)
1443 int class = tn->n_lval;
1444 struct symtab *sp;
1446 p = aryfix(p);
1447 p = tymerge(tn, p);
1448 if (a) {
1449 struct attr *ap = gcc_attr_parse(a);
1450 p->n_ap = attr_add(p->n_ap, ap);
1453 p->n_sp = sp = lookup((char *)p->n_sp, 0); /* XXX */
1455 if (fun_inline && ISFTN(p->n_type))
1456 sp->sflags |= SINLINE;
1458 if (ISFTN(p->n_type) == 0) {
1459 if (assign) {
1460 defid(p, class);
1461 sp = p->n_sp;
1462 sp->sflags |= SASG;
1463 if (sp->sflags & SDYNARRAY)
1464 uerror("can't initialize dynamic arrays");
1465 lcommdel(sp);
1466 } else
1467 nidcl(p, class);
1468 } else {
1469 extern NODE *parlink;
1470 if (assign)
1471 uerror("cannot initialise function");
1472 defid(p, uclass(class));
1473 sp = p->n_sp;
1474 if (parlink) {
1475 /* dynamic sized arrays in prototypes */
1476 tfree(parlink); /* Free delayed tree */
1477 parlink = NIL;
1480 tfree(p);
1481 return sp;
1485 * Declare old-stype function arguments.
1487 static void
1488 oldargs(NODE *p)
1490 blevel++;
1491 p->n_op = TYPE;
1492 p->n_type = FARG;
1493 p->n_sp = lookup((char *)p->n_sp, 0);/* XXX */
1494 defid(p, PARAM);
1495 blevel--;
1499 * Set NAME nodes to a null name and index of LB nodes to NOOFFSET
1500 * unless clr is one, in that case preserve variable name.
1502 static NODE *
1503 namekill(NODE *p, int clr)
1505 NODE *q;
1506 int o = p->n_op;
1508 switch (coptype(o)) {
1509 case LTYPE:
1510 if (o == NAME) {
1511 if (clr)
1512 p->n_sp = NULL;
1513 else
1514 p->n_sp = lookup((char *)p->n_sp, 0);/* XXX */
1516 break;
1518 case UTYPE:
1519 p->n_left = namekill(p->n_left, clr);
1520 break;
1522 case BITYPE:
1523 p->n_left = namekill(p->n_left, clr);
1524 if (o == LB) {
1525 if (clr) {
1526 tfree(p->n_right);
1527 p->n_right = bcon(NOOFFSET);
1528 } else
1529 p->n_right = eve(p->n_right);
1530 } else if (o == CALL)
1531 p->n_right = namekill(p->n_right, 1);
1532 else
1533 p->n_right = namekill(p->n_right, clr);
1534 if (o == TYMERGE) {
1535 q = tymerge(p->n_left, p->n_right);
1536 q->n_ap = attr_add(q->n_ap, p->n_ap);
1537 tfree(p->n_left);
1538 nfree(p);
1539 p = q;
1541 break;
1543 return p;
1547 * Declare function arguments.
1549 static NODE *
1550 funargs(NODE *p)
1552 extern NODE *arrstk[10];
1554 if (p->n_op == ELLIPSIS)
1555 return p;
1557 p = namekill(p, 0);
1558 if (ISFTN(p->n_type))
1559 p->n_type = INCREF(p->n_type);
1560 if (ISARY(p->n_type)) {
1561 p->n_type += (PTR-ARY);
1562 if (p->n_df->ddim == -1)
1563 tfree(arrstk[0]), arrstk[0] = NIL;
1564 p->n_df++;
1566 if (p->n_type == VOID && p->n_sp->sname == NULL)
1567 return p; /* sanitycheck later */
1568 else if (p->n_sp->sname == NULL)
1569 uerror("argument missing");
1570 else
1571 defid(p, PARAM);
1572 return p;
1575 static NODE *
1576 listfw(NODE *p, NODE * (*f)(NODE *))
1578 if (p->n_op == CM) {
1579 p->n_left = listfw(p->n_left, f);
1580 p->n_right = (*f)(p->n_right);
1581 } else
1582 p = (*f)(p);
1583 return p;
1588 * Declare a function.
1590 static void
1591 fundef(NODE *tp, NODE *p)
1593 extern int prolab;
1594 struct symtab *s;
1595 NODE *q, *typ;
1596 int class = tp->n_lval, oclass, ctval;
1597 char *c;
1600 * We discard all names except for those needed for
1601 * parameter declaration. While doing that, also change
1602 * non-constant array sizes to unknown.
1604 ctval = tvaloff;
1605 for (q = p; coptype(q->n_op) != LTYPE &&
1606 q->n_left->n_op != NAME; q = q->n_left) {
1607 if (q->n_op == CALL)
1608 q->n_right = namekill(q->n_right, 1);
1610 if (q->n_op != CALL && q->n_op != UCALL) {
1611 uerror("invalid function definition");
1612 p = bdty(UCALL, p);
1613 } else if (q->n_op == CALL) {
1614 blevel = 1;
1615 argoff = ARGINIT;
1616 if (oldstyle == 0)
1617 q->n_right = listfw(q->n_right, funargs);
1618 ftnarg(q);
1619 blevel = 0;
1622 p = typ = tymerge(tp, p);
1623 s = typ->n_sp = lookup((char *)typ->n_sp, 0); /* XXX */
1625 oclass = s->sclass;
1626 if (class == STATIC && oclass == EXTERN)
1627 werror("%s was first declared extern, then static", s->sname);
1629 if (fun_inline) {
1630 /* special syntax for inline functions */
1631 if (! strcmp(s->sname,"main"))
1632 uerror("cannot inline main()");
1634 s->sflags |= SINLINE;
1635 inline_start(s);
1636 if (class == EXTERN)
1637 class = EXTDEF;
1638 } else if (class == EXTERN)
1639 class = SNULL; /* same result */
1641 cftnsp = s;
1642 defid(p, class);
1643 #ifdef GCC_COMPAT
1644 if (attr_find(p->n_ap, GCC_ATYP_ALW_INL)) {
1645 /* Temporary turn on temps to make always_inline work */
1646 alwinl = 1;
1647 if (xtemps == 0) alwinl |= 2;
1648 xtemps = 1;
1650 #endif
1651 prolab = getlab();
1652 if ((c = cftnsp->soname) == NULL)
1653 c = addname(exname(cftnsp->sname));
1654 send_passt(IP_PROLOG, -1, c, cftnsp->stype,
1655 cftnsp->sclass == EXTDEF, prolab, ctval);
1656 blevel++;
1657 #ifdef STABS
1658 if (gflag)
1659 stabs_func(s);
1660 #endif
1661 tfree(tp);
1662 tfree(p);
1666 static void
1667 fend(void)
1669 if (blevel)
1670 cerror("function level error");
1671 ftnend();
1672 fun_inline = 0;
1673 if (alwinl & 2) xtemps = 0;
1674 alwinl = 0;
1675 cftnsp = NULL;
1678 NODE *
1679 structref(NODE *p, int f, char *name)
1681 NODE *r;
1683 if (f == DOT)
1684 p = buildtree(ADDROF, p, NIL);
1685 r = biop(NAME, NIL, NIL);
1686 r->n_name = name;
1687 r = buildtree(STREF, p, r);
1688 return r;
1691 static void
1692 olddecl(NODE *p, NODE *a)
1694 struct symtab *s;
1696 p = namekill(p, 0);
1697 s = p->n_sp;
1698 if (s->slevel != 1 || s->stype == UNDEF)
1699 uerror("parameter '%s' not defined", s->sname);
1700 else if (s->stype != FARG)
1701 uerror("parameter '%s' redefined", s->sname);
1703 s->stype = p->n_type;
1704 s->sdf = p->n_df;
1705 s->sap = p->n_ap;
1706 if (ISARY(s->stype)) {
1707 s->stype += (PTR-ARY);
1708 s->sdf++;
1710 if (a)
1711 attr_add(s->sap, gcc_attr_parse(a));
1712 nfree(p);
1715 void
1716 branch(int lbl)
1718 int r = reached++;
1719 ecomp(biop(GOTO, bcon(lbl), NIL));
1720 reached = r;
1724 * Create a printable string based on an encoded string.
1726 static char *
1727 mkpstr(char *str)
1729 char *s, *os;
1730 int v, l = strlen(str)+3; /* \t + \n + \0 */
1732 os = s = inlalloc(l);
1733 *s++ = '\t';
1734 for (; *str; ) {
1735 if (*str++ == '\\')
1736 v = esccon(&str);
1737 else
1738 v = str[-1];
1739 *s++ = v;
1741 *s++ = '\n';
1742 *s = 0;
1743 return os;
1747 * Estimate the max length a string will have in its internal
1748 * representation based on number of \ characters.
1750 static int
1751 maxstlen(char *str)
1753 int i;
1755 for (i = 0; *str; str++, i++)
1756 if (*str == '\\' || *str < 32 || *str > 0176)
1757 i += 3;
1758 return i;
1761 static char *
1762 voct(char *d, unsigned int v)
1764 v &= (1 << SZCHAR) - 1;
1765 *d++ = '\\';
1766 *d++ = v/64 + '0'; v &= 077;
1767 *d++ = v/8 + '0'; v &= 7;
1768 *d++ = v + '0';
1769 return d;
1774 * Convert a string to internal format. The resulting string may be no
1775 * more than len characters long.
1777 static void
1778 fixstr(char *d, char *s, int len)
1780 unsigned int v;
1782 while (*s) {
1783 if (len <= 0)
1784 cerror("fixstr");
1785 if (*s == '\\') {
1786 s++;
1787 v = esccon(&s);
1788 d = voct(d, v);
1789 len -= 4;
1790 } else if (*s < ' ' || *s > 0176) {
1791 d = voct(d, *s++);
1792 len -= 4;
1793 } else
1794 *d++ = *s++, len--;
1796 *d = 0;
1800 * Add "raw" string new to cleaned string old.
1802 static char *
1803 stradd(char *old, char *new)
1805 char *rv;
1806 int len;
1808 if (*new == 'L' && new[1] == '\"')
1809 widestr = 1, new++;
1810 if (*new == '\"') {
1811 new++; /* remove first " */
1812 new[strlen(new) - 1] = 0;/* remove last " */
1814 len = strlen(old) + maxstlen(new) + 1;
1815 rv = tmpalloc(len);
1816 strlcpy(rv, old, len);
1817 fixstr(rv + strlen(old), new, maxstlen(new) + 1);
1818 return rv;
1822 * Fake a symtab entry for compound literals.
1824 static struct symtab *
1825 clbrace(NODE *p)
1827 struct symtab *sp;
1829 sp = getsymtab(simname("cl"), STEMP);
1830 sp->stype = p->n_type;
1831 sp->squal = p->n_qual;
1832 sp->sdf = p->n_df;
1833 sp->sap = p->n_ap;
1834 tfree(p);
1835 if (blevel == 0 && xnf != NULL) {
1836 sp->sclass = STATIC;
1837 sp->slevel = 2;
1838 sp->soffset = getlab();
1839 } else {
1840 sp->sclass = blevel ? AUTO : STATIC;
1841 if (!ISARY(sp->stype) || sp->sdf->ddim != NOOFFSET) {
1842 sp->soffset = NOOFFSET;
1843 oalloc(sp, &autooff);
1846 beginit(sp);
1847 return sp;
1850 char *
1851 simname(char *s)
1853 int len = strlen(s) + 10 + 1;
1854 char *w = tmpalloc(len);
1856 snprintf(w, len, "%s%d", s, getlab());
1857 return w;
1860 NODE *
1861 biop(int op, NODE *l, NODE *r)
1863 return block(op, l, r, INT, 0, MKAP(INT));
1866 static NODE *
1867 cmop(NODE *l, NODE *r)
1869 return biop(CM, l, r);
1872 static NODE *
1873 voidcon(void)
1875 return block(ICON, NIL, NIL, STRTY, 0, MKAP(VOID));
1878 /* Support for extended assembler a' la' gcc style follows below */
1880 static NODE *
1881 xmrg(NODE *out, NODE *in)
1883 NODE *p = in;
1885 if (p->n_op == XARG) {
1886 in = cmop(out, p);
1887 } else {
1888 while (p->n_left->n_op == CM)
1889 p = p->n_left;
1890 p->n_left = cmop(out, p->n_left);
1892 return in;
1896 * Put together in and out node lists in one list, and balance it with
1897 * the constraints on the right side of a CM node.
1899 static NODE *
1900 xcmop(NODE *out, NODE *in, NODE *str)
1902 NODE *p, *q;
1904 if (out) {
1905 /* D out-list sanity check */
1906 for (p = out; p->n_op == CM; p = p->n_left) {
1907 q = p->n_right;
1908 if (q->n_name[0] != '=' && q->n_name[0] != '+')
1909 uerror("output missing =");
1911 if (p->n_name[0] != '=' && p->n_name[0] != '+')
1912 uerror("output missing =");
1913 if (in == NIL)
1914 p = out;
1915 else
1916 p = xmrg(out, in);
1917 } else if (in) {
1918 p = in;
1919 } else
1920 p = voidcon();
1922 if (str == NIL)
1923 str = voidcon();
1924 return cmop(p, str);
1928 * Generate a XARG node based on a string and an expression.
1930 static NODE *
1931 xasmop(char *str, NODE *p)
1934 p = biop(XARG, p, NIL);
1935 p->n_name = isinlining ? newstring(str, strlen(str)+1) : str;
1936 return p;
1940 * Generate a XASM node based on a string and an expression.
1942 static void
1943 mkxasm(char *str, NODE *p)
1945 NODE *q;
1947 q = biop(XASM, p->n_left, p->n_right);
1948 q->n_name = isinlining ? newstring(str, strlen(str)+1) : str;
1949 nfree(p);
1950 ecomp(q);
1953 #ifdef GCC_COMPAT
1954 static NODE *
1955 tyof(NODE *p)
1957 static struct symtab spp;
1958 NODE *q = block(TYPE, NIL, NIL, p->n_type, p->n_df, p->n_ap);
1959 q->n_qual = p->n_qual;
1960 q->n_sp = &spp; /* for typenode */
1961 tfree(p);
1962 return q;
1964 #endif
1967 * Traverse an unhandled expression tree bottom-up and call buildtree()
1968 * or equivalent as needed.
1970 NODE *
1971 eve(NODE *p)
1973 struct symtab *sp;
1974 NODE *r, *p1, *p2;
1975 int x;
1977 p1 = p->n_left;
1978 p2 = p->n_right;
1979 switch (p->n_op) {
1980 case NAME:
1981 sp = lookup((char *)p->n_sp, 0);
1982 if (sp->sflags & SINLINE)
1983 inline_ref(sp);
1984 r = nametree(sp);
1985 if (sp->sflags & SDYNARRAY)
1986 r = buildtree(UMUL, r, NIL);
1987 #ifdef GCC_COMPAT
1988 if (attr_find(sp->sap, GCC_ATYP_DEPRECATED))
1989 werror("`%s' is deprecated", sp->sname);
1990 #endif
1991 break;
1993 case DOT:
1994 case STREF:
1995 r = structref(eve(p1), p->n_op, (char *)p2->n_sp);
1996 nfree(p2);
1997 break;
1999 case CAST:
2000 p1 = buildtree(CAST, p1, eve(p2));
2001 nfree(p1->n_left);
2002 r = p1->n_right;
2003 nfree(p1);
2004 break;
2007 case SZOF:
2008 x = xinline; xinline = 0; /* XXX hack */
2009 if (p2->n_lval == 0)
2010 p1 = eve(p1);
2011 else
2012 TYMFIX(p1);
2013 nfree(p2);
2014 r = doszof(p1);
2015 xinline = x;
2016 break;
2018 case LB:
2019 p1 = eve(p->n_left);
2020 r = buildtree(UMUL, buildtree(PLUS, p1, eve(p2)), NIL);
2021 break;
2023 case COMPL:
2024 #ifndef NO_COMPLEX
2025 p1 = eve(p1);
2026 if (ANYCX(p1))
2027 r = cxconj(p1);
2028 else
2029 r = buildtree(COMPL, p1, NIL);
2030 break;
2031 #endif
2032 case UMINUS:
2033 case NOT:
2034 case UMUL:
2035 r = buildtree(p->n_op, eve(p->n_left), NIL);
2036 break;
2038 case ADDROF:
2039 r = eve(p1);
2040 if (ISFTN(p->n_type)/* || ISARY(p->n_type) */){
2041 #ifdef notdef
2042 werror( "& before array or function: ignored" );
2043 #endif
2044 } else
2045 r = buildtree(ADDROF, r, NIL);
2046 break;
2048 case CALL:
2049 p2 = eve(p2);
2050 /* FALLTHROUGH */
2051 case UCALL:
2052 if (p1->n_op == NAME) {
2053 sp = lookup((char *)p1->n_sp, 0);
2054 if (sp->stype == UNDEF) {
2055 p1->n_type = FTN|INT;
2056 p1->n_sp = sp;
2057 p1->n_ap = MKAP(INT);
2058 defid(p1, EXTERN);
2060 nfree(p1);
2061 #ifdef GCC_COMPAT
2062 if (attr_find(sp->sap, GCC_ATYP_DEPRECATED))
2063 werror("`%s' is deprecated", sp->sname);
2064 #endif
2065 r = doacall(sp, nametree(sp), p2);
2066 } else
2067 r = doacall(NULL, eve(p1), p2);
2068 break;
2070 #ifndef NO_COMPLEX
2071 case XREAL:
2072 case XIMAG:
2073 p1 = eve(p1);
2074 r = cxelem(p->n_op, p1);
2075 break;
2076 #endif
2078 case MUL:
2079 case DIV:
2080 case PLUS:
2081 case MINUS:
2082 case ASSIGN:
2083 case EQ:
2084 case NE:
2085 #ifndef NO_COMPLEX
2086 p1 = eve(p1);
2087 p2 = eve(p2);
2088 if (ANYCX(p1) || ANYCX(p2)) {
2089 r = cxop(p->n_op, p1, p2);
2090 } else if (ISITY(p1->n_type) || ISITY(p2->n_type)) {
2091 r = imop(p->n_op, p1, p2);
2092 } else
2093 r = buildtree(p->n_op, p1, p2);
2094 break;
2095 #endif
2096 case MOD:
2097 case INCR:
2098 case DECR:
2099 case CM:
2100 case GT:
2101 case GE:
2102 case LT:
2103 case LE:
2104 case RS:
2105 case LS:
2106 case RSEQ:
2107 case LSEQ:
2108 case AND:
2109 case OR:
2110 case ER:
2111 case OROR:
2112 case ANDAND:
2113 case EREQ:
2114 case OREQ:
2115 case ANDEQ:
2116 case MINUSEQ:
2117 case PLUSEQ:
2118 case MULEQ:
2119 case DIVEQ:
2120 case MODEQ:
2121 case QUEST:
2122 case COLON:
2123 p1 = eve(p1);
2124 r = buildtree(p->n_op, p1, eve(p2));
2125 break;
2127 case STRING:
2128 r = strend(p->n_lval, p->n_name);
2129 break;
2131 case COMOP:
2132 if (p1->n_op == GOTO) {
2133 /* inside ({ }), eve already called */
2134 r = buildtree(p->n_op, p1, p2);
2135 } else {
2136 p1 = eve(p1);
2137 r = buildtree(p->n_op, p1, eve(p2));
2139 break;
2141 case TYPE:
2142 case ICON:
2143 case FCON:
2144 case TEMP:
2145 return p;
2147 case CLOP:
2148 r = nametree(p->n_sp);
2149 break;
2151 default:
2152 #ifdef PCC_DEBUG
2153 fwalk(p, eprint, 0);
2154 #endif
2155 cerror("eve");
2156 r = NIL;
2158 nfree(p);
2159 return r;
2163 con_e(NODE *p)
2165 return icons(eve(p));
2168 void
2169 uawarn(NODE *p, char *s)
2171 if (p == 0)
2172 return;
2173 if (attrwarn)
2174 werror("unhandled %s attribute", s);
2175 tfree(p);
2178 static void
2179 dainit(NODE *d, NODE *a)
2181 if (d == NULL) {
2182 asginit(a);
2183 } else if (d->n_op == CM) {
2184 int is = con_e(d->n_left);
2185 int ie = con_e(d->n_right);
2186 int i;
2188 nfree(d);
2189 if (ie < is)
2190 uerror("negative initializer range");
2191 desinit(biop(LB, NIL, bcon(is)));
2192 for (i = is; i < ie; i++)
2193 asginit(ccopy(a));
2194 asginit(a);
2195 } else {
2196 cerror("dainit");
2201 * Traverse down and tymerge() where appropriate.
2203 static NODE *
2204 tymfix(NODE *p)
2206 NODE *q;
2207 int o = coptype(p->n_op);
2209 switch (o) {
2210 case LTYPE:
2211 break;
2212 case UTYPE:
2213 p->n_left = tymfix(p->n_left);
2214 break;
2215 case BITYPE:
2216 p->n_left = tymfix(p->n_left);
2217 p->n_right = tymfix(p->n_right);
2218 if (p->n_op == TYMERGE) {
2219 q = tymerge(p->n_left, p->n_right);
2220 q->n_ap = attr_add(q->n_ap, p->n_ap);
2221 tfree(p->n_left);
2222 nfree(p);
2223 p = q;
2225 break;
2227 return p;
2230 static NODE *
2231 aryfix(NODE *p)
2233 NODE *q;
2235 for (q = p; q->n_op != NAME; q = q->n_left) {
2236 if (q->n_op == LB) {
2237 q->n_right = optim(eve(q->n_right));
2238 if ((blevel == 0 || rpole != NULL) &&
2239 !nncon(q->n_right))
2240 uerror("array size not constant");
2242 * Checks according to 6.7.5.2 clause 1:
2243 * "...the expression shall have an integer type."
2244 * "If the expression is a constant expression,
2245 * it shall have a value greater than zero."
2247 if (!ISINTEGER(q->n_right->n_type))
2248 werror("array size is not an integer");
2249 else if (q->n_right->n_op == ICON &&
2250 q->n_right->n_lval < 0 &&
2251 q->n_right->n_lval != NOOFFSET) {
2252 uerror("array size cannot be negative");
2253 q->n_right->n_lval = 1;
2255 } else if (q->n_op == CALL)
2256 q->n_right = namekill(q->n_right, 1);
2258 return p;