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