00001 #include "c.h"
00002
00003
00004 static Tree addtree(int, Tree, Tree);
00005 static Tree andtree(int, Tree, Tree);
00006 static Tree cmptree(int, Tree, Tree);
00007 static int compatible(Type, Type);
00008 static int isnullptr(Tree e);
00009 static Tree multree(int, Tree, Tree);
00010 static Tree subtree(int, Tree, Tree);
00011 #define isvoidptr(ty) \
00012 (isptr(ty) && unqual(ty->type) == voidtype)
00013
00014 Tree (*optree[])(int, Tree, Tree) = {
00015 #define xx(a,b,c,d,e,f,g) e,
00016 #define yy(a,b,c,d,e,f,g) e,
00017 #include "token.h"
00018 };
00019 Tree call(Tree f, Type fty, Coordinate src) {
00020 int n = 0;
00021 Tree args = NULL, r = NULL, e;
00022 Type *proto, rty = unqual(freturn(fty));
00023 Symbol t3 = NULL;
00024
00025 if (fty->u.f.oldstyle)
00026 proto = NULL;
00027 else
00028 proto = fty->u.f.proto;
00029 if (hascall(f))
00030 r = f;
00031 if (isstruct(rty))
00032 {
00033 t3 = temporary(AUTO, unqual(rty));
00034 if (rty->size == 0)
00035 error("illegal use of incomplete type `%t'\n", rty);
00036 }
00037 if (t != ')')
00038 for (;;) {
00039 Tree q = pointer(expr1(0));
00040 if (proto && *proto && *proto != voidtype)
00041 {
00042 Type aty;
00043 q = value(q);
00044 aty = assign(*proto, q);
00045 if (aty)
00046 q = cast(q, aty);
00047 else
00048 error("type error in argument %d to %s; found `%t' expected `%t'\n", n + 1, funcname(f),
00049
00050 q->type, *proto);
00051 if ((isint(q->type) || isenum(q->type))
00052 && q->type->size != inttype->size)
00053 q = cast(q, promote(q->type));
00054 ++proto;
00055 }
00056 else
00057 {
00058 if (!fty->u.f.oldstyle && *proto == NULL)
00059 error("too many arguments to %s\n", funcname(f));
00060 q = value(q);
00061 if (isarray(q->type) || q->type->size == 0)
00062 error("type error in argument %d to %s; `%t' is illegal\n", n + 1, funcname(f), q->type);
00063
00064 else
00065 q = cast(q, promote(q->type));
00066 }
00067 if (!IR->wants_argb && isstruct(q->type))
00068 if (iscallb(q))
00069 q = addrof(q);
00070 else {
00071 Symbol t1 = temporary(AUTO, unqual(q->type));
00072 q = asgn(t1, q);
00073 q = tree(RIGHT, ptr(t1->type),
00074 root(q), lvalue(idtree(t1)));
00075 }
00076 if (q->type->size == 0)
00077 q->type = inttype;
00078 if (hascall(q))
00079 r = r ? tree(RIGHT, voidtype, r, q) : q;
00080 args = tree(mkop(ARG, q->type), q->type, q, args);
00081 n++;
00082 if (Aflag >= 2 && n == 32)
00083 warning("more than 31 arguments in a call to %s\n",
00084 funcname(f));
00085 if (t != ',')
00086 break;
00087 t = gettok();
00088 }
00089 expect(')');
00090 if (proto && *proto && *proto != voidtype)
00091 error("insufficient number of arguments to %s\n",
00092 funcname(f));
00093 if (r)
00094 args = tree(RIGHT, voidtype, r, args);
00095 e = calltree(f, rty, args, t3);
00096 if (events.calls)
00097 apply(events.calls, &src, &e);
00098 return e;
00099 }
00100 Tree calltree(Tree f, Type ty, Tree args, Symbol t3) {
00101 Tree p;
00102
00103 if (args)
00104 f = tree(RIGHT, f->type, args, f);
00105 if (isstruct(ty))
00106 assert(t3),
00107 p = tree(RIGHT, ty,
00108 tree(CALL+B, ty, f, addrof(idtree(t3))),
00109 idtree(t3));
00110 else {
00111 Type rty = ty;
00112 if (isenum(ty))
00113 rty = unqual(ty)->type;
00114 if (!isfloat(rty))
00115 rty = promote(rty);
00116 p = tree(mkop(CALL, rty), rty, f, NULL);
00117 if (isptr(ty) || p->type->size > ty->size)
00118 p = cast(p, ty);
00119 }
00120 return p;
00121 }
00122 Tree vcall(Symbol func, Type ty, ...) {
00123 va_list ap;
00124 Tree args = NULL, e, f = pointer(idtree(func)), r = NULL;
00125
00126 assert(isfunc(func->type));
00127 if (ty == NULL)
00128 ty = freturn(func->type);
00129 va_start(ap, ty);
00130 while ((e = va_arg(ap, Tree)) != NULL) {
00131 if (hascall(e))
00132 r = r == NULL ? e : tree(RIGHT, voidtype, r, e);
00133 args = tree(mkop(ARG, e->type), e->type, e, args);
00134 }
00135 va_end(ap);
00136 if (r != NULL)
00137 args = tree(RIGHT, voidtype, r, args);
00138 return calltree(f, ty, args, NULL);
00139 }
00140 int iscallb(Tree e) {
00141 return e->op == RIGHT && e->kids[0] && e->kids[1]
00142 && e->kids[0]->op == CALL+B
00143 && e->kids[1]->op == INDIR+B
00144 && isaddrop(e->kids[1]->kids[0]->op)
00145 && e->kids[1]->kids[0]->u.sym->temporary;
00146 }
00147
00148 static Tree addtree(int op, Tree l, Tree r) {
00149 Type ty = inttype;
00150
00151 if (isarith(l->type) && isarith(r->type)) {
00152 ty = binary(l->type, r->type);
00153 l = cast(l, ty);
00154 r = cast(r, ty);
00155 } else if (isptr(l->type) && isint(r->type))
00156 return addtree(ADD, r, l);
00157 else if ( isptr(r->type) && isint(l->type)
00158 && !isfunc(r->type->type))
00159 {
00160 long n;
00161 ty = unqual(r->type);
00162 n = unqual(ty->type)->size;
00163 if (n == 0)
00164 error("unknown size for type `%t'\n", ty->type);
00165 l = cast(l, promote(l->type));
00166 if (n > 1)
00167 l = multree(MUL, cnsttree(signedptr, n), l);
00168 if (YYcheck && !isaddrop(r->op))
00169 return nullcall(ty, YYcheck, r, l);
00170 return simplify(ADD, ty, l, r);
00171 }
00172
00173 else
00174 typeerror(op, l, r);
00175 return simplify(op, ty, l, r);
00176 }
00177
00178 Tree cnsttree(Type ty, ...) {
00179 Tree p = tree(mkop(CNST,ty), ty, NULL, NULL);
00180 va_list ap;
00181
00182 va_start(ap, ty);
00183 switch (ty->op) {
00184 case INT: p->u.v.i = va_arg(ap, long); break;
00185 case UNSIGNED:p->u.v.u = va_arg(ap, unsigned long)&ones(8*ty->size); break;
00186 case FLOAT: p->u.v.d = va_arg(ap, long double); break;
00187 case POINTER: p->u.v.p = va_arg(ap, void *); break;
00188 default: assert(0);
00189 }
00190 va_end(ap);
00191 return p;
00192 }
00193
00194 Tree consttree(unsigned n, Type ty) {
00195 if (isarray(ty))
00196 ty = atop(ty);
00197 else assert(isint(ty));
00198 return cnsttree(ty, (unsigned long)n);
00199 }
00200 static Tree cmptree(int op, Tree l, Tree r) {
00201 Type ty;
00202
00203 if (isarith(l->type) && isarith(r->type)) {
00204 ty = binary(l->type, r->type);
00205 l = cast(l, ty);
00206 r = cast(r, ty);
00207 } else if (compatible(l->type, r->type)) {
00208 ty = unsignedptr;
00209 l = cast(l, ty);
00210 r = cast(r, ty);
00211 } else {
00212 ty = unsignedtype;
00213 typeerror(op, l, r);
00214 }
00215 return simplify(mkop(op,ty), inttype, l, r);
00216 }
00217 static int compatible(Type ty1, Type ty2) {
00218 return isptr(ty1) && !isfunc(ty1->type)
00219 && isptr(ty2) && !isfunc(ty2->type)
00220 && eqtype(unqual(ty1->type), unqual(ty2->type), 0);
00221 }
00222 static int isnullptr(Tree e) {
00223 Type ty = unqual(e->type);
00224
00225 return generic(e->op) == CNST
00226 && (ty->op == INT && e->u.v.i == 0
00227 || ty->op == UNSIGNED && e->u.v.u == 0
00228 || isvoidptr(ty) && e->u.v.p == NULL);
00229 }
00230 Tree eqtree(int op, Tree l, Tree r) {
00231 Type xty = l->type, yty = r->type;
00232
00233 if (isptr(xty) && isnullptr(r)
00234 || isptr(xty) && !isfunc(xty->type) && isvoidptr(yty)
00235 || (isptr(xty) && isptr(yty)
00236 && eqtype(unqual(xty->type), unqual(yty->type), 1))) {
00237 Type ty = unsignedptr;
00238 l = cast(l, ty);
00239 r = cast(r, ty);
00240 return simplify(mkop(op,ty), inttype, l, r);
00241 }
00242 if (isptr(yty) && isnullptr(l)
00243 || isptr(yty) && !isfunc(yty->type) && isvoidptr(xty))
00244 return eqtree(op, r, l);
00245 return cmptree(op, l, r);
00246 }
00247
00248 Type assign(Type xty, Tree e) {
00249 Type yty = unqual(e->type);
00250
00251 xty = unqual(xty);
00252 if (isenum(xty))
00253 xty = xty->type;
00254 if (xty->size == 0 || yty->size == 0)
00255 return NULL;
00256 if ( isarith(xty) && isarith(yty)
00257 || isstruct(xty) && xty == yty)
00258 return xty;
00259 if (isptr(xty) && isnullptr(e))
00260 return xty;
00261 if ((isvoidptr(xty) && isptr(yty)
00262 || isptr(xty) && isvoidptr(yty))
00263 && ( (isconst(xty->type) || !isconst(yty->type))
00264 && (isvolatile(xty->type) || !isvolatile(yty->type))))
00265 return xty;
00266
00267 if ((isptr(xty) && isptr(yty)
00268 && eqtype(unqual(xty->type), unqual(yty->type), 1))
00269 && ( (isconst(xty->type) || !isconst(yty->type))
00270 && (isvolatile(xty->type) || !isvolatile(yty->type))))
00271 return xty;
00272 if (isptr(xty) && isptr(yty)
00273 && ( (isconst(xty->type) || !isconst(yty->type))
00274 && (isvolatile(xty->type) || !isvolatile(yty->type)))) {
00275 Type lty = unqual(xty->type), rty = unqual(yty->type);
00276 if (isenum(lty) && rty == inttype
00277 || isenum(rty) && lty == inttype) {
00278 if (Aflag >= 1)
00279 warning("assignment between `%t' and `%t' is compiler-dependent\n",
00280 xty, yty);
00281 return xty;
00282 }
00283 }
00284 return NULL;
00285 }
00286 Tree asgntree(int op, Tree l, Tree r) {
00287 Type aty, ty;
00288
00289 r = pointer(r);
00290 ty = assign(l->type, r);
00291 if (ty)
00292 r = cast(r, ty);
00293 else {
00294 typeerror(ASGN, l, r);
00295 if (r->type == voidtype)
00296 r = retype(r, inttype);
00297 ty = r->type;
00298 }
00299 if (l->op != FIELD)
00300 l = lvalue(l);
00301 aty = l->type;
00302 if (isptr(aty))
00303 aty = unqual(aty)->type;
00304 if ( isconst(aty)
00305 || isstruct(aty) && unqual(aty)->u.sym->u.s.cfields)
00306 if (isaddrop(l->op)
00307 && !l->u.sym->computed && !l->u.sym->generated)
00308 error("assignment to const identifier `%s'\n",
00309 l->u.sym->name);
00310 else
00311 error("assignment to const location\n");
00312 if (l->op == FIELD) {
00313 long n = 8*l->u.field->type->size - fieldsize(l->u.field);
00314 if (n > 0 && isunsigned(l->u.field->type))
00315 r = bittree(BAND, r,
00316 cnsttree(r->type, (unsigned long)fieldmask(l->u.field)));
00317 else if (n > 0) {
00318 if (r->op == CNST+I) {
00319 n = r->u.v.i;
00320 if (n&(1<<(fieldsize(l->u.field)-1)))
00321 n |= ~0UL<<fieldsize(l->u.field);
00322 r = cnsttree(r->type, n);
00323 } else
00324 r = shtree(RSH,
00325 shtree(LSH, r, cnsttree(inttype, n)),
00326 cnsttree(inttype, n));
00327 }
00328 }
00329 if (isstruct(ty) && isaddrop(l->op) && iscallb(r))
00330 return tree(RIGHT, ty,
00331 tree(CALL+B, ty, r->kids[0]->kids[0], l),
00332 idtree(l->u.sym));
00333 return tree(mkop(op,ty), ty, l, r);
00334 }
00335 Tree condtree(Tree e, Tree l, Tree r) {
00336 Symbol t1;
00337 Type ty, xty = l->type, yty = r->type;
00338 Tree p;
00339
00340 if (isarith(xty) && isarith(yty))
00341 ty = binary(xty, yty);
00342 else if (eqtype(xty, yty, 1))
00343 ty = unqual(xty);
00344 else if (isptr(xty) && isnullptr(r))
00345 ty = xty;
00346 else if (isnullptr(l) && isptr(yty))
00347 ty = yty;
00348 else if (isptr(xty) && !isfunc(xty->type) && isvoidptr(yty)
00349 || isptr(yty) && !isfunc(yty->type) && isvoidptr(xty))
00350 ty = voidptype;
00351 else if ((isptr(xty) && isptr(yty)
00352 && eqtype(unqual(xty->type), unqual(yty->type), 1)))
00353 ty = xty;
00354 else {
00355 typeerror(COND, l, r);
00356 return consttree(0, inttype);
00357 }
00358 if (isptr(ty)) {
00359 ty = unqual(unqual(ty)->type);
00360 if (isptr(xty) && isconst(unqual(xty)->type)
00361 || isptr(yty) && isconst(unqual(yty)->type))
00362 ty = qual(CONST, ty);
00363 if (isptr(xty) && isvolatile(unqual(xty)->type)
00364 || isptr(yty) && isvolatile(unqual(yty)->type))
00365 ty = qual(VOLATILE, ty);
00366 ty = ptr(ty);
00367 }
00368 switch (e->op) {
00369 case CNST+I: return cast(e->u.v.i != 0 ? l : r, ty);
00370 case CNST+U: return cast(e->u.v.u != 0 ? l : r, ty);
00371 case CNST+P: return cast(e->u.v.p != 0 ? l : r, ty);
00372 case CNST+F: return cast(e->u.v.d != 0.0 ? l : r, ty);
00373 }
00374 if (ty != voidtype && ty->size > 0) {
00375 t1 = genident(REGISTER, unqual(ty), level);
00376
00377 l = asgn(t1, l);
00378 r = asgn(t1, r);
00379 } else
00380 t1 = NULL;
00381 p = tree(COND, ty, cond(e),
00382 tree(RIGHT, ty, root(l), root(r)));
00383 p->u.sym = t1;
00384 return p;
00385 }
00386
00387 Tree addrof(Tree p) {
00388 Tree q = p;
00389
00390 for (;;)
00391 switch (generic(q->op)) {
00392 case RIGHT:
00393 assert(q->kids[0] || q->kids[1]);
00394 q = q->kids[1] ? q->kids[1] : q->kids[0];
00395 continue;
00396 case ASGN:
00397 q = q->kids[1];
00398 continue;
00399 case COND: {
00400 Symbol t1 = q->u.sym;
00401 q->u.sym = 0;
00402 q = idtree(t1);
00403
00404 }
00405 case INDIR:
00406 if (p == q)
00407 return q->kids[0];
00408 q = q->kids[0];
00409 return tree(RIGHT, q->type, root(p), q);
00410 default:
00411 error("addressable object required\n");
00412 return value(p);
00413 }
00414 }
00415
00416
00417 static Tree andtree(int op, Tree l, Tree r) {
00418 if (!isscalar(l->type) || !isscalar(r->type))
00419 typeerror(op, l, r);
00420 return simplify(op, inttype, cond(l), cond(r));
00421 }
00422
00423
00424 Tree asgn(Symbol p, Tree e) {
00425 if (isarray(p->type))
00426 e = tree(ASGN+B, p->type, idtree(p),
00427 tree(INDIR+B, e->type, e, NULL));
00428 else {
00429 Type ty = p->type;
00430 p->type = unqual(p->type);
00431 if (isstruct(p->type) && p->type->u.sym->u.s.cfields) {
00432 p->type->u.sym->u.s.cfields = 0;
00433 e = asgntree(ASGN, idtree(p), e);
00434 p->type->u.sym->u.s.cfields = 1;
00435 } else
00436 e = asgntree(ASGN, idtree(p), e);
00437 p->type = ty;
00438 }
00439 return e;
00440 }
00441
00442
00443 Tree bittree(int op, Tree l, Tree r) {
00444 Type ty = inttype;
00445
00446 if (isint(l->type) && isint(r->type)) {
00447 ty = binary(l->type, r->type);
00448 l = cast(l, ty);
00449 r = cast(r, ty);
00450 } else
00451 typeerror(op, l, r);
00452 return simplify(op, ty, l, r);
00453 }
00454
00455
00456 static Tree multree(int op, Tree l, Tree r) {
00457 Type ty = inttype;
00458
00459 if (isarith(l->type) && isarith(r->type)) {
00460 ty = binary(l->type, r->type);
00461 l = cast(l, ty);
00462 r = cast(r, ty);
00463 } else
00464 typeerror(op, l, r);
00465 return simplify(op, ty, l, r);
00466 }
00467
00468
00469 Tree shtree(int op, Tree l, Tree r) {
00470 Type ty = inttype;
00471
00472 if (isint(l->type) && isint(r->type)) {
00473 ty = promote(l->type);
00474 l = cast(l, ty);
00475 r = cast(r, inttype);
00476 } else
00477 typeerror(op, l, r);
00478 return simplify(op, ty, l, r);
00479 }
00480
00481
00482 static Tree subtree(int op, Tree l, Tree r) {
00483 long n;
00484 Type ty = inttype;
00485
00486 if (isarith(l->type) && isarith(r->type)) {
00487 ty = binary(l->type, r->type);
00488 l = cast(l, ty);
00489 r = cast(r, ty);
00490 } else if (isptr(l->type) && !isfunc(l->type->type) && isint(r->type)) {
00491 ty = unqual(l->type);
00492 n = unqual(ty->type)->size;
00493 if (n == 0)
00494 error("unknown size for type `%t'\n", ty->type);
00495 r = cast(r, promote(r->type));
00496 if (n > 1)
00497 r = multree(MUL, cnsttree(signedptr, n), r);
00498 if (isunsigned(r->type))
00499 r = cast(r, unsignedptr);
00500 else
00501 r = cast(r, signedptr);
00502 return simplify(SUB+P, ty, l, r);
00503 } else if (compatible(l->type, r->type)) {
00504 ty = unqual(l->type);
00505 n = unqual(ty->type)->size;
00506 if (n == 0)
00507 error("unknown size for type `%t'\n", ty->type);
00508 l = simplify(SUB+U, unsignedptr,
00509 cast(l, unsignedptr), cast(r, unsignedptr));
00510 return simplify(DIV+I, longtype,
00511 cast(l, longtype), cnsttree(longtype, n));
00512 } else
00513 typeerror(op, l, r);
00514 return simplify(op, ty, l, r);
00515 }
00516
00517
00518 void typeerror(int op, Tree l, Tree r) {
00519 int i;
00520 static struct { int op; char *name; } ops[] = {
00521 ASGN, "=", INDIR, "*", NEG, "-",
00522 ADD, "+", SUB, "-", LSH, "<<",
00523 MOD, "%", RSH, ">>", BAND, "&",
00524 BCOM, "~", BOR, "|", BXOR, "^",
00525 DIV, "/", MUL, "*", EQ, "==",
00526 GE, ">=", GT, ">", LE, "<=",
00527 LT, "<", NE, "!=", AND, "&&",
00528 NOT, "!", OR, "||", COND, "?:",
00529 0, 0
00530 };
00531
00532 op = generic(op);
00533 for (i = 0; ops[i].op; i++)
00534 if (op == ops[i].op)
00535 break;
00536 assert(ops[i].name);
00537 if (r)
00538 error("operands of %s have illegal types `%t' and `%t'\n",
00539 ops[i].name, l->type, r->type);
00540 else
00541 error("operand of unary %s has illegal type `%t'\n", ops[i].name,
00542 l->type);
00543 }