9 * Process a single external definition
15 register struct nmlist *ds;
17 if(((o=symbol())==EOFC) || o==SEMI)
22 if (getkeywords(&sclass, &typer)==0) {
28 if (sclass==DEFXTRN) {
32 if (sclass!=EXTERN && sclass!=STATIC && sclass!=TYPEDEF)
33 error("Illegal storage class");
38 if (sclass==TYPEDEF) {
39 decl1(TYPEDEF, &typer, 0, (struct nmlist *)NULL);
42 decl1(EXTERN, &typer, 0, (struct nmlist *)NULL);
46 if ((ds->htype&XTYPE)==FUNC) {
47 if ((peeksym=symbol())==LBRACE || peeksym==KEYW
48 || (peeksym==NAME && csym->hclass==TYPEDEF)) {
49 funcblk.type = decref(ds->htype);
50 funcblk.strp = ds->hstrp;
52 outcode("BS", SYMDEF, sclass==EXTERN?ds->name:"");
57 error("Inappropriate parameters");
58 } else if ((o=symbol())==COMMA || o==SEMI) {
60 o = (length((union tree *)ds)+ALIGN) & ~ALIGN;
63 outcode("BSBBSBN", SYMDEF, "", BSS, NLABEL, ds->name, SSPACE, o);
65 outcode("BSN", CSPACE, ds->name, o);
68 error("Declaration syntax");
73 outcode("BS", SYMDEF, ds->name);
74 outcode("BBS", DATA, NLABEL, ds->name);
75 if (cinit(ds, 1, sclass) & ALIGN)
78 } while ((o=symbol())==COMMA);
83 error("Too many }'s");
87 error("External definition syntax");
93 * Process a function definition.
101 outcode("BBS", PROG, RLABEL, funcsym->name);
110 outcode("BNS", PROFIL, isn++, funcsym->name);
116 if ((peeksym = symbol()) != LBRACE)
117 error("Compound statement required");
119 outcode("BNB", LABEL, retlab, RETRN);
121 /* add STAUTO; overlay bug fix, coupled with section in c11.c */
122 outcode("BN", SETSTK, -maxauto+STAUTO);
124 /*fprintf(stderr, "cb=%p\n", cp);*/
129 * Process the initializers for an external definition.
131 int cinit(anp, flex, sclass) struct nmlist *anp; int flex; int sclass; {
133 register int nel, ninit;
134 int width, isarray, o, brace, realtype;
140 if ((realtype&XTYPE) == ARRAY)
144 width = length((union tree *)&np);
147 * If it's an array, find the number of elements.
148 * temporarily modify to look like kind of thing it's
152 if (isarray || realtype==STRUCT)
153 error("No auto. aggregate initialization");
155 np.htype = decref(realtype);
157 if (width==0 && flex==0)
158 error("0-length row: %s", anp->name);
159 o = length((union tree *)&np);
160 nel = (unsigned)width/o;
164 if ((peeksym=symbol())==LBRACE && (isarray || np.htype!=STRUCT)) {
170 if ((o=symbol())==RBRACE)
173 if (o==STRING && (realtype==ARRAY+CHAR || realtype==ARRAY+UNCHAR)) {
175 error("No strings in automatic");
177 putstr(0, flex?10000:nel);
181 } else if (np.htype==STRUCT) {
182 strinit(&np, sclass);
183 } else if ((np.htype&ARRAY)==ARRAY || peeksym==LBRACE)
184 cinit(&np, 0, sclass);
192 error("No field initialization");
196 if (sclass==AUTO||sclass==REG)
198 else if (sclass==ENUMCON) {
200 error("Illegal enum constant for %s", anp->name);
201 anp->hoffset = s->c.value;
203 rcexpr(block(INIT,np.htype,(int *)NULL,
204 (union str *)NULL, (*--cp)->t.tr2, TNULL));
208 if ((ninit&077)==0 && sclass==EXTERN)
209 outcode("BS", SYMDEF, "");
210 } while ((o=symbol())==COMMA && (ninit<nel || brace || flex));
211 if (brace==0 || o!=RBRACE)
214 * If there are too few initializers, allocate
216 * If there are too many initializers, extend
217 * the declared size for benefit of "sizeof"
219 if (ninit<nel && sclass!=AUTO)
220 outcode("BN", SSPACE, (nel-ninit)*width);
221 else if (ninit>nel) {
222 if (flex && nel==0) {
223 np.hsubsp[-1] = ninit;
225 error("Too many initializers: %s", anp->name);
232 * Initialize a structure
234 void strinit(np, sclass) struct nmlist *np; int sclass; {
235 static struct nmlist junk;
236 register struct nmlist **mlp;
237 static struct nmlist *zerloc = NULL;
238 register int o, brace;
240 if ((mlp = np->hstrp->S.memlist)==NULL) {
242 error("Undefined structure initialization");
245 if ((o = symbol()) == LBRACE)
250 if ((o=symbol()) == RBRACE)
254 error("Too many structure initializers");
255 cinit(&junk, 0, sclass);
257 cinit(*mlp++, 0, sclass);
258 if (*mlp == &structhole) {
262 /* DAG -- union initialization bug fix */
263 if (*mlp && mlp[-1]->hoffset == (*mlp)->hoffset) {
264 werror("union initialization non-portable");
265 while (*mlp) /* will NOT be &structhole */
266 mlp++; /* skip other members of union */
268 } while ((o=symbol())==COMMA && (*mlp || brace));
269 if (sclass!=AUTO && sclass!=REG) {
271 outcode("BN", SSPACE, np->hstrp->S.ssize - (*mlp)->hoffset);
274 if (o!=RBRACE || brace==0)
279 * Mark already initialized
281 void setinit(np) register struct nmlist *np; {
284 error("%s multiply defined", np->name);
289 * Process one statement in a function.
299 error("Unexpected EOF");
308 if ((o=symbol())==RBRACE) {
311 outcode("BN", SETREG, sreg);
319 error("Missing '}'");
326 if (o1 = simplegoto())
338 char tmp[80], /* tmp for line buffer */
341 if (symbol() != LPARN || (o1 = symbol()) != STRING)
343 for (p = tmp; (o1 = mapch('"')) >= 0; )
346 if (symbol() != RPARN)
348 outcode("BF", ASSEM, tmp);
354 register union tree *np;
358 if ((o1=symbol())==KEYW) switch (cval) {
362 cbranch(np, o2=isn++, 0);
368 if (nextchar()==';') {
372 cbranch(np, o1=isn++, 0);
388 if ((o=symbol())!=SEMI)
390 if ((o1=symbol())==KEYW && cval==ELSE)
396 cbranch(np, o1=isn++, 0);
398 if ((o=symbol())==KEYW && cval==ELSE) {
415 label(contlab = isn++);
416 cbranch(pexpr(1), brklab=isn++, 0);
445 if ((o=symbol())==KEYW && cval==WHILE) {
446 cbranch(tree(1), o3, 1);
456 if ((o=symbol())!=COLON)
459 error("Case not in switch");
462 if(swp>=swtab+SWSIZ) {
463 error("Switch table overflow");
472 register union tree *np;
480 rcexpr(block(RFORCE,0,(int *)NULL,(union str *)NULL,np,TNULL));
489 error("Default not in switch");
491 error("More than 1 'default'");
492 if ((o=symbol())!=COLON)
494 label(deflab = isn++);
511 error("Inappropriate 'else'");
515 error("Unknown keyword");
519 register struct nmlist *np;
520 if (nextchar()==':') {
524 if (np->hblklev==0) {
547 if ((o=symbol())==SEMI)
550 error("Statement syntax");
555 * Process a for statement.
559 register union tree *st;
563 if ((o=symbol()) != LPARN)
565 if ((o=symbol()) != SEMI) { /* init part */
568 if ((o=symbol()) != SEMI)
578 if ((o=symbol()) != SEMI) { /* test part */
582 if ((o=symbol()) != SEMI) {
587 if ((o=symbol()) != RPARN) { /* incr part */
590 if ((o=symbol()) != RPARN) {
611 * A parenthesized expression,
614 union tree *pexpr(eflag) int eflag; {
616 register union tree *t;
618 if ((o=symbol())!=LPARN)
621 if ((o=symbol())!=RPARN)
624 error("Illegal use of void");
627 error("Statement syntax");
633 * The switch statement, which involves collecting the
634 * constants and labels for the cases.
637 register struct swtab *cswp, *sswp;
651 outcode("BNN", SWIT, deflab, line);
652 for (; cswp < swp; cswp++)
653 outcode("NN", cswp->swlab, cswp->swval);
661 * funchead is called at the start of each function
662 * to process the arguments, which have been linked in a list.
663 * This list is necessary because in
664 * f(a, b) float b; int a; ...
665 * the names are seen before the types.
668 * Structure resembling a block for a register variable.
670 struct nmlist hreg = { REG, 0, 0, NULL, NULL, 0 };
671 struct tnode areg = { NAME, 0, NULL, NULL, (union tree *)&hreg};
674 register struct nmlist *cs;
679 parame->sparent = NULL;
681 paraml = ¶ml->sparent->P;
682 if (cs->htype==FLOAT)
685 if ((cs->htype&XTYPE) == ARRAY) {
686 cs->htype -= (ARRAY-PTR); /* set ptr */
687 cs->hsubsp++; /* pop dims */
689 pl += rlength((union tree *)cs);
690 if (cs->hclass==AREG && (hreg.hoffset=goodreg(cs))>=0) {
692 *cp++ = (union tree *)&areg;
694 areg.type = cs->htype;
695 areg.strp = cs->hstrp;
699 cs->hoffset = hreg.hoffset;
706 for (pl=0; pl<HSHSIZ; pl++) {
707 for (cs = hshtab[pl]; cs!=NULL; cs = cs->nextnm) {
708 if (cs->hclass == ARG || cs->hclass==AREG)
709 error("Not an argument: %s", cs->name);
712 outcode("BN", SETREG, regvar);
722 outcode("BN", SETREG, regvar);
726 * After the end of a block, delete local
728 * Also complain about undefined labels.
731 register struct nmlist *cs, **lcs;
735 for (i = 0; i < HSHSIZ; i++) {
739 if (cs->hblklev > blklev
740 && (((cs->hflag&FLABL)==0 && cs->hclass!=EXTERN) || blklev<=0)) {
742 error("%s undefined", cs->name);
743 if (cs->hclass==EXTERN)
744 nameconflict(hshtab[i], cs);
753 void nameconflict(ocs, cs) register struct nmlist *ocs; register struct nmlist *cs; {
755 for (; ocs!=NULL; ocs = ocs->nextnm)
756 if (ocs!=cs && ocs->hclass==EXTERN &&
757 strncmp(cs->name, ocs->name, MAXCPS-1) == 0)
758 error("names %s and %s conflict", cs->name, ocs->name);
762 * write out special definitions of local symbols for
763 * benefit of the debugger. None of these are used
764 * by the assembler except to save them.
766 void prste(cs) struct nmlist *cs; {
769 switch (cs->hclass) {
786 outcode("BSN", nkind, cs->name, cs->hoffset);
790 * In case of error, skip to the next
791 * statement delimiter.
793 void errflush(ao) int ao; {
797 while(o>RBRACE) { /* ; { } */