1752Speter /* Copyright (c) 1979 Regents of the University of California */ 2752Speter 3*7719Smckusick static char sccsid[] = "@(#)fdec.c 1.22 08/12/82"; 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" 11752Speter 12752Speter /* 13752Speter * this array keeps the pxp counters associated with 14752Speter * functions and procedures, so that they can be output 15752Speter * when their bodies are encountered 16752Speter */ 17752Speter int bodycnts[ DSPLYSZ ]; 18752Speter 19752Speter #ifdef PC 20752Speter # include "pc.h" 21752Speter # include "pcops.h" 22752Speter #endif PC 23752Speter 24752Speter #ifdef OBJ 25752Speter int cntpatch; 26752Speter int nfppatch; 27752Speter #endif OBJ 28752Speter 29752Speter funcfwd(fp) 30752Speter struct nl *fp; 31752Speter { 32752Speter 33752Speter /* 34752Speter * save the counter for this function 35752Speter */ 36752Speter if ( monflg ) { 37752Speter fp -> value[ NL_CNTR ] = bodycnts[ cbn ]; 38752Speter } 39752Speter return (fp); 40752Speter } 41752Speter 42752Speter /* 43752Speter * Funcext marks the procedure or 44752Speter * function external in the symbol 45752Speter * table. Funcext should only be 46752Speter * called if PC, and is an error 47752Speter * otherwise. 48752Speter */ 49752Speter 50752Speter funcext(fp) 51752Speter struct nl *fp; 52752Speter { 53752Speter 547715Smckusick #ifdef OBJ 557715Smckusick error("Procedures or functions cannot be declared external."); 567715Smckusick #endif OBJ 577715Smckusick 58752Speter #ifdef PC 597715Smckusick /* 607715Smckusick * save the counter for this function 617715Smckusick */ 627715Smckusick if ( monflg ) { 637715Smckusick fp -> value[ NL_CNTR ] = bodycnts[ cbn ]; 647715Smckusick } 65752Speter if (opt('s')) { 66752Speter standard(); 67752Speter error("External procedures and functions are not standard"); 68752Speter } else { 69752Speter if (cbn == 1) { 703825Speter fp->extra_flags |= NEXTERN; 71825Speter stabefunc( fp -> symbol , fp -> class , line ); 72752Speter } 73752Speter else 74752Speter error("External procedures and functions can only be declared at the outermost level."); 75752Speter } 76752Speter #endif PC 77752Speter 78752Speter return(fp); 79752Speter } 80752Speter 81752Speter /* 82752Speter * Funcbody is called 83752Speter * when the actual (resolved) 84752Speter * declaration of a procedure is 85752Speter * encountered. It puts the names 86752Speter * of the (function) and parameters 87752Speter * into the symbol table. 88752Speter */ 89752Speter funcbody(fp) 90752Speter struct nl *fp; 91752Speter { 92752Speter register struct nl *q, *p; 933825Speter struct nl *functemp; 94752Speter 95752Speter cbn++; 96752Speter if (cbn >= DSPLYSZ) { 97752Speter error("Too many levels of function/procedure nesting"); 98752Speter pexit(ERRS); 99752Speter } 1003222Smckusic sizes[cbn].om_max = sizes[cbn].curtmps.om_off = -DPOFF1; 1013276Smckusic sizes[cbn].reg_max = -1; 1023276Smckusic sizes[cbn].curtmps.reg_off = 0; 103752Speter gotos[cbn] = NIL; 104752Speter errcnt[cbn] = syneflg; 105834Speter parts[ cbn ] = NIL; 106752Speter dfiles[ cbn ] = FALSE; 107752Speter if (fp == NIL) 108752Speter return (NIL); 109752Speter /* 110752Speter * Save the virtual name 111752Speter * list stack pointer so 112752Speter * the space can be freed 113752Speter * later (funcend). 114752Speter */ 115752Speter fp->ptr[2] = nlp; 116752Speter if (fp->class != PROG) { 117752Speter for (q = fp->chain; q != NIL; q = q->chain) { 118752Speter enter(q); 1193825Speter # ifdef PC 1203825Speter q -> extra_flags |= NPARAM; 1213825Speter # endif PC 122752Speter } 123752Speter } 124752Speter if (fp->class == FUNC) { 125752Speter /* 126752Speter * For functions, enter the fvar 127752Speter */ 128752Speter enter(fp->ptr[NL_FVAR]); 129752Speter # ifdef PC 130752Speter q = fp -> ptr[ NL_FVAR ]; 1313825Speter if (q -> type != NIL ) { 1323825Speter functemp = tmpalloc( 1333825Speter leven( 1343825Speter roundup( 1353825Speter (int)lwidth(q -> type), 1363825Speter (long)align(q -> type))), 1373825Speter q -> type, NOREG); 1383825Speter if ( q -> ptr[NL_OFFS] != functemp->value[NL_OFFS] ) 1393276Smckusic panic("func var"); 1403825Speter } 1413825Speter q -> extra_flags |= functemp -> extra_flags; 142752Speter # endif PC 143752Speter } 144752Speter # ifdef PTREE 145752Speter /* 146752Speter * pick up the pointer to porf declaration 147752Speter */ 148752Speter PorFHeader[ ++nesting ] = fp -> inTree; 149752Speter # endif PTREE 150752Speter return (fp); 151752Speter } 152752Speter 153752Speter /* 154752Speter * Segend is called to check for 155752Speter * unresolved variables, funcs and 156752Speter * procs, and deliver unresolved and 157752Speter * baduse error diagnostics at the 158752Speter * end of a routine segment (a separately 159752Speter * compiled segment that is not the 160752Speter * main program) for PC. This 161752Speter * routine should only be called 162752Speter * by PC (not standard). 163752Speter */ 164752Speter segend() 165752Speter { 166752Speter register struct nl *p; 167752Speter register int i,b; 168752Speter char *cp; 169752Speter 170752Speter #ifdef PC 171*7719Smckusick if ( monflg ) { 172*7719Smckusick error("Only the module containing the \"program\" statement"); 173*7719Smckusick cerror("can be profiled with ``pxp''.\n"); 174*7719Smckusick } 175752Speter if (opt('s')) { 176752Speter standard(); 177752Speter error("Separately compiled routine segments are not standard."); 178752Speter } else { 179752Speter b = cbn; 180752Speter for (i=0; i<077; i++) { 181752Speter for (p = disptab[i]; p != NIL && (p->nl_block & 037) == b; p = p->nl_next) { 182752Speter switch (p->class) { 183752Speter case BADUSE: 184752Speter cp = 's'; 185752Speter if (p->chain->ud_next == NIL) 186752Speter cp++; 187752Speter eholdnl(); 188752Speter if (p->value[NL_KINDS] & ISUNDEF) 189752Speter nerror("%s undefined on line%s", p->symbol, cp); 190752Speter else 191752Speter nerror("%s improperly used on line%s", p->symbol, cp); 192752Speter pnumcnt = 10; 193752Speter pnums(p->chain); 194752Speter pchr('\n'); 195752Speter break; 196752Speter 197752Speter case FUNC: 198752Speter case PROC: 1993825Speter if ((p->nl_flags & NFORWD) && 2003825Speter ((p->extra_flags & NEXTERN) == 0)) 201752Speter nerror("Unresolved forward declaration of %s %s", classes[p->class], p->symbol); 202752Speter break; 203752Speter 204752Speter case FVAR: 2053825Speter if (((p->nl_flags & NMOD) == 0) && 2063825Speter ((p->chain->extra_flags & NEXTERN) == 0)) 207752Speter nerror("No assignment to the function variable"); 208752Speter break; 209752Speter } 210752Speter } 211752Speter disptab[i] = p; 212752Speter } 213752Speter } 214752Speter #endif PC 215752Speter #ifdef OBJ 216752Speter error("Missing program statement and program body"); 217752Speter #endif OBJ 218752Speter 219752Speter } 220752Speter 221752Speter 222752Speter /* 223752Speter * Level1 does level one processing for 224752Speter * separately compiled routine segments 225752Speter */ 226752Speter level1() 227752Speter { 228752Speter 229752Speter # ifdef OBJ 230752Speter error("Missing program statement"); 231752Speter # endif OBJ 232752Speter # ifdef PC 233752Speter if (opt('s')) { 234752Speter standard(); 235752Speter error("Missing program statement"); 236752Speter } 237752Speter # endif PC 238752Speter 239752Speter cbn++; 2403222Smckusic sizes[cbn].om_max = sizes[cbn].curtmps.om_off = -DPOFF1; 241834Speter gotos[cbn] = NIL; 242834Speter errcnt[cbn] = syneflg; 243834Speter parts[ cbn ] = NIL; 244834Speter dfiles[ cbn ] = FALSE; 2453073Smckusic progseen = TRUE; 246752Speter } 247752Speter 248752Speter 249752Speter 250752Speter pnums(p) 251752Speter struct udinfo *p; 252752Speter { 253752Speter 254752Speter if (p->ud_next != NIL) 255752Speter pnums(p->ud_next); 256752Speter if (pnumcnt == 0) { 257752Speter printf("\n\t"); 258752Speter pnumcnt = 20; 259752Speter } 260752Speter pnumcnt--; 261752Speter printf(" %d", p->ud_line); 262752Speter } 263752Speter 264752Speter nerror(a1, a2, a3) 265752Speter { 266752Speter 267752Speter if (Fp != NIL) { 268752Speter yySsync(); 269752Speter #ifndef PI1 270752Speter if (opt('l')) 271752Speter yyoutline(); 272752Speter #endif 273752Speter yysetfile(filename); 274752Speter printf("In %s %s:\n", classes[Fp->class], Fp->symbol); 275752Speter Fp = NIL; 276752Speter elineoff(); 277752Speter } 278752Speter error(a1, a2, a3); 279752Speter } 280