Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030706141912

Diff

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