|
|
1.1 ! root 1: /*ident "@(#)ctrans:src/dcl.c 1.3.5.30" */ ! 2: /************************************************************************** ! 3: ! 4: C++ source for cfront, the C++ compiler front-end ! 5: written in the computer science research center of Bell Labs ! 6: ! 7: Copyright (c) 1984 AT&T, Inc. All rigths Reserved ! 8: THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T, INC. ! 9: ! 10: dcl.c: ! 11: ! 12: ``declare'' all names, that is insert them in the appropriate symbol tables. ! 13: ! 14: Calculate the size for all objects (incl. stack frames), ! 15: and find store the offsets for all members (incl. auto variables). ! 16: "size.h" holds the constants needed for calculating sizes. ! 17: ! 18: Note that (due to errors) functions may nest ! 19: ! 20: *****************************************************************************/ ! 21: ! 22: ! 23: #include "cfront.h" ! 24: #include "size.h" ! 25: ! 26: class dcl_context ccvec[MAXCONT], * cc = ccvec; ! 27: int byte_offset; ! 28: int bit_offset; ! 29: int max_align; ! 30: int friend_in_class; ! 31: static Pstmt itail; ! 32: ! 33: Pname dclass(Pname, Ptable); ! 34: Pname denum(Pname, Ptable); ! 35: void merge_init(Pname, Pfct, Pfct); ! 36: ! 37: void dosimpl(Pexpr e, Pname n) ! 38: { ! 39: //error('d',"dosimpl %k %n",e?e->base:0,n); ! 40: ! 41: extern Pname curr_fct; ! 42: extern Pname dummy_fct; ! 43: extern void make_dummy(); ! 44: ! 45: if (n==0) { ! 46: if (dummy_fct == 0) make_dummy(); ! 47: n = dummy_fct; ! 48: } ! 49: Pname cf = curr_fct; ! 50: curr_fct = n; ! 51: e->simpl(); ! 52: curr_fct = cf; ! 53: } ! 54: ! 55: static Pexpr co_array_init(Pname n, Ptable tbl) ! 56: /* ! 57: handle simple arrays only. To be done well list_check() must ! 58: be rewritten to handle dynamic initialization. ! 59: ! 60: */ ! 61: { ! 62: //error('d',"Ir forCO%n\[\]",n); ! 63: Pexpr init = n->n_initializer; ! 64: ! 65: if (init->base != ILIST) { ! 66: error("badIr for array ofCOs %n",n); ! 67: return 0; ! 68: } ! 69: ! 70: Pexpr el = 0; ! 71: Pvec v = Pvec(n->tp); ! 72: while (v->base==TYPE) v = Pvec(Pbase(v)->b_name->tp); ! 73: Pname cn = v->typ->is_cl_obj(); ! 74: Pclass cl = cn ? Pclass(cn->tp) : 0; ! 75: //error('d',"v %t cl %d %t",v,cl,cl); ! 76: int i = v->size; ! 77: ! 78: int count = 0; ! 79: Pexpr il2; ! 80: for (Pexpr il = init->e1; il; il = il2) { ! 81: // generate n[0].cl(initializer), ! 82: // ... ! 83: // n[max].cl(initializer), ! 84: Pexpr e = il->e1; ! 85: il2 = il->e2; ! 86: il->e2 = 0; ! 87: if (e == dummy) break; ! 88: //error('d',"il %k e %k",il->base,e?e->base:0); ! 89: if (e->base == VALUE) { ! 90: switch (e->tp2->base) { ! 91: case CLASS: ! 92: if (Pclass(e->tp2)!=cl) e = new texpr(VALUE,cl,il); ! 93: break; ! 94: default: ! 95: Pname n2 = e->tp2->is_cl_obj(); ! 96: if (n2==0 || Pclass(n2->tp)!=cl) e = new texpr(VALUE,cl,il); ! 97: } ! 98: } ! 99: else ! 100: e = new texpr(VALUE,cl,il); ! 101: e->e2 = new expr(DEREF,n,new ival(count++)); ! 102: e = e->typ(tbl); ! 103: dosimpl(e,cc->nof); ! 104: // e->simpl(); ! 105: if (sti_tbl == tbl) { ! 106: extern loc no_where; ! 107: Pstmt ist = new estmt(SM,no_where,e,0); ! 108: if (st_ilist == 0) ! 109: st_ilist = ist; ! 110: else ! 111: itail->s_list = ist; ! 112: itail = ist; ! 113: } ! 114: else { ! 115: el = el ? new expr(G_CM,el,e) : e; ! 116: } ! 117: } ! 118: ! 119: if (i==0) ! 120: v->size = count; ! 121: else if (i==count) ! 122: ; ! 123: else if (i<count) { ! 124: //error('d',"too manyIrs for%n (%d)",n, count); ! 125: return 0; ! 126: } ! 127: else { ! 128: // error('d',"too fewIrs for%n (%d)",n, count); ! 129: error('s',"too fewIrs for%n",n); ! 130: return 0; ! 131: } ! 132: return el; ! 133: } ! 134: ! 135: static accept_name; ! 136: ! 137: int need_sti(Pexpr e, Ptable tbl = 0) ! 138: /* ! 139: check if non-static variables or operations are used ! 140: INCOMPLETE ! 141: */ ! 142: { ! 143: if (e == 0) return 0; ! 144: // error('d',"need %k %d",e->base,tbl); ! 145: ! 146: switch (e->base) { ! 147: case QUEST: ! 148: if (need_sti(e->cond,tbl) && tbl==0) return 1; ! 149: case PLUS: ! 150: case MINUS: ! 151: case MUL: ! 152: case DIV: ! 153: case MOD: ! 154: case ER: ! 155: case OR: ! 156: case ANDAND: ! 157: case OROR: ! 158: case LS: ! 159: case RS: ! 160: case EQ: ! 161: case NE: ! 162: case LT: ! 163: case LE: ! 164: case GT: ! 165: case GE: ! 166: if (need_sti(e->e1,tbl) && tbl==0) return 1; ! 167: // no break; ! 168: ! 169: case UMINUS: ! 170: case UPLUS: ! 171: case NOT: ! 172: case COMPL: ! 173: if (need_sti(e->e2,tbl) && tbl==0) return 1; ! 174: // no break ! 175: ! 176: case SIZEOF: ! 177: default: ! 178: return 0; ! 179: ! 180: case CAST: ! 181: ! 182: return need_sti(e->e1,tbl); ! 183: ! 184: case ADDROF: ! 185: { ! 186: accept_name++; // address of global name accepted ! 187: int i = need_sti(e->e2,tbl); ! 188: accept_name--; ! 189: return i; ! 190: } ! 191: ! 192: case NAME: ! 193: if (accept_name && Pname(e)->n_stclass==STATIC) return 0; ! 194: ! 195: if (Pname(e)->n_stclass==AUTO) { ! 196: error('s',"localN%n inIr for static",e); ! 197: return 0; ! 198: } ! 199: ! 200: if (e->tp->tconst()) { ! 201: if (vec_const || fct_const) return 0; ! 202: Neval = 0; ! 203: e->eval(); ! 204: if (Neval == 0) return 0; ! 205: } ! 206: return 1; ! 207: ! 208: case DOT: ! 209: case REF: ! 210: if (tbl) { ! 211: need_sti(e->e1,tbl); ! 212: need_sti(e->e2,tbl); ! 213: } ! 214: else ! 215: if ( e->tp->base == VEC ) { ! 216: if ( e->e1->base == NAME ) { ! 217: accept_name++; ! 218: int i = need_sti(e->e1,tbl); ! 219: accept_name--; ! 220: return i; ! 221: } ! 222: } ! 223: return 1; ! 224: ! 225: case DEREF: ! 226: if (accept_name) { // &v[expr] ! 227: int x1 = need_sti(e->e1,tbl); ! 228: accept_name--; ! 229: int x2 = need_sti(e->e2,tbl); ! 230: accept_name++; ! 231: return x1 || x2; ! 232: } ! 233: // no break ! 234: ! 235: case ELIST: ! 236: // case ILIST: ! 237: case G_CM: ! 238: case CM: ! 239: //case DOT: ! 240: //case REF: ! 241: case CALL: ! 242: case G_CALL: ! 243: case NEW: ! 244: case GNEW: ! 245: if (tbl) { ! 246: need_sti(e->e1,tbl); ! 247: need_sti(e->e2,tbl); ! 248: } ! 249: // no break ! 250: case ICALL: ! 251: return 1; ! 252: case ICON: ! 253: case STRING: ! 254: case CCON: ! 255: case FCON: ! 256: //error('d',"save %k tbl %d",e->base,tbl); ! 257: if (tbl) { ! 258: char* p = new char[strlen(e->string)+1]; ! 259: strcpy(p,e->string); ! 260: e->string = p; ! 261: } ! 262: return 0; ! 263: } ! 264: } ! 265: ! 266: extern int catch_delete_bugs; ! 267: ! 268: Pname name::dcl(Ptable tbl, TOK scope) ! 269: /* ! 270: enter a copy of this name into symbol table "tbl"; ! 271: - create local symbol tables as needed ! 272: ! 273: "scope" gives the scope in which the declaration was found ! 274: - EXTERN, FCT, ARG, PUBLIC, or 0 ! 275: Compare "scope" with the specified storage class "n_sto" ! 276: - AUTO, STATIC, REGISTER, EXTERN, OVERLOAD, FRIEND, or 0 ! 277: ! 278: After name::dcl() ! 279: n_stclass == 0 class or enum member ! 280: REGISTER auto variables declared register ! 281: AUTO auto variables not registers ! 282: STATIC statically allocated object ! 283: n_scope == 0 private class member ! 284: PUBLIC public class member ! 285: EXTERN name valid in this and other files ! 286: STATIC name valid for this file only ! 287: FCT name local to a function ! 288: ARG name of a function argument ! 289: ARGT name of a type defined in an ! 290: argument list ! 291: ! 292: typecheck function bodies; ! 293: typecheck initializers; ! 294: ! 295: note that functions (error recovery) and classes (legal) nest ! 296: ! 297: The return value is used to chain symbol table entries, but cannot ! 298: be used for printout because it denotes the sum of all type information ! 299: for the name ! 300: ! 301: names of typenames are marked with n_oper==TNAME ! 302: ! 303: WARNING: The handling of scope and storage class is cursed! ! 304: */ ! 305: { ! 306: Pname nn; ! 307: Ptype nnt = 0; ! 308: Pname odcl = Cdcl; ! 309: ! 310: // if (this == 0) error('i',"0->N::dcl()"); ! 311: // if (tbl == 0) error('i',"%n->N::dcl(tbl=0,%k)",this,scope); ! 312: // if (tbl->base != TABLE) error('i',"%n->N::dcl(tbl=%d,%k)",this,tbl->base,scope); ! 313: // if (tp == 0) error('i',"N::dcl(%n,%k)T missing",this,scope); ! 314: ! 315: if(catch_delete_bugs && permanent == 3) ! 316: error('i', "name::dcl of a deleted name."); ! 317: ! 318: Cdcl = this; ! 319: ! 320: Ptype tx = tp; ! 321: ! 322: //error('d',"dcl %n %t",this,tx); ! 323: while (tx->base == TYPE) tx = Pbase(tx)->b_name->tp; ! 324: ! 325: switch (base) { ! 326: case TNAME: ! 327: nn = tbl->look(string,0); ! 328: tp->dcl(tbl); ! 329: if (nn && nn->lex_level == lex_level) { ! 330: //error('d', "dcl: cot: %s ccl: %s", cc->cot?cc->cot->string:"notset", ccl?ccl->string:"notset"); ! 331: ! 332: if ( tp->check(nn->tp,0) ) ! 333: error("%n declared as %t and %t",nn,nn->tp,tp); ! 334: else if ( nn->base == NAME && cc->cot == 0 && ! 335: (tp->base != COBJ || tp->base != EOBJ)) ! 336: error("%n declared as identifier and typedef", nn ); ! 337: Cdcl = odcl; ! 338: return 0; ! 339: ! 340: } ! 341: PERM(tp); ! 342: nn = new name(string); ! 343: nn->base = TNAME; ! 344: nn->tp = tp; ! 345: (void) tbl->insert(nn,0); ! 346: delete nn; ! 347: Cdcl = odcl; ! 348: return this; ! 349: ! 350: case NAME: ! 351: switch (n_oper) { ! 352: case COMPL: ! 353: if (tp->base != FCT) { ! 354: error("~%s notF",string); ! 355: n_oper = 0; ! 356: } ! 357: break; ! 358: case TNAME: ! 359: if (tp->base != FCT) n_oper = 0; ! 360: break; ! 361: } ! 362: break; ! 363: default: ! 364: error('i',"NX in N::dcl()"); ! 365: } ! 366: ! 367: if (n_qualifier) { ! 368: // c::f() ! 369: // class function, ! 370: // friend declaration, or ! 371: // static member initializer ! 372: ! 373: //III if (tp->base != FCT) { ! 374: // error("QdN%n inD of nonF",this); ! 375: // Cdcl = odcl; ! 376: // return 0; ! 377: // } ! 378: ! 379: Pname cn = n_qualifier; ! 380: ! 381: switch (cn->base) { ! 382: case TNAME: ! 383: break; ! 384: case NAME: ! 385: cn = gtbl->look(cn->string,0); ! 386: if (cn && cn->base==TNAME) break; ! 387: default: ! 388: error("badQr%n for%n",n_qualifier,this); ! 389: Cdcl = odcl; ! 390: return 0; ! 391: } ! 392: ! 393: if (cn->tp->base != COBJ) { ! 394: // error('d',"Qr%nnot aCN",n_qualifier); ! 395: Cdcl = odcl; ! 396: return 0; ! 397: } ! 398: ! 399: cn = Pbase(cn->tp)->b_name; ! 400: if (n_oper) check_oper(cn); ! 401: ! 402: Pclass cl = Pclass(cn->tp); ! 403: if (cl == cc->cot) { ! 404: n_qualifier = 0; ! 405: goto xdr; ! 406: } ! 407: else if ((cl->defined&(DEFINED|SIMPLIFIED)) == 0) { ! 408: error("C%nU",cn); ! 409: Cdcl = odcl; ! 410: return 0; ! 411: } ! 412: else if (cl->c_body==1) //III ! 413: cl->dcl_print(0); ! 414: ! 415: Ptable etbl = cl->memtbl; ! 416: Pname x = etbl->look(string,0); ! 417: if (x==0 || x->n_table!=etbl) { ! 418: error("%n is not aM of%n",this,cn); ! 419: Cdcl = odcl; ! 420: return 0; ! 421: } ! 422: ! 423: if (tp->base == FCT) { //III ! 424: // if (friend_in_class==0 && Pfct(tp)->body==0) { // c::f(); needed for friend ! 425: if (friend_in_class==0 ! 426: && n_sto!=FRIEND ! 427: && Pfct(tp)->body==0) { // c::f(); needed for friend ! 428: error("QdN%n inFD",x); ! 429: Cdcl = odcl; ! 430: return 0; ! 431: } ! 432: ! 433: if (Pfct(tp)->body==0) { ! 434: Pfct(tp)->memof = cl; ! 435: int xx; ! 436: if (x->tp->base==OVERLOAD) ! 437: xx = Pgen(x->tp)->find(Pfct(tp),0)==0; ! 438: else ! 439: xx = x->tp->check(tp,0); ! 440: ! 441: if (xx) { ! 442: error("%n is not aM of%n",this,cn); ! 443: Cdcl = odcl; ! 444: return 0; ! 445: } ! 446: } ! 447: } ! 448: else { ! 449: if (x->n_stclass != STATIC) { // e.g. int c::i = 7 ! 450: error("D of non staticCM %n",this); ! 451: Cdcl = odcl; ! 452: return 0; ! 453: } ! 454: if (n_sto) error("staticCM declared%k",n_sto); ! 455: tbl = etbl; ! 456: } ! 457: } ! 458: xdr: ! 459: if (n_oper ! 460: && tp->base!=FCT ! 461: && n_sto!=OVERLOAD) error("operator%k not aF",n_oper); ! 462: ! 463: ! 464: /* if a storage class was specified ! 465: check that it is legal in the scope ! 466: else ! 467: provide default storage class ! 468: some details must be left until the type of the object is known ! 469: */ ! 470: ! 471: n_stclass = n_sto; ! 472: n_scope = scope; /* default scope & storage class */ ! 473: ! 474: switch (n_sto) { ! 475: default: ! 476: error('i',"unX %k",n_sto); ! 477: case FRIEND: ! 478: { ! 479: Pclass cl = cc->cot; ! 480: ! 481: switch (scope) { ! 482: case 0: ! 483: case PUBLIC: ! 484: break; ! 485: default: ! 486: error("friend%n not inCD(%k)",this,scope); ! 487: base = 0; ! 488: Cdcl = odcl; ! 489: return 0; ! 490: } ! 491: ! 492: switch (n_oper) { ! 493: case 0: ! 494: case NEW: ! 495: case DELETE: ! 496: case CTOR: ! 497: case DTOR: ! 498: case TYPE: ! 499: n_sto = 0; ! 500: break; ! 501: default: ! 502: n_sto = OVERLOAD; ! 503: } ! 504: ! 505: switch (tx->base) { ! 506: case COBJ: ! 507: nn = Pbase(tx)->b_name; ! 508: break; ! 509: case CLASS: ! 510: nn = this; ! 511: break; ! 512: case FCT: ! 513: cc->stack(); ! 514: cc->not = 0; ! 515: cc->tot = 0; ! 516: cc->cot = 0; ! 517: friend_in_class++; ! 518: // n_sto = EXTERN; ! 519: n_sto = 0; ! 520: nn = dcl(gtbl,EXTERN); ! 521: if (nn == 0) { ! 522: Cdcl = odcl; ! 523: return 0; ! 524: } ! 525: friend_in_class--; ! 526: cc->unstack(); ! 527: if (nn->tp->base == OVERLOAD) nn = Pgen(nn->tp)->find(Pfct(tx),1); ! 528: break; ! 529: default: ! 530: error("badT%tof friend%n",tp,this); ! 531: Cdcl = odcl; ! 532: return 0; ! 533: } ! 534: PERM(nn); ! 535: cl->friend_list = new name_list(nn,cl->friend_list); ! 536: Cdcl = odcl; ! 537: return nn; ! 538: } ! 539: case OVERLOAD: ! 540: if (strict_opt) error("anachronism `overload' used"); ! 541: n_sto = 0; ! 542: // ignore overload! ! 543: // switch (scope) { ! 544: // case 0: ! 545: // case PUBLIC: ! 546: // error('w',"overload inCD (ignored)"); ! 547: switch (tp->base) { ! 548: case INT: ! 549: base = 0; ! 550: Cdcl = odcl; ! 551: return this; ! 552: // case FCT: ! 553: // Cdcl = odcl; ! 554: // return dcl(tbl,scope); ! 555: } ! 556: // } ! 557: // if (n_oper && tp->base==FCT) break; ! 558: // nn = tbl->insert(this,0); ! 559: // ! 560: // if (Nold) { ! 561: // if (nn->tp->base != OVERLOAD) { ! 562: // error("%n redefined as overloaded",this); ! 563: // nn->tp = new gen; ! 564: // } ! 565: // } ! 566: // else { ! 567: // nn->tp = new gen; ! 568: // } ! 569: // ! 570: // switch (tx->base) { ! 571: // case INT: ! 572: // base = 0; ! 573: // Cdcl = odcl; ! 574: // return nn; ! 575: // case FCT: ! 576: // break; ! 577: // default: ! 578: // error("N%n ofT%k cannot be overloaded",this,tp->base); ! 579: // Cdcl = odcl; ! 580: // return nn; ! 581: // } ! 582: break; ! 583: case REGISTER: ! 584: if (tp->base == FCT) { ! 585: error('w',"%n: register (ignored)",this); ! 586: goto ddd; ! 587: } ! 588: case AUTO: ! 589: switch (scope) { ! 590: case 0: ! 591: case PUBLIC: ! 592: case EXTERN: ! 593: error("%k not inF",n_sto); ! 594: goto ddd; ! 595: } ! 596: if (n_sto==AUTO) n_sto = 0; // always redundant ! 597: break; ! 598: case EXTERN: ! 599: switch (scope) { ! 600: case ARG: ! 601: error("externA"); ! 602: goto ddd; ! 603: case 0: ! 604: case PUBLIC: ! 605: /* extern is provided as a default for functions without body */ ! 606: if (tp->base != FCT) error("externM%n",this); ! 607: goto ddd; ! 608: case FCT: ! 609: { ! 610: Pname nn = gtbl->look( string, 0 ); ! 611: if ( nn && tp->base != FCT && ! 612: tp->check(nn->tp,0)) ! 613: { ! 614: error("twoDs of%n;Ts:%t and%t",this,nn->tp,tp); ! 615: Cdcl = odcl; ! 616: return 0; ! 617: } ! 618: } ! 619: } ! 620: n_stclass = STATIC; ! 621: n_scope = EXTERN; /* avoid FCT scoped externs to allow better checking */ ! 622: break; ! 623: case STATIC: ! 624: switch (scope) { ! 625: case ARG: ! 626: error("static used forA%n",this); ! 627: goto ddd; ! 628: case 0: ! 629: case PUBLIC: ! 630: n_stclass = STATIC; ! 631: n_scope = scope; ! 632: break; ! 633: default: ! 634: n_scope = STATIC; ! 635: } ! 636: break; ! 637: case 0: ! 638: ddd: ! 639: switch (scope) { /* default storage classes */ ! 640: case EXTERN: ! 641: n_scope = EXTERN; ! 642: n_stclass = STATIC; ! 643: break; ! 644: case FCT: ! 645: if (tp->base == FCT) { ! 646: n_stclass = STATIC; ! 647: n_scope = EXTERN; ! 648: } ! 649: else ! 650: n_stclass = AUTO; ! 651: break; ! 652: case ARG: ! 653: n_stclass = AUTO; ! 654: break; ! 655: case 0: ! 656: case PUBLIC: ! 657: n_stclass = 0; ! 658: break; ! 659: } ! 660: } ! 661: ! 662: ! 663: /* ! 664: now insert the name into the appropriate symbol table, ! 665: and compare types with previous declarations of that name ! 666: ! 667: do type dependent adjustments of the scope ! 668: */ ! 669: //error('d',"sw %d",tx->base); ! 670: switch (tx->base) { ! 671: case ASM: ! 672: { Pbase b = Pbase(tp); ! 673: Pname n = tbl->insert(this,0); ! 674: n->assign(); ! 675: n->use(); ! 676: char* s = (char*) b->b_name; // save asm string. Shoddy ! 677: int ll = strlen(s); ! 678: char* s2 = new char[ll+1]; ! 679: strcpy(s2,s); ! 680: b->b_name = Pname(s2); ! 681: Cdcl = odcl; ! 682: return this; ! 683: } ! 684: ! 685: case CLASS: ! 686: tp = tx; ! 687: nn = dclass(this,tbl); ! 688: Cdcl = odcl; ! 689: return nn; ! 690: ! 691: case ENUM: ! 692: tp = tx; ! 693: nn = denum(this,tbl); ! 694: Cdcl = odcl; ! 695: return nn; ! 696: ! 697: case FCT: ! 698: tp = tx; ! 699: nn = dofct(tbl,scope); ! 700: if (nn == 0) { ! 701: Cdcl = odcl; ! 702: return 0; ! 703: } ! 704: break; ! 705: ! 706: case FIELD: ! 707: switch (n_stclass) { ! 708: case 0: ! 709: case PUBLIC: ! 710: break; ! 711: default: ! 712: error("%k field",n_stclass); ! 713: n_stclass = 0; ! 714: } ! 715: ! 716: if (cc->not==0 || cc->cot->csu==UNION || cc->cot->csu==ANON) { ! 717: error(cc->not?"field in union":"field not inC"); ! 718: PERM(tp); ! 719: Cdcl = odcl; ! 720: return this; ! 721: } ! 722: ! 723: if (string) { ! 724: nn = tbl->insert(this,0); ! 725: n_table = nn->n_table; ! 726: if (Nold) error("twoDs of field%n",this); ! 727: } ! 728: ! 729: tp->dcl(tbl); ! 730: field_align(); ! 731: break; ! 732: ! 733: case COBJ: ! 734: { Pclass cl = Pclass(Pbase(tx)->b_name->tp); ! 735: if (cl->lex_level > lex_level) ! 736: error("C%t is not visible in this scope",cl); ! 737: ! 738: if (cl->csu == ANON) { // export member names to enclosing scope ! 739: if (tbl==gtbl && n_sto!=STATIC) error("extern anonymous union (declare as static)"); ! 740: char* p = cl->string; ! 741: while (*p++ != 'C'); /* sneaky */ ! 742: int uindex = (int)str_to_long(p); ! 743: ! 744: // cannot cope with use counts for ANONs: ! 745: Pbase(tp)->b_name->n_used = 1; ! 746: Pbase(tp)->b_name->n_assigned_to = 1; ! 747: ! 748: Ptable mtbl = cl->memtbl; ! 749: int i, err_msg = 0; ! 750: for (Pname nn=mtbl->get_mem(i=1); nn; nn=mtbl->get_mem(++i)) { ! 751: if (nn->tp->base == FCT) { ! 752: error("FM%n for anonymous union",nn); ! 753: break; ! 754: } ! 755: Ptable tb = nn->n_table; ! 756: nn->n_table = 0; ! 757: Pname n = tbl->insert(nn,0); ! 758: if (Nold) { ! 759: error("twoDs of%n (one in anonymous union)",nn); ! 760: break; ! 761: } ! 762: ! 763: Pclass tc; ! 764: if (tc = cl->in_class) ! 765: --n->lex_level; ! 766: if ( tc && tc->csu == ANON) { ! 767: //error('d', "tc->csu anon %k %s", tc->csu, string ); ! 768: if ( n->n_anon ) { ! 769: if ( !err_msg ) ! 770: error('s', "anonymous unions nested deeper than 2 levels" ); ! 771: err_msg = 1; ! 772: } ! 773: n->n_anon = string; ! 774: } ! 775: ! 776: n->n_union = uindex; ! 777: nn->n_table = tb; ! 778: } ! 779: } ! 780: if (cl->c_abstract) error("D ofO of abstractC%t",cl); ! 781: goto cde; ! 782: } ! 783: ! 784: case VOID: ! 785: if (n_scope != ARG) { ! 786: error("badBT:%k%n",tx->base,this); ! 787: Cdcl = odcl; ! 788: return 0; ! 789: } ! 790: break; ! 791: ! 792: ! 793: case PTR: ! 794: case VEC: ! 795: case RPTR: ! 796: tp->dcl(tbl); ! 797: // if (tp->base==PTR && Pptr(tp)->memof) { ! 798: // Ptype t = Pptr(tp)->typ; ! 799: // while (t->base==TYPE) t = Pbase(t)->b_name->tp; ! 800: // if (t->base == FCT) { ! 801: // // size and align ! 802: // } ! 803: // } ! 804: ! 805: default: ! 806: cde: ! 807: //error('d',"cde: %n %t",this,tp); ! 808: nn = tbl->insert(this,0); ! 809: n_table = nn->n_table; ! 810: ! 811: if (Nold) { ! 812: if (nn->tp->base == ANY) goto zzz; ! 813: ! 814: if (tp->check(nn->tp,0)) { ! 815: error("twoDs of%n;Ts:%t and%t",this,nn->tp,tp); ! 816: Cdcl = odcl; ! 817: return 0; ! 818: } ! 819: //error('d',"%n: %k %k scope %k",this,n_sto,nn->n_sto,nn->n_scope); ! 820: if (n_sto && n_sto!=nn->n_scope) { ! 821: if (n_sto==EXTERN && nn->n_scope==STATIC) { ! 822: error('w',"%n declared extern after being declared static",this); ! 823: goto ext_fudge; ! 824: } ! 825: else ! 826: error("%n declared as both%k and%k",this,n_sto,(nn->n_sto)?nn->n_sto:(scope==FCT?AUTO:EXTERN)); ! 827: } ! 828: else if (nn->n_scope==STATIC && n_scope==EXTERN) { ! 829: error('w',"static%n followed by definition",this); ! 830: ext_fudge: ! 831: if (n_initializer) { ! 832: // error('d',"static%n redefined (WIr)",this); ! 833: n_initializer = 0; ! 834: } ! 835: n_sto = EXTERN; ! 836: } ! 837: else if (nn->n_sto==STATIC && n_sto==STATIC ) ! 838: error("static%n declared twice",this); ! 839: else { ! 840: if (n_sto==0 ! 841: && nn->n_sto==EXTERN ! 842: && n_initializer ! 843: && tp->tconst()) ! 844: n_sto = EXTERN; ! 845: n_scope = nn->n_scope; ! 846: ! 847: switch (scope) { ! 848: case FCT: ! 849: if (n_sto != EXTERN) { ! 850: error("twoDs of%n",this); ! 851: Cdcl = odcl; ! 852: return 0; ! 853: } ! 854: break; ! 855: case ARG: ! 856: error("twoAs%n",this); ! 857: Cdcl = odcl; ! 858: return 0; ! 859: case 0: ! 860: case PUBLIC: ! 861: error("twoDs ofM%n",this); ! 862: Cdcl = odcl; ! 863: return 0; ! 864: case EXTERN: ! 865: if (n_sto==0 && nn->n_sto==0) { ! 866: error("two definitions of%n",this); ! 867: Cdcl = odcl; ! 868: return 0; ! 869: } ! 870: } ! 871: } ! 872: n_scope = nn->n_scope; ! 873: /* n_val */ ! 874: if (n_initializer) { ! 875: if (nn->n_initializer || nn->n_val) error("twoIrs for%n",this); ! 876: nn->n_initializer = n_initializer; ! 877: } ! 878: if (tp->base == VEC) { ! 879: // handle: extern v[]; v[200]; ! 880: // and extern u[10]; u[11]; ! 881: ! 882: Ptype ntp = nn->tp; ! 883: while (ntp->base == TYPE) ntp = Pbase(ntp)->b_name->tp; ! 884: if (Pvec(ntp)->dim == 0) Pvec(ntp)->dim = Pvec(tp)->dim; ! 885: if (Pvec(ntp)->size) { ! 886: if (Pvec(tp)->size ! 887: && Pvec(ntp)->size!=Pvec(tp)->size) ! 888: error("bad array size for%n: %d %dX",this,Pvec(tp)->size,Pvec(ntp)->size); ! 889: } ! 890: else ! 891: Pvec(ntp)->size = Pvec(tp)->size; ! 892: } ! 893: } ! 894: else { ! 895: //error('d',"%n %t scope %d sto %k",this,tp,scope,n_sto); ! 896: if (scope!=ARG ! 897: && n_sto!=EXTERN ! 898: && (!((scope==0 || scope==PUBLIC) && n_sto==STATIC)) // static member ! 899: && n_initializer==0 ! 900: && tp->base==VEC ! 901: && Pvec(tp)->size==0) ! 902: error(&where,"dimension missing for array%n",this); ! 903: ! 904: if (scope==EXTERN ! 905: && n_sto==0 ! 906: && tp->tconst() ! 907: && vec_const==0 ! 908: && fct_const==0) ! 909: nn->n_sto = n_sto = STATIC; ! 910: } ! 911: ! 912: zzz: ! 913: if (base != TNAME) { ! 914: Ptype t = nn->tp; ! 915: ! 916: if (t->base == TYPE) { ! 917: Ptype tt = Pbase(t)->b_name->tp; ! 918: if (tt->base == FCT) nn->tp = t = tt; ! 919: } ! 920: ! 921: switch (t->base) { ! 922: case FCT: ! 923: case OVERLOAD: ! 924: break; ! 925: default: ! 926: fake_sizeof = 1; ! 927: switch (nn->n_stclass) { ! 928: default: ! 929: if (nn->n_scope != ARG) { ! 930: int x = t->align(); ! 931: int y = t->tsizeof(); ! 932: ! 933: if (max_align < x) max_align = x; ! 934: ! 935: while (0 < bit_offset) { ! 936: byte_offset++; ! 937: bit_offset -= BI_IN_BYTE; ! 938: } ! 939: bit_offset = 0; ! 940: ! 941: if (byte_offset && 1<x) byte_offset = ((byte_offset-1)/x)*x+x; ! 942: nn->n_offset = byte_offset; ! 943: byte_offset += y; ! 944: } ! 945: break; ! 946: case STATIC: ! 947: if (n_sto != EXTERN ! 948: && nn->n_scope ! 949: && nn->n_scope!=PUBLIC) ! 950: t->tsizeof(); // check that size is known ! 951: } ! 952: fake_sizeof = 0; ! 953: } ! 954: } ! 955: ! 956: { Ptype t = nn->tp; ! 957: int const_old = const_save; ! 958: bit vec_seen = 0; ! 959: Pexpr init = n_initializer; ! 960: ! 961: lll: ! 962: //error('d',"lll %n %t init %d %k",this,t,init,init?init->base:0); ! 963: switch (t->base) { ! 964: case COBJ: ! 965: { Pname cn = Pbase(t)->b_name; ! 966: Pclass cl = (Pclass)cn->tp; ! 967: Pname ctor = cl->has_ctor(); ! 968: Pname dtor = cl->has_dtor(); ! 969: int stct = 0; ! 970: if (dtor) { ! 971: Pstmt dls; ! 972: ! 973: // if dtor is not public check scope of class object ! 974: ! 975: if (dtor->n_scope != PUBLIC) { ! 976: //error('d',"dcl %n->n_scope: %d fct %n",nn,nn->n_scope,cc->nof); ! 977: switch (nn->n_scope) { ! 978: case ARG: ! 979: case 0: ! 980: case PUBLIC: ! 981: break; ! 982: default: ! 983: check_visibility( dtor, 0, cl, tbl, cc->nof ); ! 984: } ! 985: // if (nn->n_scope == FCT) ! 986: // check_visibility( dtor, 0, cl, tbl, cc->nof ); ! 987: // else if ( nn->n_sto != EXTERN ) ! 988: // error("%k%n cannot access%n: %sM",nn->n_scope,nn,dtor,dtor->n_protect?"protected":"private"); ! 989: } ! 990: ! 991: switch ( nn->n_scope ) { ! 992: case 0: ! 993: case PUBLIC: ! 994: if (n_stclass==STATIC) { //III ! 995: Pclass cl = Pclass(nn->n_table->t_name->tp); ! 996: if (cl->defined&DEFINED) goto dtdt; ! 997: } ! 998: break; ! 999: case EXTERN: ! 1000: if (n_sto==EXTERN) break; ! 1001: ! 1002: case STATIC: ! 1003: { Pexpr c; ! 1004: Pexpr cdvec(Pname, Pexpr, Pclass, Pname, int, Pexpr); ! 1005: dtdt: ! 1006: // local static class objects have destructors set up in simpl2.c ! 1007: if ( nn->lex_level ! 1008: && nn->n_sto == STATIC ) ! 1009: { ! 1010: // error( 'd', "%n->dcl nn->ll: %d nn->n_sto: %k", nn, nn->lex_level, nn->n_sto ); ! 1011: // error( 'd', "dtor: ctor: %d", ctor ); ! 1012: if (ctor==0) ! 1013: error('s',"local static%n has%n but noK(add%n::%n())", nn, dtor, cn, cn ); ! 1014: goto stat_init; ! 1015: } ! 1016: ! 1017: Ptable otbl = tbl; ! 1018: // to collect temporaries generated ! 1019: // in static destructors where we ! 1020: // can find them again (in std_tbl) ! 1021: if (std_tbl == 0) std_tbl = new table(8,gtbl,0); ! 1022: tbl = std_tbl; ! 1023: if (vec_seen) ! 1024: c = cdvec(vec_del_fct,nn,cl,dtor,0,zero); ! 1025: else // nn->cl::~cl(0); ! 1026: c = call_dtor(nn,dtor,0,DOT,one); ! 1027: c->tp = any_type; // avoid another check ! 1028: dls = new estmt(SM,nn->where,c,0); ! 1029: ! 1030: // destructors for statics are executed in reverse order ! 1031: if (st_dlist) dls->s_list = st_dlist; ! 1032: st_dlist = dls; ! 1033: tbl = otbl; ! 1034: } ! 1035: } ! 1036: } ! 1037: ! 1038: // local static class objects must defer setting up static dtor ! 1039: stat_init: ! 1040: if (ctor) { ! 1041: // error('d',"ctor %n scope %k",ctor,nn->n_scope); ! 1042: Pexpr oo = nn; ! 1043: for (int vi=vec_seen; vi; vi--) oo = oo->contents(); ! 1044: int sti = 0; ! 1045: switch (nn->n_scope) { ! 1046: case EXTERN: ! 1047: if (init==0 && n_sto==EXTERN) goto ggg; ! 1048: case STATIC: ! 1049: if (tbl == gtbl) ! 1050: sti = 1; ! 1051: else ! 1052: stct = 1; ! 1053: default: ! 1054: if (vec_seen && init) { ! 1055: if (1<vec_seen) { ! 1056: if (init->base == ILIST) ! 1057: error("badIr forO ofC %t withK%n",cl,this); ! 1058: else ! 1059: error('s',"Ir for multi-dimensional array ofOsofC %t withK%n",cl,this); ! 1060: } ! 1061: else { ! 1062: if (sti) { ! 1063: if (sti_tbl==0) sti_tbl = new table(8,gtbl,0); ! 1064: const_save = 1; ! 1065: (void) co_array_init(nn,sti_tbl); ! 1066: const_save = 0; ! 1067: n_initializer = init = 0; ! 1068: } ! 1069: else ! 1070: n_initializer = init = co_array_init(nn,tbl); ! 1071: } ! 1072: goto ggg; ! 1073: } ! 1074: break; ! 1075: case PUBLIC: ! 1076: case 0: ! 1077: if (n_stclass==STATIC) { //III ! 1078: Pclass cl = Pclass(nn->n_table->t_name->tp); ! 1079: if (cl->defined&DEFINED) { ! 1080: sti = 1; ! 1081: break; ! 1082: } ! 1083: } ! 1084: // no break ! 1085: case ARG: ! 1086: goto ggg; ! 1087: } ! 1088: ! 1089: const_save = 1; ! 1090: nn->assign(); ! 1091: Ptable otbl = tbl; ! 1092: if (sti) { // to collect temporaries generated ! 1093: // in static initializers where we ! 1094: // can find them again (in sti_tbl) ! 1095: if (sti_tbl == 0) sti_tbl = new table(8,gtbl,0); ! 1096: tbl = sti_tbl; ! 1097: if (n_sto == EXTERN) nn->n_sto = n_sto = 0; ! 1098: } ! 1099: ! 1100: if (init) { ! 1101: // error('d',"init %k",init->base); ! 1102: if (init->base==VALUE) { ! 1103: switch (init->tp2->base) { ! 1104: case CLASS: ! 1105: // error('d',"class %t %t",Pclass(init->tp2),cl); ! 1106: if (Pclass(init->tp2)!=cl) goto inin; ! 1107: break; ! 1108: default: ! 1109: Pname n2 = init->tp2->is_cl_obj(); ! 1110: // error('d',"default %t %t",n2->tp,cl); ! 1111: if (n2==0 || Pclass(n2->tp)!=cl) goto inin; ! 1112: } ! 1113: ! 1114: Pexpr ee = init->e1; ! 1115: // error('d',"init->e1 %k",ee->base); ! 1116: if (ee && vec_seen==0) ! 1117: switch (ee->base) { ! 1118: case CALL: // T a = f(); ! 1119: init = ee; ! 1120: goto inin; ! 1121: case ELIST: // T a(f()); ! 1122: if (ee->e1->base==CALL ! 1123: && ee->e2 == 0) { ! 1124: init = ee->e1; ! 1125: goto inin; ! 1126: } ! 1127: } // end switch ! 1128: ! 1129: init->e2 = oo; ! 1130: init = init->typ(tbl); ! 1131: ! 1132: if (init->base == G_CM) // beware of type conversion operators ! 1133: switch (init->tp2->base) { ! 1134: case CLASS: ! 1135: if (Pclass(init->tp2)!=cl) goto inin; ! 1136: break; ! 1137: default: ! 1138: Pname n2 = init->tp2->is_cl_obj(); ! 1139: if (n2==0 || Pclass(n2->tp)!=cl) goto inin; ! 1140: } ! 1141: } ! 1142: else { ! 1143: inin: ! 1144: // error('d',"inin %k",init->base); ! 1145: init = init->typ(tbl); ! 1146: //error('d', "inin: init->typ: %d %k n->tp %t init->tp %t",init->base,init->base,nn->tp,init->tp); ! 1147: if (init->base==G_CM ! 1148: && nn->tp->check(init->tp,0)==0) ! 1149: (void) replace_temp(init,nn->address()); ! 1150: else ! 1151: init = class_init(nn,nn->tp,init,tbl); ! 1152: } ! 1153: } ! 1154: else if (vec_seen == 0) { ! 1155: //error('d',"make value"); ! 1156: init = new texpr(VALUE,cl,0); ! 1157: init->e2 = oo; ! 1158: init = init->typ(tbl); ! 1159: } ! 1160: ! 1161: Pname c; ! 1162: if (vec_seen) { ! 1163: c = cl->has_ictor(); ! 1164: if (c == 0) ! 1165: error("array ofC%n that does not have aK taking noAs",cn); ! 1166: else if (Pfct(c->tp)->nargs) ! 1167: error('s',"defaultAs forK for array ofC%n",cn); ! 1168: } ! 1169: ! 1170: // error( 'd', "stct: %d init: %d", stct, init ); ! 1171: if (stct) { ! 1172: if (tbl!=gtbl && nn->n_sto==EXTERN) { ! 1173: error(&where,"Id local extern%n",this); ! 1174: init = 0; ! 1175: } ! 1176: // bombs on vec_seen since init is not yet set ! 1177: // added sorry: not hard, just not time ! 1178: // Otherwise, in else, build up init, and set its type to STAT_INIT ! 1179: else if ( vec_seen == 0 ) ! 1180: init->base = STAT_INIT; ! 1181: else // vec_seen == 1 ! 1182: error('s', "local static vector ofC%n withK", cn); ! 1183: } ! 1184: ! 1185: if (sti) { ! 1186: if (vec_seen) { // _vec_new(vec,noe,sz,ctor); ! 1187: Pexpr cdvec(Pname f, Pexpr vec, Pclass cl, Pname cd, int ,Pexpr); ! 1188: init = cdvec(vec_new_fct,nn,cl,c,-1,0); ! 1189: init->tp = any_type; ! 1190: } ! 1191: else { ! 1192: switch (init->base) { ! 1193: case DEREF: // *constructor? ! 1194: if (init->e1->base == G_CALL) { ! 1195: Pname fn = init->e1->fct_name; ! 1196: if (fn==0 || fn->n_oper!=CTOR) goto as; ! 1197: init = init->e1; ! 1198: break; ! 1199: } ! 1200: goto as; ! 1201: case G_CM: ! 1202: init = init->e1; ! 1203: // suppress further type checking ! 1204: if (init->tp == 0) init->tp= any_type; ! 1205: break; ! 1206: case ASSIGN: ! 1207: if (init->e1 == nn) break; // simple assignment ! 1208: as: ! 1209: default: ! 1210: init = new expr(ASSIGN,nn,init); ! 1211: } ! 1212: } ! 1213: Pstmt ist = new estmt(SM,nn->where,init,0); ! 1214: // constructors for statics are executed in order ! 1215: if (st_ilist == 0) ! 1216: st_ilist = ist; ! 1217: else ! 1218: itail->s_list = ist; ! 1219: itail = ist; ! 1220: init = 0; // suppress further processing ! 1221: } // if (sti) ! 1222: nn->n_initializer = n_initializer = init; ! 1223: const_save = const_old; ! 1224: tbl = otbl; ! 1225: } ! 1226: else if (init == 0) // no initializer ! 1227: goto str; ! 1228: else if (cl->is_simple() ! 1229: // && cl->csu!=UNION // accept ANSIism ! 1230: && cl->csu!=ANON ! 1231: ) { // struct ! 1232: init = init->typ(tbl); ! 1233: if (nn->tp->check(init->tp,0)==0 ! 1234: && init->base==G_CM) ! 1235: (void) replace_temp(init,nn->address()); ! 1236: else { ! 1237: if (ansi_opt==0 ! 1238: && init->base==ILIST ! 1239: && cl->csu==UNION) ! 1240: error('s',"initialization of union withIL"); ! 1241: goto str; ! 1242: } ! 1243: } ! 1244: else if (init->base == ILIST) { // class or union ! 1245: error("cannotI%nWIrL",nn); ! 1246: } ! 1247: else { // bitwise copy ok? ! 1248: // possible to get here? ! 1249: init = init->typ(tbl); ! 1250: //error('d',"init22 %t %t",nn->tp,init->tp); ! 1251: if (nn->tp->check(init->tp,0)==0) { ! 1252: if (init->base==G_CM) ! 1253: (void) replace_temp(init,nn->address()); ! 1254: else ! 1255: goto str; ! 1256: } ! 1257: goto str; ! 1258: // else ! 1259: // error("cannotI%n:%k %s has noK",nn,cl->csu,cl->string); ! 1260: } ! 1261: break; ! 1262: } ! 1263: case VEC: ! 1264: t = Pvec(t)->typ; ! 1265: vec_seen++; ! 1266: goto lll; ! 1267: case TYPE: ! 1268: if (init==0 && Pbase(t)->b_const) { ! 1269: switch (n_scope) { ! 1270: case ARG: ! 1271: case 0: ! 1272: case PUBLIC: ! 1273: break; ! 1274: default: ! 1275: if (n_sto!=EXTERN && t->is_cl_obj()==0) error("uninitialized const%n",this); ! 1276: } ! 1277: } ! 1278: t = Pbase(t)->b_name->tp; ! 1279: goto lll; ! 1280: case RPTR: ! 1281: if (init) { ! 1282: if (nn->n_scope == ARG) break; ! 1283: if (Pptr(nn->tp)->memof) error("R toCM%n ofT%t illegal",nn,nn->tp); ! 1284: extern ref_initializer; ! 1285: ref_initializer++; ! 1286: init = init->typ(tbl); ! 1287: ref_initializer--; ! 1288: if (n_sto==STATIC ! 1289: && init->lval(0)==0 ! 1290: && fct_const==0) ! 1291: error("Ir for staticR%n not an lvalue",this); ! 1292: else ! 1293: nn->n_initializer = n_initializer = init = ref_init(Pptr(t),init,tbl); ! 1294: //error('d',"init %k %t",n_initializer->base,n_initializer->tp); ! 1295: nn->assign(); ! 1296: ! 1297: if (init->base==ILIST && init->e2==0) { ! 1298: new_list(init); ! 1299: list_check(nn,nn->tp,0); ! 1300: if (next_elem()) error(&where,"IrL too long"); ! 1301: } ! 1302: ! 1303: } ! 1304: else { ! 1305: switch (nn->n_scope) { ! 1306: default: ! 1307: if (n_sto == EXTERN) break; ! 1308: error("uninitializedR%n",this); ! 1309: case ARG: ! 1310: break; ! 1311: case PUBLIC: ! 1312: case 0: ! 1313: //III if (n_sto == STATIC) error("a staticM%n cannot be aR",this); ! 1314: break; ! 1315: } ! 1316: } ! 1317: goto stgg; ! 1318: default: ! 1319: str: ! 1320: //error('d',"str %n %t %k %t",this,tp,init?init->base:0,init?init->tp:0); ! 1321: if (init == 0) { ! 1322: switch (n_scope) { ! 1323: case ARG: ! 1324: case 0: ! 1325: case PUBLIC: ! 1326: break; ! 1327: default: ! 1328: if (n_sto!=EXTERN && t->tconst()) error("uninitialized const%n",this); ! 1329: } ! 1330: ! 1331: break; ! 1332: } ! 1333: ! 1334: const_save = const_save ! 1335: || n_scope==ARG ! 1336: || (t->tconst() && vec_const==0); ! 1337: ! 1338: nn->n_initializer = n_initializer = init = init->typ(tbl); ! 1339: if (const_save) PERM(init); ! 1340: nn->assign(); ! 1341: const_save = const_old; ! 1342: //error('d',"init2 %k %t",init->base,init->tp); ! 1343: switch (init->base) { ! 1344: case ILIST: ! 1345: if (init->e2) goto dfdf;//break; // pointer to member ! 1346: new_list(init); ! 1347: list_check(nn,nn->tp,0); ! 1348: if (next_elem()) error(&where,"IrL too long"); ! 1349: break; ! 1350: case STRING: ! 1351: { Ptype v = nn->tp; ! 1352: while (v->base == TYPE) v = Pbase(v)->b_name->tp; ! 1353: if (v->base==VEC && Pvec(v)->typ->base==CHAR) { ! 1354: int sz = Pvec(v)->size; ! 1355: int isz = Pvec(init->tp)->size; ! 1356: if (sz == 0) ! 1357: Pvec(v)->size = isz; ! 1358: else if (sz < isz) ! 1359: error(&where,"Ir too long (%d characters) for%n[%d]",isz,nn,sz); ! 1360: break; ! 1361: } ! 1362: // no break ! 1363: } ! 1364: default: ! 1365: dfdf: ! 1366: { Ptype nt = nn->tp; ! 1367: int ntc = Pbase(nt)->b_const; ! 1368: ! 1369: if (vec_seen) { ! 1370: error("badIr for array%n",nn); ! 1371: break; ! 1372: } ! 1373: tlx: ! 1374: switch (nt->base) { ! 1375: case TYPE: ! 1376: nt = Pbase(nt)->b_name->tp; ! 1377: ntc |= Pbase(nt)->b_const; ! 1378: goto tlx; ! 1379: case INT: ! 1380: case CHAR: ! 1381: case SHORT: ! 1382: case EOBJ: ! 1383: // if (init->base==ICON && init->tp==long_type) ! 1384: // error('w',"longIr constant for%k%n",nn->tp->base,nn); ! 1385: { Ptype t = init->tp; ! 1386: csi: ! 1387: switch (t->base) { ! 1388: case TYPE: ! 1389: t = Pbase(t)->b_name->tp; goto csi; ! 1390: case LONG: ! 1391: case FLOAT: ! 1392: case DOUBLE: ! 1393: case LDOUBLE: ! 1394: error('w',"%tIdW %t",nt,init->tp); ! 1395: } ! 1396: } ! 1397: // no break ! 1398: case LONG: ! 1399: if (Pbase(nt)->b_unsigned ! 1400: && init->base==UMINUS ! 1401: && init->e2->base==ICON) ! 1402: error('w',"negativeIr for unsigned%n",nn); ! 1403: if (ntc && scope!=ARG) { ! 1404: long i; ! 1405: Neval = 0; ! 1406: i = init->eval(); ! 1407: if (Neval == 0) { ! 1408: DEL(init); ! 1409: init = 0; /* invalid */ ! 1410: nn->n_evaluated = n_evaluated = 1; ! 1411: nn->n_val = n_val = i; ! 1412: nn->n_initializer = n_initializer = 0; ! 1413: goto stgg; ! 1414: } ! 1415: } ! 1416: break; ! 1417: case PTR: ! 1418: n_initializer = init = ptr_init(Pptr(nt),init,tbl); ! 1419: if (Pchecked) goto stgg; ! 1420: } ! 1421: ! 1422: { Pexpr x = try_to_coerce(nt,init,"initializer",tbl); ! 1423: if (x) { ! 1424: n_initializer = x; ! 1425: goto stgg; ! 1426: } ! 1427: } ! 1428: //error('d',"check %t %t %k",nt,init->tp,init->base); ! 1429: // if (nt->check(init->tp,ASSIGN)) { ! 1430: Pname c1 = nt->is_cl_obj(); ! 1431: Pname c2 = init->tp->is_cl_obj(); ! 1432: if (c1 ! 1433: && c2 ! 1434: && Pclass(c2->tp)->has_base(Pclass(c1->tp))) { ! 1435: init = new texpr(CAST,new ptr(PTR,nt),init->address()); ! 1436: init = init->typ(tbl); ! 1437: n_initializer = init = init->contents(); ! 1438: goto stgg; ! 1439: } ! 1440: ! 1441: if (nt->check(init->tp,ASSIGN)) { ! 1442: error("badIrT%t for%n (%tX)",init->tp,this,nn->tp); ! 1443: break; ! 1444: } ! 1445: } ! 1446: ! 1447: stgg: ! 1448: //error('d',"stgg %n init %k %t",this,init?init->base:0,init?init->tp:0); ! 1449: if (init && n_stclass==STATIC && need_sti(init)) { ! 1450: /* check if non-static variables are used */ ! 1451: int local = (0<lex_level); ! 1452: //error('d',"init %n %t local %d",nn,init->tp,local); ! 1453: if (local==0) need_sti(init,tbl); // save consts ! 1454: ! 1455: Pptr r = nn->tp->is_ref(); //III ! 1456: ! 1457: if (r) init = init->address(); ! 1458: init = new expr(ASSIGN,nn,init); ! 1459: //error('d',"init r %t: nn %n %t init %t",r,nn,nn->tp,init->tp); ! 1460: if (r) ! 1461: init->tp = nn->tp; ! 1462: else if (nn->tp!=init->tp) { // static member refs ! 1463: TOK t = nn->tp->set_const(0); //JJJ ! 1464: init = init->typ(tbl); ! 1465: nn->tp->set_const(t); //JJJ ! 1466: } ! 1467: ! 1468: if (local) { ! 1469: if (init->base != ASSIGN) error('s',"Ir for local static too complicated"); ! 1470: if (nn->n_sto == EXTERN) { ! 1471: error(&where,"Id local extern%n",this); ! 1472: init = 0; ! 1473: } ! 1474: else init->base = STAT_INIT; ! 1475: nn->n_initializer = n_initializer = init; ! 1476: ! 1477: } ! 1478: else { ! 1479: Pstmt ist = new estmt(SM,nn->where,init,0); ! 1480: // constructors for statics are executed in order ! 1481: ! 1482: if (st_ilist == 0) ! 1483: st_ilist = ist; ! 1484: else ! 1485: itail->s_list = ist; ! 1486: itail = ist; ! 1487: nn->n_initializer = n_initializer = init = 0; // suppress further processing ! 1488: nn->n_val = n_val = 1; ! 1489: } ! 1490: } ! 1491: ! 1492: ! 1493: } /* switch */ ! 1494: } /* block */ ! 1495: } /* default */ ! 1496: ! 1497: } /* switch */ ! 1498: ggg: ! 1499: //error('d',"ggg"); ! 1500: PERM(nn); ! 1501: switch (n_scope) { ! 1502: case FCT: ! 1503: nn->n_initializer = n_initializer; ! 1504: break; ! 1505: default: ! 1506: { Ptype t = nn->tp; ! 1507: px: ! 1508: PERM(t); ! 1509: switch (t->base) { ! 1510: case PTR: ! 1511: case RPTR: ! 1512: case VEC: t = Pptr(t)->typ; goto px; ! 1513: case TYPE: t = Pbase(t)->b_name->tp; goto px; ! 1514: case FCT: t = Pfct(t)->returns; goto px; /* args? */ ! 1515: } ! 1516: } ! 1517: } ! 1518: ! 1519: Cdcl = odcl; ! 1520: return nn; ! 1521: } ! 1522: ! 1523: /* ODI notes - ! 1524: delete bug catching code. ! 1525: deleting init twice. ! 1526: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.