This effectively reverts
b6f15869b324ae64a00d0fe46fa3c8c62c1edb6c.
In desktop GLSL, defining a function with the same name as a built-in
hides that built-in function completely, so there would never be
built-in and user function signatures in the same ir_function.
However, in GLSL ES, overloading built-ins is allowed, and does not
hide the built-in signatures - so we're back to needing this.
* that the previously seen signature does not have an associated definition.
*/
f = state->symbols->get_function(name);
- if (f != NULL && !f->is_builtin) {
+ if (f != NULL && !f->has_builtin_signature()) {
sig = f->exact_matching_signature(&hir_parameters);
if (sig != NULL) {
const char *badvar = sig->qualifiers_match(&hir_parameters);
: return_type(return_type), is_defined(false), _function(NULL)
{
this->ir_type = ir_type_function_signature;
+ this->is_builtin = false;
}
{
this->ir_type = ir_type_function;
this->name = talloc_strdup(this, name);
- this->is_builtin = false;
+}
+
+
+bool
+ir_function::has_builtin_signature()
+{
+ foreach_list(n, &this->signatures) {
+ ir_function_signature *const sig = (ir_function_signature *) n;
+ if (sig->is_builtin)
+ return true;
+ }
+ return false;
}
/** Whether or not this function has a body (which may be empty). */
unsigned is_defined:1;
+ /** Whether or not this function signature is a built-in. */
+ unsigned is_builtin:1;
+
/** Body of instructions in the function. */
struct exec_list body;
*/
const char *name;
- /** Whether or not this function is a built-in. */
- unsigned is_builtin:1;
+ /** Whether or not this function has a signature that is a built-in. */
+ bool has_builtin_signature();
/**
* List of ir_function_signature for each overloaded function with this name.
{
ir_function *copy = new(mem_ctx) ir_function(this->name);
- copy->is_builtin = this->is_builtin;
-
foreach_list_const(node, &this->signatures) {
const ir_function_signature *const sig =
(const ir_function_signature *const) node;
new(mem_ctx) ir_function_signature(this->return_type);
copy->is_defined = this->is_defined;
+ copy->is_builtin = this->is_builtin;
/* Clone the parameter list.
*/
* "Function calls to user-defined functions (non-built-in functions)
* cannot be used to form constant expressions."
*/
- if (!this->callee->function()->is_builtin)
+ if (!this->callee->is_builtin)
return NULL;
unsigned num_parameters = 0;
this->function = this->symbols->get_function(ir->name);
if (!this->function) {
this->function = new(this->mem_ctx) ir_function(ir->name);
- this->function->is_builtin = ir->is_builtin;
list->push_tail(this->function);
new(mem_ctx) ir_function_signature(ir->return_type);
copy->is_defined = false;
+ copy->is_builtin = ir->is_builtin;
/* Clone the parameter list, but NOT the body.
*/
void ir_print_visitor::visit(ir_function *ir)
{
- /* Don't print built-in functions as part of the IR. */
- if (ir->is_builtin)
- return;
-
printf("(function %s\n", ir->name);
indentation++;
foreach_iter(exec_list_iterator, iter, *ir) {
ir_function_signature *const sig = (ir_function_signature *) iter.get();
+ if (sig->is_builtin)
+ continue;
+
indent();
sig->accept(this);
printf("\n");
ir_function *f = st->symbols->get_function(name->value());
if (f == NULL) {
f = new(ctx) ir_function(name->value());
- f->is_builtin = true;
added = st->symbols->add_function(f->name, f);
assert(added);
}
if (sig == NULL && skip_body) {
/* If scanning for prototypes, generate a new signature. */
sig = new(ctx) ir_function_signature(return_type);
+ sig->is_builtin = true;
f->add_signature(sig);
} else if (sig != NULL) {
const char *badvar = sig->qualifiers_match(&hir_parameters);
ir_function_signature *sig =
(ir_function_signature *) iter.get();
- if (!sig->is_defined || f->is_builtin)
+ if (!sig->is_defined || sig->is_builtin)
continue;
ir_function_signature *other_sig =
other->exact_matching_signature(& sig->parameters);
if ((other_sig != NULL) && other_sig->is_defined
- && !other_sig->function()->is_builtin) {
+ && !other_sig->is_builtin) {
linker_error_printf(prog,
"function `%s' is multiply defined",
f->name);