Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20120811132920

Diff

Diff from 1.353 to:

Annotations

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

Annotated File View

ragge
1.353
1 /*      $Id: pftn.c,v 1.353 2012/08/11 13:29:20 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 *);
plunky
1.324
126 #ifdef PCC_DEBUG
ragge
1.168
127 static void alprint(union arglist *alint in);
plunky
1.324
128 #endif
ragge
1.168
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.1
132
ragge
1.347
133 void
134 defid(NODE *qint class)
135 {
136         defid2(qclass0);
137 }
138
ragge
1.168
139 /*
140  * Declaration of an identifier.  Handles redeclarations, hiding,
141  * incomplete types and forward declarations.
ragge
1.288
142  *
143  * q is a TYPE node setup after parsing with n_type, n_df and n_ap.
144  * n_sp is a pointer to the not-yet initalized symbol table entry
145  * unless it's a redeclaration or supposed to hide a variable.
ragge
1.168
146  */
147
ragge
1.2
148 void
ragge
1.347
149 defid2(NODE *qint classchar *astr)
ragge
1.2
150 {
ragge
1.306
151         struct attr *ap;
ragge
1.2
152         struct symtab *p;
ragge
1.92
153         TWORD typequal;
154         TWORD stpstq;
ragge
1.2
155         int scl;
ragge
1.52
156         union dimfun *dsym, *ddef;
ragge
1.124
157         int slevtempchanged;
ragge
1.1
158
ragge
1.32
159         if (q == NIL)
160                 return;  /* an error was detected */
ragge
1.1
161
ragge
1.353
162 #ifdef GCC_COMPAT
163         gcc_modefix(q);
164 #endif
ragge
1.33
165         p = q->n_sp;
ragge
1.1
166
ragge
1.220
167         if (p->sname == NULL)
168                 cerror("defining null identifier");
169
ragge
1.54
170 #ifdef PCC_DEBUG
ragge
1.4
171         if (ddebug) {
ragge
1.347
172                 printf("defid(%s '%s'(%p), "p->snamep->soname , p);
ragge
1.104
173                 tprint(stdoutq->n_typeq->n_qual);
ragge
1.288
174                 printf(", %s, (%p)), level %d\n\t"scnames(class),
175                     q->n_dfblevel);
176                 dump_attr(q->n_ap);
ragge
1.4
177         }
ragge
1.54
178 #endif
ragge
1.1
179
ragge
1.33
180         fixtype(qclass);
ragge
1.1
181
ragge
1.31
182         type = q->n_type;
ragge
1.92
183         qual = q->n_qual;
ragge
1.33
184         class = fixclass(classtype);
ragge
1.1
185
186         stp = p->stype;
ragge
1.92
187         stq = p->squal;
ragge
1.1
188         slev = p->slevel;
189
ragge
1.54
190 #ifdef PCC_DEBUG
ragge
1.4
191         if (ddebug) {
192                 printf("        modified to ");
ragge
1.104
193                 tprint(stdouttypequal);
ragge
1.4
194                 printf(", %s\n"scnames(class));
195                 printf("        previous def'n: ");
ragge
1.104
196                 tprint(stdoutstpstq);
ragge
1.50
197                 printf(", %s, (%p,%p)), level %d\n",
ragge
1.288
198                     scnames(p->sclass), p->sdfp->sapslev);
ragge
1.4
199         }
ragge
1.54
200 #endif
ragge
1.1
201
ragge
1.56
202         if (blevel == 1) {
ragge
1.33
203                 switch (class) {
ragge
1.1
204                 default:
ragge
1.192
205                         if (!(class&FIELD) && !ISFTN(type))
ragge
1.56
206                                 uerror("declared argument %s missing",
ragge
1.4
207                                     p->sname );
ragge
1.1
208                 case MOS:
209                 case MOU:
ragge
1.314
210                         cerror("field5");
ragge
1.1
211                 case TYPEDEF:
ragge
1.192
212                 case PARAM:
ragge
1.1
213                         ;
ragge
1.56
214                 }
ragge
1.4
215         }
ragge
1.56
216
217         if (stp == UNDEF)
218                 goto enter/* New symbol */
ragge
1.1
219
ragge
1.33
220         if (type != stp)
221                 goto mismatch;
222
223         if (blevel > slev && (class == AUTO || class == REGISTER))
ragge
1.1
224                 /* new scope */
225                 goto mismatch;
226
ragge
1.55
227         /*
228          * test (and possibly adjust) dimensions.
229          * also check that prototypes are correct.
230          */
ragge
1.52
231         dsym = p->sdf;
232         ddef = q->n_df;
ragge
1.124
233         changed = 0;
ragge
1.55
234         for (temp = typetemp & TMASKtemp = DECREF(temp)) {
235                 if (ISARY(temp)) {
ragge
1.221
236                         if (dsym->ddim == NOOFFSET) {
ragge
1.52
237                                 dsym->ddim = ddef->ddim;
ragge
1.124
238                                 changed = 1;
ragge
1.221
239                         } else if (ddef->ddim != NOOFFSET &&
240                             dsym->ddim!=ddef->ddim) {
ragge
1.1
241                                 goto mismatch;
ragge
1.50
242                         }
ragge
1.1
243                         ++dsym;
244                         ++ddef;
ragge
1.55
245                 } else if (ISFTN(temp)) {
ragge
1.110
246                         /* add a late-defined prototype here */
247                         if (cftnsp == NULL && dsym->dfun == NULL)
248                                 dsym->dfun = ddef->dfun;
ragge
1.109
249                         if (!oldstyle && ddef->dfun != NULL &&
250                             chkftn(dsym->dfunddef->dfun))
ragge
1.59
251                                 uerror("declaration doesn't match prototype");
ragge
1.55
252                         dsym++, ddef++;
ragge
1.1
253                 }
ragge
1.50
254         }
ragge
1.124
255 #ifdef STABS
256         if (changed && gflag)
ragge
1.125
257                 stabs_chgsym(p); /* symbol changed */
ragge
1.124
258 #endif
ragge
1.1
259
260         /* check that redeclarations are to the same structure */
ragge
1.246
261         if (temp == STRTY || temp == UNIONTY) {
ragge
1.288
262                 if (strmemb(p->sap) != strmemb(q->n_ap))
ragge
1.246
263                         goto mismatch;
ragge
1.33
264         }
ragge
1.1
265
ragge
1.33
266         scl = p->sclass;
ragge
1.1
267
ragge
1.54
268 #ifdef PCC_DEBUG
ragge
1.33
269         if (ddebug)
270                 printf("        previous class: %s\n"scnames(scl));
ragge
1.54
271 #endif
ragge
1.1
272
ragge
1.288
273         /*
274          * Its allowed to add attributes to existing declarations.
ragge
1.318
275          * Be careful though not to trash existing attributes.
276          * XXX - code below is probably not correct.
ragge
1.288
277          */
ragge
1.312
278         if (p->sap && p->sap->atype <= ATTR_MAX) {
ragge
1.288
279                 /* nothing special, just overwrite */
280                 p->sap = q->n_ap;
281         } else {
ragge
1.318
282                 if (p->slevel == blevel) {
283                         for (ap = q->n_apapap = ap->next) {
284                                 if (ap->atype > ATTR_MAX)
285                                         p->sap = attr_add(p->sapattr_dup(ap3));
286                         }
287                 } else
288                         p->sap = q->n_ap;
ragge
1.288
289         }
ragge
1.270
290
ragge
1.193
291         if (class & FIELD)
ragge
1.314
292                 cerror("field1");
ragge
1.193
293         switch(class) {
ragge
1.1
294
295         case EXTERN:
ragge
1.347
296                 if (astr)
297                         p->soname = astr;
ragge
1.1
298                 switchscl ){
299                 case STATIC:
300                 case USTATIC:
ragge
1.216
301                         ifslev==0 )
302                                 goto done;
ragge
1.1
303                         break;
304                 case EXTDEF:
305                 case EXTERN:
ragge
1.216
306                         goto done;
ragge
1.231
307                 case SNULL:
308                         if (p->sflags & SINLINE) {
309                                 p->sclass = EXTDEF;
310                                 inline_ref(p);
311                                 goto done;
ragge
1.1
312                         }
ragge
1.231
313                         break;
314                 }
ragge
1.1
315                 break;
316
317         case STATIC:
ragge
1.33
318                 if (scl==USTATIC || (scl==EXTERN && blevel==0)) {
ragge
1.1
319                         p->sclass = STATIC;
ragge
1.216
320                         goto done;
ragge
1.33
321                 }
ragge
1.168
322                 if (changed || (scl == STATIC && blevel == slev))
ragge
1.216
323                         goto done/* identical redeclaration */
ragge
1.1
324                 break;
325
326         case USTATIC:
ragge
1.33
327                 if (scl==STATIC || scl==USTATIC)
ragge
1.216
328                         goto done;
ragge
1.1
329                 break;
330
331         case TYPEDEF:
ragge
1.33
332                 if (scl == class)
ragge
1.216
333                         goto done;
ragge
1.1
334                 break;
335
336         case MOU:
337         case MOS:
ragge
1.314
338                 cerror("field6");
ragge
1.1
339
340         case EXTDEF:
ragge
1.10
341                 switch (scl) {
342                 case EXTERN:
ragge
1.1
343                         p->sclass = EXTDEF;
ragge
1.216
344                         goto done;
ragge
1.10
345                 case USTATIC:
346                         p->sclass = STATIC;
ragge
1.216
347                         goto done;
ragge
1.270
348                 case SNULL:
349                         /*
350                          * Handle redeclarations of inlined functions.
351                          * This is allowed if the previous declaration is of
352                          * type gnu_inline.
353                          */
ragge
1.288
354                         if (attr_find(p->sapGCC_ATYP_GNU_INLINE))
ragge
1.270
355                                 goto done;
356                         break;
ragge
1.10
357                 }
ragge
1.1
358                 break;
359
360         case AUTO:
361         case REGISTER:
ragge
1.215
362                 break;  /* mismatch.. */
363         case SNULL:
ragge
1.350
364                 if (fun_inline && ISFTN(type)) {
365                         if (scl == EXTERN) {
366                                 p->sclass = EXTDEF;
367                                 inline_ref(p);
368                         }
ragge
1.216
369                         goto done;
ragge
1.350
370                 }
ragge
1.215
371                 break;
ragge
1.33
372         }
ragge
1.1
373
374         mismatch:
375
ragge
1.55
376         /*
377          * Only allowed for automatic variables.
378          */
ragge
1.349
379         if ((blevel == 2 && slev == 1) || blevel <= slev || class == EXTERN) {
ragge
1.290
380                 uerror("redeclaration of %s"p->sname);
381                 return;
ragge
1.24
382         }
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.348
391         if (type < STRTY && (ap = attr_find(q->n_apGCC_ATYP_MODE))) {
ragge
1.343
392                 int u = ISUNSIGNED(type);
plunky
1.346
393                 type = u ? ENUNSIGN(ap->iarg(0)) : (TWORD)ap->iarg(0);
ragge
1.312
394                 if (type == XTYPE)
ragge
1.306
395                         uerror("fix XTYPE basetyp");
396         }
ragge
1.307
397         p->stype = type;
ragge
1.93
398         p->squal = qual;
gmcgarry
1.266
399         p->sclass = (char)class;
400         p->slevel = (char)blevel;
ragge
1.33
401         p->soffset = NOOFFSET;
ragge
1.312
402         if (q->n_ap)
403                 p->sap = attr_add(q->n_app->sap);
ragge
1.1
404
405         /* copy dimensions */
ragge
1.52
406         p->sdf = q->n_df;
ragge
1.68
407         /* Do not save param info for old-style functions */
408         if (ISFTN(type) && oldstyle)
409                 p->sdf->dfun = NULL;
ragge
1.1
410
ragge
1.293
411         if (arrstkp)
412                 evalidx(p);
413
ragge
1.1
414         /* allocate offsets */
ragge
1.33
415         if (class&FIELD) {
ragge
1.314
416                 cerror("field2");  /* new entry */
ragge
1.33
417         } else switch (class) {
ragge
1.1
418
ragge
1.131
419         case REGISTER:
ragge
1.347
420                 if (astr != NULL)
421                         werror("no register assignment (yet)");
422                 /* FALLTHROUGH */
ragge
1.1
423         case AUTO:
ragge
1.293
424                 if (isdyn(p)) {
425                         p->sflags |= SDYNARRAY;
ragge
1.30
426                         dynalloc(p, &autooff);
ragge
1.293
427                 } else
ragge
1.54
428                         oalloc(p, &autooff);
ragge
1.1
429                 break;
ragge
1.293
430
ragge
1.192
431         case PARAM:
ragge
1.313
432                 if (q->n_type != FARG)
433                         oalloc(p, &argoff);
ragge
1.192
434                 break;
435                 
ragge
1.1
436         case STATIC:
437         case EXTDEF:
438         case EXTERN:
ragge
1.33
439                 p->soffset = getlab();
ragge
1.347
440                 if (astr)
441                         p->soname = astr;
ragge
1.1
442                 break;
ragge
1.190
443
ragge
1.1
444         case MOU:
445         case MOS:
ragge
1.314
446                 cerror("field7");
ragge
1.215
447         case SNULL:
ragge
1.231
448 #ifdef notdef
ragge
1.215
449                 if (fun_inline) {
450                         p->slevel = 1;
451                         p->soffset = getlab();
452                 }
ragge
1.231
453 #endif
454                 break;
ragge
1.33
455         }
ragge
1.1
456
ragge
1.124
457 #ifdef STABS
ragge
1.312
458         if (gflag && p->stype != FARG)
ragge
1.125
459                 stabs_newsym(p);
ragge
1.124
460 #endif
ragge
1.1
461
ragge
1.216
462 done:
ragge
1.190
463         fixdef(p);      /* Leave last word to target */
ragge
1.281
464 #ifndef HAVE_WEAKREF
465         {
ragge
1.288
466                 struct attr *at;
ragge
1.281
467
468                 /* Refer renamed function */
ragge
1.288
469                 if ((at = attr_find(p->sapGCC_ATYP_WEAKREF)))
470                         p->soname = at->sarg(0);
ragge
1.281
471         }
472 #endif
ragge
1.54
473 #ifdef PCC_DEBUG
ragge
1.288
474         if (ddebug) {
475                 printf"       sdf, offset: %p, %d\n\t",
476                     p->sdfp->soffset);
477                 dump_attr(p->sap);
478         }
ragge
1.54
479 #endif
ragge
1.33
480 }
ragge
1.1
481
ragge
1.2
482 void
ragge
1.46
483 ssave(struct symtab *sym)
ragge
1.2
484 {
ragge
1.46
485         struct params *p;
486
487         p = tmpalloc(sizeof(struct params));
488         p->next = NULL;
489         p->sym = sym;
490
ragge
1.193
491         if ((p->prev = lparam) == NULL)
ragge
1.46
492                 lpole = p;
ragge
1.193
493         else
ragge
1.46
494                 lparam->next = p;
495         lparam = p;
ragge
1.2
496 }
ragge
1.1
497
ragge
1.2
498 /*
499  * end of function
500  */
501 void
plunky
1.345
502 ftnend(void)
ragge
1.2
503 {
ragge
1.326
504         struct attr *gc, *gd;
ragge
1.228
505         extern NODE *cftnod;
ragge
1.51
506         extern struct savbc *savbc;
ragge
1.62
507         extern struct swdef *swpole;
ragge
1.192
508         extern int tvaloff;
ragge
1.138
509         char *c;
ragge
1.51
510
ragge
1.69
511         if (retlab != NOLAB && nerrors == 0) { /* inside a real function */
ragge
1.134
512                 plabel(retlab);
ragge
1.228
513                 if (cftnod)
514                         ecomp(buildtree(FORCEcftnodNIL));
ragge
1.112
515                 efcode(); /* struct return handled here */
ragge
1.250
516                 if ((c = cftnsp->soname) == NULL)
517                         c = addname(exname(cftnsp->sname));
ragge
1.149
518                 SETOFF(maxautooffALCHAR);
mickey
1.229
519                 send_passt(IP_EPILOGmaxautooff/SZCHARc,
ragge
1.192
520                     cftnsp->stypecftnsp->sclass == EXTDEFretlabtvaloff);
ragge
1.69
521         }
ragge
1.33
522
ragge
1.228
523         cftnod = NIL;
ragge
1.1
524         tcheck();
525         brklab = contlab = retlab = NOLAB;
526         flostat = 0;
ragge
1.51
527         if (nerrors == 0) {
528                 if (savbc != NULL)
529                         cerror("bcsave error");
ragge
1.46
530                 if (lparam != NULL)
531                         cerror("parameter reset error");
ragge
1.62
532                 if (swpole != NULL)
533                         cerror("switch error");
ragge
1.46
534         }
ragge
1.326
535         if (cftnsp) {
536                 gc = attr_find(cftnsp->sapGCC_ATYP_CONSTRUCTOR);
537                 gd = attr_find(cftnsp->sapGCC_ATYP_DESTRUCTOR);
538                 if (gc || gd) {
539                         struct symtab sts = *cftnsp;
540                         NODE *p;
541                         sts.stype = INCREF(sts.stype);
542                         p = nametree(&sts);
543                         p->n_op = ICON;
544                         if (gc) {
545                                 locctr(CTORS, &sts);
546                                 inval(0SZPOINT(0), p);
547                         }
548                         if (gd) {
549                                 locctr(DTORS, &sts);
550                                 inval(0SZPOINT(0), p);
551                         }
552                         tfree(p);
553                 }
554         }
ragge
1.51
555         savbc = NULL;
ragge
1.46
556         lparam = NULL;
ragge
1.234
557         cftnsp = NULL;
ragge
1.146
558         maxautooff = autooff = AUTOINIT;
ragge
1.1
559         reached = 1;
ragge
1.66
560
561         if (isinlining)
562                 inline_end();
563         inline_prtout();
564
ragge
1.37
565         tmpfree(); /* Release memory resources */
ragge
1.2
566 }
ragge
1.89
567
gmcgarry
1.198
568 static struct symtab nulsym = {
pantzer
1.239
569         NULL0000"null""null"INT0NULLNULL
gmcgarry
1.198
570 };
571
ragge
1.2
572 void
plunky
1.345
573 dclargs(void)
ragge
1.2
574 {
ragge
1.59
575         union dimfun *df;
576         union arglist *al, *al2, *alb;
ragge
1.45
577         struct params *a;
ragge
1.123
578         struct symtab *p, **parr = NULL/* XXX gcc */
ragge
1.150
579         int i;
ragge
1.45
580
ragge
1.56
581         /*
ragge
1.59
582          * Deal with fun(void) properly.
583          */
gmcgarry
1.198
584         if (nparams == 1 && lparam->sym && lparam->sym->stype == VOID)
ragge
1.59
585                 goto done;
586
587         /*
ragge
1.56
588          * Generate a list for bfcode().
589          * Parameters were pushed in reverse order.
590          */
ragge
1.58
591         if (nparams != 0)
592                 parr = tmpalloc(sizeof(struct symtab *) * nparams);
ragge
1.56
593
ragge
1.140
594         if (nparams)
ragge
1.193
595             for (a = lparami = 0a != NULLa = a->prev) {
ragge
1.59
596                 p = a->sym;
ragge
1.56
597                 parr[i++] = p;
ragge
1.192
598                 if (p == NULL) {
gmcgarry
1.198
599                         uerror("parameter %d name missing"i);
600                         p = &nulsym/* empty symtab */
ragge
1.192
601                 }
ragge
1.312
602                 if (p->stype == FARG)
ragge
1.59
603                         p->stype = INT;
604                 if (ISARY(p->stype)) {
605                         p->stype += (PTR-ARY);
606                         p->sdf++;
ragge
1.97
607                 } else if (ISFTN(p->stype)) {
608                         werror("function declared as argument");
609                         p->stype = INCREF(p->stype);
ragge
1.59
610                 }
ragge
1.124
611 #ifdef STABS
612                 if (gflag)
ragge
1.129
613                         stabs_newsym(p);
ragge
1.124
614 #endif
ragge
1.12
615         }
ragge
1.59
616         if (oldstyle && (df = cftnsp->sdf) && (al = df->dfun)) {
617                 /*
618                  * Check against prototype of oldstyle function.
619                  */
620                 alb = al2 = tmpalloc(sizeof(union arglist) * nparams * 3 + 1);
621                 for (i = 0i < nparamsi++) {
622                         TWORD type = parr[i]->stype;
623                         (al2++)->type = type;
ragge
1.288
624                         if (ISSOU(BTYPE(type)))
625                                 (al2++)->sap = parr[i]->sap;
ragge
1.59
626                         while (!ISFTN(type) && !ISARY(type) && type > BTMASK)
627                                 type = DECREF(type);
628                         if (type > BTMASK)
629                                 (al2++)->df = parr[i]->sdf;
630                 }
631                 al2->type = TNULL;
ragge
1.60
632                 intcompare = 1;
ragge
1.59
633                 if (chkftn(alalb))
634                         uerror("function doesn't match prototype");
ragge
1.60
635                 intcompare = 0;
ragge
1.199
636
637         }
638
639         if (oldstyle && nparams) {
640                 /* Must recalculate offset for oldstyle args here */
641                 argoff = ARGINIT;
642                 for (i = 0i < nparamsi++) {
643                         parr[i]->soffset = NOOFFSET;
644                         oalloc(parr[i], &argoff);
645                 }
ragge
1.59
646         }
ragge
1.199
647
ragge
1.321
648 done:   autooff = AUTOINIT;
ragge
1.192
649
ragge
1.144
650         plabel(prolab); /* after prolog, used in optimization */
651         retlab = getlab();
ragge
1.45
652         bfcode(parrnparams);
ragge
1.284
653         if (fun_inline &&
ragge
1.288
654             (xinline || attr_find(cftnsp->sapGCC_ATYP_ALW_INL)))
ragge
1.231
655                 inline_args(parrnparams);
ragge
1.183
656         plabel(getlab()); /* used when spilling */
ragge
1.192
657         if (parlink)
658                 ecomp(parlink);
659         parlink = NIL;
ragge
1.47
660         lparam = NULL;
ragge
1.45
661         nparams = 0;
ragge
1.192
662         symclear(1);    /* In case of function pointer args */
ragge
1.2
663 }
ragge
1.1
664
ragge
1.243
665 /*
ragge
1.288
666  * basic attributes for structs and enums
ragge
1.243
667  */
ragge
1.288
668 static struct attr *
669 seattr(void)
ragge
1.243
670 {
ragge
1.312
671         return attr_add(attr_new(GCC_ATYP_ALIGNED4), attr_new(ATTR_STRUCT2));
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 {
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.288
698         if ((sp = lookup(nameSTAGNAME))->sap == NULL) {
ragge
1.193
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.288
715         if (sp->sap == NULL)
716                 sp->sap = seattr();
717         return mkty(sp->stype0sp->sap);
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->sclass = MOE;
737                 sp->soffset = enummer;
738         } else
739                 uerror("%s redeclared"name);
740         if (enummer < enumlow)
741                 enumlow = enummer;
742         if (enummer > enumhigh)
743                 enumhigh = enummer;
744         enummer++;
745 }
746
747 /*
748  * Declare an enum tag.  Complain if already defined.
749  */
750 struct symtab *
751 enumhd(char *name)
752 {
ragge
1.288
753         struct attr *ap;
ragge
1.184
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.288
767         if (sp->sap == NULL)
ragge
1.312
768                 ap = sp->sap = attr_new(ATTR_STRUCT4);
769         else
770                 ap = attr_find(sp->sapATTR_STRUCT);
ragge
1.288
771         ap->amlist = sp;
ragge
1.184
772         return sp;
773 }
774
775 /*
776  * finish declaration of an enum
777  */
778 NODE *
779 enumdcl(struct symtab *sp)
780 {
ragge
1.185
781         NODE *p;
ragge
1.184
782         TWORD t;
783
784 #ifdef ENUMSIZE
785         t = ENUMSIZE(enumhighenumlow);
786 #else
ragge
1.316
787         t = ctype(enumlow < 0 ? INT : UNSIGNED);
788 #ifdef notdef
ragge
1.184
789         if (enumhigh <= MAX_CHAR && enumlow >= MIN_CHAR)
790                 t = ctype(CHAR);
791         else if (enumhigh <= MAX_SHORT && enumlow >= MIN_SHORT)
792                 t = ctype(SHORT);
793         else
794                 t = ctype(INT);
795 #endif
ragge
1.316
796 #endif
ragge
1.288
797         
ragge
1.312
798         if (sp)
ragge
1.184
799                 sp->stype = t;
ragge
1.312
800         p = mkty(t00);
ragge
1.185
801         p->n_sp = sp;
802         return p;
ragge
1.184
803 }
804
805 /*
mickey
1.229
806  * Handle reference to an enum
ragge
1.184
807  */
808 NODE *
809 enumref(char *name)
810 {
811         struct symtab *sp;
ragge
1.185
812         NODE *p;
ragge
1.184
813
814         sp = lookup(nameSTAGNAME);
ragge
1.232
815
816 #ifdef notdef
ragge
1.219
817         /*
818          * 6.7.2.3 Clause 2:
819          * "A type specifier of the form 'enum identifier' without an
820          *  enumerator list shall only appear after the type it specifies
821          *  is complete."
822          */
ragge
1.184
823         if (sp->sclass != ENAME)
824                 uerror("enum %s undeclared"name);
ragge
1.232
825 #endif
826         if (sp->sclass == SNULL) {
827                 /* declare existence of enum */
828                 sp = enumhd(name);
829                 sp->stype = ENUMTY;
830         }
ragge
1.1
831
ragge
1.288