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_DEREF,
|
||||||
HLSL_IR_EXPR,
|
HLSL_IR_EXPR,
|
||||||
HLSL_IR_FUNCTION_DECL,
|
HLSL_IR_FUNCTION_DECL,
|
||||||
|
HLSL_IR_IF,
|
||||||
HLSL_IR_JUMP,
|
HLSL_IR_JUMP,
|
||||||
HLSL_IR_SWIZZLE,
|
HLSL_IR_SWIZZLE,
|
||||||
};
|
};
|
||||||
@ -755,6 +756,14 @@ struct hlsl_ir_function_decl
|
|||||||
struct list *body;
|
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_assignment
|
||||||
{
|
{
|
||||||
struct hlsl_ir_node node;
|
struct hlsl_ir_node node;
|
||||||
@ -939,6 +948,12 @@ struct parse_variable_def
|
|||||||
struct list *initializer;
|
struct list *initializer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct parse_if_body
|
||||||
|
{
|
||||||
|
struct list *then_instrs;
|
||||||
|
struct list *else_instrs;
|
||||||
|
};
|
||||||
|
|
||||||
enum parse_unary_op
|
enum parse_unary_op
|
||||||
{
|
{
|
||||||
UNARY_OP_PLUS,
|
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);
|
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;
|
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;
|
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;
|
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
|
%locations
|
||||||
%error-verbose
|
%error-verbose
|
||||||
|
%expect 1
|
||||||
|
|
||||||
%union
|
%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 hlsl_ir_function_decl *function;
|
||||||
struct parse_parameter parameter;
|
struct parse_parameter parameter;
|
||||||
struct parse_variable_def *variable_def;
|
struct parse_variable_def *variable_def;
|
||||||
|
struct parse_if_body if_body;
|
||||||
enum parse_unary_op unary_op;
|
enum parse_unary_op unary_op;
|
||||||
enum parse_assign_op assign_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> statement_list
|
||||||
%type <list> compound_statement
|
%type <list> compound_statement
|
||||||
%type <list> jump_statement
|
%type <list> jump_statement
|
||||||
|
%type <list> selection_statement
|
||||||
%type <function> func_declaration
|
%type <function> func_declaration
|
||||||
%type <function> func_prototype
|
%type <function> func_prototype
|
||||||
%type <parameter> parameter
|
%type <parameter> parameter
|
||||||
%type <name> semantic
|
%type <name> semantic
|
||||||
%type <variable_def> variable_def
|
%type <variable_def> variable_def
|
||||||
%type <list> variables_def
|
%type <list> variables_def
|
||||||
|
%type <if_body> if_body
|
||||||
%type <instr> primary_expr
|
%type <instr> primary_expr
|
||||||
%type <instr> postfix_expr
|
%type <instr> postfix_expr
|
||||||
%type <instr> unary_expr
|
%type <instr> unary_expr
|
||||||
@ -994,6 +998,7 @@ statement: declaration_statement
|
|||||||
| expr_statement
|
| expr_statement
|
||||||
| compound_statement
|
| compound_statement
|
||||||
| jump_statement
|
| jump_statement
|
||||||
|
| selection_statement
|
||||||
|
|
||||||
/* FIXME: add rule for return with no value */
|
/* FIXME: add rule for return with no value */
|
||||||
jump_statement: KW_RETURN expr ';'
|
jump_statement: KW_RETURN expr ';'
|
||||||
@ -1019,6 +1024,41 @@ jump_statement: KW_RETURN expr ';'
|
|||||||
list_add_tail($$, &jump->node.entry);
|
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: ';'
|
expr_statement: ';'
|
||||||
{
|
{
|
||||||
$$ = d3dcompiler_alloc(sizeof(*$$));
|
$$ = d3dcompiler_alloc(sizeof(*$$));
|
||||||
|
@ -1742,6 +1742,7 @@ static const char *debug_node_type(enum hlsl_ir_node_type type)
|
|||||||
"HLSL_IR_DEREF",
|
"HLSL_IR_DEREF",
|
||||||
"HLSL_IR_EXPR",
|
"HLSL_IR_EXPR",
|
||||||
"HLSL_IR_FUNCTION_DECL",
|
"HLSL_IR_FUNCTION_DECL",
|
||||||
|
"HLSL_IR_IF",
|
||||||
"HLSL_IR_JUMP",
|
"HLSL_IR_JUMP",
|
||||||
"HLSL_IR_SWIZZLE",
|
"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(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)
|
static void debug_dump_ir_var(const struct hlsl_ir_var *var)
|
||||||
{
|
{
|
||||||
if (var->modifiers)
|
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)
|
static void debug_dump_instr(const struct hlsl_ir_node *instr)
|
||||||
{
|
{
|
||||||
switch (instr->type)
|
switch (instr->type)
|
||||||
@ -2022,22 +2049,14 @@ static void debug_dump_instr(const struct hlsl_ir_node *instr)
|
|||||||
case HLSL_IR_JUMP:
|
case HLSL_IR_JUMP:
|
||||||
debug_dump_ir_jump(jump_from_node(instr));
|
debug_dump_ir_jump(jump_from_node(instr));
|
||||||
break;
|
break;
|
||||||
|
case HLSL_IR_IF:
|
||||||
|
debug_dump_ir_if(if_from_node(instr));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
TRACE("No dump function for %s\n", debug_node_type(instr->type));
|
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)
|
void debug_dump_ir_function(const struct hlsl_ir_function_decl *func)
|
||||||
{
|
{
|
||||||
struct hlsl_ir_var *param;
|
struct hlsl_ir_var *param;
|
||||||
@ -2159,6 +2178,14 @@ static void free_ir_assignment(struct hlsl_ir_assignment *assignment)
|
|||||||
d3dcompiler_free(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)
|
static void free_ir_jump(struct hlsl_ir_jump *jump)
|
||||||
{
|
{
|
||||||
if (jump->type == HLSL_IR_JUMP_RETURN)
|
if (jump->type == HLSL_IR_JUMP_RETURN)
|
||||||
@ -2191,6 +2218,9 @@ void free_instr(struct hlsl_ir_node *node)
|
|||||||
case HLSL_IR_ASSIGNMENT:
|
case HLSL_IR_ASSIGNMENT:
|
||||||
free_ir_assignment(assignment_from_node(node));
|
free_ir_assignment(assignment_from_node(node));
|
||||||
break;
|
break;
|
||||||
|
case HLSL_IR_IF:
|
||||||
|
free_ir_if(if_from_node(node));
|
||||||
|
break;
|
||||||
case HLSL_IR_JUMP:
|
case HLSL_IR_JUMP:
|
||||||
free_ir_jump(jump_from_node(node));
|
free_ir_jump(jump_from_node(node));
|
||||||
break;
|
break;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user