static AstExpression CheckAddOP(AstExpression expr) { Type ty1, ty2; if (expr->kids[0]->op == OP_CONST) { SWAP_KIDS(expr); } ty1 = expr->kids[0]->ty; ty2 = expr->kids[1]->ty; if (BothArithType(ty1, ty2)) { PERFORM_ARITH_CONVERSION(expr); return FoldConstant(expr); } if (IsObjectPtr(ty2) && IsIntegType(ty1)) { SWAP_KIDS(expr); ty1 = expr->kids[0]->ty; goto left_ptr; } if (IsObjectPtr(ty1) && IsIntegType(ty2)) { left_ptr: expr->kids[1] = DoIntegerPromotion(expr->kids[1]); expr->kids[1] = ScalePointerOffset(expr->kids[1], ty1->bty->size); expr->ty = ty1; return expr; } REPORT_OP_ERROR; }
static AstExpression CheckSubOP(AstExpression expr) { Type ty1, ty2; ty1 = expr->kids[0]->ty; ty2 = expr->kids[1]->ty; if (BothArithType(ty1, ty2)) { PERFORM_ARITH_CONVERSION(expr); return FoldConstant(expr); } if (IsObjectPtr(ty1) && IsIntegType(ty2)) { expr->kids[1] = DoIntegerPromotion(expr->kids[1]); expr->kids[1] = ScalePointerOffset(expr->kids[1], ty1->bty->size); expr->ty = ty1; return expr; } if (IsCompatiblePtr(ty1, ty2)) { expr->ty = T(INT); expr = PointerDifference(expr, ty1->bty->size); return expr; } REPORT_OP_ERROR; }
AstExpression CheckConstantExpression(AstExpression expr) { expr = CheckExpression(expr); if (! (expr->op == OP_CONST && IsIntegType(expr->ty))) { return NULL; } return expr; }
int CanAssign(Type lty, AstExpression expr) { Type rty = expr->ty; lty = Unqual(lty); rty = Unqual(rty); if (lty == rty) { return 1; } if (BothArithType(lty, rty)) { return 1; } if (IsCompatiblePtr(lty, rty) && ((lty->bty->qual & rty->bty->qual) == rty->bty->qual)) { return 1; } if ((NotFunctionPtr(lty) && IsVoidPtr(rty) || NotFunctionPtr(rty) && IsVoidPtr(lty))&& ((lty->bty->qual & rty->bty->qual) == rty->bty->qual)) { return 1; } if (IsPtrType(lty) && IsNullConstant(expr)) { return 1; } if (IsPtrType(lty) && IsPtrType(rty)) { //Warning(&expr->coord, "assignment from incompatible pointer type"); return 1; } if ((IsPtrType(lty) && IsIntegType(rty) || IsPtrType(rty) && IsIntegType(lty))&& (lty->size == rty->size)) { Warning(&expr->coord, "conversion between pointer and integer without a cast"); return 1; } return 0; }
static AstExpression CheckPostfixExpression(AstExpression expr) { switch (expr->op) { case OP_INDEX: expr->kids[0] = Adjust(CheckExpression(expr->kids[0]), 1); expr->kids[1] = Adjust(CheckExpression(expr->kids[1]), 1); if (IsIntegType(expr->kids[0]->ty)) { SWAP_KIDS(expr); } if (IsObjectPtr(expr->kids[0]->ty) && IsIntegType(expr->kids[1]->ty)) { expr->ty = expr->kids[0]->ty->bty; expr->lvalue = 1; expr->kids[1] = DoIntegerPromotion(expr->kids[1]); expr->kids[1] = ScalePointerOffset(expr->kids[1], expr->ty->size); return expr; } REPORT_OP_ERROR; case OP_CALL: return CheckFunctionCall(expr); case OP_MEMBER: case OP_PTR_MEMBER: return CheckMemberAccess(expr); case OP_POSTINC: case OP_POSTDEC: return TransformIncrement(expr); default: assert(0); } REPORT_OP_ERROR; }
/* 添加常量到符号表中 */ Symbol AddConstant (Type ty, union value val) { unsigned h = (unsigned)val.i[0] & SYM_HASH_MASK; Symbol p; /* 去掉修饰符 */ ty = Unqual (ty); if (IsIntegType (ty)) { ty = T (INT); } else if (IsPtrType (ty)) { ty = T (POINTER); } else if (LONGDOUBLE == ty->categ) { ty = T (DOUBLE); } /* 如果已经添加直接返回 */ for (p = Constants.buckets[h]; p; p = p->link) { if (p->ty == ty && p->val.i[0] == val.i[0] && p->val.i[1] == val.i[1]) return p; } /* 将常量添加到符号表中 */ CALLOC (p); p->kind = SK_Constant; switch (ty->categ) { case INT: p->name = FormatName ("%d", val.i[0]); break; case POINTER: p->name = (val.i[0] ? FormatName ("0x%x", val.i[0]) : "0"); break; case FLOAT: /* %g可以省略浮点多余的0 */ p->name = FormatName ("%g", val.f); break; case DOUBLE: p->name = FormatName ("%g", val.d); break; default: assert (0); } p->ty = ty; p->sclass = TK_STATIC; p->val = val; p->link = Constants.buckets[h]; Constants.buckets[h] = p; if (FLOAT == ty->categ || DOUBLE == ty->categ) { *FloatTail = p; FloatTail = &p->next; } return p; }
static AstExpression CheckUnaryExpression(AstExpression expr) { Type ty; switch (expr->op) { case OP_PREINC: case OP_PREDEC: return TransformIncrement(expr); case OP_ADDRESS: expr->kids[0] = CheckExpression(expr->kids[0]); ty = expr->kids[0]->ty; if (expr->kids[0]->op == OP_DEREF) { expr->kids[0]->kids[0]->lvalue = 0; return expr->kids[0]->kids[0]; } else if (expr->kids[0]->op == OP_INDEX) { expr->kids[0]->op = OP_ADD; expr->kids[0]->ty = PointerTo(ty); expr->kids[0]->lvalue = 0; return expr->kids[0]; } else if (IsFunctionType(ty) || (expr->kids[0]->lvalue && ! expr->kids[0]->bitfld && ! expr->kids[0]->inreg)) { expr->ty = PointerTo(ty); return expr; } break; case OP_DEREF: expr->kids[0] = Adjust(CheckExpression(expr->kids[0]), 1); ty = expr->kids[0]->ty; if (expr->kids[0]->op == OP_ADDRESS) { expr->kids[0]->kids[0]->ty = ty->bty; return expr->kids[0]->kids[0]; } else if (expr->kids[0]->op == OP_ADD && expr->kids[0]->kids[0]->isarray) { expr->kids[0]->op = OP_INDEX; expr->kids[0]->ty = ty->bty; expr->kids[0]->lvalue = 1; return expr->kids[0]; } if (IsPtrType(ty)) { expr->ty = ty->bty; if (IsFunctionType(expr->ty)) { return expr->kids[0]; } expr->lvalue = 1; return expr; } break; case OP_POS: case OP_NEG: expr->kids[0] = Adjust(CheckExpression(expr->kids[0]), 1); if (IsArithType(expr->kids[0]->ty)) { expr->kids[0] = DoIntegerPromotion(expr->kids[0]); expr->ty = expr->kids[0]->ty; return expr->op == OP_POS ? expr->kids[0] : FoldConstant(expr); } break; case OP_COMP: expr->kids[0] = Adjust(CheckExpression(expr->kids[0]), 1); if (IsIntegType(expr->kids[0]->ty)) { expr->kids[0] = DoIntegerPromotion(expr->kids[0]); expr->ty = expr->kids[0]->ty; return FoldConstant(expr); } break; case OP_NOT: expr->kids[0] = Adjust(CheckExpression(expr->kids[0]), 1); if (IsScalarType(expr->kids[0]->ty)) { expr->ty = T(INT); return FoldConstant(expr); } break; case OP_SIZEOF: if (expr->kids[0]->kind == NK_Expression) { expr->kids[0] = CheckExpression(expr->kids[0]); if (expr->kids[0]->bitfld) goto err; ty = expr->kids[0]->ty; } else { ty = CheckTypeName((AstTypeName)expr->kids[0]); } if (IsFunctionType(ty) || ty->size == 0) goto err; expr->ty = T(UINT); expr->op = OP_CONST; expr->val.i[0] = ty->size; return expr; case OP_CAST: return CheckTypeCast(expr); default: assert(0); } err: REPORT_OP_ERROR; }