Commit ca701b7d authored by Matteo Bruni's avatar Matteo Bruni Committed by Alexandre Julliard

d3dcompiler: Parse casts.

parent 46e36893
...@@ -1080,8 +1080,11 @@ struct hlsl_type *clone_hlsl_type(struct hlsl_type *old) DECLSPEC_HIDDEN; ...@@ -1080,8 +1080,11 @@ struct hlsl_type *clone_hlsl_type(struct hlsl_type *old) DECLSPEC_HIDDEN;
struct hlsl_type *get_type(struct hlsl_scope *scope, const char *name, BOOL recursive) DECLSPEC_HIDDEN; struct hlsl_type *get_type(struct hlsl_scope *scope, const char *name, BOOL recursive) DECLSPEC_HIDDEN;
BOOL find_function(const char *name) DECLSPEC_HIDDEN; BOOL find_function(const char *name) DECLSPEC_HIDDEN;
unsigned int components_count_type(struct hlsl_type *type) DECLSPEC_HIDDEN; unsigned int components_count_type(struct hlsl_type *type) DECLSPEC_HIDDEN;
BOOL compatible_data_types(struct hlsl_type *s1, struct hlsl_type *s2) DECLSPEC_HIDDEN;
struct hlsl_ir_expr *new_expr(enum hlsl_ir_expr_op op, struct hlsl_ir_node **operands, struct hlsl_ir_expr *new_expr(enum hlsl_ir_expr_op op, struct hlsl_ir_node **operands,
struct source_location *loc) DECLSPEC_HIDDEN; struct source_location *loc) DECLSPEC_HIDDEN;
struct hlsl_ir_expr *new_cast(struct hlsl_ir_node *node, struct hlsl_type *type,
struct source_location *loc) DECLSPEC_HIDDEN;
struct hlsl_ir_expr *hlsl_mul(struct hlsl_ir_node *op1, struct hlsl_ir_node *op2, struct hlsl_ir_expr *hlsl_mul(struct hlsl_ir_node *op1, struct hlsl_ir_node *op2,
struct source_location *loc) DECLSPEC_HIDDEN; struct source_location *loc) DECLSPEC_HIDDEN;
struct hlsl_ir_expr *hlsl_div(struct hlsl_ir_node *op1, struct hlsl_ir_node *op2, struct hlsl_ir_expr *hlsl_div(struct hlsl_ir_node *op1, struct hlsl_ir_node *op2,
......
...@@ -1472,6 +1472,35 @@ unary_expr: postfix_expr ...@@ -1472,6 +1472,35 @@ unary_expr: postfix_expr
$$ = &new_expr(ops[$1], operands, &loc)->node; $$ = &new_expr(ops[$1], operands, &loc)->node;
} }
} }
/* var_modifiers just to avoid shift/reduce conflicts */
| '(' var_modifiers type array ')' unary_expr
{
struct hlsl_ir_expr *expr;
struct hlsl_type *src_type = $6->data_type;
struct hlsl_type *dst_type;
struct source_location loc;
set_location(&loc, &@3);
if ($2)
{
hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
"unexpected modifier in a cast");
return 1;
}
dst_type = $3;
if (!compatible_data_types(src_type, dst_type))
{
hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
"can't cast from %s to %s",
debug_hlsl_type(src_type), debug_hlsl_type(dst_type));
return 1;
}
expr = new_cast($6, dst_type, &loc);
$$ = expr ? &expr->node : NULL;
}
unary_op: '+' unary_op: '+'
{ {
......
...@@ -1031,6 +1031,60 @@ static BOOL convertible_data_type(struct hlsl_type *type) ...@@ -1031,6 +1031,60 @@ static BOOL convertible_data_type(struct hlsl_type *type)
return type->type != HLSL_CLASS_OBJECT; return type->type != HLSL_CLASS_OBJECT;
} }
BOOL compatible_data_types(struct hlsl_type *t1, struct hlsl_type *t2)
{
if (!convertible_data_type(t1) || !convertible_data_type(t2))
return FALSE;
if (t1->type <= HLSL_CLASS_LAST_NUMERIC)
{
/* Scalar vars can be cast to pretty much everything */
if (t1->dimx == 1 && t1->dimy == 1)
return TRUE;
if (t1->type == HLSL_CLASS_VECTOR && t2->type == HLSL_CLASS_VECTOR)
return t1->dimx >= t2->dimx;
}
/* The other way around is true too i.e. whatever to scalar */
if (t2->type <= HLSL_CLASS_LAST_NUMERIC && t2->dimx == 1 && t2->dimy == 1)
return TRUE;
if (t1->type == HLSL_CLASS_ARRAY)
{
if (compare_hlsl_types(t1->e.array.type, t2))
/* e.g. float4[3] to float4 is allowed */
return TRUE;
if (t2->type == HLSL_CLASS_ARRAY || t2->type == HLSL_CLASS_STRUCT)
return components_count_type(t1) >= components_count_type(t2);
else
return components_count_type(t1) == components_count_type(t2);
}
if (t1->type == HLSL_CLASS_STRUCT)
return components_count_type(t1) >= components_count_type(t2);
if (t2->type == HLSL_CLASS_ARRAY || t2->type == HLSL_CLASS_STRUCT)
return components_count_type(t1) == components_count_type(t2);
if (t1->type == HLSL_CLASS_MATRIX || t2->type == HLSL_CLASS_MATRIX)
{
if (t1->type == HLSL_CLASS_MATRIX && t2->type == HLSL_CLASS_MATRIX && t1->dimx >= t2->dimx && t1->dimy >= t2->dimy)
return TRUE;
/* Matrix-vector conversion is apparently allowed if they have the same components count */
if ((t1->type == HLSL_CLASS_VECTOR || t2->type == HLSL_CLASS_VECTOR)
&& components_count_type(t1) == components_count_type(t2))
return TRUE;
return FALSE;
}
if (components_count_type(t1) >= components_count_type(t2))
return TRUE;
return FALSE;
}
static BOOL implicit_compatible_data_types(struct hlsl_type *t1, struct hlsl_type *t2) static BOOL implicit_compatible_data_types(struct hlsl_type *t1, struct hlsl_type *t2)
{ {
if (!convertible_data_type(t1) || !convertible_data_type(t2)) if (!convertible_data_type(t1) || !convertible_data_type(t2))
...@@ -1322,6 +1376,20 @@ struct hlsl_ir_expr *new_expr(enum hlsl_ir_expr_op op, struct hlsl_ir_node **ope ...@@ -1322,6 +1376,20 @@ struct hlsl_ir_expr *new_expr(enum hlsl_ir_expr_op op, struct hlsl_ir_node **ope
return expr; return expr;
} }
struct hlsl_ir_expr *new_cast(struct hlsl_ir_node *node, struct hlsl_type *type,
struct source_location *loc)
{
struct hlsl_ir_expr *cast;
struct hlsl_ir_node *operands[3];
operands[0] = node;
operands[1] = operands[2] = NULL;
cast = new_expr(HLSL_IR_UNOP_CAST, operands, loc);
if (cast)
cast->node.data_type = type;
return cast;
}
struct hlsl_ir_expr *hlsl_mul(struct hlsl_ir_node *op1, struct hlsl_ir_node *op2, struct hlsl_ir_expr *hlsl_mul(struct hlsl_ir_node *op1, struct hlsl_ir_node *op2,
struct source_location *loc) struct source_location *loc)
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment