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