Don't track new type names during pass-1 parsing
[mesa.git] / ast_to_hir.cpp
index e7f21ee2524ee1261c27f4317a2c0c712a8c9fc2..9f580d28cb0225a5eb50bd09df36a5fe2f95575d 100644 (file)
 #include "ir.h"
 
 void
-_mesa_generate_hir_from_ast(struct _mesa_glsl_parse_state *state)
+_mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state)
 {
    struct simple_node *ptr;
 
+   _mesa_glsl_initialize_variables(instructions, state);
+
    foreach (ptr, & state->translation_unit) {
-      if (1) {
-      }
+      ((ast_node *)ptr)->hir(instructions, state);
    }
 }
 
@@ -122,7 +123,7 @@ arithmetic_result_type(const struct glsl_type *type_a,
     *    * The two operands are scalars. In this case the operation is
     *      applied, resulting in a scalar."
     */
-   if (is_glsl_type_scalar(type_a) && is_glsl_type_scalar(type_b))
+   if (type_a->is_scalar() && type_b->is_scalar())
       return type_a;
 
    /*   "* One operand is a scalar, and the other is a vector or matrix.
@@ -130,10 +131,10 @@ arithmetic_result_type(const struct glsl_type *type_a,
     *      component of the vector or matrix, resulting in the same size
     *      vector or matrix."
     */
-   if (is_glsl_type_scalar(type_a)) {
-      if (!is_glsl_type_scalar(type_b))
+   if (type_a->is_scalar()) {
+      if (!type_b->is_scalar())
         return type_b;
-   } else if (is_glsl_type_scalar(type_b)) {
+   } else if (type_b->is_scalar()) {
       return type_a;
    }
 
@@ -148,7 +149,7 @@ arithmetic_result_type(const struct glsl_type *type_a,
     *      operation is done component-wise resulting in the same size
     *      vector."
     */
-   if (is_glsl_type_vector(type_a) && is_glsl_type_vector(type_b)) {
+   if (type_a->is_vector() && type_b->is_vector()) {
       if (type_a->vector_elements == type_b->vector_elements)
         return type_a;
       else
@@ -181,14 +182,14 @@ arithmetic_result_type(const struct glsl_type *type_a,
     *      more detail how vectors and matrices are operated on."
     */
    if (! multiply) {
-      if (is_glsl_type_matrix(type_a) && is_glsl_type_matrix(type_b)
+      if (type_a->is_matrix() && type_b->is_matrix()
          && (type_a->vector_elements == type_b->vector_elements)
          && (type_a->matrix_rows == type_b->matrix_rows))
         return type_a;
       else
         return glsl_error_type;
    } else {
-      if (is_glsl_type_matrix(type_a) && is_glsl_type_matrix(type_b)) {
+      if (type_a->is_matrix() && type_b->is_matrix()) {
         if (type_a->vector_elements == type_b->matrix_rows) {
            char type_name[7];
            const struct glsl_type *t;
@@ -211,14 +212,14 @@ arithmetic_result_type(const struct glsl_type *type_a,
               _mesa_symbol_table_find_symbol(state->symbols, 0, type_name);
            return (t != NULL) ? t : glsl_error_type;
         }
-      } else if (is_glsl_type_matrix(type_a)) {
+      } else if (type_a->is_matrix()) {
         /* A is a matrix and B is a column vector.  Columns of A must match
          * rows of B.
          */
         if (type_a->vector_elements == type_b->vector_elements)
            return type_b;
       } else {
-        assert(is_glsl_type_matrix(type_b));
+        assert(type_b->is_matrix());
 
         /* A is a row vector and B is a matrix.  Columns of A must match
          * rows of B.
@@ -273,8 +274,8 @@ modulus_result_type(const struct glsl_type *type_a,
     *    wise to the vector, resulting in the same type as the vector. If both
     *    are vectors of the same size, the result is computed component-wise."
     */
-   if (is_glsl_type_vector(type_a)) {
-      if (!is_glsl_type_vector(type_b)
+   if (type_a->is_vector()) {
+      if (!type_b->is_vector()
          || (type_a->vector_elements == type_b->vector_elements))
         return type_a;
    } else
@@ -299,8 +300,8 @@ relational_result_type(const struct glsl_type *type_a,
     */
    if (! is_numeric_base_type(type_a->base_type)
        || ! is_numeric_base_type(type_b->base_type)
-       || ! is_glsl_type_scalar(type_a) 
-       || ! is_glsl_type_scalar(type_b))
+       || !type_a->is_scalar()
+       || !type_b->is_scalar())
       return glsl_error_type;
 
    /*    "Either the operands' types must match, or the conversions from
@@ -330,7 +331,7 @@ relational_result_type(const struct glsl_type *type_a,
 
 
 ir_instruction *
-ast_node::hir(struct simple_node *instructions,
+ast_node::hir(exec_list *instructions,
              struct _mesa_glsl_parse_state *state)
 {
    (void) instructions;
@@ -341,7 +342,7 @@ ast_node::hir(struct simple_node *instructions,
 
 
 ir_instruction *
-ast_expression::hir(struct simple_node *instructions,
+ast_expression::hir(exec_list *instructions,
                    struct _mesa_glsl_parse_state *state)
 {
    static const int operations[AST_NUM_OPERATORS] = {
@@ -410,7 +411,7 @@ ast_expression::hir(struct simple_node *instructions,
    make_empty_list(& op_list);
 
    switch (this->oper) {
-   case ast_assign:
+   case ast_assign: {
       op[0] = this->subexpressions[0]->hir(instructions, state);
       op[1] = this->subexpressions[1]->hir(instructions, state);
 
@@ -449,8 +450,12 @@ ast_expression::hir(struct simple_node *instructions,
       /* FINISHME: Check that the LHS and RHS have matching types. */
       /* FINISHME: For GLSL 1.10, check that the types are not arrays. */
 
-      result = new ir_assignment(op[0], op[1], NULL);
+      ir_instruction *tmp = new ir_assignment(op[0], op[1], NULL);
+      instructions->push_tail(tmp);
+
+      result = op[0];
       break;
+   }
 
    case ast_plus:
       op[0] = this->subexpressions[0]->hir(instructions, state);
@@ -525,7 +530,7 @@ ast_expression::hir(struct simple_node *instructions,
        */
       assert((type == glsl_error_type)
             || ((type->base_type == GLSL_TYPE_BOOL)
-                && is_glsl_type_scalar(type)));
+                && type->is_scalar()));
 
       result = new ir_expression(operations[this->oper], type,
                                 op[0], op[1]);
@@ -625,21 +630,10 @@ ast_expression::hir(struct simple_node *instructions,
       break;
 
    case ast_function_call:
-      /* There are three sorts of function calls.
-       *
-       * 1. contstructors - The first subexpression is an ast_type_specifier.
-       * 2. methods - Only the .length() method of array types.
-       * 3. functions - Calls to regular old functions.
-       *
-       * Method calls are actually detected when the ast_field_selection
-       * expression is handled.
+      /* Should *NEVER* get here.  ast_function_call should always be handled
+       * by ast_function_expression::hir.
        */
-#if 0
-      result = _mesa_ast_function_call_to_hir(this->subexpressions[0],
-                                             this->subexpressions[1],
-                                             state);
-      type = result->type;
-#endif
+      assert(0);
       break;
 
    case ast_identifier: {
@@ -717,7 +711,7 @@ ast_expression::hir(struct simple_node *instructions,
 
 
 ir_instruction *
-ast_expression_statement::hir(struct simple_node *instructions,
+ast_expression_statement::hir(exec_list *instructions,
                              struct _mesa_glsl_parse_state *state)
 {
    /* It is possible to have expression statements that don't have an
@@ -739,7 +733,7 @@ ast_expression_statement::hir(struct simple_node *instructions,
 
 
 ir_instruction *
-ast_compound_statement::hir(struct simple_node *instructions,
+ast_compound_statement::hir(exec_list *instructions,
                            struct _mesa_glsl_parse_state *state)
 {
    struct simple_node *ptr;
@@ -765,73 +759,15 @@ type_specifier_to_glsl_type(const struct ast_type_specifier *spec,
                            const char **name,
                            struct _mesa_glsl_parse_state *state)
 {
-   static const char *const type_names[] = {
-      "void",
-      "float",
-      "int",
-      "uint",
-      "bool",
-      "vec2",
-      "vec3",
-      "vec4",
-      "bvec2",
-      "bvec3",
-      "bvec4",
-      "ivec2",
-      "ivec3",
-      "ivec4",
-      "uvec2",
-      "uvec3",
-      "uvec4",
-      "mat2",
-      "mat2x3",
-      "mat2x4",
-      "mat3x2",
-      "mat3",
-      "mat3x4",
-      "mat4x2",
-      "mat4x3",
-      "mat4",
-      "sampler1D",
-      "sampler2D",
-      "sampler3D",
-      "samplerCube",
-      "sampler1DShadow",
-      "sampler2DShadow",
-      "samplerCubeShadow",
-      "sampler1DArray",
-      "sampler2DArray",
-      "sampler1DArrayShadow",
-      "sampler2DArrayShadow",
-      "isampler1D",
-      "isampler2D",
-      "isampler3D",
-      "isamplerCube",
-      "isampler1DArray",
-      "isampler2DArray",
-      "usampler1D",
-      "usampler2D",
-      "usampler3D",
-      "usamplerCube",
-      "usampler1DArray",
-      "usampler2DArray",
-
-      NULL, /* ast_struct */
-      NULL  /* ast_type_name */
-   };
    struct glsl_type *type;
-   const char *type_name = NULL;
 
    if (spec->type_specifier == ast_struct) {
       /* FINISHME: Handle annonymous structures. */
       type = NULL;
    } else {
-      type_name = (spec->type_specifier == ast_type_name)
-        ? spec->type_name : type_names[spec->type_specifier];
-
       type = (glsl_type *)
-        _mesa_symbol_table_find_symbol(state->symbols, 0, type_name);
-      *name = type_name;
+        _mesa_symbol_table_find_symbol(state->symbols, 0, spec->type_name);
+      *name = spec->type_name;
 
       /* FINISHME: Handle array declarations.  Note that this requires complete
        * FINSIHME: handling of constant expressions.
@@ -863,7 +799,7 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
    else if (qual->attribute || qual->in
            || (qual->varying && (state->target == fragment_shader)))
       var->mode = ir_var_in;
-   else if (qual->out)
+   else if (qual->out || (qual->varying && (state->target == vertex_shader)))
       var->mode = ir_var_out;
    else if (qual->uniform)
       var->mode = ir_var_uniform;
@@ -880,7 +816,7 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
 
 
 ir_instruction *
-ast_declarator_list::hir(struct simple_node *instructions,
+ast_declarator_list::hir(exec_list *instructions,
                         struct _mesa_glsl_parse_state *state)
 {
    struct simple_node *ptr;
@@ -953,7 +889,7 @@ ast_declarator_list::hir(struct simple_node *instructions,
         continue;
       }
 
-      insert_at_tail(instructions, (struct simple_node *) var);
+      instructions->push_tail(var);
 
       /* FINISHME: Process the declaration initializer. */
    }
@@ -965,7 +901,7 @@ ast_declarator_list::hir(struct simple_node *instructions,
 
 
 ir_instruction *
-ast_parameter_declarator::hir(struct simple_node *instructions,
+ast_parameter_declarator::hir(exec_list *instructions,
                              struct _mesa_glsl_parse_state *state)
 {
    const struct glsl_type *type;
@@ -995,9 +931,14 @@ ast_parameter_declarator::hir(struct simple_node *instructions,
     * FINISHME: complete handling of constant expressions.
     */
 
+   /* Apply any specified qualifiers to the parameter declaration.  Note that
+    * for function parameters the default mode is 'in'.
+    */
    apply_type_qualifier_to_variable(& this->type->qualifier, var, state);
+   if (var->mode == ir_var_auto)
+      var->mode = ir_var_in;
 
-   insert_at_tail(instructions, var);
+   instructions->push_tail(var);
 
    /* Parameter declarations do not have r-values.
     */
@@ -1007,7 +948,7 @@ ast_parameter_declarator::hir(struct simple_node *instructions,
 
 static void
 ast_function_parameters_to_hir(struct simple_node *ast_parameters,
-                              struct simple_node *ir_parameters,
+                              exec_list *ir_parameters,
                               struct _mesa_glsl_parse_state *state)
 {
    struct simple_node *ptr;
@@ -1019,18 +960,17 @@ ast_function_parameters_to_hir(struct simple_node *ast_parameters,
 
 
 static bool
-parameter_lists_match(struct simple_node *list_a, struct simple_node *list_b)
+parameter_lists_match(exec_list *list_a, exec_list *list_b)
 {
-   struct simple_node *node_a;
-   struct simple_node *node_b;
+   exec_list_iterator iter_a = list_a->iterator();
+   exec_list_iterator iter_b = list_b->iterator();
 
-   node_b = first_elem(list_b);
-   foreach (node_a, list_a) {
+   while (iter_a.has_next()) {
       /* If all of the parameters from the other parameter list have been
        * exhausted, the lists have different length and, by definition,
        * do not match.
        */
-      if (at_end(list_b, node_b))
+      if (!iter_b.has_next())
         return false;
 
       /* If the types of the parameters do not match, the parameters lists
@@ -1039,7 +979,8 @@ parameter_lists_match(struct simple_node *list_a, struct simple_node *list_b)
       /* FINISHME */
 
 
-      node_b = next_elem(node_b);
+      iter_a.next();
+      iter_b.next();
    }
 
    return true;
@@ -1047,22 +988,19 @@ parameter_lists_match(struct simple_node *list_a, struct simple_node *list_b)
 
 
 ir_instruction *
-ast_function_definition::hir(struct simple_node *instructions,
+ast_function_definition::hir(exec_list *instructions,
                             struct _mesa_glsl_parse_state *state)
 {
    ir_label *label;
-   struct simple_node *ptr;
-   struct simple_node *tmp;
    ir_function_signature *signature = NULL;
    ir_function *f = NULL;
-   struct simple_node parameters;
+   exec_list parameters;
 
 
    /* Convert the list of function parameters to HIR now so that they can be
     * used below to compare this function's signature with previously seen
     * signatures for functions with the same name.
     */
-   make_empty_list(& parameters);
    ast_function_parameters_to_hir(& this->prototype->parameters, & parameters,
                                  state);
 
@@ -1075,8 +1013,8 @@ ast_function_definition::hir(struct simple_node *instructions,
       _mesa_symbol_table_find_symbol(state->symbols, 0,
                                     this->prototype->identifier);
    if (f != NULL) {
-      foreach (ptr, & f->signatures) {
-        signature = (struct ir_function_signature *) ptr;
+      foreach_iter(exec_list_iterator, iter, f->signatures) {
+        signature = (struct ir_function_signature *) iter.get();
 
         /* Compare the parameter list of the function being defined to the
          * existing function.  If the parameter lists match, then the return
@@ -1111,17 +1049,17 @@ ast_function_definition::hir(struct simple_node *instructions,
     */
    if (signature == NULL) {
       signature = new ir_function_signature();
-      insert_at_tail(& f->signatures, (struct simple_node *) signature);
+      f->signatures.push_tail(signature);
    } else {
       /* Destroy all of the previous parameter information.  The previous
        * parameter information comes from the function prototype, and it can
        * either include invalid parameter names or may not have names at all.
        */
-      foreach_s(ptr, tmp, & signature->parameters) {
-        assert(((struct ir_instruction *)ptr)->mode == ir_op_var_decl);
+      foreach_iter(exec_list_iterator, iter, signature->parameters) {
+        assert(((struct ir_instruction *)iter.get())->mode == ir_op_var_decl);
 
-        remove_from_list(ptr);
-        free(ptr);
+        iter.remove();
+        delete iter.get();
       }
    }
 
@@ -1135,7 +1073,7 @@ ast_function_definition::hir(struct simple_node *instructions,
    if (signature->definition == NULL) {
       signature->definition = label;
    }
-   insert_at_tail(instructions, label);
+   instructions->push_tail(label);
 
    /* Add the function parameters to the symbol table.  During this step the
     * parameter declarations are also moved from the temporary "parameters" list
@@ -1143,13 +1081,13 @@ ast_function_definition::hir(struct simple_node *instructions,
     * but they involve ugly linked-list gymnastics.
     */
    _mesa_symbol_table_push_scope(state->symbols);
-   foreach_s(ptr, tmp, & parameters) {
-      struct ir_variable *const var = (struct ir_variable *) ptr;
+   foreach_iter(exec_list_iterator, iter, parameters) {
+      ir_variable *const var = (ir_variable *) iter.get();
 
-      assert(var->mode == ir_op_var_decl);
+      assert(((ir_instruction *)var)->mode == ir_op_var_decl);
 
-      remove_from_list(ptr);
-      insert_at_tail(instructions, ptr);
+      iter.remove();
+      instructions->push_tail(var);
 
       _mesa_symbol_table_add_symbol(state->symbols, 0, var->name, var);
    }