glsl: Properly add functions during lazy built-in prototype importing.

The original lazy built-in importing patch did not add the newly created
function to the symbol table, nor actually emit it into the IR stream.

Adding it to the symbol table is non-trivial since importing occurs when
generating some ir_call in a nested scope.  A new add_global_function
method, backed by new symbol_table code in the previous patch, handles
this.

Fixes bug #32030.
This commit is contained in:
Kenneth Graunke
2010-12-06 10:54:21 -08:00
parent a8f52647b0
commit c17c790387
3 changed files with 25 additions and 7 deletions

View File

@@ -99,23 +99,29 @@ match_function_by_name(exec_list *instructions, const char *name,
{
void *ctx = state;
ir_function *f = state->symbols->get_function(name);
ir_function_signature *sig = NULL;
ir_function_signature *sig;
sig = f ? f->matching_signature(actual_parameters) : NULL;
/* FINISHME: This doesn't handle the case where shader X contains a
* FINISHME: matching signature but shader X + N contains an _exact_
* FINISHME: matching signature.
*/
if (f != NULL) {
sig = f->matching_signature(actual_parameters);
} else if (state->symbols->get_type(name) == NULL && (state->language_version == 110 || state->symbols->get_variable(name) == NULL)) {
if (sig == NULL && (f == NULL || state->es_shader || !f->has_user_signature()) && state->symbols->get_type(name) == NULL && (state->language_version == 110 || state->symbols->get_variable(name) == NULL)) {
/* The current shader doesn't contain a matching function or signature.
* Before giving up, look for the prototype in the built-in functions.
*/
for (unsigned i = 0; i < state->num_builtins_to_link; i++) {
f = state->builtins_to_link[i]->symbols->get_function(name);
sig = f ? f->matching_signature(actual_parameters) : NULL;
ir_function *builtin;
builtin = state->builtins_to_link[i]->symbols->get_function(name);
sig = builtin ? builtin->matching_signature(actual_parameters) : NULL;
if (sig != NULL) {
f = new(ctx) ir_function(name);
if (f == NULL) {
f = new(ctx) ir_function(name);
state->symbols->add_global_function(f);
emit_function(state, instructions, f);
}
f->add_signature(sig->clone_prototype(f, NULL));
break;
}