github.com/ader1990/go@v0.0.0-20140630135419-8c24447fa791/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, TRUNE); 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 static int 558 haspointers(Type *t) 559 { 560 Type *fld; 561 562 switch(t->etype) { 563 case TSTRUCT: 564 for(fld = t->link; fld != T; fld = fld->down) { 565 if(haspointers(fld)) 566 return 1; 567 } 568 return 0; 569 case TARRAY: 570 return haspointers(t->link); 571 case TFUNC: 572 case TIND: 573 return 1; 574 default: 575 return 0; 576 } 577 } 578 579 void 580 sualign(Type *t) 581 { 582 Type *l; 583 int32 o, w, maxal; 584 585 o = 0; 586 maxal = 0; 587 switch(t->etype) { 588 589 case TSTRUCT: 590 t->offset = 0; 591 w = 0; 592 for(l = t->link; l != T; l = l->down) { 593 if(l->nbits) { 594 if(l->shift <= 0) { 595 l->shift = -l->shift; 596 w = xround(w, tfield->width); 597 o = w; 598 w += tfield->width; 599 } 600 l->offset = o; 601 } else { 602 if(l->width <= 0) 603 if(l->down != T) 604 if(l->sym) 605 diag(Z, "incomplete structure element: %s", 606 l->sym->name); 607 else 608 diag(Z, "incomplete structure element"); 609 w = align(w, l, Ael1, &maxal); 610 l->offset = w; 611 w = align(w, l, Ael2, &maxal); 612 } 613 } 614 w = align(w, t, Asu2, &maxal); 615 t->width = w; 616 t->align = maxal; 617 acidtype(t); 618 godeftype(t); 619 return; 620 621 case TUNION: 622 t->offset = 0; 623 w = 0; 624 for(l = t->link; l != T; l = l->down) { 625 if(l->width <= 0) 626 if(l->sym) 627 diag(Z, "incomplete union element: %s", 628 l->sym->name); 629 else 630 diag(Z, "incomplete union element"); 631 l->offset = 0; 632 l->shift = 0; 633 if((debug['q'] || debug['Q']) && haspointers(l)) 634 diag(Z, "precise garbage collector cannot handle unions with pointers"); 635 636 o = align(align(0, l, Ael1, &maxal), l, Ael2, &maxal); 637 if(o > w) 638 w = o; 639 } 640 w = align(w, t, Asu2, &maxal); 641 t->width = w; 642 t->align = maxal; 643 acidtype(t); 644 godeftype(t); 645 return; 646 647 default: 648 diag(Z, "unknown type in sualign: %T", t); 649 break; 650 } 651 } 652 653 int32 654 xround(int32 v, int w) 655 { 656 int r; 657 658 if(w <= 0 || w > 8) { 659 diag(Z, "rounding by %d", w); 660 w = 1; 661 } 662 r = v%w; 663 if(r) 664 v += w-r; 665 return v; 666 } 667 668 Type* 669 ofnproto(Node *n) 670 { 671 Type *tl, *tr, *t; 672 673 if(n == Z) 674 return T; 675 switch(n->op) { 676 case OLIST: 677 tl = ofnproto(n->left); 678 tr = ofnproto(n->right); 679 if(tl == T) 680 return tr; 681 tl->down = tr; 682 return tl; 683 684 case ONAME: 685 t = copytyp(n->sym->type); 686 t->down = T; 687 return t; 688 } 689 return T; 690 } 691 692 #define ANSIPROTO 1 693 #define OLDPROTO 2 694 695 void 696 argmark(Node *n, int pass) 697 { 698 Type *t; 699 700 autoffset = align(0, thisfn->link, Aarg0, nil); 701 stkoff = 0; 702 for(; n->left != Z; n = n->left) { 703 if(n->op != OFUNC || n->left->op != ONAME) 704 continue; 705 walkparam(n->right, pass); 706 if(pass != 0 && anyproto(n->right) == OLDPROTO) { 707 t = typ(TFUNC, n->left->sym->type->link); 708 t->down = typ(TOLD, T); 709 t->down->down = ofnproto(n->right); 710 tmerge(t, n->left->sym); 711 n->left->sym->type = t; 712 } 713 break; 714 } 715 autoffset = 0; 716 stkoff = 0; 717 } 718 719 void 720 walkparam(Node *n, int pass) 721 { 722 Sym *s; 723 Node *n1; 724 725 if(n != Z && n->op == OPROTO && n->left == Z && n->type == types[TVOID]) 726 return; 727 728 loop: 729 if(n == Z) 730 return; 731 switch(n->op) { 732 default: 733 diag(n, "argument not a name/prototype: %O", n->op); 734 break; 735 736 case OLIST: 737 walkparam(n->left, pass); 738 n = n->right; 739 goto loop; 740 741 case OPROTO: 742 for(n1 = n; n1 != Z; n1=n1->left) 743 if(n1->op == ONAME) { 744 if(pass == 0) { 745 s = n1->sym; 746 push1(s); 747 s->offset = -1; 748 break; 749 } 750 dodecl(pdecl, CPARAM, n->type, n->left); 751 break; 752 } 753 if(n1) 754 break; 755 if(pass == 0) { 756 /* 757 * extension: 758 * allow no name in argument declaration 759 diag(Z, "no name in argument declaration"); 760 */ 761 break; 762 } 763 dodecl(NODECL, CPARAM, n->type, n->left); 764 pdecl(CPARAM, lastdcl, S); 765 break; 766 767 case ODOTDOT: 768 break; 769 770 case ONAME: 771 s = n->sym; 772 if(pass == 0) { 773 push1(s); 774 s->offset = -1; 775 break; 776 } 777 if(s->offset != -1) { 778 if(autoffset == 0) { 779 firstarg = s; 780 firstargtype = s->type; 781 } 782 autoffset = align(autoffset, s->type, Aarg1, nil); 783 s->offset = autoffset; 784 autoffset = align(autoffset, s->type, Aarg2, nil); 785 } else 786 dodecl(pdecl, CXXX, types[TINT], n); 787 break; 788 } 789 } 790 791 void 792 markdcl(void) 793 { 794 Decl *d; 795 796 blockno++; 797 d = push(); 798 d->val = DMARK; 799 d->offset = autoffset; 800 d->block = autobn; 801 autobn = blockno; 802 } 803 804 Node* 805 revertdcl(void) 806 { 807 Decl *d; 808 Sym *s; 809 Node *n, *n1; 810 811 n = Z; 812 for(;;) { 813 d = dclstack; 814 if(d == D) { 815 diag(Z, "pop off dcl stack"); 816 break; 817 } 818 dclstack = d->link; 819 s = d->sym; 820 switch(d->val) { 821 case DMARK: 822 autoffset = d->offset; 823 autobn = d->block; 824 return n; 825 826 case DAUTO: 827 if(debug['d']) 828 print("revert1 \"%s\"\n", s->name); 829 if(s->aused == 0) { 830 nearln = s->varlineno; 831 if(s->class == CAUTO) 832 warn(Z, "auto declared and not used: %s", s->name); 833 if(s->class == CPARAM) 834 warn(Z, "param declared and not used: %s", s->name); 835 } 836 if(s->type && (s->type->garb & GVOLATILE)) { 837 n1 = new(ONAME, Z, Z); 838 n1->sym = s; 839 n1->type = s->type; 840 n1->etype = TVOID; 841 if(n1->type != T) 842 n1->etype = n1->type->etype; 843 n1->xoffset = s->offset; 844 n1->class = s->class; 845 846 n1 = new(OADDR, n1, Z); 847 n1 = new(OUSED, n1, Z); 848 if(n == Z) 849 n = n1; 850 else 851 n = new(OLIST, n1, n); 852 } 853 s->type = d->type; 854 s->class = d->class; 855 s->offset = d->offset; 856 s->block = d->block; 857 s->varlineno = d->varlineno; 858 s->aused = d->aused; 859 break; 860 861 case DSUE: 862 if(debug['d']) 863 print("revert2 \"%s\"\n", s->name); 864 s->suetag = d->type; 865 s->sueblock = d->block; 866 break; 867 868 case DLABEL: 869 if(debug['d']) 870 print("revert3 \"%s\"\n", s->name); 871 if(s->label && s->label->addable == 0) 872 warn(s->label, "label declared and not used \"%s\"", s->name); 873 s->label = Z; 874 break; 875 } 876 } 877 return n; 878 } 879 880 Type* 881 fnproto(Node *n) 882 { 883 int r; 884 885 r = anyproto(n->right); 886 if(r == 0 || (r & OLDPROTO)) { 887 if(r & ANSIPROTO) 888 diag(n, "mixed ansi/old function declaration: %F", n->left); 889 return T; 890 } 891 return fnproto1(n->right); 892 } 893 894 int 895 anyproto(Node *n) 896 { 897 int r; 898 899 r = 0; 900 901 loop: 902 if(n == Z) 903 return r; 904 switch(n->op) { 905 case OLIST: 906 r |= anyproto(n->left); 907 n = n->right; 908 goto loop; 909 910 case ODOTDOT: 911 case OPROTO: 912 return r | ANSIPROTO; 913 } 914 return r | OLDPROTO; 915 } 916 917 Type* 918 fnproto1(Node *n) 919 { 920 Type *t; 921 922 if(n == Z) 923 return T; 924 switch(n->op) { 925 case OLIST: 926 t = fnproto1(n->left); 927 if(t != T) 928 t->down = fnproto1(n->right); 929 return t; 930 931 case OPROTO: 932 lastdcl = T; 933 dodecl(NODECL, CXXX, n->type, n->left); 934 t = typ(TXXX, T); 935 if(lastdcl != T) 936 *t = *paramconv(lastdcl, 1); 937 return t; 938 939 case ONAME: 940 diag(n, "incomplete argument prototype"); 941 return typ(TINT, T); 942 943 case ODOTDOT: 944 return typ(TDOT, T); 945 } 946 diag(n, "unknown op in fnproto"); 947 return T; 948 } 949 950 void 951 dbgdecl(Sym *s) 952 { 953 print("decl \"%s\": C=%s [B=%d:O=%d] T=%T\n", 954 s->name, cnames[s->class], s->block, s->offset, s->type); 955 } 956 957 Decl* 958 push(void) 959 { 960 Decl *d; 961 962 d = alloc(sizeof(*d)); 963 d->link = dclstack; 964 dclstack = d; 965 return d; 966 } 967 968 Decl* 969 push1(Sym *s) 970 { 971 Decl *d; 972 973 d = push(); 974 d->sym = s; 975 d->val = DAUTO; 976 d->type = s->type; 977 d->class = s->class; 978 d->offset = s->offset; 979 d->block = s->block; 980 d->varlineno = s->varlineno; 981 d->aused = s->aused; 982 return d; 983 } 984 985 int 986 sametype(Type *t1, Type *t2) 987 { 988 989 if(t1 == t2) 990 return 1; 991 return rsametype(t1, t2, 5, 1); 992 } 993 994 int 995 rsametype(Type *t1, Type *t2, int n, int f) 996 { 997 int et; 998 999 n--; 1000 for(;;) { 1001 if(t1 == t2) 1002 return 1; 1003 if(t1 == T || t2 == T) 1004 return 0; 1005 if(n <= 0) 1006 return 1; 1007 et = t1->etype; 1008 if(et != t2->etype) 1009 return 0; 1010 if(et == TFUNC) { 1011 if(!rsametype(t1->link, t2->link, n, 0)) 1012 return 0; 1013 t1 = t1->down; 1014 t2 = t2->down; 1015 while(t1 != T && t2 != T) { 1016 if(t1->etype == TOLD) { 1017 t1 = t1->down; 1018 continue; 1019 } 1020 if(t2->etype == TOLD) { 1021 t2 = t2->down; 1022 continue; 1023 } 1024 while(t1 != T || t2 != T) { 1025 if(!rsametype(t1, t2, n, 0)) 1026 return 0; 1027 t1 = t1->down; 1028 t2 = t2->down; 1029 } 1030 break; 1031 } 1032 return 1; 1033 } 1034 if(et == TARRAY) 1035 if(t1->width != t2->width && t1->width != 0 && t2->width != 0) 1036 return 0; 1037 if(typesu[et]) { 1038 if(t1->link == T) 1039 snap(t1); 1040 if(t2->link == T) 1041 snap(t2); 1042 t1 = t1->link; 1043 t2 = t2->link; 1044 for(;;) { 1045 if(t1 == t2) 1046 return 1; 1047 if(!rsametype(t1, t2, n, 0)) 1048 return 0; 1049 t1 = t1->down; 1050 t2 = t2->down; 1051 } 1052 } 1053 t1 = t1->link; 1054 t2 = t2->link; 1055 if((f || !debug['V']) && et == TIND) { 1056 if(t1 != T && t1->etype == TVOID) 1057 return 1; 1058 if(t2 != T && t2->etype == TVOID) 1059 return 1; 1060 } 1061 } 1062 } 1063 1064 typedef struct Typetab Typetab; 1065 1066 struct Typetab{ 1067 int n; 1068 Type **a; 1069 }; 1070 1071 static int 1072 sigind(Type *t, Typetab *tt) 1073 { 1074 int n; 1075 Type **a, **na, **p, **e; 1076 1077 n = tt->n; 1078 a = tt->a; 1079 e = a+n; 1080 /* linear search seems ok */ 1081 for(p = a ; p < e; p++) 1082 if(sametype(*p, t)) 1083 return p-a; 1084 if((n&15) == 0){ 1085 na = malloc((n+16)*sizeof(Type*)); 1086 if(na == nil) { 1087 print("%s: out of memory", argv0); 1088 errorexit(); 1089 } 1090 memmove(na, a, n*sizeof(Type*)); 1091 free(a); 1092 a = tt->a = na; 1093 } 1094 a[tt->n++] = t; 1095 return -1; 1096 } 1097 1098 static uint32 1099 signat(Type *t, Typetab *tt) 1100 { 1101 int i; 1102 Type *t1; 1103 int32 s; 1104 1105 s = 0; 1106 for(; t; t=t->link) { 1107 s = s*thash1 + thash[t->etype]; 1108 if(t->garb&GINCOMPLETE) 1109 return s; 1110 switch(t->etype) { 1111 default: 1112 return s; 1113 case TARRAY: 1114 s = s*thash2 + 0; /* was t->width */ 1115 break; 1116 case TFUNC: 1117 for(t1=t->down; t1; t1=t1->down) 1118 s = s*thash3 + signat(t1, tt); 1119 break; 1120 case TSTRUCT: 1121 case TUNION: 1122 if((i = sigind(t, tt)) >= 0){ 1123 s = s*thash2 + i; 1124 return s; 1125 } 1126 for(t1=t->link; t1; t1=t1->down) 1127 s = s*thash3 + signat(t1, tt); 1128 return s; 1129 case TIND: 1130 break; 1131 } 1132 } 1133 return s; 1134 } 1135 1136 uint32 1137 signature(Type *t) 1138 { 1139 uint32 s; 1140 Typetab tt; 1141 1142 tt.n = 0; 1143 tt.a = nil; 1144 s = signat(t, &tt); 1145 free(tt.a); 1146 return s; 1147 } 1148 1149 uint32 1150 sign(Sym *s) 1151 { 1152 uint32 v; 1153 Type *t; 1154 1155 if(s->sig == SIGINTERN) 1156 return SIGNINTERN; 1157 if((t = s->type) == T) 1158 return 0; 1159 v = signature(t); 1160 if(v == 0) 1161 v = SIGNINTERN; 1162 return v; 1163 } 1164 1165 void 1166 snap(Type *t) 1167 { 1168 if(typesu[t->etype]) 1169 if(t->link == T && t->tag && t->tag->suetag) { 1170 t->link = t->tag->suetag->link; 1171 t->width = t->tag->suetag->width; 1172 } 1173 } 1174 1175 Type* 1176 dotag(Sym *s, int et, int bn) 1177 { 1178 Decl *d; 1179 1180 if(bn != 0 && bn != s->sueblock) { 1181 d = push(); 1182 d->sym = s; 1183 d->val = DSUE; 1184 d->type = s->suetag; 1185 d->block = s->sueblock; 1186 s->suetag = T; 1187 } 1188 if(s->suetag == T) { 1189 s->suetag = typ(et, T); 1190 s->sueblock = autobn; 1191 } 1192 if(s->suetag->etype != et) 1193 diag(Z, "tag used for more than one type: %s", 1194 s->name); 1195 if(s->suetag->tag == S) 1196 s->suetag->tag = s; 1197 return s->suetag; 1198 } 1199 1200 Node* 1201 dcllabel(Sym *s, int f) 1202 { 1203 Decl *d, d1; 1204 Node *n; 1205 1206 n = s->label; 1207 if(n != Z) { 1208 if(f) { 1209 if(n->complex) 1210 diag(Z, "label reused: %s", s->name); 1211 n->complex = 1; // declared 1212 } else 1213 n->addable = 1; // used 1214 return n; 1215 } 1216 1217 d = push(); 1218 d->sym = s; 1219 d->val = DLABEL; 1220 dclstack = d->link; 1221 1222 d1 = *firstdcl; 1223 *firstdcl = *d; 1224 *d = d1; 1225 1226 firstdcl->link = d; 1227 firstdcl = d; 1228 1229 n = new(OXXX, Z, Z); 1230 n->sym = s; 1231 n->complex = f; 1232 n->addable = !f; 1233 s->label = n; 1234 1235 if(debug['d']) 1236 dbgdecl(s); 1237 return n; 1238 } 1239 1240 Type* 1241 paramconv(Type *t, int f) 1242 { 1243 1244 switch(t->etype) { 1245 case TUNION: 1246 case TSTRUCT: 1247 if(t->width <= 0) 1248 diag(Z, "incomplete structure: %s", t->tag->name); 1249 break; 1250 1251 case TARRAY: 1252 t = typ(TIND, t->link); 1253 t->width = types[TIND]->width; 1254 break; 1255 1256 case TFUNC: 1257 t = typ(TIND, t); 1258 t->width = types[TIND]->width; 1259 break; 1260 1261 case TFLOAT: 1262 if(!f) 1263 t = types[TDOUBLE]; 1264 break; 1265 1266 case TCHAR: 1267 case TSHORT: 1268 if(!f) 1269 t = types[TINT]; 1270 break; 1271 1272 case TUCHAR: 1273 case TUSHORT: 1274 if(!f) 1275 t = types[TUINT]; 1276 break; 1277 } 1278 return t; 1279 } 1280 1281 void 1282 adecl(int c, Type *t, Sym *s) 1283 { 1284 1285 if(c == CSTATIC) 1286 c = CLOCAL; 1287 if(t->etype == TFUNC) { 1288 if(c == CXXX) 1289 c = CEXTERN; 1290 if(c == CLOCAL) 1291 c = CSTATIC; 1292 if(c == CAUTO || c == CEXREG) 1293 diag(Z, "function cannot be %s %s", cnames[c], s->name); 1294 } 1295 if(c == CXXX) 1296 c = CAUTO; 1297 if(s) { 1298 if(s->class == CSTATIC) 1299 if(c == CEXTERN || c == CGLOBL) { 1300 warn(Z, "just say static: %s", s->name); 1301 c = CSTATIC; 1302 } 1303 if(s->class == CAUTO || s->class == CPARAM || s->class == CLOCAL) 1304 if(s->block == autobn) 1305 diag(Z, "auto redeclaration of: %s", s->name); 1306 if(c != CPARAM) 1307 push1(s); 1308 s->block = autobn; 1309 s->offset = 0; 1310 s->type = t; 1311 s->class = c; 1312 s->aused = 0; 1313 } 1314 switch(c) { 1315 case CAUTO: 1316 autoffset = align(autoffset, t, Aaut3, nil); 1317 stkoff = maxround(stkoff, autoffset); 1318 s->offset = -autoffset; 1319 break; 1320 1321 case CPARAM: 1322 if(autoffset == 0) { 1323 firstarg = s; 1324 firstargtype = t; 1325 } 1326 autoffset = align(autoffset, t, Aarg1, nil); 1327 if(s) 1328 s->offset = autoffset; 1329 autoffset = align(autoffset, t, Aarg2, nil); 1330 break; 1331 } 1332 } 1333 1334 void 1335 pdecl(int c, Type *t, Sym *s) 1336 { 1337 if(s && s->offset != -1) { 1338 diag(Z, "not a parameter: %s", s->name); 1339 return; 1340 } 1341 t = paramconv(t, c==CPARAM); 1342 if(c == CXXX) 1343 c = CPARAM; 1344 if(c != CPARAM) { 1345 diag(Z, "parameter cannot have class: %s", s->name); 1346 c = CPARAM; 1347 } 1348 adecl(c, t, s); 1349 } 1350 1351 void 1352 xdecl(int c, Type *t, Sym *s) 1353 { 1354 int32 o; 1355 1356 o = 0; 1357 switch(c) { 1358 case CEXREG: 1359 o = exreg(t); 1360 if(o == 0) 1361 c = CEXTERN; 1362 if(s->class == CGLOBL) 1363 c = CGLOBL; 1364 break; 1365 1366 case CEXTERN: 1367 if(s->class == CGLOBL) 1368 c = CGLOBL; 1369 break; 1370 1371 case CXXX: 1372 c = CGLOBL; 1373 if(s->class == CEXTERN) 1374 s->class = CGLOBL; 1375 break; 1376 1377 case CAUTO: 1378 diag(Z, "overspecified class: %s %s %s", s->name, cnames[c], cnames[s->class]); 1379 c = CEXTERN; 1380 break; 1381 1382 case CTYPESTR: 1383 if(!typesuv[t->etype]) { 1384 diag(Z, "typestr must be struct/union: %s", s->name); 1385 break; 1386 } 1387 dclfunct(t, s); 1388 break; 1389 } 1390 1391 if(s->class == CSTATIC) 1392 if(c == CEXTERN || c == CGLOBL) { 1393 warn(Z, "overspecified class: %s %s %s", s->name, cnames[c], cnames[s->class]); 1394 c = CSTATIC; 1395 } 1396 if(s->type != T) 1397 if(s->class != c || !sametype(t, s->type) || t->etype == TENUM) { 1398 diag(Z, "external redeclaration of: %s", s->name); 1399 Bprint(&diagbuf, " %s %T %L\n", cnames[c], t, nearln); 1400 Bprint(&diagbuf, " %s %T %L\n", cnames[s->class], s->type, s->varlineno); 1401 } 1402 tmerge(t, s); 1403 s->type = t; 1404 s->class = c; 1405 s->block = 0; 1406 s->offset = o; 1407 } 1408 1409 void 1410 tmerge(Type *t1, Sym *s) 1411 { 1412 Type *ta, *tb, *t2; 1413 1414 t2 = s->type; 1415 for(;;) { 1416 if(t1 == T || t2 == T || t1 == t2) 1417 break; 1418 if(t1->etype != t2->etype) 1419 break; 1420 switch(t1->etype) { 1421 case TFUNC: 1422 ta = t1->down; 1423 tb = t2->down; 1424 if(ta == T) { 1425 t1->down = tb; 1426 break; 1427 } 1428 if(tb == T) 1429 break; 1430 while(ta != T && tb != T) { 1431 if(ta == tb) 1432 break; 1433 /* ignore old-style flag */ 1434 if(ta->etype == TOLD) { 1435 ta = ta->down; 1436 continue; 1437 } 1438 if(tb->etype == TOLD) { 1439 tb = tb->down; 1440 continue; 1441 } 1442 /* checking terminated by ... */ 1443 if(ta->etype == TDOT && tb->etype == TDOT) { 1444 ta = T; 1445 tb = T; 1446 break; 1447 } 1448 if(!sametype(ta, tb)) 1449 break; 1450 ta = ta->down; 1451 tb = tb->down; 1452 } 1453 if(ta != tb) 1454 diag(Z, "function inconsistently declared: %s", s->name); 1455 1456 /* take new-style over old-style */ 1457 ta = t1->down; 1458 tb = t2->down; 1459 if(ta != T && ta->etype == TOLD) 1460 if(tb != T && tb->etype != TOLD) 1461 t1->down = tb; 1462 break; 1463 1464 case TARRAY: 1465 /* should we check array size change? */ 1466 if(t2->width > t1->width) 1467 t1->width = t2->width; 1468 break; 1469 1470 case TUNION: 1471 case TSTRUCT: 1472 return; 1473 } 1474 t1 = t1->link; 1475 t2 = t2->link; 1476 } 1477 } 1478 1479 void 1480 edecl(int c, Type *t, Sym *s) 1481 { 1482 Type *t1; 1483 1484 if(s == S) { 1485 if(!typesu[t->etype]) 1486 diag(Z, "unnamed structure element must be struct/union"); 1487 if(c != CXXX) 1488 diag(Z, "unnamed structure element cannot have class"); 1489 } else 1490 if(c != CXXX) 1491 diag(Z, "structure element cannot have class: %s", s->name); 1492 t1 = t; 1493 t = copytyp(t1); 1494 t->sym = s; 1495 t->down = T; 1496 if(lastfield) { 1497 t->shift = lastbit - lastfield; 1498 t->nbits = lastfield; 1499 if(firstbit) 1500 t->shift = -t->shift; 1501 if(typeu[t->etype]) 1502 t->etype = tufield->etype; 1503 else 1504 t->etype = tfield->etype; 1505 } 1506 if(strf == T) 1507 strf = t; 1508 else 1509 strl->down = t; 1510 strl = t; 1511 } 1512 1513 /* 1514 * this routine is very suspect. 1515 * ansi requires the enum type to 1516 * be represented as an 'int' 1517 * this means that 0x81234567 1518 * would be illegal. this routine 1519 * makes signed and unsigned go 1520 * to unsigned. 1521 */ 1522 Type* 1523 maxtype(Type *t1, Type *t2) 1524 { 1525 1526 if(t1 == T) 1527 return t2; 1528 if(t2 == T) 1529 return t1; 1530 if(t1->etype > t2->etype) 1531 return t1; 1532 return t2; 1533 } 1534 1535 void 1536 doenum(Sym *s, Node *n) 1537 { 1538 1539 if(n) { 1540 complex(n); 1541 if(n->op != OCONST) { 1542 diag(n, "enum not a constant: %s", s->name); 1543 return; 1544 } 1545 en.cenum = n->type; 1546 en.tenum = maxtype(en.cenum, en.tenum); 1547 1548 if(!typefd[en.cenum->etype]) 1549 en.lastenum = n->vconst; 1550 else 1551 en.floatenum = n->fconst; 1552 } 1553 if(dclstack) 1554 push1(s); 1555 xdecl(CXXX, types[TENUM], s); 1556 1557 if(en.cenum == T) { 1558 en.tenum = types[TINT]; 1559 en.cenum = types[TINT]; 1560 en.lastenum = 0; 1561 } 1562 s->tenum = en.cenum; 1563 1564 if(!typefd[s->tenum->etype]) { 1565 s->vconst = convvtox(en.lastenum, s->tenum->etype); 1566 en.lastenum++; 1567 } else { 1568 s->fconst = en.floatenum; 1569 en.floatenum++; 1570 } 1571 1572 if(debug['d']) 1573 dbgdecl(s); 1574 acidvar(s); 1575 godefvar(s); 1576 } 1577 1578 void 1579 symadjust(Sym *s, Node *n, int32 del) 1580 { 1581 1582 switch(n->op) { 1583 default: 1584 if(n->left) 1585 symadjust(s, n->left, del); 1586 if(n->right) 1587 symadjust(s, n->right, del); 1588 return; 1589 1590 case ONAME: 1591 if(n->sym == s) 1592 n->xoffset -= del; 1593 return; 1594 1595 case OCONST: 1596 case OSTRING: 1597 case OLSTRING: 1598 case OINDREG: 1599 case OREGISTER: 1600 return; 1601 } 1602 } 1603 1604 Node* 1605 contig(Sym *s, Node *n, int32 v) 1606 { 1607 Node *p, *r, *q, *m; 1608 int32 w; 1609 Type *zt; 1610 1611 if(debug['i']) { 1612 print("contig v = %d; s = %s\n", v, s->name); 1613 prtree(n, "doinit value"); 1614 } 1615 1616 if(n == Z) 1617 goto no; 1618 w = s->type->width; 1619 1620 /* 1621 * nightmare: an automatic array whose size 1622 * increases when it is initialized 1623 */ 1624 if(v != w) { 1625 if(v != 0) 1626 diag(n, "automatic adjustable array: %s", s->name); 1627 v = s->offset; 1628 autoffset = align(autoffset, s->type, Aaut3, nil); 1629 s->offset = -autoffset; 1630 stkoff = maxround(stkoff, autoffset); 1631 symadjust(s, n, v - s->offset); 1632 } 1633 if(w <= ewidth[TIND]) 1634 goto no; 1635 if(n->op == OAS) 1636 diag(Z, "oops in contig"); 1637 /*ZZZ this appears incorrect 1638 need to check if the list completely covers the data. 1639 if not, bail 1640 */ 1641 if(n->op == OLIST) 1642 goto no; 1643 if(n->op == OASI) 1644 if(n->left->type) 1645 if(n->left->type->width == w) 1646 goto no; 1647 while(w & (ewidth[TIND]-1)) 1648 w++; 1649 /* 1650 * insert the following code, where long becomes vlong if pointers are fat 1651 * 1652 *(long**)&X = (long*)((char*)X + sizeof(X)); 1653 do { 1654 *(long**)&X -= 1; 1655 **(long**)&X = 0; 1656 } while(*(long**)&X); 1657 */ 1658 1659 for(q=n; q->op != ONAME; q=q->left) 1660 ; 1661 1662 zt = ewidth[TIND] > ewidth[TLONG]? types[TVLONG]: types[TLONG]; 1663 1664 p = new(ONAME, Z, Z); 1665 *p = *q; 1666 p->type = typ(TIND, zt); 1667 p->xoffset = s->offset; 1668 1669 r = new(ONAME, Z, Z); 1670 *r = *p; 1671 r = new(OPOSTDEC, r, Z); 1672 1673 q = new(ONAME, Z, Z); 1674 *q = *p; 1675 q = new(OIND, q, Z); 1676 1677 m = new(OCONST, Z, Z); 1678 m->vconst = 0; 1679 m->type = zt; 1680 1681 q = new(OAS, q, m); 1682 1683 r = new(OLIST, r, q); 1684 1685 q = new(ONAME, Z, Z); 1686 *q = *p; 1687 r = new(ODWHILE, q, r); 1688 1689 q = new(ONAME, Z, Z); 1690 *q = *p; 1691 q->type = q->type->link; 1692 q->xoffset += w; 1693 q = new(OADDR, q, 0); 1694 1695 q = new(OASI, p, q); 1696 r = new(OLIST, q, r); 1697 1698 n = new(OLIST, r, n); 1699 1700 no: 1701 return n; 1702 }