[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