Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20080106150706

Diff

Diff from 1.191 to:

Annotations

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

Annotated File View

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