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