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