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