Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:otto:20071012170232

Diff

Diff from 1.179 to:

Annotations

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

Annotated File View

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