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