Quick Search:

View

Revision:
Expand:  
Changeset: BSD_44:ragge:20020324105723

Diff

Diff from 1.1.1.1 to:

Annotations

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

Annotated File View

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