Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030621182813

Diff

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