[PATCH 5/5] d3dcompiler: Handle simple struct initializers.
Matteo Bruni
mbruni at codeweavers.com
Wed Sep 26 12:22:35 CDT 2012
---
dlls/d3dcompiler_43/d3dcompiler_private.h | 1 +
dlls/d3dcompiler_43/hlsl.y | 58 ++++++++++++++++++++++++++++-
dlls/d3dcompiler_43/utils.c | 17 ++++++++
3 files changed, 74 insertions(+), 2 deletions(-)
diff --git a/dlls/d3dcompiler_43/d3dcompiler_private.h b/dlls/d3dcompiler_43/d3dcompiler_private.h
index 5ed0bda..de948fa 100644
--- a/dlls/d3dcompiler_43/d3dcompiler_private.h
+++ b/dlls/d3dcompiler_43/d3dcompiler_private.h
@@ -1122,6 +1122,7 @@ struct hlsl_ir_expr *hlsl_eq(struct hlsl_ir_node *op1, struct hlsl_ir_node *op2,
struct hlsl_ir_expr *hlsl_ne(struct hlsl_ir_node *op1, struct hlsl_ir_node *op2,
struct source_location *loc) DECLSPEC_HIDDEN;
struct hlsl_ir_deref *new_var_deref(struct hlsl_ir_var *var) DECLSPEC_HIDDEN;
+struct hlsl_ir_deref *new_record_deref(struct hlsl_ir_node *record, struct hlsl_struct_field *field) DECLSPEC_HIDDEN;
struct hlsl_ir_node *make_assignment(struct hlsl_ir_node *left, enum parse_assign_op assign_op,
DWORD writemask, struct hlsl_ir_node *right) DECLSPEC_HIDDEN;
void push_scope(struct hlsl_parse_ctx *ctx) DECLSPEC_HIDDEN;
diff --git a/dlls/d3dcompiler_43/hlsl.y b/dlls/d3dcompiler_43/hlsl.y
index d8c0d2b..f9a685a 100644
--- a/dlls/d3dcompiler_43/hlsl.y
+++ b/dlls/d3dcompiler_43/hlsl.y
@@ -502,6 +502,61 @@ static struct hlsl_ir_swizzle *get_swizzle(struct hlsl_ir_node *value, const cha
return NULL;
}
+static void struct_var_initializer(struct list *list, struct hlsl_ir_var *var, struct list *initializer)
+{
+ struct hlsl_type *type = var->node.data_type;
+ struct hlsl_ir_node *node;
+ struct hlsl_struct_field *field;
+ struct list *cur_node;
+ struct hlsl_ir_node *assignment;
+ struct hlsl_ir_deref *deref;
+
+ if (initializer_size(initializer) != components_count_type(type))
+ {
+ hlsl_report_message(var->node.loc.file, var->node.loc.line, var->node.loc.col, HLSL_LEVEL_ERROR,
+ "structure initializer mismatch");
+ free_instr_list(initializer);
+ return;
+ }
+ cur_node = list_head(initializer);
+ assert(cur_node);
+ node = LIST_ENTRY(cur_node, struct hlsl_ir_node, entry);
+ LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry)
+ {
+ if (!cur_node)
+ {
+ d3dcompiler_free(initializer);
+ return;
+ }
+ if (components_count_type(field->type) == components_count_type(node->data_type))
+ {
+ deref = new_record_deref(&var->node, field);
+ if (!deref)
+ {
+ ERR("Out of memory.\n");
+ break;
+ }
+ deref->node.loc = node->loc;
+ assignment = make_assignment(&deref->node, ASSIGN_OP_ASSIGN, BWRITERSP_WRITEMASK_ALL, node);
+ list_add_tail(list, &assignment->entry);
+ }
+ else
+ FIXME("Initializing with \"mismatched\" fields is not supported yet.\n");
+ cur_node = list_next(initializer, cur_node);
+ node = LIST_ENTRY(cur_node, struct hlsl_ir_node, entry);
+ }
+
+ /* Free initializer elements in excess. */
+ while (cur_node)
+ {
+ struct list *next = list_next(initializer, cur_node);
+ free_instr(node);
+ cur_node = next;
+ node = LIST_ENTRY(cur_node, struct hlsl_ir_node, entry);
+ }
+ d3dcompiler_free(initializer);
+}
+
static struct list *declare_vars(struct hlsl_type *basic_type, DWORD modifiers, struct list *var_list)
{
struct hlsl_type *type;
@@ -599,8 +654,7 @@ static struct list *declare_vars(struct hlsl_type *basic_type, DWORD modifiers,
if (type->type == HLSL_CLASS_STRUCT)
{
- FIXME("Struct var with an initializer.\n");
- free_instr_list(v->initializer);
+ struct_var_initializer(statements_list, var, v->initializer);
d3dcompiler_free(v);
continue;
}
diff --git a/dlls/d3dcompiler_43/utils.c b/dlls/d3dcompiler_43/utils.c
index b957643..9f91579 100644
--- a/dlls/d3dcompiler_43/utils.c
+++ b/dlls/d3dcompiler_43/utils.c
@@ -1556,6 +1556,23 @@ struct hlsl_ir_deref *new_var_deref(struct hlsl_ir_var *var)
return deref;
}
+struct hlsl_ir_deref *new_record_deref(struct hlsl_ir_node *record, struct hlsl_struct_field *field)
+{
+ struct hlsl_ir_deref *deref = d3dcompiler_alloc(sizeof(*deref));
+
+ if (!deref)
+ {
+ ERR("Out of memory.\n");
+ return NULL;
+ }
+ deref->node.type = HLSL_IR_DEREF;
+ deref->node.data_type = field->type;
+ deref->type = HLSL_IR_DEREF_RECORD;
+ deref->v.record.record = record;
+ deref->v.record.field = field;
+ return deref;
+}
+
static enum hlsl_ir_expr_op op_from_assignment(enum parse_assign_op op)
{
static const enum hlsl_ir_expr_op ops[] =
--
1.7.8.6
More information about the wine-patches
mailing list