Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20080729131308

Diff

Diff from 1.218 to:

Annotations

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

Annotated File View

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