d3dcompiler: Parse function definitions.

This commit is contained in:
Matteo Bruni 2012-06-11 19:18:34 +02:00 committed by Alexandre Julliard
parent 552f10d0e8
commit d2673848ea
3 changed files with 197 additions and 2 deletions

View File

@ -866,6 +866,7 @@ struct bwriter_shader *parse_hlsl_shader(const char *text, enum shader_type type
const char *debug_hlsl_type(const struct hlsl_type *type) DECLSPEC_HIDDEN;
const char *debug_modifiers(DWORD modifiers) DECLSPEC_HIDDEN;
void debug_dump_ir_function(const struct hlsl_ir_function_decl *func) DECLSPEC_HIDDEN;
void free_hlsl_type(struct hlsl_type *type) DECLSPEC_HIDDEN;
void free_instr(struct hlsl_ir_node *node) DECLSPEC_HIDDEN;

View File

@ -248,6 +248,9 @@ static DWORD add_modifier(DWORD modifiers, DWORD mod)
%type <instr> expr
%type <var> variable
%type <intval> array
%type <list> statement
%type <list> statement_list
%type <list> compound_statement
%type <function> func_declaration
%type <function> func_prototype
%type <parameter> parameter
@ -269,6 +272,7 @@ static DWORD add_modifier(DWORD modifiers, DWORD mod)
%type <instr> logicor_expr
%type <instr> conditional_expr
%type <instr> assignment_expr
%type <list> expr_statement
%type <modifiers> input_mod
%%
@ -300,7 +304,14 @@ any_identifier: VAR_IDENTIFIER
| TYPE_IDENTIFIER
| NEW_IDENTIFIER
func_declaration: func_prototype ';'
func_declaration: func_prototype compound_statement
{
TRACE("Function %s parsed.\n", $1->name);
$$ = $1;
$$->body = $2;
pop_scope(&hlsl_ctx);
}
| func_prototype ';'
{
TRACE("Function prototype for %s.\n", $1->name);
$$ = $1;
@ -318,6 +329,17 @@ func_prototype: var_modifiers type var_identifier '(' parameters ')' s
$$->semantic = $7;
}
compound_statement: '{' '}'
{
$$ = d3dcompiler_alloc(sizeof(*$$));
list_init($$);
}
| '{' scope_start statement_list '}'
{
pop_scope(&hlsl_ctx);
$$ = $3;
}
scope_start: /* Empty */
{
push_scope(&hlsl_ctx);
@ -666,6 +688,44 @@ boolean: KW_TRUE
$$ = FALSE;
}
statement_list: statement
{
$$ = $1;
}
| statement_list statement
{
$$ = $1;
list_move_tail($$, $2);
d3dcompiler_free($2);
}
statement: declaration_statement
{
$$ = d3dcompiler_alloc(sizeof(*$$));
list_init($$);
}
| expr_statement
{
$$ = $1;
}
| compound_statement
{
$$ = $1;
}
expr_statement: ';'
{
$$ = d3dcompiler_alloc(sizeof(*$$));
list_init($$);
}
| expr ';'
{
$$ = d3dcompiler_alloc(sizeof(*$$));
list_init($$);
if ($1)
list_add_head($$, &$1->entry);
}
primary_expr: C_FLOAT
{
struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
@ -830,6 +890,18 @@ struct bwriter_shader *parse_hlsl(enum shader_type type, DWORD version, const ch
hlsl_parse();
if (TRACE_ON(hlsl_parser))
{
struct hlsl_ir_function_decl *func;
TRACE("IR dump.\n");
LIST_FOR_EACH_ENTRY(func, &hlsl_ctx.functions, struct hlsl_ir_function_decl, node.entry)
{
if (func->body)
debug_dump_ir_function(func);
}
}
d3dcompiler_free(hlsl_ctx.source_file);
TRACE("Freeing functions IR.\n");
LIST_FOR_EACH_ENTRY(function, &hlsl_ctx.functions, struct hlsl_ir_function_decl, node.entry)

View File

@ -770,8 +770,9 @@ BOOL add_declaration(struct hlsl_scope *scope, struct hlsl_ir_var *decl, BOOL lo
if (!strcmp(decl->name, var->name))
return FALSE;
}
if (local_var)
if (local_var && scope->upper->upper == hlsl_ctx.globals)
{
/* Check whether the variable redefines a function parameter. */
LIST_FOR_EACH_ENTRY(var, &scope->upper->vars, struct hlsl_ir_var, scope_entry)
{
if (!strcmp(decl->name, var->name))
@ -1037,6 +1038,125 @@ static const char *debug_node_type(enum hlsl_ir_node_type type)
return names[type];
}
static void debug_dump_instr(const struct hlsl_ir_node *instr);
static void debug_dump_ir_var(const struct hlsl_ir_var *var)
{
if (var->modifiers)
TRACE("%s ", debug_modifiers(var->modifiers));
TRACE("%s %s", debug_hlsl_type(var->node.data_type), var->name);
if (var->semantic)
TRACE(" : %s", debugstr_a(var->semantic));
}
static void debug_dump_ir_deref(const struct hlsl_ir_deref *deref)
{
switch (deref->type)
{
case HLSL_IR_DEREF_VAR:
TRACE("deref(");
debug_dump_ir_var(deref->v.var);
TRACE(")");
break;
case HLSL_IR_DEREF_ARRAY:
debug_dump_instr(deref->v.array.array);
TRACE("[");
debug_dump_instr(deref->v.array.index);
TRACE("]");
break;
case HLSL_IR_DEREF_RECORD:
debug_dump_instr(deref->v.record.record);
TRACE(".%s", debugstr_a(deref->v.record.field));
break;
}
}
static void debug_dump_ir_constant(const struct hlsl_ir_constant *constant)
{
struct hlsl_type *type = constant->node.data_type;
unsigned int x, y;
if (type->dimy != 1)
TRACE("{");
for (y = 0; y < type->dimy; ++y)
{
if (type->dimx != 1)
TRACE("{");
for (x = 0; x < type->dimx; ++x)
{
switch (type->base_type)
{
case HLSL_TYPE_FLOAT:
TRACE("%g ", (double)constant->v.value.f[y * type->dimx + x]);
break;
case HLSL_TYPE_DOUBLE:
TRACE("%g ", constant->v.value.d[y * type->dimx + x]);
break;
case HLSL_TYPE_INT:
TRACE("%d ", constant->v.value.i[y * type->dimx + x]);
break;
case HLSL_TYPE_UINT:
TRACE("%u ", constant->v.value.u[y * type->dimx + x]);
break;
case HLSL_TYPE_BOOL:
TRACE("%s ", constant->v.value.b[y * type->dimx + x] == FALSE ? "false" : "true");
break;
default:
TRACE("Constants of type %s not supported\n", debug_base_type(type));
}
}
if (type->dimx != 1)
TRACE("}");
}
if (type->dimy != 1)
TRACE("}");
}
static void debug_dump_instr(const struct hlsl_ir_node *instr)
{
switch (instr->type)
{
case HLSL_IR_DEREF:
debug_dump_ir_deref(deref_from_node(instr));
break;
case HLSL_IR_CONSTANT:
debug_dump_ir_constant(constant_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;
TRACE("Dumping function %s.\n", debugstr_a(func->name));
TRACE("Function parameters:\n");
LIST_FOR_EACH_ENTRY(param, func->parameters, struct hlsl_ir_var, node.entry)
{
debug_dump_ir_var(param);
TRACE("\n");
}
if (func->semantic)
TRACE("Function semantic: %s\n", debugstr_a(func->semantic));
if (func->body)
{
debug_dump_instr_list(func->body);
}
}
void free_hlsl_type(struct hlsl_type *type)
{
struct hlsl_struct_field *field, *next_field;
@ -1133,4 +1253,6 @@ void free_function(struct hlsl_ir_function_decl *func)
LIST_FOR_EACH_ENTRY_SAFE(param, next_param, func->parameters, struct hlsl_ir_var, node.entry)
d3dcompiler_free(param);
d3dcompiler_free(func->parameters);
free_instr_list(func->body);
d3dcompiler_free(func->body);
}