Module: wine Branch: master Commit: 69922c671a5a092cdf68ab4a6c863ccd136c88c0 URL: http://source.winehq.org/git/wine.git/?a=commit;h=69922c671a5a092cdf68ab4a6c...
Author: Matteo Bruni mbruni@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;