Matteo Bruni : d3dcompiler: Add some checks to function definitions.

Alexandre Julliard julliard at winehq.org
Thu Oct 11 15:25:17 CDT 2012


Module: wine
Branch: master
Commit: 69922c671a5a092cdf68ab4a6c863ccd136c88c0
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=69922c671a5a092cdf68ab4a6c863ccd136c88c0

Author: Matteo Bruni <mbruni at codeweavers.com>
Date:   Thu Oct 11 19:48:49 2012 +0200

d3dcompiler: Add some checks to function definitions.

---

 dlls/d3dcompiler_43/d3dcompiler_private.h |    1 +
 dlls/d3dcompiler_43/hlsl.y                |   55 +++++++++++++++++++++++++++++
 dlls/d3dcompiler_43/utils.c               |    2 +-
 3 files changed, 57 insertions(+), 1 deletions(-)

diff --git a/dlls/d3dcompiler_43/d3dcompiler_private.h b/dlls/d3dcompiler_43/d3dcompiler_private.h
index a6c27d0..c8a92f1 100644
--- a/dlls/d3dcompiler_43/d3dcompiler_private.h
+++ b/dlls/d3dcompiler_43/d3dcompiler_private.h
@@ -1109,6 +1109,7 @@ struct hlsl_type *clone_hlsl_type(struct hlsl_type *old) DECLSPEC_HIDDEN;
 struct hlsl_type *get_type(struct hlsl_scope *scope, const char *name, BOOL recursive) DECLSPEC_HIDDEN;
 BOOL find_function(const char *name) DECLSPEC_HIDDEN;
 unsigned int components_count_type(struct hlsl_type *type) DECLSPEC_HIDDEN;
+BOOL compare_hlsl_types(const struct hlsl_type *t1, const struct hlsl_type *t2) DECLSPEC_HIDDEN;
 BOOL compatible_data_types(struct hlsl_type *s1, struct hlsl_type *s2) DECLSPEC_HIDDEN;
 struct hlsl_ir_expr *new_expr(enum hlsl_ir_expr_op op, struct hlsl_ir_node **operands,
         struct source_location *loc) DECLSPEC_HIDDEN;
diff --git a/dlls/d3dcompiler_43/hlsl.y b/dlls/d3dcompiler_43/hlsl.y
index d327102..6200b96 100644
--- a/dlls/d3dcompiler_43/hlsl.y
+++ b/dlls/d3dcompiler_43/hlsl.y
@@ -808,6 +808,29 @@ static BOOL add_typedef(DWORD modifiers, struct hlsl_type *orig_type, struct lis
     return TRUE;
 }
 
+static const struct hlsl_ir_function_decl *get_overloaded_func(struct wine_rb_tree *funcs, char *name,
+        struct list *params, BOOL exact_signature)
+{
+    struct hlsl_ir_function *func;
+    struct wine_rb_entry *entry;
+
+    entry = wine_rb_get(funcs, name);
+    if (entry)
+    {
+        func = WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function, entry);
+
+        entry = wine_rb_get(&func->overloads, params);
+        if (!entry)
+        {
+            if (!exact_signature)
+                FIXME("No exact match, search for a compatible overloaded function (if any).\n");
+            return NULL;
+        }
+        return WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function_decl, entry);
+    }
+    return NULL;
+}
+
 %}
 
 %locations
@@ -1000,6 +1023,38 @@ hlsl_prog:                /* empty */
                             }
                         | hlsl_prog func_declaration
                             {
+                                const struct hlsl_ir_function_decl *decl;
+
+                                decl = get_overloaded_func(&hlsl_ctx.functions, $2.name, $2.decl->parameters, TRUE);
+                                if (decl && !decl->func->intrinsic)
+                                {
+                                    if (decl->body && $2.decl->body)
+                                    {
+                                        hlsl_report_message($2.decl->node.loc.file, $2.decl->node.loc.line,
+                                                $2.decl->node.loc.col, HLSL_LEVEL_ERROR,
+                                                "redefinition of function %s", debugstr_a($2.name));
+                                        return 1;
+                                    }
+                                    else if (!compare_hlsl_types(decl->node.data_type, $2.decl->node.data_type))
+                                    {
+                                        hlsl_report_message($2.decl->node.loc.file, $2.decl->node.loc.line,
+                                                $2.decl->node.loc.col, HLSL_LEVEL_ERROR,
+                                                "redefining function %s with a different return type",
+                                                debugstr_a($2.name));
+                                        hlsl_report_message(decl->node.loc.file, decl->node.loc.line, decl->node.loc.col, HLSL_LEVEL_NOTE,
+                                                "%s previously declared here",
+                                                debugstr_a($2.name));
+                                        return 1;
+                                    }
+                                }
+
+                                if ($2.decl->node.data_type->base_type == HLSL_TYPE_VOID && $2.decl->semantic)
+                                {
+                                    hlsl_report_message($2.decl->node.loc.file, $2.decl->node.loc.line,
+                                            $2.decl->node.loc.col, HLSL_LEVEL_ERROR,
+                                            "void function with a semantic");
+                                }
+
                                 TRACE("Adding function '%s' to the function list.\n", $2.name);
                                 add_function_decl(&hlsl_ctx.functions, $2.name, $2.decl, FALSE);
                             }
diff --git a/dlls/d3dcompiler_43/utils.c b/dlls/d3dcompiler_43/utils.c
index e5f3f74..830965d 100644
--- a/dlls/d3dcompiler_43/utils.c
+++ b/dlls/d3dcompiler_43/utils.c
@@ -907,7 +907,7 @@ unsigned int components_count_type(struct hlsl_type *type)
     return count;
 }
 
-static BOOL compare_hlsl_types(const struct hlsl_type *t1, const struct hlsl_type *t2)
+BOOL compare_hlsl_types(const struct hlsl_type *t1, const struct hlsl_type *t2)
 {
     if (t1 == t2)
         return TRUE;




More information about the wine-cvs mailing list