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