Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20150819185248

Diff

Diff from 1.416 to:

Annotations

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

Annotated File View

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