[Mesa-dev] [PATCH 2/9] glsl: Split up function matching and call generation a bit more.
Kenneth Graunke
kenneth at whitecape.org
Wed Mar 28 20:33:01 PDT 2012
We used to have one big function, match_signature_by_name, which found
a matching signature, performed out-parameter conversions, and generated
the ir_call. As the code for matching against built-in functions became
more complicated, I split it internally, creating generate_call().
However, I left the same awkward interface. This patch splits it into
three functions:
1. match_signature_by_name()
This now takes a name, a list of parameters, the symbol table, and
returns an ir_function_signature. Simple and one purpose: matching.
2. no_matching_function_error()
Generate the "no matching function" error and list of prototypes.
This was complex enough that I felt it deserved its own function.
3. generate_call()
Do the out-parameter conversion and generate the ir_call. This
could probably use more splitting.
The caller now has a more natural workflow: find a matching signature,
then either generate an error or a call.
Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
---
src/glsl/ast_function.cpp | 82 +++++++++++++++++++++++++-------------------
1 files changed, 47 insertions(+), 35 deletions(-)
It's probably easier to apply this and compare rather than reading the
raw diff itself.
diff --git a/src/glsl/ast_function.cpp b/src/glsl/ast_function.cpp
index 1c2e861..2ad8fba 100644
--- a/src/glsl/ast_function.cpp
+++ b/src/glsl/ast_function.cpp
@@ -275,10 +275,12 @@ generate_call(exec_list *instructions, ir_function_signature *sig,
return deref;
}
-static ir_rvalue *
-match_function_by_name(exec_list *instructions, const char *name,
- YYLTYPE *loc, exec_list *actual_parameters,
- ir_call **call_ir,
+/**
+ * Given a function name and parameter list, find the matching signature.
+ */
+static ir_function_signature *
+match_function_by_name(const char *name,
+ exec_list *actual_parameters,
struct _mesa_glsl_parse_state *state)
{
void *ctx = state;
@@ -350,43 +352,45 @@ done:
}
f->add_signature(sig->clone_prototype(f, NULL));
}
+ }
+ return sig;
+}
- /* Finally, generate a call instruction. */
- return generate_call(instructions, sig, loc, actual_parameters,
- call_ir, state);
- } else {
- char *str = prototype_string(NULL, name, actual_parameters);
-
- _mesa_glsl_error(loc, state, "no matching function for call to `%s'",
- str);
- ralloc_free(str);
-
- const char *prefix = "candidates are: ";
+/**
+ * Raise a "no matching function" error, listing all possible overloads the
+ * compiler considered so developers can figure out what went wrong.
+ */
+static void
+no_matching_function_error(const char *name,
+ YYLTYPE *loc,
+ exec_list *actual_parameters,
+ _mesa_glsl_parse_state *state)
+{
+ char *str = prototype_string(NULL, name, actual_parameters);
+ _mesa_glsl_error(loc, state, "no matching function for call to `%s'", str);
+ ralloc_free(str);
- for (int i = -1; i < (int) state->num_builtins_to_link; i++) {
- glsl_symbol_table *syms = i >= 0 ? state->builtins_to_link[i]->symbols
- : state->symbols;
- f = syms->get_function(name);
- if (f == NULL)
- continue;
+ const char *prefix = "candidates are: ";
- foreach_list (node, &f->signatures) {
- ir_function_signature *sig = (ir_function_signature *) node;
+ for (int i = -1; i < (int) state->num_builtins_to_link; i++) {
+ glsl_symbol_table *syms = i >= 0 ? state->builtins_to_link[i]->symbols
+ : state->symbols;
+ ir_function *f = syms->get_function(name);
+ if (f == NULL)
+ continue;
- str = prototype_string(sig->return_type, f->name, &sig->parameters);
- _mesa_glsl_error(loc, state, "%s%s", prefix, str);
- ralloc_free(str);
+ foreach_list (node, &f->signatures) {
+ ir_function_signature *sig = (ir_function_signature *) node;
- prefix = " ";
- }
+ str = prototype_string(sig->return_type, f->name, &sig->parameters);
+ _mesa_glsl_error(loc, state, "%s%s", prefix, str);
+ ralloc_free(str);
+ prefix = " ";
}
-
- return ir_call::get_error_instruction(ctx);
}
}
-
/**
* Perform automatic type conversion of constructor parameters
*
@@ -1447,17 +1451,25 @@ ast_function_expression::hir(exec_list *instructions,
}
} else {
const ast_expression *id = subexpressions[0];
+ const char *func_name = id->primary_expression.identifier;
YYLTYPE loc = id->get_location();
exec_list actual_parameters;
process_parameters(instructions, &actual_parameters, &this->expressions,
state);
+ ir_function_signature *sig =
+ match_function_by_name(func_name, &actual_parameters, state);
+
ir_call *call = NULL;
- ir_rvalue *const value =
- match_function_by_name(instructions,
- id->primary_expression.identifier,
- &loc, &actual_parameters, &call, state);
+ ir_rvalue *value = NULL;
+ if (sig == NULL) {
+ no_matching_function_error(func_name, &loc, &actual_parameters, state);
+ value = ir_call::get_error_instruction(ctx);
+ } else {
+ value = generate_call(instructions, sig, &loc, &actual_parameters,
+ &call, state);
+ }
if (call != NULL) {
/* If a function was found, make sure that none of the 'out' or 'inout'
--
1.7.7.6
More information about the mesa-dev
mailing list