Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/d3dcompiler_43/d3dcompiler_private.h | 3 +- dlls/d3dcompiler_43/hlsl.y | 39 +++++++++++++++++++++-- dlls/d3dcompiler_43/utils.c | 33 +++++++++---------- 3 files changed, 52 insertions(+), 23 deletions(-)
diff --git a/dlls/d3dcompiler_43/d3dcompiler_private.h b/dlls/d3dcompiler_43/d3dcompiler_private.h index 830434c9ff1..d221d1056fa 100644 --- a/dlls/d3dcompiler_43/d3dcompiler_private.h +++ b/dlls/d3dcompiler_43/d3dcompiler_private.h @@ -912,7 +912,7 @@ struct hlsl_deref } array; struct { - struct hlsl_ir_node *record; + struct hlsl_deref *record; struct hlsl_struct_field *field; } record; } v; @@ -1147,7 +1147,6 @@ struct hlsl_ir_expr *new_cast(struct hlsl_ir_node *node, struct hlsl_type *type, struct hlsl_ir_node *implicit_conversion(struct hlsl_ir_node *node, struct hlsl_type *type, 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, 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 a24d29e5df8..40159c60dcc 100644 --- a/dlls/d3dcompiler_43/hlsl.y +++ b/dlls/d3dcompiler_43/hlsl.y @@ -504,6 +504,31 @@ static struct hlsl_ir_jump *new_return(struct hlsl_ir_node *value, struct source return jump; }
+static struct hlsl_ir_deref *new_record_deref(struct hlsl_ir_deref *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->src.type = HLSL_IR_DEREF_RECORD; + if (!(deref->src.v.record.record = d3dcompiler_alloc(sizeof(*deref->src.v.record.record)))) + { + ERR("Out of memory.\n"); + d3dcompiler_free(deref); + return NULL; + } + *deref->src.v.record.record = record->src; + list_remove(&record->node.entry); + d3dcompiler_free(record); + deref->src.v.record.field = field; + return deref; +} + static void struct_var_initializer(struct list *list, struct hlsl_ir_var *var, struct parse_initializer *initializer) { @@ -534,7 +559,7 @@ static void struct_var_initializer(struct list *list, struct hlsl_ir_var *var, } if (components_count_type(field->type) == components_count_type(node->data_type)) { - deref = new_record_deref(&new_var_deref(var)->node, field); + deref = new_record_deref(new_var_deref(var), field); if (!deref) { ERR("Out of memory.\n"); @@ -2025,19 +2050,27 @@ postfix_expr: primary_expr { struct hlsl_ir_node *node = node_from_list($1); struct source_location loc; - loc = get_location(&@2); if (node->data_type->type == HLSL_CLASS_STRUCT) { struct hlsl_type *type = node->data_type; struct hlsl_struct_field *field; + struct hlsl_ir_deref *src; + + if (node->type != HLSL_IR_DEREF) + { + FIXME("Unimplemented subscript of node type %s.\n", + debug_node_type(node->type)); + YYABORT; + } + src = deref_from_node(node);
$$ = NULL; LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry) { if (!strcmp($3, field->name)) { - struct hlsl_ir_deref *deref = new_record_deref(node, field); + struct hlsl_ir_deref *deref = new_record_deref(src, field);
if (!deref) { diff --git a/dlls/d3dcompiler_43/utils.c b/dlls/d3dcompiler_43/utils.c index 29b35c3d7eb..ded8d3d77e3 100644 --- a/dlls/d3dcompiler_43/utils.c +++ b/dlls/d3dcompiler_43/utils.c @@ -1385,23 +1385,6 @@ 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->src.type = HLSL_IR_DEREF_RECORD; - deref->src.v.record.record = record; - deref->src.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[] = @@ -1881,7 +1864,7 @@ static void debug_dump_deref(const struct hlsl_deref *deref) wine_dbg_printf("]"); break; case HLSL_IR_DEREF_RECORD: - debug_dump_src(deref->v.record.record); + debug_dump_deref(deref->v.record.record); wine_dbg_printf(".%s", debugstr_a(deref->v.record.field->name)); break; } @@ -2232,8 +2215,22 @@ static void free_ir_constant(struct hlsl_ir_constant *constant) d3dcompiler_free(constant); }
+static void free_deref(struct hlsl_deref *deref) +{ + switch (deref->type) + { + case HLSL_IR_DEREF_RECORD: + free_deref(deref->v.record.record); + d3dcompiler_free(deref); + break; + default: + break; + } +} + static void free_ir_deref(struct hlsl_ir_deref *deref) { + free_deref(&deref->src); d3dcompiler_free(deref); }