Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:plunky:20140606131903

Diff

Diff from 1.7 to:

Annotations

Annotate by Age | Author | Mixed | None
/fisheye/browse/pcc/pcc/cc/cxxcom/cgram.y

Annotated File View

plunky
1.7
1 /*      $Id: cgram.y,v 1.7 2014/06/06 13:19:03 plunky Exp $     */
ragge
1.1
2
3 /*
4  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 /*
29  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
30  *
31  * Redistribution and use in source and binary forms, with or without
32  * modification, are permitted provided that the following conditions
33  * are met:
34  *
35  * Redistributions of source code and documentation must retain the above
36  * copyright notice, this list of conditions and the following disclaimer.
37  * Redistributions in binary form must reproduce the above copyright
38  * notice, this list of conditions and the following disclaimer in the
39  * documentation and/or other materials provided with the distribution.
40  * All advertising materials mentioning features or use of this software
41  * must display the following acknowledgement:
42  *      This product includes software developed or owned by Caldera
43  *      International, Inc.
44  * Neither the name of Caldera International, Inc. nor the names of other
45  * contributors may be used to endorse or promote products derived from
46  * this software without specific prior written permission.
47  *
48  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
49  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
50  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
51  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
52  * DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
53  * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56  * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
57  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
58  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
59  * POSSIBILITY OF SUCH DAMAGE.
60  */
61
62 /*
63  * Comments for this grammar file. Ragge 021123
64  *
65  * ANSI support required rewrite of the function header and declaration
66  * rules almost totally.
67  *
68  * The lex/yacc shared keywords are now split from the keywords used
69  * in the rest of the compiler, to simplify use of other frontends.
70  */
71
72 /*
73  * At last count, there were 5 shift/reduce and no reduce/reduce conflicts
74  * Four are accounted for;
75  * One is "dangling else"
76  * Two is in attribute parsing
77  * One is in ({ }) parsing
78  */
79
80 /*
81  * Token used in C lex/yacc communications.
82  */
83 %token  C_STRING        /* a string constant */
84 %token  C_ICON          /* an integer constant */
85 %token  C_FCON          /* a floating point constant */
86 %token  C_NAME          /* an identifier */
87 %token  C_TYPENAME      /* a typedef'd name */
88 %token  C_ANDAND        /* && */
89 %token  C_OROR          /* || */
90 %token  C_GOTO          /* unconditional goto */
91 %token  C_RETURN        /* return from function */
92 %token  C_TYPE          /* a type */
93 %token  C_CLASS         /* a storage class */
94 %token  C_ASOP          /* assignment ops */
95 %token  C_RELOP         /* <=, <, >=, > */
96 %token  C_EQUOP         /* ==, != */
97 %token  C_DIVOP         /* /, % */
98 %token  C_SHIFTOP       /* <<, >> */
99 %token  C_INCOP         /* ++, -- */
100 %token  C_UNOP          /* !, ~ */
101 %token  C_STROP         /* ., -> */
102 %token  C_STRUCT
103 %token  C_IF
104 %token  C_ELSE
105 %token  C_SWITCH
106 %token  C_BREAK
107 %token  C_CONTINUE
108 %token  C_WHILE 
109 %token  C_DO
110 %token  C_FOR
111 %token  C_DEFAULT
112 %token  C_CASE
113 %token  C_SIZEOF
114 %token  C_ALIGNOF
115 %token  C_ENUM
116 %token  C_ELLIPSIS
117 %token  C_QUALIFIER
118 %token  C_FUNSPEC
119 %token  C_ASM
120 %token  NOMATCH
121 %token  C_TYPEOF        /* COMPAT_GCC */
122 %token  C_ATTRIBUTE     /* COMPAT_GCC */
123 %token  PCC_OFFSETOF
124 %token  GCC_DESIG
125 %token  CXX_NAMESPACE
126 %token  CXX_DUALCC
127 %token  CXX_TEMPLATE
128 %token  CXX_USING
129 %token  CXX_TYPENAME
130 %token  CXX_CASTS
131 %token  CXX_THROW
132 %token  CXX_MORENM
133 %token  CXX_NEW
134 %token  CXX_DELETE
135 %token  CXX_CLASS
136
137 /*
138  * Precedence
139  */
140 %left ','
141 %right '=' C_ASOP
142 %right '?' ':'
143 %left C_OROR
144 %left C_ANDAND
145 %left '|'
146 %left '^'
147 %left '&'
148 %left C_EQUOP
149 %left C_RELOP
150 %left C_SHIFTOP
151 %left '+' '-'
152 %left '*' C_DIVOP
153 %right C_UNOP
154 %right C_INCOP C_SIZEOF
155 %left '[' '(' C_STROP
156 %{
157 # include "pass1.h"
158 # include <stdarg.h>
159 # include <string.h>
160 # include <stdlib.h>
161
162 int fun_inline; /* Reading an inline function */
163 int oldstyle;   /* Current function being defined */
164 static struct symtab *xnf;
165 extern int enummer, tvaloff, inattr;
166 extern struct rstack *rpole;
167 static int widestr, alwinl;
168 NODE *cftnod;
169 static int attrwarn = 1;
170
171 #define NORETYP SNOCREAT /* no return type, save in unused field in symtab */
172
173        NODE *bdty(int op, ...);
174 static void fend(struct symtab *);
175 static struct symtab *fundef(NODE *tp, NODE *p);
176 static void olddecl(NODE *p, NODE *a);
177 static struct symtab *init_declarator(NODE *tn, NODE *p, int assign, NODE *a);
178 static void resetbc(int mask);
179 static void swend(void);
180 static void addcase(NODE *p);
181 #ifdef GCC_COMPAT
182 static void gcccase(NODE *p, NODE *);
183 #endif
ragge
1.6
184 static struct attr *gcc_attr_wrapper(NODE *p);
ragge
1.1
185 static void adddef(void);
186 static void savebc(void);
187 static void swstart(int, TWORD);
188 static void genswitch(int, TWORD, struct swents **, int);
189 static char *mkpstr(char *str);
190 static struct symtab *clbrace(NODE *);
191 static NODE *cmop(NODE *l, NODE *r);
192 static NODE *xcmop(NODE *out, NODE *in, NODE *str);
193 static void mkxasm(char *str, NODE *p);
194 static NODE *xasmop(char *str, NODE *p);
195 static int maxstlen(char *str);
196 static char *stradd(char *old, char *new);
197 static NODE *biop(int op, NODE *l, NODE *r);
198 static void flend(void);
199 static char * simname(char *s);
200 static NODE *tyof(NODE *);      /* COMPAT_GCC */
201 static NODE *voidcon(void);     /* COMPAT_GCC */
202 static NODE *funargs(NODE *p);
203 static void oldargs(NODE *p);
204 static void uawarn(NODE *p, char *s);
205 static int con_e(NODE *p);
206 static void dainit(NODE *d, NODE *a);
207 static NODE *tymfix(NODE *p);
208 static NODE *namekill(NODE *p, int clr);
209 static NODE *aryfix(NODE *p);
210
211 #define TYMFIX(inp) { \
212         NODE *pp = inp; \
213         inp = tymerge(pp->n_left, pp->n_right); \
214         nfree(pp->n_left); nfree(pp); }
215 /*
216  * State for saving current switch state (when nested switches).
217  */
218 struct savbc {
219         struct savbc *next;
220         int brklab;
221         int contlab;
222         int flostat;
223         int swx;
224 } *savbc, *savctx;
225
226 %}
227
228 %union {
229         int intval;
230         NODE *nodep;
231         struct symtab *symp;
232         struct rstack *rp;
233         char *strp;
234 }
235
236         /* define types */
237 %start edf
238
239 %type <intval> ifelprefix ifprefix whprefix forprefix doprefix switchpart
240                 xbegin
241 %type <nodep> e .e term enum_dcl struct_dcl cast_type declarator
242                 elist type_sq cf_spec merge_attribs
243                 parameter_declaration abstract_declarator initializer
244                 parameter_type_list parameter_list addrlbl
245                 declaration_specifiers designation
246                 specifier_qualifier_list merge_specifiers
247                 identifier_list arg_param_list type_qualifier_list
248                 designator_list designator xasm oplist oper cnstr 
249                 typeof attribute attribute_specifier /* COMPAT_GCC */
250                 attribute_list attr_spec_list attr_var /* COMPAT_GCC */
251                 new_ma new_type_sq new_ds nmrec
252 %type <strp>    string C_STRING GCC_DESIG nsname CXX_MORENM
253 %type <rp>      str_head
254 %type <symp>    xnfdeclarator clbrace enum_head funtype
255
256 %type <intval>  C_STRUCT C_RELOP C_DIVOP C_SHIFTOP
257                 C_ANDAND C_OROR C_STROP C_INCOP C_UNOP C_ASOP C_EQUOP
258
259 %type <nodep>   C_TYPE C_QUALIFIER C_ICON C_FCON C_CLASS
260 %type <strp>    C_NAME C_TYPENAME
261 %%
262
263 edf:              ext_def_list
264                 | { ftnend(); }
265                 ;
266
267 ext_def_list:     ext_def_list external_def
268                 | external_def
269                 ;
270
271 external_def:      funtype kr_args compoundstmt { fend($1); }
272                 |  declaration  { blevel = 0; symclear(0); }
273                 | namespace
274                 | extlink
275                 | blockdcl
276                 |  ';'
277                 |  error { blevel = 0; }
278                 ;
279
280 funtype:          /* no type given */ declarator {
281                     $$ = fundef(mkty(INT, 0, 0), $1);
282                     cftnsp->sflags |= NORETYP;
283                 }
284                 | declaration_specifiers declarator { $$ = fundef($1,$2); }
285                 ;
286
287 kr_args:          /* empty */
288                 | arg_dcl_list
289                 ;
290
291 blockdcl:         simple_decl
292                 | asmstatement
293                 | ns_alias
294                 | using_x
295                 ;
296
297 using_x:          CXX_USING tnopt ccopt nested_name_sp ';' { werror("using"); }
298                 | CXX_USING CXX_NAMESPACE ccopt nested_name_sp ';' { werror("using2"); }
299                 ;
300
301 tnopt:            CXX_TYPENAME { }
302                 | { }
303                 ;
304
305 ns_alias:         CXX_NAMESPACE C_NAME '=' qual_ns_sp ';' { werror("ns_alias");}
306                 ;
307
308 qual_ns_sp:       ccopt nested_name_sp
309                 ;
310
311 nested_name_sp:   nmtnm
312                 | nmtnm CXX_DUALCC nested_name_sp
313                 | nmtnm CXX_DUALCC CXX_TEMPLATE nested_name_sp
314                 ;
315
316 nmtnm:            C_NAME
317                 | C_TYPENAME
318                 ;
319
320 ccopt:            CXX_DUALCC
321                 | { }
322                 ;
323
324 simple_decl:      ')' NOMATCH { uerror("simple-declaration"); }
325                 ;
326
327 namespace:        CXX_NAMESPACE nsname attr_var nsbeg ns_body '}' { POPSYM(); }
328                 ;
329
330 nsname:           C_NAME
331                 | { $$ = NULL; }
332                 ;
333  
334 ns_body:          ext_def_list
335                 | { }
336                 ;
337
338 nsbeg:            '{' { dclns($<nodep>0, $<strp>-1); }
339                 ;
340
341 extlink:          C_CLASS C_STRING eb '{' ext_def_list '}' { elnk = LINK_DEF; }
342                 | C_CLASS C_STRING eb '{' '}' { elnk = LINK_DEF; }
343                 | C_CLASS C_STRING eb declaration { elnk = LINK_DEF; }
344                 ;
345
346 eb:               {
347                         NODE *p = $<nodep>-1;
348                         char *s = $<strp>0;
349                         if (p->n_type != EXTERN)
350                                 uerror("'extern' expected");
351                         if (strcmp(s, "\"C\"") != 0 && strcmp(s, "\"c\""))
352                                 uerror("unknown linkage %s", s);
353                         nfree(p);
354                         elnk = LINK_C;
355                 }
356                 ;
357 /*
358  * Returns a node pointer or NULL, if no types at all given.
359  * Type trees are checked for correctness and merged into one
360  * type node in typenode().
361  */
362 declaration_specifiers:
363                    merge_attribs { $$ = typenode($1); }
364                 ;
365
366 merge_attribs:     type_sq { $$ = $1; }
367                 |  type_sq merge_attribs { $$ = cmop($2, $1); }
368                 |  cf_spec { $$ = $1; }
369                 |  cf_spec merge_attribs { $$ = cmop($2, $1); }
370                 ;
371
372 type_sq:           C_TYPE { $$ = $1; }
373                 |  C_TYPENAME { 
374                         struct symtab *sp = lookup($1, 0);
375                         if (sp->stype == ENUMTY) {
376                                 sp->stype = strmemb(sp->sap)->stype;
377                         }
378                         $$ = mkty(sp->stype, sp->sdf, sp->sap);
379                         $$->n_sp = sp;
380                 }
381                 |  struct_dcl { $$ = $1; }
382                 |  enum_dcl { $$ = $1; }
383                 |  C_QUALIFIER { $$ = $1; }
384                 |  attribute_specifier { $$ = biop(ATTRIB, $1, 0); }
385                 |  typeof { $$ = $1; }
386                 ;
387
388 cf_spec:           C_CLASS { $$ = $1; }
389                 |  C_FUNSPEC { fun_inline = 1;  /* XXX - hack */
390                         $$ = block(QUALIFIER, NIL, NIL, 0, 0, 0); }
391                 ;
392
393 typeof:            C_TYPEOF '(' e ')' { $$ = tyof(eve($3)); }
394                 |  C_TYPEOF '(' cast_type ')' { TYMFIX($3); $$ = tyof($3); }
395                 ;
396
397 new_ma:            new_type_sq
398                 |  new_type_sq new_ma { $$ = cmop($2, $1); }
399                 |  cf_spec { $$ = $1; }
400                 |  cf_spec new_ma { $$ = cmop($2, $1); }
401                 ;
402
403 new_ds:            new_ma { $$ = typenode($1); }
404                 ;
405
406 new_type_sq:       C_TYPE { $$ = $1; }
407                 |  C_TYPENAME { 
408                         struct symtab *sp = lookup($1, 0);
409                         if (sp->stype == ENUMTY) {
410                                 sp->stype = strmemb(sp->sap)->stype;
411                         }
412                         $$ = mkty(sp->stype, sp->sdf, sp->sap);
413                         $$->n_sp = sp;
414                 }
415                 |  struct_dcl { $$ = $1; }
416                 |  enum_dcl { $$ = $1; }
417                 |  C_QUALIFIER { $$ = $1; }
418                 ;
419
420 attribute_specifier :
421                    C_ATTRIBUTE '(' '(' attribute_list ')' ')' { $$ = $4; }
422  /*COMPAT_GCC*/ ;
423
424 attribute_list:    attribute
425                 |  attribute ',' attribute_list { $$ = cmop($3, $1); }
426                 ;
427
428 attribute:         {
429 #ifdef GCC_COMPAT
430                          $$ = voidcon();
431 #endif
432                 }
433                 |  C_NAME { $$ = bdty(NAME, $1); }
434                 |  C_NAME '(' elist ')' {
435                         $$ = bdty($3 == NIL ? UCALL : CALL, bdty(NAME, $1), $3);
436                 }
437                 ;
438
439 /*
440  * Adds a pointer list to front of the declarators.
441  */
442 declarator:        '*' declarator { $$ = bdty(UMUL, $2); }
443                 |  '*' type_qualifier_list declarator {
444                         $$ = $2;
445                         $$->n_left = $3;
446                 }
447                 |  nmrec C_NAME { $$ = biop(NMLIST, $1, bdty(NAME, $2)); }
448                 |  C_NAME { $$ = bdty(NAME, $1); }
449                 |  '(' attr_spec_list declarator ')' {
450                         $$ = $3;
ragge
1.6
451                         $$->n_ap = attr_add($$->n_ap, gcc_attr_wrapper($2));
ragge
1.1
452                 }
453                 |  '(' declarator ')' { $$ = $2; }
454                 |  declarator '[' e ']' { $$ = biop(LB, $1, $3); }
455                 |  declarator '[' C_CLASS e ']' {
456                         if ($3->n_type != STATIC)
457                                 uerror("bad class keyword");
458                         tfree($3); /* XXX - handle */
459                         $$ = biop(LB, $1, $4);
460                 }
461                 |  declarator '[' ']' { $$ = biop(LB, $1, bcon(NOOFFSET)); }
462                 |  declarator '[' '*' ']' { $$ = biop(LB, $1, bcon(NOOFFSET)); }
463                 |  declarator '(' parameter_type_list ')' {
464                         $$ = bdty(CALL, $1, $3);
465                 }
466                 |  declarator '(' identifier_list ')' {
467                         $$ = bdty(CALL, $1, $3);
468                         oldstyle = 1;
469                 }
470                 |  declarator '(' ')' { $$ = bdty(UCALL, $1); }
471                 ;
472
473 type_qualifier_list:
474                    C_QUALIFIER { $$ = $1; $$->n_op = UMUL; }
475                 |  type_qualifier_list C_QUALIFIER {
476                         $$ = $1;
477                         $$->n_qual |= $2->n_qual;
478                         nfree($2);
479                 }
480                 |  attribute_specifier {
ragge
1.6
481                         $$ = block(UMUL, NIL, NIL, 0, 0, gcc_attr_wrapper($1));
ragge
1.1
482                 }
483                 |  type_qualifier_list attribute_specifier {
ragge
1.6
484                         $1->n_ap = attr_add($1->n_ap, gcc_attr_wrapper($2));
ragge
1.1
485                 }
486                 ;
487
488 identifier_list:   C_NAME { $$ = bdty(NAME, $1); oldargs($$); }
489                 |  identifier_list ',' C_NAME {
490                         $$ = cmop($1, bdty(NAME, $3));
491                         oldargs($$->n_right);
492                 }
493                 ;
494
495 /*
496  * Returns as parameter_list, but can add an additional ELLIPSIS node.
497  */
498 parameter_type_list:
499                    parameter_list { $$ = $1; }
500                 |  parameter_list ',' C_ELLIPSIS {
501                         $$ = cmop($1, biop(ELLIPSIS, NIL, NIL));
502                 }
503                 ;
504
505 /*
506  * Returns a linked lists of nodes of op CM with parameters on
507  * its right and additional CM nodes of its left pointer.
508  * No CM nodes if only one parameter.
509  */
510 parameter_list:    parameter_declaration { $$ = $1; }
511                 |  parameter_declaration '&' { $$ = $1; }
512                 |  parameter_list ',' parameter_declaration {
513                         $$ = cmop($1, $3);
514                 }
515                 ;
516
517 /*
518  * Returns a node pointer to the declaration.
519  */
520 parameter_declaration:
521                    declaration_specifiers declarator attr_var {
522                         if ($1->n_lval != SNULL && $1->n_lval != REGISTER)
523                                 uerror("illegal parameter class");
ragge
1.6
524                         $$ = block(TYMERGE, $1, $2, INT, 0, gcc_attr_wrapper($3));
ragge
1.1
525                 }
526                 |  declaration_specifiers abstract_declarator { 
527                         $$ = block(TYMERGE, $1, $2, INT, 0, 0);
528                 }
529                 |  declaration_specifiers {
530                         $$ = block(TYMERGE, $1, bdty(NAME, NULL), INT, 0, 0);
531                 }
532                 ;
533
534 abstract_declarator:
535                    '*' { $$ = bdty(UMUL, bdty(NAME, NULL)); }
536                 |  '*' type_qualifier_list {
537                         $$ = $2;
538                         $$->n_left = bdty(NAME, NULL);
539                 }
540                 |  '*' abstract_declarator { $$ = bdty(UMUL, $2); }
541                 |  '*' type_qualifier_list abstract_declarator {
542                         $$ = $2;
543                         $$->n_left = $3;
544                 }
545                 |  '(' abstract_declarator ')' { $$ = $2; }
546                 |  '[' ']' attr_var {
547                         $$ = block(LB, bdty(NAME, NULL), bcon(NOOFFSET),
ragge
1.6
548                             INT, 0, gcc_attr_wrapper($3));
ragge
1.1
549                 }
550                 |  '[' e ']' attr_var {
551                         $$ = block(LB, bdty(NAME, NULL), $2,
ragge
1.6
552                             INT, 0, gcc_attr_wrapper($4));
ragge
1.1
553                 }
554                 |  abstract_declarator '[' ']' attr_var {
555                         $$ = block(LB, $1, bcon(NOOFFSET),
ragge
1.6
556                             INT, 0, gcc_attr_wrapper($4));
ragge
1.1
557                 }
558                 |  abstract_declarator '[' e ']' attr_var {
ragge
1.6
559                         $$ = block(LB, $1, $3, INT, 0, gcc_attr_wrapper($5));
ragge
1.1
560                 }
561                 |  '(' ')' { $$ = bdty(UCALL, bdty(NAME, NULL)); }
562                 |  '(' ib2 parameter_type_list ')' {
563                         $$ = bdty(CALL, bdty(NAME, NULL), $3);
564                 }
565                 |  abstract_declarator '(' ')' {
566                         $$ = bdty(UCALL, $1);
567                 }
568                 |  abstract_declarator '(' ib2 parameter_type_list ')' {
569                         $$ = bdty(CALL, $1, $4);
570                 }
571                 ;
572
573 ib2:              { }
574                 ;
575 /*
576  * K&R arg declaration, between ) and {
577  */
578 arg_dcl_list:      arg_declaration
579                 |  arg_dcl_list arg_declaration
580                 ;
581
582
583 arg_declaration:   declaration_specifiers arg_param_list ';' {
584                         nfree($1);
585                 }
586                 ;
587
588 arg_param_list:    declarator attr_var {
589                         olddecl(block(TYMERGE, ccopy($<nodep>0), $1,
590                             INT, 0, 0), $2);
591                 }
592                 |  arg_param_list ',' declarator attr_var {
593                         olddecl(block(TYMERGE, ccopy($<nodep>0), $3,
594                             INT, 0, 0), $4);
595                 }
596                 ;
597
598 /*
599  * Declarations in beginning of blocks.
600  */
601 block_item_list:   block_item
602                 |  block_item_list block_item
603                 ;
604
605 block_item:        declaration
606                 |  statement
607                 ;
608
609 /*
610  * Here starts the old YACC code.
611  */
612
613 /*
614  * Variables are declared in init_declarator.
615  */
616 declaration:       declaration_specifiers ';' { tfree($1); fun_inline = 0; }
617                 |  declaration_specifiers init_declarator_list ';' {
618                         tfree($1);
619                         fun_inline = 0;
620                 }
621                 ;
622
623 /*
624  * Normal declaration of variables. curtype contains the current type node.
625  * Returns nothing, variables are declared in init_declarator.
626  */
627 init_declarator_list:
628                    init_declarator { symclear(blevel); }
629                 |  init_declarator_list ',' attr_var { $<nodep>$ = $<nodep>0; } init_declarator {
630                         uawarn($3, "init_declarator");
631                         symclear(blevel);
632                 }
633                 ;
634
635 enum_dcl:          enum_head '{' moe_list optcomma '}' { $$ = enumdcl($1); }
636                 |  C_ENUM C_NAME {  $$ = enumref($2); }
637                 ;
638
639 enum_head:         C_ENUM { $$ = enumhd(NULL); }
640                 |  C_ENUM C_NAME {  $$ = enumhd($2); }
641                 ;
642
643 moe_list:          moe
644                 |  moe_list ',' moe
645                 ;
646
647 moe:               C_NAME {  moedef($1); }
648                 |  C_TYPENAME {  moedef($1); }
649                 |  C_NAME '=' e { enummer = con_e($3); moedef($1); }
650                 |  C_TYPENAME '=' e { enummer = con_e($3); moedef($1); }
651                 ;
652
653 struct_dcl:        str_head '{' struct_dcl_list '}' {
654                         NODE *p;
655
656                         $$ = dclstruct($1);
657                         if (pragma_allpacked) {
658                                 p = bdty(CALL, bdty(NAME, "packed"),
659                                     bcon(pragma_allpacked));
ragge
1.6
660                                 $$->n_ap = attr_add($$->n_ap,gcc_attr_wrapper(p)); }
ragge
1.1
661                 }
662                 |  C_STRUCT attr_var C_NAME { 
663                         $$ = rstruct($3,$1);
664                         uawarn($2, "struct_dcl");
665                 }
666                 |  C_STRUCT attr_var nmrec C_NAME { 
667                         $$ = cxxrstruct($1,$2,$3,$4);
668                         uawarn($2, "struct_dcl");
669                 }
670  /*COMPAT_GCC*/ |  str_head '{' '}' { $$ = dclstruct($1); }
671                 ;
672
673 attr_var:          {    
674                         NODE *q, *p;
675
676                         p = pragma_aligned ? bdty(CALL, bdty(NAME, "aligned"),
677                             bcon(pragma_aligned)) : NIL;
678                         if (pragma_packed) {
679                                 q = bdty(NAME, "packed");
680                                 p = (p == NIL ? q : cmop(p, q));
681                         }
682                         pragma_aligned = pragma_packed = 0;
683                         $$ = p;
684                 }
685  /*COMPAT_GCC*/ |  attr_spec_list
686                 ;
687
688 attr_spec_list:    attribute_specifier 
689                 |  attr_spec_list attribute_specifier { $$ = cmop($1, $2); }
690                 ;
691
692 str_head:          C_STRUCT attr_var {  $$ = bstruct(NULL, $1, $2);  }
693                 |  C_STRUCT attr_var C_NAME {  $$ = bstruct($3, $1, $2);  }
694                 ;
695
696 struct_dcl_list:   struct_declaration
697                 |  struct_dcl_list struct_declaration
698                 ;
699
700 struct_declaration:
701                    declaration_specifiers struct_declarator_list optsemi {
702                         tfree($1);
703                 }
704                 |  C_NAME ':' { /* cxxaccess($1); */ }
705                 ;
706
707 optsemi:           ';' { }
708                 |  optsemi ';' { werror("extra ; in struct"); }
709                 ;
710
711 specifier_qualifier_list:
712                    merge_specifiers { $$ = typenode($1); }
713                 ;
714
715 merge_specifiers:  type_sq merge_specifiers { $$ = cmop($2, $1); }
716                 |  type_sq { $$ = $1; }
717                 ;
718
719 struct_declarator_list:
720                    struct_declarator { symclear(blevel); }
721                 |  struct_declarator_list ',' { $<nodep>$=$<nodep>0; } 
722                         struct_declarator { symclear(blevel); }
723                 ;
724
725 struct_declarator: declarator attr_var {
726                         NODE *p;
727
728                         $1 = aryfix($1);
729                         p = tymerge($<nodep>0, tymfix($1));
730                         if ($2)
ragge
1.6
731                                 p->n_ap = attr_add(p->n_ap, gcc_attr_wrapper($2));
ragge
1.1
732                         soumemb(p, (char *)$1->n_sp, $<nodep>0->n_lval);
733                         tfree(p);
734                 }
735                 |  ':' e {
736                         int ie = con_e($2);
737                         if (fldchk(ie))
738                                 ie = 1;
739                         falloc(NULL, ie, $<nodep>0);
740                 }
741                 |  declarator ':' e {
742                         int ie = con_e($3);
743                         if (fldchk(ie))
744                                 ie = 1;
745                         if ($1->n_op == NAME) {
746                                 /* XXX - tymfix() may alter $1 */
747                                 tymerge($<nodep>0, tymfix($1));
748                                 soumemb($1, (char *)$1->n_sp, FIELD | ie);
749                                 nfree($1);
750                         } else
751                                 uerror("illegal declarator");
752                 }
753                 |  declarator ':' e attr_spec_list {
754                         int ie = con_e($3);
755                         if (fldchk(ie))
756                                 ie = 1;
757                         if ($1->n_op == NAME) {
758                                 /* XXX - tymfix() may alter $1 */
759                                 tymerge($<nodep>0, tymfix($1));
760                                 if ($4)
761                                         $1->n_ap = attr_add($1->n_ap,
ragge
1.6
762                                             gcc_attr_wrapper($4));
ragge
1.1
763                                 soumemb($1, (char *)$1->n_sp, FIELD | ie);
764                                 nfree($1);
765                         } else
766                                 uerror("illegal declarator");
767                 }
768                 | /* unnamed member */ {
769                         NODE *p = $<nodep>0;
770                         char *c = permalloc(10);
771
772                         if (p->n_type != STRTY && p->n_type != UNIONTY)
773                                 uerror("bad unnamed member type");
774                         snprintf(c, 10, "*%dFAKE", getlab());
775                         soumemb(p, c, 0);
776                 }
777                 ;
778
779                 /* always preceeded by attributes */
780 xnfdeclarator:     declarator attr_var {
781                         $$ = xnf = init_declarator($<nodep>0, $1, 1, $2);
782                 }
783                 |  declarator C_ASM '(' string ')' {
784                         pragma_renamed = newstring($4, strlen($4));
785                         $$ = xnf = init_declarator($<nodep>0, $1, 1, NULL);
786                 }
787                 ;
788
789 /*
790  * Handles declarations and assignments.
791  * Returns nothing.
792  */
793 init_declarator:   declarator attr_var { init_declarator($<nodep>0, $1, 0, $2);}
794                 |  declarator C_ASM '(' string ')' attr_var {
795 #ifdef GCC_COMPAT
796                         pragma_renamed = newstring($4, strlen($4));
797                         init_declarator($<nodep>0, $1, 0, $6);
798 #else
799                         werror("gcc extension");
800                         init_declarator($<nodep>0, $1, 0, $6);
801 #endif
802                 }
803                 |  xnfdeclarator '=' e { 
804                         if ($1->sclass == STATIC || $1->sclass == EXTDEF)
805                                 statinit++;
806                         simpleinit($1, eve($3));
807                         if ($1->sclass == STATIC || $1->sclass == EXTDEF)
808                                 statinit--;
809                         xnf = NULL;
810                 }
811                 |  xnfdeclarator '=' begbr init_list optcomma '}' {
812                         endinit(0);
813                         xnf = NULL;
814                 }
815  /*COMPAT_GCC*/ |  xnfdeclarator '=' begbr '}' { endinit(0); xnf = NULL; }
816                 |  xnfdeclarator '=' addrlbl { simpleinit($1, $3); xnf = NULL; }
817                 ;
818
819 begbr:             '{' { beginit($<symp>-1); }
820                 ;
821
822 initializer:       e %prec ',' {  $$ = eve($1); }
823                 |  addrlbl {  $$ = $1; }
824                 |  ibrace init_list optcomma '}' { $$ = NULL; }
825                 |  ibrace '}' { asginit(bcon(0)); $$ = NULL; }
826                 ;
827
828 init_list:         designation initializer { dainit($1, $2); }
829                 |  init_list ','  designation initializer { dainit($3, $4); }
830                 ;
831
832 designation:       designator_list '=' { desinit($1); $$ = NIL; }
833                 |  GCC_DESIG { desinit(bdty(NAME, $1)); $$ = NIL; }
834                 |  '[' e C_ELLIPSIS e ']' '=' { $$ = biop(CM, $2, $4); }
835                 |  { $$ = NIL; }
836                 ;
837
838 designator_list:   designator { $$ = $1; }
839                 |  designator_list designator { $$ = $2; $$->n_left = $1; }
840                 ;
841
842 designator:        '[' e ']' {
843                         int ie = con_e($2);
844                         if (ie < 0) {
845                                 uerror("designator must be non-negative");
846                                 ie = 0;
847                         }
848                         $$ = biop(LB, NIL, bcon(ie));
849                 }
850                 |  C_STROP C_TYPENAME {
851                         if ($1 != DOT)
852                                 uerror("invalid designator");
853                         $$ = bdty(NAME, $2);
854                 }
855                 |  C_STROP C_NAME {
856                         if ($1 != DOT)
857                                 uerror("invalid designator");
858                         $$ = bdty(NAME, $2);
859                 }
860                 ;
861
862 optcomma        :       /* VOID */
863                 |  ','
864                 ;
865
866 ibrace:            '{' {  ilbrace(); }
867                 ;
868
869 /*      STATEMENTS      */
870
871 compoundstmt:      begin block_item_list '}' { flend(); }
872                 |  begin '}' { flend(); }
873                 ;
874
875 begin:            '{' {
876                         struct savbc *bc = tmpalloc(sizeof(struct savbc));
877                         if (blevel == 1) {
878 #ifdef STABS
879                                 if (gflag)
880                                         stabs_line(lineno);
881 #endif
882                                 dclargs();
883                         }
884 #ifdef STABS
885                         if (gflag && blevel > 1)
886                                 stabs_lbrac(blevel+1);
887 #endif
888                         ++blevel;
889                         oldstyle = 0;
890                         bc->contlab = autooff;
891                         bc->next = savctx;
892                         savctx = bc;
893                         if (!isinlining && sspflag && blevel == 2)
894                                 sspstart();
895                 }
896                 ;
897
898 statement:         e ';' { /* fwalk($1, eprint, 0); */ ecomp(eve($1)); symclear(blevel); }
899                 |  compoundstmt
900                 |  ifprefix statement { plabel($1); reached = 1; }
901                 |  ifelprefix statement {
902                         if ($1 != NOLAB) {
903                                 plabel( $1);
904                                 reached = 1;
905                         }
906                 }
907                 |  whprefix statement {
908                         branch(contlab);
909                         plabel( brklab );
910                         if( (flostat&FBRK) || !(flostat&FLOOP))
911                                 reached = 1;
912                         else
913                                 reached = 0;
914                         resetbc(0);
915                 }
916                 |  doprefix statement C_WHILE '(' e ')' ';' {
917                         plabel(contlab);
918                         if (flostat & FCONT)
919                                 reached = 1;
920                         if (reached)
921                                 cbranch(buildtree(NE, eve($5), bcon(0)),
922                                     bcon($1));
923                         else
924                                 tfree(eve($5));
925                         plabel( brklab);
926                         reached = 1;
927                         resetbc(0);
928                 }
929                 |  forprefix .e ')' statement
930                         {  plabel( contlab );
931                             if( flostat&FCONT ) reached = 1;
932                             if( $2 ) ecomp( $2 );
933                             branch($1);
934                             plabel( brklab );
935                             if( (flostat&FBRK) || !(flostat&FLOOP) ) reached = 1;
936                             else reached = 0;
937                             resetbc(0);
938                             symclear(blevel); /* if declaration inside for() */
939                             }
940                 | switchpart statement
941                         { if( reached ) branch( brklab );
942                             plabel( $1 );
943                             swend();
944                             plabel( brklab);
945                             if( (flostat&FBRK) || !(flostat&FDEF) ) reached = 1;
946                             resetbc(FCONT);
947                             }
948                 |  C_BREAK  ';' {
949                         if (brklab == NOLAB)
950                                 uerror("illegal break");
951                         else if (reached)
952                                 branch(brklab);
953                         flostat |= FBRK;
954                         reached = 0;
955                 }
956                 |  C_CONTINUE  ';' {
957                         if (contlab == NOLAB)
958                                 uerror("illegal continue");
959                         else
960                                 branch(contlab);
961                         flostat |= FCONT;
962                         goto rch;
963                 }
964                 |  C_RETURN  ';' {
965                         branch(retlab);
966                         if (cftnsp->stype != VOID && 
967                             (cftnsp->sflags & NORETYP) == 0 &&
968                             cftnsp->stype != VOID+FTN)
969                                 uerror("return value required");
970                         rch:
971                         if (!reached)
972                                 warner(Wunreachable_code, NULL);
973                         reached = 0;
974                 }
975                 |  C_RETURN e  ';' {
976                         NODE *p, *q;
977
978                         p = nametree(cftnsp);
979                         p->n_type = DECREF(p->n_type);
980                         q = eve($2);
981 #ifndef NO_COMPLEX
982                         if (ANYCX(q) || ANYCX(p))
983                                 q = cxret(q, p);
984 #endif
985                         p = buildtree(RETURN, p, q);
986                         if (p->n_type == VOID) {
987                                 ecomp(p->n_right);
988                         } else {
989                                 if (cftnod == NIL)
990                                         cftnod = tempnode(0, p->n_type,
991                                             p->n_df, p->n_ap);
992                                 ecomp(buildtree(ASSIGN,
993                                     ccopy(cftnod), p->n_right));
994                         }
995                         tfree(p->n_left);
996                         nfree(p);
997                         branch(retlab);
998                         reached = 0;
999                 }
1000                 |  C_GOTO C_NAME ';' { gotolabel($2); goto rch; }
1001                 |  C_GOTO '*' e ';' { ecomp(biop(GOTO, eve($3), NIL)); }
1002                 |  asmstatement ';'
1003                 |   ';'
1004                 |  error  ';'
1005                 |  error '}'
1006                 |  label statement
1007                 ;
1008
1009 asmstatement:      C_ASM mvol '(' string ')' { send_passt(IP_ASM, mkpstr($4)); }
1010                 |  C_ASM mvol '(' string xasm ')' { mkxasm($4, $5); }
1011                 ;
1012
1013 mvol:              /* empty */
1014                 |  C_QUALIFIER { nfree($1); }
1015                 ;
1016
1017 xasm:              ':' oplist { $$ = xcmop($2, NIL, NIL); }
1018                 |  ':' oplist ':' oplist { $$ = xcmop($2, $4, NIL); }
1019                 |  ':' oplist ':' oplist ':' cnstr { $$ = xcmop($2, $4, $6); }
1020                 ;
1021
1022 oplist:            /* nothing */ { $$ = NIL; }
1023                 |  oper { $$ = $1; }
1024                 ;
1025
1026 oper:              string '(' e ')' { $$ = xasmop($1, eve($3)); }
1027                 |  oper ',' string '(' e ')' {
1028                         $$ = cmop($1, xasmop($3, eve($5)));
1029                 }
1030                 ;
1031
1032 cnstr:             string { $$ = xasmop($1, bcon(0)); }
1033                 |  cnstr ',' string { $$ = cmop($1, xasmop($3, bcon(0))); }
1034                 ;
1035
1036 label:             C_NAME ':' attr_var { deflabel($1, $3); reached = 1; }
1037                 |  C_TYPENAME ':' attr_var { deflabel($1, $3); reached = 1; }
1038                 |  C_CASE e ':' { addcase(eve($2)); reached = 1; }
1039 /* COMPAT_GCC */|  C_CASE e C_ELLIPSIS e ':' {
1040 #ifdef GCC_COMPAT
1041                         gcccase(eve($2), eve($4)); reached = 1;
1042 #endif
1043                 }
1044                 |  C_DEFAULT ':' { reached = 1; adddef(); flostat |= FDEF; }
1045                 ;
1046
1047 doprefix:       C_DO {
1048                         savebc();
1049                         brklab = getlab();
1050                         contlab = getlab();
1051                         plabel(  $$ = getlab());
1052                         reached = 1;
1053                 }
1054                 ;
1055 ifprefix:       C_IF '(' e ')' {
1056                         cbranch(buildtree(NOT, eve($3), NIL), bcon($$ = getlab()));
1057                         reached = 1;
1058                 }
1059                 ;
1060 ifelprefix:       ifprefix statement C_ELSE {
1061                         if (reached)
1062                                 branch($$ = getlab());
1063                         else
1064                                 $$ = NOLAB;
1065                         plabel( $1);
1066                         reached = 1;
1067                 }
1068                 ;
1069
1070 whprefix:         C_WHILE  '('  e  ')' {
1071                         savebc();
1072                         $3 = eve($3);
1073                         if ($3->n_op == ICON && $3->n_lval != 0)
1074                                 flostat = FLOOP;
1075                         plabel( contlab = getlab());
1076                         reached = 1;
1077                         brklab = getlab();
1078                         if (flostat == FLOOP)
1079                                 tfree($3);
1080                         else
1081                                 cbranch(buildtree(NOT, $3, NIL), bcon(brklab));
1082                 }
1083                 ;
1084 forprefix:        C_FOR  '('  .e  ';' .e  ';' {
1085                         if ($3)
1086                                 ecomp($3);
1087                         savebc();
1088                         contlab = getlab();
1089                         brklab = getlab();
1090                         plabel( $$ = getlab());
1091                         reached = 1;
1092                         if ($5)
1093                                 cbranch(buildtree(NOT, $5, NIL), bcon(brklab));
1094                         else
1095                                 flostat |= FLOOP;
1096                 }
1097                 |  C_FOR '(' { ++blevel; } declaration .e ';' {
1098                         blevel--;
1099                         savebc();
1100                         contlab = getlab();
1101                         brklab = getlab();
1102                         plabel( $$ = getlab());
1103                         reached = 1;
1104                         if ($5)
1105                                 cbranch(buildtree(NOT, $5, NIL), bcon(brklab));
1106                         else
1107                                 flostat |= FLOOP;
1108                 }
1109                 ;
1110
1111 switchpart:        C_SWITCH  '('  e ')' {
1112                         NODE *p;
1113                         int num;
1114                         TWORD t;
1115
1116                         savebc();
1117                         brklab = getlab();
1118                         $3 = eve($3);
1119                         if (!ISINTEGER($3->n_type)) {
1120                                 uerror("switch expression must have integer "
1121                                        "type");
1122                                 t = INT;
1123                         } else {
1124                                 $3 = intprom($3);
1125                                 t = $3->n_type;
1126                         }
1127                         p = tempnode(0, t, 0, 0);
1128                         num = regno(p);
1129                         ecomp(buildtree(ASSIGN, p, $3));
1130                         branch( $$ = getlab());
1131                         swstart(num, t);
1132                         reached = 0;
1133                 }
1134                 ;
1135 /*      EXPRESSIONS     */
1136 .e:                e { $$ = eve($1); }
1137                 |       { $$=0; }
1138                 ;
1139
1140 elist:             { $$ = NIL; }
1141                 |  e %prec ','
1142                 |  elist  ','  e { $$ = biop(CM, $1, $3); }
1143                 |  elist  ','  cast_type { /* hack for stdarg */
1144                         TYMFIX($3);
1145                         $3->n_op = TYPE;
1146                         $$ = biop(CM, $1, $3);
1147                 }
1148                 ;
1149
1150 /*
1151  * Precedence order of operators.
1152  */
1153 e:                 e ',' e { $$ = biop(COMOP, $1, $3); }
1154                 |  e '=' e { $$ = biop(ASSIGN, $1, $3); }
1155                 |  e C_ASOP e { $$ = biop($2, $1, $3); }
1156                 |  e '?' e ':' e {
1157                         $$=biop(QUEST, $1, biop(COLON, $3, $5));
1158                 }
1159                 |  e '?' ':' e { 
1160                         NODE *p = tempnode(0, $1->n_type, $1->n_df, $1->n_ap);
1161                         $$ = biop(COLON, ccopy(p), $4);
1162                         $$=biop(QUEST, biop(ASSIGN, p, $1), $$);
1163                 }
1164                 |  e C_OROR e { $$ = biop($2, $1, $3); }
1165                 |  e C_ANDAND e { $$ = biop($2, $1, $3); }
1166                 |  e '|' e { $$ = biop(OR, $1, $3); }
1167                 |  e '^' e { $$ = biop(ER, $1, $3); }
1168                 |  e '&' e { $$ = biop(AND, $1, $3); }
1169                 |  e C_EQUOP  e { $$ = biop($2, $1, $3); }
1170                 |  e C_RELOP e { $$ = biop($2, $1, $3); }
1171                 |  e C_SHIFTOP e { $$ = biop($2, $1, $3); }
1172                 |  e '+' e { $$ = biop(PLUS, $1, $3); }
1173                 |  e '-' e { $$ = biop(MINUS, $1, $3); }
1174                 |  e C_DIVOP e { $$ = biop($2, $1, $3); }
1175                 |  e '*' e { $$ = biop(MUL, $1, $3); }
1176                 |  e '=' addrlbl { $$ = biop(ASSIGN, $1, $3); }
1177                 |  term
1178                 ;
1179
1180 xbegin:            begin {
1181                         $$ = getlab(); getlab(); getlab();
1182                         branch($$); plabel(($$)+1); }
1183                 ;
1184
1185 addrlbl:          C_ANDAND C_NAME {
1186 #ifdef GCC_COMPAT
1187                         struct symtab *s = lookup($2, SLBLNAME);
1188                         if (s->soffset == 0)
1189                                 s->soffset = -getlab();
1190                         $$ = buildtree(ADDROF, nametree(s), NIL);
1191 #else
1192                         uerror("gcc extension");
1193 #endif
1194                 }
1195                 ;
1196
1197 term:              term C_INCOP {  $$ = biop($2, $1, bcon(1)); }
1198                 |  '*' term { $$ = biop(UMUL, $2, NIL); }
1199                 |  '&' term { $$ = biop(ADDROF, $2, NIL); }
1200                 |  '-' term { $$ = biop(UMINUS, $2, NIL ); }
1201                 |  '+' term { $$ = biop(PLUS, $2, bcon(0)); }
1202                 |  CXX_CASTS C_RELOP cast_type C_RELOP '(' e ')' {
1203                         tfree($6);
1204                         tfree($3);
1205                         $$ = bcon(0);
1206                         werror("CXX_CASTS unhandled");
1207                 }
1208                 |  C_UNOP term { $$ = biop($1, $2, NIL); }
1209                 |  C_INCOP term {
1210                         $$ = biop($1 == INCR ? PLUSEQ : MINUSEQ, $2, bcon(1));
1211                 }
1212                 |  C_SIZEOF xa term { $$ = biop(SZOF, $3, bcon(0)); inattr = $<intval>2; }
1213                 |  '(' cast_type ')' term  %prec C_INCOP {
1214                         TYMFIX($2);
1215                         $$ = biop(CAST, $2, $4);
1216                 }
1217                 |  C_SIZEOF xa '(' cast_type ')'  %prec C_SIZEOF {
1218                         $$ = biop(SZOF, $4, bcon(1));
1219                         inattr = $<intval>2;
1220                 }
1221                 |  C_ALIGNOF xa '(' cast_type ')' {
1222                         int al;
1223                         TYMFIX($4);
1224                         al = talign($4->n_type, $4->n_ap);
1225                         $$ = bcon(al/SZCHAR);
1226                         inattr = $<intval>2;
1227                         tfree($4);
1228                 }
1229                 | '(' cast_type ')' clbrace init_list optcomma '}' {
1230                         endinit(0);
1231                         $$ = bdty(NAME, $4);
1232                         $$->n_op = CLOP;
1233                 }
1234                 | '(' cast_type ')' clbrace '}' {
1235                         endinit(0);
1236                         $$ = bdty(NAME, $4);
1237                         $$->n_op = CLOP;
1238                 }
1239                 |  term '[' e ']' {
1240                         if ($1->n_op == NEWKW) {
1241                                 $1->n_left = biop(LB, $1->n_left, $3);
1242                         } else
1243                                 $$ = biop(LB, $1, $3);
1244                 }
1245                 |  C_NAME  '(' elist ')' {
1246 #if 0
1247                         if ($3) tfree($3);
1248                         $$ = bcon(0);
1249 #else
1250                         $$ = biop($3 ? CALL : UCALL, bdty(NAME, $1), $3);
1251 #endif
1252                 }
1253                 |  term  '(' elist ')' { $$ = biop($3 ? CALL : UCALL, $1, $3); }
1254                 |  term C_STROP C_NAME { $$ = biop($2, $1, bdty(NAME, $3)); }
1255                 |  term C_STROP C_TYPENAME { $$ = biop($2, $1, bdty(NAME, $3));}
1256                 |  C_NAME %prec C_SIZEOF /* below ( */{ $$ = bdty(NAME, $1); }
1257                 |  nmrec C_NAME %prec C_SIZEOF {
1258                         $$ = biop(NMLIST, $1, bdty(NAME, $2));
1259                 }
1260                 |  PCC_OFFSETOF  '(' cast_type ',' term ')' {
1261                         TYMFIX($3);
1262                         $3->n_type = INCREF($3->n_type);
1263                         $3 = biop(CAST, $3, bcon(0));
1264                         if ($5->n_op == NAME) {
1265                                 $$ = biop(STREF, $3, $5);
1266                         } else {
1267                                 NODE *p = $5;
1268                                 while (p->n_left->n_op != NAME)
1269                                         p = p->n_left;
1270                                 p->n_left = biop(STREF, $3, p->n_left);
1271                                 $$ = $5;
1272                         }
1273                         $$ = biop(ADDROF, $$, NIL);
1274                         $3 = block(NAME, NIL, NIL, ENUNSIGN(INTPTR), 0, 0);
1275                         $$ = biop(CAST, $3, $$);
1276                 }
1277                 |  C_ICON { $$ = $1; }
1278                 |  C_FCON { $$ = $1; }
1279                 |  string { $$ = bdty(STRING, $1, widestr); }
1280                 |   '('  e  ')' { $$=$2; }
1281                 |  '(' xbegin block_item_list e ';' '}' ')' {
1282                         /* XXX - check recursive ({ }) statements */
1283                         branch(($2)+2);
1284                         plabel($2);
1285                         $$ = buildtree(COMOP,
1286                             biop(GOTO, bcon(($2)+1), NIL), eve($4));
1287                         flend();
1288                 }
1289                 |  '(' xbegin block_item_list '}' ')' { 
1290                         /* XXX - check recursive ({ }) statements */
1291                         branch(($2)+2);
1292                         plabel($2);
1293                         $$ = buildtree(COMOP,
1294                             biop(GOTO, bcon(($2)+1), NIL), voidcon());
1295                         flend();
1296                 }
1297                 |  CXX_NEW new_ds { $$ = biop(NEWKW, $2, bcon(0)); }
1298                 |  CXX_NEW '(' cast_type ')' { $$ = 0; uerror("new cast"); }
1299                 |  CXX_DELETE term %prec '-' {
1300                         $$ = biop(DELETE, $2, bcon(NM_DEL));
1301                 }
1302                 |  CXX_DELETE '[' ']' term %prec '-' {
1303                         $$ = biop(DELETE, $4, bcon(NM_DLA));
1304                 }
1305                 ;
1306
1307 nmrec:            CXX_MORENM { $$ = bdty(NAME, $1); }
1308                 | CXX_MORENM nmrec { $$ = biop(NMLIST, $2, bdty(NAME, $1)); }
1309                 ;
1310
1311 xa:               { $<intval>$ = inattr; inattr = 0; }
1312                 ;
1313
1314 clbrace:           '{'  { NODE *q = $<nodep>-1; TYMFIX(q); $$ = clbrace(q); }