📄 expr.c
字号:
case ID: if (tsym == NULL) { Symbol p = install(token, &identifiers, level, PERM); p->src = src; if (getchr() == '(') { Symbol q = lookup(token, externals); p->type = func(inttype, NULL, 1); p->sclass = EXTERN; if (Aflag >= 1) warning("missing prototype\n"); if (q && !eqtype(q->type, p->type, 1)) warning("implicit declaration of `%s' does not match previous declaration at %w\n", q->name, &q->src); if (q == NULL) { q = install(p->name, &externals, GLOBAL, PERM); q->type = p->type; q->sclass = EXTERN; q->src = src; (*IR->defsymbol)(q); } p->u.alias = q; } else { error("undeclared identifier `%s'\n", p->name); p->sclass = AUTO; p->type = inttype; if (p->scope == GLOBAL) (*IR->defsymbol)(p); else addlocal(p); } t = gettok(); if (xref) use(p, src); return idtree(p); } if (xref) use(tsym, src); if (tsym->sclass == ENUM) p = consttree(tsym->u.value, inttype); else { if (tsym->sclass == TYPEDEF) error("illegal use of type name `%s'\n", tsym->name); p = idtree(tsym); } break; case FIRSTARG: if (level > PARAM && cfunc && cfunc->u.f.callee[0]) p = idtree(cfunc->u.f.callee[0]); else { error("illegal use of `%k'\n", FIRSTARG); p = cnsttree(inttype, 0L); } break; default: error("illegal expression\n"); p = cnsttree(inttype, 0L); } t = gettok(); return p;}Tree idtree(Symbol p) { int op; Tree e; Type ty = p->type ? unqual(p->type) : voidptype; if (p->scope == GLOBAL || p->sclass == STATIC) op = ADDRG; else if (p->scope == PARAM) { op = ADDRF; if (isstruct(p->type) && !IR->wants_argb) { e = tree(mkop(op,voidptype), ptr(ptr(p->type)), NULL, NULL); e->u.sym = p; return rvalue(rvalue(e)); } } else if (p->sclass == EXTERN) { assert(p->u.alias); p = p->u.alias; op = ADDRG; } else op = ADDRL; p->ref += refinc; if (isarray(ty)) e = tree(mkop(op,voidptype), p->type, NULL, NULL); else if (isfunc(ty)) e = tree(mkop(op,funcptype), p->type, NULL, NULL); else e = tree(mkop(op,voidptype), ptr(p->type), NULL, NULL); e->u.sym = p; if (isptr(e->type)) e = rvalue(e); return e;}Tree rvalue(Tree p) { Type ty = deref(p->type); ty = unqual(ty); return tree(mkop(INDIR,ty), ty, p, NULL);}Tree lvalue(Tree p) { if (generic(p->op) != INDIR) { error("lvalue required\n"); return value(p); } else if (unqual(p->type) == voidtype) warning("`%t' used as an lvalue\n", p->type); 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->node = p->node; q->u = p->u; 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) {#define xx(t) if (xty == t || yty == t) return t xx(longdouble); xx(doubletype); xx(floattype); xx(unsignedlonglong); xx(longlong); xx(unsignedlong); if (xty == longtype && yty == unsignedtype || xty == unsignedtype && yty == longtype) if (longtype->size > unsignedtype->size) return longtype; else return unsignedlong; xx(longtype); xx(unsignedtype); return inttype;#undef xx}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); return (*optree[NEQ])(NE, p, consttree(0, inttype));}Tree cast(Tree p, Type type) { Type src, dst; p = value(p); if (p->type == type) return p; dst = unqual(type); src = unqual(p->type); if (src->op != dst->op || src->size != dst->size) { switch (src->op) { case INT: if (src->size < inttype->size) p = simplify(CVI, inttype, p, NULL); break; case UNSIGNED: if (src->size < inttype->size) p = simplify(CVU, inttype, p, NULL); else if (src->size < unsignedtype->size) p = simplify(CVU, unsignedtype, p, NULL); break; case ENUM: p = retype(p, inttype); break; case POINTER: if (isint(dst) && src->size > dst->size) warning("conversion from `%t' to `%t' is undefined\n", p->type, type); p = simplify(CVP, super(src), p, NULL); break; case FLOAT: break; default: assert(0); } { src = unqual(p->type); dst = super(dst); if (src->op != dst->op) switch (src->op) { case INT: p = simplify(CVI, dst, p, NULL); break; case UNSIGNED: if (isfloat(dst)) { Type ssrc = signedint(src); Tree two = cnsttree(longdouble, (long double)2.0); p = (*optree['+'])(ADD, (*optree['*'])(MUL, two, simplify(CVU, ssrc, simplify(RSH, src, p, consttree(1, inttype)), NULL)), simplify(CVU, ssrc, simplify(BAND, src, p, consttree(1, unsignedtype)), NULL)); } else p = simplify(CVU, dst, p, NULL); break; case FLOAT: if (isunsigned(dst)) { Type sdst = signedint(dst); Tree c = cast(cnsttree(longdouble, (long double)sdst->u.sym->u.limits.max.i + 1), src); p = condtree( simplify(GE, src, p, c), (*optree['+'])(ADD, cast(cast(simplify(SUB, src, p, c), sdst), dst), cast(cnsttree(unsignedlong, (unsigned long)sdst->u.sym->u.limits.max.i + 1), dst)), simplify(CVF, sdst, p, NULL)); } else p = simplify(CVF, dst, p, NULL); break; default: assert(0); } dst = unqual(type); } } src = unqual(p->type); switch (src->op) { case INT: if (src->op != dst->op || src->size != dst->size) p = simplify(CVI, dst, p, NULL); break; case UNSIGNED: if (src->op != dst->op || src->size != dst->size) p = simplify(CVU, dst, p, NULL); break; case FLOAT: if (src->op != dst->op || src->size != dst->size) p = simplify(CVF, dst, p, NULL); break; case POINTER: if (src->op != dst->op) p = simplify(CVP, dst, p, NULL); else { if (isfunc(src->type) && !isfunc(dst->type) || !isfunc(src->type) && isfunc(dst->type)) warning("conversion from `%t' to `%t' is compiler dependent\n", p->type, type); if (src->size != dst->size) p = simplify(CVP, dst, p, NULL); } break; default: assert(0); } return retype(p, type);}Tree field(Tree p, const 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 */ p = simplify(ADD+P, ty, p, consttree(q->offset, signedptr)); 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("unknown field `%s' of `%t'\n", name, ty); 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 "a function";}static Tree nullcheck(Tree p) { if (!needconst && YYnull && isptr(p->type)) { p = value(p); if (strcmp(YYnull->name, "_YYnull") == 0) { Symbol t1 = temporary(REGISTER, voidptype); p = tree(RIGHT, p->type, tree(OR, voidtype, cond(asgn(t1, cast(p, voidptype))), vcall(YYnull, voidtype, (file && *file ? pointer(idtree(mkstr(file)->u.c.loc)) : cnsttree(voidptype, NULL)), cnsttree(inttype, (long)lineno) , NULL)), idtree(t1)); } else p = nullcall(p->type, YYnull, p, cnsttree(inttype, 0L)); } return p;}Tree nullcall(Type pty, Symbol f, Tree p, Tree e) { Type ty; if (isarray(pty)) return retype(nullcall(atop(pty), f, p, e), pty); ty = unqual(unqual(p->type)->type); return vcall(f, pty, p, e, cnsttree(inttype, (long)ty->size), cnsttree(inttype, (long)ty->align), (file && *file ? pointer(idtree(mkstr(file)->u.c.loc)) : cnsttree(voidptype, NULL)), cnsttree(inttype, (long)lineno) , NULL);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -