Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20041230103516

Diff

Diff from 1.129 to:

Annotations

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

Annotated File View

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