From 3d5a4f133a72139bb2bcd209c5ba626ef80dadb4 Mon Sep 17 00:00:00 2001 From: Zebediah Figura Date: Tue, 2 Mar 2021 15:34:43 -0600 Subject: [PATCH] vkd3d-shader: Print the previous location for redefinition errors. Signed-off-by: Zebediah Figura Signed-off-by: Matteo Bruni Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- libs/vkd3d-shader/hlsl.c | 1 + libs/vkd3d-shader/hlsl.h | 1 + libs/vkd3d-shader/hlsl.y | 89 +++++++++++++++++++++------------------- 3 files changed, 49 insertions(+), 42 deletions(-) diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 4e73060a..0486c952 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -319,6 +319,7 @@ struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old, u vkd3d_free(type); return NULL; } + field->loc = old_field->loc; field->type = hlsl_type_clone(ctx, old_field->type, default_majority); field->name = vkd3d_strdup(old_field->name); if (old_field->semantic) diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 36e7dd0f..33eefe9f 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -130,6 +130,7 @@ struct hlsl_type struct hlsl_struct_field { struct list entry; + struct vkd3d_shader_location loc; struct hlsl_type *type; const char *name; const char *semantic; diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 50aeeab4..1caeb41f 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -286,8 +286,25 @@ static struct hlsl_ir_node *add_implicit_conversion(struct hlsl_ctx *ctx, struct return &cast->node; } +static struct hlsl_ir_function_decl *get_func_entry(struct hlsl_ctx *ctx, const char *name) +{ + struct hlsl_ir_function_decl *decl; + struct hlsl_ir_function *func; + struct rb_entry *entry; + + if ((entry = rb_get(&ctx->functions, name))) + { + func = RB_ENTRY_VALUE(entry, struct hlsl_ir_function, entry); + RB_FOR_EACH_ENTRY(decl, &func->overloads, struct hlsl_ir_function_decl, entry) + return decl; + } + + return NULL; +} + static bool declare_variable(struct hlsl_ctx *ctx, struct hlsl_ir_var *decl, bool local) { + struct hlsl_ir_function_decl *func; bool ret; if (decl->data_type->type != HLSL_CLASS_MATRIX) @@ -317,10 +334,12 @@ static bool declare_variable(struct hlsl_ctx *ctx, struct hlsl_ir_var *decl, boo } else { - if (hlsl_get_function(ctx, decl->name)) + if ((func = get_func_entry(ctx, decl->name))) { hlsl_error(ctx, decl->loc, VKD3D_SHADER_ERROR_HLSL_REDEFINED, "Variable '%s' is already defined as a function.", decl->name); + hlsl_note(ctx, func->loc, VKD3D_SHADER_LOG_ERROR, + "\"%s\" was previously defined here.", decl->name); return false; } } @@ -660,17 +679,16 @@ static struct hlsl_ir_load *add_array_load(struct hlsl_ctx *ctx, struct list *in return add_load(ctx, instrs, array, index, data_type, loc); } -static bool add_struct_field(struct list *fields, struct hlsl_struct_field *field) +static struct hlsl_struct_field *get_struct_field(struct list *fields, const char *name) { struct hlsl_struct_field *f; LIST_FOR_EACH_ENTRY(f, fields, struct hlsl_struct_field, entry) { - if (!strcmp(f->name, field->name)) - return false; + if (!strcmp(f->name, name)) + return f; } - list_add_tail(fields, &field->entry); - return true; + return NULL; } bool hlsl_type_is_row_major(const struct hlsl_type *type) @@ -739,6 +757,7 @@ static struct list *gen_struct_fields(struct hlsl_ctx *ctx, struct hlsl_type *ty field->type = hlsl_new_array_type(ctx, type, v->array_size); else field->type = type; + field->loc = v->loc; field->name = v->name; field->modifiers = modifiers; field->semantic = v->semantic; @@ -873,22 +892,6 @@ static const struct hlsl_ir_function_decl *get_overloaded_func(struct rb_tree *f return NULL; } -static struct hlsl_ir_function_decl *get_func_entry(struct hlsl_ctx *ctx, const char *name) -{ - struct hlsl_ir_function_decl *decl; - struct hlsl_ir_function *func; - struct rb_entry *entry; - - if ((entry = rb_get(&ctx->functions, name))) - { - func = RB_ENTRY_VALUE(entry, struct hlsl_ir_function, entry); - RB_FOR_EACH_ENTRY(decl, &func->overloads, struct hlsl_ir_function_decl, entry) - return decl; - } - - return NULL; -} - static struct list *make_list(struct hlsl_ir_node *node) { struct list *list; @@ -1726,14 +1729,14 @@ hlsl_prog: { hlsl_error(ctx, $2.decl->loc, VKD3D_SHADER_ERROR_HLSL_REDEFINED, "Function \"%s\" is already defined.", $2.name); + hlsl_note(ctx, decl->loc, VKD3D_SHADER_LOG_ERROR, "\"%s\" was previously defined here.", $2.name); YYABORT; } else if (!hlsl_type_compare(decl->return_type, $2.decl->return_type)) { hlsl_error(ctx, $2.decl->loc, VKD3D_SHADER_ERROR_HLSL_REDEFINED, "Function \"%s\" was already declared with a different return type.", $2.name); - hlsl_note(ctx, decl->loc, VKD3D_SHADER_LOG_ERROR, - "\"%s\" previously declared here", $2.name); + hlsl_note(ctx, decl->loc, VKD3D_SHADER_LOG_ERROR, "\"%s\" was previously declared here.", $2.name); YYABORT; } } @@ -1840,19 +1843,23 @@ fields_list: } | fields_list field { - bool ret; - struct hlsl_struct_field *field, *next; + struct hlsl_struct_field *field, *next, *existing; $$ = $1; LIST_FOR_EACH_ENTRY_SAFE(field, next, $2, struct hlsl_struct_field, entry) { - ret = add_struct_field($$, field); - if (ret == false) + if ((existing = get_struct_field($$, field->name))) { hlsl_error(ctx, @2, VKD3D_SHADER_ERROR_HLSL_REDEFINED, "Field \"%s\" is already defined.", field->name); + hlsl_note(ctx, existing->loc, VKD3D_SHADER_LOG_ERROR, + "'%s' was previously defined here.", field->name); vkd3d_free(field); } + else + { + list_add_tail($$, &field->entry); + } } vkd3d_free($2); } @@ -1889,15 +1896,20 @@ func_prototype: /* var_modifiers is necessary to avoid shift/reduce conflicts. */ var_modifiers type var_identifier '(' parameters ')' colon_attribute { + struct hlsl_ir_var *var; + if ($1) { hlsl_error(ctx, @1, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, "Modifiers are not allowed on functions."); YYABORT; } - if (hlsl_get_var(ctx->globals, $3)) + if ((var = hlsl_get_var(ctx->globals, $3))) { - hlsl_error(ctx, @3, VKD3D_SHADER_ERROR_HLSL_REDEFINED, "Function \"%s\" is already defined.", $3); + hlsl_error(ctx, @3, VKD3D_SHADER_ERROR_HLSL_REDEFINED, + "\"%s\" is already declared as a variable.", $3); + hlsl_note(ctx, var->loc, VKD3D_SHADER_LOG_ERROR, + "\"%s\" was previously declared here.", $3); YYABORT; } if (hlsl_type_is_void($2) && $7.semantic) @@ -2565,22 +2577,15 @@ postfix_expr: struct hlsl_type *type = node->data_type; struct hlsl_struct_field *field; - $$ = NULL; - LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry) - { - if (!strcmp($3, field->name)) - { - if (!add_record_load(ctx, $1, node, field, @2)) - YYABORT; - $$ = $1; - break; - } - } - if (!$$) + if (!(field = get_struct_field(type->e.elements, $3))) { hlsl_error(ctx, @3, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, "Field \"%s\" is not defined.", $3); YYABORT; } + + if (!add_record_load(ctx, $1, node, field, @2)) + YYABORT; + $$ = $1; } else if (node->data_type->type <= HLSL_CLASS_LAST_NUMERIC) {