|
|
1.1 root 1: /*ident "@(#)ctrans:src/dcl.c 1.3.5.41" */
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 rigths Reserved
8: THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T, INC.
9:
10: dcl.c:
11:
12: ``declare'' all names, that is insert them in the appropriate symbol tables.
13:
14: Calculate the size for all objects (incl. stack frames),
15: and find store the offsets for all members (incl. auto variables).
16: "size.h" holds the constants needed for calculating sizes.
17:
18: Note that (due to errors) functions may nest
19:
20: *****************************************************************************/
21:
22:
23: #include "cfront.h"
24: #include "size.h"
25:
26: class dcl_context ccvec[MAXCONT], * cc = ccvec;
27: int byte_offset;
28: int bit_offset;
29: int max_align;
30: int friend_in_class;
31: static Pstmt itail;
32:
33: Pname dclass(Pname, Ptable);
34: Pname denum(Pname, Ptable);
35: void merge_init(Pname, Pfct, Pfct);
36:
37: void dosimpl(Pexpr e, Pname n)
38: {
39: //error('d',"dosimpl %k %n",e?e->base:0,n);
40: if (n==0) {
41: if (dummy_fct == 0) make_dummy();
42: n = dummy_fct;
43: }
44: Pname cf = curr_fct;
45: curr_fct = n;
46: e->simpl();
47: curr_fct = cf;
48: }
49:
50: static Pexpr co_array_init(Pname n, Ptable tbl)
51: /*
52: handle simple arrays only. To be done well list_check() must
53: be rewritten to handle dynamic initialization.
54: */
55: {
56: // error('d',"Ir forCO%n\[\]",n);
57: Pexpr init = n->n_initializer;
58:
59: if (init->base != ILIST) {
60: error("badIr for array ofCOs %n",n);
61: return 0;
62: }
63:
64: Pexpr el = 0;
65: Pvec v = Pvec(n->tp);
66: while (v->base==TYPE) v = Pvec(Pbase(v)->b_name->tp);
67: Pname cn = v->typ->is_cl_obj();
68: Pclass cl = cn ? Pclass(cn->tp) : 0;
69: //error('d',"v %t cl %d %t",v,cl,cl);
70: int i = v->size;
71:
72: int count = 0;
73: Pexpr il2;
74: for (Pexpr il = init->e1; il; il = il2) {
75: // generate n[0].cl(initializer),
76: // ...
77: // n[max].cl(initializer),
78: Pexpr e = il->e1;
79: il2 = il->e2;
80: il->e2 = 0;
81: if (e == dummy) break;
82: //error('d',"il %k e %k",il->base,e?e->base:0);
83: if (e->base == VALUE) {
84: switch (e->tp2->base) {
85: case CLASS:
86: if (Pclass(e->tp2)!=cl) e = new texpr(VALUE,cl,il);
87: break;
88: default:
89: Pname n2 = e->tp2->is_cl_obj();
90: if (n2==0 || Pclass(n2->tp)!=cl) e = new texpr(VALUE,cl,il);
91: }
92: }
93: else
94: e = new texpr(VALUE,cl,il);
95: e->e2 = new expr(DEREF,n,new ival(count++));
96: e = e->typ(tbl);
97: dosimpl(e,cc->nof);
98: // e->simpl();
99: if (sti_tbl == tbl) {
100: Pstmt ist = new estmt(SM,no_where,e,0);
101: if (st_ilist == 0)
102: st_ilist = ist;
103: else
104: itail->s_list = ist;
105: itail = ist;
106: }
107: else {
108: el = el ? new expr(G_CM,el,e) : e;
109: }
110: }
111:
112: if (i==0)
113: v->size = count;
114: else if (i==count)
115: ;
116: else if (i<count) {
117: error("too manyIrs for%n (%d)",n, count);
118: return 0;
119: }
120: else {
121: // error('d',"too fewIrs for%n (%d)",n, count);
122: if (cl->has_ictor())
123: error('s',"too fewIrs for%n",n);
124: else error( "too fewIrs for%n (C %srequires a defaultK)", n, cl->string );
125: return 0;
126: }
127: return el;
128: }
129:
130: int need_sti(Pexpr e, Ptable tbl, bit accept_name)
131: /*
132: check if non-static variables or operations are used
133: INCOMPLETE
134: */
135: {
136: if (e == 0) return 0;
137: // error('d',"need_sti: %d - %d %k %t",tbl?1:0,accept_name,e->base,e->tp);
138:
139: switch (e->base) {
140: case QUEST:
141: if (need_sti(e->cond,tbl,0) && tbl==0) return 1;
142: case PLUS:
143: case MINUS:
144: case MUL:
145: case DIV:
146: case MOD:
147: case ER:
148: case OR:
149: case ANDAND:
150: case OROR:
151: case LS:
152: case RS:
153: case EQ:
154: case NE:
155: case LT:
156: case LE:
157: case GT:
158: case GE:
159: case INCR:
160: case DECR:
161: case ASSIGN:
162: if (need_sti(e->e1,tbl,accept_name) && tbl==0) return 1;
163: // no break;
164:
165: case UMINUS:
166: case UPLUS:
167: case NOT:
168: case COMPL:
169: if (need_sti(e->e2,tbl,accept_name) && tbl==0) return 1;
170: // no break
171:
172: case SIZEOF:
173: default:
174:
175: return 0;
176:
177: case CAST:
178:
179: return need_sti(e->e1,tbl,accept_name);
180:
181: case ADDROF:
182: {
183: int i = need_sti(e->e2,tbl,1);
184: return i;
185: }
186:
187: case NAME:
188: if (accept_name && Pname(e)->n_stclass==STATIC) return 0;
189:
190: // if ((Pname(e)->n_stclass==AUTO || Pname(e)->n_stclass==REGISTER)
191: // && strncmp(Pname(e)->string,"__Q",3) != 0 ) {
192: // error("localN%n inIr for static",e);
193: // return 0;
194: // }
195:
196: if (e->tp->tconst()) {
197: if (vec_const || fct_const) return 0;
198: Neval = 0;
199: e->eval();
200: if (Neval == 0) return 0;
201: }
202: return 1;
203:
204: case DEREF:
205: case REF:
206: case DOT:
207: if (accept_name||(e->tp && e->tp->base==VEC)) {
208: int x1 = need_sti(e->e1,tbl,e->base == DOT);
209: int x2 = need_sti(e->e2,tbl,0);
210: return x1 || x2;
211: }
212: // no break
213:
214: case ELIST:
215: // case ILIST:
216: case G_CM:
217: case CM:
218: case CALL:
219: case G_CALL:
220: case NEW:
221: case GNEW:
222: case 0: // hack for `new type (expr)'
223: if (tbl) {
224: need_sti(e->e1,tbl,accept_name);
225: need_sti(e->e2,tbl,accept_name);
226: if ( e->tp && e->tp->base == VEC &&
227: e->base == NEW || e->base == GNEW )
228: // preserve ICON,STRING,CCON,FCON
229: need_sti(Pvec(e->tp)->dim,tbl);
230: }
231: else if (e->base == 0)
232: return 0;
233: // no break
234: case ICALL:
235: return 1;
236: case ICON:
237: case STRING:
238: case CCON:
239: case FCON:
240: //error('d',"save %k tbl %d",e->base,tbl);
241: if (tbl) {
242: char* p = new char[strlen(e->string)+1];
243: strcpy(p,e->string);
244: e->string = p;
245: }
246: return 0;
247: }
248: }
249:
250: void check_def_name( Pname nn, int scope )
251: {
252: // error('d', "check_def_name: nn: %n n_sto: %k scope: %k", nn,nn->n_sto,scope );
253: if ( def_name==0 && pdef_name==0 && friend_in_class == 0 &&
254: scope == EXTERN && nn->n_scope != STATIC &&
255: nn->n_oper != NEW && nn->n_oper != DELETE ) {
256: Pfct f = Pfct(nn->tp);
257: if (f->body &&
258: f->f_inline == 0 &&
259: f->f_imeasure == 0) {
260: // error('d', "check_def_name: do it: %n", nn );
261: pdef_name = def_name = nn;
262: ptbl_init(0);
263: def_name = 0;
264: }
265: }
266: }
267:
268: Pname name::dcl(Ptable tbl, TOK scope)
269: /*
270: enter a copy of this name into symbol table "tbl";
271: - create local symbol tables as needed
272:
273: "scope" gives the scope in which the declaration was found
274: - EXTERN, FCT, ARG, PUBLIC, or 0
275: Compare "scope" with the specified storage class "n_sto"
276: - AUTO, STATIC, REGISTER, EXTERN, OVERLOAD, FRIEND, or 0
277:
278: After name::dcl()
279: n_stclass == 0 class or enum member
280: REGISTER auto variables declared register
281: AUTO auto variables not registers
282: STATIC statically allocated object
283: n_scope == 0 private class member
284: PUBLIC public class member
285: EXTERN name valid in this and other files
286: STATIC name valid for this file only
287: FCT name local to a function
288: ARG name of a function argument
289: ARGT name of a type defined in an
290: argument list
291:
292: typecheck function bodies;
293: typecheck initializers;
294:
295: note that functions (error recovery) and classes (legal) nest
296:
297: The return value is used to chain symbol table entries, but cannot
298: be used for printout because it denotes the sum of all type information
299: for the name
300:
301: names of typenames are marked with n_oper==TNAME
302:
303: WARNING: The handling of scope and storage class is cursed!
304: */
305: {
306: Pname nn;
307: Ptype nnt = 0;
308: Pname odcl = Cdcl;
309: int sti_vb = 0; // set if initialize with virtual base class
310:
311: // if (this == 0) error('i',"0->N::dcl()");
312: // if (tbl == 0) error('i',"%n->N::dcl(tbl=0,%k)",this,scope);
313: // if (tbl->base != TABLE) error('i',"%n->N::dcl(tbl=%d,%k)",this,tbl->base,scope);
314: // if (tp == 0) error('i',"N::dcl(%n,%k)T missing",this,scope);
315:
316: Cdcl = this;
317: Ptype tx = tp;
318:
319: DB( if(Ddebug>=1) error('d',"dcl %n %t",this,tx); );
320: // error('d',"dcl %n %t cc->cot: %d",this,tx,cc?cc->cot:0);
321: while (tx->base == TYPE) tx = Pbase(tx)->b_name->tp;
322:
323: switch (base) {
324: case TNAME:
325: nn = tbl->look(string,0);
326: tp->dcl(tbl);
327: if (nn && nn->lex_level == lex_level) {
328: //error('d', "dcl: cot: %s ccl: %s", cc->cot?cc->cot->string:"notset", ccl?ccl->string:"notset");
329:
330: if ( tp->check(nn->tp,0) )
331: error("%n declared as %t and %t",nn,nn->tp,tp);
332: else if ( nn->base == NAME && cc->cot == 0 &&
333: (tp->base != COBJ || tp->base != EOBJ))
334: error("%n declared as identifier and typedef", nn );
335: Cdcl = odcl;
336: return 0;
337:
338: }
339: PERM(tp);
340: nn = new name(string);
341: nn->base = TNAME;
342: nn->tp = tp;
343: Pname tn = tbl->insert(nn,0);
344: if (n_key == NESTED) {
345: tn->n_key = NESTED;
346: tn->tpdef = tpdef;
347: }
348: delete nn;
349: Cdcl = odcl;
350: return this;
351:
352: case NAME:
353: switch (n_oper) {
354: case COMPL:
355: if (tp->base != FCT) {
356: error("~%s notF",string);
357: n_oper = 0;
358: }
359: break;
360: case TNAME:
361: if (tp->base != FCT) n_oper = 0;
362: break;
363: }
364: break;
365: default:
366: error('i',"NX in N::dcl()");
367: }
368:
369: if (n_qualifier) {
370: // c::f()
371: // class function,
372: // friend declaration, or
373: // static member initializer
374:
375: //III if (tp->base != FCT) {
376: // error("QdN%n inD of nonF",this);
377: // Cdcl = odcl;
378: // return 0;
379: // }
380:
381: Pname cn = n_qualifier;
382:
383: switch (cn->base) {
384: case TNAME:
385: break;
386: case NAME:
387: cn = gtbl->look(cn->string,0);
388: if (cn && cn->base==TNAME) break;
389: default:
390: error("badQr%n for%n",n_qualifier,this);
391: Cdcl = odcl;
392: return 0;
393: }
394:
395: while (cn->tp->base == TYPE) cn->tp = Pbase(cn->tp)->b_name->tp;
396: // error('d',"actualQr%n %t",cn,cn->tp);
397: if (cn->tp->base != COBJ) {
398: error(&where,"Qr%nnot aCN",n_qualifier);
399: Cdcl = odcl;
400: return 0;
401: }
402:
403: cn = Pbase(cn->tp)->b_name;
404: if (n_oper) check_oper(cn);
405:
406: Pclass cl = Pclass(cn->tp);
407: if (cl == cc->cot) {
408: n_qualifier = 0;
409: goto xdr;
410: }
411: else if ((cl->defined&(DEFINED|SIMPLIFIED)) == 0) {
412: error("C%nU",cn);
413: Cdcl = odcl;
414: return 0;
415: }
416: else if (cl->c_body==1) //III
417: cl->dcl_print(0);
418:
419: Ptable etbl = cl->memtbl;
420: Pname x = etbl->look(string,0);
421: if (x==0 || x->n_table!=etbl) {
422: error("%n is not aM of%n",this,cn);
423: Cdcl = odcl;
424: return 0;
425: }
426:
427: if (tp->base == FCT) { //III
428: // if (friend_in_class==0 && Pfct(tp)->body==0) { // c::f(); needed for friend
429: if (friend_in_class==0
430: && n_sto!=FRIEND
431: && Pfct(tp)->body==0) { // c::f(); needed for friend
432: error("QdN%n inFD",x);
433: Cdcl = odcl;
434: return 0;
435: }
436:
437: if (Pfct(tp)->body==0) {
438: Pfct(tp)->memof = cl;
439: int xx;
440: if (x->tp->base==OVERLOAD)
441: xx = Pgen(x->tp)->find(Pfct(tp),0)==0;
442: else
443: xx = x->tp->check(tp,0);
444:
445: if (xx) {
446: error("%n is not aM of%n",this,cn);
447: Cdcl = odcl;
448: return 0;
449: }
450: }
451: }
452: else {
453: if (x->n_stclass != STATIC) { // e.g. int c::i = 7
454: error("D of non staticCM %n",this);
455: Cdcl = odcl;
456: return 0;
457: }
458: if (n_sto) error("staticCM declared%k",n_sto);
459: tbl = etbl;
460: }
461: }
462: xdr:
463: if (n_oper
464: && tp->base!=FCT
465: && n_sto!=OVERLOAD) error("operator%k not aF",n_oper);
466:
467:
468: /* if a storage class was specified
469: check that it is legal in the scope
470: else
471: provide default storage class
472: some details must be left until the type of the object is known
473: */
474:
475: n_stclass = n_sto;
476: n_scope = scope; /* default scope & storage class */
477:
478: switch (n_sto) {
479: default:
480: error('i',"unX %k",n_sto);
481: case FRIEND:
482: {
483: Pclass cl = cc->cot;
484:
485: switch (scope) {
486: case 0:
487: case PUBLIC:
488: break;
489: default:
490: error("friend%n not inCD(%k)",this,scope);
491: base = 0;
492: Cdcl = odcl;
493: return 0;
494: }
495:
496: switch (n_oper) {
497: case 0:
498: case NEW:
499: case DELETE:
500: case CTOR:
501: case DTOR:
502: case TYPE:
503: n_sto = 0;
504: break;
505: default:
506: n_sto = OVERLOAD;
507: }
508:
509: switch (tx->base) {
510: case COBJ:
511: nn = Pbase(tx)->b_name;
512: break;
513: case CLASS:
514: nn = this;
515: break;
516: case FCT:
517: cc->stack();
518: cc->not = 0;
519: cc->tot = 0;
520: cc->cot = 0;
521: friend_in_class++;
522: // n_sto = EXTERN;
523: n_sto = 0;
524: nn = dcl(gtbl,EXTERN);
525: if (nn == 0) {
526: Cdcl = odcl;
527: return 0;
528: }
529: friend_in_class--;
530: cc->unstack();
531: if (nn->tp->base == OVERLOAD) nn = Pgen(nn->tp)->find(Pfct(tx),1);
532: break;
533: default:
534: error("badT%tof friend%n",tp,this);
535: Cdcl = odcl;
536: return 0;
537: }
538: PERM(nn);
539: cl->friend_list = new name_list(nn,cl->friend_list);
540: Cdcl = odcl;
541: return nn;
542: }
543: case OVERLOAD:
544: if (strict_opt||warning_opt)
545: error(strict_opt?0:'w',"`overload' used (anachronism)");
546: n_sto = 0;
547: // ignore overload!
548: // switch (scope) {
549: // case 0:
550: // case PUBLIC:
551: // error('w',"overload inCD (ignored)");
552: switch (tp->base) {
553: case FCT:
554: break;
555: default:
556: base = 0;
557: Cdcl = odcl;
558: return this;
559: // case FCT:
560: // Cdcl = odcl;
561: // return dcl(tbl,scope);
562: }
563: // }
564: // if (n_oper && tp->base==FCT) break;
565: // nn = tbl->insert(this,0);
566: //
567: // if (Nold) {
568: // if (nn->tp->base != OVERLOAD) {
569: // error("%n redefined as overloaded",this);
570: // nn->tp = new gen;
571: // }
572: // }
573: // else {
574: // nn->tp = new gen;
575: // }
576: //
577: // switch (tx->base) {
578: // case INT:
579: // base = 0;
580: // Cdcl = odcl;
581: // return nn;
582: // case FCT:
583: // break;
584: // default:
585: // error("N%n ofT%k cannot be overloaded",this,tp->base);
586: // Cdcl = odcl;
587: // return nn;
588: // }
589: break;
590: case REGISTER:
591: if (tp->base == FCT) {
592: error('w',"%n: register (ignored)",this);
593: goto ddd;
594: }
595: case AUTO:
596: switch (scope) {
597: case 0:
598: case PUBLIC:
599: case EXTERN:
600: error("%k not inF",n_sto);
601: goto ddd;
602: }
603: if (n_sto==AUTO) n_sto = 0; // always redundant
604: break;
605: case EXTERN:
606: switch (scope) {
607: case ARG:
608: //error("externA");
609: goto ddd;
610: case 0:
611: case PUBLIC:
612: /* extern is provided as a default for functions without body */
613: if (tp->base != FCT) error("externM%n",this);
614: goto ddd;
615: case FCT:
616: {
617: Pname nn = gtbl->look( string, 0 );
618: if ( nn && tp->base != FCT &&
619: tp->check(nn->tp,0))
620: {
621: error("twoDs of%n;Ts:%t and%t",this,nn->tp,tp);
622: Cdcl = odcl;
623: return 0;
624: }
625: }
626: }
627: n_stclass = STATIC;
628: n_scope = EXTERN; /* avoid FCT scoped externs to allow better checking */
629: break;
630: case STATIC:
631: switch (scope) {
632: case ARG:
633: //error("static used forA%n",this);
634: goto ddd;
635: case 0:
636: case PUBLIC:
637: n_stclass = STATIC;
638: n_scope = scope;
639: break;
640: default:
641: n_scope = STATIC;
642: }
643: break;
644: case 0:
645: ddd:
646: switch (scope) { /* default storage classes */
647: case EXTERN:
648: n_scope = EXTERN;
649: n_stclass = STATIC;
650: break;
651: case FCT:
652: if (tp->base == FCT) {
653: n_stclass = STATIC;
654: n_scope = EXTERN;
655: }
656: else
657: n_stclass = AUTO;
658: break;
659: case ARG:
660: n_stclass = AUTO;
661: break;
662: case 0:
663: case PUBLIC:
664: n_stclass = 0;
665: break;
666: }
667: }
668:
669:
670: /*
671: now insert the name into the appropriate symbol table,
672: and compare types with previous declarations of that name
673:
674: do type dependent adjustments of the scope
675: */
676: //error('d',"sw %d",tx->base);
677: switch (tx->base) {
678: case ASM:
679: { Pbase b = Pbase(tp);
680: Pname n = tbl->insert(this,0);
681: n->assign();
682: n->use();
683: char* s = (char*) b->b_name; // save asm string. Shoddy
684: int ll = strlen(s);
685: char* s2 = new char[ll+1];
686: strcpy(s2,s);
687: b->b_name = Pname(s2);
688: Cdcl = odcl;
689: return this;
690: }
691:
692: case CLASS:
693: tp = tx;
694: nn = dclass(this,tbl);
695: Cdcl = odcl;
696: return nn;
697:
698: case ENUM:
699: tp = tx;
700: nn = denum(this,tbl);
701: Cdcl = odcl;
702: return nn;
703:
704: case FCT:
705: tp = tx;
706: nn = dofct(tbl,scope);
707: if (nn == 0) {
708: Cdcl = odcl;
709: return 0;
710: }
711:
712: // error('d', "%s n_oper: %k, scope: %k", string, n_oper, scope );
713: if (pdef_name == 0) check_def_name(nn, scope);
714: break;
715:
716: case FIELD:
717: switch (n_stclass) {
718: case 0:
719: case PUBLIC:
720: break;
721: default:
722: error("%k field",n_stclass);
723: n_stclass = 0;
724: }
725:
726: if (cc->not==0 || cc->cot->csu==UNION || cc->cot->csu==ANON) {
727: error(cc->not?"field in union":"field not inC");
728: PERM(tp);
729: Cdcl = odcl;
730: return this;
731: }
732:
733: if (string) {
734: nn = tbl->insert(this,0);
735: n_table = nn->n_table;
736: if (Nold) error("twoDs of field%n",this);
737: }
738:
739: tp->dcl(tbl);
740: field_align();
741: break;
742:
743: case COBJ:
744: { Pclass cl = Pclass(Pbase(tx)->b_name->tp);
745: //error('d',&where,"dcl %n; tx->base == cobj",this);
746: if (cl->lex_level > lex_level)
747: error("C%t is not visible in this scope",cl);
748:
749: if (cl->csu == ANON) { // export member names to enclosing scope
750: if (tbl==gtbl && n_sto!=STATIC) error("extern anonymous union (declare as static)");
751: char* p = cl->string;
752: while (*p++ != 'C'); /* sneaky */
753: int uindex = (int)str_to_long(p);
754:
755: // error('d', "%n->dcl() n_scope: %k n_protect: %k", this, n_scope, n_protect );
756: // cannot cope with use counts for ANONs:
757: Pbase(tp)->b_name->n_used = 1;
758: Pbase(tp)->b_name->n_assigned_to = 1;
759:
760: Ptable mtbl = cl->memtbl;
761: int i, err_msg = 0;
762: for (Pname nn=mtbl->get_mem(i=1); nn; nn=mtbl->get_mem(++i)) {
763: if (nn->tp->base == FCT) {
764: error("FM%n for anonymous union",nn);
765: break;
766: }
767: Ptable tb = nn->n_table;
768: nn->n_table = 0;
769: nn->n_scope = n_protect?n_protect:n_scope;
770: Pname n = tbl->insert(nn,0);
771: if (Nold) {
772: error("twoDs of%n (one in anonymous union)",nn);
773: break;
774: }
775:
776: Pclass tc;
777: if (tc = cl->in_class)
778: --n->lex_level;
779: if ( tc && tc->csu == ANON) {
780: //error('d', "tc->csu anon %k %s", tc->csu, string );
781: if ( n->n_anon ) {
782: if ( !err_msg )
783: error('s', "anonymous unions nested deeper than 2 levels" );
784: err_msg = 1;
785: }
786: n->n_anon = string;
787: }
788:
789: n->n_union = uindex;
790: nn->n_table = tb;
791: }
792: }
793: if (cl->c_abstract) error("D ofO of abstractC%t",cl);
794: goto cde;
795: }
796:
797: case VOID:
798: if (n_scope != ARG) {
799: error("badBT:%k%n",tx->base,this);
800: Cdcl = odcl;
801: return 0;
802: }
803: break;
804:
805:
806: case PTR:
807: case VEC:
808: case RPTR:
809: tp->dcl(tbl);
810: // if (tp->base==PTR && Pptr(tp)->memof) {
811: // Ptype t = Pptr(tp)->typ;
812: // while (t->base==TYPE) t = Pbase(t)->b_name->tp;
813: // if (t->base == FCT) {
814: // // size and align
815: // }
816: // }
817:
818: default:
819: cde:
820: //error('d',"cde: %n %t",this,tp);
821: nn = tbl->insert(this,0);
822: n_table = nn->n_table;
823:
824: if (Nold) {
825:
826: if ( nn->base == PUBLIC ) { // X::i
827: error("twoDs ofCM%n", nn);
828: Cdcl = odcl;
829: return 0;
830: }
831:
832: if (nn->tp->base == ANY) goto zzz;
833:
834: if (tp->check(nn->tp,0)) {
835: error("twoDs of%n;Ts:%t and%t",this,nn->tp,tp);
836: Cdcl = odcl;
837: return 0;
838: }
839: //error('d',"%n: %k %k scope %k",this,n_sto,nn->n_sto,nn->n_scope);
840: if (n_sto && n_sto!=nn->n_scope) {
841: if (n_sto==EXTERN && nn->n_scope==STATIC) {
842: error('w',"%n declared extern after being declared static",this);
843: goto ext_fudge;
844: }
845: else
846: error("%n declared as both%k and%k",this,n_sto,(nn->n_sto)?nn->n_sto:(scope==FCT?AUTO:EXTERN));
847: }
848: else if (nn->n_scope==STATIC && n_scope==EXTERN) {
849: error('w',"static%n followed by definition",this);
850: ext_fudge:
851: if (n_initializer) {
852: // error('d',"static%n redefined (WIr)",this);
853: n_initializer = 0;
854: }
855: n_sto = EXTERN;
856: }
857: else if (nn->n_sto==STATIC && n_sto==STATIC )
858: error("static%n declared twice",this);
859: else {
860: if (n_sto==0
861: && nn->n_sto==EXTERN
862: && n_initializer
863: && tp->tconst())
864: n_sto = EXTERN;
865: n_scope = nn->n_scope;
866:
867: switch (scope) {
868: case FCT:
869: if (n_sto != EXTERN) {
870: error("twoDs of%n",this);
871: Cdcl = odcl;
872: return 0;
873: }
874: break;
875: case ARG:
876: error("twoAs%n",this);
877: Cdcl = odcl;
878: return 0;
879: case 0:
880: case PUBLIC:
881: error("twoDs ofM%n",this);
882: Cdcl = odcl;
883: return 0;
884: case EXTERN:
885: if (n_sto==0) {
886: switch(nn->n_sto) {
887: case 0:
888: error("two definitions of%n",this);
889: Cdcl = odcl;
890: return 0;
891: case EXTERN:
892: if(nn->n_initializer) {
893: error("two definitions of%n",this);
894: Cdcl = odcl;
895: }
896: else
897: nn->n_sto=0;
898: break;
899: }
900: }
901: else if(n_sto==EXTERN && n_initializer) {
902: switch(nn->n_sto) {
903: case 0:
904: error("two definitions of%n",this);
905: Cdcl = odcl;
906: return 0;
907: case EXTERN:
908: nn->n_sto=0;
909: break;
910: }
911: }
912: break;
913: }
914: }
915: n_scope = nn->n_scope;
916: /* n_val */
917: if (n_initializer) {
918: if (nn->n_initializer || nn->n_val) error("twoIrs for%n",this);
919: nn->n_initializer = n_initializer;
920: }
921: if (tp->base == VEC) {
922: // handle: extern v[]; v[200];
923: // and extern u[10]; u[11];
924:
925: Ptype ntp = nn->tp;
926: while (ntp->base == TYPE) ntp = Pbase(ntp)->b_name->tp;
927: if (Pvec(ntp)->dim == 0) Pvec(ntp)->dim = Pvec(tp)->dim;
928: if (Pvec(ntp)->size) {
929: if (Pvec(tp)->size
930: && Pvec(ntp)->size!=Pvec(tp)->size)
931: error("bad array size for%n: %d %dX",this,Pvec(tp)->size,Pvec(ntp)->size);
932: }
933: else
934: Pvec(ntp)->size = Pvec(tp)->size;
935: }
936: }
937: else {
938: //error('d',"%n %t scope %d sto %k",this,tp,scope,n_sto);
939: if (scope!=ARG
940: && n_sto!=EXTERN
941: && (!((scope==0 || scope==PUBLIC) && n_sto==STATIC)) // static member
942: && n_initializer==0
943: && tp->base==VEC
944: && Pvec(tp)->size==0)
945: error(&where,"dimension missing for array%n",this);
946:
947: if (scope==EXTERN
948: && n_sto==0
949: && tp->tconst()
950: && vec_const==0
951: && fct_const==0)
952: nn->n_sto = n_sto = STATIC;
953: }
954:
955: zzz:
956: if (base != TNAME) {
957: Ptype t = nn->tp;
958:
959: if (t->base == TYPE) {
960: Ptype tt = Pbase(t)->b_name->tp;
961: if (tt->base == FCT) nn->tp = t = tt;
962: }
963:
964: switch (t->base) {
965: case FCT:
966: case OVERLOAD:
967: break;
968: default:
969: fake_sizeof = 1;
970: switch (nn->n_stclass) {
971: default:
972: if (nn->n_scope != ARG) {
973: int x = t->align();
974: int y = t->tsizeof();
975:
976: if (max_align < x) max_align = x;
977:
978: while (0 < bit_offset) {
979: byte_offset++;
980: bit_offset -= BI_IN_BYTE;
981: }
982: bit_offset = 0;
983:
984: if (byte_offset && 1<x) byte_offset = ((byte_offset-1)/x)*x+x;
985: nn->n_offset = byte_offset;
986: byte_offset += y;
987: }
988: break;
989: case STATIC:
990: if (n_sto != EXTERN
991: && nn->n_scope
992: && nn->n_scope!=PUBLIC)
993: t->tsizeof(); // check that size is known
994: }
995: fake_sizeof = 0;
996: }
997: }
998:
999: { Ptype t = nn->tp;
1000: int const_old = const_save;
1001: bit vec_seen = 0;
1002: Pexpr init = n_initializer;
1003:
1004: lll:
1005: // error('d',"lll %n %t init %d %k",this,t,init,init?init->base:0);
1006: switch (t->base) {
1007: case COBJ:
1008: { Pname cn = Pbase(t)->b_name;
1009: Pclass cl = (Pclass)cn->tp;
1010: Pname ctor = cl->has_ctor();
1011: Pname dtor = cl->has_dtor();
1012: int stct = 0;
1013: //error('d',"obj %n; class '%s'; ctor '%s'; dtor '%s'",nn,cn->string,ctor?ctor->string:"???",dtor?dtor->string:"???");
1014: if (dtor) {
1015: Pstmt dls;
1016:
1017: // if dtor is not public check scope of class object
1018:
1019: //error('d',"dcl %n has dtor",nn);
1020: if (dtor->n_scope != PUBLIC) {
1021: //error('d',"dcl %n->n_scope: %d fct %n",nn,nn->n_scope,cc->nof);
1022: switch (nn->n_scope) {
1023: case ARG:
1024: case 0:
1025: case PUBLIC:
1026: break;
1027: default:
1028: check_visibility( dtor, 0, cl, tbl, cc->nof );
1029: }
1030: // if (nn->n_scope == FCT)
1031: // check_visibility( dtor, 0, cl, tbl, cc->nof );
1032: // else if ( nn->n_sto != EXTERN )
1033: // error("%k%n cannot access%n: %sM",nn->n_scope,nn,dtor,dtor->n_protect?"protected":"private");
1034: }
1035:
1036: switch ( nn->n_scope ) {
1037: case 0:
1038: case PUBLIC:
1039: //error('d',"%n->n_scope == %s",nn,nn->n_scope?"public":"0");
1040: if (n_stclass==STATIC) { //III
1041: Pclass cl = Pclass(nn->n_table->t_name->tp);
1042: //error('d',"sto_class static; %t",cl);
1043: if (cl->defined&DEFINED) goto dtdt;
1044: }
1045: break;
1046: case EXTERN:
1047: //error('d',"%n->n_scope == extern; n_sto==%d",nn,n_sto);
1048: if (n_sto==EXTERN) break;
1049:
1050: case STATIC:
1051: //error('d',"%n->n_scope == static",nn);
1052: { Pexpr c;
1053: dtdt:
1054: // local static class objects have destructors set up in simpl2.c
1055: if ( nn->lex_level
1056: && nn->n_sto == STATIC ) {
1057: //error('d',"%n->dcl nn->ll: %d nn->n_sto: %k", nn, nn->lex_level, nn->n_sto );
1058: //error('d',"dtor: ctor: %d", ctor );
1059: if (ctor==0)
1060: error('s',"local static%n has%n but noK(add%n::%n())", nn, dtor, cn, cn );
1061: goto stat_init;
1062: }
1063:
1064: Ptable otbl = tbl;
1065: // to collect temporaries generated
1066: // in static destructors where we
1067: // can find them again (in std_tbl)
1068: if (std_tbl == 0) std_tbl = new table(8,gtbl,0);
1069: tbl = std_tbl;
1070: if (vec_seen) {
1071: c = cdvec(vec_del_fct,nn,cl,dtor,0,zero);
1072: } else { // nn->cl::~cl(0);
1073: c = call_dtor(nn,dtor,0,DOT,one);
1074: }
1075: c->tp = any_type; // avoid another check
1076: dls = new estmt(SM,nn->where,c,0);
1077:
1078: // destructors for statics are executed in reverse order
1079: if (st_dlist) dls->s_list = st_dlist;
1080: st_dlist = dls;
1081: tbl = otbl;
1082: } // case STATIC
1083: } // switch nn->n_scope
1084: } // if dtor
1085:
1086: // local static class objects must defer setting up static dtor
1087: stat_init:
1088: if (ctor) {
1089: // error('d',"ctor %n scope %k",ctor,nn->n_scope);
1090: Pexpr oo = nn;
1091: for (int vi=vec_seen; vi; vi--) oo = oo->contents();
1092: int sti = 0;
1093: switch (nn->n_scope) {
1094: case EXTERN:
1095: if (init==0 && n_sto==EXTERN) goto ggg;
1096: case STATIC:
1097: if (tbl == gtbl)
1098: sti = 1;
1099: else
1100: stct = 1;
1101: default:
1102: if (vec_seen && init) {
1103: if (1<vec_seen) {
1104: /* ?????
1105: if (init->base != ILIST)
1106: error("badIr forO ofC %t withK%n",cl,this);
1107: else
1108: */
1109: error('s',"Ir for multi-dimensional array%n ofOsofC %t withK",this,cl);
1110: }
1111: else {
1112: if (sti) {
1113: if (sti_tbl==0) sti_tbl = new table(8,gtbl,0);
1114: const_save = 1;
1115: (void) co_array_init(nn,sti_tbl);
1116: const_save = 0;
1117: n_initializer = init = 0;
1118: }
1119: else {
1120: n_initializer = init = co_array_init(nn,tbl);
1121: if (stct)
1122: nn->n_initializer = n_initializer = init = new expr( STAT_INIT, init, 0 );
1123: }
1124: }
1125: goto ggg;
1126: }
1127: break;
1128: case PUBLIC:
1129: case 0:
1130: if (n_stclass==STATIC) { //III
1131: Pclass cl = Pclass(nn->n_table->t_name->tp);
1132: if (cl->defined&DEFINED) {
1133: sti = 1;
1134: break;
1135: }
1136: }
1137: {
1138: Pname c;
1139: if (vec_seen) {
1140: c = cl->has_ictor();
1141: if (c == 0)
1142: error("array ofC%n that does not have aK taking noAs",cn);
1143: else if (Pfct(c->tp)->nargs)
1144: error("defaultAs forK for array ofC%n",cn);
1145: }
1146: }
1147: // no break
1148: case ARG:
1149: goto ggg;
1150: }
1151:
1152: const_save = 1;
1153: nn->assign();
1154: Ptable otbl = tbl;
1155: if (sti) { // to collect temporaries generated
1156: // in static initializers where we
1157: // can find them again (in sti_tbl)
1158: if (sti_tbl == 0) sti_tbl = new table(8,gtbl,0);
1159: tbl = sti_tbl;
1160: if (n_sto == EXTERN) nn->n_sto = n_sto = 0;
1161: }
1162:
1163: if (init) {
1164: // error('d',"init %k",init->base);
1165: if (init->base==VALUE) {
1166: switch (init->tp2->base) {
1167: case CLASS:
1168: // error('d',"class %t %t",Pclass(init->tp2),cl);
1169: if (Pclass(init->tp2)!=cl) goto inin;
1170: break;
1171: default:
1172: Pname n2 = init->tp2->is_cl_obj();
1173: // error('d',"default %t %t",n2->tp,cl);
1174: if (n2==0 || Pclass(n2->tp)!=cl) goto inin;
1175: }
1176:
1177: Pexpr ee = init->e1;
1178: // error('d',"init->e1 %k",ee->base);
1179: if (ee && vec_seen==0)
1180: switch (ee->base) {
1181: case CALL: // T a = f();
1182: init = ee;
1183: goto inin;
1184: case ELIST: // T a(f());
1185: if (ee->e1->base==CALL
1186: && ee->e2 == 0) {
1187: init = ee->e1;
1188: goto inin;
1189: }
1190: } // end switch
1191:
1192: init->e2 = oo;
1193: init = init->typ(tbl);
1194:
1195: if (init->base == G_CM) // beware of type conversion operators
1196: switch (init->tp2->base) {
1197: case CLASS:
1198: if (Pclass(init->tp2)!=cl) goto inin;
1199: break;
1200: default:
1201: Pname n2 = init->tp2->is_cl_obj();
1202: if (n2==0 || Pclass(n2->tp)!=cl) goto inin;
1203: }
1204: }
1205: else {
1206: inin:
1207: // error('d',"inin %k",init->base);
1208: init = init->typ(tbl);
1209: //error('d', "inin: init->typ: %d %k n->tp %t init->tp %t",init->base,init->base,nn->tp,init->tp);
1210: if (init->base==G_CM
1211: && nn->tp->check(init->tp,0)==0)
1212: (void) replace_temp(init,nn->address());
1213: else
1214: init = class_init(nn,nn->tp,init,tbl);
1215: }
1216: }
1217: else if (vec_seen == 0) {
1218: //error('d',"make value");
1219: init = new texpr(VALUE,cl,0);
1220: init->e2 = oo;
1221: init = init->typ(tbl);
1222: }
1223:
1224: Pname c;
1225: if (vec_seen) {
1226: c = cl->has_ictor();
1227: if (c == 0)
1228: error("array ofC%n that does not have aK taking noAs",cn);
1229: else if (Pfct(c->tp)->nargs)
1230: error("defaultAs forK for array ofC%n",cn);
1231: }
1232:
1233: // error( 'd', "stct: %d init: %d", stct, init );
1234: if (stct) {
1235: if (tbl!=gtbl && nn->n_sto==EXTERN) {
1236: error(&where,"Id local extern%n",this);
1237: init = 0;
1238: }
1239: else if (init)
1240: init->base = STAT_INIT;
1241: else {
1242: if (tp->base == VEC && Pvec(tp)->size ) {
1243: Pexpr ilist = 0;
1244: for (int i=Pvec(tp)->size; i>0; i--) {
1245: Pexpr e = new texpr(VALUE,cl,0);
1246: ilist = new expr(ELIST, e, ilist);
1247: }
1248: nn->n_initializer=new expr(ILIST,ilist,0);
1249: init = co_array_init(nn,tbl);
1250: nn->n_initializer = n_initializer = init = new expr( STAT_INIT, init, 0 );
1251: }
1252: else
1253: error('s',"local staticC%n (%t)",this, tp);
1254: }
1255: }
1256:
1257: // error('d', "%n->sti: %d vec_seen: %d n_stclass: %k", this, sti, vec_seen, n_stclass );
1258: if (sti) {
1259: if (vec_seen) { // _vec_new(vec,noe,sz,ctor);
1260: // error('d', "%n->dcl: n_stclass: %k ", this, n_stclass );
1261: if ( n_stclass == STATIC && n_initializer ) {
1262: const_save = 1;
1263: (void) co_array_init(nn,sti_tbl);
1264: const_save = 0;
1265: n_initializer = init = 0;
1266: goto ggg;
1267: }
1268:
1269: init = cdvec(vec_new_fct,nn,cl,c,-1,0);
1270: init->tp = any_type;
1271: }
1272: else {
1273: switch (init->base) {
1274: case DEREF: // *constructor?
1275: if (init->e1->base == G_CALL) {
1276: Pname fn = init->e1->fct_name;
1277: if (fn==0 || fn->n_oper!=CTOR) goto as;
1278: init = init->e1;
1279: break;
1280: }
1281: goto as;
1282: case G_CM:
1283: init = init->e1;
1284: // suppress further type checking
1285: if (init->tp == 0) init->tp= any_type;
1286: break;
1287: case ASSIGN:
1288: if (init->e1 == nn) break; // simple assignment
1289: as:
1290: default:
1291: init = new expr(ASSIGN,nn,init);
1292: }
1293: }
1294: Pstmt ist = new estmt(SM,nn->where,init,0);
1295: // constructors for statics are executed in order
1296: if (st_ilist == 0)
1297: st_ilist = ist;
1298: else
1299: itail->s_list = ist;
1300: itail = ist;
1301: init = 0; // suppress further processing
1302: } // if (sti)
1303: nn->n_initializer = n_initializer = init;
1304: const_save = const_old;
1305: tbl = otbl;
1306: }
1307: else if (init == 0) // no initializer
1308: goto str;
1309: else if (cl->is_simple()
1310: // && cl->csu!=UNION // accept ANSIism
1311: && cl->csu!=ANON
1312: ) { // struct
1313: init = init->typ(tbl);
1314: if (nn->tp->check(init->tp,0)==0
1315: && init->base==G_CM)
1316: (void) replace_temp(init,nn->address());
1317: else {
1318: if (ansi_opt==0
1319: && init->base==ILIST
1320: && cl->csu==UNION)
1321: error('s',"initialization of union withIL");
1322: goto str;
1323: }
1324: }
1325: else if (init->base == ILIST) { // class or union
1326: error("cannotI%nWIrL",nn);
1327: }
1328: else { // bitwise copy ok?
1329: // possible to get here?
1330: init = init->typ(tbl);
1331: //error('d',"init22 %t %t",nn->tp,init->tp);
1332: if (nn->tp->check(init->tp,0)==0) {
1333: if (init->base==G_CM)
1334: (void) replace_temp(init,nn->address());
1335: else
1336: goto str;
1337: }
1338: goto str;
1339: // else
1340: // error("cannotI%n:%k %s has noK",nn,cl->csu,cl->string);
1341: }
1342: break;
1343: }
1344: case VEC:
1345: t = Pvec(t)->typ;
1346: vec_seen++;
1347: goto lll;
1348: case TYPE:
1349: if (init==0 && Pbase(t)->b_const) {
1350: switch (n_scope) {
1351: case ARG:
1352: break;
1353: case 0:
1354: case PUBLIC:
1355: if ( cc->cot ) break;
1356: default: {
1357: Pname n = t->is_cl_obj();
1358: Pclass cl;
1359: if ( n ) cl = Pclass( n->tp );
1360:
1361: if (n_sto!=EXTERN &&
1362: (n==0 || (cl->has_ctor()==0 && is_empty(cl,1)==0)))
1363: error("uninitialized const%n",this);
1364: }
1365: }
1366: }
1367: t = Pbase(t)->b_name->tp;
1368: goto lll;
1369: case RPTR:
1370: if (init) {
1371: if (nn->n_scope == ARG) break;
1372: if (Pptr(nn->tp)->memof) error("R toCM%n ofT%t illegal",nn,nn->tp);
1373: ref_initializer++;
1374: init = init->typ(tbl);
1375: ref_initializer--;
1376: Nvirt = 0; // set within ref_init() call
1377: const_ptr = Pbase(Pptr(t)->typ)->tconst();
1378:
1379: if (n_sto==STATIC
1380: && init->lval(0)==0
1381: && fct_const==0)
1382: error("Ir for staticR%n not an lvalue",this);
1383: else
1384: nn->n_initializer = n_initializer = init = ref_init(Pptr(t),init,tbl);
1385:
1386: const_ptr = 0;
1387: if (Nvirt == VIRTUAL) sti_vb = 1;
1388: nn->assign();
1389:
1390: if (init->base==ILIST && init->e2==0) {
1391: new_list(init);
1392: list_check(nn,nn->tp,0,tbl);
1393: if (next_elem()) error(&where,"IrL too long");
1394: }
1395:
1396: }
1397: else {
1398: switch (nn->n_scope) {
1399: default:
1400: if (n_sto == EXTERN) break;
1401: error("uninitializedR%n",this);
1402: case ARG:
1403: break;
1404: case PUBLIC:
1405: case 0:
1406: //III if (n_sto == STATIC) error("a staticM%n cannot be aR",this);
1407: // error('d', "%n->dcl cot: %s", this, cc->cot?cc->cot->string:"notset");
1408: if ( cc->cot == 0 )
1409: error("uninitializedR%n",this);
1410: break;
1411: }
1412: }
1413: goto stgg;
1414: default:
1415: str:
1416: // error('d',"str %n %t %k %t",this,tp,init?init->base:0,init?init->tp:0);
1417: if (init == 0) {
1418: switch (n_scope) {
1419: case ARG:
1420: break;
1421: case 0:
1422: case PUBLIC:
1423: if ( cc->cot ) break;
1424: default:
1425: if (n_sto!=EXTERN && t->tconst()) error("uninitialized const%n",this);
1426: }
1427:
1428: break;
1429: }
1430:
1431: const_save = const_save
1432: || n_scope==ARG
1433: || (t->tconst() && vec_const==0);
1434:
1435: if ( tp->base == PTR ) {
1436: if ( cc && cc->nof
1437: && Pfct(cc->nof->tp)->f_const )
1438: cm_const_save = Pbase(Pptr(tp)->typ)->b_const;
1439: const_ptr = Pbase(Pptr(tp)->typ)->b_const;
1440: }
1441: nn->n_initializer = n_initializer = init = init->typ(tbl);
1442: cm_const_save = 0;
1443: const_ptr = 0;
1444:
1445: if (const_save) PERM(init);
1446: nn->assign();
1447: const_save = const_old;
1448: //error('d',"init2 %k %t",init->base,init->tp);
1449: switch (init->base) {
1450: case ILIST:
1451: if (init->e2) goto dfdf;//break; // pointer to member
1452: new_list(init);
1453: list_check(nn,nn->tp,0,tbl);
1454: if (next_elem()) error(&where,"IrL too long");
1455: break;
1456: case STRING:
1457: { Ptype v = nn->tp;
1458: while (v->base == TYPE) v = Pbase(v)->b_name->tp;
1459: if (v->base==VEC) {
1460: Ptype vv = Pvec(v)->typ;
1461: while(vv->base==TYPE) vv = Pbase(vv)->b_name->tp;
1462: if(vv->base==CHAR) {
1463: int sz = Pvec(v)->size;
1464: int isz = Pvec(init->tp)->size;
1465: if (sz == 0)
1466: Pvec(v)->size = isz;
1467: else if (sz < isz)
1468: error(&where,"Ir too long (%d characters) for%n[%d]",isz,nn,sz);
1469: break;
1470: }
1471: }
1472: // no break
1473: }
1474: default:
1475: dfdf:
1476: { Ptype nt = nn->tp;
1477: int ntc = Pbase(nt)->b_const;
1478:
1479: if (vec_seen) {
1480: error("badIr for array%n",nn);
1481: break;
1482: }
1483: tlx:
1484: switch (nt->base) {
1485: case TYPE:
1486: nt = Pbase(nt)->b_name->tp;
1487: ntc |= Pbase(nt)->b_const;
1488: goto tlx;
1489: case INT:
1490: case CHAR:
1491: case SHORT:
1492: case EOBJ:
1493: // if (init->base==ICON && init->tp==long_type)
1494: // error('w',"longIr constant for%k%n",nn->tp->base,nn);
1495: { Ptype t = init->tp;
1496: csi:
1497: switch (t->base) {
1498: case TYPE:
1499: t = Pbase(t)->b_name->tp; goto csi;
1500: case LONG:
1501: case FLOAT:
1502: case DOUBLE:
1503: case LDOUBLE:
1504: error('w',"%tIdW %t",nt,init->tp);
1505: }
1506: }
1507: // no break
1508: case LONG:
1509: if (Pbase(nt)->b_unsigned
1510: && init->base==UMINUS
1511: && init->e2->base==ICON)
1512: error('w',"negativeIr for unsigned%n",nn);
1513: if (ntc && scope!=ARG) {
1514: long i;
1515: Neval = 0;
1516: i = init->eval();
1517: if (Neval == 0) {
1518: DEL(init);
1519: nn->n_evaluated = n_evaluated = 1;
1520: nn->n_val = n_val = i;
1521: DEL(init);
1522: nn->n_initializer = n_initializer = 0;
1523: }
1524: }
1525: break;
1526: case PTR:
1527: Nvirt = 0;
1528: nn->n_initializer = n_initializer = init = ptr_init(Pptr(nt),init,tbl);
1529: //display_expr(init,string);
1530: if (Nvirt == VIRTUAL) sti_vb = 1;
1531: if (Pchecked) goto stgg;
1532: }
1533:
1534: { Pexpr x = try_to_coerce(nt,init,"initializer",tbl);
1535: if (x) {
1536: nn->n_initializer = n_initializer = init = x;
1537: goto stgg;
1538: }
1539: }
1540: //error('d',"check %t %t %k",nt,init->tp,init->base);
1541: // if (nt->check(init->tp,ASSIGN)) {
1542: Pname c1 = nt->is_cl_obj();
1543: Pname c2 = init->tp->is_cl_obj();
1544: if (c1
1545: && c2
1546: && Pclass(c2->tp)->has_base(Pclass(c1->tp))) {
1547: init = new texpr(CAST,new ptr(PTR,nt),init->address());
1548: init = init->typ(tbl);
1549: nn->n_initializer = n_initializer = init = init->contents();
1550: goto stgg;
1551: }
1552:
1553: if (nt->check(init->tp,ASSIGN)) {
1554: error("badIrT%t for%n (%tX)",init->tp,this,nn->tp);
1555: break;
1556: }
1557: }
1558:
1559: stgg:
1560: // error('d',"stgg %n init %k %t Nvirt: %k",this,init?init->base:0,init?init->tp:0, Nvirt);
1561: if (init && n_stclass==STATIC && (sti_vb || need_sti(init))) {
1562: /* check if non-static variables are used */
1563: int local = (0<lex_level);
1564: // error('d',"init %n %t local %d",nn,init->tp,local);
1565: if (local==0) need_sti(init,tbl); // save consts
1566:
1567: Pptr r = nn->tp->is_ref(); //III
1568:
1569: if (r) init = init->address();
1570: init = new expr(ASSIGN,nn,init);
1571: // error('d',"init r %t: nn %n %t init %t",r,nn,nn->tp,init->tp);
1572: if (r)
1573: init->tp = nn->tp;
1574: else if (nn->tp!=init->tp) { // static member refs
1575: TOK t = nn->tp->set_const(0); //JJJ
1576: init = init->typ(tbl);
1577: nn->tp->set_const(t); //JJJ
1578: }
1579:
1580: if (local) {
1581: if (init->base != ASSIGN) error('s',"Ir for local static too complicated");
1582: if (nn->n_sto == EXTERN) {
1583: error(&where,"Id local extern%n",this);
1584: init = 0;
1585: }
1586: else init->base = STAT_INIT;
1587: nn->n_initializer = n_initializer = init;
1588:
1589: }
1590: else {
1591: Pstmt ist = new estmt(SM,nn->where,init,0);
1592: // constructors for statics are executed in order
1593:
1594: if (st_ilist == 0)
1595: st_ilist = ist;
1596: else
1597: itail->s_list = ist;
1598: itail = ist;
1599: nn->n_initializer = n_initializer = init = 0; // suppress further processing
1600: nn->n_val = n_val = 1;
1601: }
1602: }
1603:
1604:
1605: } /* switch */
1606: } /* block */
1607: } /* default */
1608:
1609: } /* switch */
1610: ggg:
1611: //error('d',"ggg");
1612: PERM(nn);
1613: switch (n_scope) {
1614: case FCT:
1615: nn->n_initializer = n_initializer;
1616: break;
1617: default:
1618: { Ptype t = nn->tp;
1619: px:
1620: PERM(t);
1621: switch (t->base) {
1622: case PTR:
1623: case RPTR:
1624: case VEC: t = Pptr(t)->typ; goto px;
1625: case TYPE: t = Pbase(t)->b_name->tp; goto px;
1626: case FCT: t = Pfct(t)->returns; goto px; /* args? */
1627: }
1628: }
1629: }
1630:
1631: Cdcl = odcl;
1632: return nn;
1633: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.