Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20160305153124

Diff

Diff from 1.16 to:

Annotations

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

Annotated File View

ragge
1.16
1 /*      $Id: pftn.c,v 1.16 2016/03/05 15:31:25 ragge Exp $      */
ragge
1.1
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  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 /*
27  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
28  *
29  * Redistribution and use in source and binary forms, with or without
30  * modification, are permitted provided that the following conditions
31  * are met:
32  *
33  * Redistributions of source code and documentation must retain the above
34  * copyright notice, this list of conditions and the following disclaimer.
35  * Redistributions in binary form must reproduce the above copyright
36  * notice, this list of conditionsand the following disclaimer in the
37  * documentation and/or other materials provided with the distribution.
38  * All advertising materials mentioning features or use of this software
39  * must display the following acknowledgement:
40  *      This product includes software developed or owned by Caldera
41  *      International, Inc.
42  * Neither the name of Caldera International, Inc. nor the names of other
43  * contributors may be used to endorse or promote products derived from
44  * this software without specific prior written permission.
45  *
46  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
47  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
48  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
49  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
50  * DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
51  * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
52  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
53  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
54  * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
55  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
56  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
57  * POSSIBILITY OF SUCH DAMAGE.
58  */
59
60 /*
61  * Many changes from the 32V sources, among them:
62  * - New symbol table manager (moved to another file).
63  * - Prototype saving/checks.
64  */
65
66 # include "pass1.h"
67
68 #include "cgram.h"
69
70 struct symtab *cftnsp;
71 int arglistcntdimfuncnt;      /* statistics */
72 int symtabcntsuedefcnt;       /* statistics */
73 int autooff,            /* the next unused automatic offset */
74     maxautooff,         /* highest used automatic offset in function */
75     argoff;             /* the next unused argument offset */
76 int retlab = NOLAB;     /* return label for subroutine */
77 int brklab;
78 int contlab;
79 int flostat;
80 int blevel;
81 int reachedprolab;
82
83 struct params;
84
85 #define MKTY(p, t, d, s) r = talloc(); *r = *p; \
86         r = argcast(rtds); *p = *rnfree(r);
87
88 /*
89  * Linked list stack while reading in structs.
90  */
91 struct rstack {
92         struct  rstack *rnext;
93         int     rsou;
94         int     rstr;
95         struct  symtab *rsym;
96 //      struct  symtab *rb;
97         struct  attr *ap;
98         int     flags;
99 #define LASTELM 1
100 } *rpole;
101
102 /*
103  * Linked list for parameter (and struct elements) declaration.
104  */
105 static struct params {
plunky
1.8
106         struct params *prev;
ragge
1.1
107         struct symtab *sym;
plunky
1.8
108 } *lparam;
ragge
1.1
109 static int nparams;
110
111 /* defines used for getting things off of the initialization stack */
112
113 NODE *arrstk[10];
114 int arrstkp;
115 static int intcompare;
116 NODE *parlink;
117
118 void fixtype(NODE *pint class);
119 int fixclass(int classTWORD type);
120 static void dynalloc(struct symtab *pint *poff);
121 static void evalidx(struct symtab *p);
122 int isdyn(struct symtab *p);
123 void inforce(OFFSZ n);
124 void vfdalign(int n);
125 static void ssave(struct symtab *);
126 #ifdef PCC_DEBUG
127 static void alprint(union arglist *alint in);
128 #endif
129 static void lcommadd(struct symtab *sp);
130 static NODE *mkcmplx(NODE *pTWORD dt);
131 extern int fun_inline;
132
ragge
1.16
133 FLT flt_zero = { .fp = 0.0, };
134
ragge
1.1
135 /*
136  * Declaration of an identifier.  Handles redeclarations, hiding,
137  * incomplete types and forward declarations.
138  *
139  * q is a TYPE node setup after parsing with n_type, n_df and n_ap.
140  * n_sp is a pointer to the not-yet initalized symbol table entry
141  * unless it's a redeclaration or supposed to hide a variable.
142  */
143
144 void
145 defid(NODE *qint class)
146 {
147         struct attr *ap;
148         struct symtab *p;
149         TWORD typequal;
150         TWORD stpstq;
151         int scl;
152         union dimfun *dsym, *ddef;
153         int slevtempchanged;
154
155         if (q == NIL)
156                 return;  /* an error was detected */
157
158         p = q->n_sp;
159
160         if (p->sname == NULL)
161                 cerror("defining null identifier");
162
163 #ifdef PCC_DEBUG
164         if (ddebug) {
165                 printf("defid(%s (%p), "p->snamep);
plunky
1.6
166                 tprint(q->n_typeq->n_qual);
ragge
1.1
167                 printf(", %s, (%p)), level %d\n\t"scnames(class),
168                     q->n_dfblevel);
ragge
1.10
169 #ifdef GCC_COMPAT
ragge
1.1
170                 dump_attr(q->n_ap);
ragge
1.10
171 #endif
ragge
1.1
172         }
173 #endif
174
175         fixtype(qclass);
176
177         type = q->n_type;
178         qual = q->n_qual;
179         class = fixclass(classtype);
180
181         stp = p->stype;
182         stq = p->squal;
183         slev = p->slevel;
184
185 #ifdef PCC_DEBUG
186         if (ddebug) {
187                 printf("        modified to ");
plunky
1.6
188                 tprint(typequal);
ragge
1.1
189                 printf(", %s\n"scnames(class));
190                 printf("        previous def'n: ");
plunky
1.6
191                 tprint(stpstq);
ragge
1.1
192                 printf(", %s, (%p,%p)), level %d\n",
193                     scnames(p->sclass), p->sdfp->sapslev);
194         }
195 #endif
196
197         if (blevel == 1) {
198                 switch (class) {
199                 default:
200                         if (!(class&FIELD) && !ISFTN(type))
201                                 uerror("declared argument %s missing",
202                                     p->sname );
203                 case MOS:
204                 case MOU:
205                         cerror("field5");
206                 case TYPEDEF:
207                 case PARAM:
208                         ;
209                 }
210         }
211
212         if (stp == UNDEF)
213                 goto enter/* New symbol */
214
215         if (type != stp)
216                 goto mismatch;
217
218         if (blevel > slev && (class == AUTO || class == REGISTER))
219                 /* new scope */
220                 goto mismatch;
221
222         /*
223          * test (and possibly adjust) dimensions.
224          * also check that prototypes are correct.
225          */
226         dsym = p->sdf;
227         ddef = q->n_df;
228         changed = 0;
229         for (temp = typetemp & TMASKtemp = DECREF(temp)) {
230                 if (ISARY(temp)) {
231                         if (dsym->ddim == NOOFFSET) {
232                                 dsym->ddim = ddef->ddim;
233                                 changed = 1;
234                         } else if (ddef->ddim != NOOFFSET &&
235                             dsym->ddim!=ddef->ddim) {
236                                 goto mismatch;
237                         }
238                         ++dsym;
239                         ++ddef;
240                 } else if (ISFTN(temp)) {
241                         /* add a late-defined prototype here */
242                         if (cftnsp == NULL && dsym->dfun == NULL)
243                                 dsym->dfun = ddef->dfun;
244                         if (!oldstyle && ddef->dfun != NULL &&
245                             chkftn(dsym->dfunddef->dfun))
246                                 uerror("declaration doesn't match prototype");
247                         dsym++, ddef++;
248                 }
249         }
250 #ifdef STABS
251         if (changed && gflag)
252                 stabs_chgsym(p); /* symbol changed */
253 #endif
254
255         /* check that redeclarations are to the same structure */
256         if (temp == STRTY || temp == UNIONTY) {
257                 if (strmemb(p->sap) != strmemb(q->n_ap))
258                         goto mismatch;
259         }
260
261         scl = p->sclass;
262
263 #ifdef PCC_DEBUG
264         if (ddebug)
265                 printf("        previous class: %s\n"scnames(scl));
266 #endif
267
268         /*
269          * Its allowed to add attributes to existing declarations.
270          * Be careful though not to trash existing attributes.
271          * XXX - code below is probably not correct.
272          */
273         if (p->sap && p->sap->atype <= ATTR_MAX) {
274                 /* nothing special, just overwrite */
275                 p->sap = q->n_ap;
276         } else {
277                 if (p->slevel == blevel) {
278                         for (ap = q->n_apapap = ap->next) {
279                                 if (ap->atype > ATTR_MAX)
ragge
1.14
280                                         p->sap = attr_add(p->sapattr_dup(ap));
ragge
1.1
281                         }
282                 } else
283                         p->sap = q->n_ap;
284         }
285
286         if (class & FIELD)
287                 cerror("field1");
288         switch(class) {
289
290         case EXTERN:
291                 if (pragma_renamed)
292                         p->soname = pragma_renamed;
293                 pragma_renamed = NULL;
294                 switchscl ){
295                 case STATIC:
296                 case USTATIC:
297                         ifslev==0 )
298                                 goto done;
299                         break;
300                 case EXTDEF:
301                 case EXTERN:
302                         goto done;
303                 case SNULL:
304                         if (p->sflags & SINLINE) {
305                                 p->sclass = EXTDEF;
306                                 inline_ref(p);
307                                 goto done;
308                         }
309                         break;
310                 }
311                 break;
312
313         case STATIC:
314                 if (scl==USTATIC || (scl==EXTERN && blevel==0)) {
315                         p->sclass = STATIC;
316                         goto done;
317                 }
318                 if (changed || (scl == STATIC && blevel == slev))
319                         goto done/* identical redeclaration */
320                 break;
321
322         case USTATIC:
323                 if (scl==STATIC || scl==USTATIC)
324                         goto done;
325                 break;
326
327         case TYPEDEF:
328                 if (scl == class)
329                         goto done;
330                 break;
331
332         case MOU:
333         case MOS:
334                 cerror("field6");
335
336         case EXTDEF:
337                 switch (scl) {
338                 case EXTERN:
339                         p->sclass = EXTDEF;
340                         goto done;
341                 case USTATIC:
342                         p->sclass = STATIC;
343                         goto done;
344                 case SNULL:
345                         /*
346                          * Handle redeclarations of inlined functions.
347                          * This is allowed if the previous declaration is of
348                          * type gnu_inline.
349                          */
ragge
1.10
350 #ifdef GCC_COMPAT
ragge
1.1
351                         if (attr_find(p->sapGCC_ATYP_GNU_INLINE))
352                                 goto done;
ragge
1.10
353 #endif
ragge
1.1
354                         break;
355                 }
356                 break;
357
358         case AUTO:
359         case REGISTER:
360                 break;  /* mismatch.. */
361         case SNULL:
362                 if (fun_inline && ISFTN(type))
363                         goto done;
364                 break;
365         }
366
367         mismatch:
368
369         /*
370          * Only allowed for automatic variables.
371          */
372         if (blevel <= slev || class == EXTERN) {
373                 uerror("redeclaration of %s"p->sname);
374                 return;
375         }
376         q->n_sp = p = hide(p);
377
378         enter:  /* make a new entry */
379
380 #ifdef PCC_DEBUG
381         if(ddebug)
382                 printf("        new entry made\n");
383 #endif
ragge
1.10
384 #ifdef GCC_COMPAT
ragge
1.1
385         if (type < BTMASK && (ap = attr_find(q->n_apGCC_ATYP_MODE))) {
386                 type = ENUNSIGN(ap->iarg(0));
387                 if (type == XTYPE)
388                         uerror("fix XTYPE basetyp");
389         }
ragge
1.10
390 #endif
ragge
1.1
391         p->stype = type;
392         p->squal = qual;
393         p->sclass = (char)class;
394         p->slevel = (char)blevel;
395         p->soffset = NOOFFSET;
396 #if 0
397         if (class != TYPEDEF && blevel == 0)
398                 p->soname = decoratename(pNM_NORMAL);
399 #endif
400         if (q->n_ap)
401                 p->sap = attr_add(q->n_app->sap);
402
403         /* copy dimensions */
404         p->sdf = q->n_df;
405         /* Do not save param info for old-style functions */
406         if (ISFTN(type) && oldstyle)
407                 p->sdf->dfun = NULL;
408
409         if (arrstkp)
410                 evalidx(p);
411
412         /* allocate offsets */
413         if (class&FIELD) {
414                 cerror("field2");  /* new entry */
415         } else switch (class) {
416
417         case REGISTER:
418                 cerror("register var");
419
420         case AUTO:
421                 if (isdyn(p)) {
422                         p->sflags |= SDYNARRAY;
423                         dynalloc(p, &autooff);
424                 } else
425                         oalloc(p, &autooff);
426                 break;
427
428         case PARAM:
429                 if (q->n_type != FARG)
430                         oalloc(p, &argoff);
431                 break;
432                 
433         case STATIC:
434         case EXTDEF:
435         case EXTERN:
436                 p->soffset = getlab();
437                 if (pragma_renamed)
438                         p->soname = pragma_renamed;
439                 pragma_renamed = NULL;
440                 break;
441
442         case MOU:
443         case MOS:
444                 cerror("field7");
445         case SNULL:
446 #ifdef notdef
447                 if (fun_inline) {
448                         p->slevel = 1;
449                         p->soffset = getlab();
450                 }
451 #endif
452                 break;
453         }
454
455 #ifdef STABS
456         if (gflag && p->stype != FARG)
457                 stabs_newsym(p);
458 #endif
459
460 done:
461         cxxsetname(p);
462         fixdef(p);      /* Leave last word to target */
463 #ifndef HAVE_WEAKREF
464         {
465                 struct attr *at;
466
467                 /* Refer renamed function */
468                 if ((at = attr_find(p->sapGCC_ATYP_WEAKREF)))
469                         p->soname = at->sarg(0);
470         }
471 #endif
472 #ifdef PCC_DEBUG
473         if (ddebug) {
474                 printf"       sdf, offset: %p, %d\n\t",
475                     p->sdfp->soffset);
ragge
1.10
476 #ifdef GCC_COMPAT
ragge
1.1
477                 dump_attr(p->sap);
ragge
1.10
478 #endif
ragge
1.1
479         }
480 #endif
481 }
482
483 void
484 ssave(struct symtab *sym)
485 {
486         struct params *p;
487
488         p = tmpalloc(sizeof(struct params));
plunky
1.8
489         p->prev = lparam;
ragge
1.1
490         p->sym = sym;
491         lparam = p;
492 }
493
494 /*
495  * end of function
496  */
497 void
plunky
1.3
498 ftnend(void)
ragge
1.1
499 {
ragge
1.10
500 #ifdef GCC_COMPAT
ragge
1.1
501         struct attr *gc, *gd;
ragge
1.10
502 #endif
ragge
1.1
503         extern NODE *cftnod;
504         extern struct savbc *savbc;
505         extern struct swdef *swpole;
506         extern int tvaloff;
507         char *c;
508
509         if (retlab != NOLAB && nerrors == 0) { /* inside a real function */
510                 plabel(retlab);
511                 if (cftnod)
512                         ecomp(buildtree(FORCEcftnodNIL));
513                 efcode(); /* struct return handled here */
514                 if ((c = cftnsp->soname) == NULL)
515                         c = addname(exname(cftnsp->sname));
516                 SETOFF(maxautooffALCHAR);
517                 send_passt(IP_EPILOGmaxautooff/SZCHARc,
518                     cftnsp->stypecftnsp->sclass == EXTDEFretlabtvaloff);
519         }
520
521         cftnod = NIL;
522         tcheck();
523         brklab = contlab = retlab = NOLAB;
524         flostat = 0;
525         if (nerrors == 0) {
526                 if (savbc != NULL)
527                         cerror("bcsave error");
528                 if (lparam != NULL)
529                         cerror("parameter reset error");
530                 if (swpole != NULL)
531                         cerror("switch error");
532         }
ragge
1.10
533 #ifdef GCC_COMPAT
ragge
1.1
534         if (cftnsp) {
535                 gc = attr_find(cftnsp->sapGCC_ATYP_CONSTRUCTOR);
536                 gd = attr_find(cftnsp->sapGCC_ATYP_DESTRUCTOR);
537                 if (gc || gd) {
538                         struct symtab sts = *cftnsp;
539                         NODE *p;
540                         sts.stype = INCREF(sts.stype);
541                         p = nametree(&sts);
542                         p->n_op = ICON;
543                         if (gc) {
544                                 locctr(CTORS, &sts);
545                                 inval(0SZPOINT(0), p);
546                         }
547                         if (gd) {
548                                 locctr(DTORS, &sts);
549                                 inval(0SZPOINT(0), p);
550                         }
551                         tfree(p);
552                 }
553         }
ragge
1.10
554 #endif
ragge
1.1
555         savbc = NULL;
556         lparam = NULL;
557         cftnsp = NULL;
558         maxautooff = autooff = AUTOINIT;
559         reached = 1;
560
561         if (isinlining)
562                 inline_end();
563         inline_prtout();
564
565         tmpfree(); /* Release memory resources */
566 }
567
568 static struct symtab nulsym = {
569         NULLNULLNULL0000"null""null"INT0NULLNULL
570 };
571
572 void
plunky
1.3
573 dclargs(void)
ragge
1.1
574 {
575         union dimfun *df;
576         union arglist *al, *al2, *alb;
577         struct params *a;
578         struct symtab *p, **parr = NULL/* XXX gcc */
579         int i;
580
581         /*
582          * Deal with fun(void) properly.
583          */
584         if (nparams == 1 && lparam->sym && lparam->sym->stype == VOID)
585                 goto done;
586
587         if (cftnsp->sdown && cftnsp->sdown->sclass != NSPACE) {
588                 /* first arg is a pointer to the "sprev" class */
589                 p = cxxstrvar(cftnsp->sdown);
590                 ssave(p);
591                 nparams++;
592         }
593         /*
594          * Generate a list for bfcode().
595          * Parameters were pushed in reverse order.
596          */
597         if (nparams != 0)
598                 parr = tmpalloc(sizeof(struct symtab *) * nparams);
599
600         if (nparams)
601             for (a = lparami = 0a != NULLa = a->prev) {
602                 p = a->sym;
603                 parr[i++] = p;
604                 if (p == NULL) {
605                         uerror("parameter %d name missing"i);
606                         p = &nulsym/* empty symtab */
607                 }
608                 if (p->stype == FARG)
609                         p->stype = INT;
610                 if (ISARY(p->stype)) {
611                         p->stype += (PTR-ARY);
612                         p->sdf++;
613                 } else if (ISFTN(p->stype)) {
614                         werror("function declared as argument");
615                         p->stype = INCREF(p->stype);
616                 }
617 #ifdef STABS
618                 if (gflag)
619                         stabs_newsym(p);
620 #endif
621         }
622         if (oldstyle && (df = cftnsp->sdf) && (al = df->dfun)) {
623                 /*
624                  * Check against prototype of oldstyle function.
625                  */
626                 alb = al2 = tmpalloc(sizeof(union arglist) * nparams * 3 + 1);
627                 for (i = 0i < nparamsi++) {
628                         TWORD type = parr[i]->stype;
629                         (al2++)->type = type;
630                         if (ISSOU(BTYPE(type)))
631                                 (al2++)->sap = parr[i]->sap;
632                         while (!ISFTN(type) && !ISARY(type) && type > BTMASK)
633                                 type = DECREF(type);
634                         if (type > BTMASK)
635                                 (al2++)->df = parr[i]->sdf;
636                 }
637                 al2->type = TNULL;
638                 intcompare = 1;
639                 if (chkftn(alalb))
640                         uerror("function doesn't match prototype");
641                 intcompare = 0;
642
643         }
644
645         if (oldstyle && nparams) {
646                 /* Must recalculate offset for oldstyle args here */
647                 argoff = ARGINIT;
648                 for (i = 0i < nparamsi++) {
649                         parr[i]->soffset = NOOFFSET;
650                         oalloc(parr[i], &argoff);
651                 }
652         }
653
654 done:   autooff = AUTOINIT;
655
656         plabel(prolab); /* after prolog, used in optimization */
657         retlab = getlab();
658         bfcode(parrnparams);
ragge
1.10
659         if (fun_inline && (xinline
660 #ifdef GCC_COMPAT
661             || attr_find(cftnsp->sapGCC_ATYP_ALW_INL)
662 #endif
663                 ))
ragge
1.1
664                 inline_args(parrnparams);
665         plabel(getlab()); /* used when spilling */
666         if (parlink)
667                 ecomp(parlink);
668         parlink = NIL;
669         lparam = NULL;
670         nparams = 0;
671         symclear(1);    /* In case of function pointer args */
672 }
673
674 /*
675  * basic attributes for structs and enums
676  */
677 static struct attr *
678 seattr(void)
679 {
ragge
1.10
680         return attr_add(attr_new(ATTR_ALIGNED4), attr_new(ATTR_STRUCT2));
ragge
1.1
681 }
682
683 /*
684  * Struct/union/enum symtab construction.
685  */
686 static void
687 defstr(struct symtab *spint class)
688 {
689         sp->sclass = (char)class;
690         if (class == STNAME || class == CLNAME)
691                 sp->stype = STRTY;
692         else if (class == UNAME)
693                 sp->stype = UNIONTY;
694         else if (class == ENAME)
695                 sp->stype = ENUMTY;
696 }
697
698 /*
699  * Declare a struct/union/enum tag.
700  * If not found, create a new tag with UNDEF type.
701  */
702 static struct symtab *
703 deftag(char *nameint class)
704 {
705         struct symtab *sp;
706
707         if ((sp = cxxdclstr(name))->sap == NULL) {
708                 /* New tag */
709                 defstr(spclass);
710         } else if (sp->sclass != class)
711                 uerror("tag %s redeclared"name);
712         return sp;
713 }
714
715 /*
716  * reference to a structure or union, with no definition
717  */
718 NODE *
719 rstruct(char *tagint soru)
720 {
721         struct symtab *sp;
722
723         sp = deftag(tagsoru);
724         if (sp->sap == NULL)
725                 sp->sap = seattr();
726         return mkty(sp->stype0sp->sap);
727 }
728
729 static int enumlowenumhigh;
730 int enummer;
731
732 /*
733  * Declare a member of enum.
734  */
735 void
736 moedef(char *name)
737 {
738         struct symtab *sp;
739
740         sp = lookup(nameSNORMAL);
741         if (sp->stype == UNDEF || (sp->slevel < blevel)) {
742                 if (sp->stype != UNDEF)
743                         sp = hide(sp);
744                 sp->stype = INT/* always */
745                 sp->sclass = MOE;
746                 sp->soffset = enummer;
747         } else
748                 uerror("%s redeclared"name);
749         if (enummer < enumlow)
750                 enumlow = enummer;
751         if (enummer > enumhigh)
752                 enumhigh = enummer;
753         enummer++;
754 }
755
756 /*
757  * Declare an enum tag.  Complain if already defined.
758  */
759 struct symtab *
760 enumhd(char *name)
761 {
762         struct attr *ap;
763         struct symtab *sp;
764
765         enummer = enumlow = enumhigh = 0;
766         if (name == NULL)
767                 return NULL;
768
769         sp = deftag(nameENAME);
770         if (sp->stype != ENUMTY) {
771                 if (sp->slevel == blevel)
772                         uerror("%s redeclared"name);
773                 sp = hide(sp);
774                 defstr(spENAME);
775         }
776         if (sp->sap == NULL)
777                 ap = sp->sap = attr_new(ATTR_STRUCT4);
778         else
779                 ap = attr_find(sp->sapATTR_STRUCT);
780         ap->amlist = sp;
781         return sp;
782 }
783
784 /*
785  * finish declaration of an enum
786  */
787 NODE *
788 enumdcl(struct symtab *sp)
789 {
790         NODE *p;
791         TWORD t;
792
793 #ifdef ENUMSIZE
794         t = ENUMSIZE(enumhighenumlow);
795 #else
796         t = ctype(enumlow < 0 ? INT : UNSIGNED);
797 #ifdef notdef
798         if (enumhigh <= MAX_CHAR && enumlow >= MIN_CHAR)
799                 t = ctype(CHAR);
800         else if (enumhigh <= MAX_SHORT && enumlow >= MIN_SHORT)
801                 t = ctype(SHORT);
802         else
803                 t = ctype(INT);
804 #endif
805 #endif
806         
807         if (sp)
808                 sp->stype = t;
809         p = mkty(t00);
810         p->n_sp = sp;
811         return p;
812 }
813
814 /*
815  * Handle reference to an enum
816  */
817 NODE *
818 enumref(char *name)
819 {
820         struct symtab *sp;
821         NODE *p;
822
823         sp = lookup(nameSTAGNAME);
824
825 #ifdef notdef
826         /*
827          * 6.7.2.3 Clause 2:
828          * "A type specifier of the form 'enum identifier' without an
829          *  enumerator list shall only appear after the type it specifies
830          *  is complete."
831          */
832         if (sp->sclass != ENAME)
833                 uerror("enum %s undeclared"name);
834 #endif
835         if (sp->sclass == SNULL) {
836                 /* declare existence of enum */
837                 sp = enumhd(name);
838                 sp->stype = ENUMTY;
839         }
840
841         p = mkty(sp->stype0sp->sap);
842         p->n_sp = sp;
843         return p;
844 }
845
846 /*
847  * begining of structure or union declaration
848  * It's an error if this routine is called twice with the same struct.
849  */
850 struct rstack *
851 bstruct(char *nameint soruNODE *gp)
852 {
853         struct rstack *r;
854         struct symtab *sp;
855         struct attr *ap, *gap;
856         char nbuf[20];
857
ragge
1.10
858 #ifdef GCC_COMPAT
ragge
1.1
859         gap = gp ? gcc_attr_parse(gp) : NULL;
ragge
1.10
860 #else
861         gap = NULL;
862 #endif
ragge
1.1
863
864         if (name == NULL) {
865                 static int ancnt;
plunky
1.9
866                 snprintf(nbufsizeof(nbuf), "__%%ANON%d"ancnt++);
ragge
1.1
867                 name = addname(nbuf);
868         }
869
870         if (name != NULL) {
871                 sp = deftag(namesoru);
872                 if (sp->sap == NULL)
873                         sp->sap = seattr();
ragge
1.10
874                 ap = attr_find(sp->sapATTR_ALIGNED);
ragge
1.1
875                 if (ap->iarg(0) != 0) {
876                         if (sp->slevel < blevel) {
877                                 sp = hide(sp);
878                                 defstr(spsoru);
879                                 sp->sap = seattr();
880                         } else
881                                 uerror("%s redeclared"name);
882                 }
883                 INSSYM(sp);
884                 nscur = sp;
885                 gap = sp->sap = attr_add(sp->sapgap);
886         } else {
887                 gap = attr_add(seattr(), gap);
888                 sp = getsymtab("__%"SNORMAL);
889         }
890
891         r = tmpcalloc(sizeof(struct rstack));
892         r->rsou = soru;
893         r->rsym = sp;
894 //      r->rb = NULL;
895         r->ap = gap;
896         r->rnext = rpole;
897         rpole = r;
898
899         return r;
900 }
901
902 /*
903  * Called after a struct is declared to restore the environment.
904  * - If ALSTRUCT is defined, this will be the struct alignment and the
905  *   struct size will be a multiple of ALSTRUCT, otherwise it will use
906  *   the alignment of the largest struct member.
907  */
908 NODE *
909 dclstruct(struct rstack *r)
910 {
911         NODE *n;
912         struct attr *aps, *apb;
913         struct symtab *sp;
914         int alsasz;
915
ragge
1.10
916         apb = attr_find(r->apATTR_ALIGNED);
ragge
1.1
917         aps = attr_find(r->apATTR_STRUCT);
918 //      aps->amlist = r->rb;
919         aps->amlist = nscur->sup;
920
921 #ifdef ALSTRUCT
922         al = ALSTRUCT;
923 #else
924         al = ALCHAR;
925 #endif
926
927         /*
928          * extract size and alignment, calculate offsets
929          */
930         for (sp = /* r->rb */nscur->supspsp = sp->snext) {
931                 sp->sdown = r->rsym;
932                 if (ISFTN(sp->stype))
933                         continue;
934                 sa = talign(sp->stypesp->sap);
935                 if (sp->sclass & FIELD)
936                         sz = sp->sclass&FLDSIZ;
937                 else
938                         sz = (int)tsize(sp->stypesp->sdfsp->sap);
939                 if (sz > rpole->rstr)
940                         rpole->rstr = sz;  /* for use with unions */
941                 /*
942                  * set al, the alignment, to the lcm of the alignments
943                  * of the members.
944                  */
945                 SETOFF(alsa);
946         }
947
948         SETOFF(rpole->rstral);
949
950         aps->amsize = rpole->rstr;
951         apb->iarg(0) = al;
952
953 #ifdef PCC_DEBUG
954         if (ddebug) {
955                 printf("dclstruct(%s): size=%d, align=%d\n",
956                     r->rsym ? r->rsym->sname : "??",
957                     aps->amsizeapb->iarg(0));
958         }
959         if (ddebug>1) {
960                 printf("\tsize %d align %d link %p\n",
961                     aps->amsizeapb->iarg(0), aps->amlist);
962                 for (sp = aps->amlistsp != NULLsp = sp->snext) {
963                         printf("\tmember %s(%p)\n"sp->snamesp);
964                 }
965         }
966 #endif
967
968 #ifdef STABS
969         if (gflag)
970                 stabs_struct(r->rsymr->ap);
971 #endif
972
973         rpole = r->rnext;
974         n = mkty(r->rsou == STNAME ? STRTY : UNIONTY0r->ap);
975         n->n_sp = r->rsym;
976
977         POPSYM();
978
979         n->n_qual |= 1/* definition place XXX used by attributes */
980         return n;
981 }
982
983 /*
984  * Add a new member to the current struct or union being declared.
985  */
986 void
987 soumemb(NODE *nchar *nameint class)
988 {
989         struct symtab *sp, *lsp;
990         int incomptszal;
991         TWORD t;
992  
993         if (rpole == NULL)
994                 cerror("soumemb");
995  
996         /* check if tag name exists */
997         lsp = NULL;
998         for (sp = /* rpole->rb */ nscur->supsp != NULLlsp = spsp = sp->snext)
999                 if (*name != '*' && sp->sname == name && class == sp->sclass)
1000                         uerror("redeclaration of %s"name);
1001
1002         sp = getsymtab(nameSMOSNAME);
1003 #if 0
1004         if (rpole->rb == NULL)
1005                 rpole->rb = sp;
1006         else
1007                 lsp->snext = sp;
1008 #endif
1009         if (nscur->sup == NULL)
1010                 nscur->sup = sp;
1011         else
1012                 lsp->snext = sp;
1013
1014         n->n_sp = sp;
1015         sp->stype = n->n_type;
1016         sp->squal = n->n_qual;
1017         sp->slevel = blevel;
1018         sp->sap = n->n_ap;
1019         sp->sdf = n->n_df;
1020         sp->sdown = rpole->rsym;
1021
1022         if (class & FIELD) {
1023                 sp->sclass = (char)class;
1024                 falloc(spclass&FLDSIZNIL);
1025         } else if (class == STATIC) {
1026                 sp->sclass = USTATIC;
1027                 cxxsetname(sp);
1028         } else if (ISFTN(sp->stype)) {
1029                 sp->sclass = EXTERN;
1030                 cxxsetname(sp);
1031         } else if (rpole->rsou == STNAME || rpole->rsou == UNAME) {
1032                 sp->sclass = rpole->rsou == STNAME ? MOS : MOU;
1033                 if (sp->sclass == MOU)
1034                         rpole->rstr = 0;
1035                 al = talign(sp->stypesp->sap);
1036                 tsz = (int)tsize(sp->stypesp->sdfsp->sap);
1037                 sp->soffset = upoff(tszal, &rpole->rstr);
1038         }
1039
1040         /*
1041          * 6.7.2.1 clause 16:
1042          * "...the last member of a structure with more than one
1043          *  named member may have incomplete array type;"
1044          */
1045         if (ISARY(sp->stype) && sp->sdf->ddim == NOOFFSET)
1046                 incomp = 1;
1047         else
1048                 incomp = 0;
1049         if ((rpole->flags & LASTELM) || (/* rpole->rb */ nscur->sup == sp && incomp == 1))
1050                 uerror("incomplete array in struct");
1051         if (incomp == 1)
1052                 rpole->flags |= LASTELM;
1053
1054         /*
1055          * 6.7.2.1 clause 2:
1056          * "...such a structure shall not be a member of a structure
1057          *  or an element of an array."
1058          */
1059         t = sp->stype;
1060         if (rpole->rsou != STNAME || BTYPE(t) != STRTY)
1061                 return/* not for unions */
1062         while (ISARY(t))
1063                 t = DECREF(t);
1064         if (ISPTR(t))
1065                 return;
1066
1067         if ((lsp = strmemb(sp->sap)) != NULL) {
1068                 for (; lsp->snextlsp = lsp->snext)
1069                         ;
1070                 if (ISARY(lsp->stype) && lsp->snext &&
1071                     lsp->sdf->ddim == NOOFFSET)
1072                         uerror("incomplete struct in struct");
1073         }
1074 }
1075
1076 /*
1077  * error printing routine in parser
1078  */
1079 void
1080 yyerror(char *s)
1081 {
1082         uerror(s);
1083 }
1084
1085 void yyaccpt(void);
1086 void
1087 yyaccpt(void)
1088 {
1089         ftnend();
1090 }
1091
1092 /*
1093  * p is top of type list given to tymerge later.
1094  * Find correct CALL node and declare parameters from there.
1095  */
1096 void
1097 ftnarg(NODE *p)
1098 {
1099         NODE *q;
1100
1101 #ifdef PCC_DEBUG
1102         if (ddebug > 2)
1103                 printf("ftnarg(%p)\n"p);
1104 #endif
1105         /*
1106          * Push argument symtab entries onto param stack in reverse order,
1107          * due to the nature of the stack it will be reclaimed correct.
1108          */
1109         for (; p->n_op != NAMEp = p->n_left) {
1110                 if (p->n_op == UCALL && p->n_left->n_op == NAME)
1111                         return/* Nothing to enter */
1112                 if (p->n_op == CALL &&
1113                     (p->n_left->n_op == NAME || p->n_left->n_op == NMLIST))
1114                         break;
1115         }
1116
1117         p = p->n_right;
1118         while (p->n_op == CM) {
1119                 q = p->n_right;
1120                 if (q->n_op != ELLIPSIS) {
1121                         ssave(q->n_sp);
1122                         nparams++;
1123 #ifdef PCC_DEBUG
1124                         if (ddebug > 2)
1125                                 printf("        saving sym %s (%p) from (%p)\n",
1126                                     q->n_sp->snameq->n_spq);
1127 #endif
1128                 }
1129                 p = p->n_left;
1130         }
1131         ssave(p->n_sp);
1132         if (p->n_type != VOID)
1133                 nparams++;
1134
1135 #ifdef PCC_DEBUG
1136         if (ddebug > 2)
1137                 printf("        saving sym %s (%p) from (%p)\n",
1138                     nparams ? p->n_sp->sname : "<noname>"p->n_spp);
1139 #endif
1140 }
1141
1142 /*
1143  * compute the alignment of an object with type ty, sizeoff index s
1144  */
1145 int
1146 talign(unsigned int tystruct attr *apl)
1147 {
1148         struct attr *al;
1149         int a;
1150
1151         for (; ty > BTMASKty = DECREF(ty)) {
1152                 switch (ty & TMASK) {
1153                 case PTR:
1154                         return(ALPOINT);
1155                 case ARY:
1156                         continue;
1157                 case FTN:
1158                         cerror("compiler takes alignment of function");
1159                 }
1160         }
1161
1162         /* check for alignment attribute */
ragge
1.10
1163         if ((al = attr_find(aplATTR_ALIGNED))) {
ragge
1.1
1164                 if ((a = al->iarg(0)) == 0) {
1165                         uerror("no alignment");
1166                         a = ALINT;
1167                 } 
1168                 return a;
1169         }
1170
1171         ty = BTYPE(ty);
1172         if (ty >= CHAR && ty <= ULONGLONG && ISUNSIGNED(ty))
1173                 ty = DEUNSIGN(ty);
1174
1175         switch (ty) {
1176         case BOOLa = ALBOOLbreak;
1177         case CHARa = ALCHARbreak;
1178         case SHORTa = ALSHORTbreak;
1179         case INTa = ALINTbreak;
1180         case LONGa = ALLONGbreak;
1181         case LONGLONGa = ALLONGLONGbreak;
1182         case FLOATa = ALFLOATbreak;
1183         case DOUBLEa = ALDOUBLEbreak;
1184         case LDOUBLEa = ALLDOUBLEbreak;
1185         default:
1186                 uerror("no alignment");
1187                 a = ALINT;
1188         }
1189         return a;
1190 }
1191
1192 short sztable[] = { 0SZBOOLSZCHARSZCHARSZSHORTSZSHORTSZINTSZINT,
1193         SZLONGSZLONGSZLONGLONGSZLONGLONGSZFLOATSZDOUBLESZLDOUBLE };
1194
1195 /* compute the size associated with type ty,
1196  *  dimoff d, and sizoff s */
1197 /* BETTER NOT BE CALLED WHEN t, d, and s REFER TO A BIT FIELD... */
1198 OFFSZ
1199 tsize(TWORD tyunion dimfun *dstruct attr *apl)
1200 {
1201         struct attr *ap, *ap2;
1202         OFFSZ multsz;
1203
1204         mult = 1;
1205
1206         for (; ty > BTMASKty = DECREF(ty)) {
1207                 switch (ty & TMASK) {
1208
1209                 case FTN:
1210                         uerror"cannot take size of function");
1211                 case PTR:
1212                         returnSZPOINT(ty) * mult );
1213                 case ARY:
1214                         if (d->ddim == NOOFFSET)
1215                                 return 0;
1216                         if (d->ddim < 0)
1217                                 cerror("tsize: dynarray");
1218                         mult *= d->ddim;
1219                         d++;
1220                 }
1221         }