Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030622211330

Diff

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