[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