|
|
1.1 ! root 1: /*ident "@(#)ctrans:src/dcl3.c 1.12" */ ! 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: dcl3.c: ! 11: Routines used by ::dcl fucntions: fct::dcl() etc. ! 12: ! 13: *****************************************************************************/ ! 14: ! 15: #include "cfront.h" ! 16: #include "size.h" ! 17: #include "template.h" ! 18: #include <ctype.h> ! 19: ! 20: static void vbase_pointers(Pname fn, Pclass cl) ! 21: /* ! 22: insert argument for virtual base pointers (if any) ! 23: after f_this and before f_argtype ! 24: */ ! 25: { ! 26: //error('d',"vbase_pointers(%n,%t) %d %k",fn,cl,fn->tp,fn->n_oper); ! 27: Pfct f = Pfct(fn->tp); ! 28: if (fn->n_oper == CTOR) { ! 29: Pname d = 0; ! 30: for (Pbcl b = cl->baselist; b; b=b->next) { ! 31: if (b->base != VIRTUAL) continue; ! 32: Pname a = new name(b->bclass->string); ! 33: a->tp = b->bclass->this_type; ! 34: a->n_list = d; ! 35: a->n_table = f->body ? f->body->memtbl : 0; ! 36: a->where = fn->where; ! 37: d = a; ! 38: } ! 39: ! 40: if (d) { ! 41: for (Pname dd =d;;) { ! 42: if (d->n_list == 0) { ! 43: d->n_list = f->f_args->n_list; ! 44: break; ! 45: } ! 46: d = d->n_list; ! 47: } ! 48: f->f_args->n_list = dd; ! 49: } ! 50: } ! 51: if (fn->n_oper == DTOR) { // add __free argument ! 52: //error('d',"add __free to %n",fn); ! 53: Pname fa = new name; ! 54: fa->tp = int_type; ! 55: fa->n_scope = ARG; ! 56: fa->where = fn->where; ! 57: ! 58: Pname a = f->f_args; ! 59: if (a == 0) ! 60: f->f_args = fa; ! 61: else { ! 62: for(;;a = a->n_list) { ! 63: // error('d',"a %d %t",a,a->tp); ! 64: if (a->n_list == 0) { ! 65: a->n_list = fa; ! 66: break; ! 67: } ! 68: } ! 69: } ! 70: } ! 71: } ! 72: ! 73: void make_res(Pfct f) ! 74: /* ! 75: returns X where X(X&) has been declared ! 76: add "_result" argument of type X* ! 77: */ ! 78: { ! 79: Pname cl = f->returns->is_cl_obj(); ! 80: if (cl==0 || Pclass(cl->tp)->has_itor()==0) return; ! 81: ! 82: Pname rv = new name("_result"); ! 83: rv->tp = f->returns->addrof(); ! 84: rv->n_scope = FCT; // not a ``real'' argument ! 85: rv->n_used = 1; ! 86: rv->n_list = f->argtype; ! 87: if (f->f_this) ! 88: f->f_this->n_list = rv; ! 89: else ! 90: f->f_args = rv; ! 91: f->f_result = rv; ! 92: f->s_returns = void_type; ! 93: } ! 94: ! 95: void name::check_oper(Pname cn) ! 96: /* ! 97: check declarations of operators, ctors, dtors ! 98: */ ! 99: { ! 100: // error('d', "%n->check_oper( %n ): n_oper: %k", this, cn, n_oper ); ! 101: switch (n_oper) { ! 102: case CALL: ! 103: case DEREF: ! 104: case REF: ! 105: if (cn == 0) error("operator%s must be aM",keys[n_oper]); ! 106: break; ! 107: case ASPLUS: ! 108: case ASMINUS: ! 109: case ASMUL: ! 110: case ASDIV: ! 111: case ASMOD: ! 112: case ASAND: ! 113: case ASOR: ! 114: case ASER: ! 115: case ASLS: ! 116: case ASRS: ! 117: if ( warning_opt ) { ! 118: if ( cn == 0 || Pfct(tp)->f_static ) ! 119: error('w', "operator%s should be a non-staticMF",keys[n_oper]); ! 120: } ! 121: break; ! 122: case ASSIGN: ! 123: if (cn == 0) ! 124: error(strict_opt?0:'w',"non-member operator%k() (anachronism)",n_oper); ! 125: break; ! 126: case NOT: /* unary operators only */ ! 127: case COMPL: ! 128: // case INCR: ! 129: // case DECR: ! 130: Pfct f = Pfct(tp); ! 131: if (cn && f->argtype) ! 132: error("%n::%n takes noA",cn, this); ! 133: else if (f->nargs == 2) ! 134: error("%n takes 1A only",this); ! 135: break; ! 136: case INCR: ! 137: case DECR: ! 138: // check for postscript instance ! 139: f = Pfct(tp); ! 140: if (cn) { // member ! 141: if ( f->argtype && f->nargs == 1 ) { ! 142: Pname n = f->argtype; ! 143: if ( n->tp->base != INT ) ! 144: error("%n must takeA ofT int, not %t",this,n->tp); ! 145: } ! 146: } ! 147: else ! 148: if (f->nargs == 2) { // non-member ! 149: Pname n = f->argtype->n_list; ! 150: if ( n->tp->base != INT ) ! 151: error("%n must takeA ofT int, not %t",this,n->tp); ! 152: } ! 153: break; ! 154: ! 155: case 0: ! 156: case TNAME: /* may be a constructor */ ! 157: if (cn && ((strcmp(cn->string,string)==0) || ! 158: ((Pclass(cn->tp)->class_base == ! 159: instantiated_template_class) && ! 160: (strcmp(string, ! 161: Ptclass(cn->tp)->unparametrized_tname()->string) == 0)))) ! 162: { ! 163: if (tp->base == FCT) { ! 164: Pfct f = Pfct(tp); ! 165: if (f->returns!=defa_type) ! 166: error("%s::%s()W returnT",string,string); ! 167: f->returns = void_type; ! 168: string = "__ct"; ! 169: n_oper = CTOR; ! 170: } ! 171: else ! 172: error('s',"struct%nM%n",cn,cn); ! 173: } ! 174: else ! 175: n_oper = 0; ! 176: break; ! 177: case DTOR: /* must be a destructor */ ! 178: //error('d',"dtor %s",string); ! 179: if (cn == 0) { ! 180: n_oper = 0; ! 181: error("destructor ~%s() not inC",string); ! 182: } ! 183: else ! 184: if ((strcmp(cn->string,string) == 0) || ! 185: ((Pclass(cn->tp)->class_base == ! 186: instantiated_template_class) && ! 187: (strcmp(string, ! 188: Ptclass(cn->tp)->unparametrized_tname()->string)==0))) ! 189: { ! 190: dto: ! 191: Pfct f = (Pfct)tp; ! 192: string = "__dt"; ! 193: if (tp->base != FCT) { ! 194: error("%s::~%s notF",cn->string,cn->string); ! 195: tp = new fct(void_type,0,1); ! 196: } ! 197: else if (f->returns!=defa_type/* && f->returns!=void_type*/) { ! 198: if ( f->returns != void_type || ! 199: f->body != 0 || friend_in_class == 0 ) ! 200: error("%s::~%s()W returnT",cn->string,cn->string); ! 201: } ! 202: ! 203: if (f->argtype) { ! 204: error("%s::~%s()WAs",cn->string,cn->string); ! 205: f->nargs = 0; ! 206: f->nargs_known = 1; ! 207: f->argtype = 0; ! 208: } ! 209: f->returns = void_type; ! 210: } ! 211: else { ! 212: if (strcmp(string,"__dt") == 0) goto dto; ! 213: error("~%s in %s",string,cn->string); ! 214: n_oper = 0; ! 215: } ! 216: break; ! 217: case TYPE: ! 218: // cond stores the type of the operator function ! 219: // error('d',"type %t",cond); ! 220: if (cn == 0) { ! 221: // error("operator%t() not aM",Ptype(n_initializer)); ! 222: error("operator%t() not aM",Ptype(cond)); ! 223: n_oper = 0; ! 224: // n_initializer = 0; ! 225: cond = 0; ! 226: } ! 227: else { ! 228: Pfct f = Pfct(tp); ! 229: // n_initializer = 0; ! 230: Ptype tx = Ptype(cond); ! 231: cond = 0; ! 232: if (f->base != FCT) error("badT for%n::operator%t()",cn,tx); ! 233: if (f->returns != defa_type) { ! 234: // if (f->returns->check(tx,0)) error("bad resultT for%n::operator%t()",cn,tx); ! 235: error("resultT for%n::operator%t()",cn,tx); ! 236: DEL(f->returns); ! 237: } ! 238: if (f->argtype) { ! 239: error("%n::operator%t()WAs",cn,tx); ! 240: f->argtype = 0; ! 241: } ! 242: f->returns = tx; ! 243: Pname nx = tx->is_cl_obj(); ! 244: if (nx && can_coerce(tx,cn->tp)) error("both %n::%n(%n) and %n::operator%t()",cn,cn,nx,tx); ! 245: char buf[1024]; ! 246: char* bb = tx->signature(buf); ! 247: int l2 = bb-buf; ! 248: if (1023<l2) error('i',"N::check_oper():N buffer overflow"); ! 249: char* p = new char[l2+5]; ! 250: p[0] = '_'; ! 251: p[1] = '_'; ! 252: p[2] = 'o'; ! 253: p[3] = 'p'; ! 254: strcpy(p+4,buf); ! 255: string = p; ! 256: } ! 257: break; ! 258: } ! 259: } ! 260: ! 261: Pexpr vbase_args(Pfct a, Pname bn) ! 262: /* ! 263: constructor a calls the constructor bn for a base class ! 264: generate argument list needed for virtual base arguments ! 265: */ ! 266: { ! 267: Pfct b = Pfct(bn->tp); ! 268: //error('d',"vbase_args%n: %t %k",bn,b,b->base); ! 269: Pexpr args = 0; ! 270: Pexpr tail = 0; ! 271: if (b->base == OVERLOAD) b = Pfct(Pgen(b)->fct_list->f->tp); // doesn't matter which ! 272: for (Pname d = b->f_args->n_list; d!=b->argtype; d=d->n_list) { ! 273: for (Pname dd = a->f_args->n_list; dd; dd=dd->n_list) ! 274: // using strcmp is a trick ! 275: if (strcmp(dd->string,d->string)==0) break; ! 276: ! 277: Pexpr aa = new expr(ELIST,dd,0); ! 278: if (args == 0) ! 279: args = aa; ! 280: else ! 281: tail->e2 = aa; ! 282: tail = aa; ! 283: } ! 284: return args; ! 285: } ! 286: ! 287: void fct::init_bases(Pclass cl, Pexpr) ! 288: /* ! 289: in "cl"'s constructor "this" generate code to initialize base classes ! 290: and members using the initializers "f->f_init" ! 291: ! 292: this->f_init == list of names of classes to be initialized ! 293: COLON(b) => base class b ! 294: => constructor call in f_init->n_initializer ! 295: COLON() => unnamed base class ! 296: => constructor call in f_init->n_initializer ! 297: NAME(m) => member m ! 298: => constructor call in m->n_initializer ! 299: */ ! 300: { ! 301: Ptable ftbl = body->memtbl; ! 302: DB( if(Ddebug>=1) error('d',"init_bases %t init %d",cl,f_init); ); ! 303: ! 304: // explicit initializers ! 305: if ( cl && cl->csu == UNION && f_init && f_init->n_list ) ! 306: error(&f_init->where,"multipleIrs in unionK %s:: %s",cl->string,cl->string); ! 307: for (Pname nx, nn=f_init; nn; delete nn,(nn=nx) ) { ! 308: Pexpr i = nn->n_initializer; ! 309: nn->n_initializer = 0; ! 310: nx = nn->n_list; ! 311: ! 312: // error('d',"init_base %s %d",nn->string,i); ! 313: if (nn->string) { ! 314: // lookup in case type name hides a "real" member ! 315: { Pname mmm = cl->memtbl->look(nn->string,0); ! 316: if ( mmm ) nn->base = mmm->base; ! 317: } ! 318: if (nn->base == TNAME) { // base class ! 319: char *bn; ! 320: while ( nn->tp && nn->tp->base == TYPE ) ! 321: nn->tp = Pbase(nn->tp)->b_name->tp; ! 322: if ( nn->tp && nn->tp->base == COBJ ) ! 323: bn = Pbase(nn->tp)->b_name->string; ! 324: else ! 325: bn = nn->string; ! 326: for (Pbcl l = cl->baselist; l; l=l->next) { ! 327: Pclass bcl = l->bclass; ! 328: if ((strcmp(bcl->string,bn) == 0) || ! 329: ((bcl->class_base == ! 330: instantiated_template_class) && ! 331: ((strcmp(nn->string, ! 332: Ptclass(bcl)->unparametrized_tname()->string)) == 0))) ! 333: { ! 334: ! 335: // l->init is zeroed out in ctor_simpl ! 336: // if error_count, simpl() not invoked ! 337: if (l->init && error_count == 0) ! 338: error("twoIrs for%t",bcl); ! 339: else ! 340: l->init = base_init(bcl,i,ftbl,l->obj_offset); ! 341: goto con; ! 342: } ! 343: } ! 344: error(&nn->where,"unexpectedAL: noBC%n",nn); ! 345: con: ! 346: continue; ! 347: } ! 348: else { // member initializer ! 349: Pname m = cl->memtbl->look(nn->string,0); ! 350: if (m && m->n_table==cl->memtbl) ! 351: m->n_initializer = mem_init(m,i,ftbl); ! 352: else ! 353: error(&nn->where,"%n not inC %s",nn,cl->string); ! 354: } ! 355: } ! 356: else { // unnamed base class ! 357: Pbcl l = cl->baselist; ! 358: if (l == 0) { ! 359: error("unexpectedAL: noBC called"); ! 360: continue; ! 361: } ! 362: ! 363: if (l->next) { ! 364: bit cnt = 0, rvb = 0; // remote virtual base classes ! 365: for (Pbcl ll = l; ll; ll = ll->next, ++cnt ) ! 366: if (ll->base==VIRTUAL && ll->promoted) ++rvb; ! 367: if ( rvb ) ! 368: error("unnamedBCIr: %dBCes(%d non-explicit virtualBC%s)",cnt,rvb,rvb==1?"":"es"); ! 369: else error("unnamedBCIr: %dBCes",cnt); ! 370: continue; ! 371: } ! 372: ! 373: if (l->init) ! 374: error("twoIrs for%t",l->bclass); ! 375: else { ! 376: error(strict_opt?0:'w',&nn->where,"N ofBC%t missing from BCIr (anachronism)",l->bclass); ! 377: l->init = base_init(l->bclass,i,ftbl,l->obj_offset); ! 378: } ! 379: } ! 380: } // for ! 381: ! 382: for (Pbcl l = cl->baselist; l; l=l->next) { ! 383: // default initialization of base classes ! 384: Pname ctor; ! 385: Pclass bcl = l->bclass; ! 386: if (l->init==0 && (ctor=bcl->has_ctor())) ! 387: l->init = base_init(bcl,0,ftbl,l->obj_offset); ! 388: } ! 389: } ! 390: ! 391: int inline_restr; /* report use of constructs that the inline expanded ! 392: cannot handle here */ ! 393: ! 394: void fct::dcl(Pname n) ! 395: { ! 396: int nmem = TBLSIZE; ! 397: Pname a; ! 398: Pname ll; ! 399: Ptable ftbl; ! 400: ! 401: Pptr cct = 0; ! 402: int const_old = const_save; ! 403: ! 404: int bit_old = bit_offset; ! 405: int byte_old = byte_offset; ! 406: int max_old = max_align; ! 407: ! 408: if (base != FCT) error('i',"F::dcl(%d)",base); ! 409: if (body == 0) error('i',"F::dcl(body=%d)",body); ! 410: if (n==0 || n->base!=NAME) error('i',"F::dcl(N=%d %d)",n,(n)?n->base:0); ! 411: DB( if(Ddebug>=1) error('d',"fct::dcl(%n) %k %d %t",n,n->n_scope,body->own_tbl,this); ); ! 412: if (body->own_tbl) return; // done already ! 413: ! 414: // if (f_inline==0 ) n->n_dcl_printed = 1; // beware of recursive calls, no decl needed ! 415: // if (f_inline && debug_opt) n->n_dcl_printed = 2; ! 416: if (body->memtbl == 0) body->memtbl = new table(nmem+3,gtbl,0); ! 417: body->own_tbl = 1; ! 418: ftbl = body->memtbl; ! 419: ftbl->real_block = body; ! 420: ! 421: max_align = 0;//AL_FRAME; ! 422: bit_offset = 0; ! 423: ! 424: cc->stack(); ! 425: cc->nof = n; ! 426: cc->ftbl = ftbl; ! 427: ! 428: switch (n->n_scope) { ! 429: case 0: ! 430: case PUBLIC: ! 431: { cc->not = n->n_table->t_name; ! 432: cc->cot = Pclass(cc->not->tp); ! 433: cc->tot = cc->cot->this_type; ! 434: // if (f_this==0 || cc->tot==0) error('i',"F::dcl(%n): f_this=%d cc->tot=%d",n,f_this,cc->tot); ! 435: if (f_this) f_this->n_table = ftbl; // fake for inline printout ! 436: cc->c_this = f_this; ! 437: ! 438: ! 439: Pclass cl = Pclass(cc->not->tp); ! 440: ! 441: if (cl->c_body!=3 ! 442: || n->n_initializer ! 443: || n->n_sto==STATIC ! 444: || f_inline ! 445: || f_imeasure ! 446: || f_virtual==0) ! 447: ; ! 448: else { // could be the function where we need to ! 449: // output the vtbl ! 450: int i; ! 451: for (Pname nn=cl->memtbl->get_mem(i=1); nn; nn=cl->memtbl->get_mem(++i) ) { ! 452: Ptype t = nn->tp; ! 453: if (t) ! 454: switch (t->base) { ! 455: case FCT: ! 456: if (nn == n) goto prnt; ! 457: if (nn->n_initializer ! 458: || nn->n_sto==STATIC ! 459: || Pfct(nn->tp)->f_inline ! 460: || Pfct(nn->tp)->f_imeasure ! 461: || Pfct(nn->tp)->f_virtual==0) break; ! 462: goto zaq; ! 463: ! 464: case OVERLOAD: ! 465: { for (Plist gl=Pgen(t)->fct_list; gl; gl=gl->l) { ! 466: Pname nn = gl->f; ! 467: if (nn == n) goto prnt; ! 468: if (nn->n_initializer ! 469: || nn->n_sto==STATIC ! 470: || Pfct(nn->tp)->f_inline ! 471: || Pfct(nn->tp)->f_imeasure ! 472: || Pfct(nn->tp)->f_virtual==0) continue; ! 473: goto zaq; ! 474: } ! 475: } ! 476: } ! 477: } ! 478: goto zaq; ! 479: prnt: ! 480: cl->print_all_vtbls(cl); ! 481: goto zaq; ! 482: } ! 483: } ! 484: } ! 485: zaq: ! 486: // protect against: class x; x f(); class x { x(x&); .... ! 487: if (f_result == 0) make_res(this); ! 488: if (f_result) f_result->n_table = ftbl; // fake for inline printout ! 489: ! 490: returns->tsizeof(); // make sure size is known ! 491: ! 492: Pname ax; ! 493: for (a=argtype, ll=0; a; a=ax) { ! 494: ax = a->n_list; ! 495: Pname nn = a->dcl(ftbl,ARG); ! 496: Pname cn = nn->tp->is_cl_obj(); ! 497: if (cn == 0) cn = cl_obj_vec; ! 498: if (cn) (void)cn->tp->tsizeof(); // make sure it is printed ! 499: nn->n_assigned_to = nn->n_used = nn->n_addr_taken = 0; ! 500: nn->n_list = 0; ! 501: ! 502: switch (nn->tp->base) { ! 503: case CLASS: ! 504: case ENUM: /* unlink types declared in arg list */ ! 505: nn->dcl_print(0); ! 506: break; ! 507: default: ! 508: if (ll) ! 509: ll->n_list = nn; ! 510: else ! 511: f_args = argtype = nn; ! 512: ll = nn; ! 513: } ! 514: delete a; ! 515: } ! 516: ! 517: if (f_result) { // link in f_result ! 518: f_args = f_result; ! 519: f_result->n_list = argtype; ! 520: } ! 521: ! 522: if (f_this) { // link in f_this ! 523: f_args = f_this; ! 524: f_this->n_list = f_result ? f_result : argtype; ! 525: } ! 526: ! 527: if (n->n_oper==CTOR || n->n_oper==DTOR) vbase_pointers(n,cc->cot); ! 528: ! 529: if (n->n_oper == CTOR) { ! 530: const_save = 1; ! 531: init_bases(cc->cot,f_init); ! 532: } ! 533: else if (f_init) ! 534: error(0,"unexpectedAL: not aK"); ! 535: ! 536: PERM(returns); ! 537: const_save = f_inline&&debug_opt==0; ! 538: inline_restr = 0; ! 539: body->dcl(ftbl); ! 540: ! 541: defined |= DEFINED; ! 542: if (f_inline && inline_restr && returns->base!=VOID) { ! 543: f_inline = 0; ! 544: char* s = (inline_restr & 32) ? "continue" ! 545: : (inline_restr & 16) ? "break" ! 546: : (inline_restr & 8) ? "loop" ! 547: : (inline_restr & 4) ? "switch" ! 548: : (inline_restr & 2) ? "goto" ! 549: : (inline_restr & 1) ? "label" ! 550: : "" ; ! 551: if (warning_opt) { ! 552: error('w', "\"inline\" ignored, %n contains %s",n,s); ! 553: error('w', "out-of-line copy of %n created",n); ! 554: } ! 555: // if (cc->cot) ! 556: n->simpl(); //BS6 ! 557: n->dcl_print(0); ! 558: } ! 559: const_save = const_old; ! 560: ! 561: if (f_inline && debug_opt==0) isf_list = new name_list(n,isf_list); ! 562: ! 563: bit_offset = bit_old; ! 564: byte_offset = byte_old; ! 565: max_align = max_old; ! 566: cc->unstack(); ! 567: ! 568: //error('d',"fct-> returns %t",returns); ! 569: } ! 570: ! 571: Pexpr fct::base_init(Pclass bcl, Pexpr i, Ptable ftbl, int offset) ! 572: /* ! 573: have base class bcl and expr list i ! 574: return "( *(base*)this ) . ctor( i )" ! 575: ctor call generated in expr.typ() ! 576: */ ! 577: { ! 578: Ptype ty = bcl->this_type; ! 579: Pexpr th = rptr(ty,f_this,offset); // base* ! 580: Pname ctor = bcl->has_ctor(); ! 581: ! 582: //error('d',"fct::B_init(C %t, i %d, %d) ctor %n",bcl,i,i?i->tp:0,ctor); ! 583: ! 584: Pexpr ii = (i && i->base==ELIST)?i->e1:i; ! 585: ! 586: if (ii ! 587: && ii->base==DEREF ! 588: && ii->e1->base==CAST ! 589: && th->base==CAST) th->i2 = ii->e1->i2; ! 590: ! 591: if (ctor == 0) { ! 592: if (i && i->base!=ELIST) i = new expr(ELIST,i,0); ! 593: ! 594: Pexpr v = new texpr(VALUE,bcl,i); // ?.base(i) ! 595: v->e2 = new expr(DEREF,th,0); // (*(base*)this).base(i) ! 596: v = v->typ(ftbl); // *base(&*(base*)this,i) ! 597: //error('d',"v %k",v->base); ! 598: switch (v->base) { ! 599: case DEREF: ! 600: return v->e1; // base(&*(base*)this,i) ! 601: case ASSIGN: // degenerate base(base&): *(base*)this=i ! 602: th = new texpr(CAST,ty,f_this); ! 603: v = new expr(CM,v,th); // (*(base*)this=i,(base*)this); ! 604: return v->typ(ftbl); ! 605: default: ! 606: return 0; ! 607: } ! 608: } ! 609: ! 610: ! 611: Pname icn; ! 612: if (i) { ! 613: ii = ii->typ(ftbl); ! 614: if (bcl->has_itor()==0 ! 615: && (icn=ii->tp->is_cl_obj()) ! 616: && (Pclass(icn->tp)==bcl || Pclass(icn->tp)->has_base(bcl))) { ! 617: // degenerate base(base&): *(base*)this=i ! 618: // memberwise copy ! 619: //error('d',"copy %t",ty); ! 620: // th = new cast(ty,f_this); ! 621: // th = th->contents(); ! 622: th = new texpr(CAST,ty,f_this); ! 623: th = th->contents(); ! 624: th = th->typ(ftbl); ! 625: if (Pclass(icn->tp)!=bcl) { // cast needed ! 626: Pptr r = new ptr(RPTR,Pptr(ty)->typ); ! 627: ii = new texpr(CAST,r,ii); ! 628: ii = ii->typ(ftbl); ! 629: } ! 630: ii = new expr(ASSIGN,th,ii); ! 631: ii->tp = th->tp; ! 632: // simulate `return this': ! 633: // *(base*)this=i,(base*)this ! 634: ii = new expr(CM,ii,new cast(ty,f_this)); ! 635: ii->tp = th->tp; ! 636: return ii; ! 637: // return ii->typ(ftbl); // don't find cl::operator=() ! 638: } ! 639: if (i->base == ELIST) i->e1 = ii; ! 640: } ! 641: //Pexpr x = call_ctor(ftbl,th,ctor,i,REF,vbase_args(this,ctor)); ! 642: //error('d',"call %n %t -> %d %k",ctor,ctor->tp,x,x->base); ! 643: // return x; ! 644: return call_ctor(ftbl,th,ctor,i,REF,vbase_args(this,ctor)); ! 645: } ! 646: ! 647: ! 648: Pexpr fct::mem_init(Pname mn, Pexpr i, Ptable ftbl) ! 649: /* ! 650: return "member_ctor( m, i )" ! 651: */ ! 652: { ! 653: // a new entry for B::B_pub, in general, has no tp and no ! 654: // real info: all the tp-> only work on our systems because ! 655: // 0 pointer dereference isn't system memory. it core dumps ! 656: // in set_const since no test is made on this == 0. ! 657: //error('d',"mem_init %n",mn); ! 658: ! 659: // if (mn->n_stclass == STATIC) error('s',"MIr for static%n",mn); ! 660: switch (mn->n_stclass) { ! 661: case STATIC: ! 662: error("MIr for static%n",mn); ! 663: break; ! 664: case ENUM: ! 665: error("MIr for enumeration constant%n", mn); ! 666: break; ! 667: } ! 668: ! 669: Pname member = (mn->base==PUBLIC && mn->n_qualifier) ? mn->n_qualifier : mn; ! 670: ! 671: if (i) i = i->typ(ftbl); ! 672: Pname cn = member->tp->is_cl_obj(); // first find the class name ! 673: ! 674: // if (member->n_stclass == STATIC) error('s',"MIr for static%n",member); ! 675: // if (i) i = i->typ(ftbl); ! 676: // Pname cn = member->tp->is_cl_obj(); // first find the class name ! 677: Pref tn = new ref(REF,f_this,member); ! 678: tn->tp = member->tp; ! 679: //error('d',"MI for %n %t = %t",member,member->tp,i?i->tp:0); ! 680: //error('d',"fthis %d %t member %n tp %t",f_this,f_this->tp,member,tn->tp); ! 681: if (cn) { ! 682: Pclass mcl = Pclass(cn->tp); // then find the classdef ! 683: Pname ctor = mcl->has_ctor(); ! 684: Pname icn; ! 685: ! 686: if (i ! 687: && mcl->has_itor()==0 ! 688: && (icn=i->tp->is_cl_obj()) ! 689: && Pclass(icn->tp)==mcl) { // bitwise copy ! 690: Pexpr init = new expr(ASSIGN,tn,i); ! 691: init->tp = tn->tp; ! 692: // return init->typ(ftbl); // don't look for mcl.operator=() ! 693: member->assign(); ! 694: return init; ! 695: } ! 696: ! 697: if (ctor) return call_ctor(ftbl,tn,ctor,i,DOT); ! 698: ! 699: error("Ir forM%nW noK",member); ! 700: return 0; ! 701: } ! 702: ! 703: if (cl_obj_vec) { ! 704: if (i && i->base == ELIST) ! 705: error("illegalIrL for %t%nWinM initializationL",mn->tp,mn); ! 706: else error('s',"Ir forCM %t%nWK",mn->tp,mn); ! 707: return 0; ! 708: } ! 709: ! 710: if (i && i->base == ELIST) { ! 711: if (i->e2) error("Ir for%n not a simpleE",member); ! 712: i = i->e1; ! 713: } ! 714: ! 715: if (member->tp->is_ref() && (i == 0)) { ! 716: error("empty Ir for reference %n", member); ! 717: return 0 ; ! 718: } ! 719: ! 720: // error( 'd', "fct_mem_init: %n %k", member, member->tp->base ); ! 721: switch (member->tp->base) { ! 722: // case RPTR: ! 723: // if ( i == 0 ) { ! 724: // error( "empty Ir for reference %n", member ); ! 725: // return 0; ! 726: // } ! 727: // break; ! 728: case VEC: ! 729: case FCT: ! 730: case OVERLOAD: ! 731: error("Ir for%n ofT %t",member,member->tp); ! 732: return 0; ! 733: } ! 734: ! 735: //error('d',"tp %t",member->tp); ! 736: if (member->tp->tconst()) { ! 737: int save_ignore_const = ignore_const; ! 738: ignore_const = 1; ! 739: i = new expr(ASSIGN,tn,i); ! 740: i = i->typ(ftbl); ! 741: ignore_const = save_ignore_const; ! 742: return i; ! 743: } ! 744: ! 745: Pptr pt; ! 746: if (pt = member->tp->is_ref()) { ! 747: switch (pt->typ->base) { ! 748: case FCT: ! 749: case OVERLOAD: ! 750: i = ptr_init(pt,i,ftbl); ! 751: break; ! 752: default: ! 753: i = ref_init(pt,i,ftbl); ! 754: } ! 755: i = new expr(ASSIGN,tn,i); ! 756: i->tp = tn->tp; ! 757: member->assign(); // cannot call typ: would cause dereference ! 758: return i; ! 759: } ! 760: ! 761: i = new expr(ASSIGN,tn,i); ! 762: return i->typ(ftbl); // typ performs the type check on the assignment ! 763: } ! 764: ! 765: Pexpr replace_temp(Pexpr e, Pexpr n) ! 766: /* ! 767: e is on the form ! 768: f(&temp,arg) , temp ! 769: or ! 770: &temp->ctor(arg) , temp ! 771: or ! 772: x->f(&temp,arg) , temp ! 773: change it to ! 774: f(n,arg) ! 775: or ! 776: n->ctor(arg) ! 777: */ ! 778: { ! 779: Pexpr c = e->e1; // f(&temp,arg) or &temp->ctor(args) ! 780: Pexpr ff = c->e1; ! 781: Pexpr a = c->e2; // maybe ELIST(&temp,arg) ! 782: Pexpr tmp = e->e2; ! 783: ! 784: //error('d',"suppress(%d %k) %n",tmp->base,tmp->base,tmp->base==NAME?tmp:0); ! 785: if (tmp->base==DEREF) tmp = tmp->e1; ! 786: if (tmp->base==CAST) tmp = tmp->e1; ! 787: if (tmp->base==ADDROF || tmp->base==G_ADDROF) tmp = tmp->e2; ! 788: if (tmp->base != NAME) return e; //error('i',"replace %k",tmp->base); ! 789: tmp->tp = any_type; // temporary not used: suppress it ! 790: ! 791: //error('d',"replace_temp(%k %k) c %k ff %k",e->base,n->base,c->base,ff->base); ! 792: switch (ff->base) { ! 793: case REF: ! 794: if (ff->e1->base==G_ADDROF && ff->e1->e2==tmp) ! 795: a = ff; // &tmp -> f() ! 796: break; ! 797: case DOT: ! 798: if (ff->e1->base==NAME && ff->e1==tmp) { ! 799: a = ff; // tmp . f() ! 800: a->base = REF; ! 801: } ! 802: break; ! 803: } ! 804: a->e1 = n; ! 805: return c; ! 806: } ! 807: ! 808: Pname classdef::has_ictor() ! 809: /* ! 810: does this class have a constructor taking no arguments? ! 811: */ ! 812: { ! 813: Pname c = has_ctor(); ! 814: if (c == 0) return 0; ! 815: ! 816: Pfct f = Pfct(c->tp); ! 817: ! 818: switch (f->base) { ! 819: default: ! 820: error('i',"%s: badK (%k)",string,c->tp->base); ! 821: ! 822: case FCT: ! 823: switch (f->nargs) { ! 824: case 0: return c; ! 825: default: if (f->argtype->n_initializer) return c; ! 826: } ! 827: return 0; ! 828: ! 829: case OVERLOAD: ! 830: { for (Plist l=Pgen(f)->fct_list; l; l=l->l) { ! 831: Pname n = l->f; ! 832: f = (Pfct)n->tp; ! 833: switch (f->nargs) { ! 834: case 0: return n; ! 835: default: if (f->argtype->n_initializer) return n; ! 836: } ! 837: } ! 838: return 0; ! 839: } ! 840: } ! 841: } ! 842: ! 843: int add_first; // fudge, use ctor arg instead ! 844: Pname gen::add(Pname n) ! 845: /* ! 846: add "n" to the tail of "fct_list" ! 847: (overloaded names are searched in declaration order) ! 848: ! 849: detect: multiple identical declarations ! 850: declaration after use ! 851: multiple definitions ! 852: */ ! 853: { ! 854: Pfct f = Pfct(n->tp); ! 855: Pname nx; ! 856: //error('d',"add(%n) %d",n,add_first); ! 857: if (f->base != FCT) error("%n: overloaded nonF",n); ! 858: ! 859: if ( fct_list && (nx=find(f,1)) ) { ! 860: //error('d',"found %n %t",nx,nx->tp); ! 861: Linkage l1 = Pfct(nx->tp)->f_linkage; ! 862: Linkage l2 = f->f_linkage; ! 863: if ( l2 != linkage_default && l1 != l2 ) ! 864: error("inconsistent linkage specifications for%n",n); ! 865: Nold = 1; ! 866: } ! 867: else { ! 868: if (add_first==0 && f->f_signature==0) f->sign(); ! 869: //error('d',"signature: %d \"%s\" fct_list %d",f->f_signature,f->f_signature,fct_list); ! 870: nx = new name; ! 871: *nx = *n; ! 872: // nx->n_tbl_list = Pname(n->string); ! 873: nx->n_gen_fct_name = n->string; ! 874: PERM(nx); ! 875: Nold = 0; ! 876: if (fct_list) { ! 877: int clink = (f->f_linkage==linkage_C); ! 878: Plist gl=fct_list; ! 879: for(;;) { ! 880: if (clink ! 881: && Pfct(gl->f->tp)->f_linkage == linkage_C ) { ! 882: error("two%ns with c linkage",n); ! 883: if(f->f_signature==0) f->sign(); ! 884: } ! 885: if (gl->l) ! 886: gl = gl->l; ! 887: else ! 888: break; ! 889: } ! 890: gl->l = new name_list(nx,0); ! 891: } ! 892: else ! 893: fct_list = new name_list(nx,0); ! 894: nx->n_list = 0; ! 895: } ! 896: return nx; ! 897: } ! 898: ! 899: void fct::sign() ! 900: { ! 901: switch ( f_linkage ) { ! 902: case linkage_C: ! 903: f_signature = ""; ! 904: return; ! 905: case linkage_Cplusplus: ! 906: case linkage_default: ! 907: break; ! 908: } ! 909: char buf[1024]; ! 910: char* bb = signature(buf); ! 911: int ll = bb-buf; ! 912: if (1023 < ll) error('i',"gen::add():N buffer overflow"); ! 913: char* p = new char[ll+1]; ! 914: strcpy(p,buf); ! 915: f_signature = p; ! 916: //error('d',"fct::sign %s",p); ! 917: } ! 918: ! 919: Pname gen::find(Pfct f, bit warn) ! 920: { ! 921: for (Plist gl=fct_list; gl; gl=gl->l) { ! 922: Pname n = match(gl->f,f,warn); ! 923: if (n) return n; ! 924: } ! 925: return 0; ! 926: } ! 927: ! 928: Pname gen::match(Pname nx, Pfct f, bit warn) ! 929: { ! 930: Pfct fx = Pfct(nx->tp); ! 931: Pname a, ax; ! 932: int op = 0; // overloading problem: const, ref, vec/ptr, or basetype ! 933: //error('d',"fx %d %d f %d %d",fx->nargs_known,fx->nargs,f->nargs_known,f->nargs); ! 934: ! 935: if (f->nargs_known != fx->nargs_known) return 0; // the bets are off ! 936: // must rely on checks at ! 937: // call points ! 938: if (f->f_const != fx->f_const) return 0; ! 939: ! 940: if (fx->nargs != f->nargs ! 941: && fx->nargs_known==1 ! 942: && f->nargs_known==1) return 0; // no warning for potential ! 943: // problems due to default args ! 944: ! 945: for (ax=fx->argtype, a=f->argtype; a&&ax; ax=ax->n_list, a=a->n_list) { ! 946: Ptype at = ax->tp; ! 947: Ptype atp = a->tp; ! 948: //error('d',"at %t atp %t",at,atp); ! 949: if (at->check(atp,OVERLOAD) == 0) { ! 950: //error('d',"at %t atp %t cp %d vrp %d",at,atp,const_problem,vrp_equiv); ! 951: continue; ! 952: } ! 953: //error('d',"warn %d",warn); ! 954: if (warn == 0) goto xx; ! 955: ! 956: /* ! 957: warn against: ! 958: overload f(X&), f(X); error ! 959: overload f(int), f(const); error ! 960: overload f(int*), f(int[10]); warn ! 961: etc. ! 962: */ ! 963: ! 964: //error('d',"vrp_equiv %d const_problem %d",vrp_equiv,const_problem); ! 965: if (const_problem) { // differ only in X vs const X ! 966: if (at->is_ptr_or_ref()) return 0; ! 967: op++; ! 968: continue; ! 969: } ! 970: ! 971: aaa: ! 972: switch (atp->base) { ! 973: case TYPE: ! 974: atp = Pbase(atp)->b_name->tp; ! 975: goto aaa; ! 976: // case EOBJ: ! 977: // atp = Penum(Pbase(atp)->b_name->tp)->e_type; ! 978: // goto aaa; ! 979: case RPTR: // differ only by X vs X& ? ! 980: if (Pptr(atp)->typ->check(at,0)==0) { ! 981: op++; ! 982: continue; ! 983: } ! 984: } ! 985: ! 986: atl: ! 987: switch (at->base) { ! 988: case TYPE: ! 989: at = Pbase(at)->b_name->tp; ! 990: goto atl; ! 991: // case EOBJ: ! 992: // at = Penum(Pbase(at)->b_name->tp)->e_type; ! 993: // goto atl; ! 994: case RPTR: // differ only by X& vs X ? ! 995: if (Pptr(at)->typ->check(atp,0)==0) { ! 996: op++; ! 997: continue; ! 998: } ! 999: break; ! 1000: // case CHAR: // differ only by int vs char ? ! 1001: // case SHORT: ! 1002: // case INT: ! 1003: // if (atp->base!=at->base && atp->base==EOBJ) { ! 1004: // op++; ! 1005: // continue; ! 1006: // } ! 1007: // break; ! 1008: } ! 1009: //error('d',"return 0"); ! 1010: //goto xx; ! 1011: // some argument is really different ! 1012: // e.g. f(int), f(char*); ! 1013: return 0; ! 1014: } ! 1015: ! 1016: // arguments checked. Now look at leftover args, return type,etc. ! 1017: ! 1018: // if (warn && a && fx->nargs_known==ELLIPSIS) error('w',"... in%n'sAT hidesATs from the overloading mechanism",nx); ! 1019: ! 1020: if (a || ax) return 0; ! 1021: ! 1022: if (op == 0) { ! 1023: if (warn && fx->returns->check(f->returns,0)) ! 1024: error("two different return valueTs for%n: %t and %t",nx,fx->returns,f->returns); ! 1025: ! 1026: return nx; ! 1027: } ! 1028: xx: ! 1029: if (warn && op) ! 1030: error("the overloading mechanism cannot tell a%t from a%t",fx,f); ! 1031: ! 1032: return 0; ! 1033: } ! 1034: ! 1035: int name::no_of_names() ! 1036: { ! 1037: register int i = 0; ! 1038: register Pname n; ! 1039: for (n=this; n; n=n->n_list) i++; ! 1040: return i; ! 1041: } ! 1042: ! 1043: static Pexpr lvec[20], *lll, *curr_e; ! 1044: static Pexpr last_il = 0; ! 1045: static Pexpr list_back = 0; ! 1046: static Pexpr last_el = 0, *last_lll; ! 1047: ! 1048: void new_list(Pexpr lx) ! 1049: { ! 1050: if (lx->base != ILIST) error('i',"IrLX"); ! 1051: ! 1052: lll = last_lll = lvec; ! 1053: lll++; ! 1054: *lll = last_el = lx->e1; ! 1055: } ! 1056: ! 1057: Pexpr next_elem() ! 1058: { ! 1059: Pexpr e; ! 1060: Pexpr lx; ! 1061: ! 1062: if (lll == lvec) return 0; ! 1063: ! 1064: lx = *lll; ! 1065: ! 1066: if (list_back) { ! 1067: e = list_back; ! 1068: list_back = 0; ! 1069: return e; ! 1070: } ! 1071: ! 1072: if (lx == 0) { /* end of list */ ! 1073: lll--; ! 1074: return 0; ! 1075: } ! 1076: ! 1077: switch (lx->base) { ! 1078: case ELIST: ! 1079: e = lx->e1; ! 1080: curr_e = &lx->e1; ! 1081: last_el = lx; ! 1082: last_lll = lll; ! 1083: *lll = lx->e2; ! 1084: switch (e->base) { ! 1085: case ILIST: ! 1086: lll++; ! 1087: *lll = e->e1; ! 1088: last_il = e; ! 1089: return Pexpr(1); // start of new ILIST ! 1090: case ELIST: ! 1091: error("nestedEL"); ! 1092: return 0; ! 1093: default: ! 1094: { ! 1095: if (need_sti(e)) error('s',"generalIr inIrL"); ! 1096: return e; ! 1097: } ! 1098: } ! 1099: case IVAL: ! 1100: case ZERO: ! 1101: lll--; ! 1102: return 0; ! 1103: default: ! 1104: error('i',"IrL %k",lx->base); ! 1105: } ! 1106: } ! 1107: ! 1108: static Pexpr insert_init(Pexpr newval) { ! 1109: // splice an initializer in front of the next element in the ! 1110: // initializer list. Provides initializers for unnamed bitfields. ! 1111: Pexpr t = new expr(ELIST,last_el->e1,last_el->e2); ! 1112: ! 1113: last_el->e1=newval; ! 1114: last_el->e2=t; ! 1115: lll = last_lll; ! 1116: *lll = last_el; ! 1117: return next_elem(); ! 1118: } ! 1119: ! 1120: void skip_ilist() ! 1121: // skip ilist use to represent pointer to member function literal ! 1122: { ! 1123: Pexpr e = next_elem(); ! 1124: e = next_elem(); ! 1125: } ! 1126: ! 1127: void list_check(Pname nn, Ptype t, Pexpr il, Ptable tbl) ! 1128: /* ! 1129: see if the list "lll" can be assigned to something of type "t" ! 1130: "nn" is the name of the variable for which the assignment is taking place. ! 1131: "il" is the last list element returned by next_elem() ! 1132: */ ! 1133: { ! 1134: Pexpr e; ! 1135: bit lst = 0; ! 1136: int i; ! 1137: Pclass cl; ! 1138: int tdef = 0; ! 1139: ! 1140: //error('d',"list_check%n: %t (%d)",nn,t,il); ! 1141: if (il == Pexpr(1)) { ! 1142: lst = 1; ! 1143: e = il; ! 1144: } ! 1145: else if (il) ! 1146: list_back = il; ! 1147: ! 1148: zzz: ! 1149: switch (t->base) { ! 1150: case TYPE: ! 1151: t = Pbase(t)->b_name->tp; ! 1152: tdef = 1; ! 1153: ! 1154: // did it used to be a VEC before arg_fudge was applied? ! 1155: if (t->base==PTR && Pvec(t)->size) ! 1156: t->base=VEC; ! 1157: goto zzz; ! 1158: ! 1159: case VEC: ! 1160: { Pvec v = Pvec(t); ! 1161: Ptype vt = v->typ; ! 1162: ! 1163: if (v->size) { /* get at most v->size initializers */ ! 1164: if (v->typ->base == CHAR) { ! 1165: e = next_elem(); ! 1166: if (e->base == STRING) { // v[size] = "..." ! 1167: int isz = Pvec(e->tp)->size; ! 1168: if (v->size < isz) error("Ir too long (%d characters) for%n[%d]",isz,nn,v->size); ! 1169: break; ! 1170: } ! 1171: else ! 1172: list_back = e; ! 1173: } ! 1174: for (i=0; i<v->size; i++) { // check next list element type ! 1175: Pfct MP = 0; ! 1176: ee: ! 1177: e = next_elem(); ! 1178: if (e == 0) goto xsw; // too few initializers are ok ! 1179: vtz: ! 1180: //error('d',"vtz: %d",vt->base); ! 1181: switch (vt->base) { ! 1182: case TYPE: ! 1183: vt = Pbase(vt)->b_name->tp; ! 1184: goto vtz; ! 1185: case VEC: ! 1186: case COBJ: ! 1187: list_check(nn,vt,e); ! 1188: break; ! 1189: case PTR: ! 1190: if ((MP = vt->memptr()) && ! 1191: e==Pexpr(1)) { ! 1192: if (vt->check(last_il->tp,ASSIGN)) ! 1193: error("badIrT for%n:%t (%tX)",v,last_il->tp,vt); ! 1194: skip_ilist(); ! 1195: break; ! 1196: } ! 1197: if (MP && e && e->base==ZERO) { ! 1198: *curr_e = new expr(ELIST,zero,zero); ! 1199: *curr_e = new expr(ILIST,*curr_e,zero); ! 1200: (*curr_e)->tp = zero_type; ! 1201: break; ! 1202: } ! 1203: if (MP && e && e->tp->base==OVERLOAD) { ! 1204: Pexpr op = ptof(Pfct(Pptr(vt)->typ),e,tbl); ! 1205: if(op) { ! 1206: *curr_e = op; ! 1207: break; ! 1208: } ! 1209: } ! 1210: // no break ! 1211: default: ! 1212: { ! 1213: if (e == (Pexpr)1) { ! 1214: error("unexpectedIrL"); ! 1215: goto ee; ! 1216: } ! 1217: ! 1218: if (vt->check(e->tp,ASSIGN)) ! 1219: error("badIrT for%n:%t (%tX)",nn,e->tp,vt); ! 1220: ! 1221: Pptr p; ! 1222: if (vt->check(e->tp,0) ! 1223: && (p=vt->is_ptr()) ! 1224: && Ptype(p)!=zero_type ! 1225: && p->typ!=char_type) { ! 1226: Pexpr te = e; ! 1227: Ptype t = p->typ; ! 1228: while ( t->base == TYPE ) t = Pbase(t)->b_name->tp; ! 1229: if ( t->base == COBJ ) ! 1230: te = ptr_init( p, e, tbl ); ! 1231: if ( te == e ) ! 1232: *curr_e = new cast(vt,e); ! 1233: else *curr_e = te; ! 1234: } ! 1235: } ! 1236: } ! 1237: } ! 1238: if ( lst && (e=next_elem()) ) error("end ofIrLX after array"); ! 1239: xsw:; ! 1240: } ! 1241: else { /* determine v->size */ ! 1242: i = 0; ! 1243: (void) v->typ->tsizeof(); ! 1244: xx: ! 1245: while ( e=next_elem() ) { // get another initializer ! 1246: Pfct MP = 0; ! 1247: i++; ! 1248: vtzz: ! 1249: //error('d',"vtzz"); ! 1250: switch (vt->base) { ! 1251: case TYPE: ! 1252: vt = Pbase(vt)->b_name->tp; ! 1253: goto vtzz; ! 1254: case VEC: ! 1255: case COBJ: ! 1256: list_check(nn,vt,e); ! 1257: break; ! 1258: case PTR: ! 1259: if((MP = vt->memptr()) && ! 1260: e==Pexpr(1)) { ! 1261: if (vt->check(last_il->tp,ASSIGN)) ! 1262: error("badIrT for%n:%t (%tX)",v,last_il->tp,vt); ! 1263: skip_ilist(); ! 1264: break; ! 1265: } ! 1266: if (MP && e && e->base==ZERO) { ! 1267: *curr_e = new expr(ELIST,zero,zero); ! 1268: *curr_e = new expr(ILIST,*curr_e,zero); ! 1269: (*curr_e)->tp = zero_type; ! 1270: break; ! 1271: } ! 1272: if (MP && e && e->tp->base==OVERLOAD) { ! 1273: Pexpr op = ptof(Pfct(Pptr(vt)->typ),e,tbl); ! 1274: if(op) { ! 1275: *curr_e = op; ! 1276: break; ! 1277: } ! 1278: } ! 1279: // no break ! 1280: default: ! 1281: { if (e == Pexpr(1)) { ! 1282: error("unexpectedIrL"); ! 1283: goto xx; ! 1284: } ! 1285: ! 1286: if (vt->check(e->tp,ASSIGN)) ! 1287: error("badIrT for%n:%t (%tX)",nn,e->tp,vt); ! 1288: ! 1289: Pptr p; ! 1290: if (vt->check(e->tp,0) ! 1291: && (p=vt->is_ptr()) ! 1292: && Ptype(p)!=zero_type ! 1293: && p->typ!=char_type) { ! 1294: Pexpr te = e; ! 1295: Ptype t = p->typ; ! 1296: while ( t->base == TYPE ) t = Pbase(t)->b_name->tp; ! 1297: if ( t->base == COBJ ) ! 1298: te = ptr_init( p, e, tbl ); ! 1299: if ( te == e ) ! 1300: *curr_e = new cast(vt,e); ! 1301: else *curr_e = te; ! 1302: } ! 1303: } ! 1304: } ! 1305: } ! 1306: if (tdef==0) v->size = i; ! 1307: } ! 1308: break; ! 1309: } ! 1310: ! 1311: case CLASS: ! 1312: cl = Pclass(t); ! 1313: goto ccc; ! 1314: ! 1315: case COBJ: /* initialize members */ ! 1316: cl = Pclass(Pbase(t)->b_name->tp); ! 1317: ccc: ! 1318: if (cl->defined == 0) { ! 1319: lll = lvec; // we are lost: ignore rest of list ! 1320: return; ! 1321: } ! 1322: ! 1323: if (cl->c_body == 1) cl->dcl_print(0); ! 1324: ! 1325: { Ptable tbl = cl->memtbl; ! 1326: Pname m; ! 1327: ! 1328: if (cl->baselist) { ! 1329: if (cl->baselist->next) error("IrL forO ofC with multipleBCs"); ! 1330: list_check(nn,cl->baselist->bclass,0); ! 1331: } ! 1332: ! 1333: for (m=tbl->get_mem(i=1); m; m=tbl->get_mem(++i)) { ! 1334: Ptype mt = m->tp; ! 1335: Pfct MP = 0; ! 1336: switch (mt->base) { ! 1337: case FCT: ! 1338: case OVERLOAD: ! 1339: case CLASS: ! 1340: case ENUM: ! 1341: continue; ! 1342: } ! 1343: if (m->n_stclass == STATIC || ! 1344: m->n_stclass == ENUM ) continue; ! 1345: /* check assignment to next member */ ! 1346: dd: ! 1347: while (mt->base == TYPE) ! 1348: mt = Pbase(mt)->b_name->tp; ! 1349: ! 1350: if ((MP = mt->memptr()) && ! 1351: e==Pexpr(1) && ! 1352: last_il->tp->base == PTR) { ! 1353: if(i==1) lst=0; ! 1354: } ! 1355: else e = next_elem(); ! 1356: ! 1357: if (e == 0) return; //break; ! 1358: ! 1359: if( ! 1360: mt->base == FIELD ! 1361: && ! 1362: m->string[0]=='_' ! 1363: && ! 1364: m->string[1]=='_' ! 1365: && ! 1366: m->string[2]=='F' // unnamed bitfield ! 1367: ) { ! 1368: e = insert_init(zero); ! 1369: } ! 1370: ! 1371: //error('d',"mtz%n: %d",m,mt->base); ! 1372: switch (mt->base) { ! 1373: case CLASS: ! 1374: case ENUM: ! 1375: break; ! 1376: case VEC: ! 1377: case COBJ: ! 1378: list_check(nn,m->tp,e); ! 1379: break; ! 1380: case PTR: ! 1381: if (MP && e==Pexpr(1)) { ! 1382: if (mt->check(last_il->tp,ASSIGN)) ! 1383: error("badIrT for%n:%t (%tX)",m,last_il->tp,mt); ! 1384: skip_ilist(); ! 1385: break; ! 1386: } ! 1387: if (MP && e && e->base==ZERO) { ! 1388: *curr_e = new expr(ELIST,zero,zero); ! 1389: *curr_e = new expr(ILIST,*curr_e,zero); ! 1390: (*curr_e)->tp = zero_type; ! 1391: break; ! 1392: } ! 1393: if (MP && e && e->tp->base==OVERLOAD) { ! 1394: Pexpr op = ptof(Pfct(Pptr(mt)->typ),e,tbl); ! 1395: if(op) { ! 1396: *curr_e = op; ! 1397: break; ! 1398: } ! 1399: } ! 1400: // no break ! 1401: default: ! 1402: { if (e == Pexpr(1)) { ! 1403: error("unexpectedIrL"); ! 1404: goto dd; ! 1405: } ! 1406: ! 1407: if (mt->check(e->tp,ASSIGN)) ! 1408: error("badIrT for%n:%t (%tX)",m,e->tp,m->tp); ! 1409: ! 1410: if(MP && e && e->base==CAST) ! 1411: *curr_e = e->e1; ! 1412: ! 1413: Pptr p; ! 1414: if (mt->check(e->tp,0) ! 1415: && (p=mt->is_ptr()) ! 1416: && Ptype(p)!=zero_type ! 1417: && p->typ!=char_type) ! 1418: *curr_e = new cast(mt,e); ! 1419: } ! 1420: } ! 1421: } ! 1422: if (lst && (e=next_elem()) ) error("end ofIrLX afterCO"); ! 1423: break; ! 1424: } ! 1425: default: ! 1426: e = next_elem(); ! 1427: ! 1428: if (e == 0) { ! 1429: error("noIr forO"); ! 1430: break; ! 1431: } ! 1432: ! 1433: if (e == Pexpr(1)) { ! 1434: error("unexpectedIrL"); ! 1435: break; ! 1436: } ! 1437: //error('d',"t %t e->tp %t",t,e->tp); ! 1438: if (t->check(e->tp,ASSIGN)) error("badIrT for%n:%t (%tX)",nn,e->tp,t); ! 1439: Pptr p; ! 1440: if (t->check(e->tp,0) ! 1441: && (p=t->is_ptr()) ! 1442: && Ptype(p)!=zero_type ! 1443: && p->typ!=char_type) ! 1444: *curr_e = new cast(t,e); ! 1445: if (lst && (e=next_elem()) ) error("end ofIrLX afterO"); ! 1446: break; ! 1447: } ! 1448: } ! 1449: ! 1450: int ! 1451: is_anon(char* string) { ! 1452: // error('d',"is_anon: %s", string ); ! 1453: if ( string == 0 ) ! 1454: return 0; ! 1455: ! 1456: if ( string[0]=='_' && string[1]=='_' && ! 1457: (string[2]=='C' || string[2]=='E')) ! 1458: return 1; ! 1459: return 0; ! 1460: } ! 1461: ! 1462: Pname dclass(Pname n, Ptable tbl) ! 1463: { ! 1464: Pclass cl; ! 1465: Pbase bt; ! 1466: Pname bn; ! 1467: Pname ntbl = tbl->t_name; ! 1468: Ptype ntp = 0; ! 1469: TOK tscope; ! 1470: ! 1471: Pname nx = ktbl->look(n->string,0); // TNAME ! 1472: if (ntbl && ntbl->tp) ntp = ntbl->tp; ! 1473: ! 1474: tscope = ntp&&ntp->base==CLASS?NESTED:(n->lex_level?LOCAL:HIDDEN); ! 1475: ! 1476: DB( if(Ddebug>=1) error( 'd', &n->where, "dclass n %n %d nx %d", n,n->lex_level, nx); ); ! 1477: // error( 'd', &n->where, "dclass n %n ll %d nx %d tbl: %n", n,n->lex_level, nx, tbl->t_name); ! 1478: if (nx == 0 || n->lex_level || ! 1479: ntp && is_anon(n->string) == 0 && ntp->base == CLASS ! 1480: && (ktbl->look(n->string,tscope))) ! 1481: { ! 1482: if ( nx && ntp && ntp->base == CLASS ) { ! 1483: bt = (Pbase)nx->tp; ! 1484: bn = bt->b_name; ! 1485: cl = bn ? (Pclass)bn->tp : 0; ! 1486: if (cl && cl->lcl && ! 1487: strcmp(cl->lcl,"FUDGE007")==0) ! 1488: goto bbb; ! 1489: else { bt=0; bn=0; cl=0; } ! 1490: } ! 1491: ! 1492: int tn = 0; ! 1493: for (nx=ktbl->look(n->string,tscope); nx; nx=nx->n_tbl_list) ! 1494: { ! 1495: if (nx->n_key != tscope) continue; ! 1496: if (tscope==LOCAL && ! 1497: nx->lex_level != n->lex_level ) continue; ! 1498: ! 1499: if (nx->tp->base != COBJ) { ! 1500: tn = 1; ! 1501: continue; ! 1502: } ! 1503: ! 1504: bt = (Pbase)nx->tp; ! 1505: bn = bt->b_name; ! 1506: cl = (Pclass)bn->tp; ! 1507: ! 1508: if (cl == 0) continue; ! 1509: ! 1510: // is this class nested within class table? ! 1511: if (tscope==NESTED && ! 1512: strcmp(ntbl->string,cl->in_class->string)) ! 1513: continue; ! 1514: else ! 1515: if ( tscope==LOCAL && ! 1516: (cl->lcl==0 || strcmp(cl->lcl,Pclass(n->tp)->lcl))) ! 1517: continue; ! 1518: ! 1519: goto bbb; ! 1520: } ! 1521: ! 1522: if (tn) ! 1523: error("%n redefined using Tdef",n); ! 1524: else ! 1525: error('i',"%n is not aCN",n); ! 1526: } ! 1527: else { ! 1528: bt = Pbase(nx->tp); // COBJ ! 1529: if ( bt->base != COBJ ) { ! 1530: error("%n redefined using typedef",n); ! 1531: Pname tn = ktbl->look(n->string,HIDDEN); ! 1532: if ( tn->tp->base == COBJ ) ! 1533: bt = Pbase(tn->tp); ! 1534: else error('i',"%n is not a CN", n ); ! 1535: } ! 1536: bn = bt->b_name; ! 1537: } ! 1538: bbb: ! 1539: bn->where = nx->where; ! 1540: Pname bnn = tbl->insert(bn,CLASS); // copy for member lookup ! 1541: cl = Pclass(bn->tp); ! 1542: ! 1543: if (cl->class_base == template_class) ! 1544: error("C%n defined previously asYC", bn); ! 1545: ! 1546: if (cl->defined&(DEFINED|SIMPLIFIED)) ! 1547: error("C%n defined twice",n); ! 1548: else { ! 1549: if (bn->n_scope == ARG) bn->n_scope = ARGT; ! 1550: cl->dcl(bn,tbl); ! 1551: } ! 1552: n->tp = cl; ! 1553: return bnn; ! 1554: } ! 1555: ! 1556: Pname denum(Pname n, Ptable tbl) ! 1557: { ! 1558: Penum en; ! 1559: Pbase bt; ! 1560: Pname bn; ! 1561: Pname ntbl = tbl->t_name; ! 1562: Ptype ntp = 0; ! 1563: TOK tscope; ! 1564: ! 1565: Pname nx = ktbl->look(n->string,0); // TNAME ! 1566: if (ntbl && ntbl->tp) ntp = ntbl->tp; ! 1567: ! 1568: // note: ***** add for local enumeration declaration ! 1569: // error( 'd', &n->where, "denum n %n ll %d nx %d tbl: %n", n,n->lex_level, nx, tbl->t_name); ! 1570: if (nx == 0 || /* n->lex_level ||*/ ! 1571: ntp && is_anon(n->string)==0 && ntp->base == CLASS ) ! 1572: { ! 1573: int tn = 0; ! 1574: tscope = ntp&&ntp->base==CLASS?NESTED:(/*n->lex_level?LOCAL:*/HIDDEN); ! 1575: for (nx=ktbl->look(n->string,tscope); nx; nx=nx->n_tbl_list) ! 1576: { ! 1577: if (nx->n_key != tscope) continue; ! 1578: // if (tscope==LOCAL && ! 1579: // nx->lex_level != n->lex_level ) continue; ! 1580: ! 1581: bt = (Pbase)nx->tp; ! 1582: bn = bt->b_name; ! 1583: en = (Penum)bn->tp; ! 1584: ! 1585: // is this class nested within class table? ! 1586: if (tscope==NESTED && en->in_class && ! 1587: strcmp(ntbl->string,en->in_class->string)) ! 1588: continue; ! 1589: } ! 1590: } ! 1591: else { ! 1592: bt = (Pbase)nx->tp; ! 1593: bn = bt->b_name; ! 1594: en = (Penum)bn->tp; ! 1595: } ! 1596: ! 1597: Pname bnn = tbl->insert(bn,CLASS); ! 1598: if (en->defined&(DEFINED|SIMPLIFIED)) ! 1599: error("enum%n defined twice",n); ! 1600: else { ! 1601: if (bn->n_scope == ARG) bn->n_scope = ARGT; ! 1602: en->dcl(bn,tbl); ! 1603: } ! 1604: n->tp = en; ! 1605: return bnn; ! 1606: } ! 1607: ! 1608: ! 1609: is_probably_temp( char *str ) ! 1610: { ! 1611: // error( 'd', "is_probably_temp( %s )", str ); ! 1612: ! 1613: if ( str[0] != '_' || str[1] != '_' ) ! 1614: return 0; ! 1615: ! 1616: switch (str[2]) { ! 1617: default: ! 1618: return 0; ! 1619: case 'A': case 'C': case 'D': case 'E': case 'F': ! 1620: case 'I': case 'K': case 'L': case 'M': case 'N': ! 1621: case 'Q': case 'R': case 'S': case 'T': case 'U': ! 1622: case 'V': case 'W': case 'X': ! 1623: if (isdigit(str[3])) ! 1624: return 1; ! 1625: return 0; ! 1626: } ! 1627: ! 1628: } ! 1629: ! 1630: static void ! 1631: check_for_local( Pexpr ee ) ! 1632: { ! 1633: static Pname n[2] = {0,0}; // try not to flag multiple errors ! 1634: static index = 0; ! 1635: ! 1636: if ( ee==0 ) return; ! 1637: ! 1638: // error('d', "check_for_local( %k ) e1: %d e2: %d", ee->base, ee->e1, ee->e2); ! 1639: ! 1640: switch ( ee->base ) { ! 1641: case NAME: ! 1642: { ! 1643: Pname nn = Pname(ee); ! 1644: if ((nn->n_scope==FCT || nn->n_scope==ARG) ! 1645: && is_probably_temp(nn->string) == 0 ! 1646: && n[0]!=nn && n[1]!=nn) ! 1647: { ! 1648: error("local%n used as defaultA", nn ); ! 1649: n[index] = nn; ! 1650: index = index==0?1:0; ! 1651: } ! 1652: // no break; ! 1653: } ! 1654: case TNAME: case STRING: case IVAL: ! 1655: case ICON: case CCON: case FCON: ! 1656: case ZERO: case DUMMY: case SIZEOF: ! 1657: return; ! 1658: case QUEST: ! 1659: check_for_local( ee->cond ); ! 1660: break; ! 1661: case MDOT: ! 1662: check_for_local( ee->mem ); ! 1663: return; ! 1664: } ! 1665: ! 1666: check_for_local( ee->e1 ); ! 1667: check_for_local( ee->e2 ); ! 1668: } ! 1669: ! 1670: void dargs(Pname, Pfct f, Ptable tbl) ! 1671: { ! 1672: int argnamesize = 0; // if +a1, make sure arg names can be printed ! 1673: int oo = const_save; ! 1674: const_save = 1; ! 1675: if ( ansi_opt ) { ! 1676: Pname th = f->f_this; ! 1677: if ( th && th->string ) argnamesize += strlen(th->string) + 1; ! 1678: th = f->f_result; ! 1679: if ( th && th->string ) argnamesize += strlen(th->string) + 1; ! 1680: } ! 1681: ! 1682: for (Pname a=f->argtype; a; a=a->n_list) { ! 1683: Pexpr init; ! 1684: ! 1685: if (a->tp == 0) { ! 1686: error( "A has noT" ); ! 1687: a->tp = any_type; ! 1688: a->n_list = 0; ! 1689: continue; ! 1690: } ! 1691: if (ansi_opt && a->string) argnamesize += strlen(a->string) + 1; ! 1692: ! 1693: Pname cln = a->tp->is_cl_obj(); ! 1694: //error('d',"dargs %t",a->tp); ! 1695: if (cln && Pclass(cln->tp)->has_itor()) // mark X(X&) arguments ! 1696: a->n_xref = 1; ! 1697: else { ! 1698: Ptype t = a->tp; ! 1699: while (t->base == TYPE) t = Pbase(t)->b_name->tp; ! 1700: if (t->base == FCT) a->tp = new ptr(PTR,a->tp); ! 1701: } ! 1702: ! 1703: // if (init = a->n_initializer) { // default argument ! 1704: if ( a->n_key != NESTED && ! 1705: (init = a->n_initializer)) { // default argument ! 1706: Pptr pt; ! 1707: if (init == dummy) { ! 1708: error("emptyIr"); ! 1709: a->n_initializer = 0; ! 1710: continue; ! 1711: } ! 1712: if (cln) { ! 1713: if (init->base==VALUE) { ! 1714: switch (init->tp2->base) { ! 1715: case CLASS: ! 1716: if (Pclass(init->tp2)!=Pclass(cln->tp)) goto inin2; ! 1717: break; ! 1718: default: ! 1719: Pname n2 = init->tp2->is_cl_obj(); ! 1720: if (n2==0 || Pclass(n2->tp)!=Pclass(cln->tp)) goto inin2; ! 1721: } ! 1722: ! 1723: a->n_initializer = init = 0; ! 1724: error('s',"K as defaultA"); ! 1725: } ! 1726: else { ! 1727: inin2: ! 1728: if (init->base == ILIST) error("list as AIr"); ! 1729: Pexpr i = init->typ(tbl); ! 1730: init = class_init(a,a->tp,i,tbl); ! 1731: if (i!=init && init->base==DEREF) { ! 1732: error('s',"K needed forAIr"); ! 1733: init = 0; ! 1734: } ! 1735: else { ! 1736: dosimpl(init,cc->nof); ! 1737: // init->simpl(); ! 1738: init->permanent = 2; ! 1739: } ! 1740: a->n_initializer = init; ! 1741: } ! 1742: } ! 1743: else if (pt = a->tp->is_ref()) { ! 1744: ref_initializer++; ! 1745: init = init->typ(tbl); ! 1746: ref_initializer--; ! 1747: int tcount = stcount; ! 1748: init = ref_init(pt,init,tbl); ! 1749: if (tcount != stcount) { ! 1750: error('s',"needs temporaryV to evaluateAIr"); ! 1751: init = 0; ! 1752: } ! 1753: else { ! 1754: dosimpl(init,cc->nof); ! 1755: // init->simpl(); ! 1756: init->permanent = 2; ! 1757: } ! 1758: a->n_initializer = init; ! 1759: } ! 1760: else { ! 1761: Pptr p = a->tp->is_ptr(); ! 1762: init = init->typ(tbl); ! 1763: if (p) init = ptr_init(p,init,tbl); ! 1764: ! 1765: if (a->tp->check(init->tp,ARG)) { ! 1766: int i = can_coerce(a->tp,init->tp); ! 1767: ! 1768: switch (i) { ! 1769: case 1: ! 1770: if (Ncoerce) { ! 1771: Pname cn = init->tp->is_cl_obj(); ! 1772: Pname xx = new name(Ncoerce->string); ! 1773: Pref r = new ref(DOT,init,xx); ! 1774: init = new expr(G_CALL,r,0); ! 1775: init = init->typ(tbl); ! 1776: } ! 1777: break; ! 1778: default: ! 1779: error("%d possible conversions for defaultA",i); ! 1780: case 0: ! 1781: error("badIrT%t forA%n (%tX)",init->tp,a,a->tp); ! 1782: DEL(init); ! 1783: a->n_initializer = init = 0; ! 1784: } ! 1785: } ! 1786: ! 1787: if (init) { ! 1788: dosimpl(init,cc->nof); ! 1789: // init->simpl(); ! 1790: init->permanent = 2; ! 1791: a->n_initializer = init; ! 1792: Neval = 0; ! 1793: long i = init->eval(); ! 1794: if (Neval == 0) { ! 1795: a->n_evaluated = 1; ! 1796: a->n_val = i; ! 1797: } ! 1798: } ! 1799: } ! 1800: if ( a->n_initializer ) ! 1801: check_for_local(a->n_initializer); ! 1802: } ! 1803: } ! 1804: if ( ansi_opt && argnamesize ) { ! 1805: char* ps = new char[ argnamesize ]; ! 1806: Pname a = f->f_this; ! 1807: if ( a && a->string ) { ! 1808: int i = strlen(a->string) + 1; ! 1809: if ( (argnamesize -= i) < 0 ) goto bad; ! 1810: strcpy(ps,a->string); ! 1811: a->string = ps; ! 1812: ps += i; ! 1813: } ! 1814: a = f->f_result; ! 1815: if ( a && a->string ) { ! 1816: int i = strlen(a->string) + 1; ! 1817: if ( (argnamesize -= i) < 0 ) goto bad; ! 1818: strcpy(ps,a->string); ! 1819: a->string = ps; ! 1820: ps += i; ! 1821: } ! 1822: for ( a = f->argtype; a; a = a->n_list ) { ! 1823: if ( a->string == 0 ) continue; ! 1824: int i = strlen(a->string) + 1; ! 1825: if ( (argnamesize -= i) < 0 ) goto bad; ! 1826: strcpy(ps,a->string); ! 1827: a->string = ps; ! 1828: ps += i; ! 1829: } ! 1830: if ( argnamesize ) bad:error('i',"bad argN size for%t",f); ! 1831: } ! 1832: const_save = oo; ! 1833: } ! 1834: ! 1835: void merge_init(Pname nn, Pfct f, Pfct nf) ! 1836: { ! 1837: // Pname a1 = f->f_args; if (a1==0) a1 = f->argtype; ! 1838: // Pname a2 = nf->f_args;//nf->argtype; ! 1839: Pname a1 = f->argtype; ! 1840: Pname a2 = nf->argtype; ! 1841: ! 1842: for (; a1; a1=a1->n_list, a2=a2->n_list) { ! 1843: int i1 = a1->n_initializer || a1->n_evaluated; ! 1844: int i2 = a2->n_initializer || a2->n_evaluated; ! 1845: ! 1846: if (i1 && i2) error(&a1->where,"twoIrs for%nA%n",nn,a1); ! 1847: ! 1848: if (i1) { ! 1849: a2->n_initializer = a1->n_initializer; ! 1850: a2->n_evaluated = a1->n_evaluated; ! 1851: a2->n_val = a1->n_val; ! 1852: } ! 1853: if (i2) { ! 1854: a1->n_initializer = a2->n_initializer; ! 1855: a1->n_evaluated = a2->n_evaluated; ! 1856: a1->n_val = a2->n_val; ! 1857: } ! 1858: ! 1859: } ! 1860: } ! 1861: ! 1862: Pexpr try_to_coerce(Ptype rt, Pexpr e, char* s, Ptable tbl) ! 1863: /* ! 1864: ``e'' is of class ``cn'' coerce it to type ``rt'' ! 1865: */ ! 1866: { ! 1867: int i; ! 1868: Pname cn; ! 1869: //error('d',"try_to_coerce(%t, %t, %s, %d)",rt,e->tp,s,tbl); ! 1870: ! 1871: if ((cn=e->tp->is_cl_obj()) && (i=can_coerce(rt,e->tp)) && Ncoerce) { ! 1872: if (1 < i) error("%d possible conversions for %s",i,s); ! 1873: //error('d',"coerce %n",Ncoerce); ! 1874: Pclass cl = Pclass(cn->tp); ! 1875: // Pref r = new ref(DOT,e,Ncoerce); ! 1876: // Pexpr rr = r->typ(tbl); ! 1877: // Pexpr c = new expr(G_CALL,rr,0); ! 1878: // c->fct_name = Ncoerce; ! 1879: Pname xx = new name(Ncoerce->string); ! 1880: Pref r = new ref(DOT,e,xx); ! 1881: Pexpr c = new expr(G_CALL,r,0); ! 1882: // return c->typ(tbl); ! 1883: c = c->typ(tbl); ! 1884: //error('d',"coerce -> %k %t",c->base,c->tp); ! 1885: return c; ! 1886: } ! 1887: //error('d',"coerce ->0"); ! 1888: return 0; ! 1889: } ! 1890: ! 1891: int in_class_dcl; ! 1892: ! 1893: Pname name::dofct(Ptable tbl, TOK scope) ! 1894: { ! 1895: Pfct f = Pfct(tp); ! 1896: Pname class_name; ! 1897: Ptable etbl; ! 1898: in_class_dcl = cc->not!=0; ! 1899: int just_made = 0; ! 1900: // int fvirt = 0; //BSopt ! 1901: DB( if(Ddebug>=1) error('d',"dofct %n %d %t %s",this,tp,tp,tbl==gtbl?"global":""); ); ! 1902: // error( 'd', "%n->dofct(): n_initializer: %d f->f_virtual: %d", this, n_initializer, f->f_virtual); ! 1903: ! 1904: if (f->f_inline) n_sto = STATIC; ! 1905: ! 1906: if (n_stclass) ! 1907: switch (n_stclass) { ! 1908: case EXTERN: ! 1909: case STATIC: ! 1910: case OVERLOAD: ! 1911: break; ! 1912: default: ! 1913: error("%n declared%k",this,n_stclass); ! 1914: n_stclass = EXTERN; ! 1915: } ! 1916: ! 1917: tp->dcl(tbl); // must be done before the type check ! 1918: ! 1919: if (n_qualifier) { // qualified name: c::f() checked above ! 1920: class_name = Pbase(n_qualifier->tp)->b_name; ! 1921: etbl = Pclass(class_name->tp)->memtbl; ! 1922: ! 1923: if (f->f_virtual) { ! 1924: error("virtual specifier illegal outsideCD(%n::%s())",class_name,this->string); ! 1925: f->f_virtual = 0; ! 1926: } ! 1927: ! 1928: ! 1929: if (n_sto ! 1930: && n_sto!=FRIEND // friend X::f(); ! 1931: && f->f_inline==0) { // inline causes n_sto==STATIC ! 1932: error("%k specified for QdN%n",n_sto,this); ! 1933: n_sto = 0; ! 1934: } ! 1935: } ! 1936: else { ! 1937: class_name = cc->not; ! 1938: ! 1939: // beware of local function declarations in member functions ! 1940: if (class_name && tbl!=cc->cot->memtbl) { ! 1941: class_name = 0; ! 1942: in_class_dcl = 0; ! 1943: } ! 1944: ! 1945: if (f->f_static && f->f_virtual) { ! 1946: error("virtual staticM"); ! 1947: f->f_virtual = 0; ! 1948: } ! 1949: ! 1950: if (n_oper) check_oper(class_name); ! 1951: etbl = tbl; ! 1952: } ! 1953: ! 1954: // Pfct(tp)->memof = class_name ? Pclass(class_name->tp) : 0; ! 1955: ! 1956: if (class_name) { ! 1957: Pclass cl; ! 1958: f->memof = cl = Pclass(class_name->tp); ! 1959: if (f->f_virtual==0 && find_virtual(f->memof,this)) ! 1960: f->f_virtual = VTOK; ! 1961: //error('d',"class_name: %s fct: %s virtual: %d", class_name->string, string, f->f_virtual ); ! 1962: ! 1963: if (f->f_static && f->f_virtual) { ! 1964: error("virtual staticM"); ! 1965: f->f_virtual = 0; ! 1966: } ! 1967: ! 1968: if ( cl->csu == UNION && f->f_virtual ) // don't worry about ANON ! 1969: error( "%n: cannot declare a virtualFWin union", this ); ! 1970: } ! 1971: ! 1972: if(f->f_const && f->memof==0) { ! 1973: error("onlyMFs can be constant"); ! 1974: } ! 1975: ! 1976: if (etbl==0 || etbl->base!=TABLE) error('i',"N::dcl: etbl=%d",etbl); ! 1977: ! 1978: switch (n_oper) { ! 1979: case CTOR: ! 1980: if (f->f_virtual) { ! 1981: error("virtualK"); ! 1982: f->f_virtual = 0; ! 1983: } ! 1984: ! 1985: // case DTOR: ! 1986: // f->f_const = 1; ! 1987: break; ! 1988: ! 1989: case REF: ! 1990: if (f->argtype) ! 1991: error("%n takes no argument",this); ! 1992: else if (f->returns->is_ptr() == 0) { ! 1993: Pname cn = f->returns->is_cl_obj(); ! 1994: if (cn==0 && f->returns->base==RPTR) cn = Pptr(f->returns)->typ->is_cl_obj(); ! 1995: if (cn==0 || Pclass(cn->tp)->has_oper(REF)==0) { ! 1996: if ( cn && class_name && // B B::operator->(); ! 1997: strcmp(cn->string, class_name->string)==0 ) ! 1998: error("%s::%n cannot return aR orCO ofC%n",cn->string,this,cn); ! 1999: else error("%n must return aP toCO, aR toCO, or aCO",this); ! 2000: tp = any_type; // suppress further checking ! 2001: } ! 2002: } ! 2003: break; ! 2004: ! 2005: case NEW: // void* operator new(long) ! 2006: if (f->f_virtual) ! 2007: error("virtual%n (operator new() is static)",this); ! 2008: if (class_name) f->f_static = 1; // if member: static by default ! 2009: if (f->nargs_known != 1) ! 2010: error("ATs must be fully specified for%n",this); ! 2011: else if (f->nargs<1) ! 2012: error("%n requires a firstA ofT size_t",this); ! 2013: else if (f->argtype->tp->check(size_t_type,0)) { ! 2014: if (strict_opt==0 ! 2015: && ( f->argtype->tp->check(long_type,0)==0 || ! 2016: f->argtype->tp->check(ulong_type,0)==0)) { ! 2017: error('w',"%n firstA should be size_t (anachronism)",this); ! 2018: f->argtype->tp = size_t_type; ! 2019: if (f->f_signature) f->sign(); ! 2020: } ! 2021: else ! 2022: error("%n requires a firstA ofT size_t",this); ! 2023: } ! 2024: else { ! 2025: Ptype t = f->s_returns ? f->s_returns : f->returns; ! 2026: if (t->check(Pvoid_type,0)) error("bad returnT for %n",this); ! 2027: } ! 2028: break; ! 2029: ! 2030: case DELETE: // void operator delete(void*) or ! 2031: // void operator delete(void*, long) ! 2032: if (f->f_virtual) ! 2033: error("virtual%n (operator delete() is static)",this); ! 2034: if (class_name) f->f_static = 1; // if member: static by default ! 2035: if (f->nargs_known != 1) ! 2036: error("ATs must be fully specified for%n",this); ! 2037: else { ! 2038: Ptype t = f->s_returns ? f->s_returns : f->returns; ! 2039: if (t->base != VOID) ! 2040: error("bad returnT for %n", this); ! 2041: else { ! 2042: switch (f->nargs) { ! 2043: default: ! 2044: error("%n takes 1 or 2As",this); ! 2045: break; ! 2046: case 1: ! 2047: case 2: ! 2048: { Pname a = f->argtype; ! 2049: if (a->tp->check(Pvoid_type,0)) ! 2050: error("%n's 1stA must be a void*",this); ! 2051: else if (a = a->n_list) { ! 2052: if (class_name == 0) ! 2053: error("%n takes only oneA",this); ! 2054: else if (a->tp->check(size_t_type,0)) { ! 2055: if (strict_opt==0 ! 2056: && a->tp->check(long_type,0)==0) { ! 2057: error('w',"%n's 2ndA should be a size_t (anachronism)",this); ! 2058: a->tp = size_t_type; ! 2059: if (f->f_signature) f->sign(); ! 2060: } ! 2061: else ! 2062: error("%n's 2ndA must be a size_t",this); ! 2063: } ! 2064: } ! 2065: } ! 2066: } ! 2067: } ! 2068: } ! 2069: break; ! 2070: ! 2071: case ASSIGN: ! 2072: if (class_name && f->nargs==1) { ! 2073: Ptype t = f->argtype->tp; ! 2074: Pname an = t->is_cl_obj(); // X::operator=(X) ? ! 2075: if (an==0 && (t=t->is_ref())) { // X::operator=(X&) ? ! 2076: t = Pptr(t)->typ; ! 2077: rx1: ! 2078: switch (t->base) { ! 2079: case TYPE: t = Pbase(t)->b_name->tp; goto rx1; ! 2080: case COBJ: an = Pbase(t)->b_name; ! 2081: } ! 2082: } ! 2083: if (an && an==class_name) Pclass(an->tp)->c_xref |= C_ASS; ! 2084: } ! 2085: else if (f->nargs == 2) { ! 2086: Ptype t = f->argtype->tp; ! 2087: Pname an1; ! 2088: if (t=t->is_ref()) { // operator=(X&,?) ? ! 2089: t = Pptr(t)->typ; ! 2090: rx2: ! 2091: switch (t->base) { ! 2092: case TYPE: t = Pbase(t)->b_name->tp; goto rx2; ! 2093: case COBJ: an1 = Pbase(t)->b_name; ! 2094: } ! 2095: } ! 2096: t = f->argtype->n_list->tp; ! 2097: Pname an2 = t->is_cl_obj(); // operator=(X&,X) ? ! 2098: if (an2==0 && (t=t->is_ref())) { // operator=(X&,X&) ? ! 2099: t = Pptr(t)->typ; ! 2100: rx3: ! 2101: switch (t->base) { ! 2102: case TYPE: t = Pbase(t)->b_name->tp; goto rx3; ! 2103: case COBJ: an2 = Pbase(t)->b_name; ! 2104: } ! 2105: } ! 2106: if (an1 && an1==an2) Pclass(an1->tp)->c_xref |= C_ASS; ! 2107: } ! 2108: } ! 2109: ! 2110: switch (scope) { ! 2111: case FCT: ! 2112: case ARG: ! 2113: if (n_sto == STATIC) error("D of staticF in aF"); ! 2114: else { // detect local re-definition ! 2115: Pname nx = gtbl->look(string,0); ! 2116: if (nx) { ! 2117: switch (nx->tp->base) { ! 2118: case FCT: ! 2119: if (tp->check(nx->tp,0)) ! 2120: error('w',"%n has been locally re-declared as%t",this,tp); ! 2121: else { ! 2122: if(Pfct(nx->tp)->f_signature==0) ! 2123: Pfct(nx->tp)->sign(); ! 2124: if (Pfct(tp)->f_signature == 0) ! 2125: Pfct(tp)->sign(); ! 2126: if ( strcmp(Pfct(nx->tp)->f_signature,Pfct(tp)->f_signature)) ! 2127: error('w',"%n of type %t has been locally re-declared with different linkage",this,tp); ! 2128: } ! 2129: break; ! 2130: case OVERLOAD: ! 2131: { Pname ny = Pgen(nx->tp)->find(f,0); ! 2132: if (ny == 0) ! 2133: error('w',"overloadedF%n has been locally declared as%t",this,tp); ! 2134: else { ! 2135: if(Pfct(ny->tp)->f_signature==0) ! 2136: Pfct(ny->tp)->sign(); ! 2137: if (Pfct(tp)->f_signature == 0) ! 2138: Pfct(tp)->sign(); ! 2139: if (strcmp(Pfct(ny->tp)->f_signature,Pfct(tp)->f_signature)) ! 2140: error('w',"overloadedF%n of type %t has been locally re-declared with different linkage",this,tp); ! 2141: } ! 2142: } ! 2143: break; ! 2144: } // switch nx->base ! 2145: } // if nx ! 2146: } // else ! 2147: } // switch scope ! 2148: ! 2149: Pname nn = etbl->insert(this,0); ! 2150: if ( f->body ) nn->where = where; ! 2151: nn->assign(); ! 2152: if (nn->tp->base==FCT) { ! 2153: Pfct nnf = (Pfct)nn->tp; ! 2154: if (nnf->f_this) nnf->f_this->where=where; ! 2155: } ! 2156: n_table = etbl; ! 2157: //error('d',"%n->dofct(): n_initializer:%d f->f_virtual:%d",this,n_initializer,f->f_virtual); ! 2158: if (n_initializer) { ! 2159: if (f->f_virtual == 0) error("Ir for non-virtualF%n",this); ! 2160: if (n_initializer != zero) error("virtualFIr must be 0"); ! 2161: } ! 2162: ! 2163: if (Nold) { ! 2164: Pfct nf = Pfct(nn->tp); ! 2165: // error('d',"old %n: %t and %t",nn,nf,tp); ! 2166: int flag = 0; ! 2167: Pname af=0,anf=0; ! 2168: if (nf->base==ANY || f->base==ANY) ! 2169: ; // wild card -- do nothing ! 2170: else ! 2171: if (nf->base == OVERLOAD) { ! 2172: string = nn->string; ! 2173: nn = Pgen(nf)->add(this); ! 2174: nn->where=where; ! 2175: if (Pfct(nn->tp)->f_this!=0) ! 2176: Pfct(nn->tp)->f_this->where=where; ! 2177: ! 2178: if (Nold == 0) { ! 2179: if (f->body && n_qualifier) { ! 2180: error("badAL for%n",this); ! 2181: return 0; ! 2182: } ! 2183: goto thth; ! 2184: } ! 2185: // else { ! 2186: // if (f->body==0 && friend_in_class==0) error('w',"%n redeclared",nn); ! 2187: // } ! 2188: nf = Pfct(nn->tp); ! 2189: if (f->body && nf->body) { ! 2190: // Preserve the original definition ! 2191: // in the case of a PT class; i.e, ! 2192: // the one supplied by the user ! 2193: if (!(class_name && ! 2194: (Pclass(class_name->tp)->class_base == ! 2195: instantiated_template_class) && ! 2196: nn->n_redefined)) ! 2197: { ! 2198: error("two definitions of%n",nn); ! 2199: f->body = 0; ! 2200: } ! 2201: return 0; ! 2202: } ! 2203: if (f->body) goto bdbd; ! 2204: goto stst; ! 2205: } ! 2206: else if (nf->base != FCT) { ! 2207: error("%n declared both as%t and asF",this,nf); ! 2208: f->body = 0; ! 2209: } ! 2210: else { ! 2211: // error('d',"%t->check(%t) -> %d %d",nf,f,nf->check(f,OVERLOAD)); ! 2212: if (nf->check(f,OVERLOAD) || const_problem) { ! 2213: if (f->body && n_qualifier) { ! 2214: error("%nT mismatch: %t and %t",nn,nf,f); ! 2215: return 0; ! 2216: } ! 2217: Pgen g = new gen; ! 2218: add_first = 1; ! 2219: Pname n1 = g->add(nn); ! 2220: add_first = 0; ! 2221: string = nn->string; ! 2222: Pname n2 = g->add(this); ! 2223: nn->tp = g; ! 2224: nn = n2; ! 2225: goto thth; ! 2226: } ! 2227: ! 2228: af = f->argtype; ! 2229: anf = nf->argtype; ! 2230: for (; af && anf; af=af->n_list,anf=anf->n_list) { ! 2231: Ptype at = af->tp; ! 2232: Ptype atp = anf->tp; ! 2233: if(!exact1(af,atp)) break; ! 2234: if(at->base!=PTR || ! 2235: Pptr(at)->b_const == Pptr(atp)->b_const) continue; ! 2236: int k = Pptr(at)->typ->tconst(); ! 2237: int l = Pptr(atp)->typ->tconst(); ! 2238: if(k==l) flag=1; ! 2239: } ! 2240: if ( flag && !af && !anf) { ! 2241: error("the overloading mechanism cannot tell a%t from a%t",nf,f); ! 2242: } ! 2243: ! 2244: if (in_class_dcl) { ! 2245: // error("twoDs of%n",this); ! 2246: // f->body = 0; ! 2247: // return 0; ! 2248: } ! 2249: else if (nf->f_static && f->f_inline==0 && n_sto==STATIC) { ! 2250: //error('d',"MF%n declared static outsideF",this); ! 2251: n_sto = 0; ! 2252: } ! 2253: else if (n_sto && n_sto!=nn->n_scope) { ! 2254: if (n_sto==EXTERN && nn->n_scope==STATIC) ! 2255: error('w',"%n declared extern after being declared static",this); ! 2256: else if (nf->f_inline==0 && f->f_inline==0) { ! 2257: if (nn->tp==new_fct->tp || nn->tp==del_fct->tp) ! 2258: nn->n_sto = n_sto; ! 2259: else ! 2260: error("%n declared as both%k and%k",this,n_sto,(nn->n_sto)?nn->n_sto:EXTERN); ! 2261: } ! 2262: } ! 2263: ! 2264: //error('d',"fct %n: %k %k scope %k",this,n_sto,nn->n_sto,nn->n_scope); ! 2265: //error('d',"link %d lcount %d sig %s",linkage,lcount,nf->f_signature); ! 2266: ! 2267: { ! 2268: Linkage l1 = nf->f_linkage; ! 2269: Linkage l2 = f->f_linkage; ! 2270: if ( l2!=linkage_default && l1!=l2) ! 2271: error("inconsistent linkage specifications for%n",this); ! 2272: } ! 2273: if (nf->body && f->body) { ! 2274: // Preserve the original definition ! 2275: // in the case of a PT class; i.e, ! 2276: // the one supplied by the user ! 2277: if (!(class_name && ! 2278: (Pclass(class_name->tp)->class_base == ! 2279: instantiated_template_class) && ! 2280: nn->n_redefined)) ! 2281: { ! 2282: error("two definitions of%n",this); ! 2283: f->body = 0; ! 2284: } ! 2285: return 0; ! 2286: } ! 2287: ! 2288: if (f->body) goto bdbd; ! 2289: ! 2290: goto stst; ! 2291: ! 2292: bdbd: ! 2293: // error('d',"nn %n init: %d f_virt: %d f->body: %d", nn,nn->n_initializer,nf->f_virtual,f->body); ! 2294: if (f->nargs_known && nf->nargs_known) merge_init(nn,f,nf); ! 2295: f->f_virtual = nf->f_virtual; ! 2296: f->f_this = nf->f_this; ! 2297: f->f_result = nf->f_result; ! 2298: f->s_returns = nf->s_returns; ! 2299: f->f_args = nf->f_args; ! 2300: // f->argtype = nf->argtype; ! 2301: f->f_signature = nf->f_signature; ! 2302: f->f_const = nf->f_const; ! 2303: f->f_static = nf->f_static; ! 2304: nn->tp = f; ! 2305: if (f->f_inline) { ! 2306: if (nf->f_inline==0) { ! 2307: if (nn->n_used && nn->n_sto!=STATIC) ! 2308: error("%n declared with external linkage and called before defined as inline",nn); ! 2309: // else if (nf->memof) ! 2310: // error('w',"%n declared as non-inline but defined as inline",nn); ! 2311: else if (nn->n_used) { ! 2312: nn->take_addr(); // force printout ! 2313: if (warning_opt) error('w',"%n called before defined as inline",nn); ! 2314: } ! 2315: } ! 2316: nf->f_inline = 1; ! 2317: nn->n_sto = STATIC; ! 2318: } ! 2319: else if (nf->f_inline) { ! 2320: // error('w',"%n defined as inline but not declared as inline",this); ! 2321: f->f_inline = 1; ! 2322: } ! 2323: goto stst2; ! 2324: ! 2325: stst: ! 2326: //error('d',"stst"); ! 2327: if (f->nargs_known && nf->nargs_known) merge_init(nn,f,nf); ! 2328: f->f_args = nf->f_args; ! 2329: // f->argtype = nf->argtype; ! 2330: stst2: ! 2331: //error('d',"stst2 %n printed %d",nn,nn->n_dcl_printed); ! 2332: if (f->f_inline) n_sto = STATIC; ! 2333: ! 2334: /* superceded above (line 1978 and following) ! 2335: if (n_sto ! 2336: && nn->n_scope!=n_sto ! 2337: && friend_in_class==0 ! 2338: && f->f_inline==0){ // allow re-def to "static" ! 2339: if (n_sto == STATIC) ! 2340: nn->n_sto = STATIC; ! 2341: else { ! 2342: error("%n both%k and%k",this,n_sto,nn->n_scope); ! 2343: } ! 2344: } ! 2345: */ ! 2346: ! 2347: //// addition for 2.1 ! 2348: ! 2349: if(n_sto == STATIC && nn->n_sto == EXTERN && ! 2350: (!strcmp(string,"__nw") || !strcmp(string,"__dl"))) ! 2351: nn->n_sto = STATIC; ! 2352: ! 2353: //// end of addition ! 2354: ! 2355: n_scope = nn->n_scope; // first specifier wins ! 2356: n_sto = nn->n_sto; ! 2357: } ! 2358: } ! 2359: else { // new function: make f_this for member functions ! 2360: thth: ! 2361: just_made = 1; ! 2362: if (f->f_inline) ! 2363: nn->n_sto = STATIC; ! 2364: else if (class_name==0 && n_sto==0 && f->body==0) ! 2365: nn->n_sto = EXTERN; ! 2366: //error('d',"thth %n %t static %d sto %k",nn,f,f->f_static,nn->n_sto); ! 2367: if (f->f_static) ! 2368: switch (n_oper) { // what about + ?? ! 2369: case CTOR: ! 2370: case DTOR: ! 2371: case TYPE: ! 2372: case CALL: ! 2373: case DEREF: ! 2374: case REF: ! 2375: case ASSIGN: ! 2376: error("%n cannot be a staticMF",nn); ! 2377: f->f_static = 0; ! 2378: } ! 2379: ! 2380: if (class_name ! 2381: && f->f_static==0 // no ``this'' in static members ! 2382: && n_oper!=NEW // X::operator new() static by default ! 2383: && n_oper!=DELETE // X::operator delete() static by default ! 2384: && etbl!=gtbl) { // beware of implicit declaration ! 2385: Pname cn = nn->n_table->t_name; ! 2386: Pname tt = new name("this"); ! 2387: tt->n_scope = ARG; ! 2388: // tt->where = no_where; ! 2389: tt->where = this->where; ! 2390: // tt->n_sto = ARG; ! 2391: tt->tp = Pclass(class_name->tp)->this_type; ! 2392: PERM(tt); ! 2393: Pfct(nn->tp)->f_this = f->f_this = Pfct(nn->tp)->f_args = f->f_args = tt; ! 2394: tt->n_list = f->argtype; ! 2395: //error('d',"nn %n tp %t const %d",nn,nn->tp,f->f_const); ! 2396: if (f->f_const /*&& n_oper!=CTOR && n_oper!=DTOR*/) { ! 2397: Pbase x = Pbase(Pptr(tt->tp)->typ); ! 2398: Pbase y = new basetype(COBJ,0); ! 2399: *y = *x; ! 2400: y->b_const = 1; ! 2401: tt->tp = new ptr(PTR,y); ! 2402: Pptr(tt->tp)->b_const = 1; ! 2403: PERM(tt->tp); ! 2404: } ! 2405: } ! 2406: else { ! 2407: Pfct(nn->tp)->f_args = f->f_args = f->f_result?f->f_result:f->argtype; ! 2408: Pfct(nn->tp)->f_signature = f->f_signature; ! 2409: Pfct(nn->tp)->f_const = f->f_const; ! 2410: Pfct(nn->tp)->f_static = f->f_static; ! 2411: } ! 2412: ! 2413: // if C++ linkage encode type in function name ! 2414: if (Pfct(nn->tp)->f_signature==0) Pfct(nn->tp)->sign(); ! 2415: ! 2416: if (f->f_result == 0) { ! 2417: //error('d',"re1 %n %t %d",this,f,f); ! 2418: make_res(f); ! 2419: } ! 2420: else if (f->f_this) ! 2421: f->f_this->n_list = f->f_result; ! 2422: ! 2423: if (nn->n_oper==CTOR || nn->n_oper==DTOR) vbase_pointers(nn,Pclass(class_name->tp)); ! 2424: ! 2425: if (f->f_virtual) { ! 2426: switch (nn->n_scope) { ! 2427: default: ! 2428: error("nonC virtual%n",this); ! 2429: break; ! 2430: case 0: ! 2431: case PUBLIC: ! 2432: // if (fvirt) //BSopt ! 2433: cc->cot->virt_count = 1; ! 2434: Pfct(nn->tp)->f_virtual = f->f_virtual; ! 2435: break; ! 2436: } ! 2437: } ! 2438: } ! 2439: ! 2440: /* an operator must take at least one class object or ! 2441: reference to class object argument ! 2442: */ ! 2443: ! 2444: if (just_made) ! 2445: switch (n_oper) { ! 2446: case CTOR: ! 2447: switch (f->nargs) { // check for X(X) and X(X&) ! 2448: case 0: ! 2449: break; ! 2450: default: // handle X(X&, int i = 0) ! 2451: { Pname n2 = f->argtype->n_list; ! 2452: if (n2->n_initializer==0 && n2->n_evaluated==0) break; ! 2453: } ! 2454: case 1: ! 2455: { ! 2456: Ptype t = f->argtype->tp; ! 2457: clll: ! 2458: switch (t->base) { ! 2459: case TYPE: ! 2460: t = Pbase(t)->b_name->tp; ! 2461: goto clll; ! 2462: case RPTR: /* X(X&) ? */ ! 2463: t = Pptr(t)->typ; ! 2464: cxll: ! 2465: switch (t->base) { ! 2466: case TYPE: ! 2467: t = Pbase(t)->b_name->tp; ! 2468: goto cxll; ! 2469: case COBJ: ! 2470: if (class_name == Pbase(t)->b_name) ! 2471: Pclass(class_name->tp)->c_itor = nn; ! 2472: } ! 2473: break; ! 2474: case COBJ: /* X(X) ? */ ! 2475: if (class_name == Pbase(t)->b_name) { ! 2476: error("badK %s(%s) use %s(%s&)",class_name->string,class_name->string,class_name->string,class_name->string); ! 2477: f->argtype->tp = any_type; ! 2478: } ! 2479: } ! 2480: } ! 2481: } ! 2482: if (Pclass(class_name->tp)->c_ctor == 0) Pclass(class_name->tp)->c_ctor = nn; ! 2483: break; ! 2484: ! 2485: case TYPE: ! 2486: // somewhat simple minded solution to the inheritance of ! 2487: // conversion operator problem ! 2488: nn->n_list = Pclass(class_name->tp)->conv; ! 2489: Pclass(class_name->tp)->conv = nn; ! 2490: break; ! 2491: ! 2492: case DTOR: ! 2493: Pclass(class_name->tp)->c_dtor = nn; ! 2494: break; ! 2495: ! 2496: case NEW: ! 2497: case DELETE: ! 2498: case CALL: ! 2499: case 0: ! 2500: break; ! 2501: ! 2502: default: ! 2503: for (Pname a=f->argtype; a; a=a->n_list) { ! 2504: if ( a->n_initializer ) ! 2505: error( "%n: operatorFs cannot take defaultA", this ); ! 2506: } ! 2507: ! 2508: if (f->nargs_known != 1) { ! 2509: error("ATs must be fully specified for%n",nn); ! 2510: } ! 2511: // this doesn't catch unary operator off by one errors ! 2512: // for simplicity, placed that check in check_oper(), above ! 2513: else if (class_name == 0) { ! 2514: switch (f->nargs) { ! 2515: case 1: ! 2516: case 2: ! 2517: for (a=f->argtype; a; a=a->n_list) { ! 2518: Ptype tx = a->tp; ! 2519: while (tx->base == TYPE) tx = Pbase(tx)->b_name->tp; ! 2520: if (tx->is_ref()) tx = Pptr(tx)->typ; ! 2521: if (tx->is_cl_obj()) goto cok; ! 2522: } ! 2523: error("%n must take at least oneCTA",nn); ! 2524: break; ! 2525: default: ! 2526: error("%n must take 1 or 2As",nn); ! 2527: } ! 2528: } ! 2529: else { ! 2530: switch (f->nargs) { ! 2531: case 0: ! 2532: case 1: ! 2533: break; ! 2534: default: ! 2535: error("%n must take 0 or 1As",nn); ! 2536: } ! 2537: } ! 2538: cok:; ! 2539: } ! 2540: ! 2541: int i = 0; // check that every argument after an argument with ! 2542: // initializer have an initializer ! 2543: for (Pname a = f->f_args/*f->argtype*/; a; a=a->n_list) { ! 2544: if (a->n_initializer) ! 2545: i = 1; ! 2546: else if (i) ! 2547: error("trailingA%n withoutIr",a); ! 2548: } ! 2549: ! 2550: /* ! 2551: the body cannot be checked until the name ! 2552: has been checked and entered into its table ! 2553: */ ! 2554: if (f->body) f->dcl(nn); ! 2555: return nn; ! 2556: } ! 2557:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.