Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20050905170716

Diff

Diff from 1.146 to:

Annotations

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

Annotated File View

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