vkd3d-shader: Print the previous location for redefinition errors.

Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
Signed-off-by: Matteo Bruni <mbruni@codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zebediah Figura
2021-03-02 15:34:43 -06:00
committed by Alexandre Julliard
parent 2fe6d26dfc
commit 3d5a4f133a
3 changed files with 49 additions and 42 deletions

View File

@ -319,6 +319,7 @@ struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old, u
vkd3d_free(type); vkd3d_free(type);
return NULL; return NULL;
} }
field->loc = old_field->loc;
field->type = hlsl_type_clone(ctx, old_field->type, default_majority); field->type = hlsl_type_clone(ctx, old_field->type, default_majority);
field->name = vkd3d_strdup(old_field->name); field->name = vkd3d_strdup(old_field->name);
if (old_field->semantic) if (old_field->semantic)

View File

@ -130,6 +130,7 @@ struct hlsl_type
struct hlsl_struct_field struct hlsl_struct_field
{ {
struct list entry; struct list entry;
struct vkd3d_shader_location loc;
struct hlsl_type *type; struct hlsl_type *type;
const char *name; const char *name;
const char *semantic; const char *semantic;

View File

@ -286,8 +286,25 @@ static struct hlsl_ir_node *add_implicit_conversion(struct hlsl_ctx *ctx, struct
return &cast->node; 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) static bool declare_variable(struct hlsl_ctx *ctx, struct hlsl_ir_var *decl, bool local)
{ {
struct hlsl_ir_function_decl *func;
bool ret; bool ret;
if (decl->data_type->type != HLSL_CLASS_MATRIX) 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 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, hlsl_error(ctx, decl->loc, VKD3D_SHADER_ERROR_HLSL_REDEFINED,
"Variable '%s' is already defined as a function.", decl->name); "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; 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); 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; struct hlsl_struct_field *f;
LIST_FOR_EACH_ENTRY(f, fields, struct hlsl_struct_field, entry) LIST_FOR_EACH_ENTRY(f, fields, struct hlsl_struct_field, entry)
{ {
if (!strcmp(f->name, field->name)) if (!strcmp(f->name, name))
return false; return f;
} }
list_add_tail(fields, &field->entry); return NULL;
return true;
} }
bool hlsl_type_is_row_major(const struct hlsl_type *type) 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); field->type = hlsl_new_array_type(ctx, type, v->array_size);
else else
field->type = type; field->type = type;
field->loc = v->loc;
field->name = v->name; field->name = v->name;
field->modifiers = modifiers; field->modifiers = modifiers;
field->semantic = v->semantic; field->semantic = v->semantic;
@ -873,22 +892,6 @@ static const struct hlsl_ir_function_decl *get_overloaded_func(struct rb_tree *f
return NULL; 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) static struct list *make_list(struct hlsl_ir_node *node)
{ {
struct list *list; struct list *list;
@ -1726,14 +1729,14 @@ hlsl_prog:
{ {
hlsl_error(ctx, $2.decl->loc, VKD3D_SHADER_ERROR_HLSL_REDEFINED, hlsl_error(ctx, $2.decl->loc, VKD3D_SHADER_ERROR_HLSL_REDEFINED,
"Function \"%s\" is already defined.", $2.name); "Function \"%s\" is already defined.", $2.name);
hlsl_note(ctx, decl->loc, VKD3D_SHADER_LOG_ERROR, "\"%s\" was previously defined here.", $2.name);
YYABORT; YYABORT;
} }
else if (!hlsl_type_compare(decl->return_type, $2.decl->return_type)) else if (!hlsl_type_compare(decl->return_type, $2.decl->return_type))
{ {
hlsl_error(ctx, $2.decl->loc, VKD3D_SHADER_ERROR_HLSL_REDEFINED, hlsl_error(ctx, $2.decl->loc, VKD3D_SHADER_ERROR_HLSL_REDEFINED,
"Function \"%s\" was already declared with a different return type.", $2.name); "Function \"%s\" was already declared with a different return type.", $2.name);
hlsl_note(ctx, decl->loc, VKD3D_SHADER_LOG_ERROR, hlsl_note(ctx, decl->loc, VKD3D_SHADER_LOG_ERROR, "\"%s\" was previously declared here.", $2.name);
"\"%s\" previously declared here", $2.name);
YYABORT; YYABORT;
} }
} }
@ -1840,19 +1843,23 @@ fields_list:
} }
| fields_list field | fields_list field
{ {
bool ret; struct hlsl_struct_field *field, *next, *existing;
struct hlsl_struct_field *field, *next;
$$ = $1; $$ = $1;
LIST_FOR_EACH_ENTRY_SAFE(field, next, $2, struct hlsl_struct_field, entry) LIST_FOR_EACH_ENTRY_SAFE(field, next, $2, struct hlsl_struct_field, entry)
{ {
ret = add_struct_field($$, field); if ((existing = get_struct_field($$, field->name)))
if (ret == false)
{ {
hlsl_error(ctx, @2, VKD3D_SHADER_ERROR_HLSL_REDEFINED, hlsl_error(ctx, @2, VKD3D_SHADER_ERROR_HLSL_REDEFINED,
"Field \"%s\" is already defined.", field->name); "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); vkd3d_free(field);
} }
else
{
list_add_tail($$, &field->entry);
}
} }
vkd3d_free($2); vkd3d_free($2);
} }
@ -1889,15 +1896,20 @@ func_prototype:
/* var_modifiers is necessary to avoid shift/reduce conflicts. */ /* var_modifiers is necessary to avoid shift/reduce conflicts. */
var_modifiers type var_identifier '(' parameters ')' colon_attribute var_modifiers type var_identifier '(' parameters ')' colon_attribute
{ {
struct hlsl_ir_var *var;
if ($1) if ($1)
{ {
hlsl_error(ctx, @1, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, hlsl_error(ctx, @1, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER,
"Modifiers are not allowed on functions."); "Modifiers are not allowed on functions.");
YYABORT; 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; YYABORT;
} }
if (hlsl_type_is_void($2) && $7.semantic) if (hlsl_type_is_void($2) && $7.semantic)
@ -2565,22 +2577,15 @@ postfix_expr:
struct hlsl_type *type = node->data_type; struct hlsl_type *type = node->data_type;
struct hlsl_struct_field *field; struct hlsl_struct_field *field;
$$ = NULL; if (!(field = get_struct_field(type->e.elements, $3)))
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 (!$$)
{ {
hlsl_error(ctx, @3, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, "Field \"%s\" is not defined.", $3); hlsl_error(ctx, @3, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, "Field \"%s\" is not defined.", $3);
YYABORT; YYABORT;
} }
if (!add_record_load(ctx, $1, node, field, @2))
YYABORT;
$$ = $1;
} }
else if (node->data_type->type <= HLSL_CLASS_LAST_NUMERIC) else if (node->data_type->type <= HLSL_CLASS_LAST_NUMERIC)
{ {