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