📄 expr.c
字号:
t = gettok();
} else
error(StrTab[260]); break;// <field name expected\n>
default:
return p;
}
}
static Tree primary(void)
{
Tree p;
assert(t != '(');
switch (t) {
case ICON:
case FCON: p = tree(CNST + ttob(tsym->type), tsym->type, NULL, NULL);
p->u.v = tsym->u.c.v;
break;
case SCON: tsym->u.c.v.p = stringn(tsym->u.c.v.p, tsym->type->size);
tsym = constant(tsym->type, tsym->u.c.v);
if (tsym->u.c.loc == NULL)
tsym->u.c.loc = genident(STATIC, tsym->type, GLOBAL);
tsym->u.c.loc->isconstant = 1;
tsym->u.c.loc->x.ArraySymbol = tsym;
p = idtree(tsym->u.c.loc); break;
case ID: if (tsym == NULL)
{
Symbol q = install(token, &identifiers, level, level < LOCAL ? PERM : FUNC);
q->src = src;
t = gettok();
if (t == '(') {
Symbol r;
q->sclass = EXTERN;
q->type = func(inttype, NULL, 1);
if (Aflag >= 1)
warning(StrTab[261]);// <missing prototype\n>
(*IR->defsymbol)(q);
if ((r = lookup(q->name, externals)) != NULL) {
q->defined = r->defined;
q->temporary = r->temporary;
q->generated = r->generated;
q->computed = r->computed;
q->addressed = r->addressed;
} else {
r = install(q->name, &externals, GLOBAL, PERM);
r->src = q->src;
r->type = q->type;
r->sclass = EXTERN;
}
} else {
error(StrTab[262], q->name);// <undeclared identifier `%s'\n>
q->sclass = AUTO;
q->type = inttype;
if (q->scope == GLOBAL)
(*IR->defsymbol)(q);
else
addlocal(q);
}
if (xref)
use(q, src);
return idtree(q);
}
if (xref)
use(tsym, src);
if (tsym->sclass == ENUM)
p = consttree(tsym->u.value, inttype);
else {
if (tsym->sclass == TYPEDEF)
error(StrTab[263], tsym->name);// <illegal use of type name `%s'\n>
p = idtree(tsym);
} break;
default:
error(StrTab[264]);// <illegal expression\n>
p = consttree(0, inttype);
}
t = gettok();
return p;
}
Tree idtree(Symbol p)
{
int op;
Tree e;
Type ty = p->type ? unqual(p->type) : voidtype;
p->ref += refinc;
p->lastuse = StatementCount;
if (p->firstuse == 0)
p->firstuse = p->lastuse;
p->references++;
if (p->scope == GLOBAL
|| p->sclass == STATIC || p->sclass == EXTERN)
op = ADDRG+P;
else if (p->scope == PARAM) {
op = ADDRF+P;
if (isstruct(p->type) && !IR->wants_argb)
{
e = tree(op, ptr(ptr(p->type)), NULL, NULL);
e->u.sym = p;
return rvalue(rvalue(e));
}
} else
op = ADDRL+P;
if (isarray(ty) || isfunc(ty)) {
e = tree(op, p->type, NULL, NULL);
e->u.sym = p;
} else {
e = tree(op, ptr(p->type), NULL, NULL);
e->u.sym = p;
e = rvalue(e);
}
if (p->Flags) e->Flags = p->Flags;
return e;
}
Tree rvalue(Tree p)
{
Type ty = deref(p->type);
ty = unqual(ty);
if (YYnull && !isaddrop(p->op)) /* omit */
p = nullcheck(p); /* omit */
return tree(INDIR + (isunsigned(ty) ? I : ttob(ty)),
ty, p, NULL);
}
Tree lvalue(Tree p)
{
if (generic(p->op) != INDIR) {
error(StrTab[265]);// <lvalue required\n>
return value(p);
} else if (unqual(p->type) == voidtype)
warning(StrTab[266], p->type);// <`%t' used as an lvalue\n>
return p->kids[0];
}
Tree retype(Tree p,Type ty)
{
Tree q;
if (p->type == ty)
return p;
q = tree(p->op, ty, p->kids[0], p->kids[1]);
q->u = p->u;
q->Flags = p->Flags;
return q;
}
Tree rightkid(Tree p)
{
while (p && p->op == RIGHT)
if (p->kids[1])
p = p->kids[1];
else if (p->kids[0])
p = p->kids[0];
else
assert(0);
assert(p);
return p;
}
int hascall(Tree p)
{
if (p == 0)
return 0;
if (generic(p->op) == CALL || (IR->mulops_calls &&
(p->op == DIV+I || p->op == MOD+I || p->op == MUL+I
|| p->op == DIV+U || p->op == MOD+U || p->op == MUL+U)))
return 1;
return hascall(p->kids[0]) || hascall(p->kids[1]);
}
Type binary(Type xty,Type yty)
{
if (isdouble(xty) || isdouble(yty))
return doubletype;
if (xty == floattype || yty == floattype)
return floattype;
if (isunsigned(xty) || isunsigned(yty))
return unsignedtype;
if (xty == longlongtype || yty == longlongtype)
return longlongtype;
return inttype;
}
Tree pointer(Tree p)
{
if (isarray(p->type))
/* assert(p->op != RIGHT || p->u.sym == NULL), */
p = retype(p, atop(p->type));
else if (isfunc(p->type))
p = retype(p, ptr(p->type));
return p;
}
Tree cond(Tree p)
{
int op = generic(rightkid(p)->op);
if (op == AND || op == OR || op == NOT
|| op == EQ || op == NE
|| op == LE || op == LT || op == GE || op == GT)
return p;
p = pointer(p);
p = cast(p, promote(p->type));
return (*optree[NEQ])(NE, p, consttree(0, inttype));
}
Tree cast(Tree p,Type type)
{
Type pty, ty = unqual(type);
p = value(p);
if (p->type == type)
return p;
pty = unqual(p->type);
if (pty == ty)
return retype(p, type);
#if 0
if (Xflag && isstruct(pty) && isstruct(ty) && extends(pty, ty)) {
Field q = extends(pty, ty);
return rvalue(simplify(ADD+P, ptr(ty), addrof(p),
consttree(q->offset, inttype)));
}
#endif
switch (pty->op) {
case CHAR: p = simplify(CVC, super(pty), p, NULL); break;
case SHORT: p = simplify(CVS, super(pty), p, NULL); break;
case FLOAT: p = simplify(CVF, doubletype, p, NULL); break;
case INT: p = retype(p, inttype); break;
case DOUBLE: p = retype(p, doubletype); break;
case LONGLONG: p = retype(p,longlongtype); break;
case ENUM: p = retype(p, inttype); break;
case UNSIGNED:p = retype(p, unsignedtype); break;
case POINTER:
if (isptr(ty)) {
#if 0
Field q;
if (Xflag && isstruct(pty->type) && isstruct(ty->type)
&& (q = extends(pty->type, ty->type)) != NULL)
return simplify(ADD+P, ty, p, consttree(q->offset, inttype));
#endif
if (isfunc(pty->type) && !isfunc(ty->type)
|| !isfunc(pty->type) && isfunc(ty->type)) {
if (Aflag > 0 && !(pty->type == voidtype || ty->type == voidtype))
warning(StrTab[267], p->type, ty);// <conversion from `%t' to `%t' is compiler dependent\n>
}
return retype(p, type);
} else
p = simplify(CVP, unsignedtype, p, NULL);
break;
default: assert(0);
}
{
Type sty = super(ty);
pty = p->type;
if (pty != sty)
if (pty == inttype)
p = simplify(CVI, sty, p, NULL);
else if (pty == longlongtype) {
p = simplify(CVL,sty,p,NULL);
}
else if (pty == doubletype)
if (sty == unsignedtype) {
Tree c = tree(CNST+D, doubletype, NULL, NULL);
c->u.v.d = (double)INT_MAX + 1;
p = condtree(
simplify(GE, doubletype, p, c),
(*optree['+'])(ADD,
cast(cast(simplify(SUB, doubletype, p, c), inttype), unsignedtype),
consttree((unsigned)INT_MAX + 1, unsignedtype)),
simplify(CVD, inttype, p, NULL));
} else
p = simplify(CVD, sty, p, NULL);
else if (pty == unsignedtype)
if (sty == doubletype) {
#if 0
Tree two = tree(CNST+D, doubletype, NULL, NULL);
two->u.v.d = 2.;
p = (*optree['+'])(ADD,
(*optree['*'])(MUL,
two,
simplify(CVU, inttype,
simplify(RSH, unsignedtype,
p, consttree(1, inttype)), NULL)),
simplify(CVU, inttype,
simplify(BAND, unsignedtype,
p, consttree(1, unsignedtype)), NULL));
#else
p = simplify(CVU,sty,p,NULL);
#endif
}
else
p = simplify(CVU, sty, p, NULL);
else assert(0);
}
if (ty == signedchar || ty == chartype || ty == shorttype)
p = simplify(CVI, type, p, NULL);
else if (isptr(ty)
|| ty == unsignedchar || ty == unsignedshort)
p = simplify(CVU, type, p, NULL);
else if (ty == floattype)
p = simplify(CVD, type, p, NULL);
else
p = retype(p, type);
return p;
}
static Type super(Type ty)
{
if (ty == signedchar || ty == chartype || isenum(ty)
|| ty == shorttype || ty == inttype || ty == longtype)
return inttype;
if (isptr(ty)
|| ty == unsignedtype || ty == unsignedchar
|| ty == unsignedshort || ty == unsignedlong)
return unsignedtype;
if (ty == longlongtype)
return longlongtype;
if (ty == floattype || ty == doubletype
|| ty == longdouble || ty == ulonglongtype)
return doubletype;
assert(0);
return NULL;
}
Tree field(Tree p,char *name)
{
Field q;
Type ty1, ty = p->type;
if (isptr(ty))
ty = deref(ty);
ty1 = ty;
ty = unqual(ty);
if ((q = fieldref(name, ty)) != NULL) {
if (isarray(q->type)) {
ty = q->type->type;
if (isconst(ty1) && !isconst(ty))
ty = qual(CONST, ty);
if (isvolatile(ty1) && !isvolatile(ty))
ty = qual(VOLATILE, ty);
ty = array(ty, q->type->size/ty->size, q->type->align);
} else {
ty = q->type;
if (isconst(ty1) && !isconst(ty))
ty = qual(CONST, ty);
if (isvolatile(ty1) && !isvolatile(ty))
ty = qual(VOLATILE, ty);
ty = ptr(ty);
}
if (YYcheck && !isaddrop(p->op) && q->offset > 0) /* omit */
p = nullcall(ty, YYcheck, p, consttree(q->offset, inttype)); /* omit */
else { /* omit */
if (q->offset != 0)
p = simplify(ADD+P, ty, p, consttree(q->offset, inttype));
else
p = retype(p,ty);
}
if (q->lsb) {
p = tree(FIELD, ty->type, rvalue(p), NULL);
p->u.field = q;
} else if (!isarray(q->type))
p = rvalue(p);
} else {
error(StrTab[268], name, ty);// <unknown field `%s' of `%t'\n>
p = rvalue(retype(p, ptr(inttype)));
}
return p;
}
/* funcname - return name of function f or a function' */
char *funcname(Tree f)
{
if (isaddrop(f->op))
return stringf("`%s'", f->u.sym->name);
return StrTab[269];// <a function>
}
static Tree nullcheck(Tree p)
{
if (!needconst && YYnull) {
p = value(p);
if (strcmp(YYnull->name, "_YYnull") == 0) {
Symbol t1 = temporary(REGISTER, voidptype, level);
p = tree(RIGHT, p->type,
tree(OR, voidtype,
cond(asgn(t1, cast(p, voidptype))),
calltree(pointer(idtree(YYnull)), voidtype,
tree(ARG+I, inttype,
consttree(lineno, inttype), NULL), NULL)),
idtree(t1));
}
else
p = nullcall(p->type, YYnull, p, consttree(0, inttype));
}
return p;
}
Tree nullcall(Type pty,Symbol f,Tree p,Tree e)
{
Tree fp, r;
Type ty;
if (isarray(pty))
return retype(nullcall(atop(pty), f, p, e), pty);
ty = unqual(unqual(p->type)->type);
if (file && *file)
fp = idtree(mkstr(file)->u.c.loc);
else
fp = cast(consttree(0, inttype), voidptype);
r = calltree(pointer(idtree(f)), pty,
tree( ARG+I, inttype, consttree(lineno, inttype), tree(
ARG+P, ptr(chartype), fp, tree(
ARG+I, unsignedtype, consttree(ty->align, unsignedtype), tree(
ARG+I, unsignedtype, consttree(ty->size, unsignedtype), tree(
ARG+I, inttype, e, tree(
ARG+P, p->type, p, NULL) ))))),
NULL);
if (hascall(e))
r = tree(RIGHT, r->type, e, r);
if (hascall(p))
r = tree(RIGHT, r->type, p, r);
return r;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -