]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/cc/cc.y
Import sources from 2011-03-30 iso image
[plan9front.git] / sys / src / cmd / cc / cc.y
1 %{
2 #include "cc.h"
3 %}
4 %union  {
5         Node*   node;
6         Sym*    sym;
7         Type*   type;
8         struct
9         {
10                 Type*   t;
11                 char    c;
12         } tycl;
13         struct
14         {
15                 Type*   t1;
16                 Type*   t2;
17         } tyty;
18         struct
19         {
20                 char*   s;
21                 long    l;
22         } sval;
23         long    lval;
24         double  dval;
25         vlong   vval;
26 }
27 %type   <sym>   ltag
28 %type   <lval>  gctname gcname cname gname tname
29 %type   <lval>  gctnlist gcnlist zgnlist
30 %type   <type>  tlist sbody complex
31 %type   <tycl>  types
32 %type   <node>  zarglist arglist zcexpr
33 %type   <node>  name block stmnt cexpr expr xuexpr pexpr
34 %type   <node>  zelist elist adecl slist uexpr string lstring
35 %type   <node>  xdecor xdecor2 labels label ulstmnt
36 %type   <node>  adlist edecor tag qual qlist
37 %type   <node>  abdecor abdecor1 abdecor2 abdecor3
38 %type   <node>  zexpr lexpr init ilist forexpr
39
40 %left   ';'
41 %left   ','
42 %right  '=' LPE LME LMLE LDVE LMDE LRSHE LLSHE LANDE LXORE LORE
43 %right  '?' ':'
44 %left   LOROR
45 %left   LANDAND
46 %left   '|'
47 %left   '^'
48 %left   '&'
49 %left   LEQ LNE
50 %left   '<' '>' LLE LGE
51 %left   LLSH LRSH
52 %left   '+' '-'
53 %left   '*' '/' '%'
54 %right  LMM LPP LMG '.' '[' '('
55
56 %token  <sym>   LNAME LTYPE
57 %token  <dval>  LFCONST LDCONST
58 %token  <vval>  LCONST LLCONST LUCONST LULCONST LVLCONST LUVLCONST
59 %token  <sval>  LSTRING LLSTRING
60 %token          LAUTO LBREAK LCASE LCHAR LCONTINUE LDEFAULT LDO
61 %token          LDOUBLE LELSE LEXTERN LFLOAT LFOR LGOTO
62 %token  LIF LINT LLONG LREGISTER LRETURN LSHORT LSIZEOF LUSED
63 %token  LSTATIC LSTRUCT LSWITCH LTYPEDEF LTYPESTR LUNION LUNSIGNED
64 %token  LWHILE LVOID LENUM LSIGNED LCONSTNT LVOLATILE LSET LSIGNOF
65 %token  LRESTRICT LINLINE
66 %%
67 prog:
68 |       prog xdecl
69
70 /*
71  * external declarator
72  */
73 xdecl:
74         zctlist ';'
75         {
76                 dodecl(xdecl, lastclass, lasttype, Z);
77         }
78 |       zctlist xdlist ';'
79 |       zctlist xdecor
80         {
81                 lastdcl = T;
82                 firstarg = S;
83                 dodecl(xdecl, lastclass, lasttype, $2);
84                 if(lastdcl == T || lastdcl->etype != TFUNC) {
85                         diag($2, "not a function");
86                         lastdcl = types[TFUNC];
87                 }
88                 thisfn = lastdcl;
89                 markdcl();
90                 firstdcl = dclstack;
91                 argmark($2, 0);
92         }
93         pdecl
94         {
95                 argmark($2, 1);
96         }
97         block
98         {
99                 Node *n;
100
101                 n = revertdcl();
102                 if(n)
103                         $6 = new(OLIST, n, $6);
104                 if(!debug['a'] && !debug['Z'])
105                         codgen($6, $2);
106         }
107
108 xdlist:
109         xdecor
110         {
111                 dodecl(xdecl, lastclass, lasttype, $1);
112         }
113 |       xdecor
114         {
115                 $1 = dodecl(xdecl, lastclass, lasttype, $1);
116         }
117         '=' init
118         {
119                 doinit($1->sym, $1->type, 0L, $4);
120         }
121 |       xdlist ',' xdlist
122
123 xdecor:
124         xdecor2
125 |       '*' zgnlist xdecor
126         {
127                 $$ = new(OIND, $3, Z);
128                 $$->garb = simpleg($2);
129         }
130
131 xdecor2:
132         tag
133 |       '(' xdecor ')'
134         {
135                 $$ = $2;
136         }
137 |       xdecor2 '(' zarglist ')'
138         {
139                 $$ = new(OFUNC, $1, $3);
140         }
141 |       xdecor2 '[' zexpr ']'
142         {
143                 $$ = new(OARRAY, $1, $3);
144         }
145
146 /*
147  * automatic declarator
148  */
149 adecl:
150         ctlist ';'
151         {
152                 $$ = dodecl(adecl, lastclass, lasttype, Z);
153         }
154 |       ctlist adlist ';'
155         {
156                 $$ = $2;
157         }
158
159 adlist:
160         xdecor
161         {
162                 dodecl(adecl, lastclass, lasttype, $1);
163                 $$ = Z;
164         }
165 |       xdecor
166         {
167                 $1 = dodecl(adecl, lastclass, lasttype, $1);
168         }
169         '=' init
170         {
171                 long w;
172
173                 w = $1->sym->type->width;
174                 $$ = doinit($1->sym, $1->type, 0L, $4);
175                 $$ = contig($1->sym, $$, w);
176         }
177 |       adlist ',' adlist
178         {
179                 $$ = $1;
180                 if($3 != Z) {
181                         $$ = $3;
182                         if($1 != Z)
183                                 $$ = new(OLIST, $1, $3);
184                 }
185         }
186
187 /*
188  * parameter declarator
189  */
190 pdecl:
191 |       pdecl ctlist pdlist ';'
192
193 pdlist:
194         xdecor
195         {
196                 dodecl(pdecl, lastclass, lasttype, $1);
197         }
198 |       pdlist ',' pdlist
199
200 /*
201  * structure element declarator
202  */
203 edecl:
204         tlist
205         {
206                 lasttype = $1;
207         }
208         zedlist ';'
209 |       edecl tlist
210         {
211                 lasttype = $2;
212         }
213         zedlist ';'
214
215 zedlist:                                        /* extension */
216         {
217                 lastfield = 0;
218                 edecl(CXXX, lasttype, S);
219         }
220 |       edlist
221
222 edlist:
223         edecor
224         {
225                 dodecl(edecl, CXXX, lasttype, $1);
226         }
227 |       edlist ',' edlist
228
229 edecor:
230         xdecor
231         {
232                 lastbit = 0;
233                 firstbit = 1;
234         }
235 |       tag ':' lexpr
236         {
237                 $$ = new(OBIT, $1, $3);
238         }
239 |       ':' lexpr
240         {
241                 $$ = new(OBIT, Z, $2);
242         }
243
244 /*
245  * abstract declarator
246  */
247 abdecor:
248         {
249                 $$ = (Z);
250         }
251 |       abdecor1
252
253 abdecor1:
254         '*' zgnlist
255         {
256                 $$ = new(OIND, (Z), Z);
257                 $$->garb = simpleg($2);
258         }
259 |       '*' zgnlist abdecor1
260         {
261                 $$ = new(OIND, $3, Z);
262                 $$->garb = simpleg($2);
263         }
264 |       abdecor2
265
266 abdecor2:
267         abdecor3
268 |       abdecor2 '(' zarglist ')'
269         {
270                 $$ = new(OFUNC, $1, $3);
271         }
272 |       abdecor2 '[' zexpr ']'
273         {
274                 $$ = new(OARRAY, $1, $3);
275         }
276
277 abdecor3:
278         '(' ')'
279         {
280                 $$ = new(OFUNC, (Z), Z);
281         }
282 |       '[' zexpr ']'
283         {
284                 $$ = new(OARRAY, (Z), $2);
285         }
286 |       '(' abdecor1 ')'
287         {
288                 $$ = $2;
289         }
290
291 init:
292         expr
293 |       '{' ilist '}'
294         {
295                 $$ = new(OINIT, invert($2), Z);
296         }
297
298 qual:
299         '[' lexpr ']'
300         {
301                 $$ = new(OARRAY, $2, Z);
302         }
303 |       '.' ltag
304         {
305                 $$ = new(OELEM, Z, Z);
306                 $$->sym = $2;
307         }
308 |       qual '='
309
310 qlist:
311         init ','
312 |       qlist init ','
313         {
314                 $$ = new(OLIST, $1, $2);
315         }
316 |       qual
317 |       qlist qual
318         {
319                 $$ = new(OLIST, $1, $2);
320         }
321
322 ilist:
323         qlist
324 |       init
325 |       qlist init
326         {
327                 $$ = new(OLIST, $1, $2);
328         }
329
330 zarglist:
331         {
332                 $$ = Z;
333         }
334 |       arglist
335         {
336                 $$ = invert($1);
337         }
338
339
340 arglist:
341         name
342 |       tlist abdecor
343         {
344                 $$ = new(OPROTO, $2, Z);
345                 $$->type = $1;
346         }
347 |       tlist xdecor
348         {
349                 $$ = new(OPROTO, $2, Z);
350                 $$->type = $1;
351         }
352 |       '.' '.' '.'
353         {
354                 $$ = new(ODOTDOT, Z, Z);
355         }
356 |       arglist ',' arglist
357         {
358                 $$ = new(OLIST, $1, $3);
359         }
360
361 block:
362         '{' slist '}'
363         {
364                 $$ = invert($2);
365         //      if($2 != Z)
366         //              $$ = new(OLIST, $2, $$);
367                 if($$ == Z)
368                         $$ = new(OLIST, Z, Z);
369         }
370
371 slist:
372         {
373                 $$ = Z;
374         }
375 |       slist adecl
376         {
377                 $$ = new(OLIST, $1, $2);
378         }
379 |       slist stmnt
380         {
381                 $$ = new(OLIST, $1, $2);
382         }
383
384 labels:
385         label
386 |       labels label
387         {
388                 $$ = new(OLIST, $1, $2);
389         }
390
391 label:
392         LCASE expr ':'
393         {
394                 $$ = new(OCASE, $2, Z);
395         }
396 |       LDEFAULT ':'
397         {
398                 $$ = new(OCASE, Z, Z);
399         }
400 |       LNAME ':'
401         {
402                 $$ = new(OLABEL, dcllabel($1, 1), Z);
403         }
404
405 stmnt:
406         error ';'
407         {
408                 $$ = Z;
409         }
410 |       ulstmnt
411 |       labels ulstmnt
412         {
413                 $$ = new(OLIST, $1, $2);
414         }
415
416 forexpr:
417         zcexpr
418 |       ctlist adlist
419         {
420                 $$ = $2;
421         }
422
423 ulstmnt:
424         zcexpr ';'
425 |       {
426                 markdcl();
427         }
428         block
429         {
430                 $$ = revertdcl();
431                 if($$)
432                         $$ = new(OLIST, $$, $2);
433                 else
434                         $$ = $2;
435         }
436 |       LIF '(' cexpr ')' stmnt
437         {
438                 $$ = new(OIF, $3, new(OLIST, $5, Z));
439                 if($5 == Z)
440                         warn($3, "empty if body");
441         }
442 |       LIF '(' cexpr ')' stmnt LELSE stmnt
443         {
444                 $$ = new(OIF, $3, new(OLIST, $5, $7));
445                 if($5 == Z)
446                         warn($3, "empty if body");
447                 if($7 == Z)
448                         warn($3, "empty else body");
449         }
450 |       { markdcl(); } LFOR '(' forexpr ';' zcexpr ';' zcexpr ')' stmnt
451         {
452                 $$ = revertdcl();
453                 if($$){
454                         if($4)
455                                 $4 = new(OLIST, $$, $4);
456                         else
457                                 $4 = $$;
458                 }
459                 $$ = new(OFOR, new(OLIST, $6, new(OLIST, $4, $8)), $10);
460         }
461 |       LWHILE '(' cexpr ')' stmnt
462         {
463                 $$ = new(OWHILE, $3, $5);
464         }
465 |       LDO stmnt LWHILE '(' cexpr ')' ';'
466         {
467                 $$ = new(ODWHILE, $5, $2);
468         }
469 |       LRETURN zcexpr ';'
470         {
471                 $$ = new(ORETURN, $2, Z);
472                 $$->type = thisfn->link;
473         }
474 |       LSWITCH '(' cexpr ')' stmnt
475         {
476                 $$ = new(OCONST, Z, Z);
477                 $$->vconst = 0;
478                 $$->type = types[TINT];
479                 $3 = new(OSUB, $$, $3);
480
481                 $$ = new(OCONST, Z, Z);
482                 $$->vconst = 0;
483                 $$->type = types[TINT];
484                 $3 = new(OSUB, $$, $3);
485
486                 $$ = new(OSWITCH, $3, $5);
487         }
488 |       LBREAK ';'
489         {
490                 $$ = new(OBREAK, Z, Z);
491         }
492 |       LCONTINUE ';'
493         {
494                 $$ = new(OCONTINUE, Z, Z);
495         }
496 |       LGOTO ltag ';'
497         {
498                 $$ = new(OGOTO, dcllabel($2, 0), Z);
499         }
500 |       LUSED '(' zelist ')' ';'
501         {
502                 $$ = new(OUSED, $3, Z);
503         }
504 |       LSET '(' zelist ')' ';'
505         {
506                 $$ = new(OSET, $3, Z);
507         }
508
509 zcexpr:
510         {
511                 $$ = Z;
512         }
513 |       cexpr
514
515 zexpr:
516         {
517                 $$ = Z;
518         }
519 |       lexpr
520
521 lexpr:
522         expr
523         {
524                 $$ = new(OCAST, $1, Z);
525                 $$->type = types[TLONG];
526         }
527
528 cexpr:
529         expr
530 |       cexpr ',' cexpr
531         {
532                 $$ = new(OCOMMA, $1, $3);
533         }
534
535 expr:
536         xuexpr
537 |       expr '*' expr
538         {
539                 $$ = new(OMUL, $1, $3);
540         }
541 |       expr '/' expr
542         {
543                 $$ = new(ODIV, $1, $3);
544         }
545 |       expr '%' expr
546         {
547                 $$ = new(OMOD, $1, $3);
548         }
549 |       expr '+' expr
550         {
551                 $$ = new(OADD, $1, $3);
552         }
553 |       expr '-' expr
554         {
555                 $$ = new(OSUB, $1, $3);
556         }
557 |       expr LRSH expr
558         {
559                 $$ = new(OASHR, $1, $3);
560         }
561 |       expr LLSH expr
562         {
563                 $$ = new(OASHL, $1, $3);
564         }
565 |       expr '<' expr
566         {
567                 $$ = new(OLT, $1, $3);
568         }
569 |       expr '>' expr
570         {
571                 $$ = new(OGT, $1, $3);
572         }
573 |       expr LLE expr
574         {
575                 $$ = new(OLE, $1, $3);
576         }
577 |       expr LGE expr
578         {
579                 $$ = new(OGE, $1, $3);
580         }
581 |       expr LEQ expr
582         {
583                 $$ = new(OEQ, $1, $3);
584         }
585 |       expr LNE expr
586         {
587                 $$ = new(ONE, $1, $3);
588         }
589 |       expr '&' expr
590         {
591                 $$ = new(OAND, $1, $3);
592         }
593 |       expr '^' expr
594         {
595                 $$ = new(OXOR, $1, $3);
596         }
597 |       expr '|' expr
598         {
599                 $$ = new(OOR, $1, $3);
600         }
601 |       expr LANDAND expr
602         {
603                 $$ = new(OANDAND, $1, $3);
604         }
605 |       expr LOROR expr
606         {
607                 $$ = new(OOROR, $1, $3);
608         }
609 |       expr '?' cexpr ':' expr
610         {
611                 $$ = new(OCOND, $1, new(OLIST, $3, $5));
612         }
613 |       expr '=' expr
614         {
615                 $$ = new(OAS, $1, $3);
616         }
617 |       expr LPE expr
618         {
619                 $$ = new(OASADD, $1, $3);
620         }
621 |       expr LME expr
622         {
623                 $$ = new(OASSUB, $1, $3);
624         }
625 |       expr LMLE expr
626         {
627                 $$ = new(OASMUL, $1, $3);
628         }
629 |       expr LDVE expr
630         {
631                 $$ = new(OASDIV, $1, $3);
632         }
633 |       expr LMDE expr
634         {
635                 $$ = new(OASMOD, $1, $3);
636         }
637 |       expr LLSHE expr
638         {
639                 $$ = new(OASASHL, $1, $3);
640         }
641 |       expr LRSHE expr
642         {
643                 $$ = new(OASASHR, $1, $3);
644         }
645 |       expr LANDE expr
646         {
647                 $$ = new(OASAND, $1, $3);
648         }
649 |       expr LXORE expr
650         {
651                 $$ = new(OASXOR, $1, $3);
652         }
653 |       expr LORE expr
654         {
655                 $$ = new(OASOR, $1, $3);
656         }
657
658 xuexpr:
659         uexpr
660 |       '(' tlist abdecor ')' xuexpr
661         {
662                 $$ = new(OCAST, $5, Z);
663                 dodecl(NODECL, CXXX, $2, $3);
664                 $$->type = lastdcl;
665                 $$->xcast = 1;
666         }
667 |       '(' tlist abdecor ')' '{' ilist '}'     /* extension */
668         {
669                 $$ = new(OSTRUCT, $6, Z);
670                 dodecl(NODECL, CXXX, $2, $3);
671                 $$->type = lastdcl;
672         }
673
674 uexpr:
675         pexpr
676 |       '*' xuexpr
677         {
678                 $$ = new(OIND, $2, Z);
679         }
680 |       '&' xuexpr
681         {
682                 $$ = new(OADDR, $2, Z);
683         }
684 |       '+' xuexpr
685         {
686                 $$ = new(OPOS, $2, Z);
687         }
688 |       '-' xuexpr
689         {
690                 $$ = new(ONEG, $2, Z);
691         }
692 |       '!' xuexpr
693         {
694                 $$ = new(ONOT, $2, Z);
695         }
696 |       '~' xuexpr
697         {
698                 $$ = new(OCOM, $2, Z);
699         }
700 |       LPP xuexpr
701         {
702                 $$ = new(OPREINC, $2, Z);
703         }
704 |       LMM xuexpr
705         {
706                 $$ = new(OPREDEC, $2, Z);
707         }
708 |       LSIZEOF uexpr
709         {
710                 $$ = new(OSIZE, $2, Z);
711         }
712 |       LSIGNOF uexpr
713         {
714                 $$ = new(OSIGN, $2, Z);
715         }
716
717 pexpr:
718         '(' cexpr ')'
719         {
720                 $$ = $2;
721         }
722 |       LSIZEOF '(' tlist abdecor ')'
723         {
724                 $$ = new(OSIZE, Z, Z);
725                 dodecl(NODECL, CXXX, $3, $4);
726                 $$->type = lastdcl;
727         }
728 |       LSIGNOF '(' tlist abdecor ')'
729         {
730                 $$ = new(OSIGN, Z, Z);
731                 dodecl(NODECL, CXXX, $3, $4);
732                 $$->type = lastdcl;
733         }
734 |       pexpr '(' zelist ')'
735         {
736                 $$ = new(OFUNC, $1, Z);
737                 if($1->op == ONAME)
738                 if($1->type == T)
739                         dodecl(xdecl, CXXX, types[TINT], $$);
740                 $$->right = invert($3);
741         }
742 |       pexpr '[' cexpr ']'
743         {
744                 $$ = new(OIND, new(OADD, $1, $3), Z);
745         }
746 |       pexpr LMG ltag
747         {
748                 $$ = new(ODOT, new(OIND, $1, Z), Z);
749                 $$->sym = $3;
750         }
751 |       pexpr '.' ltag
752         {
753                 $$ = new(ODOT, $1, Z);
754                 $$->sym = $3;
755         }
756 |       pexpr LPP
757         {
758                 $$ = new(OPOSTINC, $1, Z);
759         }
760 |       pexpr LMM
761         {
762                 $$ = new(OPOSTDEC, $1, Z);
763         }
764 |       name
765 |       LCONST
766         {
767                 $$ = new(OCONST, Z, Z);
768                 $$->type = types[TINT];
769                 $$->vconst = $1;
770                 $$->cstring = strdup(symb);
771         }
772 |       LLCONST
773         {
774                 $$ = new(OCONST, Z, Z);
775                 $$->type = types[TLONG];
776                 $$->vconst = $1;
777                 $$->cstring = strdup(symb);
778         }
779 |       LUCONST
780         {
781                 $$ = new(OCONST, Z, Z);
782                 $$->type = types[TUINT];
783                 $$->vconst = $1;
784                 $$->cstring = strdup(symb);
785         }
786 |       LULCONST
787         {
788                 $$ = new(OCONST, Z, Z);
789                 $$->type = types[TULONG];
790                 $$->vconst = $1;
791                 $$->cstring = strdup(symb);
792         }
793 |       LDCONST
794         {
795                 $$ = new(OCONST, Z, Z);
796                 $$->type = types[TDOUBLE];
797                 $$->fconst = $1;
798                 $$->cstring = strdup(symb);
799         }
800 |       LFCONST
801         {
802                 $$ = new(OCONST, Z, Z);
803                 $$->type = types[TFLOAT];
804                 $$->fconst = $1;
805                 $$->cstring = strdup(symb);
806         }
807 |       LVLCONST
808         {
809                 $$ = new(OCONST, Z, Z);
810                 $$->type = types[TVLONG];
811                 $$->vconst = $1;
812                 $$->cstring = strdup(symb);
813         }
814 |       LUVLCONST
815         {
816                 $$ = new(OCONST, Z, Z);
817                 $$->type = types[TUVLONG];
818                 $$->vconst = $1;
819                 $$->cstring = strdup(symb);
820         }
821 |       string
822 |       lstring
823
824 string:
825         LSTRING
826         {
827                 $$ = new(OSTRING, Z, Z);
828                 $$->type = typ(TARRAY, types[TCHAR]);
829                 $$->type->width = $1.l + 1;
830                 $$->cstring = $1.s;
831                 $$->sym = symstring;
832                 $$->etype = TARRAY;
833                 $$->class = CSTATIC;
834         }
835 |       string LSTRING
836         {
837                 char *s;
838                 int n;
839
840                 n = $1->type->width - 1;
841                 s = alloc(n+$2.l+MAXALIGN);
842
843                 memcpy(s, $1->cstring, n);
844                 memcpy(s+n, $2.s, $2.l);
845                 s[n+$2.l] = 0;
846
847                 $$ = $1;
848                 $$->type->width += $2.l;
849                 $$->cstring = s;
850         }
851
852 lstring:
853         LLSTRING
854         {
855                 $$ = new(OLSTRING, Z, Z);
856                 $$->type = typ(TARRAY, types[TUSHORT]);
857                 $$->type->width = $1.l + sizeof(ushort);
858                 $$->rstring = (ushort*)$1.s;
859                 $$->sym = symstring;
860                 $$->etype = TARRAY;
861                 $$->class = CSTATIC;
862         }
863 |       lstring LLSTRING
864         {
865                 char *s;
866                 int n;
867
868                 n = $1->type->width - sizeof(ushort);
869                 s = alloc(n+$2.l+MAXALIGN);
870
871                 memcpy(s, $1->rstring, n);
872                 memcpy(s+n, $2.s, $2.l);
873                 *(ushort*)(s+n+$2.l) = 0;
874
875                 $$ = $1;
876                 $$->type->width += $2.l;
877                 $$->rstring = (ushort*)s;
878         }
879
880 zelist:
881         {
882                 $$ = Z;
883         }
884 |       elist
885
886 elist:
887         expr
888 |       elist ',' elist
889         {
890                 $$ = new(OLIST, $1, $3);
891         }
892
893 sbody:
894         '{'
895         {
896                 $<tyty>$.t1 = strf;
897                 $<tyty>$.t2 = strl;
898                 strf = T;
899                 strl = T;
900                 lastbit = 0;
901                 firstbit = 1;
902         }
903         edecl '}'
904         {
905                 $$ = strf;
906                 strf = $<tyty>2.t1;
907                 strl = $<tyty>2.t2;
908         }
909
910 zctlist:
911         {
912                 lastclass = CXXX;
913                 lasttype = types[TINT];
914         }
915 |       ctlist
916
917 types:
918         complex
919         {
920                 $$.t = $1;
921                 $$.c = CXXX;
922         }
923 |       tname
924         {
925                 $$.t = simplet($1);
926                 $$.c = CXXX;
927         }
928 |       gcnlist
929         {
930                 $$.t = simplet($1);
931                 $$.c = simplec($1);
932                 $$.t = garbt($$.t, $1);
933         }
934 |       complex gctnlist
935         {
936                 $$.t = $1;
937                 $$.c = simplec($2);
938                 $$.t = garbt($$.t, $2);
939                 if($2 & ~BCLASS & ~BGARB)
940                         diag(Z, "duplicate types given: %T and %Q", $1, $2);
941         }
942 |       tname gctnlist
943         {
944                 $$.t = simplet(typebitor($1, $2));
945                 $$.c = simplec($2);
946                 $$.t = garbt($$.t, $2);
947         }
948 |       gcnlist complex zgnlist
949         {
950                 $$.t = $2;
951                 $$.c = simplec($1);
952                 $$.t = garbt($$.t, $1|$3);
953         }
954 |       gcnlist tname
955         {
956                 $$.t = simplet($2);
957                 $$.c = simplec($1);
958                 $$.t = garbt($$.t, $1);
959         }
960 |       gcnlist tname gctnlist
961         {
962                 $$.t = simplet(typebitor($2, $3));
963                 $$.c = simplec($1|$3);
964                 $$.t = garbt($$.t, $1|$3);
965         }
966
967 tlist:
968         types
969         {
970                 $$ = $1.t;
971                 if($1.c != CXXX)
972                         diag(Z, "illegal combination of class 4: %s", cnames[$1.c]);
973         }
974
975 ctlist:
976         types
977         {
978                 lasttype = $1.t;
979                 lastclass = $1.c;
980         }
981
982 complex:
983         LSTRUCT ltag
984         {
985                 dotag($2, TSTRUCT, 0);
986                 $$ = $2->suetag;
987         }
988 |       LSTRUCT ltag
989         {
990                 dotag($2, TSTRUCT, autobn);
991         }
992         sbody
993         {
994                 $$ = $2->suetag;
995                 if($$->link != T)
996                         diag(Z, "redeclare tag: %s", $2->name);
997                 $$->link = $4;
998                 suallign($$);
999         }
1000 |       LSTRUCT sbody
1001         {
1002                 taggen++;
1003                 sprint(symb, "_%d_", taggen);
1004                 $$ = dotag(lookup(), TSTRUCT, autobn);
1005                 $$->link = $2;
1006                 suallign($$);
1007         }
1008 |       LUNION ltag
1009         {
1010                 dotag($2, TUNION, 0);
1011                 $$ = $2->suetag;
1012         }
1013 |       LUNION ltag
1014         {
1015                 dotag($2, TUNION, autobn);
1016         }
1017         sbody
1018         {
1019                 $$ = $2->suetag;
1020                 if($$->link != T)
1021                         diag(Z, "redeclare tag: %s", $2->name);
1022                 $$->link = $4;
1023                 suallign($$);
1024         }
1025 |       LUNION sbody
1026         {
1027                 taggen++;
1028                 sprint(symb, "_%d_", taggen);
1029                 $$ = dotag(lookup(), TUNION, autobn);
1030                 $$->link = $2;
1031                 suallign($$);
1032         }
1033 |       LENUM ltag
1034         {
1035                 dotag($2, TENUM, 0);
1036                 $$ = $2->suetag;
1037                 if($$->link == T)
1038                         $$->link = types[TINT];
1039                 $$ = $$->link;
1040         }
1041 |       LENUM ltag
1042         {
1043                 dotag($2, TENUM, autobn);
1044         }
1045         '{'
1046         {
1047                 en.tenum = T;
1048                 en.cenum = T;
1049         }
1050         enum '}'
1051         {
1052                 $$ = $2->suetag;
1053                 if($$->link != T)
1054                         diag(Z, "redeclare tag: %s", $2->name);
1055                 if(en.tenum == T) {
1056                         diag(Z, "enum type ambiguous: %s", $2->name);
1057                         en.tenum = types[TINT];
1058                 }
1059                 $$->link = en.tenum;
1060                 $$ = en.tenum;
1061         }
1062 |       LENUM '{'
1063         {
1064                 en.tenum = T;
1065                 en.cenum = T;
1066         }
1067         enum '}'
1068         {
1069                 $$ = en.tenum;
1070         }
1071 |       LTYPE
1072         {
1073                 $$ = tcopy($1->type);
1074         }
1075
1076 gctnlist:
1077         gctname
1078 |       gctnlist gctname
1079         {
1080                 $$ = typebitor($1, $2);
1081         }
1082
1083 zgnlist:
1084         {
1085                 $$ = 0;
1086         }
1087 |       zgnlist gname
1088         {
1089                 $$ = typebitor($1, $2);
1090         }
1091
1092 gctname:
1093         tname
1094 |       gname
1095 |       cname
1096
1097 gcnlist:
1098         gcname
1099 |       gcnlist gcname
1100         {
1101                 $$ = typebitor($1, $2);
1102         }
1103
1104 gcname:
1105         gname
1106 |       cname
1107
1108 enum:
1109         LNAME
1110         {
1111                 doenum($1, Z);
1112         }
1113 |       LNAME '=' expr
1114         {
1115                 doenum($1, $3);
1116         }
1117 |       enum ','
1118 |       enum ',' enum
1119
1120 tname:  /* type words */
1121         LCHAR { $$ = BCHAR; }
1122 |       LSHORT { $$ = BSHORT; }
1123 |       LINT { $$ = BINT; }
1124 |       LLONG { $$ = BLONG; }
1125 |       LSIGNED { $$ = BSIGNED; }
1126 |       LUNSIGNED { $$ = BUNSIGNED; }
1127 |       LFLOAT { $$ = BFLOAT; }
1128 |       LDOUBLE { $$ = BDOUBLE; }
1129 |       LVOID { $$ = BVOID; }
1130
1131 cname:  /* class words */
1132         LAUTO { $$ = BAUTO; }
1133 |       LSTATIC { $$ = BSTATIC; }
1134 |       LEXTERN { $$ = BEXTERN; }
1135 |       LTYPEDEF { $$ = BTYPEDEF; }
1136 |       LTYPESTR { $$ = BTYPESTR; }
1137 |       LREGISTER { $$ = BREGISTER; }
1138 |       LINLINE { $$ = 0; }
1139
1140 gname:  /* garbage words */
1141         LCONSTNT { $$ = BCONSTNT; }
1142 |       LVOLATILE { $$ = BVOLATILE; }
1143 |       LRESTRICT { $$ = 0; }
1144
1145 name:
1146         LNAME
1147         {
1148                 $$ = new(ONAME, Z, Z);
1149                 if($1->class == CLOCAL)
1150                         $1 = mkstatic($1);
1151                 $$->sym = $1;
1152                 $$->type = $1->type;
1153                 $$->etype = TVOID;
1154                 if($$->type != T)
1155                         $$->etype = $$->type->etype;
1156                 $$->xoffset = $1->offset;
1157                 $$->class = $1->class;
1158                 $1->aused = 1;
1159         }
1160 tag:
1161         ltag
1162         {
1163                 $$ = new(ONAME, Z, Z);
1164                 $$->sym = $1;
1165                 $$->type = $1->type;
1166                 $$->etype = TVOID;
1167                 if($$->type != T)
1168                         $$->etype = $$->type->etype;
1169                 $$->xoffset = $1->offset;
1170                 $$->class = $1->class;
1171         }
1172 ltag:
1173         LNAME
1174 |       LTYPE
1175 %%