static AstExpression CheckConditionalExpression(AstExpression expr) { int qual; Type ty1, ty2; expr->kids[0] = Adjust(CheckExpression(expr->kids[0]), 1); if (! IsScalarType(expr->kids[0]->ty)) { Error(&expr->coord, "The first expression shall be scalar type."); } expr->kids[1]->kids[0] = Adjust(CheckExpression(expr->kids[1]->kids[0]), 1); expr->kids[1]->kids[1] = Adjust(CheckExpression(expr->kids[1]->kids[1]), 1); ty1 = expr->kids[1]->kids[0]->ty; ty2 = expr->kids[1]->kids[1]->ty; if (BothArithType(ty1, ty2)) { expr->ty = CommonRealType(ty1, ty2); expr->kids[1]->kids[0] = Cast(expr->ty, expr->kids[1]->kids[0]); expr->kids[1]->kids[1] = Cast(expr->ty, expr->kids[1]->kids[1]); return FoldConstant(expr); } else if (IsRecordType(ty1) && ty1 == ty2) { expr->ty = ty1; } else if (ty1->categ == VOID && ty2->categ == VOID) { expr->ty = T(VOID); } else if (IsCompatiblePtr(ty1, ty2)) { qual = ty1->bty->qual | ty2->bty->qual; expr->ty = PointerTo(Qualify(qual, CompositeType(Unqual(ty1->bty), Unqual(ty2->bty)))); } else if (IsPtrType(ty1) && IsNullConstant(expr->kids[1]->kids[1])) { expr->ty = ty1; } else if (IsPtrType(ty2) && IsNullConstant(expr->kids[1]->kids[0])) { expr->ty = ty2; } else if (NotFunctionPtr(ty1) && IsVoidPtr(ty2) || NotFunctionPtr(ty2) && IsVoidPtr(ty1)) { qual = ty1->bty->qual | ty2->bty->qual; expr->ty = PointerTo(Qualify(qual, T(VOID))); } else { Error(&expr->coord, "invalid operand for ? operator."); expr->ty = T(INT); } 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; }
/* 添加常量到符号表中 */ 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 CheckMemberAccess(AstExpression expr) { Type ty; Field fld; expr->kids[0] = CheckExpression(expr->kids[0]); if (expr->op == OP_MEMBER) { expr->kids[0] = Adjust(expr->kids[0], 0); ty = expr->kids[0]->ty; if (! IsRecordType(ty)) { REPORT_OP_ERROR; } expr->lvalue = expr->kids[0]->lvalue; } else { expr->kids[0] = Adjust(expr->kids[0], 1); ty = expr->kids[0]->ty; if (! (IsPtrType(ty) && IsRecordType(ty->bty))) { REPORT_OP_ERROR; } ty = ty->bty; expr->lvalue = 1; } fld = LookupField(Unqual(ty), expr->val.p); if (fld == NULL) { Error(&expr->coord, "struct or union member %s doesn't exsist", expr->val.p); expr->ty = T(INT); return expr; } expr->ty = Qualify(ty->qual, fld->ty); expr->val.p = fld; expr->bitfld = fld->bits != 0; return expr; }
AstExpression Adjust(AstExpression expr, int rvalue) { if (rvalue) { expr->ty = Unqual(expr->ty); expr->lvalue = 0; } if (expr->ty->categ == FUNCTION) { expr->ty = PointerTo(expr->ty); expr->isfunc = 1; } else if (expr->ty->categ == ARRAY) { expr->ty = PointerTo(expr->ty->bty); expr->lvalue = 0; expr->isarray = 1; } return expr; }