|
|
1.1 ! root 1: /*ident "@(#)ctrans:src/typ.c 1.2.4.19" */ ! 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: typ.c: ! 11: ! 12: ! 13: ***************************************************************************/ ! 14: ! 15: #include "cfront.h" ! 16: #include "size.h" ! 17: ! 18: Pbase short_type; ! 19: Pbase int_type; ! 20: Pbase char_type; ! 21: Pbase long_type; ! 22: ! 23: Pbase uchar_type; ! 24: Pbase ushort_type; ! 25: Pbase uint_type; ! 26: Pbase ulong_type; ! 27: ! 28: Pbase zero_type; ! 29: Pbase float_type; ! 30: Pbase double_type; ! 31: Pbase ldouble_type; ! 32: Pbase void_type; ! 33: Pbase any_type; ! 34: ! 35: Ptype Pint_type; ! 36: Ptype Pchar_type; ! 37: Ptype Pvoid_type; ! 38: Ptype Pfctvec_type; ! 39: ! 40: Ptable gtbl; ! 41: Ptable any_tbl; ! 42: ! 43: Pname Cdcl; ! 44: Pstmt Cstmt; ! 45: ! 46: bit new_type; ! 47: extern int suppress_error; ! 48: ! 49: void echeck(Ptype t1, Ptype t2) ! 50: /* ! 51: t1 is an enum, t2 is assigned to it ! 52: */ ! 53: { ! 54: if (t1 == t2) return; ! 55: ! 56: //error('d',"echeck(%t,%t) %d %d",t1,t2,t1->base,t2->base); ! 57: //error('d',"se %d",suppress_error); ! 58: if (t1->base==EOBJ ! 59: && t2->base==EOBJ ! 60: && Pbase(t1)->b_name->tp == Pbase(t2)->b_name->tp) return; ! 61: ! 62: error(strict_opt?0:'w',"%t assigned to %t",t2,t1); ! 63: } ! 64: ! 65: ! 66: Ptype np_promote(TOK oper, TOK r1, TOK r2, Ptype t1, Ptype t2, TOK p) ! 67: /* ! 68: an arithmetic operator "oper" is applied to "t1" and "t2", ! 69: types t1 and t2 has been checked and belongs to catagories ! 70: "r1" and "r2", respectively: ! 71: A ANY ! 72: Z ZERO ! 73: I CHAR, SHORT, INT, LONG, FIELD, or EOBJ ! 74: F FLOAT DOUBLE LDOUBLE ! 75: P PTR (to something) or VEC (of something) ! 76: test for compatability of the operands, ! 77: if (p) return the promoted result type ! 78: */ ! 79: { ! 80: if (r2 == 'A') return t1; ! 81: ! 82: //error('d',"promote(%t,%t,%k)",t1,t2,oper); ! 83: // if (r1!='P' && r2=='P' && t2->check(Pvoid_type,0)==0) { ! 84: // error("%k of %t",oper,Pvoid_type); ! 85: // return any_type; ! 86: // } ! 87: ! 88: switch (r1) { ! 89: case 'A': return t2; ! 90: case 'Z': ! 91: switch (r2) { ! 92: case 'Z': return int_type; ! 93: case 'I': ! 94: case 'F': return (p) ? Pbase(t2)->arit_conv(0) : 0; ! 95: case 'P': return t2; ! 96: default: error('i',"zero(%d)",r2); ! 97: } ! 98: case 'I': ! 99: switch (r2) { ! 100: case 'Z': t2 = 0; ! 101: case 'I': ! 102: case 'F': return (p) ? Pbase(t1)->arit_conv(Pbase(t2)) : 0; ! 103: case 'P': switch (oper) { ! 104: case PLUS: ! 105: case ASPLUS: break; ! 106: default: error("int%kP",oper); return any_type; ! 107: } ! 108: return t2; ! 109: case FCT: error("int%kF",oper); return any_type; ! 110: default: error('i',"int(%d)",r2); return any_type; ! 111: } ! 112: case 'F': ! 113: switch (r2) { ! 114: case 'Z': t2 = 0; ! 115: case 'I': ! 116: case 'F': return (p) ? Pbase(t1)->arit_conv(Pbase(t2)) : 0; ! 117: case 'P': error("float%kP",oper); return any_type; ! 118: case FCT: error("float%kF",oper); return any_type; ! 119: default: error('i',"float(%d)",r2); return any_type; ! 120: } ! 121: case 'P': ! 122: // if (t1->check(Pvoid_type,0)==0) { ! 123: // error("%k of %t",oper,Pvoid_type); ! 124: // return any_type; ! 125: // } ! 126: ! 127: switch (r2) { ! 128: case 'Z': return t1; ! 129: case 'I': ! 130: switch (oper) { ! 131: case PLUS: ! 132: case MINUS: ! 133: case ASPLUS: ! 134: case ASMINUS: break; ! 135: default: error("P%k int",oper); return any_type; ! 136: } ! 137: return t1; ! 138: case 'F': error("P%k float",oper); return any_type; ! 139: case 'P': ! 140: if (t1->check(t2,ASSIGN)) { ! 141: switch (oper) { ! 142: case EQ: ! 143: case NE: ! 144: case LE: ! 145: case GE: ! 146: case GT: ! 147: case LT: ! 148: case QUEST: ! 149: if (t2->check(t1,ASSIGN) == 0) goto zz; ! 150: } ! 151: error("T mismatch:%t %k%t",t1,oper,t2); ! 152: return any_type; ! 153: } ! 154: zz: ! 155: switch (oper) { ! 156: case MINUS: ! 157: case ASMINUS: return int_type; ! 158: case PLUS: ! 159: case ASPLUS: error("P +P"); return any_type; ! 160: default: return t1; ! 161: } ! 162: case FCT: return t1; ! 163: default: error('i',"P(%d)",r2); ! 164: } ! 165: case FCT: ! 166: error("F%k%t",oper,t2); ! 167: return any_type; ! 168: default: ! 169: error('i',"np_promote(%d,%d)",r1,r2); ! 170: } ! 171: } ! 172: ! 173: TOK type::kind(TOK oper, TOK v) ! 174: /* v == 'I' integral ! 175: 'N' numeric ! 176: 'P' numeric or pointer ! 177: */ ! 178: { ! 179: Ptype t = this; ! 180: if (this == 0) error('i',"type::kind(): this==0"); ! 181: xx: ! 182: switch (t->base) { ! 183: case ANY: return 'A'; ! 184: case ZTYPE: return 'Z'; ! 185: case FIELD: ! 186: case CHAR: ! 187: case SHORT: ! 188: case INT: ! 189: case LONG: ! 190: case EOBJ: return 'I'; ! 191: case FLOAT: ! 192: case LDOUBLE: ! 193: case DOUBLE: if (v == 'I') error("float operand for %k",oper); return 'F'; ! 194: case VEC:// if (v != 'P') error("V operand for %k",oper); return 'P'; ! 195: case PTR: if (v != 'P') error("P operand for %k",oper); ! 196: switch (oper) { ! 197: case INCR: ! 198: case DECR: ! 199: case MINUS: ! 200: case PLUS: ! 201: case ASMINUS: ! 202: case ASPLUS: ! 203: if (t->base==PTR ! 204: && (Pptr(t)->memof || Pptr(t)->typ->base==FCT)) ! 205: error("%t operand of%k",this,oper); ! 206: else ! 207: Pptr(t)->typ->tsizeof(); // get increment ! 208: break; ! 209: default: ! 210: if (t->base==PTR ! 211: && (Pptr(t)->memof || Pptr(t)->typ->base==FCT)) ! 212: error("%t operand of%k",this,oper); ! 213: case ANDAND: ! 214: case OROR: ! 215: case ASSIGN: ! 216: case NE: ! 217: case EQ: ! 218: case IF: ! 219: case WHILE: ! 220: case DO: ! 221: case FOR: ! 222: case QUEST: ! 223: case NOT: ! 224: break; ! 225: ! 226: } ! 227: return 'P'; ! 228: case RPTR: error("R operand for %k",oper); return 'A'; ! 229: case TYPE: t = Pbase(t)->b_name->tp; goto xx; ! 230: case FCT: if (v != 'P') error("F operand for %k",oper); return FCT; ! 231: case OVERLOAD: error("overloaded operand for %k",oper); return 'A'; ! 232: case CLASS: ! 233: case ENUM: error("%k operand for %k",base,oper); return 'A'; ! 234: default: error("%t operand for %k",this,oper); return 'A'; ! 235: } ! 236: } ! 237: ! 238: extern int catch_delete_bugs; ! 239: ! 240: void type::dcl(Ptable tbl) ! 241: /* ! 242: go through the type (list) and ! 243: (1) evaluate vector dimensions ! 244: (2) evaluate field sizes ! 245: (3) lookup struct tags, etc. ! 246: (4) handle implicit tag declarations ! 247: */ ! 248: { ! 249: static arg_fudge; ! 250: ! 251: if(permanent == 3 && catch_delete_bugs) error ('i', "typ::dcl of a deleted expr."); ! 252: ! 253: Ptype t = this; ! 254: ! 255: if (this == 0) error('i',"T::dcl(this==0)"); ! 256: if (tbl->base != TABLE) error('i',"T::dcl(%d)",tbl->base); ! 257: ! 258: xx: ! 259: //error('d',"type::dcl %k",t->base); ! 260: switch (t->base) { ! 261: case TYPE: ! 262: t = Pbase(t)->b_name->tp; ! 263: goto xx; ! 264: case PTR: ! 265: case RPTR: ! 266: { Pptr p = Pptr(t); ! 267: t = p->typ; ! 268: if (t->base == TYPE) { ! 269: Ptype tt = Pbase(t)->b_name->tp; ! 270: if (tt->base == FCT) p->typ = tt; ! 271: return; ! 272: } ! 273: goto xx; ! 274: } ! 275: ! 276: case VEC: ! 277: { Pvec v = Pvec(t); ! 278: Pexpr e = v->dim; ! 279: if (e) { ! 280: Ptype et; ! 281: v->dim = e = e->typ(tbl); ! 282: et = e->tp; ! 283: if (et->integral(0) == 'A') { ! 284: error("UN in array dimension"); ! 285: } ! 286: else { ! 287: long i; ! 288: Neval = 0; ! 289: i = e->eval(); ! 290: if (Neval == 0) { ! 291: if (largest_int<i) ! 292: error("array dimension too large"); ! 293: v->size = int(i); ! 294: extern Ptable lcl_tbl; ! 295: // error( 'd', "lcl_tbl: %d", lcl_tbl ); ! 296: if ( lcl_tbl == 0 ) ! 297: ! 298: DEL(v->dim); ! 299: v->dim = 0; ! 300: } ! 301: ! 302: if (new_type) { ! 303: if (Neval) ! 304: ; ! 305: else if (i == 0) ! 306: v->dim = zero; ! 307: else if (i < 0) { ! 308: error("negative array dimension"); ! 309: i = 1; ! 310: } ! 311: } ! 312: else { ! 313: if (Neval) ! 314: error("%s",Neval); ! 315: else if (i == 0) ! 316: error('w',"array dimension == 0"); ! 317: else if (i < 0) { ! 318: error("negative array dimension"); ! 319: i = 1; ! 320: } ! 321: } ! 322: } ! 323: } ! 324: t = v->typ; ! 325: llx: ! 326: switch (t->base) { ! 327: case TYPE: ! 328: t = Pbase(t)->b_name->tp; ! 329: goto llx; ! 330: case FCT: ! 331: v->typ = t; ! 332: break; ! 333: case VEC: ! 334: if (Pvec(t)->dim==0 && Pvec(t)->size==0) error("null dimension (something like [][] seen)"); ! 335: if (arg_fudge) { ! 336: v->base = PTR; // X[12][10] ==> X(*)[10] ! 337: Pptr(v)->rdo = 0; ! 338: Pptr(v)->memof = 0; ! 339: } ! 340: } ! 341: goto xx; ! 342: } ! 343: ! 344: case FCT: ! 345: { Pfct f = Pfct(t); ! 346: void dargs(Pname, Pfct, Ptable); ! 347: if (f->argtype) dargs(0,f,tbl); ! 348: for (Pname n=f->argtype; n; n = n->n_list) { ! 349: arg_fudge++; ! 350: n->tp->dcl(tbl); ! 351: arg_fudge--; ! 352: } ! 353: Pname cn = f->returns->is_cl_obj(); ! 354: if (cn && Pclass(cn->tp)->has_itor()) ! 355: make_res(f); ! 356: else if (f->f_this == 0) ! 357: f->f_args = f->argtype; ! 358: t = f->returns; ! 359: goto xx; ! 360: } ! 361: ! 362: case FIELD: ! 363: { Pbase f = Pbase(t); ! 364: Pexpr e = Pexpr(f->b_name); ! 365: long i; ! 366: Ptype et; ! 367: e = e->typ(tbl); ! 368: f->b_name = Pname(e); ! 369: et = e->tp; ! 370: if (et->integral(0) == 'A') { ! 371: error("UN in field size"); ! 372: i = 1; ! 373: } ! 374: else { ! 375: Neval = 0; ! 376: i = e->eval(); ! 377: if (Neval) ! 378: error("%s",Neval); ! 379: else if (i < 0) { ! 380: error("negative field size"); ! 381: i = 1; ! 382: } ! 383: else if (f->b_fieldtype->tsizeof()*BI_IN_BYTE < i) ! 384: error("field size > sizeof(%t)",f->b_fieldtype); ! 385: DEL(e); ! 386: } ! 387: f->b_bits = int(i); ! 388: f->b_name = 0; ! 389: break; ! 390: } ! 391: } ! 392: } ! 393: ! 394: bit vrp_equiv; // vector == pointer equivalence used in check() ! 395: bit const_problem; // types differs only in const ! 396: int vhack; ! 397: int Vcheckerror; ! 398: ! 399: inline int p_rdo(Pptr p) ! 400: { ! 401: return p->rdo; ! 402: } ! 403: ! 404: inline int b_ro(Pbase b) ! 405: { ! 406: return b->b_const; ! 407: } ! 408: ! 409: bit type::check(Ptype t, TOK oper) ! 410: /* ! 411: check if "this" can be combined with "t" by the operator "oper" ! 412: ! 413: used for check of ! 414: assignment types (oper==ASSIGN) ! 415: declaration compatability (oper==0) ! 416: 255 is for parameterized type formals. ! 417: as for (oper = 0) but (oper ==255) ! 418: special checking for ANY types ! 419: argument types (oper==ARG) ! 420: return types (oper==RETURN) ! 421: overloaded function name match (oper==OVERLOAD) ! 422: overloaded function coercion (oper==COERCE) ! 423: virtual function match (oper==VIRTUAL) ! 424: ! 425: NOT for arithmetic operators ! 426: ! 427: return 1 if the check failed ! 428: ! 429: checking of const const* and *const is a mess ! 430: */ ! 431: { ! 432: const unsigned int strict_any_check = (oper == 255) ; ! 433: ! 434: Ptype t1 = this; ! 435: Ptype t2 = t; ! 436: Ptype tt1 = this; ! 437: Ptype tt2 = t; ! 438: int cnst1 = 0; ! 439: int cnst2 = 0; ! 440: TOK b1, b2; ! 441: bit first = 1; ! 442: TOK r; ! 443: int vv; ! 444: int ptr_count = 0; ! 445: int fct_seen = 0; ! 446: int over; ! 447: Pptr p1 = 0; ! 448: Pptr p2 = 0; ! 449: int p_count = 0; ! 450: ! 451: if (strict_any_check) oper = 0 ; ! 452: ! 453: //error('d',"check %k %t %t",oper,t1,t2); ! 454: if (t1==0 || t2==0) error('i',"check(%p,%p,%d)",t1,t2,oper); ! 455: ! 456: if (oper==VIRTUAL) { ! 457: vv = 1; ! 458: Vcheckerror = 0; ! 459: oper = 0; ! 460: } ! 461: else ! 462: vv = 0; ! 463: ! 464: if (oper == OVERLOAD) { ! 465: over = 1; ! 466: oper = 0; ! 467: } ! 468: else ! 469: over = 0; ! 470: ! 471: const_problem = 0; ! 472: ! 473: while (t1 && t2) { ! 474: top: ! 475: //error('d',"top: %t (%d) %t (%d)",t1,t1->base,t2,t2->base); ! 476: if (t1 == t2) { ! 477: /* if the types are the same type, ! 478: and it is a const type, it dosen't ! 479: matter whether one had a const added ! 480: on top by a typedef and the other did not. */ ! 481: if (cnst1==cnst2 || t1->tconst()) return 0; ! 482: if (oper) { ! 483: //error('d',"oper %d cnst1 %d cnst2 %d ptr %d",oper,cnst1,cnst2,tt1->is_ptr()); ! 484: if (tt1 = tt1->is_ptr()) { ! 485: ! 486: // const* = int* ! 487: if (cnst2<cnst1) return 0; ! 488: ! 489: // int* = int *const ! 490: if (cnst2==1 && tt2->tconst()) { ! 491: // check for int* = const *const ! 492: tt2 = tt2->is_ptr(); ! 493: if (tt2->tconst()) return 1; ! 494: return 0; ! 495: } ! 496: } ! 497: else { // int = const allowed ! 498: if (oper==ARG || cnst1<cnst2) return 0; ! 499: } ! 500: } ! 501: else { ! 502: if (p_count && p_rdo(p1)+cnst1==p_rdo(p2)+cnst2) ! 503: return 0; ! 504: // const_problem = 1; ! 505: } ! 506: ! 507: const_problem = 1; ! 508: return 1; ! 509: } ! 510: ! 511: if ((t1->base == ANY || t2->base == ANY)) { ! 512: if (! strict_any_check) return 0; ! 513: // Perform the check for strict_any, ie. the ! 514: return ((t1 == t2) ? 0 : 1) ; ! 515: } ! 516: ! 517: b1 = t1->base; ! 518: switch (b1) { ! 519: case TYPE: ! 520: if (b_ro(Pbase(t1))) cnst1 |= 1; /* support ! 521: multiple consts ! 522: */ ! 523: t1 = Pbase(t1)->b_name->tp; ! 524: goto top; ! 525: } ! 526: ! 527: b2 = t2->base; ! 528: switch (b2) { ! 529: case TYPE: ! 530: if (b_ro(Pbase(t2))) cnst2 |= 1; ! 531: t2 = Pbase(t2)->b_name->tp; ! 532: goto top; ! 533: } ! 534: ! 535: //error('d',"oper %k b1 %k b2 %k",oper,b1,b2); ! 536: if (b1 != b2) { ! 537: switch (b1) { ! 538: case PTR: ! 539: switch (b2) { ! 540: case VEC: ! 541: if (ptr_count) return 1; ! 542: // ptr/vec equivalence does not ! 543: // apply to declaration matching ! 544: t1 = Pptr(t1)->typ; ! 545: t2 = Pvec(t2)->typ; ! 546: if (oper == 0 && over==0) return 1; ! 547: ptr_count++; ! 548: first = 0; ! 549: goto top; ! 550: case FCT: ! 551: t1 = Pptr(t1)->typ; ! 552: if (t1->base!=VOID) ! 553: if (first==0 || t1->base!=b2) return 1; ! 554: first = 0; ! 555: goto top; ! 556: } ! 557: first = 0; ! 558: break; ! 559: ! 560: case FCT: ! 561: switch( b2 ) { ! 562: case PTR: ! 563: t2 = Pptr(t2)->typ; ! 564: if (t1->base!=VOID ! 565: && (first==0||t2->base!=b1)) return 1; ! 566: first = 0; ! 567: goto top; ! 568: } ! 569: first = 0; ! 570: break; ! 571: ! 572: case VEC: ! 573: switch (b2) { ! 574: case PTR: ! 575: if (ptr_count) return 1; ! 576: t1 = Pvec(t1)->typ; ! 577: t2 = Pptr(t2)->typ; ! 578: switch (oper) { ! 579: case ARG: ! 580: case ASSIGN: ! 581: case COERCE: ! 582: break; ! 583: case 0: ! 584: if (over) break; ! 585: default: ! 586: return 1; ! 587: } ! 588: ptr_count++; ! 589: first = 0; ! 590: goto top; ! 591: } ! 592: first = 0; ! 593: break; ! 594: } ! 595: goto base_check; ! 596: } ! 597: ! 598: switch (b1) { ! 599: case VEC: ! 600: //error('d',"vec %k %d %d",oper,Pvec(t1)->size,Pvec(t2)->size); ! 601: if (first==0 && Pvec(t1)->size!=Pvec(t2)->size) return 1; ! 602: first = 0; ! 603: t1 = Pvec(t1)->typ; ! 604: t2 = Pvec(t2)->typ; ! 605: ptr_count++; ! 606: break; ! 607: ! 608: case PTR: ! 609: case RPTR: ! 610: first = 0; ! 611: p1 = Pptr(t1); ! 612: p2 = Pptr(t2); ! 613: p_count++; ! 614: ! 615: if (p1->memof != p2->memof) { ! 616: t1 = p1->typ; ! 617: t2 = p2->typ; ! 618: while (t1->base == TYPE) t1 = Pbase(t1)->b_name->tp; ! 619: while (t2->base == TYPE) t2 = Pbase(t2)->b_name->tp; ! 620: if (t1 != t2) { ! 621: if (p1->memof==0 ! 622: || p2->memof==0 ! 623: || p1->memof->baseof(p2->memof)==0) ! 624: return 1; ! 625: Nstd++; ! 626: } ! 627: } ! 628: ! 629: t1 = p1->typ; ! 630: t2 = p2->typ; ! 631: ptr_count++; ! 632: ! 633: if (oper==0) { ! 634: if (p_rdo(p1)+cnst1!=p_rdo(p2)+cnst2 ! 635: && cnst1+b_ro(Pbase(t1))!=cnst2+b_ro(Pbase(t2))) { ! 636: // const_problem only if nothing ! 637: // more serious is wrong ! 638: if (t1->check(t2,0) == 0) const_problem = 1; ! 639: return 1; ! 640: } ! 641: ! 642: if (b1==RPTR && t1->tconst()!=t2->tconst()) ! 643: const_problem = 1; ! 644: } ! 645: break; ! 646: ! 647: case FCT: ! 648: first = 0; ! 649: { Pfct f1 = Pfct(t1); ! 650: Pfct f2 = Pfct(t2); ! 651: Pname a1 = f1->argtype; ! 652: Pname a2 = f2->argtype; ! 653: TOK k1 = f1->nargs_known; ! 654: TOK k2 = f2->nargs_known; ! 655: int n1 = f1->nargs; ! 656: int n2 = f2->nargs; ! 657: //error('d',"f1%t f2%t",f1,f2); ! 658: if (f1->memof != f2->memof) { ! 659: if (f1->memof==0 && f2->f_this==0) //SSS ! 660: goto sss; ! 661: if (vv == 0) // match even if private base class ! 662: if (f1->memof==0 ! 663: || f2->memof==0 ! 664: || f1->memof->baseof(f2->memof)==0) return 1; ! 665: Nstd++; ! 666: sss:; //SSS ! 667: } ! 668: ! 669: if (k1 != k2) return 1; ! 670: ! 671: if (n1!=n2 && k1 && k2) { ! 672: goto aaa; ! 673: } ! 674: else if (a1 && a2) { ! 675: int i = 0; ! 676: while (a1 && a2) { ! 677: i++; ! 678: if (a1->tp->check(a2->tp,over?OVERLOAD:0)) return 1; ! 679: a1 = a1->n_list; ! 680: a2 = a2->n_list; ! 681: } ! 682: if (a1 || a2) goto aaa; ! 683: } ! 684: else if (a1 || a2) { ! 685: aaa: ! 686: //error('d',"aaa k1 %d k2 %d",k1,k2); ! 687: if (k1 == ELLIPSIS) { ! 688: switch (oper) { ! 689: case 0: ! 690: if (a2 && k2==0) break; ! 691: return 1; ! 692: case ASSIGN: ! 693: if (a2 && k2==0) break; ! 694: return 1; ! 695: case ARG: ! 696: if (a1) return 1; ! 697: break; ! 698: // case OVERLOAD: ! 699: case COERCE: ! 700: return 1; ! 701: } ! 702: } ! 703: else if (k2 == ELLIPSIS) { ! 704: return 1; ! 705: } ! 706: else if (k1 || k2) { ! 707: return 1; ! 708: } ! 709: } ! 710: ! 711: t1 = f1->returns; ! 712: t2 = f2->returns; ! 713: fct_seen = 1; ! 714: ! 715: switch (oper) { //CCC ! 716: case 0: ! 717: if (f1->f_const!=f2->f_const) { ! 718: if (t1->check(t2,0)==0) const_problem = 1; ! 719: return 1; ! 720: // if (vv == 0) return 1; ! 721: // Vcheckerror = 1; ! 722: } ! 723: break; ! 724: default: // really pointer to function ! 725: if (f1->f_const && f2->f_const==0) return 1; ! 726: } ! 727: ! 728: ! 729: if (vv && t1->check(t2,0)) { Vcheckerror = 1; return 1; } ! 730: } ! 731: break; ! 732: ! 733: case FIELD: ! 734: goto field_check; ! 735: case CHAR: ! 736: case SHORT: ! 737: case INT: ! 738: case LONG: ! 739: goto int_check; ! 740: case FLOAT: ! 741: case DOUBLE: ! 742: case LDOUBLE: ! 743: goto float_check; ! 744: case EOBJ: ! 745: goto enum_check; ! 746: case COBJ: ! 747: goto cla_check; ! 748: case ZTYPE: ! 749: case VOID: ! 750: return 0; ! 751: default: ! 752: error('i',"T::check(o=%d %d %d)",oper,b1,b2); ! 753: } ! 754: } ! 755: ! 756: if (t1 || t2) { ! 757: const_problem = 0; // not a problem: the type itself is bad ! 758: return 1; ! 759: } ! 760: return 0; ! 761: ! 762: field_check: ! 763: switch (oper) { ! 764: case 0: ! 765: case ARG: ! 766: error('i',"check field?"); ! 767: } ! 768: return 0; ! 769: ! 770: enum_check: ! 771: //error('d',"enum check %t %t",t1,t2); ! 772: if (Pbase(t1)->b_name->tp != Pbase(t2)->b_name->tp) goto base_check; ! 773: goto const_check; ! 774: ! 775: float_check: ! 776: if (first==0 && b1!=b2 && b2!=ZTYPE) return 1; ! 777: // no break ! 778: ! 779: int_check: ! 780: //error('d',"int_check"); ! 781: if (Pbase(t1)->b_unsigned != Pbase(t2)->b_unsigned) { ! 782: if (first == 0) return 1; ! 783: if (oper /*&& oper!=OVERLOAD*/) ! 784: Nstd++; ! 785: else ! 786: return 1; ! 787: } ! 788: // no break ! 789: ! 790: const_check: ! 791: //error('d',"const_check %t (%d) %t (%d)",t1,t1->tconst(),t2,t2->tconst()); ! 792: if (oper==0) { ! 793: //error('d',"oper==0: t1 %t t2 %t cnst1 %d cnst2 %d",t1,t2,cnst1,cnst2); ! 794: if (t1->tconst()+cnst1!=t2->tconst()+cnst2) { ! 795: const_problem = 1; ! 796: return 1; ! 797: } ! 798: } ! 799: else if (first==0) { ! 800: if (t1->tconst()+cnst1==0 && t2->tconst()+cnst2) { ! 801: //error('d',"t1 %t t2 %t cnst1 %d cnst2 %d",t1,t2,cnst1,cnst2); ! 802: //error('d',"tt1 %t %d cnst1 %d cnst2 %d",tt1,tt1->is_ptr(),cnst1,cnst2); ! 803: //error('d',"tt2 %t",tt2); ! 804: if (tt1->is_ptr()) { ! 805: if (fct_const || vec_const) cnst2--; ! 806: ! 807: // const* = int* ! 808: if (cnst2-tt2->tconst()<cnst1-tt1->tconst()) return 0; ! 809: ! 810: // int* = *const ! 811: if (cnst2==1 && tt2->tconst()) return 0; ! 812: ! 813: // const T* = const T* ! 814: if (t2->tconst()+cnst2==t1->tconst()+cnst1) return 0; ! 815: } ! 816: else { // int = const allowed ! 817: if (cnst1<cnst2) return 0; ! 818: } ! 819: const_problem = 1; ! 820: return 1; ! 821: } ! 822: else { // const* vs int *const ! 823: /* ! 824: //error('d',"t1 %t cnst1 %d t2 %t cnst2 %d",t1,cnst1,t2,cnst2); ! 825: if (tt1->is_ptr()) { ! 826: int tt1c = tt1->tconst(); ! 827: int tt2c = tt2->tconst() - fct_const - vec_const; ! 828: //error('d',"tt1c %d tt2c %d",tt1c,tt2c); ! 829: if (tt1c<tt2c) return 1; ! 830: int t1c = t1->tconst(); ! 831: int t2c = t2->tconst() - fct_const - vec_const; ! 832: //error('d',"t1c %d t2c %d",t1c,t2c); ! 833: if (cnst1+t1c<cnst2+t2c) return 1; ! 834: if (tt2c<tt1c // *const = * ! 835: && cnst1+t1c>cnst2+t2c) // T = constT ! 836: return 1; ! 837: } ! 838: */ ! 839: ! 840: } ! 841: } ! 842: else { ! 843: //error('d',"first t1 %t t2 %t cnst1 %d cnst2 %d",t1,t2,cnst1,cnst2); ! 844: } ! 845: //error('d',"return 0"); ! 846: return 0; ! 847: ! 848: cla_check: ! 849: { Pname n1 = Pbase(t1)->b_name; ! 850: Pname n2 = Pbase(t2)->b_name; ! 851: //error('d',"cla_check %n %n ptr_count %d",n1,n2,ptr_count); ! 852: ! 853: if (n1 == n2) goto const_check; ! 854: // once again, a more comprehensive check for classes, ! 855: // since they may be parametrized. ! 856: if ((t1->base == COBJ) && (t2->base == COBJ) && ! 857: ((Pclass(n1->tp)->same_class(Pclass(n2->tp))))) ! 858: goto const_check ; ! 859: ! 860: if (/*first || */1<ptr_count || fct_seen) return 1; ! 861: ! 862: switch (oper) { ! 863: case ARG: ! 864: case ASSIGN: ! 865: case RETURN: ! 866: case COERCE: ! 867: { extern TOK ppbase; ! 868: ppbase = PUBLIC; ! 869: if (Pclass(n2->tp)->is_base(n1->string)) { ! 870: if (ppbase!=PUBLIC) { ! 871: const_problem = 0; ! 872: // vrp_equiv = 0; ! 873: return 1; // private or protected base ! 874: } ! 875: Nstd++; ! 876: goto const_check; ! 877: } ! 878: } ! 879: // no break ! 880: case 0: ! 881: case OVERLOAD: ! 882: const_problem = 0; ! 883: // vrp_equiv = 0; ! 884: return 1; ! 885: } ! 886: ! 887: goto const_check; ! 888: } ! 889: ! 890: base_check: ! 891: //error('d',"base_check t1=%t t2=%t oper=%d %s",t1,t2,oper,first?"first":""); ! 892: //error('d',"ptr_count %d",ptr_count); ! 893: if (oper) ! 894: if (first || 1!=ptr_count) { ! 895: if (b1==VOID || b2==VOID) return 1; ! 896: } ! 897: else { ! 898: if (b1 == VOID) { // check for void* = T* ! 899: register Ptype tpx = this; ! 900: tpxloop: ! 901: switch (tpx->base) { // t1 == void* ! 902: default: ! 903: const_problem = 0; ! 904: return 1; ! 905: case VOID: break; ! 906: case PTR: ! 907: case VEC: tpx = Pvec(tpx)->typ; ! 908: goto tpxloop; ! 909: case TYPE: tpx = Pbase(tpx)->b_name->tp; ! 910: goto tpxloop; ! 911: } ! 912: ! 913: tpx = t; ! 914: bloop: ! 915: switch (tpx->base) { // t2 == T* ! 916: default: ! 917: const_problem = 0; ! 918: return 1; ! 919: case VEC: ! 920: case PTR: ! 921: case FCT: Nstd++; ! 922: // return 0; ! 923: goto const_check; // prevent void* = const* ! 924: case TYPE: tpx = Pbase(tpx)->b_name->tp; ! 925: goto bloop; ! 926: } ! 927: } ! 928: ! 929: if (b2 != ZTYPE) { ! 930: const_problem = 0; ! 931: return 1; ! 932: } ! 933: } ! 934: //error('d',"oper %d b1 %d b2 %d cp %d",oper,b1,b2,const_problem); ! 935: switch (oper) { ! 936: case 0: ! 937: if (b1 != b2) { ! 938: const_problem = 0; // we have a bigger problem ! 939: // vrp_equiv = 0; ! 940: } ! 941: return 1; ! 942: case COERCE: // could probably be merged with the cases below ! 943: switch (b1) { ! 944: case EOBJ: ! 945: // echeck(t1,t2); ! 946: case ZTYPE: ! 947: case CHAR: ! 948: case SHORT: ! 949: case INT: ! 950: switch (b2) { ! 951: case LONG: ! 952: case FLOAT: ! 953: case DOUBLE: ! 954: case LDOUBLE: ! 955: // Nstd++; ! 956: case EOBJ: ! 957: case ZTYPE: ! 958: case CHAR: ! 959: case SHORT: ! 960: case INT: ! 961: case FIELD: ! 962: Nstd++; ! 963: if (b1 == EOBJ) echeck(t1,t2); ! 964: goto const_check; ! 965: } ! 966: return 1; ! 967: case LONG: // char, short, and int promotes to long ! 968: switch (b2) { ! 969: case FLOAT: ! 970: case DOUBLE: ! 971: case LDOUBLE: ! 972: case ZTYPE: ! 973: case EOBJ: ! 974: case CHAR: ! 975: case SHORT: ! 976: case INT: ! 977: case FIELD: ! 978: Nstd++; ! 979: goto const_check; ! 980: } ! 981: return 1; ! 982: case FLOAT: ! 983: // switch (b2) { ! 984: // case ZTYPE: ! 985: // Nstd++; ! 986: // case FLOAT: ! 987: // case DOUBLE: ! 988: // goto const_check; ! 989: // } ! 990: // return 1; ! 991: case DOUBLE: // char, short, int, and float promotes to double ! 992: case LDOUBLE: ! 993: switch (b2) { ! 994: case LONG: ! 995: case ZTYPE: ! 996: case EOBJ: ! 997: case CHAR: ! 998: case SHORT: ! 999: case INT: ! 1000: // Nstd++; ! 1001: case FLOAT: ! 1002: case DOUBLE: ! 1003: case LDOUBLE: ! 1004: Nstd++; ! 1005: goto const_check; ! 1006: } ! 1007: return 1; ! 1008: case PTR: ! 1009: switch (b2) { ! 1010: case ZTYPE: ! 1011: Nstd++; ! 1012: goto const_check; ! 1013: } ! 1014: case RPTR: ! 1015: case VEC: ! 1016: case COBJ: ! 1017: case FCT: ! 1018: return 1; ! 1019: } ! 1020: case ARG: ! 1021: case ASSIGN: ! 1022: case RETURN: ! 1023: switch (b1) { ! 1024: case COBJ: ! 1025: return 1; ! 1026: case EOBJ: ! 1027: // echeck(t1,t2); ! 1028: case ZTYPE: ! 1029: case CHAR: ! 1030: case SHORT: ! 1031: case INT: ! 1032: case LONG: ! 1033: suppress_error++; ! 1034: r = t2->num_ptr(ASSIGN); ! 1035: suppress_error--; ! 1036: switch (r) { ! 1037: case 'F': ! 1038: // if (oper!=ARG) error('w',"%t assigned to%t",t2,t1); ! 1039: break; ! 1040: case 'A': ! 1041: case 'P': ! 1042: case FCT: return 1; ! 1043: } ! 1044: if (b1 == EOBJ) echeck(t1,t2); ! 1045: break; ! 1046: case FLOAT: ! 1047: case DOUBLE: ! 1048: case LDOUBLE: ! 1049: suppress_error++; ! 1050: r = t2->numeric(ASSIGN); ! 1051: suppress_error--; ! 1052: switch (r) { ! 1053: case 'A': ! 1054: case 'P': ! 1055: case FCT: return 1; ! 1056: } ! 1057: break; ! 1058: case VEC: ! 1059: return 1; ! 1060: case PTR: ! 1061: suppress_error++; ! 1062: r = t2->num_ptr(ASSIGN); ! 1063: suppress_error--; ! 1064: switch (r) { ! 1065: case 'A': ! 1066: case 'I': ! 1067: case 'F': return 1; ! 1068: case FCT: if (Pptr(t1)->typ->base != FCT) return 1; ! 1069: } ! 1070: break; ! 1071: case RPTR: ! 1072: return 1; ! 1073: case FCT: ! 1074: switch (oper) { ! 1075: case ARG: ! 1076: case ASSIGN: ! 1077: return 1; ! 1078: } ! 1079: } ! 1080: break; ! 1081: } ! 1082: goto const_check; ! 1083: } ! 1084: ! 1085: /* ODI notes ! 1086: ! 1087: parameterized types ! 1088: ! 1089: constant checking fixes, especially to make ! 1090: ! 1091: typedef const int a; ! 1092: ! 1093: typedef const a b; ! 1094: ! 1095: work. ! 1096: ! 1097: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.