Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20080728113247

Diff

Diff from 1.216 to:

Annotations

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

Annotated File View

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