ir_reader: Perform a preliminary pass to scan for function prototypes.
This commit is contained in:

committed by
Ian Romanick

parent
ddf5a011e2
commit
09cad1339d
126
ir_reader.cpp
126
ir_reader.cpp
@@ -31,6 +31,12 @@ static void ir_read_error(_mesa_glsl_parse_state *, s_expression *,
|
|||||||
const char *fmt, ...);
|
const char *fmt, ...);
|
||||||
static const glsl_type *read_type(_mesa_glsl_parse_state *, s_expression *);
|
static const glsl_type *read_type(_mesa_glsl_parse_state *, s_expression *);
|
||||||
|
|
||||||
|
static void scan_for_prototypes(_mesa_glsl_parse_state *, exec_list *,
|
||||||
|
s_expression *);
|
||||||
|
static void read_prototypes(_mesa_glsl_parse_state *, exec_list *, s_list *);
|
||||||
|
static ir_function_signature *read_prototype(_mesa_glsl_parse_state *,
|
||||||
|
s_list *);
|
||||||
|
|
||||||
static void read_instructions(_mesa_glsl_parse_state *, exec_list *,
|
static void read_instructions(_mesa_glsl_parse_state *, exec_list *,
|
||||||
s_expression *, ir_loop *);
|
s_expression *, ir_loop *);
|
||||||
static ir_instruction *read_instruction(_mesa_glsl_parse_state *,
|
static ir_instruction *read_instruction(_mesa_glsl_parse_state *,
|
||||||
@@ -69,6 +75,10 @@ _mesa_glsl_read_ir(_mesa_glsl_parse_state *state, exec_list *instructions,
|
|||||||
* FINISHME: _mesa_glsl_initialize_constructors(instructions, state);
|
* FINISHME: _mesa_glsl_initialize_constructors(instructions, state);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
scan_for_prototypes(state, instructions, expr);
|
||||||
|
if (state->error)
|
||||||
|
return;
|
||||||
|
|
||||||
read_instructions(state, instructions, expr, NULL);
|
read_instructions(state, instructions, expr, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,6 +156,122 @@ read_type(_mesa_glsl_parse_state *st, s_expression *expr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
scan_for_prototypes(_mesa_glsl_parse_state *st, exec_list *instructions,
|
||||||
|
s_expression *expr)
|
||||||
|
{
|
||||||
|
s_list *list = SX_AS_LIST(expr);
|
||||||
|
if (list == NULL) {
|
||||||
|
ir_read_error(st, expr, "Expected (<instruction> ...); found an atom.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach_iter(exec_list_iterator, it, list->subexpressions) {
|
||||||
|
s_list *sub = SX_AS_LIST(it.get());
|
||||||
|
if (sub == NULL)
|
||||||
|
continue; // not a (function ...); ignore it.
|
||||||
|
|
||||||
|
s_symbol *tag = SX_AS_SYMBOL(sub->subexpressions.get_head());
|
||||||
|
if (tag == NULL || strcmp(tag->value(), "function") != 0)
|
||||||
|
continue; // not a (function ...); ignore it.
|
||||||
|
|
||||||
|
read_prototypes(st, instructions, sub);
|
||||||
|
if (st->error)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
read_prototypes(_mesa_glsl_parse_state *st, exec_list *instructions,
|
||||||
|
s_list *list)
|
||||||
|
{
|
||||||
|
if (list->length() < 3) {
|
||||||
|
ir_read_error(st, list, "Expected (function <name> (signature ...) ...)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
s_symbol *name = SX_AS_SYMBOL(list->subexpressions.head->next);
|
||||||
|
if (name == NULL) {
|
||||||
|
ir_read_error(st, list, "Expected (function <name> ...)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ir_function *f = new ir_function(name->value());
|
||||||
|
bool added = st->symbols->add_function(name->value(), f);
|
||||||
|
if (!added) {
|
||||||
|
ir_read_error(st, list, "Function %s already exists.", name->value());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
instructions->push_tail(f);
|
||||||
|
|
||||||
|
exec_list_iterator it = list->subexpressions.iterator();
|
||||||
|
it.next(); // skip "function" tag
|
||||||
|
it.next(); // skip function name
|
||||||
|
for (/* nothing */; it.has_next(); it.next()) {
|
||||||
|
s_list *siglist = SX_AS_LIST(it.get());
|
||||||
|
if (siglist == NULL) {
|
||||||
|
ir_read_error(st, list, "Expected (function (signature ...) ...)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
s_symbol *tag = SX_AS_SYMBOL(siglist->subexpressions.get_head());
|
||||||
|
if (tag == NULL || strcmp(tag->value(), "signature") != 0) {
|
||||||
|
ir_read_error(st, siglist, "Expected (signature ...)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ir_function_signature *sig = read_prototype(st, siglist);
|
||||||
|
if (sig == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
f->add_signature(sig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static ir_function_signature *
|
||||||
|
read_prototype(_mesa_glsl_parse_state *st, s_list *list)
|
||||||
|
{
|
||||||
|
if (list->length() != 4) {
|
||||||
|
ir_read_error(st, list, "Expected (signature <type> (parameters ...) "
|
||||||
|
"(<instruction> ...))");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
s_expression *type_expr = (s_expression*) list->subexpressions.head->next;
|
||||||
|
const glsl_type *return_type = read_type(st, type_expr);
|
||||||
|
if (return_type == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
s_list *paramlist = SX_AS_LIST(type_expr->next);
|
||||||
|
if (paramlist == NULL) {
|
||||||
|
ir_read_error(st, list, "Expected (signature %s (parameters ...) ...)",
|
||||||
|
return_type->name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
s_symbol *paramtag = SX_AS_SYMBOL(paramlist->subexpressions.get_head());
|
||||||
|
if (paramtag == NULL || strcmp(paramtag->value(), "parameters") != 0) {
|
||||||
|
ir_read_error(st, paramlist, "Expected (parameters ...)");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ir_function_signature *sig = new ir_function_signature(return_type);
|
||||||
|
|
||||||
|
exec_list_iterator it = paramlist->subexpressions.iterator();
|
||||||
|
for (it.next() /* skip "parameters" */; it.has_next(); it.next()) {
|
||||||
|
s_list *decl = SX_AS_LIST(it.get());
|
||||||
|
ir_variable *var = read_declaration(st, decl);
|
||||||
|
if (var == NULL) {
|
||||||
|
delete sig;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
sig->parameters.push_tail(var);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sig;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
read_instructions(_mesa_glsl_parse_state *st, exec_list *instructions,
|
read_instructions(_mesa_glsl_parse_state *st, exec_list *instructions,
|
||||||
s_expression *expr, ir_loop *loop_ctx)
|
s_expression *expr, ir_loop *loop_ctx)
|
||||||
|
Reference in New Issue
Block a user