Module: wine Branch: master Commit: 79c6ce0a0ff295e40d2e627111c2734dcf96a155 URL: http://source.winehq.org/git/wine.git/?a=commit;h=79c6ce0a0ff295e40d2e627111...
Author: Matteo Bruni mbruni@codeweavers.com Date: Wed Sep 19 19:46:11 2012 +0200
d3dcompiler: Parse "if/else" statement.
---
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;