Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20140816161152

Diff

Diff from 1.381 to:

Annotations

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

Annotated File View

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