Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20120414155859

Diff

Diff from 1.343 to:

Annotations

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

Annotated File View

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