Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20050806121819

Diff

Diff from 1.145 to:

Annotations

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

Annotated File View

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