From 3521f0bdd52d226031a3b60e2cd89b4629147690 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Mon, 10 May 2010 10:47:14 -0700 Subject: [PATCH] Store AST function call parameters in expressions Previously the list of function call parameters was stored as a circular list in ast_expression::subexpressions[1]. They are now stored as a regular list in ast_expression::expressions. --- ast.h | 3 +- ast_function.cpp | 138 +++++++++++++++++++++++-------------------------- glsl_parser.ypp | 11 ++-- glsl_parser_extras.cpp | 14 ++--- 4 files changed, 79 insertions(+), 87 deletions(-) diff --git a/ast.h b/ast.h index 41787f5..9fa6518 100644 --- a/ast.h +++ b/ast.h @@ -178,7 +178,8 @@ public: /** - * List of expressions for an \c ast_sequence. + * List of expressions for an \c ast_sequence or parameters for an + * \c ast_function_call */ struct simple_node expressions; }; diff --git a/ast_function.cpp b/ast_function.cpp index cc8e9a8..35ffcdb 100644 --- a/ast_function.cpp +++ b/ast_function.cpp @@ -32,19 +32,15 @@ process_parameters(exec_list *instructions, exec_list *actual_parameters, simple_node *parameters, struct _mesa_glsl_parse_state *state) { - simple_node *const first = parameters; + simple_node *ptr; unsigned count = 0; - if (first != NULL) { - simple_node *ptr = first; - do { - ir_rvalue *const result = - ((ast_node *) ptr)->hir(instructions, state); - ptr = ptr->next; + foreach (ptr, parameters) { + ir_rvalue *const result = + ((ast_node *) ptr)->hir(instructions, state); - actual_parameters->push_tail(result); - count++; - } while (ptr != first); + actual_parameters->push_tail(result); + count++; } return count; @@ -324,7 +320,7 @@ ast_function_expression::hir(exec_list *instructions, } return process_array_constructor(instructions, constructor_type, - & loc, subexpressions[1], state); + & loc, &this->expressions, state); } /* There are two kinds of constructor call. Constructors for built-in @@ -361,73 +357,69 @@ ast_function_expression::hir(exec_list *instructions, unsigned matrix_parameters = 0; unsigned nonmatrix_parameters = 0; exec_list actual_parameters; - simple_node *const first = subexpressions[1]; - assert(first != NULL); + assert(!is_empty_list(&this->expressions)); - if (first != NULL) { - simple_node *ptr = first; - do { - ir_rvalue *const result = - ((ast_node *) ptr)->hir(instructions, state)->as_rvalue(); - ptr = ptr->next; + simple_node *ptr; + foreach (ptr, &this->expressions) { + ir_rvalue *const result = + ((ast_node *) ptr)->hir(instructions, state)->as_rvalue(); - /* From page 50 (page 56 of the PDF) of the GLSL 1.50 spec: - * - * "It is an error to provide extra arguments beyond this - * last used argument." - */ - if (components_used >= type_components) { - _mesa_glsl_error(& loc, state, "too many parameters to `%s' " - "constructor", - constructor_type->name); - return ir_call::get_error_instruction(); - } - - 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(); - } - - /* Count the number of matrix and nonmatrix parameters. This - * is used below to enforce some of the constructor rules. - */ - if (result->type->is_matrix()) - matrix_parameters++; - else - nonmatrix_parameters++; + /* From page 50 (page 56 of the PDF) of the GLSL 1.50 spec: + * + * "It is an error to provide extra arguments beyond this + * last used argument." + */ + if (components_used >= type_components) { + _mesa_glsl_error(& loc, state, "too many parameters to `%s' " + "constructor", + constructor_type->name); + return ir_call::get_error_instruction(); + } + + 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(); + } + + /* Count the number of matrix and nonmatrix parameters. This + * is used below to enforce some of the constructor rules. + */ + if (result->type->is_matrix()) + matrix_parameters++; + else + nonmatrix_parameters++; - /* Process each of the components of the parameter. Dereference - * each component individually, perform any type conversions, and - * add it to the parameter list for the constructor. + /* Process each of the components of the parameter. Dereference + * each component individually, perform any type conversions, and + * add it to the parameter list for the constructor. + */ + for (unsigned i = 0; i < result->type->components(); i++) { + if (components_used >= type_components) + break; + + ir_rvalue *const component = + convert_component(dereference_component(result, i), + base_type); + + /* All cases that could result in component->type being the + * error type should have already been caught above. */ - for (unsigned i = 0; i < result->type->components(); i++) { - if (components_used >= type_components) - break; - - ir_rvalue *const component = - convert_component(dereference_component(result, i), - base_type); - - /* All cases that could result in component->type being the - * error type should have already been caught above. - */ - assert(component->type == base_type); - - /* Don't actually generate constructor calls for scalars. - * Instead, do the usual component selection and conversion, - * and return the single component. - */ - if (constructor_type->is_scalar()) - return component; - - actual_parameters.push_tail(component); - components_used++; - } - } while (ptr != first); + assert(component->type == base_type); + + /* Don't actually generate constructor calls for scalars. + * Instead, do the usual component selection and conversion, + * and return the single component. + */ + if (constructor_type->is_scalar()) + return component; + + actual_parameters.push_tail(component); + components_used++; + } } /* From page 28 (page 34 of the PDF) of the GLSL 1.10 spec: @@ -500,7 +492,7 @@ ast_function_expression::hir(exec_list *instructions, return match_function_by_name(instructions, id->primary_expression.identifier, & loc, - subexpressions[1], state); + &this->expressions, state); } return ir_call::get_error_instruction(); diff --git a/glsl_parser.ypp b/glsl_parser.ypp index 131f23d..fb3b345 100644 --- a/glsl_parser.ypp +++ b/glsl_parser.ypp @@ -294,6 +294,12 @@ postfix_expression: } | function_call { + /* Function call parameters used to be stored as a circular list in + * subexpressions[1]. They are now stored as a regular list in + * expressions. This assertion validates that the old code was + * correctly converted. It can eventually be removed. + */ + assert($1->subexpressions[1] == NULL); $$ = $1; } | postfix_expression '.' IDENTIFIER @@ -346,14 +352,13 @@ function_call_header_with_parameters: { $$ = $1; $$->set_location(yylloc); - $$->subexpressions[1] = $2; + insert_at_tail(& $$->expressions, (struct simple_node *) $2); } | function_call_header_with_parameters ',' assignment_expression { $$ = $1; $$->set_location(yylloc); - insert_at_tail((struct simple_node *) $$->subexpressions[1], - (struct simple_node *) $3); + insert_at_tail(& $$->expressions, (struct simple_node *) $3); } ; diff --git a/glsl_parser_extras.cpp b/glsl_parser_extras.cpp index 18280e0..201b685 100644 --- a/glsl_parser_extras.cpp +++ b/glsl_parser_extras.cpp @@ -330,19 +330,13 @@ ast_expression::print(void) const break; case ast_function_call: { - ast_expression *parameters = subexpressions[1]; - subexpressions[0]->print(); printf("( "); - if (parameters != NULL) { - struct simple_node *ptr; - - parameters->print(); - foreach (ptr, (struct simple_node *) parameters) { - printf(", "); - ((ast_node *)ptr)->print(); - } + struct simple_node *ptr; + foreach (ptr, &this->expressions) { + printf(", "); + ((ast_node *)ptr)->print(); } printf(") "); -- 2.7.4