📄 enode.c
字号:
if (isenum(lty) && rty == inttype
|| isenum(rty) && lty == inttype) {
if (Aflag >= 1)
warning(StrTab[288],// <assignment between `%t' and `%t' is compiler-dependent\n>
xty, yty);
return xty;
}
}
/* Any pointer can be assigned to any other This is a laxist
point of view... jn */
if (isptr(xty) && isptr(yty)) {
Type t1,t2;
t1 = unqual(xty->type);
t2 = unqual(yty->type);
if (t1 != t2 && !eqtype(t1,t2,1)) {
if ((t1 != signedchar && t1 != unsignedchar) &&
(t2 != signedchar && t2 != unsignedchar))
warning(StrTab[289],xty,yty);// <assignment of %t to %t\n>
}
return xty;
}
return NULL;
}
Tree asgntree(int op,Tree l,Tree r)
{
Type aty, ty;
r = pointer(r);
ty = assign(l->type, r);
if (ty)
r = cast(r, ty);
else {
if (isptr(l->type) && isptr(r->type)) {
typewarning(ASGN,l,r);
}
else
typeerror(ASGN, l, r);
if (r->type == voidtype)
r = retype(r, inttype);
ty = r->type;
}
if (l->op != FIELD)
l = lvalue(l);
aty = l->type;
if (isptr(aty))
aty = unqual(aty)->type;
if ( isconst(aty)
|| isstruct(aty) && unqual(aty)->u.sym->u.s.cfields)
if (isaddrop(l->op)
&& !l->u.sym->computed && !l->u.sym->generated)
error(StrTab[290],// <assignment to const identifier `%s'\n>
l->u.sym->name);
else
error(StrTab[291]);// <assignment to const location\n>
if (l->op == FIELD) {
int n = 8*l->u.field->type->size - fieldsize(l->u.field);
if (n > 0 && isunsigned(l->u.field->type))
r = bittree(BAND, r,
consttree(fieldmask(l->u.field), unsignedtype));
else if (n > 0) {
if (r->op == CNST+I)
r = consttree(r->u.v.i<<n, inttype);
else
r = shtree(LSH, r, consttree(n, inttype));
r = shtree(RSH, r, consttree(n, inttype));
}
}
if (isstruct(ty) && isaddrop(l->op) && iscallb(r))
return tree(RIGHT, ty,
tree(CALL+B, ty, r->kids[0]->kids[0], l),
idtree(l->u.sym));
return tree(op + (isunsigned(ty) ? I : ttob(ty)),
ty, l, r);
}
Tree condtree(Tree e,Tree l,Tree r)
{
Symbol t1;
Type ty, xty = l->type, yty = r->type;
Tree p;
if (isarith(xty) && isarith(yty))
ty = binary(xty, yty);
else if (eqtype(xty, yty, 1))
ty = unqual(xty);
else if (isptr(xty) && isnullptr(r))
ty = xty;
else if (isnullptr(l) && isptr(yty))
ty = yty;
else if (isptr(xty) && !isfunc(xty->type) && isvoidptr(yty)
|| isptr(yty) && !isfunc(yty->type) && isvoidptr(xty))
ty = voidptype;
else if ((isptr(xty) && isptr(yty)
&& eqtype(unqual(xty->type), unqual(yty->type), 1)))
ty = xty;
else {
typeerror(COND, l, r);
return consttree(0, inttype);
}
if (isptr(ty)) {
ty = unqual(unqual(ty)->type);
if (isptr(xty) && isconst(unqual(xty)->type)
|| isptr(yty) && isconst(unqual(yty)->type))
ty = qual(CONST, ty);
if (isptr(xty) && isvolatile(unqual(xty)->type)
|| isptr(yty) && isvolatile(unqual(yty)->type))
ty = qual(VOLATILE, ty);
ty = ptr(ty);
}
if (e->op == CNST+D || e->op == CNST+F) {
e = cast(e, doubletype);
return retype(e->u.v.d != 0.0 ? l : r, ty);
}
if (generic(e->op) == CNST) {
e = cast(e, unsignedtype);
return retype(e->u.v.u ? l : r, ty);
}
if (ty != voidtype && ty->size > 0) {
/*
Here was asked for a REGISTER temporary. This could lead to
that register never being freed. I changed it to AUTO instead
*/
t1 = temporary(REGISTER, unqual(ty), level);
l = asgn(t1, l);
r = asgn(t1, r);
} else
t1 = NULL;
p = tree(COND, ty, cond(e),
tree(RIGHT, ty, root(l), root(r)));
p->u.sym = t1;
return p;
}
/* addrof - address of p */
Tree addrof(Tree p)
{
Tree q = p;
for (;;)
switch (generic(q->op)) {
case RIGHT:
assert(q->kids[0] || q->kids[1]);
q = q->kids[1] ? q->kids[1] : q->kids[0];
continue;
case ASGN:
q = q->kids[1];
continue;
case COND: {
Symbol t1 = q->u.sym;
q->u.sym = 0;
q = idtree(t1);
/* fall thru */
}
case INDIR:
if (p == q)
return q->kids[0];
q = q->kids[0];
return tree(RIGHT, q->type, root(p), q);
default:
error(StrTab[292]);// <addressable object required\n>
return value(p);
}
}
/* andtree - construct tree for l [&& ||] r */
static Tree andtree(int op,Tree l,Tree r)
{
if (!isscalar(l->type) || !isscalar(r->type))
typeerror(op, l, r);
return simplify(op, inttype, cond(l), cond(r));
}
/* asgn - generate tree for assignment of expr e to symbol p sans qualifiers */
Tree asgn(Symbol p,Tree e)
{
if (isarray(p->type))
e = tree(ASGN+B, p->type, idtree(p),
tree(INDIR+B, e->type, e, NULL));
else {
Type ty = p->type;
p->type = unqual(p->type);
if (isstruct(p->type) && p->type->u.sym->u.s.cfields) {
p->type->u.sym->u.s.cfields = 0;
e = asgntree(ASGN, idtree(p), e);
p->type->u.sym->u.s.cfields = 1;
} else
e = asgntree(ASGN, idtree(p), e);
p->type = ty;
}
return e;
}
/* bittree - construct tree for l [& | ^ %] r */
Tree bittree(int op,Tree l,Tree r)
{
Type ty = inttype;
if (l->type == longlongtype || l->type == ulonglongtype) {
ty = ulonglongtype;
op = generic(op)+L;
r = cast(r,longlongtype);
}
if ((isint(l->type) && isint(r->type)) ||
((l->type == longlongtype || l->type == ulonglongtype)
&& isint(r->type)) ||
(l->type == longlongtype && r->type == longlongtype) ||
(l->type == ulonglongtype && r->type == ulonglongtype) ||
(l->type == longlongtype && r->type == ulonglongtype) ||
(l->type == ulonglongtype && r->type == longlongtype) ||
(isint(l->type) && (r->type == longlongtype ||
r->type == ulonglongtype))) {
ty = binary(l->type, r->type);
l = cast(l, ty);
r = cast(r, ty);
if (op != MOD && (l->type != ulonglongtype && l->type != longlongtype)) {
l = cast(l, unsignedtype);
r = cast(r, unsignedtype);
}
} else
typeerror(op, l, r);
if (op == MOD)
return simplify(op, ty, l, r);
else if (l->type == ulonglongtype || l->type == longlongtype)
return cast(simplify(op, ulonglongtype, l, r), ty);
return cast(simplify(op, unsignedtype, l, r), ty);
}
/* multree - construct tree for l [* /] r */
static Tree multree(int op,Tree l,Tree r)
{
Type ty = inttype;
if (isarith(l->type) && isarith(r->type)) {
ty = binary(l->type, r->type);
l = cast(l, ty);
r = cast(r, ty);
} else
typeerror(op, l, r);
return simplify(op, ty, l, r);
}
/* shtree - construct tree for l [>> <<] r */
Tree shtree(int op,Tree l,Tree r)
{
Type ty = inttype;
if (isint(l->type) && isint(r->type)) {
ty = promote(l->type);
l = cast(l, ty);
r = cast(r, inttype);
}
else if ((l->type == ulonglongtype || l->type == longlongtype)
&& ((r->type == ulonglongtype || r->type == longlongtype) ||
isint(r->type)))
return simplify((op == LSH)?LSHL:RSHL,l->type,l,r);
else
typeerror(op, l, r);
return simplify(op, ty, l, r);
}
/* subtree - construct tree for l - r */
static Tree subtree(int op,Tree l,Tree r)
{
int n;
Type ty = inttype;
if (isarith(l->type) && isarith(r->type)) {
ty = binary(l->type, r->type);
l = cast(l, ty);
r = cast(r, ty);
} else if (isptr(l->type) && !isfunc(l->type->type) && isint(r->type)) {
ty = unqual(l->type);
n = ty->type->size;
if (n == 0)
error(StrTab[293], ty->type);// <unknown size for type `%t'\n>
r = cast(r, promote(r->type));
if (n > 1)
r = multree(MUL, consttree(n, inttype), r);
return simplify(SUB+P, ty, l, r);
} else if (compatible(l->type, r->type)) {
ty = unqual(l->type);
n = ty->type->size;
if (n == 0)
error(StrTab[294], ty->type);// <unknown size for type `%t'\n>
l = simplify(SUB+U, unsignedtype, cast(l, unsignedtype),
cast(r, unsignedtype));
return simplify(DIV+I, inttype, cast(l, inttype), consttree(n, inttype));
} else
typeerror(op, l, r);
return simplify(op, ty, l, r);
}
static struct { int op; char *name; } ops[] = {
ASGN, "=", INDIR, "*", NEG, "-",
ADD, "+", SUB, "-", LSH, "<<",
MOD, "%", RSH, ">>", BAND, "&",
BCOM, "~", BOR, "|", BXOR, "^",
DIV, "/", MUL, "*", EQ, "==",
GE, ">=", GT, ">", LE, "<=",
LT, "<", NE, "!=", AND, "&&",
NOT, "!", OR, "||", COND, "?:",
0, 0
};
/* typeerror - issue "operands of op have illegal types `l' and `r'" */
void typeerror(int op,Tree l,Tree r) {
int i;
op = generic(op);
for (i = 0; ops[i].op; i++)
if (op == ops[i].op)
break;
assert(ops[i].name);
if (r)
error(StrTab[295],// <operands of %s have illegal types `%t' and `%t'\n>
ops[i].name, l->type, r->type);
else
error(StrTab[296], ops[i].name,// <operand of unary %s has illegal type `%t'\n>
l->type);
}
/* typewarning - issue "operands of op have different types `l' and `r'" */
void typewarning(int op,Tree l,Tree r) {
int i;
op = generic(op);
for (i = 0; ops[i].op; i++)
if (op == ops[i].op)
break;
assert(ops[i].name);
assert(r);
warning(StrTab[297],// <operands of %s have different types `%t' and `%t'\n>
ops[i].name, l->type, r->type);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -