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