Module: wine Branch: master Commit: 97a170d2d18e1646e339cfb82454dab79ddf2842 URL: http://source.winehq.org/git/wine.git/?a=commit;h=97a170d2d18e1646e339cfb824...
Author: Matteo Bruni mbruni@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(*$$));