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