Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20100812063922

Diff

Diff from 1.289 to:

Annotations

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

Annotated File View

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