Merge commit mesa-public/master into vulkan
authorJason Ekstrand <jason.ekstrand@intel.com>
Fri, 5 Feb 2016 23:03:04 +0000 (15:03 -0800)
committerJason Ekstrand <jason.ekstrand@intel.com>
Fri, 5 Feb 2016 23:03:44 +0000 (15:03 -0800)
This pulls in the patches that move all of the compiler stuff around

86 files changed:
1  2 
configure.ac
src/Makefile.am
src/compiler/Makefile.am
src/compiler/Makefile.sources
src/compiler/glsl/.gitignore
src/compiler/glsl/Makefile.am
src/compiler/glsl/Makefile.sources
src/compiler/glsl/ast_to_hir.cpp
src/compiler/glsl/glsl_parser_extras.cpp
src/compiler/glsl/ir.cpp
src/compiler/glsl/ir.h
src/compiler/glsl/ir_clone.cpp
src/compiler/glsl/ir_optimization.h
src/compiler/glsl/ir_validate.cpp
src/compiler/glsl/link_uniform_initializers.cpp
src/compiler/glsl/lower_packing_builtins.cpp
src/compiler/glsl/standalone_scaffolding.cpp
src/compiler/glsl_types.cpp
src/compiler/glsl_types.h
src/compiler/nir/Makefile.sources
src/compiler/nir/glsl_to_nir.cpp
src/compiler/nir/nir.c
src/compiler/nir/nir.h
src/compiler/nir/nir_algebraic.py
src/compiler/nir/nir_builder.h
src/compiler/nir/nir_clone.c
src/compiler/nir/nir_control_flow.c
src/compiler/nir/nir_dominance.c
src/compiler/nir/nir_gather_info.c
src/compiler/nir/nir_inline_functions.c
src/compiler/nir/nir_instr_set.c
src/compiler/nir/nir_intrinsics.h
src/compiler/nir/nir_lower_alu_to_scalar.c
src/compiler/nir/nir_lower_atomics.c
src/compiler/nir/nir_lower_indirect_derefs.c
src/compiler/nir/nir_lower_io.c
src/compiler/nir/nir_lower_outputs_to_temporaries.c
src/compiler/nir/nir_lower_returns.c
src/compiler/nir/nir_lower_samplers.c
src/compiler/nir/nir_lower_system_values.c
src/compiler/nir/nir_lower_vars_to_ssa.c
src/compiler/nir/nir_opcodes.py
src/compiler/nir/nir_opt_algebraic.py
src/compiler/nir/nir_phi_builder.c
src/compiler/nir/nir_phi_builder.h
src/compiler/nir/nir_print.c
src/compiler/nir/nir_remove_dead_variables.c
src/compiler/nir/nir_repair_ssa.c
src/compiler/nir/nir_sweep.c
src/compiler/nir/nir_validate.c
src/compiler/nir/spirv/GLSL.std.450.h
src/compiler/nir/spirv/nir_spirv.h
src/compiler/nir/spirv/spirv.h
src/compiler/nir/spirv/spirv_to_nir.c
src/compiler/nir/spirv/vtn_alu.c
src/compiler/nir/spirv/vtn_cfg.c
src/compiler/nir/spirv/vtn_glsl450.c
src/compiler/nir/spirv/vtn_private.h
src/compiler/nir/spirv/vtn_variables.c
src/compiler/nir/spirv2nir.c
src/compiler/nir_types.cpp
src/compiler/nir_types.h
src/compiler/shader_enums.c
src/compiler/shader_enums.h
src/mesa/drivers/dri/i965/brw_compiler.c
src/mesa/drivers/dri/i965/brw_fs.cpp
src/mesa/drivers/dri/i965/brw_fs.h
src/mesa/drivers/dri/i965/brw_fs_channel_expressions.cpp
src/mesa/drivers/dri/i965/brw_fs_nir.cpp
src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
src/mesa/drivers/dri/i965/brw_link.cpp
src/mesa/drivers/dri/i965/brw_nir.c
src/mesa/drivers/dri/i965/brw_program.c
src/mesa/drivers/dri/i965/brw_vec4.h
src/mesa/main/mtypes.h
src/mesa/program/ir_to_mesa.cpp
src/mesa/program/prog_to_nir.c
src/mesa/state_tracker/st_glsl_to_tgsi.cpp
src/vulkan/Makefile.am
src/vulkan/anv_meta.c
src/vulkan/anv_meta_clear.c
src/vulkan/anv_meta_resolve.c
src/vulkan/anv_nir.h
src/vulkan/anv_nir_apply_dynamic_offsets.c
src/vulkan/anv_nir_apply_pipeline_layout.c
src/vulkan/anv_pipeline.c

diff --cc configure.ac
Simple merge
diff --cc src/Makefile.am
Simple merge
index 0000000000000000000000000000000000000000,0bc8e48efa64c35e8c71fb4c9e75250c89dafc67..e3d297fe299f1d2b606f776af2f7b9ad24444ea7
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,323 +1,333 @@@
 -noinst_PROGRAMS = glsl_compiler
+ #
+ # Copyright © 2012 Jon TURNEY
+ # Copyright (C) 2015 Intel Corporation
+ #
+ # Permission is hereby granted, free of charge, to any person obtaining a
+ # copy of this software and associated documentation files (the "Software"),
+ # to deal in the Software without restriction, including without limitation
+ # the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ # and/or sell copies of the Software, and to permit persons to whom the
+ # Software is furnished to do so, subject to the following conditions:
+ #
+ # The above copyright notice and this permission notice (including the next
+ # paragraph) shall be included in all copies or substantial portions of the
+ # Software.
+ #
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ # IN THE SOFTWARE.
+ include Makefile.sources
+ AM_CPPFLAGS = \
+       -I$(top_srcdir)/include \
+       -I$(top_srcdir)/src \
+       -I$(top_srcdir)/src/mapi \
+       -I$(top_srcdir)/src/mesa/ \
+       -I$(top_builddir)/src/compiler/glsl\
+       -I$(top_srcdir)/src/compiler/glsl\
+       -I$(top_srcdir)/src/compiler/glsl/glcpp\
+       -I$(top_srcdir)/src/gallium/include \
+       -I$(top_srcdir)/src/gallium/auxiliary \
+       -I$(top_srcdir)/src/gtest/include \
+       $(DEFINES)
+ AM_CFLAGS = \
+       $(VISIBILITY_CFLAGS) \
+       $(MSVC2013_COMPAT_CFLAGS)
+ AM_CXXFLAGS = \
+       $(VISIBILITY_CXXFLAGS) \
+       $(MSVC2013_COMPAT_CXXFLAGS)
+ noinst_LTLIBRARIES = libcompiler.la
+ libcompiler_la_SOURCES = $(LIBCOMPILER_FILES)
+ check_PROGRAMS =
+ TESTS =
+ BUILT_SOURCES =
+ CLEANFILES =
+ EXTRA_DIST = SConscript
+ EXTRA_DIST += glsl/tests glsl/glcpp/tests glsl/README \
+       glsl/TODO glsl/glcpp/README                     \
+       glsl/glsl_lexer.ll                              \
+       glsl/glsl_parser.yy                             \
+       glsl/glcpp/glcpp-lex.l                          \
+       glsl/glcpp/glcpp-parse.y                        \
+       glsl/Makefile.sources                           \
+       glsl/SConscript
+ TESTS += glsl/glcpp/tests/glcpp-test                  \
+       glsl/glcpp/tests/glcpp-test-cr-lf               \
+       glsl/tests/blob-test                            \
+       glsl/tests/general-ir-test                      \
+       glsl/tests/optimization-test                    \
+       glsl/tests/sampler-types-test                   \
+       glsl/tests/uniform-initializer-test
+ TESTS_ENVIRONMENT= \
+       export PYTHON2=$(PYTHON2); \
+       export PYTHON_FLAGS=$(PYTHON_FLAGS);
+ check_PROGRAMS +=                                     \
+       glsl/glcpp/glcpp                                \
+       glsl/glsl_test                                  \
+       glsl/tests/blob-test                            \
+       glsl/tests/general-ir-test                      \
+       glsl/tests/sampler-types-test                   \
+       glsl/tests/uniform-initializer-test
++noinst_PROGRAMS = glsl_compiler spirv2nir
+ glsl_tests_blob_test_SOURCES =                                \
+       glsl/tests/blob_test.c
+ glsl_tests_blob_test_LDADD =                          \
+       glsl/libglsl.la
+ glsl_tests_general_ir_test_SOURCES =                  \
+       glsl/standalone_scaffolding.cpp                 \
+       glsl/tests/builtin_variable_test.cpp            \
+       glsl/tests/invalidate_locations_test.cpp        \
+       glsl/tests/general_ir_test.cpp                  \
+       glsl/tests/varyings_test.cpp
+ glsl_tests_general_ir_test_CFLAGS =                   \
+       $(PTHREAD_CFLAGS)
+ glsl_tests_general_ir_test_LDADD =                    \
+       $(top_builddir)/src/gtest/libgtest.la           \
+       glsl/libglsl.la         \
+       $(top_builddir)/src/libglsl_util.la             \
+       $(PTHREAD_LIBS)
+ glsl_tests_uniform_initializer_test_SOURCES =         \
+       glsl/tests/copy_constant_to_storage_tests.cpp   \
+       glsl/tests/set_uniform_initializer_tests.cpp    \
+       glsl/tests/uniform_initializer_utils.cpp        \
+       glsl/tests/uniform_initializer_utils.h
+ glsl_tests_uniform_initializer_test_CFLAGS =          \
+       $(PTHREAD_CFLAGS)
+ glsl_tests_uniform_initializer_test_LDADD =           \
+       $(top_builddir)/src/gtest/libgtest.la           \
+       glsl/libglsl.la         \
+       $(top_builddir)/src/libglsl_util.la             \
+       $(PTHREAD_LIBS)
+ glsl_tests_sampler_types_test_SOURCES =                       \
+       glsl/tests/sampler_types_test.cpp
+ glsl_tests_sampler_types_test_CFLAGS =                        \
+       $(PTHREAD_CFLAGS)
+ glsl_tests_sampler_types_test_LDADD =                 \
+       $(top_builddir)/src/gtest/libgtest.la           \
+       glsl/libglsl.la                                 \
+       $(top_builddir)/src/libglsl_util.la             \
+       $(PTHREAD_LIBS)
+ noinst_LTLIBRARIES += glsl/libglsl.la glsl/libglcpp.la
+ glsl_libglcpp_la_LIBADD =                             \
+       $(top_builddir)/src/util/libmesautil.la
+ glsl_libglcpp_la_SOURCES =                            \
+       glsl/glcpp/glcpp-lex.c                          \
+       glsl/glcpp/glcpp-parse.c                        \
+       glsl/glcpp/glcpp-parse.h                        \
+       $(LIBGLCPP_FILES)
+ glsl_glcpp_glcpp_SOURCES =                            \
+       glsl/glcpp/glcpp.c
+ glsl_glcpp_glcpp_LDADD =                              \
+       glsl/libglcpp.la        \
+       $(top_builddir)/src/libglsl_util.la             \
+       -lm
+ glsl_libglsl_la_LIBADD = \
+       nir/libnir.la \
+       glsl/libglcpp.la
+ glsl_libglsl_la_SOURCES =                             \
+       glsl/glsl_lexer.cpp                             \
+       glsl/glsl_parser.cpp                            \
+       glsl/glsl_parser.h                              \
+       $(LIBGLSL_FILES)
+ glsl_compiler_SOURCES = \
+       $(GLSL_COMPILER_CXX_FILES)
+ glsl_compiler_LDADD =                                 \
+       glsl/libglsl.la                                 \
+       $(top_builddir)/src/libglsl_util.la             \
+       $(top_builddir)/src/util/libmesautil.la         \
+       $(PTHREAD_LIBS)
+ glsl_glsl_test_SOURCES = \
+       glsl/standalone_scaffolding.cpp \
+       glsl/test.cpp \
+       glsl/test_optpass.cpp \
+       glsl/test_optpass.h
+ glsl_glsl_test_LDADD =                                        \
+       glsl/libglsl.la                                 \
+       $(top_builddir)/src/libglsl_util.la             \
+       $(PTHREAD_LIBS)
++spirv2nir_SOURCES = \
++      nir/spirv2nir.c
++
++spirv2nir_LDADD =                                     \
++      nir/libnir.la                                   \
++      $(top_builddir)/src/util/libmesautil.la         \
++      -lm -lstdc++                                    \
++      $(PTHREAD_LIBS)
++
+ # We write our own rules for yacc and lex below. We'd rather use automake,
+ # but automake makes it especially difficult for a number of reasons:
+ #
+ #  * < automake-1.12 generates .h files from .yy and .ypp files, but
+ #    >=automake-1.12 generates .hh and .hpp files respectively. There's no
+ #    good way of making a project that uses C++ yacc files compatible with
+ #    both versions of automake. Strong work automake developers.
+ #
+ #  * Since we're generating code from .l/.y files in a subdirectory (glcpp/)
+ #    we'd like the resulting generated code to also go in glcpp/ for purposes
+ #    of distribution. Automake gives no way to do this.
+ #
+ #  * Since we're building multiple yacc parsers into one library (and via one
+ #    Makefile) we have to use per-target YFLAGS. Using per-target YFLAGS causes
+ #    automake to name the resulting generated code as <library-name>_filename.c.
+ #    Frankly, that's ugly and we don't want a libglcpp_glcpp_parser.h file.
+ # In order to make build output print "LEX" and "YACC", we reproduce the
+ # automake variables below.
+ AM_V_LEX = $(am__v_LEX_$(V))
+ am__v_LEX_ = $(am__v_LEX_$(AM_DEFAULT_VERBOSITY))
+ am__v_LEX_0 = @echo "  LEX     " $@;
+ am__v_LEX_1 =
+ AM_V_YACC = $(am__v_YACC_$(V))
+ am__v_YACC_ = $(am__v_YACC_$(AM_DEFAULT_VERBOSITY))
+ am__v_YACC_0 = @echo "  YACC    " $@;
+ am__v_YACC_1 =
+ MKDIR_GEN = $(AM_V_at)$(MKDIR_P) $(@D)
+ YACC_GEN = $(AM_V_YACC)$(YACC) $(YFLAGS)
+ LEX_GEN = $(AM_V_LEX)$(LEX) $(LFLAGS)
+ glsl/glsl_parser.cpp glsl/glsl_parser.h: glsl/glsl_parser.yy
+       $(YACC_GEN) -o $@ -p "_mesa_glsl_" --defines=$(builddir)/glsl/glsl_parser.h $(srcdir)/glsl/glsl_parser.yy
+ glsl/glsl_lexer.cpp: glsl/glsl_lexer.ll
+       $(LEX_GEN) -o $@ $(srcdir)/glsl/glsl_lexer.ll
+ glsl/glcpp/glcpp-parse.c glsl/glcpp/glcpp-parse.h: glsl/glcpp/glcpp-parse.y
+       $(MKDIR_GEN)
+       $(YACC_GEN) -o $@ -p "glcpp_parser_" --defines=$(builddir)/glsl/glcpp/glcpp-parse.h $(srcdir)/glsl/glcpp/glcpp-parse.y
+ glsl/glcpp/glcpp-lex.c: glsl/glcpp/glcpp-lex.l
+       $(MKDIR_GEN)
+       $(LEX_GEN) -o $@ $(srcdir)/glsl/glcpp/glcpp-lex.l
+ # Only the parsers (specifically the header files generated at the same time)
+ # need to be in BUILT_SOURCES. Though if we list the parser headers YACC is
+ # called for the .c/.cpp file and the .h files. By listing the .c/.cpp files
+ # YACC is only executed once for each parser. The rest of the generated code
+ # will be created at the appropriate times according to standard automake
+ # dependency rules.
+ BUILT_SOURCES +=                                      \
+       glsl/glsl_parser.cpp                            \
+       glsl/glsl_lexer.cpp                             \
+       glsl/glcpp/glcpp-parse.c                        \
+       glsl/glcpp/glcpp-lex.c
+ CLEANFILES +=                                         \
+       glsl/glcpp/glcpp-parse.h                        \
+       glsl/glsl_parser.h                              \
+       glsl/glsl_parser.cpp                            \
+       glsl/glsl_lexer.cpp                             \
+       glsl/glcpp/glcpp-parse.c                        \
+       glsl/glcpp/glcpp-lex.c
+ clean-local:
+       $(RM) -r subtest-cr subtest-cr-lf subtest-lf subtest-lf-cr
+ dist-hook:
+       $(RM) glsl/glcpp/tests/*.out
+       $(RM) glsl/glcpp/tests/subtest*/*.out
+ noinst_LTLIBRARIES += nir/libnir.la
+ nir_libnir_la_CPPFLAGS = \
+       $(AM_CPPFLAGS) \
+       -I$(top_builddir)/src/compiler/nir \
+       -I$(top_srcdir)/src/compiler/nir
+ nir_libnir_la_LIBADD = \
+       libcompiler.la
+ nir_libnir_la_SOURCES =                                       \
+       $(NIR_FILES)                                    \
++      $(SPIRV_FILES)                                  \
+       $(NIR_GENERATED_FILES)
+ PYTHON_GEN = $(AM_V_GEN)$(PYTHON2) $(PYTHON_FLAGS)
+ nir/nir_builder_opcodes.h: nir/nir_opcodes.py nir/nir_builder_opcodes_h.py
+       $(MKDIR_GEN)
+       $(PYTHON_GEN) $(srcdir)/nir/nir_builder_opcodes_h.py > $@ || ($(RM) $@; false)
+ nir/nir_constant_expressions.c: nir/nir_opcodes.py nir/nir_constant_expressions.py
+       $(MKDIR_GEN)
+       $(PYTHON_GEN) $(srcdir)/nir/nir_constant_expressions.py > $@ || ($(RM) $@; false)
+ nir/nir_opcodes.h: nir/nir_opcodes.py nir/nir_opcodes_h.py
+       $(MKDIR_GEN)
+       $(PYTHON_GEN) $(srcdir)/nir/nir_opcodes_h.py > $@ || ($(RM) $@; false)
+ nir/nir_opcodes.c: nir/nir_opcodes.py nir/nir_opcodes_c.py
+       $(MKDIR_GEN)
+       $(PYTHON_GEN) $(srcdir)/nir/nir_opcodes_c.py > $@ || ($(RM) $@; false)
+ nir/nir_opt_algebraic.c: nir/nir_opt_algebraic.py nir/nir_algebraic.py
+       $(MKDIR_GEN)
+       $(PYTHON_GEN) $(srcdir)/nir/nir_opt_algebraic.py > $@ || ($(RM) $@; false)
+ check_PROGRAMS += nir/tests/control_flow_tests
+ nir_tests_control_flow_tests_CPPFLAGS = \
+       $(AM_CPPFLAGS) \
+       -I$(top_builddir)/src/compiler/nir \
+       -I$(top_srcdir)/src/compiler/nir
+ nir_tests_control_flow_tests_SOURCES =                        \
+       nir/tests/control_flow_tests.cpp
+ nir_tests_control_flow_tests_CFLAGS =                 \
+       $(PTHREAD_CFLAGS)
+ nir_tests_control_flow_tests_LDADD =                  \
+       $(top_builddir)/src/gtest/libgtest.la           \
+       nir/libnir.la   \
+       $(top_builddir)/src/util/libmesautil.la         \
+       $(PTHREAD_LIBS)
+ TESTS += nir/tests/control_flow_tests
+ BUILT_SOURCES += $(NIR_GENERATED_FILES)
+ CLEANFILES += $(NIR_GENERATED_FILES)
+ EXTRA_DIST += \
+       nir/nir_algebraic.py                            \
+       nir/nir_builder_opcodes_h.py                    \
+       nir/nir_constant_expressions.py                 \
+       nir/nir_opcodes.py                              \
+       nir/nir_opcodes_c.py                            \
+       nir/nir_opcodes_h.py                            \
+       nir/nir_opt_algebraic.py                        \
+       nir/tests                                       \
+       nir/Makefile.sources
index 0000000000000000000000000000000000000000,c9780d6d6f75f26ef5d3d8fd62ff043158e104d5..2a4568aa679879350e658d07c76ef651a4167483
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,226 +1,242 @@@
+ LIBCOMPILER_FILES = \
+       builtin_type_macros.h \
+       glsl_types.cpp \
+       glsl_types.h \
+       nir_types.cpp \
+       nir_types.h \
+       shader_enums.c \
+       shader_enums.h
+ # libglsl
+ LIBGLSL_FILES = \
+       glsl/ast.h \
+       glsl/ast_array_index.cpp \
+       glsl/ast_expr.cpp \
+       glsl/ast_function.cpp \
+       glsl/ast_to_hir.cpp \
+       glsl/ast_type.cpp \
+       glsl/blob.c \
+       glsl/blob.h \
+       glsl/builtin_functions.cpp \
+       glsl/builtin_types.cpp \
+       glsl/builtin_variables.cpp \
+       glsl/glsl_parser_extras.cpp \
+       glsl/glsl_parser_extras.h \
+       glsl/glsl_symbol_table.cpp \
+       glsl/glsl_symbol_table.h \
+       glsl/hir_field_selection.cpp \
+       glsl/ir_basic_block.cpp \
+       glsl/ir_basic_block.h \
+       glsl/ir_builder.cpp \
+       glsl/ir_builder.h \
+       glsl/ir_clone.cpp \
+       glsl/ir_constant_expression.cpp \
+       glsl/ir.cpp \
+       glsl/ir.h \
+       glsl/ir_equals.cpp \
+       glsl/ir_expression_flattening.cpp \
+       glsl/ir_expression_flattening.h \
+       glsl/ir_function_can_inline.cpp \
+       glsl/ir_function_detect_recursion.cpp \
+       glsl/ir_function_inlining.h \
+       glsl/ir_function.cpp \
+       glsl/ir_hierarchical_visitor.cpp \
+       glsl/ir_hierarchical_visitor.h \
+       glsl/ir_hv_accept.cpp \
+       glsl/ir_import_prototypes.cpp \
+       glsl/ir_optimization.h \
+       glsl/ir_print_visitor.cpp \
+       glsl/ir_print_visitor.h \
+       glsl/ir_reader.cpp \
+       glsl/ir_reader.h \
+       glsl/ir_rvalue_visitor.cpp \
+       glsl/ir_rvalue_visitor.h \
+       glsl/ir_set_program_inouts.cpp \
+       glsl/ir_uniform.h \
+       glsl/ir_validate.cpp \
+       glsl/ir_variable_refcount.cpp \
+       glsl/ir_variable_refcount.h \
+       glsl/ir_visitor.h \
+       glsl/linker.cpp \
+       glsl/linker.h \
+       glsl/link_atomics.cpp \
+       glsl/link_functions.cpp \
+       glsl/link_interface_blocks.cpp \
+       glsl/link_uniforms.cpp \
+       glsl/link_uniform_initializers.cpp \
+       glsl/link_uniform_block_active_visitor.cpp \
+       glsl/link_uniform_block_active_visitor.h \
+       glsl/link_uniform_blocks.cpp \
+       glsl/link_varyings.cpp \
+       glsl/link_varyings.h \
+       glsl/list.h \
+       glsl/loop_analysis.cpp \
+       glsl/loop_analysis.h \
+       glsl/loop_controls.cpp \
+       glsl/loop_unroll.cpp \
+       glsl/lower_buffer_access.cpp \
+       glsl/lower_buffer_access.h \
+       glsl/lower_clip_distance.cpp \
+       glsl/lower_const_arrays_to_uniforms.cpp \
+       glsl/lower_discard.cpp \
+       glsl/lower_discard_flow.cpp \
+       glsl/lower_if_to_cond_assign.cpp \
+       glsl/lower_instructions.cpp \
+       glsl/lower_jumps.cpp \
+       glsl/lower_mat_op_to_vec.cpp \
+       glsl/lower_noise.cpp \
+       glsl/lower_offset_array.cpp \
+       glsl/lower_packed_varyings.cpp \
+       glsl/lower_named_interface_blocks.cpp \
+       glsl/lower_packing_builtins.cpp \
+       glsl/lower_subroutine.cpp \
+       glsl/lower_tess_level.cpp \
+       glsl/lower_texture_projection.cpp \
+       glsl/lower_variable_index_to_cond_assign.cpp \
+       glsl/lower_vec_index_to_cond_assign.cpp \
+       glsl/lower_vec_index_to_swizzle.cpp \
+       glsl/lower_vector.cpp \
+       glsl/lower_vector_derefs.cpp \
+       glsl/lower_vector_insert.cpp \
+       glsl/lower_vertex_id.cpp \
+       glsl/lower_output_reads.cpp \
+       glsl/lower_shared_reference.cpp \
+       glsl/lower_ubo_reference.cpp \
+       glsl/opt_algebraic.cpp \
+       glsl/opt_array_splitting.cpp \
+       glsl/opt_conditional_discard.cpp \
+       glsl/opt_constant_folding.cpp \
+       glsl/opt_constant_propagation.cpp \
+       glsl/opt_constant_variable.cpp \
+       glsl/opt_copy_propagation.cpp \
+       glsl/opt_copy_propagation_elements.cpp \
+       glsl/opt_dead_builtin_variables.cpp \
+       glsl/opt_dead_builtin_varyings.cpp \
+       glsl/opt_dead_code.cpp \
+       glsl/opt_dead_code_local.cpp \
+       glsl/opt_dead_functions.cpp \
+       glsl/opt_flatten_nested_if_blocks.cpp \
+       glsl/opt_flip_matrices.cpp \
+       glsl/opt_function_inlining.cpp \
+       glsl/opt_if_simplification.cpp \
+       glsl/opt_minmax.cpp \
+       glsl/opt_noop_swizzle.cpp \
+       glsl/opt_rebalance_tree.cpp \
+       glsl/opt_redundant_jumps.cpp \
+       glsl/opt_structure_splitting.cpp \
+       glsl/opt_swizzle_swizzle.cpp \
+       glsl/opt_tree_grafting.cpp \
+       glsl/opt_vectorize.cpp \
+       glsl/program.h \
+       glsl/s_expression.cpp \
+       glsl/s_expression.h
+ # glsl_compiler
+ GLSL_COMPILER_CXX_FILES = \
+       glsl/standalone_scaffolding.cpp \
+       glsl/standalone_scaffolding.h \
+       glsl/main.cpp
+ # libglsl generated sources
+ LIBGLSL_GENERATED_CXX_FILES = \
+       glsl/glsl_lexer.cpp \
+       glsl/glsl_parser.cpp
+ # libglcpp
+ LIBGLCPP_FILES = \
+       glsl/glcpp/glcpp.h \
+       glsl/glcpp/pp.c
+ LIBGLCPP_GENERATED_FILES = \
+       glsl/glcpp/glcpp-lex.c \
+       glsl/glcpp/glcpp-parse.c
+ NIR_GENERATED_FILES = \
+       nir/nir_builder_opcodes.h \
+       nir/nir_constant_expressions.c \
+       nir/nir_opcodes.c \
+       nir/nir_opcodes.h \
+       nir/nir_opt_algebraic.c
+ NIR_FILES = \
+       nir/glsl_to_nir.cpp \
+       nir/glsl_to_nir.h \
+       nir/nir.c \
+       nir/nir.h \
+       nir/nir_array.h \
+       nir/nir_builder.h \
+       nir/nir_clone.c \
+       nir/nir_constant_expressions.h \
+       nir/nir_control_flow.c \
+       nir/nir_control_flow.h \
+       nir/nir_control_flow_private.h \
+       nir/nir_dominance.c \
+       nir/nir_from_ssa.c \
++      nir/nir_gather_info.c \
+       nir/nir_gs_count_vertices.c \
++      nir/nir_inline_functions.c \
+       nir/nir_intrinsics.c \
+       nir/nir_intrinsics.h \
+       nir/nir_instr_set.c \
+       nir/nir_instr_set.h \
+       nir/nir_liveness.c \
+       nir/nir_lower_alu_to_scalar.c \
+       nir/nir_lower_atomics.c \
+       nir/nir_lower_clip.c \
+       nir/nir_lower_global_vars_to_local.c \
+       nir/nir_lower_gs_intrinsics.c \
++        nir/nir_lower_indirect_derefs.c \
+       nir/nir_lower_load_const_to_scalar.c \
+       nir/nir_lower_locals_to_regs.c \
+       nir/nir_lower_idiv.c \
+       nir/nir_lower_io.c \
+       nir/nir_lower_outputs_to_temporaries.c \
+       nir/nir_lower_phis_to_scalar.c \
++      nir/nir_lower_returns.c \
+       nir/nir_lower_samplers.c \
+       nir/nir_lower_system_values.c \
+       nir/nir_lower_tex.c \
+       nir/nir_lower_to_source_mods.c \
+       nir/nir_lower_two_sided_color.c \
+       nir/nir_lower_vars_to_ssa.c \
+       nir/nir_lower_var_copies.c \
+       nir/nir_lower_vec_to_movs.c \
+       nir/nir_metadata.c \
+       nir/nir_move_vec_src_uses_to_dest.c \
+       nir/nir_normalize_cubemap_coords.c \
+       nir/nir_opt_constant_folding.c \
+       nir/nir_opt_copy_propagate.c \
+       nir/nir_opt_cse.c \
+       nir/nir_opt_dce.c \
+       nir/nir_opt_dead_cf.c \
+       nir/nir_opt_gcm.c \
+       nir/nir_opt_global_to_local.c \
+       nir/nir_opt_peephole_select.c \
+       nir/nir_opt_remove_phis.c \
+       nir/nir_opt_undef.c \
++      nir/nir_phi_builder.c \
++      nir/nir_phi_builder.h \
+       nir/nir_print.c \
+       nir/nir_remove_dead_variables.c \
++      nir/nir_repair_ssa.c \
+       nir/nir_search.c \
+       nir/nir_search.h \
+       nir/nir_split_var_copies.c \
+       nir/nir_sweep.c \
+       nir/nir_to_ssa.c \
+       nir/nir_validate.c \
+       nir/nir_vla.h \
+       nir/nir_worklist.c \
+       nir/nir_worklist.h
++
++SPIRV_FILES = \
++      nir/spirv/nir_spirv.h \
++      nir/spirv/spirv_to_nir.c \
++      nir/spirv/vtn_alu.c \
++      nir/spirv/vtn_cfg.c \
++      nir/spirv/vtn_glsl450.c \
++      nir/spirv/vtn_private.h \
++      nir/spirv/vtn_variables.c
index 0000000000000000000000000000000000000000,dda423f83db6df30eded8a2aacf772e46de3d568..e80f8af6bfcf70450f7d024e7ea36a0c6ea12226
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,10 +1,11 @@@
+ glsl_compiler
+ glsl_lexer.cpp
+ glsl_parser.cpp
+ glsl_parser.h
+ glsl_parser.output
+ glsl_test
++spirv2nir
+ subtest-cr/
+ subtest-lf/
+ subtest-cr-lf/
+ subtest-lf-cr/
index 0000000000000000000000000000000000000000,9954b81240338659ec881300cf3eec29dcc067c4..d6b1f9ed6958da6d852e88aba95229352c7b0390
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,228 +1,237 @@@
 -noinst_PROGRAMS = glsl_compiler
+ # Copyright © 2012 Jon TURNEY
+ #
+ # Permission is hereby granted, free of charge, to any person obtaining a
+ # copy of this software and associated documentation files (the "Software"),
+ # to deal in the Software without restriction, including without limitation
+ # the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ # and/or sell copies of the Software, and to permit persons to whom the
+ # Software is furnished to do so, subject to the following conditions:
+ #
+ # The above copyright notice and this permission notice (including the next
+ # paragraph) shall be included in all copies or substantial portions of the
+ # Software.
+ #
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ # IN THE SOFTWARE.
+ AM_CPPFLAGS = \
+       -I$(top_srcdir)/include \
+       -I$(top_srcdir)/src \
+       -I$(top_srcdir)/src/mapi \
+       -I$(top_srcdir)/src/mesa/ \
+       -I$(top_srcdir)/src/gallium/include \
+       -I$(top_srcdir)/src/gallium/auxiliary \
+       -I$(top_srcdir)/src/glsl/glcpp \
+       -I$(top_srcdir)/src/gtest/include \
+       $(DEFINES)
+ AM_CFLAGS = \
+       $(VISIBILITY_CFLAGS) \
+       $(MSVC2013_COMPAT_CFLAGS)
+ AM_CXXFLAGS = \
+       $(VISIBILITY_CXXFLAGS) \
+       $(MSVC2013_COMPAT_CXXFLAGS)
+ EXTRA_DIST = tests glcpp/tests README TODO glcpp/README       \
+       glsl_lexer.ll                                   \
+       glsl_parser.yy                                  \
+       glcpp/glcpp-lex.l                               \
+       glcpp/glcpp-parse.y                             \
+       SConscript
+ include Makefile.sources
+ TESTS = glcpp/tests/glcpp-test                                \
+       glcpp/tests/glcpp-test-cr-lf                    \
+       tests/blob-test                                 \
+       tests/general-ir-test                           \
+       tests/optimization-test                         \
+       tests/sampler-types-test                        \
+       tests/uniform-initializer-test
+ TESTS_ENVIRONMENT= \
+       export PYTHON2=$(PYTHON2); \
+       export PYTHON_FLAGS=$(PYTHON_FLAGS);
+ noinst_LTLIBRARIES = libglsl.la libglcpp.la
+ check_PROGRAMS =                                      \
+       glcpp/glcpp                                     \
+       glsl_test                                       \
+       tests/blob-test                                 \
+       tests/general-ir-test                           \
+       tests/sampler-types-test                        \
+       tests/uniform-initializer-test
 -
++noinst_PROGRAMS = glsl_compiler spirv2nir
+ tests_blob_test_SOURCES =                             \
+       tests/blob_test.c
+ tests_blob_test_LDADD =                                       \
+       $(top_builddir)/src/glsl/libglsl.la
+ tests_general_ir_test_SOURCES =               \
+       standalone_scaffolding.cpp                      \
+       tests/builtin_variable_test.cpp                 \
+       tests/invalidate_locations_test.cpp             \
+       tests/general_ir_test.cpp                       \
+       tests/varyings_test.cpp
+ tests_general_ir_test_CFLAGS =                                \
+       $(PTHREAD_CFLAGS)
+ tests_general_ir_test_LDADD =                         \
+       $(top_builddir)/src/gtest/libgtest.la           \
+       $(top_builddir)/src/glsl/libglsl.la             \
+       $(top_builddir)/src/libglsl_util.la             \
+       $(PTHREAD_LIBS)
+ tests_uniform_initializer_test_SOURCES =              \
+       tests/copy_constant_to_storage_tests.cpp        \
+       tests/set_uniform_initializer_tests.cpp         \
+       tests/uniform_initializer_utils.cpp             \
+       tests/uniform_initializer_utils.h
+ tests_uniform_initializer_test_CFLAGS =                       \
+       $(PTHREAD_CFLAGS)
+ tests_uniform_initializer_test_LDADD =                        \
+       $(top_builddir)/src/gtest/libgtest.la           \
+       $(top_builddir)/src/glsl/libglsl.la             \
+       $(top_builddir)/src/libglsl_util.la             \
+       $(PTHREAD_LIBS)
+ tests_sampler_types_test_SOURCES =                    \
+       tests/sampler_types_test.cpp
+ tests_sampler_types_test_CFLAGS =                     \
+       $(PTHREAD_CFLAGS)
+ tests_sampler_types_test_LDADD =                      \
+       $(top_builddir)/src/gtest/libgtest.la           \
+       $(top_builddir)/src/glsl/libglsl.la             \
+       $(top_builddir)/src/libglsl_util.la             \
+       $(PTHREAD_LIBS)
+ libglcpp_la_LIBADD =                                  \
+       $(top_builddir)/src/util/libmesautil.la
+ libglcpp_la_SOURCES =                                 \
+       glcpp/glcpp-lex.c                               \
+       glcpp/glcpp-parse.c                             \
+       glcpp/glcpp-parse.h                             \
+       $(LIBGLCPP_FILES)
+ glcpp_glcpp_SOURCES =                                 \
+       glcpp/glcpp.c
+ glcpp_glcpp_LDADD =                                   \
+       libglcpp.la                                     \
+       $(top_builddir)/src/libglsl_util.la             \
+       -lm
+ libglsl_la_LIBADD = \
+       $(top_builddir)/src/compiler/nir/libnir.la \
+       libglcpp.la
+ libglsl_la_SOURCES =                                  \
+       glsl_lexer.cpp                                  \
+       glsl_parser.cpp                                 \
+       glsl_parser.h                                   \
+       $(LIBGLSL_FILES)
+ glsl_compiler_SOURCES = \
+       $(GLSL_COMPILER_CXX_FILES)
+ glsl_compiler_LDADD =                                 \
+       libglsl.la                                      \
+       $(top_builddir)/src/libglsl_util.la             \
+       $(top_builddir)/src/util/libmesautil.la         \
+       $(PTHREAD_LIBS)
++spirv2nir_SOURCES = \
++      standalone_scaffolding.cpp \
++      standalone_scaffolding.h \
++      nir/spirv2nir.c
++
++spirv2nir_LDADD =                                     \
++      libglsl.la                                      \
++      $(top_builddir)/src/libglsl_util.la             \
++      $(PTHREAD_LIBS)
++
+ glsl_test_SOURCES = \
+       standalone_scaffolding.cpp \
+       test.cpp \
+       test_optpass.cpp \
+       test_optpass.h
+ glsl_test_LDADD =                                     \
+       libglsl.la                                      \
+       $(top_builddir)/src/libglsl_util.la             \
+       $(PTHREAD_LIBS)
+ # We write our own rules for yacc and lex below. We'd rather use automake,
+ # but automake makes it especially difficult for a number of reasons:
+ #
+ #  * < automake-1.12 generates .h files from .yy and .ypp files, but
+ #    >=automake-1.12 generates .hh and .hpp files respectively. There's no
+ #    good way of making a project that uses C++ yacc files compatible with
+ #    both versions of automake. Strong work automake developers.
+ #
+ #  * Since we're generating code from .l/.y files in a subdirectory (glcpp/)
+ #    we'd like the resulting generated code to also go in glcpp/ for purposes
+ #    of distribution. Automake gives no way to do this.
+ #
+ #  * Since we're building multiple yacc parsers into one library (and via one
+ #    Makefile) we have to use per-target YFLAGS. Using per-target YFLAGS causes
+ #    automake to name the resulting generated code as <library-name>_filename.c.
+ #    Frankly, that's ugly and we don't want a libglcpp_glcpp_parser.h file.
+ # In order to make build output print "LEX" and "YACC", we reproduce the
+ # automake variables below.
+ AM_V_LEX = $(am__v_LEX_$(V))
+ am__v_LEX_ = $(am__v_LEX_$(AM_DEFAULT_VERBOSITY))
+ am__v_LEX_0 = @echo "  LEX     " $@;
+ am__v_LEX_1 =
+ AM_V_YACC = $(am__v_YACC_$(V))
+ am__v_YACC_ = $(am__v_YACC_$(AM_DEFAULT_VERBOSITY))
+ am__v_YACC_0 = @echo "  YACC    " $@;
+ am__v_YACC_1 =
+ MKDIR_GEN = $(AM_V_at)$(MKDIR_P) $(@D)
+ YACC_GEN = $(AM_V_YACC)$(YACC) $(YFLAGS)
+ LEX_GEN = $(AM_V_LEX)$(LEX) $(LFLAGS)
+ glsl_parser.cpp glsl_parser.h: glsl_parser.yy
+       $(YACC_GEN) -o $@ -p "_mesa_glsl_" --defines=$(builddir)/glsl_parser.h $(srcdir)/glsl_parser.yy
+ glsl_lexer.cpp: glsl_lexer.ll
+       $(LEX_GEN) -o $@ $(srcdir)/glsl_lexer.ll
+ glcpp/glcpp-parse.c glcpp/glcpp-parse.h: glcpp/glcpp-parse.y
+       $(MKDIR_GEN)
+       $(YACC_GEN) -o $@ -p "glcpp_parser_" --defines=$(builddir)/glcpp/glcpp-parse.h $(srcdir)/glcpp/glcpp-parse.y
+ glcpp/glcpp-lex.c: glcpp/glcpp-lex.l
+       $(MKDIR_GEN)
+       $(LEX_GEN) -o $@ $(srcdir)/glcpp/glcpp-lex.l
+ # Only the parsers (specifically the header files generated at the same time)
+ # need to be in BUILT_SOURCES. Though if we list the parser headers YACC is
+ # called for the .c/.cpp file and the .h files. By listing the .c/.cpp files
+ # YACC is only executed once for each parser. The rest of the generated code
+ # will be created at the appropriate times according to standard automake
+ # dependency rules.
+ BUILT_SOURCES =                                               \
+       glsl_parser.cpp                                 \
+       glsl_lexer.cpp                                  \
+       glcpp/glcpp-parse.c                             \
+       glcpp/glcpp-lex.c
+ CLEANFILES =                                          \
+       glcpp/glcpp-parse.h                             \
+       glsl_parser.h                                   \
+       $(BUILT_SOURCES)
+ clean-local:
+       $(RM) -r subtest-cr subtest-cr-lf subtest-lf subtest-lf-cr
+ dist-hook:
+       $(RM) glcpp/tests/*.out
+       $(RM) glcpp/tests/subtest*/*.out
index 0000000000000000000000000000000000000000,08b40c5cc8fb64006bd7dbfd9b2ca09f0065f18f..3f537d5b37acaf83549cca35132290b5dac82bf4
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,222 +1,238 @@@
+ # shared source lists for Makefile, SConscript, and Android.mk
+ # libglcpp
+ LIBGLCPP_FILES = \
+       glcpp/glcpp.h \
+       glcpp/pp.c
+ LIBGLCPP_GENERATED_FILES = \
+       glcpp/glcpp-lex.c \
+       glcpp/glcpp-parse.c
+ NIR_GENERATED_FILES = \
+       nir/nir_builder_opcodes.h \
+       nir/nir_constant_expressions.c \
+       nir/nir_opcodes.c \
+       nir/nir_opcodes.h \
+       nir/nir_opt_algebraic.c
+ NIR_FILES = \
+       nir/nir.c \
+       nir/nir.h \
+       nir/nir_array.h \
+       nir/nir_builder.h \
+       nir/nir_clone.c \
+       nir/nir_constant_expressions.h \
+       nir/nir_control_flow.c \
+       nir/nir_control_flow.h \
+       nir/nir_control_flow_private.h \
+       nir/nir_dominance.c \
+       nir/nir_from_ssa.c \
++      nir/nir_gather_info.c \
+       nir/nir_gs_count_vertices.c \
++      nir/nir_inline_functions.c \
+       nir/nir_intrinsics.c \
+       nir/nir_intrinsics.h \
+       nir/nir_instr_set.c \
+       nir/nir_instr_set.h \
+       nir/nir_liveness.c \
+       nir/nir_lower_alu_to_scalar.c \
+       nir/nir_lower_atomics.c \
+       nir/nir_lower_clip.c \
++      nir/nir_lower_returns.c \
+       nir/nir_lower_global_vars_to_local.c \
+       nir/nir_lower_gs_intrinsics.c \
++        nir/nir_lower_indirect_derefs.c \
+       nir/nir_lower_load_const_to_scalar.c \
+       nir/nir_lower_locals_to_regs.c \
+       nir/nir_lower_idiv.c \
+       nir/nir_lower_io.c \
+       nir/nir_lower_outputs_to_temporaries.c \
+       nir/nir_lower_phis_to_scalar.c \
+       nir/nir_lower_samplers.c \
+       nir/nir_lower_system_values.c \
+       nir/nir_lower_tex.c \
+       nir/nir_lower_to_source_mods.c \
+       nir/nir_lower_two_sided_color.c \
+       nir/nir_lower_vars_to_ssa.c \
+       nir/nir_lower_var_copies.c \
+       nir/nir_lower_vec_to_movs.c \
+       nir/nir_metadata.c \
+       nir/nir_move_vec_src_uses_to_dest.c \
+       nir/nir_normalize_cubemap_coords.c \
+       nir/nir_opt_constant_folding.c \
+       nir/nir_opt_copy_propagate.c \
+       nir/nir_opt_cse.c \
+       nir/nir_opt_dce.c \
+       nir/nir_opt_dead_cf.c \
+       nir/nir_opt_gcm.c \
+       nir/nir_opt_global_to_local.c \
+       nir/nir_opt_peephole_select.c \
+       nir/nir_opt_remove_phis.c \
+       nir/nir_opt_undef.c \
++      nir/nir_phi_builder.c \
++      nir/nir_phi_builder.h \
+       nir/nir_print.c \
+       nir/nir_remove_dead_variables.c \
++      nir/nir_repair_ssa.c \
+       nir/nir_search.c \
+       nir/nir_search.h \
+       nir/nir_split_var_copies.c \
+       nir/nir_sweep.c \
+       nir/nir_to_ssa.c \
+       nir/nir_validate.c \
+       nir/nir_vla.h \
+       nir/nir_worklist.c \
+       nir/nir_worklist.h
++SPIRV_FILES = \
++      nir/spirv/nir_spirv.h \
++      nir/spirv/spirv_to_nir.c \
++      nir/spirv/vtn_alu.c \
++      nir/spirv/vtn_cfg.c \
++      nir/spirv/vtn_glsl450.c \
++      nir/spirv/vtn_private.h \
++      nir/spirv/vtn_variables.c
++
+ # libglsl
+ LIBGLSL_FILES = \
+       ast.h \
+       ast_array_index.cpp \
+       ast_expr.cpp \
+       ast_function.cpp \
+       ast_to_hir.cpp \
+       ast_type.cpp \
+       blob.c \
+       blob.h \
+       builtin_functions.cpp \
+       builtin_types.cpp \
+       builtin_variables.cpp \
+       glsl_parser_extras.cpp \
+       glsl_parser_extras.h \
+       glsl_symbol_table.cpp \
+       glsl_symbol_table.h \
+       hir_field_selection.cpp \
+       ir_basic_block.cpp \
+       ir_basic_block.h \
+       ir_builder.cpp \
+       ir_builder.h \
+       ir_clone.cpp \
+       ir_constant_expression.cpp \
+       ir.cpp \
+       ir.h \
+       ir_equals.cpp \
+       ir_expression_flattening.cpp \
+       ir_expression_flattening.h \
+       ir_function_can_inline.cpp \
+       ir_function_detect_recursion.cpp \
+       ir_function_inlining.h \
+       ir_function.cpp \
+       ir_hierarchical_visitor.cpp \
+       ir_hierarchical_visitor.h \
+       ir_hv_accept.cpp \
+       ir_import_prototypes.cpp \
+       ir_optimization.h \
+       ir_print_visitor.cpp \
+       ir_print_visitor.h \
+       ir_reader.cpp \
+       ir_reader.h \
+       ir_rvalue_visitor.cpp \
+       ir_rvalue_visitor.h \
+       ir_set_program_inouts.cpp \
+       ir_uniform.h \
+       ir_validate.cpp \
+       ir_variable_refcount.cpp \
+       ir_variable_refcount.h \
+       ir_visitor.h \
+       linker.cpp \
+       linker.h \
+       link_atomics.cpp \
+       link_functions.cpp \
+       link_interface_blocks.cpp \
+       link_uniforms.cpp \
+       link_uniform_initializers.cpp \
+       link_uniform_block_active_visitor.cpp \
+       link_uniform_block_active_visitor.h \
+       link_uniform_blocks.cpp \
+       link_varyings.cpp \
+       link_varyings.h \
+       list.h \
+       loop_analysis.cpp \
+       loop_analysis.h \
+       loop_controls.cpp \
+       loop_unroll.cpp \
+       lower_buffer_access.cpp \
+       lower_buffer_access.h \
+       lower_clip_distance.cpp \
+       lower_const_arrays_to_uniforms.cpp \
+       lower_discard.cpp \
+       lower_discard_flow.cpp \
+       lower_if_to_cond_assign.cpp \
+       lower_instructions.cpp \
+       lower_jumps.cpp \
+       lower_mat_op_to_vec.cpp \
+       lower_noise.cpp \
+       lower_offset_array.cpp \
+       lower_packed_varyings.cpp \
+       lower_named_interface_blocks.cpp \
+       lower_packing_builtins.cpp \
+       lower_subroutine.cpp \
+       lower_tess_level.cpp \
+       lower_texture_projection.cpp \
+       lower_variable_index_to_cond_assign.cpp \
+       lower_vec_index_to_cond_assign.cpp \
+       lower_vec_index_to_swizzle.cpp \
+       lower_vector.cpp \
+       lower_vector_derefs.cpp \
+       lower_vector_insert.cpp \
+       lower_vertex_id.cpp \
+       lower_output_reads.cpp \
+       lower_shared_reference.cpp \
+       lower_ubo_reference.cpp \
+       opt_algebraic.cpp \
+       opt_array_splitting.cpp \
+       opt_conditional_discard.cpp \
+       opt_constant_folding.cpp \
+       opt_constant_propagation.cpp \
+       opt_constant_variable.cpp \
+       opt_copy_propagation.cpp \
+       opt_copy_propagation_elements.cpp \
+       opt_dead_builtin_variables.cpp \
+       opt_dead_builtin_varyings.cpp \
+       opt_dead_code.cpp \
+       opt_dead_code_local.cpp \
+       opt_dead_functions.cpp \
+       opt_flatten_nested_if_blocks.cpp \
+       opt_flip_matrices.cpp \
+       opt_function_inlining.cpp \
+       opt_if_simplification.cpp \
+       opt_minmax.cpp \
+       opt_noop_swizzle.cpp \
+       opt_rebalance_tree.cpp \
+       opt_redundant_jumps.cpp \
+       opt_structure_splitting.cpp \
+       opt_swizzle_swizzle.cpp \
+       opt_tree_grafting.cpp \
+       opt_vectorize.cpp \
+       program.h \
+       s_expression.cpp \
+       s_expression.h
+ # glsl to nir pass
+ GLSL_TO_NIR_FILES = \
+       nir/glsl_to_nir.cpp \
+       nir/glsl_to_nir.h
+ # glsl_compiler
+ GLSL_COMPILER_CXX_FILES = \
+       standalone_scaffolding.cpp \
+       standalone_scaffolding.h \
+       main.cpp
+ # libglsl generated sources
+ LIBGLSL_GENERATED_CXX_FILES = \
+       glsl_lexer.cpp \
+       glsl_parser.cpp
index 0000000000000000000000000000000000000000,dfd31966eb0fa19e72b7d9621aa9246a43d366b6..98d8bc5f2681dbcf2888fb478f3b2604641cb52e
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,7583 +1,7584 @@@
+ /*
+  * Copyright © 2010 Intel Corporation
+  *
+  * Permission is hereby granted, free of charge, to any person obtaining a
+  * copy of this software and associated documentation files (the "Software"),
+  * to deal in the Software without restriction, including without limitation
+  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+  * and/or sell copies of the Software, and to permit persons to whom the
+  * Software is furnished to do so, subject to the following conditions:
+  *
+  * The above copyright notice and this permission notice (including the next
+  * paragraph) shall be included in all copies or substantial portions of the
+  * Software.
+  *
+  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+  * DEALINGS IN THE SOFTWARE.
+  */
+ /**
+  * \file ast_to_hir.c
+  * Convert abstract syntax to to high-level intermediate reprensentation (HIR).
+  *
+  * During the conversion to HIR, the majority of the symantic checking is
+  * preformed on the program.  This includes:
+  *
+  *    * Symbol table management
+  *    * Type checking
+  *    * Function binding
+  *
+  * The majority of this work could be done during parsing, and the parser could
+  * probably generate HIR directly.  However, this results in frequent changes
+  * to the parser code.  Since we do not assume that every system this complier
+  * is built on will have Flex and Bison installed, we have to store the code
+  * generated by these tools in our version control system.  In other parts of
+  * the system we've seen problems where a parser was changed but the generated
+  * code was not committed, merge conflicts where created because two developers
+  * had slightly different versions of Bison installed, etc.
+  *
+  * I have also noticed that running Bison generated parsers in GDB is very
+  * irritating.  When you get a segfault on '$$ = $1->foo', you can't very
+  * well 'print $1' in GDB.
+  *
+  * As a result, my preference is to put as little C code as possible in the
+  * parser (and lexer) sources.
+  */
+ #include "glsl_symbol_table.h"
+ #include "glsl_parser_extras.h"
+ #include "ast.h"
+ #include "compiler/glsl_types.h"
+ #include "program/hash_table.h"
+ #include "main/shaderobj.h"
+ #include "ir.h"
+ #include "ir_builder.h"
+ using namespace ir_builder;
+ static void
+ detect_conflicting_assignments(struct _mesa_glsl_parse_state *state,
+                              exec_list *instructions);
+ static void
+ remove_per_vertex_blocks(exec_list *instructions,
+                          _mesa_glsl_parse_state *state, ir_variable_mode mode);
+ /**
+  * Visitor class that finds the first instance of any write-only variable that
+  * is ever read, if any
+  */
+ class read_from_write_only_variable_visitor : public ir_hierarchical_visitor
+ {
+ public:
+    read_from_write_only_variable_visitor() : found(NULL)
+    {
+    }
+    virtual ir_visitor_status visit(ir_dereference_variable *ir)
+    {
+       if (this->in_assignee)
+          return visit_continue;
+       ir_variable *var = ir->variable_referenced();
+       /* We can have image_write_only set on both images and buffer variables,
+        * but in the former there is a distinction between reads from
+        * the variable itself (write_only) and from the memory they point to
+        * (image_write_only), while in the case of buffer variables there is
+        * no such distinction, that is why this check here is limited to
+        * buffer variables alone.
+        */
+       if (!var || var->data.mode != ir_var_shader_storage)
+          return visit_continue;
+       if (var->data.image_write_only) {
+          found = var;
+          return visit_stop;
+       }
+       return visit_continue;
+    }
+    ir_variable *get_variable() {
+       return found;
+    }
+    virtual ir_visitor_status visit_enter(ir_expression *ir)
+    {
+       /* .length() doesn't actually read anything */
+       if (ir->operation == ir_unop_ssbo_unsized_array_length)
+          return visit_continue_with_parent;
+       return visit_continue;
+    }
+ private:
+    ir_variable *found;
+ };
+ void
+ _mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state)
+ {
+    _mesa_glsl_initialize_variables(instructions, state);
+    state->symbols->separate_function_namespace = state->language_version == 110;
+    state->current_function = NULL;
+    state->toplevel_ir = instructions;
+    state->gs_input_prim_type_specified = false;
+    state->tcs_output_vertices_specified = false;
+    state->cs_input_local_size_specified = false;
+    /* Section 4.2 of the GLSL 1.20 specification states:
+     * "The built-in functions are scoped in a scope outside the global scope
+     *  users declare global variables in.  That is, a shader's global scope,
+     *  available for user-defined functions and global variables, is nested
+     *  inside the scope containing the built-in functions."
+     *
+     * Since built-in functions like ftransform() access built-in variables,
+     * it follows that those must be in the outer scope as well.
+     *
+     * We push scope here to create this nesting effect...but don't pop.
+     * This way, a shader's globals are still in the symbol table for use
+     * by the linker.
+     */
+    state->symbols->push_scope();
+    foreach_list_typed (ast_node, ast, link, & state->translation_unit)
+       ast->hir(instructions, state);
+    detect_recursion_unlinked(state, instructions);
+    detect_conflicting_assignments(state, instructions);
+    state->toplevel_ir = NULL;
+    /* Move all of the variable declarations to the front of the IR list, and
+     * reverse the order.  This has the (intended!) side effect that vertex
+     * shader inputs and fragment shader outputs will appear in the IR in the
+     * same order that they appeared in the shader code.  This results in the
+     * locations being assigned in the declared order.  Many (arguably buggy)
+     * applications depend on this behavior, and it matches what nearly all
+     * other drivers do.
+     */
+    foreach_in_list_safe(ir_instruction, node, instructions) {
+       ir_variable *const var = node->as_variable();
+       if (var == NULL)
+          continue;
+       var->remove();
+       instructions->push_head(var);
+    }
+    /* Figure out if gl_FragCoord is actually used in fragment shader */
+    ir_variable *const var = state->symbols->get_variable("gl_FragCoord");
+    if (var != NULL)
+       state->fs_uses_gl_fragcoord = var->data.used;
+    /* From section 7.1 (Built-In Language Variables) of the GLSL 4.10 spec:
+     *
+     *     If multiple shaders using members of a built-in block belonging to
+     *     the same interface are linked together in the same program, they
+     *     must all redeclare the built-in block in the same way, as described
+     *     in section 4.3.7 "Interface Blocks" for interface block matching, or
+     *     a link error will result.
+     *
+     * The phrase "using members of a built-in block" implies that if two
+     * shaders are linked together and one of them *does not use* any members
+     * of the built-in block, then that shader does not need to have a matching
+     * redeclaration of the built-in block.
+     *
+     * This appears to be a clarification to the behaviour established for
+     * gl_PerVertex by GLSL 1.50, therefore implement it regardless of GLSL
+     * version.
+     *
+     * The definition of "interface" in section 4.3.7 that applies here is as
+     * follows:
+     *
+     *     The boundary between adjacent programmable pipeline stages: This
+     *     spans all the outputs in all compilation units of the first stage
+     *     and all the inputs in all compilation units of the second stage.
+     *
+     * Therefore this rule applies to both inter- and intra-stage linking.
+     *
+     * The easiest way to implement this is to check whether the shader uses
+     * gl_PerVertex right after ast-to-ir conversion, and if it doesn't, simply
+     * remove all the relevant variable declaration from the IR, so that the
+     * linker won't see them and complain about mismatches.
+     */
+    remove_per_vertex_blocks(instructions, state, ir_var_shader_in);
+    remove_per_vertex_blocks(instructions, state, ir_var_shader_out);
+    /* Check that we don't have reads from write-only variables */
+    read_from_write_only_variable_visitor v;
+    v.run(instructions);
+    ir_variable *error_var = v.get_variable();
+    if (error_var) {
+       /* It would be nice to have proper location information, but for that
+        * we would need to check this as we process each kind of AST node
+        */
+       YYLTYPE loc;
+       memset(&loc, 0, sizeof(loc));
+       _mesa_glsl_error(&loc, state, "Read from write-only variable `%s'",
+                        error_var->name);
+    }
+ }
+ static ir_expression_operation
+ get_conversion_operation(const glsl_type *to, const glsl_type *from,
+                          struct _mesa_glsl_parse_state *state)
+ {
+    switch (to->base_type) {
+    case GLSL_TYPE_FLOAT:
+       switch (from->base_type) {
+       case GLSL_TYPE_INT: return ir_unop_i2f;
+       case GLSL_TYPE_UINT: return ir_unop_u2f;
+       case GLSL_TYPE_DOUBLE: return ir_unop_d2f;
+       default: return (ir_expression_operation)0;
+       }
+    case GLSL_TYPE_UINT:
+       if (!state->is_version(400, 0) && !state->ARB_gpu_shader5_enable)
+          return (ir_expression_operation)0;
+       switch (from->base_type) {
+          case GLSL_TYPE_INT: return ir_unop_i2u;
+          default: return (ir_expression_operation)0;
+       }
+    case GLSL_TYPE_DOUBLE:
+       if (!state->has_double())
+          return (ir_expression_operation)0;
+       switch (from->base_type) {
+       case GLSL_TYPE_INT: return ir_unop_i2d;
+       case GLSL_TYPE_UINT: return ir_unop_u2d;
+       case GLSL_TYPE_FLOAT: return ir_unop_f2d;
+       default: return (ir_expression_operation)0;
+       }
+    default: return (ir_expression_operation)0;
+    }
+ }
+ /**
+  * If a conversion is available, convert one operand to a different type
+  *
+  * The \c from \c ir_rvalue is converted "in place".
+  *
+  * \param to     Type that the operand it to be converted to
+  * \param from   Operand that is being converted
+  * \param state  GLSL compiler state
+  *
+  * \return
+  * If a conversion is possible (or unnecessary), \c true is returned.
+  * Otherwise \c false is returned.
+  */
+ bool
+ apply_implicit_conversion(const glsl_type *to, ir_rvalue * &from,
+                           struct _mesa_glsl_parse_state *state)
+ {
+    void *ctx = state;
+    if (to->base_type == from->type->base_type)
+       return true;
+    /* Prior to GLSL 1.20, there are no implicit conversions */
+    if (!state->is_version(120, 0))
+       return false;
+    /* From page 27 (page 33 of the PDF) of the GLSL 1.50 spec:
+     *
+     *    "There are no implicit array or structure conversions. For
+     *    example, an array of int cannot be implicitly converted to an
+     *    array of float.
+     */
+    if (!to->is_numeric() || !from->type->is_numeric())
+       return false;
+    /* We don't actually want the specific type `to`, we want a type
+     * with the same base type as `to`, but the same vector width as
+     * `from`.
+     */
+    to = glsl_type::get_instance(to->base_type, from->type->vector_elements,
+                                 from->type->matrix_columns);
+    ir_expression_operation op = get_conversion_operation(to, from->type, state);
+    if (op) {
+       from = new(ctx) ir_expression(op, to, from, NULL);
+       return true;
+    } else {
+       return false;
+    }
+ }
+ static const struct glsl_type *
+ arithmetic_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b,
+                        bool multiply,
+                        struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
+ {
+    const glsl_type *type_a = value_a->type;
+    const glsl_type *type_b = value_b->type;
+    /* From GLSL 1.50 spec, page 56:
+     *
+     *    "The arithmetic binary operators add (+), subtract (-),
+     *    multiply (*), and divide (/) operate on integer and
+     *    floating-point scalars, vectors, and matrices."
+     */
+    if (!type_a->is_numeric() || !type_b->is_numeric()) {
+       _mesa_glsl_error(loc, state,
+                        "operands to arithmetic operators must be numeric");
+       return glsl_type::error_type;
+    }
+    /*    "If one operand is floating-point based and the other is
+     *    not, then the conversions from Section 4.1.10 "Implicit
+     *    Conversions" are applied to the non-floating-point-based operand."
+     */
+    if (!apply_implicit_conversion(type_a, value_b, state)
+        && !apply_implicit_conversion(type_b, value_a, state)) {
+       _mesa_glsl_error(loc, state,
+                        "could not implicitly convert operands to "
+                        "arithmetic operator");
+       return glsl_type::error_type;
+    }
+    type_a = value_a->type;
+    type_b = value_b->type;
+    /*    "If the operands are integer types, they must both be signed or
+     *    both be unsigned."
+     *
+     * From this rule and the preceeding conversion it can be inferred that
+     * both types must be GLSL_TYPE_FLOAT, or GLSL_TYPE_UINT, or GLSL_TYPE_INT.
+     * The is_numeric check above already filtered out the case where either
+     * type is not one of these, so now the base types need only be tested for
+     * equality.
+     */
+    if (type_a->base_type != type_b->base_type) {
+       _mesa_glsl_error(loc, state,
+                        "base type mismatch for arithmetic operator");
+       return glsl_type::error_type;
+    }
+    /*    "All arithmetic binary operators result in the same fundamental type
+     *    (signed integer, unsigned integer, or floating-point) as the
+     *    operands they operate on, after operand type conversion. After
+     *    conversion, the following cases are valid
+     *
+     *    * The two operands are scalars. In this case the operation is
+     *      applied, resulting in a scalar."
+     */
+    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.
+     *      In this case, the scalar operation is applied independently to each
+     *      component of the vector or matrix, resulting in the same size
+     *      vector or matrix."
+     */
+    if (type_a->is_scalar()) {
+       if (!type_b->is_scalar())
+          return type_b;
+    } else if (type_b->is_scalar()) {
+       return type_a;
+    }
+    /* All of the combinations of <scalar, scalar>, <vector, scalar>,
+     * <scalar, vector>, <scalar, matrix>, and <matrix, scalar> have been
+     * handled.
+     */
+    assert(!type_a->is_scalar());
+    assert(!type_b->is_scalar());
+    /*   "* The two operands are vectors of the same size. In this case, the
+     *      operation is done component-wise resulting in the same size
+     *      vector."
+     */
+    if (type_a->is_vector() && type_b->is_vector()) {
+       if (type_a == type_b) {
+          return type_a;
+       } else {
+          _mesa_glsl_error(loc, state,
+                           "vector size mismatch for arithmetic operator");
+          return glsl_type::error_type;
+       }
+    }
+    /* All of the combinations of <scalar, scalar>, <vector, scalar>,
+     * <scalar, vector>, <scalar, matrix>, <matrix, scalar>, and
+     * <vector, vector> have been handled.  At least one of the operands must
+     * be matrix.  Further, since there are no integer matrix types, the base
+     * type of both operands must be float.
+     */
+    assert(type_a->is_matrix() || type_b->is_matrix());
+    assert(type_a->base_type == GLSL_TYPE_FLOAT ||
+           type_a->base_type == GLSL_TYPE_DOUBLE);
+    assert(type_b->base_type == GLSL_TYPE_FLOAT ||
+           type_b->base_type == GLSL_TYPE_DOUBLE);
+    /*   "* The operator is add (+), subtract (-), or divide (/), and the
+     *      operands are matrices with the same number of rows and the same
+     *      number of columns. In this case, the operation is done component-
+     *      wise resulting in the same size matrix."
+     *    * The operator is multiply (*), where both operands are matrices or
+     *      one operand is a vector and the other a matrix. A right vector
+     *      operand is treated as a column vector and a left vector operand as a
+     *      row vector. In all these cases, it is required that the number of
+     *      columns of the left operand is equal to the number of rows of the
+     *      right operand. Then, the multiply (*) operation does a linear
+     *      algebraic multiply, yielding an object that has the same number of
+     *      rows as the left operand and the same number of columns as the right
+     *      operand. Section 5.10 "Vector and Matrix Operations" explains in
+     *      more detail how vectors and matrices are operated on."
+     */
+    if (! multiply) {
+       if (type_a == type_b)
+          return type_a;
+    } else {
+       const glsl_type *type = glsl_type::get_mul_type(type_a, type_b);
+       if (type == glsl_type::error_type) {
+          _mesa_glsl_error(loc, state,
+                           "size mismatch for matrix multiplication");
+       }
+       return type;
+    }
+    /*    "All other cases are illegal."
+     */
+    _mesa_glsl_error(loc, state, "type mismatch");
+    return glsl_type::error_type;
+ }
+ static const struct glsl_type *
+ unary_arithmetic_result_type(const struct glsl_type *type,
+                              struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
+ {
+    /* From GLSL 1.50 spec, page 57:
+     *
+     *    "The arithmetic unary operators negate (-), post- and pre-increment
+     *     and decrement (-- and ++) operate on integer or floating-point
+     *     values (including vectors and matrices). All unary operators work
+     *     component-wise on their operands. These result with the same type
+     *     they operated on."
+     */
+    if (!type->is_numeric()) {
+       _mesa_glsl_error(loc, state,
+                        "operands to arithmetic operators must be numeric");
+       return glsl_type::error_type;
+    }
+    return type;
+ }
+ /**
+  * \brief Return the result type of a bit-logic operation.
+  *
+  * If the given types to the bit-logic operator are invalid, return
+  * glsl_type::error_type.
+  *
+  * \param value_a LHS of bit-logic op
+  * \param value_b RHS of bit-logic op
+  */
+ static const struct glsl_type *
+ bit_logic_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b,
+                       ast_operators op,
+                       struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
+ {
+    const glsl_type *type_a = value_a->type;
+    const glsl_type *type_b = value_b->type;
+    if (!state->check_bitwise_operations_allowed(loc)) {
+       return glsl_type::error_type;
+    }
+    /* From page 50 (page 56 of PDF) of GLSL 1.30 spec:
+     *
+     *     "The bitwise operators and (&), exclusive-or (^), and inclusive-or
+     *     (|). The operands must be of type signed or unsigned integers or
+     *     integer vectors."
+     */
+    if (!type_a->is_integer()) {
+       _mesa_glsl_error(loc, state, "LHS of `%s' must be an integer",
+                         ast_expression::operator_string(op));
+       return glsl_type::error_type;
+    }
+    if (!type_b->is_integer()) {
+       _mesa_glsl_error(loc, state, "RHS of `%s' must be an integer",
+                        ast_expression::operator_string(op));
+       return glsl_type::error_type;
+    }
+    /* Prior to GLSL 4.0 / GL_ARB_gpu_shader5, implicit conversions didn't
+     * make sense for bitwise operations, as they don't operate on floats.
+     *
+     * GLSL 4.0 added implicit int -> uint conversions, which are relevant
+     * here.  It wasn't clear whether or not we should apply them to bitwise
+     * operations.  However, Khronos has decided that they should in future
+     * language revisions.  Applications also rely on this behavior.  We opt
+     * to apply them in general, but issue a portability warning.
+     *
+     * See https://www.khronos.org/bugzilla/show_bug.cgi?id=1405
+     */
+    if (type_a->base_type != type_b->base_type) {
+       if (!apply_implicit_conversion(type_a, value_b, state)
+           && !apply_implicit_conversion(type_b, value_a, state)) {
+          _mesa_glsl_error(loc, state,
+                           "could not implicitly convert operands to "
+                           "`%s` operator",
+                           ast_expression::operator_string(op));
+          return glsl_type::error_type;
+       } else {
+          _mesa_glsl_warning(loc, state,
+                             "some implementations may not support implicit "
+                             "int -> uint conversions for `%s' operators; "
+                             "consider casting explicitly for portability",
+                             ast_expression::operator_string(op));
+       }
+       type_a = value_a->type;
+       type_b = value_b->type;
+    }
+    /*     "The fundamental types of the operands (signed or unsigned) must
+     *     match,"
+     */
+    if (type_a->base_type != type_b->base_type) {
+       _mesa_glsl_error(loc, state, "operands of `%s' must have the same "
+                        "base type", ast_expression::operator_string(op));
+       return glsl_type::error_type;
+    }
+    /*     "The operands cannot be vectors of differing size." */
+    if (type_a->is_vector() &&
+        type_b->is_vector() &&
+        type_a->vector_elements != type_b->vector_elements) {
+       _mesa_glsl_error(loc, state, "operands of `%s' cannot be vectors of "
+                        "different sizes", ast_expression::operator_string(op));
+       return glsl_type::error_type;
+    }
+    /*     "If one operand is a scalar and the other a vector, the scalar is
+     *     applied component-wise to the vector, resulting in the same type as
+     *     the vector. The fundamental types of the operands [...] will be the
+     *     resulting fundamental type."
+     */
+    if (type_a->is_scalar())
+        return type_b;
+    else
+        return type_a;
+ }
+ static const struct glsl_type *
+ modulus_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b,
+                     struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
+ {
+    const glsl_type *type_a = value_a->type;
+    const glsl_type *type_b = value_b->type;
+    if (!state->check_version(130, 300, loc, "operator '%%' is reserved")) {
+       return glsl_type::error_type;
+    }
+    /* Section 5.9 (Expressions) of the GLSL 4.00 specification says:
+     *
+     *    "The operator modulus (%) operates on signed or unsigned integers or
+     *    integer vectors."
+     */
+    if (!type_a->is_integer()) {
+       _mesa_glsl_error(loc, state, "LHS of operator %% must be an integer");
+       return glsl_type::error_type;
+    }
+    if (!type_b->is_integer()) {
+       _mesa_glsl_error(loc, state, "RHS of operator %% must be an integer");
+       return glsl_type::error_type;
+    }
+    /*    "If the fundamental types in the operands do not match, then the
+     *    conversions from section 4.1.10 "Implicit Conversions" are applied
+     *    to create matching types."
+     *
+     * Note that GLSL 4.00 (and GL_ARB_gpu_shader5) introduced implicit
+     * int -> uint conversion rules.  Prior to that, there were no implicit
+     * conversions.  So it's harmless to apply them universally - no implicit
+     * conversions will exist.  If the types don't match, we'll receive false,
+     * and raise an error, satisfying the GLSL 1.50 spec, page 56:
+     *
+     *    "The operand types must both be signed or unsigned."
+     */
+    if (!apply_implicit_conversion(type_a, value_b, state) &&
+        !apply_implicit_conversion(type_b, value_a, state)) {
+       _mesa_glsl_error(loc, state,
+                        "could not implicitly convert operands to "
+                        "modulus (%%) operator");
+       return glsl_type::error_type;
+    }
+    type_a = value_a->type;
+    type_b = value_b->type;
+    /*    "The operands cannot be vectors of differing size. If one operand is
+     *    a scalar and the other vector, then the scalar is applied component-
+     *    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 (type_a->is_vector()) {
+       if (!type_b->is_vector()
+           || (type_a->vector_elements == type_b->vector_elements))
+       return type_a;
+    } else
+       return type_b;
+    /*    "The operator modulus (%) is not defined for any other data types
+     *    (non-integer types)."
+     */
+    _mesa_glsl_error(loc, state, "type mismatch");
+    return glsl_type::error_type;
+ }
+ static const struct glsl_type *
+ relational_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b,
+                        struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
+ {
+    const glsl_type *type_a = value_a->type;
+    const glsl_type *type_b = value_b->type;
+    /* From GLSL 1.50 spec, page 56:
+     *    "The relational operators greater than (>), less than (<), greater
+     *    than or equal (>=), and less than or equal (<=) operate only on
+     *    scalar integer and scalar floating-point expressions."
+     */
+    if (!type_a->is_numeric()
+        || !type_b->is_numeric()
+        || !type_a->is_scalar()
+        || !type_b->is_scalar()) {
+       _mesa_glsl_error(loc, state,
+                        "operands to relational operators must be scalar and "
+                        "numeric");
+       return glsl_type::error_type;
+    }
+    /*    "Either the operands' types must match, or the conversions from
+     *    Section 4.1.10 "Implicit Conversions" will be applied to the integer
+     *    operand, after which the types must match."
+     */
+    if (!apply_implicit_conversion(type_a, value_b, state)
+        && !apply_implicit_conversion(type_b, value_a, state)) {
+       _mesa_glsl_error(loc, state,
+                        "could not implicitly convert operands to "
+                        "relational operator");
+       return glsl_type::error_type;
+    }
+    type_a = value_a->type;
+    type_b = value_b->type;
+    if (type_a->base_type != type_b->base_type) {
+       _mesa_glsl_error(loc, state, "base type mismatch");
+       return glsl_type::error_type;
+    }
+    /*    "The result is scalar Boolean."
+     */
+    return glsl_type::bool_type;
+ }
+ /**
+  * \brief Return the result type of a bit-shift operation.
+  *
+  * If the given types to the bit-shift operator are invalid, return
+  * glsl_type::error_type.
+  *
+  * \param type_a Type of LHS of bit-shift op
+  * \param type_b Type of RHS of bit-shift op
+  */
+ static const struct glsl_type *
+ shift_result_type(const struct glsl_type *type_a,
+                   const struct glsl_type *type_b,
+                   ast_operators op,
+                   struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
+ {
+    if (!state->check_bitwise_operations_allowed(loc)) {
+       return glsl_type::error_type;
+    }
+    /* From page 50 (page 56 of the PDF) of the GLSL 1.30 spec:
+     *
+     *     "The shift operators (<<) and (>>). For both operators, the operands
+     *     must be signed or unsigned integers or integer vectors. One operand
+     *     can be signed while the other is unsigned."
+     */
+    if (!type_a->is_integer()) {
+       _mesa_glsl_error(loc, state, "LHS of operator %s must be an integer or "
+                        "integer vector", ast_expression::operator_string(op));
+      return glsl_type::error_type;
+    }
+    if (!type_b->is_integer()) {
+       _mesa_glsl_error(loc, state, "RHS of operator %s must be an integer or "
+                        "integer vector", ast_expression::operator_string(op));
+      return glsl_type::error_type;
+    }
+    /*     "If the first operand is a scalar, the second operand has to be
+     *     a scalar as well."
+     */
+    if (type_a->is_scalar() && !type_b->is_scalar()) {
+       _mesa_glsl_error(loc, state, "if the first operand of %s is scalar, the "
+                        "second must be scalar as well",
+                        ast_expression::operator_string(op));
+      return glsl_type::error_type;
+    }
+    /* If both operands are vectors, check that they have same number of
+     * elements.
+     */
+    if (type_a->is_vector() &&
+       type_b->is_vector() &&
+       type_a->vector_elements != type_b->vector_elements) {
+       _mesa_glsl_error(loc, state, "vector operands to operator %s must "
+                        "have same number of elements",
+                        ast_expression::operator_string(op));
+      return glsl_type::error_type;
+    }
+    /*     "In all cases, the resulting type will be the same type as the left
+     *     operand."
+     */
+    return type_a;
+ }
+ /**
+  * Returns the innermost array index expression in an rvalue tree.
+  * This is the largest indexing level -- if an array of blocks, then
+  * it is the block index rather than an indexing expression for an
+  * array-typed member of an array of blocks.
+  */
+ static ir_rvalue *
+ find_innermost_array_index(ir_rvalue *rv)
+ {
+    ir_dereference_array *last = NULL;
+    while (rv) {
+       if (rv->as_dereference_array()) {
+          last = rv->as_dereference_array();
+          rv = last->array;
+       } else if (rv->as_dereference_record())
+          rv = rv->as_dereference_record()->record;
+       else if (rv->as_swizzle())
+          rv = rv->as_swizzle()->val;
+       else
+          rv = NULL;
+    }
+    if (last)
+       return last->array_index;
+    return NULL;
+ }
+ /**
+  * Validates that a value can be assigned to a location with a specified type
+  *
+  * Validates that \c rhs can be assigned to some location.  If the types are
+  * not an exact match but an automatic conversion is possible, \c rhs will be
+  * converted.
+  *
+  * \return
+  * \c NULL if \c rhs cannot be assigned to a location with type \c lhs_type.
+  * Otherwise the actual RHS to be assigned will be returned.  This may be
+  * \c rhs, or it may be \c rhs after some type conversion.
+  *
+  * \note
+  * In addition to being used for assignments, this function is used to
+  * type-check return values.
+  */
+ static ir_rvalue *
+ validate_assignment(struct _mesa_glsl_parse_state *state,
+                     YYLTYPE loc, ir_rvalue *lhs,
+                     ir_rvalue *rhs, bool is_initializer)
+ {
+    /* If there is already some error in the RHS, just return it.  Anything
+     * else will lead to an avalanche of error message back to the user.
+     */
+    if (rhs->type->is_error())
+       return rhs;
+    /* In the Tessellation Control Shader:
+     * If a per-vertex output variable is used as an l-value, it is an error
+     * if the expression indicating the vertex number is not the identifier
+     * `gl_InvocationID`.
+     */
+    if (state->stage == MESA_SHADER_TESS_CTRL) {
+       ir_variable *var = lhs->variable_referenced();
+       if (var->data.mode == ir_var_shader_out && !var->data.patch) {
+          ir_rvalue *index = find_innermost_array_index(lhs);
+          ir_variable *index_var = index ? index->variable_referenced() : NULL;
+          if (!index_var || strcmp(index_var->name, "gl_InvocationID") != 0) {
+             _mesa_glsl_error(&loc, state,
+                              "Tessellation control shader outputs can only "
+                              "be indexed by gl_InvocationID");
+             return NULL;
+          }
+       }
+    }
+    /* If the types are identical, the assignment can trivially proceed.
+     */
+    if (rhs->type == lhs->type)
+       return rhs;
+    /* If the array element types are the same and the LHS is unsized,
+     * the assignment is okay for initializers embedded in variable
+     * declarations.
+     *
+     * Note: Whole-array assignments are not permitted in GLSL 1.10, but this
+     * is handled by ir_dereference::is_lvalue.
+     */
+    const glsl_type *lhs_t = lhs->type;
+    const glsl_type *rhs_t = rhs->type;
+    bool unsized_array = false;
+    while(lhs_t->is_array()) {
+       if (rhs_t == lhs_t)
+          break; /* the rest of the inner arrays match so break out early */
+       if (!rhs_t->is_array()) {
+          unsized_array = false;
+          break; /* number of dimensions mismatch */
+       }
+       if (lhs_t->length == rhs_t->length) {
+          lhs_t = lhs_t->fields.array;
+          rhs_t = rhs_t->fields.array;
+          continue;
+       } else if (lhs_t->is_unsized_array()) {
+          unsized_array = true;
+       } else {
+          unsized_array = false;
+          break; /* sized array mismatch */
+       }
+       lhs_t = lhs_t->fields.array;
+       rhs_t = rhs_t->fields.array;
+    }
+    if (unsized_array) {
+       if (is_initializer) {
+          return rhs;
+       } else {
+          _mesa_glsl_error(&loc, state,
+                           "implicitly sized arrays cannot be assigned");
+          return NULL;
+       }
+    }
+    /* Check for implicit conversion in GLSL 1.20 */
+    if (apply_implicit_conversion(lhs->type, rhs, state)) {
+       if (rhs->type == lhs->type)
+        return rhs;
+    }
+    _mesa_glsl_error(&loc, state,
+                     "%s of type %s cannot be assigned to "
+                     "variable of type %s",
+                     is_initializer ? "initializer" : "value",
+                     rhs->type->name, lhs->type->name);
+    return NULL;
+ }
+ static void
+ mark_whole_array_access(ir_rvalue *access)
+ {
+    ir_dereference_variable *deref = access->as_dereference_variable();
+    if (deref && deref->var) {
+       deref->var->data.max_array_access = deref->type->length - 1;
+    }
+ }
+ static bool
+ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state,
+               const char *non_lvalue_description,
+               ir_rvalue *lhs, ir_rvalue *rhs,
+               ir_rvalue **out_rvalue, bool needs_rvalue,
+               bool is_initializer,
+               YYLTYPE lhs_loc)
+ {
+    void *ctx = state;
+    bool error_emitted = (lhs->type->is_error() || rhs->type->is_error());
+    ir_variable *lhs_var = lhs->variable_referenced();
+    if (lhs_var)
+       lhs_var->data.assigned = true;
+    if (!error_emitted) {
+       if (non_lvalue_description != NULL) {
+          _mesa_glsl_error(&lhs_loc, state,
+                           "assignment to %s",
+                           non_lvalue_description);
+          error_emitted = true;
+       } else if (lhs_var != NULL && (lhs_var->data.read_only ||
+                  (lhs_var->data.mode == ir_var_shader_storage &&
+                   lhs_var->data.image_read_only))) {
+          /* We can have image_read_only set on both images and buffer variables,
+           * but in the former there is a distinction between assignments to
+           * the variable itself (read_only) and to the memory they point to
+           * (image_read_only), while in the case of buffer variables there is
+           * no such distinction, that is why this check here is limited to
+           * buffer variables alone.
+           */
+          _mesa_glsl_error(&lhs_loc, state,
+                           "assignment to read-only variable '%s'",
+                           lhs_var->name);
+          error_emitted = true;
+       } else if (lhs->type->is_array() &&
+                  !state->check_version(120, 300, &lhs_loc,
+                                        "whole array assignment forbidden")) {
+          /* From page 32 (page 38 of the PDF) of the GLSL 1.10 spec:
+           *
+           *    "Other binary or unary expressions, non-dereferenced
+           *     arrays, function names, swizzles with repeated fields,
+           *     and constants cannot be l-values."
+           *
+           * The restriction on arrays is lifted in GLSL 1.20 and GLSL ES 3.00.
+           */
+          error_emitted = true;
+       } else if (!lhs->is_lvalue()) {
+          _mesa_glsl_error(& lhs_loc, state, "non-lvalue in assignment");
+          error_emitted = true;
+       }
+    }
+    ir_rvalue *new_rhs =
+       validate_assignment(state, lhs_loc, lhs, rhs, is_initializer);
+    if (new_rhs != NULL) {
+       rhs = new_rhs;
+       /* If the LHS array was not declared with a size, it takes it size from
+        * the RHS.  If the LHS is an l-value and a whole array, it must be a
+        * dereference of a variable.  Any other case would require that the LHS
+        * is either not an l-value or not a whole array.
+        */
+       if (lhs->type->is_unsized_array()) {
+          ir_dereference *const d = lhs->as_dereference();
+          assert(d != NULL);
+          ir_variable *const var = d->variable_referenced();
+          assert(var != NULL);
+          if (var->data.max_array_access >= unsigned(rhs->type->array_size())) {
+             /* FINISHME: This should actually log the location of the RHS. */
+             _mesa_glsl_error(& lhs_loc, state, "array size must be > %u due to "
+                              "previous access",
+                              var->data.max_array_access);
+          }
+          var->type = glsl_type::get_array_instance(lhs->type->fields.array,
+                                                    rhs->type->array_size());
+          d->type = var->type;
+       }
+       if (lhs->type->is_array()) {
+          mark_whole_array_access(rhs);
+          mark_whole_array_access(lhs);
+       }
+    }
+    /* Most callers of do_assignment (assign, add_assign, pre_inc/dec,
+     * but not post_inc) need the converted assigned value as an rvalue
+     * to handle things like:
+     *
+     * i = j += 1;
+     */
+    if (needs_rvalue) {
+       ir_variable *var = new(ctx) ir_variable(rhs->type, "assignment_tmp",
+                                               ir_var_temporary);
+       instructions->push_tail(var);
+       instructions->push_tail(assign(var, rhs));
+       if (!error_emitted) {
+          ir_dereference_variable *deref_var = new(ctx) ir_dereference_variable(var);
+          instructions->push_tail(new(ctx) ir_assignment(lhs, deref_var));
+       }
+       ir_rvalue *rvalue = new(ctx) ir_dereference_variable(var);
+       *out_rvalue = rvalue;
+    } else {
+       if (!error_emitted)
+          instructions->push_tail(new(ctx) ir_assignment(lhs, rhs));
+       *out_rvalue = NULL;
+    }
+    return error_emitted;
+ }
+ static ir_rvalue *
+ get_lvalue_copy(exec_list *instructions, ir_rvalue *lvalue)
+ {
+    void *ctx = ralloc_parent(lvalue);
+    ir_variable *var;
+    var = new(ctx) ir_variable(lvalue->type, "_post_incdec_tmp",
+                             ir_var_temporary);
+    instructions->push_tail(var);
+    instructions->push_tail(new(ctx) ir_assignment(new(ctx) ir_dereference_variable(var),
+                                                 lvalue));
+    return new(ctx) ir_dereference_variable(var);
+ }
+ ir_rvalue *
+ ast_node::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state)
+ {
+    (void) instructions;
+    (void) state;
+    return NULL;
+ }
+ bool
+ ast_node::has_sequence_subexpression() const
+ {
+    return false;
+ }
+ void
+ ast_function_expression::hir_no_rvalue(exec_list *instructions,
+                                        struct _mesa_glsl_parse_state *state)
+ {
+    (void)hir(instructions, state);
+ }
+ void
+ ast_aggregate_initializer::hir_no_rvalue(exec_list *instructions,
+                                          struct _mesa_glsl_parse_state *state)
+ {
+    (void)hir(instructions, state);
+ }
+ static ir_rvalue *
+ do_comparison(void *mem_ctx, int operation, ir_rvalue *op0, ir_rvalue *op1)
+ {
+    int join_op;
+    ir_rvalue *cmp = NULL;
+    if (operation == ir_binop_all_equal)
+       join_op = ir_binop_logic_and;
+    else
+       join_op = ir_binop_logic_or;
+    switch (op0->type->base_type) {
+    case GLSL_TYPE_FLOAT:
+    case GLSL_TYPE_UINT:
+    case GLSL_TYPE_INT:
+    case GLSL_TYPE_BOOL:
+    case GLSL_TYPE_DOUBLE:
+       return new(mem_ctx) ir_expression(operation, op0, op1);
+    case GLSL_TYPE_ARRAY: {
+       for (unsigned int i = 0; i < op0->type->length; i++) {
+          ir_rvalue *e0, *e1, *result;
+          e0 = new(mem_ctx) ir_dereference_array(op0->clone(mem_ctx, NULL),
+                                                 new(mem_ctx) ir_constant(i));
+          e1 = new(mem_ctx) ir_dereference_array(op1->clone(mem_ctx, NULL),
+                                                 new(mem_ctx) ir_constant(i));
+          result = do_comparison(mem_ctx, operation, e0, e1);
+          if (cmp) {
+             cmp = new(mem_ctx) ir_expression(join_op, cmp, result);
+          } else {
+             cmp = result;
+          }
+       }
+       mark_whole_array_access(op0);
+       mark_whole_array_access(op1);
+       break;
+    }
+    case GLSL_TYPE_STRUCT: {
+       for (unsigned int i = 0; i < op0->type->length; i++) {
+          ir_rvalue *e0, *e1, *result;
+          const char *field_name = op0->type->fields.structure[i].name;
+          e0 = new(mem_ctx) ir_dereference_record(op0->clone(mem_ctx, NULL),
+                                                  field_name);
+          e1 = new(mem_ctx) ir_dereference_record(op1->clone(mem_ctx, NULL),
+                                                  field_name);
+          result = do_comparison(mem_ctx, operation, e0, e1);
+          if (cmp) {
+             cmp = new(mem_ctx) ir_expression(join_op, cmp, result);
+          } else {
+             cmp = result;
+          }
+       }
+       break;
+    }
+    case GLSL_TYPE_ERROR:
+    case GLSL_TYPE_VOID:
+    case GLSL_TYPE_SAMPLER:
+    case GLSL_TYPE_IMAGE:
+    case GLSL_TYPE_INTERFACE:
++   case GLSL_TYPE_FUNCTION:
+    case GLSL_TYPE_ATOMIC_UINT:
+    case GLSL_TYPE_SUBROUTINE:
+       /* I assume a comparison of a struct containing a sampler just
+        * ignores the sampler present in the type.
+        */
+       break;
+    }
+    if (cmp == NULL)
+       cmp = new(mem_ctx) ir_constant(true);
+    return cmp;
+ }
+ /* For logical operations, we want to ensure that the operands are
+  * scalar booleans.  If it isn't, emit an error and return a constant
+  * boolean to avoid triggering cascading error messages.
+  */
+ ir_rvalue *
+ get_scalar_boolean_operand(exec_list *instructions,
+                          struct _mesa_glsl_parse_state *state,
+                          ast_expression *parent_expr,
+                          int operand,
+                          const char *operand_name,
+                          bool *error_emitted)
+ {
+    ast_expression *expr = parent_expr->subexpressions[operand];
+    void *ctx = state;
+    ir_rvalue *val = expr->hir(instructions, state);
+    if (val->type->is_boolean() && val->type->is_scalar())
+       return val;
+    if (!*error_emitted) {
+       YYLTYPE loc = expr->get_location();
+       _mesa_glsl_error(&loc, state, "%s of `%s' must be scalar boolean",
+                        operand_name,
+                        parent_expr->operator_string(parent_expr->oper));
+       *error_emitted = true;
+    }
+    return new(ctx) ir_constant(true);
+ }
+ /**
+  * If name refers to a builtin array whose maximum allowed size is less than
+  * size, report an error and return true.  Otherwise return false.
+  */
+ void
+ check_builtin_array_max_size(const char *name, unsigned size,
+                              YYLTYPE loc, struct _mesa_glsl_parse_state *state)
+ {
+    if ((strcmp("gl_TexCoord", name) == 0)
+        && (size > state->Const.MaxTextureCoords)) {
+       /* From page 54 (page 60 of the PDF) of the GLSL 1.20 spec:
+        *
+        *     "The size [of gl_TexCoord] can be at most
+        *     gl_MaxTextureCoords."
+        */
+       _mesa_glsl_error(&loc, state, "`gl_TexCoord' array size cannot "
+                        "be larger than gl_MaxTextureCoords (%u)",
+                        state->Const.MaxTextureCoords);
+    } else if (strcmp("gl_ClipDistance", name) == 0
+               && size > state->Const.MaxClipPlanes) {
+       /* From section 7.1 (Vertex Shader Special Variables) of the
+        * GLSL 1.30 spec:
+        *
+        *   "The gl_ClipDistance array is predeclared as unsized and
+        *   must be sized by the shader either redeclaring it with a
+        *   size or indexing it only with integral constant
+        *   expressions. ... The size can be at most
+        *   gl_MaxClipDistances."
+        */
+       _mesa_glsl_error(&loc, state, "`gl_ClipDistance' array size cannot "
+                        "be larger than gl_MaxClipDistances (%u)",
+                        state->Const.MaxClipPlanes);
+    }
+ }
+ /**
+  * Create the constant 1, of a which is appropriate for incrementing and
+  * decrementing values of the given GLSL type.  For example, if type is vec4,
+  * this creates a constant value of 1.0 having type float.
+  *
+  * If the given type is invalid for increment and decrement operators, return
+  * a floating point 1--the error will be detected later.
+  */
+ static ir_rvalue *
+ constant_one_for_inc_dec(void *ctx, const glsl_type *type)
+ {
+    switch (type->base_type) {
+    case GLSL_TYPE_UINT:
+       return new(ctx) ir_constant((unsigned) 1);
+    case GLSL_TYPE_INT:
+       return new(ctx) ir_constant(1);
+    default:
+    case GLSL_TYPE_FLOAT:
+       return new(ctx) ir_constant(1.0f);
+    }
+ }
+ ir_rvalue *
+ ast_expression::hir(exec_list *instructions,
+                     struct _mesa_glsl_parse_state *state)
+ {
+    return do_hir(instructions, state, true);
+ }
+ void
+ ast_expression::hir_no_rvalue(exec_list *instructions,
+                               struct _mesa_glsl_parse_state *state)
+ {
+    do_hir(instructions, state, false);
+ }
+ ir_rvalue *
+ ast_expression::do_hir(exec_list *instructions,
+                        struct _mesa_glsl_parse_state *state,
+                        bool needs_rvalue)
+ {
+    void *ctx = state;
+    static const int operations[AST_NUM_OPERATORS] = {
+       -1,               /* ast_assign doesn't convert to ir_expression. */
+       -1,               /* ast_plus doesn't convert to ir_expression. */
+       ir_unop_neg,
+       ir_binop_add,
+       ir_binop_sub,
+       ir_binop_mul,
+       ir_binop_div,
+       ir_binop_mod,
+       ir_binop_lshift,
+       ir_binop_rshift,
+       ir_binop_less,
+       ir_binop_greater,
+       ir_binop_lequal,
+       ir_binop_gequal,
+       ir_binop_all_equal,
+       ir_binop_any_nequal,
+       ir_binop_bit_and,
+       ir_binop_bit_xor,
+       ir_binop_bit_or,
+       ir_unop_bit_not,
+       ir_binop_logic_and,
+       ir_binop_logic_xor,
+       ir_binop_logic_or,
+       ir_unop_logic_not,
+       /* Note: The following block of expression types actually convert
+        * to multiple IR instructions.
+        */
+       ir_binop_mul,     /* ast_mul_assign */
+       ir_binop_div,     /* ast_div_assign */
+       ir_binop_mod,     /* ast_mod_assign */
+       ir_binop_add,     /* ast_add_assign */
+       ir_binop_sub,     /* ast_sub_assign */
+       ir_binop_lshift,  /* ast_ls_assign */
+       ir_binop_rshift,  /* ast_rs_assign */
+       ir_binop_bit_and, /* ast_and_assign */
+       ir_binop_bit_xor, /* ast_xor_assign */
+       ir_binop_bit_or,  /* ast_or_assign */
+       -1,               /* ast_conditional doesn't convert to ir_expression. */
+       ir_binop_add,     /* ast_pre_inc. */
+       ir_binop_sub,     /* ast_pre_dec. */
+       ir_binop_add,     /* ast_post_inc. */
+       ir_binop_sub,     /* ast_post_dec. */
+       -1,               /* ast_field_selection doesn't conv to ir_expression. */
+       -1,               /* ast_array_index doesn't convert to ir_expression. */
+       -1,               /* ast_function_call doesn't conv to ir_expression. */
+       -1,               /* ast_identifier doesn't convert to ir_expression. */
+       -1,               /* ast_int_constant doesn't convert to ir_expression. */
+       -1,               /* ast_uint_constant doesn't conv to ir_expression. */
+       -1,               /* ast_float_constant doesn't conv to ir_expression. */
+       -1,               /* ast_bool_constant doesn't conv to ir_expression. */
+       -1,               /* ast_sequence doesn't convert to ir_expression. */
+    };
+    ir_rvalue *result = NULL;
+    ir_rvalue *op[3];
+    const struct glsl_type *type; /* a temporary variable for switch cases */
+    bool error_emitted = false;
+    YYLTYPE loc;
+    loc = this->get_location();
+    switch (this->oper) {
+    case ast_aggregate:
+       assert(!"ast_aggregate: Should never get here.");
+       break;
+    case ast_assign: {
+       op[0] = this->subexpressions[0]->hir(instructions, state);
+       op[1] = this->subexpressions[1]->hir(instructions, state);
+       error_emitted =
+          do_assignment(instructions, state,
+                        this->subexpressions[0]->non_lvalue_description,
+                        op[0], op[1], &result, needs_rvalue, false,
+                        this->subexpressions[0]->get_location());
+       break;
+    }
+    case ast_plus:
+       op[0] = this->subexpressions[0]->hir(instructions, state);
+       type = unary_arithmetic_result_type(op[0]->type, state, & loc);
+       error_emitted = type->is_error();
+       result = op[0];
+       break;
+    case ast_neg:
+       op[0] = this->subexpressions[0]->hir(instructions, state);
+       type = unary_arithmetic_result_type(op[0]->type, state, & loc);
+       error_emitted = type->is_error();
+       result = new(ctx) ir_expression(operations[this->oper], type,
+                                       op[0], NULL);
+       break;
+    case ast_add:
+    case ast_sub:
+    case ast_mul:
+    case ast_div:
+       op[0] = this->subexpressions[0]->hir(instructions, state);
+       op[1] = this->subexpressions[1]->hir(instructions, state);
+       type = arithmetic_result_type(op[0], op[1],
+                                     (this->oper == ast_mul),
+                                     state, & loc);
+       error_emitted = type->is_error();
+       result = new(ctx) ir_expression(operations[this->oper], type,
+                                       op[0], op[1]);
+       break;
+    case ast_mod:
+       op[0] = this->subexpressions[0]->hir(instructions, state);
+       op[1] = this->subexpressions[1]->hir(instructions, state);
+       type = modulus_result_type(op[0], op[1], state, &loc);
+       assert(operations[this->oper] == ir_binop_mod);
+       result = new(ctx) ir_expression(operations[this->oper], type,
+                                       op[0], op[1]);
+       error_emitted = type->is_error();
+       break;
+    case ast_lshift:
+    case ast_rshift:
+        if (!state->check_bitwise_operations_allowed(&loc)) {
+           error_emitted = true;
+        }
+        op[0] = this->subexpressions[0]->hir(instructions, state);
+        op[1] = this->subexpressions[1]->hir(instructions, state);
+        type = shift_result_type(op[0]->type, op[1]->type, this->oper, state,
+                                 &loc);
+        result = new(ctx) ir_expression(operations[this->oper], type,
+                                        op[0], op[1]);
+        error_emitted = op[0]->type->is_error() || op[1]->type->is_error();
+        break;
+    case ast_less:
+    case ast_greater:
+    case ast_lequal:
+    case ast_gequal:
+       op[0] = this->subexpressions[0]->hir(instructions, state);
+       op[1] = this->subexpressions[1]->hir(instructions, state);
+       type = relational_result_type(op[0], op[1], state, & loc);
+       /* The relational operators must either generate an error or result
+        * in a scalar boolean.  See page 57 of the GLSL 1.50 spec.
+        */
+       assert(type->is_error()
+            || ((type->base_type == GLSL_TYPE_BOOL)
+                && type->is_scalar()));
+       result = new(ctx) ir_expression(operations[this->oper], type,
+                                       op[0], op[1]);
+       error_emitted = type->is_error();
+       break;
+    case ast_nequal:
+    case ast_equal:
+       op[0] = this->subexpressions[0]->hir(instructions, state);
+       op[1] = this->subexpressions[1]->hir(instructions, state);
+       /* From page 58 (page 64 of the PDF) of the GLSL 1.50 spec:
+        *
+        *    "The equality operators equal (==), and not equal (!=)
+        *    operate on all types. They result in a scalar Boolean. If
+        *    the operand types do not match, then there must be a
+        *    conversion from Section 4.1.10 "Implicit Conversions"
+        *    applied to one operand that can make them match, in which
+        *    case this conversion is done."
+        */
+       if (op[0]->type == glsl_type::void_type || op[1]->type == glsl_type::void_type) {
+          _mesa_glsl_error(& loc, state, "`%s':  wrong operand types: "
+                          "no operation `%1$s' exists that takes a left-hand "
+                          "operand of type 'void' or a right operand of type "
+                          "'void'", (this->oper == ast_equal) ? "==" : "!=");
+          error_emitted = true;
+       } else if ((!apply_implicit_conversion(op[0]->type, op[1], state)
+            && !apply_implicit_conversion(op[1]->type, op[0], state))
+           || (op[0]->type != op[1]->type)) {
+          _mesa_glsl_error(& loc, state, "operands of `%s' must have the same "
+                           "type", (this->oper == ast_equal) ? "==" : "!=");
+          error_emitted = true;
+       } else if ((op[0]->type->is_array() || op[1]->type->is_array()) &&
+                  !state->check_version(120, 300, &loc,
+                                        "array comparisons forbidden")) {
+          error_emitted = true;
+       } else if ((op[0]->type->contains_opaque() ||
+                   op[1]->type->contains_opaque())) {
+          _mesa_glsl_error(&loc, state, "opaque type comparisons forbidden");
+          error_emitted = true;
+       }
+       if (error_emitted) {
+          result = new(ctx) ir_constant(false);
+       } else {
+          result = do_comparison(ctx, operations[this->oper], op[0], op[1]);
+          assert(result->type == glsl_type::bool_type);
+       }
+       break;
+    case ast_bit_and:
+    case ast_bit_xor:
+    case ast_bit_or:
+       op[0] = this->subexpressions[0]->hir(instructions, state);
+       op[1] = this->subexpressions[1]->hir(instructions, state);
+       type = bit_logic_result_type(op[0], op[1], this->oper, state, &loc);
+       result = new(ctx) ir_expression(operations[this->oper], type,
+                                       op[0], op[1]);
+       error_emitted = op[0]->type->is_error() || op[1]->type->is_error();
+       break;
+    case ast_bit_not:
+       op[0] = this->subexpressions[0]->hir(instructions, state);
+       if (!state->check_bitwise_operations_allowed(&loc)) {
+          error_emitted = true;
+       }
+       if (!op[0]->type->is_integer()) {
+          _mesa_glsl_error(&loc, state, "operand of `~' must be an integer");
+          error_emitted = true;
+       }
+       type = error_emitted ? glsl_type::error_type : op[0]->type;
+       result = new(ctx) ir_expression(ir_unop_bit_not, type, op[0], NULL);
+       break;
+    case ast_logic_and: {
+       exec_list rhs_instructions;
+       op[0] = get_scalar_boolean_operand(instructions, state, this, 0,
+                                          "LHS", &error_emitted);
+       op[1] = get_scalar_boolean_operand(&rhs_instructions, state, this, 1,
+                                          "RHS", &error_emitted);
+       if (rhs_instructions.is_empty()) {
+          result = new(ctx) ir_expression(ir_binop_logic_and, op[0], op[1]);
+          type = result->type;
+       } else {
+          ir_variable *const tmp = new(ctx) ir_variable(glsl_type::bool_type,
+                                                        "and_tmp",
+                                                        ir_var_temporary);
+          instructions->push_tail(tmp);
+          ir_if *const stmt = new(ctx) ir_if(op[0]);
+          instructions->push_tail(stmt);
+          stmt->then_instructions.append_list(&rhs_instructions);
+          ir_dereference *const then_deref = new(ctx) ir_dereference_variable(tmp);
+          ir_assignment *const then_assign =
+             new(ctx) ir_assignment(then_deref, op[1]);
+          stmt->then_instructions.push_tail(then_assign);
+          ir_dereference *const else_deref = new(ctx) ir_dereference_variable(tmp);
+          ir_assignment *const else_assign =
+             new(ctx) ir_assignment(else_deref, new(ctx) ir_constant(false));
+          stmt->else_instructions.push_tail(else_assign);
+          result = new(ctx) ir_dereference_variable(tmp);
+          type = tmp->type;
+       }
+       break;
+    }
+    case ast_logic_or: {
+       exec_list rhs_instructions;
+       op[0] = get_scalar_boolean_operand(instructions, state, this, 0,
+                                          "LHS", &error_emitted);
+       op[1] = get_scalar_boolean_operand(&rhs_instructions, state, this, 1,
+                                          "RHS", &error_emitted);
+       if (rhs_instructions.is_empty()) {
+          result = new(ctx) ir_expression(ir_binop_logic_or, op[0], op[1]);
+          type = result->type;
+       } else {
+          ir_variable *const tmp = new(ctx) ir_variable(glsl_type::bool_type,
+                                                        "or_tmp",
+                                                        ir_var_temporary);
+          instructions->push_tail(tmp);
+          ir_if *const stmt = new(ctx) ir_if(op[0]);
+          instructions->push_tail(stmt);
+          ir_dereference *const then_deref = new(ctx) ir_dereference_variable(tmp);
+          ir_assignment *const then_assign =
+             new(ctx) ir_assignment(then_deref, new(ctx) ir_constant(true));
+          stmt->then_instructions.push_tail(then_assign);
+          stmt->else_instructions.append_list(&rhs_instructions);
+          ir_dereference *const else_deref = new(ctx) ir_dereference_variable(tmp);
+          ir_assignment *const else_assign =
+             new(ctx) ir_assignment(else_deref, op[1]);
+          stmt->else_instructions.push_tail(else_assign);
+          result = new(ctx) ir_dereference_variable(tmp);
+          type = tmp->type;
+       }
+       break;
+    }
+    case ast_logic_xor:
+       /* From page 33 (page 39 of the PDF) of the GLSL 1.10 spec:
+        *
+        *    "The logical binary operators and (&&), or ( | | ), and
+        *     exclusive or (^^). They operate only on two Boolean
+        *     expressions and result in a Boolean expression."
+        */
+       op[0] = get_scalar_boolean_operand(instructions, state, this, 0, "LHS",
+                                          &error_emitted);
+       op[1] = get_scalar_boolean_operand(instructions, state, this, 1, "RHS",
+                                          &error_emitted);
+       result = new(ctx) ir_expression(operations[this->oper], glsl_type::bool_type,
+                                       op[0], op[1]);
+       break;
+    case ast_logic_not:
+       op[0] = get_scalar_boolean_operand(instructions, state, this, 0,
+                                          "operand", &error_emitted);
+       result = new(ctx) ir_expression(operations[this->oper], glsl_type::bool_type,
+                                       op[0], NULL);
+       break;
+    case ast_mul_assign:
+    case ast_div_assign:
+    case ast_add_assign:
+    case ast_sub_assign: {
+       op[0] = this->subexpressions[0]->hir(instructions, state);
+       op[1] = this->subexpressions[1]->hir(instructions, state);
+       type = arithmetic_result_type(op[0], op[1],
+                                     (this->oper == ast_mul_assign),
+                                     state, & loc);
+       ir_rvalue *temp_rhs = new(ctx) ir_expression(operations[this->oper], type,
+                                                    op[0], op[1]);
+       error_emitted =
+          do_assignment(instructions, state,
+                        this->subexpressions[0]->non_lvalue_description,
+                        op[0]->clone(ctx, NULL), temp_rhs,
+                        &result, needs_rvalue, false,
+                        this->subexpressions[0]->get_location());
+       /* GLSL 1.10 does not allow array assignment.  However, we don't have to
+        * explicitly test for this because none of the binary expression
+        * operators allow array operands either.
+        */
+       break;
+    }
+    case ast_mod_assign: {
+       op[0] = this->subexpressions[0]->hir(instructions, state);
+       op[1] = this->subexpressions[1]->hir(instructions, state);
+       type = modulus_result_type(op[0], op[1], state, &loc);
+       assert(operations[this->oper] == ir_binop_mod);
+       ir_rvalue *temp_rhs;
+       temp_rhs = new(ctx) ir_expression(operations[this->oper], type,
+                                         op[0], op[1]);
+       error_emitted =
+          do_assignment(instructions, state,
+                        this->subexpressions[0]->non_lvalue_description,
+                        op[0]->clone(ctx, NULL), temp_rhs,
+                        &result, needs_rvalue, false,
+                        this->subexpressions[0]->get_location());
+       break;
+    }
+    case ast_ls_assign:
+    case ast_rs_assign: {
+       op[0] = this->subexpressions[0]->hir(instructions, state);
+       op[1] = this->subexpressions[1]->hir(instructions, state);
+       type = shift_result_type(op[0]->type, op[1]->type, this->oper, state,
+                                &loc);
+       ir_rvalue *temp_rhs = new(ctx) ir_expression(operations[this->oper],
+                                                    type, op[0], op[1]);
+       error_emitted =
+          do_assignment(instructions, state,
+                        this->subexpressions[0]->non_lvalue_description,
+                        op[0]->clone(ctx, NULL), temp_rhs,
+                        &result, needs_rvalue, false,
+                        this->subexpressions[0]->get_location());
+       break;
+    }
+    case ast_and_assign:
+    case ast_xor_assign:
+    case ast_or_assign: {
+       op[0] = this->subexpressions[0]->hir(instructions, state);
+       op[1] = this->subexpressions[1]->hir(instructions, state);
+       type = bit_logic_result_type(op[0], op[1], this->oper, state, &loc);
+       ir_rvalue *temp_rhs = new(ctx) ir_expression(operations[this->oper],
+                                                    type, op[0], op[1]);
+       error_emitted =
+          do_assignment(instructions, state,
+                        this->subexpressions[0]->non_lvalue_description,
+                        op[0]->clone(ctx, NULL), temp_rhs,
+                        &result, needs_rvalue, false,
+                        this->subexpressions[0]->get_location());
+       break;
+    }
+    case ast_conditional: {
+       /* From page 59 (page 65 of the PDF) of the GLSL 1.50 spec:
+        *
+        *    "The ternary selection operator (?:). It operates on three
+        *    expressions (exp1 ? exp2 : exp3). This operator evaluates the
+        *    first expression, which must result in a scalar Boolean."
+        */
+       op[0] = get_scalar_boolean_operand(instructions, state, this, 0,
+                                          "condition", &error_emitted);
+       /* The :? operator is implemented by generating an anonymous temporary
+        * followed by an if-statement.  The last instruction in each branch of
+        * the if-statement assigns a value to the anonymous temporary.  This
+        * temporary is the r-value of the expression.
+        */
+       exec_list then_instructions;
+       exec_list else_instructions;
+       op[1] = this->subexpressions[1]->hir(&then_instructions, state);
+       op[2] = this->subexpressions[2]->hir(&else_instructions, state);
+       /* From page 59 (page 65 of the PDF) of the GLSL 1.50 spec:
+        *
+        *     "The second and third expressions can be any type, as
+        *     long their types match, or there is a conversion in
+        *     Section 4.1.10 "Implicit Conversions" that can be applied
+        *     to one of the expressions to make their types match. This
+        *     resulting matching type is the type of the entire
+        *     expression."
+        */
+       if ((!apply_implicit_conversion(op[1]->type, op[2], state)
+           && !apply_implicit_conversion(op[2]->type, op[1], state))
+           || (op[1]->type != op[2]->type)) {
+          YYLTYPE loc = this->subexpressions[1]->get_location();
+          _mesa_glsl_error(& loc, state, "second and third operands of ?: "
+                           "operator must have matching types");
+          error_emitted = true;
+          type = glsl_type::error_type;
+       } else {
+          type = op[1]->type;
+       }
+       /* From page 33 (page 39 of the PDF) of the GLSL 1.10 spec:
+        *
+        *    "The second and third expressions must be the same type, but can
+        *    be of any type other than an array."
+        */
+       if (type->is_array() &&
+           !state->check_version(120, 300, &loc,
+                                 "second and third operands of ?: operator "
+                                 "cannot be arrays")) {
+          error_emitted = true;
+       }
+       /* From section 4.1.7 of the GLSL 4.50 spec (Opaque Types):
+        *
+        *  "Except for array indexing, structure member selection, and
+        *   parentheses, opaque variables are not allowed to be operands in
+        *   expressions; such use results in a compile-time error."
+        */
+       if (type->contains_opaque()) {
+          _mesa_glsl_error(&loc, state, "opaque variables cannot be operands "
+                           "of the ?: operator");
+          error_emitted = true;
+       }
+       ir_constant *cond_val = op[0]->constant_expression_value();
+       if (then_instructions.is_empty()
+           && else_instructions.is_empty()
+           && cond_val != NULL) {
+          result = cond_val->value.b[0] ? op[1] : op[2];
+       } else {
+          /* The copy to conditional_tmp reads the whole array. */
+          if (type->is_array()) {
+             mark_whole_array_access(op[1]);
+             mark_whole_array_access(op[2]);
+          }
+          ir_variable *const tmp =
+             new(ctx) ir_variable(type, "conditional_tmp", ir_var_temporary);
+          instructions->push_tail(tmp);
+          ir_if *const stmt = new(ctx) ir_if(op[0]);
+          instructions->push_tail(stmt);
+          then_instructions.move_nodes_to(& stmt->then_instructions);
+          ir_dereference *const then_deref =
+             new(ctx) ir_dereference_variable(tmp);
+          ir_assignment *const then_assign =
+             new(ctx) ir_assignment(then_deref, op[1]);
+          stmt->then_instructions.push_tail(then_assign);
+          else_instructions.move_nodes_to(& stmt->else_instructions);
+          ir_dereference *const else_deref =
+             new(ctx) ir_dereference_variable(tmp);
+          ir_assignment *const else_assign =
+             new(ctx) ir_assignment(else_deref, op[2]);
+          stmt->else_instructions.push_tail(else_assign);
+          result = new(ctx) ir_dereference_variable(tmp);
+       }
+       break;
+    }
+    case ast_pre_inc:
+    case ast_pre_dec: {
+       this->non_lvalue_description = (this->oper == ast_pre_inc)
+          ? "pre-increment operation" : "pre-decrement operation";
+       op[0] = this->subexpressions[0]->hir(instructions, state);
+       op[1] = constant_one_for_inc_dec(ctx, op[0]->type);
+       type = arithmetic_result_type(op[0], op[1], false, state, & loc);
+       ir_rvalue *temp_rhs;
+       temp_rhs = new(ctx) ir_expression(operations[this->oper], type,
+                                         op[0], op[1]);
+       error_emitted =
+          do_assignment(instructions, state,
+                        this->subexpressions[0]->non_lvalue_description,
+                        op[0]->clone(ctx, NULL), temp_rhs,
+                        &result, needs_rvalue, false,
+                        this->subexpressions[0]->get_location());
+       break;
+    }
+    case ast_post_inc:
+    case ast_post_dec: {
+       this->non_lvalue_description = (this->oper == ast_post_inc)
+          ? "post-increment operation" : "post-decrement operation";
+       op[0] = this->subexpressions[0]->hir(instructions, state);
+       op[1] = constant_one_for_inc_dec(ctx, op[0]->type);
+       error_emitted = op[0]->type->is_error() || op[1]->type->is_error();
+       type = arithmetic_result_type(op[0], op[1], false, state, & loc);
+       ir_rvalue *temp_rhs;
+       temp_rhs = new(ctx) ir_expression(operations[this->oper], type,
+                                         op[0], op[1]);
+       /* Get a temporary of a copy of the lvalue before it's modified.
+        * This may get thrown away later.
+        */
+       result = get_lvalue_copy(instructions, op[0]->clone(ctx, NULL));
+       ir_rvalue *junk_rvalue;
+       error_emitted =
+          do_assignment(instructions, state,
+                        this->subexpressions[0]->non_lvalue_description,
+                        op[0]->clone(ctx, NULL), temp_rhs,
+                        &junk_rvalue, false, false,
+                        this->subexpressions[0]->get_location());
+       break;
+    }
+    case ast_field_selection:
+       result = _mesa_ast_field_selection_to_hir(this, instructions, state);
+       break;
+    case ast_array_index: {
+       YYLTYPE index_loc = subexpressions[1]->get_location();
+       op[0] = subexpressions[0]->hir(instructions, state);
+       op[1] = subexpressions[1]->hir(instructions, state);
+       result = _mesa_ast_array_index_to_hir(ctx, state, op[0], op[1],
+                                             loc, index_loc);
+       if (result->type->is_error())
+          error_emitted = true;
+       break;
+    }
+    case ast_unsized_array_dim:
+       assert(!"ast_unsized_array_dim: Should never get here.");
+       break;
+    case ast_function_call:
+       /* Should *NEVER* get here.  ast_function_call should always be handled
+        * by ast_function_expression::hir.
+        */
+       assert(0);
+       break;
+    case ast_identifier: {
+       /* ast_identifier can appear several places in a full abstract syntax
+        * tree.  This particular use must be at location specified in the grammar
+        * as 'variable_identifier'.
+        */
+       ir_variable *var =
+          state->symbols->get_variable(this->primary_expression.identifier);
+       if (var != NULL) {
+          var->data.used = true;
+          result = new(ctx) ir_dereference_variable(var);
+       } else {
+          _mesa_glsl_error(& loc, state, "`%s' undeclared",
+                           this->primary_expression.identifier);
+          result = ir_rvalue::error_value(ctx);
+          error_emitted = true;
+       }
+       break;
+    }
+    case ast_int_constant:
+       result = new(ctx) ir_constant(this->primary_expression.int_constant);
+       break;
+    case ast_uint_constant:
+       result = new(ctx) ir_constant(this->primary_expression.uint_constant);
+       break;
+    case ast_float_constant:
+       result = new(ctx) ir_constant(this->primary_expression.float_constant);
+       break;
+    case ast_bool_constant:
+       result = new(ctx) ir_constant(bool(this->primary_expression.bool_constant));
+       break;
+    case ast_double_constant:
+       result = new(ctx) ir_constant(this->primary_expression.double_constant);
+       break;
+    case ast_sequence: {
+       /* It should not be possible to generate a sequence in the AST without
+        * any expressions in it.
+        */
+       assert(!this->expressions.is_empty());
+       /* The r-value of a sequence is the last expression in the sequence.  If
+        * the other expressions in the sequence do not have side-effects (and
+        * therefore add instructions to the instruction list), they get dropped
+        * on the floor.
+        */
+       exec_node *previous_tail_pred = NULL;
+       YYLTYPE previous_operand_loc = loc;
+       foreach_list_typed (ast_node, ast, link, &this->expressions) {
+          /* If one of the operands of comma operator does not generate any
+           * code, we want to emit a warning.  At each pass through the loop
+           * previous_tail_pred will point to the last instruction in the
+           * stream *before* processing the previous operand.  Naturally,
+           * instructions->tail_pred will point to the last instruction in the
+           * stream *after* processing the previous operand.  If the two
+           * pointers match, then the previous operand had no effect.
+           *
+           * The warning behavior here differs slightly from GCC.  GCC will
+           * only emit a warning if none of the left-hand operands have an
+           * effect.  However, it will emit a warning for each.  I believe that
+           * there are some cases in C (especially with GCC extensions) where
+           * it is useful to have an intermediate step in a sequence have no
+           * effect, but I don't think these cases exist in GLSL.  Either way,
+           * it would be a giant hassle to replicate that behavior.
+           */
+          if (previous_tail_pred == instructions->tail_pred) {
+             _mesa_glsl_warning(&previous_operand_loc, state,
+                                "left-hand operand of comma expression has "
+                                "no effect");
+          }
+          /* tail_pred is directly accessed instead of using the get_tail()
+           * method for performance reasons.  get_tail() has extra code to
+           * return NULL when the list is empty.  We don't care about that
+           * here, so using tail_pred directly is fine.
+           */
+          previous_tail_pred = instructions->tail_pred;
+          previous_operand_loc = ast->get_location();
+          result = ast->hir(instructions, state);
+       }
+       /* Any errors should have already been emitted in the loop above.
+        */
+       error_emitted = true;
+       break;
+    }
+    }
+    type = NULL; /* use result->type, not type. */
+    assert(result != NULL || !needs_rvalue);
+    if (result && result->type->is_error() && !error_emitted)
+       _mesa_glsl_error(& loc, state, "type mismatch");
+    return result;
+ }
+ bool
+ ast_expression::has_sequence_subexpression() const
+ {
+    switch (this->oper) {
+    case ast_plus:
+    case ast_neg:
+    case ast_bit_not:
+    case ast_logic_not:
+    case ast_pre_inc:
+    case ast_pre_dec:
+    case ast_post_inc:
+    case ast_post_dec:
+       return this->subexpressions[0]->has_sequence_subexpression();
+    case ast_assign:
+    case ast_add:
+    case ast_sub:
+    case ast_mul:
+    case ast_div:
+    case ast_mod:
+    case ast_lshift:
+    case ast_rshift:
+    case ast_less:
+    case ast_greater:
+    case ast_lequal:
+    case ast_gequal:
+    case ast_nequal:
+    case ast_equal:
+    case ast_bit_and:
+    case ast_bit_xor:
+    case ast_bit_or:
+    case ast_logic_and:
+    case ast_logic_or:
+    case ast_logic_xor:
+    case ast_array_index:
+    case ast_mul_assign:
+    case ast_div_assign:
+    case ast_add_assign:
+    case ast_sub_assign:
+    case ast_mod_assign:
+    case ast_ls_assign:
+    case ast_rs_assign:
+    case ast_and_assign:
+    case ast_xor_assign:
+    case ast_or_assign:
+       return this->subexpressions[0]->has_sequence_subexpression() ||
+              this->subexpressions[1]->has_sequence_subexpression();
+    case ast_conditional:
+       return this->subexpressions[0]->has_sequence_subexpression() ||
+              this->subexpressions[1]->has_sequence_subexpression() ||
+              this->subexpressions[2]->has_sequence_subexpression();
+    case ast_sequence:
+       return true;
+    case ast_field_selection:
+    case ast_identifier:
+    case ast_int_constant:
+    case ast_uint_constant:
+    case ast_float_constant:
+    case ast_bool_constant:
+    case ast_double_constant:
+       return false;
+    case ast_aggregate:
+       unreachable("ast_aggregate: Should never get here.");
+    case ast_function_call:
+       unreachable("should be handled by ast_function_expression::hir");
+    case ast_unsized_array_dim:
+       unreachable("ast_unsized_array_dim: Should never get here.");
+    }
+    return false;
+ }
+ ir_rvalue *
+ 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
+     * expression.  This is the solitary semicolon:
+     *
+     * for (i = 0; i < 5; i++)
+     *     ;
+     *
+     * In this case the expression will be NULL.  Test for NULL and don't do
+     * anything in that case.
+     */
+    if (expression != NULL)
+       expression->hir_no_rvalue(instructions, state);
+    /* Statements do not have r-values.
+     */
+    return NULL;
+ }
+ ir_rvalue *
+ ast_compound_statement::hir(exec_list *instructions,
+                             struct _mesa_glsl_parse_state *state)
+ {
+    if (new_scope)
+       state->symbols->push_scope();
+    foreach_list_typed (ast_node, ast, link, &this->statements)
+       ast->hir(instructions, state);
+    if (new_scope)
+       state->symbols->pop_scope();
+    /* Compound statements do not have r-values.
+     */
+    return NULL;
+ }
+ /**
+  * Evaluate the given exec_node (which should be an ast_node representing
+  * a single array dimension) and return its integer value.
+  */
+ static unsigned
+ process_array_size(exec_node *node,
+                    struct _mesa_glsl_parse_state *state)
+ {
+    exec_list dummy_instructions;
+    ast_node *array_size = exec_node_data(ast_node, node, link);
+    /**
+     * Dimensions other than the outermost dimension can by unsized if they
+     * are immediately sized by a constructor or initializer.
+     */
+    if (((ast_expression*)array_size)->oper == ast_unsized_array_dim)
+       return 0;
+    ir_rvalue *const ir = array_size->hir(& dummy_instructions, state);
+    YYLTYPE loc = array_size->get_location();
+    if (ir == NULL) {
+       _mesa_glsl_error(& loc, state,
+                        "array size could not be resolved");
+       return 0;
+    }
+    if (!ir->type->is_integer()) {
+       _mesa_glsl_error(& loc, state,
+                        "array size must be integer type");
+       return 0;
+    }
+    if (!ir->type->is_scalar()) {
+       _mesa_glsl_error(& loc, state,
+                        "array size must be scalar type");
+       return 0;
+    }
+    ir_constant *const size = ir->constant_expression_value();
+    if (size == NULL || array_size->has_sequence_subexpression()) {
+       _mesa_glsl_error(& loc, state, "array size must be a "
+                        "constant valued expression");
+       return 0;
+    }
+    if (size->value.i[0] <= 0) {
+       _mesa_glsl_error(& loc, state, "array size must be > 0");
+       return 0;
+    }
+    assert(size->type == ir->type);
+    /* If the array size is const (and we've verified that
+     * it is) then no instructions should have been emitted
+     * when we converted it to HIR. If they were emitted,
+     * then either the array size isn't const after all, or
+     * we are emitting unnecessary instructions.
+     */
+    assert(dummy_instructions.is_empty());
+    return size->value.u[0];
+ }
+ static const glsl_type *
+ process_array_type(YYLTYPE *loc, const glsl_type *base,
+                    ast_array_specifier *array_specifier,
+                    struct _mesa_glsl_parse_state *state)
+ {
+    const glsl_type *array_type = base;
+    if (array_specifier != NULL) {
+       if (base->is_array()) {
+          /* From page 19 (page 25) of the GLSL 1.20 spec:
+           *
+           * "Only one-dimensional arrays may be declared."
+           */
+          if (!state->check_arrays_of_arrays_allowed(loc)) {
+             return glsl_type::error_type;
+          }
+       }
+       for (exec_node *node = array_specifier->array_dimensions.tail_pred;
+            !node->is_head_sentinel(); node = node->prev) {
+          unsigned array_size = process_array_size(node, state);
+          array_type = glsl_type::get_array_instance(array_type, array_size);
+       }
+    }
+    return array_type;
+ }
+ static bool
+ precision_qualifier_allowed(const glsl_type *type)
+ {
+    /* Precision qualifiers apply to floating point, integer and opaque
+     * types.
+     *
+     * Section 4.5.2 (Precision Qualifiers) of the GLSL 1.30 spec says:
+     *    "Any floating point or any integer declaration can have the type
+     *    preceded by one of these precision qualifiers [...] Literal
+     *    constants do not have precision qualifiers. Neither do Boolean
+     *    variables.
+     *
+     * Section 4.5 (Precision and Precision Qualifiers) of the GLSL 1.30
+     * spec also says:
+     *
+     *     "Precision qualifiers are added for code portability with OpenGL
+     *     ES, not for functionality. They have the same syntax as in OpenGL
+     *     ES."
+     *
+     * Section 8 (Built-In Functions) of the GLSL ES 1.00 spec says:
+     *
+     *     "uniform lowp sampler2D sampler;
+     *     highp vec2 coord;
+     *     ...
+     *     lowp vec4 col = texture2D (sampler, coord);
+     *                                            // texture2D returns lowp"
+     *
+     * From this, we infer that GLSL 1.30 (and later) should allow precision
+     * qualifiers on sampler types just like float and integer types.
+     */
+    return (type->is_float()
+        || type->is_integer()
+        || type->contains_opaque())
+        && !type->without_array()->is_record();
+ }
+ const glsl_type *
+ ast_type_specifier::glsl_type(const char **name,
+                               struct _mesa_glsl_parse_state *state) const
+ {
+    const struct glsl_type *type;
+    type = state->symbols->get_type(this->type_name);
+    *name = this->type_name;
+    YYLTYPE loc = this->get_location();
+    type = process_array_type(&loc, type, this->array_specifier, state);
+    return type;
+ }
+ /**
+  * From the OpenGL ES 3.0 spec, 4.5.4 Default Precision Qualifiers:
+  *
+  * "The precision statement
+  *
+  *    precision precision-qualifier type;
+  *
+  *  can be used to establish a default precision qualifier. The type field can
+  *  be either int or float or any of the sampler types, (...) If type is float,
+  *  the directive applies to non-precision-qualified floating point type
+  *  (scalar, vector, and matrix) declarations. If type is int, the directive
+  *  applies to all non-precision-qualified integer type (scalar, vector, signed,
+  *  and unsigned) declarations."
+  *
+  * We use the symbol table to keep the values of the default precisions for
+  * each 'type' in each scope and we use the 'type' string from the precision
+  * statement as key in the symbol table. When we want to retrieve the default
+  * precision associated with a given glsl_type we need to know the type string
+  * associated with it. This is what this function returns.
+  */
+ static const char *
+ get_type_name_for_precision_qualifier(const glsl_type *type)
+ {
+    switch (type->base_type) {
+    case GLSL_TYPE_FLOAT:
+       return "float";
+    case GLSL_TYPE_UINT:
+    case GLSL_TYPE_INT:
+       return "int";
+    case GLSL_TYPE_ATOMIC_UINT:
+       return "atomic_uint";
+    case GLSL_TYPE_IMAGE:
+    /* fallthrough */
+    case GLSL_TYPE_SAMPLER: {
+       const unsigned type_idx =
+          type->sampler_array + 2 * type->sampler_shadow;
+       const unsigned offset = type->base_type == GLSL_TYPE_SAMPLER ? 0 : 4;
+       assert(type_idx < 4);
+       switch (type->sampler_type) {
+       case GLSL_TYPE_FLOAT:
+          switch (type->sampler_dimensionality) {
+          case GLSL_SAMPLER_DIM_1D: {
+             assert(type->base_type == GLSL_TYPE_SAMPLER);
+             static const char *const names[4] = {
+               "sampler1D", "sampler1DArray",
+               "sampler1DShadow", "sampler1DArrayShadow"
+             };
+             return names[type_idx];
+          }
+          case GLSL_SAMPLER_DIM_2D: {
+             static const char *const names[8] = {
+               "sampler2D", "sampler2DArray",
+               "sampler2DShadow", "sampler2DArrayShadow",
+               "image2D", "image2DArray", NULL, NULL
+             };
+             return names[offset + type_idx];
+          }
+          case GLSL_SAMPLER_DIM_3D: {
+             static const char *const names[8] = {
+               "sampler3D", NULL, NULL, NULL,
+               "image3D", NULL, NULL, NULL
+             };
+             return names[offset + type_idx];
+          }
+          case GLSL_SAMPLER_DIM_CUBE: {
+             static const char *const names[8] = {
+               "samplerCube", "samplerCubeArray",
+               "samplerCubeShadow", "samplerCubeArrayShadow",
+               "imageCube", NULL, NULL, NULL
+             };
+             return names[offset + type_idx];
+          }
+          case GLSL_SAMPLER_DIM_MS: {
+             assert(type->base_type == GLSL_TYPE_SAMPLER);
+             static const char *const names[4] = {
+               "sampler2DMS", "sampler2DMSArray", NULL, NULL
+             };
+             return names[type_idx];
+          }
+          case GLSL_SAMPLER_DIM_RECT: {
+             assert(type->base_type == GLSL_TYPE_SAMPLER);
+             static const char *const names[4] = {
+               "samplerRect", NULL, "samplerRectShadow", NULL
+             };
+             return names[type_idx];
+          }
+          case GLSL_SAMPLER_DIM_BUF: {
+             assert(type->base_type == GLSL_TYPE_SAMPLER);
+             static const char *const names[4] = {
+               "samplerBuffer", NULL, NULL, NULL
+             };
+             return names[type_idx];
+          }
+          case GLSL_SAMPLER_DIM_EXTERNAL: {
+             assert(type->base_type == GLSL_TYPE_SAMPLER);
+             static const char *const names[4] = {
+               "samplerExternalOES", NULL, NULL, NULL
+             };
+             return names[type_idx];
+          }
+          default:
+             unreachable("Unsupported sampler/image dimensionality");
+          } /* sampler/image float dimensionality */
+          break;
+       case GLSL_TYPE_INT:
+          switch (type->sampler_dimensionality) {
+          case GLSL_SAMPLER_DIM_1D: {
+             assert(type->base_type == GLSL_TYPE_SAMPLER);
+             static const char *const names[4] = {
+               "isampler1D", "isampler1DArray", NULL, NULL
+             };
+             return names[type_idx];
+          }
+          case GLSL_SAMPLER_DIM_2D: {
+             static const char *const names[8] = {
+               "isampler2D", "isampler2DArray", NULL, NULL,
+               "iimage2D", "iimage2DArray", NULL, NULL
+             };
+             return names[offset + type_idx];
+          }
+          case GLSL_SAMPLER_DIM_3D: {
+             static const char *const names[8] = {
+               "isampler3D", NULL, NULL, NULL,
+               "iimage3D", NULL, NULL, NULL
+             };
+             return names[offset + type_idx];
+          }
+          case GLSL_SAMPLER_DIM_CUBE: {
+             static const char *const names[8] = {
+               "isamplerCube", "isamplerCubeArray", NULL, NULL,
+               "iimageCube", NULL, NULL, NULL
+             };
+             return names[offset + type_idx];
+          }
+          case GLSL_SAMPLER_DIM_MS: {
+             assert(type->base_type == GLSL_TYPE_SAMPLER);
+             static const char *const names[4] = {
+               "isampler2DMS", "isampler2DMSArray", NULL, NULL
+             };
+             return names[type_idx];
+          }
+          case GLSL_SAMPLER_DIM_RECT: {
+             assert(type->base_type == GLSL_TYPE_SAMPLER);
+             static const char *const names[4] = {
+               "isamplerRect", NULL, "isamplerRectShadow", NULL
+             };
+             return names[type_idx];
+          }
+          case GLSL_SAMPLER_DIM_BUF: {
+             assert(type->base_type == GLSL_TYPE_SAMPLER);
+             static const char *const names[4] = {
+               "isamplerBuffer", NULL, NULL, NULL
+             };
+             return names[type_idx];
+          }
+          default:
+             unreachable("Unsupported isampler/iimage dimensionality");
+          } /* sampler/image int dimensionality */
+          break;
+       case GLSL_TYPE_UINT:
+          switch (type->sampler_dimensionality) {
+          case GLSL_SAMPLER_DIM_1D: {
+             assert(type->base_type == GLSL_TYPE_SAMPLER);
+             static const char *const names[4] = {
+               "usampler1D", "usampler1DArray", NULL, NULL
+             };
+             return names[type_idx];
+          }
+          case GLSL_SAMPLER_DIM_2D: {
+             static const char *const names[8] = {
+               "usampler2D", "usampler2DArray", NULL, NULL,
+               "uimage2D", "uimage2DArray", NULL, NULL
+             };
+             return names[offset + type_idx];
+          }
+          case GLSL_SAMPLER_DIM_3D: {
+             static const char *const names[8] = {
+               "usampler3D", NULL, NULL, NULL,
+               "uimage3D", NULL, NULL, NULL
+             };
+             return names[offset + type_idx];
+          }
+          case GLSL_SAMPLER_DIM_CUBE: {
+             static const char *const names[8] = {
+               "usamplerCube", "usamplerCubeArray", NULL, NULL,
+               "uimageCube", NULL, NULL, NULL
+             };
+             return names[offset + type_idx];
+          }
+          case GLSL_SAMPLER_DIM_MS: {
+             assert(type->base_type == GLSL_TYPE_SAMPLER);
+             static const char *const names[4] = {
+               "usampler2DMS", "usampler2DMSArray", NULL, NULL
+             };
+             return names[type_idx];
+          }
+          case GLSL_SAMPLER_DIM_RECT: {
+             assert(type->base_type == GLSL_TYPE_SAMPLER);
+             static const char *const names[4] = {
+               "usamplerRect", NULL, "usamplerRectShadow", NULL
+             };
+             return names[type_idx];
+          }
+          case GLSL_SAMPLER_DIM_BUF: {
+             assert(type->base_type == GLSL_TYPE_SAMPLER);
+             static const char *const names[4] = {
+               "usamplerBuffer", NULL, NULL, NULL
+             };
+             return names[type_idx];
+          }
+          default:
+             unreachable("Unsupported usampler/uimage dimensionality");
+          } /* sampler/image uint dimensionality */
+          break;
+       default:
+          unreachable("Unsupported sampler/image type");
+       } /* sampler/image type */
+       break;
+    } /* GLSL_TYPE_SAMPLER/GLSL_TYPE_IMAGE */
+    break;
+    default:
+       unreachable("Unsupported type");
+    } /* base type */
+ }
+ static unsigned
+ select_gles_precision(unsigned qual_precision,
+                       const glsl_type *type,
+                       struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
+ {
+    /* Precision qualifiers do not have any meaning in Desktop GLSL.
+     * In GLES we take the precision from the type qualifier if present,
+     * otherwise, if the type of the variable allows precision qualifiers at
+     * all, we look for the default precision qualifier for that type in the
+     * current scope.
+     */
+    assert(state->es_shader);
+    unsigned precision = GLSL_PRECISION_NONE;
+    if (qual_precision) {
+       precision = qual_precision;
+    } else if (precision_qualifier_allowed(type)) {
+       const char *type_name =
+          get_type_name_for_precision_qualifier(type->without_array());
+       assert(type_name != NULL);
+       precision =
+          state->symbols->get_default_precision_qualifier(type_name);
+       if (precision == ast_precision_none) {
+          _mesa_glsl_error(loc, state,
+                           "No precision specified in this scope for type `%s'",
+                           type->name);
+       }
+    }
+    return precision;
+ }
+ const glsl_type *
+ ast_fully_specified_type::glsl_type(const char **name,
+                                     struct _mesa_glsl_parse_state *state) const
+ {
+    return this->specifier->glsl_type(name, state);
+ }
+ /**
+  * Determine whether a toplevel variable declaration declares a varying.  This
+  * function operates by examining the variable's mode and the shader target,
+  * so it correctly identifies linkage variables regardless of whether they are
+  * declared using the deprecated "varying" syntax or the new "in/out" syntax.
+  *
+  * Passing a non-toplevel variable declaration (e.g. a function parameter) to
+  * this function will produce undefined results.
+  */
+ static bool
+ is_varying_var(ir_variable *var, gl_shader_stage target)
+ {
+    switch (target) {
+    case MESA_SHADER_VERTEX:
+       return var->data.mode == ir_var_shader_out;
+    case MESA_SHADER_FRAGMENT:
+       return var->data.mode == ir_var_shader_in;
+    default:
+       return var->data.mode == ir_var_shader_out || var->data.mode == ir_var_shader_in;
+    }
+ }
+ /**
+  * Matrix layout qualifiers are only allowed on certain types
+  */
+ static void
+ validate_matrix_layout_for_type(struct _mesa_glsl_parse_state *state,
+                                 YYLTYPE *loc,
+                                 const glsl_type *type,
+                                 ir_variable *var)
+ {
+    if (var && !var->is_in_buffer_block()) {
+       /* Layout qualifiers may only apply to interface blocks and fields in
+        * them.
+        */
+       _mesa_glsl_error(loc, state,
+                        "uniform block layout qualifiers row_major and "
+                        "column_major may not be applied to variables "
+                        "outside of uniform blocks");
+    } else if (!type->without_array()->is_matrix()) {
+       /* The OpenGL ES 3.0 conformance tests did not originally allow
+        * matrix layout qualifiers on non-matrices.  However, the OpenGL
+        * 4.4 and OpenGL ES 3.0 (revision TBD) specifications were
+        * amended to specifically allow these layouts on all types.  Emit
+        * a warning so that people know their code may not be portable.
+        */
+       _mesa_glsl_warning(loc, state,
+                          "uniform block layout qualifiers row_major and "
+                          "column_major applied to non-matrix types may "
+                          "be rejected by older compilers");
+    }
+ }
+ static bool
+ process_qualifier_constant(struct _mesa_glsl_parse_state *state,
+                            YYLTYPE *loc,
+                            const char *qual_indentifier,
+                            ast_expression *const_expression,
+                            unsigned *value)
+ {
+    exec_list dummy_instructions;
+    if (const_expression == NULL) {
+       *value = 0;
+       return true;
+    }
+    ir_rvalue *const ir = const_expression->hir(&dummy_instructions, state);
+    ir_constant *const const_int = ir->constant_expression_value();
+    if (const_int == NULL || !const_int->type->is_integer()) {
+       _mesa_glsl_error(loc, state, "%s must be an integral constant "
+                        "expression", qual_indentifier);
+       return false;
+    }
+    if (const_int->value.i[0] < 0) {
+       _mesa_glsl_error(loc, state, "%s layout qualifier is invalid (%d < 0)",
+                        qual_indentifier, const_int->value.u[0]);
+       return false;
+    }
+    /* If the location is const (and we've verified that
+     * it is) then no instructions should have been emitted
+     * when we converted it to HIR. If they were emitted,
+     * then either the location isn't const after all, or
+     * we are emitting unnecessary instructions.
+     */
+    assert(dummy_instructions.is_empty());
+    *value = const_int->value.u[0];
+    return true;
+ }
+ static bool
+ validate_stream_qualifier(YYLTYPE *loc, struct _mesa_glsl_parse_state *state,
+                           unsigned stream)
+ {
+    if (stream >= state->ctx->Const.MaxVertexStreams) {
+       _mesa_glsl_error(loc, state,
+                        "invalid stream specified %d is larger than "
+                        "MAX_VERTEX_STREAMS - 1 (%d).",
+                        stream, state->ctx->Const.MaxVertexStreams - 1);
+       return false;
+    }
+    return true;
+ }
+ static void
+ apply_explicit_binding(struct _mesa_glsl_parse_state *state,
+                        YYLTYPE *loc,
+                        ir_variable *var,
+                        const glsl_type *type,
+                        const ast_type_qualifier *qual)
+ {
+    if (!qual->flags.q.uniform && !qual->flags.q.buffer) {
+       _mesa_glsl_error(loc, state,
+                        "the \"binding\" qualifier only applies to uniforms and "
+                        "shader storage buffer objects");
+       return;
+    }
+    unsigned qual_binding;
+    if (!process_qualifier_constant(state, loc, "binding", qual->binding,
+                                    &qual_binding)) {
+       return;
+    }
+    const struct gl_context *const ctx = state->ctx;
+    unsigned elements = type->is_array() ? type->arrays_of_arrays_size() : 1;
+    unsigned max_index = qual_binding + elements - 1;
+    const glsl_type *base_type = type->without_array();
+    if (base_type->is_interface()) {
+       /* UBOs.  From page 60 of the GLSL 4.20 specification:
+        * "If the binding point for any uniform block instance is less than zero,
+        *  or greater than or equal to the implementation-dependent maximum
+        *  number of uniform buffer bindings, a compilation error will occur.
+        *  When the binding identifier is used with a uniform block instanced as
+        *  an array of size N, all elements of the array from binding through
+        *  binding + N – 1 must be within this range."
+        *
+        * The implementation-dependent maximum is GL_MAX_UNIFORM_BUFFER_BINDINGS.
+        */
+       if (qual->flags.q.uniform &&
+          max_index >= ctx->Const.MaxUniformBufferBindings) {
+          _mesa_glsl_error(loc, state, "layout(binding = %u) for %d UBOs exceeds "
+                           "the maximum number of UBO binding points (%d)",
+                           qual_binding, elements,
+                           ctx->Const.MaxUniformBufferBindings);
+          return;
+       }
+       /* SSBOs. From page 67 of the GLSL 4.30 specification:
+        * "If the binding point for any uniform or shader storage block instance
+        *  is less than zero, or greater than or equal to the
+        *  implementation-dependent maximum number of uniform buffer bindings, a
+        *  compile-time error will occur. When the binding identifier is used
+        *  with a uniform or shader storage block instanced as an array of size
+        *  N, all elements of the array from binding through binding + N – 1 must
+        *  be within this range."
+        */
+       if (qual->flags.q.buffer &&
+          max_index >= ctx->Const.MaxShaderStorageBufferBindings) {
+          _mesa_glsl_error(loc, state, "layout(binding = %u) for %d SSBOs exceeds "
+                           "the maximum number of SSBO binding points (%d)",
+                           qual_binding, elements,
+                           ctx->Const.MaxShaderStorageBufferBindings);
+          return;
+       }
+    } else if (base_type->is_sampler()) {
+       /* Samplers.  From page 63 of the GLSL 4.20 specification:
+        * "If the binding is less than zero, or greater than or equal to the
+        *  implementation-dependent maximum supported number of units, a
+        *  compilation error will occur. When the binding identifier is used
+        *  with an array of size N, all elements of the array from binding
+        *  through binding + N - 1 must be within this range."
+        */
+       unsigned limit = ctx->Const.MaxCombinedTextureImageUnits;
+       if (max_index >= limit) {
+          _mesa_glsl_error(loc, state, "layout(binding = %d) for %d samplers "
+                           "exceeds the maximum number of texture image units "
+                           "(%u)", qual_binding, elements, limit);
+          return;
+       }
+    } else if (base_type->contains_atomic()) {
+       assert(ctx->Const.MaxAtomicBufferBindings <= MAX_COMBINED_ATOMIC_BUFFERS);
+       if (qual_binding >= ctx->Const.MaxAtomicBufferBindings) {
+          _mesa_glsl_error(loc, state, "layout(binding = %d) exceeds the "
+                           " maximum number of atomic counter buffer bindings"
+                           "(%u)", qual_binding,
+                           ctx->Const.MaxAtomicBufferBindings);
+          return;
+       }
+    } else if ((state->is_version(420, 310) ||
+                state->ARB_shading_language_420pack_enable) &&
+               base_type->is_image()) {
+       assert(ctx->Const.MaxImageUnits <= MAX_IMAGE_UNITS);
+       if (max_index >= ctx->Const.MaxImageUnits) {
+          _mesa_glsl_error(loc, state, "Image binding %d exceeds the "
+                           " maximum number of image units (%d)", max_index,
+                           ctx->Const.MaxImageUnits);
+          return;
+       }
+    } else {
+       _mesa_glsl_error(loc, state,
+                        "the \"binding\" qualifier only applies to uniform "
+                        "blocks, opaque variables, or arrays thereof");
+       return;
+    }
+    var->data.explicit_binding = true;
+    var->data.binding = qual_binding;
+    return;
+ }
+ static glsl_interp_qualifier
+ interpret_interpolation_qualifier(const struct ast_type_qualifier *qual,
+                                   ir_variable_mode mode,
+                                   struct _mesa_glsl_parse_state *state,
+                                   YYLTYPE *loc)
+ {
+    glsl_interp_qualifier interpolation;
+    if (qual->flags.q.flat)
+       interpolation = INTERP_QUALIFIER_FLAT;
+    else if (qual->flags.q.noperspective)
+       interpolation = INTERP_QUALIFIER_NOPERSPECTIVE;
+    else if (qual->flags.q.smooth)
+       interpolation = INTERP_QUALIFIER_SMOOTH;
+    else
+       interpolation = INTERP_QUALIFIER_NONE;
+    if (interpolation != INTERP_QUALIFIER_NONE) {
+       if (mode != ir_var_shader_in && mode != ir_var_shader_out) {
+          _mesa_glsl_error(loc, state,
+                           "interpolation qualifier `%s' can only be applied to "
+                           "shader inputs or outputs.",
+                           interpolation_string(interpolation));
+       }
+       if ((state->stage == MESA_SHADER_VERTEX && mode == ir_var_shader_in) ||
+           (state->stage == MESA_SHADER_FRAGMENT && mode == ir_var_shader_out)) {
+          _mesa_glsl_error(loc, state,
+                           "interpolation qualifier `%s' cannot be applied to "
+                           "vertex shader inputs or fragment shader outputs",
+                           interpolation_string(interpolation));
+       }
+    }
+    return interpolation;
+ }
+ static void
+ apply_explicit_location(const struct ast_type_qualifier *qual,
+                         ir_variable *var,
+                         struct _mesa_glsl_parse_state *state,
+                         YYLTYPE *loc)
+ {
+    bool fail = false;
+    unsigned qual_location;
+    if (!process_qualifier_constant(state, loc, "location", qual->location,
+                                    &qual_location)) {
+       return;
+    }
+    /* Checks for GL_ARB_explicit_uniform_location. */
+    if (qual->flags.q.uniform) {
+       if (!state->check_explicit_uniform_location_allowed(loc, var))
+          return;
+       const struct gl_context *const ctx = state->ctx;
+       unsigned max_loc = qual_location + var->type->uniform_locations() - 1;
+       if (max_loc >= ctx->Const.MaxUserAssignableUniformLocations) {
+          _mesa_glsl_error(loc, state, "location(s) consumed by uniform %s "
+                           ">= MAX_UNIFORM_LOCATIONS (%u)", var->name,
+                           ctx->Const.MaxUserAssignableUniformLocations);
+          return;
+       }
+       var->data.explicit_location = true;
+       var->data.location = qual_location;
+       return;
+    }
+    /* Between GL_ARB_explicit_attrib_location an
+     * GL_ARB_separate_shader_objects, the inputs and outputs of any shader
+     * stage can be assigned explicit locations.  The checking here associates
+     * the correct extension with the correct stage's input / output:
+     *
+     *                     input            output
+     *                     -----            ------
+     * vertex              explicit_loc     sso
+     * tess control        sso              sso
+     * tess eval           sso              sso
+     * geometry            sso              sso
+     * fragment            sso              explicit_loc
+     */
+    switch (state->stage) {
+    case MESA_SHADER_VERTEX:
+       if (var->data.mode == ir_var_shader_in) {
+          if (!state->check_explicit_attrib_location_allowed(loc, var))
+             return;
+          break;
+       }
+       if (var->data.mode == ir_var_shader_out) {
+          if (!state->check_separate_shader_objects_allowed(loc, var))
+             return;
+          break;
+       }
+       fail = true;
+       break;
+    case MESA_SHADER_TESS_CTRL:
+    case MESA_SHADER_TESS_EVAL:
+    case MESA_SHADER_GEOMETRY:
+       if (var->data.mode == ir_var_shader_in || var->data.mode == ir_var_shader_out) {
+          if (!state->check_separate_shader_objects_allowed(loc, var))
+             return;
+          break;
+       }
+       fail = true;
+       break;
+    case MESA_SHADER_FRAGMENT:
+       if (var->data.mode == ir_var_shader_in) {
+          if (!state->check_separate_shader_objects_allowed(loc, var))
+             return;
+          break;
+       }
+       if (var->data.mode == ir_var_shader_out) {
+          if (!state->check_explicit_attrib_location_allowed(loc, var))
+             return;
+          break;
+       }
+       fail = true;
+       break;
+    case MESA_SHADER_COMPUTE:
+       _mesa_glsl_error(loc, state,
+                        "compute shader variables cannot be given "
+                        "explicit locations");
+       return;
+    };
+    if (fail) {
+       _mesa_glsl_error(loc, state,
+                        "%s cannot be given an explicit location in %s shader",
+                        mode_string(var),
+       _mesa_shader_stage_to_string(state->stage));
+    } else {
+       var->data.explicit_location = true;
+       switch (state->stage) {
+       case MESA_SHADER_VERTEX:
+          var->data.location = (var->data.mode == ir_var_shader_in)
+             ? (qual_location + VERT_ATTRIB_GENERIC0)
+             : (qual_location + VARYING_SLOT_VAR0);
+          break;
+       case MESA_SHADER_TESS_CTRL:
+       case MESA_SHADER_TESS_EVAL:
+       case MESA_SHADER_GEOMETRY:
+          if (var->data.patch)
+             var->data.location = qual_location + VARYING_SLOT_PATCH0;
+          else
+             var->data.location = qual_location + VARYING_SLOT_VAR0;
+          break;
+       case MESA_SHADER_FRAGMENT:
+          var->data.location = (var->data.mode == ir_var_shader_out)
+             ? (qual_location + FRAG_RESULT_DATA0)
+             : (qual_location + VARYING_SLOT_VAR0);
+          break;
+       case MESA_SHADER_COMPUTE:
+          assert(!"Unexpected shader type");
+          break;
+       }
+       /* Check if index was set for the uniform instead of the function */
+       if (qual->flags.q.explicit_index && qual->flags.q.subroutine) {
+          _mesa_glsl_error(loc, state, "an index qualifier can only be "
+                           "used with subroutine functions");
+          return;
+       }
+       unsigned qual_index;
+       if (qual->flags.q.explicit_index &&
+           process_qualifier_constant(state, loc, "index", qual->index,
+                                      &qual_index)) {
+          /* From the GLSL 4.30 specification, section 4.4.2 (Output
+           * Layout Qualifiers):
+           *
+           * "It is also a compile-time error if a fragment shader
+           *  sets a layout index to less than 0 or greater than 1."
+           *
+           * Older specifications don't mandate a behavior; we take
+           * this as a clarification and always generate the error.
+           */
+          if (qual_index > 1) {
+             _mesa_glsl_error(loc, state,
+                              "explicit index may only be 0 or 1");
+          } else {
+             var->data.explicit_index = true;
+             var->data.index = qual_index;
+          }
+       }
+    }
+ }
+ static void
+ apply_image_qualifier_to_variable(const struct ast_type_qualifier *qual,
+                                   ir_variable *var,
+                                   struct _mesa_glsl_parse_state *state,
+                                   YYLTYPE *loc)
+ {
+    const glsl_type *base_type = var->type->without_array();
+    if (base_type->is_image()) {
+       if (var->data.mode != ir_var_uniform &&
+           var->data.mode != ir_var_function_in) {
+          _mesa_glsl_error(loc, state, "image variables may only be declared as "
+                           "function parameters or uniform-qualified "
+                           "global variables");
+       }
+       var->data.image_read_only |= qual->flags.q.read_only;
+       var->data.image_write_only |= qual->flags.q.write_only;
+       var->data.image_coherent |= qual->flags.q.coherent;
+       var->data.image_volatile |= qual->flags.q._volatile;
+       var->data.image_restrict |= qual->flags.q.restrict_flag;
+       var->data.read_only = true;
+       if (qual->flags.q.explicit_image_format) {
+          if (var->data.mode == ir_var_function_in) {
+             _mesa_glsl_error(loc, state, "format qualifiers cannot be "
+                              "used on image function parameters");
+          }
+          if (qual->image_base_type != base_type->sampler_type) {
+             _mesa_glsl_error(loc, state, "format qualifier doesn't match the "
+                              "base data type of the image");
+          }
+          var->data.image_format = qual->image_format;
+       } else {
+          if (var->data.mode == ir_var_uniform) {
+             if (state->es_shader) {
+                _mesa_glsl_error(loc, state, "all image uniforms "
+                                 "must have a format layout qualifier");
+             } else if (!qual->flags.q.write_only) {
+                _mesa_glsl_error(loc, state, "image uniforms not qualified with "
+                                 "`writeonly' must have a format layout "
+                                 "qualifier");
+             }
+          }
+          var->data.image_format = GL_NONE;
+       }
+       /* From page 70 of the GLSL ES 3.1 specification:
+        *
+        * "Except for image variables qualified with the format qualifiers
+        *  r32f, r32i, and r32ui, image variables must specify either memory
+        *  qualifier readonly or the memory qualifier writeonly."
+        */
+       if (state->es_shader &&
+           var->data.image_format != GL_R32F &&
+           var->data.image_format != GL_R32I &&
+           var->data.image_format != GL_R32UI &&
+           !var->data.image_read_only &&
+           !var->data.image_write_only) {
+          _mesa_glsl_error(loc, state, "image variables of format other than "
+                           "r32f, r32i or r32ui must be qualified `readonly' or "
+                           "`writeonly'");
+       }
+    } else if (qual->flags.q.read_only ||
+               qual->flags.q.write_only ||
+               qual->flags.q.coherent ||
+               qual->flags.q._volatile ||
+               qual->flags.q.restrict_flag ||
+               qual->flags.q.explicit_image_format) {
+       _mesa_glsl_error(loc, state, "memory qualifiers may only be applied to "
+                        "images");
+    }
+ }
+ static inline const char*
+ get_layout_qualifier_string(bool origin_upper_left, bool pixel_center_integer)
+ {
+    if (origin_upper_left && pixel_center_integer)
+       return "origin_upper_left, pixel_center_integer";
+    else if (origin_upper_left)
+       return "origin_upper_left";
+    else if (pixel_center_integer)
+       return "pixel_center_integer";
+    else
+       return " ";
+ }
+ static inline bool
+ is_conflicting_fragcoord_redeclaration(struct _mesa_glsl_parse_state *state,
+                                        const struct ast_type_qualifier *qual)
+ {
+    /* If gl_FragCoord was previously declared, and the qualifiers were
+     * different in any way, return true.
+     */
+    if (state->fs_redeclares_gl_fragcoord) {
+       return (state->fs_pixel_center_integer != qual->flags.q.pixel_center_integer
+          || state->fs_origin_upper_left != qual->flags.q.origin_upper_left);
+    }
+    return false;
+ }
+ static inline void
+ validate_array_dimensions(const glsl_type *t,
+                           struct _mesa_glsl_parse_state *state,
+                           YYLTYPE *loc) {
+    if (t->is_array()) {
+       t = t->fields.array;
+       while (t->is_array()) {
+          if (t->is_unsized_array()) {
+             _mesa_glsl_error(loc, state,
+                              "only the outermost array dimension can "
+                              "be unsized",
+                              t->name);
+             break;
+          }
+          t = t->fields.array;
+       }
+    }
+ }
+ static void
+ apply_layout_qualifier_to_variable(const struct ast_type_qualifier *qual,
+                                    ir_variable *var,
+                                    struct _mesa_glsl_parse_state *state,
+                                    YYLTYPE *loc)
+ {
+    if (var->name != NULL && strcmp(var->name, "gl_FragCoord") == 0) {
+       /* Section 4.3.8.1, page 39 of GLSL 1.50 spec says:
+        *
+        *    "Within any shader, the first redeclarations of gl_FragCoord
+        *     must appear before any use of gl_FragCoord."
+        *
+        * Generate a compiler error if above condition is not met by the
+        * fragment shader.
+        */
+       ir_variable *earlier = state->symbols->get_variable("gl_FragCoord");
+       if (earlier != NULL &&
+           earlier->data.used &&
+           !state->fs_redeclares_gl_fragcoord) {
+          _mesa_glsl_error(loc, state,
+                           "gl_FragCoord used before its first redeclaration "
+                           "in fragment shader");
+       }
+       /* Make sure all gl_FragCoord redeclarations specify the same layout
+        * qualifiers.
+        */
+       if (is_conflicting_fragcoord_redeclaration(state, qual)) {
+          const char *const qual_string =
+             get_layout_qualifier_string(qual->flags.q.origin_upper_left,
+                                         qual->flags.q.pixel_center_integer);
+          const char *const state_string =
+             get_layout_qualifier_string(state->fs_origin_upper_left,
+                                         state->fs_pixel_center_integer);
+          _mesa_glsl_error(loc, state,
+                           "gl_FragCoord redeclared with different layout "
+                           "qualifiers (%s) and (%s) ",
+                           state_string,
+                           qual_string);
+       }
+       state->fs_origin_upper_left = qual->flags.q.origin_upper_left;
+       state->fs_pixel_center_integer = qual->flags.q.pixel_center_integer;
+       state->fs_redeclares_gl_fragcoord_with_no_layout_qualifiers =
+          !qual->flags.q.origin_upper_left && !qual->flags.q.pixel_center_integer;
+       state->fs_redeclares_gl_fragcoord =
+          state->fs_origin_upper_left ||
+          state->fs_pixel_center_integer ||
+          state->fs_redeclares_gl_fragcoord_with_no_layout_qualifiers;
+    }
+    var->data.pixel_center_integer = qual->flags.q.pixel_center_integer;
+    var->data.origin_upper_left = qual->flags.q.origin_upper_left;
+    if ((qual->flags.q.origin_upper_left || qual->flags.q.pixel_center_integer)
+        && (strcmp(var->name, "gl_FragCoord") != 0)) {
+       const char *const qual_string = (qual->flags.q.origin_upper_left)
+          ? "origin_upper_left" : "pixel_center_integer";
+       _mesa_glsl_error(loc, state,
+                      "layout qualifier `%s' can only be applied to "
+                      "fragment shader input `gl_FragCoord'",
+                      qual_string);
+    }
+    if (qual->flags.q.explicit_location) {
+       apply_explicit_location(qual, var, state, loc);
+    } else if (qual->flags.q.explicit_index) {
+       if (!qual->flags.q.subroutine_def)
+          _mesa_glsl_error(loc, state,
+                           "explicit index requires explicit location");
+    }
+    if (qual->flags.q.explicit_binding) {
+       apply_explicit_binding(state, loc, var, var->type, qual);
+    }
+    if (state->stage == MESA_SHADER_GEOMETRY &&
+        qual->flags.q.out && qual->flags.q.stream) {
+       unsigned qual_stream;
+       if (process_qualifier_constant(state, loc, "stream", qual->stream,
+                                      &qual_stream) &&
+           validate_stream_qualifier(loc, state, qual_stream)) {
+          var->data.stream = qual_stream;
+       }
+    }
+    if (var->type->contains_atomic()) {
+       if (var->data.mode == ir_var_uniform) {
+          if (var->data.explicit_binding) {
+             unsigned *offset =
+                &state->atomic_counter_offsets[var->data.binding];
+             if (*offset % ATOMIC_COUNTER_SIZE)
+                _mesa_glsl_error(loc, state,
+                                 "misaligned atomic counter offset");
+             var->data.offset = *offset;
+             *offset += var->type->atomic_size();
+          } else {
+             _mesa_glsl_error(loc, state,
+                              "atomic counters require explicit binding point");
+          }
+       } else if (var->data.mode != ir_var_function_in) {
+          _mesa_glsl_error(loc, state, "atomic counters may only be declared as "
+                           "function parameters or uniform-qualified "
+                           "global variables");
+       }
+    }
+    /* Is the 'layout' keyword used with parameters that allow relaxed checking.
+     * Many implementations of GL_ARB_fragment_coord_conventions_enable and some
+     * implementations (only Mesa?) GL_ARB_explicit_attrib_location_enable
+     * allowed the layout qualifier to be used with 'varying' and 'attribute'.
+     * These extensions and all following extensions that add the 'layout'
+     * keyword have been modified to require the use of 'in' or 'out'.
+     *
+     * The following extension do not allow the deprecated keywords:
+     *
+     *    GL_AMD_conservative_depth
+     *    GL_ARB_conservative_depth
+     *    GL_ARB_gpu_shader5
+     *    GL_ARB_separate_shader_objects
+     *    GL_ARB_tessellation_shader
+     *    GL_ARB_transform_feedback3
+     *    GL_ARB_uniform_buffer_object
+     *
+     * It is unknown whether GL_EXT_shader_image_load_store or GL_NV_gpu_shader5
+     * allow layout with the deprecated keywords.
+     */
+    const bool relaxed_layout_qualifier_checking =
+       state->ARB_fragment_coord_conventions_enable;
+    const bool uses_deprecated_qualifier = qual->flags.q.attribute
+       || qual->flags.q.varying;
+    if (qual->has_layout() && uses_deprecated_qualifier) {
+       if (relaxed_layout_qualifier_checking) {
+          _mesa_glsl_warning(loc, state,
+                             "`layout' qualifier may not be used with "
+                             "`attribute' or `varying'");
+       } else {
+          _mesa_glsl_error(loc, state,
+                           "`layout' qualifier may not be used with "
+                           "`attribute' or `varying'");
+       }
+    }
+    /* Layout qualifiers for gl_FragDepth, which are enabled by extension
+     * AMD_conservative_depth.
+     */
+    int depth_layout_count = qual->flags.q.depth_any
+       + qual->flags.q.depth_greater
+       + qual->flags.q.depth_less
+       + qual->flags.q.depth_unchanged;
+    if (depth_layout_count > 0
+        && !state->AMD_conservative_depth_enable
+        && !state->ARB_conservative_depth_enable) {
+        _mesa_glsl_error(loc, state,
+                         "extension GL_AMD_conservative_depth or "
+                         "GL_ARB_conservative_depth must be enabled "
+                         "to use depth layout qualifiers");
+    } else if (depth_layout_count > 0
+               && strcmp(var->name, "gl_FragDepth") != 0) {
+        _mesa_glsl_error(loc, state,
+                         "depth layout qualifiers can be applied only to "
+                         "gl_FragDepth");
+    } else if (depth_layout_count > 1
+               && strcmp(var->name, "gl_FragDepth") == 0) {
+       _mesa_glsl_error(loc, state,
+                        "at most one depth layout qualifier can be applied to "
+                        "gl_FragDepth");
+    }
+    if (qual->flags.q.depth_any)
+       var->data.depth_layout = ir_depth_layout_any;
+    else if (qual->flags.q.depth_greater)
+       var->data.depth_layout = ir_depth_layout_greater;
+    else if (qual->flags.q.depth_less)
+       var->data.depth_layout = ir_depth_layout_less;
+    else if (qual->flags.q.depth_unchanged)
+        var->data.depth_layout = ir_depth_layout_unchanged;
+    else
+        var->data.depth_layout = ir_depth_layout_none;
+    if (qual->flags.q.std140 ||
+        qual->flags.q.std430 ||
+        qual->flags.q.packed ||
+        qual->flags.q.shared) {
+       _mesa_glsl_error(loc, state,
+                        "uniform and shader storage block layout qualifiers "
+                        "std140, std430, packed, and shared can only be "
+                        "applied to uniform or shader storage blocks, not "
+                        "members");
+    }
+    if (qual->flags.q.row_major || qual->flags.q.column_major) {
+       validate_matrix_layout_for_type(state, loc, var->type, var);
+    }
+    /* From section 4.4.1.3 of the GLSL 4.50 specification (Fragment Shader
+     * Inputs):
+     *
+     *  "Fragment shaders also allow the following layout qualifier on in only
+     *   (not with variable declarations)
+     *     layout-qualifier-id
+     *        early_fragment_tests
+     *   [...]"
+     */
+    if (qual->flags.q.early_fragment_tests) {
+       _mesa_glsl_error(loc, state, "early_fragment_tests layout qualifier only "
+                        "valid in fragment shader input layout declaration.");
+    }
+ }
+ static void
+ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
+                                  ir_variable *var,
+                                  struct _mesa_glsl_parse_state *state,
+                                  YYLTYPE *loc,
+                                  bool is_parameter)
+ {
+    STATIC_ASSERT(sizeof(qual->flags.q) <= sizeof(qual->flags.i));
+    if (qual->flags.q.invariant) {
+       if (var->data.used) {
+          _mesa_glsl_error(loc, state,
+                           "variable `%s' may not be redeclared "
+                           "`invariant' after being used",
+                           var->name);
+       } else {
+          var->data.invariant = 1;
+       }
+    }
+    if (qual->flags.q.precise) {
+       if (var->data.used) {
+          _mesa_glsl_error(loc, state,
+                           "variable `%s' may not be redeclared "
+                           "`precise' after being used",
+                           var->name);
+       } else {
+          var->data.precise = 1;
+       }
+    }
+    if (qual->flags.q.subroutine && !qual->flags.q.uniform) {
+       _mesa_glsl_error(loc, state,
+                        "`subroutine' may only be applied to uniforms, "
+                        "subroutine type declarations, or function definitions");
+    }
+    if (qual->flags.q.constant || qual->flags.q.attribute
+        || qual->flags.q.uniform
+        || (qual->flags.q.varying && (state->stage == MESA_SHADER_FRAGMENT)))
+       var->data.read_only = 1;
+    if (qual->flags.q.centroid)
+       var->data.centroid = 1;
+    if (qual->flags.q.sample)
+       var->data.sample = 1;
+    /* Precision qualifiers do not hold any meaning in Desktop GLSL */
+    if (state->es_shader) {
+       var->data.precision =
+          select_gles_precision(qual->precision, var->type, state, loc);
+    }
+    if (qual->flags.q.patch)
+       var->data.patch = 1;
+    if (qual->flags.q.attribute && state->stage != MESA_SHADER_VERTEX) {
+       var->type = glsl_type::error_type;
+       _mesa_glsl_error(loc, state,
+                        "`attribute' variables may not be declared in the "
+                        "%s shader",
+                        _mesa_shader_stage_to_string(state->stage));
+    }
+    /* Disallow layout qualifiers which may only appear on layout declarations. */
+    if (qual->flags.q.prim_type) {
+       _mesa_glsl_error(loc, state,
+                        "Primitive type may only be specified on GS input or output "
+                        "layout declaration, not on variables.");
+    }
+    /* Section 6.1.1 (Function Calling Conventions) of the GLSL 1.10 spec says:
+     *
+     *     "However, the const qualifier cannot be used with out or inout."
+     *
+     * The same section of the GLSL 4.40 spec further clarifies this saying:
+     *
+     *     "The const qualifier cannot be used with out or inout, or a
+     *     compile-time error results."
+     */
+    if (is_parameter && qual->flags.q.constant && qual->flags.q.out) {
+       _mesa_glsl_error(loc, state,
+                        "`const' may not be applied to `out' or `inout' "
+                        "function parameters");
+    }
+    /* If there is no qualifier that changes the mode of the variable, leave
+     * the setting alone.
+     */
+    assert(var->data.mode != ir_var_temporary);
+    if (qual->flags.q.in && qual->flags.q.out)
+       var->data.mode = ir_var_function_inout;
+    else if (qual->flags.q.in)
+       var->data.mode = is_parameter ? ir_var_function_in : ir_var_shader_in;
+    else if (qual->flags.q.attribute
+           || (qual->flags.q.varying && (state->stage == MESA_SHADER_FRAGMENT)))
+       var->data.mode = ir_var_shader_in;
+    else if (qual->flags.q.out)
+       var->data.mode = is_parameter ? ir_var_function_out : ir_var_shader_out;
+    else if (qual->flags.q.varying && (state->stage == MESA_SHADER_VERTEX))
+       var->data.mode = ir_var_shader_out;
+    else if (qual->flags.q.uniform)
+       var->data.mode = ir_var_uniform;
+    else if (qual->flags.q.buffer)
+       var->data.mode = ir_var_shader_storage;
+    else if (qual->flags.q.shared_storage)
+       var->data.mode = ir_var_shader_shared;
+    if (!is_parameter && is_varying_var(var, state->stage)) {
+       /* User-defined ins/outs are not permitted in compute shaders. */
+       if (state->stage == MESA_SHADER_COMPUTE) {
+          _mesa_glsl_error(loc, state,
+                           "user-defined input and output variables are not "
+                           "permitted in compute shaders");
+       }
+       /* This variable is being used to link data between shader stages (in
+        * pre-glsl-1.30 parlance, it's a "varying").  Check that it has a type
+        * that is allowed for such purposes.
+        *
+        * From page 25 (page 31 of the PDF) of the GLSL 1.10 spec:
+        *
+        *     "The varying qualifier can be used only with the data types
+        *     float, vec2, vec3, vec4, mat2, mat3, and mat4, or arrays of
+        *     these."
+        *
+        * This was relaxed in GLSL version 1.30 and GLSL ES version 3.00.  From
+        * page 31 (page 37 of the PDF) of the GLSL 1.30 spec:
+        *
+        *     "Fragment inputs can only be signed and unsigned integers and
+        *     integer vectors, float, floating-point vectors, matrices, or
+        *     arrays of these. Structures cannot be input.
+        *
+        * Similar text exists in the section on vertex shader outputs.
+        *
+        * Similar text exists in the GLSL ES 3.00 spec, except that the GLSL ES
+        * 3.00 spec allows structs as well.  Varying structs are also allowed
+        * in GLSL 1.50.
+        */
+       switch (var->type->get_scalar_type()->base_type) {
+       case GLSL_TYPE_FLOAT:
+          /* Ok in all GLSL versions */
+          break;
+       case GLSL_TYPE_UINT:
+       case GLSL_TYPE_INT:
+          if (state->is_version(130, 300))
+             break;
+          _mesa_glsl_error(loc, state,
+                           "varying variables must be of base type float in %s",
+                           state->get_version_string());
+          break;
+       case GLSL_TYPE_STRUCT:
+          if (state->is_version(150, 300))
+             break;
+          _mesa_glsl_error(loc, state,
+                           "varying variables may not be of type struct");
+          break;
+       case GLSL_TYPE_DOUBLE:
+          break;
+       default:
+          _mesa_glsl_error(loc, state, "illegal type for a varying variable");
+          break;
+       }
+    }
+    if (state->all_invariant && (state->current_function == NULL)) {
+       switch (state->stage) {
+       case MESA_SHADER_VERTEX:
+          if (var->data.mode == ir_var_shader_out)
+             var->data.invariant = true;
+          break;
+       case MESA_SHADER_TESS_CTRL:
+       case MESA_SHADER_TESS_EVAL:
+       case MESA_SHADER_GEOMETRY:
+          if ((var->data.mode == ir_var_shader_in)
+              || (var->data.mode == ir_var_shader_out))
+             var->data.invariant = true;
+          break;
+       case MESA_SHADER_FRAGMENT:
+          if (var->data.mode == ir_var_shader_in)
+             var->data.invariant = true;
+          break;
+       case MESA_SHADER_COMPUTE:
+          /* Invariance isn't meaningful in compute shaders. */
+          break;
+       }
+    }
+    var->data.interpolation =
+       interpret_interpolation_qualifier(qual, (ir_variable_mode) var->data.mode,
+                                         state, loc);
+    /* Does the declaration use the deprecated 'attribute' or 'varying'
+     * keywords?
+     */
+    const bool uses_deprecated_qualifier = qual->flags.q.attribute
+       || qual->flags.q.varying;
+    /* Validate auxiliary storage qualifiers */
+    /* From section 4.3.4 of the GLSL 1.30 spec:
+     *    "It is an error to use centroid in in a vertex shader."
+     *
+     * From section 4.3.4 of the GLSL ES 3.00 spec:
+     *    "It is an error to use centroid in or interpolation qualifiers in
+     *    a vertex shader input."
+     */
+    /* Section 4.3.6 of the GLSL 1.30 specification states:
+     * "It is an error to use centroid out in a fragment shader."
+     *
+     * The GL_ARB_shading_language_420pack extension specification states:
+     * "It is an error to use auxiliary storage qualifiers or interpolation
+     *  qualifiers on an output in a fragment shader."
+     */
+    if (qual->flags.q.sample && (!is_varying_var(var, state->stage) || uses_deprecated_qualifier)) {
+       _mesa_glsl_error(loc, state,
+                        "sample qualifier may only be used on `in` or `out` "
+                        "variables between shader stages");
+    }
+    if (qual->flags.q.centroid && !is_varying_var(var, state->stage)) {
+       _mesa_glsl_error(loc, state,
+                        "centroid qualifier may only be used with `in', "
+                        "`out' or `varying' variables between shader stages");
+    }
+    if (qual->flags.q.shared_storage && state->stage != MESA_SHADER_COMPUTE) {
+       _mesa_glsl_error(loc, state,
+                        "the shared storage qualifiers can only be used with "
+                        "compute shaders");
+    }
+    apply_image_qualifier_to_variable(qual, var, state, loc);
+ }
+ /**
+  * Get the variable that is being redeclared by this declaration
+  *
+  * Semantic checks to verify the validity of the redeclaration are also
+  * performed.  If semantic checks fail, compilation error will be emitted via
+  * \c _mesa_glsl_error, but a non-\c NULL pointer will still be returned.
+  *
+  * \returns
+  * A pointer to an existing variable in the current scope if the declaration
+  * is a redeclaration, \c NULL otherwise.
+  */
+ static ir_variable *
+ get_variable_being_redeclared(ir_variable *var, YYLTYPE loc,
+                               struct _mesa_glsl_parse_state *state,
+                               bool allow_all_redeclarations)
+ {
+    /* Check if this declaration is actually a re-declaration, either to
+     * resize an array or add qualifiers to an existing variable.
+     *
+     * This is allowed for variables in the current scope, or when at
+     * global scope (for built-ins in the implicit outer scope).
+     */
+    ir_variable *earlier = state->symbols->get_variable(var->name);
+    if (earlier == NULL ||
+        (state->current_function != NULL &&
+        !state->symbols->name_declared_this_scope(var->name))) {
+       return NULL;
+    }
+    /* From page 24 (page 30 of the PDF) of the GLSL 1.50 spec,
+     *
+     * "It is legal to declare an array without a size and then
+     *  later re-declare the same name as an array of the same
+     *  type and specify a size."
+     */
+    if (earlier->type->is_unsized_array() && var->type->is_array()
+        && (var->type->fields.array == earlier->type->fields.array)) {
+       /* FINISHME: This doesn't match the qualifiers on the two
+        * FINISHME: declarations.  It's not 100% clear whether this is
+        * FINISHME: required or not.
+        */
+       const unsigned size = unsigned(var->type->array_size());
+       check_builtin_array_max_size(var->name, size, loc, state);
+       if ((size > 0) && (size <= earlier->data.max_array_access)) {
+          _mesa_glsl_error(& loc, state, "array size must be > %u due to "
+                           "previous access",
+                           earlier->data.max_array_access);
+       }
+       earlier->type = var->type;
+       delete var;
+       var = NULL;
+    } else if ((state->ARB_fragment_coord_conventions_enable ||
+               state->is_version(150, 0))
+               && strcmp(var->name, "gl_FragCoord") == 0
+               && earlier->type == var->type
+               && var->data.mode == ir_var_shader_in) {
+       /* Allow redeclaration of gl_FragCoord for ARB_fcc layout
+        * qualifiers.
+        */
+       earlier->data.origin_upper_left = var->data.origin_upper_left;
+       earlier->data.pixel_center_integer = var->data.pixel_center_integer;
+       /* According to section 4.3.7 of the GLSL 1.30 spec,
+        * the following built-in varaibles can be redeclared with an
+        * interpolation qualifier:
+        *    * gl_FrontColor
+        *    * gl_BackColor
+        *    * gl_FrontSecondaryColor
+        *    * gl_BackSecondaryColor
+        *    * gl_Color
+        *    * gl_SecondaryColor
+        */
+    } else if (state->is_version(130, 0)
+               && (strcmp(var->name, "gl_FrontColor") == 0
+                   || strcmp(var->name, "gl_BackColor") == 0
+                   || strcmp(var->name, "gl_FrontSecondaryColor") == 0
+                   || strcmp(var->name, "gl_BackSecondaryColor") == 0
+                   || strcmp(var->name, "gl_Color") == 0
+                   || strcmp(var->name, "gl_SecondaryColor") == 0)
+               && earlier->type == var->type
+               && earlier->data.mode == var->data.mode) {
+       earlier->data.interpolation = var->data.interpolation;
+       /* Layout qualifiers for gl_FragDepth. */
+    } else if ((state->AMD_conservative_depth_enable ||
+                state->ARB_conservative_depth_enable)
+               && strcmp(var->name, "gl_FragDepth") == 0
+               && earlier->type == var->type
+               && earlier->data.mode == var->data.mode) {
+       /** From the AMD_conservative_depth spec:
+        *     Within any shader, the first redeclarations of gl_FragDepth
+        *     must appear before any use of gl_FragDepth.
+        */
+       if (earlier->data.used) {
+          _mesa_glsl_error(&loc, state,
+                           "the first redeclaration of gl_FragDepth "
+                           "must appear before any use of gl_FragDepth");
+       }
+       /* Prevent inconsistent redeclaration of depth layout qualifier. */
+       if (earlier->data.depth_layout != ir_depth_layout_none
+           && earlier->data.depth_layout != var->data.depth_layout) {
+             _mesa_glsl_error(&loc, state,
+                              "gl_FragDepth: depth layout is declared here "
+                              "as '%s, but it was previously declared as "
+                              "'%s'",
+                              depth_layout_string(var->data.depth_layout),
+                              depth_layout_string(earlier->data.depth_layout));
+       }
+       earlier->data.depth_layout = var->data.depth_layout;
+    } else if (allow_all_redeclarations) {
+       if (earlier->data.mode != var->data.mode) {
+          _mesa_glsl_error(&loc, state,
+                           "redeclaration of `%s' with incorrect qualifiers",
+                           var->name);
+       } else if (earlier->type != var->type) {
+          _mesa_glsl_error(&loc, state,
+                           "redeclaration of `%s' has incorrect type",
+                           var->name);
+       }
+    } else {
+       _mesa_glsl_error(&loc, state, "`%s' redeclared", var->name);
+    }
+    return earlier;
+ }
+ /**
+  * Generate the IR for an initializer in a variable declaration
+  */
+ ir_rvalue *
+ process_initializer(ir_variable *var, ast_declaration *decl,
+                   ast_fully_specified_type *type,
+                   exec_list *initializer_instructions,
+                   struct _mesa_glsl_parse_state *state)
+ {
+    ir_rvalue *result = NULL;
+    YYLTYPE initializer_loc = decl->initializer->get_location();
+    /* From page 24 (page 30 of the PDF) of the GLSL 1.10 spec:
+     *
+     *    "All uniform variables are read-only and are initialized either
+     *    directly by an application via API commands, or indirectly by
+     *    OpenGL."
+     */
+    if (var->data.mode == ir_var_uniform) {
+       state->check_version(120, 0, &initializer_loc,
+                            "cannot initialize uniform %s",
+                            var->name);
+    }
+    /* Section 4.3.7 "Buffer Variables" of the GLSL 4.30 spec:
+     *
+     *    "Buffer variables cannot have initializers."
+     */
+    if (var->data.mode == ir_var_shader_storage) {
+       _mesa_glsl_error(&initializer_loc, state,
+                        "cannot initialize buffer variable %s",
+                        var->name);
+    }
+    /* From section 4.1.7 of the GLSL 4.40 spec:
+     *
+     *    "Opaque variables [...] are initialized only through the
+     *     OpenGL API; they cannot be declared with an initializer in a
+     *     shader."
+     */
+    if (var->type->contains_opaque()) {
+       _mesa_glsl_error(&initializer_loc, state,
+                        "cannot initialize opaque variable %s",
+                        var->name);
+    }
+    if ((var->data.mode == ir_var_shader_in) && (state->current_function == NULL)) {
+       _mesa_glsl_error(&initializer_loc, state,
+                        "cannot initialize %s shader input / %s %s",
+                        _mesa_shader_stage_to_string(state->stage),
+                        (state->stage == MESA_SHADER_VERTEX)
+                        ? "attribute" : "varying",
+                        var->name);
+    }
+    if (var->data.mode == ir_var_shader_out && state->current_function == NULL) {
+       _mesa_glsl_error(&initializer_loc, state,
+                        "cannot initialize %s shader output %s",
+                        _mesa_shader_stage_to_string(state->stage),
+                        var->name);
+    }
+    /* If the initializer is an ast_aggregate_initializer, recursively store
+     * type information from the LHS into it, so that its hir() function can do
+     * type checking.
+     */
+    if (decl->initializer->oper == ast_aggregate)
+       _mesa_ast_set_aggregate_type(var->type, decl->initializer);
+    ir_dereference *const lhs = new(state) ir_dereference_variable(var);
+    ir_rvalue *rhs = decl->initializer->hir(initializer_instructions, state);
+    /* Calculate the constant value if this is a const or uniform
+     * declaration.
+     *
+     * Section 4.3 (Storage Qualifiers) of the GLSL ES 1.00.17 spec says:
+     *
+     *     "Declarations of globals without a storage qualifier, or with
+     *     just the const qualifier, may include initializers, in which case
+     *     they will be initialized before the first line of main() is
+     *     executed.  Such initializers must be a constant expression."
+     *
+     * The same section of the GLSL ES 3.00.4 spec has similar language.
+     */
+    if (type->qualifier.flags.q.constant
+        || type->qualifier.flags.q.uniform
+        || (state->es_shader && state->current_function == NULL)) {
+       ir_rvalue *new_rhs = validate_assignment(state, initializer_loc,
+                                                lhs, rhs, true);
+       if (new_rhs != NULL) {
+          rhs = new_rhs;
+          /* Section 4.3.3 (Constant Expressions) of the GLSL ES 3.00.4 spec
+           * says:
+           *
+           *     "A constant expression is one of
+           *
+           *        ...
+           *
+           *        - an expression formed by an operator on operands that are
+           *          all constant expressions, including getting an element of
+           *          a constant array, or a field of a constant structure, or
+           *          components of a constant vector.  However, the sequence
+           *          operator ( , ) and the assignment operators ( =, +=, ...)
+           *          are not included in the operators that can create a
+           *          constant expression."
+           *
+           * Section 12.43 (Sequence operator and constant expressions) says:
+           *
+           *     "Should the following construct be allowed?
+           *
+           *         float a[2,3];
+           *
+           *     The expression within the brackets uses the sequence operator
+           *     (',') and returns the integer 3 so the construct is declaring
+           *     a single-dimensional array of size 3.  In some languages, the
+           *     construct declares a two-dimensional array.  It would be
+           *     preferable to make this construct illegal to avoid confusion.
+           *
+           *     One possibility is to change the definition of the sequence
+           *     operator so that it does not return a constant-expression and
+           *     hence cannot be used to declare an array size.
+           *
+           *     RESOLUTION: The result of a sequence operator is not a
+           *     constant-expression."
+           *
+           * Section 4.3.3 (Constant Expressions) of the GLSL 4.30.9 spec
+           * contains language almost identical to the section 4.3.3 in the
+           * GLSL ES 3.00.4 spec.  This is a new limitation for these GLSL
+           * versions.
+           */
+          ir_constant *constant_value = rhs->constant_expression_value();
+          if (!constant_value ||
+              (state->is_version(430, 300) &&
+               decl->initializer->has_sequence_subexpression())) {
+             const char *const variable_mode =
+                (type->qualifier.flags.q.constant)
+                ? "const"
+                : ((type->qualifier.flags.q.uniform) ? "uniform" : "global");
+             /* If ARB_shading_language_420pack is enabled, initializers of
+              * const-qualified local variables do not have to be constant
+              * expressions. Const-qualified global variables must still be
+              * initialized with constant expressions.
+              */
+             if (!state->has_420pack()
+                 || state->current_function == NULL) {
+                _mesa_glsl_error(& initializer_loc, state,
+                                 "initializer of %s variable `%s' must be a "
+                                 "constant expression",
+                                 variable_mode,
+                                 decl->identifier);
+                if (var->type->is_numeric()) {
+                   /* Reduce cascading errors. */
+                   var->constant_value = type->qualifier.flags.q.constant
+                      ? ir_constant::zero(state, var->type) : NULL;
+                }
+             }
+          } else {
+             rhs = constant_value;
+             var->constant_value = type->qualifier.flags.q.constant
+                ? constant_value : NULL;
+          }
+       } else {
+          if (var->type->is_numeric()) {
+             /* Reduce cascading errors. */
+             var->constant_value = type->qualifier.flags.q.constant
+                ? ir_constant::zero(state, var->type) : NULL;
+          }
+       }
+    }
+    if (rhs && !rhs->type->is_error()) {
+       bool temp = var->data.read_only;
+       if (type->qualifier.flags.q.constant)
+          var->data.read_only = false;
+       /* Never emit code to initialize a uniform.
+        */
+       const glsl_type *initializer_type;
+       if (!type->qualifier.flags.q.uniform) {
+          do_assignment(initializer_instructions, state,
+                        NULL,
+                        lhs, rhs,
+                        &result, true,
+                        true,
+                        type->get_location());
+          initializer_type = result->type;
+       } else
+          initializer_type = rhs->type;
+       var->constant_initializer = rhs->constant_expression_value();
+       var->data.has_initializer = true;
+       /* If the declared variable is an unsized array, it must inherrit
+        * its full type from the initializer.  A declaration such as
+        *
+        *     uniform float a[] = float[](1.0, 2.0, 3.0, 3.0);
+        *
+        * becomes
+        *
+        *     uniform float a[4] = float[](1.0, 2.0, 3.0, 3.0);
+        *
+        * The assignment generated in the if-statement (below) will also
+        * automatically handle this case for non-uniforms.
+        *
+        * If the declared variable is not an array, the types must
+        * already match exactly.  As a result, the type assignment
+        * here can be done unconditionally.  For non-uniforms the call
+        * to do_assignment can change the type of the initializer (via
+        * the implicit conversion rules).  For uniforms the initializer
+        * must be a constant expression, and the type of that expression
+        * was validated above.
+        */
+       var->type = initializer_type;
+       var->data.read_only = temp;
+    }
+    return result;
+ }
+ static void
+ validate_layout_qualifier_vertex_count(struct _mesa_glsl_parse_state *state,
+                                        YYLTYPE loc, ir_variable *var,
+                                        unsigned num_vertices,
+                                        unsigned *size,
+                                        const char *var_category)
+ {
+    if (var->type->is_unsized_array()) {
+       /* Section 4.3.8.1 (Input Layout Qualifiers) of the GLSL 1.50 spec says:
+        *
+        *   All geometry shader input unsized array declarations will be
+        *   sized by an earlier input layout qualifier, when present, as per
+        *   the following table.
+        *
+        * Followed by a table mapping each allowed input layout qualifier to
+        * the corresponding input length.
+        *
+        * Similarly for tessellation control shader outputs.
+        */
+       if (num_vertices != 0)
+          var->type = glsl_type::get_array_instance(var->type->fields.array,
+                                                    num_vertices);
+    } else {
+       /* Section 4.3.8.1 (Input Layout Qualifiers) of the GLSL 1.50 spec
+        * includes the following examples of compile-time errors:
+        *
+        *   // code sequence within one shader...
+        *   in vec4 Color1[];    // size unknown
+        *   ...Color1.length()...// illegal, length() unknown
+        *   in vec4 Color2[2];   // size is 2
+        *   ...Color1.length()...// illegal, Color1 still has no size
+        *   in vec4 Color3[3];   // illegal, input sizes are inconsistent
+        *   layout(lines) in;    // legal, input size is 2, matching
+        *   in vec4 Color4[3];   // illegal, contradicts layout
+        *   ...
+        *
+        * To detect the case illustrated by Color3, we verify that the size of
+        * an explicitly-sized array matches the size of any previously declared
+        * explicitly-sized array.  To detect the case illustrated by Color4, we
+        * verify that the size of an explicitly-sized array is consistent with
+        * any previously declared input layout.
+        */
+       if (num_vertices != 0 && var->type->length != num_vertices) {
+          _mesa_glsl_error(&loc, state,
+                           "%s size contradicts previously declared layout "
+                           "(size is %u, but layout requires a size of %u)",
+                           var_category, var->type->length, num_vertices);
+       } else if (*size != 0 && var->type->length != *size) {
+          _mesa_glsl_error(&loc, state,
+                           "%s sizes are inconsistent (size is %u, but a "
+                           "previous declaration has size %u)",
+                           var_category, var->type->length, *size);
+       } else {
+          *size = var->type->length;
+       }
+    }
+ }
+ static void
+ handle_tess_ctrl_shader_output_decl(struct _mesa_glsl_parse_state *state,
+                                     YYLTYPE loc, ir_variable *var)
+ {
+    unsigned num_vertices = 0;
+    if (state->tcs_output_vertices_specified) {
+       if (!state->out_qualifier->vertices->
+              process_qualifier_constant(state, "vertices",
+                                         &num_vertices, false)) {
+          return;
+       }
+       if (num_vertices > state->Const.MaxPatchVertices) {
+          _mesa_glsl_error(&loc, state, "vertices (%d) exceeds "
+                           "GL_MAX_PATCH_VERTICES", num_vertices);
+          return;
+       }
+    }
+    if (!var->type->is_array() && !var->data.patch) {
+       _mesa_glsl_error(&loc, state,
+                        "tessellation control shader outputs must be arrays");
+       /* To avoid cascading failures, short circuit the checks below. */
+       return;
+    }
+    if (var->data.patch)
+       return;
+    validate_layout_qualifier_vertex_count(state, loc, var, num_vertices,
+                                           &state->tcs_output_size,
+                                           "tessellation control shader output");
+ }
+ /**
+  * Do additional processing necessary for tessellation control/evaluation shader
+  * input declarations. This covers both interface block arrays and bare input
+  * variables.
+  */
+ static void
+ handle_tess_shader_input_decl(struct _mesa_glsl_parse_state *state,
+                               YYLTYPE loc, ir_variable *var)
+ {
+    if (!var->type->is_array() && !var->data.patch) {
+       _mesa_glsl_error(&loc, state,
+                        "per-vertex tessellation shader inputs must be arrays");
+       /* Avoid cascading failures. */
+       return;
+    }
+    if (var->data.patch)
+       return;
+    /* Unsized arrays are implicitly sized to gl_MaxPatchVertices. */
+    if (var->type->is_unsized_array()) {
+       var->type = glsl_type::get_array_instance(var->type->fields.array,
+             state->Const.MaxPatchVertices);
+    }
+ }
+ /**
+  * Do additional processing necessary for geometry shader input declarations
+  * (this covers both interface blocks arrays and bare input variables).
+  */
+ static void
+ handle_geometry_shader_input_decl(struct _mesa_glsl_parse_state *state,
+                                   YYLTYPE loc, ir_variable *var)
+ {
+    unsigned num_vertices = 0;
+    if (state->gs_input_prim_type_specified) {
+       num_vertices = vertices_per_prim(state->in_qualifier->prim_type);
+    }
+    /* Geometry shader input variables must be arrays.  Caller should have
+     * reported an error for this.
+     */
+    if (!var->type->is_array()) {
+       assert(state->error);
+       /* To avoid cascading failures, short circuit the checks below. */
+       return;
+    }
+    validate_layout_qualifier_vertex_count(state, loc, var, num_vertices,
+                                           &state->gs_input_size,
+                                           "geometry shader input");
+ }
+ void
+ validate_identifier(const char *identifier, YYLTYPE loc,
+                     struct _mesa_glsl_parse_state *state)
+ {
+    /* From page 15 (page 21 of the PDF) of the GLSL 1.10 spec,
+     *
+     *   "Identifiers starting with "gl_" are reserved for use by
+     *   OpenGL, and may not be declared in a shader as either a
+     *   variable or a function."
+     */
+    if (is_gl_identifier(identifier)) {
+       _mesa_glsl_error(&loc, state,
+                        "identifier `%s' uses reserved `gl_' prefix",
+                        identifier);
+    } else if (strstr(identifier, "__")) {
+       /* From page 14 (page 20 of the PDF) of the GLSL 1.10
+        * spec:
+        *
+        *     "In addition, all identifiers containing two
+        *      consecutive underscores (__) are reserved as
+        *      possible future keywords."
+        *
+        * The intention is that names containing __ are reserved for internal
+        * use by the implementation, and names prefixed with GL_ are reserved
+        * for use by Khronos.  Names simply containing __ are dangerous to use,
+        * but should be allowed.
+        *
+        * A future version of the GLSL specification will clarify this.
+        */
+       _mesa_glsl_warning(&loc, state,
+                          "identifier `%s' uses reserved `__' string",
+                          identifier);
+    }
+ }
+ ir_rvalue *
+ ast_declarator_list::hir(exec_list *instructions,
+                          struct _mesa_glsl_parse_state *state)
+ {
+    void *ctx = state;
+    const struct glsl_type *decl_type;
+    const char *type_name = NULL;
+    ir_rvalue *result = NULL;
+    YYLTYPE loc = this->get_location();
+    /* From page 46 (page 52 of the PDF) of the GLSL 1.50 spec:
+     *
+     *     "To ensure that a particular output variable is invariant, it is
+     *     necessary to use the invariant qualifier. It can either be used to
+     *     qualify a previously declared variable as being invariant
+     *
+     *         invariant gl_Position; // make existing gl_Position be invariant"
+     *
+     * In these cases the parser will set the 'invariant' flag in the declarator
+     * list, and the type will be NULL.
+     */
+    if (this->invariant) {
+       assert(this->type == NULL);
+       if (state->current_function != NULL) {
+          _mesa_glsl_error(& loc, state,
+                           "all uses of `invariant' keyword must be at global "
+                           "scope");
+       }
+       foreach_list_typed (ast_declaration, decl, link, &this->declarations) {
+          assert(decl->array_specifier == NULL);
+          assert(decl->initializer == NULL);
+          ir_variable *const earlier =
+             state->symbols->get_variable(decl->identifier);
+          if (earlier == NULL) {
+             _mesa_glsl_error(& loc, state,
+                              "undeclared variable `%s' cannot be marked "
+                              "invariant", decl->identifier);
+          } else if (!is_varying_var(earlier, state->stage)) {
+             _mesa_glsl_error(&loc, state,
+                              "`%s' cannot be marked invariant; interfaces between "
+                              "shader stages only.", decl->identifier);
+          } else if (earlier->data.used) {
+             _mesa_glsl_error(& loc, state,
+                             "variable `%s' may not be redeclared "
+                             "`invariant' after being used",
+                             earlier->name);
+          } else {
+             earlier->data.invariant = true;
+          }
+       }
+       /* Invariant redeclarations do not have r-values.
+        */
+       return NULL;
+    }
+    if (this->precise) {
+       assert(this->type == NULL);
+       foreach_list_typed (ast_declaration, decl, link, &this->declarations) {
+          assert(decl->array_specifier == NULL);
+          assert(decl->initializer == NULL);
+          ir_variable *const earlier =
+             state->symbols->get_variable(decl->identifier);
+          if (earlier == NULL) {
+             _mesa_glsl_error(& loc, state,
+                              "undeclared variable `%s' cannot be marked "
+                              "precise", decl->identifier);
+          } else if (state->current_function != NULL &&
+                     !state->symbols->name_declared_this_scope(decl->identifier)) {
+             /* Note: we have to check if we're in a function, since
+              * builtins are treated as having come from another scope.
+              */
+             _mesa_glsl_error(& loc, state,
+                              "variable `%s' from an outer scope may not be "
+                              "redeclared `precise' in this scope",
+                              earlier->name);
+          } else if (earlier->data.used) {
+             _mesa_glsl_error(& loc, state,
+                              "variable `%s' may not be redeclared "
+                              "`precise' after being used",
+                              earlier->name);
+          } else {
+             earlier->data.precise = true;
+          }
+       }
+       /* Precise redeclarations do not have r-values either. */
+       return NULL;
+    }
+    assert(this->type != NULL);
+    assert(!this->invariant);
+    assert(!this->precise);
+    /* The type specifier may contain a structure definition.  Process that
+     * before any of the variable declarations.
+     */
+    (void) this->type->specifier->hir(instructions, state);
+    decl_type = this->type->glsl_type(& type_name, state);
+    /* Section 4.3.7 "Buffer Variables" of the GLSL 4.30 spec:
+     *    "Buffer variables may only be declared inside interface blocks
+     *    (section 4.3.9 “Interface Blocks”), which are then referred to as
+     *    shader storage blocks. It is a compile-time error to declare buffer
+     *    variables at global scope (outside a block)."
+     */
+    if (type->qualifier.flags.q.buffer && !decl_type->is_interface()) {
+       _mesa_glsl_error(&loc, state,
+                        "buffer variables cannot be declared outside "
+                        "interface blocks");
+    }
+    /* An offset-qualified atomic counter declaration sets the default
+     * offset for the next declaration within the same atomic counter
+     * buffer.
+     */
+    if (decl_type && decl_type->contains_atomic()) {
+       if (type->qualifier.flags.q.explicit_binding &&
+           type->qualifier.flags.q.explicit_offset) {
+          unsigned qual_binding;
+          unsigned qual_offset;
+          if (process_qualifier_constant(state, &loc, "binding",
+                                         type->qualifier.binding,
+                                         &qual_binding)
+              && process_qualifier_constant(state, &loc, "offset",
+                                         type->qualifier.offset,
+                                         &qual_offset)) {
+             state->atomic_counter_offsets[qual_binding] = qual_offset;
+          }
+       }
+    }
+    if (this->declarations.is_empty()) {
+       /* If there is no structure involved in the program text, there are two
+        * possible scenarios:
+        *
+        * - The program text contained something like 'vec4;'.  This is an
+        *   empty declaration.  It is valid but weird.  Emit a warning.
+        *
+        * - The program text contained something like 'S;' and 'S' is not the
+        *   name of a known structure type.  This is both invalid and weird.
+        *   Emit an error.
+        *
+        * - The program text contained something like 'mediump float;'
+        *   when the programmer probably meant 'precision mediump
+        *   float;' Emit a warning with a description of what they
+        *   probably meant to do.
+        *
+        * Note that if decl_type is NULL and there is a structure involved,
+        * there must have been some sort of error with the structure.  In this
+        * case we assume that an error was already generated on this line of
+        * code for the structure.  There is no need to generate an additional,
+        * confusing error.
+        */
+       assert(this->type->specifier->structure == NULL || decl_type != NULL
+            || state->error);
+       if (decl_type == NULL) {
+          _mesa_glsl_error(&loc, state,
+                           "invalid type `%s' in empty declaration",
+                           type_name);
+       } else if (decl_type->base_type == GLSL_TYPE_ATOMIC_UINT) {
+          /* Empty atomic counter declarations are allowed and useful
+           * to set the default offset qualifier.
+           */
+          return NULL;
+       } else if (this->type->qualifier.precision != ast_precision_none) {
+          if (this->type->specifier->structure != NULL) {
+             _mesa_glsl_error(&loc, state,
+                              "precision qualifiers can't be applied "
+                              "to structures");
+          } else {
+             static const char *const precision_names[] = {
+                "highp",
+                "highp",
+                "mediump",
+                "lowp"
+             };
+             _mesa_glsl_warning(&loc, state,
+                                "empty declaration with precision qualifier, "
+                                "to set the default precision, use "
+                                "`precision %s %s;'",
+                                precision_names[this->type->qualifier.precision],
+                                type_name);
+          }
+       } else if (this->type->specifier->structure == NULL) {
+          _mesa_glsl_warning(&loc, state, "empty declaration");
+       }
+    }
+    foreach_list_typed (ast_declaration, decl, link, &this->declarations) {
+       const struct glsl_type *var_type;
+       ir_variable *var;
+       const char *identifier = decl->identifier;
+       /* FINISHME: Emit a warning if a variable declaration shadows a
+        * FINISHME: declaration at a higher scope.
+        */
+       if ((decl_type == NULL) || decl_type->is_void()) {
+          if (type_name != NULL) {
+             _mesa_glsl_error(& loc, state,
+                              "invalid type `%s' in declaration of `%s'",
+                              type_name, decl->identifier);
+          } else {
+             _mesa_glsl_error(& loc, state,
+                              "invalid type in declaration of `%s'",
+                              decl->identifier);
+          }
+          continue;
+       }
+       if (this->type->qualifier.flags.q.subroutine) {
+          const glsl_type *t;
+          const char *name;
+          t = state->symbols->get_type(this->type->specifier->type_name);
+          if (!t)
+             _mesa_glsl_error(& loc, state,
+                              "invalid type in declaration of `%s'",
+                              decl->identifier);
+          name = ralloc_asprintf(ctx, "%s_%s", _mesa_shader_stage_to_subroutine_prefix(state->stage), decl->identifier);
+          identifier = name;
+       }
+       var_type = process_array_type(&loc, decl_type, decl->array_specifier,
+                                     state);
+       var = new(ctx) ir_variable(var_type, identifier, ir_var_auto);
+       /* The 'varying in' and 'varying out' qualifiers can only be used with
+        * ARB_geometry_shader4 and EXT_geometry_shader4, which we don't support
+        * yet.
+        */
+       if (this->type->qualifier.flags.q.varying) {
+          if (this->type->qualifier.flags.q.in) {
+             _mesa_glsl_error(& loc, state,
+                              "`varying in' qualifier in declaration of "
+                              "`%s' only valid for geometry shaders using "
+                              "ARB_geometry_shader4 or EXT_geometry_shader4",
+                              decl->identifier);
+          } else if (this->type->qualifier.flags.q.out) {
+             _mesa_glsl_error(& loc, state,
+                              "`varying out' qualifier in declaration of "
+                              "`%s' only valid for geometry shaders using "
+                              "ARB_geometry_shader4 or EXT_geometry_shader4",
+                              decl->identifier);
+          }
+       }
+       /* From page 22 (page 28 of the PDF) of the GLSL 1.10 specification;
+        *
+        *     "Global variables can only use the qualifiers const,
+        *     attribute, uniform, or varying. Only one may be
+        *     specified.
+        *
+        *     Local variables can only use the qualifier const."
+        *
+        * This is relaxed in GLSL 1.30 and GLSL ES 3.00.  It is also relaxed by
+        * any extension that adds the 'layout' keyword.
+        */
+       if (!state->is_version(130, 300)
+           && !state->has_explicit_attrib_location()
+           && !state->has_separate_shader_objects()
+           && !state->ARB_fragment_coord_conventions_enable) {
+          if (this->type->qualifier.flags.q.out) {
+             _mesa_glsl_error(& loc, state,
+                              "`out' qualifier in declaration of `%s' "
+                              "only valid for function parameters in %s",
+                              decl->identifier, state->get_version_string());
+          }
+          if (this->type->qualifier.flags.q.in) {
+             _mesa_glsl_error(& loc, state,
+                              "`in' qualifier in declaration of `%s' "
+                              "only valid for function parameters in %s",
+                              decl->identifier, state->get_version_string());
+          }
+          /* FINISHME: Test for other invalid qualifiers. */
+       }
+       apply_type_qualifier_to_variable(& this->type->qualifier, var, state,
+                                      & loc, false);
+       apply_layout_qualifier_to_variable(&this->type->qualifier, var, state,
+                                          &loc);
+       if (this->type->qualifier.flags.q.invariant) {
+          if (!is_varying_var(var, state->stage)) {
+             _mesa_glsl_error(&loc, state,
+                              "`%s' cannot be marked invariant; interfaces between "
+                              "shader stages only", var->name);
+          }
+       }
+       if (state->current_function != NULL) {
+          const char *mode = NULL;
+          const char *extra = "";
+          /* There is no need to check for 'inout' here because the parser will
+           * only allow that in function parameter lists.
+           */
+          if (this->type->qualifier.flags.q.attribute) {
+             mode = "attribute";
+          } else if (this->type->qualifier.flags.q.subroutine) {
+             mode = "subroutine uniform";
+          } else if (this->type->qualifier.flags.q.uniform) {
+             mode = "uniform";
+          } else if (this->type->qualifier.flags.q.varying) {
+             mode = "varying";
+          } else if (this->type->qualifier.flags.q.in) {
+             mode = "in";
+             extra = " or in function parameter list";
+          } else if (this->type->qualifier.flags.q.out) {
+             mode = "out";
+             extra = " or in function parameter list";
+          }
+          if (mode) {
+             _mesa_glsl_error(& loc, state,
+                              "%s variable `%s' must be declared at "
+                              "global scope%s",
+                              mode, var->name, extra);
+          }
+       } else if (var->data.mode == ir_var_shader_in) {
+          var->data.read_only = true;
+          if (state->stage == MESA_SHADER_VERTEX) {
+             bool error_emitted = false;
+             /* From page 31 (page 37 of the PDF) of the GLSL 1.50 spec:
+              *
+              *    "Vertex shader inputs can only be float, floating-point
+              *    vectors, matrices, signed and unsigned integers and integer
+              *    vectors. Vertex shader inputs can also form arrays of these
+              *    types, but not structures."
+              *
+              * From page 31 (page 27 of the PDF) of the GLSL 1.30 spec:
+              *
+              *    "Vertex shader inputs can only be float, floating-point
+              *    vectors, matrices, signed and unsigned integers and integer
+              *    vectors. They cannot be arrays or structures."
+              *
+              * From page 23 (page 29 of the PDF) of the GLSL 1.20 spec:
+              *
+              *    "The attribute qualifier can be used only with float,
+              *    floating-point vectors, and matrices. Attribute variables
+              *    cannot be declared as arrays or structures."
+              *
+              * From page 33 (page 39 of the PDF) of the GLSL ES 3.00 spec:
+              *
+              *    "Vertex shader inputs can only be float, floating-point
+              *    vectors, matrices, signed and unsigned integers and integer
+              *    vectors. Vertex shader inputs cannot be arrays or
+              *    structures."
+              */
+             const glsl_type *check_type = var->type->without_array();
+             switch (check_type->base_type) {
+             case GLSL_TYPE_FLOAT:
+             break;
+             case GLSL_TYPE_UINT:
+             case GLSL_TYPE_INT:
+                if (state->is_version(120, 300))
+                   break;
+             case GLSL_TYPE_DOUBLE:
+                if (check_type->base_type == GLSL_TYPE_DOUBLE && (state->is_version(410, 0) || state->ARB_vertex_attrib_64bit_enable))
+                   break;
+             /* FALLTHROUGH */
+             default:
+                _mesa_glsl_error(& loc, state,
+                                 "vertex shader input / attribute cannot have "
+                                 "type %s`%s'",
+                                 var->type->is_array() ? "array of " : "",
+                                 check_type->name);
+                error_emitted = true;
+             }
+             if (!error_emitted && var->type->is_array() &&
+                 !state->check_version(150, 0, &loc,
+                                       "vertex shader input / attribute "
+                                       "cannot have array type")) {
+                error_emitted = true;
+             }
+          } else if (state->stage == MESA_SHADER_GEOMETRY) {
+             /* From section 4.3.4 (Inputs) of the GLSL 1.50 spec:
+              *
+              *     Geometry shader input variables get the per-vertex values
+              *     written out by vertex shader output variables of the same
+              *     names. Since a geometry shader operates on a set of
+              *     vertices, each input varying variable (or input block, see
+              *     interface blocks below) needs to be declared as an array.
+              */
+             if (!var->type->is_array()) {
+                _mesa_glsl_error(&loc, state,
+                                 "geometry shader inputs must be arrays");
+             }
+             handle_geometry_shader_input_decl(state, loc, var);
+          } else if (state->stage == MESA_SHADER_FRAGMENT) {
+             /* From section 4.3.4 (Input Variables) of the GLSL ES 3.10 spec:
+              *
+              *     It is a compile-time error to declare a fragment shader
+              *     input with, or that contains, any of the following types:
+              *
+              *     * A boolean type
+              *     * An opaque type
+              *     * An array of arrays
+              *     * An array of structures
+              *     * A structure containing an array
+              *     * A structure containing a structure
+              */
+             if (state->es_shader) {
+                const glsl_type *check_type = var->type->without_array();
+                if (check_type->is_boolean() ||
+                    check_type->contains_opaque()) {
+                   _mesa_glsl_error(&loc, state,
+                                    "fragment shader input cannot have type %s",
+                                    check_type->name);
+                }
+                if (var->type->is_array() &&
+                    var->type->fields.array->is_array()) {
+                   _mesa_glsl_error(&loc, state,
+                                    "%s shader output "
+                                    "cannot have an array of arrays",
+                                    _mesa_shader_stage_to_string(state->stage));
+                }
+                if (var->type->is_array() &&
+                    var->type->fields.array->is_record()) {
+                   _mesa_glsl_error(&loc, state,
+                                    "fragment shader input "
+                                    "cannot have an array of structs");
+                }
+                if (var->type->is_record()) {
+                   for (unsigned i = 0; i < var->type->length; i++) {
+                      if (var->type->fields.structure[i].type->is_array() ||
+                          var->type->fields.structure[i].type->is_record())
+                         _mesa_glsl_error(&loc, state,
+                                          "fragement shader input cannot have "
+                                          "a struct that contains an "
+                                          "array or struct");
+                   }
+                }
+             }
+          } else if (state->stage == MESA_SHADER_TESS_CTRL ||
+                     state->stage == MESA_SHADER_TESS_EVAL) {
+             handle_tess_shader_input_decl(state, loc, var);
+          }
+       } else if (var->data.mode == ir_var_shader_out) {
+          const glsl_type *check_type = var->type->without_array();
+          /* From section 4.3.6 (Output variables) of the GLSL 4.40 spec:
+           *
+           *     It is a compile-time error to declare a vertex, tessellation
+           *     evaluation, tessellation control, or geometry shader output
+           *     that contains any of the following:
+           *
+           *     * A Boolean type (bool, bvec2 ...)
+           *     * An opaque type
+           */
+          if (check_type->is_boolean() || check_type->contains_opaque())
+             _mesa_glsl_error(&loc, state,
+                              "%s shader output cannot have type %s",
+                              _mesa_shader_stage_to_string(state->stage),
+                              check_type->name);
+          /* From section 4.3.6 (Output variables) of the GLSL 4.40 spec:
+           *
+           *     It is a compile-time error to declare a fragment shader output
+           *     that contains any of the following:
+           *
+           *     * A Boolean type (bool, bvec2 ...)
+           *     * A double-precision scalar or vector (double, dvec2 ...)
+           *     * An opaque type
+           *     * Any matrix type
+           *     * A structure
+           */
+          if (state->stage == MESA_SHADER_FRAGMENT) {
+             if (check_type->is_record() || check_type->is_matrix())
+                _mesa_glsl_error(&loc, state,
+                                 "fragment shader output "
+                                 "cannot have struct or matrix type");
+             switch (check_type->base_type) {
+             case GLSL_TYPE_UINT:
+             case GLSL_TYPE_INT:
+             case GLSL_TYPE_FLOAT:
+                break;
+             default:
+                _mesa_glsl_error(&loc, state,
+                                 "fragment shader output cannot have "
+                                 "type %s", check_type->name);
+             }
+          }
+          /* From section 4.3.6 (Output Variables) of the GLSL ES 3.10 spec:
+           *
+           *     It is a compile-time error to declare a vertex shader output
+           *     with, or that contains, any of the following types:
+           *
+           *     * A boolean type
+           *     * An opaque type
+           *     * An array of arrays
+           *     * An array of structures
+           *     * A structure containing an array
+           *     * A structure containing a structure
+           *
+           *     It is a compile-time error to declare a fragment shader output
+           *     with, or that contains, any of the following types:
+           *
+           *     * A boolean type
+           *     * An opaque type
+           *     * A matrix
+           *     * A structure
+           *     * An array of array
+           */
+          if (state->es_shader) {
+             if (var->type->is_array() &&
+                 var->type->fields.array->is_array()) {
+                _mesa_glsl_error(&loc, state,
+                                 "%s shader output "
+                                 "cannot have an array of arrays",
+                                 _mesa_shader_stage_to_string(state->stage));
+             }
+             if (state->stage == MESA_SHADER_VERTEX) {
+                if (var->type->is_array() &&
+                    var->type->fields.array->is_record()) {
+                   _mesa_glsl_error(&loc, state,
+                                    "vertex shader output "
+                                    "cannot have an array of structs");
+                }
+                if (var->type->is_record()) {
+                   for (unsigned i = 0; i < var->type->length; i++) {
+                      if (var->type->fields.structure[i].type->is_array() ||
+                          var->type->fields.structure[i].type->is_record())
+                         _mesa_glsl_error(&loc, state,
+                                          "vertex shader output cannot have a "
+                                          "struct that contains an "
+                                          "array or struct");
+                   }
+                }
+             }
+          }
+          if (state->stage == MESA_SHADER_TESS_CTRL) {
+             handle_tess_ctrl_shader_output_decl(state, loc, var);
+          }
+       } else if (var->type->contains_subroutine()) {
+          /* declare subroutine uniforms as hidden */
+          var->data.how_declared = ir_var_hidden;
+       }
+       /* Integer fragment inputs must be qualified with 'flat'.  In GLSL ES,
+        * so must integer vertex outputs.
+        *
+        * From section 4.3.4 ("Inputs") of the GLSL 1.50 spec:
+        *    "Fragment shader inputs that are signed or unsigned integers or
+        *    integer vectors must be qualified with the interpolation qualifier
+        *    flat."
+        *
+        * From section 4.3.4 ("Input Variables") of the GLSL 3.00 ES spec:
+        *    "Fragment shader inputs that are, or contain, signed or unsigned
+        *    integers or integer vectors must be qualified with the
+        *    interpolation qualifier flat."
+        *
+        * From section 4.3.6 ("Output Variables") of the GLSL 3.00 ES spec:
+        *    "Vertex shader outputs that are, or contain, signed or unsigned
+        *    integers or integer vectors must be qualified with the
+        *    interpolation qualifier flat."
+        *
+        * Note that prior to GLSL 1.50, this requirement applied to vertex
+        * outputs rather than fragment inputs.  That creates problems in the
+        * presence of geometry shaders, so we adopt the GLSL 1.50 rule for all
+        * desktop GL shaders.  For GLSL ES shaders, we follow the spec and
+        * apply the restriction to both vertex outputs and fragment inputs.
+        *
+        * Note also that the desktop GLSL specs are missing the text "or
+        * contain"; this is presumably an oversight, since there is no
+        * reasonable way to interpolate a fragment shader input that contains
+        * an integer.
+        */
+       if (state->is_version(130, 300) &&
+           var->type->contains_integer() &&
+           var->data.interpolation != INTERP_QUALIFIER_FLAT &&
+           ((state->stage == MESA_SHADER_FRAGMENT && var->data.mode == ir_var_shader_in)
+            || (state->stage == MESA_SHADER_VERTEX && var->data.mode == ir_var_shader_out
+                && state->es_shader))) {
+          const char *var_type = (state->stage == MESA_SHADER_VERTEX) ?
+             "vertex output" : "fragment input";
+          _mesa_glsl_error(&loc, state, "if a %s is (or contains) "
+                           "an integer, then it must be qualified with 'flat'",
+                           var_type);
+       }
+       /* Double fragment inputs must be qualified with 'flat'. */
+       if (var->type->contains_double() &&
+           var->data.interpolation != INTERP_QUALIFIER_FLAT &&
+           state->stage == MESA_SHADER_FRAGMENT &&
+           var->data.mode == ir_var_shader_in) {
+          _mesa_glsl_error(&loc, state, "if a fragment input is (or contains) "
+                           "a double, then it must be qualified with 'flat'",
+                           var_type);
+       }
+       /* Interpolation qualifiers cannot be applied to 'centroid' and
+        * 'centroid varying'.
+        *
+        * From page 29 (page 35 of the PDF) of the GLSL 1.30 spec:
+        *    "interpolation qualifiers may only precede the qualifiers in,
+        *    centroid in, out, or centroid out in a declaration. They do not apply
+        *    to the deprecated storage qualifiers varying or centroid varying."
+        *
+        * These deprecated storage qualifiers do not exist in GLSL ES 3.00.
+        */
+       if (state->is_version(130, 0)
+           && this->type->qualifier.has_interpolation()
+           && this->type->qualifier.flags.q.varying) {
+          const char *i = this->type->qualifier.interpolation_string();
+          assert(i != NULL);
+          const char *s;
+          if (this->type->qualifier.flags.q.centroid)
+             s = "centroid varying";
+          else
+             s = "varying";
+          _mesa_glsl_error(&loc, state,
+                           "qualifier '%s' cannot be applied to the "
+                           "deprecated storage qualifier '%s'", i, s);
+       }
+       /* Interpolation qualifiers can only apply to vertex shader outputs and
+        * fragment shader inputs.
+        *
+        * From page 29 (page 35 of the PDF) of the GLSL 1.30 spec:
+        *    "Outputs from a vertex shader (out) and inputs to a fragment
+        *    shader (in) can be further qualified with one or more of these
+        *    interpolation qualifiers"
+        *
+        * From page 31 (page 37 of the PDF) of the GLSL ES 3.00 spec:
+        *    "These interpolation qualifiers may only precede the qualifiers
+        *    in, centroid in, out, or centroid out in a declaration. They do
+        *    not apply to inputs into a vertex shader or outputs from a
+        *    fragment shader."
+        */
+       if (state->is_version(130, 300)
+           && this->type->qualifier.has_interpolation()) {
+          const char *i = this->type->qualifier.interpolation_string();
+          assert(i != NULL);
+          switch (state->stage) {
+          case MESA_SHADER_VERTEX:
+             if (this->type->qualifier.flags.q.in) {
+                _mesa_glsl_error(&loc, state,
+                                 "qualifier '%s' cannot be applied to vertex "
+                                 "shader inputs", i);
+             }
+             break;
+          case MESA_SHADER_FRAGMENT:
+             if (this->type->qualifier.flags.q.out) {
+                _mesa_glsl_error(&loc, state,
+                                 "qualifier '%s' cannot be applied to fragment "
+                                 "shader outputs", i);
+             }
+             break;
+          default:
+             break;
+          }
+       }
+       /* From section 4.3.4 of the GLSL 4.00 spec:
+        *    "Input variables may not be declared using the patch in qualifier
+        *    in tessellation control or geometry shaders."
+        *
+        * From section 4.3.6 of the GLSL 4.00 spec:
+        *    "It is an error to use patch out in a vertex, tessellation
+        *    evaluation, or geometry shader."
+        *
+        * This doesn't explicitly forbid using them in a fragment shader, but
+        * that's probably just an oversight.
+        */
+       if (state->stage != MESA_SHADER_TESS_EVAL
+           && this->type->qualifier.flags.q.patch
+           && this->type->qualifier.flags.q.in) {
+          _mesa_glsl_error(&loc, state, "'patch in' can only be used in a "
+                           "tessellation evaluation shader");
+       }
+       if (state->stage != MESA_SHADER_TESS_CTRL
+           && this->type->qualifier.flags.q.patch
+           && this->type->qualifier.flags.q.out) {
+          _mesa_glsl_error(&loc, state, "'patch out' can only be used in a "
+                           "tessellation control shader");
+       }
+       /* Precision qualifiers exists only in GLSL versions 1.00 and >= 1.30.
+        */
+       if (this->type->qualifier.precision != ast_precision_none) {
+          state->check_precision_qualifiers_allowed(&loc);
+       }
+       /* If a precision qualifier is allowed on a type, it is allowed on
+        * an array of that type.
+        */
+       if (!(this->type->qualifier.precision == ast_precision_none
+           || precision_qualifier_allowed(var->type->without_array()))) {
+          _mesa_glsl_error(&loc, state,
+                           "precision qualifiers apply only to floating point"
+                           ", integer and opaque types");
+       }
+       /* From section 4.1.7 of the GLSL 4.40 spec:
+        *
+        *    "[Opaque types] can only be declared as function
+        *     parameters or uniform-qualified variables."
+        */
+       if (var_type->contains_opaque() &&
+           !this->type->qualifier.flags.q.uniform) {
+          _mesa_glsl_error(&loc, state,
+                           "opaque variables must be declared uniform");
+       }
+       /* Process the initializer and add its instructions to a temporary
+        * list.  This list will be added to the instruction stream (below) after
+        * the declaration is added.  This is done because in some cases (such as
+        * redeclarations) the declaration may not actually be added to the
+        * instruction stream.
+        */
+       exec_list initializer_instructions;
+       /* Examine var name here since var may get deleted in the next call */
+       bool var_is_gl_id = is_gl_identifier(var->name);
+       ir_variable *earlier =
+          get_variable_being_redeclared(var, decl->get_location(), state,
+                                        false /* allow_all_redeclarations */);
+       if (earlier != NULL) {
+          if (var_is_gl_id &&
+              earlier->data.how_declared == ir_var_declared_in_block) {
+             _mesa_glsl_error(&loc, state,
+                              "`%s' has already been redeclared using "
+                              "gl_PerVertex", earlier->name);
+          }
+          earlier->data.how_declared = ir_var_declared_normally;
+       }
+       if (decl->initializer != NULL) {
+          result = process_initializer((earlier == NULL) ? var : earlier,
+                                       decl, this->type,
+                                       &initializer_instructions, state);
+       } else {
+          validate_array_dimensions(var_type, state, &loc);
+       }
+       /* From page 23 (page 29 of the PDF) of the GLSL 1.10 spec:
+        *
+        *     "It is an error to write to a const variable outside of
+        *      its declaration, so they must be initialized when
+        *      declared."
+        */
+       if (this->type->qualifier.flags.q.constant && decl->initializer == NULL) {
+          _mesa_glsl_error(& loc, state,
+                           "const declaration of `%s' must be initialized",
+                           decl->identifier);
+       }
+       if (state->es_shader) {
+          const glsl_type *const t = (earlier == NULL)
+             ? var->type : earlier->type;
+          if (t->is_unsized_array())
+             /* Section 10.17 of the GLSL ES 1.00 specification states that
+              * unsized array declarations have been removed from the language.
+              * Arrays that are sized using an initializer are still explicitly
+              * sized.  However, GLSL ES 1.00 does not allow array
+              * initializers.  That is only allowed in GLSL ES 3.00.
+              *
+              * Section 4.1.9 (Arrays) of the GLSL ES 3.00 spec says:
+              *
+              *     "An array type can also be formed without specifying a size
+              *     if the definition includes an initializer:
+              *
+              *         float x[] = float[2] (1.0, 2.0);     // declares an array of size 2
+              *         float y[] = float[] (1.0, 2.0, 3.0); // declares an array of size 3
+              *
+              *         float a[5];
+              *         float b[] = a;"
+              */
+             _mesa_glsl_error(& loc, state,
+                              "unsized array declarations are not allowed in "
+                              "GLSL ES");
+       }
+       /* If the declaration is not a redeclaration, there are a few additional
+        * semantic checks that must be applied.  In addition, variable that was
+        * created for the declaration should be added to the IR stream.
+        */
+       if (earlier == NULL) {
+          validate_identifier(decl->identifier, loc, state);
+          /* Add the variable to the symbol table.  Note that the initializer's
+           * IR was already processed earlier (though it hasn't been emitted
+           * yet), without the variable in scope.
+           *
+           * This differs from most C-like languages, but it follows the GLSL
+           * specification.  From page 28 (page 34 of the PDF) of the GLSL 1.50
+           * spec:
+           *
+           *     "Within a declaration, the scope of a name starts immediately
+           *     after the initializer if present or immediately after the name
+           *     being declared if not."
+           */
+          if (!state->symbols->add_variable(var)) {
+             YYLTYPE loc = this->get_location();
+             _mesa_glsl_error(&loc, state, "name `%s' already taken in the "
+                              "current scope", decl->identifier);
+             continue;
+          }
+          /* Push the variable declaration to the top.  It means that all the
+           * variable declarations will appear in a funny last-to-first order,
+           * but otherwise we run into trouble if a function is prototyped, a
+           * global var is decled, then the function is defined with usage of
+           * the global var.  See glslparsertest's CorrectModule.frag.
+           */
+          instructions->push_head(var);
+       }
+       instructions->append_list(&initializer_instructions);
+    }
+    /* Generally, variable declarations do not have r-values.  However,
+     * one is used for the declaration in
+     *
+     * while (bool b = some_condition()) {
+     *   ...
+     * }
+     *
+     * so we return the rvalue from the last seen declaration here.
+     */
+    return result;
+ }
+ ir_rvalue *
+ ast_parameter_declarator::hir(exec_list *instructions,
+                               struct _mesa_glsl_parse_state *state)
+ {
+    void *ctx = state;
+    const struct glsl_type *type;
+    const char *name = NULL;
+    YYLTYPE loc = this->get_location();
+    type = this->type->glsl_type(& name, state);
+    if (type == NULL) {
+       if (name != NULL) {
+          _mesa_glsl_error(& loc, state,
+                           "invalid type `%s' in declaration of `%s'",
+                           name, this->identifier);
+       } else {
+          _mesa_glsl_error(& loc, state,
+                           "invalid type in declaration of `%s'",
+                           this->identifier);
+       }
+       type = glsl_type::error_type;
+    }
+    /* From page 62 (page 68 of the PDF) of the GLSL 1.50 spec:
+     *
+     *    "Functions that accept no input arguments need not use void in the
+     *    argument list because prototypes (or definitions) are required and
+     *    therefore there is no ambiguity when an empty argument list "( )" is
+     *    declared. The idiom "(void)" as a parameter list is provided for
+     *    convenience."
+     *
+     * Placing this check here prevents a void parameter being set up
+     * for a function, which avoids tripping up checks for main taking
+     * parameters and lookups of an unnamed symbol.
+     */
+    if (type->is_void()) {
+       if (this->identifier != NULL)
+          _mesa_glsl_error(& loc, state,
+                           "named parameter cannot have type `void'");
+       is_void = true;
+       return NULL;
+    }
+    if (formal_parameter && (this->identifier == NULL)) {
+       _mesa_glsl_error(& loc, state, "formal parameter lacks a name");
+       return NULL;
+    }
+    /* This only handles "vec4 foo[..]".  The earlier specifier->glsl_type(...)
+     * call already handled the "vec4[..] foo" case.
+     */
+    type = process_array_type(&loc, type, this->array_specifier, state);
+    if (!type->is_error() && type->is_unsized_array()) {
+       _mesa_glsl_error(&loc, state, "arrays passed as parameters must have "
+                        "a declared size");
+       type = glsl_type::error_type;
+    }
+    is_void = false;
+    ir_variable *var = new(ctx)
+       ir_variable(type, this->identifier, ir_var_function_in);
+    /* 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, & loc,
+                                     true);
+    /* From section 4.1.7 of the GLSL 4.40 spec:
+     *
+     *   "Opaque variables cannot be treated as l-values; hence cannot
+     *    be used as out or inout function parameters, nor can they be
+     *    assigned into."
+     */
+    if ((var->data.mode == ir_var_function_inout || var->data.mode == ir_var_function_out)
+        && type->contains_opaque()) {
+       _mesa_glsl_error(&loc, state, "out and inout parameters cannot "
+                        "contain opaque variables");
+       type = glsl_type::error_type;
+    }
+    /* From page 39 (page 45 of the PDF) of the GLSL 1.10 spec:
+     *
+     *    "When calling a function, expressions that do not evaluate to
+     *     l-values cannot be passed to parameters declared as out or inout."
+     *
+     * From page 32 (page 38 of the PDF) of the GLSL 1.10 spec:
+     *
+     *    "Other binary or unary expressions, non-dereferenced arrays,
+     *     function names, swizzles with repeated fields, and constants
+     *     cannot be l-values."
+     *
+     * So for GLSL 1.10, passing an array as an out or inout parameter is not
+     * allowed.  This restriction is removed in GLSL 1.20, and in GLSL ES.
+     */
+    if ((var->data.mode == ir_var_function_inout || var->data.mode == ir_var_function_out)
+        && type->is_array()
+        && !state->check_version(120, 100, &loc,
+                                 "arrays cannot be out or inout parameters")) {
+       type = glsl_type::error_type;
+    }
+    instructions->push_tail(var);
+    /* Parameter declarations do not have r-values.
+     */
+    return NULL;
+ }
+ void
+ ast_parameter_declarator::parameters_to_hir(exec_list *ast_parameters,
+                                             bool formal,
+                                             exec_list *ir_parameters,
+                                             _mesa_glsl_parse_state *state)
+ {
+    ast_parameter_declarator *void_param = NULL;
+    unsigned count = 0;
+    foreach_list_typed (ast_parameter_declarator, param, link, ast_parameters) {
+       param->formal_parameter = formal;
+       param->hir(ir_parameters, state);
+       if (param->is_void)
+          void_param = param;
+       count++;
+    }
+    if ((void_param != NULL) && (count > 1)) {
+       YYLTYPE loc = void_param->get_location();
+       _mesa_glsl_error(& loc, state,
+                        "`void' parameter must be only parameter");
+    }
+ }
+ void
+ emit_function(_mesa_glsl_parse_state *state, ir_function *f)
+ {
+    /* IR invariants disallow function declarations or definitions
+     * nested within other function definitions.  But there is no
+     * requirement about the relative order of function declarations
+     * and definitions with respect to one another.  So simply insert
+     * the new ir_function block at the end of the toplevel instruction
+     * list.
+     */
+    state->toplevel_ir->push_tail(f);
+ }
+ ir_rvalue *
+ ast_function::hir(exec_list *instructions,
+                   struct _mesa_glsl_parse_state *state)
+ {
+    void *ctx = state;
+    ir_function *f = NULL;
+    ir_function_signature *sig = NULL;
+    exec_list hir_parameters;
+    YYLTYPE loc = this->get_location();
+    const char *const name = identifier;
+    /* New functions are always added to the top-level IR instruction stream,
+     * so this instruction list pointer is ignored.  See also emit_function
+     * (called below).
+     */
+    (void) instructions;
+    /* From page 21 (page 27 of the PDF) of the GLSL 1.20 spec,
+     *
+     *   "Function declarations (prototypes) cannot occur inside of functions;
+     *   they must be at global scope, or for the built-in functions, outside
+     *   the global scope."
+     *
+     * From page 27 (page 33 of the PDF) of the GLSL ES 1.00.16 spec,
+     *
+     *   "User defined functions may only be defined within the global scope."
+     *
+     * Note that this language does not appear in GLSL 1.10.
+     */
+    if ((state->current_function != NULL) &&
+        state->is_version(120, 100)) {
+       YYLTYPE loc = this->get_location();
+       _mesa_glsl_error(&loc, state,
+                      "declaration of function `%s' not allowed within "
+                      "function body", name);
+    }
+    validate_identifier(name, this->get_location(), state);
+    /* 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.
+     */
+    ast_parameter_declarator::parameters_to_hir(& this->parameters,
+                                                is_definition,
+                                                & hir_parameters, state);
+    const char *return_type_name;
+    const glsl_type *return_type =
+       this->return_type->glsl_type(& return_type_name, state);
+    if (!return_type) {
+       YYLTYPE loc = this->get_location();
+       _mesa_glsl_error(&loc, state,
+                        "function `%s' has undeclared return type `%s'",
+                        name, return_type_name);
+       return_type = glsl_type::error_type;
+    }
+    /* ARB_shader_subroutine states:
+     *  "Subroutine declarations cannot be prototyped. It is an error to prepend
+     *   subroutine(...) to a function declaration."
+     */
+    if (this->return_type->qualifier.flags.q.subroutine_def && !is_definition) {
+       YYLTYPE loc = this->get_location();
+       _mesa_glsl_error(&loc, state,
+                        "function declaration `%s' cannot have subroutine prepended",
+                        name);
+    }
+    /* From page 56 (page 62 of the PDF) of the GLSL 1.30 spec:
+     * "No qualifier is allowed on the return type of a function."
+     */
+    if (this->return_type->has_qualifiers(state)) {
+       YYLTYPE loc = this->get_location();
+       _mesa_glsl_error(& loc, state,
+                        "function `%s' return type has qualifiers", name);
+    }
+    /* Section 6.1 (Function Definitions) of the GLSL 1.20 spec says:
+     *
+     *     "Arrays are allowed as arguments and as the return type. In both
+     *     cases, the array must be explicitly sized."
+     */
+    if (return_type->is_unsized_array()) {
+       YYLTYPE loc = this->get_location();
+       _mesa_glsl_error(& loc, state,
+                        "function `%s' return type array must be explicitly "
+                        "sized", name);
+    }
+    /* From section 4.1.7 of the GLSL 4.40 spec:
+     *
+     *    "[Opaque types] can only be declared as function parameters
+     *     or uniform-qualified variables."
+     */
+    if (return_type->contains_opaque()) {
+       YYLTYPE loc = this->get_location();
+       _mesa_glsl_error(&loc, state,
+                        "function `%s' return type can't contain an opaque type",
+                        name);
+    }
+    /* Create an ir_function if one doesn't already exist. */
+    f = state->symbols->get_function(name);
+    if (f == NULL) {
+       f = new(ctx) ir_function(name);
+       if (!this->return_type->qualifier.flags.q.subroutine) {
+          if (!state->symbols->add_function(f)) {
+             /* This function name shadows a non-function use of the same name. */
+             YYLTYPE loc = this->get_location();
+             _mesa_glsl_error(&loc, state, "function name `%s' conflicts with "
+                              "non-function", name);
+             return NULL;
+          }
+       }
+       emit_function(state, f);
+    }
+    /* From GLSL ES 3.0 spec, chapter 6.1 "Function Definitions", page 71:
+     *
+     * "A shader cannot redefine or overload built-in functions."
+     *
+     * While in GLSL ES 1.0 specification, chapter 8 "Built-in Functions":
+     *
+     * "User code can overload the built-in functions but cannot redefine
+     * them."
+     */
+    if (state->es_shader && state->language_version >= 300) {
+       /* Local shader has no exact candidates; check the built-ins. */
+       _mesa_glsl_initialize_builtin_functions();
+       if (_mesa_glsl_find_builtin_function_by_name(name)) {
+          YYLTYPE loc = this->get_location();
+          _mesa_glsl_error(& loc, state,
+                           "A shader cannot redefine or overload built-in "
+                           "function `%s' in GLSL ES 3.00", name);
+          return NULL;
+       }
+    }
+    /* Verify that this function's signature either doesn't match a previously
+     * seen signature for a function with the same name, or, if a match is found,
+     * that the previously seen signature does not have an associated definition.
+     */
+    if (state->es_shader || f->has_user_signature()) {
+       sig = f->exact_matching_signature(state, &hir_parameters);
+       if (sig != NULL) {
+          const char *badvar = sig->qualifiers_match(&hir_parameters);
+          if (badvar != NULL) {
+             YYLTYPE loc = this->get_location();
+             _mesa_glsl_error(&loc, state, "function `%s' parameter `%s' "
+                              "qualifiers don't match prototype", name, badvar);
+          }
+          if (sig->return_type != return_type) {
+             YYLTYPE loc = this->get_location();
+             _mesa_glsl_error(&loc, state, "function `%s' return type doesn't "
+                              "match prototype", name);
+          }
+          if (sig->is_defined) {
+             if (is_definition) {
+                YYLTYPE loc = this->get_location();
+                _mesa_glsl_error(& loc, state, "function `%s' redefined", name);
+             } else {
+                /* We just encountered a prototype that exactly matches a
+                 * function that's already been defined.  This is redundant,
+                 * and we should ignore it.
+                 */
+                return NULL;
+             }
+          }
+       }
+    }
+    /* Verify the return type of main() */
+    if (strcmp(name, "main") == 0) {
+       if (! return_type->is_void()) {
+          YYLTYPE loc = this->get_location();
+          _mesa_glsl_error(& loc, state, "main() must return void");
+       }
+       if (!hir_parameters.is_empty()) {
+          YYLTYPE loc = this->get_location();
+          _mesa_glsl_error(& loc, state, "main() must not take any parameters");
+       }
+    }
+    /* Finish storing the information about this new function in its signature.
+     */
+    if (sig == NULL) {
+       sig = new(ctx) ir_function_signature(return_type);
+       f->add_signature(sig);
+    }
+    sig->replace_parameters(&hir_parameters);
+    signature = sig;
+    if (this->return_type->qualifier.flags.q.subroutine_def) {
+       int idx;
+       if (this->return_type->qualifier.flags.q.explicit_index) {
+          unsigned qual_index;
+          if (process_qualifier_constant(state, &loc, "index",
+                                         this->return_type->qualifier.index,
+                                         &qual_index)) {
+             if (!state->has_explicit_uniform_location()) {
+                _mesa_glsl_error(&loc, state, "subroutine index requires "
+                                 "GL_ARB_explicit_uniform_location or "
+                                 "GLSL 4.30");
+             } else if (qual_index >= MAX_SUBROUTINES) {
+                _mesa_glsl_error(&loc, state,
+                                 "invalid subroutine index (%d) index must "
+                                 "be a number between 0 and "
+                                 "GL_MAX_SUBROUTINES - 1 (%d)", qual_index,
+                                 MAX_SUBROUTINES - 1);
+             } else {
+                f->subroutine_index = qual_index;
+             }
+          }
+       }
+       f->num_subroutine_types = this->return_type->qualifier.subroutine_list->declarations.length();
+       f->subroutine_types = ralloc_array(state, const struct glsl_type *,
+                                          f->num_subroutine_types);
+       idx = 0;
+       foreach_list_typed(ast_declaration, decl, link, &this->return_type->qualifier.subroutine_list->declarations) {
+          const struct glsl_type *type;
+          /* the subroutine type must be already declared */
+          type = state->symbols->get_type(decl->identifier);
+          if (!type) {
+             _mesa_glsl_error(& loc, state, "unknown type '%s' in subroutine function definition", decl->identifier);
+          }
+          f->subroutine_types[idx++] = type;
+       }
+       state->subroutines = (ir_function **)reralloc(state, state->subroutines,
+                                                     ir_function *,
+                                                     state->num_subroutines + 1);
+       state->subroutines[state->num_subroutines] = f;
+       state->num_subroutines++;
+    }
+    if (this->return_type->qualifier.flags.q.subroutine) {
+       if (!state->symbols->add_type(this->identifier, glsl_type::get_subroutine_instance(this->identifier))) {
+          _mesa_glsl_error(& loc, state, "type '%s' previously defined", this->identifier);
+          return NULL;
+       }
+       state->subroutine_types = (ir_function **)reralloc(state, state->subroutine_types,
+                                                          ir_function *,
+                                                          state->num_subroutine_types + 1);
+       state->subroutine_types[state->num_subroutine_types] = f;
+       state->num_subroutine_types++;
+       f->is_subroutine = true;
+    }
+    /* Function declarations (prototypes) do not have r-values.
+     */
+    return NULL;
+ }
+ ir_rvalue *
+ ast_function_definition::hir(exec_list *instructions,
+                              struct _mesa_glsl_parse_state *state)
+ {
+    prototype->is_definition = true;
+    prototype->hir(instructions, state);
+    ir_function_signature *signature = prototype->signature;
+    if (signature == NULL)
+       return NULL;
+    assert(state->current_function == NULL);
+    state->current_function = signature;
+    state->found_return = false;
+    /* Duplicate parameters declared in the prototype as concrete variables.
+     * Add these to the symbol table.
+     */
+    state->symbols->push_scope();
+    foreach_in_list(ir_variable, var, &signature->parameters) {
+       assert(var->as_variable() != NULL);
+       /* The only way a parameter would "exist" is if two parameters have
+        * the same name.
+        */
+       if (state->symbols->name_declared_this_scope(var->name)) {
+          YYLTYPE loc = this->get_location();
+          _mesa_glsl_error(& loc, state, "parameter `%s' redeclared", var->name);
+       } else {
+          state->symbols->add_variable(var);
+       }
+    }
+    /* Convert the body of the function to HIR. */
+    this->body->hir(&signature->body, state);
+    signature->is_defined = true;
+    state->symbols->pop_scope();
+    assert(state->current_function == signature);
+    state->current_function = NULL;
+    if (!signature->return_type->is_void() && !state->found_return) {
+       YYLTYPE loc = this->get_location();
+       _mesa_glsl_error(& loc, state, "function `%s' has non-void return type "
+                        "%s, but no return statement",
+                        signature->function_name(),
+                        signature->return_type->name);
+    }
+    /* Function definitions do not have r-values.
+     */
+    return NULL;
+ }
+ ir_rvalue *
+ ast_jump_statement::hir(exec_list *instructions,
+                         struct _mesa_glsl_parse_state *state)
+ {
+    void *ctx = state;
+    switch (mode) {
+    case ast_return: {
+       ir_return *inst;
+       assert(state->current_function);
+       if (opt_return_value) {
+          ir_rvalue *ret = opt_return_value->hir(instructions, state);
+          /* The value of the return type can be NULL if the shader says
+           * 'return foo();' and foo() is a function that returns void.
+           *
+           * NOTE: The GLSL spec doesn't say that this is an error.  The type
+           * of the return value is void.  If the return type of the function is
+           * also void, then this should compile without error.  Seriously.
+           */
+          const glsl_type *const ret_type =
+             (ret == NULL) ? glsl_type::void_type : ret->type;
+          /* Implicit conversions are not allowed for return values prior to
+           * ARB_shading_language_420pack.
+           */
+          if (state->current_function->return_type != ret_type) {
+             YYLTYPE loc = this->get_location();
+             if (state->has_420pack()) {
+                if (!apply_implicit_conversion(state->current_function->return_type,
+                                               ret, state)) {
+                   _mesa_glsl_error(& loc, state,
+                                    "could not implicitly convert return value "
+                                    "to %s, in function `%s'",
+                                    state->current_function->return_type->name,
+                                    state->current_function->function_name());
+                }
+             } else {
+                _mesa_glsl_error(& loc, state,
+                                 "`return' with wrong type %s, in function `%s' "
+                                 "returning %s",
+                                 ret_type->name,
+                                 state->current_function->function_name(),
+                                 state->current_function->return_type->name);
+             }
+          } else if (state->current_function->return_type->base_type ==
+                     GLSL_TYPE_VOID) {
+             YYLTYPE loc = this->get_location();
+             /* The ARB_shading_language_420pack, GLSL ES 3.0, and GLSL 4.20
+              * specs add a clarification:
+              *
+              *    "A void function can only use return without a return argument, even if
+              *     the return argument has void type. Return statements only accept values:
+              *
+              *         void func1() { }
+              *         void func2() { return func1(); } // illegal return statement"
+              */
+             _mesa_glsl_error(& loc, state,
+                              "void functions can only use `return' without a "
+                              "return argument");
+          }
+          inst = new(ctx) ir_return(ret);
+       } else {
+          if (state->current_function->return_type->base_type !=
+              GLSL_TYPE_VOID) {
+             YYLTYPE loc = this->get_location();
+             _mesa_glsl_error(& loc, state,
+                              "`return' with no value, in function %s returning "
+                              "non-void",
+             state->current_function->function_name());
+          }
+          inst = new(ctx) ir_return;
+       }
+       state->found_return = true;
+       instructions->push_tail(inst);
+       break;
+    }
+    case ast_discard:
+       if (state->stage != MESA_SHADER_FRAGMENT) {
+          YYLTYPE loc = this->get_location();
+          _mesa_glsl_error(& loc, state,
+                           "`discard' may only appear in a fragment shader");
+       }
+       instructions->push_tail(new(ctx) ir_discard);
+       break;
+    case ast_break:
+    case ast_continue:
+       if (mode == ast_continue &&
+           state->loop_nesting_ast == NULL) {
+          YYLTYPE loc = this->get_location();
+          _mesa_glsl_error(& loc, state, "continue may only appear in a loop");
+       } else if (mode == ast_break &&
+          state->loop_nesting_ast == NULL &&
+          state->switch_state.switch_nesting_ast == NULL) {
+          YYLTYPE loc = this->get_location();
+          _mesa_glsl_error(& loc, state,
+                           "break may only appear in a loop or a switch");
+       } else {
+          /* For a loop, inline the for loop expression again, since we don't
+           * know where near the end of the loop body the normal copy of it is
+           * going to be placed.  Same goes for the condition for a do-while
+           * loop.
+           */
+          if (state->loop_nesting_ast != NULL &&
+              mode == ast_continue && !state->switch_state.is_switch_innermost) {
+             if (state->loop_nesting_ast->rest_expression) {
+                state->loop_nesting_ast->rest_expression->hir(instructions,
+                                                              state);
+             }
+             if (state->loop_nesting_ast->mode ==
+                 ast_iteration_statement::ast_do_while) {
+                state->loop_nesting_ast->condition_to_hir(instructions, state);
+             }
+          }
+          if (state->switch_state.is_switch_innermost &&
+              mode == ast_continue) {
+             /* Set 'continue_inside' to true. */
+             ir_rvalue *const true_val = new (ctx) ir_constant(true);
+             ir_dereference_variable *deref_continue_inside_var =
+                new(ctx) ir_dereference_variable(state->switch_state.continue_inside);
+             instructions->push_tail(new(ctx) ir_assignment(deref_continue_inside_var,
+                                                            true_val));
+             /* Break out from the switch, continue for the loop will
+              * be called right after switch. */
+             ir_loop_jump *const jump =
+                new(ctx) ir_loop_jump(ir_loop_jump::jump_break);
+             instructions->push_tail(jump);
+          } else if (state->switch_state.is_switch_innermost &&
+              mode == ast_break) {
+             /* Force break out of switch by inserting a break. */
+             ir_loop_jump *const jump =
+                new(ctx) ir_loop_jump(ir_loop_jump::jump_break);
+             instructions->push_tail(jump);
+          } else {
+             ir_loop_jump *const jump =
+                new(ctx) ir_loop_jump((mode == ast_break)
+                   ? ir_loop_jump::jump_break
+                   : ir_loop_jump::jump_continue);
+             instructions->push_tail(jump);
+          }
+       }
+       break;
+    }
+    /* Jump instructions do not have r-values.
+     */
+    return NULL;
+ }
+ ir_rvalue *
+ ast_selection_statement::hir(exec_list *instructions,
+                              struct _mesa_glsl_parse_state *state)
+ {
+    void *ctx = state;
+    ir_rvalue *const condition = this->condition->hir(instructions, state);
+    /* From page 66 (page 72 of the PDF) of the GLSL 1.50 spec:
+     *
+     *    "Any expression whose type evaluates to a Boolean can be used as the
+     *    conditional expression bool-expression. Vector types are not accepted
+     *    as the expression to if."
+     *
+     * The checks are separated so that higher quality diagnostics can be
+     * generated for cases where both rules are violated.
+     */
+    if (!condition->type->is_boolean() || !condition->type->is_scalar()) {
+       YYLTYPE loc = this->condition->get_location();
+       _mesa_glsl_error(& loc, state, "if-statement condition must be scalar "
+                        "boolean");
+    }
+    ir_if *const stmt = new(ctx) ir_if(condition);
+    if (then_statement != NULL) {
+       state->symbols->push_scope();
+       then_statement->hir(& stmt->then_instructions, state);
+       state->symbols->pop_scope();
+    }
+    if (else_statement != NULL) {
+       state->symbols->push_scope();
+       else_statement->hir(& stmt->else_instructions, state);
+       state->symbols->pop_scope();
+    }
+    instructions->push_tail(stmt);
+    /* if-statements do not have r-values.
+     */
+    return NULL;
+ }
+ ir_rvalue *
+ ast_switch_statement::hir(exec_list *instructions,
+                           struct _mesa_glsl_parse_state *state)
+ {
+    void *ctx = state;
+    ir_rvalue *const test_expression =
+       this->test_expression->hir(instructions, state);
+    /* From page 66 (page 55 of the PDF) of the GLSL 1.50 spec:
+     *
+     *    "The type of init-expression in a switch statement must be a
+     *     scalar integer."
+     */
+    if (!test_expression->type->is_scalar() ||
+        !test_expression->type->is_integer()) {
+       YYLTYPE loc = this->test_expression->get_location();
+       _mesa_glsl_error(& loc,
+                        state,
+                        "switch-statement expression must be scalar "
+                        "integer");
+    }
+    /* Track the switch-statement nesting in a stack-like manner.
+     */
+    struct glsl_switch_state saved = state->switch_state;
+    state->switch_state.is_switch_innermost = true;
+    state->switch_state.switch_nesting_ast = this;
+    state->switch_state.labels_ht = hash_table_ctor(0, hash_table_pointer_hash,
+                                                  hash_table_pointer_compare);
+    state->switch_state.previous_default = NULL;
+    /* Initalize is_fallthru state to false.
+     */
+    ir_rvalue *const is_fallthru_val = new (ctx) ir_constant(false);
+    state->switch_state.is_fallthru_var =
+       new(ctx) ir_variable(glsl_type::bool_type,
+                            "switch_is_fallthru_tmp",
+                            ir_var_temporary);
+    instructions->push_tail(state->switch_state.is_fallthru_var);
+    ir_dereference_variable *deref_is_fallthru_var =
+       new(ctx) ir_dereference_variable(state->switch_state.is_fallthru_var);
+    instructions->push_tail(new(ctx) ir_assignment(deref_is_fallthru_var,
+                                                   is_fallthru_val));
+    /* Initialize continue_inside state to false.
+     */
+    state->switch_state.continue_inside =
+       new(ctx) ir_variable(glsl_type::bool_type,
+                            "continue_inside_tmp",
+                            ir_var_temporary);
+    instructions->push_tail(state->switch_state.continue_inside);
+    ir_rvalue *const false_val = new (ctx) ir_constant(false);
+    ir_dereference_variable *deref_continue_inside_var =
+       new(ctx) ir_dereference_variable(state->switch_state.continue_inside);
+    instructions->push_tail(new(ctx) ir_assignment(deref_continue_inside_var,
+                                                   false_val));
+    state->switch_state.run_default =
+       new(ctx) ir_variable(glsl_type::bool_type,
+                              "run_default_tmp",
+                              ir_var_temporary);
+    instructions->push_tail(state->switch_state.run_default);
+    /* Loop around the switch is used for flow control. */
+    ir_loop * loop = new(ctx) ir_loop();
+    instructions->push_tail(loop);
+    /* Cache test expression.
+     */
+    test_to_hir(&loop->body_instructions, state);
+    /* Emit code for body of switch stmt.
+     */
+    body->hir(&loop->body_instructions, state);
+    /* Insert a break at the end to exit loop. */
+    ir_loop_jump *jump = new(ctx) ir_loop_jump(ir_loop_jump::jump_break);
+    loop->body_instructions.push_tail(jump);
+    /* If we are inside loop, check if continue got called inside switch. */
+    if (state->loop_nesting_ast != NULL) {
+       ir_dereference_variable *deref_continue_inside =
+          new(ctx) ir_dereference_variable(state->switch_state.continue_inside);
+       ir_if *irif = new(ctx) ir_if(deref_continue_inside);
+       ir_loop_jump *jump = new(ctx) ir_loop_jump(ir_loop_jump::jump_continue);
+       if (state->loop_nesting_ast != NULL) {
+          if (state->loop_nesting_ast->rest_expression) {
+             state->loop_nesting_ast->rest_expression->hir(&irif->then_instructions,
+                                                           state);
+          }
+          if (state->loop_nesting_ast->mode ==
+              ast_iteration_statement::ast_do_while) {
+             state->loop_nesting_ast->condition_to_hir(&irif->then_instructions, state);
+          }
+       }
+       irif->then_instructions.push_tail(jump);
+       instructions->push_tail(irif);
+    }
+    hash_table_dtor(state->switch_state.labels_ht);
+    state->switch_state = saved;
+    /* Switch statements do not have r-values. */
+    return NULL;
+ }
+ void
+ ast_switch_statement::test_to_hir(exec_list *instructions,
+                                   struct _mesa_glsl_parse_state *state)
+ {
+    void *ctx = state;
+    /* Cache value of test expression. */
+    ir_rvalue *const test_val =
+       test_expression->hir(instructions,
+                          state);
+    state->switch_state.test_var = new(ctx) ir_variable(test_val->type,
+                                                        "switch_test_tmp",
+                                                        ir_var_temporary);
+    ir_dereference_variable *deref_test_var =
+       new(ctx) ir_dereference_variable(state->switch_state.test_var);
+    instructions->push_tail(state->switch_state.test_var);
+    instructions->push_tail(new(ctx) ir_assignment(deref_test_var, test_val));
+ }
+ ir_rvalue *
+ ast_switch_body::hir(exec_list *instructions,
+                      struct _mesa_glsl_parse_state *state)
+ {
+    if (stmts != NULL)
+       stmts->hir(instructions, state);
+    /* Switch bodies do not have r-values. */
+    return NULL;
+ }
+ ir_rvalue *
+ ast_case_statement_list::hir(exec_list *instructions,
+                              struct _mesa_glsl_parse_state *state)
+ {
+    exec_list default_case, after_default, tmp;
+    foreach_list_typed (ast_case_statement, case_stmt, link, & this->cases) {
+       case_stmt->hir(&tmp, state);
+       /* Default case. */
+       if (state->switch_state.previous_default && default_case.is_empty()) {
+          default_case.append_list(&tmp);
+          continue;
+       }
+       /* If default case found, append 'after_default' list. */
+       if (!default_case.is_empty())
+          after_default.append_list(&tmp);
+       else
+          instructions->append_list(&tmp);
+    }
+    /* Handle the default case. This is done here because default might not be
+     * the last case. We need to add checks against following cases first to see
+     * if default should be chosen or not.
+     */
+    if (!default_case.is_empty()) {
+       ir_rvalue *const true_val = new (state) ir_constant(true);
+       ir_dereference_variable *deref_run_default_var =
+          new(state) ir_dereference_variable(state->switch_state.run_default);
+       /* Choose to run default case initially, following conditional
+        * assignments might change this.
+        */
+       ir_assignment *const init_var =
+          new(state) ir_assignment(deref_run_default_var, true_val);
+       instructions->push_tail(init_var);
+       /* Default case was the last one, no checks required. */
+       if (after_default.is_empty()) {
+          instructions->append_list(&default_case);
+          return NULL;
+       }
+       foreach_in_list(ir_instruction, ir, &after_default) {
+          ir_assignment *assign = ir->as_assignment();
+          if (!assign)
+             continue;
+          /* Clone the check between case label and init expression. */
+          ir_expression *exp = (ir_expression*) assign->condition;
+          ir_expression *clone = exp->clone(state, NULL);
+          ir_dereference_variable *deref_var =
+             new(state) ir_dereference_variable(state->switch_state.run_default);
+          ir_rvalue *const false_val = new (state) ir_constant(false);
+          ir_assignment *const set_false =
+             new(state) ir_assignment(deref_var, false_val, clone);
+          instructions->push_tail(set_false);
+       }
+       /* Append default case and all cases after it. */
+       instructions->append_list(&default_case);
+       instructions->append_list(&after_default);
+    }
+    /* Case statements do not have r-values. */
+    return NULL;
+ }
+ ir_rvalue *
+ ast_case_statement::hir(exec_list *instructions,
+                         struct _mesa_glsl_parse_state *state)
+ {
+    labels->hir(instructions, state);
+    /* Guard case statements depending on fallthru state. */
+    ir_dereference_variable *const deref_fallthru_guard =
+       new(state) ir_dereference_variable(state->switch_state.is_fallthru_var);
+    ir_if *const test_fallthru = new(state) ir_if(deref_fallthru_guard);
+    foreach_list_typed (ast_node, stmt, link, & this->stmts)
+       stmt->hir(& test_fallthru->then_instructions, state);
+    instructions->push_tail(test_fallthru);
+    /* Case statements do not have r-values. */
+    return NULL;
+ }
+ ir_rvalue *
+ ast_case_label_list::hir(exec_list *instructions,
+                          struct _mesa_glsl_parse_state *state)
+ {
+    foreach_list_typed (ast_case_label, label, link, & this->labels)
+       label->hir(instructions, state);
+    /* Case labels do not have r-values. */
+    return NULL;
+ }
+ ir_rvalue *
+ ast_case_label::hir(exec_list *instructions,
+                     struct _mesa_glsl_parse_state *state)
+ {
+    void *ctx = state;
+    ir_dereference_variable *deref_fallthru_var =
+       new(ctx) ir_dereference_variable(state->switch_state.is_fallthru_var);
+    ir_rvalue *const true_val = new(ctx) ir_constant(true);
+    /* If not default case, ... */
+    if (this->test_value != NULL) {
+       /* Conditionally set fallthru state based on
+        * comparison of cached test expression value to case label.
+        */
+       ir_rvalue *const label_rval = this->test_value->hir(instructions, state);
+       ir_constant *label_const = label_rval->constant_expression_value();
+       if (!label_const) {
+          YYLTYPE loc = this->test_value->get_location();
+          _mesa_glsl_error(& loc, state,
+                           "switch statement case label must be a "
+                           "constant expression");
+          /* Stuff a dummy value in to allow processing to continue. */
+          label_const = new(ctx) ir_constant(0);
+       } else {
+          ast_expression *previous_label = (ast_expression *)
+          hash_table_find(state->switch_state.labels_ht,
+                          (void *)(uintptr_t)label_const->value.u[0]);
+          if (previous_label) {
+             YYLTYPE loc = this->test_value->get_location();
+             _mesa_glsl_error(& loc, state, "duplicate case value");
+             loc = previous_label->get_location();
+             _mesa_glsl_error(& loc, state, "this is the previous case label");
+          } else {
+             hash_table_insert(state->switch_state.labels_ht,
+                               this->test_value,
+                               (void *)(uintptr_t)label_const->value.u[0]);
+          }
+       }
+       ir_dereference_variable *deref_test_var =
+          new(ctx) ir_dereference_variable(state->switch_state.test_var);
+       ir_expression *test_cond = new(ctx) ir_expression(ir_binop_all_equal,
+                                                         label_const,
+                                                         deref_test_var);
+       /*
+        * From GLSL 4.40 specification section 6.2 ("Selection"):
+        *
+        *     "The type of the init-expression value in a switch statement must
+        *     be a scalar int or uint. The type of the constant-expression value
+        *     in a case label also must be a scalar int or uint. When any pair
+        *     of these values is tested for "equal value" and the types do not
+        *     match, an implicit conversion will be done to convert the int to a
+        *     uint (see section 4.1.10 “Implicit Conversions”) before the compare
+        *     is done."
+        */
+       if (label_const->type != state->switch_state.test_var->type) {
+          YYLTYPE loc = this->test_value->get_location();
+          const glsl_type *type_a = label_const->type;
+          const glsl_type *type_b = state->switch_state.test_var->type;
+          /* Check if int->uint implicit conversion is supported. */
+          bool integer_conversion_supported =
+             glsl_type::int_type->can_implicitly_convert_to(glsl_type::uint_type,
+                                                            state);
+          if ((!type_a->is_integer() || !type_b->is_integer()) ||
+               !integer_conversion_supported) {
+             _mesa_glsl_error(&loc, state, "type mismatch with switch "
+                              "init-expression and case label (%s != %s)",
+                              type_a->name, type_b->name);
+          } else {
+             /* Conversion of the case label. */
+             if (type_a->base_type == GLSL_TYPE_INT) {
+                if (!apply_implicit_conversion(glsl_type::uint_type,
+                                               test_cond->operands[0], state))
+                   _mesa_glsl_error(&loc, state, "implicit type conversion error");
+             } else {
+                /* Conversion of the init-expression value. */
+                if (!apply_implicit_conversion(glsl_type::uint_type,
+                                               test_cond->operands[1], state))
+                   _mesa_glsl_error(&loc, state, "implicit type conversion error");
+             }
+          }
+       }
+       ir_assignment *set_fallthru_on_test =
+          new(ctx) ir_assignment(deref_fallthru_var, true_val, test_cond);
+       instructions->push_tail(set_fallthru_on_test);
+    } else { /* default case */
+       if (state->switch_state.previous_default) {
+          YYLTYPE loc = this->get_location();
+          _mesa_glsl_error(& loc, state,
+                           "multiple default labels in one switch");
+          loc = state->switch_state.previous_default->get_location();
+          _mesa_glsl_error(& loc, state, "this is the first default label");
+       }
+       state->switch_state.previous_default = this;
+       /* Set fallthru condition on 'run_default' bool. */
+       ir_dereference_variable *deref_run_default =
+          new(ctx) ir_dereference_variable(state->switch_state.run_default);
+       ir_rvalue *const cond_true = new(ctx) ir_constant(true);
+       ir_expression *test_cond = new(ctx) ir_expression(ir_binop_all_equal,
+                                                         cond_true,
+                                                         deref_run_default);
+       /* Set falltrhu state. */
+       ir_assignment *set_fallthru =
+          new(ctx) ir_assignment(deref_fallthru_var, true_val, test_cond);
+       instructions->push_tail(set_fallthru);
+    }
+    /* Case statements do not have r-values. */
+    return NULL;
+ }
+ void
+ ast_iteration_statement::condition_to_hir(exec_list *instructions,
+                                           struct _mesa_glsl_parse_state *state)
+ {
+    void *ctx = state;
+    if (condition != NULL) {
+       ir_rvalue *const cond =
+          condition->hir(instructions, state);
+       if ((cond == NULL)
+           || !cond->type->is_boolean() || !cond->type->is_scalar()) {
+          YYLTYPE loc = condition->get_location();
+          _mesa_glsl_error(& loc, state,
+                           "loop condition must be scalar boolean");
+       } else {
+          /* As the first code in the loop body, generate a block that looks
+           * like 'if (!condition) break;' as the loop termination condition.
+           */
+          ir_rvalue *const not_cond =
+             new(ctx) ir_expression(ir_unop_logic_not, cond);
+          ir_if *const if_stmt = new(ctx) ir_if(not_cond);
+          ir_jump *const break_stmt =
+             new(ctx) ir_loop_jump(ir_loop_jump::jump_break);
+          if_stmt->then_instructions.push_tail(break_stmt);
+          instructions->push_tail(if_stmt);
+       }
+    }
+ }
+ ir_rvalue *
+ ast_iteration_statement::hir(exec_list *instructions,
+                              struct _mesa_glsl_parse_state *state)
+ {
+    void *ctx = state;
+    /* For-loops and while-loops start a new scope, but do-while loops do not.
+     */
+    if (mode != ast_do_while)
+       state->symbols->push_scope();
+    if (init_statement != NULL)
+       init_statement->hir(instructions, state);
+    ir_loop *const stmt = new(ctx) ir_loop();
+    instructions->push_tail(stmt);
+    /* Track the current loop nesting. */
+    ast_iteration_statement *nesting_ast = state->loop_nesting_ast;
+    state->loop_nesting_ast = this;
+    /* Likewise, indicate that following code is closest to a loop,
+     * NOT closest to a switch.
+     */
+    bool saved_is_switch_innermost = state->switch_state.is_switch_innermost;
+    state->switch_state.is_switch_innermost = false;
+    if (mode != ast_do_while)
+       condition_to_hir(&stmt->body_instructions, state);
+    if (body != NULL)
+       body->hir(& stmt->body_instructions, state);
+    if (rest_expression != NULL)
+       rest_expression->hir(& stmt->body_instructions, state);
+    if (mode == ast_do_while)
+       condition_to_hir(&stmt->body_instructions, state);
+    if (mode != ast_do_while)
+       state->symbols->pop_scope();
+    /* Restore previous nesting before returning. */
+    state->loop_nesting_ast = nesting_ast;
+    state->switch_state.is_switch_innermost = saved_is_switch_innermost;
+    /* Loops do not have r-values.
+     */
+    return NULL;
+ }
+ /**
+  * Determine if the given type is valid for establishing a default precision
+  * qualifier.
+  *
+  * From GLSL ES 3.00 section 4.5.4 ("Default Precision Qualifiers"):
+  *
+  *     "The precision statement
+  *
+  *         precision precision-qualifier type;
+  *
+  *     can be used to establish a default precision qualifier. The type field
+  *     can be either int or float or any of the sampler types, and the
+  *     precision-qualifier can be lowp, mediump, or highp."
+  *
+  * GLSL ES 1.00 has similar language.  GLSL 1.30 doesn't allow precision
+  * qualifiers on sampler types, but this seems like an oversight (since the
+  * intention of including these in GLSL 1.30 is to allow compatibility with ES
+  * shaders).  So we allow int, float, and all sampler types regardless of GLSL
+  * version.
+  */
+ static bool
+ is_valid_default_precision_type(const struct glsl_type *const type)
+ {
+    if (type == NULL)
+       return false;
+    switch (type->base_type) {
+    case GLSL_TYPE_INT:
+    case GLSL_TYPE_FLOAT:
+       /* "int" and "float" are valid, but vectors and matrices are not. */
+       return type->vector_elements == 1 && type->matrix_columns == 1;
+    case GLSL_TYPE_SAMPLER:
+    case GLSL_TYPE_IMAGE:
+    case GLSL_TYPE_ATOMIC_UINT:
+       return true;
+    default:
+       return false;
+    }
+ }
+ ir_rvalue *
+ ast_type_specifier::hir(exec_list *instructions,
+                         struct _mesa_glsl_parse_state *state)
+ {
+    if (this->default_precision == ast_precision_none && this->structure == NULL)
+       return NULL;
+    YYLTYPE loc = this->get_location();
+    /* If this is a precision statement, check that the type to which it is
+     * applied is either float or int.
+     *
+     * From section 4.5.3 of the GLSL 1.30 spec:
+     *    "The precision statement
+     *       precision precision-qualifier type;
+     *    can be used to establish a default precision qualifier. The type
+     *    field can be either int or float [...].  Any other types or
+     *    qualifiers will result in an error.
+     */
+    if (this->default_precision != ast_precision_none) {
+       if (!state->check_precision_qualifiers_allowed(&loc))
+          return NULL;
+       if (this->structure != NULL) {
+          _mesa_glsl_error(&loc, state,
+                           "precision qualifiers do not apply to structures");
+          return NULL;
+       }
+       if (this->array_specifier != NULL) {
+          _mesa_glsl_error(&loc, state,
+                           "default precision statements do not apply to "
+                           "arrays");
+          return NULL;
+       }
+       const struct glsl_type *const type =
+          state->symbols->get_type(this->type_name);
+       if (!is_valid_default_precision_type(type)) {
+          _mesa_glsl_error(&loc, state,
+                           "default precision statements apply only to "
+                           "float, int, and opaque types");
+          return NULL;
+       }
+       if (state->es_shader) {
+          /* Section 4.5.3 (Default Precision Qualifiers) of the GLSL ES 1.00
+           * spec says:
+           *
+           *     "Non-precision qualified declarations will use the precision
+           *     qualifier specified in the most recent precision statement
+           *     that is still in scope. The precision statement has the same
+           *     scoping rules as variable declarations. If it is declared
+           *     inside a compound statement, its effect stops at the end of
+           *     the innermost statement it was declared in. Precision
+           *     statements in nested scopes override precision statements in
+           *     outer scopes. Multiple precision statements for the same basic
+           *     type can appear inside the same scope, with later statements
+           *     overriding earlier statements within that scope."
+           *
+           * Default precision specifications follow the same scope rules as
+           * variables.  So, we can track the state of the default precision
+           * qualifiers in the symbol table, and the rules will just work.  This
+           * is a slight abuse of the symbol table, but it has the semantics
+           * that we want.
+           */
+          state->symbols->add_default_precision_qualifier(this->type_name,
+                                                          this->default_precision);
+       }
+       /* FINISHME: Translate precision statements into IR. */
+       return NULL;
+    }
+    /* _mesa_ast_set_aggregate_type() sets the <structure> field so that
+     * process_record_constructor() can do type-checking on C-style initializer
+     * expressions of structs, but ast_struct_specifier should only be translated
+     * to HIR if it is declaring the type of a structure.
+     *
+     * The ->is_declaration field is false for initializers of variables
+     * declared separately from the struct's type definition.
+     *
+     *    struct S { ... };              (is_declaration = true)
+     *    struct T { ... } t = { ... };  (is_declaration = true)
+     *    S s = { ... };                 (is_declaration = false)
+     */
+    if (this->structure != NULL && this->structure->is_declaration)
+       return this->structure->hir(instructions, state);
+    return NULL;
+ }
+ /**
+  * Process a structure or interface block tree into an array of structure fields
+  *
+  * After parsing, where there are some syntax differnces, structures and
+  * interface blocks are almost identical.  They are similar enough that the
+  * AST for each can be processed the same way into a set of
+  * \c glsl_struct_field to describe the members.
+  *
+  * If we're processing an interface block, var_mode should be the type of the
+  * interface block (ir_var_shader_in, ir_var_shader_out, ir_var_uniform or
+  * ir_var_shader_storage).  If we're processing a structure, var_mode should be
+  * ir_var_auto.
+  *
+  * \return
+  * The number of fields processed.  A pointer to the array structure fields is
+  * stored in \c *fields_ret.
+  */
+ static unsigned
+ ast_process_struct_or_iface_block_members(exec_list *instructions,
+                                           struct _mesa_glsl_parse_state *state,
+                                           exec_list *declarations,
+                                           glsl_struct_field **fields_ret,
+                                           bool is_interface,
+                                           enum glsl_matrix_layout matrix_layout,
+                                           bool allow_reserved_names,
+                                           ir_variable_mode var_mode,
+                                           ast_type_qualifier *layout,
+                                           unsigned block_stream,
+                                           unsigned expl_location)
+ {
+    unsigned decl_count = 0;
+    /* Make an initial pass over the list of fields to determine how
+     * many there are.  Each element in this list is an ast_declarator_list.
+     * This means that we actually need to count the number of elements in the
+     * 'declarations' list in each of the elements.
+     */
+    foreach_list_typed (ast_declarator_list, decl_list, link, declarations) {
+       decl_count += decl_list->declarations.length();
+    }
+    /* Allocate storage for the fields and process the field
+     * declarations.  As the declarations are processed, try to also convert
+     * the types to HIR.  This ensures that structure definitions embedded in
+     * other structure definitions or in interface blocks are processed.
+     */
+    glsl_struct_field *const fields = ralloc_array(state, glsl_struct_field,
+                                                   decl_count);
+    bool first_member = true;
+    bool first_member_has_explicit_location;
+    unsigned i = 0;
+    foreach_list_typed (ast_declarator_list, decl_list, link, declarations) {
+       const char *type_name;
+       YYLTYPE loc = decl_list->get_location();
+       decl_list->type->specifier->hir(instructions, state);
+       /* Section 10.9 of the GLSL ES 1.00 specification states that
+        * embedded structure definitions have been removed from the language.
+        */
+       if (state->es_shader && decl_list->type->specifier->structure != NULL) {
+          _mesa_glsl_error(&loc, state, "embedded structure definitions are "
+                           "not allowed in GLSL ES 1.00");
+       }
+       const glsl_type *decl_type =
+          decl_list->type->glsl_type(& type_name, state);
+       const struct ast_type_qualifier *const qual =
+          &decl_list->type->qualifier;
+       /* From section 4.3.9 of the GLSL 4.40 spec:
+        *
+        *    "[In interface blocks] opaque types are not allowed."
+        *
+        * It should be impossible for decl_type to be NULL here.  Cases that
+        * might naturally lead to decl_type being NULL, especially for the
+        * is_interface case, will have resulted in compilation having
+        * already halted due to a syntax error.
+        */
+       assert(decl_type);
+       if (is_interface && decl_type->contains_opaque()) {
+          _mesa_glsl_error(&loc, state,
+                           "uniform/buffer in non-default interface block contains "
+                           "opaque variable");
+       }
+       if (decl_type->contains_atomic()) {
+          /* From section 4.1.7.3 of the GLSL 4.40 spec:
+           *
+           *    "Members of structures cannot be declared as atomic counter
+           *     types."
+           */
+          _mesa_glsl_error(&loc, state, "atomic counter in structure, "
+                           "shader storage block or uniform block");
+       }
+       if (decl_type->contains_image()) {
+          /* FINISHME: Same problem as with atomic counters.
+           * FINISHME: Request clarification from Khronos and add
+           * FINISHME: spec quotation here.
+           */
+          _mesa_glsl_error(&loc, state,
+                           "image in structure, shader storage block or "
+                           "uniform block");
+       }
+       if (qual->flags.q.explicit_binding) {
+          _mesa_glsl_error(&loc, state,
+                           "binding layout qualifier cannot be applied "
+                           "to struct or interface block members");
+       }
+       if (is_interface) {
+          if (!first_member) {
+             if (!layout->flags.q.explicit_location &&
+                 ((first_member_has_explicit_location &&
+                   !qual->flags.q.explicit_location) ||
+                  (!first_member_has_explicit_location &&
+                   qual->flags.q.explicit_location))) {
+                _mesa_glsl_error(&loc, state,
+                                 "when block-level location layout qualifier "
+                                 "is not supplied either all members must "
+                                 "have a location layout qualifier or all "
+                                 "members must not have a location layout "
+                                 "qualifier");
+             }
+          } else {
+             first_member = false;
+             first_member_has_explicit_location =
+                qual->flags.q.explicit_location;
+          }
+       }
+       if (qual->flags.q.std140 ||
+           qual->flags.q.std430 ||
+           qual->flags.q.packed ||
+           qual->flags.q.shared) {
+          _mesa_glsl_error(&loc, state,
+                           "uniform/shader storage block layout qualifiers "
+                           "std140, std430, packed, and shared can only be "
+        &n