Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20080126221617

Diff

Diff from 1.192 to:

Annotations

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

Annotated File View

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