Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20150105154847

Diff

Diff from 1.395 to:

Annotations

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

Annotated File View

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