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