1: /* common.c 4.2 85/08/22 */ 2: 3: #ifdef PASS1COMMON 4: #include "pass1.h" 5: #else 6: #ifdef PASS2COMMON 7: #include "pass2.h" 8: #endif 9: #endif 10: 11: #ifdef FORT 12: #undef BUFSTDERR 13: #endif 14: #ifndef ONEPASS 15: #undef BUFSTDERR 16: #endif 17: # ifndef EXIT 18: # define EXIT exit 19: # endif 20: 21: int nerrors = 0; /* number of errors */ 22: 23: extern unsigned int offsz; 24: 25: unsigned caloff(){ 26: register i; 27: unsigned int temp; 28: unsigned int off; 29: temp = 1; 30: i = 0; 31: do { 32: temp <<= 1; 33: ++i; 34: } while( temp != 0 ); 35: off = 1 << (i-1); 36: return (off); 37: } 38: 39: NODE *lastfree; /* pointer to last free node; (for allocator) */ 40: 41: /* VARARGS1 */ 42: uerror( s, a ) char *s; { /* nonfatal error message */ 43: /* the routine where is different for pass 1 and pass 2; 44: /* it tells where the error took place */ 45: 46: ++nerrors; 47: where('u'); 48: fprintf( stderr, s, a ); 49: fprintf( stderr, "\n" ); 50: #ifdef BUFSTDERR 51: fflush(stderr); 52: #endif 53: if( nerrors > 30 ) cerror( "too many errors"); 54: } 55: 56: /* VARARGS1 */ 57: cerror( s, a, b, c ) char *s; { /* compiler error: die */ 58: where('c'); 59: if( nerrors && nerrors <= 30 ){ /* give the compiler the benefit of the doubt */ 60: fprintf( stderr, "cannot recover from earlier errors: goodbye!\n" ); 61: } 62: else { 63: fprintf( stderr, "compiler error: " ); 64: fprintf( stderr, s, a, b, c ); 65: fprintf( stderr, "\n" ); 66: } 67: #ifdef BUFSTDERR 68: fflush(stderr); 69: #endif 70: EXIT(1); 71: } 72: 73: int Wflag = 0; /* Non-zero means do not print warnings */ 74: 75: /* VARARGS1 */ 76: werror( s, a, b ) char *s; { /* warning */ 77: if(Wflag) return; 78: where('w'); 79: fprintf( stderr, "warning: " ); 80: fprintf( stderr, s, a, b ); 81: fprintf( stderr, "\n" ); 82: #ifdef BUFSTDERR 83: fflush(stderr); 84: #endif 85: } 86: 87: tinit(){ /* initialize expression tree search */ 88: 89: register NODE *p; 90: 91: for( p=node; p<= &node[TREESZ-1]; ++p ) p->in.op = FREE; 92: lastfree = node; 93: 94: } 95: 96: # define TNEXT(p) (p== &node[TREESZ-1]?node:p+1) 97: 98: NODE * 99: talloc(){ 100: register NODE *p, *q; 101: 102: q = lastfree; 103: for( p = TNEXT(q); p!=q; p= TNEXT(p)) 104: if( p->in.op ==FREE ) return(lastfree=p); 105: 106: cerror( "out of tree space; simplify expression"); 107: /* NOTREACHED */ 108: } 109: 110: tcheck(){ /* ensure that all nodes have been freed */ 111: 112: register NODE *p; 113: 114: if( !nerrors ) 115: for( p=node; p<= &node[TREESZ-1]; ++p ) 116: if( p->in.op != FREE ) cerror( "wasted space: %o", p ); 117: tinit(); 118: #ifdef FLEXNAMES 119: freetstr(); 120: #endif 121: } 122: tfree( p ) NODE *p; { 123: /* free the tree p */ 124: extern tfree1(); 125: 126: if( p->in.op != FREE ) walkf( p, tfree1 ); 127: 128: } 129: 130: tfree1(p) NODE *p; { 131: if( p == 0 ) cerror( "freeing blank tree!"); 132: else p->in.op = FREE; 133: } 134: 135: fwalk( t, f, down ) register NODE *t; int (*f)(); { 136: 137: int down1, down2; 138: 139: more: 140: down1 = down2 = 0; 141: 142: (*f)( t, down, &down1, &down2 ); 143: 144: switch( optype( t->in.op ) ){ 145: 146: case BITYPE: 147: fwalk( t->in.left, f, down1 ); 148: t = t->in.right; 149: down = down2; 150: goto more; 151: 152: case UTYPE: 153: t = t->in.left; 154: down = down1; 155: goto more; 156: 157: } 158: } 159: 160: #ifndef vax 161: walkf( t, f ) register NODE *t; int (*f)(); { 162: register opty; 163: 164: opty = optype(t->in.op); 165: 166: if( opty != LTYPE ) walkf( t->in.left, f ); 167: if( opty == BITYPE ) walkf( t->in.right, f ); 168: (*f)( t ); 169: } 170: #else 171: #define NR 100 172: 173: /* 174: * Deliberately avoids recursion -- use this version on machines with 175: * expensive procedure calls. 176: */ 177: walkf(t, f) 178: register NODE *t; 179: register int (*f)(); 180: { 181: register int i = 1; 182: register int opty = optype(t->in.op); 183: static NODE *at[NR]; 184: static int ao[NR]; 185: 186: #define PUSH(dir, state) \ 187: (ao[i] = state, at[i++] = t, t = t->in.dir, opty = optype(t->in.op)) 188: #define POP() \ 189: (opty = ao[--i], t = at[i]) 190: 191: do { 192: switch (opty) { 193: case LTYPE: (*f)(t); POP(); break; 194: case UTYPE: PUSH(left, LTYPE); break; 195: case BITYPE: PUSH(left, BITYPE+1); break; 196: case BITYPE+1: PUSH(right, LTYPE); break; 197: default: 198: cerror("bad op type in walkf"); 199: } 200: if (i >= NR) { 201: walkf(t, f); 202: POP(); 203: } 204: } while (i > 0); 205: } 206: #undef NR 207: #undef PUSH 208: #undef POP 209: #endif 210: 211: 212: 213: int dope[ DSIZE ]; 214: char *opst[DSIZE]; 215: 216: struct dopest { int dopeop; char opst[8]; int dopeval; } indope[] = { 217: 218: NAME, "NAME", LTYPE, 219: STRING, "STRING", LTYPE, 220: REG, "REG", LTYPE, 221: OREG, "OREG", LTYPE, 222: ICON, "ICON", LTYPE, 223: FCON, "FCON", LTYPE, 224: DCON, "DCON", LTYPE, 225: CCODES, "CCODES", LTYPE, 226: UNARY MINUS, "U-", UTYPE, 227: UNARY MUL, "U*", UTYPE, 228: UNARY AND, "U&", UTYPE, 229: UNARY CALL, "UCALL", UTYPE|CALLFLG, 230: UNARY FORTCALL, "UFCALL", UTYPE|CALLFLG, 231: NOT, "!", UTYPE|LOGFLG, 232: COMPL, "~", UTYPE, 233: FORCE, "FORCE", UTYPE, 234: INIT, "INIT", UTYPE, 235: SCONV, "SCONV", UTYPE, 236: PCONV, "PCONV", UTYPE, 237: PLUS, "+", BITYPE|FLOFLG|SIMPFLG|COMMFLG, 238: ASG PLUS, "+=", BITYPE|ASGFLG|ASGOPFLG|FLOFLG|SIMPFLG|COMMFLG, 239: MINUS, "-", BITYPE|FLOFLG|SIMPFLG, 240: ASG MINUS, "-=", BITYPE|FLOFLG|SIMPFLG|ASGFLG|ASGOPFLG, 241: MUL, "*", BITYPE|FLOFLG|MULFLG, 242: ASG MUL, "*=", BITYPE|FLOFLG|MULFLG|ASGFLG|ASGOPFLG, 243: AND, "&", BITYPE|SIMPFLG|COMMFLG, 244: ASG AND, "&=", BITYPE|SIMPFLG|COMMFLG|ASGFLG|ASGOPFLG, 245: QUEST, "?", BITYPE, 246: COLON, ":", BITYPE, 247: ANDAND, "&&", BITYPE|LOGFLG, 248: OROR, "||", BITYPE|LOGFLG, 249: CM, ",", BITYPE, 250: COMOP, ",OP", BITYPE, 251: ASSIGN, "=", BITYPE|ASGFLG, 252: DIV, "/", BITYPE|FLOFLG|MULFLG|DIVFLG, 253: ASG DIV, "/=", BITYPE|FLOFLG|MULFLG|DIVFLG|ASGFLG|ASGOPFLG, 254: MOD, "%", BITYPE|DIVFLG, 255: ASG MOD, "%=", BITYPE|DIVFLG|ASGFLG|ASGOPFLG, 256: LS, "<<", BITYPE|SHFFLG, 257: ASG LS, "<<=", BITYPE|SHFFLG|ASGFLG|ASGOPFLG, 258: RS, ">>", BITYPE|SHFFLG, 259: ASG RS, ">>=", BITYPE|SHFFLG|ASGFLG|ASGOPFLG, 260: OR, "|", BITYPE|COMMFLG|SIMPFLG, 261: ASG OR, "|=", BITYPE|COMMFLG|SIMPFLG|ASGFLG|ASGOPFLG, 262: ER, "^", BITYPE|COMMFLG|SIMPFLG, 263: ASG ER, "^=", BITYPE|COMMFLG|SIMPFLG|ASGFLG|ASGOPFLG, 264: INCR, "++", BITYPE|ASGFLG, 265: DECR, "--", BITYPE|ASGFLG, 266: STREF, "->", BITYPE, 267: CALL, "CALL", BITYPE|CALLFLG, 268: FORTCALL, "FCALL", BITYPE|CALLFLG, 269: EQ, "==", BITYPE|LOGFLG, 270: NE, "!=", BITYPE|LOGFLG, 271: LE, "<=", BITYPE|LOGFLG, 272: LT, "<", BITYPE|LOGFLG, 273: GE, ">", BITYPE|LOGFLG, 274: GT, ">", BITYPE|LOGFLG, 275: UGT, "UGT", BITYPE|LOGFLG, 276: UGE, "UGE", BITYPE|LOGFLG, 277: ULT, "ULT", BITYPE|LOGFLG, 278: ULE, "ULE", BITYPE|LOGFLG, 279: #ifdef ARS 280: ARS, "A>>", BITYPE, 281: #endif 282: TYPE, "TYPE", LTYPE, 283: LB, "[", BITYPE, 284: CBRANCH, "CBRANCH", BITYPE, 285: FLD, "FLD", UTYPE, 286: PMCONV, "PMCONV", BITYPE, 287: PVCONV, "PVCONV", BITYPE, 288: RETURN, "RETURN", BITYPE|ASGFLG|ASGOPFLG, 289: CAST, "CAST", BITYPE|ASGFLG|ASGOPFLG, 290: GOTO, "GOTO", UTYPE, 291: STASG, "STASG", BITYPE|ASGFLG, 292: STARG, "STARG", UTYPE, 293: STCALL, "STCALL", BITYPE|CALLFLG, 294: UNARY STCALL, "USTCALL", UTYPE|CALLFLG, 295: 296: -1, "", 0 297: }; 298: 299: mkdope(){ 300: register struct dopest *q; 301: 302: for( q = indope; q->dopeop >= 0; ++q ){ 303: dope[q->dopeop] = q->dopeval; 304: opst[q->dopeop] = q->opst; 305: } 306: } 307: # ifndef BUG4 308: tprint( t ) TWORD t; { /* output a nice description of the type of t */ 309: 310: static char * tnames[] = { 311: "undef", 312: "farg", 313: "char", 314: "short", 315: "int", 316: "long", 317: "float", 318: "double", 319: "strty", 320: "unionty", 321: "enumty", 322: "moety", 323: "uchar", 324: "ushort", 325: "unsigned", 326: "ulong", 327: "?", "?" 328: }; 329: 330: for(;; t = DECREF(t) ){ 331: 332: if( ISPTR(t) ) printf( "PTR " ); 333: else if( ISFTN(t) ) printf( "FTN " ); 334: else if( ISARY(t) ) printf( "ARY " ); 335: else { 336: printf( "%s", tnames[t] ); 337: return; 338: } 339: } 340: } 341: # endif 342: 343: #ifdef FLEXNAMES 344: #define NTSTRBUF 40 345: #define TSTRSZ 2048 346: char itstrbuf[TSTRSZ]; 347: char *tstrbuf[NTSTRBUF] = { itstrbuf }; 348: char **curtstr = tstrbuf; 349: int tstrused; 350: 351: char * 352: tstr(cp) 353: register char *cp; 354: { 355: register int i = strlen(cp); 356: register char *dp; 357: 358: if (tstrused + i >= TSTRSZ) { 359: if (++curtstr >= &tstrbuf[NTSTRBUF]) 360: cerror("out of temporary string space"); 361: tstrused = 0; 362: if (*curtstr == 0) { 363: dp = (char *)malloc(TSTRSZ); 364: if (dp == 0) 365: cerror("out of memory (tstr)"); 366: *curtstr = dp; 367: } 368: } 369: strcpy(dp = *curtstr+tstrused, cp); 370: tstrused += i + 1; 371: return (dp); 372: } 373: #endif