mirror of
https://github.com/reactos/wine.git
synced 2024-11-25 20:59:54 +00:00
d3dcompiler: Parse variable references in expressions.
This commit is contained in:
parent
887ef49419
commit
96470dfcb4
@ -684,6 +684,7 @@ enum hlsl_ir_node_type
|
||||
{
|
||||
HLSL_IR_VAR = 0,
|
||||
HLSL_IR_CONSTANT,
|
||||
HLSL_IR_DEREF,
|
||||
};
|
||||
|
||||
struct hlsl_ir_node
|
||||
@ -722,6 +723,33 @@ struct hlsl_ir_var
|
||||
struct hlsl_var_allocation *allocation;
|
||||
};
|
||||
|
||||
enum hlsl_ir_deref_type
|
||||
{
|
||||
HLSL_IR_DEREF_VAR,
|
||||
HLSL_IR_DEREF_ARRAY,
|
||||
HLSL_IR_DEREF_RECORD,
|
||||
};
|
||||
|
||||
struct hlsl_ir_deref
|
||||
{
|
||||
struct hlsl_ir_node node;
|
||||
enum hlsl_ir_deref_type type;
|
||||
union
|
||||
{
|
||||
struct hlsl_ir_var *var;
|
||||
struct
|
||||
{
|
||||
struct hlsl_ir_node *array;
|
||||
struct hlsl_ir_node *index;
|
||||
} array;
|
||||
struct
|
||||
{
|
||||
struct hlsl_ir_node *record;
|
||||
const char *field;
|
||||
} record;
|
||||
} v;
|
||||
};
|
||||
|
||||
struct hlsl_ir_constant
|
||||
{
|
||||
struct hlsl_ir_node node;
|
||||
@ -779,6 +807,12 @@ extern struct hlsl_parse_ctx hlsl_ctx DECLSPEC_HIDDEN;
|
||||
|
||||
void hlsl_message(const char *fmt, ...) PRINTF_ATTR(1,2) DECLSPEC_HIDDEN;
|
||||
|
||||
static inline struct hlsl_ir_deref *deref_from_node(const struct hlsl_ir_node *node)
|
||||
{
|
||||
assert(node->type == HLSL_IR_DEREF);
|
||||
return CONTAINING_RECORD(node, struct hlsl_ir_deref, node);
|
||||
}
|
||||
|
||||
static inline struct hlsl_ir_constant *constant_from_node(const struct hlsl_ir_node *node)
|
||||
{
|
||||
assert(node->type == HLSL_IR_CONSTANT);
|
||||
|
@ -124,6 +124,7 @@ static DWORD add_modifier(DWORD modifiers, DWORD mod)
|
||||
BOOL boolval;
|
||||
char *name;
|
||||
DWORD modifiers;
|
||||
struct hlsl_ir_var *var;
|
||||
struct hlsl_ir_node *instr;
|
||||
struct list *list;
|
||||
struct parse_variable_def *variable_def;
|
||||
@ -243,6 +244,7 @@ static DWORD add_modifier(DWORD modifiers, DWORD mod)
|
||||
%type <instr> initializer_expr
|
||||
%type <modifiers> var_modifiers
|
||||
%type <instr> expr
|
||||
%type <var> variable
|
||||
%type <intval> array
|
||||
%type <name> semantic
|
||||
%type <variable_def> variable_def
|
||||
@ -544,11 +546,30 @@ primary_expr: C_FLOAT
|
||||
c->v.value.b[0] = $1;
|
||||
$$ = &c->node;
|
||||
}
|
||||
| variable
|
||||
{
|
||||
struct hlsl_ir_deref *deref = new_var_deref($1);
|
||||
$$ = deref ? &deref->node : NULL;
|
||||
}
|
||||
| '(' expr ')'
|
||||
{
|
||||
$$ = $2;
|
||||
}
|
||||
|
||||
variable: VAR_IDENTIFIER
|
||||
{
|
||||
struct hlsl_ir_var *var;
|
||||
var = get_variable(hlsl_ctx.cur_scope, $1);
|
||||
if (!var)
|
||||
{
|
||||
hlsl_message("Line %d: variable '%s' not declared\n",
|
||||
hlsl_ctx.line_no, $1);
|
||||
set_parse_status(&hlsl_ctx.status, PARSE_ERR);
|
||||
return 1;
|
||||
}
|
||||
$$ = var;
|
||||
}
|
||||
|
||||
postfix_expr: primary_expr
|
||||
{
|
||||
$$ = $1;
|
||||
|
@ -844,6 +844,22 @@ BOOL find_function(const char *name)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
struct hlsl_ir_deref *new_var_deref(struct hlsl_ir_var *var)
|
||||
{
|
||||
struct hlsl_ir_deref *deref = d3dcompiler_alloc(sizeof(*deref));
|
||||
|
||||
if (!deref)
|
||||
{
|
||||
ERR("Out of memory.\n");
|
||||
return NULL;
|
||||
}
|
||||
deref->node.type = HLSL_IR_DEREF;
|
||||
deref->node.data_type = var->node.data_type;
|
||||
deref->type = HLSL_IR_DEREF_VAR;
|
||||
deref->v.var = var;
|
||||
return deref;
|
||||
}
|
||||
|
||||
void push_scope(struct hlsl_parse_ctx *ctx)
|
||||
{
|
||||
struct hlsl_scope *new_scope = d3dcompiler_alloc(sizeof(*new_scope));
|
||||
@ -951,6 +967,7 @@ const char *debug_node_type(enum hlsl_ir_node_type type)
|
||||
{
|
||||
"HLSL_IR_VAR",
|
||||
"HLSL_IR_CONSTANT",
|
||||
"HLSL_IR_DEREF",
|
||||
};
|
||||
|
||||
if (type > sizeof(names) / sizeof(names[0]))
|
||||
@ -1010,6 +1027,25 @@ static void free_ir_constant(struct hlsl_ir_constant *constant)
|
||||
d3dcompiler_free(constant);
|
||||
}
|
||||
|
||||
static void free_ir_deref(struct hlsl_ir_deref *deref)
|
||||
{
|
||||
switch (deref->type)
|
||||
{
|
||||
case HLSL_IR_DEREF_VAR:
|
||||
/* Variables are shared among nodes in the tree. */
|
||||
break;
|
||||
case HLSL_IR_DEREF_ARRAY:
|
||||
free_instr(deref->v.array.array);
|
||||
free_instr(deref->v.array.index);
|
||||
break;
|
||||
case HLSL_IR_DEREF_RECORD:
|
||||
free_instr(deref->v.record.record);
|
||||
d3dcompiler_free((void *)deref->v.record.field);
|
||||
break;
|
||||
}
|
||||
d3dcompiler_free(deref);
|
||||
}
|
||||
|
||||
void free_instr(struct hlsl_ir_node *node)
|
||||
{
|
||||
switch (node->type)
|
||||
@ -1020,6 +1056,9 @@ void free_instr(struct hlsl_ir_node *node)
|
||||
case HLSL_IR_CONSTANT:
|
||||
free_ir_constant(constant_from_node(node));
|
||||
break;
|
||||
case HLSL_IR_DEREF:
|
||||
free_ir_deref(deref_from_node(node));
|
||||
break;
|
||||
default:
|
||||
FIXME("Unsupported node type %s\n", debug_node_type(node->type));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user