Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030622101637

Diff

Diff from 1.68 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 */
ragge
1.52
345         p->sdf = q->n_df;
ragge
1.68
346         /* Do not save param info for old-style functions */
347         if (ISFTN(type) && oldstyle)
348                 p->sdf->dfun = NULL;
ragge
1.1
349
350         /* allocate offsets */
ragge
1.33
351         if (class&FIELD) {
352                 (voidfalloc(pclass&FLDSIZ0NIL);  /* new entry */
ragge
1.46
353                 ssave(p);
ragge
1.33
354         } else switch (class) {
ragge
1.1
355
356         case AUTO:
ragge
1.30
357                 if (arrstkp)
358                         dynalloc(p, &autooff);
359                 else
ragge
1.54
360                         oalloc(p, &autooff);
ragge
1.1
361                 break;
362         case STATIC:
363         case EXTDEF:
ragge
1.33
364                 p->soffset = getlab();
365                 if (class == STATIC && blevel > 0)
366                         p->sflags |= SLABEL;
ragge
1.1
367                 break;
368
369         case EXTERN:
370         case UFORTRAN:
371         case FORTRAN:
ragge
1.33
372                 p->soffset = getlab();
ragge
1.1
373                 p->slevel = 0;
374                 break;
375         case MOU:
376         case MOS:
ragge
1.54
377                 oalloc(p, &strucoff);
378                 if (class == MOU)
379                         strucoff = 0;
ragge
1.46
380                 ssave(p);
ragge
1.1
381                 break;
382
383         case MOE:
ragge
1.33
384                 p->soffset = strucoff++;
ragge
1.46
385                 ssave(p);
ragge
1.1
386                 break;
387         case REGISTER:
ragge
1.33
388                 p->soffset = regvar--;
389                 if (blevel == 1)
390                         p->sflags |= SSET;
391                 if (regvar < minrvar)
392                         minrvar = regvar;
ragge
1.1
393                 break;
ragge
1.33
394         }
ragge
1.1
395
396         /* user-supplied routine to fix up new definitions */
397         FIXDEF(p);
398
ragge
1.54
399 #ifdef PCC_DEBUG
ragge
1.33
400         if (ddebug)
ragge
1.52
401                 printf"       sdf, ssue, offset: %p, %p, %d\n",
402                     p->sdfp->ssuep->soffset);
ragge
1.54
403 #endif
ragge
1.1
404
ragge
1.33
405 }
ragge
1.1
406
ragge
1.2
407 void
ragge
1.46
408 ssave(struct symtab *sym)
ragge
1.2
409 {
ragge
1.46
410         struct params *p;
411
412         p = tmpalloc(sizeof(struct params));
413         p->next = NULL;
414         p->sym = sym;
415
416         if (lparam == NULL) {
417                 p->prev = (struct params *)&lpole;
418                 lpole = p;
419         } else {
420                 lparam->next = p;
421                 p->prev = lparam;
ragge
1.2
422         }
ragge
1.46
423         lparam = p;
ragge
1.2
424 }
ragge
1.1
425
ragge
1.2
426 /*
427  * end of function
428  */
429 void
430 ftnend()
431 {
ragge
1.51
432         extern struct savbc *savbc;
ragge
1.62
433         extern struct swdef *swpole;
ragge
1.51
434
ragge
1.33
435         if (retlab != NOLAB && nerrors == 0/* inside a real function */
ragge
1.1
436                 efcode();
ragge
1.33
437
ragge
1.1
438         checkst(0);
439         retstat = 0;
440         tcheck();
441         brklab = contlab = retlab = NOLAB;
442         flostat = 0;
ragge
1.51
443         if (nerrors == 0) {
444                 if (savbc != NULL)
445                         cerror("bcsave error");
ragge
1.46
446                 if (lparam != NULL)
447                         cerror("parameter reset error");
ragge
1.62
448                 if (swpole != NULL)
449                         cerror("switch error");
ragge
1.46
450         }
ragge
1.51
451         savbc = NULL;
ragge
1.46
452         lparam = NULL;
ragge
1.1
453         autooff = AUTOINIT;
454         minrvar = regvar = MAXRVAR;
455         reached = 1;
ragge
1.66
456
457         if (isinlining)
458                 inline_end();
459         inline_prtout();
460
461         strprint();
462
ragge
1.37
463         tmpfree(); /* Release memory resources */
ragge
1.54
464         locctr(DATA);
ragge
1.2
465 }
ragge
1.60
466         
ragge
1.2
467 void
468 dclargs()
469 {
ragge
1.59
470         union dimfun *df;
471         union arglist *al, *al2, *alb;
ragge
1.45
472         struct params *a;
473         struct symtab *p, **parr;
474         int i;
475
ragge
1.1
476         argoff = ARGINIT;
ragge
1.54
477 #ifdef PCC_DEBUG
ragge
1.12
478         if (ddebug > 2)
479                 printf("dclargs()\n");
ragge
1.54
480 #endif
ragge
1.45
481
ragge
1.56
482         /*
ragge
1.59
483          * Deal with fun(void) properly.
484          */
485         if (nparams == 1 && lparam->sym->stype == UNDEF)
486                 goto done;
487
488         /*
ragge
1.56
489          * Generate a list for bfcode().
490          * Parameters were pushed in reverse order.
491          */
ragge
1.58
492         if (nparams != 0)
493                 parr = tmpalloc(sizeof(struct symtab *) * nparams);
ragge
1.56
494
ragge
1.47
495         for (a = lparami = 0a != NULL && a != (struct params *)&lpole;
496             a = a->prev) {
ragge
1.56
497
ragge
1.59
498                 p = a->sym;
ragge
1.56
499                 parr[i++] = p;
ragge
1.59
500                 if (p->stype == FARG) {
501                         p->stype = INT;
502                         p->ssue = MKSUE(INT);
503                 }
504                 if (ISARY(p->stype)) {
505                         p->stype += (PTR-ARY);
506                         p->sdf++;
507                 }
ragge
1.54
508 #ifdef PCC_DEBUG
509                 if (ddebug > 2) {       /* XXX 4.4 */
ragge
1.59
510                         printf("\t%s (%p) "p->snamep);
ragge
1.1
511                         tprint(p->stype);
512                         printf("\n");
ragge
1.12
513                 }
ragge
1.54
514 #endif
ragge
1.56
515                 /* always set aside space, even for register arguments */
ragge
1.12
516                 oalloc(p, &argoff);
517         }
ragge
1.59
518         if (oldstyle && (df = cftnsp->sdf) && (al = df->dfun)) {
519                 /*
520                  * Check against prototype of oldstyle function.
521                  */
522                 alb = al2 = tmpalloc(sizeof(union arglist) * nparams * 3 + 1);
523                 for (i = 0i < nparamsi++) {
524                         TWORD type = parr[i]->stype;
525                         (al2++)->type = type;
526                         if (ISSTR(BTYPE(type)))
527                                 (al2++)->sue = parr[i]->ssue;
528                         while (!ISFTN(type) && !ISARY(type) && type > BTMASK)
529                                 type = DECREF(type);
530                         if (type > BTMASK)
531                                 (al2++)->df = parr[i]->sdf;
532                 }
533                 al2->type = TNULL;
ragge
1.60
534                 intcompare = 1;
ragge
1.59
535                 if (chkftn(alalb))
536                         uerror("function doesn't match prototype");
ragge
1.60
537                 intcompare = 0;
ragge
1.59
538         }
539 done:   cendarg();
ragge
1.54
540         locctr(PROG);
ragge
1.1
541         defalign(ALINT);
542         ftnno = getlab();
ragge
1.45
543         bfcode(parrnparams);
ragge
1.47
544         lparam = NULL;
ragge
1.45
545         nparams = 0;
ragge
1.2
546 }
ragge
1.1
547
ragge
1.21
548 /*
549  * reference to a structure or union, with no definition
550  */
ragge
1.1
551 NODE *
ragge
1.33
552 rstruct(char *tagint soru)
ragge
1.21
553 {
ragge
1.2
554         struct symtab *p;
555         NODE *q;
ragge
1.32
556
ragge
1.40
557         p = (struct symtab *)lookup(tagSTAGNAME);
ragge
1.21
558         switch (p->stype) {
ragge
1.1
559
560         case UNDEF:
561         def:
ragge
1.21
562                 q = block(FREENILNIL000);
ragge
1.33
563                 q->n_sp = p;
ragge
1.31
564                 q->n_type = (soru&INSTRUCT) ? STRTY :
ragge
1.21
565                     ((soru&INUNION) ? UNIONTY : ENUMTY);
566                 defid(q, (soru&INSTRUCT) ? STNAME :
567                     ((soru&INUNION) ? UNAME : ENAME));
ragge
1.1
568                 break;
569
570         case STRTY:
ragge
1.21
571                 if (soru & INSTRUCT)
572                         break;
ragge
1.1
573                 goto def;
574
575         case UNIONTY:
ragge
1.21
576                 if (soru & INUNION)
577                         break;
ragge
1.1
578                 goto def;
579
580         case ENUMTY:
ragge
1.21
581                 if (!(soru&(INUNION|INSTRUCT)))
582                         break;
ragge
1.1
583                 goto def;
584
ragge
1.21
585         }
ragge
1.43
586         q = mkty(p->stype0p->ssue);
587         q->n_sue = p->ssue;
588         return q;
ragge
1.21
589 }
ragge
1.1
590
ragge
1.2
591 void
ragge
1.33
592 moedef(char *name)
ragge
1.2
593 {
594         NODE *q;
ragge
1.1
595
ragge
1.33
596         q = block(FREENILNILMOETY00);
597         q->n_sp = lookup(name0);
598         defid(qMOE);
ragge
1.2
599 }
ragge
1.1
600
ragge
1.2
601 /*
602  * begining of structure or union declaration
603  */
ragge
1.43
604 struct rstack *
ragge
1.33
605 bstruct(char *nameint soru)
ragge
1.2
606 {
ragge
1.43
607         struct rstack *r;
ragge
1.33
608         struct symtab *s;
ragge
1.2
609         NODE *q;
ragge
1.1
610
ragge
1.33
611         if (name != NULL)
ragge
1.40
612                 s = lookup(nameSTAGNAME);
ragge
1.33
613         else
614                 s = NULL;
615
ragge
1.43
616         r = tmpalloc(sizeof(struct rstack));
617         r->rinstruct = instruct;
618         r->rclass = strunem;
619         r->rstrucoff = strucoff;
620
ragge
1.1
621         strucoff = 0;
622         instruct = soru;
ragge
1.21
623         q = block(FREENILNIL000);
ragge
1.33
624         q->n_sp = s;
ragge
1.21
625         if (instruct==INSTRUCT) {
ragge
1.18
626                 strunem = MOS;
ragge
1.31
627                 q->n_type = STRTY;
ragge
1.33
628                 if (s != NULL)
ragge
1.21
629                         defid(qSTNAME);
630         } else if(instruct == INUNION) {
ragge
1.18
631                 strunem = MOU;
ragge
1.31
632                 q->n_type = UNIONTY;
ragge
1.33
633                 if (s != NULL)
ragge
1.21
634                         defid(qUNAME);
635         } else { /* enum */
ragge
1.18
636                 strunem = MOE;
ragge
1.31
637                 q->n_type = ENUMTY;
ragge
1.33
638                 if (s != NULL)
ragge
1.21
639                         defid(qENAME);
640         }
ragge
1.43
641         r->rsym = q->n_sp;
ragge
1.46
642         r->rlparam = lparam;
ragge
1.33
643
ragge
1.43
644         return r;
ragge
1.2
645 }
ragge
1.1
646
ragge
1.18
647 /*
648  * Called after a struct is declared to restore the environment.
649  */
ragge
1.1
650 NODE *
ragge
1.43
651 dclstruct(struct rstack *r)
ragge
1.2
652 {
ragge
1.43
653         NODE *n;
ragge
1.50
654         struct params *l, *m;
ragge
1.43
655         struct suedef *sue;
ragge
1.2
656         struct symtab *p;
ragge
1.46
657         int alsasz;
ragge
1.2
658         TWORD temp;
ragge
1.50
659         int ihighlow;
ragge
1.1
660
ragge
1.43
661         if (r->rsym == NULL) {
662                 sue = permalloc(sizeof(struct suedef));
ragge
1.65
663                 suedefcnt++;
ragge
1.43
664                 sue->suesize = 0;
665                 sue->suealign = ALSTRUCT;
ragge
1.18
666         } else
ragge
1.43
667                 sue = r->rsym->ssue;
ragge
1.1
668
ragge
1.43
669 #ifdef PCC_DEBUG
670         if (ddebug)
ragge
1.46
671                 printf("dclstruct(%s)\n"r->rsym ? r->rsym->sname : "??");
ragge
1.43
672 #endif
ragge
1.1
673         temp = (instruct&INSTRUCT)?STRTY:((instruct&INUNION)?UNIONTY:ENUMTY);
ragge
1.43
674         instruct = r->rinstruct;
675         strunem = r->rclass;
ragge
1.1
676         al = ALSTRUCT;
677
678         high = low = 0;
679
ragge
1.46
680         if ((l = r->rlparam) == NULL)
681                 l = lpole;
682         else
683                 l = l->next;
684
ragge
1.50
685         /* memory for the element array must be allocated first */
686         for (m = li = 1m != NULLm = m->next)
687                 i++;
688         sue->suelem = permalloc(sizeof(struct symtab *) * i);
689
690         for (i = 0l != NULLl = l->next) {
691                 sue->suelem[i++] = p = l->sym;
692
ragge
1.46
693                 if (p == NULL)
ragge
1.43
694                         cerror("gummy structure member");
ragge
1.46
695                 if (temp == ENUMTY) {
696                         if (p->soffset < low)
697                                 low = p->soffset;
698                         if (p->soffset > high)
699                                 high = p->soffset;
ragge
1.43
700                         p->ssue = sue;
ragge
1.1
701                         continue;
ragge
1.46
702                 }
ragge
1.43
703                 sa = talign(p->stypep->ssue);
ragge
1.21
704                 if (p->sclass & FIELD) {
ragge
1.1
705                         sz = p->sclass&FLDSIZ;
ragge
1.21
706                 } else {
ragge
1.52
707                         sz = tsize(p->stypep->sdfp->ssue);
ragge
1.1
708                 }
ragge
1.21
709                 if (sz > strucoff)
710                         strucoff = sz;  /* for use with unions */
711                 /*
712                  * set al, the alignment, to the lcm of the alignments
713                  * of the members.
714                  */
715                 SETOFF(alsa);
716         }
ragge
1.50
717         sue->suelem[i] = NULL;
ragge
1.46
718         SETOFF(strucoffal);
ragge
1.1
719
ragge
1.43
720         if (temp == ENUMTY) {
ragge
1.2
721                 TWORD ty;
ragge
1.1
722
ragge
1.43
723 #ifdef ENUMSIZE
ragge
1.1
724                 ty = ENUMSIZE(high,low);
ragge
1.43
725 #else
726                 if ((char)high == high && (char)low == low)
727                         ty = ctype(CHAR);
728                 else if ((short)high == high && (short)low == low)
729                         ty = ctype(SHORT);
730                 else
731                         ty = ctype(INT);
ragge
1.1
732 #endif
ragge
1.43
733                 strucoff = tsize(ty0MKSUE(ty));
734                 sue->suealign = al = talign(tyMKSUE(ty));
ragge
1.21
735         }
ragge
1.1
736
ragge
1.43
737         sue->suesize = strucoff;
738         sue->suealign = al;
739
ragge
1.46
740 #ifdef PCC_DEBUG
ragge
1.21
741         if (ddebug>1) {
ragge
1.50
742                 int i;
743
ragge
1.46
744                 printf("\tsize %d align %d elem %p\n",
745                     sue->suesizesue->suealignsue->suelem);
ragge
1.50
746                 for (i = 0sue->suelem[i] != NULL; ++i) {
747                         printf("\tmember %s(%p)\n",
748                             sue->suelem[i]->snamesue->suelem[i]);
ragge
1.1
749                 }
ragge
1.21
750         }
ragge
1.43
751 #endif
ragge
1.1
752
ragge
1.43
753         strucoff = r->rstrucoff;
ragge
1.46
754         if ((lparam = r->rlparam) != NULL)
755                 lparam->next = NULL;
756         n = mkty(temp0sue);
ragge
1.43
757         return n;
ragge
1.21
758 }
ragge
1.1
759
ragge
1.2
760 /*
761  * error printing routine in parser
762  */
763 void yyerror(char *s);
764 void
765 yyerror(char *s)
766 {
767         uerror(s);
768 }
769
770 void yyaccpt(void);
771 void
772 yyaccpt(void)
773 {
ragge
1.1
774         ftnend();
ragge
1.2
775 }
ragge
1.1
776
ragge
1.56
777 /*
778  * p is top of type list given to tymerge later.
779  * Find correct CALL node and declare parameters from there.
780  */
781 void
782 ftnarg(NODE *p)
ragge
1.2
783 {
ragge
1.56
784         NODE *q;
785         struct symtab *s;
ragge
1.1
786
ragge
1.56
787 #ifdef PCC_DEBUG
788         if (ddebug > 2)
789                 printf("ftnarg(%p)\n"p);
790 #endif
791         /*
ragge
1.59
792          * Enter argument onto param stack.
ragge
1.56
793          * Do not declare parameters until later (in dclargs);
794          * the function must be declared first.
795          * put it on the param stack in reverse order, due to the
796          * nature of the stack it will be reclaimed correct.
797          */
798         for (; p->n_op != NAMEp = p->n_left) {
799                 if (p->n_op == (UNARY CALL) && p->n_left->n_op == NAME)
800                         return/* Nothing to enter */
801                 if (p->n_op == CALL && p->n_left->n_op == NAME)
802                         break;
803         }
804
805         p = p->n_right;
ragge
1.59
806         blevel = 1;
ragge
1.41
807
ragge
1.56
808         while (p->n_op == CM) {
809                 q = p->n_right;
810                 if (q->n_op != ELLIPSIS) {
ragge
1.59
811                         s = lookup((char *)q->n_sp0);
812                         if (s->stype != UNDEF) {
813                                 if (s->slevel > 0)
814                                         uerror("parameter '%s' redefined",
815                                             s->sname);
816                                 s = hide(s);
817                         }
818                         s->soffset = NOOFFSET;
819                         s->sclass = PARAM;
ragge
1.56
820                         s->stype = q->n_type;
821                         s->sdf = q->n_df;
822                         s->ssue = q->n_sue;
823                         ssave(s);
824                         nparams++;
825 #ifdef PCC_DEBUG
826                         if (ddebug > 2)
827                                 printf("        saving sym %s (%p) from (%p)\n",
828                                     s->snamesq);
829 #endif
830                 }
831                 p = p->n_left;
ragge
1.33
832         }
ragge
1.59
833         s = lookup((char *)p->n_sp0);
834         if (s->stype != UNDEF) {
835