Store AST function call parameters in expressions
authorIan Romanick <ian.d.romanick@intel.com>
Mon, 10 May 2010 17:47:14 +0000 (10:47 -0700)
committerIan Romanick <ian.d.romanick@intel.com>
Mon, 10 May 2010 18:04:02 +0000 (11:04 -0700)
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
ast_function.cpp
glsl_parser.ypp
glsl_parser_extras.cpp

diff --git a/ast.h b/ast.h
index 41787f5c1c37e2869f393517fddbd4a7d782d99b..9fa651878e92a42defa53c7a53b5af6ab6b9aa5a 100644 (file)
--- 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;
 };
index cc8e9a8039b3ec5214e3c0e22f894f9bd668ac89..35ffcdbb8bc4ef0fe72d96414e315cf4d2cef724 100644 (file)
@@ -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();
index 131f23d8c1e098850af6716439f75c79a346823b..fb3b34507289706b339d40a7db4b9d74e15a1ebf 100644 (file)
@@ -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);
        }
        ;
 
index 18280e0301c8cb3f2b98714dc481e9997b19da35..201b685189f168e6e1407e8691dede0cec4f5bbc 100644 (file)
@@ -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(") ");