Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20101126064434

Diff

Diff from 1.302 to:

Annotations

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

Annotated File View

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