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