|
|
1.1 ! root 1: # include "mfile1" ! 2: ! 3: # include "lmanifest" ! 4: ! 5: # include <ctype.h> ! 6: ! 7: # define VAL 0 ! 8: # define EFF 1 ! 9: ! 10: /* these are appropriate for the -p flag */ ! 11: int SZCHAR = 8; ! 12: int SZINT = 16; ! 13: int SZFLOAT = 32; ! 14: int SZDOUBLE = 64; ! 15: int SZLONG = 32; ! 16: int SZSHORT = 16; ! 17: int SZPOINT = 16; ! 18: int ALCHAR = 8; ! 19: int ALINT = 16; ! 20: int ALFLOAT = 32; ! 21: int ALDOUBLE = 64; ! 22: int ALLONG = 32; ! 23: int ALSHORT = 16; ! 24: int ALPOINT = 16; ! 25: int ALSTRUCT = 16; ! 26: ! 27: int vflag = 1; /* tell about unused argments */ ! 28: int xflag = 0; /* tell about unused externals */ ! 29: int argflag = 0; /* used to turn off complaints about arguments */ ! 30: int libflag = 0; /* used to generate library descriptions */ ! 31: int vaflag = -1; /* used to signal functions with a variable number of args */ ! 32: int aflag = 0; /* used to check precision of assignments */ ! 33: ! 34: /* flags for the "outdef" function */ ! 35: # define USUAL (-101) ! 36: # define DECTY (-102) ! 37: # define NOFILE (-103) ! 38: # define SVLINE (-104) ! 39: ! 40: # define LNAMES 250 ! 41: ! 42: struct lnm { ! 43: short lid, flgs; ! 44: } lnames[LNAMES], *lnp; ! 45: ! 46: contx( p, down, pl, pr ) register NODE *p; register *pl, *pr; { ! 47: ! 48: *pl = *pr = VAL; ! 49: switch( p->in.op ){ ! 50: ! 51: case ANDAND: ! 52: case OROR: ! 53: case QUEST: ! 54: *pr = down; ! 55: break; ! 56: ! 57: case SCONV: ! 58: case PCONV: ! 59: case COLON: ! 60: *pr = *pl = down; ! 61: break; ! 62: ! 63: case COMOP: ! 64: *pl = EFF; ! 65: *pr = down; ! 66: ! 67: case FORCE: ! 68: case INIT: ! 69: case UNARY CALL: ! 70: case STCALL: ! 71: case UNARY STCALL: ! 72: case CALL: ! 73: case UNARY FORTCALL: ! 74: case FORTCALL: ! 75: case CBRANCH: ! 76: break; ! 77: ! 78: default: ! 79: if( asgop(p->in.op) ) break; ! 80: if( p->in.op == UNARY MUL && ( p->in.type == STRTY || p->in.type == UNIONTY || p->in.type == UNDEF) ) { ! 81: /* struct x f( ); main( ) { (void) f( ); } ! 82: * the the cast call appears as U* UNDEF ! 83: */ ! 84: break; /* the compiler does this... */ ! 85: } ! 86: if( down == EFF && hflag ) werror( "null effect" ); ! 87: ! 88: } ! 89: } ! 90: ! 91: ecode( p ) NODE *p; { ! 92: /* compile code for p */ ! 93: ! 94: fwalk( p, contx, EFF ); ! 95: lnp = lnames; ! 96: lprt( p, EFF, 0 ); ! 97: } ! 98: ! 99: ejobcode( flag ){ ! 100: /* called after processing each job */ ! 101: /* flag is nonzero if errors were detected */ ! 102: register k; ! 103: register struct symtab *p; ! 104: ! 105: for( p=stab; p< &stab[SYMTSZ]; ++p ){ ! 106: ! 107: if( p->stype != TNULL ) { ! 108: ! 109: if( p->stype == STRTY || p->stype == UNIONTY ){ ! 110: if( dimtab[p->sizoff+1] < 0 ){ /* never defined */ ! 111: #ifndef FLEXNAMES ! 112: if( hflag ) werror( "struct/union %.8s never defined", p->sname ); ! 113: #else ! 114: if( hflag ) werror( "struct/union %s never defined", p->sname ); ! 115: #endif ! 116: } ! 117: } ! 118: ! 119: switch( p->sclass ){ ! 120: ! 121: case STATIC: ! 122: if( p->suse > 0 ){ ! 123: k = lineno; ! 124: lineno = p->suse; ! 125: #ifndef FLEXNAMES ! 126: uerror( "static variable %.8s unused", ! 127: #else ! 128: uerror( "static variable %s unused", ! 129: #endif ! 130: p->sname ); ! 131: lineno = k; ! 132: break; ! 133: } ! 134: ! 135: case EXTERN: ! 136: case USTATIC: ! 137: /* with the xflag, worry about externs not used */ ! 138: /* the filename may be wrong here... */ ! 139: if( xflag && p->suse >= 0 && !libflag ){ ! 140: outdef( p, LDX, NOFILE ); ! 141: } ! 142: ! 143: case EXTDEF: ! 144: if( p->suse < 0 ){ /* used */ ! 145: outdef( p, LUM, SVLINE ); ! 146: } ! 147: break; ! 148: } ! 149: ! 150: } ! 151: ! 152: } ! 153: exit( 0 ); ! 154: } ! 155: ! 156: astype( t, i ) ATYPE *t; { ! 157: TWORD tt; ! 158: int j, k=0; ! 159: ! 160: if( (tt=BTYPE(t->aty))==STRTY || tt==UNIONTY ){ ! 161: if( i<0 || i>= DIMTABSZ-3 ){ ! 162: werror( "lint's little mind is blown" ); ! 163: } ! 164: else { ! 165: j = dimtab[i+3]; ! 166: if( j<0 || j>SYMTSZ ){ ! 167: k = ((-j)<<5)^dimtab[i]|1; ! 168: } ! 169: else { ! 170: if( stab[j].suse <= 0 ) { ! 171: #ifndef FLEXNAMES ! 172: werror( "no line number for %.8s", ! 173: #else ! 174: werror( "no line number for %s", ! 175: #endif ! 176: stab[j].sname ); ! 177: } ! 178: else k = (stab[j].suse<<5) ^ dimtab[i]; ! 179: } ! 180: } ! 181: ! 182: t->extra = k; ! 183: return( 1 ); ! 184: } ! 185: else return( 0 ); ! 186: } ! 187: ! 188: bfcode( a, n ) int a[]; { ! 189: /* code for the beginning of a function; a is an array of ! 190: indices in stab for the arguments; n is the number */ ! 191: /* this must also set retlab */ ! 192: register i; ! 193: register struct symtab *cfp; ! 194: static ATYPE t; ! 195: ! 196: retlab = 1; ! 197: cfp = &stab[curftn]; ! 198: ! 199: /* if variable number of arguments, only print the ones which will be checked */ ! 200: if( vaflag > 0 ){ ! 201: if( n < vaflag ) werror( "declare the VARARGS arguments you want checked!" ); ! 202: else n = vaflag; ! 203: } ! 204: fsave( ftitle ); ! 205: outdef( cfp, libflag?LIB:LDI, vaflag>=0?-n:n ); ! 206: vaflag = -1; ! 207: ! 208: /* output the arguments */ ! 209: if( n ){ ! 210: for( i=0; i<n; ++i ) { ! 211: t.aty = stab[a[i]].stype; ! 212: t.extra = 0; ! 213: if( !astype( &t, stab[a[i]].sizoff ) ) { ! 214: switch( t.aty ){ ! 215: ! 216: case ULONG: ! 217: break; ! 218: ! 219: case CHAR: ! 220: case SHORT: ! 221: t.aty = INT; ! 222: break; ! 223: ! 224: case UCHAR: ! 225: case USHORT: ! 226: case UNSIGNED: ! 227: t.aty = UNSIGNED; ! 228: break; ! 229: ! 230: } ! 231: } ! 232: fwrite( (char *)&t, sizeof(ATYPE), 1, stdout ); ! 233: } ! 234: } ! 235: } ! 236: ! 237: ctargs( p ) NODE *p; { ! 238: /* count arguments; p points to at least one */ ! 239: /* the arguemnts are a tower of commas to the left */ ! 240: register c; ! 241: c = 1; /* count the rhs */ ! 242: while( p->in.op == CM ){ ! 243: ++c; ! 244: p = p->in.left; ! 245: } ! 246: return( c ); ! 247: } ! 248: ! 249: lpta( p ) NODE *p; { ! 250: static ATYPE t; ! 251: ! 252: if( p->in.op == CM ){ ! 253: lpta( p->in.left ); ! 254: p = p->in.right; ! 255: } ! 256: ! 257: t.aty = p->in.type; ! 258: t.extra = (p->in.op==ICON); ! 259: ! 260: if( !astype( &t, p->in.csiz ) ) { ! 261: switch( t.aty ){ ! 262: ! 263: case CHAR: ! 264: case SHORT: ! 265: t.aty = INT; ! 266: case LONG: ! 267: case ULONG: ! 268: case INT: ! 269: case UNSIGNED: ! 270: break; ! 271: ! 272: case UCHAR: ! 273: case USHORT: ! 274: t.aty = UNSIGNED; ! 275: break; ! 276: ! 277: case FLOAT: ! 278: t.aty = DOUBLE; ! 279: t.extra = 0; ! 280: break; ! 281: ! 282: default: ! 283: t.extra = 0; ! 284: break; ! 285: } ! 286: } ! 287: fwrite( (char *)&t, sizeof(ATYPE), 1, stdout ); ! 288: } ! 289: ! 290: # define VALSET 1 ! 291: # define VALUSED 2 ! 292: # define VALASGOP 4 ! 293: # define VALADDR 8 ! 294: ! 295: lprt( p, down, uses ) register NODE *p; { ! 296: register struct symtab *q; ! 297: register id; ! 298: register acount; ! 299: register down1, down2; ! 300: register use1, use2; ! 301: register struct lnm *np1, *np2; ! 302: ! 303: /* first, set variables which are set... */ ! 304: ! 305: use1 = use2 = VALUSED; ! 306: if( p->in.op == ASSIGN ) use1 = VALSET; ! 307: else if( p->in.op == UNARY AND ) use1 = VALADDR; ! 308: else if( asgop( p->in.op ) ){ /* =ops */ ! 309: use1 = VALUSED|VALSET; ! 310: if( down == EFF ) use1 |= VALASGOP; ! 311: } ! 312: ! 313: ! 314: /* print the lines for lint */ ! 315: ! 316: down2 = down1 = VAL; ! 317: acount = 0; ! 318: ! 319: switch( p->in.op ){ ! 320: ! 321: case EQ: ! 322: case NE: ! 323: case GT: ! 324: case GE: ! 325: case LT: ! 326: case LE: ! 327: if( p->in.left->in.type == CHAR && p->in.right->in.op==ICON && p->in.right->tn.lval < 0 ){ ! 328: werror( "nonportable character comparison" ); ! 329: } ! 330: if( (p->in.op==EQ || p->in.op==NE ) && ISUNSIGNED(p->in.left->in.type) && p->in.right->in.op == ICON ){ ! 331: if( p->in.right->tn.lval < 0 && p->in.right->tn.rval == NONAME && !ISUNSIGNED(p->in.right->in.type) ){ ! 332: werror( "comparison of unsigned with negative constant" ); ! 333: } ! 334: } ! 335: break; ! 336: ! 337: case UGE: ! 338: case ULT: ! 339: if( p->in.right->in.op == ICON && p->in.right->tn.lval == 0 && p->in.right->tn.rval == NONAME ){ ! 340: werror( "unsigned comparison with 0?" ); ! 341: break; ! 342: } ! 343: case UGT: ! 344: case ULE: ! 345: if( p->in.right->in.op == ICON && p->in.right->tn.lval <= 0 && !ISUNSIGNED(p->in.right->in.type) && p->in.right->tn.rval == NONAME ){ ! 346: werror( "degenerate unsigned comparison" ); ! 347: } ! 348: break; ! 349: ! 350: case COMOP: ! 351: down1 = EFF; ! 352: ! 353: case ANDAND: ! 354: case OROR: ! 355: case QUEST: ! 356: down2 = down; ! 357: /* go recursively left, then right */ ! 358: np1 = lnp; ! 359: lprt( p->in.left, down1, use1 ); ! 360: np2 = lnp; ! 361: lprt( p->in.right, down2, use2 ); ! 362: lmerge( np1, np2, 0 ); ! 363: return; ! 364: ! 365: case SCONV: ! 366: case PCONV: ! 367: case COLON: ! 368: down1 = down2 = down; ! 369: break; ! 370: ! 371: case CALL: ! 372: case STCALL: ! 373: case FORTCALL: ! 374: acount = ctargs( p->in.right ); ! 375: case UNARY CALL: ! 376: case UNARY STCALL: ! 377: case UNARY FORTCALL: ! 378: if( p->in.left->in.op == ICON && (id=p->in.left->tn.rval) != NONAME ){ /* used to be &name */ ! 379: struct symtab *sp = &stab[id]; ! 380: int lty; ! 381: /* if a function used in an effects context is ! 382: * cast to type void then consider its value ! 383: * to have been disposed of properly ! 384: * thus a call of type undef in an effects ! 385: * context is construed to be used in a value ! 386: * context ! 387: */ ! 388: if ((down == EFF) && (p->in.type != UNDEF)) { ! 389: lty = LUE; ! 390: } else if (down == EFF) { ! 391: lty = LUV | LUE; ! 392: } else { ! 393: lty = LUV; ! 394: } ! 395: fsave( ftitle ); ! 396: outdef(sp, lty, acount); ! 397: if( acount ) { ! 398: lpta( p->in.right ); ! 399: } ! 400: } ! 401: break; ! 402: ! 403: case ICON: ! 404: /* look for &name case */ ! 405: if( (id = p->tn.rval) >= 0 && id != NONAME ){ ! 406: q = &stab[id]; ! 407: q->sflags |= (SREF|SSET); ! 408: q->suse = -lineno; ! 409: } ! 410: return; ! 411: ! 412: case NAME: ! 413: if( (id = p->tn.rval) >= 0 && id != NONAME ){ ! 414: q = &stab[id]; ! 415: if( (uses&VALUSED) && !(q->sflags&SSET) ){ ! 416: if( q->sclass == AUTO || q->sclass == REGISTER ){ ! 417: if( !ISARY(q->stype ) && !ISFTN(q->stype) && q->stype!=STRTY ){ ! 418: #ifndef FLEXNAMES ! 419: werror( "%.8s may be used before set", q->sname ); ! 420: #else ! 421: werror( "%s may be used before set", q->sname ); ! 422: #endif ! 423: q->sflags |= SSET; ! 424: } ! 425: } ! 426: } ! 427: if( uses & VALASGOP ) break; /* not a real use */ ! 428: if( uses & VALSET ) q->sflags |= SSET; ! 429: if( uses & VALUSED ) q->sflags |= SREF; ! 430: if( uses & VALADDR ) q->sflags |= (SREF|SSET); ! 431: if( p->tn.lval == 0 ){ ! 432: lnp->lid = id; ! 433: lnp->flgs = (uses&VALADDR)?0:((uses&VALSET)?VALSET:VALUSED); ! 434: if( ++lnp >= &lnames[LNAMES] ) --lnp; ! 435: } ! 436: } ! 437: return; ! 438: ! 439: } ! 440: ! 441: /* recurse, going down the right side first if we can */ ! 442: ! 443: switch( optype(p->in.op) ){ ! 444: ! 445: case BITYPE: ! 446: np1 = lnp; ! 447: lprt( p->in.right, down2, use2 ); ! 448: case UTYPE: ! 449: np2 = lnp; ! 450: lprt( p->in.left, down1, use1 ); ! 451: } ! 452: ! 453: if( optype(p->in.op) == BITYPE ){ ! 454: if( p->in.op == ASSIGN && p->in.left->in.op == NAME ){ /* special case for a = .. a .. */ ! 455: lmerge( np1, np2, 0 ); ! 456: } ! 457: else lmerge( np1, np2, p->in.op != COLON ); ! 458: /* look for assignments to fields, and complain */ ! 459: if( p->in.op == ASSIGN && p->in.left->in.op == FLD && p->in.right->in.op == ICON ) fldcon( p ); ! 460: } ! 461: ! 462: } ! 463: ! 464: lmerge( np1, np2, flag ) struct lnm *np1, *np2; { ! 465: /* np1 and np2 point to lists of lnm members, for the two sides ! 466: * of a binary operator ! 467: * flag is 1 if commutation is possible, 0 otherwise ! 468: * lmerge returns a merged list, starting at np1, resetting lnp ! 469: * it also complains, if appropriate, about side effects ! 470: */ ! 471: ! 472: register struct lnm *npx, *npy; ! 473: ! 474: for( npx = np2; npx < lnp; ++npx ){ ! 475: ! 476: /* is it already there? */ ! 477: for( npy = np1; npy < np2; ++npy ){ ! 478: if( npx->lid == npy->lid ){ /* yes */ ! 479: if( npx->flgs == 0 || npx->flgs == (VALSET|VALUSED) ) ! 480: ; /* do nothing */ ! 481: else if( (npx->flgs|npy->flgs)== (VALSET|VALUSED) || ! 482: (npx->flgs&npy->flgs&VALSET) ){ ! 483: #ifndef FLEXNAMES ! 484: if( flag ) werror( "%.8s evaluation order undefined", stab[npy->lid].sname ); ! 485: #else ! 486: if( flag ) werror( "%s evaluation order undefined", stab[npy->lid].sname ); ! 487: #endif ! 488: } ! 489: if( npy->flgs == 0 ) npx->flgs = 0; ! 490: else npy->flgs |= npx->flgs; ! 491: goto foundit; ! 492: } ! 493: } ! 494: ! 495: /* not there: update entry */ ! 496: np2->lid = npx->lid; ! 497: np2->flgs = npx->flgs; ! 498: ++np2; ! 499: ! 500: foundit: ; ! 501: } ! 502: ! 503: /* all finished: merged list is at np1 */ ! 504: lnp = np2; ! 505: } ! 506: ! 507: efcode(){ ! 508: /* code for the end of a function */ ! 509: register struct symtab *cfp; ! 510: ! 511: cfp = &stab[curftn]; ! 512: if( retstat & RETVAL ) outdef( cfp, LRV, DECTY ); ! 513: if( !vflag ){ ! 514: vflag = argflag; ! 515: argflag = 0; ! 516: } ! 517: if( retstat == RETVAL+NRETVAL ) ! 518: #ifndef FLEXNAMES ! 519: werror( "function %.8s has return(e); and return;", cfp->sname); ! 520: #else ! 521: werror( "function %s has return(e); and return;", cfp->sname); ! 522: #endif ! 523: } ! 524: ! 525: aocode(p) struct symtab *p; { ! 526: /* called when automatic p removed from stab */ ! 527: register struct symtab *cfs; ! 528: cfs = &stab[curftn]; ! 529: if(p->suse>0 && !(p->sflags&(SMOS|STAG)) ){ ! 530: if( p->sclass == PARAM ){ ! 531: #ifndef FLEXNAMES ! 532: if( vflag ) werror( "argument %.8s unused in function %.8s", ! 533: #else ! 534: if( vflag ) werror( "argument %s unused in function %s", ! 535: #endif ! 536: p->sname, ! 537: cfs->sname ); ! 538: } ! 539: else { ! 540: #ifndef FLEXNAMES ! 541: if( p->sclass != TYPEDEF ) werror( "%.8s unused in function %.8s", ! 542: #else ! 543: if( p->sclass != TYPEDEF ) werror( "%s unused in function %s", ! 544: #endif ! 545: p->sname, cfs->sname ); ! 546: } ! 547: } ! 548: ! 549: if( p->suse < 0 && (p->sflags & (SSET|SREF|SMOS)) == SSET && ! 550: !ISARY(p->stype) && !ISFTN(p->stype) ){ ! 551: ! 552: #ifndef FLEXNAMES ! 553: werror( "%.8s set but not used in function %.8s", p->sname, cfs->sname ); ! 554: #else ! 555: werror( "%s set but not used in function %s", p->sname, cfs->sname ); ! 556: #endif ! 557: } ! 558: ! 559: if( p->stype == STRTY || p->stype == UNIONTY || p->stype == ENUMTY ){ ! 560: #ifndef FLEXNAMES ! 561: if( dimtab[p->sizoff+1] < 0 ) werror( "structure %.8s never defined", p->sname ); ! 562: #else ! 563: if( dimtab[p->sizoff+1] < 0 ) werror( "structure %s never defined", p->sname ); ! 564: #endif ! 565: } ! 566: ! 567: } ! 568: ! 569: defnam( p ) register struct symtab *p; { ! 570: /* define the current location as the name p->sname */ ! 571: ! 572: if( p->sclass == STATIC && p->slevel>1 ) return; ! 573: ! 574: if( !ISFTN( p->stype ) ) outdef( p, libflag?LIB:LDI, USUAL ); ! 575: } ! 576: ! 577: zecode( n ){ ! 578: /* n integer words of zeros */ ! 579: OFFSZ temp; ! 580: temp = n; ! 581: inoff += temp*SZINT; ! 582: ; ! 583: } ! 584: ! 585: andable( p ) NODE *p; { /* p is a NAME node; can it accept & ? */ ! 586: register r; ! 587: ! 588: if( p->in.op != NAME ) cerror( "andable error" ); ! 589: ! 590: if( (r = p->tn.rval) < 0 ) return(1); /* labels are andable */ ! 591: ! 592: if( stab[r].sclass == AUTO || stab[r].sclass == PARAM ) return(0); ! 593: #ifndef FLEXNAMES ! 594: if( stab[r].sclass == REGISTER ) uerror( "can't take & of %.8s", stab[r].sname ); ! 595: #else ! 596: if( stab[r].sclass == REGISTER ) uerror( "can't take & of %s", stab[r].sname ); ! 597: #endif ! 598: return(1); ! 599: } ! 600: ! 601: NODE * ! 602: clocal(p) NODE *p; { ! 603: ! 604: /* this is called to do local transformations on ! 605: an expression tree preparitory to its being ! 606: written out in intermediate code. ! 607: */ ! 608: ! 609: /* the major essential job is rewriting the ! 610: automatic variables and arguments in terms of ! 611: REG and OREG nodes */ ! 612: /* conversion ops which are not necessary are also clobbered here */ ! 613: /* in addition, any special features (such as rewriting ! 614: exclusive or) are easily handled here as well */ ! 615: ! 616: register o; ! 617: register unsigned t, tl; ! 618: ! 619: switch( o = p->in.op ){ ! 620: ! 621: case SCONV: ! 622: case PCONV: ! 623: if( p->in.left->in.type==ENUMTY ){ ! 624: p->in.left = pconvert( p->in.left ); ! 625: } ! 626: /* assume conversion takes place; type is inherited */ ! 627: t = p->in.type; ! 628: tl = p->in.left->in.type; ! 629: if( aflag && (tl==LONG||tl==ULONG) && (t!=LONG&&t!=ULONG) ){ ! 630: werror( "long assignment may lose accuracy" ); ! 631: } ! 632: if( aflag>=2 && (tl!=LONG&&tl!=ULONG) && (t==LONG||t==ULONG) && p->in.left->in.op != ICON ){ ! 633: werror( "assignment to long may sign-extend incorrectly" ); ! 634: } ! 635: if( ISPTR(tl) && ISPTR(t) ){ ! 636: tl = DECREF(tl); ! 637: t = DECREF(t); ! 638: switch( ISFTN(t) + ISFTN(tl) ){ ! 639: ! 640: case 0: /* neither is a function pointer */ ! 641: if( talign(t,p->fn.csiz) > talign(tl,p->in.left->fn.csiz) ){ ! 642: if( hflag||pflag ) werror( "possible pointer alignment problem" ); ! 643: } ! 644: break; ! 645: ! 646: case 1: ! 647: werror( "questionable conversion of function pointer" ); ! 648: ! 649: case 2: ! 650: ; ! 651: } ! 652: } ! 653: p->in.left->in.type = p->in.type; ! 654: p->in.left->fn.cdim = p->fn.cdim; ! 655: p->in.left->fn.csiz = p->fn.csiz; ! 656: p->in.op = FREE; ! 657: return( p->in.left ); ! 658: ! 659: case PVCONV: ! 660: case PMCONV: ! 661: if( p->in.right->in.op != ICON ) cerror( "bad conversion"); ! 662: p->in.op = FREE; ! 663: return( buildtree( o==PMCONV?MUL:DIV, p->in.left, p->in.right ) ); ! 664: ! 665: } ! 666: ! 667: return(p); ! 668: } ! 669: ! 670: NODE * ! 671: offcon( off, t, d, s ) OFFSZ off; TWORD t;{ /* make a structure offset node */ ! 672: register NODE *p; ! 673: p = bcon(0); ! 674: p->tn.lval = off/SZCHAR; ! 675: return(p); ! 676: } ! 677: ! 678: noinit(){ ! 679: /* storage class for such as "int a;" */ ! 680: return( pflag ? EXTDEF : EXTERN ); ! 681: } ! 682: ! 683: ! 684: cinit( p, sz ) NODE *p; { /* initialize p into size sz */ ! 685: inoff += sz; ! 686: if( p->in.op == INIT ){ ! 687: if( p->in.left->in.op == ICON ) return; ! 688: if( p->in.left->in.op == NAME && p->in.left->in.type == MOE ) return; ! 689: } ! 690: uerror( "illegal initialization" ); ! 691: } ! 692: ! 693: char * ! 694: exname( p ) char *p; { ! 695: /* make a name look like an external name in the local machine */ ! 696: static char aa[8]; ! 697: register int i; ! 698: ! 699: if( !pflag ) return(p); ! 700: for( i=0; i<6; ++i ){ ! 701: if( isupper(*p ) ) aa[i] = tolower( *p ); ! 702: else aa[i] = *p; ! 703: if( *p ) ++p; ! 704: } ! 705: aa[6] = '\0'; ! 706: return( aa ); ! 707: } ! 708: ! 709: char * ! 710: strip(s) char *s; { ! 711: #ifndef FLEXNAMES ! 712: static char x[LFNM+1]; ! 713: #else ! 714: static char x[BUFSIZ]; ! 715: #endif ! 716: register char *p; ! 717: ! 718: for( p=x; *s; ++s ){ ! 719: if( *s == '/' ) p=x; ! 720: else if( *s != '"' ){ ! 721: #ifndef FLEXNAMES ! 722: /* PATCHED by ROBERT HENRY on 8Jul80 to fix 14 character file name bug */ ! 723: if( p >= &x[LFNM] ) ! 724: cerror( "filename too long" ); ! 725: #endif ! 726: *p++ = *s; ! 727: } ! 728: } ! 729: *p = '\0'; ! 730: #ifndef FLEXNAMES ! 731: return( x ); ! 732: #else ! 733: return( hash(x) ); ! 734: #endif ! 735: } ! 736: ! 737: fsave( s ) char *s; { ! 738: static union rec fsname; ! 739: s = strip( s ); ! 740: #ifndef FLEXNAMES ! 741: if( strncmp( s, fsname.f.fn, LFNM ) ){ ! 742: #else ! 743: if( strcmp(s, fsname.f.fn)) { ! 744: #endif ! 745: /* new one */ ! 746: #ifndef FLEXNAMES ! 747: strncpy( fsname.f.fn, s, LFNM ); ! 748: #else ! 749: fsname.f.fn = s; ! 750: #endif ! 751: fsname.f.decflag = LFN; ! 752: fwrite( (char *)&fsname, sizeof(fsname), 1, stdout ); ! 753: #ifdef FLEXNAMES ! 754: fwrite( fsname.f.fn, strlen(fsname.f.fn)+1, 1, stdout ); ! 755: #endif ! 756: } ! 757: } ! 758: ! 759: where(f){ /* print true location of error */ ! 760: if( f == 'u' && nerrors>1 ) --nerrors; /* don't get "too many errors" */ ! 761: fprintf( stderr, "%s(%d): ", (f == 'c') ? ftitle : strip(ftitle), lineno ); ! 762: } ! 763: ! 764: /* a number of dummy routines, unneeded by lint */ ! 765: ! 766: branch(n){;} ! 767: defalign(n){;} ! 768: deflab(n){;} ! 769: bycode(t,i){;} ! 770: cisreg(t) TWORD t; {return(1);} /* everyting is a register variable! */ ! 771: ! 772: fldty(p) struct symtab *p; { ! 773: ; /* all types are OK here... */ ! 774: } ! 775: ! 776: fldal(t) unsigned t; { /* field alignment... */ ! 777: if( t == ENUMTY ) return( ALCHAR ); /* this should be thought through better... */ ! 778: if( ISPTR(t) ){ /* really for the benefit of honeywell (and someday IBM) */ ! 779: if( pflag ) uerror( "nonportable field type" ); ! 780: } ! 781: else uerror( "illegal field type" ); ! 782: return(ALINT); ! 783: } ! 784: ! 785: main( argc, argv ) char *argv[]; { ! 786: char *p; ! 787: ! 788: /* handle options */ ! 789: ! 790: for( p=argv[1]; argc>1 && *p; ++p ){ ! 791: ! 792: switch( *p ){ ! 793: ! 794: case '-': ! 795: continue; ! 796: ! 797: case '\0': ! 798: break; ! 799: ! 800: case 'b': ! 801: brkflag = 1; ! 802: continue; ! 803: ! 804: case 'p': ! 805: pflag = 1; ! 806: continue; ! 807: ! 808: case 'c': ! 809: cflag = 1; ! 810: continue; ! 811: ! 812: case 's': ! 813: /* for the moment, -s triggers -h */ ! 814: ! 815: case 'h': ! 816: hflag = 1; ! 817: continue; ! 818: ! 819: case 'L': ! 820: libflag = 1; ! 821: case 'v': ! 822: vflag = 0; ! 823: continue; ! 824: ! 825: case 'x': ! 826: xflag = 1; ! 827: continue; ! 828: ! 829: case 'a': ! 830: ++aflag; ! 831: case 'u': /* done in second pass */ ! 832: case 'n': /* done in shell script */ ! 833: continue; ! 834: ! 835: case 't': ! 836: werror( "option %c now default: see `man 6 lint'", *p ); ! 837: continue; ! 838: ! 839: default: ! 840: uerror( "illegal option: %c", *p ); ! 841: continue; ! 842: ! 843: } ! 844: } ! 845: ! 846: if( !pflag ){ /* set sizes to sizes of target machine */ ! 847: # ifdef gcos ! 848: SZCHAR = ALCHAR = 9; ! 849: # else ! 850: SZCHAR = ALCHAR = 8; ! 851: # endif ! 852: SZINT = ALINT = sizeof(int)*SZCHAR; ! 853: SZFLOAT = ALFLOAT = sizeof(float)*SZCHAR; ! 854: SZDOUBLE = ALDOUBLE = sizeof(double)*SZCHAR; ! 855: SZLONG = ALLONG = sizeof(long)*SZCHAR; ! 856: SZSHORT = ALSHORT = sizeof(short)*SZCHAR; ! 857: SZPOINT = ALPOINT = sizeof(int *)*SZCHAR; ! 858: ALSTRUCT = ALINT; ! 859: /* now, fix some things up for various machines (I wish we had "alignof") */ ! 860: ! 861: # ifdef pdp11 ! 862: ALLONG = ALDOUBLE = ALFLOAT = ALINT; ! 863: #endif ! 864: # ifdef ibm ! 865: ALSTRUCT = ALCHAR; ! 866: #endif ! 867: } ! 868: ! 869: return( mainp1( argc, argv ) ); ! 870: } ! 871: ! 872: ctype( type ) unsigned type; { /* are there any funny types? */ ! 873: return( type ); ! 874: } ! 875: ! 876: commdec( i ){ ! 877: /* put out a common declaration */ ! 878: outdef( &stab[i], libflag?LIB:LDC, USUAL ); ! 879: } ! 880: ! 881: isitfloat ( s ) char *s; { ! 882: /* s is a character string; ! 883: if floating point is implemented, set dcon to the value of s */ ! 884: /* lint version ! 885: */ ! 886: dcon = atof( s ); ! 887: return( FCON ); ! 888: } ! 889: ! 890: fldcon( p ) register NODE *p; { ! 891: /* p is an assignment of a constant to a field */ ! 892: /* check to see if the assignment is going to overflow, or otherwise cause trouble */ ! 893: register s; ! 894: CONSZ v; ! 895: ! 896: if( !hflag & !pflag ) return; ! 897: ! 898: s = UPKFSZ(p->in.left->tn.rval); ! 899: v = p->in.right->tn.lval; ! 900: ! 901: switch( p->in.left->in.type ){ ! 902: ! 903: case CHAR: ! 904: case INT: ! 905: case SHORT: ! 906: case LONG: ! 907: case ENUMTY: ! 908: if( v>=0 && (v>>(s-1))==0 ) return; ! 909: werror( "precision lost in assignment to (possibly sign-extended) field" ); ! 910: default: ! 911: return; ! 912: ! 913: case UNSIGNED: ! 914: case UCHAR: ! 915: case USHORT: ! 916: case ULONG: ! 917: if( v<0 || (v>>s)!=0 ) werror( "precision lost in field assignment" ); ! 918: ! 919: return; ! 920: } ! 921: ! 922: } ! 923: ! 924: outdef( p, lty, mode ) struct symtab *p; { ! 925: /* output a definition for the second pass */ ! 926: /* if mode is > USUAL, it is the number of args */ ! 927: char *fname; ! 928: TWORD t; ! 929: int line; ! 930: static union rec rc; ! 931: ! 932: if( mode == NOFILE ){ ! 933: fname = "???"; ! 934: line = p->suse; ! 935: } ! 936: else if( mode == SVLINE ){ ! 937: fname = ftitle; ! 938: line = -p->suse; ! 939: } ! 940: else { ! 941: fname = ftitle; ! 942: line = lineno; ! 943: } ! 944: fsave( fname ); ! 945: #ifndef FLEXNAMES ! 946: strncpy( rc.l.name, exname(p->sname), LCHNM ); ! 947: #endif ! 948: rc.l.decflag = lty; ! 949: t = p->stype; ! 950: if( mode == DECTY ) t = DECREF(t); ! 951: rc.l.type.aty = t; ! 952: rc.l.type.extra = 0; ! 953: astype( &rc.l.type, p->sizoff ); ! 954: rc.l.nargs = (mode>USUAL) ? mode : 0; ! 955: rc.l.fline = line; ! 956: fwrite( (char *)&rc, sizeof(rc), 1, stdout ); ! 957: #ifdef FLEXNAMES ! 958: rc.l.name = exname(p->sname); ! 959: fwrite( rc.l.name, strlen(rc.l.name)+1, 1, stdout ); ! 960: #endif ! 961: } ! 962: int proflg; ! 963: int gdebug;
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.