Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20021203220002

Diff

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