Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20160107200555

Diff

Diff from 1.420 to:

Annotations

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

Annotated File View

ragge
1.420
1 /*      $Id: pftn.c,v 1.420 2016/01/07 20:05:56 ragge Exp $     */
ragge
1.83
2 /*
3  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 /*
27  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
28  *
29  * Redistribution and use in source and binary forms, with or without
30  * modification, are permitted provided that the following conditions
31  * are met:
32  *
33  * Redistributions of source code and documentation must retain the above
34  * copyright notice, this list of conditions and the following disclaimer.
35  * Redistributions in binary form must reproduce the above copyright
36  * notice, this list of conditionsand the following disclaimer in the
37  * documentation and/or other materials provided with the distribution.
38  * All advertising materials mentioning features or use of this software
39  * must display the following acknowledgement:
40  *      This product includes software developed or owned by Caldera
41  *      International, Inc.
42  * Neither the name of Caldera International, Inc. nor the names of other
43  * contributors may be used to endorse or promote products derived from
44  * this software without specific prior written permission.
45  *
46  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
47  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
48  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
49  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
50  * DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
51  * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
52  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
53  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
54  * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
55  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
56  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
57  * POSSIBILITY OF SUCH DAMAGE.
58  */
59
60 /*
61  * Many changes from the 32V sources, among them:
62  * - New symbol table manager (moved to another file).
63  * - Prototype saving/checks.
64  */
ragge
1.1
65
66 # include "pass1.h"
ragge
1.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.417
152 static void
153 addsoname(struct symtab *spchar *so)
154 {
155         struct attr *ap = attr_new(ATTR_SONAME1);
156         ap->sarg(0) = so;
157         sp->sap = attr_add(sp->sapap);
158 }
159
ragge
1.168
160 /*
161  * Declaration of an identifier.  Handles redeclarations, hiding,
162  * incomplete types and forward declarations.
ragge
1.288
163  *
164  * q is a TYPE node setup after parsing with n_type, n_df and n_ap.
165  * n_sp is a pointer to the not-yet initalized symbol table entry
166  * unless it's a redeclaration or supposed to hide a variable.
ragge
1.168
167  */
168
ragge
1.2
169 void
ragge
1.347
170 defid2(NODE *qint classchar *astr)
ragge
1.2
171 {
ragge
1.306
172         struct attr *ap;
ragge
1.2
173         struct symtab *p;
ragge
1.92
174         TWORD typequal;
175         TWORD stpstq;
ragge
1.2
176         int scl;
ragge
1.52
177         union dimfun *dsym, *ddef;
ragge
1.124
178         int slevtempchanged;
ragge
1.1
179
ragge
1.32
180         if (q == NIL)
181                 return;  /* an error was detected */
ragge
1.1
182
ragge
1.353
183 #ifdef GCC_COMPAT
184         gcc_modefix(q);
185 #endif
ragge
1.33
186         p = q->n_sp;
ragge
1.1
187
ragge
1.220
188         if (p->sname == NULL)
189                 cerror("defining null identifier");
190
ragge
1.54
191 #ifdef PCC_DEBUG
ragge
1.4
192         if (ddebug) {
ragge
1.417
193                 printf("defid(%s '%s'(%p), "p->sname"soname" , p);
plunky
1.359
194                 tprint(q->n_typeq->n_qual);
ragge
1.288
195                 printf(", %s, (%p)), level %d\n\t"scnames(class),
196                     q->n_dfblevel);
ragge
1.368
197 #ifdef GCC_COMPAT
ragge
1.288
198                 dump_attr(q->n_ap);
ragge
1.368
199 #endif
ragge
1.4
200         }
ragge
1.54
201 #endif
ragge
1.1
202
ragge
1.33
203         fixtype(qclass);
ragge
1.1
204
ragge
1.31
205         type = q->n_type;
ragge
1.92
206         qual = q->n_qual;
ragge
1.33
207         class = fixclass(classtype);
ragge
1.1
208
209         stp = p->stype;
ragge
1.92
210         stq = p->squal;
ragge
1.1
211         slev = p->slevel;
212
ragge
1.54
213 #ifdef PCC_DEBUG
ragge
1.4
214         if (ddebug) {
215                 printf("        modified to ");
plunky
1.359
216                 tprint(typequal);
ragge
1.4
217                 printf(", %s\n"scnames(class));
218                 printf("        previous def'n: ");
plunky
1.359
219                 tprint(stpstq);
ragge
1.50
220                 printf(", %s, (%p,%p)), level %d\n",
ragge
1.288
221                     scnames(p->sclass), p->sdfp->sapslev);
ragge
1.4
222         }
ragge
1.54
223 #endif
ragge
1.1
224
ragge
1.56
225         if (blevel == 1) {
ragge
1.33
226                 switch (class) {
ragge
1.1
227                 default:
ragge
1.192
228                         if (!(class&FIELD) && !ISFTN(type))
ragge
1.56
229                                 uerror("declared argument %s missing",
ragge
1.4
230                                     p->sname );
plunky
1.361
231                         break;
ragge
1.1
232                 case MOS:
233                 case MOU:
ragge
1.314
234                         cerror("field5");
ragge
1.1
235                 case TYPEDEF:
ragge
1.192
236                 case PARAM:
plunky
1.361
237                         break;
ragge
1.56
238                 }
ragge
1.4
239         }
ragge
1.56
240
241         if (stp == UNDEF)
242                 goto enter/* New symbol */
ragge
1.1
243
ragge
1.33
244         if (type != stp)
245                 goto mismatch;
246
247         if (blevel > slev && (class == AUTO || class == REGISTER))
ragge
1.1
248                 /* new scope */
249                 goto mismatch;
250
ragge
1.55
251         /*
252          * test (and possibly adjust) dimensions.
253          * also check that prototypes are correct.
254          */
ragge
1.52
255         dsym = p->sdf;
256         ddef = q->n_df;
ragge
1.124
257         changed = 0;
ragge
1.55
258         for (temp = typetemp & TMASKtemp = DECREF(temp)) {
259                 if (ISARY(temp)) {
ragge
1.221
260                         if (dsym->ddim == NOOFFSET) {
ragge
1.52
261                                 dsym->ddim = ddef->ddim;
ragge
1.124
262                                 changed = 1;
ragge
1.221
263                         } else if (ddef->ddim != NOOFFSET &&
264                             dsym->ddim!=ddef->ddim) {
ragge
1.1
265                                 goto mismatch;
ragge
1.50
266                         }
ragge
1.1
267                         ++dsym;
268                         ++ddef;
ragge
1.55
269                 } else if (ISFTN(temp)) {
ragge
1.110
270                         /* add a late-defined prototype here */
ragge
1.370
271                         if (!oldstyle && dsym->dfun == NULL)
ragge
1.110
272                                 dsym->dfun = ddef->dfun;
ragge
1.109
273                         if (!oldstyle && ddef->dfun != NULL &&
274                             chkftn(dsym->dfunddef->dfun))
ragge
1.59
275                                 uerror("declaration doesn't match prototype");
ragge
1.55
276                         dsym++, ddef++;
ragge
1.1
277                 }
ragge
1.50
278         }
ragge
1.124
279 #ifdef STABS
280         if (changed && gflag)
ragge
1.125
281                 stabs_chgsym(p); /* symbol changed */
ragge
1.124
282 #endif
ragge
1.1
283
284         /* check that redeclarations are to the same structure */
ragge
1.246
285         if (temp == STRTY || temp == UNIONTY) {
ragge
1.288
286                 if (strmemb(p->sap) != strmemb(q->n_ap))
ragge
1.246
287                         goto mismatch;
ragge
1.33
288         }
ragge
1.1
289
ragge
1.33
290         scl = p->sclass;
ragge
1.1
291
ragge
1.54
292 #ifdef PCC_DEBUG
ragge
1.33
293         if (ddebug)
294                 printf("        previous class: %s\n"scnames(scl));
ragge
1.54
295 #endif
ragge
1.1
296
ragge
1.288
297         /*
298          * Its allowed to add attributes to existing declarations.
ragge
1.318
299          * Be careful though not to trash existing attributes.
300          * XXX - code below is probably not correct.
ragge
1.288
301          */
ragge
1.312
302         if (p->sap && p->sap->atype <= ATTR_MAX) {
ragge
1.288
303                 /* nothing special, just overwrite */
304                 p->sap = q->n_ap;
305         } else {
ragge
1.318
306                 if (p->slevel == blevel) {
307                         for (ap = q->n_apapap = ap->next) {
308                                 if (ap->atype > ATTR_MAX)
ragge
1.410
309                                         p->sap = attr_add(p->sapattr_dup(ap));
ragge
1.318
310                         }
311                 } else
312                         p->sap = q->n_ap;
ragge
1.288
313         }
ragge
1.270
314
ragge
1.193
315         if (class & FIELD)
ragge
1.314
316                 cerror("field1");
ragge
1.193
317         switch(class) {
ragge
1.1
318
319         case EXTERN:
ragge
1.347
320                 if (astr)
ragge
1.417
321                         addsoname(pastr);
ragge
1.1
322                 switchscl ){
323                 case STATIC:
324                 case USTATIC:
ragge
1.216
325                         ifslev==0 )
326                                 goto done;
ragge
1.1
327                         break;
328                 case EXTDEF:
329                 case EXTERN:
ragge
1.216
330                         goto done;
ragge
1.231
331                 case SNULL:
332                         if (p->sflags & SINLINE) {
333                                 p->sclass = EXTDEF;
334                                 inline_ref(p);
335                                 goto done;
ragge
1.1
336                         }
ragge
1.231
337                         break;
338                 }
ragge
1.1
339                 break;
340
341         case STATIC:
ragge
1.366
342                 if (astr)
ragge
1.417
343                         addsoname(pastr);
ragge
1.33
344                 if (scl==USTATIC || (scl==EXTERN && blevel==0)) {
ragge
1.1
345                         p->sclass = STATIC;
ragge
1.216
346                         goto done;
ragge
1.33
347                 }
ragge
1.168
348                 if (changed || (scl == STATIC && blevel == slev))
ragge
1.216
349                         goto done/* identical redeclaration */
ragge
1.1
350                 break;
351
352         case USTATIC:
ragge
1.33
353                 if (scl==STATIC || scl==USTATIC)
ragge
1.216
354                         goto done;
ragge
1.1
355                 break;
356
357         case TYPEDEF:
ragge
1.33
358                 if (scl == class)
ragge
1.216
359                         goto done;
ragge
1.1
360                 break;
361
362         case MOU:
363         case MOS:
ragge
1.314
364                 cerror("field6");
ragge
1.1
365
366         case EXTDEF:
ragge
1.10
367                 switch (scl) {
368                 case EXTERN:
ragge
1.1
369                         p->sclass = EXTDEF;
ragge
1.216
370                         goto done;
ragge
1.10
371                 case USTATIC:
372                         p->sclass = STATIC;
ragge
1.216
373                         goto done;
ragge
1.270
374                 case SNULL:
ragge
1.368
375 #ifdef GCC_COMPAT
ragge
1.270
376                         /*
377                          * Handle redeclarations of inlined functions.
378                          * This is allowed if the previous declaration is of
379                          * type gnu_inline.
380                          */
ragge
1.288
381                         if (attr_find(p->sapGCC_ATYP_GNU_INLINE))
ragge
1.270
382                                 goto done;
ragge
1.368
383 #endif
ragge
1.270
384                         break;
ragge
1.10
385                 }
ragge
1.1
386                 break;
387
388         case AUTO:
389         case REGISTER:
ragge
1.215
390                 break;  /* mismatch.. */
391         case SNULL:
ragge
1.350
392                 if (fun_inline && ISFTN(type)) {
393                         if (scl == EXTERN) {
394                                 p->sclass = EXTDEF;
395                                 inline_ref(p);
396                         }
ragge
1.216
397                         goto done;
ragge
1.350
398                 }
ragge
1.215
399                 break;
ragge
1.33
400         }
ragge
1.1
401
402         mismatch:
403
ragge
1.55
404         /*
405          * Only allowed for automatic variables.
406          */
ragge
1.349
407         if ((blevel == 2 && slev == 1) || blevel <= slev || class == EXTERN) {
ragge
1.290
408                 uerror("redeclaration of %s"p->sname);
409                 return;
ragge
1.24
410         }
ragge
1.395
411         if ((ISFTN(p->stype) && ISFTN(type)) ||
412             (!ISFTN(p->stype) && !ISFTN(type)))
413                 warner(Wshadowp->snamep->slevel ? "local" : "global");
ragge
1.55
414         q->n_sp = p = hide(p);
ragge
1.1
415
416         enter:  /* make a new entry */
417
ragge
1.405
418         if (type == VOID && class != TYPEDEF)
ragge
1.403
419                 uerror("void not allowed for variables");
420
ragge
1.54
421 #ifdef PCC_DEBUG
ragge
1.33
422         if(ddebug)
423                 printf("        new entry made\n");
ragge
1.54
424 #endif
ragge
1.307
425         p->stype = type;
ragge
1.93
426         p->squal = qual;
gmcgarry
1.266
427         p->sclass = (char)class;
428         p->slevel = (char)blevel;
ragge
1.33
429         p->soffset = NOOFFSET;
ragge
1.312
430         if (q->n_ap)
431                 p->sap = attr_add(q->n_app->sap);
ragge
1.1
432
433         /* copy dimensions */
ragge
1.52
434         p->sdf = q->n_df;
ragge
1.68
435         /* Do not save param info for old-style functions */
436         if (ISFTN(type) && oldstyle)
437                 p->sdf->dfun = NULL;
ragge
1.1
438
ragge
1.293
439         if (arrstkp)
440                 evalidx(p);
441
ragge
1.1
442         /* allocate offsets */
ragge
1.33
443         if (class&FIELD) {
ragge
1.314
444                 cerror("field2");  /* new entry */
ragge
1.33
445         } else switch (class) {
ragge
1.1
446
ragge
1.131
447         case REGISTER:
ragge
1.347
448                 if (astr != NULL)
449                         werror("no register assignment (yet)");
ragge
1.357
450                 p->sclass = class = AUTO;
ragge
1.347
451                 /* FALLTHROUGH */
ragge
1.1
452         case AUTO:
ragge
1.293
453                 if (isdyn(p)) {
454                         p->sflags |= SDYNARRAY;
ragge
1.30
455                         dynalloc(p, &autooff);
ragge
1.293
456                 } else
ragge
1.54
457                         oalloc(p, &autooff);
ragge
1.1
458                 break;
ragge
1.293
459
ragge
1.192
460         case PARAM:
ragge
1.313
461                 if (q->n_type != FARG)
462                         oalloc(p, &argoff);
ragge
1.192
463                 break;
464                 
ragge
1.1
465         case STATIC:
466         case EXTDEF:
467         case EXTERN:
ragge
1.33
468                 p->soffset = getlab();
ragge
1.366
469                 /* FALLTHROUGH */
470         case USTATIC:
ragge
1.347
471                 if (astr)
ragge
1.417
472                         addsoname(pastr);
ragge
1.1
473                 break;
ragge
1.190
474
ragge
1.1
475         case MOU:
476         case MOS:
ragge
1.314
477                 cerror("field7");
ragge
1.215
478         case SNULL:
ragge
1.231
479 #ifdef notdef
ragge
1.215
480                 if (fun_inline) {
481                         p->slevel = 1;
482                         p->soffset = getlab();
483                 }
ragge
1.231
484 #endif
485                 break;
ragge
1.33
486         }
ragge
1.1
487
ragge
1.124
488 #ifdef STABS
ragge
1.312
489         if (gflag && p->stype != FARG)
ragge
1.125
490                 stabs_newsym(p);
ragge
1.124
491 #endif
ragge
1.1
492
ragge
1.216
493 done:
ragge
1.190
494         fixdef(p);      /* Leave last word to target */
ragge
1.281
495 #ifndef HAVE_WEAKREF
496         {
ragge
1.288
497                 struct attr *at;
ragge
1.281
498
499                 /* Refer renamed function */
ragge
1.288
500                 if ((at = attr_find(p->sapGCC_ATYP_WEAKREF)))
ragge
1.417
501                         addsoname(pat->sarg(0));
ragge
1.281
502         }
503 #endif
ragge
1.54
504 #ifdef PCC_DEBUG
ragge
1.288
505         if (ddebug) {
506                 printf"       sdf, offset: %p, %d\n\t",
507                     p->sdfp->soffset);
ragge
1.368
508 #ifdef GCC_COMPAT
ragge
1.288
509                 dump_attr(p->sap);
ragge
1.368
510 #endif
ragge
1.288
511         }
ragge
1.54
512 #endif
ragge
1.33
513 }
ragge
1.1
514
ragge
1.2
515 void
ragge
1.46
516 ssave(struct symtab *sym)
ragge
1.2
517 {
ragge
1.46
518         struct params *p;
519
520         p = tmpalloc(sizeof(struct params));
plunky
1.362
521         p->prev = lparam;
ragge
1.46
522         p->sym = sym;
523         lparam = p;
ragge
1.2
524 }
ragge
1.1
525
ragge
1.2
526 /*
527  * end of function
528  */
529 void
plunky
1.345
530 ftnend(void)
ragge
1.2
531 {
ragge
1.368
532 #ifdef GCC_COMPAT
ragge
1.326
533         struct attr *gc, *gd;
ragge
1.368
534 #endif
ragge
1.356
535         extern int *mkclabs(void);
ragge
1.228
536         extern NODE *cftnod;
ragge
1.51
537         extern struct savbc *savbc;
ragge
1.62
538         extern struct swdef *swpole;
ragge
1.192
539         extern int tvaloff;
ragge
1.138
540         char *c;
ragge
1.51
541
ragge
1.69
542         if (retlab != NOLAB && nerrors == 0) { /* inside a real function */
ragge
1.134
543                 plabel(retlab);
ragge
1.228
544                 if (cftnod)
ragge
1.415
545                         ecomp(buildtree(FORCEp1tcopy(cftnod), NIL));
ragge
1.112
546                 efcode(); /* struct return handled here */
ragge
1.417
547                 c = getexname(cftnsp);
ragge
1.149
548                 SETOFF(maxautooffALCHAR);
mickey
1.229
549                 send_passt(IP_EPILOGmaxautooff/SZCHARc,
ragge
1.356
550                     cftnsp->stypecftnsp->sclass == EXTDEF,
551                     retlabtvaloffmkclabs());
ragge
1.69
552         }
ragge
1.33
553
ragge
1.228
554         cftnod = NIL;
ragge
1.1
555         tcheck();
556         brklab = contlab = retlab = NOLAB;
557         flostat = 0;
ragge
1.51
558         if (nerrors == 0) {
559                 if (savbc != NULL)
560                         cerror("bcsave error");
ragge
1.46
561                 if (lparam != NULL)
562                         cerror("parameter reset error");
ragge
1.62
563                 if (swpole != NULL)
564                         cerror("switch error");
ragge
1.46
565         }
ragge
1.368
566 #ifdef GCC_COMPAT
ragge
1.326
567         if (cftnsp) {
568                 gc = attr_find(cftnsp->sapGCC_ATYP_CONSTRUCTOR);
569                 gd = attr_find(cftnsp->sapGCC_ATYP_DESTRUCTOR);
570                 if (gc || gd) {
571                         struct symtab sts = *cftnsp;
572                         NODE *p;
573                         sts.stype = INCREF(sts.stype);
574                         p = nametree(&sts);
575                         p->n_op = ICON;
576                         if (gc) {
ragge
1.372
577                                 locctr(CTORSNULL);
ragge
1.326
578                                 inval(0SZPOINT(0), p);
579                         }
580                         if (gd) {
ragge
1.372
581                                 locctr(DTORSNULL);
ragge
1.326
582                                 inval(0SZPOINT(0), p);
583                         }
584                         tfree(p);
585                 }
586         }
ragge
1.368
587 #endif
ragge
1.51
588         savbc = NULL;
ragge
1.46
589         lparam = NULL;
ragge
1.234
590         cftnsp = NULL;
ragge
1.146
591         maxautooff = autooff = AUTOINIT;
ragge
1.1
592         reached = 1;
ragge
1.66
593
594         if (isinlining)
595                 inline_end();
596         inline_prtout();
597
ragge
1.37
598         tmpfree(); /* Release memory resources */
ragge
1.2
599 }
ragge
1.89
600
gmcgarry
1.198
601 static struct symtab nulsym = {
ragge
1.417
602         NULL0000"null"INT0NULLNULL
gmcgarry
1.198
603 };
604
ragge
1.2
605 void
plunky
1.345
606 dclargs(void)
ragge
1.2
607 {
ragge
1.59
608         union dimfun *df;
ragge
1.407
609         union arglist *al;
ragge
1.45
610         struct params *a;
ragge
1.123
611         struct symtab *p, **parr = NULL/* XXX gcc */
ragge
1.150
612         int i;
ragge
1.45
613
ragge
1.56
614         /*
ragge
1.59
615          * Deal with fun(void) properly.
616          */
gmcgarry
1.198
617         if (nparams == 1 && lparam->sym && lparam->sym->stype == VOID)
ragge
1.59
618                 goto done;
619
620         /*
ragge
1.56
621          * Generate a list for bfcode().
622          * Parameters were pushed in reverse order.
623          */
ragge
1.58
624         if (nparams != 0)
ragge
1.405
625                 parr = FUNALLO(sizeof(struct symtab *) * nparams);
ragge
1.56
626
ragge
1.140
627         if (nparams)
ragge
1.193
628             for (a = lparami = 0a != NULLa = a->prev) {
ragge
1.59
629                 p = a->sym;
ragge
1.56
630                 parr[i++] = p;
ragge
1.192
631                 if (p == NULL) {
gmcgarry
1.198
632                         uerror("parameter %d name missing"i);
633                         p = &nulsym/* empty symtab */
ragge
1.192
634                 }
ragge
1.312
635                 if (p->stype == FARG)
ragge
1.59
636                         p->stype = INT;
637                 if (ISARY(p->stype)) {
638                         p->stype += (PTR-ARY);
639                         p->sdf++;
ragge
1.97
640                 } else if (ISFTN(p->stype)) {
641                         werror("function declared as argument");
642                         p->stype = INCREF(p->stype);
ragge
1.59
643                 }
ragge
1.124
644 #ifdef STABS
645                 if (gflag)
ragge
1.129
646                         stabs_newsym(p);
ragge
1.124
647 #endif
ragge
1.12
648         }
ragge
1.59
649         if (oldstyle && (df = cftnsp->sdf) && (al = df->dfun)) {
650                 /*
651                  * Check against prototype of oldstyle function.
652                  */
ragge
1.407
653                 union arglist *al2, *alb;
654
655                 alb = al2 = FUNALLO(sizeof(union arglist) * nparams * 3 + 1);
ragge
1.59
656                 for (i = 0i < nparamsi++) {
657                         TWORD type = parr[i]->stype;
658                         (al2++)->type = type;
ragge
1.288
659                         if (ISSOU(BTYPE(type)))
660                                 (al2++)->sap = parr[i]->sap;
ragge
1.59
661                         while (!ISFTN(type) && !ISARY(type) && type > BTMASK)
662                                 type = DECREF(type);
663                         if (type > BTMASK)
664                                 (al2++)->df = parr[i]->sdf;
665                 }
666                 al2->type = TNULL;
ragge
1.60
667                 intcompare = 1;
ragge
1.59
668                 if (chkftn(alalb))
669                         uerror("function doesn't match prototype");
ragge
1.407
670                 FUNFREE(alb);
ragge
1.60
671                 intcompare = 0;
ragge
1.199
672
673         }
674
675         if (oldstyle && nparams) {
676                 /* Must recalculate offset for oldstyle args here */
677                 argoff = ARGINIT;
678                 for (i = 0i < nparamsi++) {
679                         parr[i]->soffset = NOOFFSET;
680                         oalloc(parr[i], &argoff);
681                 }
ragge
1.59
682         }
ragge
1.199
683
ragge
1.321
684 done:   autooff = AUTOINIT;
ragge
1.192
685
ragge
1.144
686         plabel(prolab); /* after prolog, used in optimization */
687         retlab = getlab();
ragge
1.45
688         bfcode(parrnparams);
ragge
1.368
689         if (fun_inline && (xinline
690 #ifdef GCC_COMPAT
691  || attr_find(cftnsp->sapGCC_ATYP_ALW_INL)
692 #endif
693                 ))
ragge
1.231
694                 inline_args(parrnparams);
ragge
1.405
695         FUNFREE(parr);
ragge
1.183
696         plabel(getlab()); /* used when spilling */
ragge
1.192
697         if (parlink)
698                 ecomp(parlink);
699         parlink = NIL;
ragge
1.47
700         lparam = NULL;
ragge
1.45
701         nparams = 0;
ragge
1.192
702         symclear(1);    /* In case of function pointer args */
ragge
1.2
703 }
ragge
1.1
704
ragge
1.243
705 /*
ragge
1.288
706  * basic attributes for structs and enums
ragge
1.243
707  */
ragge
1.288
708 static struct attr *
709 seattr(void)
ragge
1.243
710 {
ragge
1.368
711         return attr_add(attr_new(ATTR_ALIGNED4), attr_new(ATTR_STRUCT2));
ragge
1.243
712 }
713
ragge
1.21
714 /*
ragge
1.200
715  * Struct/union/enum symtab construction.
716  */
717 static void
718 defstr(struct symtab *spint class)
719 {
gmcgarry
1.266
720         sp->sclass = (char)class;
ragge
1.200
721         if (class == STNAME)
722                 sp->stype = STRTY;
723         else if (class == UNAME)
724                 sp->stype = UNIONTY;
ragge
1.232
725         else if (class == ENAME)
726                 sp->stype = ENUMTY;
ragge
1.200
727 }
728
729 /*
ragge
1.184
730  * Declare a struct/union/enum tag.
731  * If not found, create a new tag with UNDEF type.
732  */
733 static struct symtab *
734 deftag(char *nameint class)
735 {
736         struct symtab *sp;
737
ragge
1.288
738         if ((sp = lookup(nameSTAGNAME))->sap == NULL) {
ragge
1.193
739                 /* New tag */
ragge
1.200
740                 defstr(spclass);
741         } else if (sp->sclass != class)
ragge
1.184
742                 uerror("tag %s redeclared"name);
743         return sp;
744 }
745
ragge
1.193
746 /*
747  * reference to a structure or union, with no definition
748  */
749 NODE *
750 rstruct(char *tagint soru)
751 {
752         struct symtab *sp;
753
754         sp = deftag(tagsoru);
ragge
1.288
755         if (sp->sap == NULL)
756                 sp->sap = seattr();
757         return mkty(sp->stype0sp->sap);
ragge
1.193
758 }
759
ragge
1.184
760 static int enumlowenumhigh;
761 int enummer;
762
763 /*
764  * Declare a member of enum.
765  */
ragge
1.2
766 void
ragge
1.33
767 moedef(char *name)
ragge
1.2
768 {
ragge
1.184
769         struct symtab *sp;
770
771         sp = lookup(nameSNORMAL);
772         if (sp->stype == UNDEF || (sp->slevel < blevel)) {
773                 if (sp->stype != UNDEF)
774                         sp = hide(sp);
775                 sp->stype = INT/* always */
776                 sp->sclass = MOE;
777                 sp->soffset = enummer;
778         } else
779                 uerror("%s redeclared"name);
780         if (enummer < enumlow)
781                 enumlow = enummer;
782         if (enummer > enumhigh)
783                 enumhigh = enummer;
784         enummer++;
785 }
786
787 /*
788  * Declare an enum tag.  Complain if already defined.
789  */
790 struct symtab *
791 enumhd(char *name)
792 {
ragge
1.288
793         struct attr *ap;
ragge
1.184
794         struct symtab *sp;
795
796         enummer = enumlow = enumhigh = 0;
797         if (name == NULL)
798                 return NULL;
799
800         sp = deftag(nameENAME);
ragge
1.232
801         if (sp->stype != ENUMTY) {
ragge
1.200
802                 if (sp->slevel == blevel)
803                         uerror("%s redeclared"name);
804                 sp = hide(sp);
805                 defstr(spENAME);
806         }
ragge
1.288
807         if (sp->sap == NULL)
ragge
1.312
808