|
|
1.1 ! root 1: /* C compiler: type-checking and tree construction for expressions */ ! 2: ! 3: #include "c.h" ! 4: ! 5: dclproto(static Tree addnode,(int, Tree, Tree)); ! 6: dclproto(static Tree andnode,(int, Tree, Tree)); ! 7: dclproto(static Type binary,(Type, Type)); ! 8: dclproto(static Tree cmpnode,(int, Tree, Tree)); ! 9: dclproto(static int compatible,(Type, Type)); ! 10: dclproto(static Tree mulnode,(int, Tree, Tree)); ! 11: dclproto(static Tree subnode,(int, Tree, Tree)); ! 12: ! 13: dclproto(Tree (*opnode[]),(int, Tree, Tree)) = { ! 14: #define xx(a,b,c,d,e,f,g) e, ! 15: #include "token.h" ! 16: }; ! 17: ! 18: /* addnode - construct tree for l + r */ ! 19: static Tree addnode(op, l, r) Tree l, r; { ! 20: int n; ! 21: Type ty = inttype; ! 22: ! 23: if (isarith(l->type) && isarith(r->type)) { ! 24: ty = binary(l->type, r->type); ! 25: l = cast(l, ty); ! 26: r = cast(r, ty); ! 27: } else if (isptr(l->type) && isint(r->type)) ! 28: return addnode(ADD, r, l); ! 29: else if (isptr(r->type) && isint(l->type)) { ! 30: ty = unqual(r->type); ! 31: if ((n = ty->type->size) == 0) ! 32: error("unknown size of type `%t'\n", ty->type); ! 33: l = cast(l, promote(l->type)); ! 34: if (n > 1) ! 35: l = mulnode(MUL, constnode(n, inttype), l); ! 36: return simplify(ADD+P, ty, l, r); ! 37: } else ! 38: typeerror(op, l, r); ! 39: return simplify(op, ty, l, r); ! 40: } ! 41: ! 42: /* andnode - construct tree for l [&& ||] r */ ! 43: static Tree andnode(op, l, r) Tree l, r; { ! 44: if (!isscalar(l->type) || !isscalar(r->type)) ! 45: typeerror(op, l, r); ! 46: return simplify(op, inttype, cond(l), cond(r)); ! 47: } ! 48: ! 49: /* asgnnode - construct tree for l = r */ ! 50: Tree asgnnode(op, l, r) Tree l, r; { ! 51: Type aty, ty; ! 52: ! 53: r = pointer(r); ! 54: if ((ty = assign(l->type, r)) == 0) { ! 55: typeerror(ASGN, l, r); ! 56: if (r->type == voidtype) ! 57: r = retype(r, inttype); ! 58: ty = r->type; ! 59: } ! 60: if (l->op != FIELD) ! 61: l = lvalue(l); ! 62: aty = l->type; ! 63: if (isptr(aty)) ! 64: aty = unqual(aty)->type; ! 65: if (isconst(aty) || (isstruct(aty) && unqual(aty)->u.sym->u.s.cfields)) ! 66: if (isaddrop(l->op) && !l->u.sym->computed && !l->u.sym->generated) ! 67: error("assignment to const identifier `%s'\n", l->u.sym->name); ! 68: else ! 69: error("assignment to const location\n"); ! 70: r = cast(r, ty); ! 71: if (l->op == FIELD && fieldsize(l->u.field) < 8*l->u.field->type->size) ! 72: if (isunsigned(l->u.field->type)) ! 73: r = bitnode(BAND, r, ! 74: constnode(fieldmask(l->u.field), unsignedtype)); ! 75: else { ! 76: int n = 8*l->u.field->type->size - fieldsize(l->u.field); ! 77: /* ! 78: * The value of assignment is the value of the left ! 79: * operand (sec. 3.3.16), which for bit fields is the ! 80: * same as extracting the field. When r is a constant, ! 81: * the explicit left shift below avoids overflow that ! 82: * would occur if shnode(LSH, ...) were used. The ! 83: * subsequent shnode(RSH, ...) will be signed and thus ! 84: * extend the sign bit correctly. ! 85: */ ! 86: if (r->op == CNST+I) ! 87: r = constnode(r->u.v.i<<n, inttype); ! 88: else ! 89: r = shnode(LSH, r, constnode(n, inttype)); ! 90: r = shnode(RSH, r, constnode(n, inttype)); ! 91: } ! 92: if (isstruct(ty)) { ! 93: if (r->op == RIGHT && r->kids[0] && r->kids[0]->op == CALL+B ! 94: && isaddrop(l->op)) { ! 95: /* ! 96: * When x=f() where f returns a struct and x is a simple ! 97: * address, release the temporary generated to hold f's ! 98: * return value and use x in its place. The RIGHT tree ! 99: * assigned to r below returns x's address, and ! 100: * rvalue(r) hangs that tree under an INDIR+B, ! 101: * thus identifying the result as an lvalue. ! 102: */ ! 103: r = r->kids[0]; /* CALL+B node */ ! 104: release(r->kids[1]->u.sym); ! 105: r = tree(RIGHT, l->type, ! 106: tree(CALL+B, r->kids[0]->type, r->kids[0], l), ! 107: retype(isarray(l->u.sym->type) ? idnode(l->u.sym) : addrof(idnode(l->u.sym)), l->type)); ! 108: return rvalue(r); ! 109: } ! 110: return tree(ASGN+B, ty, l, r); ! 111: } ! 112: return tree(op + (isunsigned(ty) ? I : ttob(ty)), ty, l, r); ! 113: } ! 114: ! 115: /* binary - usual arithmetic conversions, return target type */ ! 116: static Type binary(xty, yty) Type xty, yty; { ! 117: if (isdouble(xty) || isdouble(yty)) ! 118: return doubletype; ! 119: if (xty == floattype || yty == floattype) ! 120: return floattype; ! 121: if (isunsigned(xty) || isunsigned(yty)) ! 122: return unsignedtype; ! 123: return inttype; ! 124: } ! 125: ! 126: /* bitnode - construct tree for l [& | ^ %] r */ ! 127: Tree bitnode(op, l, r) Tree l, r; { ! 128: Type ty = inttype; ! 129: ! 130: if (isint(l->type) && isint(r->type)) { ! 131: ty = binary(l->type, r->type); ! 132: l = cast(l, ty); ! 133: r = cast(r, ty); ! 134: if (op != MOD) { ! 135: l = cast(l, unsignedtype); ! 136: r = cast(r, unsignedtype); ! 137: } ! 138: } else ! 139: typeerror(op, l, r); ! 140: if (op == MOD) ! 141: return simplify(op, ty, l, r); ! 142: return cast(simplify(op, unsignedtype, l, r), ty); ! 143: } ! 144: ! 145: /* callnode - construct call node to f, return type ty, arguments args */ ! 146: Tree callnode(f, ty, args) Tree f, args; Type ty; { ! 147: Tree p; ! 148: ! 149: if (args) ! 150: f = tree(RIGHT, f->type, args, f); ! 151: if (isstruct(ty)) { ! 152: Symbol t1 = temporary(AUTO, unqual(ty)); ! 153: if (ty->size == 0) ! 154: error("illegal use of incomplete type `%t'\n", ty); ! 155: p = tree(RIGHT, ty, tree(CALL+B, ty, f, lvalue(idnode(t1))), ! 156: idnode(t1)); ! 157: } else { ! 158: Type rty = ty; ! 159: if (isenum(ty)) ! 160: rty = unqual(ty)->type; ! 161: else if (isptr(ty)) ! 162: rty = unsignedtype; ! 163: p = tree(CALL + widen(rty), rty, f, 0); ! 164: if (isptr(ty)) ! 165: p = cast(p, ty); ! 166: } ! 167: return p; ! 168: } ! 169: ! 170: /* cmpnode - construct tree for l [< <= >= >] r */ ! 171: static Tree cmpnode(op, l, r) Tree l, r; { ! 172: Type ty = unsignedtype; ! 173: ! 174: if (isarith(l->type) && isarith(r->type)) { ! 175: ty = binary(l->type, r->type); ! 176: l = cast(l, ty); ! 177: r = cast(r, ty); ! 178: } else if (compatible(l->type, r->type)) { ! 179: l = cast(l, ty); ! 180: r = cast(r, ty); ! 181: } else ! 182: typeerror(op, l, r); ! 183: return simplify(op + ttob(ty), inttype, l, r); ! 184: } ! 185: ! 186: /* compatible - are ty1 & ty2 sans qualifiers pointers to compatible object or incomplete types? */ ! 187: static int compatible(ty1, ty2) Type ty1, ty2; { ! 188: if (isptr(ty1) && !isfunc(ty1->type) && isptr(ty2) && !isfunc(ty2->type)) { ! 189: do { ! 190: ty1 = unqual(ty1->type); ! 191: ty2 = unqual(ty2->type); ! 192: } while (isptr(ty1) && isptr(ty2)); ! 193: return eqtype(ty1, ty2, 0); ! 194: } ! 195: return 0; ! 196: } ! 197: ! 198: /* condnode - build a tree for e ? l : r */ ! 199: Tree condnode(e, l, r) Tree e, l, r; { ! 200: Symbol t1 = 0; ! 201: Type ty = 0, lty = l->type, rty = r->type; ! 202: Tree p; ! 203: ! 204: if (isarith(lty) && isarith(rty)) { ! 205: ty = binary(lty, rty); ! 206: l = cast(l, ty); ! 207: r = cast(r, ty); ! 208: } else if (eqtype(lty, rty, 1) ! 209: || isptr(lty) && isint(rty) && assign(lty, r)) ! 210: ty = unqual(lty); ! 211: else if (isptr(rty) && isint(lty) && assign(rty, l)) ! 212: ty = unqual(rty); ! 213: else if (isptr(lty) && isptr(rty)) { ! 214: lty = lty->type; ! 215: rty = rty->type; ! 216: if (unqual(lty) == voidtype || unqual(rty) == voidtype) ! 217: ty = voidtype; ! 218: else if (eqtype(unqual(lty), unqual(rty), 1)) ! 219: ty = unqual(lty); ! 220: if (ty) { ! 221: if (isconst(lty) || isconst(rty)) ! 222: ty = qual(CONST, ty); ! 223: if (isvolatile(lty) || isvolatile(rty)) ! 224: ty = qual(VOLATILE, ty); ! 225: ty = ptr(ty); ! 226: } ! 227: } ! 228: if (ty == 0) { ! 229: typeerror(COND, l, r); ! 230: ty = inttype; ! 231: } else if (e->op == CNST+D || e->op == CNST+F) { ! 232: e = cast(e, doubletype); ! 233: return retype(e->u.v.d != 0.0 ? l : r, ty); ! 234: } else if (generic(e->op) == CNST) { ! 235: e = cast(e, unsignedtype); ! 236: return retype(e->u.v.u ? l : r, ty); ! 237: } else if (ty != voidtype && ty->size > 0) { ! 238: Opcode op = generic(e->op); ! 239: t1 = temporary(REGISTER, ty); ! 240: l = root(asgn(t1, l)); ! 241: if (op != AND && op != OR && op != NOT && op != EQ && op != NE ! 242: && op != LE && op != LT && op != GE && op != GT && op != RIGHT ! 243: && r->op == CNST+I && r->u.v.i == 0 ! 244: && assign(e->type, r)) { ! 245: /* e1?e2:0 => ((t1=e1,t1)?(t1=e2): ) */ ! 246: e = tree(RIGHT, ty, asgn(t1, cast(e, ty)), idnode(t1)); ! 247: r = 0; ! 248: } else ! 249: r = root(asgn(t1, r)); ! 250: } ! 251: p = tree(COND, ty, cond(e), tree(RIGHT, ty, l, r)); ! 252: p->u.sym = t1; ! 253: return p; ! 254: } ! 255: ! 256: /* constnode - return a tree for a constant n of type ty (int or unsigned) */ ! 257: Tree constnode(n, ty) unsigned n; Type ty; { ! 258: Tree p; ! 259: ! 260: if (isarray(ty)) ! 261: p = tree(CNST+P, atop(ty), 0, 0); ! 262: else ! 263: p = tree(CNST + ttob(ty), ty, 0, 0); ! 264: p->u.v.u = n; ! 265: return p; ! 266: } ! 267: ! 268: /* eqnode - construct tree for l [== !=] r */ ! 269: Tree eqnode(op, l, r) Tree l, r; { ! 270: if (isint(l->type) && isptr(r->type)) ! 271: return eqnode(op, r, l); ! 272: if (isptr(l->type) && isint(r->type)) { ! 273: l = cast(l, unsignedtype); ! 274: r = cast(r, unsignedtype); ! 275: if (r->op != CNST+U || r->u.v.u) ! 276: error("operands of %s have incompatible types\n", ! 277: op == EQ ? "==" : "!="); ! 278: return simplify(op + U, inttype, l, r); ! 279: } ! 280: if (isptr(l->type) && isptr(r->type) && eqtype(unqual(l->type), unqual(r->type), 1) ! 281: || isptr(l->type) && !isfunc(l->type->type) ! 282: && (isptr(r->type) && unqual(r->type->type) == voidtype) ! 283: || isptr(r->type) && !isfunc(r->type->type) ! 284: && (isptr(l->type) && unqual(l->type->type) == voidtype)) { ! 285: l = cast(l, unsignedtype); ! 286: r = cast(r, unsignedtype); ! 287: return simplify(op + U, inttype, l, r); ! 288: } ! 289: return cmpnode(op, l, r); ! 290: } ! 291: ! 292: /* mulnode - construct tree for l [* /] r */ ! 293: static Tree mulnode(op, l, r) Tree l, r; { ! 294: Type ty = inttype; ! 295: ! 296: if (isarith(l->type) && isarith(r->type)) { ! 297: ty = binary(l->type, r->type); ! 298: l = cast(l, ty); ! 299: r = cast(r, ty); ! 300: } else ! 301: typeerror(op, l, r); ! 302: return simplify(op, ty, l, r); ! 303: } ! 304: ! 305: /* shnode - construct tree for l [>> <<] r */ ! 306: Tree shnode(op, l, r) Tree l, r; { ! 307: Type ty = inttype; ! 308: ! 309: if (isint(l->type) && isint(r->type)) { ! 310: ty = promote(l->type); ! 311: l = cast(l, ty); ! 312: r = cast(r, inttype); ! 313: } else ! 314: typeerror(op, l, r); ! 315: return simplify(op, ty, l, r); ! 316: } ! 317: ! 318: /* subnode - construct tree for l - r */ ! 319: static Tree subnode(op, l, r) Tree l, r; { ! 320: int n; ! 321: Type ty = inttype; ! 322: ! 323: if (isarith(l->type) && isarith(r->type)) { ! 324: ty = binary(l->type, r->type); ! 325: l = cast(l, ty); ! 326: r = cast(r, ty); ! 327: } else if (isptr(l->type) && !isfunc(l->type->type) && isint(r->type)) { ! 328: ty = unqual(l->type); ! 329: if ((n = ty->type->size) == 0) ! 330: error("unknown size of type `%t'\n", ty->type); ! 331: r = cast(r, promote(r->type)); ! 332: if (n > 1) ! 333: r = mulnode(MUL, constnode(n, inttype), r); ! 334: return simplify(SUB+P, ty, l, r); ! 335: } else if (compatible(l->type, r->type)) { ! 336: if ((n = deref(l->type)->size) == 0) ! 337: error("unknown size of type `%t'\n", deref(l->type)); ! 338: l = simplify(SUB+U, unsignedtype, cast(l, unsignedtype), ! 339: cast(r, unsignedtype)); ! 340: return simplify(DIV+I, inttype, cast(l, inttype), constnode(n, inttype)); ! 341: } else ! 342: typeerror(op, l, r); ! 343: return simplify(op, ty, l, r); ! 344: } ! 345: ! 346: /* typeerror - issue "operands of op have illegal types `l' and `r'" */ ! 347: void typeerror(op, l, r) Tree l, r; { ! 348: int i; ! 349: static struct { Opcode op; char *name; } ops[] = { ! 350: ASGN, "=", INDIR, "*", NEG, "-", ! 351: ADD, "+", SUB, "-", LSH, "<<", ! 352: MOD, "%", RSH, ">>", BAND, "&", ! 353: BCOM, "~", BOR, "|", BXOR, "^", ! 354: DIV, "/", MUL, "*", EQ, "==", ! 355: GE, ">=", GT, ">", LE, "<=", ! 356: LT, "<", NE, "!=", AND, "&&", ! 357: NOT, "!", OR, "||", COND, "?:", ! 358: 0, 0 ! 359: }; ! 360: ! 361: op = generic(op); ! 362: for (i = 0; ops[i].op; i++) ! 363: if (op == ops[i].op) ! 364: break; ! 365: assert(ops[i].name); ! 366: if (r) ! 367: error("operands of %s have illegal types `%t' and `%t'\n", ! 368: ops[i].name, l->type, r->type); ! 369: else ! 370: error("operand of unary %s has illegal type `%t'\n", ops[i].name, ! 371: l->type); ! 372: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.