7 #include "c1.h" /* pswitch0() one-pass version */
9 * Process a single external definition
14 /* struct nmlist typer;*/
16 static struct type t_int = {INT};
17 register struct nmlist *ds;
21 if(((o=symbol())==EOFC) || o==SEMI)
26 if (/*getkeywords(&sclass, &typer)==0*/(dtype = getkeywords(&sclass)) == NULL) {
33 if (sclass==DEFXTRN) {
37 if (sclass!=EXTERN && sclass!=STATIC && sclass!=TYPEDEF)
38 error0("Illegal storage class");
43 if (sclass==TYPEDEF) {
44 decl1(TYPEDEF, /*&typer*/dtype, 0, (struct nmlist *)NULL);
47 decl1(EXTERN, /*&typer*/dtype, 0, (struct nmlist *)NULL);
51 if (/*(ds->nl_type&XTYPE)==FUNC*/ds->nl_dtype->t_id==(REF|FUNC)) {
52 if ((peeksym=symbol())==LBRACE || peeksym==KEYW
53 || (peeksym==NAME && csym->nl_class==TYPEDEF)) {
54 /* create a fake local variable of same type as function's return type */
55 /* funcblk.locnn_type = decref0(ds->nl_type);
56 funcblk.locnn_strp = ds->nl_strp;*/
58 funcblk.locnn_type = XXXoldtype(((struct ftype *)ds->nl_dtype)->ft_reftype, &dim, (struct SS **)&funcblk.locnn_strp);
59 funcblk.locnn_subsp = dim.rank ? (int *)Tblock(dim.rank*sizeof(dim.rank)) : NULL;
60 for (a=0; a<dim.rank; a++)
61 funcblk.locnn_subsp[a] = dim.dimens[a];
63 outcode("BS", SYMDEF, sclass==EXTERN?ds->nl_name:"");
68 error0("Inappropriate parameters");
69 } else if ((o=symbol())==COMMA || o==SEMI) {
71 o = (length(/*(struct node *)ds*/ds->nl_dtype)+ALIGN) & ~ALIGN;
74 outcode("BSBBSBN", SYMDEF, "", BSS, NLABEL, ds->nl_name, SSPACE, o);
76 outcode("BSN", CSPACE, ds->nl_name, o);
79 error0("Declaration syntax");
84 outcode("BS", SYMDEF, ds->nl_name);
85 outcode("BBS", DATA, NLABEL, ds->nl_name);
86 if (cinit(ds, 1, sclass) & ALIGN)
89 } while ((o=symbol())==COMMA);
94 error0("Too many }'s");
98 error0("External definition syntax");
104 * Process a function definition.
112 outcode("BBS", PROG, RLABEL, funcsym->nl_name);
121 outcode("BNS", PROFIL, isn0++, funcsym->nl_name);
127 if ((peeksym = symbol()) != LBRACE)
128 error0("Compound statement required");
130 outcode("BNB", LABEL, retlab, RETRN);
132 /* add STAUTO; overlay bug fix, coupled with section in c11.c */
133 outcode("BN", SETSTK, -maxauto+STAUTO);
135 /*fprintf(stderr, "cb=%p\n", cp);*/
140 * Process the initializers for an external definition.
142 int cinit(anp, flex, sclass) struct nmlist *anp; int flex; int sclass; {
144 register int nel, ninit;
145 int width, isarray, o, brace/*, realtype*/;
146 struct type *realtype;
154 realtype = /*np.nl_type*/np.nl_dtype;
156 if (/*(realtype&XTYPE) == ARRAY*/realtype->t_id == (REF | ARRAY))
160 width = length(/*(struct node *)&np*/np.nl_dtype);
163 * If it's an array, find the number of elements.
164 * temporarily modify to look like kind of thing it's
168 if (isarray || /*realtype*/realtype->t_id==STRUCT)
169 error0("No auto. aggregate initialization");
171 /* np.nl_type = decref0(realtype);
173 np.nl_dtype = ((struct atype *)realtype)->at_reftype;
174 if (width==0 && flex==0)
175 error0("0-length row: %s", anp->nl_name);
176 o = length(/*(struct node *)&np*/np.nl_dtype);
177 nel = (unsigned)width/o;
181 if ((peeksym=symbol())==LBRACE && (isarray || /*np.nl_type*/np.nl_dtype->t_id!=STRUCT)) {
187 if ((o=symbol())==RBRACE)
190 if (o==STRING && /*(realtype==ARRAY+CHAR || realtype==ARRAY+UNCHAR)*/realtype->t_id == (REF | ARRAY) && (((struct atype *)realtype)->at_reftype->t_id == CHAR || ((struct atype *)realtype)->at_reftype->t_id == UNCHAR)) {
192 error0("No strings in automatic");
194 putstr(0, flex?10000:nel);
198 } else if (/*np.nl_type*/np.nl_dtype->t_id==STRUCT) {
199 strinit(&np, sclass);
200 } else if (/*(np.nl_type&ARRAY)==ARRAY*/np.nl_dtype->t_id==(REF|ARRAY) || peeksym==LBRACE)
201 cinit(&np, 0, sclass);
208 if (np./*nl_flag&FFIELD*/nl_dtype->t_id==BITFLD)
209 error0("No field initialization");
210 *cp++ = (struct node *)nblock(&np);
213 if (sclass==AUTO||sclass==REG)
215 else if (sclass==ENUMCON) {
217 error0("Illegal enum constant for %s", anp->nl_name);
218 anp->nl_offset = ((struct cnode *)s)->cn_value;
222 type = XXXoldtype(np.nl_dtype, &dim, (struct SS **)&strp);
223 subsp = dim.rank ? (int *)Tblock(dim.rank*sizeof(dim.rank)) : NULL;
224 for (a=0; a<dim.rank; a++)
225 subsp[a] = dim.dimens[a];
226 rcexpr0((struct node *)block(INIT,/*np.nl_type*/type,/*(int *)NULL*/subsp,
227 /*(union str *)NULL*/strp, ((struct tnode *)(*--cp))->tn_tr2, (struct node *)NULL));
232 if ((ninit&077)==0 && sclass==EXTERN)
233 outcode("BS", SYMDEF, "");
234 } while ((o=symbol())==COMMA && (ninit<nel || brace || flex));
235 if (brace==0 || o!=RBRACE)
238 * If there are too few initializers, allocate
240 * If there are too many initializers, extend
241 * the declared size for benefit of "sizeof"
243 if (ninit<nel && sclass!=AUTO)
244 outcode("BN", SSPACE, (nel-ninit)*width);
245 else if (ninit>nel) {
246 if (flex && nel==0) {
247 /* note: nel==0 implies isarray, since otherwise nel must be 1 */
248 /* np.nl_subsp[-1] = ninit;*/
249 #define arealtype (*(struct atype **)&realtype)
250 arealtype = (struct atype *)Dblock(sizeof(struct atype));
251 arealtype->at_id = REF | ARRAY;
252 arealtype->at_reftype = np.nl_dtype;
253 arealtype->at_nelt = ninit;
254 anp->nl_dtype = (struct type *)arealtype;
257 error0("Too many initializers: %s", anp->nl_name);
264 * Initialize a structure
266 void strinit(np, sclass) struct nmlist *np; int sclass; {
267 /* static*/ struct nmlist junk;
268 static struct type t_int = {INT};
269 register struct nmlist **mlp;
270 static struct nmlist *zerloc = NULL;
271 register int o, brace;
273 if ((mlp = /*np->nl_strp->S.memlist*/((struct stype *)np->nl_dtype)->st_memlist)==NULL) {
275 error0("Undefined structure initialization");
278 if ((o = symbol()) == LBRACE)
283 if ((o=symbol()) == RBRACE)
287 /* change this to a static struct nmlist later when nmlist has stabilized */
288 bzero(&junk, sizeof(struct nmlist));
289 junk.nl_dtype = &t_int;
290 error0("Too many structure initializers");
291 cinit(&junk, 0, sclass);
293 cinit(*mlp++, 0, sclass);
294 if (*mlp == &structhole) {
298 /* DAG -- union initialization bug fix */
299 if (*mlp && mlp[-1]->nl_offset == (*mlp)->nl_offset) {
300 werror0("union initialization non-portable");
301 while (*mlp) /* will NOT be &structhole */
302 mlp++; /* skip other members of union */
304 } while ((o=symbol())==COMMA && (*mlp || brace));
305 if (sclass!=AUTO && sclass!=REG) {
307 outcode("BN", SSPACE, /*np->nl_strp->S.ssize*/((struct stype *)np->nl_dtype)->st_ssize - (*mlp)->nl_offset);
310 if (o!=RBRACE || brace==0)
315 * Mark already initialized
317 void setinit(np) register struct nmlist *np; {
319 if (np->nl_flag&FINIT)
320 error0("%s multiply defined", np->nl_name);
321 np->nl_flag |= FINIT;
325 * Process one statement in a function.
327 struct type gototype = {0}; /* dummy type distinguished by its address */
336 error0("Unexpected EOF");
345 if ((o=symbol())==RBRACE) {
348 outcode("BN", SETREG, sreg);
356 error0("Missing '}'");
363 if (o1 = simplegoto())
375 char tmp[80], /* tmp for line buffer */
378 if (symbol() != LPARN || (o1 = symbol()) != STRING)
380 for (p = tmp; (o1 = mapch('"')) >= 0; )
383 if (symbol() != RPARN)
385 outcode("BF", ASSEM, tmp);
391 register struct node *np;
393 char *st = starttree();
396 if ((o1=symbol())==KEYW) switch (cval) {
400 cbranch0(np, o2=isn0++, 0);
406 if (nextchar()==';') {
410 cbranch0(np, o1=isn0++, 0);
427 if ((o=symbol())!=SEMI)
429 if ((o1=symbol())==KEYW && cval==ELSE)
435 cbranch0(np, o1=isn0++, 0);
438 if ((o=symbol())==KEYW && cval==ELSE) {
456 label0(contlab = isn0++);
458 cbranch0(pexpr(/*1*/), brklab=isn0++, 0);
488 if ((o=symbol())==KEYW && cval==WHILE) {
489 char *st = starttree();
490 cbranch0(tree(/*1*/), o3, 1);
501 if ((o=symbol())!=COLON)
504 error0("Case not in switch");
507 if(swp>=swtab+SWSIZ) {
508 error0("Switch table overflow");
517 register struct node *np;
525 rcexpr0((struct node *)block(RFORCE,0,(int *)NULL,(union str *)NULL,np,(struct node *)NULL));
534 error0("Default not in switch");
536 error0("More than 1 'default'");
537 if ((o=symbol())!=COLON)
539 label0(deflab = isn0++);
556 error0("Inappropriate 'else'");
560 error0("Unknown keyword");
564 register struct nmlist *np;
565 if (nextchar()==':') {
568 if (np->nl_class>0) {
569 if (np->nl_blklev==0) {
578 np->nl_class = STATIC;
579 /* np->nl_type = ARRAY;*/
580 np->nl_dtype = &gototype;
581 np->nl_flag |= FLABL;
582 if (np->nl_offset==0)
583 np->nl_offset = isn0++;
584 label0(np->nl_offset);
591 char *st = starttree();
592 rcexpr0(tree(/*1*/));
597 if ((o=symbol())==SEMI)
600 error0("Statement syntax");
605 * Process a for statement.
609 register struct node *st;
613 if ((o=symbol()) != LPARN)
616 if ((o=symbol()) != SEMI) { /* init part */
618 rcexpr0(tree(/*1*/));
619 if ((o=symbol()) != SEMI)
632 if ((o=symbol()) != SEMI) { /* test part */
634 /* ss = starttree();*/
636 if ((o=symbol()) != SEMI) {
641 if ((o=symbol()) != RPARN) { /* incr part */
643 rcexpr0(tree(/*1*/));
644 if ((o=symbol()) != RPARN) {
652 cbranch0(st, l+1, 1);
666 * A parenthesized expression,
669 struct node *pexpr(/*eflag*/) /*int eflag;*/ {
671 register struct node *t;
673 if ((o=symbol())!=LPARN)
676 if ((o=symbol())!=RPARN)
679 error0("Illegal use of void");
682 error0("Statement syntax");
688 * The switch statement, which involves collecting the
689 * constants and labels for the cases.
692 register struct swtab *cswp, *sswp;
694 #if 1 /* one-pass version */
701 branch0(swlab=isn0++);
709 #if 1 /* one-pass version */
710 svtree = starttree();
711 pswitch1(cswp, swp, deflab);
714 outcode("BNN", SWIT, deflab, line);
715 for (; cswp < swp; cswp++)
716 outcode("NN", cswp->swlab, cswp->swval);
725 * funchead is called at the start of each function
726 * to process the arguments, which have been linked in a list.
727 * This list is necessary because in
728 * f(a, b) float b; int a; ...
729 * the names are seen before the types.
732 * Structure resembling a block for a register variable.
734 struct nmlist hreg = { REG, 0, /*0, (int *)NULL, (union str *)NULL,*/ (struct type *)NULL, 0/*nl_offset*/ }; /* note: remaining fields not initialized */
735 struct locnnode areg = { { { NAME, 0, (int *)NULL, (union str *)NULL }, &hreg/*nn_nmlist*/, REG/*nn_class*/, 0/*nn_regno*/, 0/*nn_offset*/}, 0/*locnn_nloc*/ };
738 register struct nmlist *cs;
740 static struct type t_double = {DOUBLE};
746 parame->nl_sparent = NULL;
748 paraml = ¶ml->nl_sparent->P;
749 if (cs->/*nl_type*/nl_dtype->t_id==FLOAT)
750 cs->/*nl_type*/nl_dtype = /*DOUBLE*/&t_double;
752 if (/*(cs->nl_type&XTYPE) == ARRAY*/cs->nl_dtype->t_id == (REF | ARRAY)) {
753 /* cs->nl_type -= (ARRAY-PTR); *//* set ptr *//*
754 cs->nl_subsp++;*/ /* pop dims */
755 struct rtype *rt = (struct rtype *)Dblock(sizeof(struct rtype));
756 rt->rt_id = REF | PTR;
757 rt->rt_reftype = ((struct rtype *)cs->nl_dtype)->rt_reftype;
758 cs->nl_dtype = (struct type *)rt;
760 pl += rlength(/*(struct node *)cs*/cs->nl_dtype);
761 if (cs->nl_class==AREG && (hreg.nl_offset=goodreg(cs))>=0) {
762 /* make hreg = *cs but in the chosen register */
763 /*hreg.nl_type = cs->nl_type;
764 hreg.nl_subsp = cs->nl_subsp;
765 hreg.nl_strp = cs->nl_strp;*/
766 hreg.nl_dtype = cs->nl_dtype;
768 /* make areg look like result of nblock(&hreg) */
769 areg.locnn_nloc = hreg.nl_offset;
770 /*areg.locnn_op = NAME;
771 areg.locnn_type = hreg.nl_type;
772 areg.locnn_subsp = hreg.nl_subsp;
773 areg.nocnn_strp = hreg.nl_strp;*/
775 areg.locnn_type = XXXoldtype(cs->nl_dtype, &dim, (struct SS **)&areg.locnn_strp);
776 areg.locnn_subsp = dim.rank ? (int *)Tblock(dim.rank*sizeof(dim.rank)) : NULL;
777 for (a=0; a<dim.rank; a++)
778 areg.locnn_subsp[a] = dim.dimens[a];
779 /*areg.locnn_nmlist = &hreg;
780 areg.locnn_class = hreg.nl_class==0?STATIC:hreg.nl_class;
781 areg.locnn_regno = 0;
782 areg.locnn_offset = 0;*/
783 *cp++ = (struct node *)&areg;
784 /* formerly rcexpr0() would have translated struct nmlist * to class, regno, */
785 /* offset, but now this happens in nblock, so we have to set class earlier */
787 *cp++ = (struct node *)nblock(cs);
788 /* areg.locnn_type = cs->nl_type;
789 areg.locnn_strp = cs->nl_strp;*/
790 /* cs->nl_class = AUTO;*/
793 cs->nl_offset = hreg.nl_offset;
800 for (pl=0; pl<HSHSIZ; pl++) {
801 for (cs = hshtab[pl]; cs!=NULL; cs = cs->nl_nextnm) {
802 if (cs->nl_class == ARG || cs->nl_class==AREG)
803 error0("Not an argument: %s", cs->nl_name);
806 outcode("BN", SETREG, regvar);
816 outcode("BN", SETREG, regvar);
820 * After the end of a block, delete local
822 * Also complain about undefined labels.
825 register struct nmlist *cs, **lcs;
829 for (i = 0; i < HSHSIZ; i++) {
833 if (cs->nl_blklev > blklev
834 && (((cs->nl_flag&FLABL)==0 && cs->nl_class!=EXTERN) || blklev<=0)) {
836 error0("%s undefined", cs->nl_name);
837 if (cs->nl_class==EXTERN)
838 nameconflict(hshtab[i], cs);
839 *lcs = cs->nl_nextnm;
841 lcs = &cs->nl_nextnm;
847 void nameconflict(ocs, cs) register struct nmlist *ocs; register struct nmlist *cs; {
849 for (; ocs!=NULL; ocs = ocs->nl_nextnm)
850 if (ocs!=cs && ocs->nl_class==EXTERN &&
851 strncmp(cs->nl_name, ocs->nl_name, MAXCPS-1) == 0)
852 error0("names %s and %s conflict", cs->nl_name, ocs->nl_name);
856 * write out special definitions of local symbols for
857 * benefit of the debugger. None of these are used
858 * by the assembler except to save them.
860 void prste(cs) struct nmlist *cs; {
863 switch (cs->nl_class) {
880 outcode("BSN", nkind, cs->nl_name, cs->nl_offset);
884 * In case of error, skip to the next
885 * statement delimiter.
887 void errflush(ao) int ao; {
891 while(o>RBRACE) { /* ; { } */