xref: /csrg-svn/usr.bin/pascal/src/fdec.c (revision 62207)
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