Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20060629054332

Diff

Diff from 1.155 to:

Annotations

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

Annotated File View

ragge
1.155
1 /*      $Id: pftn.c,v 1.155 2006/06/29 05:43:32 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  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 /*
29  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
30  *
31  * Redistribution and use in source and binary forms, with or without
32  * modification, are permitted provided that the following conditions
33  * are met:
34  *
35  * Redistributions of source code and documentation must retain the above
36  * copyright notice, this list of conditions and the following disclaimer.
37  * Redistributions in binary form must reproduce the above copyright
38  * notice, this list of conditionsand the following disclaimer in the
39  * documentation and/or other materials provided with the distribution.
40  * All advertising materials mentioning features or use of this software
41  * must display the following acknowledgement:
42  *      This product includes software developed or owned by Caldera
43  *      International, Inc.
44  * Neither the name of Caldera International, Inc. nor the names of other
45  * contributors may be used to endorse or promote products derived from
46  * this software without specific prior written permission.
47  *
48  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
49  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
50  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
51  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
52  * DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
53  * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56  * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
57  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
58  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
59  * POSSIBILITY OF SUCH DAMAGE.
60  */
61
62 /*
63  * Many changes from the 32V sources, among them:
64  * - New symbol table manager (moved to another file).
65  * - Prototype saving/checks.
66  */
ragge
1.1
67
68 # include "pass1.h"
ragge
1.25
69
ragge
1.33
70 struct symtab *spname;
71 struct symtab *cftnsp;
ragge
1.65
72 static int strunem;             /* currently parsed member type */
73 int arglistcntdimfuncnt;      /* statistics */
ragge
1.69
74 int symtabcntsuedefcnt;       /* statistics */
75 int autooff,            /* the next unused automatic offset */
ragge
1.146
76     maxautooff,         /* highest used automatic offset in function */
ragge
1.69
77     argoff,             /* the next unused argument offset */
78     strucoff;           /* the next structure offset position */
79 int retlab = NOLAB;     /* return label for subroutine */
80 int brklab;
81 int contlab;
82 int flostat;
ragge
1.91
83 int instructblevel;
84 OFFSZ inoff;
ragge
1.150
85 int reachedprolab;
ragge
1.1
86
ragge
1.46
87 struct params;
88
ragge
1.59
89 #define ISSTR(ty) (ty == STRTY || ty == UNIONTY || ty == ENUMTY)
90 #define ISSOU(ty) (ty == STRTY || ty == UNIONTY)
91 #define MKTY(p, t, d, s) r = talloc(); *r = *p; \
ragge
1.74
92         r = argcast(rtds); *p = *rnfree(r);
ragge
1.59
93
ragge
1.43
94 /*
ragge
1.66
95  * Info stored for delaying string printouts.
96  */
97 struct strsched {
98         struct strsched *next;
99         int locctr;
100         struct symtab *sym;
101 } *strpole;
102
103 /*
ragge
1.43
104  * Linked list stack while reading in structs.
105  */
106 struct rstack {
107         struct  rstack *rnext;
108         int     rinstruct;
109         int     rclass;
110         int     rstrucoff;
ragge
1.46
111         struct  params *rlparam;
ragge
1.43
112         struct  symtab *rsym;
113 };
114
ragge
1.45
115 /*
ragge
1.47
116  * Linked list for parameter (and struct elements) declaration.
ragge
1.45
117  */
118 static struct params {
ragge
1.46
119         struct params *next, *prev;
ragge
1.45
120         struct symtab *sym;
ragge
1.47
121 } *lpole, *lparam;
ragge
1.45
122 static int nparams;
123
ragge
1.2
124 /* defines used for getting things off of the initialization stack */
ragge
1.1
125
ragge
1.30
126 static NODE *arrstk[10];
127 static int arrstkp;
ragge
1.60
128 static int intcompare;
ragge
1.1
129
ragge
1.2
130 void fixtype(NODE *pint class);
131 int fixclass(int classTWORD type);
132 int falloc(struct symtab *pint wint newNODE *pty);
ragge
1.30
133 static void dynalloc(struct symtab *pint *poff);
ragge
1.2
134 void inforce(OFFSZ n);
135 void vfdalign(int n);
ragge
1.46
136 static void ssave(struct symtab *);
ragge
1.66
137 static void strprint(void);
ragge
1.1
138
139 int ddebug = 0;
140
ragge
1.2
141 void
142 defid(NODE *qint class)
143 {
144         struct symtab *p;
ragge
1.92
145         TWORD typequal;
146         TWORD stpstq;
ragge
1.2
147         int scl;
ragge
1.52
148         union dimfun *dsym, *ddef;
ragge
1.124
149         int slevtempchanged;
ragge
1.1
150
ragge
1.32
151         if (q == NIL)
152                 return;  /* an error was detected */
ragge
1.1
153
ragge
1.33
154         p = q->n_sp;
ragge
1.1
155
ragge
1.54
156 #ifdef PCC_DEBUG
ragge
1.4
157         if (ddebug) {
ragge
1.33
158                 printf("defid(%s (%p), "p->snamep);
ragge
1.104
159                 tprint(stdoutq->n_typeq->n_qual);
ragge
1.50
160                 printf(", %s, (%p,%p)), level %d\n"scnames(class),
ragge
1.52
161                     q->n_dfq->n_sueblevel);
ragge
1.4
162         }
ragge
1.54
163 #endif
ragge
1.1
164
ragge
1.33
165         fixtype(qclass);
ragge
1.1
166
ragge
1.31
167         type = q->n_type;
ragge
1.92
168         qual = q->n_qual;
ragge
1.33
169         class = fixclass(classtype);
ragge
1.1
170
171         stp = p->stype;
ragge
1.92
172         stq = p->squal;
ragge
1.1
173         slev = p->slevel;
174
ragge
1.54
175 #ifdef PCC_DEBUG
ragge
1.4
176         if (ddebug) {
177                 printf("        modified to ");
ragge
1.104
178                 tprint(stdouttypequal);
ragge
1.4
179                 printf(", %s\n"scnames(class));
180                 printf("        previous def'n: ");
ragge
1.104
181                 tprint(stdoutstpstq);
ragge
1.50
182                 printf(", %s, (%p,%p)), level %d\n",
ragge
1.52
183                     scnames(p->sclass), p->sdfp->ssueslev);
ragge
1.4
184         }
ragge
1.54
185 #endif
ragge
1.1
186
ragge
1.56
187         if (blevel == 1) {
ragge
1.33
188                 switch (class) {
ragge
1.1
189                 default:
ragge
1.4
190                         if (!(class&FIELD))
ragge
1.56
191                                 uerror("declared argument %s missing",
ragge
1.4
192                                     p->sname );
ragge
1.1
193                 case MOS:
194                 case STNAME:
195                 case MOU:
196                 case UNAME:
197                 case MOE:
198                 case ENAME:
199                 case TYPEDEF:
200                         ;
ragge
1.56
201                 }
ragge
1.4
202         }
ragge
1.56
203
204         if (stp == UNDEF)
205                 goto enter/* New symbol */
ragge
1.1
206
ragge
1.33
207         if (type != stp)
208                 goto mismatch;
209
210         if (blevel > slev && (class == AUTO || class == REGISTER))
ragge
1.1
211                 /* new scope */
212                 goto mismatch;
213
ragge
1.55
214         /*
215          * test (and possibly adjust) dimensions.
216          * also check that prototypes are correct.
217          */
ragge
1.52
218         dsym = p->sdf;
219         ddef = q->n_df;
ragge
1.124
220         changed = 0;
ragge
1.55
221         for (temp = typetemp & TMASKtemp = DECREF(temp)) {
222                 if (ISARY(temp)) {
ragge
1.52
223                         if (dsym->ddim == 0) {
224                                 dsym->ddim = ddef->ddim;
ragge
1.124
225                                 changed = 1;
ragge
1.52
226                         } else if (ddef->ddim != 0 && dsym->ddim!=ddef->ddim) {
ragge
1.1
227                                 goto mismatch;
ragge
1.50
228                         }
ragge
1.1
229                         ++dsym;
230                         ++ddef;
ragge
1.55
231                 } else if (ISFTN(temp)) {
ragge
1.110
232                         /* add a late-defined prototype here */
233                         if (cftnsp == NULL && dsym->dfun == NULL)
234                                 dsym->dfun = ddef->dfun;
ragge
1.109
235                         if (!oldstyle && ddef->dfun != NULL &&
236                             chkftn(dsym->dfunddef->dfun))
ragge
1.59
237                                 uerror("declaration doesn't match prototype");
ragge
1.55
238                         dsym++, ddef++;
ragge
1.1
239                 }
ragge
1.50
240         }
ragge
1.124
241 #ifdef STABS
242         if (changed && gflag)
ragge
1.125
243                 stabs_chgsym(p); /* symbol changed */
ragge
1.124
244 #endif
ragge
1.1
245
246         /* check that redeclarations are to the same structure */
ragge
1.33
247         if ((temp == STRTY || temp == UNIONTY || temp == ENUMTY) &&
ragge
1.43
248             p->ssue != q->n_sue &&
ragge
1.33
249             class != STNAME && class != UNAME && class != ENAME) {
ragge
1.1
250                 goto mismatch;
ragge
1.33
251         }
ragge
1.1
252
ragge
1.33
253         scl = p->sclass;
ragge
1.1
254
ragge
1.54
255 #ifdef PCC_DEBUG
ragge
1.33
256         if (ddebug)
257                 printf("        previous class: %s\n"scnames(scl));
ragge
1.54
258 #endif
ragge
1.1
259
ragge
1.33
260         if (class&FIELD) {
ragge
1.1
261                 /* redefinition */
ragge
1.33
262                 if (!falloc(pclass&FLDSIZ1NIL)) {
ragge
1.1
263                         /* successful allocation */
ragge
1.46
264                         ssave(p);
ragge
1.1
265                         return;
ragge
1.33
266                 }
ragge
1.1
267                 /* blew it: resume at end of switch... */
ragge
1.33
268         } else switch(class) {
ragge
1.1
269
270         case EXTERN:
271                 switchscl ){
272                 case STATIC:
273                 case USTATIC:
274                         ifslev==0 ) return;
275                         break;
276                 case EXTDEF:
277                 case EXTERN:
278                 case FORTRAN:
279                 case UFORTRAN:
280                         return;
281                         }
282                 break;
283
284         case STATIC:
ragge
1.33
285                 if (scl==USTATIC || (scl==EXTERN && blevel==0)) {
ragge
1.1
286                         p->sclass = STATIC;
287                         return;
ragge
1.33
288                 }
ragge
1.1
289                 break;
290
291         case USTATIC:
ragge
1.33
292                 if (scl==STATIC || scl==USTATIC)
293                         return;
ragge
1.1
294                 break;
295
296         case TYPEDEF:
ragge
1.33
297                 if (scl == class)
298                         return;
ragge
1.1
299                 break;
300
301         case UFORTRAN:
ragge
1.33
302                 if (scl == UFORTRAN || scl == FORTRAN)
303                         return;
ragge
1.1
304                 break;
305
306         case FORTRAN:
ragge
1.33
307                 if (scl == UFORTRAN) {
ragge
1.1
308                         p->sclass = FORTRAN;
309                         return;
ragge
1.33
310                 }
ragge
1.1
311                 break;
312
313         case MOU:
314         case MOS:
ragge
1.33
315                 if (scl == class) {
316                         if (oalloc(p, &strucoff))
317                                 break;
318                         if (class == MOU)
319                                 strucoff = 0;
ragge
1.46
320                         ssave(p);
ragge
1.1
321                         return;
ragge
1.33
322                 }
ragge
1.1
323                 break;
324
ragge
1.78
325         case MOE:
ragge
1.1
326                 break;
327
328         case EXTDEF:
ragge
1.10
329                 switch (scl) {
330                 case EXTERN:
ragge
1.1
331                         p->sclass = EXTDEF;
332                         return;
ragge
1.10
333                 case USTATIC:
334                         p->sclass = STATIC;
335                         return;
336                 }
ragge
1.1
337                 break;
338
339         case STNAME:
340         case UNAME:
341         case ENAME:
ragge
1.33
342                 if (scl != class)
343                         break;
ragge
1.43
344                 if (p->ssue->suesize == 0)
ragge
1.33
345                         return;  /* previous entry just a mention */
ragge
1.1
346                 break;
347
348         case AUTO:
349         case REGISTER:
350                 ;  /* mismatch.. */
ragge
1.33
351         }
ragge
1.1
352
353         mismatch:
354
ragge
1.55
355         /*
356          * Only allowed for automatic variables.
357          */
358         if (blevel == slev || class == EXTERN || class == FORTRAN ||
359             class == UFORTRAN) {
360                 uerror("redeclaration of %s"p->sname);
361                 return;
ragge
1.24
362         }
ragge
1.55
363         q->n_sp = p = hide(p);
ragge
1.1
364
365         enter:  /* make a new entry */
366
ragge
1.54
367 #ifdef PCC_DEBUG
ragge
1.33
368         if(ddebug)
369                 printf("        new entry made\n");
ragge
1.54
370 #endif
ragge
1.1
371         p->stype = type;
ragge
1.93
372         p->squal = qual;
ragge
1.1
373         p->sclass = class;
374         p->slevel = blevel;
ragge
1.33
375         p->soffset = NOOFFSET;
ragge
1.1
376         p->suse = lineno;
ragge
1.43
377         if (class == STNAME || class == UNAME || class == ENAME) {
378                 p->ssue = permalloc(sizeof(struct suedef));
ragge
1.65
379                 suedefcnt++;
ragge
1.43
380                 p->ssue->suesize = 0;
381                 p->ssue->suelem = NULL
382                 p->ssue->suealign = ALSTRUCT;
383         } else {
384                 switch (BTYPE(type)) {
ragge
1.1
385                 case STRTY:
386                 case UNIONTY:
387                 case ENUMTY:
ragge
1.43
388                         p->ssue = q->n_sue;
ragge
1.1
389                         break;
390                 default:
ragge
1.45
391                         p->ssue = MKSUE(BTYPE(type));
ragge
1.1
392                 }
ragge
1.43
393         }
ragge
1.1
394
395         /* copy dimensions */
ragge
1.52
396         p->sdf = q->n_df;
ragge
1.68
397         /* Do not save param info for old-style functions */
398         if (ISFTN(type) && oldstyle)
399                 p->sdf->dfun = NULL;
ragge
1.1
400
401         /* allocate offsets */
ragge
1.33
402         if (class&FIELD) {
403                 (voidfalloc(pclass&FLDSIZ0NIL);  /* new entry */
ragge
1.46
404                 ssave(p);
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.30
411                 if (arrstkp)
412                         dynalloc(p, &autooff);
413                 else
ragge
1.54
414                         oalloc(p, &autooff);
ragge
1.1
415                 break;
416         case STATIC:
417         case EXTDEF:
ragge
1.33
418                 p->soffset = getlab();
ragge
1.108
419 #ifdef GCC_COMPAT
420                 {       extern char *renname;
421                         if (renname)
422                                 gcc_rename(prenname);
423                         renname = NULL;
424                 }
425 #endif
ragge
1.1
426                 break;
427
428         case EXTERN:
429         case UFORTRAN:
430         case FORTRAN:
ragge
1.33
431                 p->soffset = getlab();
ragge
1.115
432 #ifdef notdef
433                 /* Cannot reset level here. What does the standard say??? */
ragge
1.1
434                 p->slevel = 0;
ragge
1.115
435 #endif
ragge
1.108
436 #ifdef GCC_COMPAT
437                 {       extern char *renname;
438                         if (renname)
439                                 gcc_rename(prenname);
440                         renname = NULL;
441                 }
442 #endif
ragge
1.1
443                 break;
444         case MOU:
445         case MOS:
ragge
1.54
446                 oalloc(p, &strucoff);
447                 if (class == MOU)
448                         strucoff = 0;
ragge
1.46
449                 ssave(p);
ragge
1.1
450                 break;
451
452         case MOE:
ragge
1.33
453                 p->soffset = strucoff++;
ragge
1.46
454                 ssave(p);
ragge
1.1
455                 break;
ragge
1.131
456
ragge
1.33
457         }
ragge
1.1
458
ragge
1.124
459 #ifdef STABS
460         if (gflag)
ragge
1.125
461                 stabs_newsym(p);
ragge
1.124
462 #endif
ragge
1.1
463
ragge
1.54
464 #ifdef PCC_DEBUG
ragge
1.33
465         if (ddebug)
ragge
1.52
466                 printf"       sdf, ssue, offset: %p, %p, %d\n",
467                     p->sdfp->ssuep->soffset);
ragge
1.54
468 #endif
ragge
1.1
469
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
481         if (lparam == NULL) {
482                 p->prev = (struct params *)&lpole;
483                 lpole = p;
484         } else {
485                 lparam->next = p;
486                 p->prev = lparam;
ragge
1.2
487         }
ragge
1.46
488         lparam = p;
ragge
1.2
489 }
ragge
1.1
490
ragge
1.2
491 /*
492  * end of function
493  */
494 void
495 ftnend()
496 {
ragge
1.51
497         extern struct savbc *savbc;
ragge
1.62
498         extern struct swdef *swpole;
ragge
1.138
499         char *c;
ragge
1.51
500
ragge
1.69
501         if (retlab != NOLAB && nerrors == 0) { /* inside a real function */
ragge
1.134
502                 plabel(retlab);
ragge
1.112
503                 efcode(); /* struct return handled here */
ragge
1.138
504                 c = cftnsp->sname;
505 #ifdef GCC_COMPAT
506                 c = gcc_findname(cftnsp);
507 #endif
ragge
1.149
508                 SETOFF(maxautooffALCHAR);
509                 send_passt(IP_EPILOG0maxautooff/SZCHARc,
ragge
1.138
510                     cftnsp->stypecftnsp->sclass == EXTDEFretlab);
ragge
1.69
511         }
ragge
1.33
512
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.146
526         maxautooff = autooff = AUTOINIT;
ragge
1.1
527         reached = 1;
ragge
1.66
528
529         if (isinlining)
530                 inline_end();
531         inline_prtout();
532
533         strprint();
534
ragge
1.37
535         tmpfree(); /* Release memory resources */
ragge
1.2
536 }
ragge
1.89
537
ragge
1.2
538 void
539 dclargs()
540 {
ragge
1.59
541         union dimfun *df;
542         union arglist *al, *al2, *alb;
ragge
1.45
543         struct params *a;
ragge
1.123
544         struct symtab *p, **parr = NULL/* XXX gcc */
ragge
1.138
545         char *c;
ragge
1.150
546         int i;
ragge
1.45
547
ragge
1.1
548         argoff = ARGINIT;
ragge
1.45
549
ragge
1.56
550         /*
ragge
1.59
551          * Deal with fun(void) properly.
552          */
ragge
1.84
553         if (nparams == 1 && 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)
564             for (a = lparami = 0a != NULL && a != (struct params *)&lpole;
ragge
1.47
565             a = a->prev) {
ragge
1.56
566
ragge
1.59
567                 p = a->sym;
ragge
1.56
568                 parr[i++] = p;
ragge
1.59
569                 if (p->stype == FARG) {
570                         p->stype = INT;
571                         p->ssue = MKSUE(INT);
572                 }
573                 if (ISARY(p->stype)) {
574                         p->stype += (PTR-ARY);
575                         p->sdf++;
ragge
1.97
576                 } else if (ISFTN(p->stype)) {
577                         werror("function declared as argument");
578                         p->stype = INCREF(p->stype);
ragge
1.59
579                 }
ragge
1.56
580                 /* always set aside space, even for register arguments */
ragge
1.129
581                 oalloc(p, &argoff);
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;
595                         if (ISSTR(BTYPE(type)))
596                                 (al2++)->sue = parr[i]->ssue;
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.59
607         }
608 done:   cendarg();
ragge
1.138
609         c = cftnsp->sname;
610 #ifdef GCC_COMPAT
611         c = gcc_findname(cftnsp);
612 #endif
ragge
1.150
613 #if 0
ragge
1.144
614         prolab = getlab();
ragge
1.138
615         send_passt(IP_PROLOG, -1, -1ccftnsp->stype
ragge
1.144
616             cftnsp->sclass == EXTDEFprolab);
ragge
1.150
617 #endif
ragge
1.144
618         plabel(prolab); /* after prolog, used in optimization */
619         retlab = getlab();
ragge
1.45
620         bfcode(parrnparams);
ragge
1.153
621         if (xtemps) {
622                 /* put arguments in temporaries */
623                 for (i = 0i < nparamsi++) {
624                         NODE *q, *r, *s;
625
626                         p = parr[i];
627                         if (p->stype == STRTY || p->stype == UNIONTY ||
628                             cisreg(p->stype) == 0)
629                                 continue;
630                         spname = p;
631                         q = buildtree(NAME00);
632                         r = tempnode(0p->stypep->sdfp->ssue);
633                         s = buildtree(ASSIGNrq);
634                         p->soffset = r->n_lval;
635                         p->sflags |= STNODE;
636                         ecomp(s);
637                 }
ragge
1.154
638                 plabel(getlab()); /* used when spilling */
ragge
1.153
639         }
ragge
1.47
640         lparam = NULL;
ragge
1.45
641         nparams = 0;
ragge
1.2
642 }
ragge
1.1
643
ragge
1.21
644 /*
645  * reference to a structure or union, with no definition
646  */
ragge
1.1
647 NODE *
ragge
1.33
648 rstruct(char *tagint soru)
ragge
1.21
649 {
ragge
1.2
650         struct symtab *p;
651         NODE *q;
ragge
1.32
652
ragge
1.40
653         p = (struct symtab *)lookup(tagSTAGNAME);
ragge
1.21
654         switch (p->stype) {
ragge
1.1
655
656         case UNDEF:
657         def:
ragge
1.74
658                 q = block(NAMENILNIL000);
ragge
1.33
659                 q->n_sp = p;
ragge
1.31
660                 q->n_type = (soru&INSTRUCT) ? STRTY :
ragge
1.21
661                     ((soru&INUNION) ? UNIONTY : ENUMTY);
662                 defid(q, (soru&INSTRUCT) ? STNAME :
663                     ((soru&INUNION) ? UNAME : ENAME));
ragge
1.74
664                 nfree(q);
ragge
1.1
665                 break;
666
667         case STRTY:
ragge
1.21
668                 if (soru & INSTRUCT)
669                         break;
ragge
1.1
670                 goto def;
671
672         case UNIONTY:
ragge
1.21
673                 if (soru & INUNION)
674                         break;
ragge
1.1
675                 goto def;
676
677         case ENUMTY:
ragge
1.21
678                 if (!(soru&(INUNION|INSTRUCT)))
679                         break;
ragge
1.1
680                 goto def;
681
ragge
1.21
682         }
ragge
1.43
683         q = mkty(p->stype0p->ssue);
684         q->n_sue = p->ssue;
685         return q;
ragge
1.21
686 }
ragge
1.1
687
ragge
1.2
688 void
ragge
1.33
689 moedef(char *name)
ragge
1.2
690 {
691         NODE *q;
ragge
1.1
692
ragge
1.74
693         q = block(NAMENILNILMOETY00);
ragge
1.33
694         q->n_sp = lookup(name0);
695         defid(qMOE);
ragge
1.74
696         nfree(q);
ragge
1.2
697 }
ragge
1.1
698
ragge
1.2
699 /*
700  * begining of structure or union declaration
701  */
ragge
1.43
702 struct rstack *
ragge
1.33
703 bstruct(char *nameint soru)
ragge
1.2
704 {
ragge
1.43
705         struct rstack *r;
ragge
1.33
706         struct symtab *s;
ragge
1.2
707         NODE *q;
ragge
1.1
708
ragge
1.33
709         if (name != NULL)
ragge
1.40
710                 s = lookup(nameSTAGNAME);
ragge
1.33
711         else
712                 s = NULL;
713
ragge
1.43
714         r = tmpalloc(sizeof(struct rstack));
715         r->rinstruct = instruct;
716         r->rclass = strunem;
717         r->rstrucoff = strucoff;
718
ragge
1.1
719         strucoff = 0;
720         instruct = soru;
ragge
1.74
721         q = block(NAMENILNIL000);
ragge
1.33
722         q->n_sp = s;
ragge
1.21
723         if (instruct==INSTRUCT) {
ragge
1.18
724                 strunem = MOS;
ragge
1.31
725                 q->n_type = STRTY;
ragge
1.33
726                 if (s != NULL)
ragge
1.21
727                         defid(qSTNAME);
728         } else if(instruct == INUNION) {
ragge
1.18
729                 strunem = MOU;
ragge
1.31
730                 q->n_type = UNIONTY;
ragge
1.33
731                 if (s != NULL)
ragge
1.21
732                         defid(qUNAME);
733         } else { /* enum */
ragge
1.18
734                 strunem = MOE;
ragge
1.31
735                 q->n_type = ENUMTY;
ragge
1.33
736                 if (s != NULL)
ragge
1.21
737                         defid(qENAME);
738         }
ragge
1.43
739         r->rsym = q->n_sp;
ragge
1.46
740         r->rlparam = lparam;
ragge
1.74
741         nfree(q);
ragge
1.33
742
ragge
1.43
743         return r;
ragge
1.2
744 }
ragge
1.1
745
ragge
1.18
746 /*
747  * Called after a struct is declared to restore the environment.
748  */
ragge
1.1
749 NODE *
ragge
1.43
750 dclstruct(struct rstack *r)
ragge
1.2
751 {
ragge
1.43
752         NODE *n;
ragge
1.50
753         struct params *l, *m;
ragge
1.43
754         struct suedef *sue;
ragge
1.2
755         struct symtab *p;
ragge
1.46
756         int alsasz;
ragge
1.2
757         TWORD temp;
ragge
1.50
758         int ihighlow;
ragge
1.1
759
ragge
1.43
760         if (r->rsym == NULL) {
761                 sue = permalloc(sizeof(struct suedef));
ragge
1.65
762                 suedefcnt++;
ragge
1.43
763                 sue->suesize = 0;
764                 sue->suealign = ALSTRUCT;
ragge
1.18
765         } else
ragge
1.43
766                 sue = r->rsym->ssue;
ragge
1.1
767
ragge
1.43
768 #ifdef PCC_DEBUG
769         if (ddebug)
ragge
1.46
770                 printf("dclstruct(%s)\n"r->rsym ? r->rsym->sname : "??");
ragge
1.43
771 #endif
ragge
1.1
772         temp = (instruct&INSTRUCT)?STRTY:((instruct&INUNION)?UNIONTY:ENUMTY);
ragge
1.43
773         instruct = r->rinstruct;
774         strunem = r->rclass;
ragge
1.1
775         al = ALSTRUCT;
776
777         high = low = 0;
778
ragge
1.46
779         if ((l = r->rlparam) == NULL)
780                 l = lpole;
781         else
782                 l = l->next;
783
ragge
1.50
784         /* memory for the element array must be allocated first */
785         for (m = li = 1m != NULLm = m->next)
786                 i++;
787         sue->suelem = permalloc(sizeof(struct symtab *) * i);
788
789         for (i = 0l != NULLl = l->next) {
790                 sue->suelem[i++] = p = l->sym;
791
ragge
1.46
792                 if (p == NULL)
ragge
1.43
793                         cerror("gummy structure member");
ragge
1.46
794                 if (temp == ENUMTY) {
795                         if (p->soffset < low)
796                                 low = p->soffset;
797                         if (p->soffset > high)
798                                 high = p->soffset;
ragge
1.43
799                         p->ssue = sue;
ragge
1.1
800                         continue;
ragge
1.46
801                 }
ragge
1.43
802                 sa = talign(p->stypep->ssue);
ragge
1.21
803                 if (p->sclass & FIELD) {
ragge
1.1
804                         sz = p->sclass&FLDSIZ;
ragge
1.21
805                 } else {
ragge
1.52
806                         sz = tsize(p->stypep->sdfp->ssue);
ragge
1.1
807                 }
ragge
1.21
808                 if (sz > strucoff)
809                         strucoff = sz;  /* for use with unions */
810                 /*
811                  * set al, the alignment, to the lcm of the alignments
812                  * of the members.
813                  */
814                 SETOFF(alsa);
815         }
ragge
1.50
816         sue->suelem[i] = NULL;
ragge
1.46
817         SETOFF(strucoffal);
ragge
1.1
818
ragge
1.43
819         if (temp == ENUMTY) {
ragge
1.2
820                 TWORD ty;
ragge
1.1
821
ragge
1.43
822 #ifdef ENUMSIZE
ragge
1.1
823                 ty = ENUMSIZE(high,low);
ragge
1.43
824 #else
825                 if ((char)high == high && (char)low == low)
826                         ty = ctype(CHAR);
827                 else if ((short)high == high && (short)low == low)
828                         ty = ctype(SHORT);
829                 else
830                         ty =