static void dump_type(type t) { if (type_complex(t)) { printf("C"); t = make_base_type(t); } if (type_network_base_type(t)) printf("N%s", type_networkdef(t)->name); /* Enums treated as ints for now */ else if (type_integer(t)) if (type_unsigned(t)) printf("U"); else printf("I"); else if (type_float(t)) printf("F"); else if (type_double(t)) printf("D"); else if (type_long_double(t)) printf("LD"); else if (type_union(t)) if (type_network(t)) printf("ANU"); else printf("AU"); else if (type_struct(t)) if (type_network(t)) printf("ANS"); else printf("AS"); else if (type_pointer(t)) printf("U"); else assert(0); }
expression make_unary(location loc, int unop, expression e) { switch (unop) { case kind_address_of: return make_address_of(loc, e); case kind_preincrement: return make_preincrement(loc, e); case kind_predecrement: return make_predecrement(loc, e); default: { expression result = CAST(expression, newkind_unary(parse_region, unop, loc, e)); type etype = default_conversion(e); const char *errstring = NULL; if (etype == error_type) result->type = error_type; else { switch (unop) { case kind_unary_plus: if (!type_arithmetic(etype)) errstring = "wrong type argument to unary plus"; break; case kind_unary_minus: if (!type_arithmetic(etype)) errstring = "wrong type argument to unary minus"; break; case kind_bitnot: if (type_complex(etype)) result->kind = kind_conjugate; else if (!type_integer(etype)) errstring = "wrong type argument to bit-complement"; break; case kind_not: if (!type_scalar(etype)) errstring = "wrong type argument to unary exclamation mark"; else etype = int_type; break; case kind_realpart: case kind_imagpart: if (!type_arithmetic(etype)) if (unop == kind_realpart) errstring = "wrong type argument to __real__"; else errstring = "wrong type argument to __imag__"; else etype = type_complex(etype) ? make_base_type(etype) : etype; default: assert(0); } if (errstring) { error(errstring); result->type = error_type; } else { result->type = etype; result->cst = fold_unary(result); } } return result; } } }
bool check_conversion(type to, type from) { if (type_equal_unqualified(to, from)) return TRUE; if (to == error_type || from == error_type) return FALSE; if (type_void(from)) { error("void value not ignored as it ought to be"); return FALSE; } if (type_void(to)) return TRUE; if (type_integer(to)) { if (!type_scalar(from)) { error("aggregate value used where an integer was expected"); return FALSE; } } else if (type_pointer(to)) { if (!(type_integer(from) || type_pointer(from))) { error("cannot convert to a pointer type"); return FALSE; } } else if (type_floating(to)) { if (type_pointer(from)) { error("pointer value used where a floating point value was expected"); return FALSE; } else if (!type_arithmetic(from)) { error("aggregate value used where a float was expected"); return FALSE; } } else if (type_complex(to)) { if (type_pointer(from)) { error("pointer value used where a complex was expected"); return FALSE; } else if (!type_arithmetic(from)) { error("aggregate value used where a complex was expected"); return FALSE; } } else { error("conversion to non-scalar type requested"); return FALSE; } return TRUE; }