Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:gmcgarry:20080415095232

Diff

Diff from 1.42 to:

Annotations

Annotate by Age | Author | Mixed | None
/fisheye/browse/pcc/pcc/cc/ccom/init.c

Annotated File View

gmcgarry
1.42
1 /*      $Id: init.c,v 1.42 2008/04/15 09:52:32 gmcgarry Exp $   */
ragge
1.1
2
ragge
1.8
3 /*
ragge
1.21
4  * Copyright (c) 2004, 2007 Anders Magnusson (ragge@ludd.ltu.se).
ragge
1.8
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. The name of the author may not be used to endorse or promote products
16  *    derived from this software without specific prior written permission
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 /*
31  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
32  *
33  * Redistribution and use in source and binary forms, with or without
34  * modification, are permitted provided that the following conditions
35  * are met:
36  *
37  * Redistributions of source code and documentation must retain the above
38  * copyright notice, this list of conditions and the following disclaimer.
39  * Redistributions in binary form must reproduce the above copyright
40  * notice, this list of conditions and the following disclaimer in the
41  * documentation and/or other materials provided with the distribution.
42  * All advertising materials mentioning features or use of this software
43  * must display the following acknowledgement:
44  *      This product includes software developed or owned by Caldera
45  *      International, Inc.
46  * Neither the name of Caldera International, Inc. nor the names of other
47  * contributors may be used to endorse or promote products derived from
48  * this software without specific prior written permission.
49  *
50  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
51  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
52  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
53  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
54  * DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
55  * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
56  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
57  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
58  * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
59  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
60  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
61  * POSSIBILITY OF SUCH DAMAGE.
62  */
ragge
1.1
63
ragge
1.21
64 #include "pass1.h"
ragge
1.16
65 #include <string.h>
ragge
1.1
66
ragge
1.2
67 /*
gmcgarry
1.35
68  * The following machine-dependent routines may be called during
69  * initialization:
ragge
1.2
70  * 
ragge
1.21
71  * zbits(OFFSZ, int)    - sets int bits of zero at position OFFSZ.
72  * infld(CONSZ off, int fsz, CONSZ val)
73  *                      - sets the bitfield val starting at off and size fsz.
gmcgarry
1.35
74  * ninval(CONSZ off, int fsz, NODE *)
ragge
1.21
75  *                      - prints an integer constant which may have
76  *                        a label associated with it, located at off and
77  *                        size fsz.
ragge
1.15
78  *
79  * Initialization may be of different kind:
80  * - Initialization at compile-time, all values are constants and laid
81  *   out in memory. Static or extern variables outside functions.
82  * - Initialization at run-time, written to their values as code.
83  *
84  * Currently run-time-initialized variables are only initialized by using
85  * move instructions.  An optimization might be to detect that it is
86  * initialized with constants and therefore copied from readonly memory.
87  */
ragge
1.21
88
ragge
1.15
89 /*
ragge
1.21
90  * The base element(s) of an initialized variable is kept in a linked 
91  * list, allocated while initialized.
ragge
1.15
92  *
93  * When a scalar is found, entries are popped of the instk until it's
94  * possible to find an entry for a new scalar; then onstk() is called 
95  * to get the correct type and size of that scalar.
96  *
97  * If a right brace is found, pop the stack until a matching left brace
98  * were found while filling the elements with zeros.  This left brace is
99  * also marking where the current level is for designated initializations.
100  *
101  * Position entries are increased when traversing back down into the stack.
ragge
1.2
102  */
ragge
1.1
103
104 /*
ragge
1.18
105  * Good-to-know entries from symtab:
106  *      soffset - # of bits from beginning of this structure.
107  */
108
109 /*
ragge
1.21
110  * TO FIX:
111  * - Alignment of structs on like i386 char members.
112  */
113
ragge
1.26
114 int idebug;
115
ragge
1.21
116 /*
ragge
1.1
117  * Struct used in array initialisation.
118  */
119 static struct instk {
120         struct  instk *in_prev/* linked list */
ragge
1.41
121         struct  symtab *in_lnk/* member in structure initializations */
122         struct  symtab *in_sym/* symtab index */
ragge
1.22
123         union   dimfun *in_df;  /* dimenston of array */
124         TWORD   in_t;           /* type for this level */
ragge
1.21
125         int     in_n;           /* number of arrays seen so far */
ragge
1.1
126         int     in_fl;  /* flag which says if this level is controlled by {} */
ragge
1.15
127 } *pstkpbase;
ragge
1.1
128
ragge
1.2
129 static struct symtab *csym;
ragge
1.1
130
131 #define ISSOU(ty) (ty == STRTY || ty == UNIONTY)
132
ragge
1.15
133 #ifdef PCC_DEBUG
134 static void prtstk(struct instk *in);
135 #endif
ragge
1.2
136
137 /*
ragge
1.21
138  * Linked lists for initializations.
ragge
1.16
139  */
ragge
1.21
140 struct ilist {
141         struct ilist *next;
142         CONSZ off;      /* bit offset of this entry */
143         int fsz;        /* bit size of this entry */
144         NODE *n;        /* node containing this data info */
145 };
146
ragge
1.16
147 struct llist {
148         SLIST_ENTRY(llistnext;
ragge
1.18
149         CONSZ begsz;    /* bit offset of this entry */
ragge
1.21
150         struct ilist *il;
151 } *curll;
ragge
1.16
152 static SLIST_HEAD(, llistlpole;
153 static CONSZ basesz;
ragge
1.18
154 static int numents/* # of array entries allocated */
ragge
1.16
155
ragge
1.21
156 static struct ilist *
157 getil(struct ilist *nextCONSZ bint szNODE *n)
158 {
159         struct ilist *il = tmpalloc(sizeof(struct ilist));
160
161         il->off = b;
162         il->fsz = sz;
163         il->n = n;
164         il->next = next;
165         return il;
166 }
167
ragge
1.16
168 /*
ragge
1.22
169  * Allocate a new struct defining a block of initializers appended to the
ragge
1.16
170  * end of the llist. Return that entry.
171  */
172 static struct llist *
173 getll(void)
174 {
175         struct llist *ll;
176
177         ll = tmpalloc(sizeof(struct llist));
ragge
1.18
178         ll->begsz = numents * basesz;
ragge
1.23
179         ll->il = NULL;
ragge
1.16
180         SLIST_INSERT_LAST(&lpolellnext);
ragge
1.18
181         numents++;
ragge
1.16
182         return ll;
183 }
184
ragge
1.18
185 /*
186  * Return structure containing off bitnumber.
187  * Allocate more entries, if needed.
188  */
189 static struct llist *
ragge
1.21
190 setll(OFFSZ off)
ragge
1.18
191 {
otto
1.34
192         struct llist *ll = NULL;
ragge
1.18
193
194         /* Ensure that we have enough entries */
195         while (off >= basesz * numents)
otto
1.34
196                  ll = getll();
197
198         if (ll != NULL && ll->begsz <= off && ll->begsz + basesz > off)
199                 return ll;
200
ragge
1.18
201         SLIST_FOREACH(ll, &lpolenext)
202                 if (ll->begsz <= off && ll->begsz + basesz > off)
203                         break;
204         return ll/* ``cannot fail'' */
ragge
1.2
205 }
ragge
1.1
206
207 /*
208  * beginning of initialization; allocate space to store initialized data.
209  * remember storage class for writeout in endinit().
ragge
1.15
210  * p is the newly declarated type.
ragge
1.1
211  */
212 void
ragge
1.15
213 beginit(struct symtab *sp)
ragge
1.1
214 {
ragge
1.15
215         struct instk *is = &pbase;
ragge
1.16
216         struct llist *ll;
ragge
1.15
217
ragge
1.1
218 #ifdef PCC_DEBUG
ragge
1.21
219         if (idebug)
220                 printf("beginit(), sclass %s\n"scnames(sp->sclass));
ragge
1.1
221 #endif
222
ragge
1.15
223         csym = sp;
ragge
1.1
224
ragge
1.18
225         numents = 0/* no entries in array list */
ragge
1.22
226         if (ISARY(sp->stype))
227                 basesz = tsize(DECREF(sp->stype), sp->sdf+1sp->ssue);
228         else
229                 basesz = tsize(DECREF(sp->stype), sp->sdfsp->ssue);
ragge
1.16
230         SLIST_INIT(&lpole);
ragge
1.17
231         curll = ll = getll(); /* at least first entry in list */
ragge
1.16
232
ragge
1.15
233         /* first element */
ragge
1.41
234         is->in_lnk = ISSOU(sp->stype) ? sp->ssue->sylnk : NULL;
ragge
1.15
235         is->in_n = 0;
236         is->in_t = sp->stype;
237         is->in_sym = sp;
ragge
1.22
238         is->in_df = sp->sdf;
ragge
1.20
239         is->in_fl = 0;
ragge
1.15
240         is->in_prev = NULL;
241         pstk = is;
242 }
243
244 /*
245  * Push a new entry on the initializer stack.
246  * The new entry will be "decremented" to the new sub-type of the previous
247  * entry when called.
248  * Popping of entries is done elsewhere.
249  */
ragge
1.21
250 static void
251 stkpush(void)
252 {
ragge
1.15
253         struct instk *is;
ragge
1.24
254         struct symtab *sq, *sp;
255         TWORD t;
256
257         if (pstk == NULL) {
258                 sp = csym;
259                 t = 0;
260         } else {
261                 t = pstk->in_t;
262                 sp = pstk->in_sym;
263         }
ragge
1.15
264
265 #ifdef PCC_DEBUG
ragge
1.16
266         if (idebug) {
ragge
1.21
267                 printf("stkpush: '%s' %s "sp->snamescnames(sp->sclass));
ragge
1.16
268                 tprint(stdoutt0);
269         }
ragge
1.15
270 #endif
ragge
1.1
271
ragge
1.15
272         /*
ragge
1.22
273          * Figure out what the next initializer will be, and push it on 
ragge
1.15
274          * the stack.  If this is an array, just decrement type, if it
275          * is a struct or union, extract the next element.
276          */
ragge
1.22
277         is = tmpalloc(sizeof(struct instk));
ragge
1.16
278         is->in_fl = 0;
279         is->in_n = 0;
ragge
1.24
280         if (pstk == NULL) {
281                 /* stack empty */
ragge
1.41
282                 is->in_lnk = ISSOU(sp->stype) ? sp->ssue->sylnk : NULL;
ragge
1.24
283                 is->in_t = sp->stype;
284                 is->in_sym = sp;
285                 is->in_df = sp->sdf;
286         } else if (ISSOU(t)) {
ragge
1.41
287                 sq = pstk->in_lnk;
ragge
1.29
288                 if (sq == NULL) {
289                         uerror("excess of initializing elements");
290                 } else {
ragge
1.41
291                         is->in_lnk = ISSOU(sq->stype) ? sq->ssue->sylnk : 0;
ragge
1.29
292                         is->in_t = sq->stype;
293                         is->in_sym = sq;
294                         is->in_df = sq->sdf;
295                 }
ragge
1.16
296         } else if (ISARY(t)) {
ragge
1.41
297                 is->in_lnk = ISSOU(DECREF(t)) ? pstk->in_sym->ssue->sylnk : 0;
ragge
1.16
298                 is->in_t = DECREF(t);
ragge
1.15
299                 is->in_sym = sp;
ragge
1.26
300                 if (pstk->in_df->ddim && pstk->in_n >= pstk->in_df->ddim) {
301                         werror("excess of initializing elements");
302                         pstk->in_n--;
303                 }
ragge
1.22
304                 if (ISARY(is->in_t))
305                         is->in_df = pstk->in_df+1;
ragge
1.15
306         } else
ragge
1.30
307                 uerror("too many left braces");
ragge
1.15
308         is->in_prev = pstk;
309         pstk = is;
ragge
1.1
310
311 #ifdef PCC_DEBUG
ragge
1.16
312         if (idebug) {
313                 printf(" newtype ");
314                 tprint(stdoutis->in_t0);
315                 printf("\n");
316         }
ragge
1.2
317 #endif
ragge
1.1
318 }
ragge
1.15
319
320 /*
ragge
1.22
321  * pop down to either next level that can handle a new initializer or
ragge
1.15
322  * to the next braced level.
323  */
324 static void
325 stkpop(void)
326 {
ragge
1.18
327 #ifdef PCC_DEBUG
328         if (idebug)
329                 printf("stkpop\n");
330 #endif
ragge
1.15
331         for (; pstkpstk = pstk->in_prev) {
ragge
1.41
332                 if (pstk->in_t == STRTY && pstk->in_lnk != NULL) {
333                         pstk->in_lnk = pstk->in_lnk->snext;
334                         if (pstk->in_lnk != NULL)
ragge
1.20
335                                 break;
336                 }
ragge
1.21
337                 if (ISSOU(pstk->in_t) && pstk->in_fl)
338                         break/* need } */
339                 if (ISARY(pstk->in_t)) {
ragge
1.15
340                         pstk->in_n++;
ragge
1.22
341                         if (pstk->in_fl)
342                                 break;
343                         if (pstk->in_df->ddim == 0 ||
344                             pstk->in_n < pstk->in_df->ddim)
ragge
1.21
345                                 break/* ger more elements */
346                 }
ragge
1.15
347         }
ragge
1.22
348 #ifdef PCC_DEBUG
349         if (idebug > 1)
350                 prtstk(pstk);
351 #endif
352 }
353
354 /*
355  * Count how many elements an array may consist of.
356  */
357 static int
358 acalc(struct instk *isint n)
359 {
360         if (is == NULL || !ISARY(is->in_t))
361                 return 0;
362         return acalc(is->in_prevn * is->in_df->ddim) + n * is->in_n;
ragge
1.15
363 }
364
365 /*
ragge
1.18
366  * Find current bit offset of the top element on the stack from
367  * the beginning of the aggregate.
368  */
369 static CONSZ
370 findoff(void)
371 {
ragge
1.20
372         struct instk *is;
ragge
1.22
373         OFFSZ off;
ragge
1.18
374
375 #ifdef PCC_DEBUG
376         if (ISARY(pstk->in_t) || ISSOU(pstk->in_t))
377                 cerror("findoff on bad type");
378 #endif
379
ragge
1.20
380         /*
381          * Offset calculations. If:
382          * - previous type is STRTY, soffset has in-struct offset.
383          * - this type is ARY, offset is ninit*stsize.
384          */
385         for (off = 0is = pstkisis = is->in_prev) {
386                 if (is->in_prev && is->in_prev->in_t == STRTY)
387                         off += is->in_sym->soffset;
ragge
1.22
388                 if (ISARY(is->in_t)) {
389                         /* suesize is the basic type, so adjust */
390                         TWORD t = is->in_t;
391                         OFFSZ o;
392                         while (ISARY(t))
393                                 t = DECREF(t);
394                         o = ISPTR(t) ? SZPOINT(t) : is->in_sym->ssue->suesize;
395                         off += o * acalc(is1);
ragge
1.27
396                         while (is->in_prev && ISARY(is->in_prev->in_t)) {
397                                 if (is->in_prev->in_prev &&
398                                     is->in_prev->in_prev->in_t == STRTY)
399                                         off += is->in_sym->soffset;
ragge
1.22
400                                 is = is->in_prev;
ragge
1.27
401                         }
ragge
1.22
402                 }
ragge
1.18
403         }
gmcgarry
1.42
404 #ifdef PCC_DEBUG
ragge
1.20
405         if (idebug>1) {
ragge
1.18
406                 printf("findoff: off %lld\n"off);
ragge
1.20
407                 prtstk(pstk);
408         }
gmcgarry
1.42
409 #endif
ragge
1.18
410         return off;
411 }
412
413 /*
ragge
1.21
414  * Insert the node p with size fsz at position off.
415  * Bit fields are already dealt with, so a node of correct type
416  * with correct alignment and correct bit offset is given.
ragge
1.18
417  */
418 static void
ragge
1.21
419 nsetval(CONSZ offint fszNODE *p)
ragge
1.18
420 {
ragge
1.21
421         struct llist *ll;
422         struct ilist *il;
ragge
1.18
423
424         if (idebug>1)
ragge
1.21
425                 printf("setval: off %lld fsz %d p %p\n"offfszp);
ragge
1.18
426
ragge
1.19
427         if (fsz == 0)
428                 return;
429
ragge
1.21
430         ll = setll(off);
431         off -= ll->begsz;
432         if (ll->il == NULL) {
433                 ll->il = getil(NULLofffszp);
434         } else {
ragge
1.24
435                 il = ll->il;
436                 if (il->off > off) {
437                         ll->il = getil(ll->ilofffszp);
438                 } else {
439                         for (il = ll->ilil->nextil = il->next)
440                                 if (il->off <= off && il->next->off > off)
441                                         break;
442                         if (il->off == off) {
443                                 /* replace */
444                                 nfree(il->n);
445                                 il->n = p;
446                         } else
447                                 il->next = getil(il->nextofffszp);
448                 }
ragge
1.21
449         }
ragge
1.18
450 }
451
452 /*
ragge
1.15
453  * take care of generating a value for the initializer p
454  * inoff has the current offset (last bit written)
455  * in the current word being generated
456  */
457 void
458 scalinit(NODE *p)
459 {
ragge
1.21
460         CONSZ woff;
ragge
1.15
461         NODE *q;
ragge
1.21
462         int fsz;
ragge
1.15
463
464 #ifdef PCC_DEBUG
465         if (idebug > 2) {
ragge
1.20
466                 printf("scalinit(%p)\n"p);
ragge
1.15
467                 fwalk(peprint0);
468                 prtstk(pstk);
469         }
470 #endif
471
472         if (nerrors)
473                 return;
474
ragge
1.23
475         p = optim(p);
476
ragge
1.36
477 #ifdef notdef /* leave to the target to decide if useable */
ragge
1.22
478         if (csym->sclass != AUTO && p->n_op != ICON &&
479             p->n_op != FCON && p->n_op != NAME)
ragge
1.16
480                 cerror("scalinit not leaf");
ragge
1.36
481 #endif
ragge
1.20
482
483         /* Out of elements? */
484         if (pstk == NULL) {
ragge
1.21
485                 uerror("excess of initializing elements");
ragge
1.20
486                 return;
487         }
488
ragge
1.15
489         /*
490          * Get to the simple type if needed.
491          */
492         while (ISSOU(pstk->in_t) || ISARY(pstk->in_t))
493                 stkpush();
494                 
ragge
1.21
495         /* let buildtree do typechecking (and casting) */
496         q = block(NAMENIL,NILpstk->in_tpstk->in_sym->sdf,
497             pstk->in_sym->ssue);
ragge
1.15
498         p = buildtree(ASSIGNqp);
499         nfree(p->n_left);
ragge
1.22
500         q = optim(p->n_right);
ragge
1.15
501         nfree(p);
502
ragge
1.21
503         /* bitfield sizes are special */
504         if (pstk->in_sym->sclass & FIELD)
505                 fsz = -(pstk->in_sym->sclass & FLDSIZ);
506         else
507                 fsz = tsize(pstk->in_tpstk->in_sym->sdfpstk->in_sym->ssue);
508         woff = findoff();
ragge
1.19
509
ragge
1.21
510         nsetval(wofffszq);
ragge
1.18
511
ragge
1.15
512         stkpop();
ragge
1.2
513 #ifdef PCC_DEBUG
ragge
1.8
514         if (idebug > 2) {
ragge
1.20
515                 printf("scalinit e(%p)\n"p);
ragge
1.8
516         }
ragge
1.2
517 #endif
ragge
1.1
518 }
519
ragge
1.7
520 /*
ragge
1.21
521  * Generate code to insert a value into a bitfield.
522  */
523 static void
524 insbf(OFFSZ offint fszint val)
525 {
526         struct symtab sym;
527         NODE *p, *r;
528         TWORD typ;
529
530 #ifdef PCC_DEBUG
531         if (idebug > 1)
532                 printf("insbf: off %lld fsz %d val %d\n"offfszval);
533 #endif
534
535         if (fsz == 0)
536                 return;
537
538         /* small opt: do char instead of bf asg */
539         if ((off & (ALCHAR-1)) == 0 && fsz == SZCHAR)
540                 typ = CHAR;
541         else
542                 typ = INT;
543         /* Fake a struct reference */
544         spname = csym;
545         p = buildtree(ADDROF,
546             buildtree(NAMENILNIL), NIL);
547         sym.stype = typ;
548         sym.squal = 0;
549         sym.sdf = 0;
550         sym.ssue = MKSUE(typ);
551         sym.soffset = off;
552         sym.sclass = typ == INT ? FIELD | fsz : MOU;
stefan
1.39
553         r = xbcon(0, &symtyp);
ragge
1.21
554         p = block(STREFprINT0MKSUE(INT));
555         ecode(buildtree(ASSIGNstref(p), bcon(val)));
556 }
557
558 /*
559  * Clear a bitfield, starting at off and size fsz.
560  */
561 static void
562 clearbf(OFFSZ offOFFSZ fsz)
563 {
564         /* Pad up to the next even initializer */
565         if ((off & (ALCHAR-1)) || (fsz < SZCHAR)) {
566                 int ba = ((off + (SZCHAR-1)) & ~(SZCHAR-1)) - off;
567                 if (ba > fsz)
568                         ba = fsz;
569                 insbf(offba0);
570                 off += ba;
571                 fsz -= ba;
572         }
573         while (fsz >= SZCHAR) {
574                 insbf(offSZCHAR0);
575                 off += SZCHAR;
576                 fsz -= SZCHAR;
577         }
578         if (fsz)
579                 insbf(offfsz0);
580 }
581
582 /*
ragge
1.7
583  * final step of initialization.
584  * print out init nodes and generate copy code (if needed).
585  */
ragge
1.1
586 void
587 endinit(void)
588 {
ragge
1.18
589         struct llist *ll;
ragge
1.21
590         struct ilist *il;
591         int fsz;
592         OFFSZ lastofftbit;
ragge
1.1
593
594 #ifdef PCC_DEBUG
595         if (idebug)
ragge
1.18
596                 printf("endinit()\n");
ragge
1.1
597 #endif
598
ragge
1.23
599         if (csym->sclass != AUTO)
ragge
1.40
600                 defloc(csym);
ragge
1.18
601
ragge
1.21
602         /* Calculate total block size */
603         if (ISARY(csym->stype) && csym->sdf->ddim == 0) {
604                 tbit = numents*basesz/* open-ended arrays */
605                 csym->sdf->ddim = numents;
ragge
1.22
606                 if (csym->sclass == AUTO) { /* Get stack space */
607                         csym->soffset = NOOFFSET;
ragge
1.21
608                         oalloc(csym, &autooff);
ragge
1.22
609                 }
ragge
1.21
610         } else
611                 tbit = tsize(csym->stypecsym->sdfcsym->ssue);
612
ragge
1.17
613         /* Traverse all entries and print'em out */
ragge
1.21
614         lastoff = 0;
ragge
1.18
615         SLIST_FOREACH(ll, &lpolenext) {
ragge
1.21
616                 for (il = ll->ililil = il->next) {
617 #ifdef PCC_DEBUG
618                         if (idebug > 1) {
619                                 printf("off %lld size %d val %lld type ",
620                                     ll->begsz+il->offil->fszil->n->n_lval);
621                                 tprint(stdoutil->n->n_type0);
622                                 printf("\n");
623                         }
624 #endif
625                         fsz = il->fsz;
626                         if (csym->sclass == AUTO) {
627                                 struct symtab sym;
628                                 NODE *p, *r, *n;
629
630                                 if (ll->begsz + il->off > lastoff)
631                                         clearbf(lastoff,
632                                             (ll->begsz + il->off) - lastoff);
633
634                                 /* Fake a struct reference */
635                                 spname = csym;
636                                 p = buildtree(ADDROF,
637                                     buildtree(NAMENILNIL), NIL);
638                                 n = il->n;
639                                 sym.stype = n->n_type;
640                                 sym.squal = n->n_qual;
641                                 sym.sdf = n->n_df;
642                                 sym.ssue = n->n_sue;
643                                 sym.soffset = ll->begsz + il->off;
644                                 sym.sclass = fsz < 0 ? FIELD | -fsz : 0;
stefan
1.39
645                                 r = xbcon(0, &symINT);
ragge
1.21
646                                 p = block(STREFprINT0MKSUE(INT));
647                                 ecode(buildtree(ASSIGNstref(p), il->n));
648                                 if (fsz < 0)
649                                         fsz = -fsz;
650
651                         } else {
652                                 if (ll->begsz + il->off > lastoff)
653                                         zbits(lastoff,
654                                             (ll->begsz + il->off) - lastoff);
655                                 if (fsz < 0) {
656                                         fsz = -fsz;
657                                         infld(il->offfszil->n->n_lval);
658                                 } else
659                                         ninval(il->offfszil->n);
ragge
1.36
660                                 tfree(il->n);
ragge
1.21
661                         }
662                         lastoff = ll->begsz + il->off + fsz;
ragge
1.2
663                 }
664         }
ragge
1.21
665         if (csym->sclass == AUTO) {
666                 clearbf(lastofftbit-lastoff);
667         } else
668                 zbits(lastofftbit-lastoff);
ragge
1.1
669 }
670
671 /*
672  * process an initializer's left brace
673  */
674 void
675 ilbrace()
676 {
677
ragge
1.15
678 #ifdef PCC_DEBUG
679         if (idebug)
680                 printf("ilbrace()\n");
681 #endif
ragge
1.1
682
ragge
1.20
683         if (pstk == NULL)
684                 return;
685
ragge
1.18
686         stkpush();
687         pstk->in_fl = 1/* mark lbrace */
ragge
1.22
688 #ifdef PCC_DEBUG
689         if (idebug > 1)
690                 prtstk(pstk);
691 #endif
ragge
1.1
692 }
693
694 /*
695  * called when a '}' is seen
696  */
697 void
698 irbrace()
699 {
700 #ifdef PCC_DEBUG
ragge
1.18
701         if (idebug)
702                 printf("irbrace()\n");
ragge
1.15
703         if (idebug > 2)
704                 prtstk(pstk);
ragge
1.1
705 #endif
706
ragge
1.21
707         if (pstk == NULL)
708                 return;
709
ragge
1.18
710         /* Got right brace, search for corresponding in the stack */
ragge
1.1
711         for (; pstk->in_prev != NULLpstk = pstk->in_prev) {
712                 if(!pstk->in_fl)
713                         continue;
714
715                 /* we have one now */
716
717                 pstk->in_fl = 0;  /* cancel { */
ragge
1.20
718                 if (ISARY(pstk->in_t))
ragge
1.22
719                         pstk->in_n = pstk->in_df->ddim;
720                 else if (pstk->in_t == STRTY) {
ragge
1.41
721                         while (pstk->in_lnk != NULL &&
722                             pstk->in_lnk->snext != NULL)
723                                 pstk->in_lnk = pstk->in_lnk->snext;
ragge
1.22
724                 }
ragge
1.18
725                 stkpop();
ragge
1.1
726                 return;
727         }
728 }
729
ragge
1.15
730 /*
ragge
1.22
731  * Create a new init stack based on given elements.
ragge
1.15
732  */
733 static void
ragge
1.22
734 mkstack(NODE *p)
ragge
1.15
735 {
ragge
1.22
736
737 #ifdef PCC_DEBUG
738         if (idebug)
739                 printf("mkstack: %p\n"p);
ragge
1.15
740 #endif
ragge
1.22
741
742         if (p == NULL)
743                 return;
744         mkstack(p->n_left);
745
746         switch (p->n_op) {
747         case LB/* Array index */
748                 if (p->n_right->n_op != ICON)
749                         cerror("mkstack");
750                 if (!ISARY(pstk->in_t))
751                         uerror("array indexing non-array");
752                 pstk->in_n = p->n_right->n_lval;
753                 nfree(p->n_right);
754                 break;
755
756         case NAME:
ragge
1.41
757                 if (pstk->in_lnk) {
758                         for (; pstk->in_lnkpstk->in_lnk = pstk->in_lnk->snext)
759                                 if (pstk->in_lnk->sname == (char *)p->n_sp)
ragge
1.24
760                                         break;
ragge
1.41
761                         if (pstk->in_lnk == NULL)
ragge
1.24
762                                 uerror("member missing");
ragge
1.25
763                 } else {
ragge
1.24
764                         uerror("not a struct/union");
ragge
1.25
765                 }
ragge
1.22
766                 break;
767         default:
768                 cerror("mkstack2");
769         }
770         nfree(p);
ragge
1.24
771         stkpush();
772
ragge
1.22
773 }
774
775 /*
776  * Initialize a specific element, as per C99.
777  */
778 void
779 desinit(NODE *p)
780 {
ragge
1.25
781         int op = p->n_op;
ragge
1.22
782
ragge
1.26
783         if (pstk == NULL)
784                 stkpush(); /* passed end of array */
ragge
1.24
785         while (pstk->in_prev && pstk->in_fl == 0)
786                 pstk = pstk->in_prev/* Empty stack */
ragge
1.22
787
ragge
1.24
788         if (ISSOU(pstk->in_t))
ragge
1.41
789                 pstk->in_lnk = pstk->in_sym->ssue->sylnk;
ragge
1.24
790
ragge
1.25
791         mkstack(p);     /* Setup for assignment */
792
793         /* pop one step if SOU, ilbrace will push */
ragge
1.38
794         if (op == NAME || op == LB)
ragge
1.25
795                 pstk = pstk->in_prev;
ragge
1.22
796
ragge
1.24
797 #ifdef PCC_DEBUG
798         if (idebug > 1) {
799                 printf("desinit e\n");
800                 prtstk(pstk);
801         }
802 #endif
ragge
1.15
803 }
804
805 /*
ragge
1.26
806  * Convert a string to an array of char/wchar for asginit.
ragge
1.21
807  */
808 static void
ragge
1.22
809 strcvt(NODE *p)
ragge
1.21
810 {
811         char *s;
812         int i;
813
ragge
1.23
814         for (s = p->n_sp->sname; *s != 0; ) {
815                 if (*s++ == '\\') {
ragge
1.21
816                         i = esccon(&s);  
ragge
1.23
817                 } else
ragge
1.26
818                         i = (unsigned char)s[-1];
ragge
1.22
819                 asginit(bcon(i));
ragge
1.21
820         } 
ragge
1.37
821         tfree(p);
ragge
1.21
822 }
823
824 /*
ragge
1.15
825  * Do an assignment to a struct element.
826  */
827 void
ragge
1.22
828 asginit(NODE *p)
ragge
1.15
829 {
ragge
1.21
830         int g;
831
ragge
1.26
832 #ifdef PCC_DEBUG
833         if (idebug)
834                 printf("asginit %p\n"p);
835         if (idebug > 1 && p)
836                 fwalk(peprint0);
837 #endif
838
ragge
1.21
839         /* convert string to array of char */
840         if (p && DEUNSIGN(p->n_type) == ARY+CHAR) {
ragge
1.22
841                 /*
842                  * ...but only if next element is ARY+CHAR, otherwise 
843                  * just fall through.
844                  */
845
846                 /* HACKHACKHACK */
847                 struct instk *is = pstk;
848
ragge
1.28
849                 if (pstk == NULL)
850                         stkpush();
ragge
1.22
851                 while (ISSOU(pstk->in_t) || ISARY(pstk->in_t))
852                         stkpush();
ragge
1.26
853                 if (pstk->in_prev && 
854                     DEUNSIGN(pstk->in_prev->in_t) == ARY+CHAR) {
855                         pstk = pstk->in_prev;
ragge
1.22
856                         if ((g = pstk->in_fl) == 0)
ragge
1.26
857                                 pstk->in_fl = 1/* simulate ilbrace */
ragge
1.22
858
859                         strcvt(p);
860                         if (g == 0)
861                                 irbrace();
862                         return;
ragge
1.26
863                 } else
864                         pstk = is/* no array of char */
865                 /* END HACKHACKHACK */
ragge
1.21
866         }
867
ragge
1.15
868         if (p == NULL) { /* only end of compound stmt */
869                 irbrace();
ragge
1.22
870         } else /* assign next element */
ragge
1.15
871                 scalinit(p);
872 }
873
874 #ifdef PCC_DEBUG
875 void
876 prtstk(struct instk *in)
877 {
878         int io = 0;
879
ragge
1.16
880         printf("init stack:\n");
ragge
1.15
881         for (; in != NULLin = in->in_prev) {
882                 for (i = 0i < oi++)
883                         printf("  ");
884                 printf("%p) '%s' "inin->in_sym->sname);
885                 tprint(stdoutin->in_t0);
ragge
1.21
886                 printf(" %s "scnames(in->in_sym->sclass));
ragge
1.22
887                 if (in->in_df && in->in_df->ddim)
888                     printf("arydim=%d "in->in_df->ddim);
ragge
1.15
889                 printf("ninit=%d "in->in_n);
ragge
1.22
890                 if (BTYPE(in->in_t) == STRTY || ISARY(in->in_t))
ragge
1.21
891                         printf("stsize=%d "in->in_sym->ssue->suesize);
ragge
1.15
892                 if (in->in_flprintf("{ ");
ragge
1.20
893                 printf("soff=%d "in->in_sym->soffset);
ragge
1.23
894                 if (in->in_t == STRTY) {
ragge
1.41
895                         if (in->in_lnk)
896                                 printf("curel %s "in->in_lnk->sname);
ragge
1.23
897                         else
898                                 printf("END struct");
899                 }
ragge
1.15
900                 printf("\n");
901                 o++;
902         }
903 }
904 #endif
905
906 /*
907  * Do a simple initialization.
908  * At block 0, just print out the value, at higher levels generate
909  * appropriate code.
910  */
911 void
912 simpleinit(struct symtab *spNODE *p)
913 {
914         /* May be an initialization of an array of char by a string */
ragge
1.26
915         if ((DEUNSIGN(p->n_type) == ARY+CHAR &&
916             DEUNSIGN(sp->stype) == ARY+CHAR) ||
917             (DEUNSIGN(p->n_type) == ARY+WCHAR_TYPE &&
918             DEUNSIGN(sp->stype) == ARY+WCHAR_TYPE)) {
ragge
1.21
919                 /* Handle "aaa" as { 'a', 'a', 'a' } */
920                 beginit(sp);
ragge
1.22
921                 strcvt(p);
ragge
1.21
922                 if (csym->sdf->ddim == 0)
923                         scalinit(bcon(0)); /* Null-term arrays */
924                 endinit();
ragge
1.19
925                 return;
ragge
1.15
926         }
927
928         switch (sp->sclass) {
929         case STATIC:
930         case EXTDEF:
931                 spname = sp;
932                 p = optim(buildtree(ASSIGNbuildtree(NAMENILNIL), p));
ragge
1.40
933                 defloc(sp);
ragge
1.37
934                 ninval(0p->n_right->n_sue->suesizep->n_right);
ragge
1.15
935                 tfree(p);
936                 break;
937
938         case AUTO:
939         case REGISTER:
ragge
1.23
940                 if (ISARY(sp->stype))
941                         cerror("no array init");
ragge
1.15
942                 spname = sp;
943                 ecomp(buildtree(ASSIGNbuildtree(NAMENILNIL), p));
944                 break;
945
946         default:
947                 uerror("illegal initialization");
948         }
949 }
FishEye: Open Source License registered to PCC.
Your maintenance has expired. You can renew your license at http://www.atlassian.com/fisheye/renew
Atlassian FishEye, CVS analysis. (Version:1.6.3 Build:build-336 2008-11-04) - Administration - Page generated 2014-11-01 04:21 +0100