Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20070819192451

Diff

Diff from 1.166 to:

Annotations

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

Annotated File View

ragge
1.166
1 /*      $Id: pftn.c,v 1.166 2007/08/19 19:24:51 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.157
70 #include <string.h> /* XXX - for strcmp */
71
ragge
1.33
72 struct symtab *spname;
73 struct symtab *cftnsp;
ragge
1.65
74 static int strunem;             /* currently parsed member type */
75 int arglistcntdimfuncnt;      /* statistics */
ragge
1.69
76 int symtabcntsuedefcnt;       /* statistics */
77 int autooff,            /* the next unused automatic offset */
ragge
1.146
78     maxautooff,         /* highest used automatic offset in function */
ragge
1.69
79     argoff,             /* the next unused argument offset */
80     strucoff;           /* the next structure offset position */
81 int retlab = NOLAB;     /* return label for subroutine */
82 int brklab;
83 int contlab;
84 int flostat;
ragge
1.91
85 int instructblevel;
ragge
1.150
86 int reachedprolab;
ragge
1.1
87
ragge
1.46
88 struct params;
89
ragge
1.59
90 #define ISSTR(ty) (ty == STRTY || ty == UNIONTY || ty == ENUMTY)
91 #define ISSOU(ty) (ty == STRTY || ty == UNIONTY)
92 #define MKTY(p, t, d, s) r = talloc(); *r = *p; \
ragge
1.74
93         r = argcast(rtds); *p = *rnfree(r);
ragge
1.59
94
ragge
1.43
95 /*
ragge
1.66
96  * Info stored for delaying string printouts.
97  */
98 struct strsched {
99         struct strsched *next;
100         int locctr;
101         struct symtab *sym;
102 } *strpole;
103
104 /*
ragge
1.43
105  * Linked list stack while reading in structs.
106  */
107 struct rstack {
108         struct  rstack *rnext;
109         int     rinstruct;
110         int     rclass;
111         int     rstrucoff;
ragge
1.46
112         struct  params *rlparam;
ragge
1.43
113         struct  symtab *rsym;
114 };
115
ragge
1.45
116 /*
ragge
1.47
117  * Linked list for parameter (and struct elements) declaration.
ragge
1.45
118  */
119 static struct params {
ragge
1.46
120         struct params *next, *prev;
ragge
1.45
121         struct symtab *sym;
ragge
1.47
122 } *lpole, *lparam;
ragge
1.45
123 static int nparams;
124
ragge
1.2
125 /* defines used for getting things off of the initialization stack */
ragge
1.1
126
ragge
1.30
127 static NODE *arrstk[10];
128 static int arrstkp;
ragge
1.60
129 static int intcompare;
ragge
1.1
130
ragge
1.2
131 void fixtype(NODE *pint class);
132 int fixclass(int classTWORD type);
133 int falloc(struct symtab *pint wint newNODE *pty);
ragge
1.30
134 static void dynalloc(struct symtab *pint *poff);
ragge
1.2
135 void inforce(OFFSZ n);
136 void vfdalign(int n);
ragge
1.46
137 static void ssave(struct symtab *);
ragge
1.66
138 static void strprint(void);
ragge
1.1
139
140 int ddebug = 0;
141
ragge
1.2
142 void
143 defid(NODE *qint class)
144 {
145         struct symtab *p;
ragge
1.92
146         TWORD typequal;
147         TWORD stpstq;
ragge
1.2
148         int scl;
ragge
1.52
149         union dimfun *dsym, *ddef;
ragge
1.124
150         int slevtempchanged;
ragge
1.1
151
ragge
1.32
152         if (q == NIL)
153                 return;  /* an error was detected */
ragge
1.1
154
ragge
1.33
155         p = q->n_sp;
ragge
1.1
156
ragge
1.54
157 #ifdef PCC_DEBUG
ragge
1.4
158         if (ddebug) {
ragge
1.33
159                 printf("defid(%s (%p), "p->snamep);
ragge
1.104
160                 tprint(stdoutq->n_typeq->n_qual);
ragge
1.50
161                 printf(", %s, (%p,%p)), level %d\n"scnames(class),
ragge
1.52
162                     q->n_dfq->n_sueblevel);
ragge
1.4
163         }
ragge
1.54
164 #endif
ragge
1.1
165
ragge
1.33
166         fixtype(qclass);
ragge
1.1
167
ragge
1.31
168         type = q->n_type;
ragge
1.92
169         qual = q->n_qual;
ragge
1.33
170         class = fixclass(classtype);
ragge
1.1
171
172         stp = p->stype;
ragge
1.92
173         stq = p->squal;
ragge
1.1
174         slev = p->slevel;
175
ragge
1.54
176 #ifdef PCC_DEBUG
ragge
1.4
177         if (ddebug) {
178                 printf("        modified to ");
ragge
1.104
179                 tprint(stdouttypequal);
ragge
1.4
180                 printf(", %s\n"scnames(class));
181                 printf("        previous def'n: ");
ragge
1.104
182                 tprint(stdoutstpstq);
ragge
1.50
183                 printf(", %s, (%p,%p)), level %d\n",
ragge
1.52
184                     scnames(p->sclass), p->sdfp->ssueslev);
ragge
1.4
185         }
ragge
1.54
186 #endif
ragge
1.1
187
ragge
1.56
188         if (blevel == 1) {
ragge
1.33
189                 switch (class) {
ragge
1.1
190                 default:
ragge
1.4
191                         if (!(class&FIELD))
ragge
1.56
192                                 uerror("declared argument %s missing",
ragge
1.4
193                                     p->sname );
ragge
1.1
194                 case MOS:
195                 case STNAME:
196                 case MOU:
197                 case UNAME:
198                 case MOE:
199                 case ENAME:
200                 case TYPEDEF:
201                         ;
ragge
1.56
202                 }
ragge
1.4
203         }
ragge
1.56
204
205         if (stp == UNDEF)
206                 goto enter/* New symbol */
ragge
1.1
207
ragge
1.33
208         if (type != stp)
209                 goto mismatch;
210
211         if (blevel > slev && (class == AUTO || class == REGISTER))
ragge
1.1
212                 /* new scope */
213                 goto mismatch;
214
ragge
1.55
215         /*
216          * test (and possibly adjust) dimensions.
217          * also check that prototypes are correct.
218          */
ragge
1.52
219         dsym = p->sdf;
220         ddef = q->n_df;
ragge
1.124
221         changed = 0;
ragge
1.55
222         for (temp = typetemp & TMASKtemp = DECREF(temp)) {
223                 if (ISARY(temp)) {
ragge
1.52
224                         if (dsym->ddim == 0) {
225                                 dsym->ddim = ddef->ddim;
ragge
1.124
226                                 changed = 1;
ragge
1.52
227                         } else if (ddef->ddim != 0 && dsym->ddim!=ddef->ddim) {
ragge
1.1
228                                 goto mismatch;
ragge
1.50
229                         }
ragge
1.1
230                         ++dsym;
231                         ++ddef;
ragge
1.55
232                 } else if (ISFTN(temp)) {
ragge
1.110
233                         /* add a late-defined prototype here */
234                         if (cftnsp == NULL && dsym->dfun == NULL)
235                                 dsym->dfun = ddef->dfun;
ragge
1.109
236                         if (!oldstyle && ddef->dfun != NULL &&
237                             chkftn(dsym->dfunddef->dfun))
ragge
1.59
238                                 uerror("declaration doesn't match prototype");
ragge
1.55
239                         dsym++, ddef++;
ragge
1.1
240                 }
ragge
1.50
241         }
ragge
1.124
242 #ifdef STABS
243         if (changed && gflag)
ragge
1.125
244                 stabs_chgsym(p); /* symbol changed */
ragge
1.124
245 #endif
ragge
1.1
246
247         /* check that redeclarations are to the same structure */
ragge
1.33
248         if ((temp == STRTY || temp == UNIONTY || temp == ENUMTY) &&
ragge
1.43
249             p->ssue != q->n_sue &&
ragge
1.33
250             class != STNAME && class != UNAME && class != ENAME) {
ragge
1.1
251                 goto mismatch;
ragge
1.33
252         }
ragge
1.1
253
ragge
1.33
254         scl = p->sclass;
ragge
1.1
255
ragge
1.54
256 #ifdef PCC_DEBUG
ragge
1.33
257         if (ddebug)
258                 printf("        previous class: %s\n"scnames(scl));
ragge
1.54
259 #endif
ragge
1.1
260
ragge
1.33
261         if (class&FIELD) {
ragge
1.1
262                 /* redefinition */
ragge
1.33
263                 if (!falloc(pclass&FLDSIZ1NIL)) {
ragge
1.1
264                         /* successful allocation */
ragge
1.46
265                         ssave(p);
ragge
1.1
266                         return;
ragge
1.33
267                 }
ragge
1.1
268                 /* blew it: resume at end of switch... */
ragge
1.33
269         } else switch(class) {
ragge
1.1
270
271         case EXTERN:
272                 switchscl ){
273                 case STATIC:
274                 case USTATIC:
275                         ifslev==0 ) return;
276                         break;
277                 case EXTDEF:
278                 case EXTERN:
279                 case FORTRAN:
280                 case UFORTRAN:
281                         return;
282                         }
283                 break;
284
285         case STATIC:
ragge
1.33
286                 if (scl==USTATIC || (scl==EXTERN && blevel==0)) {
ragge
1.1
287                         p->sclass = STATIC;
288                         return;
ragge
1.33
289                 }
ragge
1.1
290                 break;
291
292         case USTATIC:
ragge
1.33
293                 if (scl==STATIC || scl==USTATIC)
294                         return;
ragge
1.1
295                 break;
296
297         case TYPEDEF:
ragge
1.33
298                 if (scl == class)
299                         return;
ragge
1.1
300                 break;
301
302         case UFORTRAN:
ragge
1.33
303                 if (scl == UFORTRAN || scl == FORTRAN)
304                         return;
ragge
1.1
305                 break;
306
307         case FORTRAN:
ragge
1.33
308                 if (scl == UFORTRAN) {
ragge
1.1
309                         p->sclass = FORTRAN;
310                         return;
ragge
1.33
311                 }
ragge
1.1
312                 break;
313
314         case MOU:
315         case MOS:
ragge
1.33
316                 if (scl == class) {
317                         if (oalloc(p, &strucoff))
318                                 break;
319                         if (class == MOU)
320                                 strucoff = 0;
ragge
1.46
321                         ssave(p);
ragge
1.1
322                         return;
ragge
1.33
323                 }
ragge
1.1
324                 break;
325
ragge
1.78
326         case MOE:
ragge
1.1
327                 break;
328
329         case EXTDEF:
ragge
1.10
330                 switch (scl) {
331                 case EXTERN:
ragge
1.1
332                         p->sclass = EXTDEF;
333                         return;
ragge
1.10
334                 case USTATIC:
335                         p->sclass = STATIC;
336                         return;
337                 }
ragge
1.1
338                 break;
339
340         case STNAME:
341         case UNAME:
342         case ENAME:
ragge
1.33
343                 if (scl != class)
344                         break;
ragge
1.43
345                 if (p->ssue->suesize == 0)
ragge
1.33
346                         return;  /* previous entry just a mention */
ragge
1.1
347                 break;
348
349         case AUTO:
350         case REGISTER:
351                 ;  /* mismatch.. */
ragge
1.33
352         }
ragge
1.1
353
354         mismatch:
355
ragge
1.55
356         /*
357          * Only allowed for automatic variables.
358          */
359         if (blevel == slev || class == EXTERN || class == FORTRAN ||
360             class == UFORTRAN) {
ragge
1.158
361                 if (ISSTR(class) && !ISSTR(p->sclass)) {
362                         uerror("redeclaration of %s"p->sname);
363                         return;
364                 }
ragge
1.24
365         }
ragge
1.55
366         q->n_sp = p = hide(p);
ragge
1.1
367
368         enter:  /* make a new entry */
369
ragge
1.54
370 #ifdef PCC_DEBUG
ragge
1.33
371         if(ddebug)
372                 printf("        new entry made\n");
ragge
1.54
373 #endif
ragge
1.1
374         p->stype = type;
ragge
1.93
375         p->squal = qual;
ragge
1.1
376         p->sclass = class;
377         p->slevel = blevel;
ragge
1.33
378         p->soffset = NOOFFSET;
ragge
1.1
379         p->suse = lineno;
ragge
1.43
380         if (class == STNAME || class == UNAME || class == ENAME) {
381                 p->ssue = permalloc(sizeof(struct suedef));
ragge
1.65
382                 suedefcnt++;
ragge
1.43
383                 p->ssue->suesize = 0;
384                 p->ssue->suelem = NULL
385                 p->ssue->suealign = ALSTRUCT;
386         } else {
387                 switch (BTYPE(type)) {
ragge
1.1
388                 case STRTY:
389                 case UNIONTY:
390                 case ENUMTY:
ragge
1.43
391                         p->ssue = q->n_sue;
ragge
1.1
392                         break;
393                 default:
ragge
1.45
394                         p->ssue = MKSUE(BTYPE(type));
ragge
1.1
395                 }
ragge
1.43
396         }
ragge
1.1
397
398         /* copy dimensions */
ragge
1.52
399         p->sdf = q->n_df;
ragge
1.68
400         /* Do not save param info for old-style functions */
401         if (ISFTN(type) && oldstyle)
402                 p->sdf->dfun = NULL;
ragge
1.1
403
404         /* allocate offsets */
ragge
1.33
405         if (class&FIELD) {
406                 (voidfalloc(pclass&FLDSIZ0NIL);  /* new entry */
ragge
1.46
407                 ssave(p);
ragge
1.33
408         } else switch (class) {
ragge
1.1
409
ragge
1.131
410         case REGISTER:
ragge
1.147
411                 cerror("register var");
ragge
1.131
412
ragge
1.1
413         case AUTO:
ragge
1.30
414                 if (arrstkp)
415                         dynalloc(p, &autooff);
416                 else
ragge
1.54
417                         oalloc(p, &autooff);
ragge
1.1
418                 break;
419         case STATIC:
420         case EXTDEF:
ragge
1.33
421                 p->soffset = getlab();
ragge
1.108
422 #ifdef GCC_COMPAT
423                 {       extern char *renname;
424                         if (renname)
425                                 gcc_rename(prenname);
426                         renname = NULL;
427                 }
428 #endif
ragge
1.1
429                 break;
430
431         case EXTERN:
432         case UFORTRAN:
433         case FORTRAN:
ragge
1.33
434                 p->soffset = getlab();
ragge
1.115
435 #ifdef notdef
436                 /* Cannot reset level here. What does the standard say??? */
ragge
1.1
437                 p->slevel = 0;
ragge
1.115
438 #endif
ragge
1.108
439 #ifdef GCC_COMPAT
440                 {       extern char *renname;
441                         if (renname)
442                                 gcc_rename(prenname);
443                         renname = NULL;
444                 }
445 #endif
ragge
1.1
446                 break;
447         case MOU:
448         case MOS:
ragge
1.54
449                 oalloc(p, &strucoff);
450                 if (class == MOU)
451                         strucoff = 0;
ragge
1.46
452                 ssave(p);
ragge
1.1
453                 break;
454
455         case MOE:
ragge
1.33
456                 p->soffset = strucoff++;
ragge
1.46
457                 ssave(p);
ragge
1.1
458                 break;
ragge
1.131
459
ragge
1.33
460         }
ragge
1.1
461
ragge
1.124
462 #ifdef STABS
463         if (gflag)
ragge
1.125
464                 stabs_newsym(p);
ragge
1.124
465 #endif
ragge
1.1
466
ragge
1.54
467 #ifdef PCC_DEBUG
ragge
1.33
468         if (ddebug)
ragge
1.52
469                 printf"       sdf, ssue, offset: %p, %p, %d\n",
470                     p->sdfp->ssuep->soffset);
ragge
1.54
471 #endif
ragge
1.1
472
ragge
1.33
473 }
ragge
1.1
474
ragge
1.2
475 void
ragge
1.46
476 ssave(struct symtab *sym)
ragge
1.2
477 {
ragge
1.46
478         struct params *p;
479
480         p = tmpalloc(sizeof(struct params));
481         p->next = NULL;
482         p->sym = sym;
483
484         if (lparam == NULL) {
485                 p->prev = (struct params *)&lpole;
486                 lpole = p;
487         } else {
488                 lparam->next = p;
489                 p->prev = lparam;
ragge
1.2
490         }
ragge
1.46
491         lparam = p;
ragge
1.2
492 }
ragge
1.1
493
ragge
1.2
494 /*
495  * end of function
496  */
497 void
498 ftnend()
499 {
ragge
1.51
500         extern struct savbc *savbc;
ragge
1.62
501         extern struct swdef *swpole;
ragge
1.138
502         char *c;
ragge
1.51
503
ragge
1.69
504         if (retlab != NOLAB && nerrors == 0) { /* inside a real function */
ragge
1.134
505                 plabel(retlab);
ragge
1.112
506                 efcode(); /* struct return handled here */
ragge
1.138
507                 c = cftnsp->sname;
508 #ifdef GCC_COMPAT
509                 c = gcc_findname(cftnsp);
510 #endif
ragge
1.149
511                 SETOFF(maxautooffALCHAR);
512                 send_passt(IP_EPILOG0maxautooff/SZCHARc,
ragge
1.138
513                     cftnsp->stypecftnsp->sclass == EXTDEFretlab);
ragge
1.69
514         }
ragge
1.33
515
ragge
1.1
516         tcheck();
517         brklab = contlab = retlab = NOLAB;
518         flostat = 0;
ragge
1.51
519         if (nerrors == 0) {
520                 if (savbc != NULL)
521                         cerror("bcsave error");
ragge
1.46
522                 if (lparam != NULL)
523                         cerror("parameter reset error");
ragge
1.62
524                 if (swpole != NULL)
525                         cerror("switch error");
ragge
1.46
526         }
ragge
1.51
527         savbc = NULL;
ragge
1.46
528         lparam = NULL;
ragge
1.146
529         maxautooff = autooff = AUTOINIT;
ragge
1.1
530         reached = 1;
ragge
1.66
531
532         if (isinlining)
533                 inline_end();
534         inline_prtout();
535
536         strprint();
537
ragge
1.37
538         tmpfree(); /* Release memory resources */
ragge
1.2
539 }
ragge
1.89
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.138
548         char *c;
ragge
1.150
549         int i;
ragge
1.45
550
ragge
1.1
551         argoff = ARGINIT;
ragge
1.45
552
ragge
1.56
553         /*
ragge
1.59
554          * Deal with fun(void) properly.
555          */
ragge
1.84
556         if (nparams == 1 && lparam->sym->stype == VOID)
ragge
1.59
557                 goto done;
558
559         /*
ragge
1.56
560          * Generate a list for bfcode().
561          * Parameters were pushed in reverse order.
562          */
ragge
1.58
563         if (nparams != 0)
564                 parr = tmpalloc(sizeof(struct symtab *) * nparams);
ragge
1.56
565
ragge
1.140
566         if (nparams)
567             for (a = lparami = 0a != NULL && a != (struct params *)&lpole;
ragge
1.47
568             a = a->prev) {
ragge
1.56
569
ragge
1.59
570                 p = a->sym;
ragge
1.56
571                 parr[i++] = p;
ragge
1.59
572                 if (p->stype == FARG) {
573                         p->stype = INT;
574                         p->ssue = MKSUE(INT);
575                 }
576                 if (ISARY(p->stype)) {
577                         p->stype += (PTR-ARY);
578                         p->sdf++;
ragge
1.97
579                 } else if (ISFTN(p->stype)) {
580                         werror("function declared as argument");
581                         p->stype = INCREF(p->stype);
ragge
1.59
582                 }
ragge
1.56
583                 /* always set aside space, even for register arguments */
ragge
1.129
584                 oalloc(p, &argoff);
ragge
1.124
585 #ifdef STABS
586                 if (gflag)
ragge
1.129
587                         stabs_newsym(p);
ragge
1.124
588 #endif
ragge
1.12
589         }
ragge
1.59
590         if (oldstyle && (df = cftnsp->sdf) && (al = df->dfun)) {
591                 /*
592                  * Check against prototype of oldstyle function.
593                  */
594                 alb = al2 = tmpalloc(sizeof(union arglist) * nparams * 3 + 1);
595                 for (i = 0i < nparamsi++) {
596                         TWORD type = parr[i]->stype;
597                         (al2++)->type = type;
598                         if (ISSTR(BTYPE(type)))
599                                 (al2++)->sue = parr[i]->ssue;
600                         while (!ISFTN(type) && !ISARY(type) && type > BTMASK)
601                                 type = DECREF(type);
602                         if (type > BTMASK)
603                                 (al2++)->df = parr[i]->sdf;
604                 }
605                 al2->type = TNULL;
ragge
1.60
606                 intcompare = 1;
ragge
1.59
607                 if (chkftn(alalb))
608                         uerror("function doesn't match prototype");
ragge
1.60
609                 intcompare = 0;
ragge
1.59
610         }
611 done:   cendarg();
ragge
1.138
612         c = cftnsp->sname;
613 #ifdef GCC_COMPAT
614         c = gcc_findname(cftnsp);
615 #endif
ragge
1.150
616 #if 0
ragge
1.144
617         prolab = getlab();
ragge
1.138
618         send_passt(IP_PROLOG, -1, -1ccftnsp->stype
ragge
1.144
619             cftnsp->sclass == EXTDEFprolab);
ragge
1.150
620 #endif
ragge
1.144
621         plabel(prolab); /* after prolog, used in optimization */
622         retlab = getlab();
ragge
1.45
623         bfcode(parrnparams);
ragge
1.153
624         if (xtemps) {
625                 /* put arguments in temporaries */
626                 for (i = 0i < nparamsi++) {
627                         NODE *q, *r, *s;
628
629                         p = parr[i];
630                         if (p->stype == STRTY || p->stype == UNIONTY ||
631                             cisreg(p->stype) == 0)
632                                 continue;
633                         spname = p;
634                         q = buildtree(NAME00);
635                         r = tempnode(0p->stypep->sdfp->ssue);
636                         s = buildtree(ASSIGNrq);
637                         p->soffset = r->n_lval;
638                         p->sflags |= STNODE;
639                         ecomp(s);
640                 }
ragge
1.154
641                 plabel(getlab()); /* used when spilling */
ragge
1.153
642         }
ragge
1.47
643         lparam = NULL;
ragge
1.45
644         nparams = 0;
ragge
1.2
645 }
ragge
1.1
646
ragge
1.21
647 /*
648  * reference to a structure or union, with no definition
649  */
ragge
1.1
650 NODE *
ragge
1.33
651 rstruct(char *tagint soru)
ragge
1.21
652 {
ragge
1.2
653         struct symtab *p;
654         NODE *q;
ragge
1.32
655
ragge
1.40
656         p = (struct symtab *)lookup(tagSTAGNAME);
ragge
1.21
657         switch (p->stype) {
ragge
1.1
658
659         case UNDEF:
660         def:
ragge
1.74
661                 q = block(NAMENILNIL000);
ragge
1.33
662                 q->n_sp = p;
ragge
1.31
663                 q->n_type = (soru&INSTRUCT) ? STRTY :
ragge
1.21
664                     ((soru&INUNION) ? UNIONTY : ENUMTY);
665                 defid(q, (soru&INSTRUCT) ? STNAME :
666                     ((soru&INUNION) ? UNAME : ENAME));
ragge
1.74
667                 nfree(q);
ragge
1.1
668                 break;
669
670         case STRTY:
ragge
1.21
671                 if (soru & INSTRUCT)
672                         break;
ragge
1.1
673                 goto def;
674
675         case UNIONTY:
ragge
1.21
676                 if (soru & INUNION)
677                         break;
ragge
1.1
678                 goto def;
679
680         case ENUMTY:
ragge
1.21
681                 if (!(soru&(INUNION|INSTRUCT)))
682                         break;
ragge
1.1
683                 goto def;
684
ragge
1.21
685         }
ragge
1.43
686         q = mkty(p->stype0p->ssue);
687         q->n_sue = p->ssue;
688         return q;
ragge
1.21
689 }
ragge
1.1
690
ragge
1.2
691 void
ragge
1.33
692 moedef(char *name)
ragge
1.2
693 {
694         NODE *q;
ragge
1.1
695
ragge
1.74
696         q = block(NAMENILNILMOETY00);
ragge
1.33
697         q->n_sp = lookup(name0);
698         defid(qMOE);
ragge
1.74
699         nfree(q);
ragge
1.2
700 }
ragge
1.1
701
ragge
1.2
702 /*
703  * begining of structure or union declaration
704  */
ragge
1.43
705 struct rstack *
ragge
1.33
706 bstruct(char *nameint soru)
ragge
1.2
707 {
ragge
1.43
708         struct rstack *r;
ragge
1.33
709         struct symtab *s;
ragge
1.2
710         NODE *q;
ragge
1.1
711
ragge
1.33
712         if (name != NULL)
ragge
1.40
713                 s = lookup(nameSTAGNAME);
ragge
1.33
714         else
715                 s = NULL;
716
ragge
1.43
717         r = tmpalloc(sizeof(struct rstack));
718         r->rinstruct = instruct;
719         r->rclass = strunem;
720         r->rstrucoff = strucoff;
721
ragge
1.1
722         strucoff = 0;
723         instruct = soru;
ragge
1.74
724         q = block(NAMENILNIL000);
ragge
1.33
725         q->n_sp = s;
ragge
1.21
726         if (instruct==INSTRUCT) {
ragge
1.18
727                 strunem = MOS;
ragge
1.31
728                 q->n_type = STRTY;
ragge
1.33
729                 if (s != NULL)
ragge
1.21
730                         defid(qSTNAME);
731         } else if(instruct == INUNION) {
ragge
1.18
732                 strunem = MOU;
ragge
1.31
733                 q->n_type = UNIONTY;
ragge
1.33
734                 if (s != NULL)
ragge
1.21
735                         defid(qUNAME);
736         } else { /* enum */
ragge
1.18
737                 strunem = MOE;
ragge
1.31
738                 q->n_type = ENUMTY;
ragge
1.33
739                 if (s != NULL)
ragge
1.21
740                         defid(qENAME);
741         }
ragge
1.43
742         r->rsym = q->n_sp;
ragge
1.46
743         r->rlparam = lparam;
ragge
1.74
744         nfree(q);
ragge
1.33
745
ragge
1.43
746         return r;
ragge
1.2
747 }
ragge
1.1
748
ragge
1.18
749 /*
750  * Called after a struct is declared to restore the environment.
751  */
ragge
1.1
752 NODE *
ragge
1.43
753 dclstruct(struct rstack *r)
ragge
1.2
754 {
ragge
1.43
755         NODE *n;
ragge
1.50
756         struct params *l, *m;
ragge
1.43
757         struct suedef *sue;
ragge
1.2
758         struct symtab *p;
ragge
1.46
759         int alsasz;
ragge
1.2
760         TWORD temp;
ragge
1.50
761         int ihighlow;
ragge
1.1
762
ragge
1.43
763         if (r->rsym == NULL) {
764                 sue = permalloc(sizeof(struct suedef));
ragge
1.65
765                 suedefcnt++;
ragge
1.43
766                 sue->suesize = 0;
767                 sue->suealign = ALSTRUCT;
ragge
1.18
768         } else
ragge
1.43
769                 sue = r->rsym->ssue;
ragge
1.1
770
ragge
1.43
771 #ifdef PCC_DEBUG
772         if (ddebug)
ragge
1.46
773                 printf("dclstruct(%s)\n"r->rsym ? r->rsym->sname : "??");
ragge
1.43
774 #endif
ragge
1.1
775         temp = (instruct&INSTRUCT)?STRTY:((instruct&INUNION)?UNIONTY:ENUMTY);
ragge
1.43
776         instruct = r->rinstruct;
777         strunem = r->rclass;
ragge
1.1
778         al = ALSTRUCT;
779
780         high = low = 0;
781
ragge
1.46
782         if ((l = r->rlparam) == NULL)
783                 l = lpole;
784         else
785                 l = l->next;
786
ragge
1.50
787         /* memory for the element array must be allocated first */
788         for (m = li = 1m != NULLm = m->next)
789                 i++;
790         sue->suelem = permalloc(sizeof(struct symtab *) * i);
791
792         for (i = 0l != NULLl = l->next) {
793                 sue->suelem[i++] = p = l->sym;
794
ragge
1.46
795                 if (p == NULL)
ragge
1.43
796                         cerror("gummy structure member");
ragge
1.46
797                 if (temp == ENUMTY) {
798                         if (p->soffset < low)
799                                 low = p->soffset;
800                         if (p->soffset > high)
801                                 high = p->soffset;
ragge
1.43
802                         p->ssue = sue;
ragge
1.1
803                         continue;
ragge
1.46
804                 }
ragge
1.43
805                 sa = talign(p->stypep->ssue);
ragge
1.21
806                 if (p->sclass & FIELD) {
ragge
1.1
807                         sz = p->sclass&FLDSIZ;
ragge
1.21
808                 } else {
ragge
1.52
809                         sz = tsize(p->stypep->sdfp->ssue);
ragge
1.1
810                 }
ragge
1.21
811                 if (sz > strucoff)
812                         strucoff = sz;  /* for use with unions */
813                 /*
814                  * set al, the alignment, to the lcm of the alignments
815                  * of the members.
816                  */
817                 SETOFF(alsa);
818         }
ragge
1.50
819         sue->suelem[i] = NULL;
ragge
1.46
820         SETOFF(strucoffal);
ragge
1.1
821
ragge
1.43
822         if (temp == ENUMTY) {
ragge
1.2
823                 TWORD ty;
ragge
1.1
824
ragge
1.43
825 #ifdef ENUMSIZE
ragge
1.1
826                 ty = ENUMSIZE(high,low);
ragge
1.43</