Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20070930203323

Diff

Diff from 1.174 to:

Annotations

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

Annotated File View

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