Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20080101171757

Diff

Diff from 1.190 to:

Annotations

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

Annotated File View

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