Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20160305153124

Diff

Diff from 1.421 to:

Annotations

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

Annotated File View

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