const char *comma = "";
foreach_list(node, parameters) {
- const ir_instruction *const param = (ir_instruction *) node;
+ const ir_variable *const param = (ir_variable *) node;
ralloc_asprintf_append(&str, "%s%s", comma, param->type->name);
comma = ", ";
return false;
}
- if (actual->variable_referenced()
- && actual->variable_referenced()->read_only) {
+ ir_variable *var = actual->variable_referenced();
+ if (var)
+ var->assigned = true;
+
+ if (var && var->read_only) {
_mesa_glsl_error(&loc, state,
"function parameter '%s %s' references the "
"read-only variable '%s'",
formal_iter.next();
}
- /* Always insert the call in the instruction stream, and return a deref
- * of its return val if it returns a value, since we don't know if
- * the rvalue is going to be assigned to anything or not.
+ /* If the function call is a constant expression, don't generate any
+ * instructions; just generate an ir_constant.
*
- * Also insert any out parameter conversions after the call.
+ * Function calls were first allowed to be constant expressions in GLSL 1.20.
*/
- ir_call *call = new(ctx) ir_call(sig, actual_parameters);
- ir_dereference_variable *deref;
- if (!sig->return_type->is_void()) {
- /* If the function call is a constant expression, don't
- * generate the instructions to call it; just generate an
- * ir_constant representing the constant value.
- *
- * Function calls can only be constant expressions starting
- * in GLSL 1.20.
- */
- if (state->language_version >= 120) {
- ir_constant *const_val = call->constant_expression_value();
- if (const_val) {
- return const_val;
- }
+ if (state->language_version >= 120) {
+ ir_constant *value = sig->constant_expression_value(actual_parameters, NULL);
+ if (value != NULL) {
+ return value;
}
+ }
+ ir_dereference_variable *deref = NULL;
+ if (!sig->return_type->is_void()) {
+ /* Create a new temporary to hold the return value. */
ir_variable *var;
var = new(ctx) ir_variable(sig->return_type,
instructions->push_tail(var);
deref = new(ctx) ir_dereference_variable(var);
- ir_assignment *assign = new(ctx) ir_assignment(deref, call, NULL);
- instructions->push_tail(assign);
- *call_ir = call;
-
- deref = new(ctx) ir_dereference_variable(var);
- } else {
- instructions->push_tail(call);
- *call_ir = call;
- deref = NULL;
}
+ ir_call *call = new(ctx) ir_call(sig, deref, actual_parameters);
+ instructions->push_tail(call);
+
+ /* Also emit any necessary out-parameter conversions. */
instructions->append_list(&post_call_conversions);
- return deref;
+
+ return deref ? deref->clone(ctx, NULL) : NULL;
}
/**
result = new(ctx) ir_expression(ir_unop_i2u, src);
break;
case GLSL_TYPE_FLOAT:
- result = new(ctx) ir_expression(ir_unop_i2u,
- new(ctx) ir_expression(ir_unop_f2i, src));
+ result = new(ctx) ir_expression(ir_unop_f2u, src);
break;
case GLSL_TYPE_BOOL:
result = new(ctx) ir_expression(ir_unop_i2u,
"parameter%s",
(constructor_type->length != 0) ? "at least" : "exactly",
min_param, (min_param <= 1) ? "" : "s");
- return ir_call::get_error_instruction(ctx);
+ return ir_rvalue::error_value(ctx);
}
if (constructor_type->length == 0) {
_mesa_glsl_error(& loc, state, "unknown type `%s' (structure name "
"may be shadowed by a variable with the same name)",
type->type_name);
- return ir_call::get_error_instruction(ctx);
+ return ir_rvalue::error_value(ctx);
}
if (constructor_type->is_sampler()) {
_mesa_glsl_error(& loc, state, "cannot construct sampler type `%s'",
constructor_type->name);
- return ir_call::get_error_instruction(ctx);
+ return ir_rvalue::error_value(ctx);
}
if (constructor_type->is_array()) {
if (state->language_version <= 110) {
_mesa_glsl_error(& loc, state,
"array constructors forbidden in GLSL 1.10");
- return ir_call::get_error_instruction(ctx);
+ return ir_rvalue::error_value(ctx);
}
return process_array_constructor(instructions, constructor_type,
"insufficient parameters to constructor "
"for `%s'",
constructor_type->name);
- return ir_call::get_error_instruction(ctx);
+ return ir_rvalue::error_value(ctx);
}
if (apply_implicit_conversion(constructor_type->fields.structure[i].type,
constructor_type->fields.structure[i].name,
ir->type->name,
constructor_type->fields.structure[i].type->name);
- return ir_call::get_error_instruction(ctx);;
+ return ir_rvalue::error_value(ctx);;
}
node = node->next;
if (!node->is_tail_sentinel()) {
_mesa_glsl_error(&loc, state, "too many parameters in constructor "
"for `%s'", constructor_type->name);
- return ir_call::get_error_instruction(ctx);
+ return ir_rvalue::error_value(ctx);
}
ir_rvalue *const constant =
}
if (!constructor_type->is_numeric() && !constructor_type->is_boolean())
- return ir_call::get_error_instruction(ctx);
+ return ir_rvalue::error_value(ctx);
/* Total number of components of the type being constructed. */
const unsigned type_components = constructor_type->components();
_mesa_glsl_error(& loc, state, "too many parameters to `%s' "
"constructor",
constructor_type->name);
- return ir_call::get_error_instruction(ctx);
+ return ir_rvalue::error_value(ctx);
}
if (!result->type->is_numeric() && !result->type->is_boolean()) {
_mesa_glsl_error(& loc, state, "cannot construct `%s' from a "
"non-numeric data type",
constructor_type->name);
- return ir_call::get_error_instruction(ctx);
+ return ir_rvalue::error_value(ctx);
}
/* Count the number of matrix and nonmatrix parameters. This
_mesa_glsl_error(& loc, state, "cannot construct `%s' from a "
"matrix in GLSL 1.10",
constructor_type->name);
- return ir_call::get_error_instruction(ctx);
+ return ir_rvalue::error_value(ctx);
}
/* From page 50 (page 56 of the PDF) of the GLSL 1.50 spec:
_mesa_glsl_error(& loc, state, "for matrix `%s' constructor, "
"matrix must be only parameter",
constructor_type->name);
- return ir_call::get_error_instruction(ctx);
+ return ir_rvalue::error_value(ctx);
}
/* From page 28 (page 34 of the PDF) of the GLSL 1.10 spec:
_mesa_glsl_error(& loc, state, "too few components to construct "
"`%s'",
constructor_type->name);
- return ir_call::get_error_instruction(ctx);
+ return ir_rvalue::error_value(ctx);
}
/* Later, we cast each parameter to the same base type as the
ir_rvalue *value = NULL;
if (sig == NULL) {
no_matching_function_error(func_name, &loc, &actual_parameters, state);
- value = ir_call::get_error_instruction(ctx);
+ value = ir_rvalue::error_value(ctx);
} else if (!verify_parameter_modes(state, sig, actual_parameters, this->expressions)) {
/* an error has already been emitted */
- value = ir_call::get_error_instruction(ctx);
+ value = ir_rvalue::error_value(ctx);
} else {
value = generate_call(instructions, sig, &loc, &actual_parameters,
&call, state);
return value;
}
- return ir_call::get_error_instruction(ctx);
+ return ir_rvalue::error_value(ctx);
}