1 /* $Id: cgram.y,v 1.319 2011/01/27 18:00:32 ragge Exp $ */
4 * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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
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
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
/* ., -> */
123 %token C_TYPEOF
/* COMPAT_GCC */
124 %token C_ATTRIBUTE
/* COMPAT_GCC */
144 %right C_INCOP C_SIZEOF
145 %left
'[' '(' C_STROP
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
;
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
);
172 static void gcccase
(NODE
*p
, NODE
*);
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
);
190 static NODE
*tyof
(NODE
*); /* COMPAT_GCC */
191 static NODE
*voidcon
(void); /* COMPAT_GCC */
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) { \
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).
230 %type
<intval
> ifelprefix ifprefix whprefix forprefix doprefix switchpart
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
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
257 external_def: funtype kr_args compoundstmt
{ fend
(); }
258 | declaration
{ blevel
= 0; symclear
(0); }
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); }
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; }
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
);
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; }
319 attribute_list: attribute
320 | attribute
',' attribute_list
{ $$
= cmop
($3, $1); }
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
{
342 | C_NAME
{ $$
= bdty
(NAME
, $1); }
343 |
'(' attr_spec_list declarator
')' {
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);
364 | declarator
'(' ')' { $$
= bdty
(UCALL
, $1); }
368 C_QUALIFIER
{ $$
= $1; $$
->n_op
= UMUL
; }
369 | type_qualifier_list C_QUALIFIER
{
371 $$
->n_qual |
= $2->n_qual
;
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.
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
{
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);
428 '*' { $$
= bdty
(UMUL
, bdty
(NAME
, NULL
)); }
429 |
'*' type_qualifier_list
{
431 $$
->n_left
= bdty
(NAME
, NULL
);
433 |
'*' abstract_declarator
{ $$
= bdty
(UMUL
, $2); }
434 |
'*' type_qualifier_list abstract_declarator
{
438 |
'(' abstract_declarator
')' { $$
= $2; }
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);
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
';' {
481 arg_param_list: declarator attr_var
{
482 olddecl
(block
(TYMERGE
, ccopy
($
<nodep
>0), $1,
485 | arg_param_list
',' declarator attr_var
{
486 olddecl
(block
(TYMERGE
, ccopy
($
<nodep
>0), $3,
492 * Declarations in beginning of blocks.
494 block_item_list: block_item
495 | block_item_list block_item
498 block_item: declaration
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
';' {
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");
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); }
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
'}' {
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
{
558 uawarn
($2, "struct_dcl");
560 /*COMPAT_GCC*/ | str_head
'{' '}' { $$
= dclstruct
($1); }
566 p
= pragma_aligned ? bdty
(CALL
, bdty
(NAME
, "aligned"),
567 bcon
(pragma_aligned
)) : NIL
;
569 q
= bdty
(NAME
, "packed");
570 p
= (p
== NIL ? q
: cmop
(p
, q
));
572 pragma_aligned
= pragma_packed
= 0;
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
591 specifier_qualifier_list struct_declarator_list 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
{
618 p
= tymerge
($
<nodep
>0, tymfix
($1));
620 p
->n_ap
= attr_add
(p
->n_ap
, gcc_attr_parse
($2));
621 soumemb
(p
, (char *)$1->n_sp
, 0);
628 falloc
(NULL
, ie
, $
<nodep
>0);
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
);
640 uerror
("illegal declarator");
642 | declarator
':' e attr_spec_list
{
646 if
($1->n_op
== NAME
) {
647 /* XXX - tymfix() may alter $1 */
648 tymerge
($
<nodep
>0, tymfix
($1));
650 $1->n_ap
= attr_add
($1->n_ap
,
652 soumemb
($1, (char *)$1->n_sp
, FIELD | ie
);
655 uerror
("illegal declarator");
657 |
/* unnamed member */ {
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
());
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.
682 init_declarator: declarator attr_var
{ init_declarator
($
<nodep
>0, $1, 0, $2);}
683 | declarator C_ASM
'(' string ')' attr_var
{
685 pragma_renamed
= newstring
($4, strlen
($4));
686 init_declarator
($
<nodep
>0, $1, 0, $6);
688 werror
("gcc extension");
689 init_declarator
($
<nodep
>0, $1, 0, $6);
692 | xnfdeclarator
'=' e
{ simpleinit
($1, eve
($3)); xnf
= NULL
; }
693 | xnfdeclarator
'=' begbr init_list optcomma
'}' {
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); }
719 designator_list: designator
{ $$
= $1; }
720 | designator_list designator
{ $$
= $2; $$
->n_left
= $1; }
723 designator: '[' e
']' {
726 uerror
("designator must be non-negative");
729 $$
= biop
(LB
, NIL
, bcon
(ie
));
731 | C_STROP C_TYPENAME
{
733 uerror
("invalid designator");
738 uerror
("invalid designator");
743 optcomma
: /* VOID */
747 ibrace: '{' { ilbrace
(); }
752 compoundstmt: begin block_item_list
'}' { flend
(); }
753 | begin
'}' { flend
(); }
757 struct savbc
*bc
= tmpalloc
(sizeof
(struct savbc
));
766 if
(gflag
&& blevel
> 1)
767 stabs_lbrac
(blevel
+1);
771 bc
->contlab
= autooff
;
775 if
(!isinlining
&& sspflag
&& blevel
== 2)
780 statement: e
';' { ecomp
(eve
($1)); symclear
(blevel
); }
782 | ifprefix statement
{ plabel
($1); reached
= 1; }
783 | ifelprefix statement
{
789 | whprefix statement
{
792 if
( (flostat
&FBRK
) ||
!(flostat
&FLOOP
))
798 | doprefix statement C_WHILE
'(' e
')' ';' {
803 cbranch
(buildtree
(NE
, eve
($5), bcon
(0)),
811 | forprefix .e
')' statement
813 if
( flostat
&FCONT
) reached
= 1;
814 if
( $2 ) ecomp
( $2 );
817 if
( (flostat
&FBRK
) ||
!(flostat
&FLOOP
) ) reached
= 1;
821 | switchpart statement
822 { if
( reached
) branch
( brklab
);
826 if
( (flostat
&FBRK
) ||
!(flostat
&FDEF
) ) reached
= 1;
831 uerror
("illegal break");
838 if
(contlab
== NOLAB
)
839 uerror
("illegal continue");
847 if
(cftnsp
->stype
!= VOID
&&
848 (cftnsp
->sflags
& NORETYP
) == 0 &&
849 cftnsp
->stype
!= VOID
+FTN
)
850 uerror
("return value required");
853 warner
(Wunreachable_code
, NULL
);
859 p
= nametree
(cftnsp
);
860 p
->n_type
= DECREF
(p
->n_type
);
863 if
(ANYCX
(q
) || ANYCX
(p
))
866 p
= buildtree
(RETURN
, p
, q
);
867 if
(p
->n_type
== VOID
) {
871 cftnod
= tempnode
(0, p
->n_type
,
873 ecomp
(buildtree
(ASSIGN
,
874 ccopy
(cftnod
), p
->n_right
));
881 | C_GOTO C_NAME
';' { gotolabel
($2); goto rch
; }
882 | C_GOTO
'*' e
';' { ecomp
(biop
(GOTO
, eve
($3), NIL
)); }
890 asmstatement: C_ASM mvol
'(' string ')' { send_passt
(IP_ASM
, mkpstr
($4)); }
891 | C_ASM mvol
'(' string xasm
')' { mkxasm
($4, $5); }
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
; }
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
':' {
922 gcccase
(eve
($2), eve
($4)); reached
= 1;
925 | C_DEFAULT
':' { reached
= 1; adddef
(); flostat |
= FDEF
; }
932 plabel
( $$
= getlab
());
936 ifprefix: C_IF
'(' e
')' {
937 cbranch
(buildtree
(NOT
, eve
($3), NIL
), bcon
($$
= getlab
()));
941 ifelprefix: ifprefix statement C_ELSE
{
943 branch
($$
= getlab
());
951 whprefix: C_WHILE
'(' e
')' {
954 if
($3->n_op
== ICON
&& $3->n_lval
!= 0)
956 plabel
( contlab
= getlab
());
959 if
(flostat
== FLOOP
)
962 cbranch
(buildtree
(NOT
, $3, NIL
), bcon
(brklab
));
965 forprefix: C_FOR
'(' .e
';' .e
';' {
971 plabel
( $$
= getlab
());
974 cbranch
(buildtree
(NOT
, $5, NIL
), bcon
(brklab
));
978 | C_FOR
'(' { ++blevel
; } declaration .e
';' {
983 plabel
( $$
= getlab
());
986 cbranch
(buildtree
(NOT
, $5, NIL
), bcon
(brklab
));
992 switchpart: C_SWITCH
'(' e
')' {
1000 if
(($3->n_type
!= BOOL
&& $3->n_type
> ULONGLONG
) ||
1001 $3->n_type
< CHAR
) {
1002 uerror
("switch expression must have integer "
1009 p
= tempnode
(0, t
, 0, MKAP
(t
));
1011 ecomp
(buildtree
(ASSIGN
, p
, $3));
1012 branch
( $$
= getlab
());
1018 .e
: e
{ $$
= eve
($1); }
1022 elist: { $$
= NIL
; }
1024 | elist
',' e
{ $$
= biop
(CM
, $1, $3); }
1025 | elist
',' cast_type
{ /* hack for stdarg */
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); }
1039 $$
=biop
(QUEST
, $1, biop
(COLON
, $3, $5));
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); }
1063 $$
= getlab
(); getlab
(); getlab
();
1064 branch
($$
); plabel
(($$
)+1); }
1067 addrlbl: C_ANDAND C_NAME
{
1069 struct symtab
*s
= lookup
($2, SLBLNAME
);
1070 if
(s
->soffset
== 0)
1071 s
->soffset
= -getlab
();
1072 $$
= buildtree
(ADDROF
, nametree
(s
), NIL
);
1074 uerror
("gcc extension");
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
); }
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
{
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
')' {
1099 int al
= talign
($4->n_type
, $4->n_ap
);
1100 $$
= bcon
(al
/SZCHAR
);
1101 inattr
= $
<intval
>2;
1104 |
'(' cast_type
')' clbrace init_list optcomma
'}' {
1106 $$
= bdty
(NAME
, $4);
1109 |
'(' cast_type
')' clbrace
'}' {
1111 $$
= bdty
(NAME
, $4);
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
')' {
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);
1130 while
(p
->n_left
->n_op
!= NAME
)
1132 p
->n_left
= biop
(STREF
, $3, p
->n_left
);
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 */
1148 $$
= buildtree
(COMOP
,
1149 biop
(GOTO
, bcon
(($2)+1), NIL
), eve
($4));
1152 |
'(' xbegin block_item_list
'}' ')' {
1153 /* XXX - check recursive ({ }) statements */
1156 $$
= buildtree
(COMOP
,
1157 biop
(GOTO
, bcon
(($2)+1), NIL
), voidcon
());
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));
1183 mkty
(TWORD t
, union dimfun
*d
, struct attr
*sue
)
1185 return block
(TYPE
, NIL
, NIL
, t
, d
, sue
);
1196 q
= biop
(op
, NIL
, NIL
);
1201 q
->n_left
= va_arg
(ap
, NODE
*);
1206 q
->n_left
= va_arg
(ap
, NODE
*);
1207 q
->n_right
= va_arg
(ap
, NODE
*);
1211 q
->n_left
= va_arg
(ap
, NODE
*);
1212 if
((val
= va_arg
(ap
, int)) <= 0) {
1213 uerror
("array size must be positive");
1216 q
->n_right
= bcon
(val
);
1220 q
->n_sp
= va_arg
(ap
, struct symtab
*); /* XXX survive tymerge */
1224 q
->n_name
= va_arg
(ap
, char *);
1225 q
->n_lval
= va_arg
(ap
, int);
1239 if
(!isinlining
&& sspflag
&& blevel
== 2)
1242 if
(gflag
&& blevel
> 2)
1243 stabs_rbrac
(blevel
);
1248 symclear
(blevel
); /* Clean ut the symbol table */
1249 if
(autooff
> maxautooff
)
1250 maxautooff
= autooff
;
1251 autooff
= savctx
->contlab
;
1252 savctx
= savctx
->next
;
1258 struct savbc
*bc
= tmpalloc
(sizeof
(struct savbc
));
1260 bc
->brklab
= brklab
;
1261 bc
->contlab
= contlab
;
1262 bc
->flostat
= flostat
;
1271 flostat
= savbc
->flostat |
(flostat
&mask
);
1272 contlab
= savbc
->contlab
;
1273 brklab
= savbc
->brklab
;
1274 savbc
= savbc
->next
;
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 */
1287 * add case to switch
1292 struct swents
**put
, *w
, *sw
= tmpalloc
(sizeof
(struct swents
));
1295 p
= optim
(p
); /* change enum to ints */
1296 if
(p
->n_op
!= ICON || p
->n_sp
!= NULL
) {
1297 uerror
( "non-constant case expression");
1300 if
(swpole
== NULL
) {
1301 uerror
("case not in switch");
1305 if
(DEUNSIGN
(swpole
->type
) != DEUNSIGN
(p
->n_type
)) {
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 "
1311 if
(p
->n_lval
!= val
)
1312 werror
("case expression truncated");
1314 sw
->sval
= p
->n_lval
;
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
;
1323 for
(w
= swpole
->ents
; w
!= NULL
&& w
->sval
< sw
->sval
;
1327 if
(w
!= NULL
&& w
->sval
== sw
->sval
) {
1328 uerror
("duplicate case in switch");
1331 plabel
(sw
->slab
= getlab
());
1339 gcccase
(NODE
*ln
, NODE
*hn
)
1343 l
= icons
(optim
(ln
));
1344 h
= icons
(optim
(hn
));
1347 i
= l
, l
= h
, h
= i
;
1349 for
(i
= l
; i
<= h
; i
++)
1350 addcase
(xbcon
(i
, NULL
, hn
->n_type
));
1355 * add default case to switch
1361 uerror
("default not inside switch");
1362 else if
(swpole
->deflbl
!= 0)
1363 uerror
("duplicate default in switch");
1365 plabel
( swpole
->deflbl
= getlab
());
1369 swstart
(int num
, TWORD type
)
1371 struct swdef
*sw
= tmpalloc
(sizeof
(struct swdef
));
1373 sw
->deflbl
= sw
->nents
= 0;
1382 * end a switch block
1387 struct swents
*sw
, **swp
;
1390 sw
= tmpalloc
(sizeof
(struct swents
));
1391 swp
= tmpalloc
(sizeof
(struct swents
*) * (swpole
->nents
+1));
1393 sw
->slab
= swpole
->deflbl
;
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)
1417 genswitch
(int num
, TWORD type
, struct swents
**p
, int n
)
1422 if
(mygenswitch
(num
, type
, p
, n
))
1425 /* simple switch code */
1426 for
(i
= 1; i
<= n
; ++i
) {
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
));
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
;
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) {
1463 if
(sp
->sflags
& SDYNARRAY
)
1464 uerror
("can't initialize dynamic arrays");
1469 extern NODE
*parlink
;
1471 uerror
("cannot initialise function");
1472 defid
(p
, uclass
(class
));
1475 /* dynamic sized arrays in prototypes */
1476 tfree
(parlink
); /* Free delayed tree */
1485 * Declare old-stype function arguments.
1493 p
->n_sp
= lookup
((char *)p
->n_sp
, 0);/* XXX */
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.
1503 namekill
(NODE
*p
, int clr
)
1508 switch
(coptype
(o
)) {
1514 p
->n_sp
= lookup
((char *)p
->n_sp
, 0);/* XXX */
1519 p
->n_left
= namekill
(p
->n_left
, clr
);
1523 p
->n_left
= namekill
(p
->n_left
, clr
);
1527 p
->n_right
= bcon
(NOOFFSET
);
1529 p
->n_right
= eve
(p
->n_right
);
1530 } else if
(o
== CALL
)
1531 p
->n_right
= namekill
(p
->n_right
, 1);
1533 p
->n_right
= namekill
(p
->n_right
, clr
);
1535 q
= tymerge
(p
->n_left
, p
->n_right
);
1536 q
->n_ap
= attr_add
(q
->n_ap
, p
->n_ap
);
1547 * Declare function arguments.
1552 extern NODE
*arrstk
[10];
1554 if
(p
->n_op
== ELLIPSIS
)
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
;
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");
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
);
1588 * Declare a function.
1591 fundef
(NODE
*tp
, NODE
*p
)
1596 int class
= tp
->n_lval
, oclass
, ctval
;
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.
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");
1613 } else if
(q
->n_op
== CALL
) {
1617 q
->n_right
= listfw
(q
->n_right
, funargs
);
1622 p
= typ
= tymerge
(tp
, p
);
1623 s
= typ
->n_sp
= lookup
((char *)typ
->n_sp
, 0); /* XXX */
1626 if
(class
== STATIC
&& oclass
== EXTERN
)
1627 werror
("%s was first declared extern, then static", s
->sname
);
1630 /* special syntax for inline functions */
1631 if
(! strcmp
(s
->sname
,"main"))
1632 uerror
("cannot inline main()");
1634 s
->sflags |
= SINLINE
;
1636 if
(class
== EXTERN
)
1638 } else if
(class
== EXTERN
)
1639 class
= SNULL
; /* same result */
1644 if
(attr_find
(p
->n_ap
, GCC_ATYP_ALW_INL
)) {
1645 /* Temporary turn on temps to make always_inline work */
1647 if
(xtemps
== 0) alwinl |
= 2;
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
);
1670 cerror
("function level error");
1673 if
(alwinl
& 2) xtemps
= 0;
1679 structref
(NODE
*p
, int f
, char *name
)
1684 p
= buildtree
(ADDROF
, p
, NIL
);
1685 r
= biop
(NAME
, NIL
, NIL
);
1687 r
= buildtree
(STREF
, p
, r
);
1692 olddecl
(NODE
*p
, NODE
*a
)
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
;
1706 if
(ISARY
(s
->stype
)) {
1707 s
->stype
+= (PTR
-ARY
);
1711 attr_add
(s
->sap
, gcc_attr_parse
(a
));
1719 ecomp
(biop
(GOTO
, bcon
(lbl
), NIL
));
1724 * Create a printable string based on an encoded string.
1730 int v
, l
= strlen
(str
)+3; /* \t + \n + \0 */
1732 os
= s
= inlalloc
(l
);
1747 * Estimate the max length a string will have in its internal
1748 * representation based on number of \ characters.
1755 for
(i
= 0; *str
; str
++, i
++)
1756 if
(*str
== '\\' ||
*str
< 32 ||
*str
> 0176)
1762 voct
(char *d
, unsigned int v
)
1764 v
&= (1 << SZCHAR
) - 1;
1766 *d
++ = v
/64 + '0'; v
&= 077;
1767 *d
++ = v
/8 + '0'; v
&= 7;
1774 * Convert a string to internal format. The resulting string may be no
1775 * more than len characters long.
1778 fixstr
(char *d
, char *s
, int len
)
1790 } else if
(*s
< ' ' ||
*s
> 0176) {
1800 * Add "raw" string new to cleaned string old.
1803 stradd
(char *old
, char *new
)
1808 if
(*new
== 'L' && new
[1] == '\"')
1811 new
++; /* remove first " */
1812 new
[strlen
(new
) - 1] = 0;/* remove last " */
1814 len
= strlen
(old
) + maxstlen
(new
) + 1;
1816 strlcpy
(rv
, old
, len
);
1817 fixstr
(rv
+ strlen
(old
), new
, maxstlen
(new
) + 1);
1822 * Fake a symtab entry for compound literals.
1824 static struct symtab
*
1829 sp
= getsymtab
(simname
("cl"), STEMP
);
1830 sp
->stype
= p
->n_type
;
1831 sp
->squal
= p
->n_qual
;
1835 if
(blevel
== 0 && xnf
!= NULL
) {
1836 sp
->sclass
= STATIC
;
1838 sp
->soffset
= getlab
();
1840 sp
->sclass
= blevel ? AUTO
: STATIC
;
1841 if
(!ISARY
(sp
->stype
) || sp
->sdf
->ddim
!= NOOFFSET
) {
1842 sp
->soffset
= NOOFFSET
;
1843 oalloc
(sp
, &autooff
);
1853 int len
= strlen
(s
) + 10 + 1;
1854 char *w
= tmpalloc
(len
);
1856 snprintf
(w
, len
, "%s%d", s
, getlab
());
1861 biop
(int op
, NODE
*l
, NODE
*r
)
1863 return block
(op
, l
, r
, INT
, 0, MKAP
(INT
));
1867 cmop
(NODE
*l
, NODE
*r
)
1869 return biop
(CM
, l
, r
);
1875 return block
(ICON
, NIL
, NIL
, STRTY
, 0, MKAP
(VOID
));
1878 /* Support for extended assembler a' la' gcc style follows below */
1881 xmrg
(NODE
*out
, NODE
*in
)
1885 if
(p
->n_op
== XARG
) {
1888 while
(p
->n_left
->n_op
== CM
)
1890 p
->n_left
= cmop
(out
, p
->n_left
);
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.
1900 xcmop
(NODE
*out
, NODE
*in
, NODE
*str
)
1905 /* D out-list sanity check */
1906 for
(p
= out
; p
->n_op
== CM
; p
= p
->n_left
) {
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 =");
1924 return cmop
(p
, str
);
1928 * Generate a XARG node based on a string and an expression.
1931 xasmop
(char *str
, NODE
*p
)
1934 p
= biop
(XARG
, p
, NIL
);
1935 p
->n_name
= isinlining ? newstring
(str
, strlen
(str
)+1) : str
;
1940 * Generate a XASM node based on a string and an expression.
1943 mkxasm
(char *str
, NODE
*p
)
1947 q
= biop
(XASM
, p
->n_left
, p
->n_right
);
1948 q
->n_name
= isinlining ? newstring
(str
, strlen
(str
)+1) : str
;
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 */
1967 * Traverse an unhandled expression tree bottom-up and call buildtree()
1968 * or equivalent as needed.
1981 sp
= lookup
((char *)p
->n_sp
, 0);
1982 if
(sp
->sflags
& SINLINE
)
1985 if
(sp
->sflags
& SDYNARRAY
)
1986 r
= buildtree
(UMUL
, r
, NIL
);
1988 if
(attr_find
(sp
->sap
, GCC_ATYP_DEPRECATED
))
1989 werror
("`%s' is deprecated", sp
->sname
);
1995 r
= structref
(eve
(p1
), p
->n_op
, (char *)p2
->n_sp
);
2000 p1
= buildtree
(CAST
, p1
, eve
(p2
));
2008 x
= xinline
; xinline
= 0; /* XXX hack */
2009 if
(p2
->n_lval
== 0)
2019 p1
= eve
(p
->n_left
);
2020 r
= buildtree
(UMUL
, buildtree
(PLUS
, p1
, eve
(p2
)), NIL
);
2029 r
= buildtree
(COMPL
, p1
, NIL
);
2035 r
= buildtree
(p
->n_op
, eve
(p
->n_left
), NIL
);
2040 if
(ISFTN
(p
->n_type
)/* || ISARY(p->n_type) */){
2042 werror
( "& before array or function: ignored" );
2045 r
= buildtree
(ADDROF
, r
, NIL
);
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
;
2057 p1
->n_ap
= MKAP
(INT
);
2062 if
(attr_find
(sp
->sap
, GCC_ATYP_DEPRECATED
))
2063 werror
("`%s' is deprecated", sp
->sname
);
2065 r
= doacall
(sp
, nametree
(sp
), p2
);
2067 r
= doacall
(NULL
, eve
(p1
), p2
);
2074 r
= cxelem
(p
->n_op
, p1
);
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
);
2093 r
= buildtree
(p
->n_op
, p1
, p2
);
2124 r
= buildtree
(p
->n_op
, p1
, eve
(p2
));
2128 r
= strend
(p
->n_lval
, p
->n_name
);
2132 if
(p1
->n_op
== GOTO
) {
2133 /* inside ({ }), eve already called */
2134 r
= buildtree
(p
->n_op
, p1
, p2
);
2137 r
= buildtree
(p
->n_op
, p1
, eve
(p2
));
2148 r
= nametree
(p
->n_sp
);
2153 fwalk
(p
, eprint
, 0);
2165 return icons
(eve
(p
));
2169 uawarn
(NODE
*p
, char *s
)
2174 werror
("unhandled %s attribute", s
);
2179 dainit
(NODE
*d
, NODE
*a
)
2183 } else if
(d
->n_op
== CM
) {
2184 int is
= con_e
(d
->n_left
);
2185 int ie
= con_e
(d
->n_right
);
2190 uerror
("negative initializer range");
2191 desinit
(biop
(LB
, NIL
, bcon
(is
)));
2192 for
(i
= is
; i
< ie
; i
++)
2201 * Traverse down and tymerge() where appropriate.
2207 int o
= coptype
(p
->n_op
);
2213 p
->n_left
= tymfix
(p
->n_left
);
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
);
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
) &&
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);