Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20080129215030

Diff

Diff from 1.193 to:

Annotations

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

Annotated File View

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