d3dcompiler: Parse "if/else" statement.
This commit is contained in:
parent
e3a2e3a1c9
commit
79c6ce0a0f
|
@ -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;
|
||||
|
|
|
@ -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(*$$));
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue