[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