d3dcompiler: Parse "return" statement.

This commit is contained in:
Matteo Bruni 2012-09-18 18:18:08 +02:00 committed by Alexandre Julliard
parent 47e931823c
commit ae11ba0b23
3 changed files with 83 additions and 7 deletions

View File

@ -706,6 +706,7 @@ enum hlsl_ir_node_type
HLSL_IR_DEREF,
HLSL_IR_EXPR,
HLSL_IR_FUNCTION_DECL,
HLSL_IR_JUMP,
HLSL_IR_SWIZZLE,
};
@ -837,6 +838,21 @@ struct hlsl_ir_expr
struct list *subexpressions;
};
enum hlsl_ir_jump_type
{
HLSL_IR_JUMP_BREAK,
HLSL_IR_JUMP_CONTINUE,
HLSL_IR_JUMP_DISCARD,
HLSL_IR_JUMP_RETURN,
};
struct hlsl_ir_jump
{
struct hlsl_ir_node node;
enum hlsl_ir_jump_type type;
struct hlsl_ir_node *return_value;
};
struct hlsl_ir_swizzle
{
struct hlsl_ir_node node;
@ -1003,6 +1019,12 @@ static inline struct hlsl_ir_constant *constant_from_node(const struct hlsl_ir_n
return CONTAINING_RECORD(node, struct hlsl_ir_constant, node);
}
static inline struct hlsl_ir_jump *jump_from_node(const struct hlsl_ir_node *node)
{
assert(node->type == HLSL_IR_JUMP);
return CONTAINING_RECORD(node, struct hlsl_ir_jump, node);
}
static inline struct hlsl_ir_assignment *assignment_from_node(const struct hlsl_ir_node *node)
{
assert(node->type == HLSL_IR_ASSIGNMENT);

View File

@ -497,6 +497,7 @@ static struct hlsl_ir_swizzle *get_swizzle(struct hlsl_ir_node *value, const cha
%type <list> statement
%type <list> statement_list
%type <list> compound_statement
%type <list> jump_statement
%type <function> func_declaration
%type <function> func_prototype
%type <parameter> parameter
@ -990,16 +991,32 @@ statement_list: statement
}
statement: declaration_statement
{
$$ = $1;
}
| expr_statement
{
$$ = $1;
}
| compound_statement
| jump_statement
/* FIXME: add rule for return with no value */
jump_statement: KW_RETURN expr ';'
{
$$ = $1;
struct hlsl_ir_jump *jump = d3dcompiler_alloc(sizeof(*jump));
if (!jump)
{
ERR("Out of memory\n");
return -1;
}
jump->node.type = HLSL_IR_JUMP;
set_location(&jump->node.loc, &@1);
jump->type = HLSL_IR_JUMP_RETURN;
jump->node.data_type = $2->data_type;
jump->return_value = $2;
FIXME("Check for valued return on void function.\n");
FIXME("Implicit conversion to the return type if needed, "
"error out if conversion not possible.\n");
$$ = d3dcompiler_alloc(sizeof(*$$));
list_init($$);
list_add_tail($$, &jump->node.entry);
}
expr_statement: ';'

View File

@ -1742,6 +1742,8 @@ static const char *debug_node_type(enum hlsl_ir_node_type type)
"HLSL_IR_DEREF",
"HLSL_IR_EXPR",
"HLSL_IR_FUNCTION_DECL",
"HLSL_IR_JUMP",
"HLSL_IR_SWIZZLE",
};
if (type >= sizeof(names) / sizeof(names[0]))
@ -1973,6 +1975,28 @@ static void debug_dump_ir_swizzle(const struct hlsl_ir_swizzle *swizzle)
}
}
static void debug_dump_ir_jump(const struct hlsl_ir_jump *jump)
{
switch (jump->type)
{
case HLSL_IR_JUMP_BREAK:
TRACE("break");
break;
case HLSL_IR_JUMP_CONTINUE:
TRACE("continue");
break;
case HLSL_IR_JUMP_DISCARD:
TRACE("discard");
break;
case HLSL_IR_JUMP_RETURN:
TRACE("return ");
if (jump->return_value)
debug_dump_instr(jump->return_value);
TRACE(";");
break;
}
}
static void debug_dump_instr(const struct hlsl_ir_node *instr)
{
switch (instr->type)
@ -1995,6 +2019,9 @@ static void debug_dump_instr(const struct hlsl_ir_node *instr)
case HLSL_IR_CONSTRUCTOR:
debug_dump_ir_constructor(constructor_from_node(instr));
break;
case HLSL_IR_JUMP:
debug_dump_ir_jump(jump_from_node(instr));
break;
default:
TRACE("No dump function for %s\n", debug_node_type(instr->type));
}
@ -2132,6 +2159,13 @@ static void free_ir_assignment(struct hlsl_ir_assignment *assignment)
d3dcompiler_free(assignment);
}
static void free_ir_jump(struct hlsl_ir_jump *jump)
{
if (jump->type == HLSL_IR_JUMP_RETURN)
free_instr(jump->return_value);
d3dcompiler_free(jump);
}
void free_instr(struct hlsl_ir_node *node)
{
switch (node->type)
@ -2157,6 +2191,9 @@ void free_instr(struct hlsl_ir_node *node)
case HLSL_IR_ASSIGNMENT:
free_ir_assignment(assignment_from_node(node));
break;
case HLSL_IR_JUMP:
free_ir_jump(jump_from_node(node));
break;
default:
FIXME("Unsupported node type %s\n", debug_node_type(node->type));
}