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