Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030801131203

Diff

Diff from 1.92 to:

Annotations

Annotate by Age | Author | Mixed | None
/fisheye/browse/pcc/pcc/cc/ccom/pftn.c

Annotated File View

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