Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:gmcgarry:20080625061409

Diff

Diff from 1.209 to:

Annotations

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

Annotated File View

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