Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20040612085728

Diff

Diff from 1.114 to:

Annotations

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

Annotated File View

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