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