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