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

Alexandre Julliard julliard at winehq.org
Thu Mar 4 15:46:31 CST 2021


Module: vkd3d
Branch: master
Commit: 3d5a4f133a72139bb2bcd209c5ba626ef80dadb4
URL:    https://source.winehq.org/git/vkd3d.git/?a=commit;h=3d5a4f133a72139bb2bcd209c5ba626ef80dadb4

Author: Zebediah Figura <zfigura at codeweavers.com>
Date:   Tue Mar  2 15:34:43 2021 -0600

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

Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
Signed-off-by: Matteo Bruni <mbruni at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 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 4e73060..0486c95 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 36e7dd0..33eefe9 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 50aeeab..1caeb41 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)
             {




More information about the wine-cvs mailing list