[PATCH 1/5] d3dcompiler: Parse "if/else" statement.

Matteo Bruni mbruni at codeweavers.com
Wed Sep 19 12:46:11 CDT 2012


---
 dlls/d3dcompiler_43/d3dcompiler_private.h |   21 +++++++++++
 dlls/d3dcompiler_43/hlsl.y                |   40 ++++++++++++++++++++++
 dlls/d3dcompiler_43/utils.c               |   52 ++++++++++++++++++++++------
 3 files changed, 102 insertions(+), 11 deletions(-)

diff --git a/dlls/d3dcompiler_43/d3dcompiler_private.h b/dlls/d3dcompiler_43/d3dcompiler_private.h
index eb75448..5171abe 100644
--- a/dlls/d3dcompiler_43/d3dcompiler_private.h
+++ b/dlls/d3dcompiler_43/d3dcompiler_private.h
@@ -706,6 +706,7 @@ enum hlsl_ir_node_type
     HLSL_IR_DEREF,
     HLSL_IR_EXPR,
     HLSL_IR_FUNCTION_DECL,
+    HLSL_IR_IF,
     HLSL_IR_JUMP,
     HLSL_IR_SWIZZLE,
 };
@@ -755,6 +756,14 @@ struct hlsl_ir_function_decl
     struct list *body;
 };
 
+struct hlsl_ir_if
+{
+    struct hlsl_ir_node node;
+    struct hlsl_ir_node *condition;
+    struct list *then_instrs;
+    struct list *else_instrs;
+};
+
 struct hlsl_ir_assignment
 {
     struct hlsl_ir_node node;
@@ -939,6 +948,12 @@ struct parse_variable_def
     struct list *initializer;
 };
 
+struct parse_if_body
+{
+    struct list *then_instrs;
+    struct list *else_instrs;
+};
+
 enum parse_unary_op
 {
     UNARY_OP_PLUS,
@@ -1043,6 +1058,12 @@ static inline struct hlsl_ir_constructor *constructor_from_node(const struct hls
     return CONTAINING_RECORD(node, struct hlsl_ir_constructor, node);
 }
 
+static inline struct hlsl_ir_if *if_from_node(const struct hlsl_ir_node *node)
+{
+    assert(node->type == HLSL_IR_IF);
+    return CONTAINING_RECORD(node, struct hlsl_ir_if, 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;
diff --git a/dlls/d3dcompiler_43/hlsl.y b/dlls/d3dcompiler_43/hlsl.y
index 75b5741..97a1d62 100644
--- a/dlls/d3dcompiler_43/hlsl.y
+++ b/dlls/d3dcompiler_43/hlsl.y
@@ -358,6 +358,7 @@ static struct hlsl_ir_swizzle *get_swizzle(struct hlsl_ir_node *value, const cha
 
 %locations
 %error-verbose
+%expect 1
 
 %union
 {
@@ -373,6 +374,7 @@ static struct hlsl_ir_swizzle *get_swizzle(struct hlsl_ir_node *value, const cha
     struct hlsl_ir_function_decl *function;
     struct parse_parameter parameter;
     struct parse_variable_def *variable_def;
+    struct parse_if_body if_body;
     enum parse_unary_op unary_op;
     enum parse_assign_op assign_op;
 }
@@ -498,12 +500,14 @@ static struct hlsl_ir_swizzle *get_swizzle(struct hlsl_ir_node *value, const cha
 %type <list> statement_list
 %type <list> compound_statement
 %type <list> jump_statement
+%type <list> selection_statement
 %type <function> func_declaration
 %type <function> func_prototype
 %type <parameter> parameter
 %type <name> semantic
 %type <variable_def> variable_def
 %type <list> variables_def
+%type <if_body> if_body
 %type <instr> primary_expr
 %type <instr> postfix_expr
 %type <instr> unary_expr
@@ -994,6 +998,7 @@ statement:                declaration_statement
                         | expr_statement
                         | compound_statement
                         | jump_statement
+                        | selection_statement
 
                           /* FIXME: add rule for return with no value */
 jump_statement:           KW_RETURN expr ';'
@@ -1019,6 +1024,41 @@ jump_statement:           KW_RETURN expr ';'
                                 list_add_tail($$, &jump->node.entry);
                             }
 
+selection_statement:      KW_IF '(' expr ')' if_body
+                            {
+                                struct hlsl_ir_if *instr = d3dcompiler_alloc(sizeof(*instr));
+                                if (!instr)
+                                {
+                                    ERR("Out of memory\n");
+                                    return -1;
+                                }
+                                instr->node.type = HLSL_IR_IF;
+                                set_location(&instr->node.loc, &@1);
+                                instr->condition = $3;
+                                instr->then_instrs = $5.then_instrs;
+                                instr->else_instrs = $5.else_instrs;
+                                if ($3->data_type->dimx > 1 || $3->data_type->dimy > 1)
+                                {
+                                    hlsl_report_message(instr->node.loc.file, instr->node.loc.line,
+                                            instr->node.loc.col, HLSL_LEVEL_ERROR,
+                                            "if condition requires a scalar");
+                                }
+                                $$ = d3dcompiler_alloc(sizeof(*$$));
+                                list_init($$);
+                                list_add_head($$, &instr->node.entry);
+                            }
+
+if_body:                  statement
+                            {
+                                $$.then_instrs = $1;
+                                $$.else_instrs = NULL;
+                            }
+                        | statement KW_ELSE statement
+                            {
+                                $$.then_instrs = $1;
+                                $$.else_instrs = $3;
+                            }
+
 expr_statement:           ';'
                             {
                                 $$ = d3dcompiler_alloc(sizeof(*$$));
diff --git a/dlls/d3dcompiler_43/utils.c b/dlls/d3dcompiler_43/utils.c
index e0d351c..05f769c 100644
--- a/dlls/d3dcompiler_43/utils.c
+++ b/dlls/d3dcompiler_43/utils.c
@@ -1742,6 +1742,7 @@ static const char *debug_node_type(enum hlsl_ir_node_type type)
         "HLSL_IR_DEREF",
         "HLSL_IR_EXPR",
         "HLSL_IR_FUNCTION_DECL",
+        "HLSL_IR_IF",
         "HLSL_IR_JUMP",
         "HLSL_IR_SWIZZLE",
     };
@@ -1753,6 +1754,17 @@ static const char *debug_node_type(enum hlsl_ir_node_type type)
 
 static void debug_dump_instr(const struct hlsl_ir_node *instr);
 
+static void debug_dump_instr_list(const struct list *list)
+{
+    struct hlsl_ir_node *instr;
+
+    LIST_FOR_EACH_ENTRY(instr, list, struct hlsl_ir_node, entry)
+    {
+        debug_dump_instr(instr);
+        TRACE("\n");
+    }
+}
+
 static void debug_dump_ir_var(const struct hlsl_ir_var *var)
 {
     if (var->modifiers)
@@ -1997,6 +2009,21 @@ static void debug_dump_ir_jump(const struct hlsl_ir_jump *jump)
     }
 }
 
+static void debug_dump_ir_if(const struct hlsl_ir_if *if_node)
+{
+    TRACE("if (");
+    debug_dump_instr(if_node->condition);
+    TRACE(")\n{\n");
+    debug_dump_instr_list(if_node->then_instrs);
+    TRACE("}\n");
+    if (if_node->else_instrs)
+    {
+        TRACE("else\n{\n");
+        debug_dump_instr_list(if_node->else_instrs);
+        TRACE("}\n");
+    }
+}
+
 static void debug_dump_instr(const struct hlsl_ir_node *instr)
 {
     switch (instr->type)
@@ -2022,22 +2049,14 @@ static void debug_dump_instr(const struct hlsl_ir_node *instr)
         case HLSL_IR_JUMP:
             debug_dump_ir_jump(jump_from_node(instr));
             break;
+        case HLSL_IR_IF:
+            debug_dump_ir_if(if_from_node(instr));
+            break;
         default:
             TRACE("No dump function for %s\n", debug_node_type(instr->type));
     }
 }
 
-static void debug_dump_instr_list(const struct list *list)
-{
-    struct hlsl_ir_node *instr;
-
-    LIST_FOR_EACH_ENTRY(instr, list, struct hlsl_ir_node, entry)
-    {
-        debug_dump_instr(instr);
-        TRACE("\n");
-    }
-}
-
 void debug_dump_ir_function(const struct hlsl_ir_function_decl *func)
 {
     struct hlsl_ir_var *param;
@@ -2159,6 +2178,14 @@ static void free_ir_assignment(struct hlsl_ir_assignment *assignment)
     d3dcompiler_free(assignment);
 }
 
+static void free_ir_if(struct hlsl_ir_if *if_node)
+{
+    free_instr(if_node->condition);
+    free_instr_list(if_node->then_instrs);
+    free_instr_list(if_node->else_instrs);
+    d3dcompiler_free(if_node);
+}
+
 static void free_ir_jump(struct hlsl_ir_jump *jump)
 {
     if (jump->type == HLSL_IR_JUMP_RETURN)
@@ -2191,6 +2218,9 @@ void free_instr(struct hlsl_ir_node *node)
         case HLSL_IR_ASSIGNMENT:
             free_ir_assignment(assignment_from_node(node));
             break;
+        case HLSL_IR_IF:
+            free_ir_if(if_from_node(node));
+            break;
         case HLSL_IR_JUMP:
             free_ir_jump(jump_from_node(node));
             break;
-- 
1.7.8.6




More information about the wine-patches mailing list