Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:gmcgarry:20090315100614

Diff

Diff from 1.255 to:

Annotations

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

Annotated File View

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