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