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