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