148116Sbostic /*-
2*62207Sbostic * Copyright (c) 1980, 1993
3*62207Sbostic * The Regents of the University of California. All rights reserved.
448116Sbostic *
548116Sbostic * %sccs.include.redist.c%
622163Sdist */
7752Speter
814729Sthien #ifndef lint
9*62207Sbostic static char sccsid[] = "@(#)fdec.c 8.1 (Berkeley) 06/06/93";
1048116Sbostic #endif /* not lint */
11752Speter
12752Speter #include "whoami.h"
13752Speter #include "0.h"
14752Speter #include "tree.h"
15752Speter #include "opcode.h"
16752Speter #include "objfmt.h"
17752Speter #include "align.h"
1811334Speter #include "tmps.h"
19752Speter
20752Speter /*
21752Speter * this array keeps the pxp counters associated with
22752Speter * functions and procedures, so that they can be output
23752Speter * when their bodies are encountered
24752Speter */
25752Speter int bodycnts[ DSPLYSZ ];
26752Speter
27752Speter #ifdef PC
28752Speter # include "pc.h"
2918456Sralph # include <pcc.h>
30752Speter #endif PC
31752Speter
32752Speter #ifdef OBJ
33752Speter int cntpatch;
34752Speter int nfppatch;
35752Speter #endif OBJ
36752Speter
37752Speter funcfwd(fp)
38752Speter struct nl *fp;
39752Speter {
40752Speter
41752Speter /*
42752Speter * save the counter for this function
43752Speter */
44752Speter if ( monflg ) {
45752Speter fp -> value[ NL_CNTR ] = bodycnts[ cbn ];
46752Speter }
47752Speter }
48752Speter
49752Speter /*
50752Speter * Funcext marks the procedure or
51752Speter * function external in the symbol
52752Speter * table. Funcext should only be
53752Speter * called if PC, and is an error
54752Speter * otherwise.
55752Speter */
56752Speter
5714729Sthien struct nl *
funcext(fp)58752Speter funcext(fp)
59752Speter struct nl *fp;
60752Speter {
61752Speter
627715Smckusick #ifdef OBJ
637715Smckusick error("Procedures or functions cannot be declared external.");
647715Smckusick #endif OBJ
657715Smckusick
66752Speter #ifdef PC
677715Smckusick /*
687715Smckusick * save the counter for this function
697715Smckusick */
707715Smckusick if ( monflg ) {
717715Smckusick fp -> value[ NL_CNTR ] = bodycnts[ cbn ];
727715Smckusick }
73752Speter if (opt('s')) {
74752Speter standard();
75752Speter error("External procedures and functions are not standard");
76752Speter } else {
77752Speter if (cbn == 1) {
783825Speter fp->extra_flags |= NEXTERN;
79825Speter stabefunc( fp -> symbol , fp -> class , line );
80752Speter }
81752Speter else
82752Speter error("External procedures and functions can only be declared at the outermost level.");
83752Speter }
84752Speter #endif PC
85752Speter
86752Speter return(fp);
87752Speter }
88752Speter
89752Speter /*
90752Speter * Funcbody is called
91752Speter * when the actual (resolved)
92752Speter * declaration of a procedure is
93752Speter * encountered. It puts the names
94752Speter * of the (function) and parameters
95752Speter * into the symbol table.
96752Speter */
9714729Sthien struct nl *
funcbody(fp)98752Speter funcbody(fp)
99752Speter struct nl *fp;
100752Speter {
10114729Sthien register struct nl *q;
102752Speter
103752Speter cbn++;
104752Speter if (cbn >= DSPLYSZ) {
105752Speter error("Too many levels of function/procedure nesting");
106752Speter pexit(ERRS);
107752Speter }
10811334Speter tmpinit(cbn);
109752Speter gotos[cbn] = NIL;
110752Speter errcnt[cbn] = syneflg;
111834Speter parts[ cbn ] = NIL;
112752Speter dfiles[ cbn ] = FALSE;
113752Speter if (fp == NIL)
114752Speter return (NIL);
115752Speter /*
116752Speter * Save the virtual name
117752Speter * list stack pointer so
118752Speter * the space can be freed
119752Speter * later (funcend).
120752Speter */
121752Speter fp->ptr[2] = nlp;
122752Speter if (fp->class != PROG) {
123752Speter for (q = fp->chain; q != NIL; q = q->chain) {
12414729Sthien (void) enter(q);
1253825Speter # ifdef PC
1263825Speter q -> extra_flags |= NPARAM;
1273825Speter # endif PC
128752Speter }
129752Speter }
130752Speter if (fp->class == FUNC) {
131752Speter /*
132752Speter * For functions, enter the fvar
133752Speter */
13414729Sthien (void) enter(fp->ptr[NL_FVAR]);
135752Speter # ifdef PC
136752Speter q = fp -> ptr[ NL_FVAR ];
1373825Speter if (q -> type != NIL ) {
13811334Speter sizes[cbn].curtmps.om_off = q -> value[NL_OFFS];
13911334Speter sizes[cbn].om_max = q -> value[NL_OFFS];
1403825Speter }
141752Speter # endif PC
142752Speter }
143752Speter # ifdef PTREE
144752Speter /*
145752Speter * pick up the pointer to porf declaration
146752Speter */
147752Speter PorFHeader[ ++nesting ] = fp -> inTree;
148752Speter # endif PTREE
149752Speter return (fp);
150752Speter }
151752Speter
152752Speter /*
153752Speter * Segend is called to check for
154752Speter * unresolved variables, funcs and
155752Speter * procs, and deliver unresolved and
156752Speter * baduse error diagnostics at the
157752Speter * end of a routine segment (a separately
158752Speter * compiled segment that is not the
159752Speter * main program) for PC. This
160752Speter * routine should only be called
161752Speter * by PC (not standard).
162752Speter */
segend()163752Speter segend()
164752Speter {
16514729Sthien #ifdef PC
166752Speter register struct nl *p;
167752Speter register int i,b;
168752Speter char *cp;
169752Speter
1707719Smckusick if ( monflg ) {
1717719Smckusick error("Only the module containing the \"program\" statement");
1727719Smckusick cerror("can be profiled with ``pxp''.\n");
1737719Smckusick }
174752Speter if (opt('s')) {
175752Speter standard();
176752Speter error("Separately compiled routine segments are not standard.");
177752Speter } else {
178752Speter b = cbn;
179752Speter for (i=0; i<077; i++) {
180752Speter for (p = disptab[i]; p != NIL && (p->nl_block & 037) == b; p = p->nl_next) {
181752Speter switch (p->class) {
182752Speter case BADUSE:
18314729Sthien cp = "s";
18414729Sthien if (((struct udinfo *) (p->chain))->ud_next == NIL)
185752Speter cp++;
186752Speter eholdnl();
187752Speter if (p->value[NL_KINDS] & ISUNDEF)
188752Speter nerror("%s undefined on line%s", p->symbol, cp);
189752Speter else
190752Speter nerror("%s improperly used on line%s", p->symbol, cp);
191752Speter pnumcnt = 10;
19214729Sthien pnums((struct udinfo *) (p->chain));
193752Speter pchr('\n');
194752Speter break;
195752Speter
196752Speter case FUNC:
197752Speter case PROC:
1983825Speter if ((p->nl_flags & NFORWD) &&
1993825Speter ((p->extra_flags & NEXTERN) == 0))
200752Speter nerror("Unresolved forward declaration of %s %s", classes[p->class], p->symbol);
201752Speter break;
202752Speter
203752Speter case FVAR:
2043825Speter if (((p->nl_flags & NMOD) == 0) &&
2053825Speter ((p->chain->extra_flags & NEXTERN) == 0))
206752Speter nerror("No assignment to the function variable");
207752Speter break;
208752Speter }
209752Speter }
210752Speter disptab[i] = p;
211752Speter }
212752Speter }
213752Speter #endif PC
214752Speter #ifdef OBJ
215752Speter error("Missing program statement and program body");
216752Speter #endif OBJ
217752Speter
218752Speter }
219752Speter
220752Speter
221752Speter /*
222752Speter * Level1 does level one processing for
223752Speter * separately compiled routine segments
224752Speter */
level1()225752Speter level1()
226752Speter {
227752Speter
228752Speter # ifdef OBJ
229752Speter error("Missing program statement");
230752Speter # endif OBJ
231752Speter # ifdef PC
232752Speter if (opt('s')) {
233752Speter standard();
234752Speter error("Missing program statement");
235752Speter }
236752Speter # endif PC
237752Speter
238752Speter cbn++;
23911334Speter tmpinit(cbn);
240834Speter gotos[cbn] = NIL;
241834Speter errcnt[cbn] = syneflg;
242834Speter parts[ cbn ] = NIL;
243834Speter dfiles[ cbn ] = FALSE;
2443073Smckusic progseen = TRUE;
245752Speter }
246752Speter
247752Speter
248752Speter
249752Speter pnums(p)
250752Speter struct udinfo *p;
251752Speter {
252752Speter
253752Speter if (p->ud_next != NIL)
254752Speter pnums(p->ud_next);
255752Speter if (pnumcnt == 0) {
256752Speter printf("\n\t");
257752Speter pnumcnt = 20;
258752Speter }
259752Speter pnumcnt--;
260752Speter printf(" %d", p->ud_line);
261752Speter }
262752Speter
26314729Sthien /*VARARGS*/
nerror(a1,a2,a3)264752Speter nerror(a1, a2, a3)
26514729Sthien char *a1,*a2,*a3;
266752Speter {
267752Speter
268752Speter if (Fp != NIL) {
269752Speter yySsync();
270752Speter #ifndef PI1
271752Speter if (opt('l'))
272752Speter yyoutline();
273752Speter #endif
274752Speter yysetfile(filename);
275752Speter printf("In %s %s:\n", classes[Fp->class], Fp->symbol);
276752Speter Fp = NIL;
277752Speter elineoff();
278752Speter }
279752Speter error(a1, a2, a3);
280752Speter }
281