4 static Tree addtree(int, Tree, Tree);
5 static Tree andtree(int, Tree, Tree);
6 static Tree cmptree(int, Tree, Tree);
7 static int compatible(Type, Type);
8 static int isnullptr(Tree e);
9 static Tree multree(int, Tree, Tree);
10 static Tree subtree(int, Tree, Tree);
11 #define isvoidptr(ty) \
12 (isptr(ty) && unqual(ty->type) == voidtype)
14 Tree (*optree[])(int, Tree, Tree) = {
15 #define xx(a,b,c,d,e,f,g) e,
16 #define yy(a,b,c,d,e,f,g) e,
19 Tree call(Tree f, Type fty, Coordinate src) {
21 Tree args = NULL, r = NULL, e;
22 Type *proto, rty = unqual(freturn(fty));
25 if (fty->u.f.oldstyle)
28 proto = fty->u.f.proto;
33 t3 = temporary(AUTO, unqual(rty));
35 error("illegal use of incomplete type `%t'\n", rty);
39 Tree q = pointer(expr1(0));
40 if (proto && *proto && *proto != voidtype)
44 aty = assign(*proto, q);
48 error("type error in argument %d to %s; found `%t' expected `%t'\n", n + 1, funcname(f),
51 if ((isint(q->type) || isenum(q->type))
52 && q->type->size != inttype->size)
53 q = cast(q, promote(q->type));
58 if (!fty->u.f.oldstyle && *proto == NULL)
59 error("too many arguments to %s\n", funcname(f));
61 if (isarray(q->type) || q->type->size == 0)
62 error("type error in argument %d to %s; `%t' is illegal\n", n + 1, funcname(f), q->type);
65 q = cast(q, promote(q->type));
67 if (!IR->wants_argb && isstruct(q->type)) {
71 Symbol t1 = temporary(AUTO, unqual(q->type));
73 q = tree(RIGHT, ptr(t1->type),
74 root(q), lvalue(idtree(t1)));
77 if (q->type->size == 0)
80 r = r ? tree(RIGHT, voidtype, r, q) : q;
81 args = tree(mkop(ARG, q->type), q->type, q, args);
83 if (Aflag >= 2 && n == 32)
84 warning("more than 31 arguments in a call to %s\n",
91 if (proto && *proto && *proto != voidtype)
92 error("insufficient number of arguments to %s\n",
95 args = tree(RIGHT, voidtype, r, args);
96 e = calltree(f, rty, args, t3);
98 apply(events.calls, &src, &e);
101 Tree calltree(Tree f, Type ty, Tree args, Symbol t3) {
105 f = tree(RIGHT, f->type, args, f);
109 tree(CALL+B, ty, f, addrof(idtree(t3))),
114 rty = unqual(ty)->type;
117 p = tree(mkop(CALL, rty), rty, f, NULL);
118 if (isptr(ty) || p->type->size > ty->size)
123 Tree vcall(Symbol func, Type ty, ...) {
125 Tree args = NULL, e, f = pointer(idtree(func)), r = NULL;
127 assert(isfunc(func->type));
129 ty = freturn(func->type);
131 while ((e = va_arg(ap, Tree)) != NULL) {
133 r = r == NULL ? e : tree(RIGHT, voidtype, r, e);
134 args = tree(mkop(ARG, e->type), e->type, e, args);
138 args = tree(RIGHT, voidtype, r, args);
139 return calltree(f, ty, args, NULL);
141 int iscallb(Tree e) {
142 return e->op == RIGHT && e->kids[0] && e->kids[1]
143 && e->kids[0]->op == CALL+B
144 && e->kids[1]->op == INDIR+B
145 && isaddrop(e->kids[1]->kids[0]->op)
146 && e->kids[1]->kids[0]->u.sym->temporary;
149 static Tree addtree(int op, Tree l, Tree r) {
152 if (isarith(l->type) && isarith(r->type)) {
153 ty = binary(l->type, r->type);
156 } else if (isptr(l->type) && isint(r->type))
157 return addtree(ADD, r, l);
158 else if ( isptr(r->type) && isint(l->type)
159 && !isfunc(r->type->type))
162 ty = unqual(r->type);
163 n = unqual(ty->type)->size;
165 error("unknown size for type `%t'\n", ty->type);
166 l = cast(l, promote(l->type));
168 l = multree(MUL, cnsttree(signedptr, n), l);
169 if (YYcheck && !isaddrop(r->op)) /* omit */
170 return nullcall(ty, YYcheck, r, l); /* omit */
171 return simplify(ADD, ty, l, r);
176 return simplify(op, ty, l, r);
179 Tree cnsttree(Type ty, ...) {
180 Tree p = tree(mkop(CNST,ty), ty, NULL, NULL);
185 case INT: p->u.v.i = va_arg(ap, long); break;
186 case UNSIGNED:p->u.v.u = va_arg(ap, unsigned long)&ones(8*ty->size); break;
187 case FLOAT: p->u.v.d = va_arg(ap, double); break;
188 case POINTER: p->u.v.p = va_arg(ap, void *); break;
195 Tree consttree(unsigned n, Type ty) {
198 else assert(isint(ty));
199 return cnsttree(ty, (unsigned long)n);
201 static Tree cmptree(int op, Tree l, Tree r) {
204 if (isarith(l->type) && isarith(r->type)) {
205 ty = binary(l->type, r->type);
208 } else if (compatible(l->type, r->type)) {
216 return simplify(mkop(op,ty), inttype, l, r);
218 static int compatible(Type ty1, Type ty2) {
219 return isptr(ty1) && !isfunc(ty1->type)
220 && isptr(ty2) && !isfunc(ty2->type)
221 && eqtype(unqual(ty1->type), unqual(ty2->type), 0);
223 static int isnullptr(Tree e) {
224 Type ty = unqual(e->type);
226 return generic(e->op) == CNST
227 && ((ty->op == INT && e->u.v.i == 0)
228 || (ty->op == UNSIGNED && e->u.v.u == 0)
229 || (isvoidptr(ty) && e->u.v.p == NULL));
231 Tree eqtree(int op, Tree l, Tree r) {
232 Type xty = l->type, yty = r->type;
234 if ((isptr(xty) && isnullptr(r))
235 || (isptr(xty) && !isfunc(xty->type) && isvoidptr(yty))
236 || (isptr(xty) && isptr(yty)
237 && eqtype(unqual(xty->type), unqual(yty->type), 1))) {
238 Type ty = unsignedptr;
241 return simplify(mkop(op,ty), inttype, l, r);
243 if ((isptr(yty) && isnullptr(l))
244 || (isptr(yty) && !isfunc(yty->type) && isvoidptr(xty)))
245 return eqtree(op, r, l);
246 return cmptree(op, l, r);
249 Type assign(Type xty, Tree e) {
250 Type yty = unqual(e->type);
255 if (xty->size == 0 || yty->size == 0)
257 if ( (isarith(xty) && isarith(yty))
258 || (isstruct(xty) && xty == yty))
260 if (isptr(xty) && isnullptr(e))
262 if (((isvoidptr(xty) && isptr(yty))
263 || (isptr(xty) && isvoidptr(yty)))
264 && ( (isconst(xty->type) || !isconst(yty->type))
265 && (isvolatile(xty->type) || !isvolatile(yty->type))))
268 if ((isptr(xty) && isptr(yty)
269 && eqtype(unqual(xty->type), unqual(yty->type), 1))
270 && ( (isconst(xty->type) || !isconst(yty->type))
271 && (isvolatile(xty->type) || !isvolatile(yty->type))))
273 if (isptr(xty) && isptr(yty)
274 && ( (isconst(xty->type) || !isconst(yty->type))
275 && (isvolatile(xty->type) || !isvolatile(yty->type)))) {
276 Type lty = unqual(xty->type), rty = unqual(yty->type);
277 if ((isenum(lty) && rty == inttype)
278 || (isenum(rty) && lty == inttype)) {
280 warning("assignment between `%t' and `%t' is compiler-dependent\n",
287 Tree asgntree(int op, Tree l, Tree r) {
291 ty = assign(l->type, r);
295 typeerror(ASGN, l, r);
296 if (r->type == voidtype)
297 r = retype(r, inttype);
304 aty = unqual(aty)->type;
306 || (isstruct(aty) && unqual(aty)->u.sym->u.s.cfields)) {
308 && !l->u.sym->computed && !l->u.sym->generated)
309 error("assignment to const identifier `%s'\n",
312 error("assignment to const location\n");
314 if (l->op == FIELD) {
315 long n = 8*l->u.field->type->size - fieldsize(l->u.field);
316 if (n > 0 && isunsigned(l->u.field->type))
318 cnsttree(r->type, (unsigned long)fieldmask(l->u.field)));
320 if (r->op == CNST+I) {
322 if (n&(1<<(fieldsize(l->u.field)-1)))
323 n |= ~0UL<<fieldsize(l->u.field);
324 r = cnsttree(r->type, n);
327 shtree(LSH, r, cnsttree(inttype, n)),
328 cnsttree(inttype, n));
331 if (isstruct(ty) && isaddrop(l->op) && iscallb(r))
332 return tree(RIGHT, ty,
333 tree(CALL+B, ty, r->kids[0]->kids[0], l),
335 return tree(mkop(op,ty), ty, l, r);
337 Tree condtree(Tree e, Tree l, Tree r) {
339 Type ty, xty = l->type, yty = r->type;
342 if (isarith(xty) && isarith(yty))
343 ty = binary(xty, yty);
344 else if (eqtype(xty, yty, 1))
346 else if (isptr(xty) && isnullptr(r))
348 else if (isnullptr(l) && isptr(yty))
350 else if ((isptr(xty) && !isfunc(xty->type) && isvoidptr(yty))
351 || (isptr(yty) && !isfunc(yty->type) && isvoidptr(xty)))
353 else if ((isptr(xty) && isptr(yty)
354 && eqtype(unqual(xty->type), unqual(yty->type), 1)))
357 typeerror(COND, l, r);
358 return consttree(0, inttype);
361 ty = unqual(unqual(ty)->type);
362 if ((isptr(xty) && isconst(unqual(xty)->type))
363 || (isptr(yty) && isconst(unqual(yty)->type)))
364 ty = qual(CONST, ty);
365 if ((isptr(xty) && isvolatile(unqual(xty)->type))
366 || (isptr(yty) && isvolatile(unqual(yty)->type)))
367 ty = qual(VOLATILE, ty);
371 case CNST+I: return cast(e->u.v.i != 0 ? l : r, ty);
372 case CNST+U: return cast(e->u.v.u != 0 ? l : r, ty);
373 case CNST+P: return cast(e->u.v.p != 0 ? l : r, ty);
374 case CNST+F: return cast(e->u.v.d != 0.0 ? l : r, ty);
376 if (ty != voidtype && ty->size > 0) {
377 t1 = genident(REGISTER, unqual(ty), level);
378 /* t1 = temporary(REGISTER, unqual(ty)); */
383 p = tree(COND, ty, cond(e),
384 tree(RIGHT, ty, root(l), root(r)));
388 /* addrof - address of p */
389 Tree addrof(Tree p) {
393 switch (generic(q->op)) {
395 assert(q->kids[0] || q->kids[1]);
396 q = q->kids[1] ? q->kids[1] : q->kids[0];
402 Symbol t1 = q->u.sym;
411 return tree(RIGHT, q->type, root(p), q);
413 error("addressable object required\n");
418 /* andtree - construct tree for l [&& ||] r */
419 static Tree andtree(int op, Tree l, Tree r) {
420 if (!isscalar(l->type) || !isscalar(r->type))
422 return simplify(op, inttype, cond(l), cond(r));
425 /* asgn - generate tree for assignment of expr e to symbol p sans qualifiers */
426 Tree asgn(Symbol p, Tree e) {
427 if (isarray(p->type))
428 e = tree(ASGN+B, p->type, idtree(p),
429 tree(INDIR+B, e->type, e, NULL));
432 p->type = unqual(p->type);
433 if (isstruct(p->type) && p->type->u.sym->u.s.cfields) {
434 p->type->u.sym->u.s.cfields = 0;
435 e = asgntree(ASGN, idtree(p), e);
436 p->type->u.sym->u.s.cfields = 1;
438 e = asgntree(ASGN, idtree(p), e);
444 /* bittree - construct tree for l [& | ^ %] r */
445 Tree bittree(int op, Tree l, Tree r) {
448 if (isint(l->type) && isint(r->type)) {
449 ty = binary(l->type, r->type);
454 return simplify(op, ty, l, r);
457 /* multree - construct tree for l [* /] r */
458 static Tree multree(int op, Tree l, Tree r) {
461 if (isarith(l->type) && isarith(r->type)) {
462 ty = binary(l->type, r->type);
467 return simplify(op, ty, l, r);
470 /* shtree - construct tree for l [>> <<] r */
471 Tree shtree(int op, Tree l, Tree r) {
474 if (isint(l->type) && isint(r->type)) {
475 ty = promote(l->type);
477 r = cast(r, inttype);
480 return simplify(op, ty, l, r);
483 /* subtree - construct tree for l - r */
484 static Tree subtree(int op, Tree l, Tree r) {
488 if (isarith(l->type) && isarith(r->type)) {
489 ty = binary(l->type, r->type);
492 } else if (isptr(l->type) && !isfunc(l->type->type) && isint(r->type)) {
493 ty = unqual(l->type);
494 n = unqual(ty->type)->size;
496 error("unknown size for type `%t'\n", ty->type);
497 r = cast(r, promote(r->type));
499 r = multree(MUL, cnsttree(signedptr, n), r);
500 if (isunsigned(r->type))
501 r = cast(r, unsignedptr);
503 r = cast(r, signedptr);
504 return simplify(SUB+P, ty, l, r);
505 } else if (compatible(l->type, r->type)) {
506 ty = unqual(l->type);
507 n = unqual(ty->type)->size;
509 error("unknown size for type `%t'\n", ty->type);
510 l = simplify(SUB+U, unsignedptr,
511 cast(l, unsignedptr), cast(r, unsignedptr));
512 return simplify(DIV+I, longtype,
513 cast(l, longtype), cnsttree(longtype, n));
516 return simplify(op, ty, l, r);
519 /* typeerror - issue "operands of op have illegal types `l' and `r'" */
520 void typeerror(int op, Tree l, Tree r) {
522 static struct { int op; char *name; } ops[] = {
523 {ASGN, "="}, {INDIR, "*"}, {NEG, "-"},
524 {ADD, "+"}, {SUB, "-"}, {LSH, "<<"},
525 {MOD, "%"}, {RSH, ">>"}, {BAND, "&"},
526 {BCOM, "~"}, {BOR, "|"}, {BXOR, "^"},
527 {DIV, "/"}, {MUL, "*"}, {EQ, "=="},
528 {GE, ">="}, {GT, ">"}, {LE, "<="},
529 {LT, "<"}, {NE, "!="}, {AND, "&&"},
530 {NOT, "!"}, {OR, "||"}, {COND, "?:"},
535 for (i = 0; ops[i].op; i++)
540 error("operands of %s have illegal types `%t' and `%t'\n",
541 ops[i].name, l->type, r->type);
543 error("operand of unary %s has illegal type `%t'\n", ops[i].name,