Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20110707065010

Diff

Diff from 1.332 to:

Annotations

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

Annotated File View

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