Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030703135351

Diff

Diff from 1.74 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; \
ragge
1.74
33         r = argcast(rtds); *p = *rnfree(r);
ragge
1.59
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.72
456                 send_passt(IP_EPILOGminrvarmaxautooffretlab);
ragge
1.69
457         }
ragge
1.33
458
ragge
1.1
459         checkst(0);
460         retstat = 0;
461         tcheck();
462         brklab = contlab = retlab = NOLAB;
463         flostat = 0;
ragge
1.51
464         if (nerrors == 0) {
465                 if (savbc != NULL)
466                         cerror("bcsave error");
ragge
1.46
467                 if (lparam != NULL)
468                         cerror("parameter reset error");
ragge
1.62
469                 if (swpole != NULL)
470                         cerror("switch error");
ragge
1.46
471         }
ragge
1.51
472         savbc = NULL;
ragge
1.46
473         lparam = NULL;
ragge
1.69
474         maxautooff = autooff = AUTOINIT;
ragge
1.1
475         minrvar = regvar = MAXRVAR;
476         reached = 1;
ragge
1.66
477
478         if (isinlining)
479                 inline_end();
480         inline_prtout();
481
482         strprint();
483
ragge
1.37
484         tmpfree(); /* Release memory resources */
ragge
1.73
485         send_passt(IP_LOCCTRDATA);
ragge
1.2
486 }
ragge
1.60
487         
ragge
1.2
488 void
489 dclargs()
490 {
ragge
1.59
491         union dimfun *df;
492         union arglist *al, *al2, *alb;
ragge
1.45
493         struct params *a;
494         struct symtab *p, **parr;
495         int i;
496
ragge
1.1
497         argoff = ARGINIT;
ragge
1.54
498 #ifdef PCC_DEBUG
ragge
1.12
499         if (ddebug > 2)
500                 printf("dclargs()\n");
ragge
1.54
501 #endif
ragge
1.45
502
ragge
1.56
503         /*
ragge
1.59
504          * Deal with fun(void) properly.
505          */
506         if (nparams == 1 && lparam->sym->stype == UNDEF)
507                 goto done;
508
509         /*
ragge
1.56
510          * Generate a list for bfcode().
511          * Parameters were pushed in reverse order.
512          */
ragge
1.58
513         if (nparams != 0)
514                 parr = tmpalloc(sizeof(struct symtab *) * nparams);
ragge
1.56
515
ragge
1.47
516         for (a = lparami = 0a != NULL && a != (struct params *)&lpole;
517             a = a->prev) {
ragge
1.56
518
ragge
1.59
519                 p = a->sym;
ragge
1.56
520                 parr[i++] = p;
ragge
1.59
521                 if (p->stype == FARG) {
522                         p->stype = INT;
523                         p->ssue = MKSUE(INT);
524                 }
525                 if (ISARY(p->stype)) {
526                         p->stype += (PTR-ARY);
527                         p->sdf++;
528                 }
ragge
1.54
529 #ifdef PCC_DEBUG
530                 if (ddebug > 2) {       /* XXX 4.4 */
ragge
1.59
531                         printf("\t%s (%p) "p->snamep);
ragge
1.1
532                         tprint(p->stype);
533                         printf("\n");
ragge
1.12
534                 }
ragge
1.54
535 #endif
ragge
1.56
536                 /* always set aside space, even for register arguments */
ragge
1.12
537                 oalloc(p, &argoff);
538         }
ragge
1.59
539         if (oldstyle && (df = cftnsp->sdf) && (al = df->dfun)) {
540                 /*
541                  * Check against prototype of oldstyle function.
542                  */
543                 alb = al2 = tmpalloc(sizeof(union arglist) * nparams * 3 + 1);
544                 for (i = 0i < nparamsi++) {
545                         TWORD type = parr[i]->stype;
546                         (al2++)->type = type;
547                         if (ISSTR(BTYPE(type)))
548                                 (al2++)->sue = parr[i]->ssue;
549                         while (!ISFTN(type) && !ISARY(type) && type > BTMASK)
550                                 type = DECREF(type);
551                         if (type > BTMASK)
552                                 (al2++)->df = parr[i]->sdf;
553                 }
554                 al2->type = TNULL;
ragge
1.60
555                 intcompare = 1;
ragge
1.59
556                 if (chkftn(alalb))
557                         uerror("function doesn't match prototype");
ragge
1.60
558                 intcompare = 0;
ragge
1.59
559         }
560 done:   cendarg();
ragge
1.73
561         send_passt(IP_LOCCTRPROG);
ragge
1.1
562         defalign(ALINT);
563         ftnno = getlab();
ragge
1.69
564         retlab = getlab();
ragge
1.45
565         bfcode(parrnparams);
ragge
1.72
566         send_passt(IP_PROLOG, -1, -1);
ragge
1.47
567         lparam = NULL;
ragge
1.45
568         nparams = 0;
ragge
1.2
569 }
ragge
1.1
570
ragge
1.21
571 /*
572  * reference to a structure or union, with no definition
573  */
ragge
1.1
574 NODE *
ragge
1.33
575 rstruct(char *tagint soru)
ragge
1.21
576 {
ragge
1.2
577         struct symtab *p;
578         NODE *q;
ragge
1.32
579
ragge
1.40
580         p = (struct symtab *)lookup(tagSTAGNAME);
ragge
1.21
581         switch (p->stype) {
ragge
1.1
582
583         case UNDEF:
584         def:
ragge
1.74
585                 q = block(NAMENILNIL000);
ragge
1.33
586                 q->n_sp = p;
ragge
1.31
587                 q->n_type = (soru&INSTRUCT) ? STRTY :
ragge
1.21
588                     ((soru&INUNION) ? UNIONTY : ENUMTY);
589                 defid(q, (soru&INSTRUCT) ? STNAME :
590                     ((soru&INUNION) ? UNAME : ENAME));
ragge
1.74
591                 nfree(q);
ragge
1.1
592                 break;
593
594         case STRTY:
ragge
1.21
595                 if (soru & INSTRUCT)
596                         break;
ragge
1.1
597                 goto def;
598
599         case UNIONTY:
ragge
1.21
600                 if (soru & INUNION)
601                         break;
ragge
1.1
602                 goto def;
603
604         case ENUMTY:
ragge
1.21
605                 if (!(soru&(INUNION|INSTRUCT)))
606                         break;
ragge
1.1
607                 goto def;
608
ragge
1.21
609         }
ragge
1.43
610         q = mkty(p->stype0p->ssue);
611         q->n_sue = p->ssue;
612         return q;
ragge
1.21
613 }
ragge
1.1
614
ragge
1.2
615 void
ragge
1.33
616 moedef(char *name)
ragge
1.2
617 {
618         NODE *q;
ragge
1.1
619
ragge
1.74
620         q = block(NAMENILNILMOETY00);
ragge
1.33
621         q->n_sp = lookup(name0);
622         defid(qMOE);
ragge
1.74
623         nfree(q);
ragge
1.2
624 }
ragge
1.1
625
ragge
1.2
626 /*
627  * begining of structure or union declaration
628  */
ragge
1.43
629 struct rstack *
ragge
1.33
630 bstruct(char *nameint soru)
ragge
1.2
631 {
ragge
1.43
632         struct rstack *r;
ragge
1.33
633         struct symtab *s;
ragge
1.2
634         NODE *q;
ragge
1.1
635
ragge
1.33
636         if (name != NULL)
ragge
1.40
637                 s = lookup(nameSTAGNAME);
ragge
1.33
638         else
639                 s = NULL;
640
ragge
1.43
641         r = tmpalloc(sizeof(struct rstack));
642         r->rinstruct = instruct;
643         r->rclass = strunem;
644         r->rstrucoff = strucoff;
645
ragge
1.1
646         strucoff = 0;
647         instruct = soru;
ragge
1.74
648         q = block(NAMENILNIL000);
ragge
1.33
649         q->n_sp = s;
ragge
1.21
650         if (instruct==INSTRUCT) {
ragge
1.18
651                 strunem = MOS;
ragge
1.31
652                 q->n_type = STRTY;
ragge
1.33
653                 if (s != NULL)
ragge
1.21
654                         defid(qSTNAME);
655         } else if(instruct == INUNION) {
ragge
1.18
656                 strunem = MOU;
ragge
1.31
657                 q->n_type = UNIONTY;
ragge
1.33
658                 if (s != NULL)
ragge
1.21
659                         defid(qUNAME);
660         } else { /* enum */
ragge
1.18
661                 strunem = MOE;
ragge
1.31
662                 q->n_type = ENUMTY;
ragge
1.33
663                 if (s != NULL)
ragge
1.21
664                         defid(qENAME);
665         }
ragge
1.43
666         r->rsym = q->n_sp;
ragge
1.46
667         r->rlparam = lparam;
ragge
1.74
668         nfree(q);
ragge
1.33
669
ragge
1.43
670         return r;
ragge
1.2
671 }
ragge
1.1
672
ragge
1.18
673 /*
674  * Called after a struct is declared to restore the environment.
675  */
ragge
1.1
676 NODE *
ragge
1.43
677 dclstruct(struct rstack *r)
ragge
1.2
678 {
ragge
1.43
679         NODE *n;
ragge
1.50
680         struct params *l, *m;
ragge
1.43
681         struct suedef *sue;
ragge
1.2
682         struct symtab *p;
ragge
1.46
683         int alsasz;
ragge
1.2
684         TWORD temp;
ragge
1.50
685         int ihighlow;
ragge
1.1
686
ragge
1.43
687         if (r->rsym == NULL) {
688                 sue = permalloc(sizeof(struct suedef));
ragge
1.65
689                 suedefcnt++;
ragge
1.43
690                 sue->suesize = 0;
691                 sue->suealign = ALSTRUCT;
ragge
1.18
692         } else
ragge
1.43
693                 sue = r->rsym->ssue;
ragge
1.1
694
ragge
1.43
695 #ifdef PCC_DEBUG
696         if (ddebug)
ragge
1.46
697                 printf("dclstruct(%s)\n"r->rsym ? r->rsym->sname : "??");
ragge
1.43
698 #endif
ragge
1.1
699         temp = (instruct&INSTRUCT)?STRTY:((instruct&INUNION)?UNIONTY:ENUMTY);
ragge
1.43
700         instruct = r->rinstruct;
701         strunem = r->rclass;
ragge
1.1
702         al = ALSTRUCT;
703
704         high = low = 0;
705
ragge
1.46
706         if ((l = r->rlparam) == NULL)
707                 l = lpole;
708         else
709                 l = l->next;
710
ragge
1.50
711         /* memory for the element array must be allocated first */
712         for (m = li = 1m != NULLm = m->next)
713                 i++;
714         sue->suelem = permalloc(sizeof(struct symtab *) * i);
715
716         for (i = 0l != NULLl = l->next) {
717                 sue->suelem[i++] = p = l->sym;
718
ragge
1.46
719                 if (p == NULL)
ragge
1.43
720                         cerror("gummy structure member");
ragge
1.46
721                 if (temp == ENUMTY) {
722                         if (p->soffset < low)
723                                 low = p->soffset;
724                         if (p->soffset > high)
725                                 high = p->soffset;
ragge
1.43
726                         p->ssue = sue;
ragge
1.1
727                         continue;
ragge
1.46
728                 }
ragge
1.43
729                 sa = talign(p->stypep->ssue);
ragge
1.21
730                 if (p->sclass & FIELD) {
ragge
1.1
731                         sz = p->sclass&FLDSIZ;
ragge
1.21
732                 } else {
ragge
1.52
733                         sz = tsize(p->stypep->sdfp->ssue);
ragge
1.1
734                 }
ragge
1.21
735                 if (sz > strucoff)
736                         strucoff = sz;  /* for use with unions */
737                 /*
738                  * set al, the alignment, to the lcm of the alignments
739                  * of the members.
740                  */
741                 SETOFF(alsa);
742         }
ragge
1.50
743         sue->suelem[i] = NULL;
ragge
1.46
744         SETOFF(strucoffal);
ragge
1.1
745
ragge
1.43
746         if (temp == ENUMTY) {
ragge
1.2
747                 TWORD ty;
ragge
1.1
748
ragge
1.43
749 #ifdef ENUMSIZE
ragge
1.1
750                 ty = ENUMSIZE(high,low);
ragge
1.43
751 #else
752                 if ((char)high == high && (char)low == low)
753                         ty = ctype(CHAR);
754                 else if ((short)high == high && (short)low == low)
755                         ty = ctype(SHORT);
756                 else
757                         ty = ctype(INT);
ragge
1.1
758 #endif
ragge
1.43
759                 strucoff = tsize(ty0MKSUE(ty));
760                 sue->suealign = al = talign(tyMKSUE(ty));
ragge
1.21
761         }
ragge
1.1
762
ragge
1.43
763         sue->suesize = strucoff;
764         sue->suealign = al;
765
ragge
1.46
766 #ifdef PCC_DEBUG
ragge
1.21
767         if (ddebug>1) {
ragge
1.50
768                 int i;
769
ragge
1.46
770                 printf("\tsize %d align %d elem %p\n",
771                     sue->suesizesue->suealignsue->suelem);
ragge
1.50
772                 for (i = 0sue->suelem[i] != NULL; ++i) {
773                         printf("\tmember %s(%p)\n",
774                             sue->suelem[i]->snamesue->suelem[i]);
ragge
1.1
775                 }
ragge
1.21
776         }
ragge
1.43
777 #endif
ragge
1.1
778
ragge
1.43
779         strucoff = r->rstrucoff;
ragge
1.46
780         if ((lparam = r->rlparam) != NULL)
781                 lparam->next = NULL;
782         n = mkty(temp0sue);
ragge
1.43
783         return n;
ragge
1.21
784 }
ragge
1.1
785
ragge
1.2
786 /*
787  * error printing routine in parser
788  */
789 void yyerror(char *s);
790 void
791 yyerror(char *s)
792 {
793         uerror(s);
794 }
795
796 void yyaccpt(void);
797 void
798 yyaccpt(void)
799 {
ragge
1.1
800         ftnend();
ragge
1.2
801 }
ragge
1.1
802
ragge
1.56
803 /*
804  * p is top of type list given to tymerge later.
805  * Find correct CALL node and declare parameters from there.
806  */
807 void
808 ftnarg(NODE *p)
ragge
1.2
809 {
ragge
1.56
810         NODE *q;
811         struct symtab *s;
ragge
1.1
812
ragge
1.56
813 #ifdef PCC_DEBUG
814         if (ddebug > 2)
815                 printf("ftnarg(%p)\n"p);
816 #endif
817         /*
ragge
1.59
818          * Enter argument onto param stack.
ragge
1.56
819          * Do not declare parameters until later (in dclargs);
820          * the function must be declared first.
821          * put it on the param stack in reverse order, due to the
822          * nature of the stack it will be reclaimed correct.
823          */
824         for (; p->n_op != NAMEp = p->n_left) {
825                 if (p->n_op == (UNARY CALL) && p->n_left->n_op == NAME)
826                         return/* Nothing to enter */
827                 if (p->n_op == CALL && p->n_left->n_op == NAME)
828                         break;
829         }
830
831         p = p->n_right;
ragge
1.59
832         blevel = 1;
ragge
1.41
833
ragge