|
|
1.1 ! root 1: /* C compiler: expression parsing */ ! 2: ! 3: #include "c.h" ! 4: ! 5: static char prec[] = { ! 6: #define xx(a,b,c,d,e,f,g) c, ! 7: #include "token.h" ! 8: }; ! 9: static int oper[] = { ! 10: #define xx(a,b,c,d,e,f,g) d, ! 11: #include "token.h" ! 12: }; ! 13: dclproto(static Tree call,(Tree, Type, Coordinate)); ! 14: dclproto(static Tree expr2,(void)); ! 15: dclproto(static Tree expr3,(int)); ! 16: dclproto(static Tree nullcheck,(Tree)); ! 17: dclproto(static Tree postfix,(Tree)); ! 18: dclproto(static Tree prefix,(void)); ! 19: dclproto(static Tree primary,(void)); ! 20: dclproto(static Tree rightkid,(Tree)); ! 21: dclproto(static Tree value,(Tree)); ! 22: ! 23: /* addrof - address of p */ ! 24: Tree addrof(p) Tree p; { ! 25: Tree q = p; ! 26: ! 27: for (;;) ! 28: switch (generic(q->op)) { ! 29: case RIGHT: ! 30: assert(q->kids[0] || q->kids[1]); ! 31: q = q->kids[1] ? q->kids[1] : q->kids[0]; ! 32: continue; ! 33: case ASGN: ! 34: q = q->kids[1]; ! 35: continue; ! 36: case COND: { ! 37: Symbol t1 = q->u.sym; ! 38: q->u.sym = 0; ! 39: q = idnode(t1); ! 40: /* fall thru */ ! 41: } ! 42: case INDIR: ! 43: if (p == q) ! 44: return q->kids[0]; ! 45: q = q->kids[0]; ! 46: return tree(RIGHT, q->type, root(p), q); ! 47: default: ! 48: error("addressable object required\n"); ! 49: return value(p); ! 50: } ! 51: } ! 52: ! 53: /* asgn - generate tree for assignment of expr e to symbol p sans qualifiers */ ! 54: Tree asgn(p, e) Symbol p; Tree e; { ! 55: if (isarray(p->type)) ! 56: e = tree(ASGN+B, p->type, idnode(p), ! 57: tree(INDIR+B, e->type, e, 0)); ! 58: else { ! 59: Type ty = p->type; ! 60: p->type = unqual(p->type); ! 61: if (isstruct(p->type) && p->type->u.sym->u.s.cfields) { ! 62: p->type->u.sym->u.s.cfields = 0; ! 63: e = asgnnode(ASGN, idnode(p), e); ! 64: p->type->u.sym->u.s.cfields = 1; ! 65: } else ! 66: e = asgnnode(ASGN, idnode(p), e); ! 67: p->type = ty; ! 68: } ! 69: return e; ! 70: } ! 71: ! 72: /* assign - perform type-checking of assignment of p to variable of type xty */ ! 73: Type assign(xty, p) Type xty; Tree p; { ! 74: Type yty = unqual(p->type); ! 75: ! 76: if (yty->size == 0) ! 77: return 0; ! 78: xty = unqual(xty); ! 79: if (isenum(xty)) ! 80: xty = xty->type; ! 81: if (isarith(xty) && isarith(yty)) ! 82: return xty; ! 83: if (isstruct(xty) && xty == yty) ! 84: return xty; ! 85: if (isstruct(xty) && isstruct(yty) && extends(yty, xty)) ! 86: return xty; ! 87: if (isptr(xty) && isptr(yty)) { ! 88: Type lty = xty->type, rty = yty->type; ! 89: if (isstruct(lty) && isstruct(rty) && extends(rty, lty)) ! 90: return xty; ! 91: if (eqtype(lty, rty, 1) ! 92: || (eqtype(unqual(lty), unqual(rty), 1) ! 93: && ( !isconst(rty) || isconst(lty)) ! 94: && (!isvolatile(rty) || isvolatile(lty)))) ! 95: return yty; ! 96: if (xty == voidptype || unqual(lty) == voidtype ! 97: || yty == voidptype || unqual(rty) == voidtype) ! 98: return xty; ! 99: if (lty == inttype && isenum(rty) || rty == inttype && isenum(lty)) { ! 100: if (Aflag >= 1) ! 101: warning("assignment between `%t' and `%t' is compiler-dependent\n", ! 102: xty, yty); ! 103: return xty; ! 104: } ! 105: } ! 106: if (isptr(xty) && isint(p->type) && generic(p->op) == CNST ! 107: && cast(p, unsignedtype)->u.v.u == 0) ! 108: return xty; ! 109: return 0; ! 110: } ! 111: ! 112: /* call - parse function call to f, type fty */ ! 113: static Tree call(f, fty, src) Tree f; Type fty; Coordinate src; { ! 114: int n = 0; ! 115: Tree args = 0, r = 0; ! 116: Type *proto = fty->u.f.oldstyle ? (Type *)0 : fty->u.f.proto; ! 117: ! 118: if (hascall(f)) ! 119: r = f; ! 120: if (t != ')') ! 121: do { ! 122: Tree q = pointer(expr1(0)); ! 123: if (proto && *proto && *proto != voidtype) { ! 124: Type aty; ! 125: q = value(q); ! 126: if (aty = assign(*proto, q)) { ! 127: q = cast(q, aty); ! 128: if ((isint(q->type) || isenum(q->type)) ! 129: && q->type->size != inttype->size) ! 130: q = cast(q, promote(q->type)); ! 131: } else ! 132: error("type error in argument %d to %s; found `%t' expected `%t'\n", ! 133: n + 1, funcname(f), q->type, *proto); ! 134: proto++; ! 135: } else { ! 136: if (!fty->u.f.oldstyle && *proto == 0) ! 137: error("too many arguments to %s\n", funcname(f)); ! 138: q = value(q); ! 139: if (q->type == floattype) ! 140: q = cast(q, doubletype); ! 141: else if ((isint(q->type) || isenum(q->type)) ! 142: && q->type->size != inttype->size) ! 143: q = cast(q, promote(q->type)); ! 144: else if (isarray(q->type) || q->type->size == 0) ! 145: error("type error in argument %d to %s; `%t' is illegal\n", ! 146: n + 1, funcname(f), q->type); ! 147: } ! 148: if (IR->no_argb && isstruct(q->type)) { ! 149: Symbol t1; ! 150: if (q->op == RIGHT && q->kids[0] ! 151: && q->kids[0]->op == CALL+B) { ! 152: /* ! 153: * When the argument is f() where f ! 154: * returns a struct, simply use the ! 155: * temporary generated to hold f's ! 156: * return value. ! 157: */ ! 158: assert(q->kids[0]->kids[1]); ! 159: t1 = q->kids[0]->kids[1]->u.sym; ! 160: q = q->kids[0]; ! 161: } else { ! 162: t1 = temporary(AUTO, unqual(q->type)); ! 163: q = asgn(t1, q); ! 164: } ! 165: q = tree(RIGHT, ptr(q->type), root(q), lvalue(idnode(t1))); ! 166: } ! 167: if (q->type->size == 0) ! 168: q->type = inttype; ! 169: if (hascall(q)) ! 170: r = tree(RIGHT, voidtype, r, q); ! 171: args = tree(ARG + widen(q->type), q->type, q, args); ! 172: n++; ! 173: if (Aflag >= 2 && n == 32) ! 174: warning("more than 31 arguments in a call to %s\n", funcname(f)); ! 175: } while (t == ',' && (t = gettok())); ! 176: expect(')'); ! 177: if (proto && *proto && *proto != voidtype) ! 178: error("insufficient number of arguments to %s\n", funcname(f)); ! 179: if (r) ! 180: args = tree(RIGHT, voidtype, r, args); ! 181: if (events.calls) ! 182: apply(events.calls, (Generic)&src, (Generic)&f); ! 183: return callnode(f, freturn(fty), args); ! 184: } ! 185: ! 186: /* cast - cast expression p to type */ ! 187: Tree cast(p, type) Tree p; Type type; { ! 188: Field q; ! 189: Type pty, ty = unqual(type); ! 190: ! 191: p = value(p); ! 192: if (p->type == type) ! 193: return p; ! 194: pty = unqual(p->type); ! 195: if (pty == ty) ! 196: return retype(p, type); ! 197: if (pty == signedchar || pty == chartype) ! 198: p = simplify(CVC, inttype, p, 0); ! 199: else if (pty == shorttype) ! 200: p = simplify(CVS, inttype, p, 0); ! 201: else if (pty == longtype) ! 202: p = retype(p, inttype); ! 203: else if (pty == floattype) ! 204: p = simplify(CVF, doubletype, p, 0); ! 205: else if (pty == longdouble) ! 206: p = retype(p, doubletype); ! 207: else if (pty == unsignedchar) ! 208: p = simplify(CVC, unsignedtype, p, 0); ! 209: else if (pty == unsignedshort) ! 210: p = simplify(CVS, unsignedtype, p, 0); ! 211: else if (pty == unsignedlong) ! 212: p = retype(p, unsignedtype); ! 213: else if (isptr(pty)) { ! 214: if (isstruct(pty->type) && isptr(ty) && isstruct(ty->type) ! 215: && (q = extends(pty->type, ty->type))) ! 216: return simplify(ADD+P, ty, p, constnode(q->offset, inttype)); ! 217: if (isptr(ty)) { ! 218: if (isfunc(pty->type) && !isfunc(ty->type) ! 219: || !isfunc(pty->type) && isfunc(ty->type)) ! 220: warning("conversion from `%t' to `%t' is compiler-dependent\n", ! 221: p->type, ty); ! 222: return retype(p, type); ! 223: } ! 224: p = simplify(CVP, unsignedtype, p, 0); ! 225: } ! 226: else if (isstruct(pty) && isstruct(ty) && (q = extends(pty, ty))) ! 227: return rvalue(simplify(ADD+P, ptr(ty), addrof(p), ! 228: constnode(q->offset, inttype))); ! 229: pty = unqual(p->type); ! 230: if (pty == inttype || isenum(pty)) { ! 231: if (ty == floattype || ty == doubletype || ty == longdouble) ! 232: p = simplify(CVI, doubletype, p, 0); ! 233: else if (ty == unsignedtype || ty == unsignedchar ! 234: || ty == unsignedshort || ty == unsignedlong || isptr(ty)) ! 235: p = simplify(CVI, unsignedtype, p, 0); ! 236: } else if (pty == doubletype) { ! 237: if (ty == signedchar || ty == chartype || isenum(ty) ! 238: || ty == shorttype || ty == inttype || ty == longtype) ! 239: p = simplify(CVD, inttype, p, 0); ! 240: else if (ty == unsignedtype || ty == unsignedchar ! 241: || ty == unsignedshort || ty == unsignedlong || isptr(ty)) { ! 242: /* ! 243: * For (unsigned)d for double d, build ! 244: * d >= INT_MAX+1 ? (unsigned)(int)(d-(INT_MAX+1)) + INT_MAX+1 : ! 245: * (unsigned)(int)d ! 246: */ ! 247: Tree c = tree(CNST+D, doubletype, 0, 0); ! 248: c->u.v.d = (double)INT_MAX + 1; ! 249: p = condnode( ! 250: simplify(GE, doubletype, p, c), ! 251: (*opnode['+'])(ADD, ! 252: cast(cast(simplify(SUB, doubletype, p, c), inttype), unsignedtype), ! 253: constnode((unsigned)INT_MAX + 1, unsignedtype)), ! 254: simplify(CVD, inttype, p, 0)); ! 255: } ! 256: } else if (pty == unsignedtype) { ! 257: if (ty == signedchar || ty == chartype || isenum(ty) ! 258: || ty == shorttype || ty == inttype || ty == longtype) ! 259: p = simplify(CVU, inttype, p, 0); ! 260: else if (ty == floattype || ty == doubletype || ty == longdouble) { ! 261: /* ! 262: * For (double)u for unsigned u, build ! 263: * (int)u >= 0 ? (double)(int)u : (double)(int)u + UINT_MAX + 1 ! 264: */ ! 265: Tree u = simplify(CVU, inttype, p, 0); ! 266: p = tree(CNST+D, doubletype, 0, 0); ! 267: p->u.v.d = utod(UINT_MAX) + 1; ! 268: p = condnode( ! 269: simplify(GE, inttype, u, constnode(0, inttype)), ! 270: simplify(CVI, doubletype, u, 0), ! 271: (*opnode['+'])(ADD, simplify(CVI, doubletype, u, 0), p)); ! 272: } ! 273: } else ! 274: assert(0); ! 275: if (ty == signedchar || ty == chartype || ty == shorttype) ! 276: p = simplify(CVI, type, p, 0); ! 277: else if (ty == floattype) ! 278: p = simplify(CVD, type, p, 0); ! 279: else if (ty == unsignedchar || ty == unsignedshort || isptr(ty)) ! 280: p = simplify(CVU, type, p, 0); ! 281: else ! 282: p = retype(p, type); ! 283: return p; ! 284: } ! 285: ! 286: /* cond - check for conditional operator, add comparison if necessary */ ! 287: Tree cond(p) Tree p; { ! 288: Opcode op = generic(rightkid(p)->op); ! 289: ! 290: if (op == AND || op == OR || op == NOT || op == EQ || op == NE ! 291: || op == LE || op == LT || op == GE || op == GT) ! 292: return p; ! 293: p = pointer(p); ! 294: p = cast(p, promote(p->type)); ! 295: return (*opnode[NEQ])(NE, p, constnode(0, inttype)); ! 296: } ! 297: ! 298: /* conditional - parse expression and cast to conditional */ ! 299: Tree conditional(tok) { ! 300: Tree p = expr(tok); ! 301: ! 302: if (Aflag > 1 && isfunc(p->type)) ! 303: warning("%s used in a conditional expression\n", funcname(p)); ! 304: return cond(p); ! 305: } ! 306: ! 307: /* constexpr - parse a constant expression */ ! 308: Tree constexpr(tok) { ! 309: Tree p; ! 310: ! 311: needconst++; ! 312: p = expr1(tok); ! 313: needconst--; ! 314: return p; ! 315: } ! 316: ! 317: /* expr0 - parse an expression for side effect */ ! 318: Tree expr0(tok) { ! 319: return root(expr(tok)); ! 320: } ! 321: ! 322: /* expr - parse an expression */ ! 323: Tree expr(tok) { ! 324: Tree p = expr1(0); ! 325: ! 326: while (t == ',') { ! 327: Tree q; ! 328: t = gettok(); ! 329: q = pointer(expr1(0)); ! 330: if (generic(p->op) != CNST) ! 331: p = root(value(p)); ! 332: p = tree(RIGHT, q->type, p, q); ! 333: } ! 334: if (tok && t == tok) ! 335: t = gettok(); ! 336: else if (tok) { ! 337: static char follow[] = { IF, ID, '}', 0 }; ! 338: test(tok, follow); ! 339: } ! 340: return p; ! 341: } ! 342: ! 343: /* expr1 - parse assignments */ ! 344: Tree expr1(tok) { ! 345: Tree p = expr2(); ! 346: ! 347: while (t == '=' || (prec[t] >= 6 && prec[t] <= 8) ! 348: || (prec[t] >= 11 && prec[t] <= 13)) { ! 349: Opcode op = t; ! 350: t = gettok(); ! 351: if (oper[op] == ASGN) ! 352: p = asgnnode(ASGN, p, value(expr1(0))); ! 353: else { ! 354: expect('='); ! 355: p = incr(op, p, expr1(0)); ! 356: } ! 357: } ! 358: if (tok && t == tok) ! 359: t = gettok(); ! 360: else if (tok) { ! 361: static char follow[] = { IF, ID, 0 }; ! 362: test(tok, follow); ! 363: } ! 364: return p; ! 365: } ! 366: ! 367: /* expr2 - parse conditional expressions */ ! 368: static Tree expr2() { ! 369: Tree p = expr3(4); ! 370: ! 371: if (t == '?') { ! 372: Tree l, r; ! 373: if (Aflag > 1 && isfunc(p->type)) ! 374: warning("%s used in a conditional expression\n", funcname(p)); ! 375: p = pointer(p); ! 376: t = gettok(); ! 377: if (events.points) { ! 378: Tree e = 0; ! 379: apply(events.points, (Generic)&src, (Generic)&e); ! 380: l = right(e, pointer(expr(':'))); ! 381: e = 0; ! 382: apply(events.points, (Generic)&src, (Generic)&e); ! 383: r = right(e, pointer(expr2())); ! 384: } else { ! 385: l = pointer(expr(':')); ! 386: r = pointer(expr2()); ! 387: } ! 388: p = condnode(p, l, r); ! 389: } ! 390: return p; ! 391: } ! 392: ! 393: /* expr3 - parse expressions at precedence level k */ ! 394: static Tree expr3(k) { ! 395: int k1; ! 396: Tree p = prefix(); ! 397: ! 398: for (k1 = prec[t]; k1 >= k; k1--) ! 399: while (prec[t] == k1 && *cp != '=') { ! 400: Tree r; ! 401: Opcode op = t; ! 402: t = gettok(); ! 403: p = pointer(p); ! 404: if (events.points && (op == ANDAND || op == OROR)) { ! 405: Tree e = 0; ! 406: apply(events.points, (Generic)&src, (Generic)&e); ! 407: r = right(e, pointer(expr3(k1 + (k1>5)))); ! 408: } else ! 409: r = pointer(expr3(k1 + (k1>5))); ! 410: p = (*opnode[op])(oper[op], p, r); ! 411: } ! 412: return p; ! 413: } ! 414: ! 415: /* field - construct tree for reference to field name via p */ ! 416: Tree field(p, name) Tree p; char *name; { ! 417: Field q; ! 418: Type ty1, ty = p->type; ! 419: ! 420: if (isptr(ty)) ! 421: ty = deref(ty); ! 422: ty1 = ty; ! 423: ty = unqual(ty); ! 424: if (q = fieldref(name, ty)) { ! 425: ty = q->type; ! 426: if (isconst(ty1) && !isconst(ty)) ! 427: ty = qual(CONST, ty); ! 428: if (isvolatile(ty1) && !isvolatile(ty)) ! 429: ty = qual(VOLATILE, ty); ! 430: if (!isarray(q->type)) ! 431: ty = ptr(ty); ! 432: p = simplify(ADD+P, ty, p, constnode(q->offset, inttype)); ! 433: if (q->lsb) { ! 434: p = tree(FIELD, q->type, rvalue(p), 0); ! 435: p->u.field = q; ! 436: } else if (!isarray(q->type)) ! 437: p = rvalue(p); ! 438: } else { ! 439: error("unknown field `%s' of `%t'\n", name, ty); ! 440: p = rvalue(retype(p, ptr(inttype))); ! 441: } ! 442: return p; ! 443: } ! 444: ! 445: /* funcname - return name of function f or `a function' */ ! 446: char *funcname(f) Tree f; { ! 447: if (isaddrop(f->op)) ! 448: return stringf("`%s'", f->u.sym->name); ! 449: return "a function"; ! 450: } ! 451: ! 452: /* idnode - construct tree for reference to r-value of identifier p */ ! 453: Tree idnode(p) Symbol p; { ! 454: Opcode op; ! 455: Tree e; ! 456: Type ty = p->type ? unqual(p->type) : voidtype; ! 457: ! 458: p->ref += refinc; ! 459: if (p->scope == PARAM) { ! 460: if (IR->no_argb && isstruct(p->type)) { ! 461: e = tree(ADDRF+P, ptr(ptr(p->type)), 0, 0); ! 462: e->u.sym = p; ! 463: e = rvalue(e); ! 464: } else { ! 465: e = tree(ADDRF+P, ptr(p->type), 0, 0); ! 466: e->u.sym = p; ! 467: } ! 468: return rvalue(e); ! 469: } ! 470: if (p->scope == GLOBAL || p->sclass == STATIC || p->sclass == EXTERN) { ! 471: op = ADDRG+P; ! 472: if (isfunc(ty)) ! 473: p->addressed = 1; ! 474: } else ! 475: op = ADDRL+P; ! 476: if (isarray(ty) || isfunc(ty)) { ! 477: e = tree(op, p->type ? p->type : voidtype, 0, 0); ! 478: e->u.sym = p; ! 479: return e; ! 480: } else { ! 481: e = tree(op, ptr(p->type), 0, 0); ! 482: e->u.sym = p; ! 483: return rvalue(e); ! 484: } ! 485: } ! 486: ! 487: /* incr - construct tree for e1 op= e2 */ ! 488: Tree incr(op, e1, e2) Tree e1, e2; { ! 489: return asgnnode(ASGN, e1, (*opnode[op])(oper[op], e1, e2)); ! 490: } ! 491: ! 492: /* intexpr - parse a constant expression and return int value, default n */ ! 493: int intexpr(tok, n) { ! 494: Tree p = constexpr(tok); ! 495: ! 496: needconst++; ! 497: if (generic(p->op) == CNST && isint(p->type)) ! 498: n = cast(p, inttype)->u.v.i; ! 499: else ! 500: error("integer expression must be constant\n"); ! 501: needconst--; ! 502: return n; ! 503: } ! 504: ! 505: /* lvalue - check for lvalue, return pointer to lvalue tree */ ! 506: Tree lvalue(p) Tree p; { ! 507: if (generic(p->op) == INDIR) { ! 508: if (unqual(p->type) == voidtype) ! 509: warning("`%t' used as an lvalue\n", p->type); ! 510: return p->kids[0]; ! 511: } ! 512: error("lvalue required\n"); ! 513: return value(p); ! 514: } ! 515: ! 516: /* nullcheck - test if p null; build ((!p ? _YYnull(lineno) : ), p) */ ! 517: static Tree nullcheck(p) Tree p; { ! 518: Tree q, arg; ! 519: ! 520: if (needconst) ! 521: return p; ! 522: arg = tree(ARG+I, inttype, constnode(lineno, inttype), 0); ! 523: q = tree(COND, voidtype, ! 524: tree(NOT, inttype, cond(p), 0), ! 525: tree(RIGHT, inttype, callnode(pointer(idnode(YYnull)), voidtype, arg), 0)); ! 526: return tree(RIGHT, p->type, q, p); ! 527: } ! 528: ! 529: /* pointer - re-type `array of T', `T function' to `ptr to T', `ptr to T function', resp. */ ! 530: Tree pointer(p) Tree p; { ! 531: if (isarray(p->type) && (p->op != RIGHT || p->u.sym == 0)) ! 532: p = retype(p, atop(p->type)); ! 533: else if (isfunc(p->type)) ! 534: p = retype(p, ptr(p->type)); ! 535: return p; ! 536: } ! 537: ! 538: /* postfix - parse a postfix expresssion; p is the primary dag */ ! 539: static Tree postfix(p) Tree p; { ! 540: Tree q; ! 541: Type ty; ! 542: ! 543: for (;;) ! 544: switch (t) { ! 545: case INCR: case DECR: ! 546: p = tree(RIGHT, p->type, ! 547: tree(RIGHT, p->type, p, root(incr(t, p, constnode(1, inttype)))), ! 548: p); ! 549: t = gettok(); ! 550: continue; ! 551: case '[': ! 552: t = gettok(); ! 553: q = expr(']'); ! 554: if (YYnull) ! 555: if (isptr(p->type)) ! 556: p = nullcheck(p); ! 557: else if (isptr(q->type)) ! 558: q = nullcheck(q); ! 559: q = pointer(q); ! 560: p = (*opnode['+'])(ADD, pointer(p), q); ! 561: if (isptr(p->type) && isarray(p->type->type)) ! 562: p = retype(p, p->type->type); ! 563: else ! 564: p = rvalue(p); ! 565: continue; ! 566: case '(': { ! 567: Coordinate pt; ! 568: p = pointer(p); ! 569: if (isptr(p->type) && isfunc(p->type->type)) ! 570: ty = p->type->type; ! 571: else { ! 572: error("found `%t' expected a function\n", p->type); ! 573: ty = func(voidtype, 0, 1); ! 574: } ! 575: pt = src; ! 576: t = gettok(); ! 577: p = call(p, ty, pt); ! 578: continue; ! 579: } ! 580: case '.': ! 581: t = gettok(); ! 582: if (t == ID) { ! 583: if (isstruct(p->type)) { ! 584: q = addrof(p); ! 585: p = field(q, token); /* refme */ ! 586: q = rightkid(q); ! 587: if (isaddrop(q->op) && q->u.sym->temporary) { ! 588: p = tree(RIGHT, p->type, p, 0); ! 589: p->u.sym = q->u.sym; ! 590: } ! 591: } else ! 592: error("left operand of . has incompatible type `%t'\n", ! 593: p->type); ! 594: t = gettok(); ! 595: } else ! 596: error("field name expected\n"); ! 597: continue; ! 598: case DEREF: ! 599: t = gettok(); ! 600: p = pointer(p); ! 601: if (t == ID) { ! 602: if (isptr(p->type)) ! 603: ty = deref(p->type); ! 604: if (isptr(p->type) && isstruct(ty)) { ! 605: if (YYnull) ! 606: p = nullcheck(p); ! 607: p = field(p, token); /* refme */ ! 608: } else ! 609: error("left operand of -> has incompatible type `%t'\n", ! 610: p->type); ! 611: t = gettok(); ! 612: } else ! 613: error("field name expected\n"); ! 614: continue; ! 615: default: ! 616: return p; ! 617: } ! 618: } ! 619: ! 620: /* prefix - parse a prefix expression */ ! 621: static Tree prefix() { ! 622: Tree p; ! 623: ! 624: switch (t) { ! 625: case '*': ! 626: t = gettok(); ! 627: p = pointer(prefix()); ! 628: if (isptr(p->type) && (isfunc(p->type->type) || isarray(p->type->type))) { ! 629: p = retype(p, p->type->type); ! 630: break; ! 631: } ! 632: if (YYnull) ! 633: p = nullcheck(p); ! 634: p = rvalue(p); ! 635: break; ! 636: case '&': ! 637: t = gettok(); ! 638: p = prefix(); ! 639: if (isarray(p->type) || isfunc(p->type)) ! 640: p = retype(p, ptr(p->type)); ! 641: else ! 642: p = lvalue(p); ! 643: if (isaddrop(p->op)) ! 644: if (p->u.sym->sclass == REGISTER) ! 645: error("invalid operand of unary &; `%s' is declared register\n", ! 646: p->u.sym->name); ! 647: else ! 648: p->u.sym->addressed = 1; ! 649: break; ! 650: case '+': ! 651: t = gettok(); ! 652: p = pointer(prefix()); ! 653: if (isarith(p->type)) ! 654: p = cast(p, promote(p->type)); ! 655: else ! 656: typeerror(ADD, p, 0); ! 657: break; ! 658: case '-': ! 659: t = gettok(); ! 660: p = pointer(prefix()); ! 661: if (isarith(p->type)) { ! 662: p = cast(p, promote(p->type)); ! 663: if (isunsigned(p->type)) { ! 664: warning("unsigned operand of unary -\n"); ! 665: p = cast(simplify(NEG+I, inttype, cast(p, inttype), 0), unsignedtype); ! 666: } else ! 667: p = simplify(NEG + ttob(p->type), p->type, p, 0); ! 668: } else ! 669: typeerror(SUB, p, 0); ! 670: break; ! 671: case '~': ! 672: t = gettok(); ! 673: p = pointer(prefix()); ! 674: if (isint(p->type)) { ! 675: Type ty = promote(p->type); ! 676: p = simplify(BCOM, ty, cast(p, ty), 0); ! 677: } else ! 678: typeerror(BCOM, p, 0); ! 679: break; ! 680: case '!': ! 681: t = gettok(); ! 682: p = pointer(prefix()); ! 683: if (isscalar(p->type)) ! 684: p = simplify(NOT, inttype, cond(p), 0); ! 685: else ! 686: typeerror(NOT, p, 0); ! 687: break; ! 688: case INCR: case DECR: { ! 689: Opcode op = t; ! 690: t = gettok(); ! 691: p = incr(op, pointer(prefix()), constnode(1, inttype)); ! 692: break; ! 693: } ! 694: case SIZEOF: { ! 695: Type ty; ! 696: t = gettok(); ! 697: p = 0; ! 698: if (t == '(') { ! 699: t = gettok(); ! 700: if (kind[t] == CHAR || t == ID ! 701: && tsym && tsym->sclass == TYPEDEF) { ! 702: ty = typename(); ! 703: expect(')'); ! 704: } else if (t == SCON) { ! 705: ty = tsym->type; ! 706: t = gettok(); ! 707: expect(')'); ! 708: } else ! 709: p = postfix(expr(')')); ! 710: } else if (t == SCON) { ! 711: ty = tsym->type; ! 712: t = gettok(); ! 713: } else ! 714: p = prefix(); ! 715: if (p) ! 716: ty = p->type; ! 717: if (isfunc(ty) || ty->size == 0) ! 718: error("invalid type argument `%t' to `sizeof'\n", ty); ! 719: else if (p && p->op == FIELD) ! 720: error("`sizeof' applied to a bit field\n"); ! 721: p = constnode(ty->size, unsignedtype); ! 722: break; ! 723: } ! 724: case '(': ! 725: t = gettok(); ! 726: if (kind[t] == CHAR || t == ID ! 727: && tsym && tsym->sclass == TYPEDEF) { ! 728: Type ty, ty1 = typename(); ! 729: ty = unqual(ty1); ! 730: if (isenum(ty)) { ! 731: Type ty2 = ty->type; ! 732: if (isconst(ty1)) ! 733: ty2 = qual(CONST, ty2); ! 734: if (isvolatile(ty1)) ! 735: ty2 = qual(VOLATILE, ty2); ! 736: ty1 = ty2; ! 737: ty = ty->type; ! 738: } ! 739: expect(')'); ! 740: if (isstruct(ty) && t == '{') { ! 741: Symbol t1 = temporary(AUTO, ty); ! 742: if (Aflag >= 2) ! 743: warning("non-ANSI constructor for `%t'\n", ty); ! 744: p = tree(RIGHT, ty1, structexp(ty, t1), idnode(t1)); ! 745: break; ! 746: } ! 747: p = pointer(prefix()); ! 748: if ((isarith(p->type) || isenum(p->type)) && isarith(ty) ! 749: || isptr(ty) && (isptr(p->type) || isint(p->type) || isenum(p->type))) ! 750: p = cast(p, ty); ! 751: else if (isint(ty) && isptr(p->type)) { ! 752: if (Aflag >= 1 && ty->size < p->type->size) ! 753: warning("conversion from `%t' to `%t' is compiler-dependent\n", ! 754: p->type, ty); ! 755: p = cast(p, ty); ! 756: } else if (ty != voidtype) { ! 757: error("cast from `%t' to `%t' is illegal\n", ! 758: p->type, ty1); ! 759: ty1 = inttype; ! 760: } ! 761: p = retype(p, ty1); ! 762: if (/* ty != ty1 && generic(p->op) == CNST ! 763: || */ generic(p->op) == INDIR) ! 764: p = tree(RIGHT, ty, 0, p); ! 765: } else ! 766: p = postfix(expr(')')); ! 767: break; ! 768: default: ! 769: p = postfix(primary()); ! 770: } ! 771: return p; ! 772: } ! 773: ! 774: /* primary - parse a primary expression */ ! 775: static Tree primary() { ! 776: Tree p; ! 777: ! 778: switch (t) { ! 779: case ID: ! 780: if (tsym == 0) { ! 781: Symbol q = install(token, &identifiers, level < LOCAL); ! 782: q->src = src; ! 783: t = gettok(); ! 784: if (t == '(') { ! 785: Symbol r; ! 786: q->sclass = EXTERN; ! 787: q->type = func(inttype, (Type *)0, 1); ! 788: if (Aflag >= 1) ! 789: warning("missing prototype\n"); ! 790: (*IR->defsymbol)(q); ! 791: if (r = lookup(q->name, externals)) { ! 792: q->defined = r->defined; ! 793: q->temporary = r->temporary; ! 794: q->generated = r->generated; ! 795: q->computed = r->computed; ! 796: q->addressed = r->addressed; ! 797: } else { ! 798: r = install(q->name, &externals, 1); ! 799: r->src = q->src; ! 800: r->type = q->type; ! 801: r->sclass = EXTERN; ! 802: } ! 803: } else { ! 804: error("undeclared identifier `%s'\n", q->name); ! 805: q->sclass = AUTO; ! 806: q->type = inttype; ! 807: if (q->scope == GLOBAL) ! 808: (*IR->defsymbol)(q); ! 809: else ! 810: addlocal(q); ! 811: } ! 812: if (xref) ! 813: use(q, src); ! 814: return idnode(q); ! 815: } ! 816: if (xref) ! 817: use(tsym, src); ! 818: if (tsym->sclass == ENUM) ! 819: p = constnode(tsym->u.value, inttype); ! 820: else { ! 821: if (tsym->sclass == TYPEDEF) ! 822: error("illegal use of type name `%s'\n", tsym->name); ! 823: p = idnode(tsym); ! 824: } ! 825: break; ! 826: case ICON: case FCON: ! 827: p = tree(CNST + ttob(tsym->type), tsym->type, 0, 0); ! 828: p->u.v = tsym->u.c.v; ! 829: break; ! 830: case SCON: ! 831: tsym->u.c.v.p = stringn(tsym->u.c.v.p, tsym->type->size); ! 832: tsym = constant(tsym->type, tsym->u.c.v); ! 833: if (tsym->u.c.loc == 0) ! 834: tsym->u.c.loc = genident(STATIC, tsym->type, GLOBAL); ! 835: p = idnode(tsym->u.c.loc); ! 836: break; ! 837: case '(': ! 838: t = gettok(); ! 839: return expr(')'); ! 840: default: ! 841: error("illegal expression\n"); ! 842: p = constnode(0, inttype); ! 843: } ! 844: t = gettok(); ! 845: return p; ! 846: } ! 847: ! 848: /* promote - the usual integral promotions */ ! 849: Type promote(ty) Type ty; { ! 850: ty = unqual(ty); ! 851: if (isunsigned(ty) || ty == longtype) ! 852: return ty; ! 853: else if (isint(ty) || isenum(ty)) ! 854: return inttype; ! 855: return ty; ! 856: } ! 857: ! 858: /* right - return (RIGHT, q->type, root(p), q) or just root(p/q) if q/p==0 */ ! 859: Tree right(p, q) Tree p, q; { ! 860: assert(p || q); ! 861: if (p && q) ! 862: return tree(RIGHT, q->type, root(p), q); ! 863: return p ? p : q; ! 864: } ! 865: ! 866: /* rightkid - dereference RIGHT nodes to find ultimate offspring */ ! 867: static Tree rightkid(p) Tree p; { ! 868: while (p && p->op == RIGHT) { ! 869: assert(p->kids[0] || p->kids[1]); ! 870: p = p->kids[1] ? p->kids[1] : p->kids[0]; ! 871: } ! 872: assert(p); ! 873: return p; ! 874: } ! 875: ! 876: /* rvalue - convert p to an rvalue */ ! 877: Tree rvalue(p) Tree p; { ! 878: Type ty = deref(p->type); ! 879: ! 880: ty = unqual(ty); ! 881: return tree(INDIR + (isunsigned(ty) ? I : ttob(ty)), ty, p, 0); ! 882: } ! 883: ! 884: /* value - convert p from a conditional to a value, if necessary */ ! 885: static Tree value(p) Tree p; { ! 886: Opcode op = generic(rightkid(p)->op); ! 887: ! 888: if (op == AND || op == OR || op == NOT || op == EQ || op == NE ! 889: || op == LE || op == LT || op == GE || op == GT) ! 890: p = condnode(p, constnode(1, inttype), constnode(0, inttype)); ! 891: return p; ! 892: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.