Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:gmcgarry:20090519230951

Diff

Diff from 1.263 to:

Annotations

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

Annotated File View

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