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(TRune); 860 $$->rstring = (TRune*)$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(TRune); 871 s = alloc(n+$2.l+MAXALIGN); 872 873 memcpy(s, $1->rstring, n); 874 memcpy(s+n, $2.s, $2.l); 875 *(TRune*)(s+n+$2.l) = 0; 876 877 $$ = $1; 878 $$->type->width += $2.l; 879 $$->rstring = (TRune*)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 snprint(symb, sizeof 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 snprint(symb, sizeof 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 %% 1184