1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright © 2010 Intel Corporation
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the "Software"),
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to deal in the Software without restriction, including without limitation
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and/or sell copies of the Software, and to permit persons to whom the
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software is furnished to do so, subject to the following conditions:
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the next
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * paragraph) shall be included in all copies or substantial portions of the
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software.
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * DEALINGS IN THE SOFTWARE.
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \file ast_to_hir.c
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Convert abstract syntax to to high-level intermediate reprensentation (HIR).
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * During the conversion to HIR, the majority of the symantic checking is
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * preformed on the program.  This includes:
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    * Symbol table management
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    * Type checking
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    * Function binding
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The majority of this work could be done during parsing, and the parser could
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * probably generate HIR directly.  However, this results in frequent changes
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to the parser code.  Since we do not assume that every system this complier
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * is built on will have Flex and Bison installed, we have to store the code
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * generated by these tools in our version control system.  In other parts of
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the system we've seen problems where a parser was changed but the generated
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * code was not committed, merge conflicts where created because two developers
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * had slightly different versions of Bison installed, etc.
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * I have also noticed that running Bison generated parsers in GDB is very
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * irritating.  When you get a segfault on '$$ = $1->foo', you can't very
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * well 'print $1' in GDB.
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * As a result, my preference is to put as little C code as possible in the
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * parser (and lexer) sources.
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/core.h" /* for struct gl_extensions */
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "glsl_symbol_table.h"
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "glsl_parser_extras.h"
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "ast.h"
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "glsl_types.h"
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "program/hash_table.h"
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "ir.h"
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdetect_conflicting_assignments(struct _mesa_glsl_parse_state *state,
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			       exec_list *instructions);
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state)
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   _mesa_glsl_initialize_variables(instructions, state);
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   state->symbols->language_version = state->language_version;
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   state->current_function = NULL;
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   state->toplevel_ir = instructions;
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Section 4.2 of the GLSL 1.20 specification states:
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * "The built-in functions are scoped in a scope outside the global scope
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *  users declare global variables in.  That is, a shader's global scope,
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *  available for user-defined functions and global variables, is nested
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *  inside the scope containing the built-in functions."
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * Since built-in functions like ftransform() access built-in variables,
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * it follows that those must be in the outer scope as well.
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * We push scope here to create this nesting effect...but don't pop.
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * This way, a shader's globals are still in the symbol table for use
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * by the linker.
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   state->symbols->push_scope();
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   foreach_list_typed (ast_node, ast, link, & state->translation_unit)
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ast->hir(instructions, state);
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   detect_recursion_unlinked(state, instructions);
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   detect_conflicting_assignments(state, instructions);
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   state->toplevel_ir = NULL;
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * If a conversion is available, convert one operand to a different type
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The \c from \c ir_rvalue is converted "in place".
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param to     Type that the operand it to be converted to
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param from   Operand that is being converted
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param state  GLSL compiler state
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \return
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * If a conversion is possible (or unnecessary), \c true is returned.
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Otherwise \c false is returned.
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgapply_implicit_conversion(const glsl_type *to, ir_rvalue * &from,
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  struct _mesa_glsl_parse_state *state)
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void *ctx = state;
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (to->base_type == from->type->base_type)
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return true;
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* This conversion was added in GLSL 1.20.  If the compilation mode is
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * GLSL 1.10, the conversion is skipped.
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (state->language_version < 120)
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return false;
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* From page 27 (page 33 of the PDF) of the GLSL 1.50 spec:
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    "There are no implicit array or structure conversions. For
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    example, an array of int cannot be implicitly converted to an
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    array of float. There are no implicit conversions between
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    signed and unsigned integers."
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* FINISHME: The above comment is partially a lie.  There is int/uint
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * FINISHME: conversion for immediate constants.
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!to->is_float() || !from->type->is_numeric())
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return false;
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Convert to a floating point type with the same number of components
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * as the original type - i.e. int to float, not int to vec4.
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   to = glsl_type::get_instance(GLSL_TYPE_FLOAT, from->type->vector_elements,
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			        from->type->matrix_columns);
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (from->type->base_type) {
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GLSL_TYPE_INT:
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      from = new(ctx) ir_expression(ir_unop_i2f, to, from, NULL);
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GLSL_TYPE_UINT:
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      from = new(ctx) ir_expression(ir_unop_u2f, to, from, NULL);
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GLSL_TYPE_BOOL:
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      from = new(ctx) ir_expression(ir_unop_b2f, to, from, NULL);
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(0);
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return true;
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const struct glsl_type *
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgarithmetic_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b,
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       bool multiply,
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const glsl_type *type_a = value_a->type;
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const glsl_type *type_b = value_b->type;
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* From GLSL 1.50 spec, page 56:
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    "The arithmetic binary operators add (+), subtract (-),
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    multiply (*), and divide (/) operate on integer and
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    floating-point scalars, vectors, and matrices."
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!type_a->is_numeric() || !type_b->is_numeric()) {
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(loc, state,
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       "Operands to arithmetic operators must be numeric");
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return glsl_type::error_type;
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*    "If one operand is floating-point based and the other is
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    not, then the conversions from Section 4.1.10 "Implicit
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    Conversions" are applied to the non-floating-point-based operand."
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!apply_implicit_conversion(type_a, value_b, state)
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       && !apply_implicit_conversion(type_b, value_a, state)) {
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(loc, state,
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       "Could not implicitly convert operands to "
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       "arithmetic operator");
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return glsl_type::error_type;
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   type_a = value_a->type;
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   type_b = value_b->type;
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*    "If the operands are integer types, they must both be signed or
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    both be unsigned."
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * From this rule and the preceeding conversion it can be inferred that
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * both types must be GLSL_TYPE_FLOAT, or GLSL_TYPE_UINT, or GLSL_TYPE_INT.
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * The is_numeric check above already filtered out the case where either
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * type is not one of these, so now the base types need only be tested for
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * equality.
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (type_a->base_type != type_b->base_type) {
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(loc, state,
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       "base type mismatch for arithmetic operator");
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return glsl_type::error_type;
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*    "All arithmetic binary operators result in the same fundamental type
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    (signed integer, unsigned integer, or floating-point) as the
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    operands they operate on, after operand type conversion. After
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    conversion, the following cases are valid
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    * The two operands are scalars. In this case the operation is
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *      applied, resulting in a scalar."
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (type_a->is_scalar() && type_b->is_scalar())
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return type_a;
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*   "* One operand is a scalar, and the other is a vector or matrix.
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *      In this case, the scalar operation is applied independently to each
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *      component of the vector or matrix, resulting in the same size
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *      vector or matrix."
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (type_a->is_scalar()) {
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!type_b->is_scalar())
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 return type_b;
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else if (type_b->is_scalar()) {
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return type_a;
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* All of the combinations of <scalar, scalar>, <vector, scalar>,
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * <scalar, vector>, <scalar, matrix>, and <matrix, scalar> have been
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * handled.
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(!type_a->is_scalar());
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(!type_b->is_scalar());
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*   "* The two operands are vectors of the same size. In this case, the
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *      operation is done component-wise resulting in the same size
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *      vector."
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (type_a->is_vector() && type_b->is_vector()) {
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (type_a == type_b) {
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 return type_a;
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 _mesa_glsl_error(loc, state,
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  "vector size mismatch for arithmetic operator");
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 return glsl_type::error_type;
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* All of the combinations of <scalar, scalar>, <vector, scalar>,
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * <scalar, vector>, <scalar, matrix>, <matrix, scalar>, and
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * <vector, vector> have been handled.  At least one of the operands must
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * be matrix.  Further, since there are no integer matrix types, the base
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * type of both operands must be float.
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(type_a->is_matrix() || type_b->is_matrix());
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(type_a->base_type == GLSL_TYPE_FLOAT);
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(type_b->base_type == GLSL_TYPE_FLOAT);
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*   "* The operator is add (+), subtract (-), or divide (/), and the
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *      operands are matrices with the same number of rows and the same
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *      number of columns. In this case, the operation is done component-
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *      wise resulting in the same size matrix."
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    * The operator is multiply (*), where both operands are matrices or
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *      one operand is a vector and the other a matrix. A right vector
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *      operand is treated as a column vector and a left vector operand as a
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *      row vector. In all these cases, it is required that the number of
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *      columns of the left operand is equal to the number of rows of the
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *      right operand. Then, the multiply (*) operation does a linear
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *      algebraic multiply, yielding an object that has the same number of
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *      rows as the left operand and the same number of columns as the right
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *      operand. Section 5.10 "Vector and Matrix Operations" explains in
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *      more detail how vectors and matrices are operated on."
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (! multiply) {
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (type_a == type_b)
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 return type_a;
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (type_a->is_matrix() && type_b->is_matrix()) {
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* Matrix multiply.  The columns of A must match the rows of B.  Given
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * the other previously tested constraints, this means the vector type
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * of a row from A must be the same as the vector type of a column from
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * B.
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  */
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (type_a->row_type() == type_b->column_type()) {
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    /* The resulting matrix has the number of columns of matrix B and
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     * the number of rows of matrix A.  We get the row count of A by
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     * looking at the size of a vector that makes up a column.  The
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     * transpose (size of a row) is done for B.
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     */
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    const glsl_type *const type =
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       glsl_type::get_instance(type_a->base_type,
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       type_a->column_type()->vector_elements,
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       type_b->row_type()->vector_elements);
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    assert(type != glsl_type::error_type);
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    return type;
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else if (type_a->is_matrix()) {
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* A is a matrix and B is a column vector.  Columns of A must match
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * rows of B.  Given the other previously tested constraints, this
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * means the vector type of a row from A must be the same as the
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * vector the type of B.
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  */
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (type_a->row_type() == type_b) {
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    /* The resulting vector has a number of elements equal to
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     * the number of rows of matrix A. */
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    const glsl_type *const type =
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       glsl_type::get_instance(type_a->base_type,
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       type_a->column_type()->vector_elements,
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       1);
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    assert(type != glsl_type::error_type);
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    return type;
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 assert(type_b->is_matrix());
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* A is a row vector and B is a matrix.  Columns of A must match rows
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * of B.  Given the other previously tested constraints, this means
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * the type of A must be the same as the vector type of a column from
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * B.
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  */
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (type_a == type_b->column_type()) {
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    /* The resulting vector has a number of elements equal to
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     * the number of columns of matrix B. */
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    const glsl_type *const type =
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       glsl_type::get_instance(type_a->base_type,
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       type_b->row_type()->vector_elements,
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       1);
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    assert(type != glsl_type::error_type);
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    return type;
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(loc, state, "size mismatch for matrix multiplication");
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return glsl_type::error_type;
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*    "All other cases are illegal."
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   _mesa_glsl_error(loc, state, "type mismatch");
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return glsl_type::error_type;
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const struct glsl_type *
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgunary_arithmetic_result_type(const struct glsl_type *type,
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* From GLSL 1.50 spec, page 57:
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    "The arithmetic unary operators negate (-), post- and pre-increment
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *     and decrement (-- and ++) operate on integer or floating-point
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *     values (including vectors and matrices). All unary operators work
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *     component-wise on their operands. These result with the same type
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *     they operated on."
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!type->is_numeric()) {
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(loc, state,
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       "Operands to arithmetic operators must be numeric");
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return glsl_type::error_type;
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return type;
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \brief Return the result type of a bit-logic operation.
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * If the given types to the bit-logic operator are invalid, return
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * glsl_type::error_type.
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param type_a Type of LHS of bit-logic op
385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param type_b Type of RHS of bit-logic op
386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const struct glsl_type *
388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbit_logic_result_type(const struct glsl_type *type_a,
389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      const struct glsl_type *type_b,
390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      ast_operators op,
391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (state->language_version < 130) {
394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       _mesa_glsl_error(loc, state, "bit operations require GLSL 1.30");
395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       return glsl_type::error_type;
396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    /* From page 50 (page 56 of PDF) of GLSL 1.30 spec:
399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     *
400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     *     "The bitwise operators and (&), exclusive-or (^), and inclusive-or
401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     *     (|). The operands must be of type signed or unsigned integers or
402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     *     integer vectors."
403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     */
404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (!type_a->is_integer()) {
405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       _mesa_glsl_error(loc, state, "LHS of `%s' must be an integer",
406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         ast_expression::operator_string(op));
407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       return glsl_type::error_type;
408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (!type_b->is_integer()) {
410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       _mesa_glsl_error(loc, state, "RHS of `%s' must be an integer",
411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        ast_expression::operator_string(op));
412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       return glsl_type::error_type;
413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    /*     "The fundamental types of the operands (signed or unsigned) must
416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     *     match,"
417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     */
418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (type_a->base_type != type_b->base_type) {
419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       _mesa_glsl_error(loc, state, "operands of `%s' must have the same "
420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        "base type", ast_expression::operator_string(op));
421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       return glsl_type::error_type;
422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    /*     "The operands cannot be vectors of differing size." */
425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (type_a->is_vector() &&
426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        type_b->is_vector() &&
427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        type_a->vector_elements != type_b->vector_elements) {
428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       _mesa_glsl_error(loc, state, "operands of `%s' cannot be vectors of "
429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        "different sizes", ast_expression::operator_string(op));
430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       return glsl_type::error_type;
431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    /*     "If one operand is a scalar and the other a vector, the scalar is
434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     *     applied component-wise to the vector, resulting in the same type as
435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     *     the vector. The fundamental types of the operands [...] will be the
436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     *     resulting fundamental type."
437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     */
438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (type_a->is_scalar())
439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        return type_b;
440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    else
441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        return type_a;
442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const struct glsl_type *
445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgmodulus_result_type(const struct glsl_type *type_a,
446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		    const struct glsl_type *type_b,
447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		    struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (state->language_version < 130) {
450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(loc, state,
451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       "operator '%%' is reserved in %s",
452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       state->version_string);
453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return glsl_type::error_type;
454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* From GLSL 1.50 spec, page 56:
457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    "The operator modulus (%) operates on signed or unsigned integers or
458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    integer vectors. The operand types must both be signed or both be
459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    unsigned."
460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!type_a->is_integer()) {
462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(loc, state, "LHS of operator %% must be an integer.");
463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return glsl_type::error_type;
464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!type_b->is_integer()) {
466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(loc, state, "RHS of operator %% must be an integer.");
467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return glsl_type::error_type;
468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (type_a->base_type != type_b->base_type) {
470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(loc, state,
471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       "operands of %% must have the same base type");
472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return glsl_type::error_type;
473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*    "The operands cannot be vectors of differing size. If one operand is
476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    a scalar and the other vector, then the scalar is applied component-
477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    wise to the vector, resulting in the same type as the vector. If both
478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    are vectors of the same size, the result is computed component-wise."
479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (type_a->is_vector()) {
481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!type_b->is_vector()
482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  || (type_a->vector_elements == type_b->vector_elements))
483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 return type_a;
484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else
485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return type_b;
486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*    "The operator modulus (%) is not defined for any other data types
488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    (non-integer types)."
489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   _mesa_glsl_error(loc, state, "type mismatch");
491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return glsl_type::error_type;
492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const struct glsl_type *
496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgrelational_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b,
497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const glsl_type *type_a = value_a->type;
500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const glsl_type *type_b = value_b->type;
501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* From GLSL 1.50 spec, page 56:
503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    "The relational operators greater than (>), less than (<), greater
504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    than or equal (>=), and less than or equal (<=) operate only on
505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    scalar integer and scalar floating-point expressions."
506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!type_a->is_numeric()
508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       || !type_b->is_numeric()
509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       || !type_a->is_scalar()
510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       || !type_b->is_scalar()) {
511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(loc, state,
512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       "Operands to relational operators must be scalar and "
513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       "numeric");
514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return glsl_type::error_type;
515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*    "Either the operands' types must match, or the conversions from
518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    Section 4.1.10 "Implicit Conversions" will be applied to the integer
519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    operand, after which the types must match."
520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!apply_implicit_conversion(type_a, value_b, state)
522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       && !apply_implicit_conversion(type_b, value_a, state)) {
523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(loc, state,
524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       "Could not implicitly convert operands to "
525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       "relational operator");
526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return glsl_type::error_type;
527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   type_a = value_a->type;
529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   type_b = value_b->type;
530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (type_a->base_type != type_b->base_type) {
532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(loc, state, "base type mismatch");
533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return glsl_type::error_type;
534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*    "The result is scalar Boolean."
537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return glsl_type::bool_type;
539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \brief Return the result type of a bit-shift operation.
543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * If the given types to the bit-shift operator are invalid, return
545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * glsl_type::error_type.
546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param type_a Type of LHS of bit-shift op
548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param type_b Type of RHS of bit-shift op
549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const struct glsl_type *
551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgshift_result_type(const struct glsl_type *type_a,
552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  const struct glsl_type *type_b,
553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  ast_operators op,
554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (state->language_version < 130) {
557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(loc, state, "bit operations require GLSL 1.30");
558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return glsl_type::error_type;
559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* From page 50 (page 56 of the PDF) of the GLSL 1.30 spec:
562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *     "The shift operators (<<) and (>>). For both operators, the operands
564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *     must be signed or unsigned integers or integer vectors. One operand
565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *     can be signed while the other is unsigned."
566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!type_a->is_integer()) {
568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(loc, state, "LHS of operator %s must be an integer or "
569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              "integer vector", ast_expression::operator_string(op));
570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     return glsl_type::error_type;
571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!type_b->is_integer()) {
574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(loc, state, "RHS of operator %s must be an integer or "
575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              "integer vector", ast_expression::operator_string(op));
576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     return glsl_type::error_type;
577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*     "If the first operand is a scalar, the second operand has to be
580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *     a scalar as well."
581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (type_a->is_scalar() && !type_b->is_scalar()) {
583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(loc, state, "If the first operand of %s is scalar, the "
584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              "second must be scalar as well",
585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              ast_expression::operator_string(op));
586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     return glsl_type::error_type;
587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* If both operands are vectors, check that they have same number of
590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * elements.
591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (type_a->is_vector() &&
593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      type_b->is_vector() &&
594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      type_a->vector_elements != type_b->vector_elements) {
595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(loc, state, "Vector operands to operator %s must "
596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              "have same number of elements",
597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              ast_expression::operator_string(op));
598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     return glsl_type::error_type;
599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*     "In all cases, the resulting type will be the same type as the left
602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *     operand."
603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return type_a;
605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Validates that a value can be assigned to a location with a specified type
609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Validates that \c rhs can be assigned to some location.  If the types are
611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * not an exact match but an automatic conversion is possible, \c rhs will be
612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * converted.
613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \return
615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \c NULL if \c rhs cannot be assigned to a location with type \c lhs_type.
616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Otherwise the actual RHS to be assigned will be returned.  This may be
617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \c rhs, or it may be \c rhs after some type conversion.
618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \note
620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * In addition to being used for assignments, this function is used to
621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * type-check return values.
622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue *
624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvalidate_assignment(struct _mesa_glsl_parse_state *state,
625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		    const glsl_type *lhs_type, ir_rvalue *rhs,
626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		    bool is_initializer)
627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* If there is already some error in the RHS, just return it.  Anything
629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * else will lead to an avalanche of error message back to the user.
630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (rhs->type->is_error())
632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return rhs;
633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* If the types are identical, the assignment can trivially proceed.
635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (rhs->type == lhs_type)
637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return rhs;
638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* If the array element types are the same and the size of the LHS is zero,
640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * the assignment is okay for initializers embedded in variable
641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * declarations.
642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * Note: Whole-array assignments are not permitted in GLSL 1.10, but this
644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * is handled by ir_dereference::is_lvalue.
645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (is_initializer && lhs_type->is_array() && rhs->type->is_array()
647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       && (lhs_type->element_type() == rhs->type->element_type())
648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       && (lhs_type->array_size() == 0)) {
649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return rhs;
650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Check for implicit conversion in GLSL 1.20 */
653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (apply_implicit_conversion(lhs_type, rhs, state)) {
654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (rhs->type == lhs_type)
655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 return rhs;
656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return NULL;
659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgmark_whole_array_access(ir_rvalue *access)
663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_dereference_variable *deref = access->as_dereference_variable();
665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (deref && deref->var) {
667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      deref->var->max_array_access = deref->type->length - 1;
668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue *
672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdo_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state,
673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      const char *non_lvalue_description,
674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      ir_rvalue *lhs, ir_rvalue *rhs, bool is_initializer,
675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      YYLTYPE lhs_loc)
676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void *ctx = state;
678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   bool error_emitted = (lhs->type->is_error() || rhs->type->is_error());
679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_variable *lhs_var = lhs->variable_referenced();
681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (lhs_var)
682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lhs_var->assigned = true;
683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!error_emitted) {
685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (non_lvalue_description != NULL) {
686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         _mesa_glsl_error(&lhs_loc, state,
687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          "assignment to %s",
688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  non_lvalue_description);
689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 error_emitted = true;
690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else if (lhs->variable_referenced() != NULL
691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 && lhs->variable_referenced()->read_only) {
692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         _mesa_glsl_error(&lhs_loc, state,
693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          "assignment to read-only variable '%s'",
694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          lhs->variable_referenced()->name);
695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         error_emitted = true;
696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else if (state->language_version <= 110 && lhs->type->is_array()) {
698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* From page 32 (page 38 of the PDF) of the GLSL 1.10 spec:
699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  *
700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  *    "Other binary or unary expressions, non-dereferenced
701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  *     arrays, function names, swizzles with repeated fields,
702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  *     and constants cannot be l-values."
703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  */
704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 _mesa_glsl_error(&lhs_loc, state, "whole array assignment is not "
705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  "allowed in GLSL 1.10 or GLSL ES 1.00.");
706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 error_emitted = true;
707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else if (!lhs->is_lvalue()) {
708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 _mesa_glsl_error(& lhs_loc, state, "non-lvalue in assignment");
709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 error_emitted = true;
710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_rvalue *new_rhs =
714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      validate_assignment(state, lhs->type, rhs, is_initializer);
715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (new_rhs == NULL) {
716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(& lhs_loc, state, "type mismatch");
717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      rhs = new_rhs;
719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* If the LHS array was not declared with a size, it takes it size from
721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * the RHS.  If the LHS is an l-value and a whole array, it must be a
722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * dereference of a variable.  Any other case would require that the LHS
723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * is either not an l-value or not a whole array.
724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (lhs->type->array_size() == 0) {
726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ir_dereference *const d = lhs->as_dereference();
727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 assert(d != NULL);
729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ir_variable *const var = d->variable_referenced();
731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 assert(var != NULL);
733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (var->max_array_access >= unsigned(rhs->type->array_size())) {
735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    /* FINISHME: This should actually log the location of the RHS. */
736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    _mesa_glsl_error(& lhs_loc, state, "array size must be > %u due to "
737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     "previous access",
738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     var->max_array_access);
739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 var->type = glsl_type::get_array_instance(lhs->type->element_type(),
742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						   rhs->type->array_size());
743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 d->type = var->type;
744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      mark_whole_array_access(rhs);
746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      mark_whole_array_access(lhs);
747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Most callers of do_assignment (assign, add_assign, pre_inc/dec,
750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * but not post_inc) need the converted assigned value as an rvalue
751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * to handle things like:
752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * i = j += 1;
754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * So we always just store the computed value being assigned to a
756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * temporary and return a deref of that temporary.  If the rvalue
757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * ends up not being used, the temp will get copy-propagated out.
758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_variable *var = new(ctx) ir_variable(rhs->type, "assignment_tmp",
760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					   ir_var_temporary);
761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_dereference_variable *deref_var = new(ctx) ir_dereference_variable(var);
762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   instructions->push_tail(var);
763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   instructions->push_tail(new(ctx) ir_assignment(deref_var, rhs));
764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   deref_var = new(ctx) ir_dereference_variable(var);
765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!error_emitted)
767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      instructions->push_tail(new(ctx) ir_assignment(lhs, deref_var));
768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return new(ctx) ir_dereference_variable(var);
770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic ir_rvalue *
773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgget_lvalue_copy(exec_list *instructions, ir_rvalue *lvalue)
774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void *ctx = ralloc_parent(lvalue);
776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_variable *var;
777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   var = new(ctx) ir_variable(lvalue->type, "_post_incdec_tmp",
779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			      ir_var_temporary);
780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   instructions->push_tail(var);
781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   var->mode = ir_var_auto;
782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   instructions->push_tail(new(ctx) ir_assignment(new(ctx) ir_dereference_variable(var),
784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						  lvalue));
785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return new(ctx) ir_dereference_variable(var);
787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue *
791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgast_node::hir(exec_list *instructions,
792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      struct _mesa_glsl_parse_state *state)
793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) instructions;
795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) state;
796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return NULL;
798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic ir_rvalue *
801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdo_comparison(void *mem_ctx, int operation, ir_rvalue *op0, ir_rvalue *op1)
802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int join_op;
804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_rvalue *cmp = NULL;
805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (operation == ir_binop_all_equal)
807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      join_op = ir_binop_logic_and;
808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else
809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      join_op = ir_binop_logic_or;
810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (op0->type->base_type) {
812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GLSL_TYPE_FLOAT:
813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GLSL_TYPE_UINT:
814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GLSL_TYPE_INT:
815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GLSL_TYPE_BOOL:
816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return new(mem_ctx) ir_expression(operation, op0, op1);
817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GLSL_TYPE_ARRAY: {
819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned int i = 0; i < op0->type->length; i++) {
820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ir_rvalue *e0, *e1, *result;
821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 e0 = new(mem_ctx) ir_dereference_array(op0->clone(mem_ctx, NULL),
823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						new(mem_ctx) ir_constant(i));
824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 e1 = new(mem_ctx) ir_dereference_array(op1->clone(mem_ctx, NULL),
825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						new(mem_ctx) ir_constant(i));
826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 result = do_comparison(mem_ctx, operation, e0, e1);
827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (cmp) {
829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    cmp = new(mem_ctx) ir_expression(join_op, cmp, result);
830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 } else {
831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    cmp = result;
832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      mark_whole_array_access(op0);
836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      mark_whole_array_access(op1);
837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GLSL_TYPE_STRUCT: {
841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned int i = 0; i < op0->type->length; i++) {
842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ir_rvalue *e0, *e1, *result;
843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 const char *field_name = op0->type->fields.structure[i].name;
844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 e0 = new(mem_ctx) ir_dereference_record(op0->clone(mem_ctx, NULL),
846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						 field_name);
847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 e1 = new(mem_ctx) ir_dereference_record(op1->clone(mem_ctx, NULL),
848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						 field_name);
849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 result = do_comparison(mem_ctx, operation, e0, e1);
850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (cmp) {
852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    cmp = new(mem_ctx) ir_expression(join_op, cmp, result);
853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 } else {
854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    cmp = result;
855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GLSL_TYPE_ERROR:
861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GLSL_TYPE_VOID:
862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GLSL_TYPE_SAMPLER:
863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* I assume a comparison of a struct containing a sampler just
864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * ignores the sampler present in the type.
865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(!"Should not get here.");
870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (cmp == NULL)
874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      cmp = new(mem_ctx) ir_constant(true);
875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return cmp;
877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* For logical operations, we want to ensure that the operands are
880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * scalar booleans.  If it isn't, emit an error and return a constant
881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * boolean to avoid triggering cascading error messages.
882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue *
884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgget_scalar_boolean_operand(exec_list *instructions,
885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   struct _mesa_glsl_parse_state *state,
886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   ast_expression *parent_expr,
887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   int operand,
888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   const char *operand_name,
889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   bool *error_emitted)
890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ast_expression *expr = parent_expr->subexpressions[operand];
892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void *ctx = state;
893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_rvalue *val = expr->hir(instructions, state);
894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (val->type->is_boolean() && val->type->is_scalar())
896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return val;
897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!*error_emitted) {
899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      YYLTYPE loc = expr->get_location();
900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(&loc, state, "%s of `%s' must be scalar boolean",
901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       operand_name,
902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       parent_expr->operator_string(parent_expr->oper));
903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *error_emitted = true;
904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return new(ctx) ir_constant(true);
907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * If name refers to a builtin array whose maximum allowed size is less than
911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * size, report an error and return true.  Otherwise return false.
912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic bool
914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgcheck_builtin_array_max_size(const char *name, unsigned size,
915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             YYLTYPE loc, struct _mesa_glsl_parse_state *state)
916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if ((strcmp("gl_TexCoord", name) == 0)
918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       && (size > state->Const.MaxTextureCoords)) {
919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* From page 54 (page 60 of the PDF) of the GLSL 1.20 spec:
920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *     "The size [of gl_TexCoord] can be at most
922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *     gl_MaxTextureCoords."
923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(&loc, state, "`gl_TexCoord' array size cannot "
925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       "be larger than gl_MaxTextureCoords (%u)\n",
926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       state->Const.MaxTextureCoords);
927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return true;
928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else if (strcmp("gl_ClipDistance", name) == 0
929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              && size > state->Const.MaxClipPlanes) {
930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* From section 7.1 (Vertex Shader Special Variables) of the
931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * GLSL 1.30 spec:
932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *   "The gl_ClipDistance array is predeclared as unsized and
934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *   must be sized by the shader either redeclaring it with a
935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *   size or indexing it only with integral constant
936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *   expressions. ... The size can be at most
937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *   gl_MaxClipDistances."
938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(&loc, state, "`gl_ClipDistance' array size cannot "
940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       "be larger than gl_MaxClipDistances (%u)\n",
941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       state->Const.MaxClipPlanes);
942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return true;
943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return false;
945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Create the constant 1, of a which is appropriate for incrementing and
949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * decrementing values of the given GLSL type.  For example, if type is vec4,
950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * this creates a constant value of 1.0 having type float.
951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * If the given type is invalid for increment and decrement operators, return
953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * a floating point 1--the error will be detected later.
954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic ir_rvalue *
956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgconstant_one_for_inc_dec(void *ctx, const glsl_type *type)
957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (type->base_type) {
959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GLSL_TYPE_UINT:
960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return new(ctx) ir_constant((unsigned) 1);
961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GLSL_TYPE_INT:
962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return new(ctx) ir_constant(1);
963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GLSL_TYPE_FLOAT:
965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return new(ctx) ir_constant(1.0f);
966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue *
970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgast_expression::hir(exec_list *instructions,
971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		    struct _mesa_glsl_parse_state *state)
972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void *ctx = state;
974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   static const int operations[AST_NUM_OPERATORS] = {
975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      -1,               /* ast_assign doesn't convert to ir_expression. */
976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      -1,               /* ast_plus doesn't convert to ir_expression. */
977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_unop_neg,
978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_binop_add,
979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_binop_sub,
980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_binop_mul,
981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_binop_div,
982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_binop_mod,
983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_binop_lshift,
984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_binop_rshift,
985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_binop_less,
986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_binop_greater,
987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_binop_lequal,
988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_binop_gequal,
989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_binop_all_equal,
990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_binop_any_nequal,
991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_binop_bit_and,
992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_binop_bit_xor,
993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_binop_bit_or,
994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_unop_bit_not,
995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_binop_logic_and,
996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_binop_logic_xor,
997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_binop_logic_or,
998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_unop_logic_not,
999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Note: The following block of expression types actually convert
1001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * to multiple IR instructions.
1002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_binop_mul,     /* ast_mul_assign */
1004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_binop_div,     /* ast_div_assign */
1005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_binop_mod,     /* ast_mod_assign */
1006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_binop_add,     /* ast_add_assign */
1007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_binop_sub,     /* ast_sub_assign */
1008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_binop_lshift,  /* ast_ls_assign */
1009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_binop_rshift,  /* ast_rs_assign */
1010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_binop_bit_and, /* ast_and_assign */
1011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_binop_bit_xor, /* ast_xor_assign */
1012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_binop_bit_or,  /* ast_or_assign */
1013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      -1,               /* ast_conditional doesn't convert to ir_expression. */
1015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_binop_add,     /* ast_pre_inc. */
1016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_binop_sub,     /* ast_pre_dec. */
1017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_binop_add,     /* ast_post_inc. */
1018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_binop_sub,     /* ast_post_dec. */
1019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      -1,               /* ast_field_selection doesn't conv to ir_expression. */
1020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      -1,               /* ast_array_index doesn't convert to ir_expression. */
1021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      -1,               /* ast_function_call doesn't conv to ir_expression. */
1022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      -1,               /* ast_identifier doesn't convert to ir_expression. */
1023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      -1,               /* ast_int_constant doesn't convert to ir_expression. */
1024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      -1,               /* ast_uint_constant doesn't conv to ir_expression. */
1025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      -1,               /* ast_float_constant doesn't conv to ir_expression. */
1026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      -1,               /* ast_bool_constant doesn't conv to ir_expression. */
1027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      -1,               /* ast_sequence doesn't convert to ir_expression. */
1028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   };
1029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_rvalue *result = NULL;
1030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_rvalue *op[3];
1031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct glsl_type *type; /* a temporary variable for switch cases */
1032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   bool error_emitted = false;
1033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   YYLTYPE loc;
1034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   loc = this->get_location();
1036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (this->oper) {
1038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_assign: {
1039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      op[0] = this->subexpressions[0]->hir(instructions, state);
1040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      op[1] = this->subexpressions[1]->hir(instructions, state);
1041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result = do_assignment(instructions, state,
1043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     this->subexpressions[0]->non_lvalue_description,
1044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     op[0], op[1], false,
1045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     this->subexpressions[0]->get_location());
1046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      error_emitted = result->type->is_error();
1047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_plus:
1051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      op[0] = this->subexpressions[0]->hir(instructions, state);
1052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      type = unary_arithmetic_result_type(op[0]->type, state, & loc);
1054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      error_emitted = type->is_error();
1056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result = op[0];
1058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_neg:
1061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      op[0] = this->subexpressions[0]->hir(instructions, state);
1062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      type = unary_arithmetic_result_type(op[0]->type, state, & loc);
1064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      error_emitted = type->is_error();
1066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result = new(ctx) ir_expression(operations[this->oper], type,
1068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				      op[0], NULL);
1069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_add:
1072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_sub:
1073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_mul:
1074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_div:
1075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      op[0] = this->subexpressions[0]->hir(instructions, state);
1076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      op[1] = this->subexpressions[1]->hir(instructions, state);
1077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      type = arithmetic_result_type(op[0], op[1],
1079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				    (this->oper == ast_mul),
1080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				    state, & loc);
1081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      error_emitted = type->is_error();
1082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result = new(ctx) ir_expression(operations[this->oper], type,
1084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				      op[0], op[1]);
1085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_mod:
1088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      op[0] = this->subexpressions[0]->hir(instructions, state);
1089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      op[1] = this->subexpressions[1]->hir(instructions, state);
1090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      type = modulus_result_type(op[0]->type, op[1]->type, state, & loc);
1092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(operations[this->oper] == ir_binop_mod);
1094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result = new(ctx) ir_expression(operations[this->oper], type,
1096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				      op[0], op[1]);
1097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      error_emitted = type->is_error();
1098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_lshift:
1101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_rshift:
1102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       if (state->language_version < 130) {
1103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          _mesa_glsl_error(&loc, state, "operator %s requires GLSL 1.30",
1104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              operator_string(this->oper));
1105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          error_emitted = true;
1106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       }
1107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       op[0] = this->subexpressions[0]->hir(instructions, state);
1109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       op[1] = this->subexpressions[1]->hir(instructions, state);
1110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       type = shift_result_type(op[0]->type, op[1]->type, this->oper, state,
1111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                &loc);
1112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       result = new(ctx) ir_expression(operations[this->oper], type,
1113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       op[0], op[1]);
1114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       error_emitted = op[0]->type->is_error() || op[1]->type->is_error();
1115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       break;
1116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_less:
1118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_greater:
1119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_lequal:
1120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_gequal:
1121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      op[0] = this->subexpressions[0]->hir(instructions, state);
1122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      op[1] = this->subexpressions[1]->hir(instructions, state);
1123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      type = relational_result_type(op[0], op[1], state, & loc);
1125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* The relational operators must either generate an error or result
1127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * in a scalar boolean.  See page 57 of the GLSL 1.50 spec.
1128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(type->is_error()
1130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     || ((type->base_type == GLSL_TYPE_BOOL)
1131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 && type->is_scalar()));
1132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result = new(ctx) ir_expression(operations[this->oper], type,
1134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				      op[0], op[1]);
1135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      error_emitted = type->is_error();
1136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_nequal:
1139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_equal:
1140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      op[0] = this->subexpressions[0]->hir(instructions, state);
1141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      op[1] = this->subexpressions[1]->hir(instructions, state);
1142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* From page 58 (page 64 of the PDF) of the GLSL 1.50 spec:
1144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
1145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *    "The equality operators equal (==), and not equal (!=)
1146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *    operate on all types. They result in a scalar Boolean. If
1147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *    the operand types do not match, then there must be a
1148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *    conversion from Section 4.1.10 "Implicit Conversions"
1149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *    applied to one operand that can make them match, in which
1150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *    case this conversion is done."
1151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if ((!apply_implicit_conversion(op[0]->type, op[1], state)
1153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   && !apply_implicit_conversion(op[1]->type, op[0], state))
1154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  || (op[0]->type != op[1]->type)) {
1155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 _mesa_glsl_error(& loc, state, "operands of `%s' must have the same "
1156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  "type", (this->oper == ast_equal) ? "==" : "!=");
1157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 error_emitted = true;
1158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else if ((state->language_version <= 110)
1159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 && (op[0]->type->is_array() || op[1]->type->is_array())) {
1160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 _mesa_glsl_error(& loc, state, "array comparisons forbidden in "
1161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  "GLSL 1.10");
1162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 error_emitted = true;
1163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (error_emitted) {
1166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 result = new(ctx) ir_constant(false);
1167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
1168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 result = do_comparison(ctx, operations[this->oper], op[0], op[1]);
1169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 assert(result->type == glsl_type::bool_type);
1170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_bit_and:
1174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_bit_xor:
1175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_bit_or:
1176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      op[0] = this->subexpressions[0]->hir(instructions, state);
1177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      op[1] = this->subexpressions[1]->hir(instructions, state);
1178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      type = bit_logic_result_type(op[0]->type, op[1]->type, this->oper,
1179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   state, &loc);
1180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result = new(ctx) ir_expression(operations[this->oper], type,
1181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				      op[0], op[1]);
1182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      error_emitted = op[0]->type->is_error() || op[1]->type->is_error();
1183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_bit_not:
1186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      op[0] = this->subexpressions[0]->hir(instructions, state);
1187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (state->language_version < 130) {
1189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 _mesa_glsl_error(&loc, state, "bit-wise operations require GLSL 1.30");
1190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 error_emitted = true;
1191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!op[0]->type->is_integer()) {
1194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 _mesa_glsl_error(&loc, state, "operand of `~' must be an integer");
1195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 error_emitted = true;
1196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      type = error_emitted ? glsl_type::error_type : op[0]->type;
1199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result = new(ctx) ir_expression(ir_unop_bit_not, type, op[0], NULL);
1200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_logic_and: {
1203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      exec_list rhs_instructions;
1204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      op[0] = get_scalar_boolean_operand(instructions, state, this, 0,
1205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					 "LHS", &error_emitted);
1206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      op[1] = get_scalar_boolean_operand(&rhs_instructions, state, this, 1,
1207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					 "RHS", &error_emitted);
1208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (rhs_instructions.is_empty()) {
1210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 result = new(ctx) ir_expression(ir_binop_logic_and, op[0], op[1]);
1211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 type = result->type;
1212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
1213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ir_variable *const tmp = new(ctx) ir_variable(glsl_type::bool_type,
1214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						       "and_tmp",
1215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						       ir_var_temporary);
1216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 instructions->push_tail(tmp);
1217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ir_if *const stmt = new(ctx) ir_if(op[0]);
1219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 instructions->push_tail(stmt);
1220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 stmt->then_instructions.append_list(&rhs_instructions);
1222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ir_dereference *const then_deref = new(ctx) ir_dereference_variable(tmp);
1223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ir_assignment *const then_assign =
1224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    new(ctx) ir_assignment(then_deref, op[1]);
1225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 stmt->then_instructions.push_tail(then_assign);
1226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ir_dereference *const else_deref = new(ctx) ir_dereference_variable(tmp);
1228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ir_assignment *const else_assign =
1229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    new(ctx) ir_assignment(else_deref, new(ctx) ir_constant(false));
1230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 stmt->else_instructions.push_tail(else_assign);
1231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 result = new(ctx) ir_dereference_variable(tmp);
1233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 type = tmp->type;
1234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_logic_or: {
1239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      exec_list rhs_instructions;
1240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      op[0] = get_scalar_boolean_operand(instructions, state, this, 0,
1241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					 "LHS", &error_emitted);
1242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      op[1] = get_scalar_boolean_operand(&rhs_instructions, state, this, 1,
1243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					 "RHS", &error_emitted);
1244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (rhs_instructions.is_empty()) {
1246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 result = new(ctx) ir_expression(ir_binop_logic_or, op[0], op[1]);
1247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 type = result->type;
1248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
1249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ir_variable *const tmp = new(ctx) ir_variable(glsl_type::bool_type,
1250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						       "or_tmp",
1251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						       ir_var_temporary);
1252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 instructions->push_tail(tmp);
1253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ir_if *const stmt = new(ctx) ir_if(op[0]);
1255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 instructions->push_tail(stmt);
1256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ir_dereference *const then_deref = new(ctx) ir_dereference_variable(tmp);
1258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ir_assignment *const then_assign =
1259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    new(ctx) ir_assignment(then_deref, new(ctx) ir_constant(true));
1260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 stmt->then_instructions.push_tail(then_assign);
1261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 stmt->else_instructions.append_list(&rhs_instructions);
1263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ir_dereference *const else_deref = new(ctx) ir_dereference_variable(tmp);
1264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ir_assignment *const else_assign =
1265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    new(ctx) ir_assignment(else_deref, op[1]);
1266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 stmt->else_instructions.push_tail(else_assign);
1267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 result = new(ctx) ir_dereference_variable(tmp);
1269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 type = tmp->type;
1270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_logic_xor:
1275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* From page 33 (page 39 of the PDF) of the GLSL 1.10 spec:
1276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
1277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *    "The logical binary operators and (&&), or ( | | ), and
1278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *     exclusive or (^^). They operate only on two Boolean
1279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *     expressions and result in a Boolean expression."
1280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      op[0] = get_scalar_boolean_operand(instructions, state, this, 0, "LHS",
1282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					 &error_emitted);
1283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      op[1] = get_scalar_boolean_operand(instructions, state, this, 1, "RHS",
1284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					 &error_emitted);
1285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result = new(ctx) ir_expression(operations[this->oper], glsl_type::bool_type,
1287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				      op[0], op[1]);
1288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_logic_not:
1291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      op[0] = get_scalar_boolean_operand(instructions, state, this, 0,
1292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					 "operand", &error_emitted);
1293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result = new(ctx) ir_expression(operations[this->oper], glsl_type::bool_type,
1295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				      op[0], NULL);
1296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_mul_assign:
1299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_div_assign:
1300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_add_assign:
1301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_sub_assign: {
1302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      op[0] = this->subexpressions[0]->hir(instructions, state);
1303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      op[1] = this->subexpressions[1]->hir(instructions, state);
1304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      type = arithmetic_result_type(op[0], op[1],
1306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				    (this->oper == ast_mul_assign),
1307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				    state, & loc);
1308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_rvalue *temp_rhs = new(ctx) ir_expression(operations[this->oper], type,
1310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						   op[0], op[1]);
1311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result = do_assignment(instructions, state,
1313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     this->subexpressions[0]->non_lvalue_description,
1314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     op[0]->clone(ctx, NULL), temp_rhs, false,
1315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     this->subexpressions[0]->get_location());
1316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      error_emitted = (op[0]->type->is_error());
1317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* GLSL 1.10 does not allow array assignment.  However, we don't have to
1319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * explicitly test for this because none of the binary expression
1320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * operators allow array operands either.
1321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_mod_assign: {
1327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      op[0] = this->subexpressions[0]->hir(instructions, state);
1328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      op[1] = this->subexpressions[1]->hir(instructions, state);
1329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      type = modulus_result_type(op[0]->type, op[1]->type, state, & loc);
1331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(operations[this->oper] == ir_binop_mod);
1333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_rvalue *temp_rhs;
1335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      temp_rhs = new(ctx) ir_expression(operations[this->oper], type,
1336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					op[0], op[1]);
1337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result = do_assignment(instructions, state,
1339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     this->subexpressions[0]->non_lvalue_description,
1340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     op[0]->clone(ctx, NULL), temp_rhs, false,
1341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     this->subexpressions[0]->get_location());
1342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      error_emitted = type->is_error();
1343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_ls_assign:
1347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_rs_assign: {
1348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      op[0] = this->subexpressions[0]->hir(instructions, state);
1349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      op[1] = this->subexpressions[1]->hir(instructions, state);
1350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      type = shift_result_type(op[0]->type, op[1]->type, this->oper, state,
1351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               &loc);
1352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_rvalue *temp_rhs = new(ctx) ir_expression(operations[this->oper],
1353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                   type, op[0], op[1]);
1354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result = do_assignment(instructions, state,
1355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     this->subexpressions[0]->non_lvalue_description,
1356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     op[0]->clone(ctx, NULL), temp_rhs, false,
1357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             this->subexpressions[0]->get_location());
1358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      error_emitted = op[0]->type->is_error() || op[1]->type->is_error();
1359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_and_assign:
1363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_xor_assign:
1364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_or_assign: {
1365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      op[0] = this->subexpressions[0]->hir(instructions, state);
1366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      op[1] = this->subexpressions[1]->hir(instructions, state);
1367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      type = bit_logic_result_type(op[0]->type, op[1]->type, this->oper,
1368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   state, &loc);
1369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_rvalue *temp_rhs = new(ctx) ir_expression(operations[this->oper],
1370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                   type, op[0], op[1]);
1371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result = do_assignment(instructions, state,
1372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     this->subexpressions[0]->non_lvalue_description,
1373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     op[0]->clone(ctx, NULL), temp_rhs, false,
1374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             this->subexpressions[0]->get_location());
1375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      error_emitted = op[0]->type->is_error() || op[1]->type->is_error();
1376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_conditional: {
1380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* From page 59 (page 65 of the PDF) of the GLSL 1.50 spec:
1381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
1382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *    "The ternary selection operator (?:). It operates on three
1383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *    expressions (exp1 ? exp2 : exp3). This operator evaluates the
1384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *    first expression, which must result in a scalar Boolean."
1385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      op[0] = get_scalar_boolean_operand(instructions, state, this, 0,
1387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					 "condition", &error_emitted);
1388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* The :? operator is implemented by generating an anonymous temporary
1390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * followed by an if-statement.  The last instruction in each branch of
1391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * the if-statement assigns a value to the anonymous temporary.  This
1392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * temporary is the r-value of the expression.
1393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      exec_list then_instructions;
1395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      exec_list else_instructions;
1396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      op[1] = this->subexpressions[1]->hir(&then_instructions, state);
1398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      op[2] = this->subexpressions[2]->hir(&else_instructions, state);
1399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* From page 59 (page 65 of the PDF) of the GLSL 1.50 spec:
1401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
1402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *     "The second and third expressions can be any type, as
1403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *     long their types match, or there is a conversion in
1404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *     Section 4.1.10 "Implicit Conversions" that can be applied
1405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *     to one of the expressions to make their types match. This
1406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *     resulting matching type is the type of the entire
1407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *     expression."
1408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if ((!apply_implicit_conversion(op[1]->type, op[2], state)
1410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   && !apply_implicit_conversion(op[2]->type, op[1], state))
1411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  || (op[1]->type != op[2]->type)) {
1412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 YYLTYPE loc = this->subexpressions[1]->get_location();
1413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 _mesa_glsl_error(& loc, state, "Second and third operands of ?: "
1415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  "operator must have matching types.");
1416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 error_emitted = true;
1417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 type = glsl_type::error_type;
1418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
1419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 type = op[1]->type;
1420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* From page 33 (page 39 of the PDF) of the GLSL 1.10 spec:
1423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
1424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *    "The second and third expressions must be the same type, but can
1425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *    be of any type other than an array."
1426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if ((state->language_version <= 110) && type->is_array()) {
1428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 _mesa_glsl_error(& loc, state, "Second and third operands of ?: "
1429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  "operator must not be arrays.");
1430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 error_emitted = true;
1431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_constant *cond_val = op[0]->constant_expression_value();
1434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_constant *then_val = op[1]->constant_expression_value();
1435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_constant *else_val = op[2]->constant_expression_value();
1436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (then_instructions.is_empty()
1438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  && else_instructions.is_empty()
1439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  && (cond_val != NULL) && (then_val != NULL) && (else_val != NULL)) {
1440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 result = (cond_val->value.b[0]) ? then_val : else_val;
1441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
1442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ir_variable *const tmp =
1443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    new(ctx) ir_variable(type, "conditional_tmp", ir_var_temporary);
1444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 instructions->push_tail(tmp);
1445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ir_if *const stmt = new(ctx) ir_if(op[0]);
1447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 instructions->push_tail(stmt);
1448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 then_instructions.move_nodes_to(& stmt->then_instructions);
1450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ir_dereference *const then_deref =
1451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    new(ctx) ir_dereference_variable(tmp);
1452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ir_assignment *const then_assign =
1453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    new(ctx) ir_assignment(then_deref, op[1]);
1454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 stmt->then_instructions.push_tail(then_assign);
1455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 else_instructions.move_nodes_to(& stmt->else_instructions);
1457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ir_dereference *const else_deref =
1458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    new(ctx) ir_dereference_variable(tmp);
1459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ir_assignment *const else_assign =
1460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    new(ctx) ir_assignment(else_deref, op[2]);
1461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 stmt->else_instructions.push_tail(else_assign);
1462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 result = new(ctx) ir_dereference_variable(tmp);
1464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_pre_inc:
1469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_pre_dec: {
1470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->non_lvalue_description = (this->oper == ast_pre_inc)
1471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ? "pre-increment operation" : "pre-decrement operation";
1472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      op[0] = this->subexpressions[0]->hir(instructions, state);
1474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      op[1] = constant_one_for_inc_dec(ctx, op[0]->type);
1475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      type = arithmetic_result_type(op[0], op[1], false, state, & loc);
1477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_rvalue *temp_rhs;
1479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      temp_rhs = new(ctx) ir_expression(operations[this->oper], type,
1480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					op[0], op[1]);
1481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result = do_assignment(instructions, state,
1483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     this->subexpressions[0]->non_lvalue_description,
1484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     op[0]->clone(ctx, NULL), temp_rhs, false,
1485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     this->subexpressions[0]->get_location());
1486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      error_emitted = op[0]->type->is_error();
1487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_post_inc:
1491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_post_dec: {
1492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->non_lvalue_description = (this->oper == ast_post_inc)
1493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ? "post-increment operation" : "post-decrement operation";
1494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      op[0] = this->subexpressions[0]->hir(instructions, state);
1495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      op[1] = constant_one_for_inc_dec(ctx, op[0]->type);
1496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      error_emitted = op[0]->type->is_error() || op[1]->type->is_error();
1498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      type = arithmetic_result_type(op[0], op[1], false, state, & loc);
1500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_rvalue *temp_rhs;
1502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      temp_rhs = new(ctx) ir_expression(operations[this->oper], type,
1503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					op[0], op[1]);
1504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Get a temporary of a copy of the lvalue before it's modified.
1506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * This may get thrown away later.
1507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result = get_lvalue_copy(instructions, op[0]->clone(ctx, NULL));
1509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      (void)do_assignment(instructions, state,
1511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  this->subexpressions[0]->non_lvalue_description,
1512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  op[0]->clone(ctx, NULL), temp_rhs, false,
1513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  this->subexpressions[0]->get_location());
1514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      error_emitted = op[0]->type->is_error();
1516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_field_selection:
1520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result = _mesa_ast_field_selection_to_hir(this, instructions, state);
1521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_array_index: {
1524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      YYLTYPE index_loc = subexpressions[1]->get_location();
1525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      op[0] = subexpressions[0]->hir(instructions, state);
1527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      op[1] = subexpressions[1]->hir(instructions, state);
1528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      error_emitted = op[0]->type->is_error() || op[1]->type->is_error();
1530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_rvalue *const array = op[0];
1532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result = new(ctx) ir_dereference_array(op[0], op[1]);
1534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Do not use op[0] after this point.  Use array.
1536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      op[0] = NULL;
1538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (error_emitted)
1541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!array->type->is_array()
1544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  && !array->type->is_matrix()
1545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  && !array->type->is_vector()) {
1546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 _mesa_glsl_error(& index_loc, state,
1547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  "cannot dereference non-array / non-matrix / "
1548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  "non-vector");
1549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 error_emitted = true;
1550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!op[1]->type->is_integer()) {
1553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 _mesa_glsl_error(& index_loc, state,
1554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  "array index must be integer type");
1555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 error_emitted = true;
1556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else if (!op[1]->type->is_scalar()) {
1557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 _mesa_glsl_error(& index_loc, state,
1558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  "array index must be scalar");
1559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 error_emitted = true;
1560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* If the array index is a constant expression and the array has a
1563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * declared size, ensure that the access is in-bounds.  If the array
1564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * index is not a constant expression, ensure that the array has a
1565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * declared size.
1566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_constant *const const_index = op[1]->constant_expression_value();
1568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (const_index != NULL) {
1569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 const int idx = const_index->value.i[0];
1570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 const char *type_name;
1571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 unsigned bound = 0;
1572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (array->type->is_matrix()) {
1574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    type_name = "matrix";
1575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 } else if (array->type->is_vector()) {
1576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    type_name = "vector";
1577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 } else {
1578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    type_name = "array";
1579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
1580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* From page 24 (page 30 of the PDF) of the GLSL 1.50 spec:
1582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  *
1583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  *    "It is illegal to declare an array with a size, and then
1584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  *    later (in the same shader) index the same array with an
1585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  *    integral constant expression greater than or equal to the
1586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  *    declared size. It is also illegal to index an array with a
1587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  *    negative constant expression."
1588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  */
1589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (array->type->is_matrix()) {
1590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    if (array->type->row_type()->vector_elements <= idx) {
1591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       bound = array->type->row_type()->vector_elements;
1592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    }
1593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 } else if (array->type->is_vector()) {
1594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    if (array->type->vector_elements <= idx) {
1595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       bound = array->type->vector_elements;
1596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    }
1597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 } else {
1598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    if ((array->type->array_size() > 0)
1599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		&& (array->type->array_size() <= idx)) {
1600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       bound = array->type->array_size();
1601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    }
1602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
1603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (bound > 0) {
1605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    _mesa_glsl_error(& loc, state, "%s index must be < %u",
1606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     type_name, bound);
1607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    error_emitted = true;
1608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 } else if (idx < 0) {
1609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    _mesa_glsl_error(& loc, state, "%s index must be >= 0",
1610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     type_name);
1611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    error_emitted = true;
1612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
1613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (array->type->is_array()) {
1615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    /* If the array is a variable dereference, it dereferences the
1616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     * whole array, by definition.  Use this to get the variable.
1617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     *
1618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     * FINISHME: Should some methods for getting / setting / testing
1619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     * FINISHME: array access limits be added to ir_dereference?
1620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     */
1621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    ir_variable *const v = array->whole_variable_referenced();
1622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    if ((v != NULL) && (unsigned(idx) > v->max_array_access)) {
1623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       v->max_array_access = idx;
1624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               /* Check whether this access will, as a side effect, implicitly
1626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                * cause the size of a built-in array to be too large.
1627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                */
1628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               if (check_builtin_array_max_size(v->name, idx+1, loc, state))
1629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  error_emitted = true;
1630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
1632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else if (array->type->array_size() == 0) {
1633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 _mesa_glsl_error(&loc, state, "unsized array index must be constant");
1634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
1635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (array->type->is_array()) {
1636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    /* whole_variable_referenced can return NULL if the array is a
1637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     * member of a structure.  In this case it is safe to not update
1638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     * the max_array_access field because it is never used for fields
1639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     * of structures.
1640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     */
1641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    ir_variable *v = array->whole_variable_referenced();
1642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    if (v != NULL)
1643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       v->max_array_access = array->type->array_size() - 1;
1644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
1645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* From page 23 (29 of the PDF) of the GLSL 1.30 spec:
1648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
1649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *    "Samplers aggregated into arrays within a shader (using square
1650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *    brackets [ ]) can only be indexed with integral constant
1651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *    expressions [...]."
1652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
1653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * This restriction was added in GLSL 1.30.  Shaders using earlier version
1654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * of the language should not be rejected by the compiler front-end for
1655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * using this construct.  This allows useful things such as using a loop
1656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * counter as the index to an array of samplers.  If the loop in unrolled,
1657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * the code should compile correctly.  Instead, emit a warning.
1658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (array->type->is_array() &&
1660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          array->type->element_type()->is_sampler() &&
1661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          const_index == NULL) {
1662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (state->language_version == 100) {
1664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    _mesa_glsl_warning(&loc, state,
1665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			       "sampler arrays indexed with non-constant "
1666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			       "expressions is optional in GLSL ES 1.00");
1667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 } else if (state->language_version < 130) {
1668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    _mesa_glsl_warning(&loc, state,
1669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			       "sampler arrays indexed with non-constant "
1670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			       "expressions is forbidden in GLSL 1.30 and "
1671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			       "later");
1672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 } else {
1673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    _mesa_glsl_error(&loc, state,
1674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     "sampler arrays indexed with non-constant "
1675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     "expressions is forbidden in GLSL 1.30 and "
1676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     "later");
1677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    error_emitted = true;
1678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
1679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (error_emitted)
1682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 result->type = glsl_type::error_type;
1683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_function_call:
1688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Should *NEVER* get here.  ast_function_call should always be handled
1689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * by ast_function_expression::hir.
1690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(0);
1692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_identifier: {
1695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* ast_identifier can appear several places in a full abstract syntax
1696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * tree.  This particular use must be at location specified in the grammar
1697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * as 'variable_identifier'.
1698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_variable *var =
1700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 state->symbols->get_variable(this->primary_expression.identifier);
1701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (var != NULL) {
1703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 var->used = true;
1704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 result = new(ctx) ir_dereference_variable(var);
1705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
1706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 _mesa_glsl_error(& loc, state, "`%s' undeclared",
1707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  this->primary_expression.identifier);
1708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 result = ir_rvalue::error_value(ctx);
1710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 error_emitted = true;
1711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_int_constant:
1716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result = new(ctx) ir_constant(this->primary_expression.int_constant);
1717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_uint_constant:
1720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result = new(ctx) ir_constant(this->primary_expression.uint_constant);
1721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_float_constant:
1724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result = new(ctx) ir_constant(this->primary_expression.float_constant);
1725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_bool_constant:
1728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result = new(ctx) ir_constant(bool(this->primary_expression.bool_constant));
1729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_sequence: {
1732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* It should not be possible to generate a sequence in the AST without
1733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * any expressions in it.
1734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(!this->expressions.is_empty());
1736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* The r-value of a sequence is the last expression in the sequence.  If
1738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * the other expressions in the sequence do not have side-effects (and
1739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * therefore add instructions to the instruction list), they get dropped
1740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * on the floor.
1741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      exec_node *previous_tail_pred = NULL;
1743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      YYLTYPE previous_operand_loc = loc;
1744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      foreach_list_typed (ast_node, ast, link, &this->expressions) {
1746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* If one of the operands of comma operator does not generate any
1747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * code, we want to emit a warning.  At each pass through the loop
1748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * previous_tail_pred will point to the last instruction in the
1749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * stream *before* processing the previous operand.  Naturally,
1750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * instructions->tail_pred will point to the last instruction in the
1751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * stream *after* processing the previous operand.  If the two
1752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * pointers match, then the previous operand had no effect.
1753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  *
1754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * The warning behavior here differs slightly from GCC.  GCC will
1755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * only emit a warning if none of the left-hand operands have an
1756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * effect.  However, it will emit a warning for each.  I believe that
1757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * there are some cases in C (especially with GCC extensions) where
1758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * it is useful to have an intermediate step in a sequence have no
1759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * effect, but I don't think these cases exist in GLSL.  Either way,
1760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * it would be a giant hassle to replicate that behavior.
1761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  */
1762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (previous_tail_pred == instructions->tail_pred) {
1763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    _mesa_glsl_warning(&previous_operand_loc, state,
1764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			       "left-hand operand of comma expression has "
1765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			       "no effect");
1766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
1767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* tail_pred is directly accessed instead of using the get_tail()
1769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * method for performance reasons.  get_tail() has extra code to
1770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * return NULL when the list is empty.  We don't care about that
1771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * here, so using tail_pred directly is fine.
1772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  */
1773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 previous_tail_pred = instructions->tail_pred;
1774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 previous_operand_loc = ast->get_location();
1775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 result = ast->hir(instructions, state);
1777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Any errors should have already been emitted in the loop above.
1780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      error_emitted = true;
1782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   type = NULL; /* use result->type, not type. */
1786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(result != NULL);
1787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (result->type->is_error() && !error_emitted)
1789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(& loc, state, "type mismatch");
1790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return result;
1792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue *
1796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgast_expression_statement::hir(exec_list *instructions,
1797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			      struct _mesa_glsl_parse_state *state)
1798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* It is possible to have expression statements that don't have an
1800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * expression.  This is the solitary semicolon:
1801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
1802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * for (i = 0; i < 5; i++)
1803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *     ;
1804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
1805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * In this case the expression will be NULL.  Test for NULL and don't do
1806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * anything in that case.
1807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (expression != NULL)
1809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      expression->hir(instructions, state);
1810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Statements do not have r-values.
1812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return NULL;
1814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue *
1818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgast_compound_statement::hir(exec_list *instructions,
1819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			    struct _mesa_glsl_parse_state *state)
1820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (new_scope)
1822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      state->symbols->push_scope();
1823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   foreach_list_typed (ast_node, ast, link, &this->statements)
1825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ast->hir(instructions, state);
1826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (new_scope)
1828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      state->symbols->pop_scope();
1829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Compound statements do not have r-values.
1831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return NULL;
1833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const glsl_type *
1837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgprocess_array_type(YYLTYPE *loc, const glsl_type *base, ast_node *array_size,
1838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		   struct _mesa_glsl_parse_state *state)
1839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned length = 0;
1841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* From page 19 (page 25) of the GLSL 1.20 spec:
1843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
1844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *     "Only one-dimensional arrays may be declared."
1845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (base->is_array()) {
1847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(loc, state,
1848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       "invalid array of `%s' (only one-dimensional arrays "
1849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       "may be declared)",
1850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       base->name);
1851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return glsl_type::error_type;
1852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (array_size != NULL) {
1855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      exec_list dummy_instructions;
1856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_rvalue *const ir = array_size->hir(& dummy_instructions, state);
1857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      YYLTYPE loc = array_size->get_location();
1858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (ir != NULL) {
1860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (!ir->type->is_integer()) {
1861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    _mesa_glsl_error(& loc, state, "array size must be integer type");
1862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 } else if (!ir->type->is_scalar()) {
1863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    _mesa_glsl_error(& loc, state, "array size must be scalar type");
1864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 } else {
1865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    ir_constant *const size = ir->constant_expression_value();
1866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    if (size == NULL) {
1868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       _mesa_glsl_error(& loc, state, "array size must be a "
1869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				"constant valued expression");
1870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    } else if (size->value.i[0] <= 0) {
1871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       _mesa_glsl_error(& loc, state, "array size must be > 0");
1872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    } else {
1873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       assert(size->type == ir->type);
1874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       length = size->value.u[0];
1875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               /* If the array size is const (and we've verified that
1877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                * it is) then no instructions should have been emitted
1878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                * when we converted it to HIR.  If they were emitted,
1879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                * then either the array size isn't const after all, or
1880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                * we are emitting unnecessary instructions.
1881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                */
1882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               assert(dummy_instructions.is_empty());
1883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    }
1884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
1885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else if (state->es_shader) {
1887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Section 10.17 of the GLSL ES 1.00 specification states that unsized
1888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * array declarations have been removed from the language.
1889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(loc, state, "unsized array declarations are not "
1891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       "allowed in GLSL ES 1.00.");
1892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return glsl_type::get_array_instance(base, length);
1895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgconst glsl_type *
1899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgast_type_specifier::glsl_type(const char **name,
1900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			      struct _mesa_glsl_parse_state *state) const
1901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct glsl_type *type;
1903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   type = state->symbols->get_type(this->type_name);
1905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   *name = this->type_name;
1906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (this->is_array) {
1908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      YYLTYPE loc = this->get_location();
1909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      type = process_array_type(&loc, type, this->array_size, state);
1910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return type;
1913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
1917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgapply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
1918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				 ir_variable *var,
1919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				 struct _mesa_glsl_parse_state *state,
1920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				 YYLTYPE *loc,
1921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				 bool ubo_qualifiers_valid)
1922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (qual->flags.q.invariant) {
1924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (var->used) {
1925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 _mesa_glsl_error(loc, state,
1926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  "variable `%s' may not be redeclared "
1927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  "`invariant' after being used",
1928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  var->name);
1929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
1930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 var->invariant = 1;
1931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (qual->flags.q.constant || qual->flags.q.attribute
1935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       || qual->flags.q.uniform
1936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       || (qual->flags.q.varying && (state->target == fragment_shader)))
1937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      var->read_only = 1;
1938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (qual->flags.q.centroid)
1940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      var->centroid = 1;
1941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (qual->flags.q.attribute && state->target != vertex_shader) {
1943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      var->type = glsl_type::error_type;
1944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(loc, state,
1945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       "`attribute' variables may not be declared in the "
1946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       "%s shader",
1947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       _mesa_glsl_shader_target_name(state->target));
1948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* From page 25 (page 31 of the PDF) of the GLSL 1.10 spec:
1951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
1952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *     "The varying qualifier can be used only with the data types
1953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *     float, vec2, vec3, vec4, mat2, mat3, and mat4, or arrays of
1954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *     these."
1955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (qual->flags.q.varying) {
1957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const glsl_type *non_array_type;
1958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (var->type && var->type->is_array())
1960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 non_array_type = var->type->fields.array;
1961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
1962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 non_array_type = var->type;
1963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (non_array_type && non_array_type->base_type != GLSL_TYPE_FLOAT) {
1965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 var->type = glsl_type::error_type;
1966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 _mesa_glsl_error(loc, state,
1967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  "varying variables must be of base type float");
1968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* If there is no qualifier that changes the mode of the variable, leave
1972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * the setting alone.
1973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (qual->flags.q.in && qual->flags.q.out)
1975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      var->mode = ir_var_inout;
1976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else if (qual->flags.q.attribute || qual->flags.q.in
1977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    || (qual->flags.q.varying && (state->target == fragment_shader)))
1978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      var->mode = ir_var_in;
1979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else if (qual->flags.q.out
1980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    || (qual->flags.q.varying && (state->target == vertex_shader)))
1981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      var->mode = ir_var_out;
1982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else if (qual->flags.q.uniform)
1983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      var->mode = ir_var_uniform;
1984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (state->all_invariant && (state->current_function == NULL)) {
1986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      switch (state->target) {
1987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case vertex_shader:
1988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (var->mode == ir_var_out)
1989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    var->invariant = true;
1990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case geometry_shader:
1992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if ((var->mode == ir_var_in) || (var->mode == ir_var_out))
1993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    var->invariant = true;
1994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case fragment_shader:
1996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (var->mode == ir_var_in)
1997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    var->invariant = true;
1998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (qual->flags.q.flat)
2003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      var->interpolation = INTERP_QUALIFIER_FLAT;
2004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else if (qual->flags.q.noperspective)
2005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      var->interpolation = INTERP_QUALIFIER_NOPERSPECTIVE;
2006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else if (qual->flags.q.smooth)
2007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      var->interpolation = INTERP_QUALIFIER_SMOOTH;
2008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else
2009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      var->interpolation = INTERP_QUALIFIER_NONE;
2010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (var->interpolation != INTERP_QUALIFIER_NONE &&
2012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       !(state->target == vertex_shader && var->mode == ir_var_out) &&
2013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       !(state->target == fragment_shader && var->mode == ir_var_in)) {
2014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(loc, state,
2015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       "interpolation qualifier `%s' can only be applied to "
2016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       "vertex shader outputs and fragment shader inputs.",
2017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       var->interpolation_string());
2018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   var->pixel_center_integer = qual->flags.q.pixel_center_integer;
2021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   var->origin_upper_left = qual->flags.q.origin_upper_left;
2022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if ((qual->flags.q.origin_upper_left || qual->flags.q.pixel_center_integer)
2023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       && (strcmp(var->name, "gl_FragCoord") != 0)) {
2024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const char *const qual_string = (qual->flags.q.origin_upper_left)
2025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ? "origin_upper_left" : "pixel_center_integer";
2026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(loc, state,
2028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       "layout qualifier `%s' can only be applied to "
2029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       "fragment shader input `gl_FragCoord'",
2030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       qual_string);
2031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (qual->flags.q.explicit_location) {
2034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const bool global_scope = (state->current_function == NULL);
2035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      bool fail = false;
2036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const char *string = "";
2037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* In the vertex shader only shader inputs can be given explicit
2039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * locations.
2040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
2041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * In the fragment shader only shader outputs can be given explicit
2042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * locations.
2043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      switch (state->target) {
2045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case vertex_shader:
2046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (!global_scope || (var->mode != ir_var_in)) {
2047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    fail = true;
2048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    string = "input";
2049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
2050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
2051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case geometry_shader:
2053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 _mesa_glsl_error(loc, state,
2054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  "geometry shader variables cannot be given "
2055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  "explicit locations\n");
2056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
2057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case fragment_shader:
2059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (!global_scope || (var->mode != ir_var_out)) {
2060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    fail = true;
2061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    string = "output";
2062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
2063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
2064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      };
2065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (fail) {
2067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 _mesa_glsl_error(loc, state,
2068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  "only %s shader %s variables can be given an "
2069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  "explicit location\n",
2070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  _mesa_glsl_shader_target_name(state->target),
2071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  string);
2072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
2073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 var->explicit_location = true;
2074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* This bit of silliness is needed because invalid explicit locations
2076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * are supposed to be flagged during linking.  Small negative values
2077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * biased by VERT_ATTRIB_GENERIC0 or FRAG_RESULT_DATA0 could alias
2078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * built-in values (e.g., -16+VERT_ATTRIB_GENERIC0 = VERT_ATTRIB_POS).
2079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * The linker needs to be able to differentiate these cases.  This
2080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * ensures that negative values stay negative.
2081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  */
2082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (qual->location >= 0) {
2083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    var->location = (state->target == vertex_shader)
2084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       ? (qual->location + VERT_ATTRIB_GENERIC0)
2085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       : (qual->location + FRAG_RESULT_DATA0);
2086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 } else {
2087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    var->location = qual->location;
2088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
2089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (qual->flags.q.explicit_index) {
2091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* From the GLSL 4.30 specification, section 4.4.2 (Output
2092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             * Layout Qualifiers):
2093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             *
2094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             * "It is also a compile-time error if a fragment shader
2095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             *  sets a layout index to less than 0 or greater than 1."
2096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             *
2097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             * Older specifications don't mandate a behavior; we take
2098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             * this as a clarification and always generate the error.
2099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             */
2100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (qual->index < 0 || qual->index > 1) {
2101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               _mesa_glsl_error(loc, state,
2102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                "explicit index may only be 0 or 1\n");
2103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            } else {
2104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               var->explicit_index = true;
2105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               var->index = qual->index;
2106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
2107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
2108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else if (qual->flags.q.explicit_index) {
2110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 _mesa_glsl_error(loc, state,
2111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  "explicit index requires explicit location\n");
2112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Does the declaration use the 'layout' keyword?
2115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
2116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const bool uses_layout = qual->flags.q.pixel_center_integer
2117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      || qual->flags.q.origin_upper_left
2118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      || qual->flags.q.explicit_location; /* no need for index since it relies on location */
2119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Does the declaration use the deprecated 'attribute' or 'varying'
2121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * keywords?
2122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
2123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const bool uses_deprecated_qualifier = qual->flags.q.attribute
2124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      || qual->flags.q.varying;
2125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Is the 'layout' keyword used with parameters that allow relaxed checking.
2127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * Many implementations of GL_ARB_fragment_coord_conventions_enable and some
2128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * implementations (only Mesa?) GL_ARB_explicit_attrib_location_enable
2129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * allowed the layout qualifier to be used with 'varying' and 'attribute'.
2130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * These extensions and all following extensions that add the 'layout'
2131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * keyword have been modified to require the use of 'in' or 'out'.
2132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
2133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * The following extension do not allow the deprecated keywords:
2134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
2135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    GL_AMD_conservative_depth
2136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    GL_ARB_conservative_depth
2137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    GL_ARB_gpu_shader5
2138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    GL_ARB_separate_shader_objects
2139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    GL_ARB_tesselation_shader
2140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    GL_ARB_transform_feedback3
2141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    GL_ARB_uniform_buffer_object
2142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
2143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * It is unknown whether GL_EXT_shader_image_load_store or GL_NV_gpu_shader5
2144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * allow layout with the deprecated keywords.
2145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
2146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const bool relaxed_layout_qualifier_checking =
2147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      state->ARB_fragment_coord_conventions_enable;
2148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (uses_layout && uses_deprecated_qualifier) {
2150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (relaxed_layout_qualifier_checking) {
2151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 _mesa_glsl_warning(loc, state,
2152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			    "`layout' qualifier may not be used with "
2153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			    "`attribute' or `varying'");
2154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
2155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 _mesa_glsl_error(loc, state,
2156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  "`layout' qualifier may not be used with "
2157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  "`attribute' or `varying'");
2158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Layout qualifiers for gl_FragDepth, which are enabled by extension
2162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * AMD_conservative_depth.
2163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
2164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int depth_layout_count = qual->flags.q.depth_any
2165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      + qual->flags.q.depth_greater
2166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      + qual->flags.q.depth_less
2167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      + qual->flags.q.depth_unchanged;
2168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (depth_layout_count > 0
2169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       && !state->AMD_conservative_depth_enable
2170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       && !state->ARB_conservative_depth_enable) {
2171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       _mesa_glsl_error(loc, state,
2172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        "extension GL_AMD_conservative_depth or "
2173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        "GL_ARB_conservative_depth must be enabled "
2174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			"to use depth layout qualifiers");
2175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else if (depth_layout_count > 0
2176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              && strcmp(var->name, "gl_FragDepth") != 0) {
2177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       _mesa_glsl_error(loc, state,
2178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        "depth layout qualifiers can be applied only to "
2179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        "gl_FragDepth");
2180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else if (depth_layout_count > 1
2181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              && strcmp(var->name, "gl_FragDepth") == 0) {
2182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(loc, state,
2183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       "at most one depth layout qualifier can be applied to "
2184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       "gl_FragDepth");
2185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (qual->flags.q.depth_any)
2187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      var->depth_layout = ir_depth_layout_any;
2188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else if (qual->flags.q.depth_greater)
2189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      var->depth_layout = ir_depth_layout_greater;
2190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else if (qual->flags.q.depth_less)
2191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      var->depth_layout = ir_depth_layout_less;
2192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else if (qual->flags.q.depth_unchanged)
2193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       var->depth_layout = ir_depth_layout_unchanged;
2194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else
2195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       var->depth_layout = ir_depth_layout_none;
2196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (qual->flags.q.std140 ||
2198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       qual->flags.q.packed ||
2199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       qual->flags.q.shared) {
2200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(loc, state,
2201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       "uniform block layout qualifiers std140, packed, and "
2202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       "shared can only be applied to uniform blocks, not "
2203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       "members");
2204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!ubo_qualifiers_valid &&
2207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       (qual->flags.q.row_major || qual->flags.q.column_major)) {
2208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(loc, state,
2209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       "uniform block layout qualifiers row_major and "
2210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       "column_major can only be applied to uniform block "
2211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       "members");
2212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
2216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Get the variable that is being redeclared by this declaration
2217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
2218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Semantic checks to verify the validity of the redeclaration are also
2219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * performed.  If semantic checks fail, compilation error will be emitted via
2220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \c _mesa_glsl_error, but a non-\c NULL pointer will still be returned.
2221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
2222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \returns
2223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * A pointer to an existing variable in the current scope if the declaration
2224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * is a redeclaration, \c NULL otherwise.
2225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
2226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_variable *
2227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgget_variable_being_redeclared(ir_variable *var, ast_declaration *decl,
2228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			      struct _mesa_glsl_parse_state *state)
2229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Check if this declaration is actually a re-declaration, either to
2231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * resize an array or add qualifiers to an existing variable.
2232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
2233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * This is allowed for variables in the current scope, or when at
2234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * global scope (for built-ins in the implicit outer scope).
2235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
2236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_variable *earlier = state->symbols->get_variable(decl->identifier);
2237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (earlier == NULL ||
2238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       (state->current_function != NULL &&
2239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	!state->symbols->name_declared_this_scope(decl->identifier))) {
2240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
2241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   YYLTYPE loc = decl->get_location();
2245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* From page 24 (page 30 of the PDF) of the GLSL 1.50 spec,
2247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
2248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * "It is legal to declare an array without a size and then
2249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *  later re-declare the same name as an array of the same
2250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *  type and specify a size."
2251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
2252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if ((earlier->type->array_size() == 0)
2253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       && var->type->is_array()
2254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       && (var->type->element_type() == earlier->type->element_type())) {
2255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* FINISHME: This doesn't match the qualifiers on the two
2256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * FINISHME: declarations.  It's not 100% clear whether this is
2257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * FINISHME: required or not.
2258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const unsigned size = unsigned(var->type->array_size());
2261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      check_builtin_array_max_size(var->name, size, loc, state);
2262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if ((size > 0) && (size <= earlier->max_array_access)) {
2263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 _mesa_glsl_error(& loc, state, "array size must be > %u due to "
2264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  "previous access",
2265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  earlier->max_array_access);
2266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      earlier->type = var->type;
2269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      delete var;
2270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      var = NULL;
2271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else if (state->ARB_fragment_coord_conventions_enable
2272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      && strcmp(var->name, "gl_FragCoord") == 0
2273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      && earlier->type == var->type
2274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      && earlier->mode == var->mode) {
2275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Allow redeclaration of gl_FragCoord for ARB_fcc layout
2276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * qualifiers.
2277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      earlier->origin_upper_left = var->origin_upper_left;
2279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      earlier->pixel_center_integer = var->pixel_center_integer;
2280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* According to section 4.3.7 of the GLSL 1.30 spec,
2282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * the following built-in varaibles can be redeclared with an
2283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * interpolation qualifier:
2284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *    * gl_FrontColor
2285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *    * gl_BackColor
2286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *    * gl_FrontSecondaryColor
2287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *    * gl_BackSecondaryColor
2288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *    * gl_Color
2289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *    * gl_SecondaryColor
2290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else if (state->language_version >= 130
2292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      && (strcmp(var->name, "gl_FrontColor") == 0
2293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  || strcmp(var->name, "gl_BackColor") == 0
2294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  || strcmp(var->name, "gl_FrontSecondaryColor") == 0
2295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  || strcmp(var->name, "gl_BackSecondaryColor") == 0
2296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  || strcmp(var->name, "gl_Color") == 0
2297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  || strcmp(var->name, "gl_SecondaryColor") == 0)
2298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      && earlier->type == var->type
2299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      && earlier->mode == var->mode) {
2300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      earlier->interpolation = var->interpolation;
2301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Layout qualifiers for gl_FragDepth. */
2303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else if ((state->AMD_conservative_depth_enable ||
2304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               state->ARB_conservative_depth_enable)
2305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      && strcmp(var->name, "gl_FragDepth") == 0
2306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      && earlier->type == var->type
2307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      && earlier->mode == var->mode) {
2308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /** From the AMD_conservative_depth spec:
2310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *     Within any shader, the first redeclarations of gl_FragDepth
2311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *     must appear before any use of gl_FragDepth.
2312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (earlier->used) {
2314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 _mesa_glsl_error(&loc, state,
2315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  "the first redeclaration of gl_FragDepth "
2316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  "must appear before any use of gl_FragDepth");
2317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Prevent inconsistent redeclaration of depth layout qualifier. */
2320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (earlier->depth_layout != ir_depth_layout_none
2321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  && earlier->depth_layout != var->depth_layout) {
2322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 _mesa_glsl_error(&loc, state,
2323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  "gl_FragDepth: depth layout is declared here "
2324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  "as '%s, but it was previously declared as "
2325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  "'%s'",
2326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  depth_layout_string(var->depth_layout),
2327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  depth_layout_string(earlier->depth_layout));
2328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      earlier->depth_layout = var->depth_layout;
2331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
2333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(&loc, state, "`%s' redeclared", decl->identifier);
2334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return earlier;
2337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
2340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Generate the IR for an initializer in a variable declaration
2341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
2342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue *
2343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgprocess_initializer(ir_variable *var, ast_declaration *decl,
2344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		    ast_fully_specified_type *type,
2345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		    exec_list *initializer_instructions,
2346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		    struct _mesa_glsl_parse_state *state)
2347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_rvalue *result = NULL;
2349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   YYLTYPE initializer_loc = decl->initializer->get_location();
2351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* From page 24 (page 30 of the PDF) of the GLSL 1.10 spec:
2353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
2354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    "All uniform variables are read-only and are initialized either
2355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    directly by an application via API commands, or indirectly by
2356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    OpenGL."
2357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
2358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if ((state->language_version <= 110)
2359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       && (var->mode == ir_var_uniform)) {
2360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(& initializer_loc, state,
2361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       "cannot initialize uniforms in GLSL 1.10");
2362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (var->type->is_sampler()) {
2365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(& initializer_loc, state,
2366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       "cannot initialize samplers");
2367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if ((var->mode == ir_var_in) && (state->current_function == NULL)) {
2370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(& initializer_loc, state,
2371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       "cannot initialize %s shader input / %s",
2372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       _mesa_glsl_shader_target_name(state->target),
2373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       (state->target == vertex_shader)
2374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       ? "attribute" : "varying");
2375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_dereference *const lhs = new(state) ir_dereference_variable(var);
2378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_rvalue *rhs = decl->initializer->hir(initializer_instructions,
2379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					   state);
2380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Calculate the constant value if this is a const or uniform
2382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * declaration.
2383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
2384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (type->qualifier.flags.q.constant
2385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       || type->qualifier.flags.q.uniform) {
2386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_rvalue *new_rhs = validate_assignment(state, var->type, rhs, true);
2387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (new_rhs != NULL) {
2388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 rhs = new_rhs;
2389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ir_constant *constant_value = rhs->constant_expression_value();
2391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (!constant_value) {
2392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    _mesa_glsl_error(& initializer_loc, state,
2393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     "initializer of %s variable `%s' must be a "
2394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     "constant expression",
2395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     (type->qualifier.flags.q.constant)
2396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     ? "const" : "uniform",
2397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     decl->identifier);
2398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    if (var->type->is_numeric()) {
2399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       /* Reduce cascading errors. */
2400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       var->constant_value = ir_constant::zero(state, var->type);
2401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    }
2402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 } else {
2403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    rhs = constant_value;
2404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    var->constant_value = constant_value;
2405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
2406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
2407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 _mesa_glsl_error(&initializer_loc, state,
2408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  "initializer of type %s cannot be assigned to "
2409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  "variable of type %s",
2410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  rhs->type->name, var->type->name);
2411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (var->type->is_numeric()) {
2412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    /* Reduce cascading errors. */
2413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    var->constant_value = ir_constant::zero(state, var->type);
2414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
2415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (rhs && !rhs->type->is_error()) {
2419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      bool temp = var->read_only;
2420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (type->qualifier.flags.q.constant)
2421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 var->read_only = false;
2422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Never emit code to initialize a uniform.
2424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const glsl_type *initializer_type;
2426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!type->qualifier.flags.q.uniform) {
2427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 result = do_assignment(initializer_instructions, state,
2428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				NULL,
2429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				lhs, rhs, true,
2430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				type->get_location());
2431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 initializer_type = result->type;
2432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else
2433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 initializer_type = rhs->type;
2434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      var->constant_initializer = rhs->constant_expression_value();
2436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      var->has_initializer = true;
2437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* If the declared variable is an unsized array, it must inherrit
2439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * its full type from the initializer.  A declaration such as
2440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
2441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *     uniform float a[] = float[](1.0, 2.0, 3.0, 3.0);
2442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
2443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * becomes
2444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
2445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *     uniform float a[4] = float[](1.0, 2.0, 3.0, 3.0);
2446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
2447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * The assignment generated in the if-statement (below) will also
2448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * automatically handle this case for non-uniforms.
2449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
2450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * If the declared variable is not an array, the types must
2451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * already match exactly.  As a result, the type assignment
2452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * here can be done unconditionally.  For non-uniforms the call
2453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * to do_assignment can change the type of the initializer (via
2454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * the implicit conversion rules).  For uniforms the initializer
2455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * must be a constant expression, and the type of that expression
2456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * was validated above.
2457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      var->type = initializer_type;
2459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      var->read_only = temp;
2461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return result;
2464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue *
2467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgast_declarator_list::hir(exec_list *instructions,
2468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			 struct _mesa_glsl_parse_state *state)
2469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void *ctx = state;
2471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct glsl_type *decl_type;
2472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const char *type_name = NULL;
2473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_rvalue *result = NULL;
2474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   YYLTYPE loc = this->get_location();
2475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* From page 46 (page 52 of the PDF) of the GLSL 1.50 spec:
2477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
2478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *     "To ensure that a particular output variable is invariant, it is
2479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *     necessary to use the invariant qualifier. It can either be used to
2480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *     qualify a previously declared variable as being invariant
2481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
2482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *         invariant gl_Position; // make existing gl_Position be invariant"
2483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
2484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * In these cases the parser will set the 'invariant' flag in the declarator
2485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * list, and the type will be NULL.
2486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
2487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (this->invariant) {
2488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(this->type == NULL);
2489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (state->current_function != NULL) {
2491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 _mesa_glsl_error(& loc, state,
2492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  "All uses of `invariant' keyword must be at global "
2493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  "scope\n");
2494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      foreach_list_typed (ast_declaration, decl, link, &this->declarations) {
2497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 assert(!decl->is_array);
2498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 assert(decl->array_size == NULL);
2499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 assert(decl->initializer == NULL);
2500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ir_variable *const earlier =
2502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    state->symbols->get_variable(decl->identifier);
2503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (earlier == NULL) {
2504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    _mesa_glsl_error(& loc, state,
2505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     "Undeclared variable `%s' cannot be marked "
2506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     "invariant\n", decl->identifier);
2507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 } else if ((state->target == vertex_shader)
2508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       && (earlier->mode != ir_var_out)) {
2509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    _mesa_glsl_error(& loc, state,
2510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     "`%s' cannot be marked invariant, vertex shader "
2511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     "outputs only\n", decl->identifier);
2512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 } else if ((state->target == fragment_shader)
2513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       && (earlier->mode != ir_var_in)) {
2514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    _mesa_glsl_error(& loc, state,
2515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     "`%s' cannot be marked invariant, fragment shader "
2516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     "inputs only\n", decl->identifier);
2517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 } else if (earlier->used) {
2518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    _mesa_glsl_error(& loc, state,
2519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     "variable `%s' may not be redeclared "
2520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     "`invariant' after being used",
2521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     earlier->name);
2522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 } else {
2523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    earlier->invariant = true;
2524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
2525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Invariant redeclarations do not have r-values.
2528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
2530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(this->type != NULL);
2533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(!this->invariant);
2534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* The type specifier may contain a structure definition.  Process that
2536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * before any of the variable declarations.
2537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
2538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) this->type->specifier->hir(instructions, state);
2539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   decl_type = this->type->specifier->glsl_type(& type_name, state);
2541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (this->declarations.is_empty()) {
2542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* If there is no structure involved in the program text, there are two
2543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * possible scenarios:
2544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
2545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * - The program text contained something like 'vec4;'.  This is an
2546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *   empty declaration.  It is valid but weird.  Emit a warning.
2547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
2548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * - The program text contained something like 'S;' and 'S' is not the
2549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *   name of a known structure type.  This is both invalid and weird.
2550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *   Emit an error.
2551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
2552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * Note that if decl_type is NULL and there is a structure involved,
2553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * there must have been some sort of error with the structure.  In this
2554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * case we assume that an error was already generated on this line of
2555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * code for the structure.  There is no need to generate an additional,
2556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * confusing error.
2557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(this->type->specifier->structure == NULL || decl_type != NULL
2559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     || state->error);
2560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (this->type->specifier->structure == NULL) {
2561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (decl_type != NULL) {
2562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    _mesa_glsl_warning(&loc, state, "empty declaration");
2563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 } else {
2564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    _mesa_glsl_error(&loc, state,
2565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     "invalid type `%s' in empty declaration",
2566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     type_name);
2567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
2568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   foreach_list_typed (ast_declaration, decl, link, &this->declarations) {
2572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const struct glsl_type *var_type;
2573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_variable *var;
2574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* FINISHME: Emit a warning if a variable declaration shadows a
2576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * FINISHME: declaration at a higher scope.
2577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if ((decl_type == NULL) || decl_type->is_void()) {
2580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (type_name != NULL) {
2581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    _mesa_glsl_error(& loc, state,
2582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     "invalid type `%s' in declaration of `%s'",
2583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     type_name, decl->identifier);
2584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 } else {
2585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    _mesa_glsl_error(& loc, state,
2586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     "invalid type in declaration of `%s'",
2587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     decl->identifier);
2588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
2589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 continue;
2590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (decl->is_array) {
2593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 var_type = process_array_type(&loc, decl_type, decl->array_size,
2594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       state);
2595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (var_type->is_error())
2596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    continue;
2597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
2598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 var_type = decl_type;
2599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      var = new(ctx) ir_variable(var_type, decl->identifier, ir_var_auto);
2602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* From page 22 (page 28 of the PDF) of the GLSL 1.10 specification;
2604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
2605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *     "Global variables can only use the qualifiers const,
2606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *     attribute, uni form, or varying. Only one may be
2607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *     specified.
2608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
2609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *     Local variables can only use the qualifier const."
2610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
2611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * This is relaxed in GLSL 1.30.  It is also relaxed by any extension
2612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * that adds the 'layout' keyword.
2613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if ((state->language_version < 130)
2615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  && !state->ARB_explicit_attrib_location_enable
2616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  && !state->ARB_fragment_coord_conventions_enable) {
2617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (this->type->qualifier.flags.q.out) {
2618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    _mesa_glsl_error(& loc, state,
2619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     "`out' qualifier in declaration of `%s' "
2620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     "only valid for function parameters in %s.",
2621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     decl->identifier, state->version_string);
2622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
2623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (this->type->qualifier.flags.q.in) {
2624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    _mesa_glsl_error(& loc, state,
2625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     "`in' qualifier in declaration of `%s' "
2626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     "only valid for function parameters in %s.",
2627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     decl->identifier, state->version_string);
2628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
2629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* FINISHME: Test for other invalid qualifiers. */
2630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      apply_type_qualifier_to_variable(& this->type->qualifier, var, state,
2633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       & loc, this->ubo_qualifiers_valid);
2634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (this->type->qualifier.flags.q.invariant) {
2636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if ((state->target == vertex_shader) && !(var->mode == ir_var_out ||
2637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						   var->mode == ir_var_inout)) {
2638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    /* FINISHME: Note that this doesn't work for invariant on
2639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     * a function signature outval
2640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     */
2641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    _mesa_glsl_error(& loc, state,
2642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     "`%s' cannot be marked invariant, vertex shader "
2643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     "outputs only\n", var->name);
2644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 } else if ((state->target == fragment_shader) &&
2645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		    !(var->mode == ir_var_in || var->mode == ir_var_inout)) {
2646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    /* FINISHME: Note that this doesn't work for invariant on
2647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     * a function signature inval
2648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     */
2649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    _mesa_glsl_error(& loc, state,
2650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     "`%s' cannot be marked invariant, fragment shader "
2651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     "inputs only\n", var->name);
2652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
2653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (state->current_function != NULL) {
2656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 const char *mode = NULL;
2657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 const char *extra = "";
2658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* There is no need to check for 'inout' here because the parser will
2660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * only allow that in function parameter lists.
2661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  */
2662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (this->type->qualifier.flags.q.attribute) {
2663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    mode = "attribute";
2664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 } else if (this->type->qualifier.flags.q.uniform) {
2665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    mode = "uniform";
2666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 } else if (this->type->qualifier.flags.q.varying) {
2667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    mode = "varying";
2668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 } else if (this->type->qualifier.flags.q.in) {
2669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    mode = "in";
2670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    extra = " or in function parameter list";
2671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 } else if (this->type->qualifier.flags.q.out) {
2672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    mode = "out";
2673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    extra = " or in function parameter list";
2674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
2675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (mode) {
2677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    _mesa_glsl_error(& loc, state,
2678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     "%s variable `%s' must be declared at "
2679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     "global scope%s",
2680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     mode, var->name, extra);
2681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
2682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else if (var->mode == ir_var_in) {
2683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         var->read_only = true;
2684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (state->target == vertex_shader) {
2686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    bool error_emitted = false;
2687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    /* From page 31 (page 37 of the PDF) of the GLSL 1.50 spec:
2689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     *
2690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     *    "Vertex shader inputs can only be float, floating-point
2691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     *    vectors, matrices, signed and unsigned integers and integer
2692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     *    vectors. Vertex shader inputs can also form arrays of these
2693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     *    types, but not structures."
2694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     *
2695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     * From page 31 (page 27 of the PDF) of the GLSL 1.30 spec:
2696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     *
2697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     *    "Vertex shader inputs can only be float, floating-point
2698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     *    vectors, matrices, signed and unsigned integers and integer
2699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     *    vectors. They cannot be arrays or structures."
2700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     *
2701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     * From page 23 (page 29 of the PDF) of the GLSL 1.20 spec:
2702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     *
2703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     *    "The attribute qualifier can be used only with float,
2704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     *    floating-point vectors, and matrices. Attribute variables
2705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     *    cannot be declared as arrays or structures."
2706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     */
2707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    const glsl_type *check_type = var->type->is_array()
2708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       ? var->type->fields.array : var->type;
2709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    switch (check_type->base_type) {
2711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    case GLSL_TYPE_FLOAT:
2712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       break;
2713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    case GLSL_TYPE_UINT:
2714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    case GLSL_TYPE_INT:
2715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       if (state->language_version > 120)
2716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  break;
2717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       /* FALLTHROUGH */
2718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    default:
2719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       _mesa_glsl_error(& loc, state,
2720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				"vertex shader input / attribute cannot have "
2721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				"type %s`%s'",
2722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				var->type->is_array() ? "array of " : "",
2723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				check_type->name);
2724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       error_emitted = true;
2725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    }
2726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    if (!error_emitted && (state->language_version <= 130)
2728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		&& var->type->is_array()) {
2729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       _mesa_glsl_error(& loc, state,
2730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				"vertex shader input / attribute cannot have "
2731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				"array type");
2732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       error_emitted = true;
2733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    }
2734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
2735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Integer vertex outputs must be qualified with 'flat'.
2738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
2739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * From section 4.3.6 of the GLSL 1.30 spec:
2740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *    "If a vertex output is a signed or unsigned integer or integer
2741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *    vector, then it must be qualified with the interpolation qualifier
2742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *    flat."
2743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (state->language_version >= 130
2745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          && state->target == vertex_shader
2746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          && state->current_function == NULL
2747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          && var->type->is_integer()
2748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          && var->mode == ir_var_out
2749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          && var->interpolation != INTERP_QUALIFIER_FLAT) {
2750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         _mesa_glsl_error(&loc, state, "If a vertex output is an integer, "
2752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          "then it must be qualified with 'flat'");
2753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Interpolation qualifiers cannot be applied to 'centroid' and
2757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * 'centroid varying'.
2758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
2759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * From page 29 (page 35 of the PDF) of the GLSL 1.30 spec:
2760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *    "interpolation qualifiers may only precede the qualifiers in,
2761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *    centroid in, out, or centroid out in a declaration. They do not apply
2762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *    to the deprecated storage qualifiers varying or centroid varying."
2763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (state->language_version >= 130
2765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          && this->type->qualifier.has_interpolation()
2766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          && this->type->qualifier.flags.q.varying) {
2767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const char *i = this->type->qualifier.interpolation_string();
2769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         assert(i != NULL);
2770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const char *s;
2771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (this->type->qualifier.flags.q.centroid)
2772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            s = "centroid varying";
2773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else
2774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            s = "varying";
2775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         _mesa_glsl_error(&loc, state,
2777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          "qualifier '%s' cannot be applied to the "
2778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          "deprecated storage qualifier '%s'", i, s);
2779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Interpolation qualifiers can only apply to vertex shader outputs and
2783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * fragment shader inputs.
2784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
2785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * From page 29 (page 35 of the PDF) of the GLSL 1.30 spec:
2786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *    "Outputs from a vertex shader (out) and inputs to a fragment
2787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *    shader (in) can be further qualified with one or more of these
2788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *    interpolation qualifiers"
2789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (state->language_version >= 130
2791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          && this->type->qualifier.has_interpolation()) {
2792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const char *i = this->type->qualifier.interpolation_string();
2794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         assert(i != NULL);
2795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         switch (state->target) {
2797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         case vertex_shader:
2798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (this->type->qualifier.flags.q.in) {
2799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               _mesa_glsl_error(&loc, state,
2800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                "qualifier '%s' cannot be applied to vertex "
2801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                "shader inputs", i);
2802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
2803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            break;
2804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         case fragment_shader:
2805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (this->type->qualifier.flags.q.out) {
2806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               _mesa_glsl_error(&loc, state,
2807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                "qualifier '%s' cannot be applied to fragment "
2808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                "shader outputs", i);
2809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
2810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            break;
2811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         default:
2812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            assert(0);
2813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
2814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* From section 4.3.4 of the GLSL 1.30 spec:
2818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *    "It is an error to use centroid in in a vertex shader."
2819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (state->language_version >= 130
2821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          && this->type->qualifier.flags.q.centroid
2822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          && this->type->qualifier.flags.q.in
2823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          && state->target == vertex_shader) {
2824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         _mesa_glsl_error(&loc, state,
2826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          "'centroid in' cannot be used in a vertex shader");
2827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Precision qualifiers exists only in GLSL versions 1.00 and >= 1.30.
2831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (this->type->specifier->precision != ast_precision_none
2833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          && state->language_version != 100
2834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          && state->language_version < 130) {
2835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         _mesa_glsl_error(&loc, state,
2837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          "precision qualifiers are supported only in GLSL ES "
2838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          "1.00, and GLSL 1.30 and later");
2839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Precision qualifiers only apply to floating point and integer types.
2843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
2844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * From section 4.5.2 of the GLSL 1.30 spec:
2845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *    "Any floating point or any integer declaration can have the type
2846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *    preceded by one of these precision qualifiers [...] Literal
2847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *    constants do not have precision qualifiers. Neither do Boolean
2848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *    variables.
2849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
2850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * In GLSL ES, sampler types are also allowed.
2851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
2852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * From page 87 of the GLSL ES spec:
2853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *    "RESOLUTION: Allow sampler types to take a precision qualifier."
2854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (this->type->specifier->precision != ast_precision_none
2856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          && !var->type->is_float()
2857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          && !var->type->is_integer()
2858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          && !(var->type->is_sampler() && state->es_shader)
2859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          && !(var->type->is_array()
2860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               && (var->type->fields.array->is_float()
2861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   || var->type->fields.array->is_integer()))) {
2862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         _mesa_glsl_error(&loc, state,
2864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          "precision qualifiers apply only to floating point"
2865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          "%s types", state->es_shader ? ", integer, and sampler"
2866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						       : "and integer");
2867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* From page 17 (page 23 of the PDF) of the GLSL 1.20 spec:
2870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
2871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *    "[Sampler types] can only be declared as function
2872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *    parameters or uniform variables (see Section 4.3.5
2873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *    "Uniform")".
2874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (var_type->contains_sampler() &&
2876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          !this->type->qualifier.flags.q.uniform) {
2877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         _mesa_glsl_error(&loc, state, "samplers must be declared uniform");
2878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Process the initializer and add its instructions to a temporary
2881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * list.  This list will be added to the instruction stream (below) after
2882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * the declaration is added.  This is done because in some cases (such as
2883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * redeclarations) the declaration may not actually be added to the
2884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * instruction stream.
2885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      exec_list initializer_instructions;
2887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_variable *earlier = get_variable_being_redeclared(var, decl, state);
2888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (decl->initializer != NULL) {
2890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 result = process_initializer((earlier == NULL) ? var : earlier,
2891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				      decl, this->type,
2892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				      &initializer_instructions, state);
2893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* From page 23 (page 29 of the PDF) of the GLSL 1.10 spec:
2896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
2897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *     "It is an error to write to a const variable outside of
2898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *      its declaration, so they must be initialized when
2899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *      declared."
2900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (this->type->qualifier.flags.q.constant && decl->initializer == NULL) {
2902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 _mesa_glsl_error(& loc, state,
2903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  "const declaration of `%s' must be initialized",
2904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  decl->identifier);
2905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* If the declaration is not a redeclaration, there are a few additional
2908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * semantic checks that must be applied.  In addition, variable that was
2909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * created for the declaration should be added to the IR stream.
2910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (earlier == NULL) {
2912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* From page 15 (page 21 of the PDF) of the GLSL 1.10 spec,
2913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  *
2914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  *   "Identifiers starting with "gl_" are reserved for use by
2915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  *   OpenGL, and may not be declared in a shader as either a
2916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  *   variable or a function."
2917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  */
2918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (strncmp(decl->identifier, "gl_", 3) == 0)
2919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    _mesa_glsl_error(& loc, state,
2920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     "identifier `%s' uses reserved `gl_' prefix",
2921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     decl->identifier);
2922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 else if (strstr(decl->identifier, "__")) {
2923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    /* From page 14 (page 20 of the PDF) of the GLSL 1.10
2924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     * spec:
2925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     *
2926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     *     "In addition, all identifiers containing two
2927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     *      consecutive underscores (__) are reserved as
2928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     *      possible future keywords."
2929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     */
2930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    _mesa_glsl_error(& loc, state,
2931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     "identifier `%s' uses reserved `__' string",
2932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     decl->identifier);
2933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
2934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* Add the variable to the symbol table.  Note that the initializer's
2936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * IR was already processed earlier (though it hasn't been emitted
2937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * yet), without the variable in scope.
2938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  *
2939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * This differs from most C-like languages, but it follows the GLSL
2940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * specification.  From page 28 (page 34 of the PDF) of the GLSL 1.50
2941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * spec:
2942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  *
2943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  *     "Within a declaration, the scope of a name starts immediately
2944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  *     after the initializer if present or immediately after the name
2945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  *     being declared if not."
2946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  */
2947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (!state->symbols->add_variable(var)) {
2948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    YYLTYPE loc = this->get_location();
2949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    _mesa_glsl_error(&loc, state, "name `%s' already taken in the "
2950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     "current scope", decl->identifier);
2951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    continue;
2952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
2953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* Push the variable declaration to the top.  It means that all the
2955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * variable declarations will appear in a funny last-to-first order,
2956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * but otherwise we run into trouble if a function is prototyped, a
2957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * global var is decled, then the function is defined with usage of
2958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * the global var.  See glslparsertest's CorrectModule.frag.
2959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  */
2960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 instructions->push_head(var);
2961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      instructions->append_list(&initializer_instructions);
2964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Generally, variable declarations do not have r-values.  However,
2968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * one is used for the declaration in
2969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
2970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * while (bool b = some_condition()) {
2971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *   ...
2972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * }
2973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
2974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * so we return the rvalue from the last seen declaration here.
2975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
2976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return result;
2977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue *
2981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgast_parameter_declarator::hir(exec_list *instructions,
2982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			      struct _mesa_glsl_parse_state *state)
2983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void *ctx = state;
2985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct glsl_type *type;
2986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const char *name = NULL;
2987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   YYLTYPE loc = this->get_location();
2988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   type = this->type->specifier->glsl_type(& name, state);
2990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (type == NULL) {
2992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (name != NULL) {
2993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 _mesa_glsl_error(& loc, state,
2994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  "invalid type `%s' in declaration of `%s'",
2995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  name, this->identifier);
2996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
2997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 _mesa_glsl_error(& loc, state,
2998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  "invalid type in declaration of `%s'",
2999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  this->identifier);
3000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      type = glsl_type::error_type;
3003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* From page 62 (page 68 of the PDF) of the GLSL 1.50 spec:
3006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
3007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    "Functions that accept no input arguments need not use void in the
3008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    argument list because prototypes (or definitions) are required and
3009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    therefore there is no ambiguity when an empty argument list "( )" is
3010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    declared. The idiom "(void)" as a parameter list is provided for
3011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    convenience."
3012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
3013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * Placing this check here prevents a void parameter being set up
3014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * for a function, which avoids tripping up checks for main taking
3015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * parameters and lookups of an unnamed symbol.
3016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
3017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (type->is_void()) {
3018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (this->identifier != NULL)
3019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 _mesa_glsl_error(& loc, state,
3020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  "named parameter cannot have type `void'");
3021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      is_void = true;
3023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
3024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (formal_parameter && (this->identifier == NULL)) {
3027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(& loc, state, "formal parameter lacks a name");
3028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
3029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* This only handles "vec4 foo[..]".  The earlier specifier->glsl_type(...)
3032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * call already handled the "vec4[..] foo" case.
3033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
3034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (this->is_array) {
3035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      type = process_array_type(&loc, type, this->array_size, state);
3036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!type->is_error() && type->array_size() == 0) {
3039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(&loc, state, "arrays passed as parameters must have "
3040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       "a declared size.");
3041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      type = glsl_type::error_type;
3042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   is_void = false;
3045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_variable *var = new(ctx) ir_variable(type, this->identifier, ir_var_in);
3046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Apply any specified qualifiers to the parameter declaration.  Note that
3048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * for function parameters the default mode is 'in'.
3049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
3050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   apply_type_qualifier_to_variable(& this->type->qualifier, var, state, & loc,
3051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				    false);
3052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* From page 17 (page 23 of the PDF) of the GLSL 1.20 spec:
3054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
3055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    "Samplers cannot be treated as l-values; hence cannot be used
3056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    as out or inout function parameters, nor can they be assigned
3057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    into."
3058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
3059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if ((var->mode == ir_var_inout || var->mode == ir_var_out)
3060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       && type->contains_sampler()) {
3061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(&loc, state, "out and inout parameters cannot contain samplers");
3062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      type = glsl_type::error_type;
3063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* From page 39 (page 45 of the PDF) of the GLSL 1.10 spec:
3066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
3067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    "When calling a function, expressions that do not evaluate to
3068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *     l-values cannot be passed to parameters declared as out or inout."
3069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
3070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * From page 32 (page 38 of the PDF) of the GLSL 1.10 spec:
3071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
3072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    "Other binary or unary expressions, non-dereferenced arrays,
3073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *     function names, swizzles with repeated fields, and constants
3074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *     cannot be l-values."
3075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
3076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * So for GLSL 1.10, passing an array as an out or inout parameter is not
3077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * allowed.  This restriction is removed in GLSL 1.20, and in GLSL ES.
3078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
3079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if ((var->mode == ir_var_inout || var->mode == ir_var_out)
3080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       && type->is_array() && state->language_version == 110) {
3081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(&loc, state, "Arrays cannot be out or inout parameters in GLSL 1.10");
3082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      type = glsl_type::error_type;
3083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   instructions->push_tail(var);
3086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Parameter declarations do not have r-values.
3088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
3089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return NULL;
3090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
3094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgast_parameter_declarator::parameters_to_hir(exec_list *ast_parameters,
3095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					    bool formal,
3096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					    exec_list *ir_parameters,
3097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					    _mesa_glsl_parse_state *state)
3098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ast_parameter_declarator *void_param = NULL;
3100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned count = 0;
3101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   foreach_list_typed (ast_parameter_declarator, param, link, ast_parameters) {
3103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      param->formal_parameter = formal;
3104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      param->hir(ir_parameters, state);
3105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (param->is_void)
3107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 void_param = param;
3108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      count++;
3110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if ((void_param != NULL) && (count > 1)) {
3113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      YYLTYPE loc = void_param->get_location();
3114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(& loc, state,
3116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       "`void' parameter must be only parameter");
3117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
3122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgemit_function(_mesa_glsl_parse_state *state, ir_function *f)
3123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* IR invariants disallow function declarations or definitions
3125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * nested within other function definitions.  But there is no
3126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * requirement about the relative order of function declarations
3127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * and definitions with respect to one another.  So simply insert
3128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * the new ir_function block at the end of the toplevel instruction
3129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * list.
3130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
3131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   state->toplevel_ir->push_tail(f);
3132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue *
3136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgast_function::hir(exec_list *instructions,
3137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  struct _mesa_glsl_parse_state *state)
3138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void *ctx = state;
3140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_function *f = NULL;
3141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_function_signature *sig = NULL;
3142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   exec_list hir_parameters;
3143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const char *const name = identifier;
3145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* New functions are always added to the top-level IR instruction stream,
3147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * so this instruction list pointer is ignored.  See also emit_function
3148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * (called below).
3149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
3150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) instructions;
3151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* From page 21 (page 27 of the PDF) of the GLSL 1.20 spec,
3153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
3154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *   "Function declarations (prototypes) cannot occur inside of functions;
3155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *   they must be at global scope, or for the built-in functions, outside
3156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *   the global scope."
3157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
3158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * From page 27 (page 33 of the PDF) of the GLSL ES 1.00.16 spec,
3159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
3160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *   "User defined functions may only be defined within the global scope."
3161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
3162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * Note that this language does not appear in GLSL 1.10.
3163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
3164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if ((state->current_function != NULL) && (state->language_version != 110)) {
3165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      YYLTYPE loc = this->get_location();
3166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(&loc, state,
3167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       "declaration of function `%s' not allowed within "
3168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       "function body", name);
3169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* From page 15 (page 21 of the PDF) of the GLSL 1.10 spec,
3172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
3173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *   "Identifiers starting with "gl_" are reserved for use by
3174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *   OpenGL, and may not be declared in a shader as either a
3175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *   variable or a function."
3176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
3177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (strncmp(name, "gl_", 3) == 0) {
3178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      YYLTYPE loc = this->get_location();
3179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(&loc, state,
3180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       "identifier `%s' uses reserved `gl_' prefix", name);
3181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Convert the list of function parameters to HIR now so that they can be
3184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * used below to compare this function's signature with previously seen
3185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * signatures for functions with the same name.
3186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
3187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ast_parameter_declarator::parameters_to_hir(& this->parameters,
3188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					       is_definition,
3189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					       & hir_parameters, state);
3190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const char *return_type_name;
3192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const glsl_type *return_type =
3193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->return_type->specifier->glsl_type(& return_type_name, state);
3194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!return_type) {
3196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      YYLTYPE loc = this->get_location();
3197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(&loc, state,
3198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       "function `%s' has undeclared return type `%s'",
3199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       name, return_type_name);
3200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return_type = glsl_type::error_type;
3201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* From page 56 (page 62 of the PDF) of the GLSL 1.30 spec:
3204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * "No qualifier is allowed on the return type of a function."
3205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
3206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (this->return_type->has_qualifiers()) {
3207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      YYLTYPE loc = this->get_location();
3208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(& loc, state,
3209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       "function `%s' return type has qualifiers", name);
3210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* From page 17 (page 23 of the PDF) of the GLSL 1.20 spec:
3213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
3214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    "[Sampler types] can only be declared as function parameters
3215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    or uniform variables (see Section 4.3.5 "Uniform")".
3216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
3217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (return_type->contains_sampler()) {
3218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      YYLTYPE loc = this->get_location();
3219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(&loc, state,
3220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       "function `%s' return type can't contain a sampler",
3221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       name);
3222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Verify that this function's signature either doesn't match a previously
3225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * seen signature for a function with the same name, or, if a match is found,
3226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * that the previously seen signature does not have an associated definition.
3227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
3228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   f = state->symbols->get_function(name);
3229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (f != NULL && (state->es_shader || f->has_user_signature())) {
3230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sig = f->exact_matching_signature(&hir_parameters);
3231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (sig != NULL) {
3232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 const char *badvar = sig->qualifiers_match(&hir_parameters);
3233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (badvar != NULL) {
3234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    YYLTYPE loc = this->get_location();
3235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    _mesa_glsl_error(&loc, state, "function `%s' parameter `%s' "
3237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     "qualifiers don't match prototype", name, badvar);
3238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
3239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (sig->return_type != return_type) {
3241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    YYLTYPE loc = this->get_location();
3242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    _mesa_glsl_error(&loc, state, "function `%s' return type doesn't "
3244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     "match prototype", name);
3245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
3246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (is_definition && sig->is_defined) {
3248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    YYLTYPE loc = this->get_location();
3249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    _mesa_glsl_error(& loc, state, "function `%s' redefined", name);
3251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
3252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
3254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      f = new(ctx) ir_function(name);
3255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!state->symbols->add_function(f)) {
3256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* This function name shadows a non-function use of the same name. */
3257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 YYLTYPE loc = this->get_location();
3258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 _mesa_glsl_error(&loc, state, "function name `%s' conflicts with "
3260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  "non-function", name);
3261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 return NULL;
3262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit_function(state, f);
3265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Verify the return type of main() */
3268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (strcmp(name, "main") == 0) {
3269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (! return_type->is_void()) {
3270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 YYLTYPE loc = this->get_location();
3271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 _mesa_glsl_error(& loc, state, "main() must return void");
3273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!hir_parameters.is_empty()) {
3276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 YYLTYPE loc = this->get_location();
3277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 _mesa_glsl_error(& loc, state, "main() must not take any parameters");
3279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Finish storing the information about this new function in its signature.
3283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
3284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (sig == NULL) {
3285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sig = new(ctx) ir_function_signature(return_type);
3286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      f->add_signature(sig);
3287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sig->replace_parameters(&hir_parameters);
3290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   signature = sig;
3291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Function declarations (prototypes) do not have r-values.
3293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
3294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return NULL;
3295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue *
3299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgast_function_definition::hir(exec_list *instructions,
3300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     struct _mesa_glsl_parse_state *state)
3301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   prototype->is_definition = true;
3303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   prototype->hir(instructions, state);
3304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_function_signature *signature = prototype->signature;
3306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (signature == NULL)
3307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
3308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(state->current_function == NULL);
3310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   state->current_function = signature;
3311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   state->found_return = false;
3312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Duplicate parameters declared in the prototype as concrete variables.
3314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * Add these to the symbol table.
3315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
3316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   state->symbols->push_scope();
3317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   foreach_iter(exec_list_iterator, iter, signature->parameters) {
3318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_variable *const var = ((ir_instruction *) iter.get())->as_variable();
3319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(var != NULL);
3321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* The only way a parameter would "exist" is if two parameters have
3323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * the same name.
3324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
3325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (state->symbols->name_declared_this_scope(var->name)) {
3326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 YYLTYPE loc = this->get_location();
3327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 _mesa_glsl_error(& loc, state, "parameter `%s' redeclared", var->name);
3329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
3330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 state->symbols->add_variable(var);
3331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Convert the body of the function to HIR. */
3335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   this->body->hir(&signature->body, state);
3336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   signature->is_defined = true;
3337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   state->symbols->pop_scope();
3339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(state->current_function == signature);
3341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   state->current_function = NULL;
3342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!signature->return_type->is_void() && !state->found_return) {
3344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      YYLTYPE loc = this->get_location();
3345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(& loc, state, "function `%s' has non-void return type "
3346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       "%s, but no return statement",
3347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       signature->function_name(),
3348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       signature->return_type->name);
3349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Function definitions do not have r-values.
3352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
3353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return NULL;
3354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue *
3358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgast_jump_statement::hir(exec_list *instructions,
3359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			struct _mesa_glsl_parse_state *state)
3360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void *ctx = state;
3362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (mode) {
3364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_return: {
3365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_return *inst;
3366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(state->current_function);
3367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (opt_return_value) {
3369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ir_rvalue *const ret = opt_return_value->hir(instructions, state);
3370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* The value of the return type can be NULL if the shader says
3372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * 'return foo();' and foo() is a function that returns void.
3373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  *
3374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * NOTE: The GLSL spec doesn't say that this is an error.  The type
3375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * of the return value is void.  If the return type of the function is
3376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * also void, then this should compile without error.  Seriously.
3377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  */
3378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 const glsl_type *const ret_type =
3379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    (ret == NULL) ? glsl_type::void_type : ret->type;
3380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* Implicit conversions are not allowed for return values. */
3382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (state->current_function->return_type != ret_type) {
3383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    YYLTYPE loc = this->get_location();
3384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    _mesa_glsl_error(& loc, state,
3386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     "`return' with wrong type %s, in function `%s' "
3387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     "returning %s",
3388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     ret_type->name,
3389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     state->current_function->function_name(),
3390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     state->current_function->return_type->name);
3391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
3392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 inst = new(ctx) ir_return(ret);
3394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
3395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (state->current_function->return_type->base_type !=
3396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     GLSL_TYPE_VOID) {
3397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    YYLTYPE loc = this->get_location();
3398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    _mesa_glsl_error(& loc, state,
3400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     "`return' with no value, in function %s returning "
3401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     "non-void",
3402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     state->current_function->function_name());
3403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
3404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 inst = new(ctx) ir_return;
3405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      state->found_return = true;
3408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      instructions->push_tail(inst);
3409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
3410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_discard:
3413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (state->target != fragment_shader) {
3414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 YYLTYPE loc = this->get_location();
3415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 _mesa_glsl_error(& loc, state,
3417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  "`discard' may only appear in a fragment shader");
3418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      instructions->push_tail(new(ctx) ir_discard);
3420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
3421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_break:
3423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ast_continue:
3424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (mode == ast_continue &&
3425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  state->loop_nesting_ast == NULL) {
3426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 YYLTYPE loc = this->get_location();
3427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 _mesa_glsl_error(& loc, state,
3429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  "continue may only appear in a loop");
3430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else if (mode == ast_break &&
3431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 state->loop_nesting_ast == NULL &&
3432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 state->switch_state.switch_nesting_ast == NULL) {
3433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 YYLTYPE loc = this->get_location();
3434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 _mesa_glsl_error(& loc, state,
3436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  "break may only appear in a loop or a switch");
3437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
3438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* For a loop, inline the for loop expression again,
3439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * since we don't know where near the end of
3440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * the loop body the normal copy of it
3441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * is going to be placed.
3442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  */
3443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (state->loop_nesting_ast != NULL &&
3444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     mode == ast_continue &&
3445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     state->loop_nesting_ast->rest_expression) {
3446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    state->loop_nesting_ast->rest_expression->hir(instructions,
3447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org							  state);
3448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
3449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (state->switch_state.is_switch_innermost &&
3451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     mode == ast_break) {
3452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    /* Force break out of switch by setting is_break switch state.
3453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     */
3454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    ir_variable *const is_break_var = state->switch_state.is_break_var;
3455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    ir_dereference_variable *const deref_is_break_var =
3456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       new(ctx) ir_dereference_variable(is_break_var);
3457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    ir_constant *const true_val = new(ctx) ir_constant(true);
3458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    ir_assignment *const set_break_var =
3459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       new(ctx) ir_assignment(deref_is_break_var, true_val);
3460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    instructions->push_tail(set_break_var);
3462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
3463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 else {
3464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    ir_loop_jump *const jump =
3465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       new(ctx) ir_loop_jump((mode == ast_break)
3466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				     ? ir_loop_jump::jump_break
3467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				     : ir_loop_jump::jump_continue);
3468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    instructions->push_tail(jump);
3469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
3470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
3473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Jump instructions do not have r-values.
3476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
3477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return NULL;
3478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue *
3482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgast_selection_statement::hir(exec_list *instructions,
3483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     struct _mesa_glsl_parse_state *state)
3484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void *ctx = state;
3486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_rvalue *const condition = this->condition->hir(instructions, state);
3488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* From page 66 (page 72 of the PDF) of the GLSL 1.50 spec:
3490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
3491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    "Any expression whose type evaluates to a Boolean can be used as the
3492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    conditional expression bool-expression. Vector types are not accepted
3493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    as the expression to if."
3494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
3495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * The checks are separated so that higher quality diagnostics can be
3496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * generated for cases where both rules are violated.
3497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
3498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!condition->type->is_boolean() || !condition->type->is_scalar()) {
3499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      YYLTYPE loc = this->condition->get_location();
3500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(& loc, state, "if-statement condition must be scalar "
3502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       "boolean");
3503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_if *const stmt = new(ctx) ir_if(condition);
3506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (then_statement != NULL) {
3508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      state->symbols->push_scope();
3509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      then_statement->hir(& stmt->then_instructions, state);
3510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      state->symbols->pop_scope();
3511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (else_statement != NULL) {
3514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      state->symbols->push_scope();
3515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else_statement->hir(& stmt->else_instructions, state);
3516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      state->symbols->pop_scope();
3517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   instructions->push_tail(stmt);
3520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* if-statements do not have r-values.
3522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
3523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return NULL;
3524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue *
3528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgast_switch_statement::hir(exec_list *instructions,
3529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  struct _mesa_glsl_parse_state *state)
3530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void *ctx = state;
3532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_rvalue *const test_expression =
3534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->test_expression->hir(instructions, state);
3535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* From page 66 (page 55 of the PDF) of the GLSL 1.50 spec:
3537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
3538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    "The type of init-expression in a switch statement must be a
3539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *     scalar integer."
3540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
3541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!test_expression->type->is_scalar() ||
3542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       !test_expression->type->is_integer()) {
3543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      YYLTYPE loc = this->test_expression->get_location();
3544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(& loc,
3546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       state,
3547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       "switch-statement expression must be scalar "
3548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       "integer");
3549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Track the switch-statement nesting in a stack-like manner.
3552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
3553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct glsl_switch_state saved = state->switch_state;
3554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   state->switch_state.is_switch_innermost = true;
3556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   state->switch_state.switch_nesting_ast = this;
3557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   state->switch_state.labels_ht = hash_table_ctor(0, hash_table_pointer_hash,
3558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						   hash_table_pointer_compare);
3559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   state->switch_state.previous_default = NULL;
3560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Initalize is_fallthru state to false.
3562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
3563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_rvalue *const is_fallthru_val = new (ctx) ir_constant(false);
3564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   state->switch_state.is_fallthru_var =
3565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      new(ctx) ir_variable(glsl_type::bool_type,
3566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   "switch_is_fallthru_tmp",
3567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   ir_var_temporary);
3568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   instructions->push_tail(state->switch_state.is_fallthru_var);
3569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_dereference_variable *deref_is_fallthru_var =
3571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      new(ctx) ir_dereference_variable(state->switch_state.is_fallthru_var);
3572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   instructions->push_tail(new(ctx) ir_assignment(deref_is_fallthru_var,
3573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						  is_fallthru_val));
3574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Initalize is_break state to false.
3576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
3577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_rvalue *const is_break_val = new (ctx) ir_constant(false);
3578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   state->switch_state.is_break_var = new(ctx) ir_variable(glsl_type::bool_type,
3579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org							   "switch_is_break_tmp",
3580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org							   ir_var_temporary);
3581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   instructions->push_tail(state->switch_state.is_break_var);
3582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_dereference_variable *deref_is_break_var =
3584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      new(ctx) ir_dereference_variable(state->switch_state.is_break_var);
3585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   instructions->push_tail(new(ctx) ir_assignment(deref_is_break_var,
3586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						  is_break_val));
3587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Cache test expression.
3589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
3590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   test_to_hir(instructions, state);
3591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Emit code for body of switch stmt.
3593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
3594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   body->hir(instructions, state);
3595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   hash_table_dtor(state->switch_state.labels_ht);
3597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   state->switch_state = saved;
3599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Switch statements do not have r-values. */
3601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return NULL;
3602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
3606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgast_switch_statement::test_to_hir(exec_list *instructions,
3607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				  struct _mesa_glsl_parse_state *state)
3608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void *ctx = state;
3610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Cache value of test expression. */
3612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_rvalue *const test_val =
3613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      test_expression->hir(instructions,
3614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   state);
3615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   state->switch_state.test_var = new(ctx) ir_variable(test_val->type,
3617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						       "switch_test_tmp",
3618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						       ir_var_temporary);
3619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_dereference_variable *deref_test_var =
3620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      new(ctx) ir_dereference_variable(state->switch_state.test_var);
3621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   instructions->push_tail(state->switch_state.test_var);
3623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   instructions->push_tail(new(ctx) ir_assignment(deref_test_var, test_val));
3624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue *
3628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgast_switch_body::hir(exec_list *instructions,
3629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		     struct _mesa_glsl_parse_state *state)
3630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (stmts != NULL)
3632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      stmts->hir(instructions, state);
3633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Switch bodies do not have r-values. */
3635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return NULL;
3636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue *
3639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgast_case_statement_list::hir(exec_list *instructions,
3640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     struct _mesa_glsl_parse_state *state)
3641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   foreach_list_typed (ast_case_statement, case_stmt, link, & this->cases)
3643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case_stmt->hir(instructions, state);
3644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Case statements do not have r-values. */
3646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return NULL;
3647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue *
3650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgast_case_statement::hir(exec_list *instructions,
3651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			struct _mesa_glsl_parse_state *state)
3652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   labels->hir(instructions, state);
3654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Conditionally set fallthru state based on break state. */
3656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_constant *const false_val = new(state) ir_constant(false);
3657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_dereference_variable *const deref_is_fallthru_var =
3658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      new(state) ir_dereference_variable(state->switch_state.is_fallthru_var);
3659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_dereference_variable *const deref_is_break_var =
3660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      new(state) ir_dereference_variable(state->switch_state.is_break_var);
3661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_assignment *const reset_fallthru_on_break =
3662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      new(state) ir_assignment(deref_is_fallthru_var,
3663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			       false_val,
3664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			       deref_is_break_var);
3665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   instructions->push_tail(reset_fallthru_on_break);
3666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Guard case statements depending on fallthru state. */
3668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_dereference_variable *const deref_fallthru_guard =
3669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      new(state) ir_dereference_variable(state->switch_state.is_fallthru_var);
3670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_if *const test_fallthru = new(state) ir_if(deref_fallthru_guard);
3671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   foreach_list_typed (ast_node, stmt, link, & this->stmts)
3673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      stmt->hir(& test_fallthru->then_instructions, state);
3674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   instructions->push_tail(test_fallthru);
3676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Case statements do not have r-values. */
3678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return NULL;
3679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue *
3683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgast_case_label_list::hir(exec_list *instructions,
3684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			 struct _mesa_glsl_parse_state *state)
3685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   foreach_list_typed (ast_case_label, label, link, & this->labels)
3687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      label->hir(instructions, state);
3688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Case labels do not have r-values. */
3690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return NULL;
3691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue *
3694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgast_case_label::hir(exec_list *instructions,
3695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		    struct _mesa_glsl_parse_state *state)
3696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void *ctx = state;
3698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_dereference_variable *deref_fallthru_var =
3700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      new(ctx) ir_dereference_variable(state->switch_state.is_fallthru_var);
3701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_rvalue *const true_val = new(ctx) ir_constant(true);
3703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* If not default case, ... */
3705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (this->test_value != NULL) {
3706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Conditionally set fallthru state based on
3707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * comparison of cached test expression value to case label.
3708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
3709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_rvalue *const label_rval = this->test_value->hir(instructions, state);
3710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_constant *label_const = label_rval->constant_expression_value();
3711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!label_const) {
3713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 YYLTYPE loc = this->test_value->get_location();
3714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 _mesa_glsl_error(& loc, state,
3716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  "switch statement case label must be a "
3717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  "constant expression");
3718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* Stuff a dummy value in to allow processing to continue. */
3720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 label_const = new(ctx) ir_constant(0);
3721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
3722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ast_expression *previous_label = (ast_expression *)
3723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    hash_table_find(state->switch_state.labels_ht,
3724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			    (void *)(uintptr_t)label_const->value.u[0]);
3725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (previous_label) {
3727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    YYLTYPE loc = this->test_value->get_location();
3728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    _mesa_glsl_error(& loc, state,
3729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     "duplicate case value");
3730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    loc = previous_label->get_location();
3732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    _mesa_glsl_error(& loc, state,
3733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     "this is the previous case label");
3734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 } else {
3735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    hash_table_insert(state->switch_state.labels_ht,
3736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			      this->test_value,
3737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			      (void *)(uintptr_t)label_const->value.u[0]);
3738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
3739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_dereference_variable *deref_test_var =
3742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 new(ctx) ir_dereference_variable(state->switch_state.test_var);
3743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_rvalue *const test_cond = new(ctx) ir_expression(ir_binop_all_equal,
3745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org							  label_const,
3746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org							  deref_test_var);
3747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_assignment *set_fallthru_on_test =
3749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 new(ctx) ir_assignment(deref_fallthru_var,
3750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				true_val,
3751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				test_cond);
3752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      instructions->push_tail(set_fallthru_on_test);
3754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else { /* default case */
3755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (state->switch_state.previous_default) {
3756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 YYLTYPE loc = this->get_location();
3757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 _mesa_glsl_error(& loc, state,
3758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  "multiple default labels in one switch");
3759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 loc = state->switch_state.previous_default->get_location();
3761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 _mesa_glsl_error(& loc, state,
3762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  "this is the first default label");
3763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      state->switch_state.previous_default = this;
3765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Set falltrhu state. */
3767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_assignment *set_fallthru =
3768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 new(ctx) ir_assignment(deref_fallthru_var, true_val);
3769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      instructions->push_tail(set_fallthru);
3771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Case statements do not have r-values. */
3774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return NULL;
3775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
3778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgast_iteration_statement::condition_to_hir(ir_loop *stmt,
3779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					  struct _mesa_glsl_parse_state *state)
3780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void *ctx = state;
3782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (condition != NULL) {
3784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_rvalue *const cond =
3785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 condition->hir(& stmt->body_instructions, state);
3786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if ((cond == NULL)
3788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  || !cond->type->is_boolean() || !cond->type->is_scalar()) {
3789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 YYLTYPE loc = condition->get_location();
3790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 _mesa_glsl_error(& loc, state,
3792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  "loop condition must be scalar boolean");
3793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
3794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* As the first code in the loop body, generate a block that looks
3795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * like 'if (!condition) break;' as the loop termination condition.
3796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  */
3797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ir_rvalue *const not_cond =
3798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    new(ctx) ir_expression(ir_unop_logic_not, cond);
3799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ir_if *const if_stmt = new(ctx) ir_if(not_cond);
3801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ir_jump *const break_stmt =
3803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    new(ctx) ir_loop_jump(ir_loop_jump::jump_break);
3804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if_stmt->then_instructions.push_tail(break_stmt);
3806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 stmt->body_instructions.push_tail(if_stmt);
3807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue *
3813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgast_iteration_statement::hir(exec_list *instructions,
3814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     struct _mesa_glsl_parse_state *state)
3815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void *ctx = state;
3817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* For-loops and while-loops start a new scope, but do-while loops do not.
3819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
3820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (mode != ast_do_while)
3821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      state->symbols->push_scope();
3822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (init_statement != NULL)
3824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      init_statement->hir(instructions, state);
3825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_loop *const stmt = new(ctx) ir_loop();
3827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   instructions->push_tail(stmt);
3828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Track the current loop nesting. */
3830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ast_iteration_statement *nesting_ast = state->loop_nesting_ast;
3831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   state->loop_nesting_ast = this;
3833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Likewise, indicate that following code is closest to a loop,
3835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * NOT closest to a switch.
3836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
3837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   bool saved_is_switch_innermost = state->switch_state.is_switch_innermost;
3838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   state->switch_state.is_switch_innermost = false;
3839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (mode != ast_do_while)
3841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      condition_to_hir(stmt, state);
3842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (body != NULL)
3844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      body->hir(& stmt->body_instructions, state);
3845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (rest_expression != NULL)
3847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      rest_expression->hir(& stmt->body_instructions, state);
3848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (mode == ast_do_while)
3850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      condition_to_hir(stmt, state);
3851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (mode != ast_do_while)
3853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      state->symbols->pop_scope();
3854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Restore previous nesting before returning. */
3856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   state->loop_nesting_ast = nesting_ast;
3857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   state->switch_state.is_switch_innermost = saved_is_switch_innermost;
3858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Loops do not have r-values.
3860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
3861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return NULL;
3862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue *
3866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgast_type_specifier::hir(exec_list *instructions,
3867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  struct _mesa_glsl_parse_state *state)
3868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!this->is_precision_statement && this->structure == NULL)
3870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
3871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   YYLTYPE loc = this->get_location();
3873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (this->precision != ast_precision_none
3875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       && state->language_version != 100
3876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       && state->language_version < 130) {
3877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(&loc, state,
3878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       "precision qualifiers exist only in "
3879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       "GLSL ES 1.00, and GLSL 1.30 and later");
3880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
3881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (this->precision != ast_precision_none
3883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       && this->structure != NULL) {
3884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(&loc, state,
3885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       "precision qualifiers do not apply to structures");
3886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
3887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* If this is a precision statement, check that the type to which it is
3890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * applied is either float or int.
3891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
3892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * From section 4.5.3 of the GLSL 1.30 spec:
3893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    "The precision statement
3894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *       precision precision-qualifier type;
3895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    can be used to establish a default precision qualifier. The type
3896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    field can be either int or float [...].  Any other types or
3897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *    qualifiers will result in an error.
3898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
3899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (this->is_precision_statement) {
3900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(this->precision != ast_precision_none);
3901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(this->structure == NULL); /* The check for structures was
3902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                        * performed above. */
3903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (this->is_array) {
3904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         _mesa_glsl_error(&loc, state,
3905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          "default precision statements do not apply to "
3906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          "arrays");
3907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return NULL;
3908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (strcmp(this->type_name, "float") != 0 &&
3910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  strcmp(this->type_name, "int") != 0) {
3911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         _mesa_glsl_error(&loc, state,
3912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          "default precision statements apply only to types "
3913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          "float and int");
3914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return NULL;
3915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* FINISHME: Translate precision statements into IR. */
3918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
3919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (this->structure != NULL)
3922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return this->structure->hir(instructions, state);
3923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return NULL;
3925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue *
3929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgast_struct_specifier::hir(exec_list *instructions,
3930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  struct _mesa_glsl_parse_state *state)
3931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned decl_count = 0;
3933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Make an initial pass over the list of structure fields to determine how
3935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * many there are.  Each element in this list is an ast_declarator_list.
3936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * This means that we actually need to count the number of elements in the
3937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * 'declarations' list in each of the elements.
3938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
3939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   foreach_list_typed (ast_declarator_list, decl_list, link,
3940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       &this->declarations) {
3941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      foreach_list_const (decl_ptr, & decl_list->declarations) {
3942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 decl_count++;
3943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Allocate storage for the structure fields and process the field
3947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * declarations.  As the declarations are processed, try to also convert
3948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * the types to HIR.  This ensures that structure definitions embedded in
3949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * other structure definitions are processed.
3950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
3951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   glsl_struct_field *const fields = ralloc_array(state, glsl_struct_field,
3952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						  decl_count);
3953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned i = 0;
3955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   foreach_list_typed (ast_declarator_list, decl_list, link,
3956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       &this->declarations) {
3957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const char *type_name;
3958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      decl_list->type->specifier->hir(instructions, state);
3960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Section 10.9 of the GLSL ES 1.00 specification states that
3962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * embedded structure definitions have been removed from the language.
3963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
3964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (state->es_shader && decl_list->type->specifier->structure != NULL) {
3965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 YYLTYPE loc = this->get_location();
3966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 _mesa_glsl_error(&loc, state, "Embedded structure definitions are "
3967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  "not allowed in GLSL ES 1.00.");
3968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const glsl_type *decl_type =
3971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 decl_list->type->specifier->glsl_type(& type_name, state);
3972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      foreach_list_typed (ast_declaration, decl, link,
3974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  &decl_list->declarations) {
3975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 const struct glsl_type *field_type = decl_type;
3976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (decl->is_array) {
3977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    YYLTYPE loc = decl->get_location();
3978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    field_type = process_array_type(&loc, decl_type, decl->array_size,
3979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					    state);
3980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
3981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 fields[i].type = (field_type != NULL)
3982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    ? field_type : glsl_type::error_type;
3983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 fields[i].name = decl->identifier;
3984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 i++;
3985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(i == decl_count);
3989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const glsl_type *t =
3991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      glsl_type::get_record_instance(fields, decl_count, this->name);
3992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   YYLTYPE loc = this->get_location();
3994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!state->symbols->add_type(name, t)) {
3995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(& loc, state, "struct `%s' previously defined", name);
3996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
3997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const glsl_type **s = reralloc(state, state->user_structures,
3998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				     const glsl_type *,
3999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				     state->num_user_structures + 1);
4000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (s != NULL) {
4001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 s[state->num_user_structures] = t;
4002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 state->user_structures = s;
4003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 state->num_user_structures++;
4004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
4005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
4006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Structure type definitions do not have r-values.
4008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
4009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return NULL;
4010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
4011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct gl_uniform_block *
4013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgget_next_uniform_block(struct _mesa_glsl_parse_state *state)
4014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
4015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (state->num_uniform_blocks >= state->uniform_block_array_size) {
4016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      state->uniform_block_array_size *= 2;
4017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (state->uniform_block_array_size <= 4)
4018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 state->uniform_block_array_size = 4;
4019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      state->uniform_blocks = reralloc(state,
4021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       state->uniform_blocks,
4022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       struct gl_uniform_block,
4023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       state->uniform_block_array_size);
4024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
4025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(&state->uniform_blocks[state->num_uniform_blocks],
4027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  0, sizeof(*state->uniform_blocks));
4028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return &state->uniform_blocks[state->num_uniform_blocks++];
4029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
4030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue *
4032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgast_uniform_block::hir(exec_list *instructions,
4033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       struct _mesa_glsl_parse_state *state)
4034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
4035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* The ast_uniform_block has a list of ast_declarator_lists.  We
4036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * need to turn those into ir_variables with an association
4037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * with this uniform block.
4038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
4039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct gl_uniform_block *ubo = get_next_uniform_block(state);
4040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ubo->Name = ralloc_strdup(state->uniform_blocks, this->block_name);
4041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!state->symbols->add_uniform_block(ubo)) {
4043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      YYLTYPE loc = this->get_location();
4044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(&loc, state, "Uniform block name `%s' already taken in "
4045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       "the current scope.\n", ubo->Name);
4046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
4047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned int num_variables = 0;
4049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   foreach_list_typed(ast_declarator_list, decl_list, link, &declarations) {
4050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      foreach_list_const(node, &decl_list->declarations) {
4051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 num_variables++;
4052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
4053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
4054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   bool block_row_major = this->layout.flags.q.row_major;
4056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ubo->Uniforms = rzalloc_array(state->uniform_blocks,
4058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				 struct gl_uniform_buffer_variable,
4059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				 num_variables);
4060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   foreach_list_typed(ast_declarator_list, decl_list, link, &declarations) {
4062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      exec_list declared_variables;
4063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      decl_list->hir(&declared_variables, state);
4065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      foreach_list_const(node, &declared_variables) {
4067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 struct ir_variable *var = (ir_variable *)node;
4068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 struct gl_uniform_buffer_variable *ubo_var =
4070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    &ubo->Uniforms[ubo->NumUniforms++];
4071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 var->uniform_block = ubo - state->uniform_blocks;
4073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ubo_var->Name = ralloc_strdup(state->uniform_blocks, var->name);
4075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ubo_var->Type = var->type;
4076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ubo_var->Buffer = ubo - state->uniform_blocks;
4077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ubo_var->Offset = 0; /* Assigned at link time. */
4078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (var->type->is_matrix() ||
4080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     (var->type->is_array() && var->type->fields.array->is_matrix())) {
4081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    ubo_var->RowMajor = block_row_major;
4082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    if (decl_list->type->qualifier.flags.q.row_major)
4083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       ubo_var->RowMajor = true;
4084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    else if (decl_list->type->qualifier.flags.q.column_major)
4085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       ubo_var->RowMajor = false;
4086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
4087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* From the GL_ARB_uniform_buffer_object spec:
4089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  *
4090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  *     "Sampler types are not allowed inside of uniform
4091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  *      blocks. All other types, arrays, and structures
4092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  *      allowed for uniforms are allowed within a uniform
4093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  *      block."
4094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  */
4095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (var->type->contains_sampler()) {
4096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    YYLTYPE loc = decl_list->get_location();
4097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    _mesa_glsl_error(&loc, state,
4098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     "Uniform in non-default uniform block contains sampler\n");
4099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
4100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
4101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      instructions->append_list(&declared_variables);
4103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
4104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return NULL;
4106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
4107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
4109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdetect_conflicting_assignments(struct _mesa_glsl_parse_state *state,
4110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			       exec_list *instructions)
4111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
4112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   bool gl_FragColor_assigned = false;
4113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   bool gl_FragData_assigned = false;
4114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   bool user_defined_fs_output_assigned = false;
4115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_variable *user_defined_fs_output = NULL;
4116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* It would be nice to have proper location information. */
4118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   YYLTYPE loc;
4119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(&loc, 0, sizeof(loc));
4120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   foreach_list(node, instructions) {
4122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_variable *var = ((ir_instruction *)node)->as_variable();
4123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!var || !var->assigned)
4125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 continue;
4126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (strcmp(var->name, "gl_FragColor") == 0)
4128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 gl_FragColor_assigned = true;
4129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else if (strcmp(var->name, "gl_FragData") == 0)
4130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 gl_FragData_assigned = true;
4131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else if (strncmp(var->name, "gl_", 3) != 0) {
4132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (state->target == fragment_shader &&
4133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     (var->mode == ir_var_out || var->mode == ir_var_inout)) {
4134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    user_defined_fs_output_assigned = true;
4135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    user_defined_fs_output = var;
4136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
4137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
4138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
4139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* From the GLSL 1.30 spec:
4141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
4142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *     "If a shader statically assigns a value to gl_FragColor, it
4143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *      may not assign a value to any element of gl_FragData. If a
4144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *      shader statically writes a value to any element of
4145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *      gl_FragData, it may not assign a value to
4146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *      gl_FragColor. That is, a shader may assign values to either
4147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *      gl_FragColor or gl_FragData, but not both. Multiple shaders
4148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *      linked together must also consistently write just one of
4149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *      these variables.  Similarly, if user declared output
4150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *      variables are in use (statically assigned to), then the
4151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *      built-in variables gl_FragColor and gl_FragData may not be
4152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *      assigned to. These incorrect usages all generate compile
4153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *      time errors."
4154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
4155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (gl_FragColor_assigned && gl_FragData_assigned) {
4156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(&loc, state, "fragment shader writes to both "
4157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       "`gl_FragColor' and `gl_FragData'\n");
4158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else if (gl_FragColor_assigned && user_defined_fs_output_assigned) {
4159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(&loc, state, "fragment shader writes to both "
4160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       "`gl_FragColor' and `%s'\n",
4161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       user_defined_fs_output->name);
4162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else if (gl_FragData_assigned && user_defined_fs_output_assigned) {
4163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_glsl_error(&loc, state, "fragment shader writes to both "
4164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       "`gl_FragData' and `%s'\n",
4165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       user_defined_fs_output->name);
4166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
4167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
4168