[PATCH 4/5] d3dcompiler: Parse function definitions.
Matteo Bruni
mbruni at codeweavers.com
Mon Jun 11 12:18:34 CDT 2012
---
dlls/d3dcompiler_43/d3dcompiler_private.h | 1 +
dlls/d3dcompiler_43/hlsl.y | 74 +++++++++++++++++-
dlls/d3dcompiler_43/utils.c | 124 ++++++++++++++++++++++++++++-
3 files changed, 197 insertions(+), 2 deletions(-)
diff --git a/dlls/d3dcompiler_43/d3dcompiler_private.h b/dlls/d3dcompiler_43/d3dcompiler_private.h
index 0fa3ac0..695ee7d 100644
--- a/dlls/d3dcompiler_43/d3dcompiler_private.h
+++ b/dlls/d3dcompiler_43/d3dcompiler_private.h
@@ -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;
diff --git a/dlls/d3dcompiler_43/hlsl.y b/dlls/d3dcompiler_43/hlsl.y
index ce004f9..5151002 100644
--- a/dlls/d3dcompiler_43/hlsl.y
+++ b/dlls/d3dcompiler_43/hlsl.y
@@ -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)
diff --git a/dlls/d3dcompiler_43/utils.c b/dlls/d3dcompiler_43/utils.c
index 53dd7f3..d92243d 100644
--- a/dlls/d3dcompiler_43/utils.c
+++ b/dlls/d3dcompiler_43/utils.c
@@ -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);
}
--
1.7.3.4
More information about the wine-patches
mailing list