1752Speter /* Copyright (c) 1979 Regents of the University of California */ 2752Speter 3*11334Speter static char sccsid[] = "@(#)fdec.c 1.23 02/28/83"; 4752Speter 5752Speter #include "whoami.h" 6752Speter #include "0.h" 7752Speter #include "tree.h" 8752Speter #include "opcode.h" 9752Speter #include "objfmt.h" 10752Speter #include "align.h" 11*11334Speter #include "tmps.h" 12752Speter 13752Speter /* 14752Speter * this array keeps the pxp counters associated with 15752Speter * functions and procedures, so that they can be output 16752Speter * when their bodies are encountered 17752Speter */ 18752Speter int bodycnts[ DSPLYSZ ]; 19752Speter 20752Speter #ifdef PC 21752Speter # include "pc.h" 22752Speter # include "pcops.h" 23752Speter #endif PC 24752Speter 25752Speter #ifdef OBJ 26752Speter int cntpatch; 27752Speter int nfppatch; 28752Speter #endif OBJ 29752Speter 30752Speter funcfwd(fp) 31752Speter struct nl *fp; 32752Speter { 33752Speter 34752Speter /* 35752Speter * save the counter for this function 36752Speter */ 37752Speter if ( monflg ) { 38752Speter fp -> value[ NL_CNTR ] = bodycnts[ cbn ]; 39752Speter } 40752Speter return (fp); 41752Speter } 42752Speter 43752Speter /* 44752Speter * Funcext marks the procedure or 45752Speter * function external in the symbol 46752Speter * table. Funcext should only be 47752Speter * called if PC, and is an error 48752Speter * otherwise. 49752Speter */ 50752Speter 51752Speter funcext(fp) 52752Speter struct nl *fp; 53752Speter { 54752Speter 557715Smckusick #ifdef OBJ 567715Smckusick error("Procedures or functions cannot be declared external."); 577715Smckusick #endif OBJ 587715Smckusick 59752Speter #ifdef PC 607715Smckusick /* 617715Smckusick * save the counter for this function 627715Smckusick */ 637715Smckusick if ( monflg ) { 647715Smckusick fp -> value[ NL_CNTR ] = bodycnts[ cbn ]; 657715Smckusick } 66752Speter if (opt('s')) { 67752Speter standard(); 68752Speter error("External procedures and functions are not standard"); 69752Speter } else { 70752Speter if (cbn == 1) { 713825Speter fp->extra_flags |= NEXTERN; 72825Speter stabefunc( fp -> symbol , fp -> class , line ); 73752Speter } 74752Speter else 75752Speter error("External procedures and functions can only be declared at the outermost level."); 76752Speter } 77752Speter #endif PC 78752Speter 79752Speter return(fp); 80752Speter } 81752Speter 82752Speter /* 83752Speter * Funcbody is called 84752Speter * when the actual (resolved) 85752Speter * declaration of a procedure is 86752Speter * encountered. It puts the names 87752Speter * of the (function) and parameters 88752Speter * into the symbol table. 89752Speter */ 90752Speter funcbody(fp) 91752Speter struct nl *fp; 92752Speter { 93752Speter register struct nl *q, *p; 94752Speter 95752Speter cbn++; 96752Speter if (cbn >= DSPLYSZ) { 97752Speter error("Too many levels of function/procedure nesting"); 98752Speter pexit(ERRS); 99752Speter } 100*11334Speter tmpinit(cbn); 101752Speter gotos[cbn] = NIL; 102752Speter errcnt[cbn] = syneflg; 103834Speter parts[ cbn ] = NIL; 104752Speter dfiles[ cbn ] = FALSE; 105752Speter if (fp == NIL) 106752Speter return (NIL); 107752Speter /* 108752Speter * Save the virtual name 109752Speter * list stack pointer so 110752Speter * the space can be freed 111752Speter * later (funcend). 112752Speter */ 113752Speter fp->ptr[2] = nlp; 114752Speter if (fp->class != PROG) { 115752Speter for (q = fp->chain; q != NIL; q = q->chain) { 116752Speter enter(q); 1173825Speter # ifdef PC 1183825Speter q -> extra_flags |= NPARAM; 1193825Speter # endif PC 120752Speter } 121752Speter } 122752Speter if (fp->class == FUNC) { 123752Speter /* 124752Speter * For functions, enter the fvar 125752Speter */ 126752Speter enter(fp->ptr[NL_FVAR]); 127752Speter # ifdef PC 128752Speter q = fp -> ptr[ NL_FVAR ]; 1293825Speter if (q -> type != NIL ) { 130*11334Speter sizes[cbn].curtmps.om_off = q -> value[NL_OFFS]; 131*11334Speter sizes[cbn].om_max = q -> value[NL_OFFS]; 1323825Speter } 133752Speter # endif PC 134752Speter } 135752Speter # ifdef PTREE 136752Speter /* 137752Speter * pick up the pointer to porf declaration 138752Speter */ 139752Speter PorFHeader[ ++nesting ] = fp -> inTree; 140752Speter # endif PTREE 141752Speter return (fp); 142752Speter } 143752Speter 144752Speter /* 145752Speter * Segend is called to check for 146752Speter * unresolved variables, funcs and 147752Speter * procs, and deliver unresolved and 148752Speter * baduse error diagnostics at the 149752Speter * end of a routine segment (a separately 150752Speter * compiled segment that is not the 151752Speter * main program) for PC. This 152752Speter * routine should only be called 153752Speter * by PC (not standard). 154752Speter */ 155752Speter segend() 156752Speter { 157752Speter register struct nl *p; 158752Speter register int i,b; 159752Speter char *cp; 160752Speter 161752Speter #ifdef PC 1627719Smckusick if ( monflg ) { 1637719Smckusick error("Only the module containing the \"program\" statement"); 1647719Smckusick cerror("can be profiled with ``pxp''.\n"); 1657719Smckusick } 166752Speter if (opt('s')) { 167752Speter standard(); 168752Speter error("Separately compiled routine segments are not standard."); 169752Speter } else { 170752Speter b = cbn; 171752Speter for (i=0; i<077; i++) { 172752Speter for (p = disptab[i]; p != NIL && (p->nl_block & 037) == b; p = p->nl_next) { 173752Speter switch (p->class) { 174752Speter case BADUSE: 175752Speter cp = 's'; 176752Speter if (p->chain->ud_next == NIL) 177752Speter cp++; 178752Speter eholdnl(); 179752Speter if (p->value[NL_KINDS] & ISUNDEF) 180752Speter nerror("%s undefined on line%s", p->symbol, cp); 181752Speter else 182752Speter nerror("%s improperly used on line%s", p->symbol, cp); 183752Speter pnumcnt = 10; 184752Speter pnums(p->chain); 185752Speter pchr('\n'); 186752Speter break; 187752Speter 188752Speter case FUNC: 189752Speter case PROC: 1903825Speter if ((p->nl_flags & NFORWD) && 1913825Speter ((p->extra_flags & NEXTERN) == 0)) 192752Speter nerror("Unresolved forward declaration of %s %s", classes[p->class], p->symbol); 193752Speter break; 194752Speter 195752Speter case FVAR: 1963825Speter if (((p->nl_flags & NMOD) == 0) && 1973825Speter ((p->chain->extra_flags & NEXTERN) == 0)) 198752Speter nerror("No assignment to the function variable"); 199752Speter break; 200752Speter } 201752Speter } 202752Speter disptab[i] = p; 203752Speter } 204752Speter } 205752Speter #endif PC 206752Speter #ifdef OBJ 207752Speter error("Missing program statement and program body"); 208752Speter #endif OBJ 209752Speter 210752Speter } 211752Speter 212752Speter 213752Speter /* 214752Speter * Level1 does level one processing for 215752Speter * separately compiled routine segments 216752Speter */ 217752Speter level1() 218752Speter { 219752Speter 220752Speter # ifdef OBJ 221752Speter error("Missing program statement"); 222752Speter # endif OBJ 223752Speter # ifdef PC 224752Speter if (opt('s')) { 225752Speter standard(); 226752Speter error("Missing program statement"); 227752Speter } 228752Speter # endif PC 229752Speter 230752Speter cbn++; 231*11334Speter tmpinit(cbn); 232834Speter gotos[cbn] = NIL; 233834Speter errcnt[cbn] = syneflg; 234834Speter parts[ cbn ] = NIL; 235834Speter dfiles[ cbn ] = FALSE; 2363073Smckusic progseen = TRUE; 237752Speter } 238752Speter 239752Speter 240752Speter 241752Speter pnums(p) 242752Speter struct udinfo *p; 243752Speter { 244752Speter 245752Speter if (p->ud_next != NIL) 246752Speter pnums(p->ud_next); 247752Speter if (pnumcnt == 0) { 248752Speter printf("\n\t"); 249752Speter pnumcnt = 20; 250752Speter } 251752Speter pnumcnt--; 252752Speter printf(" %d", p->ud_line); 253752Speter } 254752Speter 255752Speter nerror(a1, a2, a3) 256752Speter { 257752Speter 258752Speter if (Fp != NIL) { 259752Speter yySsync(); 260752Speter #ifndef PI1 261752Speter if (opt('l')) 262752Speter yyoutline(); 263752Speter #endif 264752Speter yysetfile(filename); 265752Speter printf("In %s %s:\n", classes[Fp->class], Fp->symbol); 266752Speter Fp = NIL; 267752Speter elineoff(); 268752Speter } 269752Speter error(a1, a2, a3); 270752Speter } 271