Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20020817125448

Diff

Diff from 1.11 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:
ragge
1.10
227                 switch (scl) {
228                 case EXTERN:
ragge
1.1
229                         p->sclass = EXTDEF;
ragge
1.10
230                         if (ISFTN(type))
231                                 curftn = idp;
ragge
1.1
232                         return;
ragge
1.10
233                 case USTATIC:
234                         p->sclass = STATIC;
235                         if (ISFTN(type))
236                                 curftn = idp;
237                         return;
238                 }
ragge
1.1
239                 break;
240
241         case STNAME:
242         case UNAME:
243         case ENAME:
244                 ifscl != class ) break;
245                 ifdimtab[p->sizoff] == 0 ) return;  /* previous entry just a mention */
246                 break;
247
248         case ULABEL:
249                 ifscl == LABEL || scl == ULABEL ) return;
250         case PARAM:
251         case AUTO:
252         case REGISTER:
253                 ;  /* mismatch.. */
254
255                 }
256
257         mismatch:
258         /* allow nonunique structure/union member names */
259
260         ifclass==MOU || class==MOS || class & FIELD ){/* make a new entry */
ragge
1.2
261                 int *memp;
ragge
1.1
262                 p->sflags |= SNONUNIQ;  /* old entry is nonunique */
263                 /* determine if name has occurred in this structure/union */
264                 if (paramno > 0formemp = &paramstk[paramno-1];
265                         /* while */ *memp>=0 && stab[*memp].sclass != STNAME
266                                 && stab[*memp].sclass != UNAME;
267                         /* iterate */ --memp){ char *cname, *oname;
268                         ifstab[*memp].sflags & SNONUNIQ ){
269                                 cname=p->sname;
270                                 oname=stab[*memp].sname;
271                                 if (cname != onamegoto diff;
272                                 uerror("redeclaration of: %s",p->sname);
273                                 break;
274                                 diffcontinue;
275                                 }
276                         }
277                 p = mknonuniq( &idp ); /* update p and idp to new entry */
278                 goto enter;
279                 }
280         ifblevel > slev && class != EXTERN && class != FORTRAN &&
281                 class != UFORTRAN && !( class == LABEL && slev >= 2 ) ){
282                 q->tn.rval = idp = hidep );
283                 p = &stab[idp];
284                 goto enter;
285                 }
286         uerror"redeclaration of %s"p->sname );
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         {
ragge
1.2
374                 int l = p->slevel;
ragge
1.1
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
ragge
1.2
395 void
396 psave(int i)
397 {
ragge
1.1
398         ifparamno >= PARAMSZ ){
399                 cerror"parameter stack overflow");
ragge
1.2
400         }
ragge
1.1
401         paramstkparamno++ ] = i;
ragge
1.2
402 }
ragge
1.1
403
ragge
1.2
404 /*
405  * end of function
406  */
407 void
408 ftnend()
409 {
ragge
1.1
410         ifretlab != NOLAB && nerrors == 0 ){ /* inside a real function */
411                 efcode();
ragge
1.2
412         }
ragge
1.1
413         checkst(0);
414         retstat = 0;
415         tcheck();
416         curclass = SNULL;
417         brklab = contlab = retlab = NOLAB;
418         flostat = 0;
419         ifnerrors == 0 ){
420                 ifpsavbc != & asavbc[0] ) cerror("bcsave error");
421                 ifparamno != 0 ) cerror("parameter reset error");
422                 ifswx != 0 ) cerror"switch error");
423                 }
424         psavbc = &asavbc[0];
425         paramno = 0;
426         autooff = AUTOINIT;
427         minrvar = regvar = MAXRVAR;
428         reached = 1;
429         swx = 0;
430         swp = swtab;
431         (voidlocctr(DATA);
ragge
1.2
432 }
ragge
1.1
433
ragge
1.2
434 void
435 dclargs()
436 {
437         int ij;
438         struct symtab *p;
439         NODE *q;
ragge
1.1
440         argoff = ARGINIT;
441 # ifndef BUG1
442         ifddebug > 2printf("dclargs()\n");
443 # endif
444         fori=0i<paramno; ++i ){
445                 if( (j = paramstk[i]) < 0 ) continue;
446                 p = &stab[j];
447 # ifndef BUG1
448                 ifddebug > 2 ){
449                         printf("\t%s (%d) ",p->snamej);
450                         tprint(p->stype);
451                         printf("\n");
452                         }
453 # endif
454                 ifp->stype == FARG ) {
455                         q = block(FREE,NIL,NIL,INT,0,INT);
456                         q->tn.rval = j;
457                         defidqPARAM );
458                         }
459                 FIXARG(p); /* local arg hook, eg. for sym. debugger */
460                 oallocp, &argoff );  /* always set aside space, even for register arguments */
461                 }
462         cendarg();
463         (voidlocctr(PROG);
464         defalign(ALINT);
465         ftnno = getlab();
466         bfcodeparamstkparamno );
467         paramno = 0;
ragge
1.2
468 }
ragge
1.1
469
470 NODE *
471 rstructidnsoru ){ /* reference to a structure or union, with no definition */
ragge
1.2
472         struct symtab *p;
473         NODE *q;
ragge
1.1
474         p = &stab[idn];
475         switchp->stype ){
476
477         case UNDEF:
478         def:
479                 q = blockFREENILNIL000 );
480                 q->tn.rval = idn;
481                 q->in.type = (soru&INSTRUCT) ? STRTY : ( (soru&INUNION) ? UNIONTY : ENUMTY );
482                 defidq, (soru&INSTRUCT) ? STNAME : ( (soru&INUNION) ? UNAME : ENAME ) );
483                 break;
484
485         case STRTY:
486                 ifsoru & INSTRUCT ) break;
487                 goto def;
488
489         case UNIONTY:
490                 ifsoru & INUNION ) break;
491                 goto def;
492
493         case ENUMTY:
494                 if( !(soru&(INUNION|INSTRUCT)) ) break;
495                 goto def;
496
497                 }
498         stwart = instruct;
499         returnmktyp->stype0p->sizoff ) );
500         }
501
ragge
1.2
502 void
503 moedef(int idn)
504 {
505         NODE *q;
ragge
1.1
506
507         q = blockFREENILNILMOETY00 );
508         q->tn.rval = idn;
509         ifidn>=0 ) defidqMOE );
ragge
1.2
510 }
ragge
1.1
511
ragge
1.2
512 /*
513  * begining of structure or union declaration
514  */
515 int
516 bstruct(int idnint soru)
517 {
518         NODE *q;
ragge
1.1
519
520         psaveinstruct );
521         psavecurclass );
522         psavestrucoff );
523         strucoff = 0;
524         instruct = soru;
525         q = blockFREENILNIL000 );
526         q->tn.rval = idn;
527         ifinstruct==INSTRUCT ){
528                 curclass = MOS;
529                 q->in.type = STRTY;
530                 ifidn >= 0 ) defidqSTNAME );
531                 }
532         else ifinstruct == INUNION ) {
533                 curclass = MOU;
534                 q->in.type = UNIONTY;
535                 ifidn >= 0 ) defidqUNAME );
536                 }
537         else { /* enum */
538                 curclass = MOE;
539                 q->in.type = ENUMTY;
540                 ifidn >= 0 ) defidqENAME );
541                 }
542         psaveidn = q->tn.rval );
543         /* the "real" definition is where the members are seen */
544         if ( idn >= 0 ) stab[idn].suse = lineno;
545         returnparamno-4 );
ragge
1.2
546 }
ragge
1.1
547
548 NODE *
ragge
1.2
549 dclstruct(int oparam)
550 {
551         struct symtab *p;
552         int ialsajszszindex;
553         TWORD temp;
554         int highlow;
ragge
1.1
555
556         /* paramstk contains:
557                 paramstk[ oparam ] = previous instruct
558                 paramstk[ oparam+1 ] = previous class
559                 paramstk[ oparam+2 ] = previous strucoff
560                 paramstk[ oparam+3 ] = structure name
561
562                 paramstk[ oparam+4, ... ]  = member stab indices
563
564                 */
565
566
567         if( (i=paramstk[oparam+3]) < 0 ){
568                 szindex = curdim;
569                 dstash0 );  /* size */
570                 dstash( -1 );  /* index to member names */
571                 dstashALSTRUCT );  /* alignment */
572                 dstash( -lineno );      /* name of structure */
573                 }
574         else {
575                 szindex = stab[i].sizoff;
576                 }
577
578 # ifndef BUG1
579         ifddebug ){
580                 printf"dclstruct( %s ), szindex = %d\n", (i>=0)? stab[i].sname : "??"szindex );
581                 }
582 # endif
583         temp = (instruct&INSTRUCT)?STRTY:((instruct&INUNION)?UNIONTY:ENUMTY);
584         stwart = instruct = paramstkoparam ];
585         curclass = paramstkoparam+1 ];
586         dimtabszindex+1 ] = curdim;
587         al = ALSTRUCT;
588
589         high = low = 0;
590
591         fori = oparam+4;  iparamno; ++i ){
592                 dstashj=paramstk[i] );
593                 ifj<0 || j>= SYMTSZ ) cerror"gummy structure member" );
594                 p = &stab[j];
595                 iftemp == ENUMTY ){
596                         ifp->offset < low ) low = p->offset;
597                         ifp->offset > high ) high = p->offset;
598                         p->sizoff = szindex;
599                         continue;
600                         }
601                 sa = talignp->stypep->sizoff );
602                 ifp->sclass & FIELD ){
603                         sz = p->sclass&FLDSIZ;
604                         }
605                 else {
606                         sz = tsizep->stypep->dimoffp->sizoff );
607                         }
608                 ifsz == 0 ){
609                         werror"illegal zero sized structure member: %s"p->sname );
610                         }
611                 ifsz > strucoff ) strucoff = sz;  /* for use with unions */
612                 SETOFFalsa );
613                 /* set al, the alignment, to the lcm of the alignments of the members */
614                 }
615         dstash( -1 );  /* endmarker */
616         SETOFFstrucoffal );
617
618         iftemp == ENUMTY ){
ragge
1.2
619                 TWORD ty;
ragge
1.1
620
621 # ifdef ENUMSIZE
622                 ty = ENUMSIZE(high,low);
623 # else
624                 if( (char)high == high && (char)low == low ) ty = ctypeCHAR );
625                 else if( (short)high == high && (short)low == low ) ty = ctypeSHORT );
626                 else ty = ctype(INT);
627 #endif
628                 strucoff = tsizety0, (int)ty );
629                 dimtabszindex+2 ] = al = talignty, (int)ty );
630                 }
631
632         ifstrucoff == 0 ) uerror"zero sized structure" );
633         dimtabszindex ] = strucoff;
634         dimtabszindex+2 ] = al;
635         dimtabszindex+3 ] = paramstkoparam+3 ];  /* name index */
636
637         FIXSTRUCTszindexoparam ); /* local hook, eg. for sym debugger */
638 # ifndef BUG1
639         ifddebug>1 ){
640                 printf"\tdimtab[%d,%d,%d] = %d,%d,%d\n"szindex,szindex+1,szindex+2,
641                                 dimtab[szindex],dimtab[szindex+1],dimtab[szindex+2] );
642                 fori = dimtab[szindex+1]; dimtab[i] >= 0; ++i ){
643                         printf"\tmember %s(%d)\n"stab[dimtab[i]].snamedimtab[i] );
644                         }
645                 }
646 # endif
647
648         strucoff = paramstkoparam+2 ];
649         paramno = oparam;
650
651         returnmktytemp0szindex ) );
652         }
653
ragge
1.2
654 /*
655  * error printing routine in parser
656  */
657 void yyerror(char *s);
658 void
659 yyerror(char *s)
660 {
661         uerror(s);
662 }
663
664 void yyaccpt(void);
665 void
666 yyaccpt(void)
667 {
ragge
1.1
668         ftnend();
ragge
1.2
669 }
ragge
1.1
670
ragge
1.2
671 void
672 ftnarg(int idn)
673 {
ragge
1.1
674         switchstab[idn].stype ){
675
676         case UNDEF:
677                 /* this parameter, entered at scan */
678                 break;
679         case FARG:
680                 uerror("redeclaration of formal parameter, %s",
681                         stab[idn].sname);
682                 /* fall thru */
683         case FTN:
684                 /* the name of this function matches parm */
685                 /* fall thru */
686         default:
687                 idn = hide( &stab[idn]);
688                 break;
689         case TNULL:
690                 /* unused entry, fill it */
691                 ;
692                 }
693         stab[idn].stype = FARG;
694         stab[idn].sclass = PARAM;
695         psaveidn );
ragge
1.2
696 }
ragge
1.1
697
ragge
1.2
698 /*
699  * compute the alignment of an object with type ty, sizeoff index s
700  */
701 int
702 talign(unsigned int tyint s)
703 {
704         int i;
ragge
1.1
705
706         ifs<0 && ty!=INT && ty!=CHAR && ty!=SHORT && ty!=UNSIGNED && ty!=UCHAR && ty!=USHORT 
707                                         ){
708                 returnfldalty ) );
709                 }
710
711         fori=0i<=(SZINT-BTSHIFT-1); i+=TSHIFT ){
712                 switch( (ty>>i)&TMASK ){
713
714                 case FTN:
715                         uerror"can't assign to function" );
716                         returnALCHAR );
717                 case PTR:
718                         returnALPOINT );
719                 case ARY:
720                         continue;
721                 case 0:
722                         break;
723                         }
724                 }
725
726         switchBTYPE(ty) ){
727
728         case UNIONTY:
729         case ENUMTY:
730         case STRTY:
731                 return( (unsigned intdimtabs+2 ] );
732         case CHAR:
733         case UCHAR:
ragge
1.9
734                 return (ALCHAR);
ragge
1.1
735         case FLOAT:
ragge
1.9
736                 return (ALFLOAT);
ragge
1.1
737         case DOUBLE:
ragge
1.9
738                 return (ALDOUBLE);
739         case LONGLONG:
740         case ULONGLONG:
741                 return (ALLONGLONG);
ragge
1.1
742         case LONG:
743         case ULONG:
ragge
1.9
744                 return (ALLONG);
ragge
1.1
745         case SHORT:
746         case USHORT:
ragge
1.9
747                 return (ALSHORT);
ragge
1.1
748         default:
ragge
1.9
749                 return (ALINT);
ragge
1.1
750                 }
751         }
752
753 OFFSZ
754 tsizetyds )  TWORD ty; {
755         /* compute the size associated with type ty,
756             dimoff d, and sizoff s */
757         /* BETTER NOT BE CALLED WHEN t, d, and s REFER TO A BIT FIELD... */
758
759         int i;
760         OFFSZ mult;
761
762         mult = 1;
763
764         fori=0i<=(SZINT-BTSHIFT-1); i+=TSHIFT ){
765                 switch( (ty>>i)&TMASK ){
766
767                 case FTN:
768                         /* cerror( "compiler takes size of function"); */
769                         uerror"can't take size of function" );
770                         returnSZCHAR );
771                 case PTR:
772                         returnSZPOINT * mult );
773                 case ARY:
774                         mult *= (unsigned intdimtabd++ ];
775                         continue;
776                 case 0:
777                         break;
778
779                         }
780                 }
781
782         ifdimtab[s]==0 ) {
783                 ifty == STRTY )
784                         uerror"undefined structure" );
785                 else
786                         uerror"unknown size");
787                 returnSZINT );
788                 }
789         return( (unsigned intdimtabs ] * mult );
790         }
791
ragge
1.2
792 /*
793  * force inoff to have the value n
794  */
795 void
796 inforce(OFFSZ n)
797 {
ragge
1.1
798         /* inoff is updated to have the value n */
799         OFFSZ wb;
ragge
1.2
800         int rest;
ragge
1.1
801         /* rest is used to do a lot of conversion to ints... */
802
803         ifinoff == n ) return;
804         ifinoff > n ) {
805                 cerror"initialization alignment error");
806                 }
807
808         wb = inoff;
809         SETOFFwbSZINT );
810
811         /* wb now has the next higher word boundary */
812
813         ifwb >= n ){ /* in the same word */
814                 rest = n - inoff;
815                 vfdzerorest );
816                 return;
817                 }
818
819         /* otherwise, extend inoff to be word aligned */
820
821         rest = wb - inoff;
822         vfdzerorest );
823
824         /* now, skip full words until near to n */
825
826         rest = (n-inoff)/SZINT;
827         zecoderest );
828
829         /* now, the remainder of the last word */
830
831         rest = n-inoff;
832         vfdzerorest );
833         ifinoff != n ) cerror"inoff error");
834
835         }
836
ragge
1.2
837 /*
838  * make inoff have the offset the next alignment of n
839  */
840 void
841 vfdalign(int n)
842 {
ragge
1.1
843         OFFSZ m;
844
845         m = inoff;
846         SETOFFmn );
847         inforcem );
ragge
1.2
848 }
ragge
1.1
849
850
851 int idebug = 0;
852
853 int ibseen = 0;  /* the number of } constructions which have been filled */
854
855 int ifull = 0/* 1 if all initializers have been seen */
856
857 int iclass;  /* storage class of thing being initialized */
858
859 int ilocctr = 0;  /* location counter for current initialization */
860
ragge
1.2
861 /*
862  * beginning of initilization; set location ctr and set type
863  */
864 void
865 beginit(int curid)
866 {
867         struct symtab *p;
ragge
1.1
868
869 # ifndef BUG1
870         ifidebug >= 3 ) printf"beginit(), curid = %d\n"curid );
871 # endif
872
873         p = &stab[curid];
874
875         iclass = p->sclass;
876         ifcurclass == EXTERN || curclass == FORTRAN ) iclass = EXTERN;
877         switchiclass ){
878
879         case UNAME:
880         case EXTERN:
881                 return;
882         case AUTO:
883         case REGISTER:
884                 break;
885         case EXTDEF:
886         case STATIC:
887                 ilocctr = ISARY(p->stype)?ADATA:DATA;
888                 ifnerrors == 0 ){
889                         (voidlocctrilocctr );
890                         defaligntalignp->stypep->sizoff ) );
891                         defnamp );
892                 }
ragge
1.2
893         }
ragge
1.1
894
895         inoff = 0;
896         ibseen = 0;
897         ifull = 0;
898
899         pstk = 0;
900
901         instkcuridp->stypep->dimoffp->sizoffinoff );
902
ragge
1.2
903 }
ragge
1.1
904
ragge
1.2
905 /*
906  * make a new entry on the parameter stack to initialize id
907  */
908 void
909 instk(int idTWORD tint dint sOFFSZ off)
910 {
911         struct symtab *p;
ragge
1.1
912
ragge
1.2
913         for (;;) {
ragge
1.1
914 # ifndef BUG1
ragge
1.2
915                 if (idebug)
ragge
1.11
916                         printf("instk((%d, %o,%d,%d, %lld)\n",
917                             idtds, (long long)off);
ragge
1.1
918 # endif
919
920                 /* save information on the stack */
921
922                 if( !pstk ) pstk = instack;
923                 else ++pstk;
924
925                 pstk->in_fl = 0;        /* { flag */
926                 pstk->in_id =  id ;
927                 pstk->in_t =  t ;
928                 pstk->in_d =  d ;
929                 pstk->in_s =  s ;
930                 pstk->in_n = 0;  /* number seen */
931                 pstk->in_x =  t==STRTY ?dimtab[s+1] : 0 ;
932                 pstk->in_off =  off;   /* offset at the beginning of this element */
933                 /* if t is an array, DECREF(t) can't be a field */
934                 /* INS_sz has size of array elements, and -size for fields */
935                 ifISARY(t) ){
936                         pstk->in_sz = tsizeDECREF(t), d+1s );
937                         }
938                 else ifstab[id].sclass & FIELD ){
939                         pstk->in_sz = - ( stab[id].sclass & FLDSIZ );
940                         }
941                 else {
942                         pstk->in_sz = 0;
943                         }
944
945                 if( (iclass==AUTO || iclass == REGISTER ) &&
946                         (ISARY(t) || t==STRTY) ) uerror"no automatic aggregate initialization" );
947
948                 /* now, if this is not a scalar, put on another element */
949
950                 ifISARY(t) ){
951                         t = DECREF(t);
952                         ++d;
953                         continue;
954                         }
955                 else ift == STRTY ){
956                         ifdimtab[pstk->in_s] == 0 ){
957                                 uerror"can't initialize undefined structure" );
958                                 iclass = -1;
959                                 return;
960                                 }
961                         id = dimtab[pstk->in_x];
962                         p = &stab[id];
963                         ifp->sclass != MOS && !(p->sclass&FIELD) ) cerror"insane structure member list" );
964                         t = p->stype;
965                         d = p->dimoff;
966                         s = p->sizoff;
967                         off += p->offset;
968                         continue;
969                         }
970                 else return;
971                 }
972         }
973
974 NODE *
975 getstr(){ /* decide if the string is external or an initializer, and get the contents accordingly */
976
ragge
1.2
977         int ltemp;
978         NODE *p;
ragge
1.1
979
980         if( (iclass==EXTDEF||iclass==STATIC) && (pstk->in_t == CHAR || pstk->in_t == UCHAR) &&
981                         pstk!=instack && ISARYpstk[-1].in_t ) ){
982                 /* treat "abc" as { 'a', 'b', 'c', 0 } */
983                 strflg = 1;
984                 ilbrace();  /* simulate { */
985                 inforcepstk->in_off );
986                 /* if the array is inflexible (not top level), pass in the size and
987                         be prepared to throw away unwanted initializers */
988                 lxstr((pstk-1)!=instack?dimtab[(pstk-1)->in_d]:0);  /* get the contents */
989                 irbrace();  /* simulate } */
990                 returnNIL );
991                 }
992         else { /* make a label, and get the contents and stash them away */
993                 ificlass != SNULL ){ /* initializing */
994                         /* fill out previous word, to permit pointer */
995                         vfdalignALPOINT );
996                         }
997                 temp = locctrblevel==0?ISTRNG:STRNG ); /* set up location counter */
998                 deflabl = getlab() );
999                 strflg = 0;
1000                 lxstr(0); /* get the contents */
1001                 (voidlocctrblevel==0?ilocctr:temp );
1002                 p = buildtreeSTRINGNILNIL );
1003                 p->tn.rval = -l;
1004                 return(p);
1005                 }
1006         }
1007
ragge
1.2
1008 /*
1009  * simulate byte v appearing in a list of integer values
1010  */
1011 void
1012 putbyte(int v)
1013 {
1014         NODE *p;
ragge
1.1
1015         p = bcon(v);
1016         incodepSZCHAR );
1017         tfreep );
1018         gotscal();
ragge
1.2
1019 }
ragge
1.1
1020
ragge
1.2
1021 void
1022 endinit(void)
1023 {
1024         TWORD t;
1025         int dsnd1;
ragge
1.1
1026
1027 # ifndef BUG1
ragge
1.2
1028         if (idebug)
ragge
1.11
1029                 printf("endinit(), inoff = %lld\n", (long long)inoff);
ragge
1.1
1030 # endif
1031
1032         switchiclass ){
1033
1034         case EXTERN:
1035         case AUTO:
1036         case REGISTER:
1037         case -1:
1038                 return;
1039                 }
1040
1041         pstk = instack;
1042
1043         t = pstk->in_t;
1044         d = pstk->in_d;
1045         s = pstk->in_s;
1046         n = pstk->in_n;
1047
1048         ifISARY(t) ){
1049                 d1 = dimtab[d];
1050
1051                 vfdalignpstk->in_sz );  /* fill out part of the last element, if needed */
1052                 n = inoff/pstk->in_sz;  /* real number of initializers */
1053                 ifd1 >= n ){
1054                         /* once again, t is an array, so no fields */
1055                         inforcetsizetds ) );
1056                         n = d1;
1057                         }
1058                 ifd1!=0 && d1!=n ) uerror"too many initializers");
1059                 ifn==0 ) werror"empty array declaration");
1060                 dimtab[d] = n;
ragge
1.2
1061                 if (d1==0) {
1062                         FIXDEF(&stab[pstk->in_id]);
ragge
1.1
1063                 }
ragge