|
|
1.1 root 1: /*
2: * C compiler.
3: * Initializers.
4: * (All storage classes).
5: */
6: #ifdef vax
7: #include "INC$LIB:cc0.h"
8: #else
9: #include "cc0.h"
10: #endif
11:
12: init(sp, dp, bo, flex)
13: register SYM *sp;
14: register DIM *dp;
15: sizeof_t bo;
16: int flex;
17: {
18: register int t;
19: DIM *ndp;
20: TREE *tp;
21: sizeof_t width, nbe, nel, ninit;
22: int brace, c, adj;
23:
24: t = sp->s_type;
25: width = sdsize(sp, dp);
26: ndp = dp;
27: if (dp!=NULL && dp->d_type==D_ARRAY) {
28: if (dp->d_bound != 0)
29: flex = 0;
30: ndp = dp->d_dp;
31: if (width==0 && !flex)
32: cerror("array row has 0 length");
33: } else
34: flex = 0;
35: nel = 0;
36: nbe = sdsize(sp, ndp);
37: if (nbe != 0)
38: nel = width/nbe;
39: brace = 0;
40: if (s==LBRACE && (dp!=NULL || !istruct(t))) {
41: ++brace;
42: lex();
43: } else if (s!=LBRACE && (dp!=NULL || istruct(t)))
44: notbook();
45: ninit = 0;
46: while (s != RBRACE) {
47: if (ndp==NULL && istruct(t))
48: sinit(sp, bo);
49: else if (ndp!=NULL && ndp->d_type==D_ARRAY)
50: init(sp, ndp, bo, 0);
51: else {
52: adj = 0;
53: if (s==STRING && t<T_INT && ndp==NULL) {
54: again: while ((c = getmap('\"')) >= 0) {
55: newtree(sizeof(TREE));
56: icollect(bicon(c), bo, sp, ndp);
57: ++ninit;
58: ++bo;
59: }
60: if (lex() == STRING) {
61: ++adj;
62: goto again;
63: }
64: if (adj)
65: notbook();
66: if (!flex && ninit==nel) {
67: cwarn("string initializer not terminated by NUL");
68: break;
69: }
70: newtree(sizeof(TREE));
71: icollect(bicon(0), bo, sp, ndp);
72: ++ninit;
73: break;
74: }
75: newtree(sizeof(TREE));
76: ++ininit;
77: tp = expr();
78: --ininit;
79: icollect(tp, bo, sp, ndp);
80: }
81: ++ninit;
82: bo += nbe;
83: if (s != COMMA)
84: break;
85: if (ninit>=nel && !flex) {
86: if (brace) {
87: lex();
88: if (s == RBRACE)
89: cwarn("trailing ',' in initialization list");
90: else {
91: cerror("too many initializers");
92: iskip();
93: }
94: }
95: break;
96: }
97: itrail();
98: }
99: if (brace)
100: mustbe(RBRACE);
101: if (ninit < nel) {
102: c = sp->s_class;
103: if (c==C_GDEF || c==C_SIN || c==C_SEX) {
104: bput(BLOCK);
105: zput(nbe*(nel-ninit));
106: }
107: }
108: if (ninit > nel) {
109: if (!flex)
110: cerror("too many initializers");
111: if (dp != NULL)
112: dp->d_bound = ninit;
113: }
114: }
115:
116: /*
117: * Initialize a structure.
118: * Create a fake variable for each member;
119: * this is necessary for the call to build() in iassign()
120: * to do the correct things.
121: */
122: sinit(sp, bo)
123: SYM *sp;
124: sizeof_t bo;
125: {
126: register SYM *mp;
127: register INFO *ip;
128: register int n;
129: int brace, c, t, f;
130: sizeof_t mo, lo;
131: SYM sym;
132:
133: c = sp->s_class;
134: t = sp->s_type;
135: if (t==T_UNION || t==T_FUNION)
136: cerror("cannot initialize unions");
137: if (t==T_FSTRUCT || t==T_FUNION)
138: return;
139: ip = sp->s_ip;
140: sym.s_class = c;
141: sym.s_value = sp->s_value;
142: brace = 0;
143: if (s == LBRACE) {
144: ++brace;
145: lex();
146: }
147: lo = n = f = 0;
148: while (s != RBRACE) {
149: if (n >= ip->i_nsp) {
150: if (f == 0) {
151: cerror("too many structure initializers");
152: ++f;
153: }
154: sym.s_type = T_INT;
155: sym.s_dp = sym.s_ip = NULL;
156: mo = 0;
157: } else {
158: mp = ip->i_sp[n++];
159: sym.s_type = mp->s_type;
160: sym.s_dp = mp->s_dp;
161: sym.s_ip = mp->s_ip;
162: mo = mp->s_value;
163: if (mp->s_width != 0)
164: cerror("cannot initialize fields");
165: if (!isauto(&sym) && lo!=mo) {
166: bput(BLOCK);
167: zput(mo-lo);
168: lo = mo;
169: }
170: }
171: init(&sym, sym.s_dp, bo+mo, 0);
172: lo += ssize(&sym);
173: if (s != COMMA || (n>=ip->i_nsp && !brace))
174: break;
175: itrail();
176: }
177: if (brace)
178: mustbe(RBRACE);
179: if (t==T_STRUCT && (c==C_GDEF || c==C_SIN || c==C_SEX)) {
180: if ((mo = ip->i_size-lo) > 0) {
181: bput(BLOCK);
182: zput(mo);
183: }
184: }
185: }
186:
187: /*
188: * Fetch the next symbol.
189: * The current symbol is a COMMA.
190: * If the new symbol is '}', the program has said ", }"; this is legal.
191: * If you pull the comments here, it becomes not quite so legal.
192: */
193: static
194: itrail()
195: {
196: lex();
197: if (s == RBRACE)
198: cwarn("trailing ',' in initialization list");
199: }
200:
201: /*
202: * An initialization starting with '{' contains too many initializers.
203: * Skip initializers to the matching '}' or EOF.
204: */
205: static
206: iskip()
207: {
208: register int braces;
209:
210: braces = 0;
211: for(;;) {
212: if (s == LBRACE)
213: ++braces;
214: else if (s == RBRACE) {
215: if (braces == 0)
216: return;
217: else
218: --braces;
219: }
220: else if (s == EOF)
221: return;
222: lex();
223: }
224: }
225:
226: /*
227: * Return true if symbol "sp" is an automatic,
228: * in the sense that an assigment statement must be generated
229: * for the initialization item.
230: * Registers are considered auto.
231: */
232: isauto(sp)
233: register SYM *sp;
234: {
235: register int c;
236:
237: c = sp->s_class;
238: if (c==C_AUTO || c==C_PAUTO || c==C_REG)
239: return (1);
240: return (0);
241: }
242:
243: /*
244: * This routine actually performs the initialization.
245: * Either an assignment node is built up and evaluated for effect,
246: * or an initialization tree is output.
247: */
248: icollect(tp, bo, sp, dp)
249: register TREE *tp;
250: sizeof_t bo;
251: register SYM *sp;
252: DIM *dp;
253: {
254: register TREE *ip;
255:
256: if (isauto(sp)) {
257: iassign(sp, dp, bo, tp);
258: return;
259: }
260: ip = talloc();
261: ip->t_op = INIT;
262: ip->t_type = sp->s_type;
263: ip->t_dp = dp;
264: ip->t_ip = sp->s_ip;
265: ip->t_lp = tp;
266: tput(IEXPR, 0, ip);
267: }
268:
269: /*
270: * Actually do the assignment for an automatic initialization thing.
271: */
272: iassign(sp, dp, bo, tp)
273: register SYM *sp;
274: register TREE *tp;
275: sizeof_t bo;
276: DIM *dp;
277: {
278: register TREE *ip;
279: DIM *ssdp;
280:
281: ssdp = sp->s_dp;
282: sp->s_dp = dp;
283: ip = bid(sp);
284: sp->s_dp = ssdp;
285: if (sp->s_class != C_REG)
286: ip->t_offs += bo;
287: tp = build(ASSIGN, ip, tp);
288: tput(EEXPR, 0, tp);
289: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.