Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030707102945

Diff

Diff from 1.83 to:

Annotations

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

Annotated File View

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