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