Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20020520162701

Diff

Diff from 1.9 to:

Annotations

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

Annotated File View

ragge
1.2
1 #if 0
ragge
1.1
2 static char *sccsid ="@(#)pftn.c        1.29 (Berkeley) 6/18/90";
ragge
1.2
3 #endif
ragge
1.1
4
5 # include "pass1.h"
6
7 unsigned int offsz;
8
9 struct symtab *schain[MAXSCOPES];       /* sym chains for clearst */
10 int chaintop;                           /* highest active entry */
11
12 struct instk {
13         int in_sz;   /* size of array element */
14         int in_x;    /* current index for structure member in structure initializations */
15         int in_n;    /* number of initializations seen */
16         int in_s;    /* sizoff */
17         int in_d;    /* dimoff */
18         TWORD in_t;    /* type */
19         int in_id;   /* stab index */
20         int in_fl;   /* flag which says if this level is controlled by {} */
21         OFFSZ in_off;  /* offset of the beginning of this level */
ragge
1.2
22 instack[10], *pstk;
ragge
1.1
23
ragge
1.2
24 /* defines used for getting things off of the initialization stack */
ragge
1.1
25
26
ragge
1.2
27 struct symtab *relook(struct symtab *);
28 struct symtab * mknonuniq(int *);
29 void fixtype(NODE *pint class);
30 int fixclass(int classTWORD type);
31 int falloc(struct symtab *pint wint newNODE *pty);
32 void psave(int);
33 int oalloc(struct symtab *pint *poff);
34 int hide(struct symtab *p);
35 void inforce(OFFSZ n);
36 void vfdalign(int n);
37 void instk(int idTWORD tint dint sOFFSZ off);
38 void gotscal(void);
ragge
1.1
39
40 int ddebug = 0;
41
ragge
1.2
42 void
43 defid(NODE *qint class)
44 {
45         struct symtab *p;
ragge
1.1
46         int idp;
ragge
1.2
47         TWORD type;
ragge
1.1
48         TWORD stp;
ragge
1.2
49         int scl;
ragge
1.1
50         int dsymddef;
51         int slevtemp;
52         int changed;
53
54         ifq == NIL ) return;  /* an error was detected */
55
56         ifq < node || q >= &node[TREESZ] ) cerror"defid call" );
57
58         idp = q->tn.rval;
59
60         ifidp < 0 ) cerror"tyreduce" );
61         p = &stab[idp];
62
63 # ifndef BUG1
ragge
1.4
64         if (ddebug) {
65                 printf("defid(%s (%d), "p->snameidp);
66                 tprint(q->in.type);
67                 printf(", %s, (%d,%d)), level %d\n"scnames(class),
68                     q->fn.cdimq->fn.csizblevel);
69         }
ragge
1.1
70 # endif
71
72         fixtypeqclass );
73
74         type = q->in.type;
75         class = fixclassclasstype );
76
77         stp = p->stype;
78         slev = p->slevel;
79
80 # ifndef BUG1
ragge
1.4
81         if (ddebug) {
82                 printf("        modified to ");
83                 tprint(type);
84                 printf(", %s\n"scnames(class));
85                 printf("        previous def'n: ");
86                 tprint(stp);
87                 printf(", %s, (%d,%d)), level %d\n",
88                     scnames(p->sclass), p->dimoffp->sizoffslev);
89         }
ragge
1.1
90 # endif
91
92         ifstp == FTN && p->sclass == SNULL )goto enter;
ragge
1.4
93         if (blevel==1 && stp!=FARG)
94                 switchclass ){
ragge
1.1
95                 default:
ragge
1.4
96                         if (!(class&FIELD))
97                                 uerror"declared argument %s is missing",
98                                     p->sname );
ragge
1.1
99                 case MOS:
100                 case STNAME:
101                 case MOU:
102                 case UNAME:
103                 case MOE:
104                 case ENAME:
105                 case TYPEDEF:
106                         ;
ragge
1.4
107         }
ragge
1.1
108         ifstp == UNDEF|| stp == FARG ) goto enter;
109
110         iftype != stp ) goto mismatch;
111         ifblevel > slev && (class == AUTO || class == REGISTER) )
112                 /* new scope */
113                 goto mismatch;
114
115         /* test (and possibly adjust) dimensions */
116         dsym = p->dimoff;
117         ddef = q->fn.cdim;
118         changed = 0;
119         fortemp=typetemp&TMASKtemp = DECREF(temp) ){
120                 ifISARY(temp) ){
121                         if (dimtab[dsym] == 0) {
122                                 dimtab[dsym] = dimtab[ddef];
123                                 changed = 1;
124                                 }
125                         else if (dimtab[ddef]!=0&&dimtab[dsym]!=dimtab[ddef]) {
126                                 goto mismatch;
127                                 }
128                         ++dsym;
129                         ++ddef;
130                         }
131                 }
132
133         if (changed) {
134                 FIXDEF(p);
135                 }
136
137         /* check that redeclarations are to the same structure */
138         if( (temp==STRTY||temp==UNIONTY||temp==ENUMTY) && p->sizoff != q->fn.csiz
139                  && class!=STNAME && class!=UNAME && class!=ENAME ){
140                 goto mismatch;
141                 }
142
143         scl = ( p->sclass );
144
145 # ifndef BUG1
146         ifddebug ){
147                 printf"       previous class: %s\n"scnames(scl) );
148                 }
149 # endif
150
151         ifclass&FIELD ){
152                 /* redefinition */
153                 if( !fallocpclass&FLDSIZ1NIL ) ) {
154                         /* successful allocation */
155                         psaveidp );
156                         return;
157                         }
158                 /* blew it: resume at end of switch... */
159                 }
160
161         else switchclass ){
162
163         case EXTERN:
164                 switchscl ){
165                 case STATIC:
166                 case USTATIC:
167                         ifslev==0 ) return;
168                         break;
169                 case EXTDEF:
170                 case EXTERN:
171                 case FORTRAN:
172                 case UFORTRAN:
173                         return;
174                         }
175                 break;
176
177         case STATIC:
178                 ifscl==USTATIC || (scl==EXTERN && blevel==0) ){
179                         p->sclass = STATIC;
180                         ifISFTN(type) ) curftn = idp;
181                         return;
182                         }
183                 break;
184
185         case USTATIC:
186                 ifscl==STATIC || scl==USTATIC ) return;
187                 break;
188
189         case LABEL:
190                 ifscl == ULABEL ){
191                         p->sclass = LABEL;
192                         deflabp->offset );
193                         return;
194                         }
195                 break;
196
197         case TYPEDEF:
198                 ifscl == class ) return;
199                 break;
200
201         case UFORTRAN:
202                 ifscl == UFORTRAN || scl == FORTRAN ) return;
203                 break;
204
205         case FORTRAN:
206                 ifscl == UFORTRAN ){
207                         p->sclass = FORTRAN;
208                         ifISFTN(type) ) curftn = idp;
209                         return;
210                         }
211                 break;
212
213         case MOU:
214         case MOS:
215                 ifscl == class ) {
216                         ifoallocp, &strucoff ) ) break;
217                         ifclass == MOU ) strucoff = 0;
218                         psaveidp );
219                         return;
220                         }
221                 break;
222
223         case MOE:
224                 break;
225
226         case EXTDEF:
227                 ifscl == EXTERN ) {
228                         p->sclass = EXTDEF;
229                         ifISFTN(type) ) curftn = idp;
230                         return;
231                         }
232                 break;
233
234         case STNAME:
235         case UNAME:
236         case ENAME:
237                 ifscl != class ) break;
238                 ifdimtab[p->sizoff] == 0 ) return;  /* previous entry just a mention */
239                 break;
240
241         case ULABEL:
242                 ifscl == LABEL || scl == ULABEL ) return;
243         case PARAM:
244         case AUTO:
245         case REGISTER:
246                 ;  /* mismatch.. */
247
248                 }
249
250         mismatch:
251         /* allow nonunique structure/union member names */
252
253         ifclass==MOU || class==MOS || class & FIELD ){/* make a new entry */
ragge
1.2
254                 int *memp;
ragge
1.1
255                 p->sflags |= SNONUNIQ;  /* old entry is nonunique */
256                 /* determine if name has occurred in this structure/union */
257                 if (paramno > 0formemp = &paramstk[paramno-1];
258                         /* while */ *memp>=0 && stab[*memp].sclass != STNAME
259                                 && stab[*memp].sclass != UNAME;
260                         /* iterate */ --memp){ char *cname, *oname;
261                         ifstab[*memp].sflags & SNONUNIQ ){
262                                 cname=p->sname;
263                                 oname=stab[*memp].sname;
264                                 if (cname != onamegoto diff;
265                                 uerror("redeclaration of: %s",p->sname);
266                                 break;
267                                 diffcontinue;
268                                 }
269                         }
270                 p = mknonuniq( &idp ); /* update p and idp to new entry */
271                 goto enter;
272                 }
273         ifblevel > slev && class != EXTERN && class != FORTRAN &&
274                 class != UFORTRAN && !( class == LABEL && slev >= 2 ) ){
275                 q->tn.rval = idp = hidep );
276                 p = &stab[idp];
277                 goto enter;
278                 }
279         uerror"redeclaration of %s"p->sname );
280         ifclass==EXTDEF && ISFTN(type) ) curftn = idp;
281         return;
282
283         enter:  /* make a new entry */
284
285 # ifndef BUG1
286         ifddebug ) printf"  new entry made\n" );
287 # endif
288         iftype == UNDEF ) uerror("void type for %s",p->sname);
289         p->stype = type;
290         p->sclass = class;
291         p->slevel = blevel;
292         p->offset = NOOFFSET;
293         p->suse = lineno;
294         ifclass == STNAME || class == UNAME || class == ENAME ) {
295                 p->sizoff = curdim;
296                 dstash0 );  /* size */
297                 dstash( -1 ); /* index to members of str or union */
298                 dstashALSTRUCT );  /* alignment */
299                 dstashidp );
300                 }
301         else {
302                 switchBTYPE(type) ){
303                 case STRTY:
304                 case UNIONTY:
305                 case ENUMTY:
306                         p->sizoff = q->fn.csiz;
307                         break;
308                 default:
309                         p->sizoff = BTYPE(type);
310                         }
311                 }
312
313         /* copy dimensions */
314
315         p->dimoff = q->fn.cdim;
316
317         /* allocate offsets */
318         ifclass&FIELD ){
319                 (voidfallocpclass&FLDSIZ0NIL );  /* new entry */
320                 psaveidp );
321                 }
322         else switchclass ){
323
324         case AUTO:
325                 (voidoallocp, &autooff );
326                 break;
327         case STATIC:
328         case EXTDEF:
329                 p->offset = getlab();
330                 ifISFTN(type) ) curftn = idp;
331                 break;
332         case ULABEL:
333         case LABEL:
334                 p->offset = getlab();
335                 p->slevel = 2;
336                 ifclass == LABEL ){
337                         (voidlocctrPROG );
338                         deflabp->offset );
339                         }
340                 break;
341
342         case EXTERN:
343         case UFORTRAN:
344         case FORTRAN:
345                 p->offset = getlab();
346                 p->slevel = 0;
347                 break;
348         case MOU:
349         case MOS:
350                 (voidoallocp, &strucoff );
351                 ifclass == MOU ) strucoff = 0;
352                 psaveidp );
353                 break;
354
355         case MOE:
356                 p->offset = strucoff++;
357                 psaveidp );
358                 break;
359         case REGISTER:
360                 p->offset = regvar--;
361                 ifblevel == 1 ) p->sflags |= SSET;
362                 ifregvar < minrvar ) minrvar = regvar;
363                 break;
364                 }
365
366         {
ragge
1.2
367                 int l = p->slevel;
ragge
1.1
368
369                 ifl >= MAXSCOPES )
370                         cerror"scopes nested too deep" );
371
372                 p->snext = schain[l];
373                 schain[l] = p;
374                 ifl >= chaintop )
375                         chaintop = l + 1;
376                 }
377
378         /* user-supplied routine to fix up new definitions */
379
380         FIXDEF(p);
381
382 # ifndef BUG1
383         ifddebug ) printf"  dimoff, sizoff, offset: %d, %d, %d\n"p->dimoffp->sizoffp->offset );
384 # endif
385
386         }
387
ragge
1.2
388 void
389 psave(int i)
390 {
ragge
1.1
391         ifparamno >= PARAMSZ ){
392                 cerror"parameter stack overflow");
ragge
1.2
393         }
ragge
1.1
394         paramstkparamno++ ] = i;
ragge
1.2
395 }
ragge
1.1
396
ragge
1.2
397 /*
398  * end of function
399  */
400 void
401 ftnend()
402 {
ragge
1.1
403         ifretlab != NOLAB && nerrors == 0 ){ /* inside a real function */
404                 efcode();
ragge
1.2
405         }
ragge
1.1
406         checkst(0);
407         retstat = 0;
408         tcheck();
409         curclass = SNULL;
410         brklab = contlab = retlab = NOLAB;
411         flostat = 0;
412         ifnerrors == 0 ){
413                 ifpsavbc != & asavbc[0] ) cerror("bcsave error");
414                 ifparamno != 0 ) cerror("parameter reset error");
415                 ifswx != 0 ) cerror"switch error");
416                 }
417         psavbc = &asavbc[0];
418         paramno = 0;
419         autooff = AUTOINIT;
420         minrvar = regvar = MAXRVAR;
421         reached = 1;
422         swx = 0;
423         swp = swtab;
424         (voidlocctr(DATA);
ragge
1.2
425 }
ragge
1.1
426
ragge
1.2
427 void
428 dclargs()
429 {
430         int ij;
431         struct symtab *p;
432         NODE *q;
ragge
1.1
433         argoff = ARGINIT;
434 # ifndef BUG1
435         ifddebug > 2printf("dclargs()\n");
436 # endif
437         fori=0i<paramno; ++i ){
438                 if( (j = paramstk[i]) < 0 ) continue;
439                 p = &stab[j];
440 # ifndef BUG1
441                 ifddebug > 2 ){
442                         printf("\t%s (%d) ",p->snamej);
443                         tprint(p->stype);
444                         printf("\n");
445                         }
446 # endif
447                 ifp->stype == FARG ) {
448                         q = block(FREE,NIL,NIL,INT,0,INT);
449                         q->tn.rval = j;
450                         defidqPARAM );
451                         }
452                 FIXARG(p); /* local arg hook, eg. for sym. debugger */
453                 oallocp, &argoff );  /* always set aside space, even for register arguments */
454                 }
455         cendarg();
456         (voidlocctr(PROG);
457         defalign(ALINT);
458         ftnno = getlab();
459         bfcodeparamstkparamno );
460         paramno = 0;
ragge
1.2
461 }
ragge
1.1
462
463 NODE *
464 rstructidnsoru ){ /* reference to a structure or union, with no definition */
ragge
1.2
465         struct symtab *p;
466         NODE *q;
ragge
1.1
467         p = &stab[idn];
468         switchp->stype ){
469
470         case UNDEF:
471         def:
472                 q = blockFREENILNIL000 );
473                 q->tn.rval = idn;
474                 q->in.type = (soru&INSTRUCT) ? STRTY : ( (soru&INUNION) ? UNIONTY : ENUMTY );
475                 defidq, (soru&INSTRUCT) ? STNAME : ( (soru&INUNION) ? UNAME : ENAME ) );
476                 break;
477
478         case STRTY:
479                 ifsoru & INSTRUCT ) break;
480                 goto def;
481
482         case UNIONTY:
483                 ifsoru & INUNION ) break;
484                 goto def;
485
486         case ENUMTY:
487                 if( !(soru&(INUNION|INSTRUCT)) ) break;
488                 goto def;
489
490                 }
491         stwart = instruct;
492         returnmktyp->stype0p->sizoff ) );
493         }
494
ragge
1.2
495 void
496 moedef(int idn)
497 {
498         NODE *q;
ragge
1.1
499
500         q = blockFREENILNILMOETY00 );
501         q->tn.rval = idn;
502         ifidn>=0 ) defidqMOE );
ragge
1.2
503 }
ragge
1.1
504
ragge
1.2
505 /*
506  * begining of structure or union declaration
507  */
508 int
509 bstruct(int idnint soru)
510 {
511         NODE *q;
ragge
1.1
512
513         psaveinstruct );
514         psavecurclass );
515         psavestrucoff );
516         strucoff = 0;
517         instruct = soru;
518         q = blockFREENILNIL000 );
519         q->tn.rval = idn;
520         ifinstruct==INSTRUCT ){
521                 curclass = MOS;
522                 q->in.type = STRTY;
523                 ifidn >= 0 ) defidqSTNAME );
524                 }
525         else ifinstruct == INUNION ) {
526                 curclass = MOU;
527                 q->in.type = UNIONTY;
528                 ifidn >= 0 ) defidqUNAME );
529                 }
530         else { /* enum */
531                 curclass = MOE;
532                 q->in.type = ENUMTY;
533                 ifidn >= 0 ) defidqENAME );
534                 }
535         psaveidn = q->tn.rval );
536         /* the "real" definition is where the members are seen */
537         if ( idn >= 0 ) stab[idn].suse = lineno;
538         returnparamno-4 );
ragge
1.2
539 }
ragge
1.1
540
541 NODE *
ragge
1.2
542 dclstruct(int oparam)
543 {
544         struct symtab *p;
545         int ialsajszszindex;
546         TWORD temp;
547         int highlow;
ragge
1.1
548
549         /* paramstk contains:
550                 paramstk[ oparam ] = previous instruct
551                 paramstk[ oparam+1 ] = previous class
552                 paramstk[ oparam+2 ] = previous strucoff
553                 paramstk[ oparam+3 ] = structure name
554
555                 paramstk[ oparam+4, ... ]  = member stab indices
556
557                 */
558
559
560         if( (i=paramstk[oparam+3]) < 0 ){
561                 szindex = curdim;
562                 dstash0 );  /* size */
563                 dstash( -1 );  /* index to member names */
564                 dstashALSTRUCT );  /* alignment */
565                 dstash( -lineno );      /* name of structure */
566                 }
567         else {
568                 szindex = stab[i].sizoff;
569                 }
570
571 # ifndef BUG1
572         ifddebug ){
573                 printf"dclstruct( %s ), szindex = %d\n", (i>=0)? stab[i].sname : "??"szindex );
574                 }
575 # endif
576         temp = (instruct&INSTRUCT)?STRTY:((instruct&INUNION)?UNIONTY:ENUMTY);
577         stwart = instruct = paramstkoparam ];
578         curclass = paramstkoparam+1 ];
579         dimtabszindex+1 ] = curdim;
580         al = ALSTRUCT;
581
582         high = low = 0;
583
584         fori = oparam+4;  iparamno; ++i ){
585                 dstashj=paramstk[i] );
586                 ifj<0 || j>= SYMTSZ ) cerror"gummy structure member" );
587                 p = &stab[j];
588                 iftemp == ENUMTY ){
589                         ifp->offset < low ) low = p->offset;
590                         ifp->offset > high ) high = p->offset;
591                         p->sizoff = szindex;
592                         continue;
593                         }
594                 sa = talignp->stypep->sizoff );
595                 ifp->sclass & FIELD ){
596                         sz = p->sclass&FLDSIZ;
597                         }
598                 else {
599                         sz = tsizep->stypep->dimoffp->sizoff );
600                         }
601                 ifsz == 0 ){
602                         werror"illegal zero sized structure member: %s"p->sname );
603                         }
604                 ifsz > strucoff ) strucoff = sz;  /* for use with unions */
605                 SETOFFalsa );
606                 /* set al, the alignment, to the lcm of the alignments of the members */
607                 }
608         dstash( -1 );  /* endmarker */
609         SETOFFstrucoffal );
610
611         iftemp == ENUMTY ){
ragge
1.2
612                 TWORD ty;
ragge
1.1
613
614 # ifdef ENUMSIZE
615                 ty = ENUMSIZE(high,low);
616 # else
617                 if( (char)high == high && (char)low == low ) ty = ctypeCHAR );
618                 else if( (short)high == high && (short)low == low ) ty = ctypeSHORT );
619                 else ty = ctype(INT);
620 #endif
621                 strucoff = tsizety0, (int)ty );
622                 dimtabszindex+2 ] = al = talignty, (int)ty );
623                 }
624
625         ifstrucoff == 0 ) uerror"zero sized structure" );
626         dimtabszindex ] = strucoff;
627         dimtabszindex+2 ] = al;
628         dimtabszindex+3 ] = paramstkoparam+3 ];  /* name index */
629
630         FIXSTRUCTszindexoparam ); /* local hook, eg. for sym debugger */
631 # ifndef BUG1
632         ifddebug>1 ){
633                 printf"\tdimtab[%d,%d,%d] = %d,%d,%d\n"szindex,szindex+1,szindex+2,
634                                 dimtab[szindex],dimtab[szindex+1],dimtab[szindex+2] );
635                 fori = dimtab[szindex+1]; dimtab[i] >= 0; ++i ){
636                         printf"\tmember %s(%d)\n"stab[dimtab[i]].snamedimtab[i] );
637                         }
638                 }
639 # endif
640
641         strucoff = paramstkoparam+2 ];
642         paramno = oparam;
643
644         returnmktytemp0szindex ) );
645         }
646
ragge
1.2
647 /*
648  * error printing routine in parser
649  */
650 void yyerror(char *s);
651 void
652 yyerror(char *s)
653 {
654         uerror(s);
655 }
656
657 void yyaccpt(void);
658 void
659 yyaccpt(void)
660 {
ragge
1.1
661         ftnend();
ragge
1.2
662 }
ragge
1.1
663
ragge
1.2
664 void
665 ftnarg(int idn)
666 {
ragge
1.1
667         switchstab[idn].stype ){
668
669         case UNDEF:
670                 /* this parameter, entered at scan */
671                 break;
672         case FARG:
673                 uerror("redeclaration of formal parameter, %s",
674                         stab[idn].sname);
675                 /* fall thru */
676         case FTN:
677                 /* the name of this function matches parm */
678                 /* fall thru */
679         default:
680                 idn = hide( &stab[idn]);
681                 break;
682         case TNULL:
683                 /* unused entry, fill it */
684                 ;
685                 }
686         stab[idn].stype = FARG;
687         stab[idn].sclass = PARAM;
688         psaveidn );
ragge
1.2
689 }
ragge
1.1
690
ragge
1.2
691 /*
692  * compute the alignment of an object with type ty, sizeoff index s
693  */
694 int
695 talign(unsigned int tyint s)
696 {
697         int i;
ragge
1.1
698
699         ifs<0 && ty!=INT && ty!=CHAR && ty!=SHORT && ty!=UNSIGNED && ty!=UCHAR && ty!=USHORT 
700                                         ){
701                 returnfldalty ) );
702                 }
703
704         fori=0i<=(SZINT-BTSHIFT-1); i+=TSHIFT ){
705                 switch( (ty>>i)&TMASK ){
706
707                 case FTN:
708                         uerror"can't assign to function" );
709                         returnALCHAR );
710                 case PTR:
711                         returnALPOINT );
712                 case ARY:
713                         continue;
714                 case 0:
715                         break;
716                         }
717                 }
718
719         switchBTYPE(ty) ){
720
721         case UNIONTY:
722         case ENUMTY:
723         case STRTY:
724                 return( (unsigned intdimtabs+2 ] );
725         case CHAR:
726         case UCHAR:
ragge
1.9
727                 return (ALCHAR);
ragge
1.1
728         case FLOAT:
ragge
1.9
729                 return (ALFLOAT);
ragge
1.1
730         case DOUBLE:
ragge
1.9
731                 return (ALDOUBLE);
732         case LONGLONG:
733         case ULONGLONG:
734                 return (ALLONGLONG);
ragge
1.1
735         case LONG:
736         case ULONG:
ragge
1.9
737                 return (ALLONG);
ragge
1.1
738         case SHORT:
739         case USHORT:
ragge
1.9
740                 return (ALSHORT);
ragge
1.1
741         default:
ragge
1.9
742                 return (ALINT);
ragge
1.1
743                 }
744         }
745
746 OFFSZ
747 tsizetyds )  TWORD ty; {
748         /* compute the size associated with type ty,
749             dimoff d, and sizoff s */
750         /* BETTER NOT BE CALLED WHEN t, d, and s REFER TO A BIT FIELD... */
751
752         int i;
753         OFFSZ mult;
754
755         mult = 1;
756
757         fori=0i<=(SZINT-BTSHIFT-1); i+=TSHIFT ){
758                 switch( (ty>>i)&TMASK ){
759
760                 case FTN:
761                         /* cerror( "compiler takes size of function"); */
762                         uerror"can't take size of function" );
763                         returnSZCHAR );
764                 case PTR:
765                         returnSZPOINT * mult );
766                 case ARY:
767                         mult *= (unsigned intdimtabd++ ];
768                         continue;
769                 case 0:
770                         break;
771
772                         }
773                 }
774
775         ifdimtab[s]==0 ) {
776                 ifty == STRTY )
777                         uerror"undefined structure" );
778                 else
779                         uerror"unknown size");
780                 returnSZINT );
781                 }
782         return( (unsigned intdimtabs ] * mult );
783         }
784
ragge
1.2
785 /*
786  * force inoff to have the value n
787  */
788 void
789 inforce(OFFSZ n)
790 {
ragge
1.1
791         /* inoff is updated to have the value n */
792         OFFSZ wb;
ragge
1.2
793         int rest;
ragge
1.1
794         /* rest is used to do a lot of conversion to ints... */
795
796         ifinoff == n ) return;
797         ifinoff > n ) {
798                 cerror"initialization alignment error");
799                 }
800
801         wb = inoff;
802         SETOFFwbSZINT );
803
804         /* wb now has the next higher word boundary */
805
806         ifwb >= n ){ /* in the same word */
807                 rest = n - inoff;
808                 vfdzerorest );
809                 return;
810                 }
811
812         /* otherwise, extend inoff to be word aligned */
813
814         rest = wb - inoff;
815         vfdzerorest );
816
817         /* now, skip full words until near to n */
818
819         rest = (n-inoff)/SZINT;
820         zecoderest );
821
822         /* now, the remainder of the last word */
823
824         rest = n-inoff;
825         vfdzerorest );
826         ifinoff != n ) cerror"inoff error");
827
828         }
829
ragge
1.2
830 /*
831  * make inoff have the offset the next alignment of n
832  */
833 void
834 vfdalign(int n)
835 {
ragge
1.1
836         OFFSZ m;
837
838         m = inoff;
839         SETOFFmn );
840         inforcem );
ragge
1.2
841 }
ragge
1.1
842
843
844 int idebug = 0;
845
846 int ibseen = 0;  /* the number of } constructions which have been filled */
847
848 int ifull = 0/* 1 if all initializers have been seen */
849
850 int iclass;  /* storage class of thing being initialized */
851
852 int ilocctr = 0;  /* location counter for current initialization */
853
ragge
1.2
854 /*
855  * beginning of initilization; set location ctr and set type
856  */
857 void
858 beginit(int curid)
859 {
860         struct symtab *p;
ragge
1.1
861
862 # ifndef BUG1
863         ifidebug >= 3 ) printf"beginit(), curid = %d\n"curid );
864 # endif
865
866         p = &stab[curid];
867
868         iclass = p->sclass;
869         ifcurclass == EXTERN || curclass == FORTRAN ) iclass = EXTERN;
870         switchiclass ){
871
872         case UNAME:
873         case EXTERN:
874                 return;
875         case AUTO:
876         case REGISTER:
877                 break;
878         case EXTDEF:
879         case STATIC:
880                 ilocctr = ISARY(p->stype)?ADATA:DATA;
881                 ifnerrors == 0 ){
882                         (voidlocctrilocctr );
883                         defaligntalignp->stypep->sizoff ) );
884                         defnamp );
885                 }
ragge
1.2
886         }
ragge
1.1
887
888         inoff = 0;
889         ibseen = 0;
890         ifull = 0;
891
892         pstk = 0;
893
894         instkcuridp->stypep->dimoffp->sizoffinoff );
895
ragge
1.2
896 }
ragge
1.1
897
ragge
1.2
898 /*
899  * make a new entry on the parameter stack to initialize id
900  */
901 void
902 instk(int idTWORD tint dint sOFFSZ off)
903 {
904         struct symtab *p;
ragge
1.1
905
ragge
1.2
906         for (;;) {
ragge
1.1
907 # ifndef BUG1
ragge
1.2
908                 if (idebug)
909                         printf("instk((%d, %o,%d,%d, %ld)\n"idtdsoff);
ragge
1.1
910 # endif
911
912                 /* save information on the stack */
913
914                 if( !pstk ) pstk = instack;
915                 else ++pstk;
916
917                 pstk->in_fl = 0;        /* { flag */
918                 pstk->in_id =  id ;
919                 pstk->in_t =  t ;
920                 pstk->in_d =  d ;
921                 pstk->in_s =  s ;
922                 pstk->in_n = 0;  /* number seen */
923                 pstk->in_x =  t==STRTY ?dimtab[s+1] : 0 ;
924                 pstk->in_off =  off;   /* offset at the beginning of this element */
925                 /* if t is an array, DECREF(t) can't be a field */
926                 /* INS_sz has size of array elements, and -size for fields */
927                 ifISARY(t) ){
928                         pstk->in_sz = tsizeDECREF(t), d+1s );
929                         }
930                 else ifstab[id].sclass & FIELD ){
931                         pstk->in_sz = - ( stab[id].sclass & FLDSIZ );
932                         }
933                 else {
934                         pstk->in_sz = 0;
935                         }
936
937                 if( (iclass==AUTO || iclass == REGISTER ) &&
938                         (ISARY(t) || t==STRTY) ) uerror"no automatic aggregate initialization" );
939
940                 /* now, if this is not a scalar, put on another element */
941
942                 ifISARY(t) ){
943                         t = DECREF(t);
944                         ++d;
945                         continue;
946                         }
947                 else ift == STRTY ){
948                         ifdimtab[pstk->in_s] == 0 ){
949                                 uerror"can't initialize undefined structure" );
950                                 iclass = -1;
951                                 return;
952                                 }
953                         id = dimtab[pstk->in_x];
954                         p = &stab[id];
955                         ifp->sclass != MOS && !(p->sclass&FIELD) ) cerror"insane structure member list" );
956                         t = p->stype;
957                         d = p->dimoff;
958                         s = p->sizoff;
959                         off += p->offset;
960                         continue;
961                         }
962                 else return;
963                 }
964         }
965
966 NODE *
967 getstr(){ /* decide if the string is external or an initializer, and get the contents accordingly */
968
ragge
1.2
969         int ltemp;
970         NODE *p;
ragge
1.1
971
972         if( (iclass==EXTDEF||iclass==STATIC) && (pstk->in_t == CHAR || pstk->in_t == UCHAR) &&
973                         pstk!=instack && ISARYpstk[-1].in_t ) ){
974                 /* treat "abc" as { 'a', 'b', 'c', 0 } */
975                 strflg = 1;
976                 ilbrace();  /* simulate { */
977                 inforcepstk->in_off );
978                 /* if the array is inflexible (not top level), pass in the size and
979                         be prepared to throw away unwanted initializers */
980                 lxstr((pstk-1)!=instack?dimtab[(pstk-1)->in_d]:0);  /* get the contents */
981                 irbrace();  /* simulate } */
982                 returnNIL );
983                 }
984         else { /* make a label, and get the contents and stash them away */
985                 ificlass != SNULL ){ /* initializing */
986                         /* fill out previous word, to permit pointer */
987                         vfdalignALPOINT );
988                         }
989                 temp = locctrblevel==0?ISTRNG:STRNG ); /* set up location counter */
990                 deflabl = getlab() );
991                 strflg = 0;
992                 lxstr(0); /* get the contents */
993                 (voidlocctrblevel==0?ilocctr:temp );
994                 p = buildtreeSTRINGNILNIL );
995                 p->tn.rval = -l;
996                 return(p);
997                 }
998         }
999
ragge
1.2
1000 /*
1001  * simulate byte v appearing in a list of integer values
1002  */
1003 void
1004 putbyte(int v)
1005 {
1006         NODE *p;
ragge
1.1
1007         p = bcon(v);
1008         incodepSZCHAR );
1009         tfreep );
1010         gotscal();
ragge
1.2
1011 }
ragge
1.1
1012
ragge
1.2
1013 void
1014 endinit(void)
1015 {
1016         TWORD t;
1017         int dsnd1;
ragge
1.1
1018
1019 # ifndef BUG1
ragge
1.2
1020         if (idebug)
1021                 printf("endinit(), inoff = %ld\n"inoff);
ragge
1.1
1022 # endif
1023
1024         switchiclass ){
1025
1026         case EXTERN:
1027         case AUTO:
1028         case REGISTER:
1029         case -1:
1030                 return;
1031                 }
1032
1033         pstk = instack;
1034
1035         t = pstk->in_t;
1036         d = pstk->in_d;
1037         s = pstk->in_s;
1038         n = pstk->in_n;
1039
1040         ifISARY(t) ){
1041                 d1 = dimtab[d];
1042
1043                 vfdalignpstk->in_sz );  /* fill out part of the last element, if needed */
1044                 n = inoff/pstk->in_sz;  /* real number of initializers */
1045                 ifd1 >= n ){
1046                         /* once again, t is an array, so no fields */
1047                         inforcetsizetds ) );
1048                         n = d1;
1049                         }
1050                 ifd1!=0 && d1!=n ) uerror"too many initializers");
1051                 ifn==0 ) werror"empty array declaration");
1052                 dimtab[d] = n;
ragge
1.2
1053                 if (d1==0) {
1054                         FIXDEF(&stab[pstk->in_id]);
ragge
1.1
1055                 }
ragge
1.2
1056         }
ragge
1.1
1057
1058         else ift == STRTY || t == UNIONTY ){
1059                 /* clearly not fields either */
1060                 inforcetsizetds ) );
1061                 }
1062         else ifn > 1 ) uerror"bad scalar initialization");
1063         /* this will never be called with a field element... */
1064         else inforcetsize(t,d,s) );
1065
1066         paramno = 0;
1067