Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20080728161605

Diff

Diff from 1.217 to:

Annotations

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

Annotated File View

ragge
1.217
1 /*      $Id: pftn.c,v 1.217 2008/07/28 16:16:05 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.157
70 #include <string.h> /* XXX - for strcmp */
71
ragge
1.178
72 #include "cgram.h"
73
ragge
1.33
74 struct symtab *spname;
75 struct symtab *cftnsp;
ragge
1.65
76 int arglistcntdimfuncnt;      /* statistics */
ragge
1.69
77 int symtabcntsuedefcnt;       /* statistics */
78 int autooff,            /* the next unused automatic offset */
ragge
1.146
79     maxautooff,         /* highest used automatic offset in function */
ragge
1.194
80     argoff;             /* the next unused argument offset */
ragge
1.69
81 int retlab = NOLAB;     /* return label for subroutine */
82 int brklab;
83 int contlab;
84 int flostat;
ragge
1.194
85 int blevel;
ragge
1.150
86 int reachedprolab;
ragge
1.1
87
ragge
1.46
88 struct params;
89
ragge
1.184
90 #define ISSTR(ty) (ty == STRTY || ty == UNIONTY)
ragge
1.59
91 #define ISSOU(ty) (ty == STRTY || ty == UNIONTY)
92 #define MKTY(p, t, d, s) r = talloc(); *r = *p; \
ragge
1.74
93         r = argcast(rtds); *p = *rnfree(r);
ragge
1.59
94
ragge
1.43
95 /*
96  * Linked list stack while reading in structs.
97  */
ragge
1.194
98 struct rstack {
ragge
1.43
99         struct  rstack *rnext;
ragge
1.194
100         int     rsou;
101         int     rstr;
ragge
1.43
102         struct  symtab *rsym;
ragge
1.194
103         struct  symtab *rb;
ragge
1.217
104         int     flags;
105 #define LASTELM 1
ragge
1.193
106 } *rpole;
ragge
1.43
107
ragge
1.45
108 /*
ragge
1.47
109  * Linked list for parameter (and struct elements) declaration.
ragge
1.45
110  */
111 static struct params {
ragge
1.46
112         struct params *next, *prev;
ragge
1.45
113         struct symtab *sym;
ragge
1.47
114 } *lpole, *lparam;
ragge
1.45
115 static int nparams;
116
ragge
1.2
117 /* defines used for getting things off of the initialization stack */
ragge
1.1
118
ragge
1.30
119 static NODE *arrstk[10];
120 static int arrstkp;
ragge
1.60
121 static int intcompare;
ragge
1.192
122 static NODE *parlink;
ragge
1.1
123
ragge
1.2
124 void fixtype(NODE *pint class);
125 int fixclass(int classTWORD type);
126 int falloc(struct symtab *pint wint newNODE *pty);
ragge
1.30
127 static void dynalloc(struct symtab *pint *poff);
ragge
1.2
128 void inforce(OFFSZ n);
129 void vfdalign(int n);
ragge
1.46
130 static void ssave(struct symtab *);
ragge
1.168
131 static void alprint(union arglist *alint in);
132 static void lcommadd(struct symtab *sp);
ragge
1.1
133
134 int ddebug = 0;
135
ragge
1.168
136 /*
137  * Declaration of an identifier.  Handles redeclarations, hiding,
138  * incomplete types and forward declarations.
139  */
140
ragge
1.2
141 void
142 defid(NODE *qint class)
143 {
ragge
1.215
144         extern int fun_inline;
ragge
1.2
145         struct symtab *p;
ragge
1.92
146         TWORD typequal;
147         TWORD stpstq;
ragge
1.2
148         int scl;
ragge
1.52
149         union dimfun *dsym, *ddef;
ragge
1.124
150         int slevtempchanged;
ragge
1.1
151
ragge
1.32
152         if (q == NIL)
153                 return;  /* an error was detected */
ragge
1.1
154
ragge
1.33
155         p = q->n_sp;
ragge
1.1
156
ragge
1.54
157 #ifdef PCC_DEBUG
ragge
1.4
158         if (ddebug) {
ragge
1.33
159                 printf("defid(%s (%p), "p->snamep);
ragge
1.104
160                 tprint(stdoutq->n_typeq->n_qual);
ragge
1.50
161                 printf(", %s, (%p,%p)), level %d\n"scnames(class),
ragge
1.52
162                     q->n_dfq->n_sueblevel);
ragge
1.4
163         }
ragge
1.54
164 #endif
ragge
1.1
165
ragge
1.33
166         fixtype(qclass);
ragge
1.1
167
ragge
1.31
168         type = q->n_type;
ragge
1.92
169         qual = q->n_qual;
ragge
1.33
170         class = fixclass(classtype);
ragge
1.1
171
172         stp = p->stype;
ragge
1.92
173         stq = p->squal;
ragge
1.1
174         slev = p->slevel;
175
ragge
1.54
176 #ifdef PCC_DEBUG
ragge
1.4
177         if (ddebug) {
178                 printf("        modified to ");
ragge
1.104
179                 tprint(stdouttypequal);
ragge
1.4
180                 printf(", %s\n"scnames(class));
181                 printf("        previous def'n: ");
ragge
1.104
182                 tprint(stdoutstpstq);
ragge
1.50
183                 printf(", %s, (%p,%p)), level %d\n",
ragge
1.52
184                     scnames(p->sclass), p->sdfp->ssueslev);
ragge
1.4
185         }
ragge
1.54
186 #endif
ragge
1.1
187
ragge
1.56
188         if (blevel == 1) {
ragge
1.33
189                 switch (class) {
ragge
1.1
190                 default:
ragge
1.192
191                         if (!(class&FIELD) && !ISFTN(type))
ragge
1.56
192                                 uerror("declared argument %s missing",
ragge
1.4
193                                     p->sname );
ragge
1.1
194                 case MOS:
195                 case MOU:
196                 case TYPEDEF:
ragge
1.192
197                 case PARAM:
ragge
1.1
198                         ;
ragge
1.56
199                 }
ragge
1.4
200         }
ragge
1.56
201
202         if (stp == UNDEF)
203                 goto enter/* New symbol */
ragge
1.1
204
ragge
1.33
205         if (type != stp)
206                 goto mismatch;
207
208         if (blevel > slev && (class == AUTO || class == REGISTER))
ragge
1.1
209                 /* new scope */
210                 goto mismatch;
211
ragge
1.55
212         /*
213          * test (and possibly adjust) dimensions.
214          * also check that prototypes are correct.
215          */
ragge
1.52
216         dsym = p->sdf;
217         ddef = q->n_df;
ragge
1.124
218         changed = 0;
ragge
1.55
219         for (temp = typetemp & TMASKtemp = DECREF(temp)) {
220                 if (ISARY(temp)) {
ragge
1.52
221                         if (dsym->ddim == 0) {
222                                 dsym->ddim = ddef->ddim;
ragge
1.124
223                                 changed = 1;
ragge
1.52
224                         } else if (ddef->ddim != 0 && dsym->ddim!=ddef->ddim) {
ragge
1.1
225                                 goto mismatch;
ragge
1.50
226                         }
ragge
1.1
227                         ++dsym;
228                         ++ddef;
ragge
1.55
229                 } else if (ISFTN(temp)) {
ragge
1.110
230                         /* add a late-defined prototype here */
231                         if (cftnsp == NULL && dsym->dfun == NULL)
232                                 dsym->dfun = ddef->dfun;
ragge
1.109
233                         if (!oldstyle && ddef->dfun != NULL &&
234                             chkftn(dsym->dfunddef->dfun))
ragge
1.59
235                                 uerror("declaration doesn't match prototype");
ragge
1.55
236                         dsym++, ddef++;
ragge
1.1
237                 }
ragge
1.50
238         }
ragge
1.124
239 #ifdef STABS
240         if (changed && gflag)
ragge
1.125
241                 stabs_chgsym(p); /* symbol changed */
ragge
1.124
242 #endif
ragge
1.1
243
244         /* check that redeclarations are to the same structure */
ragge
1.193
245         if ((temp == STRTY || temp == UNIONTY) && p->ssue != q->n_sue) {
ragge
1.1
246                 goto mismatch;
ragge
1.33
247         }
ragge
1.1
248
ragge
1.33
249         scl = p->sclass;
ragge
1.1
250
ragge
1.54
251 #ifdef PCC_DEBUG
ragge
1.33
252         if (ddebug)
253                 printf("        previous class: %s\n"scnames(scl));
ragge
1.54
254 #endif
ragge
1.1
255
ragge
1.193
256         if (class & FIELD)
257                 return;
258         switch(class) {
ragge
1.1
259
260         case EXTERN:
261                 switchscl ){
262                 case STATIC:
263                 case USTATIC:
ragge
1.216
264                         ifslev==0 )
265                                 goto done;
ragge
1.1
266                         break;
267                 case EXTDEF:
268                 case EXTERN:
269                 case FORTRAN:
270                 case UFORTRAN:
ragge
1.216
271                         goto done;
ragge
1.1
272                         }
273                 break;
274
275         case STATIC:
ragge
1.33
276                 if (scl==USTATIC || (scl==EXTERN && blevel==0)) {
ragge
1.1
277                         p->sclass = STATIC;
ragge
1.216
278                         goto done;
ragge
1.33
279                 }
ragge
1.168
280                 if (changed || (scl == STATIC && blevel == slev))
ragge
1.216
281                         goto done/* identical redeclaration */
ragge
1.1
282                 break;
283
284         case USTATIC:
ragge
1.33
285                 if (scl==STATIC || scl==USTATIC)
ragge
1.216
286                         goto done;
ragge
1.1
287                 break;
288
289         case TYPEDEF:
ragge
1.33
290                 if (scl == class)
ragge
1.216
291                         goto done;
ragge
1.1
292                 break;
293
294         case UFORTRAN:
ragge
1.33
295                 if (scl == UFORTRAN || scl == FORTRAN)
ragge
1.216
296                         goto done;
ragge
1.1
297                 break;
298
299         case FORTRAN:
ragge
1.33
300                 if (scl == UFORTRAN) {
ragge
1.1
301                         p->sclass = FORTRAN;
ragge
1.216
302                         goto done;
ragge
1.33
303                 }
ragge
1.1
304                 break;
305
306         case MOU:
307         case MOS:
ragge
1.216
308                 goto done;
ragge
1.1
309
310         case EXTDEF:
ragge
1.10
311                 switch (scl) {
312                 case EXTERN:
ragge
1.1
313                         p->sclass = EXTDEF;
ragge
1.216
314                         goto done;
ragge
1.10
315                 case USTATIC:
316                         p->sclass = STATIC;
ragge
1.216
317                         goto done;
ragge
1.10
318                 }
ragge
1.1
319                 break;
320
321         case AUTO:
322         case REGISTER:
ragge
1.192
323                 if (blevel == slev)
324                         goto redec;
ragge
1.215
325                 break;  /* mismatch.. */
326         case SNULL:
327                 if (fun_inline && ISFTN(type))
ragge
1.216
328                         goto done;
ragge
1.215
329                 break;
ragge
1.33
330         }
ragge
1.1
331
332         mismatch:
333
ragge
1.55
334         /*
335          * Only allowed for automatic variables.
336          */
337         if (blevel == slev || class == EXTERN || class == FORTRAN ||
338             class == UFORTRAN) {
ragge
1.158
339                 if (ISSTR(class) && !ISSTR(p->sclass)) {
ragge
1.192
340 redec:                  uerror("redeclaration of %s"p->sname);
ragge
1.158
341                         return;
342                 }
ragge
1.24
343         }
ragge
1.168
344         if (blevel == 0)
ragge
1.192
345                 goto redec;
ragge
1.55
346         q->n_sp = p = hide(p);
ragge
1.1
347
348         enter:  /* make a new entry */
349
ragge
1.54
350 #ifdef PCC_DEBUG
ragge
1.33
351         if(ddebug)
352                 printf("        new entry made\n");
ragge
1.54
353 #endif
ragge
1.1
354         p->stype = type;
ragge
1.93
355         p->squal = qual;
ragge
1.1
356         p->sclass = class;
357         p->slevel = blevel;
ragge
1.33
358         p->soffset = NOOFFSET;
ragge
1.193
359         if (q->n_sue == NULL)
360                 cerror("q->n_sue == NULL");
361         p->ssue = q->n_sue;
ragge
1.1
362
363         /* copy dimensions */
ragge
1.52
364         p->sdf = q->n_df;
ragge
1.68
365         /* Do not save param info for old-style functions */
366         if (ISFTN(type) && oldstyle)
367                 p->sdf->dfun = NULL;
ragge
1.1
368
369         /* allocate offsets */
ragge
1.33
370         if (class&FIELD) {
371                 (voidfalloc(pclass&FLDSIZ0NIL);  /* new entry */
372         } else switch (class) {
ragge
1.1
373
ragge
1.131
374         case REGISTER:
ragge
1.147
375                 cerror("register var");
ragge
1.131
376
ragge
1.1
377         case AUTO:
ragge
1.30
378                 if (arrstkp)
379                         dynalloc(p, &autooff);
380                 else
ragge
1.54
381                         oalloc(p, &autooff);
ragge
1.1
382                 break;
ragge
1.192
383         case PARAM:
ragge
1.196
384                 if (ISARY(p->stype)) {
385                         /* remove array type on parameters before oalloc */
386                         p->stype += (PTR-ARY);
387                         p->sdf++;
388                 }
ragge
1.192
389                 if (arrstkp)
390                         dynalloc(p, &argoff);
391                 else
392                         oalloc(p, &argoff);
393                 break;
394                 
ragge
1.1
395         case STATIC:
396         case EXTDEF:
397         case EXTERN:
398         case UFORTRAN:
399         case FORTRAN:
ragge
1.33
400                 p->soffset = getlab();
ragge
1.190
401                 if (pragma_renamed)
402                         p->soname = pragma_renamed;
403                 pragma_renamed = NULL;
ragge
1.1
404                 break;
ragge
1.190
405
ragge
1.1
406         case MOU:
407         case MOS:
ragge
1.194
408                 oalloc(p, &rpole->rstr);
ragge
1.54
409                 if (class == MOU)
ragge
1.194
410                         rpole->rstr = 0;
ragge
1.1
411                 break;
ragge
1.215
412         case SNULL:
413                 if (fun_inline) {
414                         p->slevel = 1;
415                         p->soffset = getlab();
416                 }
ragge
1.33
417         }
ragge
1.1
418
ragge
1.124
419 #ifdef STABS
420         if (gflag)
ragge
1.125
421                 stabs_newsym(p);
ragge
1.124
422 #endif
ragge
1.1
423
ragge
1.216
424 done:
ragge
1.190
425         fixdef(p);      /* Leave last word to target */
ragge
1.54
426 #ifdef PCC_DEBUG
ragge
1.33
427         if (ddebug)
ragge
1.52
428                 printf"       sdf, ssue, offset: %p, %p, %d\n",
429                     p->sdfp->ssuep->soffset);
ragge
1.54
430 #endif
ragge
1.33
431 }
ragge
1.1
432
ragge
1.2
433 void
ragge
1.46
434 ssave(struct symtab *sym)
ragge
1.2
435 {
ragge
1.46
436         struct params *p;
437
438         p = tmpalloc(sizeof(struct params));
439         p->next = NULL;
440         p->sym = sym;
441
ragge
1.193
442         if ((p->prev = lparam) == NULL)
ragge
1.46
443                 lpole = p;
ragge
1.193
444         else
ragge
1.46
445                 lparam->next = p;
446         lparam = p;
ragge
1.2
447 }
ragge
1.1
448
ragge
1.2
449 /*
450  * end of function
451  */
452 void
453 ftnend()
454 {
ragge
1.51
455         extern struct savbc *savbc;
ragge
1.62
456         extern struct swdef *swpole;
ragge
1.192
457         extern int tvaloff;
ragge
1.138
458         char *c;
ragge
1.51
459
ragge
1.69
460         if (retlab != NOLAB && nerrors == 0) { /* inside a real function */
ragge
1.134
461                 plabel(retlab);
ragge
1.112
462                 efcode(); /* struct return handled here */
ragge
1.190
463                 c = cftnsp->soname;
ragge
1.149
464                 SETOFF(maxautooffALCHAR);
465                 send_passt(IP_EPILOG0maxautooff/SZCHARc,
ragge
1.192
466                     cftnsp->stypecftnsp->sclass == EXTDEFretlabtvaloff);
ragge
1.69
467         }
ragge
1.33
468
ragge
1.1
469         tcheck();
470         brklab = contlab = retlab = NOLAB;
471         flostat = 0;
ragge
1.51
472         if (nerrors == 0) {
473                 if (savbc != NULL)
474                         cerror("bcsave error");
ragge
1.46
475                 if (lparam != NULL)
476                         cerror("parameter reset error");
ragge
1.62
477                 if (swpole != NULL)
478                         cerror("switch error");
ragge
1.46
479         }
ragge
1.51
480         savbc = NULL;
ragge
1.46
481         lparam = NULL;
ragge
1.146
482         maxautooff = autooff = AUTOINIT;
ragge
1.1
483         reached = 1;
ragge
1.66
484
485         if (isinlining)
486                 inline_end();
487         inline_prtout();
488
ragge
1.37
489         tmpfree(); /* Release memory resources */
ragge
1.2
490 }
ragge
1.89
491
gmcgarry
1.198
492 static struct symtab nulsym = {
493         { NULL0000 }, "null""null"INT0NULLNULL
494 };
495
ragge
1.2
496 void
497 dclargs()
498 {
ragge
1.59
499         union dimfun *df;
500         union arglist *al, *al2, *alb;
ragge
1.45
501         struct params *a;
ragge
1.123
502         struct symtab *p, **parr = NULL/* XXX gcc */
ragge
1.150
503         int i;
ragge
1.45
504
ragge
1.56
505         /*
ragge
1.59
506          * Deal with fun(void) properly.
507          */
gmcgarry
1.198
508         if (nparams == 1 && lparam->sym && lparam->sym->stype == VOID)
ragge
1.59
509                 goto done;
510
511         /*
ragge
1.56
512          * Generate a list for bfcode().
513          * Parameters were pushed in reverse order.
514          */
ragge
1.58
515         if (nparams != 0)
516                 parr = tmpalloc(sizeof(struct symtab *) * nparams);
ragge
1.56
517
ragge
1.140
518         if (nparams)
ragge
1.193
519             for (a = lparami = 0a != NULLa = a->prev) {
ragge
1.59
520                 p = a->sym;
ragge
1.56
521                 parr[i++] = p;
ragge
1.192
522                 if (p == NULL) {
gmcgarry
1.198
523                         uerror("parameter %d name missing"i);
524                         p = &nulsym/* empty symtab */
ragge
1.192
525                 }
ragge
1.59
526                 if (p->stype == FARG) {
527                         p->stype = INT;
528                         p->ssue = MKSUE(INT);
529                 }
530                 if (ISARY(p->stype)) {
531                         p->stype += (PTR-ARY);
532                         p->sdf++;
ragge
1.97
533                 } else if (ISFTN(p->stype)) {
534                         werror("function declared as argument");
535                         p->stype = INCREF(p->stype);
ragge
1.59
536                 }
ragge
1.124
537 #ifdef STABS
538                 if (gflag)
ragge
1.129
539                         stabs_newsym(p);
ragge
1.124
540 #endif
ragge
1.12
541         }
ragge
1.59
542         if (oldstyle && (df = cftnsp->sdf) && (al = df->dfun)) {
543                 /*
544                  * Check against prototype of oldstyle function.
545                  */
546                 alb = al2 = tmpalloc(sizeof(union arglist) * nparams * 3 + 1);
547                 for (i = 0i < nparamsi++) {
548                         TWORD type = parr[i]->stype;
549                         (al2++)->type = type;
550                         if (ISSTR(BTYPE(type)))
551                                 (al2++)->sue = parr[i]->ssue;
552                         while (!ISFTN(type) && !ISARY(type) && type > BTMASK)
553                                 type = DECREF(type);
554                         if (type > BTMASK)
555                                 (al2++)->df = parr[i]->sdf;
556                 }
557                 al2->type = TNULL;
ragge
1.60
558                 intcompare = 1;
ragge
1.59
559                 if (chkftn(alalb))
560                         uerror("function doesn't match prototype");
ragge
1.60
561                 intcompare = 0;
ragge
1.199
562
563         }
564
565         if (oldstyle && nparams) {
566                 /* Must recalculate offset for oldstyle args here */
567                 argoff = ARGINIT;
568                 for (i = 0i < nparamsi++) {
569                         parr[i]->soffset = NOOFFSET;
570                         oalloc(parr[i], &argoff);
571                 }
ragge
1.59
572         }
ragge
1.199
573
ragge
1.59
574 done:   cendarg();
ragge
1.192
575
ragge
1.144
576         plabel(prolab); /* after prolog, used in optimization */
577         retlab = getlab();
ragge
1.45
578         bfcode(parrnparams);
ragge
1.183
579         plabel(getlab()); /* used when spilling */
ragge
1.192
580         if (parlink)
581                 ecomp(parlink);
582         parlink = NIL;
ragge
1.47
583         lparam = NULL;
ragge
1.45
584         nparams = 0;
ragge
1.192
585         symclear(1);    /* In case of function pointer args */
ragge
1.2
586 }
ragge
1.1
587
ragge
1.21
588 /*
ragge
1.200
589  * Struct/union/enum symtab construction.
590  */
591 static void
592 defstr(struct symtab *spint class)
593 {
594         sp->ssue = permalloc(sizeof(struct suedef));
595         sp->ssue->suesize = 0;
596         sp->ssue->sylnk = NULL
597         sp->ssue->suealign = 0;
598         sp->sclass = class;
599         if (class == STNAME)
600                 sp->stype = STRTY;
601         else if (class == UNAME)
602                 sp->stype = UNIONTY;
603 }
604
605 /*
ragge
1.184
606  * Declare a struct/union/enum tag.
607  * If not found, create a new tag with UNDEF type.
608  */
609 static struct symtab *
610 deftag(char *nameint class)
611 {
612         struct symtab *sp;
613
ragge
1.193
614         if ((sp = lookup(nameSTAGNAME))->ssue == NULL) {
615                 /* New tag */
ragge
1.200
616                 defstr(spclass);
617         } else if (sp->sclass != class)
ragge
1.184
618                 uerror("tag %s redeclared"name);
619         return sp;
620 }
621
ragge
1.193
622 /*
623  * reference to a structure or union, with no definition
624  */
625 NODE *
626 rstruct(char *tagint soru)
627 {
628         struct symtab *sp;
629
630         sp = deftag(tagsoru);
ragge
1.194
631         return mkty(sp->stype0sp->ssue);
ragge
1.193
632 }
633
ragge
1.184
634 static int enumlowenumhigh;
635 int enummer;
636
637 /*
638  * Declare a member of enum.
639  */
ragge
1.2
640 void
ragge
1.33
641 moedef(char *name)
ragge
1.2
642 {
ragge
1.184
643         struct symtab *sp;
644
645         sp = lookup(nameSNORMAL);
646         if (sp->stype == UNDEF || (sp->slevel < blevel)) {
647                 if (sp->stype != UNDEF)
648                         sp = hide(sp);
649                 sp->stype = INT/* always */
650                 sp->ssue = MKSUE(INT);
651                 sp->sclass = MOE;
652                 sp->soffset = enummer;
653         } else
654                 uerror("%s redeclared"name);
655         if (enummer < enumlow)
656                 enumlow = enummer;
657         if (enummer > enumhigh)
658                 enumhigh = enummer;
659         enummer++;
660 }
661
662 /*
663  * Declare an enum tag.  Complain if already defined.
664  */
665 struct symtab *
666 enumhd(char *name)
667 {
668         struct symtab *sp;
669
670         enummer = enumlow = enumhigh = 0;
671         if (name == NULL)
672                 return NULL;
673
674         sp = deftag(nameENAME);
ragge
1.200
675         if (sp->stype != UNDEF) {
676                 if (sp->slevel == blevel)
677                         uerror("%s redeclared"name);
678                 sp = hide(sp);
679                 defstr(spENAME);
680         }
ragge
1.184
681         return sp;
682 }
683
684 /*
685  * finish declaration of an enum
686  */
687 NODE *
688 enumdcl(struct symtab *sp)
689 {
ragge
1.185
690         NODE *p;
ragge
1.184
691         TWORD t;
692
693 #ifdef ENUMSIZE
694         t = ENUMSIZE(enumhighenumlow);
695 #else
696         if (enumhigh <= MAX_CHAR && enumlow >= MIN_CHAR)
697                 t = ctype(CHAR);
698         else if (enumhigh <= MAX_SHORT && enumlow >= MIN_SHORT)
699                 t = ctype(SHORT);
700         else
701                 t = ctype(INT);
702 #endif
703         if (sp) {
704                 sp->stype = t;
705                 sp->ssue = MKSUE(t);
706         }
ragge
1.185
707         p = mkty(t0MKSUE(t));
708         p->n_sp = sp;
709         return p;
ragge
1.184
710 }
711
712 /*
713  * Handle reference to an enum
714  */
715 NODE *
716 enumref(char *name)
717 {
718         struct symtab *sp;
ragge
1.185
719         NODE *p;
ragge
1.184
720
721         sp = lookup(nameSTAGNAME);
722         if (sp->sclass != ENAME)
723                 uerror("enum %s undeclared"name);
ragge
1.1
724
ragge
1.185
725         p = mkty(sp->stype0sp->ssue);
726         p->n_sp = sp;
727         return p;
ragge
1.2
728 }
ragge
1.1
729
ragge
1.2
730 /*
731  * begining of structure or union declaration
732  */
ragge
1.43
733 struct rstack *
ragge
1.33
734 bstruct(char *nameint soru)
ragge
1.2
735 {
ragge
1.43
736         struct rstack *r;
ragge
1.193
737         struct symtab *sp;
738
739         if (name != NULL) {
740                 sp = deftag(namesoru);
ragge
1.200
741                 if (sp->ssue->suealign != 0) {
742                         if (sp->slevel < blevel) {
743                                 sp = hide(sp);
744                                 defstr(spsoru);
745                         } else
746                                 uerror("%s redeclared"name);
747                 }
ragge
1.194
748                 sp->ssue->suealign = ALSTRUCT;
ragge
1.193
749         } else
750                 sp = NULL;
ragge
1.1
751
ragge
1.217
752         r = tmpcalloc(sizeof(struct rstack));
ragge
1.194
753         r->rsou = soru;
ragge
1.193
754         r->rsym = sp;
ragge
1.194
755         r->rb = NULL;
ragge
1.193
756         r->rnext = rpole;
757         rpole = r;
ragge
1.43
758
759         return r;
ragge
1.2
760 }
ragge
1.1
761
ragge
1.18
762 /*
763  * Called after a struct is declared to restore the environment.
764  */
ragge
1.1
765 NODE *
ragge
1.190
766 dclstruct(struct rstack *r)
ragge
1.2
767 {
ragge
1.43
768         NODE *n;
769         struct suedef *sue;
ragge
1.194
770         struct symtab *sp;
ragge
1.178
771         int alsaszcoff;
ragge
1.2
772         TWORD temp;
ragge
1.1
773
ragge
1.43
774         if (r->rsym == NULL) {
775                 sue = permalloc(sizeof(struct suedef));
ragge
1.65
776                 suedefcnt++;
ragge
1.43
777                 sue->suesize = 0;
778                 sue->suealign = ALSTRUCT;
ragge
1.18
779         } else
ragge
1.43
780                 sue = r->rsym->ssue;
ragge
1.194
781         if (sue->suealign == 0)  /* suealign == 0 is undeclared struct */
782                 sue->suealign = ALSTRUCT;
ragge
1.1
783
ragge
1.43
784 #ifdef PCC_DEBUG
785         if (ddebug)
ragge
1.46
786                 printf("dclstruct(%s)\n"r->rsym ? r->rsym->sname : "??");
ragge
1.43
787 #endif
ragge
1.194
788         temp = r->rsou == STNAME ? STRTY : UNIONTY;
ragge
1.1
789         al = ALSTRUCT;
790
ragge
1.178
791         coff = 0;
ragge
1.190
792         if (pragma_packed || pragma_aligned)
ragge
1.194
793                 rpole->rstr = 0/* must recount it */
ragge
1.178
794
ragge
1.194
795         sue->sylnk = r->rb;
796         for (sp = r->rbspsp = sp->snext) {
797                 sa = talign(sp->stypesp->ssue);
798                 if (sp->sclass & FIELD)
799                         sz = sp->sclass&FLDSIZ;
ragge
1.178
800                 else
ragge
1.194
801                         sz = tsize(sp->stypesp->sdfsp->ssue);
ragge
1.178
802
ragge
1.190
803                 if (pragma_packed || pragma_aligned) {
804                         /* XXX check pack/align sizes */
ragge
1.194
805                         sp->soffset = coff;
ragge
1.190
806                         if (pragma_aligned)
ragge
1.178
807                                 coff += ALLDOUBLE;
808                         else
809                                 coff += sz;
ragge
1.194
810                         rpole->rstr = coff;
ragge
1.1
811                 }
ragge
1.178
812
ragge
1.194
813                 if (sz > rpole->rstr)
814                         rpole->rstr = sz;  /* for use with unions */
ragge
1.21
815                 /*
816                  * set al, the alignment, to the lcm of the alignments
817                  * of the members.
818                  */
819                 SETOFF(alsa);
820         }
ragge
1.194
821         SETOFF(rpole->rstral);
ragge
1.1
822
ragge
1.194
823         sue->suesize = rpole->rstr;
ragge
1.43
824         sue->suealign = al;
825
ragge
1.190
826         pragma_packed = pragma_aligned = 0;
827
ragge
1.124
828 #ifdef STABS
829         if (gflag)
ragge
1.129
830                 stabs_struct(r->rsymsue);
ragge
1.124
831 #endif
832
ragge
1.46
833 #ifdef PCC_DEBUG
ragge
1.21
834         if (ddebug>1) {
ragge
1.194
835                 printf("\tsize %d align %d link %p\n",
836                     sue->suesizesue->suealignsue->sylnk);
837                 for (sp = sue->sylnksp != NULLsp = sp->snext) {
838                         printf("\tmember %s(%p)\n"sp->snamesp);
ragge
1.1
839                 }
ragge
1.21
840         }
ragge
1.43
841 #endif
ragge
1.1
842
ragge
1.193
843         rpole = r->rnext;
ragge
1.46
844         n = mkty(temp