Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030730114833

Diff

Diff from 1.90 to:

Annotations

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

Annotated File View

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