[PATCH 5/5] d3dcompiler: Parse variable references in expressions.
Matteo Bruni
mbruni at codeweavers.com
Wed Jun 6 17:19:05 CDT 2012
---
dlls/d3dcompiler_43/d3dcompiler_private.h | 34 +++++++++++++++++++++++++
dlls/d3dcompiler_43/hlsl.y | 21 +++++++++++++++
dlls/d3dcompiler_43/utils.c | 39 +++++++++++++++++++++++++++++
3 files changed, 94 insertions(+), 0 deletions(-)
diff --git a/dlls/d3dcompiler_43/d3dcompiler_private.h b/dlls/d3dcompiler_43/d3dcompiler_private.h
index cb322bc..9f7fce1 100644
--- a/dlls/d3dcompiler_43/d3dcompiler_private.h
+++ b/dlls/d3dcompiler_43/d3dcompiler_private.h
@@ -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);
diff --git a/dlls/d3dcompiler_43/hlsl.y b/dlls/d3dcompiler_43/hlsl.y
index 0057d5d..ae1599f 100644
--- a/dlls/d3dcompiler_43/hlsl.y
+++ b/dlls/d3dcompiler_43/hlsl.y
@@ -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;
diff --git a/dlls/d3dcompiler_43/utils.c b/dlls/d3dcompiler_43/utils.c
index b15a89a..c890fd8 100644
--- a/dlls/d3dcompiler_43/utils.c
+++ b/dlls/d3dcompiler_43/utils.c
@@ -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));
}
--
1.7.3.4
More information about the wine-patches
mailing list