Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030616222950

Diff

Diff from 1.56 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
ragge
1.25
7 # include <stdlib.h>
8
ragge
1.1
9 unsigned int offsz;
10
ragge
1.33
11 struct symtab *spname;
12 struct symtab *cftnsp;
ragge
1.55
13 static int strunem;     /* currently parsed member type */
ragge
1.1
14
ragge
1.46
15 struct params;
16
ragge
1.43
17 /*
ragge
1.55
18  * Argument list member info when storing prototypes.
19  */
20 union arglist {
21         TWORD type;
22         union dimfun *df;
23         struct suedef *sue;
24 };
25
26 /*
ragge
1.43
27  * Linked list stack while reading in structs.
28  */
29 struct rstack {
30         struct  rstack *rnext;
31         int     rinstruct;
32         int     rclass;
33         int     rstrucoff;
ragge
1.46
34         struct  params *rlparam;
ragge
1.43
35         struct  symtab *rsym;
36 };
37
ragge
1.45
38 /*
ragge
1.47
39  * Linked list for parameter (and struct elements) declaration.
ragge
1.45
40  */
41 static struct params {
ragge
1.46
42         struct params *next, *prev;
ragge
1.45
43         struct symtab *sym;
ragge
1.47
44 } *lpole, *lparam;
ragge
1.45
45 static int nparams;
46
47 /*
48  * Struct used in array initialisation.
49  */
50 static struct instk {
ragge
1.44
51         struct  instk *in_prev/* linked list */
52         int     in_sz;          /* size of array element */
53         struct  symtab **in_xp;  /* member in structure initializations */
54         int     in_n;           /* number of initializations seen */
55         struct  suedef *in_sue;
ragge
1.52
56         union   dimfun *in_df;  /* dimoff/protos */
ragge
1.44
57         TWORD   in_t;           /* type */
58         struct  symtab *in_sym/* stab index */
59         int     in_fl;  /* flag which says if this level is controlled by {} */
60         OFFSZ   in_off;         /* offset of the beginning of this level */
61 } *pstk;
ragge
1.1
62
ragge
1.2
63 /* defines used for getting things off of the initialization stack */
ragge
1.1
64
ragge
1.30
65 static NODE *arrstk[10];
66 static int arrstkp;
ragge
1.1
67
ragge
1.2
68 void fixtype(NODE *pint class);
69 int fixclass(int classTWORD type);
70 int falloc(struct symtab *pint wint newNODE *pty);
71 int oalloc(struct symtab *pint *poff);
ragge
1.30
72 static void dynalloc(struct symtab *pint *poff);
ragge
1.2
73 void inforce(OFFSZ n);
74 void vfdalign(int n);
ragge
1.52
75 static void instk(struct symtab *pTWORD tunion dimfun *d,
76     struct suedef *, OFFSZ off);
ragge
1.2
77 void gotscal(void);
ragge
1.46
78 static void ssave(struct symtab *);
ragge
1.1
79
80 int ddebug = 0;
81
ragge
1.2
82 void
83 defid(NODE *qint class)
84 {
85         struct symtab *p;
86         TWORD type;
ragge
1.1
87         TWORD stp;
ragge
1.2
88         int scl;
ragge
1.52
89         union dimfun *dsym, *ddef;
ragge
1.1
90         int slevtemp;
91
ragge
1.32
92         if (q == NIL)
93                 return;  /* an error was detected */
ragge
1.1
94
ragge
1.32
95         if (q < node || q >= &node[TREESZ])
96                 cerror("defid call");
ragge
1.1
97
ragge
1.33
98         p = q->n_sp;
ragge
1.1
99
ragge
1.54
100 #ifdef PCC_DEBUG
ragge
1.4
101         if (ddebug) {
ragge
1.33
102                 printf("defid(%s (%p), "p->snamep);
ragge
1.31
103                 tprint(q->n_type);
ragge
1.50
104                 printf(", %s, (%p,%p)), level %d\n"scnames(class),
ragge
1.52
105                     q->n_dfq->n_sueblevel);
ragge
1.4
106         }
ragge
1.54
107 #endif
ragge
1.1
108
ragge
1.33
109         fixtype(qclass);
ragge
1.1
110
ragge
1.31
111         type = q->n_type;
ragge
1.33
112         class = fixclass(classtype);
ragge
1.1
113
114         stp = p->stype;
115         slev = p->slevel;
116
ragge
1.54
117 #ifdef PCC_DEBUG
ragge
1.4
118         if (ddebug) {
119                 printf("        modified to ");
120                 tprint(type);
121                 printf(", %s\n"scnames(class));
122                 printf("        previous def'n: ");
123                 tprint(stp);
ragge
1.50
124                 printf(", %s, (%p,%p)), level %d\n",
ragge
1.52
125                     scnames(p->sclass), p->sdfp->ssueslev);
ragge
1.4
126         }
ragge
1.54
127 #endif
ragge
1.1
128
ragge
1.56
129         if (blevel == 1) {
ragge
1.33
130                 switch (class) {
ragge
1.1
131                 default:
ragge
1.4
132                         if (!(class&FIELD))
ragge
1.56
133                                 uerror("declared argument %s missing",
ragge
1.4
134                                     p->sname );
ragge
1.1
135                 case MOS:
136                 case STNAME:
137                 case MOU:
138                 case UNAME:
139                 case MOE:
140                 case ENAME:
141                 case TYPEDEF:
142                         ;
ragge
1.56
143                 }
ragge
1.4
144         }
ragge
1.56
145
146         if (stp == UNDEF)
147                 goto enter/* New symbol */
ragge
1.1
148
ragge
1.33
149         if (type != stp)
150                 goto mismatch;
151
152         if (blevel > slev && (class == AUTO || class == REGISTER))
ragge
1.1
153                 /* new scope */
154                 goto mismatch;
155
ragge
1.55
156         /*
157          * test (and possibly adjust) dimensions.
158          * also check that prototypes are correct.
159          */
ragge
1.52
160         dsym = p->sdf;
161         ddef = q->n_df;
ragge
1.55
162         for (temp = typetemp & TMASKtemp = DECREF(temp)) {
163                 if (ISARY(temp)) {
ragge
1.52
164                         if (dsym->ddim == 0) {
165                                 dsym->ddim = ddef->ddim;
166                         } else if (ddef->ddim != 0 && dsym->ddim!=ddef->ddim) {
ragge
1.1
167                                 goto mismatch;
ragge
1.50
168                         }
ragge
1.1
169                         ++dsym;
170                         ++ddef;
ragge
1.55
171                 } else if (ISFTN(temp)) {
172                         union arglist *usym = dsym->dfun;
173                         union arglist *udef = ddef->dfun;
174                         while (usym->type != TNULL) {
175                                 TWORD t2 = usym->type;
176                                 if (usym->type != udef->type)
177                                         goto mismatch;
178                                 while (t2 > BTMASK) {
179                                         /* XXX no multilevel checks */
180                                         if (ISFTN(t2))
181                                                 usym++, udef++;
182                                         t2 = DECREF(t2);
183                                 }
184                                 usym++, udef++;
185                         }
186                         if (usym->type != udef->type)
187                                 goto mismatch;
188                         dsym++, ddef++;
ragge
1.1
189                 }
ragge
1.50
190         }
ragge
1.1
191
192         /* check that redeclarations are to the same structure */
ragge
1.33
193         if ((temp == STRTY || temp == UNIONTY || temp == ENUMTY) &&
ragge
1.43
194             p->ssue != q->n_sue &&
ragge
1.33
195             class != STNAME && class != UNAME && class != ENAME) {
ragge
1.1
196                 goto mismatch;
ragge
1.33
197         }
ragge
1.1
198
ragge
1.33
199         scl = p->sclass;
ragge
1.1
200
ragge
1.54
201 #ifdef PCC_DEBUG
ragge
1.33
202         if (ddebug)
203                 printf("        previous class: %s\n"scnames(scl));
ragge
1.54
204 #endif
ragge
1.1
205
ragge
1.33
206         if (class&FIELD) {
ragge
1.1
207                 /* redefinition */
ragge
1.33
208                 if (!falloc(pclass&FLDSIZ1NIL)) {
ragge
1.1
209                         /* successful allocation */
ragge
1.46
210                         ssave(p);
ragge
1.1
211                         return;
ragge
1.33
212                 }
ragge
1.1
213                 /* blew it: resume at end of switch... */
ragge
1.33
214         } else switch(class) {
ragge
1.1
215
216         case EXTERN:
217                 switchscl ){
218                 case STATIC:
219                 case USTATIC:
220                         ifslev==0 ) return;
221                         break;
222                 case EXTDEF:
223                 case EXTERN:
224                 case FORTRAN:
225                 case UFORTRAN:
226                         return;
227                         }
228                 break;
229
230         case STATIC:
ragge
1.33
231                 if (scl==USTATIC || (scl==EXTERN && blevel==0)) {
ragge
1.1
232                         p->sclass = STATIC;
ragge
1.33
233                         if (ISFTN(type))
234                                 cftnsp = p;
ragge
1.1
235                         return;
ragge
1.33
236                 }
ragge
1.1
237                 break;
238
239         case USTATIC:
ragge
1.33
240                 if (scl==STATIC || scl==USTATIC)
241                         return;
ragge
1.1
242                 break;
243
244         case TYPEDEF:
ragge
1.33
245                 if (scl == class)
246                         return;
ragge
1.1
247                 break;
248
249         case UFORTRAN:
ragge
1.33
250                 if (scl == UFORTRAN || scl == FORTRAN)
251                         return;
ragge
1.1
252                 break;
253
254         case FORTRAN:
ragge
1.33
255                 if (scl == UFORTRAN) {
ragge
1.1
256                         p->sclass = FORTRAN;
ragge
1.33
257                         if (ISFTN(type))
258                                 cftnsp = p;
ragge
1.1
259                         return;
ragge
1.33
260                 }
ragge
1.1
261                 break;
262
263         case MOU:
264         case MOS:
ragge
1.33
265                 if (scl == class) {
266                         if (oalloc(p, &strucoff))
267                                 break;
268                         if (class == MOU)
269                                 strucoff = 0;
ragge
1.46
270                         ssave(p);
ragge
1.1
271                         return;
ragge
1.33
272                 }
ragge
1.1
273                 break;
274
ragge
1.54
275         case MOE:       /* XXX 4.4 */
ragge
1.1
276                 break;
277
278         case EXTDEF:
ragge
1.10
279                 switch (scl) {
280                 case EXTERN:
ragge
1.1
281                         p->sclass = EXTDEF;
ragge
1.10
282                         if (ISFTN(type))
ragge
1.33
283                                 cftnsp = p;
ragge
1.1
284                         return;
ragge
1.10
285                 case USTATIC:
286                         p->sclass = STATIC;
287                         if (ISFTN(type))
ragge
1.33
288                                 cftnsp = p;
ragge
1.10
289                         return;
290                 }
ragge
1.1
291                 break;
292
293         case STNAME:
294         case UNAME:
295         case ENAME:
ragge
1.33
296                 if (scl != class)
297                         break;
ragge
1.43
298                 if (p->ssue->suesize == 0)
ragge
1.33
299                         return;  /* previous entry just a mention */
ragge
1.1
300                 break;
301
302         case AUTO:
303         case REGISTER:
304                 ;  /* mismatch.. */
ragge
1.33
305         }
ragge
1.1
306
307         mismatch:
308
ragge
1.55
309         /*
310          * Only allowed for automatic variables.
311          */
312         if (blevel == slev || class == EXTERN || class == FORTRAN ||
313             class == UFORTRAN) {
314                 uerror("redeclaration of %s"p->sname);
315                 if (class == EXTDEF && ISFTN(type))
316                         cftnsp = p;
317                 return;
ragge
1.24
318         }
ragge
1.55
319         q->n_sp = p = hide(p);
ragge
1.1
320
321         enter:  /* make a new entry */
322
ragge
1.54
323 #ifdef PCC_DEBUG
ragge
1.33
324         if(ddebug)
325                 printf("        new entry made\n");
ragge
1.54
326 #endif
ragge
1.1
327         p->stype = type;
328         p->sclass = class;
329         p->slevel = blevel;
ragge
1.33
330         p->soffset = NOOFFSET;
ragge
1.1
331         p->suse = lineno;
ragge
1.43
332         if (class == STNAME || class == UNAME || class == ENAME) {
333                 p->ssue = permalloc(sizeof(struct suedef));
334                 p->ssue->suesize = 0;
335                 p->ssue->suelem = NULL
336                 p->ssue->suealign = ALSTRUCT;
337         } else {
338                 switch (BTYPE(type)) {
ragge
1.1
339                 case STRTY:
340                 case UNIONTY:
341                 case ENUMTY:
ragge
1.43
342                         p->ssue = q->n_sue;
ragge
1.1
343                         break;
344                 default:
ragge
1.45
345                         p->ssue = MKSUE(BTYPE(type));
ragge
1.1
346                 }
ragge
1.43
347         }
ragge
1.1
348
349         /* copy dimensions */
350
ragge
1.52
351         p->sdf = q->n_df;
ragge
1.1
352
353         /* allocate offsets */
ragge
1.33
354         if (class&FIELD) {
355                 (voidfalloc(pclass&FLDSIZ0NIL);  /* new entry */
ragge
1.46
356                 ssave(p);
ragge
1.33
357         } else switch (class) {
ragge
1.1
358
359         case AUTO:
ragge
1.30
360                 if (arrstkp)
361                         dynalloc(p, &autooff);
362                 else
ragge
1.54
363                         oalloc(p, &autooff);
ragge
1.1
364                 break;
365         case STATIC:
366         case EXTDEF:
ragge
1.33
367                 p->soffset = getlab();
368                 if (class == STATIC && blevel > 0)
369                         p->sflags |= SLABEL;
370                 if (ISFTN(type))
371                         cftnsp = p;
ragge
1.1
372                 break;
373
374         case EXTERN:
375         case UFORTRAN:
376         case FORTRAN:
ragge
1.33
377                 p->soffset = getlab();
ragge
1.1
378                 p->slevel = 0;
379                 break;
380         case MOU:
381         case MOS:
ragge
1.54
382                 oalloc(p, &strucoff);
383                 if (class == MOU)
384                         strucoff = 0;
ragge
1.46
385                 ssave(p);
ragge
1.1
386                 break;
387
388         case MOE:
ragge
1.33
389                 p->soffset = strucoff++;
ragge
1.46
390                 ssave(p);
ragge
1.1
391                 break;
392         case REGISTER:
ragge
1.33
393                 p->soffset = regvar--;
394                 if (blevel == 1)
395                         p->sflags |= SSET;
396                 if (regvar < minrvar)
397                         minrvar = regvar;
ragge
1.1
398                 break;
ragge
1.33
399         }
ragge
1.1
400
401         /* user-supplied routine to fix up new definitions */
402         FIXDEF(p);
403
ragge
1.54
404 #ifdef PCC_DEBUG
ragge
1.33
405         if (ddebug)
ragge
1.52
406                 printf"       sdf, ssue, offset: %p, %p, %d\n",
407                     p->sdfp->ssuep->soffset);
ragge
1.54
408 #endif
ragge
1.1
409
ragge
1.33
410 }
ragge
1.1
411
ragge
1.2
412 void
ragge
1.46
413 ssave(struct symtab *sym)
ragge
1.2
414 {
ragge
1.46
415         struct params *p;
416
417         p = tmpalloc(sizeof(struct params));
418         p->next = NULL;
419         p->sym = sym;
420
421         if (lparam == NULL) {
422                 p->prev = (struct params *)&lpole;
423                 lpole = p;
424         } else {
425                 lparam->next = p;
426                 p->prev = lparam;
ragge
1.2
427         }
ragge
1.46
428         lparam = p;
ragge
1.2
429 }
ragge
1.1
430
ragge
1.2
431 /*
432  * end of function
433  */
434 void
435 ftnend()
436 {
ragge
1.51
437         extern struct savbc *savbc;
438
ragge
1.33
439         if (retlab != NOLAB && nerrors == 0/* inside a real function */
ragge
1.1
440                 efcode();
ragge
1.33
441
ragge
1.1
442         checkst(0);
443         retstat = 0;
444         tcheck();
445         brklab = contlab = retlab = NOLAB;
446         flostat = 0;
ragge
1.51
447         if (nerrors == 0) {
448                 if (savbc != NULL)
449                         cerror("bcsave error");
ragge
1.46
450                 if (lparam != NULL)
451                         cerror("parameter reset error");
ragge
1.1
452                 ifswx != 0 ) cerror"switch error");
ragge
1.46
453         }
ragge
1.51
454         savbc = NULL;
ragge
1.46
455         lparam = NULL;
ragge
1.1
456         autooff = AUTOINIT;
457         minrvar = regvar = MAXRVAR;
458         reached = 1;
459         swx = 0;
460         swp = swtab;
ragge
1.37
461         tmpfree(); /* Release memory resources */
ragge
1.54
462         locctr(DATA);
ragge
1.2
463 }
ragge
1.1
464
ragge
1.2
465 void
466 dclargs()
467 {
ragge
1.45
468         struct params *a;
469         struct symtab *p, **parr;
470         int i;
471
ragge
1.56
472         blevel = 1;
ragge
1.1
473         argoff = ARGINIT;
ragge
1.54
474 #ifdef PCC_DEBUG
ragge
1.12
475         if (ddebug > 2)
476                 printf("dclargs()\n");
ragge
1.54
477 #endif
ragge
1.45
478
ragge
1.56
479         /*
480          * Generate a list for bfcode().
481          * Parameters were pushed in reverse order.
482          */
ragge
1.45
483         parr = tmpalloc(sizeof(struct symtab *) * nparams);
ragge
1.56
484
ragge
1.47
485         for (a = lparami = 0a != NULL && a != (struct params *)&lpole;
486             a = a->prev) {
ragge
1.56
487
488                 /*
489                  * Enter function args into the symbol table.
490                  */
491                 p = lookup(a->sym->sname0);
492                 if (p->stype != UNDEF)
493                         p = hide(p);
494
495                 p->stype = a->sym->stype;
496                 p->soffset = NOOFFSET;
497                 p->sclass = PARAM;
498                 p->sdf = a->sym->sdf;
499                 p->ssue = a->sym->ssue;
500
501                 parr[i++] = p;
ragge
1.54
502 #ifdef PCC_DEBUG
503                 if (ddebug > 2) {       /* XXX 4.4 */
ragge
1.45
504                         printf("\t%s (%p) ",p->snamep);
ragge
1.1
505                         tprint(p->stype);
506                         printf("\n");
ragge
1.12
507                 }
ragge
1.54
508 #endif
ragge
1.56
509                 /* always set aside space, even for register arguments */
ragge
1.12
510                 oalloc(p, &argoff);
511         }
ragge
1.1
512         cendarg();
ragge
1.54
513         locctr(PROG);
ragge
1.1
514         defalign(ALINT);
515         ftnno = getlab();
ragge
1.45
516         bfcode(parrnparams);
ragge
1.47
517         lparam = NULL;
ragge
1.45
518         nparams = 0;
ragge
1.2
519 }
ragge
1.1
520
ragge
1.21
521 /*
522  * reference to a structure or union, with no definition
523  */
ragge
1.1
524 NODE *
ragge
1.33
525 rstruct(char *tagint soru)
ragge
1.21
526 {
ragge
1.2
527         struct symtab *p;
528         NODE *q;
ragge
1.32
529
ragge
1.40
530         p = (struct symtab *)lookup(tagSTAGNAME);
ragge
1.21
531         switch (p->stype) {
ragge
1.1
532
533         case UNDEF:
534         def:
ragge
1.21
535                 q = block(FREENILNIL000);
ragge
1.33
536                 q->n_sp = p;
ragge
1.31
537                 q->n_type = (soru&INSTRUCT) ? STRTY :
ragge
1.21
538                     ((soru&INUNION) ? UNIONTY : ENUMTY);
539                 defid(q, (soru&INSTRUCT) ? STNAME :
540                     ((soru&INUNION) ? UNAME : ENAME));
ragge
1.1
541                 break;
542
543         case STRTY:
ragge
1.21
544                 if (soru & INSTRUCT)
545                         break;
ragge
1.1
546                 goto def;
547
548         case UNIONTY:
ragge
1.21
549                 if (soru & INUNION)
550                         break;
ragge
1.1
551                 goto def;
552
553         case ENUMTY:
ragge
1.21
554                 if (!(soru&(INUNION|INSTRUCT)))
555                         break;
ragge
1.1
556                 goto def;
557
ragge
1.21
558         }
ragge
1.43
559         q = mkty(p->stype0p->ssue);
560         q->n_sue = p->ssue;
561         return q;
ragge
1.21
562 }
ragge
1.1
563
ragge
1.2
564 void
ragge
1.33
565 moedef(char *name)
ragge
1.2
566 {
567         NODE *q;
ragge
1.1
568
ragge
1.33
569         q = block(FREENILNILMOETY00);
570         q->n_sp = lookup(name0);
571         defid(qMOE);
ragge
1.2
572 }
ragge
1.1
573
ragge
1.2
574 /*
575  * begining of structure or union declaration
576  */
ragge
1.43
577 struct rstack *
ragge
1.33
578 bstruct(char *nameint soru)
ragge
1.2
579 {
ragge
1.43
580         struct rstack *r;
ragge
1.33
581         struct symtab *s;
ragge
1.2
582         NODE *q;
ragge
1.1
583
ragge
1.33
584         if (name != NULL)
ragge
1.40
585                 s = lookup(nameSTAGNAME);
ragge
1.33
586         else
587                 s = NULL;
588
ragge
1.43
589         r = tmpalloc(sizeof(struct rstack));
590         r->rinstruct = instruct;
591         r->rclass = strunem;
592         r->rstrucoff = strucoff;
593
ragge
1.1
594         strucoff = 0;
595         instruct = soru;
ragge
1.21
596         q = block(FREENILNIL000);
ragge
1.33
597         q->n_sp = s;
ragge
1.21
598         if (instruct==INSTRUCT) {
ragge
1.18
599                 strunem = MOS;
ragge
1.31
600                 q->n_type = STRTY;
ragge
1.33
601                 if (s != NULL)
ragge
1.21
602                         defid(qSTNAME);
603         } else if(instruct == INUNION) {
ragge
1.18
604                 strunem = MOU;
ragge
1.31
605                 q->n_type = UNIONTY;
ragge
1.33
606                 if (s != NULL)
ragge
1.21
607                         defid(qUNAME);
608         } else { /* enum */
ragge
1.18
609                 strunem = MOE;
ragge
1.31
610                 q->n_type = ENUMTY;
ragge
1.33
611                 if (s != NULL)
ragge
1.21
612                         defid(qENAME);
613         }
ragge
1.43
614         r->rsym = q->n_sp;
ragge
1.46
615         r->rlparam = lparam;
ragge
1.33
616
ragge
1.43
617         return r;
ragge
1.2
618 }
ragge
1.1
619
ragge
1.18
620 /*
621  * Called after a struct is declared to restore the environment.
622  */
ragge
1.1
623 NODE *
ragge
1.43
624 dclstruct(struct rstack *r)
ragge
1.2
625 {
ragge
1.43
626         NODE *n;
ragge
1.50
627         struct params *l, *m;
ragge
1.43
628         struct suedef *sue;
ragge
1.2
629         struct symtab *p;
ragge
1.46
630         int alsasz;
ragge
1.2
631         TWORD temp;
ragge
1.50
632         int ihighlow;
ragge
1.1
633
ragge
1.43
634         if (r->rsym == NULL) {
635                 sue = permalloc(sizeof(struct suedef));
636                 sue->suesize = 0;
637                 sue->suealign = ALSTRUCT;
ragge
1.18
638         } else
ragge
1.43
639                 sue = r->rsym->ssue;
ragge
1.1
640
ragge
1.43
641 #ifdef PCC_DEBUG
642         if (ddebug)
ragge
1.46
643                 printf("dclstruct(%s)\n"r->rsym ? r->rsym->sname : "??");
ragge
1.43
644 #endif
ragge
1.1
645         temp = (instruct&INSTRUCT)?STRTY:((instruct&INUNION)?UNIONTY:ENUMTY);
ragge
1.43
646         instruct = r->rinstruct;
647         strunem = r->rclass;
ragge
1.1
648         al = ALSTRUCT;
649
650         high = low = 0;
651
ragge
1.46
652         if ((l = r->rlparam) == NULL)
653                 l = lpole;
654         else
655                 l = l->next;
656
ragge
1.50
657         /* memory for the element array must be allocated first */
658         for (m = li = 1m != NULLm = m->next)
659                 i++;
660         sue->suelem = permalloc(sizeof(struct symtab *) * i);
661
662         for (i = 0l != NULLl = l->next) {
663                 sue->suelem[i++] = p = l->sym;
664
ragge
1.46
665                 if (p == NULL)
ragge
1.43
666                         cerror("gummy structure member");
ragge
1.46
667                 if (temp == ENUMTY) {
668                         if (p->soffset < low)
669                                 low = p->soffset;
670                         if (p->soffset > high)
671                                 high = p->soffset;
ragge
1.43
672                         p->ssue = sue;
ragge
1.1
673                         continue;
ragge
1.46
674                 }
ragge
1.43
675                 sa = talign(p->stypep->ssue);
ragge
1.21
676                 if (p->sclass & FIELD) {
ragge
1.1
677                         sz = p->sclass&FLDSIZ;
ragge
1.21
678                 } else {
ragge
1.52
679                         sz = tsize(p->stypep->sdfp->ssue);
ragge
1.1
680                 }
ragge
1.21
681                 if (sz > strucoff)
682                         strucoff = sz;  /* for use with unions */
683                 /*
684                  * set al, the alignment, to the lcm of the alignments
685                  * of the members.
686                  */
687                 SETOFF(alsa);
688         }
ragge
1.50
689         sue->suelem[i] = NULL;
ragge
1.46
690         SETOFF(strucoffal);
ragge
1.1
691
ragge
1.43
692         if (temp == ENUMTY) {
ragge
1.2
693                 TWORD ty;
ragge
1.1
694
ragge
1.43
695 #ifdef ENUMSIZE
ragge
1.1
696                 ty = ENUMSIZE(high,low);
ragge
1.43
697 #else
698                 if ((char)high == high && (char)low == low)
699                         ty = ctype(CHAR);
700                 else if ((short)high == high && (short)low == low)
701                         ty = ctype(SHORT);
702                 else
703                         ty = ctype(INT);
ragge
1.1
704 #endif
ragge
1.43
705                 strucoff = tsize(ty0MKSUE(ty));
706                 sue->suealign = al = talign(tyMKSUE(ty));
ragge
1.21
707         }
ragge
1.1
708
ragge
1.43
709         sue->suesize = strucoff;
710         sue->suealign = al;
711
ragge
1.46
712 #ifdef PCC_DEBUG
ragge
1.21
713         if (ddebug>1) {
ragge
1.50
714                 int i;
715
ragge
1.46
716                 printf("\tsize %d align %d elem %p\n",
717                     sue->suesizesue->suealignsue->suelem);
ragge
1.50
718                 for (i = 0sue->suelem[i] != NULL; ++i) {
719                         printf("\tmember %s(%p)\n",
720                             sue->suelem[i]->snamesue->suelem[i]);
ragge
1.1
721                 }
ragge
1.21
722         }
ragge
1.43
723 #endif
ragge
1.1
724
ragge
1.43
725         strucoff = r->rstrucoff;
ragge
1.46
726         if ((lparam = r->rlparam) != NULL)
727                 lparam->next = NULL;
728         n = mkty(temp0sue);
ragge
1.43
729         return n;
ragge
1.21
730 }
ragge
1.1
731
ragge
1.2
732 /*
733  * error printing routine in parser
734  */
735 void yyerror(char *s);
736 void
737 yyerror(char *s)
738 {
739         uerror(s);
740 }
741
742 void yyaccpt(void);
743 void
744 yyaccpt(void)
745 {
ragge
1.1
746         ftnend();
ragge
1.2
747 }
ragge
1.1
748
ragge
1.56
749 /*
750  * p is top of type list given to tymerge later.
751  * Find correct CALL node and declare parameters from there.
752  */
753 void
754 ftnarg(NODE *p)
ragge
1.2
755 {
ragge
1.56
756         NODE *q;
757         struct symtab *s;
ragge
1.1
758
ragge
1.56
759 #ifdef PCC_DEBUG
760         if (ddebug > 2)
761                 printf("ftnarg(%p)\n"p);
762 #endif
763         /*
764          * Enter argument into param stack.
765          * Do not declare parameters until later (in dclargs);
766          * the function must be declared first.
767          * put it on the param stack in reverse order, due to the
768          * nature of the stack it will be reclaimed correct.
769          */
770         for (; p->n_op != NAMEp = p->n_left) {
771                 if (p->n_op == (UNARY CALL) && p->n_left->n_op == NAME)
772                         return/* Nothing to enter */
773                 if (p->n_op == CALL && p->n_left->n_op == NAME)
774                         break;
775         }
776
777         p = p->n_right;
ragge
1.41
778
ragge
1.56
779         while (p->n_op == CM) {
780                 q = p->n_right;
781                 if (q->n_op != ELLIPSIS) {
782                         s = getsymtab((char *)q->n_spSTEMP);
783                         s->stype = q->n_type;
784                         s->sdf = q->n_df;
785                         s->ssue = q->n_sue;
786                         ssave(s);
787                         nparams++;
788 #ifdef PCC_DEBUG
789                         if (ddebug > 2)
790                                 printf("        saving sym %s (%p) from (%p)\n",
791                                     s->snamesq);
792 #endif
793                 }
794                 p = p->n_left;
ragge
1.33
795         }
ragge
1.56
796         s = getsymtab((char *)p->n_spSTEMP);
797         s->stype = p->n_type;
798         s->sdf = p->n_df;
799         s->ssue = p->n_sue;
ragge
1.47
800         ssave(s);
ragge
1.45
801         nparams++;
ragge
1.56
802 #ifdef PCC_DEBUG
803         if (ddebug > 2)
804                 printf("        saving sym %s (%p) from (%p)\n",
805                     s->snamesp);
806 #endif
ragge
1.2
807 }
ragge
1.1
808
ragge
1.2
809 /*
810  * compute the alignment of an object with type ty, sizeoff index s
811  */
812 int
ragge
1.43
813 talign(unsigned int tystruct suedef *sue)
ragge
1.2
814 {
815         int i;
ragge
1.1
816
ragge
1.43
817         if(sue == NULL && ty!=INT && ty!=CHAR && ty!=SHORT &&
818             ty!=UNSIGNED && ty!=UCHAR && ty!=USHORT) {
819                 return(fldal(ty));
820         }
ragge
1.1
821
822         fori=0i<=(SZINT-BTSHIFT-1); i+=TSHIFT ){
823                 switch( (ty>>i)&TMASK ){
824
825                 case FTN:
ragge
1.54
826                         cerror("compiler takes alignment of function");
ragge
1.1
827                 case PTR:
ragge
1.54
828                         return(ALPOINT);
ragge
1.1
829                 case ARY:
830                         continue;
831                 case 0:
832                         break;
833                         }
834                 }
835
836         switchBTYPE(ty) ){
837
838         case UNIONTY: