Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20100508154745

Diff

Diff from 1.279 to:

Annotations

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

Annotated File View

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