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:
parent
dbd25cb308
commit
ba91ee607c
|
@ -33,6 +33,10 @@
|
||||||
#include "expr.h"
|
#include "expr.h"
|
||||||
#include "header.h"
|
#include "header.h"
|
||||||
#include "typetree.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)
|
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->ref = expr;
|
||||||
e->u.tref = tref;
|
e->u.tref = tref;
|
||||||
e->is_const = FALSE;
|
e->is_const = FALSE;
|
||||||
/* check for cast of constant expression */
|
|
||||||
if (type == EXPR_SIZEOF)
|
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:
|
unsigned int align = 0;
|
||||||
case RPC_FC_CHAR:
|
|
||||||
case RPC_FC_SMALL:
|
|
||||||
case RPC_FC_USMALL:
|
|
||||||
e->is_const = TRUE;
|
e->is_const = TRUE;
|
||||||
e->cval = 1;
|
e->cval = type_memsize(tref, &align);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* check for cast of constant expression */
|
||||||
if (type == EXPR_CAST && expr->is_const)
|
if (type == EXPR_CAST && expr->is_const)
|
||||||
{
|
{
|
||||||
e->is_const = TRUE;
|
e->is_const = TRUE;
|
||||||
|
@ -302,34 +285,46 @@ struct expression_type
|
||||||
|
|
||||||
static int is_integer_type(const type_t *type)
|
static int is_integer_type(const type_t *type)
|
||||||
{
|
{
|
||||||
switch (type->type)
|
switch (type_get_type(type))
|
||||||
{
|
{
|
||||||
case RPC_FC_BYTE:
|
case TYPE_ENUM:
|
||||||
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:
|
|
||||||
return TRUE;
|
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:
|
default:
|
||||||
return FALSE;
|
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,
|
static void check_scalar_type(const struct expr_loc *expr_loc,
|
||||||
const type_t *cont_type, const type_t *type)
|
const type_t *cont_type, const type_t *type)
|
||||||
{
|
{
|
||||||
if (!cont_type || (!is_integer_type(type) && !is_ptr(type) &&
|
if (!cont_type || (!is_integer_type(type) && !is_ptr(type) &&
|
||||||
type->type != RPC_FC_FLOAT &&
|
!is_float_type(type)))
|
||||||
type->type != RPC_FC_DOUBLE))
|
|
||||||
error_loc_info(&expr_loc->v->loc_info, "scalar type required in expression%s%s\n",
|
error_loc_info(&expr_loc->v->loc_info, "scalar type required in expression%s%s\n",
|
||||||
expr_loc->attr ? " for attribute " : "",
|
expr_loc->attr ? " for attribute " : "",
|
||||||
expr_loc->attr ? expr_loc->attr : "");
|
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,
|
static void check_arithmetic_type(const struct expr_loc *expr_loc,
|
||||||
const type_t *cont_type, const type_t *type)
|
const type_t *cont_type, const type_t *type)
|
||||||
{
|
{
|
||||||
if (!cont_type || (!is_integer_type(type) &&
|
if (!cont_type || (!is_integer_type(type) && !is_float_type(type)))
|
||||||
type->type != RPC_FC_FLOAT &&
|
|
||||||
type->type != RPC_FC_DOUBLE))
|
|
||||||
error_loc_info(&expr_loc->v->loc_info, "arithmetic type required in expression%s%s\n",
|
error_loc_info(&expr_loc->v->loc_info, "arithmetic type required in expression%s%s\n",
|
||||||
expr_loc->attr ? " for attribute " : "",
|
expr_loc->attr ? " for attribute " : "",
|
||||||
expr_loc->attr ? expr_loc->attr : "");
|
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)
|
||||||
{
|
{
|
||||||
if (cont_type->type == RPC_FC_FUNCTION)
|
switch (type_get_type(cont_type))
|
||||||
|
{
|
||||||
|
case TYPE_FUNCTION:
|
||||||
fields = type_function_get_args(cont_type);
|
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);
|
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);
|
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 )
|
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;
|
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,
|
static struct expression_type resolve_expression(const struct expr_loc *expr_loc,
|
||||||
const type_t *cont_type,
|
const type_t *cont_type,
|
||||||
const expr_t *e)
|
const expr_t *e)
|
||||||
|
@ -528,7 +555,7 @@ static struct expression_type resolve_expression(const struct expr_loc *expr_loc
|
||||||
}
|
}
|
||||||
case EXPR_MEMBER:
|
case EXPR_MEMBER:
|
||||||
result = resolve_expression(expr_loc, cont_type, e->ref);
|
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);
|
result = resolve_expression(expr_loc, result.type, e->u.ext);
|
||||||
else
|
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",
|
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",
|
||||||
|
|
Loading…
Reference in New Issue