Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20080803125044

Diff

Diff from 1.220 to:

Annotations

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

Annotated File View

ragge
1.220
1 /*      $Id: pftn.c,v 1.220 2008/08/03 12:50:44 ragge Exp $     */
ragge
1.83
2 /*
3  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 /*
29  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
30  *
31  * Redistribution and use in source and binary forms, with or without
32  * modification, are permitted provided that the following conditions
33  * are met:
34  *
35  * Redistributions of source code and documentation must retain the above
36  * copyright notice, this list of conditions and the following disclaimer.
37  * Redistributions in binary form must reproduce the above copyright
38  * notice, this list of conditionsand the following disclaimer in the
39  * documentation and/or other materials provided with the distribution.
40  * All advertising materials mentioning features or use of this software
41  * must display the following acknowledgement:
42  *      This product includes software developed or owned by Caldera
43  *      International, Inc.
44  * Neither the name of Caldera International, Inc. nor the names of other
45  * contributors may be used to endorse or promote products derived from
46  * this software without specific prior written permission.
47  *
48  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
49  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
50  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
51  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
52  * DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
53  * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56  * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
57  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
58  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
59  * POSSIBILITY OF SUCH DAMAGE.
60  */
61
62 /*
63  * Many changes from the 32V sources, among them:
64  * - New symbol table manager (moved to another file).
65  * - Prototype saving/checks.
66  */
ragge
1.1
67
68 # include "pass1.h"
ragge
1.25
69
ragge
1.157
70 #include <string.h> /* XXX - for strcmp */
71
ragge
1.178
72 #include "cgram.h"
73
ragge
1.33
74 struct symtab *cftnsp;
ragge
1.65
75 int arglistcntdimfuncnt;      /* statistics */
ragge
1.69
76 int symtabcntsuedefcnt;       /* statistics */
77 int autooff,            /* the next unused automatic offset */
ragge
1.146
78     maxautooff,         /* highest used automatic offset in function */
ragge
1.194
79     argoff;             /* the next unused argument offset */
ragge
1.69
80 int retlab = NOLAB;     /* return label for subroutine */
81 int brklab;
82 int contlab;
83 int flostat;
ragge
1.194
84 int blevel;
ragge
1.150
85 int reachedprolab;
ragge
1.1
86
ragge
1.46
87 struct params;
88
ragge
1.184
89 #define ISSTR(ty) (ty == STRTY || ty == UNIONTY)
ragge
1.59
90 #define ISSOU(ty) (ty == STRTY || ty == UNIONTY)
91 #define MKTY(p, t, d, s) r = talloc(); *r = *p; \
ragge
1.74
92         r = argcast(rtds); *p = *rnfree(r);
ragge
1.59
93
ragge
1.43
94 /*
95  * Linked list stack while reading in structs.
96  */
ragge
1.194
97 struct rstack {
ragge
1.43
98         struct  rstack *rnext;
ragge
1.194
99         int     rsou;
100         int     rstr;
ragge
1.43
101         struct  symtab *rsym;
ragge
1.194
102         struct  symtab *rb;
ragge
1.217
103         int     flags;
104 #define LASTELM 1
ragge
1.193
105 } *rpole;
ragge
1.43
106
ragge
1.45
107 /*
ragge
1.47
108  * Linked list for parameter (and struct elements) declaration.
ragge
1.45
109  */
110 static struct params {
ragge
1.46
111         struct params *next, *prev;
ragge
1.45
112         struct symtab *sym;
ragge
1.47
113 } *lpole, *lparam;
ragge
1.45
114 static int nparams;
115
ragge
1.2
116 /* defines used for getting things off of the initialization stack */
ragge
1.1
117
ragge
1.30
118 static NODE *arrstk[10];
119 static int arrstkp;
ragge
1.60
120 static int intcompare;
ragge
1.192
121 static NODE *parlink;
ragge
1.1
122
ragge
1.2
123 void fixtype(NODE *pint class);
124 int fixclass(int classTWORD type);
125 int falloc(struct symtab *pint wint newNODE *pty);
ragge
1.30
126 static void dynalloc(struct symtab *pint *poff);
ragge
1.2
127 void inforce(OFFSZ n);
128 void vfdalign(int n);
ragge
1.46
129 static void ssave(struct symtab *);
ragge
1.168
130 static void alprint(union arglist *alint in);
131 static void lcommadd(struct symtab *sp);
ragge
1.1
132
133 int ddebug = 0;
134
ragge
1.168
135 /*
136  * Declaration of an identifier.  Handles redeclarations, hiding,
137  * incomplete types and forward declarations.
138  */
139
ragge
1.2
140 void
141 defid(NODE *qint class)
142 {
ragge
1.215
143         extern int fun_inline;
ragge
1.2
144         struct symtab *p;
ragge
1.92
145         TWORD typequal;
146         TWORD stpstq;
ragge
1.2
147         int scl;
ragge
1.52
148         union dimfun *dsym, *ddef;
ragge
1.124
149         int slevtempchanged;
ragge
1.1
150
ragge
1.32
151         if (q == NIL)
152                 return;  /* an error was detected */
ragge
1.1
153
ragge
1.33
154         p = q->n_sp;
ragge
1.1
155
ragge
1.220
156         if (p->sname == NULL)
157                 cerror("defining null identifier");
158
ragge
1.54
159 #ifdef PCC_DEBUG
ragge
1.4
160         if (ddebug) {
ragge
1.33
161                 printf("defid(%s (%p), "p->snamep);
ragge
1.104
162                 tprint(stdoutq->n_typeq->n_qual);
ragge
1.50
163                 printf(", %s, (%p,%p)), level %d\n"scnames(class),
ragge
1.52
164                     q->n_dfq->n_sueblevel);
ragge
1.4
165         }
ragge
1.54
166 #endif
ragge
1.1
167
ragge
1.33
168         fixtype(qclass);
ragge
1.1
169
ragge
1.31
170         type = q->n_type;
ragge
1.92
171         qual = q->n_qual;
ragge
1.33
172         class = fixclass(classtype);
ragge
1.1
173
174         stp = p->stype;
ragge
1.92
175         stq = p->squal;
ragge
1.1
176         slev = p->slevel;
177
ragge
1.54
178 #ifdef PCC_DEBUG
ragge
1.4
179         if (ddebug) {
180                 printf("        modified to ");
ragge
1.104
181                 tprint(stdouttypequal);
ragge
1.4
182                 printf(", %s\n"scnames(class));
183                 printf("        previous def'n: ");
ragge
1.104
184                 tprint(stdoutstpstq);
ragge
1.50
185                 printf(", %s, (%p,%p)), level %d\n",
ragge
1.52
186                     scnames(p->sclass), p->sdfp->ssueslev);
ragge
1.4
187         }
ragge
1.54
188 #endif
ragge
1.1
189
ragge
1.56
190         if (blevel == 1) {
ragge
1.33
191                 switch (class) {
ragge
1.1
192                 default:
ragge
1.192
193                         if (!(class&FIELD) && !ISFTN(type))
ragge
1.56
194                                 uerror("declared argument %s missing",
ragge
1.4
195                                     p->sname );
ragge
1.1
196                 case MOS:
197                 case MOU:
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.193
247         if ((temp == STRTY || temp == UNIONTY) && p->ssue != q->n_sue) {
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.193
258         if (class & FIELD)
259                 return;
260         switch(class) {
ragge
1.1
261
262         case EXTERN:
263                 switchscl ){
264                 case STATIC:
265                 case USTATIC:
ragge
1.216
266                         ifslev==0 )
267                                 goto done;
ragge
1.1
268                         break;
269                 case EXTDEF:
270                 case EXTERN:
271                 case FORTRAN:
272                 case UFORTRAN:
ragge
1.216
273                         goto done;
ragge
1.1
274                         }
275                 break;
276
277         case STATIC:
ragge
1.33
278                 if (scl==USTATIC || (scl==EXTERN && blevel==0)) {
ragge
1.1
279                         p->sclass = STATIC;
ragge
1.216
280                         goto done;
ragge
1.33
281                 }
ragge
1.168
282                 if (changed || (scl == STATIC && blevel == slev))
ragge
1.216
283                         goto done/* identical redeclaration */
ragge
1.1
284                 break;
285
286         case USTATIC:
ragge
1.33
287                 if (scl==STATIC || scl==USTATIC)
ragge
1.216
288                         goto done;
ragge
1.1
289                 break;
290
291         case TYPEDEF:
ragge
1.33
292                 if (scl == class)
ragge
1.216
293                         goto done;
ragge
1.1
294                 break;
295
296         case UFORTRAN:
ragge
1.33
297                 if (scl == UFORTRAN || scl == FORTRAN)
ragge
1.216
298                         goto done;
ragge
1.1
299                 break;
300
301         case FORTRAN:
ragge
1.33
302                 if (scl == UFORTRAN) {
ragge
1.1
303                         p->sclass = FORTRAN;
ragge
1.216
304                         goto done;
ragge
1.33
305                 }
ragge
1.1
306                 break;
307
308         case MOU:
309         case MOS:
ragge
1.216
310                 goto done;
ragge
1.1
311
312         case EXTDEF:
ragge
1.10
313                 switch (scl) {
314                 case EXTERN:
ragge
1.1
315                         p->sclass = EXTDEF;
ragge
1.216
316                         goto done;
ragge
1.10
317                 case USTATIC:
318                         p->sclass = STATIC;
ragge
1.216
319                         goto done;
ragge
1.10
320                 }
ragge
1.1
321                 break;
322
323         case AUTO:
324         case REGISTER:
ragge
1.192
325                 if (blevel == slev)
326                         goto redec;
ragge
1.215
327                 break;  /* mismatch.. */
328         case SNULL:
329                 if (fun_inline && ISFTN(type))
ragge
1.216
330                         goto done;
ragge
1.215
331                 break;
ragge
1.33
332         }
ragge
1.1
333
334         mismatch:
335
ragge
1.55
336         /*
337          * Only allowed for automatic variables.
338          */
339         if (blevel == slev || class == EXTERN || class == FORTRAN ||
340             class == UFORTRAN) {
ragge
1.158
341                 if (ISSTR(class) && !ISSTR(p->sclass)) {
ragge
1.192
342 redec:                  uerror("redeclaration of %s"p->sname);
ragge
1.158
343                         return;
344                 }
ragge
1.24
345         }
ragge
1.168
346         if (blevel == 0)
ragge
1.192
347                 goto redec;
ragge
1.55
348         q->n_sp = p = hide(p);
ragge
1.1
349
350         enter:  /* make a new entry */
351
ragge
1.54
352 #ifdef PCC_DEBUG
ragge
1.33
353         if(ddebug)
354                 printf("        new entry made\n");
ragge
1.54
355 #endif
ragge
1.1
356         p->stype = type;
ragge
1.93
357         p->squal = qual;
ragge
1.1
358         p->sclass = class;
359         p->slevel = blevel;
ragge
1.33
360         p->soffset = NOOFFSET;
ragge
1.193
361         if (q->n_sue == NULL)
362                 cerror("q->n_sue == NULL");
363         p->ssue = q->n_sue;
ragge
1.1
364
365         /* copy dimensions */
ragge
1.52
366         p->sdf = q->n_df;
ragge
1.68
367         /* Do not save param info for old-style functions */
368         if (ISFTN(type) && oldstyle)
369                 p->sdf->dfun = NULL;
ragge
1.1
370
371         /* allocate offsets */
ragge
1.33
372         if (class&FIELD) {
373                 (voidfalloc(pclass&FLDSIZ0NIL);  /* new entry */
374         } else switch (class) {
ragge
1.1
375
ragge
1.131
376         case REGISTER:
ragge
1.147
377                 cerror("register var");
ragge
1.131
378
ragge
1.1
379         case AUTO:
ragge
1.30
380                 if (arrstkp)
381                         dynalloc(p, &autooff);
382                 else
ragge
1.54
383                         oalloc(p, &autooff);
ragge
1.1
384                 break;
ragge
1.192
385         case PARAM:
ragge
1.196
386                 if (ISARY(p->stype)) {
387                         /* remove array type on parameters before oalloc */
388                         p->stype += (PTR-ARY);
389                         p->sdf++;
390                 }
ragge
1.192
391                 if (arrstkp)
392                         dynalloc(p, &argoff);
393                 else
394                         oalloc(p, &argoff);
395                 break;
396                 
ragge
1.1
397         case STATIC:
398         case EXTDEF:
399         case EXTERN:
400         case UFORTRAN:
401         case FORTRAN:
ragge
1.33
402                 p->soffset = getlab();
ragge
1.190
403                 if (pragma_renamed)
404                         p->soname = pragma_renamed;
405                 pragma_renamed = NULL;
ragge
1.1
406                 break;
ragge
1.190
407
ragge
1.1
408         case MOU:
409         case MOS:
ragge
1.194
410                 oalloc(p, &rpole->rstr);
ragge
1.54
411                 if (class == MOU)
ragge
1.194
412                         rpole->rstr = 0;
ragge
1.1
413                 break;
ragge
1.215
414         case SNULL:
415                 if (fun_inline) {
416                         p->slevel = 1;
417                         p->soffset = getlab();
418                 }
ragge
1.33
419         }
ragge
1.1
420
ragge
1.124
421 #ifdef STABS
422         if (gflag)
ragge
1.125
423                 stabs_newsym(p);
ragge
1.124
424 #endif
ragge
1.1
425
ragge
1.216
426 done:
ragge
1.190
427         fixdef(p);      /* Leave last word to target */
ragge
1.54
428 #ifdef PCC_DEBUG
ragge
1.33
429         if (ddebug)
ragge
1.52
430                 printf"       sdf, ssue, offset: %p, %p, %d\n",
431                     p->sdfp->ssuep->soffset);
ragge
1.54
432 #endif
ragge
1.33
433 }
ragge
1.1
434
ragge
1.2
435 void
ragge
1.46
436 ssave(struct symtab *sym)
ragge
1.2
437 {
ragge
1.46
438         struct params *p;
439
440         p = tmpalloc(sizeof(struct params));
441         p->next = NULL;
442         p->sym = sym;
443
ragge
1.193
444         if ((p->prev = lparam) == NULL)
ragge
1.46
445                 lpole = p;
ragge
1.193
446         else
ragge
1.46
447                 lparam->next = p;
448         lparam = p;
ragge
1.2
449 }
ragge
1.1
450
ragge
1.2
451 /*
452  * end of function
453  */
454 void
455 ftnend()
456 {
ragge
1.51
457         extern struct savbc *savbc;
ragge
1.62
458         extern struct swdef *swpole;
ragge
1.192
459         extern int tvaloff;
ragge
1.138
460         char *c;
ragge
1.51
461
ragge
1.69
462         if (retlab != NOLAB && nerrors == 0) { /* inside a real function */
ragge
1.134
463                 plabel(retlab);
ragge
1.112
464                 efcode(); /* struct return handled here */
ragge
1.190
465                 c = cftnsp->soname;
ragge
1.149
466                 SETOFF(maxautooffALCHAR);
467                 send_passt(IP_EPILOG0maxautooff/SZCHARc,
ragge
1.192
468                     cftnsp->stypecftnsp->sclass == EXTDEFretlabtvaloff);
ragge
1.69
469         }
ragge
1.33
470
ragge
1.1
471         tcheck();
472         brklab = contlab = retlab = NOLAB;
473         flostat = 0;
ragge
1.51
474         if (nerrors == 0) {
475                 if (savbc != NULL)
476                         cerror("bcsave error");
ragge
1.46
477                 if (lparam != NULL)
478                         cerror("parameter reset error");
ragge
1.62
479                 if (swpole != NULL)
480                         cerror("switch error");
ragge
1.46
481         }
ragge
1.51
482         savbc = NULL;
ragge
1.46
483         lparam = NULL;
ragge
1.146
484         maxautooff = autooff = AUTOINIT;
ragge
1.1
485         reached = 1;
ragge
1.66
486
487         if (isinlining)
488                 inline_end();
489         inline_prtout();
490
ragge
1.37
491         tmpfree(); /* Release memory resources */
ragge
1.2
492 }
ragge
1.89
493
gmcgarry
1.198
494 static struct symtab nulsym = {
495         { NULL0000 }, "null""null"INT0NULLNULL
496 };
497
ragge
1.2
498 void
499 dclargs()
500 {
ragge
1.59
501         union dimfun *df;
502         union arglist *al, *al2, *alb;
ragge
1.45
503         struct params *a;
ragge
1.123
504         struct symtab *p, **parr = NULL/* XXX gcc */
ragge
1.150
505         int i;
ragge
1.45
506
ragge
1.56
507         /*
ragge
1.59
508          * Deal with fun(void) properly.
509          */
gmcgarry
1.198
510         if (nparams == 1 && lparam->sym && lparam->sym->stype == VOID)
ragge
1.59
511                 goto done;
512
513         /*
ragge
1.56
514          * Generate a list for bfcode().
515          * Parameters were pushed in reverse order.
516          */
ragge
1.58
517         if (nparams != 0)
518                 parr = tmpalloc(sizeof(struct symtab *) * nparams);
ragge
1.56
519
ragge
1.140
520         if (nparams)
ragge
1.193
521             for (a = lparami = 0a != NULLa = a->prev) {
ragge
1.59
522                 p = a->sym;
ragge
1.56
523                 parr[i++] = p;
ragge
1.192
524                 if (p == NULL) {
gmcgarry
1.198
525                         uerror("parameter %d name missing"i);
526                         p = &nulsym/* empty symtab */
ragge
1.192
527                 }
ragge
1.59
528                 if (p->stype == FARG) {
529                         p->stype = INT;
530                         p->ssue = MKSUE(INT);
531                 }
532                 if (ISARY(p->stype)) {
533                         p->stype += (PTR-ARY);
534                         p->sdf++;
ragge
1.97
535                 } else if (ISFTN(p->stype)) {
536                         werror("function declared as argument");
537                         p->stype = INCREF(p->stype);
ragge
1.59
538                 }
ragge
1.124
539 #ifdef STABS
540                 if (gflag)
ragge
1.129
541                         stabs_newsym(p);
ragge
1.124
542 #endif
ragge
1.12
543         }
ragge
1.59
544         if (oldstyle && (df = cftnsp->sdf) && (al = df->dfun)) {
545                 /*
546                  * Check against prototype of oldstyle function.
547                  */
548                 alb = al2 = tmpalloc(sizeof(union arglist) * nparams * 3 + 1);
549                 for (i = 0i < nparamsi++) {
550                         TWORD type = parr[i]->stype;
551                         (al2++)->type = type;
552                         if (ISSTR(BTYPE(type)))
553                                 (al2++)->sue = parr[i]->ssue;
554                         while (!ISFTN(type) && !ISARY(type) && type > BTMASK)
555                                 type = DECREF(type);
556                         if (type > BTMASK)
557                                 (al2++)->df = parr[i]->sdf;
558                 }
559                 al2->type = TNULL;
ragge
1.60
560                 intcompare = 1;
ragge
1.59
561                 if (chkftn(alalb))
562                         uerror("function doesn't match prototype");
ragge
1.60
563                 intcompare = 0;
ragge
1.199
564
565         }
566
567         if (oldstyle && nparams) {
568                 /* Must recalculate offset for oldstyle args here */
569                 argoff = ARGINIT;
570                 for (i = 0i < nparamsi++) {
571                         parr[i]->soffset = NOOFFSET;
572                         oalloc(parr[i], &argoff);
573                 }
ragge
1.59
574         }
ragge
1.199
575
ragge
1.59
576 done:   cendarg();
ragge
1.192
577
ragge
1.144
578         plabel(prolab); /* after prolog, used in optimization */
579         retlab = getlab();
ragge
1.45
580         bfcode(parrnparams);
ragge
1.183
581         plabel(getlab()); /* used when spilling */
ragge
1.192
582         if (parlink)
583                 ecomp(parlink);
584         parlink = NIL;
ragge
1.47
585         lparam = NULL;
ragge
1.45
586         nparams = 0;
ragge
1.192
587         symclear(1);    /* In case of function pointer args */
ragge
1.2
588 }
ragge
1.1
589
ragge
1.21
590 /*
ragge
1.200
591  * Struct/union/enum symtab construction.
592  */
593 static void
594 defstr(struct symtab *spint class)
595 {
596         sp->ssue = permalloc(sizeof(struct suedef));
597         sp->ssue->suesize = 0;
598         sp->ssue->sylnk = NULL
599         sp->ssue->suealign = 0;
600         sp->sclass = class;
601         if (class == STNAME)
602                 sp->stype = STRTY;
603         else if (class == UNAME)
604                 sp->stype = UNIONTY;
605 }
606
607 /*
ragge
1.184
608  * Declare a struct/union/enum tag.
609  * If not found, create a new tag with UNDEF type.
610  */
611 static struct symtab *
612 deftag(char *nameint class)
613 {
614         struct symtab *sp;
615
ragge
1.193
616         if ((sp = lookup(nameSTAGNAME))->ssue == NULL) {
617                 /* New tag */
ragge
1.200
618                 defstr(spclass);
619         } else if (sp->sclass != class)
ragge
1.184
620                 uerror("tag %s redeclared"name);
621         return sp;
622 }
623
ragge
1.193
624 /*
625  * reference to a structure or union, with no definition
626  */
627 NODE *
628 rstruct(char *tagint soru)
629 {
630         struct symtab *sp;
631
632         sp = deftag(tagsoru);
ragge
1.194
633         return mkty(sp->stype0sp->ssue);
ragge
1.193
634 }
635
ragge
1.184
636 static int enumlowenumhigh;
637 int enummer;
638
639 /*
640  * Declare a member of enum.
641  */
ragge
1.2
642 void
ragge
1.33
643 moedef(char *name)
ragge
1.2
644 {
ragge
1.184
645         struct symtab *sp;
646
647         sp = lookup(nameSNORMAL);
648         if (sp->stype == UNDEF || (sp->slevel < blevel)) {
649                 if (sp->stype != UNDEF)
650                         sp = hide(sp);
651                 sp->stype = INT/* always */
652                 sp->ssue = MKSUE(INT);
653                 sp->sclass = MOE;
654                 sp->soffset = enummer;
655         } else
656                 uerror("%s redeclared"name);
657         if (enummer < enumlow)
658                 enumlow = enummer;
659         if (enummer > enumhigh)
660                 enumhigh = enummer;
661         enummer++;
662 }
663
664 /*
665  * Declare an enum tag.  Complain if already defined.
666  */
667 struct symtab *
668 enumhd(char *name)
669 {
670         struct symtab *sp;
671
672         enummer = enumlow = enumhigh = 0;
673         if (name == NULL)
674                 return NULL;
675
676         sp = deftag(nameENAME);
ragge
1.200
677         if (sp->stype != UNDEF) {
678                 if (sp->slevel == blevel)
679                         uerror("%s redeclared"name);
680                 sp = hide(sp);
681                 defstr(spENAME);
682         }
ragge
1.184
683         return sp;
684 }
685
686 /*
687  * finish declaration of an enum
688  */
689 NODE *
690 enumdcl(struct symtab *sp)
691 {
ragge
1.185
692         NODE *p;
ragge
1.184
693         TWORD t;
694
695 #ifdef ENUMSIZE
696         t = ENUMSIZE(enumhighenumlow);
697 #else
698         if (enumhigh <= MAX_CHAR && enumlow >= MIN_CHAR)
699                 t = ctype(CHAR);
700         else if (enumhigh <= MAX_SHORT && enumlow >= MIN_SHORT)
701                 t = ctype(SHORT);
702         else
703                 t = ctype(INT);
704 #endif
705         if (sp) {
706                 sp->stype = t;
707                 sp->ssue = MKSUE(t);
708         }
ragge
1.185
709         p = mkty(t0MKSUE(t));
710         p->n_sp = sp;
711         return p;
ragge
1.184
712 }
713
714 /*
715  * Handle reference to an enum
716  */
717 NODE *
718 enumref(char *name)
719 {
720         struct symtab *sp;
ragge
1.185
721         NODE *p;
ragge
1.184
722
723         sp = lookup(nameSTAGNAME);
ragge
1.219
724         /*
725          * 6.7.2.3 Clause 2:
726          * "A type specifier of the form 'enum identifier' without an
727          *  enumerator list shall only appear after the type it specifies
728          *  is complete."
729          */
ragge
1.184
730         if (sp->sclass != ENAME)
731                 uerror("enum %s undeclared"name);
ragge
1.1
732
ragge
1.185
733         p = mkty(sp->stype0sp->ssue);
734         p->n_sp = sp;
735         return p;
ragge
1.2
736 }
ragge
1.1
737
ragge
1.2
738 /*
739  * begining of structure or union declaration
740  */
ragge
1.43
741 struct rstack *
ragge
1.33
742 bstruct(char *nameint soru)
ragge
1.2
743 {
ragge
1.43
744         struct rstack *r;
ragge
1.193
745         struct symtab *sp;
746
747         if (name != NULL) {
748                 sp = deftag(namesoru);
ragge
1.200
749                 if (sp->ssue->suealign != 0) {
750                         if (sp->slevel < blevel) {
751                                 sp = hide(sp);
752                                 defstr(spsoru);
753                         } else
754                                 uerror("%s redeclared"name);
755                 }
ragge
1.194
756                 sp->ssue->suealign = ALSTRUCT;
ragge
1.193
757         } else
758                 sp = NULL;
ragge
1.1
759
ragge
1.217
760         r = tmpcalloc(sizeof(struct rstack));
ragge
1.194
761         r->rsou = soru;
ragge
1.193
762         r->rsym = sp;
ragge
1.194
763         r->rb = NULL;
ragge
1.193
764         r->rnext = rpole;
765         rpole = r;
ragge
1.43
766
767         return r;
ragge
1.2
768 }
ragge
1.1
769
ragge
1.18
770 /*
771  * Called after a struct is declared to restore the environment.
772  */
ragge
1.1
773 NODE *
ragge
1.190
774 dclstruct(struct rstack *r)
ragge
1.2
775 {
ragge
1.43
776         NODE *n;
777         struct suedef *sue;
ragge
1.194
778         struct symtab *sp;
ragge
1.178
779         int alsaszcoff;
ragge
1.2
780         TWORD temp;
ragge
1.1
781
ragge
1.43
782         if (r->rsym == NULL) {
783                 sue = permalloc(sizeof(struct suedef));
ragge
1.65
784                 suedefcnt++;
ragge
1.43
785                 sue->suesize = 0;
786                 sue->suealign = ALSTRUCT;
ragge
1.18
787         } else
ragge
1.43
788                 sue = r->rsym->ssue;
ragge
1.194
789         if (sue->suealign == 0)  /* suealign == 0 is undeclared struct */
790                 sue->suealign = ALSTRUCT;
ragge
1.1
791
ragge
1.43
792 #ifdef PCC_DEBUG
793         if (ddebug)
ragge
1.46
794                 printf("dclstruct(%s)\n"r->rsym ? r->rsym->sname : "??");
ragge
1.43
795 #endif
ragge
1.194
796         temp = r->rsou == STNAME ? STRTY : UNIONTY;
ragge
1.1
797         al = ALSTRUCT;
798
ragge
1.178
799         coff = 0;
ragge
1.190
800         if (pragma_packed || pragma_aligned)
ragge
1.194
801                 rpole->rstr = 0/* must recount it */
ragge
1.178
802
ragge
1.194
803         sue->sylnk = r->rb;
804         for (sp = r->rbspsp = sp->snext) {
805                 sa = talign(sp->stypesp->ssue);
806                 if (sp->sclass & FIELD)
807                         sz = sp->sclass&FLDSIZ;
ragge
1.178
808                 else
ragge
1.194
809                         sz = tsize(sp->stypesp->sdfsp->ssue);
ragge
1.178
810
ragge
1.190
811                 if (pragma_packed || pragma_aligned) {
812                         /* XXX check pack/align sizes */
ragge
1.194
813                         sp->soffset = coff;
ragge
1.190
814                         if (pragma_aligned)
ragge
1.178
815                                 coff += ALLDOUBLE;
816                         else
817                                 coff += sz;
ragge
1.194
818                         rpole->rstr = coff;
ragge
1.1
819                 }
ragge
1.178
820
ragge
1.194
821                 if (sz > rpole->rstr)
822                         rpole->rstr = sz;  /* for use with unions */
ragge
1.21
823                 /*
824                  * set al, the alignment, to the lcm of the alignments
825                  * of the members.
826                  */
827                 SETOFF(alsa);
828         }
ragge
1.194
829         SETOFF(rpole->rstral);
ragge
1.1
830
ragge
1.194
831         sue->suesize = rpole->rstr;
ragge
1.43
832         sue->suealign = al;
833
ragge
1.190
834         pragma_packed = pragma_aligned = 0;
835
ragge
1.124
836 #ifdef STABS
837         if (gflag)
ragge
1.129
838                 stabs_struct(r->rsymsue);
ragge
1.124
839 #endif
840
ragge
1.46
841 #ifdef PCC_DEBUG
ragge
1.21
842         if (ddebug>1) {
ragge
1.194
843                 printf("\tsize %d align %d link %p\n",
844                     sue->suesizesue->suealignsue->sylnk);
845                 for (sp = sue->sylnksp != NULLsp = sp->snext) {
846                         printf("\tmember %s(%p)\n"sp->snamesp);
ragge
1.1