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