Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20020325225236

Diff

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