}
/**
- * If a function call is generated, \c call_ir will point to it on exit.
- * Otherwise \c call_ir will be set to \c NULL.
+ * Generate a function call.
+ *
+ * For non-void functions, this returns a dereference of the temporary variable
+ * which stores the return value for the call. For void functions, this returns
+ * NULL.
*/
static ir_rvalue *
generate_call(exec_list *instructions, ir_function_signature *sig,
exec_list *actual_parameters,
- ir_call **call_ir,
struct _mesa_glsl_parse_state *state)
{
void *ctx = state;
exec_list post_call_conversions;
- *call_ir = NULL;
-
/* Perform implicit conversion of arguments. For out parameters, we need
* to place them in a temporary variable and do the conversion after the
* call takes place. Since we haven't emitted the call yet, we'll place
if (f != NULL) {
/* Look for a match in the local shader. If exact, we're done. */
bool is_exact = false;
- sig = local_sig = f->matching_signature(actual_parameters, &is_exact);
+ sig = local_sig = f->matching_signature(state, actual_parameters,
+ &is_exact);
if (is_exact)
goto done;
}
/* Local shader has no exact candidates; check the built-ins. */
- _mesa_glsl_initialize_functions(state);
- for (unsigned i = 0; i < state->num_builtins_to_link; i++) {
- ir_function *builtin =
- state->builtins_to_link[i]->symbols->get_function(name);
- if (builtin == NULL)
- continue;
-
- bool is_exact = false;
- ir_function_signature *builtin_sig =
- builtin->matching_signature(actual_parameters, &is_exact);
-
- if (builtin_sig == NULL)
- continue;
-
- /* If the built-in signature is exact, we can stop. */
- if (is_exact) {
- sig = builtin_sig;
- goto done;
- }
-
- if (sig == NULL) {
- /* We found an inexact match, which is better than nothing. However,
- * we should keep searching for an exact match.
- */
- sig = builtin_sig;
- }
- }
+ _mesa_glsl_initialize_builtin_functions();
+ sig = _mesa_glsl_find_builtin_function(state, name, actual_parameters);
done:
if (sig != NULL) {
return sig;
}
+static void
+print_function_prototypes(_mesa_glsl_parse_state *state, YYLTYPE *loc,
+ ir_function *f)
+{
+ if (f == NULL)
+ return;
+
+ foreach_list (node, &f->signatures) {
+ ir_function_signature *sig = (ir_function_signature *) node;
+
+ if (sig->is_builtin() && !sig->is_builtin_available(state))
+ continue;
+
+ char *str = prototype_string(sig->return_type, f->name, &sig->parameters);
+ _mesa_glsl_error(loc, state, " %s", str);
+ ralloc_free(str);
+ }
+}
+
/**
* Raise a "no matching function" error, listing all possible overloads the
* compiler considered so developers can figure out what went wrong.
_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);
+ _mesa_glsl_error(loc, state,
+ "no matching function for call to `%s'; candidates are:",
+ str);
ralloc_free(str);
- const char *prefix = "candidates are: ";
-
- 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;
-
- foreach_list (node, &f->signatures) {
- ir_function_signature *sig = (ir_function_signature *) node;
+ print_function_prototypes(state, loc, state->symbols->get_function(name));
- str = prototype_string(sig->return_type, f->name, &sig->parameters);
- _mesa_glsl_error(loc, state, "%s%s", prefix, str);
- ralloc_free(str);
-
- prefix = " ";
- }
+ if (state->uses_builtin_functions) {
+ gl_shader *sh = _mesa_glsl_get_builtin_function_shader();
+ print_function_prototypes(state, loc, sh->symbols->get_function(name));
}
}
* int i = { 1 }; // illegal, i is not an aggregate"
*/
if (constructor_type->vector_elements <= 1) {
- _mesa_glsl_error(loc, state, "Aggregates can only initialize vectors, "
+ _mesa_glsl_error(loc, state, "aggregates can only initialize vectors, "
"matrices, arrays, and structs");
return ir_rvalue::error_value(ctx);
}
exec_list actual_parameters;
const unsigned parameter_count =
process_parameters(instructions, &actual_parameters, parameters, state);
+ bool is_unsized_array = constructor_type->is_unsized_array();
- if ((parameter_count == 0)
- || ((constructor_type->length != 0)
- && (constructor_type->length != parameter_count))) {
- const unsigned min_param = (constructor_type->length == 0)
- ? 1 : constructor_type->length;
+ if ((parameter_count == 0) ||
+ (!is_unsized_array && (constructor_type->length != parameter_count))) {
+ const unsigned min_param = is_unsized_array
+ ? 1 : constructor_type->length;
_mesa_glsl_error(loc, state, "array constructor must have %s %u "
"parameter%s",
- (constructor_type->length == 0) ? "at least" : "exactly",
+ is_unsized_array ? "at least" : "exactly",
min_param, (min_param <= 1) ? "" : "s");
return ir_rvalue::error_value(ctx);
}
- if (constructor_type->length == 0) {
+ if (is_unsized_array) {
constructor_type =
glsl_type::get_array_instance(constructor_type->element_type(),
parameter_count);
ir_function_signature *sig =
match_function_by_name(func_name, &actual_parameters, state);
- ir_call *call = NULL;
ir_rvalue *value = NULL;
if (sig == NULL) {
no_matching_function_error(func_name, &loc, &actual_parameters, state);
/* an error has already been emitted */
value = ir_rvalue::error_value(ctx);
} else {
- value = generate_call(instructions, sig, &actual_parameters,
- &call, state);
+ value = generate_call(instructions, sig, &actual_parameters, state);
}
return value;
return ir_rvalue::error_value(ctx);
}
+
+ir_rvalue *
+ast_aggregate_initializer::hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ void *ctx = state;
+ YYLTYPE loc = this->get_location();
+ const char *name;
+
+ if (!this->constructor_type) {
+ _mesa_glsl_error(&loc, state, "type of C-style initializer unknown");
+ return ir_rvalue::error_value(ctx);
+ }
+ const glsl_type *const constructor_type =
+ this->constructor_type->glsl_type(&name, state);
+
+ if (!state->ARB_shading_language_420pack_enable) {
+ _mesa_glsl_error(&loc, state, "C-style initialization requires the "
+ "GL_ARB_shading_language_420pack extension");
+ return ir_rvalue::error_value(ctx);
+ }
+
+ if (this->constructor_type->is_array) {
+ return process_array_constructor(instructions, constructor_type, &loc,
+ &this->expressions, state);
+ }
+
+ if (this->constructor_type->structure) {
+ return process_record_constructor(instructions, constructor_type, &loc,
+ &this->expressions, state);
+ }
+
+ return process_vec_mat_constructor(instructions, constructor_type, &loc,
+ &this->expressions, state);
+}