1*48116Sbostic /*- 2*48116Sbostic * Copyright (c) 1980 The Regents of the University of California. 3*48116Sbostic * All rights reserved. 4*48116Sbostic * 5*48116Sbostic * %sccs.include.redist.c% 622163Sdist */ 7752Speter 814729Sthien #ifndef lint 9*48116Sbostic static char sccsid[] = "@(#)fdec.c 5.2 (Berkeley) 04/16/91"; 10*48116Sbostic #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 * 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 * 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 */ 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 */ 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*/ 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