|
|
1.1 ! root 1: /*ident "@(#)ctrans:src/dcl2.c 1.3.4.22" */ ! 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: dcl2.c: ! 11: ! 12: *************************************************************************/ ! 13: ! 14: #include "cfront.h" ! 15: #include "size.h" ! 16: ! 17: Pname conv_dominates(Pname on1, Pname on2) ! 18: /* ! 19: compare for duplicates and dominance: ! 20: ! 21: on1 and on2 are two conversion operator functions ! 22: return the the one that dominates the other (according to the ! 23: class hierarchy) otherwise 0 (0 thus indicats ambiguous conversion) ! 24: */ ! 25: { ! 26: Ptype r1 = Pfct(on1->tp)->returns; ! 27: Ptype r2 = Pfct(on2->tp)->returns; ! 28: //error('d',"conv_dominates(%n,%n)",on1,on2); ! 29: if (r1==r2 || r1->check(r2,0)==0) return on1; ! 30: Pptr p1 = r1->is_ptr_or_ref(); ! 31: Pptr p2 = r2->is_ptr_or_ref(); ! 32: if (p1 && p2) { ! 33: Pname cn1 = p1->typ->is_cl_obj(); ! 34: Pname cn2 = p2->typ->is_cl_obj(); ! 35: if (cn1 && cn2) { ! 36: // is_cl_obj() returns b_name ! 37: // Pclass c1 = Pclass(Pbase(cn1->tp)->b_name->tp); ! 38: // Pclass c2 = Pclass(Pbase(cn2->tp)->b_name->tp); ! 39: Pclass c1 = Pclass(cn1->tp); ! 40: Pclass c2 = Pclass(cn2->tp); ! 41: if (c1 && c2) { ! 42: if (c1==c2 || c1->has_base(c2)) ! 43: return on1; ! 44: else if (c2->has_base(c1)) ! 45: return on2; ! 46: } ! 47: } ! 48: } ! 49: return 0; ! 50: } ! 51: ! 52: ! 53: Pstmt curr_loop; ! 54: Pstmt curr_switch; ! 55: Pblock curr_block; ! 56: ! 57: void stmt::reached() ! 58: { ! 59: register Pstmt ss = s_list; ! 60: ! 61: if (ss == 0) return; ! 62: ! 63: switch (ss->base) { ! 64: case LABEL: ! 65: case CASE: ! 66: case DEFAULT: ! 67: break; ! 68: default: ! 69: error('w',"S after%k not reached",base); ! 70: for (; ss; ss=ss->s_list) { // delete unreacheable code ! 71: switch (ss->base) { ! 72: case LABEL: ! 73: case CASE: ! 74: case DEFAULT: // reachable ! 75: s_list = ss; ! 76: return; ! 77: case DCL: // the dcl may be used later ! 78: // keep to avoid cascading errors ! 79: case IF: ! 80: case DO: ! 81: case WHILE: ! 82: case SWITCH: ! 83: case FOR: ! 84: case BLOCK: // may hide a label ! 85: s_list = ss; ! 86: return; ! 87: } ! 88: } ! 89: s_list = 0; ! 90: } ! 91: } ! 92: ! 93: bit arg_err_suppress; ! 94: ! 95: Pexpr check_cond(Pexpr e, TOK b, Ptable tbl) ! 96: { ! 97: //error('d',"check_cond(%k %k) tbl %d",e->base,b,tbl); ! 98: Pname cn; ! 99: ! 100: if (e == dummy) error("empty condition for %k",b); ! 101: ! 102: if (cn = e->tp->is_cl_obj()) { ! 103: Pclass cl = Pclass(cn->tp); ! 104: int i = 0; ! 105: Pname found = 0; ! 106: for (Pname on = cl->conv; on; on=on->n_list) { ! 107: Pfct f = Pfct(on->tp); ! 108: Ptype t = f->returns; ! 109: xx: ! 110: switch (t->base) { ! 111: case TYPE: ! 112: t = Pbase(t)->b_name->tp; ! 113: goto xx; ! 114: case FLOAT: ! 115: case DOUBLE: ! 116: case LDOUBLE: ! 117: case PTR: ! 118: if (b == DEREF) break; ! 119: case CHAR: ! 120: case SHORT: ! 121: case INT: ! 122: case LONG: ! 123: case EOBJ: ! 124: // if (found==0 || found->tp->check(on->tp,0)) { ! 125: //error('d',"found %n on %n",found,on); ! 126: { Pname xx = found; ! 127: if (found == 0) { ! 128: i = 1; ! 129: found = on; ! 130: } ! 131: else if ((found = conv_dominates(found,on)) == 0) { ! 132: i = 2; ! 133: found = on; ! 134: error("two conversions for%nO in%kE: %n and %n",cn,b,xx,on); ! 135: return e; ! 136: } ! 137: } ! 138: } ! 139: } ! 140: //error('d',"i %d",i); ! 141: switch (i) { ! 142: case 0: ! 143: error("%nO in%kE",cn,b); ! 144: return e; ! 145: /* ! 146: case 1: ! 147: { Pname xx = new name(found->string); ! 148: Pref r = new ref(DOT,e,xx); ! 149: Pexpr rr = r->typ(tbl); ! 150: Pexpr c = new expr(G_CALL,rr,0); ! 151: ! 152: if (e->lval(0)) { ! 153: // Pref r = new ref(DOT,e,found); ! 154: // r->tp = found->tp; ! 155: // Pexpr c = new expr(G_CALL,r,0); ! 156: // c->fct_name = found; ! 157: return c->typ(tbl); ! 158: } ! 159: else { // (temp=init,temp.coerce()) ! 160: Pname tmp = make_tmp('U',e->tp,tbl); ! 161: Pexpr ass = init_tmp(tmp,e,tbl); ! 162: // Pref r = new ref(DOT,tmp,found); ! 163: // Pexpr rr = r->typ(tbl); ! 164: // Pexpr c = new expr(G_CALL,rr,0); ! 165: // c->fct_name = found; ! 166: ass = new expr(CM,ass,c); ! 167: return ass->typ(tbl); ! 168: } ! 169: } ! 170: */ ! 171: case 1: ! 172: { Pname xx = new name(found->string); ! 173: Pexpr c; ! 174: ! 175: if (e->lval(0)) { ! 176: Pref r = new ref(DOT,e,xx); ! 177: Pexpr rr = r->typ(tbl); ! 178: c = new expr(G_CALL,rr,0); ! 179: } ! 180: else { // (temp=init,temp.coerce()) ! 181: Pname tmp = make_tmp('U',e->tp,tbl); ! 182: Pexpr ass = init_tmp(tmp,e,tbl); ! 183: Pref r = new ref(DOT,tmp,xx); ! 184: Pexpr rr = r->typ(tbl); ! 185: c = new expr(G_CALL,rr,0); ! 186: c = new expr(CM,ass,c); ! 187: } ! 188: return c->typ(tbl); ! 189: } ! 190: // default: ! 191: // error("%d possible conversions for%nO in%kE",i,cn,b); ! 192: // return e; ! 193: } ! 194: ! 195: } ! 196: if (e->tp->memptr()) { ! 197: e = new mdot("i",e); ! 198: e->i1 = 9; ! 199: e = new expr(NE,e,zero); ! 200: } ! 201: else if (e->tp->num_ptr(b) == FCT) ! 202: error("%k(F)",b); ! 203: return e; ! 204: } ! 205: ! 206: extern int catch_delete_bugs; ! 207: ! 208: void stmt::dcl() ! 209: /* ! 210: typecheck statement "this" in scope "curr_block->tbl" ! 211: */ ! 212: { ! 213: Pstmt ss; ! 214: Pname n; ! 215: Pname nn; ! 216: Pstmt ostmt = Cstmt; ! 217: ! 218: if(permanent == 3 && catch_delete_bugs) ! 219: error ('i', "stmt::dcl of a deleted stmt."); ! 220: ! 221: for (ss=this; ss; ss=ss->s_list) { ! 222: Pstmt old_loop, old_switch; ! 223: Cstmt = ss; ! 224: Ptable tbl = curr_block->memtbl; ! 225: //error('d',"stmt::dcl %k",ss->base); ! 226: switch (ss->base) { ! 227: case BREAK: ! 228: inline_restr |= 16; ! 229: if (curr_loop==0 && curr_switch==0) ! 230: error("break not in loop or switch"); ! 231: ss->reached(); ! 232: break; ! 233: ! 234: case CONTINUE: ! 235: inline_restr |= 32; ! 236: if (curr_loop == 0) error("continue not in loop"); ! 237: ss->reached(); ! 238: break; ! 239: ! 240: case DEFAULT: ! 241: if (curr_switch == 0) { ! 242: error("default not in switch"); ! 243: break; ! 244: } ! 245: if (curr_switch->has_default) error("two defaults in switch"); ! 246: curr_switch->has_default = ss; ! 247: ss->s->s_list = ss->s_list; ! 248: ss->s_list = 0; ! 249: ss->s->dcl(); ! 250: break; ! 251: ! 252: case SM: ! 253: { if (ss->e ==0) break; ! 254: TOK b = ss->e->base; ! 255: switch (b) { ! 256: case DUMMY: ! 257: ss->e = 0; ! 258: break; ! 259: // check for unused results ! 260: // don't check operators that are likely ! 261: // to be overloaded to represent "actions": ! 262: // ! ~ < <= > >= << >> ! 263: case EQ: ! 264: case NE: ! 265: case PLUS: ! 266: case MINUS: ! 267: case REF: ! 268: case DOT: ! 269: case MUL: ! 270: case DIV: ! 271: case ADDROF: ! 272: case AND: ! 273: case OR: ! 274: case ER: ! 275: case DEREF: ! 276: case ANDAND: ! 277: case OROR: ! 278: case NAME: ! 279: case VALUE: ! 280: if (ss->e->tp) break; // avoid looking at generated code ! 281: ss->e = ss->e->typ(tbl); ! 282: if (ss->e->base == CALL) break; ! 283: if (ss->e->tp->base != VOID) { ! 284: error('w',"result of%kE not used",b); ! 285: if (ss->e->not_simple()==0) ss->e = dummy; ! 286: } ! 287: break; ! 288: default: ! 289: ss->e = ss->e->typ(tbl); ! 290: } ! 291: break; ! 292: } ! 293: case RETURN: ! 294: { Pname fn = cc->nof; ! 295: Pfct f = Pfct(fn->tp); ! 296: Ptype rt = f->returns; ! 297: Pexpr v = ss->e; ! 298: //error('d',"rt %t",rt); ! 299: if (v != dummy) { ! 300: while (rt->base == TYPE) rt = Pbase(rt)->b_name->tp; ! 301: extern ref_initializer; ! 302: if (rt->base == RPTR) { ! 303: ref_initializer++; ! 304: v = v->typ(tbl); ! 305: ref_initializer--; ! 306: } else ! 307: v = v->typ(tbl); ! 308: ! 309: if (fn->n_oper==CTOR ! 310: || fn->n_oper==DTOR ! 311: || (rt->base==VOID && v->tp!=void_type)) { ! 312: error("unexpected return value"); ! 313: // refuse to return the value: ! 314: ss->e = dummy; ! 315: } ! 316: else { ! 317: lx: ! 318: switch (rt->base) { ! 319: case TYPE: ! 320: rt = Pbase(rt)->b_name->tp; ! 321: goto lx; ! 322: case RPTR: ! 323: switch (v->base) { ! 324: case NAME: ! 325: if (Pname(v)->n_scope==FCT ! 326: || Pname(v)->n_scope==ARG) ! 327: error('w',"R to localV returned"); ! 328: break; ! 329: case ICON: ! 330: case CCON: ! 331: case FCON: ! 332: case STRING: ! 333: if (Pptr(rt)->typ->tconst()==0) ! 334: error('w',"R to literal returned"); ! 335: } ! 336: v = ref_init(Pptr(rt),v,tbl); ! 337: if (v->base==G_CM ! 338: && v->e2->base==G_ADDROF ! 339: && v->e2->e2->base==NAME) ! 340: error('w',"R to temporary returned (return value is not lvalue or of wrongT)"); ! 341: case ANY: ! 342: break; ! 343: case COBJ: ! 344: if (v->base == DEREF) { ! 345: Pexpr v1 = v->e1; ! 346: if (v1->base==CAST) { ! 347: Pexpr v2 = v1->e1; ! 348: if (v2->base == G_CM) { // *(T)(e1,e2) => (e1,*(T)e2) ! 349: Pexpr v3 = v2->e2; ! 350: v2->e2 = v; ! 351: v2->tp = v->tp; ! 352: v = v2; ! 353: v1->e1 = v3; ! 354: } ! 355: } ! 356: } ! 357: if (f->f_result) { ! 358: if (v->base==G_CM && rt->check(v->tp,0/*ASSIGN*/)==0) ! 359: v = replace_temp(v,f->f_result); ! 360: else { ! 361: v = class_init(f->f_result->contents(),rt,v,tbl); ! 362: Pname rcn = rt->is_cl_obj(); ! 363: if (Pclass(rcn->tp)->has_itor()==0) { ! 364: // can happen for virtuals and for user defined conversions ! 365: v->tp = rt; ! 366: v = new expr(ASSIGN,f->f_result->contents(),v); ! 367: v->tp = rt; ! 368: } ! 369: } ! 370: } ! 371: else ! 372: v = class_init(0,rt,v,tbl); ! 373: break; ! 374: case PTR: ! 375: { Pexpr x = v; ! 376: v = ptr_init(Pptr(rt),v,tbl); ! 377: if (v->base == ADDROF ! 378: && v->e2->base == NAME ! 379: && Pname(v->e2)->n_stclass == AUTO) ! 380: error('w',"P to local variable%n returned",Pname(v->e2)); ! 381: // if (v==x ||v->e2==x) goto def; ! 382: if (Pchecked == 0) goto def; ! 383: goto ret_save; ! 384: // break; ! 385: } ! 386: case INT: ! 387: case CHAR: ! 388: case LONG: ! 389: case SHORT: ! 390: if (Pbase(rt)->b_unsigned ! 391: && v->base==UMINUS ! 392: && v->e2->base==ICON) ! 393: error('w',"negative retured fromF returning unsigned"); ! 394: default: ! 395: def: ! 396: { ! 397: Pexpr x = try_to_coerce(rt,v,"return value",tbl); ! 398: if (x) ! 399: v = x; ! 400: else if (rt->check(v->tp,ASSIGN)) ! 401: error("bad return valueT for%n:%t (%tX)",fn,v->tp,rt); ! 402: } ! 403: ! 404: } ! 405: ret_save: ! 406: ss->ret_tp = rt; ! 407: ss->e = v; ! 408: } ! 409: } ! 410: else { ! 411: if (rt->base != VOID) error("return valueX"); ! 412: } ! 413: ss->reached(); ! 414: break; ! 415: } ! 416: ! 417: case DO: // in DO the stmt is before the test ! 418: inline_restr |= 8; ! 419: old_loop = curr_loop; ! 420: curr_loop = ss; ! 421: if (ss->s->base == DCL) error("D as onlyS in do-loop"); ! 422: ss->s->dcl(); ! 423: ss->e = ss->e->typ(tbl); ! 424: ss->e = check_cond(ss->e,DO,tbl); ! 425: curr_loop = old_loop; ! 426: break; ! 427: ! 428: case WHILE: ! 429: inline_restr |= 8; ! 430: old_loop = curr_loop; ! 431: curr_loop = ss; ! 432: ss->e = ss->e->typ(tbl); ! 433: ss->e = check_cond(ss->e,WHILE,tbl); ! 434: if (ss->s->base == DCL) error("D as onlyS in while-loop"); ! 435: ss->s->dcl(); ! 436: curr_loop = old_loop; ! 437: break; ! 438: ! 439: case SWITCH: ! 440: { int ne = 0; ! 441: inline_restr |= 4; ! 442: old_switch = curr_switch; ! 443: curr_switch = ss; ! 444: ss->e = ss->e->typ(tbl); ! 445: ss->e = check_cond(ss->e,SWITCH,tbl); ! 446: if (ss->s->base == DCL) error("D as onlyS in switchS"); ! 447: { Ptype tt = ss->e->tp; ! 448: sii: ! 449: switch (tt->base) { ! 450: case TYPE: ! 451: tt = Pbase(tt)->b_name->tp; goto sii; ! 452: case EOBJ: ! 453: ne = Penum(Pbase(tt)->b_name->tp)->no_of_enumerators; ! 454: case ZTYPE: ! 455: case ANY: ! 456: case CHAR: ! 457: case SHORT: ! 458: case INT: ! 459: case LONG: ! 460: case FIELD: ! 461: break; ! 462: default: ! 463: error("%t switchE",ss->e->tp); ! 464: } ! 465: } ! 466: ss->s->dcl(); ! 467: if (ne) { /* see if the number of cases is "close to" ! 468: but not equal to the number of enumerators ! 469: */ ! 470: int i = 0; ! 471: Pstmt cs; ! 472: for (cs=ss->case_list; cs; cs=cs->case_list) i++; ! 473: if (i && i!=ne) { ! 474: if (ne < i) { ! 475: ee: error('w',"switch (%t)W %d cases (%d enumerators)",ss->e->tp,i,ne); ! 476: } ! 477: else { ! 478: switch (ne-i) { ! 479: case 1: if (3<ne) goto ee; ! 480: case 2: if (7<ne) goto ee; ! 481: case 3: if (23<ne) goto ee; ! 482: case 4: if (60<ne) goto ee; ! 483: case 5: if (99<ne) goto ee; ! 484: } ! 485: } ! 486: } ! 487: } ! 488: curr_switch = old_switch; ! 489: break; ! 490: } ! 491: case CASE: ! 492: if (curr_switch == 0) { ! 493: error("case not in switch"); ! 494: break; ! 495: } ! 496: ss->e = ss->e->typ(tbl); ! 497: ss->e->tp->num_ptr(CASE); ! 498: { Ptype tt = ss->e->tp; ! 499: iii: ! 500: switch (tt->base) { ! 501: case TYPE: ! 502: tt = Pbase(tt)->b_name->tp; goto iii; ! 503: case ZTYPE: ! 504: case ANY: ! 505: case CHAR: ! 506: case SHORT: ! 507: case INT: ! 508: case LONG: ! 509: case EOBJ: ! 510: Neval = 0; ! 511: long i = ss->e->eval(); ! 512: if (Neval == 0) { ! 513: Pstmt cs; ! 514: if (largest_int<i) error("long case value"); ! 515: for (cs=curr_switch->case_list; cs; cs=cs->case_list) { ! 516: if (cs->case_value == i) error("case %d used twice in switch",i); ! 517: } ! 518: ss->case_value = int(i); ! 519: ss->case_list = curr_switch->case_list; ! 520: curr_switch->case_list = ss; ! 521: } ! 522: else ! 523: error("bad case label: %s",Neval); ! 524: break; ! 525: default: ! 526: error("%t caseE",ss->e->tp); ! 527: } ! 528: } ! 529: // if (1) { ! 530: // Neval = 0; ! 531: // long i = ss->e->eval(); ! 532: // if (Neval == 0) { ! 533: // Pstmt cs; ! 534: // if (largest_int<i) error("long case value"); ! 535: // for (cs=curr_switch->case_list; cs; cs=cs->case_list) { ! 536: // if (cs->case_value == i) error("case %d used twice in switch",i); ! 537: // } ! 538: // ss->case_value = int(i); ! 539: // ss->case_list = curr_switch->case_list; ! 540: // curr_switch->case_list = ss; ! 541: // } ! 542: // else ! 543: // error("bad case label: %s",Neval); ! 544: // } ! 545: if (ss->s->s_list) error('i',"case%k",ss->s->s_list->base); ! 546: ss->s->s_list = ss->s_list; ! 547: ss->s_list = 0; ! 548: ss->s->dcl(); ! 549: break; ! 550: ! 551: case GOTO: ! 552: inline_restr |= 2; ! 553: ss->reached(); ! 554: case LABEL: ! 555: /* Insert label in function mem table; ! 556: labels have function scope. ! 557: */ ! 558: n = ss->d; ! 559: nn = cc->ftbl->insert(n,LABEL); ! 560: ! 561: /* Set a ptr to the mem table corresponding to the scope ! 562: in which the label actually occurred. This allows the ! 563: processing of goto's in the presence of ctors and dtors ! 564: */ ! 565: if (ss->base == LABEL) { ! 566: nn->n_realscope = curr_block->memtbl; ! 567: inline_restr |= 1; ! 568: } ! 569: ! 570: if (Nold) { ! 571: if (ss->base == LABEL) { ! 572: if (nn->n_initializer) error("twoDs of label%n",n); ! 573: nn->n_initializer = (Pexpr)1; ! 574: } ! 575: if (n != nn) ss->d = nn; ! 576: } ! 577: else { ! 578: if (ss->base == LABEL) nn->n_initializer = (Pexpr)1; ! 579: nn->where = ss->where; ! 580: } ! 581: if (ss->base == GOTO) ! 582: nn->use(); ! 583: else { ! 584: if (ss->s->s_list) error('i',"label%k",ss->s->s_list->base); ! 585: ss->s->s_list = ss->s_list; ! 586: ss->s_list = 0; ! 587: nn->assign(); ! 588: } ! 589: if (ss->s) ss->s->dcl(); ! 590: break; ! 591: ! 592: case IF: ! 593: { ! 594: Pexpr ee = ss->e->typ(tbl); ! 595: if (ee->base == ASSIGN) { ! 596: Neval = 0; ! 597: (void)ee->e2->eval(); ! 598: if (Neval == 0) ! 599: error('w',"constant assignment in condition"); ! 600: } ! 601: ss->e = ee = check_cond(ee,IF,tbl); ! 602: ! 603: if (ss->s->base == DCL) error("D as onlyS after `if'"); ! 604: ! 605: // pointer to member returns with a tp set to 0 ! 606: if ( ee->tp ) switch (ee->tp->base) { ! 607: case INT: ! 608: case EOBJ: ! 609: case ZTYPE: ! 610: { long i; ! 611: Neval = 0; ! 612: i = ee->eval(); ! 613: ! 614: if (Neval == 0) { ! 615: Pstmt sl = ss->s_list; ! 616: if (i) { ! 617: DEL(ss->else_stmt); ! 618: ss->s->dcl(); ! 619: *ss = *ss->s; ! 620: } ! 621: else { ! 622: DEL(ss->s); ! 623: if (ss->else_stmt) { ! 624: ss->else_stmt->dcl(); ! 625: *ss = *ss->else_stmt; ! 626: } ! 627: else { ! 628: ss->base = SM; ! 629: ss->e = dummy; ! 630: ss->s = 0; ! 631: } ! 632: } ! 633: ss->s_list = sl; ! 634: continue; ! 635: } ! 636: } ! 637: } ! 638: ss->s->dcl(); ! 639: if (ss->else_stmt) { ! 640: if (ss->else_stmt->base == DCL) error("D as onlyS after `else'"); ! 641: ss->else_stmt->dcl(); ! 642: } ! 643: break; ! 644: } ! 645: case FOR: ! 646: inline_restr |= 8; ! 647: old_loop = curr_loop; ! 648: curr_loop = ss; ! 649: if (ss->for_init) { ! 650: Pstmt fi = ss->for_init; ! 651: switch (fi->base) { ! 652: case SM: ! 653: if (fi->e == dummy) { ! 654: ss->for_init = 0; ! 655: break; ! 656: } ! 657: default: ! 658: fi->dcl(); ! 659: break; ! 660: case DCL: ! 661: // if () ! 662: // { ! 663: // // for (dcl; e1; e2) stmt1 stmt2 ! 664: // // => { dcl; for( ; e1; e2) stmt1 } stmt2 ! 665: // ss->base = BLOCK; ! 666: // ss->d = fi->d; ! 667: // ss->s = new forstmt(ss->where,new estmt(SM,ss->where,dummy,0),ss->e,ss->e2,ss->s); ! 668: // Pblock(ss)->dcl(tbl); ! 669: // continue; ! 670: // } ! 671: // else { ! 672: fi->dcl(); ! 673: switch (fi->base) { ! 674: case BLOCK: ! 675: { ! 676: // { ... for( { a } b ; c) d ; e } ! 677: // => { ... { a for ( ; b ; c) d ; e }} ! 678: Pstmt tmp = new stmt (SM,curloc,0); ! 679: *tmp = *ss; // tmp = for ! 680: tmp->for_init = 0; ! 681: *ss = *fi; // ss = { } ! 682: if (ss->s) ! 683: ss->s->s_list = tmp; ! 684: else ! 685: ss->s = tmp; ! 686: curr_block = Pblock(ss); ! 687: tbl = curr_block->memtbl; ! 688: Cstmt = ss = tmp; // rest of for and s_list ! 689: break; ! 690: } ! 691: } ! 692: // } ! 693: ! 694: } ! 695: } ! 696: if (ss->e == dummy) ! 697: ss->e = 0; ! 698: else { ! 699: ss->e = ss->e->typ(tbl); ! 700: ss->e = check_cond(ss->e,FOR,tbl); ! 701: } ! 702: if (ss->s->base == DCL) error("D as onlyS in for-loop"); ! 703: ss->s->dcl(); ! 704: ss->e2 = (ss->e2 == dummy) ? 0 : ss->e2->typ(tbl); ! 705: curr_loop = old_loop; ! 706: break; ! 707: ! 708: case DCL: /* declaration after statement */ ! 709: { ! 710: /* collect all the contiguous DCL nodes from the ! 711: head of the s_list. find the next statement ! 712: */ ! 713: int non_trivial = 0; ! 714: int count = 0; ! 715: Pname tail = ss->d; ! 716: for (Pname nn=tail; nn; nn=nn->n_list) { ! 717: // find tail; ! 718: // detect non-trivial declarations ! 719: count++; ! 720: ! 721: if (nn->n_list) tail = nn->n_list; ! 722: Pname n = tbl->look(nn->string,0); ! 723: ! 724: if (n && n->n_table==tbl) non_trivial = 2; ! 725: if (non_trivial == 2) continue; ! 726: if ((nn->n_sto==STATIC && nn->tp->base!=FCT) ! 727: || nn->tp->is_ref() ! 728: || (nn->tp->tconst() && fct_const==0)) { ! 729: non_trivial = 2; ! 730: continue; ! 731: } ! 732: ! 733: Pexpr in = nn->n_initializer; ! 734: if (in) ! 735: switch (in->base) { ! 736: case ILIST: ! 737: case STRING: ! 738: non_trivial = 2; ! 739: continue; ! 740: default: ! 741: non_trivial = 1; ! 742: } ! 743: Pname cln = nn->tp->is_cl_obj(); ! 744: if (cln == 0) cln = cl_obj_vec; ! 745: if (cln == 0) continue; ! 746: if (Pclass(cln->tp)->has_ctor()) { ! 747: non_trivial = 2; ! 748: continue; ! 749: } ! 750: if (Pclass(cln->tp)->has_dtor()) non_trivial = 2; ! 751: } ! 752: ! 753: while( ss->s_list && ss->s_list->base==DCL ) { ! 754: Pstmt sx = ss->s_list; ! 755: tail = tail->n_list = sx->d; // add to tail ! 756: for (nn=sx->d; nn; nn=nn->n_list) { ! 757: // find tail; ! 758: // detect non-trivial declarations ! 759: count++; ! 760: if (nn->n_list) tail = nn->n_list; ! 761: Pname n = tbl->look(nn->string,0); ! 762: if (n && n->n_table==tbl) non_trivial = 2; ! 763: if (non_trivial == 2) continue; ! 764: if ((nn->n_sto==STATIC && nn->tp->base!=FCT) ! 765: || nn->tp->is_ref() ! 766: || (nn->tp->tconst() && fct_const==0)) { ! 767: non_trivial = 2; ! 768: continue; ! 769: } ! 770: Pexpr in = nn->n_initializer; ! 771: if (in) ! 772: switch (in->base) { ! 773: case ILIST: ! 774: case STRING: ! 775: non_trivial = 2; ! 776: continue; ! 777: } ! 778: non_trivial = 1; ! 779: Pname cln = nn->tp->is_cl_obj(); ! 780: if (cln == 0) cln = cl_obj_vec; ! 781: if (cln == 0) continue; ! 782: if (Pclass(cln->tp)->has_ctor()) { ! 783: non_trivial = 2; ! 784: continue; ! 785: } ! 786: if (Pclass(cln->tp)->has_dtor()) continue; ! 787: } ! 788: ss->s_list = sx->s_list; ! 789: /* delete sx; */ ! 790: } ! 791: ! 792: Pstmt next_st = ss->s_list; ! 793: if (non_trivial==2 // must ! 794: || (non_trivial==1 // might ! 795: && ( curr_block->own_tbl==0 // why not? ! 796: || inline_restr&3 /* label seen */) ! 797: ) ! 798: ) { ! 799: if (curr_switch && non_trivial==2) { ! 800: Pstmt cs = curr_switch->case_list; ! 801: Pstmt ds = curr_switch->has_default; ! 802: Pstmt bl; ! 803: if (cs == 0) ! 804: bl = ds; ! 805: else if (ds == 0) ! 806: bl = cs; ! 807: else if (cs->where.line<ds->where.line) ! 808: bl = ds; ! 809: else ! 810: bl = cs; ! 811: ! 812: if ((bl==0 || bl->s->base!=BLOCK) && curr_switch->s->memtbl==tbl) ! 813: error('s',"non trivialD in switchS (try enclosing it in a block)"); ! 814: } ! 815: ! 816: /* Create a new block, ! 817: put all the declarations at the head, ! 818: and the remainder of the slist as the ! 819: statement list of the block. ! 820: */ ! 821: ss->base = BLOCK; ! 822: ! 823: /* check that there are no redefinitions since the last ! 824: "real" (user-written, non-generated) block ! 825: */ ! 826: for( nn=ss->d; nn; nn=nn->n_list ) { ! 827: Pname n; ! 828: if( curr_block->own_tbl ! 829: && (n=curr_block->memtbl->look(nn->string,0)) ! 830: && n->n_table->real_block==curr_block->memtbl->real_block ! 831: && n->tp->base!=FCT && n->tp->base!=OVERLOAD ! 832: && nn->lex_level == n->lex_level ) ! 833: error("twoDs of%n",n); ! 834: } ! 835: ! 836: /* attach the remainder of the s_list ! 837: as the statement part of the block. ! 838: */ ! 839: ss->s = next_st; ! 840: ss->s_list = 0; ! 841: ! 842: /* create the table in advance, in order to set the ! 843: real_block ptr to that of the enclosing table ! 844: */ ! 845: ss->memtbl = new table(count+4,tbl,0); ! 846: ss->memtbl->real_block = curr_block->memtbl->real_block; ! 847: Pblock(ss)->dcl(ss->memtbl); ! 848: } ! 849: else { /* to reduce the number of symbol tables, ! 850: do not make a new block, ! 851: instead insert names in enclosing block, ! 852: and make the initializers into expression ! 853: statements. ! 854: */ ! 855: Pstmt sss = ss; ! 856: for( nn=ss->d; nn; nn=nn->n_list ) { ! 857: Pname n; ! 858: //error('d',"nn %n",nn); ! 859: if( curr_block->own_tbl ! 860: && (n=curr_block->memtbl->look(nn->string,0)) ! 861: && n->n_table->real_block==curr_block->memtbl->real_block ! 862: && n->tp->base!=FCT && n->tp->base!=OVERLOAD ! 863: && nn->lex_level == n->lex_level ) ! 864: { ! 865: printf( "\ndump tables: bl_level: %d", bl_level ); ! 866: /* ! 867: //extern void display_table( Ptable,int=0 );display_table(curr_block->memtbl); ! 868: //extern void display_name( Pname ); display_name( nn ); display_name(n); ! 869: */ ! 870: error("twoDs of%n",n); ! 871: } ! 872: //error("twoDs of%n",n); ! 873: /*Pname */n = nn->dcl(tbl,FCT); ! 874: ! 875: if (n == 0) { ! 876: if (ss) { ! 877: ss->base = SM; ! 878: ss->e = 0; ! 879: } ! 880: continue; ! 881: } ! 882: ! 883: Pexpr in = n->n_initializer; ! 884: n->n_initializer = 0; ! 885: ! 886: if (ss) { ! 887: sss->base = SM; ! 888: ss = 0; ! 889: } ! 890: else ! 891: sss = sss->s_list = new estmt(SM,sss->where,0,0); ! 892: if (in) { ! 893: switch (in->base) { ! 894: case G_CALL: /* constructor? */ ! 895: { ! 896: Pname fn = in->fct_name; ! 897: if (fn && fn->n_oper==CTOR) break; ! 898: } ! 899: default: ! 900: in = new expr(ASSIGN,n,in); ! 901: in->tp = n->tp; ! 902: } ! 903: // sss->e = in->typ(tbl); ! 904: sss->e = in; ! 905: } ! 906: else ! 907: sss->e = dummy; ! 908: } ! 909: ! 910: ss = sss; ! 911: ss->s_list = next_st; ! 912: } ! 913: break; ! 914: } ! 915: ! 916: case BLOCK: ! 917: Pblock(ss)->dcl(tbl); ! 918: break; ! 919: ! 920: case ASM: ! 921: /* save string */ ! 922: { ! 923: char* s = (char*)ss->e; ! 924: int ll = strlen(s); ! 925: char* s2 = new char[ll+1]; ! 926: strcpy(s2,s); ! 927: ss->e = Pexpr(s2); ! 928: break; ! 929: } ! 930: default: ! 931: error('i',"badS(%p %d)",ss,ss->base); ! 932: } ! 933: } ! 934: Cstmt = ostmt; ! 935: } ! 936: ! 937: extern int in_class_dcl; ! 938: void block::dcl(Ptable tbl) ! 939: /* ! 940: Note: for a block without declarations memtbl denotes the table ! 941: for the enclosing scope. ! 942: A function body has its memtbl created by fct::dcl(). ! 943: */ ! 944: { ! 945: int bit_old = bit_offset; ! 946: int byte_old = byte_offset; ! 947: int max_old = max_align; ! 948: Pblock block_old = curr_block; ! 949: ! 950: if (base != BLOCK) error('i',"block::dcl(%d)",base); ! 951: ! 952: curr_block = this; ! 953: //error('d',"block %k %k",d?d->base:0,s?s->base:0); ! 954: if (d) { ! 955: own_tbl = 1; ! 956: if (memtbl == 0) { ! 957: int nmem = d->no_of_names()+4; ! 958: memtbl = new table(nmem,tbl,0); ! 959: memtbl->real_block = this; ! 960: /* this is a "real" block from the ! 961: source text, and not one created by DCL's ! 962: inside a block. */ ! 963: } ! 964: else ! 965: if (memtbl != tbl) error('i',"block::dcl(?)"); ! 966: ! 967: Pname nx; ! 968: for (Pname n=d; n; n=nx) { ! 969: nx = n->n_list; ! 970: n->dcl(memtbl,FCT); ! 971: switch (n->tp->base) { ! 972: case CLASS: ! 973: case ANON: ! 974: case ENUM: ! 975: break; ! 976: default: ! 977: delete n; ! 978: } ! 979: } ! 980: } ! 981: else ! 982: memtbl = tbl; ! 983: ! 984: if (s) { ! 985: Pname odcl = Cdcl; ! 986: Pname m; ! 987: int i; ! 988: ! 989: s->dcl(); ! 990: ! 991: if (own_tbl) ! 992: for (m=memtbl->get_mem(i=1); m; m=memtbl->get_mem(++i)) { ! 993: Ptype t = m->tp; ! 994: ! 995: if (in_class_dcl) m->lex_level -= 1; ! 996: ! 997: if (t == 0) { ! 998: if (m->n_assigned_to == 0) ! 999: error("label %sU",m->string); ! 1000: if (m->n_used == 0) ! 1001: error('w',"label %s not used", m->string); ! 1002: continue; ! 1003: } ! 1004: ll: ! 1005: switch (t->base) { ! 1006: case TYPE: t = Pbase(t)->b_name->tp; goto ll; ! 1007: case CLASS: ! 1008: case ANON: ! 1009: case ENUM: ! 1010: case FCT: ! 1011: case VEC: continue; ! 1012: } ! 1013: ! 1014: if (m->n_addr_taken == 0) { ! 1015: if (m->n_used) { ! 1016: if (m->n_assigned_to) { ! 1017: } ! 1018: else { ! 1019: switch (m->n_scope) { ! 1020: case FCT: ! 1021: Cdcl = m; ! 1022: if (m->string[0] != '_' && m->string[1] != '_' ) ! 1023: error('w',&m->where,"%n used but not set",m); ! 1024: } ! 1025: } ! 1026: } ! 1027: else { ! 1028: if (m->n_assigned_to) { ! 1029: } ! 1030: else if (m->string[0]!='_' || m->string[1]!='_') { ! 1031: switch (m->n_scope) { ! 1032: case ARG: ! 1033: case FCT: ! 1034: Cdcl = m; ! 1035: error('w',&m->where,"%n not used",m); ! 1036: } ! 1037: } ! 1038: } ! 1039: } ! 1040: } ! 1041: Cdcl = odcl; ! 1042: } ! 1043: ! 1044: d = 0; ! 1045: ! 1046: if (bit_offset) byte_offset += SZ_WORD; ! 1047: bit_offset = bit_old; ! 1048: byte_offset = byte_old; ! 1049: curr_block = block_old; ! 1050: } ! 1051: ! 1052: extern int ZB_BOUNDARY; ! 1053: ! 1054: void name::field_align() ! 1055: /* ! 1056: adjust alignment ! 1057: */ ! 1058: { ! 1059: Pbase fld = (Pbase) tp; ! 1060: ! 1061: int a; ! 1062: a = (F_SENSITIVE) ? fld->b_fieldtype->align() : ZB_BOUNDARY; ! 1063: if (max_align < a) ! 1064: max_align = a; ! 1065: ! 1066: if (fld->b_bits == 0) { /* # force word alignment # */ ! 1067: int b; ! 1068: if (bit_offset && bit_offset != ZB_BOUNDARY * BI_IN_BYTE) ! 1069: fld->b_bits = (BI_IN_BYTE * ZB_BOUNDARY) - bit_offset; ! 1070: else if (b = byte_offset % ZB_BOUNDARY) ! 1071: fld->b_bits = b * BI_IN_BYTE; ! 1072: /* # else # */ ! 1073: /* # fld->b_bits = BI_IN_WORD; # */ ! 1074: if (max_align < ZB_BOUNDARY) ! 1075: max_align = ZB_BOUNDARY; ! 1076: } else if (bit_offset == 0) { /* # take care of part of word # */ ! 1077: int b = byte_offset % ZB_BOUNDARY; ! 1078: if (b) { ! 1079: byte_offset -= b; ! 1080: bit_offset = b * BI_IN_BYTE; ! 1081: } ! 1082: } ! 1083: /*#error('d',"byteoff %d bitoff %d bits %d",byte_offset,bit_offset,fld->b_bits); #*/ ! 1084: int x = (bit_offset += fld->b_bits); ! 1085: ! 1086: if (BI_IN_WORD < x) { ! 1087: fld->b_offset = 0; ! 1088: byte_offset += SZ_WORD; ! 1089: bit_offset = fld->b_bits; ! 1090: } else { ! 1091: fld->b_offset = bit_offset; ! 1092: if (BI_IN_WORD == x) { ! 1093: bit_offset = 0; ! 1094: byte_offset += SZ_WORD; ! 1095: } else ! 1096: bit_offset = x; ! 1097: } ! 1098: n_offset = byte_offset; ! 1099: } ! 1100: ! 1101: /* ODI notes -- ! 1102: delete bug catching code. ! 1103: fix to bitfield alignment on 68K ! 1104: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.