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