[PATCH 4/5] d3dcompiler: Parse variable initializers, basic expressions.

Matteo Bruni mbruni at codeweavers.com
Wed Jun 6 17:19:04 CDT 2012


---
 dlls/d3dcompiler_43/d3dcompiler_private.h |   29 ++++
 dlls/d3dcompiler_43/hlsl.y                |  198 +++++++++++++++++++++++++++++
 dlls/d3dcompiler_43/utils.c               |   49 +++++++
 3 files changed, 276 insertions(+), 0 deletions(-)

diff --git a/dlls/d3dcompiler_43/d3dcompiler_private.h b/dlls/d3dcompiler_43/d3dcompiler_private.h
index 77d81fe..cb322bc 100644
--- a/dlls/d3dcompiler_43/d3dcompiler_private.h
+++ b/dlls/d3dcompiler_43/d3dcompiler_private.h
@@ -33,6 +33,8 @@
 
 #include "d3dcompiler.h"
 
+#include <assert.h>
+
 /*
  * This doesn't belong here, but for some functions it is possible to return that value,
  * see http://msdn.microsoft.com/en-us/library/bb205278%28v=VS.85%29.aspx
@@ -681,6 +683,7 @@ struct hlsl_struct_field
 enum hlsl_ir_node_type
 {
     HLSL_IR_VAR = 0,
+    HLSL_IR_CONSTANT,
 };
 
 struct hlsl_ir_node
@@ -719,6 +722,24 @@ struct hlsl_ir_var
     struct hlsl_var_allocation *allocation;
 };
 
+struct hlsl_ir_constant
+{
+    struct hlsl_ir_node node;
+    union
+    {
+        union
+        {
+            unsigned u[16];
+            int i[16];
+            float f[16];
+            double d[16];
+            BOOL b[16];
+        } value;
+        struct hlsl_ir_constant *array_elements;
+        struct list *struct_elements;
+    } v;
+};
+
 struct hlsl_scope
 {
     struct list entry;
@@ -758,6 +779,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_constant *constant_from_node(const struct hlsl_ir_node *node)
+{
+    assert(node->type == HLSL_IR_CONSTANT);
+    return CONTAINING_RECORD(node, struct hlsl_ir_constant, node);
+}
+
 BOOL add_declaration(struct hlsl_scope *scope, struct hlsl_ir_var *decl, BOOL local_var) DECLSPEC_HIDDEN;
 struct hlsl_ir_var *get_variable(struct hlsl_scope *scope, const char *name) DECLSPEC_HIDDEN;
 void free_declaration(struct hlsl_ir_var *decl) DECLSPEC_HIDDEN;
@@ -777,6 +804,8 @@ const char *debug_base_type(const struct hlsl_type *type) DECLSPEC_HIDDEN;
 const char *debug_hlsl_type(const struct hlsl_type *type) DECLSPEC_HIDDEN;
 const char *debug_modifiers(DWORD modifiers) DECLSPEC_HIDDEN;
 void free_hlsl_type(struct hlsl_type *type) DECLSPEC_HIDDEN;
+void free_instr(struct hlsl_ir_node *node) DECLSPEC_HIDDEN;
+void free_instr_list(struct list *list) DECLSPEC_HIDDEN;
 
 
 #define MAKE_TAG(ch0, ch1, ch2, ch3) \
diff --git a/dlls/d3dcompiler_43/hlsl.y b/dlls/d3dcompiler_43/hlsl.y
index 704d5d6..0057d5d 100644
--- a/dlls/d3dcompiler_43/hlsl.y
+++ b/dlls/d3dcompiler_43/hlsl.y
@@ -121,8 +121,10 @@ static DWORD add_modifier(DWORD modifiers, DWORD mod)
     struct hlsl_type *type;
     INT intval;
     FLOAT floatval;
+    BOOL boolval;
     char *name;
     DWORD modifiers;
+    struct hlsl_ir_node *instr;
     struct list *list;
     struct parse_variable_def *variable_def;
 }
@@ -233,13 +235,33 @@ static DWORD add_modifier(DWORD modifiers, DWORD mod)
 %token <name> STRING
 %token <floatval> C_FLOAT
 %token <intval> C_INTEGER
+%type <boolval> boolean
 %type <type> base_type
 %type <type> type
+%type <list> complex_initializer
+%type <list> initializer_expr_list
+%type <instr> initializer_expr
 %type <modifiers> var_modifiers
+%type <instr> expr
 %type <intval> array
 %type <name> semantic
 %type <variable_def> variable_def
 %type <list> variables_def
+%type <instr> primary_expr
+%type <instr> postfix_expr
+%type <instr> unary_expr
+%type <instr> mul_expr
+%type <instr> add_expr
+%type <instr> shift_expr
+%type <instr> relational_expr
+%type <instr> equality_expr
+%type <instr> bitand_expr
+%type <instr> bitxor_expr
+%type <instr> bitor_expr
+%type <instr> logicand_expr
+%type <instr> logicor_expr
+%type <instr> conditional_expr
+%type <instr> assignment_expr
 %%
 
 hlsl_prog:                /* empty */
@@ -337,6 +359,7 @@ declaration:              var_modifiers type variables_def ';'
                                     if (v->initializer)
                                     {
                                         FIXME("Variable with an initializer.\n");
+                                        free_instr_list(v->initializer);
                                     }
 
                                     if (hlsl_ctx.cur_scope == hlsl_ctx.globals)
@@ -375,11 +398,26 @@ variable_def:             any_identifier array semantic
                                 $$->array_size = $2;
                                 $$->semantic = $3;
                             }
+                        | any_identifier array semantic '=' complex_initializer
+                            {
+                                TRACE("Declaration with initializer.\n");
+                                $$ = d3dcompiler_alloc(sizeof(*$$));
+                                $$->name = $1;
+                                $$->array_size = $2;
+                                $$->semantic = $3;
+                                $$->initializer = $5;
+                            }
 
 array:                    /* Empty */
                             {
                                 $$ = 0;
                             }
+                        | '[' expr ']'
+                            {
+                                FIXME("Array.\n");
+                                $$ = 0;
+                                free_instr($2);
+                            }
 
 var_modifiers:            /* Empty */
                             {
@@ -430,6 +468,166 @@ var_modifiers:            /* Empty */
                                 $$ = add_modifier($2, HLSL_MODIFIER_COLUMN_MAJOR);
                             }
 
+complex_initializer:      initializer_expr
+                            {
+                                $$ = d3dcompiler_alloc(sizeof(*$$));
+                                list_init($$);
+                                list_add_head($$, &$1->entry);
+                            }
+                        | '{' initializer_expr_list '}'
+                            {
+                                $$ = $2;
+                            }
+
+initializer_expr:         assignment_expr
+                            {
+                                $$ = $1;
+                            }
+
+initializer_expr_list:    initializer_expr
+                            {
+                                $$ = d3dcompiler_alloc(sizeof(*$$));
+                                list_init($$);
+                                list_add_head($$, &$1->entry);
+                            }
+                        | initializer_expr_list ',' initializer_expr
+                            {
+                                $$ = $1;
+                                list_add_tail($$, &$3->entry);
+                            }
+
+boolean:                  KW_TRUE
+                            {
+                                $$ = TRUE;
+                            }
+                        | KW_FALSE
+                            {
+                                $$ = FALSE;
+                            }
+
+primary_expr:             C_FLOAT
+                            {
+                                struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
+                                if (!c)
+                                {
+                                    ERR("Out of memory.\n");
+                                    return -1;
+                                }
+                                c->node.type = HLSL_IR_CONSTANT;
+                                c->node.data_type = new_hlsl_type("float", HLSL_CLASS_SCALAR, HLSL_TYPE_FLOAT, 1, 1);
+                                c->v.value.f[0] = $1;
+                                $$ = &c->node;
+                            }
+                        | C_INTEGER
+                            {
+                                struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
+                                if (!c)
+                                {
+                                    ERR("Out of memory.\n");
+                                    return -1;
+                                }
+                                c->node.type = HLSL_IR_CONSTANT;
+                                c->node.data_type = new_hlsl_type("int", HLSL_CLASS_SCALAR, HLSL_TYPE_INT, 1, 1);
+                                c->v.value.i[0] = $1;
+                                $$ = &c->node;
+                            }
+                        | boolean
+                            {
+                                struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
+                                if (!c)
+                                {
+                                    ERR("Out of memory.\n");
+                                    return -1;
+                                }
+                                c->node.type = HLSL_IR_CONSTANT;
+                                c->node.data_type = new_hlsl_type("bool", HLSL_CLASS_SCALAR, HLSL_TYPE_BOOL, 1, 1);
+                                c->v.value.b[0] = $1;
+                                $$ = &c->node;
+                            }
+                        | '(' expr ')'
+                            {
+                                $$ = $2;
+                            }
+
+postfix_expr:             primary_expr
+                            {
+                                $$ = $1;
+                            }
+
+unary_expr:               postfix_expr
+                            {
+                                $$ = $1;
+                            }
+
+mul_expr:                 unary_expr
+                            {
+                                $$ = $1;
+                            }
+
+add_expr:                 mul_expr
+                            {
+                                $$ = $1;
+                            }
+
+shift_expr:               add_expr
+                            {
+                                $$ = $1;
+                            }
+
+relational_expr:          shift_expr
+                            {
+                                $$ = $1;
+                            }
+
+equality_expr:            relational_expr
+                            {
+                                $$ = $1;
+                            }
+
+bitand_expr:              equality_expr
+                            {
+                                $$ = $1;
+                            }
+
+bitxor_expr:              bitand_expr
+                            {
+                                $$ = $1;
+                            }
+
+bitor_expr:               bitxor_expr
+                            {
+                                $$ = $1;
+                            }
+
+logicand_expr:            bitor_expr
+                            {
+                                $$ = $1;
+                            }
+
+logicor_expr:             logicand_expr
+                            {
+                                $$ = $1;
+                            }
+
+conditional_expr:         logicor_expr
+                            {
+                                $$ = $1;
+                            }
+
+assignment_expr:          conditional_expr
+                            {
+                                $$ = $1;
+                            }
+
+expr:                     assignment_expr
+                            {
+                                $$ = $1;
+                            }
+                        | expr ',' assignment_expr
+                            {
+                                FIXME("Comma expression\n");
+                            }
+
 %%
 
 struct bwriter_shader *parse_hlsl(enum shader_type type, DWORD version, const char *entrypoint, char **messages)
diff --git a/dlls/d3dcompiler_43/utils.c b/dlls/d3dcompiler_43/utils.c
index 33cce05..b15a89a 100644
--- a/dlls/d3dcompiler_43/utils.c
+++ b/dlls/d3dcompiler_43/utils.c
@@ -950,6 +950,7 @@ const char *debug_node_type(enum hlsl_ir_node_type type)
     const char *names[] =
     {
         "HLSL_IR_VAR",
+        "HLSL_IR_CONSTANT",
     };
 
     if (type > sizeof(names) / sizeof(names[0]))
@@ -975,3 +976,51 @@ void free_hlsl_type(struct hlsl_type *type)
     }
     d3dcompiler_free(type);
 }
+
+void free_instr_list(struct list *list)
+{
+    struct hlsl_ir_node *node, *next_node;
+
+    if (!list)
+        return;
+    LIST_FOR_EACH_ENTRY_SAFE(node, next_node, list, struct hlsl_ir_node, entry)
+        free_instr(node);
+}
+
+static void free_ir_constant(struct hlsl_ir_constant *constant)
+{
+    struct hlsl_type *type = constant->node.data_type;
+    unsigned int i;
+    struct hlsl_ir_constant *field, *next_field;
+
+    switch (type->type)
+    {
+        case HLSL_CLASS_ARRAY:
+            for (i = 0; i < type->e.array.elements_count; ++i)
+                free_ir_constant(&constant->v.array_elements[i]);
+            d3dcompiler_free(constant->v.array_elements);
+            break;
+        case HLSL_CLASS_STRUCT:
+            LIST_FOR_EACH_ENTRY_SAFE(field, next_field, constant->v.struct_elements, struct hlsl_ir_constant, node.entry)
+                free_ir_constant(field);
+            break;
+        default:
+            break;
+    }
+    d3dcompiler_free(constant);
+}
+
+void free_instr(struct hlsl_ir_node *node)
+{
+    switch (node->type)
+    {
+        case HLSL_IR_VAR:
+            /* These are freed later on from the scopes. */
+            break;
+        case HLSL_IR_CONSTANT:
+            free_ir_constant(constant_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