Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20090114211001

Diff

Diff from 1.245 to:

Annotations

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

Annotated File View

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