Matteo Bruni : d3dcompiler: Parse structure declarations.

Alexandre Julliard julliard at winehq.org
Thu Sep 27 15:39:07 CDT 2012


Module: wine
Branch: master
Commit: 97a170d2d18e1646e339cfb82454dab79ddf2842
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=97a170d2d18e1646e339cfb82454dab79ddf2842

Author: Matteo Bruni <mbruni at codeweavers.com>
Date:   Wed Sep 26 19:22:32 2012 +0200

d3dcompiler: Parse structure declarations.

---

 dlls/d3dcompiler_43/hlsl.y |  189 +++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 186 insertions(+), 3 deletions(-)

diff --git a/dlls/d3dcompiler_43/hlsl.y b/dlls/d3dcompiler_43/hlsl.y
index 670b4f5..d8c0d2b 100644
--- a/dlls/d3dcompiler_43/hlsl.y
+++ b/dlls/d3dcompiler_43/hlsl.y
@@ -597,6 +597,13 @@ static struct list *declare_vars(struct hlsl_type *basic_type, DWORD modifiers,
                 continue;
             }
 
+            if (type->type == HLSL_CLASS_STRUCT)
+            {
+                FIXME("Struct var with an initializer.\n");
+                free_instr_list(v->initializer);
+                d3dcompiler_free(v);
+                continue;
+            }
             if (type->type > HLSL_CLASS_LAST_NUMERIC)
             {
                 FIXME("Initializers for non scalar/struct variables not supported yet.\n");
@@ -630,6 +637,79 @@ static struct list *declare_vars(struct hlsl_type *basic_type, DWORD modifiers,
     return statements_list;
 }
 
+static BOOL add_struct_field(struct list *fields, struct hlsl_struct_field *field)
+{
+    struct hlsl_struct_field *f;
+
+    LIST_FOR_EACH_ENTRY(f, fields, struct hlsl_struct_field, entry)
+    {
+        if (!strcmp(f->name, field->name))
+            return FALSE;
+    }
+    list_add_tail(fields, &field->entry);
+    return TRUE;
+}
+
+static struct list *gen_struct_fields(struct hlsl_type *type, DWORD modifiers, struct list *fields)
+{
+    struct parse_variable_def *v, *v_next;
+    struct hlsl_struct_field *field;
+    struct list *list;
+
+    list = d3dcompiler_alloc(sizeof(*list));
+    if (!list)
+    {
+        ERR("Out of memory.\n");
+        return NULL;
+    }
+    list_init(list);
+    LIST_FOR_EACH_ENTRY_SAFE(v, v_next, fields, struct parse_variable_def, entry)
+    {
+        debug_dump_decl(type, 0, v->name, v->loc.line);
+        field = d3dcompiler_alloc(sizeof(*field));
+        if (!field)
+        {
+            ERR("Out of memory.\n");
+            d3dcompiler_free(v);
+            return list;
+        }
+        field->type = type;
+        field->name = v->name;
+        field->modifiers = modifiers;
+        field->semantic = v->semantic;
+        if (v->initializer)
+        {
+            hlsl_report_message(v->loc.file, v->loc.line, v->loc.col, HLSL_LEVEL_ERROR,
+                    "struct field with an initializer.\n");
+            free_instr_list(v->initializer);
+        }
+        list_add_tail(list, &field->entry);
+        d3dcompiler_free(v);
+    }
+    d3dcompiler_free(fields);
+    return list;
+}
+
+static struct hlsl_type *new_struct_type(const char *name, DWORD modifiers, struct list *fields)
+{
+    struct hlsl_type *type = d3dcompiler_alloc(sizeof(*type));
+
+    if (!type)
+    {
+        ERR("Out of memory.\n");
+        return NULL;
+    }
+    type->type = HLSL_CLASS_STRUCT;
+    type->name = name;
+    type->dimx = type->dimy = 1;
+    type->modifiers = modifiers;
+    type->e.elements = fields;
+
+    list_add_tail(&hlsl_ctx.types, &type->entry);
+
+    return type;
+}
+
 static BOOL add_typedef(DWORD modifiers, struct hlsl_type *orig_type, struct list *list,
         struct source_location *loc)
 {
@@ -809,12 +889,17 @@ static BOOL add_typedef(DWORD modifiers, struct hlsl_type *orig_type, struct lis
 %type <type> type
 %type <list> declaration_statement
 %type <list> declaration
+%type <list> struct_declaration
+%type <type> struct_spec
+%type <type> named_struct_spec
+%type <type> unnamed_struct_spec
 %type <list> type_specs
 %type <variable_def> type_spec
 %type <list> complex_initializer
 %type <list> initializer_expr_list
 %type <instr> initializer_expr
 %type <modifiers> var_modifiers
+%type <list> field
 %type <list> parameters
 %type <list> param_list
 %type <instr> expr
@@ -828,10 +913,12 @@ static BOOL add_typedef(DWORD modifiers, struct hlsl_type *orig_type, struct lis
 %type <list> loop_statement
 %type <function> func_declaration
 %type <function> func_prototype
+%type <list> fields_list
 %type <parameter> parameter
 %type <name> semantic
 %type <variable_def> variable_def
 %type <list> variables_def
+%type <list> variables_def_optional
 %type <if_body> if_body
 %type <instr> primary_expr
 %type <instr> postfix_expr
@@ -889,10 +976,99 @@ preproc_directive:        PRE_LINE STRING
                                 }
                             }
 
+struct_declaration:       struct_spec variables_def_optional ';'
+                            {
+                                struct source_location loc;
+
+                                set_location(&loc, &@3);
+                                if (!$2)
+                                {
+                                    if (!$1->name)
+                                    {
+                                        hlsl_report_message(loc.file, loc.line, loc.col,
+                                                HLSL_LEVEL_ERROR, "anonymous struct declaration with no variables");
+                                    }
+                                    check_type_modifiers($1->modifiers, &loc);
+                                }
+                                $$ = declare_vars($1, 0, $2);
+                            }
+
+struct_spec:              named_struct_spec
+                        | unnamed_struct_spec
+
+named_struct_spec:        var_modifiers KW_STRUCT any_identifier '{' fields_list '}'
+                            {
+                                BOOL ret;
+                                struct source_location loc;
+
+                                TRACE("Structure %s declaration.\n", debugstr_a($3));
+                                set_location(&loc, &@1);
+                                check_invalid_matrix_modifiers($1, &loc);
+                                $$ = new_struct_type($3, $1, $5);
+
+                                if (get_variable(hlsl_ctx.cur_scope, $3))
+                                {
+                                    hlsl_report_message(hlsl_ctx.source_file, @3.first_line, @3.first_column,
+                                            HLSL_LEVEL_ERROR, "redefinition of '%s'", $3);
+                                    return 1;
+                                }
+
+                                ret = add_type_to_scope(hlsl_ctx.cur_scope, $$);
+                                if (!ret)
+                                {
+                                    hlsl_report_message(hlsl_ctx.source_file, @3.first_line, @3.first_column,
+                                            HLSL_LEVEL_ERROR, "redefinition of struct '%s'", $3);
+                                    return 1;
+                                }
+                            }
+
+unnamed_struct_spec:      var_modifiers KW_STRUCT '{' fields_list '}'
+                            {
+                                struct source_location loc;
+
+                                TRACE("Anonymous structure declaration.\n");
+                                set_location(&loc, &@1);
+                                check_invalid_matrix_modifiers($1, &loc);
+                                $$ = new_struct_type(NULL, $1, $4);
+                            }
+
 any_identifier:           VAR_IDENTIFIER
                         | TYPE_IDENTIFIER
                         | NEW_IDENTIFIER
 
+fields_list:              /* Empty */
+                            {
+                                $$ = d3dcompiler_alloc(sizeof(*$$));
+                                list_init($$);
+                            }
+                        | fields_list field
+                            {
+                                BOOL ret;
+                                struct hlsl_struct_field *field, *next;
+
+                                $$ = $1;
+                                LIST_FOR_EACH_ENTRY_SAFE(field, next, $2, struct hlsl_struct_field, entry)
+                                {
+                                    ret = add_struct_field($$, field);
+                                    if (ret == FALSE)
+                                    {
+                                        hlsl_report_message(hlsl_ctx.source_file, @2.first_line, @2.first_column,
+                                                HLSL_LEVEL_ERROR, "redefinition of '%s'", field->name);
+                                        d3dcompiler_free(field);
+                                    }
+                                }
+                                d3dcompiler_free($2);
+                            }
+
+field:                    var_modifiers type variables_def ';'
+                            {
+                                $$ = gen_struct_fields($2, $1, $3);
+                            }
+                        | unnamed_struct_spec variables_def ';'
+                            {
+                                $$ = gen_struct_fields($1, 0, $2);
+                            }
+
 func_declaration:         func_prototype compound_statement
                             {
                                 TRACE("Function %s parsed.\n", $1->name);
@@ -1123,9 +1299,7 @@ base_type:                KW_VOID
                             }
 
 declaration_statement:    declaration
-                            {
-                                $$ = $1;
-                            }
+                        | struct_declaration
                         | typedef
                             {
                                 $$ = d3dcompiler_alloc(sizeof(*$$));
@@ -1171,6 +1345,15 @@ declaration:              var_modifiers type variables_def ';'
                                 $$ = declare_vars($2, $1, $3);
                             }
 
+variables_def_optional:   /* Empty */
+                            {
+                                $$ = NULL;
+                            }
+                        | variables_def
+                            {
+                                $$ = $1;
+                            }
+
 variables_def:            variable_def
                             {
                                 $$ = d3dcompiler_alloc(sizeof(*$$));




More information about the wine-cvs mailing list