Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20100401122656

Diff

Diff from 1.276 to:

Annotations

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

Annotated File View

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