changelog shortlog tags branches changeset files revisions annotate raw help

Mercurial > hg > plan9front / sys/src/cmd/cc/cc.y

changeset 6843: 7db92ee68f7e
parent: 80d018033b9d
author: 23hiro@gmail.com
date: Thu, 25 Oct 2018 08:09:10 +0200
permissions: -rw-r--r--
description: add Centrino Wireless-N 1030 (thanks lksmk from brazil)
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 %%