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