ast_to_hir.cpp revision 76ea56c007263ec3b79234e7b775e3a7b519a54a
1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/*
2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Copyright © 2010 Intel Corporation
3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Permission is hereby granted, free of charge, to any person obtaining a
5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * copy of this software and associated documentation files (the "Software"),
6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * to deal in the Software without restriction, including without limitation
7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * and/or sell copies of the Software, and to permit persons to whom the
9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Software is furnished to do so, subject to the following conditions:
10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The above copyright notice and this permission notice (including the next
12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * paragraph) shall be included in all copies or substantial portions of the
13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Software.
14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
218c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * DEALINGS IN THE SOFTWARE.
220519c0de2e55eeb3566c5ee913a500eb45886f7fElliott Hughes */
235aafac4db69e6d087c512cdfa5c7c0e2f1611681Jesse Wilson
24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * \file ast_to_hir.c
268c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * Convert abstract syntax to to high-level intermediate reprensentation (HIR).
278c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *
288c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * During the conversion to HIR, the majority of the symantic checking is
298c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * preformed on the program.  This includes:
308c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *
31f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes *    * Symbol table management
328c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *    * Type checking
338c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *    * Function binding
348c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *
358c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * The majority of this work could be done during parsing, and the parser could
368c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * probably generate HIR directly.  However, this results in frequent changes
378c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * to the parser code.  Since we do not assume that every system this complier
388c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * is built on will have Flex and Bison installed, we have to store the code
398c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * generated by these tools in our version control system.  In other parts of
408c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * the system we've seen problems where a parser was changed but the generated
418c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * code was not committed, merge conflicts where created because two developers
428c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * had slightly different versions of Bison installed, etc.
438c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *
448c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * I have also noticed that running Bison generated parsers in GDB is very
458c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * irritating.  When you get a segfault on '$$ = $1->foo', you can't very
468c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * well 'print $1' in GDB.
478c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *
488c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * As a result, my preference is to put as little C code as possible in the
498c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * parser (and lexer) sources.
508c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson */
51eb09bc383703f0b2d6c99daf83479d5ce573a2f9Jesse Wilson#include <stdio.h>
52eb09bc383703f0b2d6c99daf83479d5ce573a2f9Jesse Wilson#include "main/imports.h"
538c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson#include "glsl_symbol_table.h"
548c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson#include "glsl_parser_extras.h"
558c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson#include "ast.h"
568c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson#include "glsl_types.h"
578c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson#include "ir.h"
588c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson
598c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilsonvoid
608c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson_mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state)
618c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson{
628c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson   struct simple_node *ptr;
638c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson
648c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson   _mesa_glsl_initialize_variables(instructions, state);
658c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson   _mesa_glsl_initialize_constructors(instructions, state);
668c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson
678c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson   state->current_function = NULL;
688bccf8cdf7a3b8a6e90bb1b411a957b6368e4a1aBrian Carlstrom
698bccf8cdf7a3b8a6e90bb1b411a957b6368e4a1aBrian Carlstrom   foreach (ptr, & state->translation_unit) {
708bccf8cdf7a3b8a6e90bb1b411a957b6368e4a1aBrian Carlstrom      ((ast_node *)ptr)->hir(instructions, state);
718bccf8cdf7a3b8a6e90bb1b411a957b6368e4a1aBrian Carlstrom   }
728bccf8cdf7a3b8a6e90bb1b411a957b6368e4a1aBrian Carlstrom}
738bccf8cdf7a3b8a6e90bb1b411a957b6368e4a1aBrian Carlstrom
748bccf8cdf7a3b8a6e90bb1b411a957b6368e4a1aBrian Carlstrom
758bccf8cdf7a3b8a6e90bb1b411a957b6368e4a1aBrian Carlstromstatic const struct glsl_type *
768bccf8cdf7a3b8a6e90bb1b411a957b6368e4a1aBrian Carlstromarithmetic_result_type(const struct glsl_type *type_a,
778bccf8cdf7a3b8a6e90bb1b411a957b6368e4a1aBrian Carlstrom		       const struct glsl_type *type_b,
788bccf8cdf7a3b8a6e90bb1b411a957b6368e4a1aBrian Carlstrom		       bool multiply,
798bccf8cdf7a3b8a6e90bb1b411a957b6368e4a1aBrian Carlstrom		       struct _mesa_glsl_parse_state *state)
8023e3c8dad87724420bad70e9e9c4e8b94a565f14Jesse Wilson{
818c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson   /* From GLSL 1.50 spec, page 56:
828c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson    *
8355bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson    *    "The arithmetic binary operators add (+), subtract (-),
8455bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson    *    multiply (*), and divide (/) operate on integer and
858c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson    *    floating-point scalars, vectors, and matrices."
8655bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson    */
8755bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson   if (!type_a->is_numeric() || !type_b->is_numeric()) {
8855bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson      return glsl_type::error_type;
8955bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson   }
908c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson
918c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson
928c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson   /*    "If one operand is floating-point based and the other is
938c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson    *    not, then the conversions from Section 4.1.10 "Implicit
948c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson    *    Conversions" are applied to the non-floating-point-based operand."
958c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson    *
968c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson    * This conversion was added in GLSL 1.20.  If the compilation mode is
978c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson    * GLSL 1.10, the conversion is skipped.
988c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson    */
998c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson   if (state->language_version >= 120) {
1008c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson      if ((type_a->base_type == GLSL_TYPE_FLOAT)
1018c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson	  && (type_b->base_type != GLSL_TYPE_FLOAT)) {
10223e3c8dad87724420bad70e9e9c4e8b94a565f14Jesse Wilson      } else if ((type_a->base_type != GLSL_TYPE_FLOAT)
1038c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson		 && (type_b->base_type == GLSL_TYPE_FLOAT)) {
1048c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson      }
1058c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson   }
10655bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson
1078c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson   /*    "If the operands are integer types, they must both be signed or
1088c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson    *    both be unsigned."
1098c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson    *
1108c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson    * From this rule and the preceeding conversion it can be inferred that
1118c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson    * both types must be GLSL_TYPE_FLOAT, or GLSL_TYPE_UINT, or GLSL_TYPE_INT.
1128c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson    * The is_numeric check above already filtered out the case where either
1138c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson    * type is not one of these, so now the base types need only be tested for
1148c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson    * equality.
1158c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson    */
1168c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson   if (type_a->base_type != type_b->base_type) {
1178c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson      return glsl_type::error_type;
11855bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson   }
11955bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson
12055bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson   /*    "All arithmetic binary operators result in the same fundamental type
12155bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson    *    (signed integer, unsigned integer, or floating-point) as the
12255bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson    *    operands they operate on, after operand type conversion. After
12355bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson    *    conversion, the following cases are valid
12455bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson    *
12555bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson    *    * The two operands are scalars. In this case the operation is
12655bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson    *      applied, resulting in a scalar."
12755bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson    */
12855bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson   if (type_a->is_scalar() && type_b->is_scalar())
12955bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson      return type_a;
13055bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson
13155bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson   /*   "* One operand is a scalar, and the other is a vector or matrix.
132eb09bc383703f0b2d6c99daf83479d5ce573a2f9Jesse Wilson    *      In this case, the scalar operation is applied independently to each
133eb09bc383703f0b2d6c99daf83479d5ce573a2f9Jesse Wilson    *      component of the vector or matrix, resulting in the same size
13455bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson    *      vector or matrix."
13555bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson    */
13655bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson   if (type_a->is_scalar()) {
13755bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson      if (!type_b->is_scalar())
13855bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson	 return type_b;
13955bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson   } else if (type_b->is_scalar()) {
14055bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson      return type_a;
14155bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson   }
14255bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson
14355bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson   /* All of the combinations of <scalar, scalar>, <vector, scalar>,
14455bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson    * <scalar, vector>, <scalar, matrix>, and <matrix, scalar> have been
14555bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson    * handled.
14655bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson    */
14755bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson   assert(!type_a->is_scalar());
14823e3c8dad87724420bad70e9e9c4e8b94a565f14Jesse Wilson   assert(!type_b->is_scalar());
14923e3c8dad87724420bad70e9e9c4e8b94a565f14Jesse Wilson
15023e3c8dad87724420bad70e9e9c4e8b94a565f14Jesse Wilson   /*   "* The two operands are vectors of the same size. In this case, the
15123e3c8dad87724420bad70e9e9c4e8b94a565f14Jesse Wilson    *      operation is done component-wise resulting in the same size
15223e3c8dad87724420bad70e9e9c4e8b94a565f14Jesse Wilson    *      vector."
15323e3c8dad87724420bad70e9e9c4e8b94a565f14Jesse Wilson    */
15423e3c8dad87724420bad70e9e9c4e8b94a565f14Jesse Wilson   if (type_a->is_vector() && type_b->is_vector()) {
15523e3c8dad87724420bad70e9e9c4e8b94a565f14Jesse Wilson      return (type_a == type_b) ? type_a : glsl_type::error_type;
15623e3c8dad87724420bad70e9e9c4e8b94a565f14Jesse Wilson   }
15723e3c8dad87724420bad70e9e9c4e8b94a565f14Jesse Wilson
15823e3c8dad87724420bad70e9e9c4e8b94a565f14Jesse Wilson   /* All of the combinations of <scalar, scalar>, <vector, scalar>,
15923e3c8dad87724420bad70e9e9c4e8b94a565f14Jesse Wilson    * <scalar, vector>, <scalar, matrix>, <matrix, scalar>, and
16023e3c8dad87724420bad70e9e9c4e8b94a565f14Jesse Wilson    * <vector, vector> have been handled.  At least one of the operands must
16123e3c8dad87724420bad70e9e9c4e8b94a565f14Jesse Wilson    * be matrix.  Further, since there are no integer matrix types, the base
16223e3c8dad87724420bad70e9e9c4e8b94a565f14Jesse Wilson    * type of both operands must be float.
16323e3c8dad87724420bad70e9e9c4e8b94a565f14Jesse Wilson    */
16423e3c8dad87724420bad70e9e9c4e8b94a565f14Jesse Wilson   assert(type_a->is_matrix() || type_b->is_matrix());
16523e3c8dad87724420bad70e9e9c4e8b94a565f14Jesse Wilson   assert(type_a->base_type == GLSL_TYPE_FLOAT);
16623e3c8dad87724420bad70e9e9c4e8b94a565f14Jesse Wilson   assert(type_b->base_type == GLSL_TYPE_FLOAT);
16723e3c8dad87724420bad70e9e9c4e8b94a565f14Jesse Wilson
16823e3c8dad87724420bad70e9e9c4e8b94a565f14Jesse Wilson   /*   "* The operator is add (+), subtract (-), or divide (/), and the
1698c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson    *      operands are matrices with the same number of rows and the same
1708c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson    *      number of columns. In this case, the operation is done component-
1718c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson    *      wise resulting in the same size matrix."
1728c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson    *    * The operator is multiply (*), where both operands are matrices or
1738c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson    *      one operand is a vector and the other a matrix. A right vector
1748c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson    *      operand is treated as a column vector and a left vector operand as a
1758c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson    *      row vector. In all these cases, it is required that the number of
1768c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson    *      columns of the left operand is equal to the number of rows of the
1778c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson    *      right operand. Then, the multiply (*) operation does a linear
1788c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson    *      algebraic multiply, yielding an object that has the same number of
1798c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson    *      rows as the left operand and the same number of columns as the right
1808c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson    *      operand. Section 5.10 "Vector and Matrix Operations" explains in
1818c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson    *      more detail how vectors and matrices are operated on."
1828c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson    */
1838c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson   if (! multiply) {
1848c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson      return (type_a == type_b) ? type_a : glsl_type::error_type;
1858c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson   } else {
1868c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson      if (type_a->is_matrix() && type_b->is_matrix()) {
1878c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson	 /* Matrix multiply.  The columns of A must match the rows of B.  Given
1888c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson	  * the other previously tested constraints, this means the vector type
1898c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson	  * of a row from A must be the same as the vector type of a column from
1908c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson	  * B.
1918c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson	  */
1928c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson	 if (type_a->row_type() == type_b->column_type()) {
1938c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson	    /* The resulting matrix has the number of columns of matrix B and
1948c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson	     * the number of rows of matrix A.  We get the row count of A by
1958c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson	     * looking at the size of a vector that makes up a column.  The
1968c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson	     * transpose (size of a row) is done for B.
1978c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson	     */
1988c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson	    return
1998c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson	       glsl_type::get_instance(type_a->base_type,
2008c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson				       type_a->column_type()->vector_elements,
2018c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson				       type_b->row_type()->vector_elements);
2028c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson	 }
2038c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson      } else if (type_a->is_matrix()) {
20455bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson	 /* A is a matrix and B is a column vector.  Columns of A must match
20555bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson	  * rows of B.  Given the other previously tested constraints, this
20655bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson	  * means the vector type of a row from A must be the same as the
20755bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson	  * vector the type of B.
20855bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson	  */
20955bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson	 if (type_a->row_type() == type_b)
21055bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson	    return type_b;
21155bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson      } else {
21255bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson	 assert(type_b->is_matrix());
2138c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson
2148c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson	 /* A is a row vector and B is a matrix.  Columns of A must match rows
2158c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson	  * of B.  Given the other previously tested constraints, this means
2168c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson	  * the type of A must be the same as the vector type of a column from
2178c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson	  * B.
21855bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson	  */
2198c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson	 if (type_a == type_b->column_type())
22011b9d26222315d4ddea223ce8f119ec25a1ba3d5Jesse Wilson	    return type_a;
22111b9d26222315d4ddea223ce8f119ec25a1ba3d5Jesse Wilson      }
22211b9d26222315d4ddea223ce8f119ec25a1ba3d5Jesse Wilson   }
22311b9d26222315d4ddea223ce8f119ec25a1ba3d5Jesse Wilson
22411b9d26222315d4ddea223ce8f119ec25a1ba3d5Jesse Wilson
22511b9d26222315d4ddea223ce8f119ec25a1ba3d5Jesse Wilson   /*    "All other cases are illegal."
22655bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson    */
2278c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson   return glsl_type::error_type;
2288c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson}
2298c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson
2308c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson
2318c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilsonstatic const struct glsl_type *
2328c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilsonunary_arithmetic_result_type(const struct glsl_type *type)
2338c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson{
23455bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson   /* From GLSL 1.50 spec, page 57:
2358c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson    *
2368c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson    *    "The arithmetic unary operators negate (-), post- and pre-increment
2378c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson    *     and decrement (-- and ++) operate on integer or floating-point
2388c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson    *     values (including vectors and matrices). All unary operators work
23955bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson    *     component-wise on their operands. These result with the same type
2408c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson    *     they operated on."
2418c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson    */
2428c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson   if (!type->is_numeric())
2438c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson      return glsl_type::error_type;
2448c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson
2458c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson   return type;
2468c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson}
2478c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson
2488c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson
249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectstatic const struct glsl_type *
250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectmodulus_result_type(const struct glsl_type *type_a,
251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project		    const struct glsl_type *type_b)
252c8977f474b30c5f3807398859a6b16687af6fc7bJesse Wilson{
253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   /* From GLSL 1.50 spec, page 56:
254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    *    "The operator modulus (%) operates on signed or unsigned integers or
255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    *    integer vectors. The operand types must both be signed or both be
256c8977f474b30c5f3807398859a6b16687af6fc7bJesse Wilson    *    unsigned."
257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    */
258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   if (!type_a->is_integer() || !type_b->is_integer()
259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project       || (type_a->base_type != type_b->base_type)) {
260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      return glsl_type::error_type;
261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   }
262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   /*    "The operands cannot be vectors of differing size. If one operand is
264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    *    a scalar and the other vector, then the scalar is applied component-
265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    *    wise to the vector, resulting in the same type as the vector. If both
266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    *    are vectors of the same size, the result is computed component-wise."
267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    */
268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   if (type_a->is_vector()) {
269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      if (!type_b->is_vector()
270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project	  || (type_a->vector_elements == type_b->vector_elements))
271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project	 return type_a;
272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   } else
273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      return type_b;
274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   /*    "The operator modulus (%) is not defined for any other data types
276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    *    (non-integer types)."
277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    */
278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   return glsl_type::error_type;
279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectstatic const struct glsl_type *
283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectrelational_result_type(const struct glsl_type *type_a,
284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project		       const struct glsl_type *type_b,
285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project		       struct _mesa_glsl_parse_state *state)
286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project{
287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   /* From GLSL 1.50 spec, page 56:
288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    *    "The relational operators greater than (>), less than (<), greater
289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    *    than or equal (>=), and less than or equal (<=) operate only on
290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    *    scalar integer and scalar floating-point expressions."
291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    */
292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   if (!type_a->is_numeric()
293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project       || !type_b->is_numeric()
294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project       || !type_a->is_scalar()
295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project       || !type_b->is_scalar())
296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      return glsl_type::error_type;
297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   /*    "Either the operands' types must match, or the conversions from
299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    *    Section 4.1.10 "Implicit Conversions" will be applied to the integer
300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    *    operand, after which the types must match."
301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    *
302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    * This conversion was added in GLSL 1.20.  If the compilation mode is
303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    * GLSL 1.10, the conversion is skipped.
3040d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes    */
305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   if (state->language_version >= 120) {
306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      if ((type_a->base_type == GLSL_TYPE_FLOAT)
307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project	  && (type_b->base_type != GLSL_TYPE_FLOAT)) {
308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project	 /* FINISHME: Generate the implicit type conversion. */
3090d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes      } else if ((type_a->base_type != GLSL_TYPE_FLOAT)
310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project		 && (type_b->base_type == GLSL_TYPE_FLOAT)) {
311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project	 /* FINISHME: Generate the implicit type conversion. */
312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      }
313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   }
3140d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes
315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   if (type_a->base_type != type_b->base_type)
316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      return glsl_type::error_type;
317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   /*    "The result is scalar Boolean."
3190d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes    */
320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   return glsl_type::bool_type;
321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
3240d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes/**
325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Validates that a value can be assigned to a location with a specified type
326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Validates that \c rhs can be assigned to some location.  If the types are
328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * not an exact match but an automatic conversion is possible, \c rhs will be
3290d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes * converted.
330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * \return
332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * \c NULL if \c rhs cannot be assigned to a location with type \c lhs_type.
333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Otherwise the actual RHS to be assigned will be returned.  This may be
3340d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes * \c rhs, or it may be \c rhs after some type conversion.
335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * \note
337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * In addition to being used for assignments, this function is used to
338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * type-check return values.
3390d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes */
340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectir_rvalue *
341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectvalidate_assignment(const glsl_type *lhs_type, ir_rvalue *rhs)
342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project{
343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   const glsl_type *const rhs_type = rhs->type;
3440d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes
345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   /* If there is already some error in the RHS, just return it.  Anything
346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    * else will lead to an avalanche of error message back to the user.
347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    */
348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   if (rhs_type->is_error())
3490d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes      return rhs;
350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   /* FINISHME: For GLSL 1.10, check that the types are not arrays. */
352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   /* If the types are identical, the assignment can trivially proceed.
3540d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes    */
355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   if (rhs_type == lhs_type)
356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      return rhs;
357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   /* FINISHME: Check for and apply automatic conversions. */
3590d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes   return NULL;
360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectir_rvalue *
363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectdo_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state,
3640d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes	      ir_rvalue *lhs, ir_rvalue *rhs,
365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project	      YYLTYPE lhs_loc)
366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project{
367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   bool error_emitted = (lhs->type->is_error() || rhs->type->is_error());
368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
3690d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes   if (!error_emitted) {
370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      /* FINISHME: This does not handle 'foo.bar.a.b.c[5].d = 5' */
371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      if (!lhs->is_lvalue()) {
372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project	 _mesa_glsl_error(& lhs_loc, state, "non-lvalue in assignment");
373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project	 error_emitted = true;
3740d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes      }
375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   }
376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   ir_rvalue *new_rhs = validate_assignment(lhs->type, rhs);
378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   if (new_rhs == NULL) {
3790d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes      _mesa_glsl_error(& lhs_loc, state, "type mismatch");
380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   } else {
381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      rhs = new_rhs;
382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   }
383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
3840d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes   ir_instruction *tmp = new ir_assignment(lhs, rhs, NULL);
385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   instructions->push_tail(tmp);
386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   return rhs;
388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
3890d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes
390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectstatic ir_rvalue *
391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectget_lvalue_copy(exec_list *instructions, struct _mesa_glsl_parse_state *state,
392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project		ir_rvalue *lvalue, YYLTYPE loc)
393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project{
3940d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes   ir_variable *var;
395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   ir_rvalue *var_deref;
396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   /* FINISHME: Give unique names to the temporaries. */
398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   var = new ir_variable(lvalue->type, "_internal_tmp");
3990d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes   var->mode = ir_var_auto;
400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   var_deref = new ir_dereference(var);
402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   do_assignment(instructions, state, var_deref, lvalue, loc);
403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
4040d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes   /* Once we've created this temporary, mark it read only so it's no
405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    * longer considered an lvalue.
406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    */
407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   var->read_only = true;
408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
4090d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes   return var_deref;
410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectir_rvalue *
4140d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughesast_node::hir(exec_list *instructions,
415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project	      struct _mesa_glsl_parse_state *state)
416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project{
417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   (void) instructions;
418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   (void) state;
4190d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes
420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   return NULL;
421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
4240d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughesir_rvalue *
425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectast_expression::hir(exec_list *instructions,
426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project		    struct _mesa_glsl_parse_state *state)
427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project{
428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   static const int operations[AST_NUM_OPERATORS] = {
4290d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes      -1,               /* ast_assign doesn't convert to ir_expression. */
430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      -1,               /* ast_plus doesn't convert to ir_expression. */
431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      ir_unop_neg,
432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      ir_binop_add,
433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      ir_binop_sub,
4340d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes      ir_binop_mul,
435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      ir_binop_div,
436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      ir_binop_mod,
437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      ir_binop_lshift,
438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      ir_binop_rshift,
4390d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes      ir_binop_less,
440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      ir_binop_greater,
441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      ir_binop_lequal,
442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      ir_binop_gequal,
443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      ir_binop_equal,
4440d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes      ir_binop_nequal,
445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      ir_binop_bit_and,
446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      ir_binop_bit_xor,
447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      ir_binop_bit_or,
448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      ir_unop_bit_not,
4490d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes      ir_binop_logic_and,
450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      ir_binop_logic_xor,
451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      ir_binop_logic_or,
452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      ir_unop_logic_not,
453f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      /* Note: The following block of expression types actually convert
455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project       * to multiple IR instructions.
456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project       */
4570d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes      ir_binop_mul,     /* ast_mul_assign */
458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      ir_binop_div,     /* ast_div_assign */
459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      ir_binop_mod,     /* ast_mod_assign */
460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      ir_binop_add,     /* ast_add_assign */
461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      ir_binop_sub,     /* ast_sub_assign */
4620d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes      ir_binop_lshift,  /* ast_ls_assign */
463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      ir_binop_rshift,  /* ast_rs_assign */
464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      ir_binop_bit_and, /* ast_and_assign */
465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      ir_binop_bit_xor, /* ast_xor_assign */
466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      ir_binop_bit_or,  /* ast_or_assign */
4670d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes
468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      -1,               /* ast_conditional doesn't convert to ir_expression. */
469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      ir_binop_add,     /* ast_pre_inc. */
470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      ir_binop_sub,     /* ast_pre_dec. */
471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      ir_binop_add,     /* ast_post_inc. */
4720d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes      ir_binop_sub,     /* ast_post_dec. */
473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      -1,               /* ast_field_selection doesn't conv to ir_expression. */
474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      -1,               /* ast_array_index doesn't convert to ir_expression. */
475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      -1,               /* ast_function_call doesn't conv to ir_expression. */
476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      -1,               /* ast_identifier doesn't convert to ir_expression. */
4770d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes      -1,               /* ast_int_constant doesn't convert to ir_expression. */
478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      -1,               /* ast_uint_constant doesn't conv to ir_expression. */
479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      -1,               /* ast_float_constant doesn't conv to ir_expression. */
480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      -1,               /* ast_bool_constant doesn't conv to ir_expression. */
481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      -1,               /* ast_sequence doesn't convert to ir_expression. */
4820d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes   };
483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   ir_rvalue *result = NULL;
484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   ir_rvalue *op[2];
485adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   struct simple_node op_list;
486adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   const struct glsl_type *type = glsl_type::error_type;
487f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes   bool error_emitted = false;
488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   YYLTYPE loc;
489adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
490adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   loc = this->get_location();
491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   make_empty_list(& op_list);
492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   switch (this->oper) {
494adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   case ast_assign: {
495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      op[0] = this->subexpressions[0]->hir(instructions, state);
496adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      op[1] = this->subexpressions[1]->hir(instructions, state);
497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      result = do_assignment(instructions, state, op[0], op[1],
499f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes			     this->subexpressions[0]->get_location());
500adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      error_emitted = result->type->is_error();
501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      type = result->type;
502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      break;
503adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   }
504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
505adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   case ast_plus:
506adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      op[0] = this->subexpressions[0]->hir(instructions, state);
507adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      error_emitted = op[0]->type->is_error();
509f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes      if (type->is_error())
510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project	 op[0]->type = type;
511adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
5128c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson      result = op[0];
513adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      break;
514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   case ast_neg:
516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      op[0] = this->subexpressions[0]->hir(instructions, state);
517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      type = unary_arithmetic_result_type(op[0]->type);
519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
520f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes      error_emitted = op[0]->type->is_error();
521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
522adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      result = new ir_expression(operations[this->oper], type,
523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project				 op[0], NULL);
524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      break;
525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
526adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   case ast_add:
527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   case ast_sub:
528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   case ast_mul:
529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   case ast_div:
530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      op[0] = this->subexpressions[0]->hir(instructions, state);
531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      op[1] = this->subexpressions[1]->hir(instructions, state);
532adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
533f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes      type = arithmetic_result_type(op[0]->type, op[1]->type,
534adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project				    (this->oper == ast_mul),
535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project				    state);
536adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
537adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      result = new ir_expression(operations[this->oper], type,
538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project				 op[0], op[1]);
539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      break;
540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   case ast_mod:
542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      op[0] = this->subexpressions[0]->hir(instructions, state);
543adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      op[1] = this->subexpressions[1]->hir(instructions, state);
544adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
545f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes      error_emitted = op[0]->type->is_error() || op[1]->type->is_error();
546f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
547adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      type = modulus_result_type(op[0]->type, op[1]->type);
548adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      assert(operations[this->oper] == ir_binop_mod);
550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      result = new ir_expression(operations[this->oper], type,
552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project				 op[0], op[1]);
553f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes      break;
554adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   case ast_lshift:
556adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   case ast_rshift:
557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      /* FINISHME: Implement bit-shift operators. */
558adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      break;
559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   case ast_less:
561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   case ast_greater:
562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   case ast_lequal:
563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   case ast_gequal:
564f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes      op[0] = this->subexpressions[0]->hir(instructions, state);
565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      op[1] = this->subexpressions[1]->hir(instructions, state);
566adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
567adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      error_emitted = op[0]->type->is_error() || op[1]->type->is_error();
568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
569adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      type = relational_result_type(op[0]->type, op[1]->type, state);
570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      /* The relational operators must either generate an error or result
572adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project       * in a scalar boolean.  See page 57 of the GLSL 1.50 spec.
573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project       */
574adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      assert(type->is_error()
575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project	     || ((type->base_type == GLSL_TYPE_BOOL)
576adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project		 && type->is_scalar()));
577adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      result = new ir_expression(operations[this->oper], type,
579f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes				 op[0], op[1]);
580adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      break;
581adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
582adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   case ast_nequal:
583adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   case ast_equal:
584adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      /* FINISHME: Implement equality operators. */
585adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      break;
586adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
587adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   case ast_bit_and:
588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   case ast_bit_xor:
589adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   case ast_bit_or:
590adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   case ast_bit_not:
591adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      /* FINISHME: Implement bit-wise operators. */
592adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      break;
593adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   case ast_logic_and:
595adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   case ast_logic_xor:
596f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes   case ast_logic_or:
597adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   case ast_logic_not:
598adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      /* FINISHME: Implement logical operators. */
599adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      break;
600adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
601adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   case ast_mul_assign:
602adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   case ast_div_assign:
603adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   case ast_add_assign:
604adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   case ast_sub_assign: {
605adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      op[0] = this->subexpressions[0]->hir(instructions, state);
606adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      op[1] = this->subexpressions[1]->hir(instructions, state);
607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
608adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      type = arithmetic_result_type(op[0]->type, op[1]->type,
609adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project				    (this->oper == ast_mul_assign),
610adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project				    state);
611adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
61287548e8585334658c3ee89050ec917a10ca35e5aElliott Hughes      ir_rvalue *temp_rhs = new ir_expression(operations[this->oper], type,
613f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes				              op[0], op[1]);
614adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
615adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      result = do_assignment(instructions, state, op[0], temp_rhs,
616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project			     this->subexpressions[0]->get_location());
617adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      type = result->type;
618adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      error_emitted = (op[0]->type->is_error());
619adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
620adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      /* GLSL 1.10 does not allow array assignment.  However, we don't have to
621adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project       * explicitly test for this because none of the binary expression
622adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project       * operators allow array operands either.
623adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project       */
624f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
625adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      break;
626adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   }
627adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
628adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   case ast_mod_assign: {
629adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      op[0] = this->subexpressions[0]->hir(instructions, state);
630adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      op[1] = this->subexpressions[1]->hir(instructions, state);
631adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
632adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      error_emitted = op[0]->type->is_error() || op[1]->type->is_error();
633adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
634adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      type = modulus_result_type(op[0]->type, op[1]->type);
635b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes
636adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      assert(operations[this->oper] == ir_binop_mod);
637c8977f474b30c5f3807398859a6b16687af6fc7bJesse Wilson
638c8977f474b30c5f3807398859a6b16687af6fc7bJesse Wilson      struct ir_rvalue *temp_rhs;
639adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      temp_rhs = new ir_expression(operations[this->oper], type,
640adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project				   op[0], op[1]);
641c8977f474b30c5f3807398859a6b16687af6fc7bJesse Wilson
642adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      result = do_assignment(instructions, state, op[0], temp_rhs,
643adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project			     this->subexpressions[0]->get_location());
644adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      type = result->type;
645adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      error_emitted = op[0]->type->is_error();
6460519c0de2e55eeb3566c5ee913a500eb45886f7fElliott Hughes      break;
6470519c0de2e55eeb3566c5ee913a500eb45886f7fElliott Hughes   }
648adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
649adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   case ast_ls_assign:
650adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   case ast_rs_assign:
651adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
652f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes   case ast_and_assign:
653adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   case ast_xor_assign:
654adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   case ast_or_assign:
655adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
656adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   case ast_conditional:
657adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
658adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   case ast_pre_inc:
659d4bddd7d1fb7b1b7f0836648228235c6e4b56a18Jesse Wilson   case ast_pre_dec: {
660d4bddd7d1fb7b1b7f0836648228235c6e4b56a18Jesse Wilson      op[0] = this->subexpressions[0]->hir(instructions, state);
661d4bddd7d1fb7b1b7f0836648228235c6e4b56a18Jesse Wilson      if (op[0]->type->base_type == GLSL_TYPE_FLOAT)
662d4bddd7d1fb7b1b7f0836648228235c6e4b56a18Jesse Wilson	 op[1] = new ir_constant(1.0f);
663d4bddd7d1fb7b1b7f0836648228235c6e4b56a18Jesse Wilson      else
664d4bddd7d1fb7b1b7f0836648228235c6e4b56a18Jesse Wilson	 op[1] = new ir_constant(1);
665d4bddd7d1fb7b1b7f0836648228235c6e4b56a18Jesse Wilson
666d4bddd7d1fb7b1b7f0836648228235c6e4b56a18Jesse Wilson      type = arithmetic_result_type(op[0]->type, op[1]->type,
667d4bddd7d1fb7b1b7f0836648228235c6e4b56a18Jesse Wilson				    false, state);
668d4bddd7d1fb7b1b7f0836648228235c6e4b56a18Jesse Wilson
669d4bddd7d1fb7b1b7f0836648228235c6e4b56a18Jesse Wilson      struct ir_rvalue *temp_rhs;
670adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      temp_rhs = new ir_expression(operations[this->oper], type,
671f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes				   op[0], op[1]);
672adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
673adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      result = do_assignment(instructions, state, op[0], temp_rhs,
674adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project			     this->subexpressions[0]->get_location());
675adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      type = result->type;
676adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      error_emitted = op[0]->type->is_error();
677adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      break;
678adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   }
679adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
680adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   case ast_post_inc:
681f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes   case ast_post_dec: {
682adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      op[0] = this->subexpressions[0]->hir(instructions, state);
683adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      if (op[0]->type->base_type == GLSL_TYPE_FLOAT)
684adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project	 op[1] = new ir_constant(1.0f);
685adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      else
686adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project	 op[1] = new ir_constant(1);
687adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
688adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      error_emitted = op[0]->type->is_error() || op[1]->type->is_error();
689adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
690adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      type = arithmetic_result_type(op[0]->type, op[1]->type,
691adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project				    false, state);
692adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
693adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      struct ir_rvalue *temp_rhs;
694f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes      temp_rhs = new ir_expression(operations[this->oper], type,
695adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project				   op[0], op[1]);
696adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
697adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      /* Get a temporary of a copy of the lvalue before it's modified.
698adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project       * This may get thrown away later.
699adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project       */
700adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      result = get_lvalue_copy(instructions, state, op[0],
701adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project			       this->subexpressions[0]->get_location());
702adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
703adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      (void)do_assignment(instructions, state, op[0], temp_rhs,
704adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project			  this->subexpressions[0]->get_location());
705adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
706adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      type = result->type;
707adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      error_emitted = op[0]->type->is_error();
708adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      break;
709adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   }
710adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
711adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   case ast_field_selection:
712f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes      result = _mesa_ast_field_selection_to_hir(this, instructions, state);
713adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      type = result->type;
714adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      break;
715adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   case ast_array_index:
7171208f030332b3e1eae3d55d416f1af1d68f7e33dElliott Hughes      break;
718adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
719adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   case ast_function_call:
720adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      /* Should *NEVER* get here.  ast_function_call should always be handled
721adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project       * by ast_function_expression::hir.
722adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project       */
723b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes      assert(0);
724adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      break;
725b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes
726b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes   case ast_identifier: {
727adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      /* ast_identifier can appear several places in a full abstract syntax
728b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes       * tree.  This particular use must be at location specified in the grammar
729b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes       * as 'variable_identifier'.
730adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project       */
731adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      ir_variable *var =
732adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project	 state->symbols->get_variable(this->primary_expression.identifier);
733adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
734adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      result = new ir_dereference(var);
73555bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson
73655bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson      if (var != NULL) {
73755bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson	 type = result->type;
73855bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson      } else {
73955bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson	 _mesa_glsl_error(& loc, state, "`%s' undeclared",
74055bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson			  this->primary_expression.identifier);
74155bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson
74255bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson	 error_emitted = true;
74355bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson      }
744f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes      break;
745adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   }
74655bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson
74755bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson   case ast_int_constant:
74855bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson      type = glsl_type::int_type;
74955bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson      result = new ir_constant(type, & this->primary_expression);
750adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      break;
751ffd579b668428272b78f5c6c64f9c89766f37c1aJesse Wilson
752adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   case ast_uint_constant:
753b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes      type = glsl_type::uint_type;
754adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      result = new ir_constant(type, & this->primary_expression);
755ffd579b668428272b78f5c6c64f9c89766f37c1aJesse Wilson      break;
756b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes
757adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   case ast_float_constant:
758ffd579b668428272b78f5c6c64f9c89766f37c1aJesse Wilson      type = glsl_type::float_type;
759125f068f0a6cd739beac97821c9421cf8317cc87Jesse Wilson      result = new ir_constant(type, & this->primary_expression);
760adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      break;
761ffd579b668428272b78f5c6c64f9c89766f37c1aJesse Wilson
762adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project   case ast_bool_constant:
763adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      type = glsl_type::bool_type;
764adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      result = new ir_constant(type, & this->primary_expression);
765      break;
766
767   case ast_sequence: {
768      struct simple_node *ptr;
769
770      /* It should not be possible to generate a sequence in the AST without
771       * any expressions in it.
772       */
773      assert(!is_empty_list(&this->expressions));
774
775      /* The r-value of a sequence is the last expression in the sequence.  If
776       * the other expressions in the sequence do not have side-effects (and
777       * therefore add instructions to the instruction list), they get dropped
778       * on the floor.
779       */
780      foreach (ptr, &this->expressions)
781	 result = ((ast_node *)ptr)->hir(instructions, state);
782
783      type = result->type;
784
785      /* Any errors should have already been emitted in the loop above.
786       */
787      error_emitted = true;
788      break;
789   }
790   }
791
792   if (type->is_error() && !error_emitted)
793      _mesa_glsl_error(& loc, state, "type mismatch");
794
795   return result;
796}
797
798
799ir_rvalue *
800ast_expression_statement::hir(exec_list *instructions,
801			      struct _mesa_glsl_parse_state *state)
802{
803   /* It is possible to have expression statements that don't have an
804    * expression.  This is the solitary semicolon:
805    *
806    * for (i = 0; i < 5; i++)
807    *     ;
808    *
809    * In this case the expression will be NULL.  Test for NULL and don't do
810    * anything in that case.
811    */
812   if (expression != NULL)
813      expression->hir(instructions, state);
814
815   /* Statements do not have r-values.
816    */
817   return NULL;
818}
819
820
821ir_rvalue *
822ast_compound_statement::hir(exec_list *instructions,
823			    struct _mesa_glsl_parse_state *state)
824{
825   struct simple_node *ptr;
826
827
828   if (new_scope)
829      state->symbols->push_scope();
830
831   foreach (ptr, &statements)
832      ((ast_node *)ptr)->hir(instructions, state);
833
834   if (new_scope)
835      state->symbols->pop_scope();
836
837   /* Compound statements do not have r-values.
838    */
839   return NULL;
840}
841
842
843static const struct glsl_type *
844type_specifier_to_glsl_type(const struct ast_type_specifier *spec,
845			    const char **name,
846			    struct _mesa_glsl_parse_state *state)
847{
848   struct glsl_type *type;
849
850   if (spec->type_specifier == ast_struct) {
851      /* FINISHME: Handle annonymous structures. */
852      type = NULL;
853   } else {
854      type = state->symbols->get_type(spec->type_name);
855      *name = spec->type_name;
856
857      /* FINISHME: Handle array declarations.  Note that this requires complete
858       * FINISHME: handling of constant expressions.
859       */
860   }
861
862   return type;
863}
864
865
866static void
867apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
868				 struct ir_variable *var,
869				 struct _mesa_glsl_parse_state *state)
870{
871   if (qual->invariant)
872      var->invariant = 1;
873
874   /* FINISHME: Mark 'in' variables at global scope as read-only. */
875   if (qual->constant || qual->attribute || qual->uniform
876       || (qual->varying && (state->target == fragment_shader)))
877      var->read_only = 1;
878
879   if (qual->centroid)
880      var->centroid = 1;
881
882   if (qual->in && qual->out)
883      var->mode = ir_var_inout;
884   else if (qual->attribute || qual->in
885	    || (qual->varying && (state->target == fragment_shader)))
886      var->mode = ir_var_in;
887   else if (qual->out || (qual->varying && (state->target == vertex_shader)))
888      var->mode = ir_var_out;
889   else if (qual->uniform)
890      var->mode = ir_var_uniform;
891   else
892      var->mode = ir_var_auto;
893
894   if (qual->flat)
895      var->interpolation = ir_var_flat;
896   else if (qual->noperspective)
897      var->interpolation = ir_var_noperspective;
898   else
899      var->interpolation = ir_var_smooth;
900}
901
902
903ir_rvalue *
904ast_declarator_list::hir(exec_list *instructions,
905			 struct _mesa_glsl_parse_state *state)
906{
907   struct simple_node *ptr;
908   const struct glsl_type *decl_type;
909   const char *type_name = NULL;
910
911
912   /* FINISHME: Handle vertex shader "invariant" declarations that do not
913    * FINISHME: include a type.  These re-declare built-in variables to be
914    * FINISHME: invariant.
915    */
916
917   decl_type = type_specifier_to_glsl_type(this->type->specifier,
918					   & type_name, state);
919
920   foreach (ptr, &this->declarations) {
921      struct ast_declaration *const decl = (struct ast_declaration * )ptr;
922      const struct glsl_type *var_type;
923      struct ir_variable *var;
924
925
926      /* FINISHME: Emit a warning if a variable declaration shadows a
927       * FINISHME: declaration at a higher scope.
928       */
929
930      if ((decl_type == NULL) || decl_type->is_void()) {
931	 YYLTYPE loc;
932
933	 loc = this->get_location();
934	 if (type_name != NULL) {
935	    _mesa_glsl_error(& loc, state,
936			     "invalid type `%s' in declaration of `%s'",
937			     type_name, decl->identifier);
938	 } else {
939	    _mesa_glsl_error(& loc, state,
940			     "invalid type in declaration of `%s'",
941			     decl->identifier);
942	 }
943	 continue;
944      }
945
946      if (decl->is_array) {
947	 /* FINISHME: Handle array declarations.  Note that this requires
948	  * FINISHME: complete handling of constant expressions.
949	  */
950
951	 /* FINISHME: Reject delcarations of multidimensional arrays. */
952      } else {
953	 var_type = decl_type;
954      }
955
956      var = new ir_variable(var_type, decl->identifier);
957
958      /* FINISHME: Variables that are attribute, uniform, varying, in, or
959       * FINISHME: out varibles must be declared either at global scope or
960       * FINISHME: in a parameter list (in and out only).
961       */
962
963      apply_type_qualifier_to_variable(& this->type->qualifier, var, state);
964
965      /* Attempt to add the variable to the symbol table.  If this fails, it
966       * means the variable has already been declared at this scope.
967       */
968      if (state->symbols->name_declared_this_scope(decl->identifier)) {
969	 YYLTYPE loc = this->get_location();
970
971	 _mesa_glsl_error(& loc, state, "`%s' redeclared",
972			  decl->identifier);
973	 continue;
974      }
975
976      const bool added_variable =
977	 state->symbols->add_variable(decl->identifier, var);
978      assert(added_variable);
979
980      instructions->push_tail(var);
981
982      /* FINISHME: Process the declaration initializer. */
983   }
984
985   /* Variable declarations do not have r-values.
986    */
987   return NULL;
988}
989
990
991ir_rvalue *
992ast_parameter_declarator::hir(exec_list *instructions,
993			      struct _mesa_glsl_parse_state *state)
994{
995   const struct glsl_type *type;
996   const char *name = NULL;
997
998
999   type = type_specifier_to_glsl_type(this->type->specifier, & name, state);
1000
1001   if (type == NULL) {
1002      YYLTYPE loc = this->get_location();
1003      if (name != NULL) {
1004	 _mesa_glsl_error(& loc, state,
1005			  "invalid type `%s' in declaration of `%s'",
1006			  name, this->identifier);
1007      } else {
1008	 _mesa_glsl_error(& loc, state,
1009			  "invalid type in declaration of `%s'",
1010			  this->identifier);
1011      }
1012
1013      type = glsl_type::error_type;
1014   }
1015
1016   ir_variable *var = new ir_variable(type, this->identifier);
1017
1018   /* FINISHME: Handle array declarations.  Note that this requires
1019    * FINISHME: complete handling of constant expressions.
1020    */
1021
1022   /* Apply any specified qualifiers to the parameter declaration.  Note that
1023    * for function parameters the default mode is 'in'.
1024    */
1025   apply_type_qualifier_to_variable(& this->type->qualifier, var, state);
1026   if (var->mode == ir_var_auto)
1027      var->mode = ir_var_in;
1028
1029   instructions->push_tail(var);
1030
1031   /* Parameter declarations do not have r-values.
1032    */
1033   return NULL;
1034}
1035
1036
1037static void
1038ast_function_parameters_to_hir(struct simple_node *ast_parameters,
1039			       exec_list *ir_parameters,
1040			       struct _mesa_glsl_parse_state *state)
1041{
1042   struct simple_node *ptr;
1043
1044   foreach (ptr, ast_parameters) {
1045      ((ast_node *)ptr)->hir(ir_parameters, state);
1046   }
1047}
1048
1049
1050static bool
1051parameter_lists_match(exec_list *list_a, exec_list *list_b)
1052{
1053   exec_list_iterator iter_a = list_a->iterator();
1054   exec_list_iterator iter_b = list_b->iterator();
1055
1056   while (iter_a.has_next()) {
1057      /* If all of the parameters from the other parameter list have been
1058       * exhausted, the lists have different length and, by definition,
1059       * do not match.
1060       */
1061      if (!iter_b.has_next())
1062	 return false;
1063
1064      /* If the types of the parameters do not match, the parameters lists
1065       * are different.
1066       */
1067      /* FINISHME */
1068
1069
1070      iter_a.next();
1071      iter_b.next();
1072   }
1073
1074   return true;
1075}
1076
1077
1078ir_rvalue *
1079ast_function_definition::hir(exec_list *instructions,
1080			     struct _mesa_glsl_parse_state *state)
1081{
1082   ir_label *label;
1083   ir_function_signature *signature = NULL;
1084   ir_function *f = NULL;
1085   exec_list parameters;
1086
1087
1088   /* Convert the list of function parameters to HIR now so that they can be
1089    * used below to compare this function's signature with previously seen
1090    * signatures for functions with the same name.
1091    */
1092   ast_function_parameters_to_hir(& this->prototype->parameters, & parameters,
1093				  state);
1094
1095   const char *return_type_name;
1096   const glsl_type *return_type =
1097      type_specifier_to_glsl_type(this->prototype->return_type->specifier,
1098				  & return_type_name, state);
1099
1100   assert(return_type != NULL);
1101
1102
1103   /* Verify that this function's signature either doesn't match a previously
1104    * seen signature for a function with the same name, or, if a match is found,
1105    * that the previously seen signature does not have an associated definition.
1106    */
1107   const char *const name = this->prototype->identifier;
1108   f = state->symbols->get_function(name);
1109   if (f != NULL) {
1110      foreach_iter(exec_list_iterator, iter, f->signatures) {
1111	 signature = (struct ir_function_signature *) iter.get();
1112
1113	 /* Compare the parameter list of the function being defined to the
1114	  * existing function.  If the parameter lists match, then the return
1115	  * type must also match and the existing function must not have a
1116	  * definition.
1117	  */
1118	 if (parameter_lists_match(& parameters, & signature->parameters)) {
1119	    /* FINISHME: Compare return types. */
1120
1121	    if (signature->definition != NULL) {
1122	       YYLTYPE loc = this->get_location();
1123
1124	       _mesa_glsl_error(& loc, state, "function `%s' redefined", name);
1125	       signature = NULL;
1126	       break;
1127	    }
1128	 }
1129
1130	 signature = NULL;
1131      }
1132
1133   } else if (state->symbols->name_declared_this_scope(name)) {
1134      /* This function name shadows a non-function use of the same name.
1135       */
1136      YYLTYPE loc = this->get_location();
1137
1138      _mesa_glsl_error(& loc, state, "function name `%s' conflicts with "
1139		       "non-function", name);
1140      signature = NULL;
1141   } else {
1142      f = new ir_function(name);
1143      state->symbols->add_function(f->name, f);
1144   }
1145
1146
1147   /* Finish storing the information about this new function in its signature.
1148    */
1149   if (signature == NULL) {
1150      signature = new ir_function_signature(return_type);
1151      f->signatures.push_tail(signature);
1152   } else {
1153      /* Destroy all of the previous parameter information.  The previous
1154       * parameter information comes from the function prototype, and it can
1155       * either include invalid parameter names or may not have names at all.
1156       */
1157      foreach_iter(exec_list_iterator, iter, signature->parameters) {
1158	 assert(((ir_instruction *) iter.get())->as_variable() != NULL);
1159
1160	 iter.remove();
1161	 delete iter.get();
1162      }
1163   }
1164
1165
1166   assert(state->current_function == NULL);
1167   state->current_function = signature;
1168
1169   ast_function_parameters_to_hir(& this->prototype->parameters,
1170				  & signature->parameters,
1171				  state);
1172   /* FINISHME: Set signature->return_type */
1173
1174   label = new ir_label(name);
1175   if (signature->definition == NULL) {
1176      signature->definition = label;
1177   }
1178   instructions->push_tail(label);
1179
1180   /* Add the function parameters to the symbol table.  During this step the
1181    * parameter declarations are also moved from the temporary "parameters" list
1182    * to the instruction list.  There are other more efficient ways to do this,
1183    * but they involve ugly linked-list gymnastics.
1184    */
1185   state->symbols->push_scope();
1186   foreach_iter(exec_list_iterator, iter, parameters) {
1187      ir_variable *const var = (ir_variable *) iter.get();
1188
1189      assert(((ir_instruction *) var)->as_variable() != NULL);
1190
1191      iter.remove();
1192      instructions->push_tail(var);
1193
1194      /* The only way a parameter would "exist" is if two parameters have
1195       * the same name.
1196       */
1197      if (state->symbols->name_declared_this_scope(var->name)) {
1198	 YYLTYPE loc = this->get_location();
1199
1200	 _mesa_glsl_error(& loc, state, "parameter `%s' redeclared", var->name);
1201      } else {
1202	 state->symbols->add_variable(var->name, var);
1203      }
1204   }
1205
1206   /* Convert the body of the function to HIR, and append the resulting
1207    * instructions to the list that currently consists of the function label
1208    * and the function parameters.
1209    */
1210   this->body->hir(instructions, state);
1211
1212   state->symbols->pop_scope();
1213
1214   assert(state->current_function == signature);
1215   state->current_function = NULL;
1216
1217   /* Function definitions do not have r-values.
1218    */
1219   return NULL;
1220}
1221
1222
1223ir_rvalue *
1224ast_jump_statement::hir(exec_list *instructions,
1225			struct _mesa_glsl_parse_state *state)
1226{
1227
1228   if (mode == ast_return) {
1229      ir_return *inst;
1230
1231      if (opt_return_value) {
1232	 /* FINISHME: Make sure the enclosing function has a non-void return
1233	  * FINISHME: type.
1234	  */
1235
1236	 ir_expression *const ret = (ir_expression *)
1237	    opt_return_value->hir(instructions, state);
1238	 assert(ret != NULL);
1239
1240	 /* FINISHME: Make sure the type of the return value matches the return
1241	  * FINISHME: type of the enclosing function.
1242	  */
1243
1244	 inst = new ir_return(ret);
1245      } else {
1246	 /* FINISHME: Make sure the enclosing function has a void return type.
1247	  */
1248	 inst = new ir_return;
1249      }
1250
1251      instructions->push_tail(inst);
1252   }
1253
1254   /* Jump instructions do not have r-values.
1255    */
1256   return NULL;
1257}
1258