widl: Don't directly access the type structure when determining the types in expressions.

Use type_get_type and friends instead.
This commit is contained in:
Rob Shearman 2009-02-23 13:47:57 +00:00 committed by Alexandre Julliard
parent dbd25cb308
commit ba91ee607c
1 changed files with 77 additions and 50 deletions

View File

@ -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",