Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20050120212414

Diff

Diff from 1.134 to:

Annotations

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

Annotated File View

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