diff --git a/tools/widl/expr.c b/tools/widl/expr.c index 7717da3f7bf..58d7a5b60ca 100644 --- a/tools/widl/expr.c +++ b/tools/widl/expr.c @@ -33,6 +33,10 @@ #include "expr.h" #include "header.h" #include "typetree.h" +#include "typegen.h" + +static int is_integer_type(const type_t *type); +static int is_float_type(const type_t *type); expr_t *make_expr(enum expr_type type) { @@ -105,38 +109,17 @@ expr_t *make_exprt(enum expr_type type, type_t *tref, expr_t *expr) e->ref = expr; e->u.tref = tref; e->is_const = FALSE; - /* check for cast of constant expression */ if (type == EXPR_SIZEOF) { - switch (tref->type) + /* only do this for types that should be the same on all platforms */ + if (is_integer_type(tref) || is_float_type(tref)) { - case RPC_FC_BYTE: - case RPC_FC_CHAR: - case RPC_FC_SMALL: - case RPC_FC_USMALL: + unsigned int align = 0; e->is_const = TRUE; - e->cval = 1; - break; - case RPC_FC_WCHAR: - case RPC_FC_USHORT: - case RPC_FC_SHORT: - e->is_const = TRUE; - e->cval = 2; - break; - case RPC_FC_LONG: - case RPC_FC_ULONG: - case RPC_FC_FLOAT: - case RPC_FC_ERROR_STATUS_T: - e->is_const = TRUE; - e->cval = 4; - break; - case RPC_FC_HYPER: - case RPC_FC_DOUBLE: - e->is_const = TRUE; - e->cval = 8; - break; + e->cval = type_memsize(tref, &align); } } + /* check for cast of constant expression */ if (type == EXPR_CAST && expr->is_const) { e->is_const = TRUE; @@ -302,34 +285,46 @@ struct expression_type static int is_integer_type(const type_t *type) { - switch (type->type) + switch (type_get_type(type)) { - case RPC_FC_BYTE: - case RPC_FC_CHAR: - case RPC_FC_SMALL: - case RPC_FC_USMALL: - case RPC_FC_WCHAR: - case RPC_FC_SHORT: - case RPC_FC_USHORT: - case RPC_FC_LONG: - case RPC_FC_ULONG: - case RPC_FC_INT3264: - case RPC_FC_UINT3264: - case RPC_FC_HYPER: - case RPC_FC_ENUM16: - case RPC_FC_ENUM32: + case TYPE_ENUM: return TRUE; + case TYPE_BASIC: + switch (type_basic_get_fc(type)) + { + case RPC_FC_BYTE: + case RPC_FC_CHAR: + case RPC_FC_SMALL: + case RPC_FC_USMALL: + case RPC_FC_WCHAR: + case RPC_FC_SHORT: + case RPC_FC_USHORT: + case RPC_FC_LONG: + case RPC_FC_ULONG: + case RPC_FC_INT3264: + case RPC_FC_UINT3264: + case RPC_FC_HYPER: + return TRUE; + default: + return FALSE; + } default: return FALSE; } } +static int is_float_type(const type_t *type) +{ + return (type_get_type(type) == TYPE_BASIC && + (type_basic_get_fc(type) == RPC_FC_FLOAT || + type_basic_get_fc(type) == RPC_FC_DOUBLE)); +} + static void check_scalar_type(const struct expr_loc *expr_loc, const type_t *cont_type, const type_t *type) { if (!cont_type || (!is_integer_type(type) && !is_ptr(type) && - type->type != RPC_FC_FLOAT && - type->type != RPC_FC_DOUBLE)) + !is_float_type(type))) error_loc_info(&expr_loc->v->loc_info, "scalar type required in expression%s%s\n", expr_loc->attr ? " for attribute " : "", expr_loc->attr ? expr_loc->attr : ""); @@ -338,9 +333,7 @@ static void check_scalar_type(const struct expr_loc *expr_loc, static void check_arithmetic_type(const struct expr_loc *expr_loc, const type_t *cont_type, const type_t *type) { - if (!cont_type || (!is_integer_type(type) && - type->type != RPC_FC_FLOAT && - type->type != RPC_FC_DOUBLE)) + if (!cont_type || (!is_integer_type(type) && !is_float_type(type))) error_loc_info(&expr_loc->v->loc_info, "arithmetic type required in expression%s%s\n", expr_loc->attr ? " for attribute " : "", expr_loc->attr ? expr_loc->attr : ""); @@ -365,12 +358,33 @@ static type_t *find_identifier(const char *identifier, const type_t *cont_type, if (cont_type) { - if (cont_type->type == RPC_FC_FUNCTION) + switch (type_get_type(cont_type)) + { + case TYPE_FUNCTION: fields = type_function_get_args(cont_type); - else if (is_struct(cont_type->type)) + break; + case TYPE_STRUCT: fields = type_struct_get_fields(cont_type); - else if (is_union(cont_type->type)) + break; + case TYPE_UNION: + case TYPE_ENCAPSULATED_UNION: fields = type_union_get_cases(cont_type); + break; + case TYPE_VOID: + case TYPE_BASIC: + case TYPE_ENUM: + case TYPE_MODULE: + case TYPE_COCLASS: + case TYPE_INTERFACE: + case TYPE_POINTER: + case TYPE_ARRAY: + /* nothing to do */ + break; + case TYPE_ALIAS: + /* shouldn't get here because of using type_get_type above */ + assert(0); + break; + } } if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry ) @@ -390,6 +404,19 @@ static type_t *find_identifier(const char *identifier, const type_t *cont_type, return type; } +static int is_valid_member_operand(const type_t *type) +{ + switch (type_get_type(type)) + { + case TYPE_STRUCT: + case TYPE_UNION: + case TYPE_ENUM: + return TRUE; + default: + return FALSE; + } +} + static struct expression_type resolve_expression(const struct expr_loc *expr_loc, const type_t *cont_type, const expr_t *e) @@ -528,7 +555,7 @@ static struct expression_type resolve_expression(const struct expr_loc *expr_loc } case EXPR_MEMBER: result = resolve_expression(expr_loc, cont_type, e->ref); - if (result.type && (is_struct(result.type->type) || is_union(result.type->type) || result.type->type == RPC_FC_ENUM16 || result.type->type == RPC_FC_ENUM32)) + if (result.type && is_valid_member_operand(result.type)) result = resolve_expression(expr_loc, result.type, e->u.ext); else error_loc_info(&expr_loc->v->loc_info, "'.' or '->' operator applied to a type that isn't a structure, union or enumeration in expression%s%s\n",