1 #include "cc.h" 2 3 Node* 4 dodecl(void (*f)(int,Type*,Sym*), int c, Type *t, Node *n) 5 { 6 Sym *s; 7 Node *n1; 8 long v; 9 10 nearln = lineno; 11 lastfield = 0; 12 13 loop: 14 if(n != Z) 15 switch(n->op) { 16 default: 17 diag(n, "unknown declarator: %O", n->op); 18 break; 19 20 case OARRAY: 21 t = typ(TARRAY, t); 22 t->width = 0; 23 n1 = n->right; 24 n = n->left; 25 if(n1 != Z) { 26 complex(n1); 27 v = -1; 28 if(n1->op == OCONST) 29 v = n1->vconst; 30 if(v <= 0) { 31 diag(n, "array size must be a positive constant"); 32 v = 1; 33 } 34 t->width = v * t->link->width; 35 } 36 goto loop; 37 38 case OIND: 39 t = typ(TIND, t); 40 t->garb = n->garb; 41 n = n->left; 42 goto loop; 43 44 case OFUNC: 45 t = typ(TFUNC, t); 46 t->down = fnproto(n); 47 n = n->left; 48 goto loop; 49 50 case OBIT: 51 n1 = n->right; 52 complex(n1); 53 lastfield = -1; 54 if(n1->op == OCONST) 55 lastfield = n1->vconst; 56 if(lastfield < 0) { 57 diag(n, "field width must be non-negative constant"); 58 lastfield = 1; 59 } 60 if(lastfield == 0) { 61 lastbit = 0; 62 firstbit = 1; 63 if(n->left != Z) { 64 diag(n, "zero width named field"); 65 lastfield = 1; 66 } 67 } 68 if(!typei[t->etype]) { 69 diag(n, "field type must be int-like"); 70 t = types[TINT]; 71 lastfield = 1; 72 } 73 if(lastfield > tfield->width*8) { 74 diag(n, "field width larger than field unit"); 75 lastfield = 1; 76 } 77 lastbit += lastfield; 78 if(lastbit > tfield->width*8) { 79 lastbit = lastfield; 80 firstbit = 1; 81 } 82 n = n->left; 83 goto loop; 84 85 case ONAME: 86 if(f == NODECL) 87 break; 88 s = n->sym; 89 (*f)(c, t, s); 90 if(s->class == CLOCAL) 91 s = mkstatic(s); 92 firstbit = 0; 93 n->sym = s; 94 n->type = s->type; 95 n->xoffset = s->offset; 96 n->class = s->class; 97 n->etype = TVOID; 98 if(n->type != T) 99 n->etype = n->type->etype; 100 if(debug['d']) 101 dbgdecl(s); 102 acidvar(s); 103 s->varlineno = lineno; 104 break; 105 } 106 lastdcl = t; 107 return n; 108 } 109 110 Sym* 111 mkstatic(Sym *s) 112 { 113 Sym *s1; 114 115 if(s->class != CLOCAL) 116 return s; 117 snprint(symb, NSYMB, "%s$%d", s->name, s->block); 118 s1 = lookup(); 119 if(s1->class != CSTATIC) { 120 s1->type = s->type; 121 s1->offset = s->offset; 122 s1->block = s->block; 123 s1->class = CSTATIC; 124 } 125 return s1; 126 } 127 128 /* 129 * make a copy of a typedef 130 * the problem is to split out incomplete 131 * arrays so that it is in the variable 132 * rather than the typedef. 133 */ 134 Type* 135 tcopy(Type *t) 136 { 137 Type *tl, *tx; 138 int et; 139 140 if(t == T) 141 return t; 142 et = t->etype; 143 if(typesu[et]) 144 return t; 145 tl = tcopy(t->link); 146 if(tl != t->link || 147 (et == TARRAY && t->width == 0)) { 148 tx = copytyp(t); 149 tx->link = tl; 150 return tx; 151 } 152 return t; 153 } 154 155 Node* 156 doinit(Sym *s, Type *t, long o, Node *a) 157 { 158 Node *n; 159 160 if(t == T) 161 return Z; 162 if(s->class == CEXTERN) { 163 s->class = CGLOBL; 164 if(debug['d']) 165 dbgdecl(s); 166 } 167 if(debug['i']) { 168 print("t = %T; o = %ld; n = %s\n", t, o, s->name); 169 prtree(a, "doinit value"); 170 } 171 172 173 n = initlist; 174 if(a->op == OINIT) 175 a = a->left; 176 initlist = a; 177 178 a = init1(s, t, o, 0); 179 if(initlist != Z) 180 diag(initlist, "more initializers than structure: %s", 181 s->name); 182 initlist = n; 183 184 return a; 185 } 186 187 /* 188 * get next major operator, 189 * dont advance initlist. 190 */ 191 Node* 192 peekinit(void) 193 { 194 Node *a; 195 196 a = initlist; 197 198 loop: 199 if(a == Z) 200 return a; 201 if(a->op == OLIST) { 202 a = a->left; 203 goto loop; 204 } 205 return a; 206 } 207 208 /* 209 * consume and return next element on 210 * initlist. expand strings. 211 */ 212 Node* 213 nextinit(void) 214 { 215 Node *a, *b, *n; 216 217 a = initlist; 218 n = Z; 219 220 if(a == Z) 221 return a; 222 if(a->op == OLIST) { 223 n = a->right; 224 a = a->left; 225 } 226 if(a->op == OUSED) { 227 a = a->left; 228 b = new(OCONST, Z, Z); 229 b->type = a->type->link; 230 if(a->op == OSTRING) { 231 b->vconst = convvtox(*a->cstring, TCHAR); 232 a->cstring++; 233 } 234 if(a->op == OLSTRING) { 235 b->vconst = convvtox(*a->rstring, TRUNE); 236 a->rstring++; 237 } 238 a->type->width -= b->type->width; 239 if(a->type->width <= 0) 240 initlist = n; 241 return b; 242 } 243 initlist = n; 244 return a; 245 } 246 247 int 248 isstruct(Node *a, Type *t) 249 { 250 Node *n; 251 252 switch(a->op) { 253 case ODOTDOT: 254 n = a->left; 255 if(n && n->type && sametype(n->type, t)) 256 return 1; 257 case OSTRING: 258 case OLSTRING: 259 case OCONST: 260 case OINIT: 261 case OELEM: 262 return 0; 263 } 264 265 n = new(ODOTDOT, Z, Z); 266 *n = *a; 267 268 /* 269 * ODOTDOT is a flag for tcom 270 * a second tcom will not be performed 271 */ 272 a->op = ODOTDOT; 273 a->left = n; 274 a->right = Z; 275 276 if(tcom(n)) 277 return 0; 278 279 if(sametype(n->type, t)) 280 return 1; 281 return 0; 282 } 283 284 Node* 285 init1(Sym *s, Type *t, long o, int exflag) 286 { 287 Node *a, *l, *r, nod; 288 Type *t1; 289 long e, w, so, mw; 290 291 a = peekinit(); 292 if(a == Z) 293 return Z; 294 295 if(debug['i']) { 296 print("t = %T; o = %ld; n = %s\n", t, o, s->name); 297 prtree(a, "init1 value"); 298 } 299 300 if(exflag && a->op == OINIT) 301 return doinit(s, t, o, nextinit()); 302 303 switch(t->etype) { 304 default: 305 diag(Z, "unknown type in initialization: %T to: %s", t, s->name); 306 return Z; 307 308 case TCHAR: 309 case TUCHAR: 310 case TINT: 311 case TUINT: 312 case TSHORT: 313 case TUSHORT: 314 case TLONG: 315 case TULONG: 316 case TVLONG: 317 case TUVLONG: 318 case TFLOAT: 319 case TDOUBLE: 320 case TIND: 321 single: 322 if(a->op == OARRAY || a->op == OELEM) 323 return Z; 324 325 a = nextinit(); 326 if(a == Z) 327 return Z; 328 329 if(t->nbits) 330 diag(Z, "cannot initialize bitfields"); 331 if(s->class == CAUTO) { 332 l = new(ONAME, Z, Z); 333 l->sym = s; 334 l->type = t; 335 l->etype = TVOID; 336 if(s->type) 337 l->etype = s->type->etype; 338 l->xoffset = s->offset + o; 339 l->class = s->class; 340 341 l = new(OASI, l, a); 342 return l; 343 } 344 345 complex(a); 346 if(a->type == T) 347 return Z; 348 349 if(a->op == OCONST) { 350 if(vconst(a) && t->etype == TIND && a->type && a->type->etype != TIND){ 351 diag(a, "initialize pointer to an integer: %s", s->name); 352 return Z; 353 } 354 if(!sametype(a->type, t)) { 355 /* hoop jumping to save malloc */ 356 if(nodcast == Z) 357 nodcast = new(OCAST, Z, Z); 358 nod = *nodcast; 359 nod.left = a; 360 nod.type = t; 361 nod.lineno = a->lineno; 362 complex(&nod); 363 if(nod.type) 364 *a = nod; 365 } 366 if(a->op != OCONST) { 367 diag(a, "initializer is not a constant: %s", 368 s->name); 369 return Z; 370 } 371 if(vconst(a) == 0) 372 return Z; 373 goto gext; 374 } 375 if(t->etype == TIND) { 376 while(a->op == OCAST) { 377 warn(a, "CAST in initialization ignored"); 378 a = a->left; 379 } 380 if(!sametype(t, a->type)) { 381 diag(a, "initialization of incompatible pointers: %s\n%T and %T", 382 s->name, t, a->type); 383 } 384 if(a->op == OADDR) 385 a = a->left; 386 goto gext; 387 } 388 389 while(a->op == OCAST) 390 a = a->left; 391 if(a->op == OADDR) { 392 warn(a, "initialize pointer to an integer: %s", s->name); 393 a = a->left; 394 goto gext; 395 } 396 diag(a, "initializer is not a constant: %s", s->name); 397 return Z; 398 399 gext: 400 gextern(s, a, o, t->width); 401 402 return Z; 403 404 case TARRAY: 405 w = t->link->width; 406 if(a->op == OSTRING || a->op == OLSTRING) 407 if(typei[t->link->etype]) { 408 /* 409 * get rid of null if sizes match exactly 410 */ 411 a = nextinit(); 412 mw = t->width/w; 413 so = a->type->width/a->type->link->width; 414 if(mw && so > mw) { 415 if(so != mw+1) 416 diag(a, "string initialization larger than array"); 417 a->type->width -= a->type->link->width; 418 } 419 420 /* 421 * arrange strings to be expanded 422 * inside OINIT braces. 423 */ 424 a = new(OUSED, a, Z); 425 return doinit(s, t, o, a); 426 } 427 428 mw = -w; 429 l = Z; 430 for(e=0;;) { 431 /* 432 * peek ahead for element initializer 433 */ 434 a = peekinit(); 435 if(a == Z) 436 break; 437 if(a->op == OELEM && t->link->etype != TSTRUCT) 438 break; 439 if(a->op == OARRAY) { 440 if(e && exflag) 441 break; 442 a = nextinit(); 443 r = a->left; 444 complex(r); 445 if(r->op != OCONST) { 446 diag(r, "initializer subscript must be constant"); 447 return Z; 448 } 449 e = r->vconst; 450 if(t->width != 0) 451 if(e < 0 || e*w >= t->width) { 452 diag(a, "initialization index out of range: %ld", e); 453 continue; 454 } 455 } 456 457 so = e*w; 458 if(so > mw) 459 mw = so; 460 if(t->width != 0) 461 if(mw >= t->width) 462 break; 463 r = init1(s, t->link, o+so, 1); 464 l = newlist(l, r); 465 e++; 466 } 467 if(t->width == 0) 468 t->width = mw+w; 469 return l; 470 471 case TUNION: 472 case TSTRUCT: 473 /* 474 * peek ahead to find type of rhs. 475 * if its a structure, then treat 476 * this element as a variable 477 * rather than an aggregate. 478 */ 479 if(isstruct(a, t)) 480 goto single; 481 482 if(t->width <= 0) { 483 diag(Z, "incomplete structure: %s", s->name); 484 return Z; 485 } 486 l = Z; 487 488 again: 489 for(t1 = t->link; t1 != T; t1 = t1->down) { 490 if(a->op == OARRAY && t1->etype != TARRAY) 491 break; 492 if(a->op == OELEM) { 493 if(t1->sym != a->sym) 494 continue; 495 nextinit(); 496 } 497 r = init1(s, t1, o+t1->offset, 1); 498 l = newlist(l, r); 499 a = peekinit(); 500 if(a == Z) 501 break; 502 if(a->op == OELEM) 503 goto again; 504 } 505 if(a && a->op == OELEM) 506 diag(a, "structure element not found %F", a); 507 return l; 508 } 509 } 510 511 Node* 512 newlist(Node *l, Node *r) 513 { 514 if(r == Z) 515 return l; 516 if(l == Z) 517 return r; 518 return new(OLIST, l, r); 519 } 520 521 void 522 sualign(Type *t) 523 { 524 Type *l; 525 long o, w; 526 527 o = 0; 528 switch(t->etype) { 529 530 case TSTRUCT: 531 t->offset = 0; 532 w = 0; 533 for(l = t->link; l != T; l = l->down) { 534 if(l->nbits) { 535 if(l->shift <= 0) { 536 l->shift = -l->shift; 537 w = round(w, tfield->width); 538 o = w; 539 w += tfield->width; 540 } 541 l->offset = o; 542 } else { 543 if(l->width < 0 || 544 l->width == 0 && l->down != T) 545 if(l->sym) 546 diag(Z, "incomplete structure element: %s", 547 l->sym->name); 548 else 549 diag(Z, "incomplete structure element"); 550 w = align(w, l, Ael1); 551 l->offset = w; 552 w = align(w, l, Ael2); 553 } 554 } 555 w = align(w, t, Asu2); 556 t->width = w; 557 acidtype(t); 558 pickletype(t); 559 return; 560 561 case TUNION: 562 t->offset = 0; 563 w = 0; 564 for(l = t->link; l != T; l = l->down) { 565 if(l->width <= 0) 566 if(l->sym) 567 diag(Z, "incomplete union element: %s", 568 l->sym->name); 569 else 570 diag(Z, "incomplete union element"); 571 l->offset = 0; 572 l->shift = 0; 573 o = align(align(0, l, Ael1), l, Ael2); 574 if(o > w) 575 w = o; 576 } 577 w = align(w, t, Asu2); 578 t->width = w; 579 acidtype(t); 580 pickletype(t); 581 return; 582 583 default: 584 diag(Z, "unknown type in sualign: %T", t); 585 break; 586 } 587 } 588 589 long 590 round(long v, int w) 591 { 592 int r; 593 594 if(w <= 0 || w > 8) { 595 diag(Z, "rounding by %d", w); 596 w = 1; 597 } 598 r = v%w; 599 if(r) 600 v += w-r; 601 return v; 602 } 603 604 Type* 605 ofnproto(Node *n) 606 { 607 Type *tl, *tr, *t; 608 609 if(n == Z) 610 return T; 611 switch(n->op) { 612 case OLIST: 613 tl = ofnproto(n->left); 614 tr = ofnproto(n->right); 615 if(tl == T) 616 return tr; 617 tl->down = tr; 618 return tl; 619 620 case ONAME: 621 t = copytyp(n->sym->type); 622 t->down = T; 623 return t; 624 } 625 return T; 626 } 627 628 #define ANSIPROTO 1 629 #define OLDPROTO 2 630 631 void 632 argmark(Node *n, int pass) 633 { 634 Type *t; 635 636 autoffset = align(0, thisfn->link, Aarg0); 637 stkoff = 0; 638 for(; n->left != Z; n = n->left) { 639 if(n->op != OFUNC || n->left->op != ONAME) 640 continue; 641 walkparam(n->right, pass); 642 if(pass != 0 && anyproto(n->right) == OLDPROTO) { 643 t = typ(TFUNC, n->left->sym->type->link); 644 t->down = typ(TOLD, T); 645 t->down->down = ofnproto(n->right); 646 tmerge(t, n->left->sym); 647 n->left->sym->type = t; 648 } 649 break; 650 } 651 autoffset = 0; 652 stkoff = 0; 653 } 654 655 void 656 walkparam(Node *n, int pass) 657 { 658 Sym *s; 659 Node *n1; 660 661 if(n != Z && n->op == OPROTO && n->left == Z && n->type == types[TVOID]) 662 return; 663 664 loop: 665 if(n == Z) 666 return; 667 switch(n->op) { 668 default: 669 diag(n, "argument not a name/prototype: %O", n->op); 670 break; 671 672 case OLIST: 673 walkparam(n->left, pass); 674 n = n->right; 675 goto loop; 676 677 case OPROTO: 678 for(n1 = n; n1 != Z; n1=n1->left) 679 if(n1->op == ONAME) { 680 if(pass == 0) { 681 s = n1->sym; 682 push1(s); 683 s->offset = -1; 684 break; 685 } 686 dodecl(pdecl, CPARAM, n->type, n->left); 687 break; 688 } 689 if(n1) 690 break; 691 if(pass == 0) { 692 /* 693 * extension: 694 * allow no name in argument declaration 695 diag(Z, "no name in argument declaration"); 696 */ 697 break; 698 } 699 dodecl(NODECL, CPARAM, n->type, n->left); 700 pdecl(CPARAM, lastdcl, S); 701 break; 702 703 case ODOTDOT: 704 break; 705 706 case ONAME: 707 s = n->sym; 708 if(pass == 0) { 709 push1(s); 710 s->offset = -1; 711 break; 712 } 713 if(s->offset != -1) { 714 if(autoffset == 0) { 715 firstarg = s; 716 firstargtype = s->type; 717 } 718 autoffset = align(autoffset, s->type, Aarg1); 719 s->offset = autoffset; 720 autoffset = align(autoffset, s->type, Aarg2); 721 } else 722 dodecl(pdecl, CXXX, types[TINT], n); 723 break; 724 } 725 } 726 727 void 728 markdcl(void) 729 { 730 Decl *d; 731 732 blockno++; 733 d = push(); 734 d->val = DMARK; 735 d->offset = autoffset; 736 d->block = autobn; 737 autobn = blockno; 738 } 739 740 Node* 741 revertdcl(void) 742 { 743 Decl *d; 744 Sym *s; 745 Node *n, *n1; 746 747 n = Z; 748 for(;;) { 749 d = dclstack; 750 if(d == D) { 751 diag(Z, "pop off dcl stack"); 752 break; 753 } 754 dclstack = d->link; 755 s = d->sym; 756 switch(d->val) { 757 case DMARK: 758 autoffset = d->offset; 759 autobn = d->block; 760 return n; 761 762 case DAUTO: 763 if(debug['d']) 764 print("revert1 \"%s\"\n", s->name); 765 if(s->aused == 0) { 766 nearln = s->varlineno; 767 if(s->class == CAUTO) 768 warn(Z, "auto declared and not used: %s", s->name); 769 if(s->class == CPARAM) 770 warn(Z, "param declared and not used: %s", s->name); 771 } 772 if(s->type && (s->type->garb & GVOLATILE)) { 773 n1 = new(ONAME, Z, Z); 774 n1->sym = s; 775 n1->type = s->type; 776 n1->etype = TVOID; 777 if(n1->type != T) 778 n1->etype = n1->type->etype; 779 n1->xoffset = s->offset; 780 n1->class = s->class; 781 782 n1 = new(OADDR, n1, Z); 783 n1 = new(OUSED, n1, Z); 784 if(n == Z) 785 n = n1; 786 else 787 n = new(OLIST, n1, n); 788 } 789 s->type = d->type; 790 s->class = d->class; 791 s->offset = d->offset; 792 s->block = d->block; 793 s->varlineno = d->varlineno; 794 s->aused = d->aused; 795 break; 796 797 case DSUE: 798 if(debug['d']) 799 print("revert2 \"%s\"\n", s->name); 800 s->suetag = d->type; 801 s->sueblock = d->block; 802 break; 803 804 case DLABEL: 805 if(debug['d']) 806 print("revert3 \"%s\"\n", s->name); 807 if(s->label && s->label->addable == 0) 808 warn(s->label, "label declared and not used \"%s\"", s->name); 809 s->label = Z; 810 break; 811 } 812 } 813 return n; 814 } 815 816 Type* 817 fnproto(Node *n) 818 { 819 int r; 820 821 r = anyproto(n->right); 822 if(r == 0 || (r & OLDPROTO)) { 823 if(r & ANSIPROTO) 824 diag(n, "mixed ansi/old function declaration: %F", n->left); 825 return T; 826 } 827 return fnproto1(n->right); 828 } 829 830 int 831 anyproto(Node *n) 832 { 833 int r; 834 835 r = 0; 836 837 loop: 838 if(n == Z) 839 return r; 840 switch(n->op) { 841 case OLIST: 842 r |= anyproto(n->left); 843 n = n->right; 844 goto loop; 845 846 case ODOTDOT: 847 case OPROTO: 848 return r | ANSIPROTO; 849 } 850 return r | OLDPROTO; 851 } 852 853 Type* 854 fnproto1(Node *n) 855 { 856 Type *t; 857 858 if(n == Z) 859 return T; 860 switch(n->op) { 861 case OLIST: 862 t = fnproto1(n->left); 863 if(t != T) 864 t->down = fnproto1(n->right); 865 return t; 866 867 case OPROTO: 868 lastdcl = T; 869 dodecl(NODECL, CXXX, n->type, n->left); 870 t = typ(TXXX, T); 871 if(lastdcl != T) 872 *t = *paramconv(lastdcl, 1, 0); 873 return t; 874 875 case ONAME: 876 diag(n, "incomplete argument prototype"); 877 return typ(TINT, T); 878 879 case ODOTDOT: 880 return typ(TDOT, T); 881 } 882 diag(n, "unknown op in fnproto"); 883 return T; 884 } 885 886 void 887 dbgdecl(Sym *s) 888 { 889 print("decl \"%s\": C=%s [B=%d:O=%ld] T=%T\n", 890 s->name, cnames[s->class], s->block, s->offset, s->type); 891 } 892 893 Decl* 894 push(void) 895 { 896 Decl *d; 897 898 d = alloc(sizeof(*d)); 899 d->link = dclstack; 900 dclstack = d; 901 return d; 902 } 903 904 Decl* 905 push1(Sym *s) 906 { 907 Decl *d; 908 909 d = push(); 910 d->sym = s; 911 d->val = DAUTO; 912 d->type = s->type; 913 d->class = s->class; 914 d->offset = s->offset; 915 d->block = s->block; 916 d->varlineno = s->varlineno; 917 d->aused = s->aused; 918 return d; 919 } 920 921 int 922 sametype(Type *t1, Type *t2) 923 { 924 925 if(t1 == t2) 926 return 1; 927 return rsametype(t1, t2, 5, 1); 928 } 929 930 int 931 rsametype(Type *t1, Type *t2, int n, int f) 932 { 933 int et; 934 935 n--; 936 for(;;) { 937 if(t1 == t2) 938 return 1; 939 if(t1 == T || t2 == T) 940 return 0; 941 if(n <= 0) 942 return 1; 943 et = t1->etype; 944 if(et != t2->etype) 945 return 0; 946 if(et == TFUNC) { 947 if(!rsametype(t1->link, t2->link, n, 0)) 948 return 0; 949 t1 = t1->down; 950 t2 = t2->down; 951 while(t1 != T && t2 != T) { 952 if(t1->etype == TOLD) { 953 t1 = t1->down; 954 continue; 955 } 956 if(t2->etype == TOLD) { 957 t2 = t2->down; 958 continue; 959 } 960 while(t1 != T || t2 != T) { 961 if(!rsametype(t1, t2, n, 0)) 962 return 0; 963 t1 = t1->down; 964 t2 = t2->down; 965 } 966 break; 967 } 968 return 1; 969 } 970 if(et == TARRAY) 971 if(t1->width != t2->width && t1->width != 0 && t2->width != 0) 972 return 0; 973 if(typesu[et]) { 974 if(t1->link == T) 975 snap(t1); 976 if(t2->link == T) 977 snap(t2); 978 if(t1 != t2 && t1->link == T && t2->link == T){ 979 /* structs with missing or different tag names aren't considered equal */ 980 if(t1->tag == nil || t2->tag == nil || 981 strcmp(t1->tag->name, t2->tag->name) != 0) 982 return 0; 983 } 984 t1 = t1->link; 985 t2 = t2->link; 986 for(;;) { 987 if(t1 == t2) 988 return 1; 989 if(!rsametype(t1, t2, n, 0)) 990 return 0; 991 t1 = t1->down; 992 t2 = t2->down; 993 } 994 } 995 t1 = t1->link; 996 t2 = t2->link; 997 if((f || !debug['V']) && et == TIND) { 998 if(t1 != T && t1->etype == TVOID) 999 return 1; 1000 if(t2 != T && t2->etype == TVOID) 1001 return 1; 1002 } 1003 } 1004 } 1005 1006 typedef struct Typetab Typetab; 1007 1008 struct Typetab{ 1009 int n; 1010 Type **a; 1011 }; 1012 1013 static int 1014 sigind(Type *t, Typetab *tt) 1015 { 1016 int n; 1017 Type **a, **na, **p, **e; 1018 1019 n = tt->n; 1020 a = tt->a; 1021 e = a+n; 1022 /* linear search seems ok */ 1023 for(p = a ; p < e; p++) 1024 if(sametype(*p, t)) 1025 return p-a; 1026 if((n&15) == 0){ 1027 na = malloc((n+16)*sizeof(Type*)); 1028 memmove(na, a, n*sizeof(Type*)); 1029 free(a); 1030 a = tt->a = na; 1031 } 1032 a[tt->n++] = t; 1033 return -1; 1034 } 1035 1036 static ulong 1037 signat(Type *t, Typetab *tt) 1038 { 1039 int i; 1040 Type *t1; 1041 long s; 1042 1043 s = 0; 1044 for(; t; t=t->link) { 1045 s = s*thash1 + thash[t->etype]; 1046 if(t->garb&GINCOMPLETE) 1047 return s; 1048 switch(t->etype) { 1049 default: 1050 return s; 1051 case TARRAY: 1052 s = s*thash2 + 0; /* was t->width */ 1053 break; 1054 case TFUNC: 1055 for(t1=t->down; t1; t1=t1->down) 1056 s = s*thash3 + signat(t1, tt); 1057 break; 1058 case TSTRUCT: 1059 case TUNION: 1060 if((i = sigind(t, tt)) >= 0){ 1061 s = s*thash2 + i; 1062 return s; 1063 } 1064 for(t1=t->link; t1; t1=t1->down) 1065 s = s*thash3 + signat(t1, tt); 1066 return s; 1067 case TIND: 1068 break; 1069 } 1070 } 1071 return s; 1072 } 1073 1074 ulong 1075 signature(Type *t) 1076 { 1077 ulong s; 1078 Typetab tt; 1079 1080 tt.n = 0; 1081 tt.a = nil; 1082 s = signat(t, &tt); 1083 free(tt.a); 1084 return s; 1085 } 1086 1087 ulong 1088 sign(Sym *s) 1089 { 1090 ulong v; 1091 Type *t; 1092 1093 if(s->sig == SIGINTERN) 1094 return SIGNINTERN; 1095 if((t = s->type) == T) 1096 return 0; 1097 v = signature(t); 1098 if(v == 0) 1099 v = SIGNINTERN; 1100 return v; 1101 } 1102 1103 void 1104 snap(Type *t) 1105 { 1106 if(typesu[t->etype]) 1107 if(t->link == T && t->tag && t->tag->suetag) { 1108 t->link = t->tag->suetag->link; 1109 t->width = t->tag->suetag->width; 1110 } 1111 } 1112 1113 Type* 1114 dotag(Sym *s, int et, int bn) 1115 { 1116 Decl *d; 1117 1118 if(bn != 0 && bn != s->sueblock) { 1119 d = push(); 1120 d->sym = s; 1121 d->val = DSUE; 1122 d->type = s->suetag; 1123 d->block = s->sueblock; 1124 s->suetag = T; 1125 } 1126 if(s->suetag == T) { 1127 s->suetag = typ(et, T); 1128 s->sueblock = autobn; 1129 } 1130 if(s->suetag->etype != et) 1131 diag(Z, "tag used for more than one type: %s", 1132 s->name); 1133 if(s->suetag->tag == S) 1134 s->suetag->tag = s; 1135 return s->suetag; 1136 } 1137 1138 Node* 1139 dcllabel(Sym *s, int f) 1140 { 1141 Decl *d, d1; 1142 Node *n; 1143 1144 n = s->label; 1145 if(n != Z) { 1146 if(f) { 1147 if(n->complex) 1148 diag(Z, "label reused: %s", s->name); 1149 n->complex = 1; // declared 1150 } else 1151 n->addable = 1; // used 1152 return n; 1153 } 1154 1155 d = push(); 1156 d->sym = s; 1157 d->val = DLABEL; 1158 dclstack = d->link; 1159 1160 d1 = *firstdcl; 1161 *firstdcl = *d; 1162 *d = d1; 1163 1164 firstdcl->link = d; 1165 firstdcl = d; 1166 1167 n = new(OXXX, Z, Z); 1168 n->sym = s; 1169 n->complex = f; 1170 n->addable = !f; 1171 s->label = n; 1172 1173 if(debug['d']) 1174 dbgdecl(s); 1175 return n; 1176 } 1177 1178 Type* 1179 paramconv(Type *t, int f, int defining) 1180 { 1181 1182 switch(t->etype) { 1183 case TUNION: 1184 case TSTRUCT: 1185 if(t->width <= 0 && defining) 1186 diag(Z, "incomplete structure: %s", t->tag->name); 1187 break; 1188 1189 case TARRAY: 1190 t = typ(TIND, t->link); 1191 t->width = types[TIND]->width; 1192 break; 1193 1194 case TFUNC: 1195 t = typ(TIND, t); 1196 t->width = types[TIND]->width; 1197 break; 1198 1199 case TFLOAT: 1200 if(!f) 1201 t = types[TDOUBLE]; 1202 break; 1203 1204 case TCHAR: 1205 case TSHORT: 1206 if(!f) 1207 t = types[TINT]; 1208 break; 1209 1210 case TUCHAR: 1211 case TUSHORT: 1212 if(!f) 1213 t = types[TUINT]; 1214 break; 1215 } 1216 return t; 1217 } 1218 1219 void 1220 adecl(int c, Type *t, Sym *s) 1221 { 1222 1223 if(c == CSTATIC) 1224 c = CLOCAL; 1225 if(t->etype == TFUNC) { 1226 if(c == CXXX) 1227 c = CEXTERN; 1228 if(c == CLOCAL) 1229 c = CSTATIC; 1230 if(c == CAUTO || c == CEXREG) 1231 diag(Z, "function cannot be %s %s", cnames[c], s->name); 1232 } 1233 if(c == CXXX) 1234 c = CAUTO; 1235 if(s) { 1236 if(s->class == CSTATIC) 1237 if(c == CEXTERN || c == CGLOBL) { 1238 warn(Z, "just say static: %s", s->name); 1239 c = CSTATIC; 1240 } 1241 if(s->class == CAUTO || s->class == CPARAM || s->class == CLOCAL) 1242 if(s->block == autobn) 1243 diag(Z, "auto redeclaration of: %s", s->name); 1244 if(c != CPARAM) 1245 push1(s); 1246 s->block = autobn; 1247 s->offset = 0; 1248 s->type = t; 1249 s->class = c; 1250 s->aused = 0; 1251 } 1252 switch(c) { 1253 case CAUTO: 1254 autoffset = align(autoffset, t, Aaut3); 1255 stkoff = maxround(stkoff, autoffset); 1256 s->offset = -autoffset; 1257 break; 1258 1259 case CPARAM: 1260 if(autoffset == 0) { 1261 firstarg = s; 1262 firstargtype = t; 1263 } 1264 autoffset = align(autoffset, t, Aarg1); 1265 if(s) 1266 s->offset = autoffset; 1267 autoffset = align(autoffset, t, Aarg2); 1268 break; 1269 } 1270 } 1271 1272 void 1273 pdecl(int c, Type *t, Sym *s) 1274 { 1275 if(s && s->offset != -1) { 1276 diag(Z, "not a parameter: %s", s->name); 1277 return; 1278 } 1279 t = paramconv(t, c==CPARAM, 1); 1280 if(c == CXXX) 1281 c = CPARAM; 1282 if(c != CPARAM) { 1283 diag(Z, "parameter cannot have class: %s", s->name); 1284 c = CPARAM; 1285 } 1286 adecl(c, t, s); 1287 } 1288 1289 void 1290 xdecl(int c, Type *t, Sym *s) 1291 { 1292 long o; 1293 1294 o = 0; 1295 switch(c) { 1296 case CEXREG: 1297 o = exreg(t); 1298 if(o == 0) 1299 c = CEXTERN; 1300 if(s->class == CGLOBL) 1301 c = CGLOBL; 1302 break; 1303 1304 case CEXTERN: 1305 if(s->class == CGLOBL) 1306 c = CGLOBL; 1307 break; 1308 1309 case CXXX: 1310 c = CGLOBL; 1311 if(s->class == CEXTERN) 1312 s->class = CGLOBL; 1313 break; 1314 1315 case CAUTO: 1316 diag(Z, "overspecified class: %s %s %s", s->name, cnames[c], cnames[s->class]); 1317 c = CEXTERN; 1318 break; 1319 1320 case CTYPESTR: 1321 if(!typesuv[t->etype]) { 1322 diag(Z, "typestr must be struct/union: %s", s->name); 1323 break; 1324 } 1325 dclfunct(t, s); 1326 break; 1327 } 1328 1329 if(s->class == CSTATIC) 1330 if(c == CEXTERN || c == CGLOBL) { 1331 warn(Z, "overspecified class: %s %s %s", s->name, cnames[c], cnames[s->class]); 1332 c = CSTATIC; 1333 } 1334 if(s->type != T) 1335 if(s->class != c || !sametype(t, s->type) || t->etype == TENUM) { 1336 diag(Z, "external redeclaration of: %s", s->name); 1337 Bprint(&diagbuf, " %s %T %L\n", cnames[c], t, nearln); 1338 Bprint(&diagbuf, " %s %T %L\n", cnames[s->class], s->type, s->varlineno); 1339 } 1340 tmerge(t, s); 1341 s->type = t; 1342 s->class = c; 1343 s->block = 0; 1344 s->offset = o; 1345 } 1346 1347 void 1348 tmerge(Type *t1, Sym *s) 1349 { 1350 Type *ta, *tb, *t2; 1351 1352 t2 = s->type; 1353 /*print("merge %T; %T\n", t1, t2);/**/ 1354 for(;;) { 1355 if(t1 == T || t2 == T || t1 == t2) 1356 break; 1357 if(t1->etype != t2->etype) 1358 break; 1359 switch(t1->etype) { 1360 case TFUNC: 1361 ta = t1->down; 1362 tb = t2->down; 1363 if(ta == T) { 1364 t1->down = tb; 1365 break; 1366 } 1367 if(tb == T) 1368 break; 1369 while(ta != T && tb != T) { 1370 if(ta == tb) 1371 break; 1372 /* ignore old-style flag */ 1373 if(ta->etype == TOLD) { 1374 ta = ta->down; 1375 continue; 1376 } 1377 if(tb->etype == TOLD) { 1378 tb = tb->down; 1379 continue; 1380 } 1381 /* checking terminated by ... */ 1382 if(ta->etype == TDOT && tb->etype == TDOT) { 1383 ta = T; 1384 tb = T; 1385 break; 1386 } 1387 if(!sametype(ta, tb)) 1388 break; 1389 ta = ta->down; 1390 tb = tb->down; 1391 } 1392 if(ta != tb) 1393 diag(Z, "function inconsistently declared: %s", s->name); 1394 1395 /* take new-style over old-style */ 1396 ta = t1->down; 1397 tb = t2->down; 1398 if(ta != T && ta->etype == TOLD) 1399 if(tb != T && tb->etype != TOLD) 1400 t1->down = tb; 1401 break; 1402 1403 case TARRAY: 1404 /* should we check array size change? */ 1405 if(t2->width > t1->width) 1406 t1->width = t2->width; 1407 break; 1408 1409 case TUNION: 1410 case TSTRUCT: 1411 return; 1412 } 1413 t1 = t1->link; 1414 t2 = t2->link; 1415 } 1416 } 1417 1418 void 1419 edecl(int c, Type *t, Sym *s) 1420 { 1421 Type *t1; 1422 1423 if(s == S) { 1424 if(!typesu[t->etype]) 1425 diag(Z, "unnamed structure element must be struct/union"); 1426 if(c != CXXX) 1427 diag(Z, "unnamed structure element cannot have class"); 1428 } else 1429 if(c != CXXX) 1430 diag(Z, "structure element cannot have class: %s", s->name); 1431 t1 = t; 1432 t = copytyp(t1); 1433 t->sym = s; 1434 t->down = T; 1435 if(lastfield) { 1436 t->shift = lastbit - lastfield; 1437 t->nbits = lastfield; 1438 if(firstbit) 1439 t->shift = -t->shift; 1440 if(typeu[t->etype]) 1441 t->etype = tufield->etype; 1442 else 1443 t->etype = tfield->etype; 1444 } 1445 if(strf == T) 1446 strf = t; 1447 else 1448 strl->down = t; 1449 strl = t; 1450 } 1451 1452 /* 1453 * this routine is very suspect. 1454 * ansi requires the enum type to 1455 * be represented as an 'int' 1456 * this means that 0x81234567 1457 * would be illegal. this routine 1458 * makes signed and unsigned go 1459 * to unsigned. 1460 */ 1461 Type* 1462 maxtype(Type *t1, Type *t2) 1463 { 1464 1465 if(t1 == T) 1466 return t2; 1467 if(t2 == T) 1468 return t1; 1469 if(t1->etype > t2->etype) 1470 return t1; 1471 return t2; 1472 } 1473 1474 void 1475 doenum(Sym *s, Node *n) 1476 { 1477 1478 if(n) { 1479 complex(n); 1480 if(n->op != OCONST) { 1481 diag(n, "enum not a constant: %s", s->name); 1482 return; 1483 } 1484 en.cenum = n->type; 1485 en.tenum = maxtype(en.cenum, en.tenum); 1486 1487 if(!typefd[en.cenum->etype]) 1488 en.lastenum = n->vconst; 1489 else 1490 en.floatenum = n->fconst; 1491 } 1492 if(dclstack) 1493 push1(s); 1494 xdecl(CXXX, types[TENUM], s); 1495 1496 if(en.cenum == T) { 1497 en.tenum = types[TINT]; 1498 en.cenum = types[TINT]; 1499 en.lastenum = 0; 1500 } 1501 s->tenum = en.cenum; 1502 1503 if(!typefd[s->tenum->etype]) { 1504 s->vconst = convvtox(en.lastenum, s->tenum->etype); 1505 en.lastenum++; 1506 } else { 1507 s->fconst = en.floatenum; 1508 en.floatenum++; 1509 } 1510 1511 if(debug['d']) 1512 dbgdecl(s); 1513 acidvar(s); 1514 } 1515 1516 void 1517 symadjust(Sym *s, Node *n, long del) 1518 { 1519 1520 switch(n->op) { 1521 default: 1522 if(n->left) 1523 symadjust(s, n->left, del); 1524 if(n->right) 1525 symadjust(s, n->right, del); 1526 return; 1527 1528 case ONAME: 1529 if(n->sym == s) 1530 n->xoffset -= del; 1531 return; 1532 1533 case OCONST: 1534 case OSTRING: 1535 case OLSTRING: 1536 case OINDREG: 1537 case OREGISTER: 1538 return; 1539 } 1540 } 1541 1542 Node* 1543 contig(Sym *s, Node *n, long v) 1544 { 1545 Node *p, *r, *q, *m; 1546 long w; 1547 Type *zt; 1548 1549 if(debug['i']) { 1550 print("contig v = %ld; s = %s\n", v, s->name); 1551 prtree(n, "doinit value"); 1552 } 1553 1554 if(n == Z) 1555 goto no; 1556 w = s->type->width; 1557 1558 /* 1559 * nightmare: an automatic array whose size 1560 * increases when it is initialized 1561 */ 1562 if(v != w) { 1563 if(v != 0) 1564 diag(n, "automatic adjustable array: %s", s->name); 1565 v = s->offset; 1566 autoffset = align(autoffset, s->type, Aaut3); 1567 s->offset = -autoffset; 1568 stkoff = maxround(stkoff, autoffset); 1569 symadjust(s, n, v - s->offset); 1570 } 1571 if(w <= ewidth[TIND]) 1572 goto no; 1573 if(n->op == OAS) 1574 diag(Z, "oops in contig"); 1575 /*ZZZ this appears incorrect 1576 need to check if the list completely covers the data. 1577 if not, bail 1578 */ 1579 if(n->op == OLIST) 1580 goto no; 1581 if(n->op == OASI) 1582 if(n->left->type) 1583 if(n->left->type->width == w) 1584 goto no; 1585 while(w & (ewidth[TIND]-1)) 1586 w++; 1587 /* 1588 * insert the following code, where long becomes vlong if pointers are fat 1589 * 1590 *(long**)&X = (long*)((char*)X + sizeof(X)); 1591 do { 1592 *(long**)&X -= 1; 1593 **(long**)&X = 0; 1594 } while(*(long**)&X); 1595 */ 1596 1597 for(q=n; q->op != ONAME; q=q->left) 1598 ; 1599 1600 zt = ewidth[TIND] > ewidth[TLONG]? types[TVLONG]: types[TLONG]; 1601 1602 p = new(ONAME, Z, Z); 1603 *p = *q; 1604 p->type = typ(TIND, zt); 1605 p->xoffset = s->offset; 1606 1607 r = new(ONAME, Z, Z); 1608 *r = *p; 1609 r = new(OPOSTDEC, r, Z); 1610 1611 q = new(ONAME, Z, Z); 1612 *q = *p; 1613 q = new(OIND, q, Z); 1614 1615 m = new(OCONST, Z, Z); 1616 m->vconst = 0; 1617 m->type = zt; 1618 1619 q = new(OAS, q, m); 1620 1621 r = new(OLIST, r, q); 1622 1623 q = new(ONAME, Z, Z); 1624 *q = *p; 1625 r = new(ODWHILE, q, r); 1626 1627 q = new(ONAME, Z, Z); 1628 *q = *p; 1629 q->type = q->type->link; 1630 q->xoffset += w; 1631 q = new(OADDR, q, 0); 1632 1633 q = new(OASI, p, q); 1634 r = new(OLIST, q, r); 1635 1636 n = new(OLIST, r, n); 1637 1638 no: 1639 return n; 1640 } 1641