|
|
1.1 ! root 1: /*ident "@(#)ctrans:src/typ.c 1.4" */ ! 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: goto sss; ! 679: if (vv == 0) // match even if private base class ! 680: if (f1->memof==0 ! 681: || f2->memof==0 ! 682: || f1->memof->baseof(f2->memof)==0) return 1; ! 683: Nstd++; ! 684: sss:; //SSS ! 685: } ! 686: ! 687: if (k1 != k2) return 1; ! 688: ! 689: if (n1!=n2 && k1 && k2) { ! 690: goto aaa; ! 691: } ! 692: else if (a1 && a2) { ! 693: int i = 0; ! 694: while (a1 && a2) { ! 695: i++; ! 696: if (a1->tp->check(a2->tp,over?OVERLOAD:0)) return 1; ! 697: a1 = a1->n_list; ! 698: a2 = a2->n_list; ! 699: } ! 700: if (a1 || a2) goto aaa; ! 701: } ! 702: else if (a1 || a2) { ! 703: aaa: ! 704: //error('d',"aaa k1 %d k2 %d",k1,k2); ! 705: if (k1 == ELLIPSIS) { ! 706: switch (oper) { ! 707: case 0: ! 708: if (a2 && k2==0) break; ! 709: return 1; ! 710: case ASSIGN: ! 711: if (a2 && k2==0) break; ! 712: return 1; ! 713: case ARG: ! 714: if (a1) return 1; ! 715: break; ! 716: // case OVERLOAD: ! 717: case COERCE: ! 718: return 1; ! 719: } ! 720: } ! 721: else if (k2 == ELLIPSIS) { ! 722: return 1; ! 723: } ! 724: else if (k1 || k2) { ! 725: return 1; ! 726: } ! 727: } ! 728: ! 729: t1 = f1->returns; ! 730: t2 = f2->returns; ! 731: fct_seen = 1; ! 732: ! 733: switch (oper) { //CCC ! 734: case 0: ! 735: if (f1->f_const!=f2->f_const) { ! 736: if (t1->check(t2,0)==0) const_problem = 1; ! 737: return 1; ! 738: // if (vv == 0) return 1; ! 739: // Vcheckerror = 1; ! 740: } ! 741: break; ! 742: default: // really pointer to function ! 743: if (f1->f_const && f2->f_const==0) return 1; ! 744: } ! 745: ! 746: ! 747: if (vv && t1->check(t2,0)) { Vcheckerror = 1; return 1; } ! 748: } ! 749: break; ! 750: ! 751: case FIELD: ! 752: goto field_check; ! 753: case CHAR: ! 754: case SHORT: ! 755: case INT: ! 756: case LONG: ! 757: goto int_check; ! 758: case FLOAT: ! 759: case DOUBLE: ! 760: case LDOUBLE: ! 761: goto float_check; ! 762: case EOBJ: ! 763: goto enum_check; ! 764: case COBJ: ! 765: goto cla_check; ! 766: case ZTYPE: ! 767: case VOID: ! 768: return 0; ! 769: default: ! 770: error('i',"T::check(o=%d %d %d)",oper,b1,b2); ! 771: } ! 772: } ! 773: ! 774: if (t1 || t2) { ! 775: const_problem = 0; // not a problem: the type itself is bad ! 776: return 1; ! 777: } ! 778: return 0; ! 779: ! 780: field_check: ! 781: switch (oper) { ! 782: case 0: ! 783: case ARG: ! 784: error('i',"check field?"); ! 785: } ! 786: return 0; ! 787: ! 788: enum_check: ! 789: //error('d',"enum check %t %t",t1,t2); ! 790: if (Pbase(t1)->b_name->tp != Pbase(t2)->b_name->tp) goto base_check; ! 791: goto const_check; ! 792: ! 793: float_check: ! 794: if (first==0 && b1!=b2 && b2!=ZTYPE) return 1; ! 795: // no break ! 796: ! 797: int_check: ! 798: //error('d',"int_check"); ! 799: if (Pbase(t1)->b_unsigned != Pbase(t2)->b_unsigned) { ! 800: if (first == 0) return 1; ! 801: if (oper /*&& oper!=OVERLOAD*/) ! 802: Nstd++; ! 803: else ! 804: return 1; ! 805: } ! 806: // no break ! 807: ! 808: const_check: ! 809: //error('d',"const_check %t (%d) %t (%d)",t1,t1->tconst(),t2,t2->tconst()); ! 810: if (oper==0) { ! 811: //error('d',"oper==0: t1 %t t2 %t cnst1 %d cnst2 %d",t1,t2,cnst1,cnst2); ! 812: if (t1->tconst()+cnst1!=t2->tconst()+cnst2) { ! 813: const_problem = 1; ! 814: return 1; ! 815: } ! 816: } ! 817: else if (first==0) { ! 818: if (t1->tconst()+cnst1==0 && t2->tconst()+cnst2) { ! 819: //error('d',"t1 %t t2 %t cnst1 %d cnst2 %d",t1,t2,cnst1,cnst2); ! 820: //error('d',"tt1 %t %d cnst1 %d cnst2 %d",tt1,tt1->is_ptr(),cnst1,cnst2); ! 821: //error('d',"tt2 %t",tt2); ! 822: if (tt1->is_ptr()) { ! 823: if (fct_const || vec_const) cnst2--; ! 824: ! 825: // const* = int* ! 826: if (cnst2-tt2->tconst()<cnst1-tt1->tconst()) return 0; ! 827: ! 828: // int* = *const ! 829: //if (cnst2==1 && tt2->tconst()) return 0; ! 830: ! 831: // const T* = const T* ! 832: if (t2->tconst()+cnst2==t1->tconst()+cnst1) return 0; ! 833: } ! 834: else { // int = const allowed ! 835: if (cnst1<cnst2) return 0; ! 836: } ! 837: const_problem = 1; ! 838: return 1; ! 839: } ! 840: else { // const* vs int *const ! 841: /* ! 842: //error('d',"t1 %t cnst1 %d t2 %t cnst2 %d",t1,cnst1,t2,cnst2); ! 843: if (tt1->is_ptr()) { ! 844: int tt1c = tt1->tconst(); ! 845: int tt2c = tt2->tconst() - fct_const - vec_const; ! 846: //error('d',"tt1c %d tt2c %d",tt1c,tt2c); ! 847: if (tt1c<tt2c) return 1; ! 848: int t1c = t1->tconst(); ! 849: int t2c = t2->tconst() - fct_const - vec_const; ! 850: //error('d',"t1c %d t2c %d",t1c,t2c); ! 851: if (cnst1+t1c<cnst2+t2c) return 1; ! 852: if (tt2c<tt1c // *const = * ! 853: && cnst1+t1c>cnst2+t2c) // T = constT ! 854: return 1; ! 855: } ! 856: */ ! 857: ! 858: } ! 859: } ! 860: else { ! 861: //error('d',"first t1 %t t2 %t cnst1 %d cnst2 %d",t1,t2,cnst1,cnst2); ! 862: } ! 863: //error('d',"return 0"); ! 864: return 0; ! 865: ! 866: cla_check: ! 867: { Pname n1 = Pbase(t1)->b_name; ! 868: Pname n2 = Pbase(t2)->b_name; ! 869: //error('d',"cla_check %n %n ptr_count %d",n1,n2,ptr_count); ! 870: if (n1 == n2) goto const_check; ! 871: ! 872: // once again, a more comprehensive check for classes, ! 873: // since they may be parametrized. ! 874: if ((t1->base == COBJ) && (t2->base == COBJ) && ! 875: ((Pclass(n1->tp)->same_class(Pclass(n2->tp))))) ! 876: goto const_check; ! 877: ! 878: if (/*first || */1<ptr_count || fct_seen) return 1; ! 879: ! 880: switch (oper) { ! 881: case ARG: ! 882: case ASSIGN: ! 883: case RETURN: ! 884: case COERCE: ! 885: { ! 886: ppbase = PUBLIC; ! 887: if (Pclass(n2->tp)->is_base(n1->string)) { ! 888: if (ppbase!=PUBLIC) { ! 889: const_problem = 0; ! 890: // vrp_equiv = 0; ! 891: return 1; // private or protected base ! 892: } ! 893: Nstd++; ! 894: goto const_check; ! 895: } ! 896: } ! 897: // no break ! 898: case 0: ! 899: case OVERLOAD: ! 900: const_problem = 0; ! 901: // vrp_equiv = 0; ! 902: return 1; ! 903: } ! 904: ! 905: goto const_check; ! 906: } ! 907: ! 908: base_check: ! 909: //error('d',"base_check t1=%t t2=%t oper=%d %s",t1,t2,oper,first?"first":""); ! 910: //error('d',"ptr_count %d",ptr_count); ! 911: if (oper) ! 912: if (first || 1!=ptr_count) { ! 913: if (b1==VOID || b2==VOID) return 1; ! 914: } ! 915: else { ! 916: if (b1 == VOID) { // check for void* = T* ! 917: register Ptype tpx = this; ! 918: tpxloop: ! 919: switch (tpx->base) { // t1 == void* ! 920: default: ! 921: const_problem = 0; ! 922: return 1; ! 923: case VOID: break; ! 924: case PTR: ! 925: case VEC: tpx = Pvec(tpx)->typ; ! 926: goto tpxloop; ! 927: case TYPE: tpx = Pbase(tpx)->b_name->tp; ! 928: goto tpxloop; ! 929: } ! 930: ! 931: tpx = t; ! 932: bloop: ! 933: switch (tpx->base) { // t2 == T* ! 934: default: ! 935: const_problem = 0; ! 936: return 1; ! 937: case VEC: ! 938: case PTR: ! 939: case FCT: Nstd++; ! 940: // return 0; ! 941: goto const_check; // prevent void* = const* ! 942: case TYPE: tpx = Pbase(tpx)->b_name->tp; ! 943: goto bloop; ! 944: } ! 945: } ! 946: ! 947: if (b2 != ZTYPE) { ! 948: const_problem = 0; ! 949: return 1; ! 950: } ! 951: } ! 952: //error('d',"oper %d b1 %d b2 %d cp %d",oper,b1,b2,const_problem); ! 953: switch (oper) { ! 954: case 0: ! 955: if (b1 != b2) { ! 956: const_problem = 0; // we have a bigger problem ! 957: // vrp_equiv = 0; ! 958: } ! 959: return 1; ! 960: case COERCE: // could probably be merged with the cases below ! 961: switch (b1) { ! 962: case EOBJ: ! 963: case ZTYPE: ! 964: case CHAR: ! 965: case SHORT: ! 966: case INT: ! 967: switch (b2) { ! 968: case LONG: ! 969: case FLOAT: ! 970: case DOUBLE: ! 971: case LDOUBLE: ! 972: case EOBJ: ! 973: case ZTYPE: ! 974: case CHAR: ! 975: case SHORT: ! 976: case INT: ! 977: case FIELD: ! 978: Nstd++; ! 979: suppress_error++; ! 980: if (b1 == EOBJ) echeck(t1,t2); ! 981: suppress_error--; ! 982: goto const_check; ! 983: } ! 984: return 1; ! 985: case LONG: // char, short, and int promotes to long ! 986: switch (b2) { ! 987: case FLOAT: ! 988: case DOUBLE: ! 989: case LDOUBLE: ! 990: case ZTYPE: ! 991: case EOBJ: ! 992: case CHAR: ! 993: case SHORT: ! 994: case INT: ! 995: case FIELD: ! 996: Nstd++; ! 997: goto const_check; ! 998: } ! 999: return 1; ! 1000: case FLOAT: ! 1001: // switch (b2) { ! 1002: // case ZTYPE: ! 1003: // Nstd++; ! 1004: // case FLOAT: ! 1005: // case DOUBLE: ! 1006: // goto const_check; ! 1007: // } ! 1008: // return 1; ! 1009: case DOUBLE: // char, short, int, and float promotes to double ! 1010: case LDOUBLE: ! 1011: switch (b2) { ! 1012: case LONG: ! 1013: case ZTYPE: ! 1014: case EOBJ: ! 1015: case CHAR: ! 1016: case SHORT: ! 1017: case INT: ! 1018: // Nstd++; ! 1019: case FLOAT: ! 1020: case DOUBLE: ! 1021: case LDOUBLE: ! 1022: Nstd++; ! 1023: goto const_check; ! 1024: } ! 1025: return 1; ! 1026: case PTR: ! 1027: switch (b2) { ! 1028: case ZTYPE: ! 1029: Nstd++; ! 1030: goto const_check; ! 1031: } ! 1032: case RPTR: ! 1033: case VEC: ! 1034: case COBJ: ! 1035: case FCT: ! 1036: return 1; ! 1037: } ! 1038: case ARG: ! 1039: case ASSIGN: ! 1040: case RETURN: ! 1041: switch (b1) { ! 1042: case COBJ: ! 1043: return 1; ! 1044: case EOBJ: ! 1045: case ZTYPE: ! 1046: case CHAR: ! 1047: case SHORT: ! 1048: case INT: ! 1049: case LONG: ! 1050: suppress_error++; ! 1051: r = t2->num_ptr(ASSIGN); ! 1052: suppress_error--; ! 1053: switch (r) { ! 1054: case 'F': ! 1055: // if (oper!=ARG) error('w',"%t assigned to%t",t2,t1); ! 1056: break; ! 1057: case 'A': ! 1058: case 'P': ! 1059: case FCT: return 1; ! 1060: } ! 1061: if (b1 == EOBJ) echeck(t1,t2); ! 1062: break; ! 1063: case FLOAT: ! 1064: case DOUBLE: ! 1065: case LDOUBLE: ! 1066: suppress_error++; ! 1067: r = t2->numeric(ASSIGN); ! 1068: suppress_error--; ! 1069: switch (r) { ! 1070: case 'A': ! 1071: case 'P': ! 1072: case FCT: return 1; ! 1073: } ! 1074: break; ! 1075: case VEC: ! 1076: if(oper==ARG && b2==ZTYPE) goto const_check; ! 1077: return 1; ! 1078: case PTR: ! 1079: suppress_error++; ! 1080: r = t2->num_ptr(ASSIGN); ! 1081: suppress_error--; ! 1082: switch (r) { ! 1083: case 'A': ! 1084: case 'I': ! 1085: case 'F': return 1; ! 1086: case FCT: if (Pptr(t1)->typ->base != FCT) return 1; ! 1087: } ! 1088: break; ! 1089: case RPTR: ! 1090: return 1; ! 1091: case FCT: ! 1092: switch (oper) { ! 1093: case ARG: ! 1094: case ASSIGN: ! 1095: return 1; ! 1096: } ! 1097: } ! 1098: break; ! 1099: } ! 1100: goto const_check; ! 1101: } ! 1102:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.