1752Speter /* Copyright (c) 1979 Regents of the University of California */ 2752Speter 3*14729Sthien #ifndef lint 4*14729Sthien static char sccsid[] = "@(#)fdec.c 1.24 08/19/83"; 5*14729Sthien #endif 6752Speter 7752Speter #include "whoami.h" 8752Speter #include "0.h" 9752Speter #include "tree.h" 10752Speter #include "opcode.h" 11752Speter #include "objfmt.h" 12752Speter #include "align.h" 1311334Speter #include "tmps.h" 14752Speter 15752Speter /* 16752Speter * this array keeps the pxp counters associated with 17752Speter * functions and procedures, so that they can be output 18752Speter * when their bodies are encountered 19752Speter */ 20752Speter int bodycnts[ DSPLYSZ ]; 21752Speter 22752Speter #ifdef PC 23752Speter # include "pc.h" 24752Speter # include "pcops.h" 25752Speter #endif PC 26752Speter 27752Speter #ifdef OBJ 28752Speter int cntpatch; 29752Speter int nfppatch; 30752Speter #endif OBJ 31752Speter 32752Speter funcfwd(fp) 33752Speter struct nl *fp; 34752Speter { 35752Speter 36752Speter /* 37752Speter * save the counter for this function 38752Speter */ 39752Speter if ( monflg ) { 40752Speter fp -> value[ NL_CNTR ] = bodycnts[ cbn ]; 41752Speter } 42752Speter } 43752Speter 44752Speter /* 45752Speter * Funcext marks the procedure or 46752Speter * function external in the symbol 47752Speter * table. Funcext should only be 48752Speter * called if PC, and is an error 49752Speter * otherwise. 50752Speter */ 51752Speter 52*14729Sthien struct nl * 53752Speter funcext(fp) 54752Speter struct nl *fp; 55752Speter { 56752Speter 577715Smckusick #ifdef OBJ 587715Smckusick error("Procedures or functions cannot be declared external."); 597715Smckusick #endif OBJ 607715Smckusick 61752Speter #ifdef PC 627715Smckusick /* 637715Smckusick * save the counter for this function 647715Smckusick */ 657715Smckusick if ( monflg ) { 667715Smckusick fp -> value[ NL_CNTR ] = bodycnts[ cbn ]; 677715Smckusick } 68752Speter if (opt('s')) { 69752Speter standard(); 70752Speter error("External procedures and functions are not standard"); 71752Speter } else { 72752Speter if (cbn == 1) { 733825Speter fp->extra_flags |= NEXTERN; 74825Speter stabefunc( fp -> symbol , fp -> class , line ); 75752Speter } 76752Speter else 77752Speter error("External procedures and functions can only be declared at the outermost level."); 78752Speter } 79752Speter #endif PC 80752Speter 81752Speter return(fp); 82752Speter } 83752Speter 84752Speter /* 85752Speter * Funcbody is called 86752Speter * when the actual (resolved) 87752Speter * declaration of a procedure is 88752Speter * encountered. It puts the names 89752Speter * of the (function) and parameters 90752Speter * into the symbol table. 91752Speter */ 92*14729Sthien struct nl * 93752Speter funcbody(fp) 94752Speter struct nl *fp; 95752Speter { 96*14729Sthien register struct nl *q; 97752Speter 98752Speter cbn++; 99752Speter if (cbn >= DSPLYSZ) { 100752Speter error("Too many levels of function/procedure nesting"); 101752Speter pexit(ERRS); 102752Speter } 10311334Speter tmpinit(cbn); 104752Speter gotos[cbn] = NIL; 105752Speter errcnt[cbn] = syneflg; 106834Speter parts[ cbn ] = NIL; 107752Speter dfiles[ cbn ] = FALSE; 108752Speter if (fp == NIL) 109752Speter return (NIL); 110752Speter /* 111752Speter * Save the virtual name 112752Speter * list stack pointer so 113752Speter * the space can be freed 114752Speter * later (funcend). 115752Speter */ 116752Speter fp->ptr[2] = nlp; 117752Speter if (fp->class != PROG) { 118752Speter for (q = fp->chain; q != NIL; q = q->chain) { 119*14729Sthien (void) enter(q); 1203825Speter # ifdef PC 1213825Speter q -> extra_flags |= NPARAM; 1223825Speter # endif PC 123752Speter } 124752Speter } 125752Speter if (fp->class == FUNC) { 126752Speter /* 127752Speter * For functions, enter the fvar 128752Speter */ 129*14729Sthien (void) enter(fp->ptr[NL_FVAR]); 130752Speter # ifdef PC 131752Speter q = fp -> ptr[ NL_FVAR ]; 1323825Speter if (q -> type != NIL ) { 13311334Speter sizes[cbn].curtmps.om_off = q -> value[NL_OFFS]; 13411334Speter sizes[cbn].om_max = q -> value[NL_OFFS]; 1353825Speter } 136752Speter # endif PC 137752Speter } 138752Speter # ifdef PTREE 139752Speter /* 140752Speter * pick up the pointer to porf declaration 141752Speter */ 142752Speter PorFHeader[ ++nesting ] = fp -> inTree; 143752Speter # endif PTREE 144752Speter return (fp); 145752Speter } 146752Speter 147752Speter /* 148752Speter * Segend is called to check for 149752Speter * unresolved variables, funcs and 150752Speter * procs, and deliver unresolved and 151752Speter * baduse error diagnostics at the 152752Speter * end of a routine segment (a separately 153752Speter * compiled segment that is not the 154752Speter * main program) for PC. This 155752Speter * routine should only be called 156752Speter * by PC (not standard). 157752Speter */ 158752Speter segend() 159752Speter { 160*14729Sthien #ifdef PC 161752Speter register struct nl *p; 162752Speter register int i,b; 163752Speter char *cp; 164752Speter 1657719Smckusick if ( monflg ) { 1667719Smckusick error("Only the module containing the \"program\" statement"); 1677719Smckusick cerror("can be profiled with ``pxp''.\n"); 1687719Smckusick } 169752Speter if (opt('s')) { 170752Speter standard(); 171752Speter error("Separately compiled routine segments are not standard."); 172752Speter } else { 173752Speter b = cbn; 174752Speter for (i=0; i<077; i++) { 175752Speter for (p = disptab[i]; p != NIL && (p->nl_block & 037) == b; p = p->nl_next) { 176752Speter switch (p->class) { 177752Speter case BADUSE: 178*14729Sthien cp = "s"; 179*14729Sthien if (((struct udinfo *) (p->chain))->ud_next == NIL) 180752Speter cp++; 181752Speter eholdnl(); 182752Speter if (p->value[NL_KINDS] & ISUNDEF) 183752Speter nerror("%s undefined on line%s", p->symbol, cp); 184752Speter else 185752Speter nerror("%s improperly used on line%s", p->symbol, cp); 186752Speter pnumcnt = 10; 187*14729Sthien pnums((struct udinfo *) (p->chain)); 188752Speter pchr('\n'); 189752Speter break; 190752Speter 191752Speter case FUNC: 192752Speter case PROC: 1933825Speter if ((p->nl_flags & NFORWD) && 1943825Speter ((p->extra_flags & NEXTERN) == 0)) 195752Speter nerror("Unresolved forward declaration of %s %s", classes[p->class], p->symbol); 196752Speter break; 197752Speter 198752Speter case FVAR: 1993825Speter if (((p->nl_flags & NMOD) == 0) && 2003825Speter ((p->chain->extra_flags & NEXTERN) == 0)) 201752Speter nerror("No assignment to the function variable"); 202752Speter break; 203752Speter } 204752Speter } 205752Speter disptab[i] = p; 206752Speter } 207752Speter } 208752Speter #endif PC 209752Speter #ifdef OBJ 210752Speter error("Missing program statement and program body"); 211752Speter #endif OBJ 212752Speter 213752Speter } 214752Speter 215752Speter 216752Speter /* 217752Speter * Level1 does level one processing for 218752Speter * separately compiled routine segments 219752Speter */ 220752Speter level1() 221752Speter { 222752Speter 223752Speter # ifdef OBJ 224752Speter error("Missing program statement"); 225752Speter # endif OBJ 226752Speter # ifdef PC 227752Speter if (opt('s')) { 228752Speter standard(); 229752Speter error("Missing program statement"); 230752Speter } 231752Speter # endif PC 232752Speter 233752Speter cbn++; 23411334Speter tmpinit(cbn); 235834Speter gotos[cbn] = NIL; 236834Speter errcnt[cbn] = syneflg; 237834Speter parts[ cbn ] = NIL; 238834Speter dfiles[ cbn ] = FALSE; 2393073Smckusic progseen = TRUE; 240752Speter } 241752Speter 242752Speter 243752Speter 244752Speter pnums(p) 245752Speter struct udinfo *p; 246752Speter { 247752Speter 248752Speter if (p->ud_next != NIL) 249752Speter pnums(p->ud_next); 250752Speter if (pnumcnt == 0) { 251752Speter printf("\n\t"); 252752Speter pnumcnt = 20; 253752Speter } 254752Speter pnumcnt--; 255752Speter printf(" %d", p->ud_line); 256752Speter } 257752Speter 258*14729Sthien /*VARARGS*/ 259752Speter nerror(a1, a2, a3) 260*14729Sthien char *a1,*a2,*a3; 261752Speter { 262752Speter 263752Speter if (Fp != NIL) { 264752Speter yySsync(); 265752Speter #ifndef PI1 266752Speter if (opt('l')) 267752Speter yyoutline(); 268752Speter #endif 269752Speter yysetfile(filename); 270752Speter printf("In %s %s:\n", classes[Fp->class], Fp->symbol); 271752Speter Fp = NIL; 272752Speter elineoff(); 273752Speter } 274752Speter error(a1, a2, a3); 275752Speter } 276