[PATCH 3/5] d3dcompiler: Parse function declarations.

Matteo Bruni mbruni at codeweavers.com
Mon Jun 11 12:18:33 CDT 2012


---
 dlls/d3dcompiler_43/d3dcompiler_private.h |   22 ++++++
 dlls/d3dcompiler_43/hlsl.y                |  104 ++++++++++++++++++++++++++++-
 dlls/d3dcompiler_43/utils.c               |   63 +++++++++++++++++-
 3 files changed, 187 insertions(+), 2 deletions(-)

diff --git a/dlls/d3dcompiler_43/d3dcompiler_private.h b/dlls/d3dcompiler_43/d3dcompiler_private.h
index 1c4b776..0fa3ac0 100644
--- a/dlls/d3dcompiler_43/d3dcompiler_private.h
+++ b/dlls/d3dcompiler_43/d3dcompiler_private.h
@@ -695,6 +695,7 @@ enum hlsl_ir_node_type
     HLSL_IR_VAR = 0,
     HLSL_IR_CONSTANT,
     HLSL_IR_DEREF,
+    HLSL_IR_FUNCTION_DECL,
 };
 
 struct hlsl_ir_node
@@ -733,6 +734,15 @@ struct hlsl_ir_var
     struct hlsl_var_allocation *allocation;
 };
 
+struct hlsl_ir_function_decl
+{
+    struct hlsl_ir_node node;
+    const char *name;
+    const char *semantic;
+    struct list *parameters;
+    struct list *body;
+};
+
 enum hlsl_ir_deref_type
 {
     HLSL_IR_DEREF_VAR,
@@ -787,6 +797,14 @@ struct hlsl_scope
 };
 
 /* Structures used only during parsing */
+struct parse_parameter
+{
+    struct hlsl_type *type;
+    const char *name;
+    const char *semantic;
+    unsigned int modifiers;
+};
+
 struct parse_variable_def
 {
     struct list entry;
@@ -832,6 +850,7 @@ static inline struct hlsl_ir_constant *constant_from_node(const struct hlsl_ir_n
 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;
 void free_declaration(struct hlsl_ir_var *decl) DECLSPEC_HIDDEN;
+BOOL add_func_parameter(struct list *list, struct parse_parameter *param, unsigned int line) DECLSPEC_HIDDEN;
 struct hlsl_type *new_hlsl_type(const char *name, enum hlsl_type_class type_class,
         enum hlsl_base_type base_type, unsigned dimx, unsigned dimy) DECLSPEC_HIDDEN;
 struct hlsl_type *new_array_type(struct hlsl_type *basic_type, unsigned int array_size) DECLSPEC_HIDDEN;
@@ -841,14 +860,17 @@ unsigned int components_count_type(struct hlsl_type *type) DECLSPEC_HIDDEN;
 struct hlsl_ir_deref *new_var_deref(struct hlsl_ir_var *var) DECLSPEC_HIDDEN;
 void push_scope(struct hlsl_parse_ctx *ctx) DECLSPEC_HIDDEN;
 BOOL pop_scope(struct hlsl_parse_ctx *ctx) DECLSPEC_HIDDEN;
+struct hlsl_ir_function_decl *new_func_decl(const char *name, struct hlsl_type *return_type, struct list *parameters) DECLSPEC_HIDDEN;
 struct bwriter_shader *parse_hlsl_shader(const char *text, enum shader_type type, DWORD version,
         const char *entrypoint, char **messages) DECLSPEC_HIDDEN;
 
 const char *debug_hlsl_type(const struct hlsl_type *type) DECLSPEC_HIDDEN;
 const char *debug_modifiers(DWORD modifiers) DECLSPEC_HIDDEN;
+
 void free_hlsl_type(struct hlsl_type *type) DECLSPEC_HIDDEN;
 void free_instr(struct hlsl_ir_node *node) DECLSPEC_HIDDEN;
 void free_instr_list(struct list *list) DECLSPEC_HIDDEN;
+void free_function(struct hlsl_ir_function_decl *func) DECLSPEC_HIDDEN;
 
 
 #define MAKE_TAG(ch0, ch1, ch2, ch3) \
diff --git a/dlls/d3dcompiler_43/hlsl.y b/dlls/d3dcompiler_43/hlsl.y
index 7384e88..ce004f9 100644
--- a/dlls/d3dcompiler_43/hlsl.y
+++ b/dlls/d3dcompiler_43/hlsl.y
@@ -127,6 +127,8 @@ static DWORD add_modifier(DWORD modifiers, DWORD mod)
     struct hlsl_ir_var *var;
     struct hlsl_ir_node *instr;
     struct list *list;
+    struct hlsl_ir_function_decl *function;
+    struct parse_parameter parameter;
     struct parse_variable_def *variable_def;
 }
 
@@ -230,7 +232,7 @@ static DWORD add_modifier(DWORD modifiers, DWORD mod)
 %token <intval> PRE_LINE
 
 %token <name> VAR_IDENTIFIER TYPE_IDENTIFIER NEW_IDENTIFIER
-%type <name> any_identifier
+%type <name> any_identifier var_identifier
 %token <name> STRING
 %token <floatval> C_FLOAT
 %token <intval> C_INTEGER
@@ -241,9 +243,14 @@ static DWORD add_modifier(DWORD modifiers, DWORD mod)
 %type <list> initializer_expr_list
 %type <instr> initializer_expr
 %type <modifiers> var_modifiers
+%type <list> parameters
+%type <list> param_list
 %type <instr> expr
 %type <var> variable
 %type <intval> array
+%type <function> func_declaration
+%type <function> func_prototype
+%type <parameter> parameter
 %type <name> semantic
 %type <variable_def> variable_def
 %type <list> variables_def
@@ -262,11 +269,17 @@ static DWORD add_modifier(DWORD modifiers, DWORD mod)
 %type <instr> logicor_expr
 %type <instr> conditional_expr
 %type <instr> assignment_expr
+%type <modifiers> input_mod
 %%
 
 hlsl_prog:                /* empty */
                             {
                             }
+                        | hlsl_prog func_declaration
+                            {
+                                FIXME("Check that the function doesn't conflict with an already declared one.\n");
+                                list_add_tail(&hlsl_ctx.functions, &$2->node.entry);
+                            }
                         | hlsl_prog declaration_statement
                             {
                                 TRACE("Declaration statement parsed.\n");
@@ -287,6 +300,32 @@ any_identifier:           VAR_IDENTIFIER
                         | TYPE_IDENTIFIER
                         | NEW_IDENTIFIER
 
+func_declaration:         func_prototype ';'
+                            {
+                                TRACE("Function prototype for %s.\n", $1->name);
+                                $$ = $1;
+                                pop_scope(&hlsl_ctx);
+                            }
+
+func_prototype:           var_modifiers type var_identifier '(' parameters ')' semantic
+                            {
+                                $$ = new_func_decl($3, $2, $5);
+                                if (!$$)
+                                {
+                                    ERR("Out of memory.\n");
+                                    return -1;
+                                }
+                                $$->semantic = $7;
+                            }
+
+scope_start:              /* Empty */
+                            {
+                                push_scope(&hlsl_ctx);
+                            }
+
+var_identifier:           VAR_IDENTIFIER
+                        | NEW_IDENTIFIER
+
 semantic:                 /* Empty */
                             {
                                 $$ = NULL;
@@ -296,6 +335,65 @@ semantic:                 /* Empty */
                                 $$ = $2;
                             }
 
+parameters:               scope_start
+                            {
+                                $$ = d3dcompiler_alloc(sizeof(*$$));
+                                list_init($$);
+                            }
+                        | scope_start param_list
+                            {
+                                $$ = $2;
+                            }
+
+param_list:               parameter
+                            {
+                                $$ = d3dcompiler_alloc(sizeof(*$$));
+                                list_init($$);
+                                if (!add_func_parameter($$, &$1, hlsl_ctx.line_no))
+                                {
+                                    ERR("Error adding function parameter %s.\n", $1.name);
+                                    set_parse_status(&hlsl_ctx.status, PARSE_ERR);
+                                    return -1;
+                                }
+                            }
+                        | param_list ',' parameter
+                            {
+                                $$ = $1;
+                                if (!add_func_parameter($$, &$3, hlsl_ctx.line_no))
+                                {
+                                    hlsl_message("Line %u: duplicate parameter %s.\n",
+                                            hlsl_ctx.line_no, $3.name);
+                                    set_parse_status(&hlsl_ctx.status, PARSE_ERR);
+                                    return 1;
+                                }
+                            }
+
+parameter:                input_mod var_modifiers type any_identifier semantic
+                            {
+                                $$.modifiers = $1;
+                                $$.modifiers |= $2;
+                                $$.type = $3;
+                                $$.name = $4;
+                                $$.semantic = $5;
+                            }
+
+input_mod:                /* Empty */
+                            {
+                                $$ = HLSL_MODIFIER_IN;
+                            }
+                        | KW_IN
+                            {
+                                $$ = HLSL_MODIFIER_IN;
+                            }
+                        | KW_OUT
+                            {
+                                $$ = HLSL_MODIFIER_OUT;
+                            }
+                        | KW_INOUT
+                            {
+                                $$ = HLSL_MODIFIER_IN | HLSL_MODIFIER_OUT;
+                            }
+
 type:                     base_type
                             {
                                 $$ = $1;
@@ -714,6 +812,7 @@ expr:                     assignment_expr
 
 struct bwriter_shader *parse_hlsl(enum shader_type type, DWORD version, const char *entrypoint, char **messages)
 {
+    struct hlsl_ir_function_decl *function;
     struct hlsl_scope *scope, *next_scope;
     struct hlsl_type *hlsl_type, *next_type;
     struct hlsl_ir_var *var, *next_var;
@@ -732,6 +831,9 @@ struct bwriter_shader *parse_hlsl(enum shader_type type, DWORD version, const ch
     hlsl_parse();
 
     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)
+        free_function(function);
 
     TRACE("Freeing variables.\n");
     LIST_FOR_EACH_ENTRY_SAFE(scope, next_scope, &hlsl_ctx.scopes, struct hlsl_scope, entry)
diff --git a/dlls/d3dcompiler_43/utils.c b/dlls/d3dcompiler_43/utils.c
index 6f8b013..53dd7f3 100644
--- a/dlls/d3dcompiler_43/utils.c
+++ b/dlls/d3dcompiler_43/utils.c
@@ -804,6 +804,31 @@ void free_declaration(struct hlsl_ir_var *decl)
     d3dcompiler_free(decl);
 }
 
+BOOL add_func_parameter(struct list *list, struct parse_parameter *param, unsigned int line)
+{
+    struct hlsl_ir_var *decl = d3dcompiler_alloc(sizeof(*decl));
+
+    if (!decl)
+    {
+        ERR("Out of memory.\n");
+        return FALSE;
+    }
+    decl->node.type = HLSL_IR_VAR;
+    decl->node.data_type = param->type;
+    decl->node.line = line;
+    decl->name = param->name;
+    decl->semantic = param->semantic;
+    decl->modifiers = param->modifiers;
+
+    if (!add_declaration(hlsl_ctx.cur_scope, decl, FALSE))
+    {
+        free_declaration(decl);
+        return FALSE;
+    }
+    list_add_tail(list, &decl->node.entry);
+    return TRUE;
+}
+
 struct hlsl_type *new_hlsl_type(const char *name, enum hlsl_type_class type_class,
         enum hlsl_base_type base_type, unsigned dimx, unsigned dimy)
 {
@@ -840,7 +865,13 @@ struct hlsl_type *get_type(struct hlsl_scope *scope, const char *name, BOOL recu
 
 BOOL find_function(const char *name)
 {
-    FIXME("stub.\n");
+    struct hlsl_ir_function_decl *func;
+
+    LIST_FOR_EACH_ENTRY(func, &hlsl_ctx.functions, struct hlsl_ir_function_decl, node.entry)
+    {
+        if (!strcmp(func->name, name))
+            return TRUE;
+    }
     return FALSE;
 }
 
@@ -886,6 +917,24 @@ BOOL pop_scope(struct hlsl_parse_ctx *ctx)
     return TRUE;
 }
 
+struct hlsl_ir_function_decl *new_func_decl(const char *name, struct hlsl_type *return_type, struct list *parameters)
+{
+    struct hlsl_ir_function_decl *decl;
+
+    decl = d3dcompiler_alloc(sizeof(*decl));
+    if (!decl)
+    {
+        ERR("Out of memory.\n");
+        return NULL;
+    }
+    decl->node.type = HLSL_IR_FUNCTION_DECL;
+    decl->node.data_type = return_type;
+    decl->name = name;
+    decl->parameters = parameters;
+
+    return decl;
+}
+
 static const char *debug_base_type(const struct hlsl_type *type)
 {
     const char *name = "(unknown)";
@@ -978,6 +1027,7 @@ static const char *debug_node_type(enum hlsl_ir_node_type type)
         "HLSL_IR_VAR",
         "HLSL_IR_CONSTANT",
         "HLSL_IR_DEREF",
+        "HLSL_IR_FUNCTION_DECL",
     };
 
     if (type > sizeof(names) / sizeof(names[0]))
@@ -1073,3 +1123,14 @@ void free_instr(struct hlsl_ir_node *node)
             FIXME("Unsupported node type %s\n", debug_node_type(node->type));
     }
 }
+
+void free_function(struct hlsl_ir_function_decl *func)
+{
+    struct hlsl_ir_var *param, *next_param;
+
+    d3dcompiler_free((void *)func->name);
+    d3dcompiler_free((void *)func->semantic);
+    LIST_FOR_EACH_ENTRY_SAFE(param, next_param, func->parameters, struct hlsl_ir_var, node.entry)
+        d3dcompiler_free(param);
+    d3dcompiler_free(func->parameters);
+}
-- 
1.7.3.4




More information about the wine-patches mailing list