1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright © 2010 Intel Corporation
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
10bf215546Sopenharmony_ci *
11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next
12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
13bf215546Sopenharmony_ci * Software.
14bf215546Sopenharmony_ci *
15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21bf215546Sopenharmony_ci * DEALINGS IN THE SOFTWARE.
22bf215546Sopenharmony_ci */
23bf215546Sopenharmony_ci
24bf215546Sopenharmony_ci/**
25bf215546Sopenharmony_ci * \file ast_to_hir.c
26bf215546Sopenharmony_ci * Convert abstract syntax to to high-level intermediate reprensentation (HIR).
27bf215546Sopenharmony_ci *
28bf215546Sopenharmony_ci * During the conversion to HIR, the majority of the symantic checking is
29bf215546Sopenharmony_ci * preformed on the program.  This includes:
30bf215546Sopenharmony_ci *
31bf215546Sopenharmony_ci *    * Symbol table management
32bf215546Sopenharmony_ci *    * Type checking
33bf215546Sopenharmony_ci *    * Function binding
34bf215546Sopenharmony_ci *
35bf215546Sopenharmony_ci * The majority of this work could be done during parsing, and the parser could
36bf215546Sopenharmony_ci * probably generate HIR directly.  However, this results in frequent changes
37bf215546Sopenharmony_ci * to the parser code.  Since we do not assume that every system this complier
38bf215546Sopenharmony_ci * is built on will have Flex and Bison installed, we have to store the code
39bf215546Sopenharmony_ci * generated by these tools in our version control system.  In other parts of
40bf215546Sopenharmony_ci * the system we've seen problems where a parser was changed but the generated
41bf215546Sopenharmony_ci * code was not committed, merge conflicts where created because two developers
42bf215546Sopenharmony_ci * had slightly different versions of Bison installed, etc.
43bf215546Sopenharmony_ci *
44bf215546Sopenharmony_ci * I have also noticed that running Bison generated parsers in GDB is very
45bf215546Sopenharmony_ci * irritating.  When you get a segfault on '$$ = $1->foo', you can't very
46bf215546Sopenharmony_ci * well 'print $1' in GDB.
47bf215546Sopenharmony_ci *
48bf215546Sopenharmony_ci * As a result, my preference is to put as little C code as possible in the
49bf215546Sopenharmony_ci * parser (and lexer) sources.
50bf215546Sopenharmony_ci */
51bf215546Sopenharmony_ci
52bf215546Sopenharmony_ci#include "glsl_symbol_table.h"
53bf215546Sopenharmony_ci#include "glsl_parser_extras.h"
54bf215546Sopenharmony_ci#include "ast.h"
55bf215546Sopenharmony_ci#include "compiler/glsl_types.h"
56bf215546Sopenharmony_ci#include "util/hash_table.h"
57bf215546Sopenharmony_ci#include "main/consts_exts.h"
58bf215546Sopenharmony_ci#include "main/macros.h"
59bf215546Sopenharmony_ci#include "main/shaderobj.h"
60bf215546Sopenharmony_ci#include "ir.h"
61bf215546Sopenharmony_ci#include "ir_builder.h"
62bf215546Sopenharmony_ci#include "builtin_functions.h"
63bf215546Sopenharmony_ci
64bf215546Sopenharmony_ciusing namespace ir_builder;
65bf215546Sopenharmony_ci
66bf215546Sopenharmony_cistatic void
67bf215546Sopenharmony_cidetect_conflicting_assignments(struct _mesa_glsl_parse_state *state,
68bf215546Sopenharmony_ci                               exec_list *instructions);
69bf215546Sopenharmony_cistatic void
70bf215546Sopenharmony_civerify_subroutine_associated_funcs(struct _mesa_glsl_parse_state *state);
71bf215546Sopenharmony_ci
72bf215546Sopenharmony_cistatic void
73bf215546Sopenharmony_ciremove_per_vertex_blocks(exec_list *instructions,
74bf215546Sopenharmony_ci                         _mesa_glsl_parse_state *state, ir_variable_mode mode);
75bf215546Sopenharmony_ci
76bf215546Sopenharmony_ci/**
77bf215546Sopenharmony_ci * Visitor class that finds the first instance of any write-only variable that
78bf215546Sopenharmony_ci * is ever read, if any
79bf215546Sopenharmony_ci */
80bf215546Sopenharmony_ciclass read_from_write_only_variable_visitor : public ir_hierarchical_visitor
81bf215546Sopenharmony_ci{
82bf215546Sopenharmony_cipublic:
83bf215546Sopenharmony_ci   read_from_write_only_variable_visitor() : found(NULL)
84bf215546Sopenharmony_ci   {
85bf215546Sopenharmony_ci   }
86bf215546Sopenharmony_ci
87bf215546Sopenharmony_ci   virtual ir_visitor_status visit(ir_dereference_variable *ir)
88bf215546Sopenharmony_ci   {
89bf215546Sopenharmony_ci      if (this->in_assignee)
90bf215546Sopenharmony_ci         return visit_continue;
91bf215546Sopenharmony_ci
92bf215546Sopenharmony_ci      ir_variable *var = ir->variable_referenced();
93bf215546Sopenharmony_ci      /* We can have memory_write_only set on both images and buffer variables,
94bf215546Sopenharmony_ci       * but in the former there is a distinction between reads from
95bf215546Sopenharmony_ci       * the variable itself (write_only) and from the memory they point to
96bf215546Sopenharmony_ci       * (memory_write_only), while in the case of buffer variables there is
97bf215546Sopenharmony_ci       * no such distinction, that is why this check here is limited to
98bf215546Sopenharmony_ci       * buffer variables alone.
99bf215546Sopenharmony_ci       */
100bf215546Sopenharmony_ci      if (!var || var->data.mode != ir_var_shader_storage)
101bf215546Sopenharmony_ci         return visit_continue;
102bf215546Sopenharmony_ci
103bf215546Sopenharmony_ci      if (var->data.memory_write_only) {
104bf215546Sopenharmony_ci         found = var;
105bf215546Sopenharmony_ci         return visit_stop;
106bf215546Sopenharmony_ci      }
107bf215546Sopenharmony_ci
108bf215546Sopenharmony_ci      return visit_continue;
109bf215546Sopenharmony_ci   }
110bf215546Sopenharmony_ci
111bf215546Sopenharmony_ci   ir_variable *get_variable() {
112bf215546Sopenharmony_ci      return found;
113bf215546Sopenharmony_ci   }
114bf215546Sopenharmony_ci
115bf215546Sopenharmony_ci   virtual ir_visitor_status visit_enter(ir_expression *ir)
116bf215546Sopenharmony_ci   {
117bf215546Sopenharmony_ci      /* .length() doesn't actually read anything */
118bf215546Sopenharmony_ci      if (ir->operation == ir_unop_ssbo_unsized_array_length)
119bf215546Sopenharmony_ci         return visit_continue_with_parent;
120bf215546Sopenharmony_ci
121bf215546Sopenharmony_ci      return visit_continue;
122bf215546Sopenharmony_ci   }
123bf215546Sopenharmony_ci
124bf215546Sopenharmony_ciprivate:
125bf215546Sopenharmony_ci   ir_variable *found;
126bf215546Sopenharmony_ci};
127bf215546Sopenharmony_ci
128bf215546Sopenharmony_civoid
129bf215546Sopenharmony_ci_mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state)
130bf215546Sopenharmony_ci{
131bf215546Sopenharmony_ci   _mesa_glsl_initialize_variables(instructions, state);
132bf215546Sopenharmony_ci
133bf215546Sopenharmony_ci   state->symbols->separate_function_namespace = state->language_version == 110;
134bf215546Sopenharmony_ci
135bf215546Sopenharmony_ci   state->current_function = NULL;
136bf215546Sopenharmony_ci
137bf215546Sopenharmony_ci   state->toplevel_ir = instructions;
138bf215546Sopenharmony_ci
139bf215546Sopenharmony_ci   state->gs_input_prim_type_specified = false;
140bf215546Sopenharmony_ci   state->tcs_output_vertices_specified = false;
141bf215546Sopenharmony_ci   state->cs_input_local_size_specified = false;
142bf215546Sopenharmony_ci
143bf215546Sopenharmony_ci   /* Section 4.2 of the GLSL 1.20 specification states:
144bf215546Sopenharmony_ci    * "The built-in functions are scoped in a scope outside the global scope
145bf215546Sopenharmony_ci    *  users declare global variables in.  That is, a shader's global scope,
146bf215546Sopenharmony_ci    *  available for user-defined functions and global variables, is nested
147bf215546Sopenharmony_ci    *  inside the scope containing the built-in functions."
148bf215546Sopenharmony_ci    *
149bf215546Sopenharmony_ci    * Since built-in functions like ftransform() access built-in variables,
150bf215546Sopenharmony_ci    * it follows that those must be in the outer scope as well.
151bf215546Sopenharmony_ci    *
152bf215546Sopenharmony_ci    * We push scope here to create this nesting effect...but don't pop.
153bf215546Sopenharmony_ci    * This way, a shader's globals are still in the symbol table for use
154bf215546Sopenharmony_ci    * by the linker.
155bf215546Sopenharmony_ci    */
156bf215546Sopenharmony_ci   state->symbols->push_scope();
157bf215546Sopenharmony_ci
158bf215546Sopenharmony_ci   foreach_list_typed (ast_node, ast, link, & state->translation_unit)
159bf215546Sopenharmony_ci      ast->hir(instructions, state);
160bf215546Sopenharmony_ci
161bf215546Sopenharmony_ci   verify_subroutine_associated_funcs(state);
162bf215546Sopenharmony_ci   detect_recursion_unlinked(state, instructions);
163bf215546Sopenharmony_ci   detect_conflicting_assignments(state, instructions);
164bf215546Sopenharmony_ci
165bf215546Sopenharmony_ci   state->toplevel_ir = NULL;
166bf215546Sopenharmony_ci
167bf215546Sopenharmony_ci   /* Move all of the variable declarations to the front of the IR list, and
168bf215546Sopenharmony_ci    * reverse the order.  This has the (intended!) side effect that vertex
169bf215546Sopenharmony_ci    * shader inputs and fragment shader outputs will appear in the IR in the
170bf215546Sopenharmony_ci    * same order that they appeared in the shader code.  This results in the
171bf215546Sopenharmony_ci    * locations being assigned in the declared order.  Many (arguably buggy)
172bf215546Sopenharmony_ci    * applications depend on this behavior, and it matches what nearly all
173bf215546Sopenharmony_ci    * other drivers do.
174bf215546Sopenharmony_ci    */
175bf215546Sopenharmony_ci   foreach_in_list_safe(ir_instruction, node, instructions) {
176bf215546Sopenharmony_ci      ir_variable *const var = node->as_variable();
177bf215546Sopenharmony_ci
178bf215546Sopenharmony_ci      if (var == NULL)
179bf215546Sopenharmony_ci         continue;
180bf215546Sopenharmony_ci
181bf215546Sopenharmony_ci      var->remove();
182bf215546Sopenharmony_ci      instructions->push_head(var);
183bf215546Sopenharmony_ci   }
184bf215546Sopenharmony_ci
185bf215546Sopenharmony_ci   /* Figure out if gl_FragCoord is actually used in fragment shader */
186bf215546Sopenharmony_ci   ir_variable *const var = state->symbols->get_variable("gl_FragCoord");
187bf215546Sopenharmony_ci   if (var != NULL)
188bf215546Sopenharmony_ci      state->fs_uses_gl_fragcoord = var->data.used;
189bf215546Sopenharmony_ci
190bf215546Sopenharmony_ci   /* From section 7.1 (Built-In Language Variables) of the GLSL 4.10 spec:
191bf215546Sopenharmony_ci    *
192bf215546Sopenharmony_ci    *     If multiple shaders using members of a built-in block belonging to
193bf215546Sopenharmony_ci    *     the same interface are linked together in the same program, they
194bf215546Sopenharmony_ci    *     must all redeclare the built-in block in the same way, as described
195bf215546Sopenharmony_ci    *     in section 4.3.7 "Interface Blocks" for interface block matching, or
196bf215546Sopenharmony_ci    *     a link error will result.
197bf215546Sopenharmony_ci    *
198bf215546Sopenharmony_ci    * The phrase "using members of a built-in block" implies that if two
199bf215546Sopenharmony_ci    * shaders are linked together and one of them *does not use* any members
200bf215546Sopenharmony_ci    * of the built-in block, then that shader does not need to have a matching
201bf215546Sopenharmony_ci    * redeclaration of the built-in block.
202bf215546Sopenharmony_ci    *
203bf215546Sopenharmony_ci    * This appears to be a clarification to the behaviour established for
204bf215546Sopenharmony_ci    * gl_PerVertex by GLSL 1.50, therefore implement it regardless of GLSL
205bf215546Sopenharmony_ci    * version.
206bf215546Sopenharmony_ci    *
207bf215546Sopenharmony_ci    * The definition of "interface" in section 4.3.7 that applies here is as
208bf215546Sopenharmony_ci    * follows:
209bf215546Sopenharmony_ci    *
210bf215546Sopenharmony_ci    *     The boundary between adjacent programmable pipeline stages: This
211bf215546Sopenharmony_ci    *     spans all the outputs in all compilation units of the first stage
212bf215546Sopenharmony_ci    *     and all the inputs in all compilation units of the second stage.
213bf215546Sopenharmony_ci    *
214bf215546Sopenharmony_ci    * Therefore this rule applies to both inter- and intra-stage linking.
215bf215546Sopenharmony_ci    *
216bf215546Sopenharmony_ci    * The easiest way to implement this is to check whether the shader uses
217bf215546Sopenharmony_ci    * gl_PerVertex right after ast-to-ir conversion, and if it doesn't, simply
218bf215546Sopenharmony_ci    * remove all the relevant variable declaration from the IR, so that the
219bf215546Sopenharmony_ci    * linker won't see them and complain about mismatches.
220bf215546Sopenharmony_ci    */
221bf215546Sopenharmony_ci   remove_per_vertex_blocks(instructions, state, ir_var_shader_in);
222bf215546Sopenharmony_ci   remove_per_vertex_blocks(instructions, state, ir_var_shader_out);
223bf215546Sopenharmony_ci
224bf215546Sopenharmony_ci   /* Check that we don't have reads from write-only variables */
225bf215546Sopenharmony_ci   read_from_write_only_variable_visitor v;
226bf215546Sopenharmony_ci   v.run(instructions);
227bf215546Sopenharmony_ci   ir_variable *error_var = v.get_variable();
228bf215546Sopenharmony_ci   if (error_var) {
229bf215546Sopenharmony_ci      /* It would be nice to have proper location information, but for that
230bf215546Sopenharmony_ci       * we would need to check this as we process each kind of AST node
231bf215546Sopenharmony_ci       */
232bf215546Sopenharmony_ci      YYLTYPE loc;
233bf215546Sopenharmony_ci      memset(&loc, 0, sizeof(loc));
234bf215546Sopenharmony_ci      _mesa_glsl_error(&loc, state, "Read from write-only variable `%s'",
235bf215546Sopenharmony_ci                       error_var->name);
236bf215546Sopenharmony_ci   }
237bf215546Sopenharmony_ci}
238bf215546Sopenharmony_ci
239bf215546Sopenharmony_ci
240bf215546Sopenharmony_cistatic ir_expression_operation
241bf215546Sopenharmony_ciget_implicit_conversion_operation(const glsl_type *to, const glsl_type *from,
242bf215546Sopenharmony_ci                                  struct _mesa_glsl_parse_state *state)
243bf215546Sopenharmony_ci{
244bf215546Sopenharmony_ci   switch (to->base_type) {
245bf215546Sopenharmony_ci   case GLSL_TYPE_FLOAT:
246bf215546Sopenharmony_ci      switch (from->base_type) {
247bf215546Sopenharmony_ci      case GLSL_TYPE_INT: return ir_unop_i2f;
248bf215546Sopenharmony_ci      case GLSL_TYPE_UINT: return ir_unop_u2f;
249bf215546Sopenharmony_ci      default: return (ir_expression_operation)0;
250bf215546Sopenharmony_ci      }
251bf215546Sopenharmony_ci
252bf215546Sopenharmony_ci   case GLSL_TYPE_UINT:
253bf215546Sopenharmony_ci      if (!state->has_implicit_int_to_uint_conversion())
254bf215546Sopenharmony_ci         return (ir_expression_operation)0;
255bf215546Sopenharmony_ci      switch (from->base_type) {
256bf215546Sopenharmony_ci         case GLSL_TYPE_INT: return ir_unop_i2u;
257bf215546Sopenharmony_ci         default: return (ir_expression_operation)0;
258bf215546Sopenharmony_ci      }
259bf215546Sopenharmony_ci
260bf215546Sopenharmony_ci   case GLSL_TYPE_DOUBLE:
261bf215546Sopenharmony_ci      if (!state->has_double())
262bf215546Sopenharmony_ci         return (ir_expression_operation)0;
263bf215546Sopenharmony_ci      switch (from->base_type) {
264bf215546Sopenharmony_ci      case GLSL_TYPE_INT: return ir_unop_i2d;
265bf215546Sopenharmony_ci      case GLSL_TYPE_UINT: return ir_unop_u2d;
266bf215546Sopenharmony_ci      case GLSL_TYPE_FLOAT: return ir_unop_f2d;
267bf215546Sopenharmony_ci      case GLSL_TYPE_INT64: return ir_unop_i642d;
268bf215546Sopenharmony_ci      case GLSL_TYPE_UINT64: return ir_unop_u642d;
269bf215546Sopenharmony_ci      default: return (ir_expression_operation)0;
270bf215546Sopenharmony_ci      }
271bf215546Sopenharmony_ci
272bf215546Sopenharmony_ci   case GLSL_TYPE_UINT64:
273bf215546Sopenharmony_ci      if (!state->has_int64())
274bf215546Sopenharmony_ci         return (ir_expression_operation)0;
275bf215546Sopenharmony_ci      switch (from->base_type) {
276bf215546Sopenharmony_ci      case GLSL_TYPE_INT: return ir_unop_i2u64;
277bf215546Sopenharmony_ci      case GLSL_TYPE_UINT: return ir_unop_u2u64;
278bf215546Sopenharmony_ci      case GLSL_TYPE_INT64: return ir_unop_i642u64;
279bf215546Sopenharmony_ci      default: return (ir_expression_operation)0;
280bf215546Sopenharmony_ci      }
281bf215546Sopenharmony_ci
282bf215546Sopenharmony_ci   case GLSL_TYPE_INT64:
283bf215546Sopenharmony_ci      if (!state->has_int64())
284bf215546Sopenharmony_ci         return (ir_expression_operation)0;
285bf215546Sopenharmony_ci      switch (from->base_type) {
286bf215546Sopenharmony_ci      case GLSL_TYPE_INT: return ir_unop_i2i64;
287bf215546Sopenharmony_ci      default: return (ir_expression_operation)0;
288bf215546Sopenharmony_ci      }
289bf215546Sopenharmony_ci
290bf215546Sopenharmony_ci   default: return (ir_expression_operation)0;
291bf215546Sopenharmony_ci   }
292bf215546Sopenharmony_ci}
293bf215546Sopenharmony_ci
294bf215546Sopenharmony_ci
295bf215546Sopenharmony_ci/**
296bf215546Sopenharmony_ci * If a conversion is available, convert one operand to a different type
297bf215546Sopenharmony_ci *
298bf215546Sopenharmony_ci * The \c from \c ir_rvalue is converted "in place".
299bf215546Sopenharmony_ci *
300bf215546Sopenharmony_ci * \param to     Type that the operand it to be converted to
301bf215546Sopenharmony_ci * \param from   Operand that is being converted
302bf215546Sopenharmony_ci * \param state  GLSL compiler state
303bf215546Sopenharmony_ci *
304bf215546Sopenharmony_ci * \return
305bf215546Sopenharmony_ci * If a conversion is possible (or unnecessary), \c true is returned.
306bf215546Sopenharmony_ci * Otherwise \c false is returned.
307bf215546Sopenharmony_ci */
308bf215546Sopenharmony_cistatic bool
309bf215546Sopenharmony_ciapply_implicit_conversion(const glsl_type *to, ir_rvalue * &from,
310bf215546Sopenharmony_ci                          struct _mesa_glsl_parse_state *state)
311bf215546Sopenharmony_ci{
312bf215546Sopenharmony_ci   void *ctx = state;
313bf215546Sopenharmony_ci   if (to->base_type == from->type->base_type)
314bf215546Sopenharmony_ci      return true;
315bf215546Sopenharmony_ci
316bf215546Sopenharmony_ci   /* Prior to GLSL 1.20, there are no implicit conversions */
317bf215546Sopenharmony_ci   if (!state->has_implicit_conversions())
318bf215546Sopenharmony_ci      return false;
319bf215546Sopenharmony_ci
320bf215546Sopenharmony_ci   /* From page 27 (page 33 of the PDF) of the GLSL 1.50 spec:
321bf215546Sopenharmony_ci    *
322bf215546Sopenharmony_ci    *    "There are no implicit array or structure conversions. For
323bf215546Sopenharmony_ci    *    example, an array of int cannot be implicitly converted to an
324bf215546Sopenharmony_ci    *    array of float.
325bf215546Sopenharmony_ci    */
326bf215546Sopenharmony_ci   if (!to->is_numeric() || !from->type->is_numeric())
327bf215546Sopenharmony_ci      return false;
328bf215546Sopenharmony_ci
329bf215546Sopenharmony_ci   /* We don't actually want the specific type `to`, we want a type
330bf215546Sopenharmony_ci    * with the same base type as `to`, but the same vector width as
331bf215546Sopenharmony_ci    * `from`.
332bf215546Sopenharmony_ci    */
333bf215546Sopenharmony_ci   to = glsl_type::get_instance(to->base_type, from->type->vector_elements,
334bf215546Sopenharmony_ci                                from->type->matrix_columns);
335bf215546Sopenharmony_ci
336bf215546Sopenharmony_ci   ir_expression_operation op = get_implicit_conversion_operation(to, from->type, state);
337bf215546Sopenharmony_ci   if (op) {
338bf215546Sopenharmony_ci      from = new(ctx) ir_expression(op, to, from, NULL);
339bf215546Sopenharmony_ci      return true;
340bf215546Sopenharmony_ci   } else {
341bf215546Sopenharmony_ci      return false;
342bf215546Sopenharmony_ci   }
343bf215546Sopenharmony_ci}
344bf215546Sopenharmony_ci
345bf215546Sopenharmony_ci
346bf215546Sopenharmony_cistatic const struct glsl_type *
347bf215546Sopenharmony_ciarithmetic_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b,
348bf215546Sopenharmony_ci                       bool multiply,
349bf215546Sopenharmony_ci                       struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
350bf215546Sopenharmony_ci{
351bf215546Sopenharmony_ci   const glsl_type *type_a = value_a->type;
352bf215546Sopenharmony_ci   const glsl_type *type_b = value_b->type;
353bf215546Sopenharmony_ci
354bf215546Sopenharmony_ci   /* From GLSL 1.50 spec, page 56:
355bf215546Sopenharmony_ci    *
356bf215546Sopenharmony_ci    *    "The arithmetic binary operators add (+), subtract (-),
357bf215546Sopenharmony_ci    *    multiply (*), and divide (/) operate on integer and
358bf215546Sopenharmony_ci    *    floating-point scalars, vectors, and matrices."
359bf215546Sopenharmony_ci    */
360bf215546Sopenharmony_ci   if (!type_a->is_numeric() || !type_b->is_numeric()) {
361bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state,
362bf215546Sopenharmony_ci                       "operands to arithmetic operators must be numeric");
363bf215546Sopenharmony_ci      return glsl_type::error_type;
364bf215546Sopenharmony_ci   }
365bf215546Sopenharmony_ci
366bf215546Sopenharmony_ci
367bf215546Sopenharmony_ci   /*    "If one operand is floating-point based and the other is
368bf215546Sopenharmony_ci    *    not, then the conversions from Section 4.1.10 "Implicit
369bf215546Sopenharmony_ci    *    Conversions" are applied to the non-floating-point-based operand."
370bf215546Sopenharmony_ci    */
371bf215546Sopenharmony_ci   if (!apply_implicit_conversion(type_a, value_b, state)
372bf215546Sopenharmony_ci       && !apply_implicit_conversion(type_b, value_a, state)) {
373bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state,
374bf215546Sopenharmony_ci                       "could not implicitly convert operands to "
375bf215546Sopenharmony_ci                       "arithmetic operator");
376bf215546Sopenharmony_ci      return glsl_type::error_type;
377bf215546Sopenharmony_ci   }
378bf215546Sopenharmony_ci   type_a = value_a->type;
379bf215546Sopenharmony_ci   type_b = value_b->type;
380bf215546Sopenharmony_ci
381bf215546Sopenharmony_ci   /*    "If the operands are integer types, they must both be signed or
382bf215546Sopenharmony_ci    *    both be unsigned."
383bf215546Sopenharmony_ci    *
384bf215546Sopenharmony_ci    * From this rule and the preceeding conversion it can be inferred that
385bf215546Sopenharmony_ci    * both types must be GLSL_TYPE_FLOAT, or GLSL_TYPE_UINT, or GLSL_TYPE_INT.
386bf215546Sopenharmony_ci    * The is_numeric check above already filtered out the case where either
387bf215546Sopenharmony_ci    * type is not one of these, so now the base types need only be tested for
388bf215546Sopenharmony_ci    * equality.
389bf215546Sopenharmony_ci    */
390bf215546Sopenharmony_ci   if (type_a->base_type != type_b->base_type) {
391bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state,
392bf215546Sopenharmony_ci                       "base type mismatch for arithmetic operator");
393bf215546Sopenharmony_ci      return glsl_type::error_type;
394bf215546Sopenharmony_ci   }
395bf215546Sopenharmony_ci
396bf215546Sopenharmony_ci   /*    "All arithmetic binary operators result in the same fundamental type
397bf215546Sopenharmony_ci    *    (signed integer, unsigned integer, or floating-point) as the
398bf215546Sopenharmony_ci    *    operands they operate on, after operand type conversion. After
399bf215546Sopenharmony_ci    *    conversion, the following cases are valid
400bf215546Sopenharmony_ci    *
401bf215546Sopenharmony_ci    *    * The two operands are scalars. In this case the operation is
402bf215546Sopenharmony_ci    *      applied, resulting in a scalar."
403bf215546Sopenharmony_ci    */
404bf215546Sopenharmony_ci   if (type_a->is_scalar() && type_b->is_scalar())
405bf215546Sopenharmony_ci      return type_a;
406bf215546Sopenharmony_ci
407bf215546Sopenharmony_ci   /*   "* One operand is a scalar, and the other is a vector or matrix.
408bf215546Sopenharmony_ci    *      In this case, the scalar operation is applied independently to each
409bf215546Sopenharmony_ci    *      component of the vector or matrix, resulting in the same size
410bf215546Sopenharmony_ci    *      vector or matrix."
411bf215546Sopenharmony_ci    */
412bf215546Sopenharmony_ci   if (type_a->is_scalar()) {
413bf215546Sopenharmony_ci      if (!type_b->is_scalar())
414bf215546Sopenharmony_ci         return type_b;
415bf215546Sopenharmony_ci   } else if (type_b->is_scalar()) {
416bf215546Sopenharmony_ci      return type_a;
417bf215546Sopenharmony_ci   }
418bf215546Sopenharmony_ci
419bf215546Sopenharmony_ci   /* All of the combinations of <scalar, scalar>, <vector, scalar>,
420bf215546Sopenharmony_ci    * <scalar, vector>, <scalar, matrix>, and <matrix, scalar> have been
421bf215546Sopenharmony_ci    * handled.
422bf215546Sopenharmony_ci    */
423bf215546Sopenharmony_ci   assert(!type_a->is_scalar());
424bf215546Sopenharmony_ci   assert(!type_b->is_scalar());
425bf215546Sopenharmony_ci
426bf215546Sopenharmony_ci   /*   "* The two operands are vectors of the same size. In this case, the
427bf215546Sopenharmony_ci    *      operation is done component-wise resulting in the same size
428bf215546Sopenharmony_ci    *      vector."
429bf215546Sopenharmony_ci    */
430bf215546Sopenharmony_ci   if (type_a->is_vector() && type_b->is_vector()) {
431bf215546Sopenharmony_ci      if (type_a == type_b) {
432bf215546Sopenharmony_ci         return type_a;
433bf215546Sopenharmony_ci      } else {
434bf215546Sopenharmony_ci         _mesa_glsl_error(loc, state,
435bf215546Sopenharmony_ci                          "vector size mismatch for arithmetic operator");
436bf215546Sopenharmony_ci         return glsl_type::error_type;
437bf215546Sopenharmony_ci      }
438bf215546Sopenharmony_ci   }
439bf215546Sopenharmony_ci
440bf215546Sopenharmony_ci   /* All of the combinations of <scalar, scalar>, <vector, scalar>,
441bf215546Sopenharmony_ci    * <scalar, vector>, <scalar, matrix>, <matrix, scalar>, and
442bf215546Sopenharmony_ci    * <vector, vector> have been handled.  At least one of the operands must
443bf215546Sopenharmony_ci    * be matrix.  Further, since there are no integer matrix types, the base
444bf215546Sopenharmony_ci    * type of both operands must be float.
445bf215546Sopenharmony_ci    */
446bf215546Sopenharmony_ci   assert(type_a->is_matrix() || type_b->is_matrix());
447bf215546Sopenharmony_ci   assert(type_a->is_float() || type_a->is_double());
448bf215546Sopenharmony_ci   assert(type_b->is_float() || type_b->is_double());
449bf215546Sopenharmony_ci
450bf215546Sopenharmony_ci   /*   "* The operator is add (+), subtract (-), or divide (/), and the
451bf215546Sopenharmony_ci    *      operands are matrices with the same number of rows and the same
452bf215546Sopenharmony_ci    *      number of columns. In this case, the operation is done component-
453bf215546Sopenharmony_ci    *      wise resulting in the same size matrix."
454bf215546Sopenharmony_ci    *    * The operator is multiply (*), where both operands are matrices or
455bf215546Sopenharmony_ci    *      one operand is a vector and the other a matrix. A right vector
456bf215546Sopenharmony_ci    *      operand is treated as a column vector and a left vector operand as a
457bf215546Sopenharmony_ci    *      row vector. In all these cases, it is required that the number of
458bf215546Sopenharmony_ci    *      columns of the left operand is equal to the number of rows of the
459bf215546Sopenharmony_ci    *      right operand. Then, the multiply (*) operation does a linear
460bf215546Sopenharmony_ci    *      algebraic multiply, yielding an object that has the same number of
461bf215546Sopenharmony_ci    *      rows as the left operand and the same number of columns as the right
462bf215546Sopenharmony_ci    *      operand. Section 5.10 "Vector and Matrix Operations" explains in
463bf215546Sopenharmony_ci    *      more detail how vectors and matrices are operated on."
464bf215546Sopenharmony_ci    */
465bf215546Sopenharmony_ci   if (! multiply) {
466bf215546Sopenharmony_ci      if (type_a == type_b)
467bf215546Sopenharmony_ci         return type_a;
468bf215546Sopenharmony_ci   } else {
469bf215546Sopenharmony_ci      const glsl_type *type = glsl_type::get_mul_type(type_a, type_b);
470bf215546Sopenharmony_ci
471bf215546Sopenharmony_ci      if (type == glsl_type::error_type) {
472bf215546Sopenharmony_ci         _mesa_glsl_error(loc, state,
473bf215546Sopenharmony_ci                          "size mismatch for matrix multiplication");
474bf215546Sopenharmony_ci      }
475bf215546Sopenharmony_ci
476bf215546Sopenharmony_ci      return type;
477bf215546Sopenharmony_ci   }
478bf215546Sopenharmony_ci
479bf215546Sopenharmony_ci
480bf215546Sopenharmony_ci   /*    "All other cases are illegal."
481bf215546Sopenharmony_ci    */
482bf215546Sopenharmony_ci   _mesa_glsl_error(loc, state, "type mismatch");
483bf215546Sopenharmony_ci   return glsl_type::error_type;
484bf215546Sopenharmony_ci}
485bf215546Sopenharmony_ci
486bf215546Sopenharmony_ci
487bf215546Sopenharmony_cistatic const struct glsl_type *
488bf215546Sopenharmony_ciunary_arithmetic_result_type(const struct glsl_type *type,
489bf215546Sopenharmony_ci                             struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
490bf215546Sopenharmony_ci{
491bf215546Sopenharmony_ci   /* From GLSL 1.50 spec, page 57:
492bf215546Sopenharmony_ci    *
493bf215546Sopenharmony_ci    *    "The arithmetic unary operators negate (-), post- and pre-increment
494bf215546Sopenharmony_ci    *     and decrement (-- and ++) operate on integer or floating-point
495bf215546Sopenharmony_ci    *     values (including vectors and matrices). All unary operators work
496bf215546Sopenharmony_ci    *     component-wise on their operands. These result with the same type
497bf215546Sopenharmony_ci    *     they operated on."
498bf215546Sopenharmony_ci    */
499bf215546Sopenharmony_ci   if (!type->is_numeric()) {
500bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state,
501bf215546Sopenharmony_ci                       "operands to arithmetic operators must be numeric");
502bf215546Sopenharmony_ci      return glsl_type::error_type;
503bf215546Sopenharmony_ci   }
504bf215546Sopenharmony_ci
505bf215546Sopenharmony_ci   return type;
506bf215546Sopenharmony_ci}
507bf215546Sopenharmony_ci
508bf215546Sopenharmony_ci/**
509bf215546Sopenharmony_ci * \brief Return the result type of a bit-logic operation.
510bf215546Sopenharmony_ci *
511bf215546Sopenharmony_ci * If the given types to the bit-logic operator are invalid, return
512bf215546Sopenharmony_ci * glsl_type::error_type.
513bf215546Sopenharmony_ci *
514bf215546Sopenharmony_ci * \param value_a LHS of bit-logic op
515bf215546Sopenharmony_ci * \param value_b RHS of bit-logic op
516bf215546Sopenharmony_ci */
517bf215546Sopenharmony_cistatic const struct glsl_type *
518bf215546Sopenharmony_cibit_logic_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b,
519bf215546Sopenharmony_ci                      ast_operators op,
520bf215546Sopenharmony_ci                      struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
521bf215546Sopenharmony_ci{
522bf215546Sopenharmony_ci   const glsl_type *type_a = value_a->type;
523bf215546Sopenharmony_ci   const glsl_type *type_b = value_b->type;
524bf215546Sopenharmony_ci
525bf215546Sopenharmony_ci   if (!state->check_bitwise_operations_allowed(loc)) {
526bf215546Sopenharmony_ci      return glsl_type::error_type;
527bf215546Sopenharmony_ci   }
528bf215546Sopenharmony_ci
529bf215546Sopenharmony_ci   /* From page 50 (page 56 of PDF) of GLSL 1.30 spec:
530bf215546Sopenharmony_ci    *
531bf215546Sopenharmony_ci    *     "The bitwise operators and (&), exclusive-or (^), and inclusive-or
532bf215546Sopenharmony_ci    *     (|). The operands must be of type signed or unsigned integers or
533bf215546Sopenharmony_ci    *     integer vectors."
534bf215546Sopenharmony_ci    */
535bf215546Sopenharmony_ci   if (!type_a->is_integer_32_64()) {
536bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state, "LHS of `%s' must be an integer",
537bf215546Sopenharmony_ci                        ast_expression::operator_string(op));
538bf215546Sopenharmony_ci      return glsl_type::error_type;
539bf215546Sopenharmony_ci   }
540bf215546Sopenharmony_ci   if (!type_b->is_integer_32_64()) {
541bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state, "RHS of `%s' must be an integer",
542bf215546Sopenharmony_ci                       ast_expression::operator_string(op));
543bf215546Sopenharmony_ci      return glsl_type::error_type;
544bf215546Sopenharmony_ci   }
545bf215546Sopenharmony_ci
546bf215546Sopenharmony_ci   /* Prior to GLSL 4.0 / GL_ARB_gpu_shader5, implicit conversions didn't
547bf215546Sopenharmony_ci    * make sense for bitwise operations, as they don't operate on floats.
548bf215546Sopenharmony_ci    *
549bf215546Sopenharmony_ci    * GLSL 4.0 added implicit int -> uint conversions, which are relevant
550bf215546Sopenharmony_ci    * here.  It wasn't clear whether or not we should apply them to bitwise
551bf215546Sopenharmony_ci    * operations.  However, Khronos has decided that they should in future
552bf215546Sopenharmony_ci    * language revisions.  Applications also rely on this behavior.  We opt
553bf215546Sopenharmony_ci    * to apply them in general, but issue a portability warning.
554bf215546Sopenharmony_ci    *
555bf215546Sopenharmony_ci    * See https://www.khronos.org/bugzilla/show_bug.cgi?id=1405
556bf215546Sopenharmony_ci    */
557bf215546Sopenharmony_ci   if (type_a->base_type != type_b->base_type) {
558bf215546Sopenharmony_ci      if (!apply_implicit_conversion(type_a, value_b, state)
559bf215546Sopenharmony_ci          && !apply_implicit_conversion(type_b, value_a, state)) {
560bf215546Sopenharmony_ci         _mesa_glsl_error(loc, state,
561bf215546Sopenharmony_ci                          "could not implicitly convert operands to "
562bf215546Sopenharmony_ci                          "`%s` operator",
563bf215546Sopenharmony_ci                          ast_expression::operator_string(op));
564bf215546Sopenharmony_ci         return glsl_type::error_type;
565bf215546Sopenharmony_ci      } else {
566bf215546Sopenharmony_ci         _mesa_glsl_warning(loc, state,
567bf215546Sopenharmony_ci                            "some implementations may not support implicit "
568bf215546Sopenharmony_ci                            "int -> uint conversions for `%s' operators; "
569bf215546Sopenharmony_ci                            "consider casting explicitly for portability",
570bf215546Sopenharmony_ci                            ast_expression::operator_string(op));
571bf215546Sopenharmony_ci      }
572bf215546Sopenharmony_ci      type_a = value_a->type;
573bf215546Sopenharmony_ci      type_b = value_b->type;
574bf215546Sopenharmony_ci   }
575bf215546Sopenharmony_ci
576bf215546Sopenharmony_ci   /*     "The fundamental types of the operands (signed or unsigned) must
577bf215546Sopenharmony_ci    *     match,"
578bf215546Sopenharmony_ci    */
579bf215546Sopenharmony_ci   if (type_a->base_type != type_b->base_type) {
580bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state, "operands of `%s' must have the same "
581bf215546Sopenharmony_ci                       "base type", ast_expression::operator_string(op));
582bf215546Sopenharmony_ci      return glsl_type::error_type;
583bf215546Sopenharmony_ci   }
584bf215546Sopenharmony_ci
585bf215546Sopenharmony_ci   /*     "The operands cannot be vectors of differing size." */
586bf215546Sopenharmony_ci   if (type_a->is_vector() &&
587bf215546Sopenharmony_ci       type_b->is_vector() &&
588bf215546Sopenharmony_ci       type_a->vector_elements != type_b->vector_elements) {
589bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state, "operands of `%s' cannot be vectors of "
590bf215546Sopenharmony_ci                       "different sizes", ast_expression::operator_string(op));
591bf215546Sopenharmony_ci      return glsl_type::error_type;
592bf215546Sopenharmony_ci   }
593bf215546Sopenharmony_ci
594bf215546Sopenharmony_ci   /*     "If one operand is a scalar and the other a vector, the scalar is
595bf215546Sopenharmony_ci    *     applied component-wise to the vector, resulting in the same type as
596bf215546Sopenharmony_ci    *     the vector. The fundamental types of the operands [...] will be the
597bf215546Sopenharmony_ci    *     resulting fundamental type."
598bf215546Sopenharmony_ci    */
599bf215546Sopenharmony_ci   if (type_a->is_scalar())
600bf215546Sopenharmony_ci       return type_b;
601bf215546Sopenharmony_ci   else
602bf215546Sopenharmony_ci       return type_a;
603bf215546Sopenharmony_ci}
604bf215546Sopenharmony_ci
605bf215546Sopenharmony_cistatic const struct glsl_type *
606bf215546Sopenharmony_cimodulus_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b,
607bf215546Sopenharmony_ci                    struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
608bf215546Sopenharmony_ci{
609bf215546Sopenharmony_ci   const glsl_type *type_a = value_a->type;
610bf215546Sopenharmony_ci   const glsl_type *type_b = value_b->type;
611bf215546Sopenharmony_ci
612bf215546Sopenharmony_ci   if (!state->EXT_gpu_shader4_enable &&
613bf215546Sopenharmony_ci       !state->check_version(130, 300, loc, "operator '%%' is reserved")) {
614bf215546Sopenharmony_ci      return glsl_type::error_type;
615bf215546Sopenharmony_ci   }
616bf215546Sopenharmony_ci
617bf215546Sopenharmony_ci   /* Section 5.9 (Expressions) of the GLSL 4.00 specification says:
618bf215546Sopenharmony_ci    *
619bf215546Sopenharmony_ci    *    "The operator modulus (%) operates on signed or unsigned integers or
620bf215546Sopenharmony_ci    *    integer vectors."
621bf215546Sopenharmony_ci    */
622bf215546Sopenharmony_ci   if (!type_a->is_integer_32_64()) {
623bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state, "LHS of operator %% must be an integer");
624bf215546Sopenharmony_ci      return glsl_type::error_type;
625bf215546Sopenharmony_ci   }
626bf215546Sopenharmony_ci   if (!type_b->is_integer_32_64()) {
627bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state, "RHS of operator %% must be an integer");
628bf215546Sopenharmony_ci      return glsl_type::error_type;
629bf215546Sopenharmony_ci   }
630bf215546Sopenharmony_ci
631bf215546Sopenharmony_ci   /*    "If the fundamental types in the operands do not match, then the
632bf215546Sopenharmony_ci    *    conversions from section 4.1.10 "Implicit Conversions" are applied
633bf215546Sopenharmony_ci    *    to create matching types."
634bf215546Sopenharmony_ci    *
635bf215546Sopenharmony_ci    * Note that GLSL 4.00 (and GL_ARB_gpu_shader5) introduced implicit
636bf215546Sopenharmony_ci    * int -> uint conversion rules.  Prior to that, there were no implicit
637bf215546Sopenharmony_ci    * conversions.  So it's harmless to apply them universally - no implicit
638bf215546Sopenharmony_ci    * conversions will exist.  If the types don't match, we'll receive false,
639bf215546Sopenharmony_ci    * and raise an error, satisfying the GLSL 1.50 spec, page 56:
640bf215546Sopenharmony_ci    *
641bf215546Sopenharmony_ci    *    "The operand types must both be signed or unsigned."
642bf215546Sopenharmony_ci    */
643bf215546Sopenharmony_ci   if (!apply_implicit_conversion(type_a, value_b, state) &&
644bf215546Sopenharmony_ci       !apply_implicit_conversion(type_b, value_a, state)) {
645bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state,
646bf215546Sopenharmony_ci                       "could not implicitly convert operands to "
647bf215546Sopenharmony_ci                       "modulus (%%) operator");
648bf215546Sopenharmony_ci      return glsl_type::error_type;
649bf215546Sopenharmony_ci   }
650bf215546Sopenharmony_ci   type_a = value_a->type;
651bf215546Sopenharmony_ci   type_b = value_b->type;
652bf215546Sopenharmony_ci
653bf215546Sopenharmony_ci   /*    "The operands cannot be vectors of differing size. If one operand is
654bf215546Sopenharmony_ci    *    a scalar and the other vector, then the scalar is applied component-
655bf215546Sopenharmony_ci    *    wise to the vector, resulting in the same type as the vector. If both
656bf215546Sopenharmony_ci    *    are vectors of the same size, the result is computed component-wise."
657bf215546Sopenharmony_ci    */
658bf215546Sopenharmony_ci   if (type_a->is_vector()) {
659bf215546Sopenharmony_ci      if (!type_b->is_vector()
660bf215546Sopenharmony_ci          || (type_a->vector_elements == type_b->vector_elements))
661bf215546Sopenharmony_ci      return type_a;
662bf215546Sopenharmony_ci   } else
663bf215546Sopenharmony_ci      return type_b;
664bf215546Sopenharmony_ci
665bf215546Sopenharmony_ci   /*    "The operator modulus (%) is not defined for any other data types
666bf215546Sopenharmony_ci    *    (non-integer types)."
667bf215546Sopenharmony_ci    */
668bf215546Sopenharmony_ci   _mesa_glsl_error(loc, state, "type mismatch");
669bf215546Sopenharmony_ci   return glsl_type::error_type;
670bf215546Sopenharmony_ci}
671bf215546Sopenharmony_ci
672bf215546Sopenharmony_ci
673bf215546Sopenharmony_cistatic const struct glsl_type *
674bf215546Sopenharmony_cirelational_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b,
675bf215546Sopenharmony_ci                       struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
676bf215546Sopenharmony_ci{
677bf215546Sopenharmony_ci   const glsl_type *type_a = value_a->type;
678bf215546Sopenharmony_ci   const glsl_type *type_b = value_b->type;
679bf215546Sopenharmony_ci
680bf215546Sopenharmony_ci   /* From GLSL 1.50 spec, page 56:
681bf215546Sopenharmony_ci    *    "The relational operators greater than (>), less than (<), greater
682bf215546Sopenharmony_ci    *    than or equal (>=), and less than or equal (<=) operate only on
683bf215546Sopenharmony_ci    *    scalar integer and scalar floating-point expressions."
684bf215546Sopenharmony_ci    */
685bf215546Sopenharmony_ci   if (!type_a->is_numeric()
686bf215546Sopenharmony_ci       || !type_b->is_numeric()
687bf215546Sopenharmony_ci       || !type_a->is_scalar()
688bf215546Sopenharmony_ci       || !type_b->is_scalar()) {
689bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state,
690bf215546Sopenharmony_ci                       "operands to relational operators must be scalar and "
691bf215546Sopenharmony_ci                       "numeric");
692bf215546Sopenharmony_ci      return glsl_type::error_type;
693bf215546Sopenharmony_ci   }
694bf215546Sopenharmony_ci
695bf215546Sopenharmony_ci   /*    "Either the operands' types must match, or the conversions from
696bf215546Sopenharmony_ci    *    Section 4.1.10 "Implicit Conversions" will be applied to the integer
697bf215546Sopenharmony_ci    *    operand, after which the types must match."
698bf215546Sopenharmony_ci    */
699bf215546Sopenharmony_ci   if (!apply_implicit_conversion(type_a, value_b, state)
700bf215546Sopenharmony_ci       && !apply_implicit_conversion(type_b, value_a, state)) {
701bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state,
702bf215546Sopenharmony_ci                       "could not implicitly convert operands to "
703bf215546Sopenharmony_ci                       "relational operator");
704bf215546Sopenharmony_ci      return glsl_type::error_type;
705bf215546Sopenharmony_ci   }
706bf215546Sopenharmony_ci   type_a = value_a->type;
707bf215546Sopenharmony_ci   type_b = value_b->type;
708bf215546Sopenharmony_ci
709bf215546Sopenharmony_ci   if (type_a->base_type != type_b->base_type) {
710bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state, "base type mismatch");
711bf215546Sopenharmony_ci      return glsl_type::error_type;
712bf215546Sopenharmony_ci   }
713bf215546Sopenharmony_ci
714bf215546Sopenharmony_ci   /*    "The result is scalar Boolean."
715bf215546Sopenharmony_ci    */
716bf215546Sopenharmony_ci   return glsl_type::bool_type;
717bf215546Sopenharmony_ci}
718bf215546Sopenharmony_ci
719bf215546Sopenharmony_ci/**
720bf215546Sopenharmony_ci * \brief Return the result type of a bit-shift operation.
721bf215546Sopenharmony_ci *
722bf215546Sopenharmony_ci * If the given types to the bit-shift operator are invalid, return
723bf215546Sopenharmony_ci * glsl_type::error_type.
724bf215546Sopenharmony_ci *
725bf215546Sopenharmony_ci * \param type_a Type of LHS of bit-shift op
726bf215546Sopenharmony_ci * \param type_b Type of RHS of bit-shift op
727bf215546Sopenharmony_ci */
728bf215546Sopenharmony_cistatic const struct glsl_type *
729bf215546Sopenharmony_cishift_result_type(const struct glsl_type *type_a,
730bf215546Sopenharmony_ci                  const struct glsl_type *type_b,
731bf215546Sopenharmony_ci                  ast_operators op,
732bf215546Sopenharmony_ci                  struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
733bf215546Sopenharmony_ci{
734bf215546Sopenharmony_ci   if (!state->check_bitwise_operations_allowed(loc)) {
735bf215546Sopenharmony_ci      return glsl_type::error_type;
736bf215546Sopenharmony_ci   }
737bf215546Sopenharmony_ci
738bf215546Sopenharmony_ci   /* From page 50 (page 56 of the PDF) of the GLSL 1.30 spec:
739bf215546Sopenharmony_ci    *
740bf215546Sopenharmony_ci    *     "The shift operators (<<) and (>>). For both operators, the operands
741bf215546Sopenharmony_ci    *     must be signed or unsigned integers or integer vectors. One operand
742bf215546Sopenharmony_ci    *     can be signed while the other is unsigned."
743bf215546Sopenharmony_ci    */
744bf215546Sopenharmony_ci   if (!type_a->is_integer_32_64()) {
745bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state, "LHS of operator %s must be an integer or "
746bf215546Sopenharmony_ci                       "integer vector", ast_expression::operator_string(op));
747bf215546Sopenharmony_ci     return glsl_type::error_type;
748bf215546Sopenharmony_ci
749bf215546Sopenharmony_ci   }
750bf215546Sopenharmony_ci   if (!type_b->is_integer_32()) {
751bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state, "RHS of operator %s must be an integer or "
752bf215546Sopenharmony_ci                       "integer vector", ast_expression::operator_string(op));
753bf215546Sopenharmony_ci     return glsl_type::error_type;
754bf215546Sopenharmony_ci   }
755bf215546Sopenharmony_ci
756bf215546Sopenharmony_ci   /*     "If the first operand is a scalar, the second operand has to be
757bf215546Sopenharmony_ci    *     a scalar as well."
758bf215546Sopenharmony_ci    */
759bf215546Sopenharmony_ci   if (type_a->is_scalar() && !type_b->is_scalar()) {
760bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state, "if the first operand of %s is scalar, the "
761bf215546Sopenharmony_ci                       "second must be scalar as well",
762bf215546Sopenharmony_ci                       ast_expression::operator_string(op));
763bf215546Sopenharmony_ci     return glsl_type::error_type;
764bf215546Sopenharmony_ci   }
765bf215546Sopenharmony_ci
766bf215546Sopenharmony_ci   /* If both operands are vectors, check that they have same number of
767bf215546Sopenharmony_ci    * elements.
768bf215546Sopenharmony_ci    */
769bf215546Sopenharmony_ci   if (type_a->is_vector() &&
770bf215546Sopenharmony_ci      type_b->is_vector() &&
771bf215546Sopenharmony_ci      type_a->vector_elements != type_b->vector_elements) {
772bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state, "vector operands to operator %s must "
773bf215546Sopenharmony_ci                       "have same number of elements",
774bf215546Sopenharmony_ci                       ast_expression::operator_string(op));
775bf215546Sopenharmony_ci     return glsl_type::error_type;
776bf215546Sopenharmony_ci   }
777bf215546Sopenharmony_ci
778bf215546Sopenharmony_ci   /*     "In all cases, the resulting type will be the same type as the left
779bf215546Sopenharmony_ci    *     operand."
780bf215546Sopenharmony_ci    */
781bf215546Sopenharmony_ci   return type_a;
782bf215546Sopenharmony_ci}
783bf215546Sopenharmony_ci
784bf215546Sopenharmony_ci/**
785bf215546Sopenharmony_ci * Returns the innermost array index expression in an rvalue tree.
786bf215546Sopenharmony_ci * This is the largest indexing level -- if an array of blocks, then
787bf215546Sopenharmony_ci * it is the block index rather than an indexing expression for an
788bf215546Sopenharmony_ci * array-typed member of an array of blocks.
789bf215546Sopenharmony_ci */
790bf215546Sopenharmony_cistatic ir_rvalue *
791bf215546Sopenharmony_cifind_innermost_array_index(ir_rvalue *rv)
792bf215546Sopenharmony_ci{
793bf215546Sopenharmony_ci   ir_dereference_array *last = NULL;
794bf215546Sopenharmony_ci   while (rv) {
795bf215546Sopenharmony_ci      if (rv->as_dereference_array()) {
796bf215546Sopenharmony_ci         last = rv->as_dereference_array();
797bf215546Sopenharmony_ci         rv = last->array;
798bf215546Sopenharmony_ci      } else if (rv->as_dereference_record())
799bf215546Sopenharmony_ci         rv = rv->as_dereference_record()->record;
800bf215546Sopenharmony_ci      else if (rv->as_swizzle())
801bf215546Sopenharmony_ci         rv = rv->as_swizzle()->val;
802bf215546Sopenharmony_ci      else
803bf215546Sopenharmony_ci         rv = NULL;
804bf215546Sopenharmony_ci   }
805bf215546Sopenharmony_ci
806bf215546Sopenharmony_ci   if (last)
807bf215546Sopenharmony_ci      return last->array_index;
808bf215546Sopenharmony_ci
809bf215546Sopenharmony_ci   return NULL;
810bf215546Sopenharmony_ci}
811bf215546Sopenharmony_ci
812bf215546Sopenharmony_ci/**
813bf215546Sopenharmony_ci * Validates that a value can be assigned to a location with a specified type
814bf215546Sopenharmony_ci *
815bf215546Sopenharmony_ci * Validates that \c rhs can be assigned to some location.  If the types are
816bf215546Sopenharmony_ci * not an exact match but an automatic conversion is possible, \c rhs will be
817bf215546Sopenharmony_ci * converted.
818bf215546Sopenharmony_ci *
819bf215546Sopenharmony_ci * \return
820bf215546Sopenharmony_ci * \c NULL if \c rhs cannot be assigned to a location with type \c lhs_type.
821bf215546Sopenharmony_ci * Otherwise the actual RHS to be assigned will be returned.  This may be
822bf215546Sopenharmony_ci * \c rhs, or it may be \c rhs after some type conversion.
823bf215546Sopenharmony_ci *
824bf215546Sopenharmony_ci * \note
825bf215546Sopenharmony_ci * In addition to being used for assignments, this function is used to
826bf215546Sopenharmony_ci * type-check return values.
827bf215546Sopenharmony_ci */
828bf215546Sopenharmony_cistatic ir_rvalue *
829bf215546Sopenharmony_civalidate_assignment(struct _mesa_glsl_parse_state *state,
830bf215546Sopenharmony_ci                    YYLTYPE loc, ir_rvalue *lhs,
831bf215546Sopenharmony_ci                    ir_rvalue *rhs, bool is_initializer)
832bf215546Sopenharmony_ci{
833bf215546Sopenharmony_ci   /* If there is already some error in the RHS, just return it.  Anything
834bf215546Sopenharmony_ci    * else will lead to an avalanche of error message back to the user.
835bf215546Sopenharmony_ci    */
836bf215546Sopenharmony_ci   if (rhs->type->is_error())
837bf215546Sopenharmony_ci      return rhs;
838bf215546Sopenharmony_ci
839bf215546Sopenharmony_ci   /* In the Tessellation Control Shader:
840bf215546Sopenharmony_ci    * If a per-vertex output variable is used as an l-value, it is an error
841bf215546Sopenharmony_ci    * if the expression indicating the vertex number is not the identifier
842bf215546Sopenharmony_ci    * `gl_InvocationID`.
843bf215546Sopenharmony_ci    */
844bf215546Sopenharmony_ci   if (state->stage == MESA_SHADER_TESS_CTRL && !lhs->type->is_error()) {
845bf215546Sopenharmony_ci      ir_variable *var = lhs->variable_referenced();
846bf215546Sopenharmony_ci      if (var && var->data.mode == ir_var_shader_out && !var->data.patch) {
847bf215546Sopenharmony_ci         ir_rvalue *index = find_innermost_array_index(lhs);
848bf215546Sopenharmony_ci         ir_variable *index_var = index ? index->variable_referenced() : NULL;
849bf215546Sopenharmony_ci         if (!index_var || strcmp(index_var->name, "gl_InvocationID") != 0) {
850bf215546Sopenharmony_ci            _mesa_glsl_error(&loc, state,
851bf215546Sopenharmony_ci                             "Tessellation control shader outputs can only "
852bf215546Sopenharmony_ci                             "be indexed by gl_InvocationID");
853bf215546Sopenharmony_ci            return NULL;
854bf215546Sopenharmony_ci         }
855bf215546Sopenharmony_ci      }
856bf215546Sopenharmony_ci   }
857bf215546Sopenharmony_ci
858bf215546Sopenharmony_ci   /* If the types are identical, the assignment can trivially proceed.
859bf215546Sopenharmony_ci    */
860bf215546Sopenharmony_ci   if (rhs->type == lhs->type)
861bf215546Sopenharmony_ci      return rhs;
862bf215546Sopenharmony_ci
863bf215546Sopenharmony_ci   /* If the array element types are the same and the LHS is unsized,
864bf215546Sopenharmony_ci    * the assignment is okay for initializers embedded in variable
865bf215546Sopenharmony_ci    * declarations.
866bf215546Sopenharmony_ci    *
867bf215546Sopenharmony_ci    * Note: Whole-array assignments are not permitted in GLSL 1.10, but this
868bf215546Sopenharmony_ci    * is handled by ir_dereference::is_lvalue.
869bf215546Sopenharmony_ci    */
870bf215546Sopenharmony_ci   const glsl_type *lhs_t = lhs->type;
871bf215546Sopenharmony_ci   const glsl_type *rhs_t = rhs->type;
872bf215546Sopenharmony_ci   bool unsized_array = false;
873bf215546Sopenharmony_ci   while(lhs_t->is_array()) {
874bf215546Sopenharmony_ci      if (rhs_t == lhs_t)
875bf215546Sopenharmony_ci         break; /* the rest of the inner arrays match so break out early */
876bf215546Sopenharmony_ci      if (!rhs_t->is_array()) {
877bf215546Sopenharmony_ci         unsized_array = false;
878bf215546Sopenharmony_ci         break; /* number of dimensions mismatch */
879bf215546Sopenharmony_ci      }
880bf215546Sopenharmony_ci      if (lhs_t->length == rhs_t->length) {
881bf215546Sopenharmony_ci         lhs_t = lhs_t->fields.array;
882bf215546Sopenharmony_ci         rhs_t = rhs_t->fields.array;
883bf215546Sopenharmony_ci         continue;
884bf215546Sopenharmony_ci      } else if (lhs_t->is_unsized_array()) {
885bf215546Sopenharmony_ci         unsized_array = true;
886bf215546Sopenharmony_ci      } else {
887bf215546Sopenharmony_ci         unsized_array = false;
888bf215546Sopenharmony_ci         break; /* sized array mismatch */
889bf215546Sopenharmony_ci      }
890bf215546Sopenharmony_ci      lhs_t = lhs_t->fields.array;
891bf215546Sopenharmony_ci      rhs_t = rhs_t->fields.array;
892bf215546Sopenharmony_ci   }
893bf215546Sopenharmony_ci   if (unsized_array) {
894bf215546Sopenharmony_ci      if (is_initializer) {
895bf215546Sopenharmony_ci         if (rhs->type->get_scalar_type() == lhs->type->get_scalar_type())
896bf215546Sopenharmony_ci            return rhs;
897bf215546Sopenharmony_ci      } else {
898bf215546Sopenharmony_ci         _mesa_glsl_error(&loc, state,
899bf215546Sopenharmony_ci                          "implicitly sized arrays cannot be assigned");
900bf215546Sopenharmony_ci         return NULL;
901bf215546Sopenharmony_ci      }
902bf215546Sopenharmony_ci   }
903bf215546Sopenharmony_ci
904bf215546Sopenharmony_ci   /* Check for implicit conversion in GLSL 1.20 */
905bf215546Sopenharmony_ci   if (apply_implicit_conversion(lhs->type, rhs, state)) {
906bf215546Sopenharmony_ci      if (rhs->type == lhs->type)
907bf215546Sopenharmony_ci         return rhs;
908bf215546Sopenharmony_ci   }
909bf215546Sopenharmony_ci
910bf215546Sopenharmony_ci   _mesa_glsl_error(&loc, state,
911bf215546Sopenharmony_ci                    "%s of type %s cannot be assigned to "
912bf215546Sopenharmony_ci                    "variable of type %s",
913bf215546Sopenharmony_ci                    is_initializer ? "initializer" : "value",
914bf215546Sopenharmony_ci                    rhs->type->name, lhs->type->name);
915bf215546Sopenharmony_ci
916bf215546Sopenharmony_ci   return NULL;
917bf215546Sopenharmony_ci}
918bf215546Sopenharmony_ci
919bf215546Sopenharmony_cistatic void
920bf215546Sopenharmony_cimark_whole_array_access(ir_rvalue *access)
921bf215546Sopenharmony_ci{
922bf215546Sopenharmony_ci   ir_dereference_variable *deref = access->as_dereference_variable();
923bf215546Sopenharmony_ci
924bf215546Sopenharmony_ci   if (deref && deref->var) {
925bf215546Sopenharmony_ci      deref->var->data.max_array_access = deref->type->length - 1;
926bf215546Sopenharmony_ci   }
927bf215546Sopenharmony_ci}
928bf215546Sopenharmony_ci
929bf215546Sopenharmony_cistatic bool
930bf215546Sopenharmony_cido_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state,
931bf215546Sopenharmony_ci              const char *non_lvalue_description,
932bf215546Sopenharmony_ci              ir_rvalue *lhs, ir_rvalue *rhs,
933bf215546Sopenharmony_ci              ir_rvalue **out_rvalue, bool needs_rvalue,
934bf215546Sopenharmony_ci              bool is_initializer,
935bf215546Sopenharmony_ci              YYLTYPE lhs_loc)
936bf215546Sopenharmony_ci{
937bf215546Sopenharmony_ci   void *ctx = state;
938bf215546Sopenharmony_ci   bool error_emitted = (lhs->type->is_error() || rhs->type->is_error());
939bf215546Sopenharmony_ci
940bf215546Sopenharmony_ci   ir_variable *lhs_var = lhs->variable_referenced();
941bf215546Sopenharmony_ci   if (lhs_var)
942bf215546Sopenharmony_ci      lhs_var->data.assigned = true;
943bf215546Sopenharmony_ci
944bf215546Sopenharmony_ci   bool omit_assignment = false;
945bf215546Sopenharmony_ci   if (!error_emitted) {
946bf215546Sopenharmony_ci      if (non_lvalue_description != NULL) {
947bf215546Sopenharmony_ci         _mesa_glsl_error(&lhs_loc, state,
948bf215546Sopenharmony_ci                          "assignment to %s",
949bf215546Sopenharmony_ci                          non_lvalue_description);
950bf215546Sopenharmony_ci         error_emitted = true;
951bf215546Sopenharmony_ci      } else if (lhs_var != NULL && (lhs_var->data.read_only ||
952bf215546Sopenharmony_ci                 (lhs_var->data.mode == ir_var_shader_storage &&
953bf215546Sopenharmony_ci                  lhs_var->data.memory_read_only))) {
954bf215546Sopenharmony_ci         /* We can have memory_read_only set on both images and buffer variables,
955bf215546Sopenharmony_ci          * but in the former there is a distinction between assignments to
956bf215546Sopenharmony_ci          * the variable itself (read_only) and to the memory they point to
957bf215546Sopenharmony_ci          * (memory_read_only), while in the case of buffer variables there is
958bf215546Sopenharmony_ci          * no such distinction, that is why this check here is limited to
959bf215546Sopenharmony_ci          * buffer variables alone.
960bf215546Sopenharmony_ci          */
961bf215546Sopenharmony_ci
962bf215546Sopenharmony_ci         if (state->ignore_write_to_readonly_var)
963bf215546Sopenharmony_ci            omit_assignment = true;
964bf215546Sopenharmony_ci         else {
965bf215546Sopenharmony_ci            _mesa_glsl_error(&lhs_loc, state,
966bf215546Sopenharmony_ci                             "assignment to read-only variable '%s'",
967bf215546Sopenharmony_ci                             lhs_var->name);
968bf215546Sopenharmony_ci            error_emitted = true;
969bf215546Sopenharmony_ci         }
970bf215546Sopenharmony_ci      } else if (lhs->type->is_array() &&
971bf215546Sopenharmony_ci                 !state->check_version(state->allow_glsl_120_subset_in_110 ? 110 : 120,
972bf215546Sopenharmony_ci                                       300, &lhs_loc,
973bf215546Sopenharmony_ci                                       "whole array assignment forbidden")) {
974bf215546Sopenharmony_ci         /* From page 32 (page 38 of the PDF) of the GLSL 1.10 spec:
975bf215546Sopenharmony_ci          *
976bf215546Sopenharmony_ci          *    "Other binary or unary expressions, non-dereferenced
977bf215546Sopenharmony_ci          *     arrays, function names, swizzles with repeated fields,
978bf215546Sopenharmony_ci          *     and constants cannot be l-values."
979bf215546Sopenharmony_ci          *
980bf215546Sopenharmony_ci          * The restriction on arrays is lifted in GLSL 1.20 and GLSL ES 3.00.
981bf215546Sopenharmony_ci          */
982bf215546Sopenharmony_ci         error_emitted = true;
983bf215546Sopenharmony_ci      } else if (!lhs->is_lvalue(state)) {
984bf215546Sopenharmony_ci         _mesa_glsl_error(& lhs_loc, state, "non-lvalue in assignment");
985bf215546Sopenharmony_ci         error_emitted = true;
986bf215546Sopenharmony_ci      }
987bf215546Sopenharmony_ci   }
988bf215546Sopenharmony_ci
989bf215546Sopenharmony_ci   ir_rvalue *new_rhs =
990bf215546Sopenharmony_ci      validate_assignment(state, lhs_loc, lhs, rhs, is_initializer);
991bf215546Sopenharmony_ci   if (new_rhs != NULL) {
992bf215546Sopenharmony_ci      rhs = new_rhs;
993bf215546Sopenharmony_ci
994bf215546Sopenharmony_ci      /* If the LHS array was not declared with a size, it takes it size from
995bf215546Sopenharmony_ci       * the RHS.  If the LHS is an l-value and a whole array, it must be a
996bf215546Sopenharmony_ci       * dereference of a variable.  Any other case would require that the LHS
997bf215546Sopenharmony_ci       * is either not an l-value or not a whole array.
998bf215546Sopenharmony_ci       */
999bf215546Sopenharmony_ci      if (lhs->type->is_unsized_array()) {
1000bf215546Sopenharmony_ci         ir_dereference *const d = lhs->as_dereference();
1001bf215546Sopenharmony_ci
1002bf215546Sopenharmony_ci         assert(d != NULL);
1003bf215546Sopenharmony_ci
1004bf215546Sopenharmony_ci         ir_variable *const var = d->variable_referenced();
1005bf215546Sopenharmony_ci
1006bf215546Sopenharmony_ci         assert(var != NULL);
1007bf215546Sopenharmony_ci
1008bf215546Sopenharmony_ci         if (var->data.max_array_access >= rhs->type->array_size()) {
1009bf215546Sopenharmony_ci            /* FINISHME: This should actually log the location of the RHS. */
1010bf215546Sopenharmony_ci            _mesa_glsl_error(& lhs_loc, state, "array size must be > %u due to "
1011bf215546Sopenharmony_ci                             "previous access",
1012bf215546Sopenharmony_ci                             var->data.max_array_access);
1013bf215546Sopenharmony_ci         }
1014bf215546Sopenharmony_ci
1015bf215546Sopenharmony_ci         var->type = glsl_type::get_array_instance(lhs->type->fields.array,
1016bf215546Sopenharmony_ci                                                   rhs->type->array_size());
1017bf215546Sopenharmony_ci         d->type = var->type;
1018bf215546Sopenharmony_ci      }
1019bf215546Sopenharmony_ci      if (lhs->type->is_array()) {
1020bf215546Sopenharmony_ci         mark_whole_array_access(rhs);
1021bf215546Sopenharmony_ci         mark_whole_array_access(lhs);
1022bf215546Sopenharmony_ci      }
1023bf215546Sopenharmony_ci   } else {
1024bf215546Sopenharmony_ci     error_emitted = true;
1025bf215546Sopenharmony_ci   }
1026bf215546Sopenharmony_ci
1027bf215546Sopenharmony_ci   if (omit_assignment) {
1028bf215546Sopenharmony_ci      *out_rvalue = needs_rvalue ? ir_rvalue::error_value(ctx) : NULL;
1029bf215546Sopenharmony_ci      return error_emitted;
1030bf215546Sopenharmony_ci   }
1031bf215546Sopenharmony_ci
1032bf215546Sopenharmony_ci   /* Most callers of do_assignment (assign, add_assign, pre_inc/dec,
1033bf215546Sopenharmony_ci    * but not post_inc) need the converted assigned value as an rvalue
1034bf215546Sopenharmony_ci    * to handle things like:
1035bf215546Sopenharmony_ci    *
1036bf215546Sopenharmony_ci    * i = j += 1;
1037bf215546Sopenharmony_ci    */
1038bf215546Sopenharmony_ci   if (needs_rvalue) {
1039bf215546Sopenharmony_ci      ir_rvalue *rvalue;
1040bf215546Sopenharmony_ci      if (!error_emitted) {
1041bf215546Sopenharmony_ci         ir_variable *var = new(ctx) ir_variable(rhs->type, "assignment_tmp",
1042bf215546Sopenharmony_ci                                                 ir_var_temporary);
1043bf215546Sopenharmony_ci         instructions->push_tail(var);
1044bf215546Sopenharmony_ci         instructions->push_tail(assign(var, rhs));
1045bf215546Sopenharmony_ci
1046bf215546Sopenharmony_ci         ir_dereference_variable *deref_var =
1047bf215546Sopenharmony_ci            new(ctx) ir_dereference_variable(var);
1048bf215546Sopenharmony_ci         instructions->push_tail(new(ctx) ir_assignment(lhs, deref_var));
1049bf215546Sopenharmony_ci         rvalue = new(ctx) ir_dereference_variable(var);
1050bf215546Sopenharmony_ci      } else {
1051bf215546Sopenharmony_ci         rvalue = ir_rvalue::error_value(ctx);
1052bf215546Sopenharmony_ci      }
1053bf215546Sopenharmony_ci      *out_rvalue = rvalue;
1054bf215546Sopenharmony_ci   } else {
1055bf215546Sopenharmony_ci      if (!error_emitted)
1056bf215546Sopenharmony_ci         instructions->push_tail(new(ctx) ir_assignment(lhs, rhs));
1057bf215546Sopenharmony_ci      *out_rvalue = NULL;
1058bf215546Sopenharmony_ci   }
1059bf215546Sopenharmony_ci
1060bf215546Sopenharmony_ci   return error_emitted;
1061bf215546Sopenharmony_ci}
1062bf215546Sopenharmony_ci
1063bf215546Sopenharmony_cistatic ir_rvalue *
1064bf215546Sopenharmony_ciget_lvalue_copy(exec_list *instructions, ir_rvalue *lvalue)
1065bf215546Sopenharmony_ci{
1066bf215546Sopenharmony_ci   void *ctx = ralloc_parent(lvalue);
1067bf215546Sopenharmony_ci   ir_variable *var;
1068bf215546Sopenharmony_ci
1069bf215546Sopenharmony_ci   var = new(ctx) ir_variable(lvalue->type, "_post_incdec_tmp",
1070bf215546Sopenharmony_ci                              ir_var_temporary);
1071bf215546Sopenharmony_ci   instructions->push_tail(var);
1072bf215546Sopenharmony_ci
1073bf215546Sopenharmony_ci   instructions->push_tail(new(ctx) ir_assignment(new(ctx) ir_dereference_variable(var),
1074bf215546Sopenharmony_ci                                                  lvalue));
1075bf215546Sopenharmony_ci
1076bf215546Sopenharmony_ci   return new(ctx) ir_dereference_variable(var);
1077bf215546Sopenharmony_ci}
1078bf215546Sopenharmony_ci
1079bf215546Sopenharmony_ci
1080bf215546Sopenharmony_ciir_rvalue *
1081bf215546Sopenharmony_ciast_node::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state)
1082bf215546Sopenharmony_ci{
1083bf215546Sopenharmony_ci   (void) instructions;
1084bf215546Sopenharmony_ci   (void) state;
1085bf215546Sopenharmony_ci
1086bf215546Sopenharmony_ci   return NULL;
1087bf215546Sopenharmony_ci}
1088bf215546Sopenharmony_ci
1089bf215546Sopenharmony_cibool
1090bf215546Sopenharmony_ciast_node::has_sequence_subexpression() const
1091bf215546Sopenharmony_ci{
1092bf215546Sopenharmony_ci   return false;
1093bf215546Sopenharmony_ci}
1094bf215546Sopenharmony_ci
1095bf215546Sopenharmony_civoid
1096bf215546Sopenharmony_ciast_node::set_is_lhs(bool /* new_value */)
1097bf215546Sopenharmony_ci{
1098bf215546Sopenharmony_ci}
1099bf215546Sopenharmony_ci
1100bf215546Sopenharmony_civoid
1101bf215546Sopenharmony_ciast_function_expression::hir_no_rvalue(exec_list *instructions,
1102bf215546Sopenharmony_ci                                       struct _mesa_glsl_parse_state *state)
1103bf215546Sopenharmony_ci{
1104bf215546Sopenharmony_ci   (void)hir(instructions, state);
1105bf215546Sopenharmony_ci}
1106bf215546Sopenharmony_ci
1107bf215546Sopenharmony_civoid
1108bf215546Sopenharmony_ciast_aggregate_initializer::hir_no_rvalue(exec_list *instructions,
1109bf215546Sopenharmony_ci                                         struct _mesa_glsl_parse_state *state)
1110bf215546Sopenharmony_ci{
1111bf215546Sopenharmony_ci   (void)hir(instructions, state);
1112bf215546Sopenharmony_ci}
1113bf215546Sopenharmony_ci
1114bf215546Sopenharmony_cistatic ir_rvalue *
1115bf215546Sopenharmony_cido_comparison(void *mem_ctx, int operation, ir_rvalue *op0, ir_rvalue *op1)
1116bf215546Sopenharmony_ci{
1117bf215546Sopenharmony_ci   int join_op;
1118bf215546Sopenharmony_ci   ir_rvalue *cmp = NULL;
1119bf215546Sopenharmony_ci
1120bf215546Sopenharmony_ci   if (operation == ir_binop_all_equal)
1121bf215546Sopenharmony_ci      join_op = ir_binop_logic_and;
1122bf215546Sopenharmony_ci   else
1123bf215546Sopenharmony_ci      join_op = ir_binop_logic_or;
1124bf215546Sopenharmony_ci
1125bf215546Sopenharmony_ci   switch (op0->type->base_type) {
1126bf215546Sopenharmony_ci   case GLSL_TYPE_FLOAT:
1127bf215546Sopenharmony_ci   case GLSL_TYPE_FLOAT16:
1128bf215546Sopenharmony_ci   case GLSL_TYPE_UINT:
1129bf215546Sopenharmony_ci   case GLSL_TYPE_INT:
1130bf215546Sopenharmony_ci   case GLSL_TYPE_BOOL:
1131bf215546Sopenharmony_ci   case GLSL_TYPE_DOUBLE:
1132bf215546Sopenharmony_ci   case GLSL_TYPE_UINT64:
1133bf215546Sopenharmony_ci   case GLSL_TYPE_INT64:
1134bf215546Sopenharmony_ci   case GLSL_TYPE_UINT16:
1135bf215546Sopenharmony_ci   case GLSL_TYPE_INT16:
1136bf215546Sopenharmony_ci   case GLSL_TYPE_UINT8:
1137bf215546Sopenharmony_ci   case GLSL_TYPE_INT8:
1138bf215546Sopenharmony_ci      return new(mem_ctx) ir_expression(operation, op0, op1);
1139bf215546Sopenharmony_ci
1140bf215546Sopenharmony_ci   case GLSL_TYPE_ARRAY: {
1141bf215546Sopenharmony_ci      for (unsigned int i = 0; i < op0->type->length; i++) {
1142bf215546Sopenharmony_ci         ir_rvalue *e0, *e1, *result;
1143bf215546Sopenharmony_ci
1144bf215546Sopenharmony_ci         e0 = new(mem_ctx) ir_dereference_array(op0->clone(mem_ctx, NULL),
1145bf215546Sopenharmony_ci                                                new(mem_ctx) ir_constant(i));
1146bf215546Sopenharmony_ci         e1 = new(mem_ctx) ir_dereference_array(op1->clone(mem_ctx, NULL),
1147bf215546Sopenharmony_ci                                                new(mem_ctx) ir_constant(i));
1148bf215546Sopenharmony_ci         result = do_comparison(mem_ctx, operation, e0, e1);
1149bf215546Sopenharmony_ci
1150bf215546Sopenharmony_ci         if (cmp) {
1151bf215546Sopenharmony_ci            cmp = new(mem_ctx) ir_expression(join_op, cmp, result);
1152bf215546Sopenharmony_ci         } else {
1153bf215546Sopenharmony_ci            cmp = result;
1154bf215546Sopenharmony_ci         }
1155bf215546Sopenharmony_ci      }
1156bf215546Sopenharmony_ci
1157bf215546Sopenharmony_ci      mark_whole_array_access(op0);
1158bf215546Sopenharmony_ci      mark_whole_array_access(op1);
1159bf215546Sopenharmony_ci      break;
1160bf215546Sopenharmony_ci   }
1161bf215546Sopenharmony_ci
1162bf215546Sopenharmony_ci   case GLSL_TYPE_STRUCT: {
1163bf215546Sopenharmony_ci      for (unsigned int i = 0; i < op0->type->length; i++) {
1164bf215546Sopenharmony_ci         ir_rvalue *e0, *e1, *result;
1165bf215546Sopenharmony_ci         const char *field_name = op0->type->fields.structure[i].name;
1166bf215546Sopenharmony_ci
1167bf215546Sopenharmony_ci         e0 = new(mem_ctx) ir_dereference_record(op0->clone(mem_ctx, NULL),
1168bf215546Sopenharmony_ci                                                 field_name);
1169bf215546Sopenharmony_ci         e1 = new(mem_ctx) ir_dereference_record(op1->clone(mem_ctx, NULL),
1170bf215546Sopenharmony_ci                                                 field_name);
1171bf215546Sopenharmony_ci         result = do_comparison(mem_ctx, operation, e0, e1);
1172bf215546Sopenharmony_ci
1173bf215546Sopenharmony_ci         if (cmp) {
1174bf215546Sopenharmony_ci            cmp = new(mem_ctx) ir_expression(join_op, cmp, result);
1175bf215546Sopenharmony_ci         } else {
1176bf215546Sopenharmony_ci            cmp = result;
1177bf215546Sopenharmony_ci         }
1178bf215546Sopenharmony_ci      }
1179bf215546Sopenharmony_ci      break;
1180bf215546Sopenharmony_ci   }
1181bf215546Sopenharmony_ci
1182bf215546Sopenharmony_ci   case GLSL_TYPE_ERROR:
1183bf215546Sopenharmony_ci   case GLSL_TYPE_VOID:
1184bf215546Sopenharmony_ci   case GLSL_TYPE_SAMPLER:
1185bf215546Sopenharmony_ci   case GLSL_TYPE_TEXTURE:
1186bf215546Sopenharmony_ci   case GLSL_TYPE_IMAGE:
1187bf215546Sopenharmony_ci   case GLSL_TYPE_INTERFACE:
1188bf215546Sopenharmony_ci   case GLSL_TYPE_ATOMIC_UINT:
1189bf215546Sopenharmony_ci   case GLSL_TYPE_SUBROUTINE:
1190bf215546Sopenharmony_ci   case GLSL_TYPE_FUNCTION:
1191bf215546Sopenharmony_ci      /* I assume a comparison of a struct containing a sampler just
1192bf215546Sopenharmony_ci       * ignores the sampler present in the type.
1193bf215546Sopenharmony_ci       */
1194bf215546Sopenharmony_ci      break;
1195bf215546Sopenharmony_ci   }
1196bf215546Sopenharmony_ci
1197bf215546Sopenharmony_ci   if (cmp == NULL)
1198bf215546Sopenharmony_ci      cmp = new(mem_ctx) ir_constant(true);
1199bf215546Sopenharmony_ci
1200bf215546Sopenharmony_ci   return cmp;
1201bf215546Sopenharmony_ci}
1202bf215546Sopenharmony_ci
1203bf215546Sopenharmony_ci/* For logical operations, we want to ensure that the operands are
1204bf215546Sopenharmony_ci * scalar booleans.  If it isn't, emit an error and return a constant
1205bf215546Sopenharmony_ci * boolean to avoid triggering cascading error messages.
1206bf215546Sopenharmony_ci */
1207bf215546Sopenharmony_cistatic ir_rvalue *
1208bf215546Sopenharmony_ciget_scalar_boolean_operand(exec_list *instructions,
1209bf215546Sopenharmony_ci                           struct _mesa_glsl_parse_state *state,
1210bf215546Sopenharmony_ci                           ast_expression *parent_expr,
1211bf215546Sopenharmony_ci                           int operand,
1212bf215546Sopenharmony_ci                           const char *operand_name,
1213bf215546Sopenharmony_ci                           bool *error_emitted)
1214bf215546Sopenharmony_ci{
1215bf215546Sopenharmony_ci   ast_expression *expr = parent_expr->subexpressions[operand];
1216bf215546Sopenharmony_ci   void *ctx = state;
1217bf215546Sopenharmony_ci   ir_rvalue *val = expr->hir(instructions, state);
1218bf215546Sopenharmony_ci
1219bf215546Sopenharmony_ci   if (val->type->is_boolean() && val->type->is_scalar())
1220bf215546Sopenharmony_ci      return val;
1221bf215546Sopenharmony_ci
1222bf215546Sopenharmony_ci   if (!*error_emitted) {
1223bf215546Sopenharmony_ci      YYLTYPE loc = expr->get_location();
1224bf215546Sopenharmony_ci      _mesa_glsl_error(&loc, state, "%s of `%s' must be scalar boolean",
1225bf215546Sopenharmony_ci                       operand_name,
1226bf215546Sopenharmony_ci                       parent_expr->operator_string(parent_expr->oper));
1227bf215546Sopenharmony_ci      *error_emitted = true;
1228bf215546Sopenharmony_ci   }
1229bf215546Sopenharmony_ci
1230bf215546Sopenharmony_ci   return new(ctx) ir_constant(true);
1231bf215546Sopenharmony_ci}
1232bf215546Sopenharmony_ci
1233bf215546Sopenharmony_ci/**
1234bf215546Sopenharmony_ci * If name refers to a builtin array whose maximum allowed size is less than
1235bf215546Sopenharmony_ci * size, report an error and return true.  Otherwise return false.
1236bf215546Sopenharmony_ci */
1237bf215546Sopenharmony_civoid
1238bf215546Sopenharmony_cicheck_builtin_array_max_size(const char *name, unsigned size,
1239bf215546Sopenharmony_ci                             YYLTYPE loc, struct _mesa_glsl_parse_state *state)
1240bf215546Sopenharmony_ci{
1241bf215546Sopenharmony_ci   if ((strcmp("gl_TexCoord", name) == 0)
1242bf215546Sopenharmony_ci       && (size > state->Const.MaxTextureCoords)) {
1243bf215546Sopenharmony_ci      /* From page 54 (page 60 of the PDF) of the GLSL 1.20 spec:
1244bf215546Sopenharmony_ci       *
1245bf215546Sopenharmony_ci       *     "The size [of gl_TexCoord] can be at most
1246bf215546Sopenharmony_ci       *     gl_MaxTextureCoords."
1247bf215546Sopenharmony_ci       */
1248bf215546Sopenharmony_ci      _mesa_glsl_error(&loc, state, "`gl_TexCoord' array size cannot "
1249bf215546Sopenharmony_ci                       "be larger than gl_MaxTextureCoords (%u)",
1250bf215546Sopenharmony_ci                       state->Const.MaxTextureCoords);
1251bf215546Sopenharmony_ci   } else if (strcmp("gl_ClipDistance", name) == 0) {
1252bf215546Sopenharmony_ci      state->clip_dist_size = size;
1253bf215546Sopenharmony_ci      if (size + state->cull_dist_size > state->Const.MaxClipPlanes) {
1254bf215546Sopenharmony_ci         /* From section 7.1 (Vertex Shader Special Variables) of the
1255bf215546Sopenharmony_ci          * GLSL 1.30 spec:
1256bf215546Sopenharmony_ci          *
1257bf215546Sopenharmony_ci          *   "The gl_ClipDistance array is predeclared as unsized and
1258bf215546Sopenharmony_ci          *   must be sized by the shader either redeclaring it with a
1259bf215546Sopenharmony_ci          *   size or indexing it only with integral constant
1260bf215546Sopenharmony_ci          *   expressions. ... The size can be at most
1261bf215546Sopenharmony_ci          *   gl_MaxClipDistances."
1262bf215546Sopenharmony_ci          */
1263bf215546Sopenharmony_ci         _mesa_glsl_error(&loc, state, "`gl_ClipDistance' array size cannot "
1264bf215546Sopenharmony_ci                          "be larger than gl_MaxClipDistances (%u)",
1265bf215546Sopenharmony_ci                          state->Const.MaxClipPlanes);
1266bf215546Sopenharmony_ci      }
1267bf215546Sopenharmony_ci   } else if (strcmp("gl_CullDistance", name) == 0) {
1268bf215546Sopenharmony_ci      state->cull_dist_size = size;
1269bf215546Sopenharmony_ci      if (size + state->clip_dist_size > state->Const.MaxClipPlanes) {
1270bf215546Sopenharmony_ci         /* From the ARB_cull_distance spec:
1271bf215546Sopenharmony_ci          *
1272bf215546Sopenharmony_ci          *   "The gl_CullDistance array is predeclared as unsized and
1273bf215546Sopenharmony_ci          *    must be sized by the shader either redeclaring it with
1274bf215546Sopenharmony_ci          *    a size or indexing it only with integral constant
1275bf215546Sopenharmony_ci          *    expressions. The size determines the number and set of
1276bf215546Sopenharmony_ci          *    enabled cull distances and can be at most
1277bf215546Sopenharmony_ci          *    gl_MaxCullDistances."
1278bf215546Sopenharmony_ci          */
1279bf215546Sopenharmony_ci         _mesa_glsl_error(&loc, state, "`gl_CullDistance' array size cannot "
1280bf215546Sopenharmony_ci                          "be larger than gl_MaxCullDistances (%u)",
1281bf215546Sopenharmony_ci                          state->Const.MaxClipPlanes);
1282bf215546Sopenharmony_ci      }
1283bf215546Sopenharmony_ci   }
1284bf215546Sopenharmony_ci}
1285bf215546Sopenharmony_ci
1286bf215546Sopenharmony_ci/**
1287bf215546Sopenharmony_ci * Create the constant 1, of a which is appropriate for incrementing and
1288bf215546Sopenharmony_ci * decrementing values of the given GLSL type.  For example, if type is vec4,
1289bf215546Sopenharmony_ci * this creates a constant value of 1.0 having type float.
1290bf215546Sopenharmony_ci *
1291bf215546Sopenharmony_ci * If the given type is invalid for increment and decrement operators, return
1292bf215546Sopenharmony_ci * a floating point 1--the error will be detected later.
1293bf215546Sopenharmony_ci */
1294bf215546Sopenharmony_cistatic ir_rvalue *
1295bf215546Sopenharmony_ciconstant_one_for_inc_dec(void *ctx, const glsl_type *type)
1296bf215546Sopenharmony_ci{
1297bf215546Sopenharmony_ci   switch (type->base_type) {
1298bf215546Sopenharmony_ci   case GLSL_TYPE_UINT:
1299bf215546Sopenharmony_ci      return new(ctx) ir_constant((unsigned) 1);
1300bf215546Sopenharmony_ci   case GLSL_TYPE_INT:
1301bf215546Sopenharmony_ci      return new(ctx) ir_constant(1);
1302bf215546Sopenharmony_ci   case GLSL_TYPE_UINT64:
1303bf215546Sopenharmony_ci      return new(ctx) ir_constant((uint64_t) 1);
1304bf215546Sopenharmony_ci   case GLSL_TYPE_INT64:
1305bf215546Sopenharmony_ci      return new(ctx) ir_constant((int64_t) 1);
1306bf215546Sopenharmony_ci   default:
1307bf215546Sopenharmony_ci   case GLSL_TYPE_FLOAT:
1308bf215546Sopenharmony_ci      return new(ctx) ir_constant(1.0f);
1309bf215546Sopenharmony_ci   }
1310bf215546Sopenharmony_ci}
1311bf215546Sopenharmony_ci
1312bf215546Sopenharmony_ciir_rvalue *
1313bf215546Sopenharmony_ciast_expression::hir(exec_list *instructions,
1314bf215546Sopenharmony_ci                    struct _mesa_glsl_parse_state *state)
1315bf215546Sopenharmony_ci{
1316bf215546Sopenharmony_ci   return do_hir(instructions, state, true);
1317bf215546Sopenharmony_ci}
1318bf215546Sopenharmony_ci
1319bf215546Sopenharmony_civoid
1320bf215546Sopenharmony_ciast_expression::hir_no_rvalue(exec_list *instructions,
1321bf215546Sopenharmony_ci                              struct _mesa_glsl_parse_state *state)
1322bf215546Sopenharmony_ci{
1323bf215546Sopenharmony_ci   do_hir(instructions, state, false);
1324bf215546Sopenharmony_ci}
1325bf215546Sopenharmony_ci
1326bf215546Sopenharmony_civoid
1327bf215546Sopenharmony_ciast_expression::set_is_lhs(bool new_value)
1328bf215546Sopenharmony_ci{
1329bf215546Sopenharmony_ci   /* is_lhs is tracked only to print "variable used uninitialized" warnings,
1330bf215546Sopenharmony_ci    * if we lack an identifier we can just skip it.
1331bf215546Sopenharmony_ci    */
1332bf215546Sopenharmony_ci   if (this->primary_expression.identifier == NULL)
1333bf215546Sopenharmony_ci      return;
1334bf215546Sopenharmony_ci
1335bf215546Sopenharmony_ci   this->is_lhs = new_value;
1336bf215546Sopenharmony_ci
1337bf215546Sopenharmony_ci   /* We need to go through the subexpressions tree to cover cases like
1338bf215546Sopenharmony_ci    * ast_field_selection
1339bf215546Sopenharmony_ci    */
1340bf215546Sopenharmony_ci   if (this->subexpressions[0] != NULL)
1341bf215546Sopenharmony_ci      this->subexpressions[0]->set_is_lhs(new_value);
1342bf215546Sopenharmony_ci}
1343bf215546Sopenharmony_ci
1344bf215546Sopenharmony_ciir_rvalue *
1345bf215546Sopenharmony_ciast_expression::do_hir(exec_list *instructions,
1346bf215546Sopenharmony_ci                       struct _mesa_glsl_parse_state *state,
1347bf215546Sopenharmony_ci                       bool needs_rvalue)
1348bf215546Sopenharmony_ci{
1349bf215546Sopenharmony_ci   void *ctx = state;
1350bf215546Sopenharmony_ci   static const int operations[AST_NUM_OPERATORS] = {
1351bf215546Sopenharmony_ci      -1,               /* ast_assign doesn't convert to ir_expression. */
1352bf215546Sopenharmony_ci      -1,               /* ast_plus doesn't convert to ir_expression. */
1353bf215546Sopenharmony_ci      ir_unop_neg,
1354bf215546Sopenharmony_ci      ir_binop_add,
1355bf215546Sopenharmony_ci      ir_binop_sub,
1356bf215546Sopenharmony_ci      ir_binop_mul,
1357bf215546Sopenharmony_ci      ir_binop_div,
1358bf215546Sopenharmony_ci      ir_binop_mod,
1359bf215546Sopenharmony_ci      ir_binop_lshift,
1360bf215546Sopenharmony_ci      ir_binop_rshift,
1361bf215546Sopenharmony_ci      ir_binop_less,
1362bf215546Sopenharmony_ci      ir_binop_less,    /* This is correct.  See the ast_greater case below. */
1363bf215546Sopenharmony_ci      ir_binop_gequal,  /* This is correct.  See the ast_lequal case below. */
1364bf215546Sopenharmony_ci      ir_binop_gequal,
1365bf215546Sopenharmony_ci      ir_binop_all_equal,
1366bf215546Sopenharmony_ci      ir_binop_any_nequal,
1367bf215546Sopenharmony_ci      ir_binop_bit_and,
1368bf215546Sopenharmony_ci      ir_binop_bit_xor,
1369bf215546Sopenharmony_ci      ir_binop_bit_or,
1370bf215546Sopenharmony_ci      ir_unop_bit_not,
1371bf215546Sopenharmony_ci      ir_binop_logic_and,
1372bf215546Sopenharmony_ci      ir_binop_logic_xor,
1373bf215546Sopenharmony_ci      ir_binop_logic_or,
1374bf215546Sopenharmony_ci      ir_unop_logic_not,
1375bf215546Sopenharmony_ci
1376bf215546Sopenharmony_ci      /* Note: The following block of expression types actually convert
1377bf215546Sopenharmony_ci       * to multiple IR instructions.
1378bf215546Sopenharmony_ci       */
1379bf215546Sopenharmony_ci      ir_binop_mul,     /* ast_mul_assign */
1380bf215546Sopenharmony_ci      ir_binop_div,     /* ast_div_assign */
1381bf215546Sopenharmony_ci      ir_binop_mod,     /* ast_mod_assign */
1382bf215546Sopenharmony_ci      ir_binop_add,     /* ast_add_assign */
1383bf215546Sopenharmony_ci      ir_binop_sub,     /* ast_sub_assign */
1384bf215546Sopenharmony_ci      ir_binop_lshift,  /* ast_ls_assign */
1385bf215546Sopenharmony_ci      ir_binop_rshift,  /* ast_rs_assign */
1386bf215546Sopenharmony_ci      ir_binop_bit_and, /* ast_and_assign */
1387bf215546Sopenharmony_ci      ir_binop_bit_xor, /* ast_xor_assign */
1388bf215546Sopenharmony_ci      ir_binop_bit_or,  /* ast_or_assign */
1389bf215546Sopenharmony_ci
1390bf215546Sopenharmony_ci      -1,               /* ast_conditional doesn't convert to ir_expression. */
1391bf215546Sopenharmony_ci      ir_binop_add,     /* ast_pre_inc. */
1392bf215546Sopenharmony_ci      ir_binop_sub,     /* ast_pre_dec. */
1393bf215546Sopenharmony_ci      ir_binop_add,     /* ast_post_inc. */
1394bf215546Sopenharmony_ci      ir_binop_sub,     /* ast_post_dec. */
1395bf215546Sopenharmony_ci      -1,               /* ast_field_selection doesn't conv to ir_expression. */
1396bf215546Sopenharmony_ci      -1,               /* ast_array_index doesn't convert to ir_expression. */
1397bf215546Sopenharmony_ci      -1,               /* ast_function_call doesn't conv to ir_expression. */
1398bf215546Sopenharmony_ci      -1,               /* ast_identifier doesn't convert to ir_expression. */
1399bf215546Sopenharmony_ci      -1,               /* ast_int_constant doesn't convert to ir_expression. */
1400bf215546Sopenharmony_ci      -1,               /* ast_uint_constant doesn't conv to ir_expression. */
1401bf215546Sopenharmony_ci      -1,               /* ast_float_constant doesn't conv to ir_expression. */
1402bf215546Sopenharmony_ci      -1,               /* ast_bool_constant doesn't conv to ir_expression. */
1403bf215546Sopenharmony_ci      -1,               /* ast_sequence doesn't convert to ir_expression. */
1404bf215546Sopenharmony_ci      -1,               /* ast_aggregate shouldn't ever even get here. */
1405bf215546Sopenharmony_ci   };
1406bf215546Sopenharmony_ci   ir_rvalue *result = NULL;
1407bf215546Sopenharmony_ci   ir_rvalue *op[3];
1408bf215546Sopenharmony_ci   const struct glsl_type *type, *orig_type;
1409bf215546Sopenharmony_ci   bool error_emitted = false;
1410bf215546Sopenharmony_ci   YYLTYPE loc;
1411bf215546Sopenharmony_ci
1412bf215546Sopenharmony_ci   loc = this->get_location();
1413bf215546Sopenharmony_ci
1414bf215546Sopenharmony_ci   switch (this->oper) {
1415bf215546Sopenharmony_ci   case ast_aggregate:
1416bf215546Sopenharmony_ci      unreachable("ast_aggregate: Should never get here.");
1417bf215546Sopenharmony_ci
1418bf215546Sopenharmony_ci   case ast_assign: {
1419bf215546Sopenharmony_ci      this->subexpressions[0]->set_is_lhs(true);
1420bf215546Sopenharmony_ci      op[0] = this->subexpressions[0]->hir(instructions, state);
1421bf215546Sopenharmony_ci      op[1] = this->subexpressions[1]->hir(instructions, state);
1422bf215546Sopenharmony_ci
1423bf215546Sopenharmony_ci      error_emitted =
1424bf215546Sopenharmony_ci         do_assignment(instructions, state,
1425bf215546Sopenharmony_ci                       this->subexpressions[0]->non_lvalue_description,
1426bf215546Sopenharmony_ci                       op[0], op[1], &result, needs_rvalue, false,
1427bf215546Sopenharmony_ci                       this->subexpressions[0]->get_location());
1428bf215546Sopenharmony_ci      break;
1429bf215546Sopenharmony_ci   }
1430bf215546Sopenharmony_ci
1431bf215546Sopenharmony_ci   case ast_plus:
1432bf215546Sopenharmony_ci      op[0] = this->subexpressions[0]->hir(instructions, state);
1433bf215546Sopenharmony_ci
1434bf215546Sopenharmony_ci      type = unary_arithmetic_result_type(op[0]->type, state, & loc);
1435bf215546Sopenharmony_ci
1436bf215546Sopenharmony_ci      error_emitted = type->is_error();
1437bf215546Sopenharmony_ci
1438bf215546Sopenharmony_ci      result = op[0];
1439bf215546Sopenharmony_ci      break;
1440bf215546Sopenharmony_ci
1441bf215546Sopenharmony_ci   case ast_neg:
1442bf215546Sopenharmony_ci      op[0] = this->subexpressions[0]->hir(instructions, state);
1443bf215546Sopenharmony_ci
1444bf215546Sopenharmony_ci      type = unary_arithmetic_result_type(op[0]->type, state, & loc);
1445bf215546Sopenharmony_ci
1446bf215546Sopenharmony_ci      error_emitted = type->is_error();
1447bf215546Sopenharmony_ci
1448bf215546Sopenharmony_ci      result = new(ctx) ir_expression(operations[this->oper], type,
1449bf215546Sopenharmony_ci                                      op[0], NULL);
1450bf215546Sopenharmony_ci      break;
1451bf215546Sopenharmony_ci
1452bf215546Sopenharmony_ci   case ast_add:
1453bf215546Sopenharmony_ci   case ast_sub:
1454bf215546Sopenharmony_ci   case ast_mul:
1455bf215546Sopenharmony_ci   case ast_div:
1456bf215546Sopenharmony_ci      op[0] = this->subexpressions[0]->hir(instructions, state);
1457bf215546Sopenharmony_ci      op[1] = this->subexpressions[1]->hir(instructions, state);
1458bf215546Sopenharmony_ci
1459bf215546Sopenharmony_ci      type = arithmetic_result_type(op[0], op[1],
1460bf215546Sopenharmony_ci                                    (this->oper == ast_mul),
1461bf215546Sopenharmony_ci                                    state, & loc);
1462bf215546Sopenharmony_ci      error_emitted = type->is_error();
1463bf215546Sopenharmony_ci
1464bf215546Sopenharmony_ci      result = new(ctx) ir_expression(operations[this->oper], type,
1465bf215546Sopenharmony_ci                                      op[0], op[1]);
1466bf215546Sopenharmony_ci      break;
1467bf215546Sopenharmony_ci
1468bf215546Sopenharmony_ci   case ast_mod:
1469bf215546Sopenharmony_ci      op[0] = this->subexpressions[0]->hir(instructions, state);
1470bf215546Sopenharmony_ci      op[1] = this->subexpressions[1]->hir(instructions, state);
1471bf215546Sopenharmony_ci
1472bf215546Sopenharmony_ci      type = modulus_result_type(op[0], op[1], state, &loc);
1473bf215546Sopenharmony_ci
1474bf215546Sopenharmony_ci      assert(operations[this->oper] == ir_binop_mod);
1475bf215546Sopenharmony_ci
1476bf215546Sopenharmony_ci      result = new(ctx) ir_expression(operations[this->oper], type,
1477bf215546Sopenharmony_ci                                      op[0], op[1]);
1478bf215546Sopenharmony_ci      error_emitted = type->is_error();
1479bf215546Sopenharmony_ci      break;
1480bf215546Sopenharmony_ci
1481bf215546Sopenharmony_ci   case ast_lshift:
1482bf215546Sopenharmony_ci   case ast_rshift:
1483bf215546Sopenharmony_ci       if (!state->check_bitwise_operations_allowed(&loc)) {
1484bf215546Sopenharmony_ci          error_emitted = true;
1485bf215546Sopenharmony_ci       }
1486bf215546Sopenharmony_ci
1487bf215546Sopenharmony_ci       op[0] = this->subexpressions[0]->hir(instructions, state);
1488bf215546Sopenharmony_ci       op[1] = this->subexpressions[1]->hir(instructions, state);
1489bf215546Sopenharmony_ci       type = shift_result_type(op[0]->type, op[1]->type, this->oper, state,
1490bf215546Sopenharmony_ci                                &loc);
1491bf215546Sopenharmony_ci       result = new(ctx) ir_expression(operations[this->oper], type,
1492bf215546Sopenharmony_ci                                       op[0], op[1]);
1493bf215546Sopenharmony_ci       error_emitted = op[0]->type->is_error() || op[1]->type->is_error();
1494bf215546Sopenharmony_ci       break;
1495bf215546Sopenharmony_ci
1496bf215546Sopenharmony_ci   case ast_less:
1497bf215546Sopenharmony_ci   case ast_greater:
1498bf215546Sopenharmony_ci   case ast_lequal:
1499bf215546Sopenharmony_ci   case ast_gequal:
1500bf215546Sopenharmony_ci      op[0] = this->subexpressions[0]->hir(instructions, state);
1501bf215546Sopenharmony_ci      op[1] = this->subexpressions[1]->hir(instructions, state);
1502bf215546Sopenharmony_ci
1503bf215546Sopenharmony_ci      type = relational_result_type(op[0], op[1], state, & loc);
1504bf215546Sopenharmony_ci
1505bf215546Sopenharmony_ci      /* The relational operators must either generate an error or result
1506bf215546Sopenharmony_ci       * in a scalar boolean.  See page 57 of the GLSL 1.50 spec.
1507bf215546Sopenharmony_ci       */
1508bf215546Sopenharmony_ci      assert(type->is_error()
1509bf215546Sopenharmony_ci             || (type->is_boolean() && type->is_scalar()));
1510bf215546Sopenharmony_ci
1511bf215546Sopenharmony_ci      /* Like NIR, GLSL IR does not have opcodes for > or <=.  Instead, swap
1512bf215546Sopenharmony_ci       * the arguments and use < or >=.
1513bf215546Sopenharmony_ci       */
1514bf215546Sopenharmony_ci      if (this->oper == ast_greater || this->oper == ast_lequal) {
1515bf215546Sopenharmony_ci         ir_rvalue *const tmp = op[0];
1516bf215546Sopenharmony_ci         op[0] = op[1];
1517bf215546Sopenharmony_ci         op[1] = tmp;
1518bf215546Sopenharmony_ci      }
1519bf215546Sopenharmony_ci
1520bf215546Sopenharmony_ci      result = new(ctx) ir_expression(operations[this->oper], type,
1521bf215546Sopenharmony_ci                                      op[0], op[1]);
1522bf215546Sopenharmony_ci      error_emitted = type->is_error();
1523bf215546Sopenharmony_ci      break;
1524bf215546Sopenharmony_ci
1525bf215546Sopenharmony_ci   case ast_nequal:
1526bf215546Sopenharmony_ci   case ast_equal:
1527bf215546Sopenharmony_ci      op[0] = this->subexpressions[0]->hir(instructions, state);
1528bf215546Sopenharmony_ci      op[1] = this->subexpressions[1]->hir(instructions, state);
1529bf215546Sopenharmony_ci
1530bf215546Sopenharmony_ci      /* From page 58 (page 64 of the PDF) of the GLSL 1.50 spec:
1531bf215546Sopenharmony_ci       *
1532bf215546Sopenharmony_ci       *    "The equality operators equal (==), and not equal (!=)
1533bf215546Sopenharmony_ci       *    operate on all types. They result in a scalar Boolean. If
1534bf215546Sopenharmony_ci       *    the operand types do not match, then there must be a
1535bf215546Sopenharmony_ci       *    conversion from Section 4.1.10 "Implicit Conversions"
1536bf215546Sopenharmony_ci       *    applied to one operand that can make them match, in which
1537bf215546Sopenharmony_ci       *    case this conversion is done."
1538bf215546Sopenharmony_ci       */
1539bf215546Sopenharmony_ci
1540bf215546Sopenharmony_ci      if (op[0]->type == glsl_type::void_type || op[1]->type == glsl_type::void_type) {
1541bf215546Sopenharmony_ci         _mesa_glsl_error(& loc, state, "`%s':  wrong operand types: "
1542bf215546Sopenharmony_ci                         "no operation `%1$s' exists that takes a left-hand "
1543bf215546Sopenharmony_ci                         "operand of type 'void' or a right operand of type "
1544bf215546Sopenharmony_ci                         "'void'", (this->oper == ast_equal) ? "==" : "!=");
1545bf215546Sopenharmony_ci         error_emitted = true;
1546bf215546Sopenharmony_ci      } else if ((!apply_implicit_conversion(op[0]->type, op[1], state)
1547bf215546Sopenharmony_ci           && !apply_implicit_conversion(op[1]->type, op[0], state))
1548bf215546Sopenharmony_ci          || (op[0]->type != op[1]->type)) {
1549bf215546Sopenharmony_ci         _mesa_glsl_error(& loc, state, "operands of `%s' must have the same "
1550bf215546Sopenharmony_ci                          "type", (this->oper == ast_equal) ? "==" : "!=");
1551bf215546Sopenharmony_ci         error_emitted = true;
1552bf215546Sopenharmony_ci      } else if ((op[0]->type->is_array() || op[1]->type->is_array()) &&
1553bf215546Sopenharmony_ci                 !state->check_version(120, 300, &loc,
1554bf215546Sopenharmony_ci                                       "array comparisons forbidden")) {
1555bf215546Sopenharmony_ci         error_emitted = true;
1556bf215546Sopenharmony_ci      } else if ((op[0]->type->contains_subroutine() ||
1557bf215546Sopenharmony_ci                  op[1]->type->contains_subroutine())) {
1558bf215546Sopenharmony_ci         _mesa_glsl_error(&loc, state, "subroutine comparisons forbidden");
1559bf215546Sopenharmony_ci         error_emitted = true;
1560bf215546Sopenharmony_ci      } else if ((op[0]->type->contains_opaque() ||
1561bf215546Sopenharmony_ci                  op[1]->type->contains_opaque())) {
1562bf215546Sopenharmony_ci         _mesa_glsl_error(&loc, state, "opaque type comparisons forbidden");
1563bf215546Sopenharmony_ci         error_emitted = true;
1564bf215546Sopenharmony_ci      }
1565bf215546Sopenharmony_ci
1566bf215546Sopenharmony_ci      if (error_emitted) {
1567bf215546Sopenharmony_ci         result = new(ctx) ir_constant(false);
1568bf215546Sopenharmony_ci      } else {
1569bf215546Sopenharmony_ci         result = do_comparison(ctx, operations[this->oper], op[0], op[1]);
1570bf215546Sopenharmony_ci         assert(result->type == glsl_type::bool_type);
1571bf215546Sopenharmony_ci      }
1572bf215546Sopenharmony_ci      break;
1573bf215546Sopenharmony_ci
1574bf215546Sopenharmony_ci   case ast_bit_and:
1575bf215546Sopenharmony_ci   case ast_bit_xor:
1576bf215546Sopenharmony_ci   case ast_bit_or:
1577bf215546Sopenharmony_ci      op[0] = this->subexpressions[0]->hir(instructions, state);
1578bf215546Sopenharmony_ci      op[1] = this->subexpressions[1]->hir(instructions, state);
1579bf215546Sopenharmony_ci      type = bit_logic_result_type(op[0], op[1], this->oper, state, &loc);
1580bf215546Sopenharmony_ci      result = new(ctx) ir_expression(operations[this->oper], type,
1581bf215546Sopenharmony_ci                                      op[0], op[1]);
1582bf215546Sopenharmony_ci      error_emitted = op[0]->type->is_error() || op[1]->type->is_error();
1583bf215546Sopenharmony_ci      break;
1584bf215546Sopenharmony_ci
1585bf215546Sopenharmony_ci   case ast_bit_not:
1586bf215546Sopenharmony_ci      op[0] = this->subexpressions[0]->hir(instructions, state);
1587bf215546Sopenharmony_ci
1588bf215546Sopenharmony_ci      if (!state->check_bitwise_operations_allowed(&loc)) {
1589bf215546Sopenharmony_ci         error_emitted = true;
1590bf215546Sopenharmony_ci      }
1591bf215546Sopenharmony_ci
1592bf215546Sopenharmony_ci      if (!op[0]->type->is_integer_32_64()) {
1593bf215546Sopenharmony_ci         _mesa_glsl_error(&loc, state, "operand of `~' must be an integer");
1594bf215546Sopenharmony_ci         error_emitted = true;
1595bf215546Sopenharmony_ci      }
1596bf215546Sopenharmony_ci
1597bf215546Sopenharmony_ci      type = error_emitted ? glsl_type::error_type : op[0]->type;
1598bf215546Sopenharmony_ci      result = new(ctx) ir_expression(ir_unop_bit_not, type, op[0], NULL);
1599bf215546Sopenharmony_ci      break;
1600bf215546Sopenharmony_ci
1601bf215546Sopenharmony_ci   case ast_logic_and: {
1602bf215546Sopenharmony_ci      exec_list rhs_instructions;
1603bf215546Sopenharmony_ci      op[0] = get_scalar_boolean_operand(instructions, state, this, 0,
1604bf215546Sopenharmony_ci                                         "LHS", &error_emitted);
1605bf215546Sopenharmony_ci      op[1] = get_scalar_boolean_operand(&rhs_instructions, state, this, 1,
1606bf215546Sopenharmony_ci                                         "RHS", &error_emitted);
1607bf215546Sopenharmony_ci
1608bf215546Sopenharmony_ci      if (rhs_instructions.is_empty()) {
1609bf215546Sopenharmony_ci         result = new(ctx) ir_expression(ir_binop_logic_and, op[0], op[1]);
1610bf215546Sopenharmony_ci      } else {
1611bf215546Sopenharmony_ci         ir_variable *const tmp = new(ctx) ir_variable(glsl_type::bool_type,
1612bf215546Sopenharmony_ci                                                       "and_tmp",
1613bf215546Sopenharmony_ci                                                       ir_var_temporary);
1614bf215546Sopenharmony_ci         instructions->push_tail(tmp);
1615bf215546Sopenharmony_ci
1616bf215546Sopenharmony_ci         ir_if *const stmt = new(ctx) ir_if(op[0]);
1617bf215546Sopenharmony_ci         instructions->push_tail(stmt);
1618bf215546Sopenharmony_ci
1619bf215546Sopenharmony_ci         stmt->then_instructions.append_list(&rhs_instructions);
1620bf215546Sopenharmony_ci         ir_dereference *const then_deref = new(ctx) ir_dereference_variable(tmp);
1621bf215546Sopenharmony_ci         ir_assignment *const then_assign =
1622bf215546Sopenharmony_ci            new(ctx) ir_assignment(then_deref, op[1]);
1623bf215546Sopenharmony_ci         stmt->then_instructions.push_tail(then_assign);
1624bf215546Sopenharmony_ci
1625bf215546Sopenharmony_ci         ir_dereference *const else_deref = new(ctx) ir_dereference_variable(tmp);
1626bf215546Sopenharmony_ci         ir_assignment *const else_assign =
1627bf215546Sopenharmony_ci            new(ctx) ir_assignment(else_deref, new(ctx) ir_constant(false));
1628bf215546Sopenharmony_ci         stmt->else_instructions.push_tail(else_assign);
1629bf215546Sopenharmony_ci
1630bf215546Sopenharmony_ci         result = new(ctx) ir_dereference_variable(tmp);
1631bf215546Sopenharmony_ci      }
1632bf215546Sopenharmony_ci      break;
1633bf215546Sopenharmony_ci   }
1634bf215546Sopenharmony_ci
1635bf215546Sopenharmony_ci   case ast_logic_or: {
1636bf215546Sopenharmony_ci      exec_list rhs_instructions;
1637bf215546Sopenharmony_ci      op[0] = get_scalar_boolean_operand(instructions, state, this, 0,
1638bf215546Sopenharmony_ci                                         "LHS", &error_emitted);
1639bf215546Sopenharmony_ci      op[1] = get_scalar_boolean_operand(&rhs_instructions, state, this, 1,
1640bf215546Sopenharmony_ci                                         "RHS", &error_emitted);
1641bf215546Sopenharmony_ci
1642bf215546Sopenharmony_ci      if (rhs_instructions.is_empty()) {
1643bf215546Sopenharmony_ci         result = new(ctx) ir_expression(ir_binop_logic_or, op[0], op[1]);
1644bf215546Sopenharmony_ci      } else {
1645bf215546Sopenharmony_ci         ir_variable *const tmp = new(ctx) ir_variable(glsl_type::bool_type,
1646bf215546Sopenharmony_ci                                                       "or_tmp",
1647bf215546Sopenharmony_ci                                                       ir_var_temporary);
1648bf215546Sopenharmony_ci         instructions->push_tail(tmp);
1649bf215546Sopenharmony_ci
1650bf215546Sopenharmony_ci         ir_if *const stmt = new(ctx) ir_if(op[0]);
1651bf215546Sopenharmony_ci         instructions->push_tail(stmt);
1652bf215546Sopenharmony_ci
1653bf215546Sopenharmony_ci         ir_dereference *const then_deref = new(ctx) ir_dereference_variable(tmp);
1654bf215546Sopenharmony_ci         ir_assignment *const then_assign =
1655bf215546Sopenharmony_ci            new(ctx) ir_assignment(then_deref, new(ctx) ir_constant(true));
1656bf215546Sopenharmony_ci         stmt->then_instructions.push_tail(then_assign);
1657bf215546Sopenharmony_ci
1658bf215546Sopenharmony_ci         stmt->else_instructions.append_list(&rhs_instructions);
1659bf215546Sopenharmony_ci         ir_dereference *const else_deref = new(ctx) ir_dereference_variable(tmp);
1660bf215546Sopenharmony_ci         ir_assignment *const else_assign =
1661bf215546Sopenharmony_ci            new(ctx) ir_assignment(else_deref, op[1]);
1662bf215546Sopenharmony_ci         stmt->else_instructions.push_tail(else_assign);
1663bf215546Sopenharmony_ci
1664bf215546Sopenharmony_ci         result = new(ctx) ir_dereference_variable(tmp);
1665bf215546Sopenharmony_ci      }
1666bf215546Sopenharmony_ci      break;
1667bf215546Sopenharmony_ci   }
1668bf215546Sopenharmony_ci
1669bf215546Sopenharmony_ci   case ast_logic_xor:
1670bf215546Sopenharmony_ci      /* From page 33 (page 39 of the PDF) of the GLSL 1.10 spec:
1671bf215546Sopenharmony_ci       *
1672bf215546Sopenharmony_ci       *    "The logical binary operators and (&&), or ( | | ), and
1673bf215546Sopenharmony_ci       *     exclusive or (^^). They operate only on two Boolean
1674bf215546Sopenharmony_ci       *     expressions and result in a Boolean expression."
1675bf215546Sopenharmony_ci       */
1676bf215546Sopenharmony_ci      op[0] = get_scalar_boolean_operand(instructions, state, this, 0, "LHS",
1677bf215546Sopenharmony_ci                                         &error_emitted);
1678bf215546Sopenharmony_ci      op[1] = get_scalar_boolean_operand(instructions, state, this, 1, "RHS",
1679bf215546Sopenharmony_ci                                         &error_emitted);
1680bf215546Sopenharmony_ci
1681bf215546Sopenharmony_ci      result = new(ctx) ir_expression(operations[this->oper], glsl_type::bool_type,
1682bf215546Sopenharmony_ci                                      op[0], op[1]);
1683bf215546Sopenharmony_ci      break;
1684bf215546Sopenharmony_ci
1685bf215546Sopenharmony_ci   case ast_logic_not:
1686bf215546Sopenharmony_ci      op[0] = get_scalar_boolean_operand(instructions, state, this, 0,
1687bf215546Sopenharmony_ci                                         "operand", &error_emitted);
1688bf215546Sopenharmony_ci
1689bf215546Sopenharmony_ci      result = new(ctx) ir_expression(operations[this->oper], glsl_type::bool_type,
1690bf215546Sopenharmony_ci                                      op[0], NULL);
1691bf215546Sopenharmony_ci      break;
1692bf215546Sopenharmony_ci
1693bf215546Sopenharmony_ci   case ast_mul_assign:
1694bf215546Sopenharmony_ci   case ast_div_assign:
1695bf215546Sopenharmony_ci   case ast_add_assign:
1696bf215546Sopenharmony_ci   case ast_sub_assign: {
1697bf215546Sopenharmony_ci      this->subexpressions[0]->set_is_lhs(true);
1698bf215546Sopenharmony_ci      op[0] = this->subexpressions[0]->hir(instructions, state);
1699bf215546Sopenharmony_ci      op[1] = this->subexpressions[1]->hir(instructions, state);
1700bf215546Sopenharmony_ci
1701bf215546Sopenharmony_ci      orig_type = op[0]->type;
1702bf215546Sopenharmony_ci
1703bf215546Sopenharmony_ci      /* Break out if operand types were not parsed successfully. */
1704bf215546Sopenharmony_ci      if ((op[0]->type == glsl_type::error_type ||
1705bf215546Sopenharmony_ci           op[1]->type == glsl_type::error_type)) {
1706bf215546Sopenharmony_ci         error_emitted = true;
1707bf215546Sopenharmony_ci         result = ir_rvalue::error_value(ctx);
1708bf215546Sopenharmony_ci         break;
1709bf215546Sopenharmony_ci      }
1710bf215546Sopenharmony_ci
1711bf215546Sopenharmony_ci      type = arithmetic_result_type(op[0], op[1],
1712bf215546Sopenharmony_ci                                    (this->oper == ast_mul_assign),
1713bf215546Sopenharmony_ci                                    state, & loc);
1714bf215546Sopenharmony_ci
1715bf215546Sopenharmony_ci      if (type != orig_type) {
1716bf215546Sopenharmony_ci         _mesa_glsl_error(& loc, state,
1717bf215546Sopenharmony_ci                          "could not implicitly convert "
1718bf215546Sopenharmony_ci                          "%s to %s", type->name, orig_type->name);
1719bf215546Sopenharmony_ci         type = glsl_type::error_type;
1720bf215546Sopenharmony_ci      }
1721bf215546Sopenharmony_ci
1722bf215546Sopenharmony_ci      ir_rvalue *temp_rhs = new(ctx) ir_expression(operations[this->oper], type,
1723bf215546Sopenharmony_ci                                                   op[0], op[1]);
1724bf215546Sopenharmony_ci
1725bf215546Sopenharmony_ci      error_emitted =
1726bf215546Sopenharmony_ci         do_assignment(instructions, state,
1727bf215546Sopenharmony_ci                       this->subexpressions[0]->non_lvalue_description,
1728bf215546Sopenharmony_ci                       op[0]->clone(ctx, NULL), temp_rhs,
1729bf215546Sopenharmony_ci                       &result, needs_rvalue, false,
1730bf215546Sopenharmony_ci                       this->subexpressions[0]->get_location());
1731bf215546Sopenharmony_ci
1732bf215546Sopenharmony_ci      /* GLSL 1.10 does not allow array assignment.  However, we don't have to
1733bf215546Sopenharmony_ci       * explicitly test for this because none of the binary expression
1734bf215546Sopenharmony_ci       * operators allow array operands either.
1735bf215546Sopenharmony_ci       */
1736bf215546Sopenharmony_ci
1737bf215546Sopenharmony_ci      break;
1738bf215546Sopenharmony_ci   }
1739bf215546Sopenharmony_ci
1740bf215546Sopenharmony_ci   case ast_mod_assign: {
1741bf215546Sopenharmony_ci      this->subexpressions[0]->set_is_lhs(true);
1742bf215546Sopenharmony_ci      op[0] = this->subexpressions[0]->hir(instructions, state);
1743bf215546Sopenharmony_ci      op[1] = this->subexpressions[1]->hir(instructions, state);
1744bf215546Sopenharmony_ci
1745bf215546Sopenharmony_ci      /* Break out if operand types were not parsed successfully. */
1746bf215546Sopenharmony_ci      if ((op[0]->type == glsl_type::error_type ||
1747bf215546Sopenharmony_ci           op[1]->type == glsl_type::error_type)) {
1748bf215546Sopenharmony_ci         error_emitted = true;
1749bf215546Sopenharmony_ci         result = ir_rvalue::error_value(ctx);
1750bf215546Sopenharmony_ci         break;
1751bf215546Sopenharmony_ci      }
1752bf215546Sopenharmony_ci
1753bf215546Sopenharmony_ci      orig_type = op[0]->type;
1754bf215546Sopenharmony_ci      type = modulus_result_type(op[0], op[1], state, &loc);
1755bf215546Sopenharmony_ci
1756bf215546Sopenharmony_ci      if (type != orig_type) {
1757bf215546Sopenharmony_ci         _mesa_glsl_error(& loc, state,
1758bf215546Sopenharmony_ci                          "could not implicitly convert "
1759bf215546Sopenharmony_ci                          "%s to %s", type->name, orig_type->name);
1760bf215546Sopenharmony_ci         type = glsl_type::error_type;
1761bf215546Sopenharmony_ci      }
1762bf215546Sopenharmony_ci
1763bf215546Sopenharmony_ci      assert(operations[this->oper] == ir_binop_mod);
1764bf215546Sopenharmony_ci
1765bf215546Sopenharmony_ci      ir_rvalue *temp_rhs;
1766bf215546Sopenharmony_ci      temp_rhs = new(ctx) ir_expression(operations[this->oper], type,
1767bf215546Sopenharmony_ci                                        op[0], op[1]);
1768bf215546Sopenharmony_ci
1769bf215546Sopenharmony_ci      error_emitted =
1770bf215546Sopenharmony_ci         do_assignment(instructions, state,
1771bf215546Sopenharmony_ci                       this->subexpressions[0]->non_lvalue_description,
1772bf215546Sopenharmony_ci                       op[0]->clone(ctx, NULL), temp_rhs,
1773bf215546Sopenharmony_ci                       &result, needs_rvalue, false,
1774bf215546Sopenharmony_ci                       this->subexpressions[0]->get_location());
1775bf215546Sopenharmony_ci      break;
1776bf215546Sopenharmony_ci   }
1777bf215546Sopenharmony_ci
1778bf215546Sopenharmony_ci   case ast_ls_assign:
1779bf215546Sopenharmony_ci   case ast_rs_assign: {
1780bf215546Sopenharmony_ci      this->subexpressions[0]->set_is_lhs(true);
1781bf215546Sopenharmony_ci      op[0] = this->subexpressions[0]->hir(instructions, state);
1782bf215546Sopenharmony_ci      op[1] = this->subexpressions[1]->hir(instructions, state);
1783bf215546Sopenharmony_ci
1784bf215546Sopenharmony_ci      /* Break out if operand types were not parsed successfully. */
1785bf215546Sopenharmony_ci      if ((op[0]->type == glsl_type::error_type ||
1786bf215546Sopenharmony_ci           op[1]->type == glsl_type::error_type)) {
1787bf215546Sopenharmony_ci         error_emitted = true;
1788bf215546Sopenharmony_ci         result = ir_rvalue::error_value(ctx);
1789bf215546Sopenharmony_ci         break;
1790bf215546Sopenharmony_ci      }
1791bf215546Sopenharmony_ci
1792bf215546Sopenharmony_ci      type = shift_result_type(op[0]->type, op[1]->type, this->oper, state,
1793bf215546Sopenharmony_ci                               &loc);
1794bf215546Sopenharmony_ci      ir_rvalue *temp_rhs = new(ctx) ir_expression(operations[this->oper],
1795bf215546Sopenharmony_ci                                                   type, op[0], op[1]);
1796bf215546Sopenharmony_ci      error_emitted =
1797bf215546Sopenharmony_ci         do_assignment(instructions, state,
1798bf215546Sopenharmony_ci                       this->subexpressions[0]->non_lvalue_description,
1799bf215546Sopenharmony_ci                       op[0]->clone(ctx, NULL), temp_rhs,
1800bf215546Sopenharmony_ci                       &result, needs_rvalue, false,
1801bf215546Sopenharmony_ci                       this->subexpressions[0]->get_location());
1802bf215546Sopenharmony_ci      break;
1803bf215546Sopenharmony_ci   }
1804bf215546Sopenharmony_ci
1805bf215546Sopenharmony_ci   case ast_and_assign:
1806bf215546Sopenharmony_ci   case ast_xor_assign:
1807bf215546Sopenharmony_ci   case ast_or_assign: {
1808bf215546Sopenharmony_ci      this->subexpressions[0]->set_is_lhs(true);
1809bf215546Sopenharmony_ci      op[0] = this->subexpressions[0]->hir(instructions, state);
1810bf215546Sopenharmony_ci      op[1] = this->subexpressions[1]->hir(instructions, state);
1811bf215546Sopenharmony_ci
1812bf215546Sopenharmony_ci      /* Break out if operand types were not parsed successfully. */
1813bf215546Sopenharmony_ci      if ((op[0]->type == glsl_type::error_type ||
1814bf215546Sopenharmony_ci           op[1]->type == glsl_type::error_type)) {
1815bf215546Sopenharmony_ci         error_emitted = true;
1816bf215546Sopenharmony_ci         result = ir_rvalue::error_value(ctx);
1817bf215546Sopenharmony_ci         break;
1818bf215546Sopenharmony_ci      }
1819bf215546Sopenharmony_ci
1820bf215546Sopenharmony_ci      orig_type = op[0]->type;
1821bf215546Sopenharmony_ci      type = bit_logic_result_type(op[0], op[1], this->oper, state, &loc);
1822bf215546Sopenharmony_ci
1823bf215546Sopenharmony_ci      if (type != orig_type) {
1824bf215546Sopenharmony_ci         _mesa_glsl_error(& loc, state,
1825bf215546Sopenharmony_ci                          "could not implicitly convert "
1826bf215546Sopenharmony_ci                          "%s to %s", type->name, orig_type->name);
1827bf215546Sopenharmony_ci         type = glsl_type::error_type;
1828bf215546Sopenharmony_ci      }
1829bf215546Sopenharmony_ci
1830bf215546Sopenharmony_ci      ir_rvalue *temp_rhs = new(ctx) ir_expression(operations[this->oper],
1831bf215546Sopenharmony_ci                                                   type, op[0], op[1]);
1832bf215546Sopenharmony_ci      error_emitted =
1833bf215546Sopenharmony_ci         do_assignment(instructions, state,
1834bf215546Sopenharmony_ci                       this->subexpressions[0]->non_lvalue_description,
1835bf215546Sopenharmony_ci                       op[0]->clone(ctx, NULL), temp_rhs,
1836bf215546Sopenharmony_ci                       &result, needs_rvalue, false,
1837bf215546Sopenharmony_ci                       this->subexpressions[0]->get_location());
1838bf215546Sopenharmony_ci      break;
1839bf215546Sopenharmony_ci   }
1840bf215546Sopenharmony_ci
1841bf215546Sopenharmony_ci   case ast_conditional: {
1842bf215546Sopenharmony_ci      /* From page 59 (page 65 of the PDF) of the GLSL 1.50 spec:
1843bf215546Sopenharmony_ci       *
1844bf215546Sopenharmony_ci       *    "The ternary selection operator (?:). It operates on three
1845bf215546Sopenharmony_ci       *    expressions (exp1 ? exp2 : exp3). This operator evaluates the
1846bf215546Sopenharmony_ci       *    first expression, which must result in a scalar Boolean."
1847bf215546Sopenharmony_ci       */
1848bf215546Sopenharmony_ci      op[0] = get_scalar_boolean_operand(instructions, state, this, 0,
1849bf215546Sopenharmony_ci                                         "condition", &error_emitted);
1850bf215546Sopenharmony_ci
1851bf215546Sopenharmony_ci      /* The :? operator is implemented by generating an anonymous temporary
1852bf215546Sopenharmony_ci       * followed by an if-statement.  The last instruction in each branch of
1853bf215546Sopenharmony_ci       * the if-statement assigns a value to the anonymous temporary.  This
1854bf215546Sopenharmony_ci       * temporary is the r-value of the expression.
1855bf215546Sopenharmony_ci       */
1856bf215546Sopenharmony_ci      exec_list then_instructions;
1857bf215546Sopenharmony_ci      exec_list else_instructions;
1858bf215546Sopenharmony_ci
1859bf215546Sopenharmony_ci      op[1] = this->subexpressions[1]->hir(&then_instructions, state);
1860bf215546Sopenharmony_ci      op[2] = this->subexpressions[2]->hir(&else_instructions, state);
1861bf215546Sopenharmony_ci
1862bf215546Sopenharmony_ci      /* From page 59 (page 65 of the PDF) of the GLSL 1.50 spec:
1863bf215546Sopenharmony_ci       *
1864bf215546Sopenharmony_ci       *     "The second and third expressions can be any type, as
1865bf215546Sopenharmony_ci       *     long their types match, or there is a conversion in
1866bf215546Sopenharmony_ci       *     Section 4.1.10 "Implicit Conversions" that can be applied
1867bf215546Sopenharmony_ci       *     to one of the expressions to make their types match. This
1868bf215546Sopenharmony_ci       *     resulting matching type is the type of the entire
1869bf215546Sopenharmony_ci       *     expression."
1870bf215546Sopenharmony_ci       */
1871bf215546Sopenharmony_ci      if ((!apply_implicit_conversion(op[1]->type, op[2], state)
1872bf215546Sopenharmony_ci          && !apply_implicit_conversion(op[2]->type, op[1], state))
1873bf215546Sopenharmony_ci          || (op[1]->type != op[2]->type)) {
1874bf215546Sopenharmony_ci         YYLTYPE loc = this->subexpressions[1]->get_location();
1875bf215546Sopenharmony_ci
1876bf215546Sopenharmony_ci         _mesa_glsl_error(& loc, state, "second and third operands of ?: "
1877bf215546Sopenharmony_ci                          "operator must have matching types");
1878bf215546Sopenharmony_ci         error_emitted = true;
1879bf215546Sopenharmony_ci         type = glsl_type::error_type;
1880bf215546Sopenharmony_ci      } else {
1881bf215546Sopenharmony_ci         type = op[1]->type;
1882bf215546Sopenharmony_ci      }
1883bf215546Sopenharmony_ci
1884bf215546Sopenharmony_ci      /* From page 33 (page 39 of the PDF) of the GLSL 1.10 spec:
1885bf215546Sopenharmony_ci       *
1886bf215546Sopenharmony_ci       *    "The second and third expressions must be the same type, but can
1887bf215546Sopenharmony_ci       *    be of any type other than an array."
1888bf215546Sopenharmony_ci       */
1889bf215546Sopenharmony_ci      if (type->is_array() &&
1890bf215546Sopenharmony_ci          !state->check_version(120, 300, &loc,
1891bf215546Sopenharmony_ci                                "second and third operands of ?: operator "
1892bf215546Sopenharmony_ci                                "cannot be arrays")) {
1893bf215546Sopenharmony_ci         error_emitted = true;
1894bf215546Sopenharmony_ci      }
1895bf215546Sopenharmony_ci
1896bf215546Sopenharmony_ci      /* From section 4.1.7 of the GLSL 4.50 spec (Opaque Types):
1897bf215546Sopenharmony_ci       *
1898bf215546Sopenharmony_ci       *  "Except for array indexing, structure member selection, and
1899bf215546Sopenharmony_ci       *   parentheses, opaque variables are not allowed to be operands in
1900bf215546Sopenharmony_ci       *   expressions; such use results in a compile-time error."
1901bf215546Sopenharmony_ci       */
1902bf215546Sopenharmony_ci      if (type->contains_opaque()) {
1903bf215546Sopenharmony_ci         if (!(state->has_bindless() && (type->is_image() || type->is_sampler()))) {
1904bf215546Sopenharmony_ci            _mesa_glsl_error(&loc, state, "variables of type %s cannot be "
1905bf215546Sopenharmony_ci                             "operands of the ?: operator", type->name);
1906bf215546Sopenharmony_ci            error_emitted = true;
1907bf215546Sopenharmony_ci         }
1908bf215546Sopenharmony_ci      }
1909bf215546Sopenharmony_ci
1910bf215546Sopenharmony_ci      ir_constant *cond_val = op[0]->constant_expression_value(ctx);
1911bf215546Sopenharmony_ci
1912bf215546Sopenharmony_ci      if (then_instructions.is_empty()
1913bf215546Sopenharmony_ci          && else_instructions.is_empty()
1914bf215546Sopenharmony_ci          && cond_val != NULL) {
1915bf215546Sopenharmony_ci         result = cond_val->value.b[0] ? op[1] : op[2];
1916bf215546Sopenharmony_ci      } else {
1917bf215546Sopenharmony_ci         /* The copy to conditional_tmp reads the whole array. */
1918bf215546Sopenharmony_ci         if (type->is_array()) {
1919bf215546Sopenharmony_ci            mark_whole_array_access(op[1]);
1920bf215546Sopenharmony_ci            mark_whole_array_access(op[2]);
1921bf215546Sopenharmony_ci         }
1922bf215546Sopenharmony_ci
1923bf215546Sopenharmony_ci         ir_variable *const tmp =
1924bf215546Sopenharmony_ci            new(ctx) ir_variable(type, "conditional_tmp", ir_var_temporary);
1925bf215546Sopenharmony_ci         instructions->push_tail(tmp);
1926bf215546Sopenharmony_ci
1927bf215546Sopenharmony_ci         ir_if *const stmt = new(ctx) ir_if(op[0]);
1928bf215546Sopenharmony_ci         instructions->push_tail(stmt);
1929bf215546Sopenharmony_ci
1930bf215546Sopenharmony_ci         then_instructions.move_nodes_to(& stmt->then_instructions);
1931bf215546Sopenharmony_ci         ir_dereference *const then_deref =
1932bf215546Sopenharmony_ci            new(ctx) ir_dereference_variable(tmp);
1933bf215546Sopenharmony_ci         ir_assignment *const then_assign =
1934bf215546Sopenharmony_ci            new(ctx) ir_assignment(then_deref, op[1]);
1935bf215546Sopenharmony_ci         stmt->then_instructions.push_tail(then_assign);
1936bf215546Sopenharmony_ci
1937bf215546Sopenharmony_ci         else_instructions.move_nodes_to(& stmt->else_instructions);
1938bf215546Sopenharmony_ci         ir_dereference *const else_deref =
1939bf215546Sopenharmony_ci            new(ctx) ir_dereference_variable(tmp);
1940bf215546Sopenharmony_ci         ir_assignment *const else_assign =
1941bf215546Sopenharmony_ci            new(ctx) ir_assignment(else_deref, op[2]);
1942bf215546Sopenharmony_ci         stmt->else_instructions.push_tail(else_assign);
1943bf215546Sopenharmony_ci
1944bf215546Sopenharmony_ci         result = new(ctx) ir_dereference_variable(tmp);
1945bf215546Sopenharmony_ci      }
1946bf215546Sopenharmony_ci      break;
1947bf215546Sopenharmony_ci   }
1948bf215546Sopenharmony_ci
1949bf215546Sopenharmony_ci   case ast_pre_inc:
1950bf215546Sopenharmony_ci   case ast_pre_dec: {
1951bf215546Sopenharmony_ci      this->non_lvalue_description = (this->oper == ast_pre_inc)
1952bf215546Sopenharmony_ci         ? "pre-increment operation" : "pre-decrement operation";
1953bf215546Sopenharmony_ci
1954bf215546Sopenharmony_ci      op[0] = this->subexpressions[0]->hir(instructions, state);
1955bf215546Sopenharmony_ci      op[1] = constant_one_for_inc_dec(ctx, op[0]->type);
1956bf215546Sopenharmony_ci
1957bf215546Sopenharmony_ci      type = arithmetic_result_type(op[0], op[1], false, state, & loc);
1958bf215546Sopenharmony_ci
1959bf215546Sopenharmony_ci      ir_rvalue *temp_rhs;
1960bf215546Sopenharmony_ci      temp_rhs = new(ctx) ir_expression(operations[this->oper], type,
1961bf215546Sopenharmony_ci                                        op[0], op[1]);
1962bf215546Sopenharmony_ci
1963bf215546Sopenharmony_ci      error_emitted =
1964bf215546Sopenharmony_ci         do_assignment(instructions, state,
1965bf215546Sopenharmony_ci                       this->subexpressions[0]->non_lvalue_description,
1966bf215546Sopenharmony_ci                       op[0]->clone(ctx, NULL), temp_rhs,
1967bf215546Sopenharmony_ci                       &result, needs_rvalue, false,
1968bf215546Sopenharmony_ci                       this->subexpressions[0]->get_location());
1969bf215546Sopenharmony_ci      break;
1970bf215546Sopenharmony_ci   }
1971bf215546Sopenharmony_ci
1972bf215546Sopenharmony_ci   case ast_post_inc:
1973bf215546Sopenharmony_ci   case ast_post_dec: {
1974bf215546Sopenharmony_ci      this->non_lvalue_description = (this->oper == ast_post_inc)
1975bf215546Sopenharmony_ci         ? "post-increment operation" : "post-decrement operation";
1976bf215546Sopenharmony_ci      op[0] = this->subexpressions[0]->hir(instructions, state);
1977bf215546Sopenharmony_ci      op[1] = constant_one_for_inc_dec(ctx, op[0]->type);
1978bf215546Sopenharmony_ci
1979bf215546Sopenharmony_ci      error_emitted = op[0]->type->is_error() || op[1]->type->is_error();
1980bf215546Sopenharmony_ci
1981bf215546Sopenharmony_ci      if (error_emitted) {
1982bf215546Sopenharmony_ci         result = ir_rvalue::error_value(ctx);
1983bf215546Sopenharmony_ci         break;
1984bf215546Sopenharmony_ci      }
1985bf215546Sopenharmony_ci
1986bf215546Sopenharmony_ci      type = arithmetic_result_type(op[0], op[1], false, state, & loc);
1987bf215546Sopenharmony_ci
1988bf215546Sopenharmony_ci      ir_rvalue *temp_rhs;
1989bf215546Sopenharmony_ci      temp_rhs = new(ctx) ir_expression(operations[this->oper], type,
1990bf215546Sopenharmony_ci                                        op[0], op[1]);
1991bf215546Sopenharmony_ci
1992bf215546Sopenharmony_ci      /* Get a temporary of a copy of the lvalue before it's modified.
1993bf215546Sopenharmony_ci       * This may get thrown away later.
1994bf215546Sopenharmony_ci       */
1995bf215546Sopenharmony_ci      result = get_lvalue_copy(instructions, op[0]->clone(ctx, NULL));
1996bf215546Sopenharmony_ci
1997bf215546Sopenharmony_ci      ir_rvalue *junk_rvalue;
1998bf215546Sopenharmony_ci      error_emitted =
1999bf215546Sopenharmony_ci         do_assignment(instructions, state,
2000bf215546Sopenharmony_ci                       this->subexpressions[0]->non_lvalue_description,
2001bf215546Sopenharmony_ci                       op[0]->clone(ctx, NULL), temp_rhs,
2002bf215546Sopenharmony_ci                       &junk_rvalue, false, false,
2003bf215546Sopenharmony_ci                       this->subexpressions[0]->get_location());
2004bf215546Sopenharmony_ci
2005bf215546Sopenharmony_ci      break;
2006bf215546Sopenharmony_ci   }
2007bf215546Sopenharmony_ci
2008bf215546Sopenharmony_ci   case ast_field_selection:
2009bf215546Sopenharmony_ci      result = _mesa_ast_field_selection_to_hir(this, instructions, state);
2010bf215546Sopenharmony_ci      break;
2011bf215546Sopenharmony_ci
2012bf215546Sopenharmony_ci   case ast_array_index: {
2013bf215546Sopenharmony_ci      YYLTYPE index_loc = subexpressions[1]->get_location();
2014bf215546Sopenharmony_ci
2015bf215546Sopenharmony_ci      /* Getting if an array is being used uninitialized is beyond what we get
2016bf215546Sopenharmony_ci       * from ir_value.data.assigned. Setting is_lhs as true would force to
2017bf215546Sopenharmony_ci       * not raise a uninitialized warning when using an array
2018bf215546Sopenharmony_ci       */
2019bf215546Sopenharmony_ci      subexpressions[0]->set_is_lhs(true);
2020bf215546Sopenharmony_ci      op[0] = subexpressions[0]->hir(instructions, state);
2021bf215546Sopenharmony_ci      op[1] = subexpressions[1]->hir(instructions, state);
2022bf215546Sopenharmony_ci
2023bf215546Sopenharmony_ci      result = _mesa_ast_array_index_to_hir(ctx, state, op[0], op[1],
2024bf215546Sopenharmony_ci                                            loc, index_loc);
2025bf215546Sopenharmony_ci
2026bf215546Sopenharmony_ci      if (result->type->is_error())
2027bf215546Sopenharmony_ci         error_emitted = true;
2028bf215546Sopenharmony_ci
2029bf215546Sopenharmony_ci      break;
2030bf215546Sopenharmony_ci   }
2031bf215546Sopenharmony_ci
2032bf215546Sopenharmony_ci   case ast_unsized_array_dim:
2033bf215546Sopenharmony_ci      unreachable("ast_unsized_array_dim: Should never get here.");
2034bf215546Sopenharmony_ci
2035bf215546Sopenharmony_ci   case ast_function_call:
2036bf215546Sopenharmony_ci      /* Should *NEVER* get here.  ast_function_call should always be handled
2037bf215546Sopenharmony_ci       * by ast_function_expression::hir.
2038bf215546Sopenharmony_ci       */
2039bf215546Sopenharmony_ci      unreachable("ast_function_call: handled elsewhere ");
2040bf215546Sopenharmony_ci
2041bf215546Sopenharmony_ci   case ast_identifier: {
2042bf215546Sopenharmony_ci      /* ast_identifier can appear several places in a full abstract syntax
2043bf215546Sopenharmony_ci       * tree.  This particular use must be at location specified in the grammar
2044bf215546Sopenharmony_ci       * as 'variable_identifier'.
2045bf215546Sopenharmony_ci       */
2046bf215546Sopenharmony_ci      ir_variable *var =
2047bf215546Sopenharmony_ci         state->symbols->get_variable(this->primary_expression.identifier);
2048bf215546Sopenharmony_ci
2049bf215546Sopenharmony_ci      if (var == NULL) {
2050bf215546Sopenharmony_ci         /* the identifier might be a subroutine name */
2051bf215546Sopenharmony_ci         char *sub_name;
2052bf215546Sopenharmony_ci         sub_name = ralloc_asprintf(ctx, "%s_%s", _mesa_shader_stage_to_subroutine_prefix(state->stage), this->primary_expression.identifier);
2053bf215546Sopenharmony_ci         var = state->symbols->get_variable(sub_name);
2054bf215546Sopenharmony_ci         ralloc_free(sub_name);
2055bf215546Sopenharmony_ci      }
2056bf215546Sopenharmony_ci
2057bf215546Sopenharmony_ci      if (var != NULL) {
2058bf215546Sopenharmony_ci         var->data.used = true;
2059bf215546Sopenharmony_ci         result = new(ctx) ir_dereference_variable(var);
2060bf215546Sopenharmony_ci
2061bf215546Sopenharmony_ci         if ((var->data.mode == ir_var_auto || var->data.mode == ir_var_shader_out)
2062bf215546Sopenharmony_ci             && !this->is_lhs
2063bf215546Sopenharmony_ci             && result->variable_referenced()->data.assigned != true
2064bf215546Sopenharmony_ci             && !is_gl_identifier(var->name)) {
2065bf215546Sopenharmony_ci            _mesa_glsl_warning(&loc, state, "`%s' used uninitialized",
2066bf215546Sopenharmony_ci                               this->primary_expression.identifier);
2067bf215546Sopenharmony_ci         }
2068bf215546Sopenharmony_ci
2069bf215546Sopenharmony_ci         if (var->is_fb_fetch_color_output()) {
2070bf215546Sopenharmony_ci            /* From the EXT_shader_framebuffer_fetch spec:
2071bf215546Sopenharmony_ci             *
2072bf215546Sopenharmony_ci             *   "Unless the GL_EXT_shader_framebuffer_fetch extension has been
2073bf215546Sopenharmony_ci             *    enabled in addition, it's an error to use gl_LastFragData if it
2074bf215546Sopenharmony_ci             *    hasn't been explicitly redeclared with layout(noncoherent)."
2075bf215546Sopenharmony_ci             */
2076bf215546Sopenharmony_ci            if (var->data.memory_coherent && !state->EXT_shader_framebuffer_fetch_enable) {
2077bf215546Sopenharmony_ci               _mesa_glsl_error(&loc, state,
2078bf215546Sopenharmony_ci                                "invalid use of framebuffer fetch output not "
2079bf215546Sopenharmony_ci                                "qualified with layout(noncoherent)");
2080bf215546Sopenharmony_ci            }
2081bf215546Sopenharmony_ci         } else if (var->data.fb_fetch_output) {
2082bf215546Sopenharmony_ci            /* From the ARM_shader_framebuffer_fetch_depth_stencil spec:
2083bf215546Sopenharmony_ci             *
2084bf215546Sopenharmony_ci             *   "It is not legal for a fragment shader to read from gl_LastFragDepthARM
2085bf215546Sopenharmony_ci             *    and gl_LastFragStencilARM if the early_fragment_tests layout qualifier
2086bf215546Sopenharmony_ci             *    is specified. This will result in a compile-time error."
2087bf215546Sopenharmony_ci             */
2088bf215546Sopenharmony_ci            if (state->fs_early_fragment_tests) {
2089bf215546Sopenharmony_ci               _mesa_glsl_error(&loc, state,
2090bf215546Sopenharmony_ci                                "invalid use of depth or stencil fetch "
2091bf215546Sopenharmony_ci                                "with early fragment tests enabled");
2092bf215546Sopenharmony_ci            }
2093bf215546Sopenharmony_ci         }
2094bf215546Sopenharmony_ci
2095bf215546Sopenharmony_ci      } else {
2096bf215546Sopenharmony_ci         _mesa_glsl_error(& loc, state, "`%s' undeclared",
2097bf215546Sopenharmony_ci                          this->primary_expression.identifier);
2098bf215546Sopenharmony_ci
2099bf215546Sopenharmony_ci         result = ir_rvalue::error_value(ctx);
2100bf215546Sopenharmony_ci         error_emitted = true;
2101bf215546Sopenharmony_ci      }
2102bf215546Sopenharmony_ci      break;
2103bf215546Sopenharmony_ci   }
2104bf215546Sopenharmony_ci
2105bf215546Sopenharmony_ci   case ast_int_constant:
2106bf215546Sopenharmony_ci      result = new(ctx) ir_constant(this->primary_expression.int_constant);
2107bf215546Sopenharmony_ci      break;
2108bf215546Sopenharmony_ci
2109bf215546Sopenharmony_ci   case ast_uint_constant:
2110bf215546Sopenharmony_ci      result = new(ctx) ir_constant(this->primary_expression.uint_constant);
2111bf215546Sopenharmony_ci      break;
2112bf215546Sopenharmony_ci
2113bf215546Sopenharmony_ci   case ast_float_constant:
2114bf215546Sopenharmony_ci      result = new(ctx) ir_constant(this->primary_expression.float_constant);
2115bf215546Sopenharmony_ci      break;
2116bf215546Sopenharmony_ci
2117bf215546Sopenharmony_ci   case ast_bool_constant:
2118bf215546Sopenharmony_ci      result = new(ctx) ir_constant(bool(this->primary_expression.bool_constant));
2119bf215546Sopenharmony_ci      break;
2120bf215546Sopenharmony_ci
2121bf215546Sopenharmony_ci   case ast_double_constant:
2122bf215546Sopenharmony_ci      result = new(ctx) ir_constant(this->primary_expression.double_constant);
2123bf215546Sopenharmony_ci      break;
2124bf215546Sopenharmony_ci
2125bf215546Sopenharmony_ci   case ast_uint64_constant:
2126bf215546Sopenharmony_ci      result = new(ctx) ir_constant(this->primary_expression.uint64_constant);
2127bf215546Sopenharmony_ci      break;
2128bf215546Sopenharmony_ci
2129bf215546Sopenharmony_ci   case ast_int64_constant:
2130bf215546Sopenharmony_ci      result = new(ctx) ir_constant(this->primary_expression.int64_constant);
2131bf215546Sopenharmony_ci      break;
2132bf215546Sopenharmony_ci
2133bf215546Sopenharmony_ci   case ast_sequence: {
2134bf215546Sopenharmony_ci      /* It should not be possible to generate a sequence in the AST without
2135bf215546Sopenharmony_ci       * any expressions in it.
2136bf215546Sopenharmony_ci       */
2137bf215546Sopenharmony_ci      assert(!this->expressions.is_empty());
2138bf215546Sopenharmony_ci
2139bf215546Sopenharmony_ci      /* The r-value of a sequence is the last expression in the sequence.  If
2140bf215546Sopenharmony_ci       * the other expressions in the sequence do not have side-effects (and
2141bf215546Sopenharmony_ci       * therefore add instructions to the instruction list), they get dropped
2142bf215546Sopenharmony_ci       * on the floor.
2143bf215546Sopenharmony_ci       */
2144bf215546Sopenharmony_ci      exec_node *previous_tail = NULL;
2145bf215546Sopenharmony_ci      YYLTYPE previous_operand_loc = loc;
2146bf215546Sopenharmony_ci
2147bf215546Sopenharmony_ci      foreach_list_typed (ast_node, ast, link, &this->expressions) {
2148bf215546Sopenharmony_ci         /* If one of the operands of comma operator does not generate any
2149bf215546Sopenharmony_ci          * code, we want to emit a warning.  At each pass through the loop
2150bf215546Sopenharmony_ci          * previous_tail will point to the last instruction in the stream
2151bf215546Sopenharmony_ci          * *before* processing the previous operand.  Naturally,
2152bf215546Sopenharmony_ci          * instructions->get_tail_raw() will point to the last instruction in
2153bf215546Sopenharmony_ci          * the stream *after* processing the previous operand.  If the two
2154bf215546Sopenharmony_ci          * pointers match, then the previous operand had no effect.
2155bf215546Sopenharmony_ci          *
2156bf215546Sopenharmony_ci          * The warning behavior here differs slightly from GCC.  GCC will
2157bf215546Sopenharmony_ci          * only emit a warning if none of the left-hand operands have an
2158bf215546Sopenharmony_ci          * effect.  However, it will emit a warning for each.  I believe that
2159bf215546Sopenharmony_ci          * there are some cases in C (especially with GCC extensions) where
2160bf215546Sopenharmony_ci          * it is useful to have an intermediate step in a sequence have no
2161bf215546Sopenharmony_ci          * effect, but I don't think these cases exist in GLSL.  Either way,
2162bf215546Sopenharmony_ci          * it would be a giant hassle to replicate that behavior.
2163bf215546Sopenharmony_ci          */
2164bf215546Sopenharmony_ci         if (previous_tail == instructions->get_tail_raw()) {
2165bf215546Sopenharmony_ci            _mesa_glsl_warning(&previous_operand_loc, state,
2166bf215546Sopenharmony_ci                               "left-hand operand of comma expression has "
2167bf215546Sopenharmony_ci                               "no effect");
2168bf215546Sopenharmony_ci         }
2169bf215546Sopenharmony_ci
2170bf215546Sopenharmony_ci         /* The tail is directly accessed instead of using the get_tail()
2171bf215546Sopenharmony_ci          * method for performance reasons.  get_tail() has extra code to
2172bf215546Sopenharmony_ci          * return NULL when the list is empty.  We don't care about that
2173bf215546Sopenharmony_ci          * here, so using get_tail_raw() is fine.
2174bf215546Sopenharmony_ci          */
2175bf215546Sopenharmony_ci         previous_tail = instructions->get_tail_raw();
2176bf215546Sopenharmony_ci         previous_operand_loc = ast->get_location();
2177bf215546Sopenharmony_ci
2178bf215546Sopenharmony_ci         result = ast->hir(instructions, state);
2179bf215546Sopenharmony_ci      }
2180bf215546Sopenharmony_ci
2181bf215546Sopenharmony_ci      /* Any errors should have already been emitted in the loop above.
2182bf215546Sopenharmony_ci       */
2183bf215546Sopenharmony_ci      error_emitted = true;
2184bf215546Sopenharmony_ci      break;
2185bf215546Sopenharmony_ci   }
2186bf215546Sopenharmony_ci   }
2187bf215546Sopenharmony_ci   type = NULL; /* use result->type, not type. */
2188bf215546Sopenharmony_ci   assert(error_emitted || (result != NULL || !needs_rvalue));
2189bf215546Sopenharmony_ci
2190bf215546Sopenharmony_ci   if (result && result->type->is_error() && !error_emitted)
2191bf215546Sopenharmony_ci      _mesa_glsl_error(& loc, state, "type mismatch");
2192bf215546Sopenharmony_ci
2193bf215546Sopenharmony_ci   return result;
2194bf215546Sopenharmony_ci}
2195bf215546Sopenharmony_ci
2196bf215546Sopenharmony_cibool
2197bf215546Sopenharmony_ciast_expression::has_sequence_subexpression() const
2198bf215546Sopenharmony_ci{
2199bf215546Sopenharmony_ci   switch (this->oper) {
2200bf215546Sopenharmony_ci   case ast_plus:
2201bf215546Sopenharmony_ci   case ast_neg:
2202bf215546Sopenharmony_ci   case ast_bit_not:
2203bf215546Sopenharmony_ci   case ast_logic_not:
2204bf215546Sopenharmony_ci   case ast_pre_inc:
2205bf215546Sopenharmony_ci   case ast_pre_dec:
2206bf215546Sopenharmony_ci   case ast_post_inc:
2207bf215546Sopenharmony_ci   case ast_post_dec:
2208bf215546Sopenharmony_ci      return this->subexpressions[0]->has_sequence_subexpression();
2209bf215546Sopenharmony_ci
2210bf215546Sopenharmony_ci   case ast_assign:
2211bf215546Sopenharmony_ci   case ast_add:
2212bf215546Sopenharmony_ci   case ast_sub:
2213bf215546Sopenharmony_ci   case ast_mul:
2214bf215546Sopenharmony_ci   case ast_div:
2215bf215546Sopenharmony_ci   case ast_mod:
2216bf215546Sopenharmony_ci   case ast_lshift:
2217bf215546Sopenharmony_ci   case ast_rshift:
2218bf215546Sopenharmony_ci   case ast_less:
2219bf215546Sopenharmony_ci   case ast_greater:
2220bf215546Sopenharmony_ci   case ast_lequal:
2221bf215546Sopenharmony_ci   case ast_gequal:
2222bf215546Sopenharmony_ci   case ast_nequal:
2223bf215546Sopenharmony_ci   case ast_equal:
2224bf215546Sopenharmony_ci   case ast_bit_and:
2225bf215546Sopenharmony_ci   case ast_bit_xor:
2226bf215546Sopenharmony_ci   case ast_bit_or:
2227bf215546Sopenharmony_ci   case ast_logic_and:
2228bf215546Sopenharmony_ci   case ast_logic_or:
2229bf215546Sopenharmony_ci   case ast_logic_xor:
2230bf215546Sopenharmony_ci   case ast_array_index:
2231bf215546Sopenharmony_ci   case ast_mul_assign:
2232bf215546Sopenharmony_ci   case ast_div_assign:
2233bf215546Sopenharmony_ci   case ast_add_assign:
2234bf215546Sopenharmony_ci   case ast_sub_assign:
2235bf215546Sopenharmony_ci   case ast_mod_assign:
2236bf215546Sopenharmony_ci   case ast_ls_assign:
2237bf215546Sopenharmony_ci   case ast_rs_assign:
2238bf215546Sopenharmony_ci   case ast_and_assign:
2239bf215546Sopenharmony_ci   case ast_xor_assign:
2240bf215546Sopenharmony_ci   case ast_or_assign:
2241bf215546Sopenharmony_ci      return this->subexpressions[0]->has_sequence_subexpression() ||
2242bf215546Sopenharmony_ci             this->subexpressions[1]->has_sequence_subexpression();
2243bf215546Sopenharmony_ci
2244bf215546Sopenharmony_ci   case ast_conditional:
2245bf215546Sopenharmony_ci      return this->subexpressions[0]->has_sequence_subexpression() ||
2246bf215546Sopenharmony_ci             this->subexpressions[1]->has_sequence_subexpression() ||
2247bf215546Sopenharmony_ci             this->subexpressions[2]->has_sequence_subexpression();
2248bf215546Sopenharmony_ci
2249bf215546Sopenharmony_ci   case ast_sequence:
2250bf215546Sopenharmony_ci      return true;
2251bf215546Sopenharmony_ci
2252bf215546Sopenharmony_ci   case ast_field_selection:
2253bf215546Sopenharmony_ci   case ast_identifier:
2254bf215546Sopenharmony_ci   case ast_int_constant:
2255bf215546Sopenharmony_ci   case ast_uint_constant:
2256bf215546Sopenharmony_ci   case ast_float_constant:
2257bf215546Sopenharmony_ci   case ast_bool_constant:
2258bf215546Sopenharmony_ci   case ast_double_constant:
2259bf215546Sopenharmony_ci   case ast_int64_constant:
2260bf215546Sopenharmony_ci   case ast_uint64_constant:
2261bf215546Sopenharmony_ci      return false;
2262bf215546Sopenharmony_ci
2263bf215546Sopenharmony_ci   case ast_aggregate:
2264bf215546Sopenharmony_ci      return false;
2265bf215546Sopenharmony_ci
2266bf215546Sopenharmony_ci   case ast_function_call:
2267bf215546Sopenharmony_ci      unreachable("should be handled by ast_function_expression::hir");
2268bf215546Sopenharmony_ci
2269bf215546Sopenharmony_ci   case ast_unsized_array_dim:
2270bf215546Sopenharmony_ci      unreachable("ast_unsized_array_dim: Should never get here.");
2271bf215546Sopenharmony_ci   }
2272bf215546Sopenharmony_ci
2273bf215546Sopenharmony_ci   return false;
2274bf215546Sopenharmony_ci}
2275bf215546Sopenharmony_ci
2276bf215546Sopenharmony_ciir_rvalue *
2277bf215546Sopenharmony_ciast_expression_statement::hir(exec_list *instructions,
2278bf215546Sopenharmony_ci                              struct _mesa_glsl_parse_state *state)
2279bf215546Sopenharmony_ci{
2280bf215546Sopenharmony_ci   /* It is possible to have expression statements that don't have an
2281bf215546Sopenharmony_ci    * expression.  This is the solitary semicolon:
2282bf215546Sopenharmony_ci    *
2283bf215546Sopenharmony_ci    * for (i = 0; i < 5; i++)
2284bf215546Sopenharmony_ci    *     ;
2285bf215546Sopenharmony_ci    *
2286bf215546Sopenharmony_ci    * In this case the expression will be NULL.  Test for NULL and don't do
2287bf215546Sopenharmony_ci    * anything in that case.
2288bf215546Sopenharmony_ci    */
2289bf215546Sopenharmony_ci   if (expression != NULL)
2290bf215546Sopenharmony_ci      expression->hir_no_rvalue(instructions, state);
2291bf215546Sopenharmony_ci
2292bf215546Sopenharmony_ci   /* Statements do not have r-values.
2293bf215546Sopenharmony_ci    */
2294bf215546Sopenharmony_ci   return NULL;
2295bf215546Sopenharmony_ci}
2296bf215546Sopenharmony_ci
2297bf215546Sopenharmony_ci
2298bf215546Sopenharmony_ciir_rvalue *
2299bf215546Sopenharmony_ciast_compound_statement::hir(exec_list *instructions,
2300bf215546Sopenharmony_ci                            struct _mesa_glsl_parse_state *state)
2301bf215546Sopenharmony_ci{
2302bf215546Sopenharmony_ci   if (new_scope)
2303bf215546Sopenharmony_ci      state->symbols->push_scope();
2304bf215546Sopenharmony_ci
2305bf215546Sopenharmony_ci   foreach_list_typed (ast_node, ast, link, &this->statements)
2306bf215546Sopenharmony_ci      ast->hir(instructions, state);
2307bf215546Sopenharmony_ci
2308bf215546Sopenharmony_ci   if (new_scope)
2309bf215546Sopenharmony_ci      state->symbols->pop_scope();
2310bf215546Sopenharmony_ci
2311bf215546Sopenharmony_ci   /* Compound statements do not have r-values.
2312bf215546Sopenharmony_ci    */
2313bf215546Sopenharmony_ci   return NULL;
2314bf215546Sopenharmony_ci}
2315bf215546Sopenharmony_ci
2316bf215546Sopenharmony_ci/**
2317bf215546Sopenharmony_ci * Evaluate the given exec_node (which should be an ast_node representing
2318bf215546Sopenharmony_ci * a single array dimension) and return its integer value.
2319bf215546Sopenharmony_ci */
2320bf215546Sopenharmony_cistatic unsigned
2321bf215546Sopenharmony_ciprocess_array_size(exec_node *node,
2322bf215546Sopenharmony_ci                   struct _mesa_glsl_parse_state *state)
2323bf215546Sopenharmony_ci{
2324bf215546Sopenharmony_ci   void *mem_ctx = state;
2325bf215546Sopenharmony_ci
2326bf215546Sopenharmony_ci   exec_list dummy_instructions;
2327bf215546Sopenharmony_ci
2328bf215546Sopenharmony_ci   ast_node *array_size = exec_node_data(ast_node, node, link);
2329bf215546Sopenharmony_ci
2330bf215546Sopenharmony_ci   /**
2331bf215546Sopenharmony_ci    * Dimensions other than the outermost dimension can by unsized if they
2332bf215546Sopenharmony_ci    * are immediately sized by a constructor or initializer.
2333bf215546Sopenharmony_ci    */
2334bf215546Sopenharmony_ci   if (((ast_expression*)array_size)->oper == ast_unsized_array_dim)
2335bf215546Sopenharmony_ci      return 0;
2336bf215546Sopenharmony_ci
2337bf215546Sopenharmony_ci   ir_rvalue *const ir = array_size->hir(& dummy_instructions, state);
2338bf215546Sopenharmony_ci   YYLTYPE loc = array_size->get_location();
2339bf215546Sopenharmony_ci
2340bf215546Sopenharmony_ci   if (ir == NULL) {
2341bf215546Sopenharmony_ci      _mesa_glsl_error(& loc, state,
2342bf215546Sopenharmony_ci                       "array size could not be resolved");
2343bf215546Sopenharmony_ci      return 0;
2344bf215546Sopenharmony_ci   }
2345bf215546Sopenharmony_ci
2346bf215546Sopenharmony_ci   if (!ir->type->is_integer_32()) {
2347bf215546Sopenharmony_ci      _mesa_glsl_error(& loc, state,
2348bf215546Sopenharmony_ci                       "array size must be integer type");
2349bf215546Sopenharmony_ci      return 0;
2350bf215546Sopenharmony_ci   }
2351bf215546Sopenharmony_ci
2352bf215546Sopenharmony_ci   if (!ir->type->is_scalar()) {
2353bf215546Sopenharmony_ci      _mesa_glsl_error(& loc, state,
2354bf215546Sopenharmony_ci                       "array size must be scalar type");
2355bf215546Sopenharmony_ci      return 0;
2356bf215546Sopenharmony_ci   }
2357bf215546Sopenharmony_ci
2358bf215546Sopenharmony_ci   ir_constant *const size = ir->constant_expression_value(mem_ctx);
2359bf215546Sopenharmony_ci   if (size == NULL ||
2360bf215546Sopenharmony_ci       (state->is_version(120, 300) &&
2361bf215546Sopenharmony_ci        array_size->has_sequence_subexpression())) {
2362bf215546Sopenharmony_ci      _mesa_glsl_error(& loc, state, "array size must be a "
2363bf215546Sopenharmony_ci                       "constant valued expression");
2364bf215546Sopenharmony_ci      return 0;
2365bf215546Sopenharmony_ci   }
2366bf215546Sopenharmony_ci
2367bf215546Sopenharmony_ci   if (size->value.i[0] <= 0) {
2368bf215546Sopenharmony_ci      _mesa_glsl_error(& loc, state, "array size must be > 0");
2369bf215546Sopenharmony_ci      return 0;
2370bf215546Sopenharmony_ci   }
2371bf215546Sopenharmony_ci
2372bf215546Sopenharmony_ci   assert(size->type == ir->type);
2373bf215546Sopenharmony_ci
2374bf215546Sopenharmony_ci   /* If the array size is const (and we've verified that
2375bf215546Sopenharmony_ci    * it is) then no instructions should have been emitted
2376bf215546Sopenharmony_ci    * when we converted it to HIR. If they were emitted,
2377bf215546Sopenharmony_ci    * then either the array size isn't const after all, or
2378bf215546Sopenharmony_ci    * we are emitting unnecessary instructions.
2379bf215546Sopenharmony_ci    */
2380bf215546Sopenharmony_ci   assert(dummy_instructions.is_empty());
2381bf215546Sopenharmony_ci
2382bf215546Sopenharmony_ci   return size->value.u[0];
2383bf215546Sopenharmony_ci}
2384bf215546Sopenharmony_ci
2385bf215546Sopenharmony_cistatic const glsl_type *
2386bf215546Sopenharmony_ciprocess_array_type(YYLTYPE *loc, const glsl_type *base,
2387bf215546Sopenharmony_ci                   ast_array_specifier *array_specifier,
2388bf215546Sopenharmony_ci                   struct _mesa_glsl_parse_state *state)
2389bf215546Sopenharmony_ci{
2390bf215546Sopenharmony_ci   const glsl_type *array_type = base;
2391bf215546Sopenharmony_ci
2392bf215546Sopenharmony_ci   if (array_specifier != NULL) {
2393bf215546Sopenharmony_ci      if (base->is_array()) {
2394bf215546Sopenharmony_ci
2395bf215546Sopenharmony_ci         /* From page 19 (page 25) of the GLSL 1.20 spec:
2396bf215546Sopenharmony_ci          *
2397bf215546Sopenharmony_ci          * "Only one-dimensional arrays may be declared."
2398bf215546Sopenharmony_ci          */
2399bf215546Sopenharmony_ci         if (!state->check_arrays_of_arrays_allowed(loc)) {
2400bf215546Sopenharmony_ci            return glsl_type::error_type;
2401bf215546Sopenharmony_ci         }
2402bf215546Sopenharmony_ci      }
2403bf215546Sopenharmony_ci
2404bf215546Sopenharmony_ci      for (exec_node *node = array_specifier->array_dimensions.get_tail_raw();
2405bf215546Sopenharmony_ci           !node->is_head_sentinel(); node = node->prev) {
2406bf215546Sopenharmony_ci         unsigned array_size = process_array_size(node, state);
2407bf215546Sopenharmony_ci         array_type = glsl_type::get_array_instance(array_type, array_size);
2408bf215546Sopenharmony_ci      }
2409bf215546Sopenharmony_ci   }
2410bf215546Sopenharmony_ci
2411bf215546Sopenharmony_ci   return array_type;
2412bf215546Sopenharmony_ci}
2413bf215546Sopenharmony_ci
2414bf215546Sopenharmony_cistatic bool
2415bf215546Sopenharmony_ciprecision_qualifier_allowed(const glsl_type *type)
2416bf215546Sopenharmony_ci{
2417bf215546Sopenharmony_ci   /* Precision qualifiers apply to floating point, integer and opaque
2418bf215546Sopenharmony_ci    * types.
2419bf215546Sopenharmony_ci    *
2420bf215546Sopenharmony_ci    * Section 4.5.2 (Precision Qualifiers) of the GLSL 1.30 spec says:
2421bf215546Sopenharmony_ci    *    "Any floating point or any integer declaration can have the type
2422bf215546Sopenharmony_ci    *    preceded by one of these precision qualifiers [...] Literal
2423bf215546Sopenharmony_ci    *    constants do not have precision qualifiers. Neither do Boolean
2424bf215546Sopenharmony_ci    *    variables.
2425bf215546Sopenharmony_ci    *
2426bf215546Sopenharmony_ci    * Section 4.5 (Precision and Precision Qualifiers) of the GLSL 1.30
2427bf215546Sopenharmony_ci    * spec also says:
2428bf215546Sopenharmony_ci    *
2429bf215546Sopenharmony_ci    *     "Precision qualifiers are added for code portability with OpenGL
2430bf215546Sopenharmony_ci    *     ES, not for functionality. They have the same syntax as in OpenGL
2431bf215546Sopenharmony_ci    *     ES."
2432bf215546Sopenharmony_ci    *
2433bf215546Sopenharmony_ci    * Section 8 (Built-In Functions) of the GLSL ES 1.00 spec says:
2434bf215546Sopenharmony_ci    *
2435bf215546Sopenharmony_ci    *     "uniform lowp sampler2D sampler;
2436bf215546Sopenharmony_ci    *     highp vec2 coord;
2437bf215546Sopenharmony_ci    *     ...
2438bf215546Sopenharmony_ci    *     lowp vec4 col = texture2D (sampler, coord);
2439bf215546Sopenharmony_ci    *                                            // texture2D returns lowp"
2440bf215546Sopenharmony_ci    *
2441bf215546Sopenharmony_ci    * From this, we infer that GLSL 1.30 (and later) should allow precision
2442bf215546Sopenharmony_ci    * qualifiers on sampler types just like float and integer types.
2443bf215546Sopenharmony_ci    */
2444bf215546Sopenharmony_ci   const glsl_type *const t = type->without_array();
2445bf215546Sopenharmony_ci
2446bf215546Sopenharmony_ci   return (t->is_float() || t->is_integer_32() || t->contains_opaque()) &&
2447bf215546Sopenharmony_ci          !t->is_struct();
2448bf215546Sopenharmony_ci}
2449bf215546Sopenharmony_ci
2450bf215546Sopenharmony_ciconst glsl_type *
2451bf215546Sopenharmony_ciast_type_specifier::glsl_type(const char **name,
2452bf215546Sopenharmony_ci                              struct _mesa_glsl_parse_state *state) const
2453bf215546Sopenharmony_ci{
2454bf215546Sopenharmony_ci   const struct glsl_type *type;
2455bf215546Sopenharmony_ci
2456bf215546Sopenharmony_ci   if (this->type != NULL)
2457bf215546Sopenharmony_ci      type = this->type;
2458bf215546Sopenharmony_ci   else if (structure)
2459bf215546Sopenharmony_ci      type = structure->type;
2460bf215546Sopenharmony_ci   else
2461bf215546Sopenharmony_ci      type = state->symbols->get_type(this->type_name);
2462bf215546Sopenharmony_ci   *name = this->type_name;
2463bf215546Sopenharmony_ci
2464bf215546Sopenharmony_ci   YYLTYPE loc = this->get_location();
2465bf215546Sopenharmony_ci   type = process_array_type(&loc, type, this->array_specifier, state);
2466bf215546Sopenharmony_ci
2467bf215546Sopenharmony_ci   return type;
2468bf215546Sopenharmony_ci}
2469bf215546Sopenharmony_ci
2470bf215546Sopenharmony_ci/**
2471bf215546Sopenharmony_ci * From the OpenGL ES 3.0 spec, 4.5.4 Default Precision Qualifiers:
2472bf215546Sopenharmony_ci *
2473bf215546Sopenharmony_ci * "The precision statement
2474bf215546Sopenharmony_ci *
2475bf215546Sopenharmony_ci *    precision precision-qualifier type;
2476bf215546Sopenharmony_ci *
2477bf215546Sopenharmony_ci *  can be used to establish a default precision qualifier. The type field can
2478bf215546Sopenharmony_ci *  be either int or float or any of the sampler types, (...) If type is float,
2479bf215546Sopenharmony_ci *  the directive applies to non-precision-qualified floating point type
2480bf215546Sopenharmony_ci *  (scalar, vector, and matrix) declarations. If type is int, the directive
2481bf215546Sopenharmony_ci *  applies to all non-precision-qualified integer type (scalar, vector, signed,
2482bf215546Sopenharmony_ci *  and unsigned) declarations."
2483bf215546Sopenharmony_ci *
2484bf215546Sopenharmony_ci * We use the symbol table to keep the values of the default precisions for
2485bf215546Sopenharmony_ci * each 'type' in each scope and we use the 'type' string from the precision
2486bf215546Sopenharmony_ci * statement as key in the symbol table. When we want to retrieve the default
2487bf215546Sopenharmony_ci * precision associated with a given glsl_type we need to know the type string
2488bf215546Sopenharmony_ci * associated with it. This is what this function returns.
2489bf215546Sopenharmony_ci */
2490bf215546Sopenharmony_cistatic const char *
2491bf215546Sopenharmony_ciget_type_name_for_precision_qualifier(const glsl_type *type)
2492bf215546Sopenharmony_ci{
2493bf215546Sopenharmony_ci   switch (type->base_type) {
2494bf215546Sopenharmony_ci   case GLSL_TYPE_FLOAT:
2495bf215546Sopenharmony_ci      return "float";
2496bf215546Sopenharmony_ci   case GLSL_TYPE_UINT:
2497bf215546Sopenharmony_ci   case GLSL_TYPE_INT:
2498bf215546Sopenharmony_ci      return "int";
2499bf215546Sopenharmony_ci   case GLSL_TYPE_ATOMIC_UINT:
2500bf215546Sopenharmony_ci      return "atomic_uint";
2501bf215546Sopenharmony_ci   case GLSL_TYPE_IMAGE:
2502bf215546Sopenharmony_ci   FALLTHROUGH;
2503bf215546Sopenharmony_ci   case GLSL_TYPE_SAMPLER: {
2504bf215546Sopenharmony_ci      const unsigned type_idx =
2505bf215546Sopenharmony_ci         type->sampler_array + 2 * type->sampler_shadow;
2506bf215546Sopenharmony_ci      const unsigned offset = type->is_sampler() ? 0 : 4;
2507bf215546Sopenharmony_ci      assert(type_idx < 4);
2508bf215546Sopenharmony_ci      switch (type->sampled_type) {
2509bf215546Sopenharmony_ci      case GLSL_TYPE_FLOAT:
2510bf215546Sopenharmony_ci         switch (type->sampler_dimensionality) {
2511bf215546Sopenharmony_ci         case GLSL_SAMPLER_DIM_1D: {
2512bf215546Sopenharmony_ci            assert(type->is_sampler());
2513bf215546Sopenharmony_ci            static const char *const names[4] = {
2514bf215546Sopenharmony_ci              "sampler1D", "sampler1DArray",
2515bf215546Sopenharmony_ci              "sampler1DShadow", "sampler1DArrayShadow"
2516bf215546Sopenharmony_ci            };
2517bf215546Sopenharmony_ci            return names[type_idx];
2518bf215546Sopenharmony_ci         }
2519bf215546Sopenharmony_ci         case GLSL_SAMPLER_DIM_2D: {
2520bf215546Sopenharmony_ci            static const char *const names[8] = {
2521bf215546Sopenharmony_ci              "sampler2D", "sampler2DArray",
2522bf215546Sopenharmony_ci              "sampler2DShadow", "sampler2DArrayShadow",
2523bf215546Sopenharmony_ci              "image2D", "image2DArray", NULL, NULL
2524bf215546Sopenharmony_ci            };
2525bf215546Sopenharmony_ci            return names[offset + type_idx];
2526bf215546Sopenharmony_ci         }
2527bf215546Sopenharmony_ci         case GLSL_SAMPLER_DIM_3D: {
2528bf215546Sopenharmony_ci            static const char *const names[8] = {
2529bf215546Sopenharmony_ci              "sampler3D", NULL, NULL, NULL,
2530bf215546Sopenharmony_ci              "image3D", NULL, NULL, NULL
2531bf215546Sopenharmony_ci            };
2532bf215546Sopenharmony_ci            return names[offset + type_idx];
2533bf215546Sopenharmony_ci         }
2534bf215546Sopenharmony_ci         case GLSL_SAMPLER_DIM_CUBE: {
2535bf215546Sopenharmony_ci            static const char *const names[8] = {
2536bf215546Sopenharmony_ci              "samplerCube", "samplerCubeArray",
2537bf215546Sopenharmony_ci              "samplerCubeShadow", "samplerCubeArrayShadow",
2538bf215546Sopenharmony_ci              "imageCube", NULL, NULL, NULL
2539bf215546Sopenharmony_ci            };
2540bf215546Sopenharmony_ci            return names[offset + type_idx];
2541bf215546Sopenharmony_ci         }
2542bf215546Sopenharmony_ci         case GLSL_SAMPLER_DIM_MS: {
2543bf215546Sopenharmony_ci            assert(type->is_sampler());
2544bf215546Sopenharmony_ci            static const char *const names[4] = {
2545bf215546Sopenharmony_ci              "sampler2DMS", "sampler2DMSArray", NULL, NULL
2546bf215546Sopenharmony_ci            };
2547bf215546Sopenharmony_ci            return names[type_idx];
2548bf215546Sopenharmony_ci         }
2549bf215546Sopenharmony_ci         case GLSL_SAMPLER_DIM_RECT: {
2550bf215546Sopenharmony_ci            assert(type->is_sampler());
2551bf215546Sopenharmony_ci            static const char *const names[4] = {
2552bf215546Sopenharmony_ci              "samplerRect", NULL, "samplerRectShadow", NULL
2553bf215546Sopenharmony_ci            };
2554bf215546Sopenharmony_ci            return names[type_idx];
2555bf215546Sopenharmony_ci         }
2556bf215546Sopenharmony_ci         case GLSL_SAMPLER_DIM_BUF: {
2557bf215546Sopenharmony_ci            static const char *const names[8] = {
2558bf215546Sopenharmony_ci              "samplerBuffer", NULL, NULL, NULL,
2559bf215546Sopenharmony_ci              "imageBuffer", NULL, NULL, NULL
2560bf215546Sopenharmony_ci            };
2561bf215546Sopenharmony_ci            return names[offset + type_idx];
2562bf215546Sopenharmony_ci         }
2563bf215546Sopenharmony_ci         case GLSL_SAMPLER_DIM_EXTERNAL: {
2564bf215546Sopenharmony_ci            assert(type->is_sampler());
2565bf215546Sopenharmony_ci            static const char *const names[4] = {
2566bf215546Sopenharmony_ci              "samplerExternalOES", NULL, NULL, NULL
2567bf215546Sopenharmony_ci            };
2568bf215546Sopenharmony_ci            return names[type_idx];
2569bf215546Sopenharmony_ci         }
2570bf215546Sopenharmony_ci         default:
2571bf215546Sopenharmony_ci            unreachable("Unsupported sampler/image dimensionality");
2572bf215546Sopenharmony_ci         } /* sampler/image float dimensionality */
2573bf215546Sopenharmony_ci         break;
2574bf215546Sopenharmony_ci      case GLSL_TYPE_INT:
2575bf215546Sopenharmony_ci         switch (type->sampler_dimensionality) {
2576bf215546Sopenharmony_ci         case GLSL_SAMPLER_DIM_1D: {
2577bf215546Sopenharmony_ci            assert(type->is_sampler());
2578bf215546Sopenharmony_ci            static const char *const names[4] = {
2579bf215546Sopenharmony_ci              "isampler1D", "isampler1DArray", NULL, NULL
2580bf215546Sopenharmony_ci            };
2581bf215546Sopenharmony_ci            return names[type_idx];
2582bf215546Sopenharmony_ci         }
2583bf215546Sopenharmony_ci         case GLSL_SAMPLER_DIM_2D: {
2584bf215546Sopenharmony_ci            static const char *const names[8] = {
2585bf215546Sopenharmony_ci              "isampler2D", "isampler2DArray", NULL, NULL,
2586bf215546Sopenharmony_ci              "iimage2D", "iimage2DArray", NULL, NULL
2587bf215546Sopenharmony_ci            };
2588bf215546Sopenharmony_ci            return names[offset + type_idx];
2589bf215546Sopenharmony_ci         }
2590bf215546Sopenharmony_ci         case GLSL_SAMPLER_DIM_3D: {
2591bf215546Sopenharmony_ci            static const char *const names[8] = {
2592bf215546Sopenharmony_ci              "isampler3D", NULL, NULL, NULL,
2593bf215546Sopenharmony_ci              "iimage3D", NULL, NULL, NULL
2594bf215546Sopenharmony_ci            };
2595bf215546Sopenharmony_ci            return names[offset + type_idx];
2596bf215546Sopenharmony_ci         }
2597bf215546Sopenharmony_ci         case GLSL_SAMPLER_DIM_CUBE: {
2598bf215546Sopenharmony_ci            static const char *const names[8] = {
2599bf215546Sopenharmony_ci              "isamplerCube", "isamplerCubeArray", NULL, NULL,
2600bf215546Sopenharmony_ci              "iimageCube", NULL, NULL, NULL
2601bf215546Sopenharmony_ci            };
2602bf215546Sopenharmony_ci            return names[offset + type_idx];
2603bf215546Sopenharmony_ci         }
2604bf215546Sopenharmony_ci         case GLSL_SAMPLER_DIM_MS: {
2605bf215546Sopenharmony_ci            assert(type->is_sampler());
2606bf215546Sopenharmony_ci            static const char *const names[4] = {
2607bf215546Sopenharmony_ci              "isampler2DMS", "isampler2DMSArray", NULL, NULL
2608bf215546Sopenharmony_ci            };
2609bf215546Sopenharmony_ci            return names[type_idx];
2610bf215546Sopenharmony_ci         }
2611bf215546Sopenharmony_ci         case GLSL_SAMPLER_DIM_RECT: {
2612bf215546Sopenharmony_ci            assert(type->is_sampler());
2613bf215546Sopenharmony_ci            static const char *const names[4] = {
2614bf215546Sopenharmony_ci              "isamplerRect", NULL, "isamplerRectShadow", NULL
2615bf215546Sopenharmony_ci            };
2616bf215546Sopenharmony_ci            return names[type_idx];
2617bf215546Sopenharmony_ci         }
2618bf215546Sopenharmony_ci         case GLSL_SAMPLER_DIM_BUF: {
2619bf215546Sopenharmony_ci            static const char *const names[8] = {
2620bf215546Sopenharmony_ci              "isamplerBuffer", NULL, NULL, NULL,
2621bf215546Sopenharmony_ci              "iimageBuffer", NULL, NULL, NULL
2622bf215546Sopenharmony_ci            };
2623bf215546Sopenharmony_ci            return names[offset + type_idx];
2624bf215546Sopenharmony_ci         }
2625bf215546Sopenharmony_ci         default:
2626bf215546Sopenharmony_ci            unreachable("Unsupported isampler/iimage dimensionality");
2627bf215546Sopenharmony_ci         } /* sampler/image int dimensionality */
2628bf215546Sopenharmony_ci         break;
2629bf215546Sopenharmony_ci      case GLSL_TYPE_UINT:
2630bf215546Sopenharmony_ci         switch (type->sampler_dimensionality) {
2631bf215546Sopenharmony_ci         case GLSL_SAMPLER_DIM_1D: {
2632bf215546Sopenharmony_ci            assert(type->is_sampler());
2633bf215546Sopenharmony_ci            static const char *const names[4] = {
2634bf215546Sopenharmony_ci              "usampler1D", "usampler1DArray", NULL, NULL
2635bf215546Sopenharmony_ci            };
2636bf215546Sopenharmony_ci            return names[type_idx];
2637bf215546Sopenharmony_ci         }
2638bf215546Sopenharmony_ci         case GLSL_SAMPLER_DIM_2D: {
2639bf215546Sopenharmony_ci            static const char *const names[8] = {
2640bf215546Sopenharmony_ci              "usampler2D", "usampler2DArray", NULL, NULL,
2641bf215546Sopenharmony_ci              "uimage2D", "uimage2DArray", NULL, NULL
2642bf215546Sopenharmony_ci            };
2643bf215546Sopenharmony_ci            return names[offset + type_idx];
2644bf215546Sopenharmony_ci         }
2645bf215546Sopenharmony_ci         case GLSL_SAMPLER_DIM_3D: {
2646bf215546Sopenharmony_ci            static const char *const names[8] = {
2647bf215546Sopenharmony_ci              "usampler3D", NULL, NULL, NULL,
2648bf215546Sopenharmony_ci              "uimage3D", NULL, NULL, NULL
2649bf215546Sopenharmony_ci            };
2650bf215546Sopenharmony_ci            return names[offset + type_idx];
2651bf215546Sopenharmony_ci         }
2652bf215546Sopenharmony_ci         case GLSL_SAMPLER_DIM_CUBE: {
2653bf215546Sopenharmony_ci            static const char *const names[8] = {
2654bf215546Sopenharmony_ci              "usamplerCube", "usamplerCubeArray", NULL, NULL,
2655bf215546Sopenharmony_ci              "uimageCube", NULL, NULL, NULL
2656bf215546Sopenharmony_ci            };
2657bf215546Sopenharmony_ci            return names[offset + type_idx];
2658bf215546Sopenharmony_ci         }
2659bf215546Sopenharmony_ci         case GLSL_SAMPLER_DIM_MS: {
2660bf215546Sopenharmony_ci            assert(type->is_sampler());
2661bf215546Sopenharmony_ci            static const char *const names[4] = {
2662bf215546Sopenharmony_ci              "usampler2DMS", "usampler2DMSArray", NULL, NULL
2663bf215546Sopenharmony_ci            };
2664bf215546Sopenharmony_ci            return names[type_idx];
2665bf215546Sopenharmony_ci         }
2666bf215546Sopenharmony_ci         case GLSL_SAMPLER_DIM_RECT: {
2667bf215546Sopenharmony_ci            assert(type->is_sampler());
2668bf215546Sopenharmony_ci            static const char *const names[4] = {
2669bf215546Sopenharmony_ci              "usamplerRect", NULL, "usamplerRectShadow", NULL
2670bf215546Sopenharmony_ci            };
2671bf215546Sopenharmony_ci            return names[type_idx];
2672bf215546Sopenharmony_ci         }
2673bf215546Sopenharmony_ci         case GLSL_SAMPLER_DIM_BUF: {
2674bf215546Sopenharmony_ci            static const char *const names[8] = {
2675bf215546Sopenharmony_ci              "usamplerBuffer", NULL, NULL, NULL,
2676bf215546Sopenharmony_ci              "uimageBuffer", NULL, NULL, NULL
2677bf215546Sopenharmony_ci            };
2678bf215546Sopenharmony_ci            return names[offset + type_idx];
2679bf215546Sopenharmony_ci         }
2680bf215546Sopenharmony_ci         default:
2681bf215546Sopenharmony_ci            unreachable("Unsupported usampler/uimage dimensionality");
2682bf215546Sopenharmony_ci         } /* sampler/image uint dimensionality */
2683bf215546Sopenharmony_ci         break;
2684bf215546Sopenharmony_ci      default:
2685bf215546Sopenharmony_ci         unreachable("Unsupported sampler/image type");
2686bf215546Sopenharmony_ci      } /* sampler/image type */
2687bf215546Sopenharmony_ci      break;
2688bf215546Sopenharmony_ci   } /* GLSL_TYPE_SAMPLER/GLSL_TYPE_IMAGE */
2689bf215546Sopenharmony_ci   break;
2690bf215546Sopenharmony_ci   default:
2691bf215546Sopenharmony_ci      unreachable("Unsupported type");
2692bf215546Sopenharmony_ci   } /* base type */
2693bf215546Sopenharmony_ci}
2694bf215546Sopenharmony_ci
2695bf215546Sopenharmony_cistatic unsigned
2696bf215546Sopenharmony_ciselect_gles_precision(unsigned qual_precision,
2697bf215546Sopenharmony_ci                      const glsl_type *type,
2698bf215546Sopenharmony_ci                      struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
2699bf215546Sopenharmony_ci{
2700bf215546Sopenharmony_ci   /* Precision qualifiers do not have any meaning in Desktop GLSL.
2701bf215546Sopenharmony_ci    * In GLES we take the precision from the type qualifier if present,
2702bf215546Sopenharmony_ci    * otherwise, if the type of the variable allows precision qualifiers at
2703bf215546Sopenharmony_ci    * all, we look for the default precision qualifier for that type in the
2704bf215546Sopenharmony_ci    * current scope.
2705bf215546Sopenharmony_ci    */
2706bf215546Sopenharmony_ci   assert(state->es_shader);
2707bf215546Sopenharmony_ci
2708bf215546Sopenharmony_ci   unsigned precision = GLSL_PRECISION_NONE;
2709bf215546Sopenharmony_ci   if (qual_precision) {
2710bf215546Sopenharmony_ci      precision = qual_precision;
2711bf215546Sopenharmony_ci   } else if (precision_qualifier_allowed(type)) {
2712bf215546Sopenharmony_ci      const char *type_name =
2713bf215546Sopenharmony_ci         get_type_name_for_precision_qualifier(type->without_array());
2714bf215546Sopenharmony_ci      assert(type_name != NULL);
2715bf215546Sopenharmony_ci
2716bf215546Sopenharmony_ci      precision =
2717bf215546Sopenharmony_ci         state->symbols->get_default_precision_qualifier(type_name);
2718bf215546Sopenharmony_ci      if (precision == ast_precision_none) {
2719bf215546Sopenharmony_ci         _mesa_glsl_error(loc, state,
2720bf215546Sopenharmony_ci                          "No precision specified in this scope for type `%s'",
2721bf215546Sopenharmony_ci                          type->name);
2722bf215546Sopenharmony_ci      }
2723bf215546Sopenharmony_ci   }
2724bf215546Sopenharmony_ci
2725bf215546Sopenharmony_ci
2726bf215546Sopenharmony_ci   /* Section 4.1.7.3 (Atomic Counters) of the GLSL ES 3.10 spec says:
2727bf215546Sopenharmony_ci    *
2728bf215546Sopenharmony_ci    *    "The default precision of all atomic types is highp. It is an error to
2729bf215546Sopenharmony_ci    *    declare an atomic type with a different precision or to specify the
2730bf215546Sopenharmony_ci    *    default precision for an atomic type to be lowp or mediump."
2731bf215546Sopenharmony_ci    */
2732bf215546Sopenharmony_ci   if (type->is_atomic_uint() && precision != ast_precision_high) {
2733bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state,
2734bf215546Sopenharmony_ci                       "atomic_uint can only have highp precision qualifier");
2735bf215546Sopenharmony_ci   }
2736bf215546Sopenharmony_ci
2737bf215546Sopenharmony_ci   return precision;
2738bf215546Sopenharmony_ci}
2739bf215546Sopenharmony_ci
2740bf215546Sopenharmony_ciconst glsl_type *
2741bf215546Sopenharmony_ciast_fully_specified_type::glsl_type(const char **name,
2742bf215546Sopenharmony_ci                                    struct _mesa_glsl_parse_state *state) const
2743bf215546Sopenharmony_ci{
2744bf215546Sopenharmony_ci   return this->specifier->glsl_type(name, state);
2745bf215546Sopenharmony_ci}
2746bf215546Sopenharmony_ci
2747bf215546Sopenharmony_ci/**
2748bf215546Sopenharmony_ci * Determine whether a toplevel variable declaration declares a varying.  This
2749bf215546Sopenharmony_ci * function operates by examining the variable's mode and the shader target,
2750bf215546Sopenharmony_ci * so it correctly identifies linkage variables regardless of whether they are
2751bf215546Sopenharmony_ci * declared using the deprecated "varying" syntax or the new "in/out" syntax.
2752bf215546Sopenharmony_ci *
2753bf215546Sopenharmony_ci * Passing a non-toplevel variable declaration (e.g. a function parameter) to
2754bf215546Sopenharmony_ci * this function will produce undefined results.
2755bf215546Sopenharmony_ci */
2756bf215546Sopenharmony_cistatic bool
2757bf215546Sopenharmony_ciis_varying_var(ir_variable *var, gl_shader_stage target)
2758bf215546Sopenharmony_ci{
2759bf215546Sopenharmony_ci   switch (target) {
2760bf215546Sopenharmony_ci   case MESA_SHADER_VERTEX:
2761bf215546Sopenharmony_ci      return var->data.mode == ir_var_shader_out;
2762bf215546Sopenharmony_ci   case MESA_SHADER_FRAGMENT:
2763bf215546Sopenharmony_ci      return var->data.mode == ir_var_shader_in ||
2764bf215546Sopenharmony_ci             (var->data.mode == ir_var_system_value &&
2765bf215546Sopenharmony_ci              var->data.location == SYSTEM_VALUE_FRAG_COORD);
2766bf215546Sopenharmony_ci   default:
2767bf215546Sopenharmony_ci      return var->data.mode == ir_var_shader_out || var->data.mode == ir_var_shader_in;
2768bf215546Sopenharmony_ci   }
2769bf215546Sopenharmony_ci}
2770bf215546Sopenharmony_ci
2771bf215546Sopenharmony_cistatic bool
2772bf215546Sopenharmony_ciis_allowed_invariant(ir_variable *var, struct _mesa_glsl_parse_state *state)
2773bf215546Sopenharmony_ci{
2774bf215546Sopenharmony_ci   if (is_varying_var(var, state->stage))
2775bf215546Sopenharmony_ci      return true;
2776bf215546Sopenharmony_ci
2777bf215546Sopenharmony_ci   /* From Section 4.6.1 ("The Invariant Qualifier") GLSL 1.20 spec:
2778bf215546Sopenharmony_ci    * "Only variables output from a vertex shader can be candidates
2779bf215546Sopenharmony_ci    * for invariance".
2780bf215546Sopenharmony_ci    */
2781bf215546Sopenharmony_ci   if (!state->is_version(130, 100))
2782bf215546Sopenharmony_ci      return false;
2783bf215546Sopenharmony_ci
2784bf215546Sopenharmony_ci   /*
2785bf215546Sopenharmony_ci    * Later specs remove this language - so allowed invariant
2786bf215546Sopenharmony_ci    * on fragment shader outputs as well.
2787bf215546Sopenharmony_ci    */
2788bf215546Sopenharmony_ci   if (state->stage == MESA_SHADER_FRAGMENT &&
2789bf215546Sopenharmony_ci       var->data.mode == ir_var_shader_out)
2790bf215546Sopenharmony_ci      return true;
2791bf215546Sopenharmony_ci   return false;
2792bf215546Sopenharmony_ci}
2793bf215546Sopenharmony_ci
2794bf215546Sopenharmony_cistatic void
2795bf215546Sopenharmony_civalidate_component_layout_for_type(struct _mesa_glsl_parse_state *state,
2796bf215546Sopenharmony_ci                                   YYLTYPE *loc, const glsl_type *type,
2797bf215546Sopenharmony_ci                                   unsigned qual_component)
2798bf215546Sopenharmony_ci{
2799bf215546Sopenharmony_ci   type = type->without_array();
2800bf215546Sopenharmony_ci   unsigned components = type->component_slots();
2801bf215546Sopenharmony_ci
2802bf215546Sopenharmony_ci   if (type->is_matrix() || type->is_struct()) {
2803bf215546Sopenharmony_ci       _mesa_glsl_error(loc, state, "component layout qualifier "
2804bf215546Sopenharmony_ci                        "cannot be applied to a matrix, a structure, "
2805bf215546Sopenharmony_ci                        "a block, or an array containing any of these.");
2806bf215546Sopenharmony_ci   } else if (components > 4 && type->is_64bit()) {
2807bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state, "component layout qualifier "
2808bf215546Sopenharmony_ci                       "cannot be applied to dvec%u.",
2809bf215546Sopenharmony_ci                        components / 2);
2810bf215546Sopenharmony_ci   } else if (qual_component != 0 && (qual_component + components - 1) > 3) {
2811bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state, "component overflow (%u > 3)",
2812bf215546Sopenharmony_ci                       (qual_component + components - 1));
2813bf215546Sopenharmony_ci   } else if (qual_component == 1 && type->is_64bit()) {
2814bf215546Sopenharmony_ci      /* We don't bother checking for 3 as it should be caught by the
2815bf215546Sopenharmony_ci       * overflow check above.
2816bf215546Sopenharmony_ci       */
2817bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state, "doubles cannot begin at component 1 or 3");
2818bf215546Sopenharmony_ci   }
2819bf215546Sopenharmony_ci}
2820bf215546Sopenharmony_ci
2821bf215546Sopenharmony_ci/**
2822bf215546Sopenharmony_ci * Matrix layout qualifiers are only allowed on certain types
2823bf215546Sopenharmony_ci */
2824bf215546Sopenharmony_cistatic void
2825bf215546Sopenharmony_civalidate_matrix_layout_for_type(struct _mesa_glsl_parse_state *state,
2826bf215546Sopenharmony_ci                                YYLTYPE *loc,
2827bf215546Sopenharmony_ci                                const glsl_type *type,
2828bf215546Sopenharmony_ci                                ir_variable *var)
2829bf215546Sopenharmony_ci{
2830bf215546Sopenharmony_ci   if (var && !var->is_in_buffer_block()) {
2831bf215546Sopenharmony_ci      /* Layout qualifiers may only apply to interface blocks and fields in
2832bf215546Sopenharmony_ci       * them.
2833bf215546Sopenharmony_ci       */
2834bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state,
2835bf215546Sopenharmony_ci                       "uniform block layout qualifiers row_major and "
2836bf215546Sopenharmony_ci                       "column_major may not be applied to variables "
2837bf215546Sopenharmony_ci                       "outside of uniform blocks");
2838bf215546Sopenharmony_ci   } else if (!type->without_array()->is_matrix()) {
2839bf215546Sopenharmony_ci      /* The OpenGL ES 3.0 conformance tests did not originally allow
2840bf215546Sopenharmony_ci       * matrix layout qualifiers on non-matrices.  However, the OpenGL
2841bf215546Sopenharmony_ci       * 4.4 and OpenGL ES 3.0 (revision TBD) specifications were
2842bf215546Sopenharmony_ci       * amended to specifically allow these layouts on all types.  Emit
2843bf215546Sopenharmony_ci       * a warning so that people know their code may not be portable.
2844bf215546Sopenharmony_ci       */
2845bf215546Sopenharmony_ci      _mesa_glsl_warning(loc, state,
2846bf215546Sopenharmony_ci                         "uniform block layout qualifiers row_major and "
2847bf215546Sopenharmony_ci                         "column_major applied to non-matrix types may "
2848bf215546Sopenharmony_ci                         "be rejected by older compilers");
2849bf215546Sopenharmony_ci   }
2850bf215546Sopenharmony_ci}
2851bf215546Sopenharmony_ci
2852bf215546Sopenharmony_cistatic bool
2853bf215546Sopenharmony_civalidate_xfb_buffer_qualifier(YYLTYPE *loc,
2854bf215546Sopenharmony_ci                              struct _mesa_glsl_parse_state *state,
2855bf215546Sopenharmony_ci                              unsigned xfb_buffer) {
2856bf215546Sopenharmony_ci   if (xfb_buffer >= state->Const.MaxTransformFeedbackBuffers) {
2857bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state,
2858bf215546Sopenharmony_ci                       "invalid xfb_buffer specified %d is larger than "
2859bf215546Sopenharmony_ci                       "MAX_TRANSFORM_FEEDBACK_BUFFERS - 1 (%d).",
2860bf215546Sopenharmony_ci                       xfb_buffer,
2861bf215546Sopenharmony_ci                       state->Const.MaxTransformFeedbackBuffers - 1);
2862bf215546Sopenharmony_ci      return false;
2863bf215546Sopenharmony_ci   }
2864bf215546Sopenharmony_ci
2865bf215546Sopenharmony_ci   return true;
2866bf215546Sopenharmony_ci}
2867bf215546Sopenharmony_ci
2868bf215546Sopenharmony_ci/* From the ARB_enhanced_layouts spec:
2869bf215546Sopenharmony_ci *
2870bf215546Sopenharmony_ci *    "Variables and block members qualified with *xfb_offset* can be
2871bf215546Sopenharmony_ci *    scalars, vectors, matrices, structures, and (sized) arrays of these.
2872bf215546Sopenharmony_ci *    The offset must be a multiple of the size of the first component of
2873bf215546Sopenharmony_ci *    the first qualified variable or block member, or a compile-time error
2874bf215546Sopenharmony_ci *    results.  Further, if applied to an aggregate containing a double,
2875bf215546Sopenharmony_ci *    the offset must also be a multiple of 8, and the space taken in the
2876bf215546Sopenharmony_ci *    buffer will be a multiple of 8.
2877bf215546Sopenharmony_ci */
2878bf215546Sopenharmony_cistatic bool
2879bf215546Sopenharmony_civalidate_xfb_offset_qualifier(YYLTYPE *loc,
2880bf215546Sopenharmony_ci                              struct _mesa_glsl_parse_state *state,
2881bf215546Sopenharmony_ci                              int xfb_offset, const glsl_type *type,
2882bf215546Sopenharmony_ci                              unsigned component_size) {
2883bf215546Sopenharmony_ci  const glsl_type *t_without_array = type->without_array();
2884bf215546Sopenharmony_ci
2885bf215546Sopenharmony_ci   if (xfb_offset != -1 && type->is_unsized_array()) {
2886bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state,
2887bf215546Sopenharmony_ci                       "xfb_offset can't be used with unsized arrays.");
2888bf215546Sopenharmony_ci      return false;
2889bf215546Sopenharmony_ci   }
2890bf215546Sopenharmony_ci
2891bf215546Sopenharmony_ci   /* Make sure nested structs don't contain unsized arrays, and validate
2892bf215546Sopenharmony_ci    * any xfb_offsets on interface members.
2893bf215546Sopenharmony_ci    */
2894bf215546Sopenharmony_ci   if (t_without_array->is_struct() || t_without_array->is_interface())
2895bf215546Sopenharmony_ci      for (unsigned int i = 0; i < t_without_array->length; i++) {
2896bf215546Sopenharmony_ci         const glsl_type *member_t = t_without_array->fields.structure[i].type;
2897bf215546Sopenharmony_ci
2898bf215546Sopenharmony_ci         /* When the interface block doesn't have an xfb_offset qualifier then
2899bf215546Sopenharmony_ci          * we apply the component size rules at the member level.
2900bf215546Sopenharmony_ci          */
2901bf215546Sopenharmony_ci         if (xfb_offset == -1)
2902bf215546Sopenharmony_ci            component_size = member_t->contains_double() ? 8 : 4;
2903bf215546Sopenharmony_ci
2904bf215546Sopenharmony_ci         int xfb_offset = t_without_array->fields.structure[i].offset;
2905bf215546Sopenharmony_ci         validate_xfb_offset_qualifier(loc, state, xfb_offset, member_t,
2906bf215546Sopenharmony_ci                                       component_size);
2907bf215546Sopenharmony_ci      }
2908bf215546Sopenharmony_ci
2909bf215546Sopenharmony_ci  /* Nested structs or interface block without offset may not have had an
2910bf215546Sopenharmony_ci   * offset applied yet so return.
2911bf215546Sopenharmony_ci   */
2912bf215546Sopenharmony_ci   if (xfb_offset == -1) {
2913bf215546Sopenharmony_ci     return true;
2914bf215546Sopenharmony_ci   }
2915bf215546Sopenharmony_ci
2916bf215546Sopenharmony_ci   if (xfb_offset % component_size) {
2917bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state,
2918bf215546Sopenharmony_ci                       "invalid qualifier xfb_offset=%d must be a multiple "
2919bf215546Sopenharmony_ci                       "of the first component size of the first qualified "
2920bf215546Sopenharmony_ci                       "variable or block member. Or double if an aggregate "
2921bf215546Sopenharmony_ci                       "that contains a double (%d).",
2922bf215546Sopenharmony_ci                       xfb_offset, component_size);
2923bf215546Sopenharmony_ci      return false;
2924bf215546Sopenharmony_ci   }
2925bf215546Sopenharmony_ci
2926bf215546Sopenharmony_ci   return true;
2927bf215546Sopenharmony_ci}
2928bf215546Sopenharmony_ci
2929bf215546Sopenharmony_cistatic bool
2930bf215546Sopenharmony_civalidate_stream_qualifier(YYLTYPE *loc, struct _mesa_glsl_parse_state *state,
2931bf215546Sopenharmony_ci                          unsigned stream)
2932bf215546Sopenharmony_ci{
2933bf215546Sopenharmony_ci   if (stream >= state->consts->MaxVertexStreams) {
2934bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state,
2935bf215546Sopenharmony_ci                       "invalid stream specified %d is larger than "
2936bf215546Sopenharmony_ci                       "MAX_VERTEX_STREAMS - 1 (%d).",
2937bf215546Sopenharmony_ci                       stream, state->consts->MaxVertexStreams - 1);
2938bf215546Sopenharmony_ci      return false;
2939bf215546Sopenharmony_ci   }
2940bf215546Sopenharmony_ci
2941bf215546Sopenharmony_ci   return true;
2942bf215546Sopenharmony_ci}
2943bf215546Sopenharmony_ci
2944bf215546Sopenharmony_cistatic void
2945bf215546Sopenharmony_ciapply_explicit_binding(struct _mesa_glsl_parse_state *state,
2946bf215546Sopenharmony_ci                       YYLTYPE *loc,
2947bf215546Sopenharmony_ci                       ir_variable *var,
2948bf215546Sopenharmony_ci                       const glsl_type *type,
2949bf215546Sopenharmony_ci                       const ast_type_qualifier *qual)
2950bf215546Sopenharmony_ci{
2951bf215546Sopenharmony_ci   if (!qual->flags.q.uniform && !qual->flags.q.buffer) {
2952bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state,
2953bf215546Sopenharmony_ci                       "the \"binding\" qualifier only applies to uniforms and "
2954bf215546Sopenharmony_ci                       "shader storage buffer objects");
2955bf215546Sopenharmony_ci      return;
2956bf215546Sopenharmony_ci   }
2957bf215546Sopenharmony_ci
2958bf215546Sopenharmony_ci   unsigned qual_binding;
2959bf215546Sopenharmony_ci   if (!process_qualifier_constant(state, loc, "binding", qual->binding,
2960bf215546Sopenharmony_ci                                   &qual_binding)) {
2961bf215546Sopenharmony_ci      return;
2962bf215546Sopenharmony_ci   }
2963bf215546Sopenharmony_ci
2964bf215546Sopenharmony_ci   const struct gl_constants *consts = state->consts;
2965bf215546Sopenharmony_ci   unsigned elements = type->is_array() ? type->arrays_of_arrays_size() : 1;
2966bf215546Sopenharmony_ci   unsigned max_index = qual_binding + elements - 1;
2967bf215546Sopenharmony_ci   const glsl_type *base_type = type->without_array();
2968bf215546Sopenharmony_ci
2969bf215546Sopenharmony_ci   if (base_type->is_interface()) {
2970bf215546Sopenharmony_ci      /* UBOs.  From page 60 of the GLSL 4.20 specification:
2971bf215546Sopenharmony_ci       * "If the binding point for any uniform block instance is less than zero,
2972bf215546Sopenharmony_ci       *  or greater than or equal to the implementation-dependent maximum
2973bf215546Sopenharmony_ci       *  number of uniform buffer bindings, a compilation error will occur.
2974bf215546Sopenharmony_ci       *  When the binding identifier is used with a uniform block instanced as
2975bf215546Sopenharmony_ci       *  an array of size N, all elements of the array from binding through
2976bf215546Sopenharmony_ci       *  binding + N – 1 must be within this range."
2977bf215546Sopenharmony_ci       *
2978bf215546Sopenharmony_ci       * The implementation-dependent maximum is GL_MAX_UNIFORM_BUFFER_BINDINGS.
2979bf215546Sopenharmony_ci       */
2980bf215546Sopenharmony_ci      if (qual->flags.q.uniform &&
2981bf215546Sopenharmony_ci         max_index >= consts->MaxUniformBufferBindings) {
2982bf215546Sopenharmony_ci         _mesa_glsl_error(loc, state, "layout(binding = %u) for %d UBOs exceeds "
2983bf215546Sopenharmony_ci                          "the maximum number of UBO binding points (%d)",
2984bf215546Sopenharmony_ci                          qual_binding, elements,
2985bf215546Sopenharmony_ci                          consts->MaxUniformBufferBindings);
2986bf215546Sopenharmony_ci         return;
2987bf215546Sopenharmony_ci      }
2988bf215546Sopenharmony_ci
2989bf215546Sopenharmony_ci      /* SSBOs. From page 67 of the GLSL 4.30 specification:
2990bf215546Sopenharmony_ci       * "If the binding point for any uniform or shader storage block instance
2991bf215546Sopenharmony_ci       *  is less than zero, or greater than or equal to the
2992bf215546Sopenharmony_ci       *  implementation-dependent maximum number of uniform buffer bindings, a
2993bf215546Sopenharmony_ci       *  compile-time error will occur. When the binding identifier is used
2994bf215546Sopenharmony_ci       *  with a uniform or shader storage block instanced as an array of size
2995bf215546Sopenharmony_ci       *  N, all elements of the array from binding through binding + N – 1 must
2996bf215546Sopenharmony_ci       *  be within this range."
2997bf215546Sopenharmony_ci       */
2998bf215546Sopenharmony_ci      if (qual->flags.q.buffer &&
2999bf215546Sopenharmony_ci         max_index >= consts->MaxShaderStorageBufferBindings) {
3000bf215546Sopenharmony_ci         _mesa_glsl_error(loc, state, "layout(binding = %u) for %d SSBOs exceeds "
3001bf215546Sopenharmony_ci                          "the maximum number of SSBO binding points (%d)",
3002bf215546Sopenharmony_ci                          qual_binding, elements,
3003bf215546Sopenharmony_ci                          consts->MaxShaderStorageBufferBindings);
3004bf215546Sopenharmony_ci         return;
3005bf215546Sopenharmony_ci      }
3006bf215546Sopenharmony_ci   } else if (base_type->is_sampler()) {
3007bf215546Sopenharmony_ci      /* Samplers.  From page 63 of the GLSL 4.20 specification:
3008bf215546Sopenharmony_ci       * "If the binding is less than zero, or greater than or equal to the
3009bf215546Sopenharmony_ci       *  implementation-dependent maximum supported number of units, a
3010bf215546Sopenharmony_ci       *  compilation error will occur. When the binding identifier is used
3011bf215546Sopenharmony_ci       *  with an array of size N, all elements of the array from binding
3012bf215546Sopenharmony_ci       *  through binding + N - 1 must be within this range."
3013bf215546Sopenharmony_ci       */
3014bf215546Sopenharmony_ci      unsigned limit = consts->MaxCombinedTextureImageUnits;
3015bf215546Sopenharmony_ci
3016bf215546Sopenharmony_ci      if (max_index >= limit) {
3017bf215546Sopenharmony_ci         _mesa_glsl_error(loc, state, "layout(binding = %d) for %d samplers "
3018bf215546Sopenharmony_ci                          "exceeds the maximum number of texture image units "
3019bf215546Sopenharmony_ci                          "(%u)", qual_binding, elements, limit);
3020bf215546Sopenharmony_ci
3021bf215546Sopenharmony_ci         return;
3022bf215546Sopenharmony_ci      }
3023bf215546Sopenharmony_ci   } else if (base_type->contains_atomic()) {
3024bf215546Sopenharmony_ci      assert(consts->MaxAtomicBufferBindings <= MAX_COMBINED_ATOMIC_BUFFERS);
3025bf215546Sopenharmony_ci      if (qual_binding >= consts->MaxAtomicBufferBindings) {
3026bf215546Sopenharmony_ci         _mesa_glsl_error(loc, state, "layout(binding = %d) exceeds the "
3027bf215546Sopenharmony_ci                          "maximum number of atomic counter buffer bindings "
3028bf215546Sopenharmony_ci                          "(%u)", qual_binding,
3029bf215546Sopenharmony_ci                          consts->MaxAtomicBufferBindings);
3030bf215546Sopenharmony_ci
3031bf215546Sopenharmony_ci         return;
3032bf215546Sopenharmony_ci      }
3033bf215546Sopenharmony_ci   } else if ((state->is_version(420, 310) ||
3034bf215546Sopenharmony_ci               state->ARB_shading_language_420pack_enable) &&
3035bf215546Sopenharmony_ci              base_type->is_image()) {
3036bf215546Sopenharmony_ci      assert(consts->MaxImageUnits <= MAX_IMAGE_UNITS);
3037bf215546Sopenharmony_ci      if (max_index >= consts->MaxImageUnits) {
3038bf215546Sopenharmony_ci         _mesa_glsl_error(loc, state, "Image binding %d exceeds the "
3039bf215546Sopenharmony_ci                          "maximum number of image units (%d)", max_index,
3040bf215546Sopenharmony_ci                          consts->MaxImageUnits);
3041bf215546Sopenharmony_ci         return;
3042bf215546Sopenharmony_ci      }
3043bf215546Sopenharmony_ci
3044bf215546Sopenharmony_ci   } else {
3045bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state,
3046bf215546Sopenharmony_ci                       "the \"binding\" qualifier only applies to uniform "
3047bf215546Sopenharmony_ci                       "blocks, storage blocks, opaque variables, or arrays "
3048bf215546Sopenharmony_ci                       "thereof");
3049bf215546Sopenharmony_ci      return;
3050bf215546Sopenharmony_ci   }
3051bf215546Sopenharmony_ci
3052bf215546Sopenharmony_ci   var->data.explicit_binding = true;
3053bf215546Sopenharmony_ci   var->data.binding = qual_binding;
3054bf215546Sopenharmony_ci
3055bf215546Sopenharmony_ci   return;
3056bf215546Sopenharmony_ci}
3057bf215546Sopenharmony_ci
3058bf215546Sopenharmony_cistatic void
3059bf215546Sopenharmony_civalidate_fragment_flat_interpolation_input(struct _mesa_glsl_parse_state *state,
3060bf215546Sopenharmony_ci                                           YYLTYPE *loc,
3061bf215546Sopenharmony_ci                                           const glsl_interp_mode interpolation,
3062bf215546Sopenharmony_ci                                           const struct glsl_type *var_type,
3063bf215546Sopenharmony_ci                                           ir_variable_mode mode)
3064bf215546Sopenharmony_ci{
3065bf215546Sopenharmony_ci   if (state->stage != MESA_SHADER_FRAGMENT ||
3066bf215546Sopenharmony_ci       interpolation == INTERP_MODE_FLAT ||
3067bf215546Sopenharmony_ci       mode != ir_var_shader_in)
3068bf215546Sopenharmony_ci      return;
3069bf215546Sopenharmony_ci
3070bf215546Sopenharmony_ci   /* Integer fragment inputs must be qualified with 'flat'.  In GLSL ES,
3071bf215546Sopenharmony_ci    * so must integer vertex outputs.
3072bf215546Sopenharmony_ci    *
3073bf215546Sopenharmony_ci    * From section 4.3.4 ("Inputs") of the GLSL 1.50 spec:
3074bf215546Sopenharmony_ci    *    "Fragment shader inputs that are signed or unsigned integers or
3075bf215546Sopenharmony_ci    *    integer vectors must be qualified with the interpolation qualifier
3076bf215546Sopenharmony_ci    *    flat."
3077bf215546Sopenharmony_ci    *
3078bf215546Sopenharmony_ci    * From section 4.3.4 ("Input Variables") of the GLSL 3.00 ES spec:
3079bf215546Sopenharmony_ci    *    "Fragment shader inputs that are, or contain, signed or unsigned
3080bf215546Sopenharmony_ci    *    integers or integer vectors must be qualified with the
3081bf215546Sopenharmony_ci    *    interpolation qualifier flat."
3082bf215546Sopenharmony_ci    *
3083bf215546Sopenharmony_ci    * From section 4.3.6 ("Output Variables") of the GLSL 3.00 ES spec:
3084bf215546Sopenharmony_ci    *    "Vertex shader outputs that are, or contain, signed or unsigned
3085bf215546Sopenharmony_ci    *    integers or integer vectors must be qualified with the
3086bf215546Sopenharmony_ci    *    interpolation qualifier flat."
3087bf215546Sopenharmony_ci    *
3088bf215546Sopenharmony_ci    * Note that prior to GLSL 1.50, this requirement applied to vertex
3089bf215546Sopenharmony_ci    * outputs rather than fragment inputs.  That creates problems in the
3090bf215546Sopenharmony_ci    * presence of geometry shaders, so we adopt the GLSL 1.50 rule for all
3091bf215546Sopenharmony_ci    * desktop GL shaders.  For GLSL ES shaders, we follow the spec and
3092bf215546Sopenharmony_ci    * apply the restriction to both vertex outputs and fragment inputs.
3093bf215546Sopenharmony_ci    *
3094bf215546Sopenharmony_ci    * Note also that the desktop GLSL specs are missing the text "or
3095bf215546Sopenharmony_ci    * contain"; this is presumably an oversight, since there is no
3096bf215546Sopenharmony_ci    * reasonable way to interpolate a fragment shader input that contains
3097bf215546Sopenharmony_ci    * an integer. See Khronos bug #15671.
3098bf215546Sopenharmony_ci    */
3099bf215546Sopenharmony_ci   if ((state->is_version(130, 300) || state->EXT_gpu_shader4_enable)
3100bf215546Sopenharmony_ci       && var_type->contains_integer()) {
3101bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state, "if a fragment input is (or contains) "
3102bf215546Sopenharmony_ci                       "an integer, then it must be qualified with 'flat'");
3103bf215546Sopenharmony_ci   }
3104bf215546Sopenharmony_ci
3105bf215546Sopenharmony_ci   /* Double fragment inputs must be qualified with 'flat'.
3106bf215546Sopenharmony_ci    *
3107bf215546Sopenharmony_ci    * From the "Overview" of the ARB_gpu_shader_fp64 extension spec:
3108bf215546Sopenharmony_ci    *    "This extension does not support interpolation of double-precision
3109bf215546Sopenharmony_ci    *    values; doubles used as fragment shader inputs must be qualified as
3110bf215546Sopenharmony_ci    *    "flat"."
3111bf215546Sopenharmony_ci    *
3112bf215546Sopenharmony_ci    * From section 4.3.4 ("Inputs") of the GLSL 4.00 spec:
3113bf215546Sopenharmony_ci    *    "Fragment shader inputs that are signed or unsigned integers, integer
3114bf215546Sopenharmony_ci    *    vectors, or any double-precision floating-point type must be
3115bf215546Sopenharmony_ci    *    qualified with the interpolation qualifier flat."
3116bf215546Sopenharmony_ci    *
3117bf215546Sopenharmony_ci    * Note that the GLSL specs are missing the text "or contain"; this is
3118bf215546Sopenharmony_ci    * presumably an oversight. See Khronos bug #15671.
3119bf215546Sopenharmony_ci    *
3120bf215546Sopenharmony_ci    * The 'double' type does not exist in GLSL ES so far.
3121bf215546Sopenharmony_ci    */
3122bf215546Sopenharmony_ci   if (state->has_double()
3123bf215546Sopenharmony_ci       && var_type->contains_double()) {
3124bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state, "if a fragment input is (or contains) "
3125bf215546Sopenharmony_ci                       "a double, then it must be qualified with 'flat'");
3126bf215546Sopenharmony_ci   }
3127bf215546Sopenharmony_ci
3128bf215546Sopenharmony_ci   /* Bindless sampler/image fragment inputs must be qualified with 'flat'.
3129bf215546Sopenharmony_ci    *
3130bf215546Sopenharmony_ci    * From section 4.3.4 of the ARB_bindless_texture spec:
3131bf215546Sopenharmony_ci    *
3132bf215546Sopenharmony_ci    *    "(modify last paragraph, p. 35, allowing samplers and images as
3133bf215546Sopenharmony_ci    *     fragment shader inputs) ... Fragment inputs can only be signed and
3134bf215546Sopenharmony_ci    *     unsigned integers and integer vectors, floating point scalars,
3135bf215546Sopenharmony_ci    *     floating-point vectors, matrices, sampler and image types, or arrays
3136bf215546Sopenharmony_ci    *     or structures of these.  Fragment shader inputs that are signed or
3137bf215546Sopenharmony_ci    *     unsigned integers, integer vectors, or any double-precision floating-
3138bf215546Sopenharmony_ci    *     point type, or any sampler or image type must be qualified with the
3139bf215546Sopenharmony_ci    *     interpolation qualifier "flat"."
3140bf215546Sopenharmony_ci    */
3141bf215546Sopenharmony_ci   if (state->has_bindless()
3142bf215546Sopenharmony_ci       && (var_type->contains_sampler() || var_type->contains_image())) {
3143bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state, "if a fragment input is (or contains) "
3144bf215546Sopenharmony_ci                       "a bindless sampler (or image), then it must be "
3145bf215546Sopenharmony_ci                       "qualified with 'flat'");
3146bf215546Sopenharmony_ci   }
3147bf215546Sopenharmony_ci}
3148bf215546Sopenharmony_ci
3149bf215546Sopenharmony_cistatic void
3150bf215546Sopenharmony_civalidate_interpolation_qualifier(struct _mesa_glsl_parse_state *state,
3151bf215546Sopenharmony_ci                                 YYLTYPE *loc,
3152bf215546Sopenharmony_ci                                 const glsl_interp_mode interpolation,
3153bf215546Sopenharmony_ci                                 const struct ast_type_qualifier *qual,
3154bf215546Sopenharmony_ci                                 const struct glsl_type *var_type,
3155bf215546Sopenharmony_ci                                 ir_variable_mode mode)
3156bf215546Sopenharmony_ci{
3157bf215546Sopenharmony_ci   /* Interpolation qualifiers can only apply to shader inputs or outputs, but
3158bf215546Sopenharmony_ci    * not to vertex shader inputs nor fragment shader outputs.
3159bf215546Sopenharmony_ci    *
3160bf215546Sopenharmony_ci    * From section 4.3 ("Storage Qualifiers") of the GLSL 1.30 spec:
3161bf215546Sopenharmony_ci    *    "Outputs from a vertex shader (out) and inputs to a fragment
3162bf215546Sopenharmony_ci    *    shader (in) can be further qualified with one or more of these
3163bf215546Sopenharmony_ci    *    interpolation qualifiers"
3164bf215546Sopenharmony_ci    *    ...
3165bf215546Sopenharmony_ci    *    "These interpolation qualifiers may only precede the qualifiers in,
3166bf215546Sopenharmony_ci    *    centroid in, out, or centroid out in a declaration. They do not apply
3167bf215546Sopenharmony_ci    *    to the deprecated storage qualifiers varying or centroid
3168bf215546Sopenharmony_ci    *    varying. They also do not apply to inputs into a vertex shader or
3169bf215546Sopenharmony_ci    *    outputs from a fragment shader."
3170bf215546Sopenharmony_ci    *
3171bf215546Sopenharmony_ci    * From section 4.3 ("Storage Qualifiers") of the GLSL ES 3.00 spec:
3172bf215546Sopenharmony_ci    *    "Outputs from a shader (out) and inputs to a shader (in) can be
3173bf215546Sopenharmony_ci    *    further qualified with one of these interpolation qualifiers."
3174bf215546Sopenharmony_ci    *    ...
3175bf215546Sopenharmony_ci    *    "These interpolation qualifiers may only precede the qualifiers
3176bf215546Sopenharmony_ci    *    in, centroid in, out, or centroid out in a declaration. They do
3177bf215546Sopenharmony_ci    *    not apply to inputs into a vertex shader or outputs from a
3178bf215546Sopenharmony_ci    *    fragment shader."
3179bf215546Sopenharmony_ci    */
3180bf215546Sopenharmony_ci   if ((state->is_version(130, 300) || state->EXT_gpu_shader4_enable)
3181bf215546Sopenharmony_ci       && interpolation != INTERP_MODE_NONE) {
3182bf215546Sopenharmony_ci      const char *i = interpolation_string(interpolation);
3183bf215546Sopenharmony_ci      if (mode != ir_var_shader_in && mode != ir_var_shader_out)
3184bf215546Sopenharmony_ci         _mesa_glsl_error(loc, state,
3185bf215546Sopenharmony_ci                          "interpolation qualifier `%s' can only be applied to "
3186bf215546Sopenharmony_ci                          "shader inputs or outputs.", i);
3187bf215546Sopenharmony_ci
3188bf215546Sopenharmony_ci      switch (state->stage) {
3189bf215546Sopenharmony_ci      case MESA_SHADER_VERTEX:
3190bf215546Sopenharmony_ci         if (mode == ir_var_shader_in) {
3191bf215546Sopenharmony_ci            _mesa_glsl_error(loc, state,
3192bf215546Sopenharmony_ci                             "interpolation qualifier '%s' cannot be applied to "
3193bf215546Sopenharmony_ci                             "vertex shader inputs", i);
3194bf215546Sopenharmony_ci         }
3195bf215546Sopenharmony_ci         break;
3196bf215546Sopenharmony_ci      case MESA_SHADER_FRAGMENT:
3197bf215546Sopenharmony_ci         if (mode == ir_var_shader_out) {
3198bf215546Sopenharmony_ci            _mesa_glsl_error(loc, state,
3199bf215546Sopenharmony_ci                             "interpolation qualifier '%s' cannot be applied to "
3200bf215546Sopenharmony_ci                             "fragment shader outputs", i);
3201bf215546Sopenharmony_ci         }
3202bf215546Sopenharmony_ci         break;
3203bf215546Sopenharmony_ci      default:
3204bf215546Sopenharmony_ci         break;
3205bf215546Sopenharmony_ci      }
3206bf215546Sopenharmony_ci   }
3207bf215546Sopenharmony_ci
3208bf215546Sopenharmony_ci   /* Interpolation qualifiers cannot be applied to 'centroid' and
3209bf215546Sopenharmony_ci    * 'centroid varying'.
3210bf215546Sopenharmony_ci    *
3211bf215546Sopenharmony_ci    * From section 4.3 ("Storage Qualifiers") of the GLSL 1.30 spec:
3212bf215546Sopenharmony_ci    *    "interpolation qualifiers may only precede the qualifiers in,
3213bf215546Sopenharmony_ci    *    centroid in, out, or centroid out in a declaration. They do not apply
3214bf215546Sopenharmony_ci    *    to the deprecated storage qualifiers varying or centroid varying."
3215bf215546Sopenharmony_ci    *
3216bf215546Sopenharmony_ci    * These deprecated storage qualifiers do not exist in GLSL ES 3.00.
3217bf215546Sopenharmony_ci    *
3218bf215546Sopenharmony_ci    * GL_EXT_gpu_shader4 allows this.
3219bf215546Sopenharmony_ci    */
3220bf215546Sopenharmony_ci   if (state->is_version(130, 0) && !state->EXT_gpu_shader4_enable
3221bf215546Sopenharmony_ci       && interpolation != INTERP_MODE_NONE
3222bf215546Sopenharmony_ci       && qual->flags.q.varying) {
3223bf215546Sopenharmony_ci
3224bf215546Sopenharmony_ci      const char *i = interpolation_string(interpolation);
3225bf215546Sopenharmony_ci      const char *s;
3226bf215546Sopenharmony_ci      if (qual->flags.q.centroid)
3227bf215546Sopenharmony_ci         s = "centroid varying";
3228bf215546Sopenharmony_ci      else
3229bf215546Sopenharmony_ci         s = "varying";
3230bf215546Sopenharmony_ci
3231bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state,
3232bf215546Sopenharmony_ci                       "qualifier '%s' cannot be applied to the "
3233bf215546Sopenharmony_ci                       "deprecated storage qualifier '%s'", i, s);
3234bf215546Sopenharmony_ci   }
3235bf215546Sopenharmony_ci
3236bf215546Sopenharmony_ci   validate_fragment_flat_interpolation_input(state, loc, interpolation,
3237bf215546Sopenharmony_ci                                              var_type, mode);
3238bf215546Sopenharmony_ci}
3239bf215546Sopenharmony_ci
3240bf215546Sopenharmony_cistatic glsl_interp_mode
3241bf215546Sopenharmony_ciinterpret_interpolation_qualifier(const struct ast_type_qualifier *qual,
3242bf215546Sopenharmony_ci                                  const struct glsl_type *var_type,
3243bf215546Sopenharmony_ci                                  ir_variable_mode mode,
3244bf215546Sopenharmony_ci                                  struct _mesa_glsl_parse_state *state,
3245bf215546Sopenharmony_ci                                  YYLTYPE *loc)
3246bf215546Sopenharmony_ci{
3247bf215546Sopenharmony_ci   glsl_interp_mode interpolation;
3248bf215546Sopenharmony_ci   if (qual->flags.q.flat)
3249bf215546Sopenharmony_ci      interpolation = INTERP_MODE_FLAT;
3250bf215546Sopenharmony_ci   else if (qual->flags.q.noperspective)
3251bf215546Sopenharmony_ci      interpolation = INTERP_MODE_NOPERSPECTIVE;
3252bf215546Sopenharmony_ci   else if (qual->flags.q.smooth)
3253bf215546Sopenharmony_ci      interpolation = INTERP_MODE_SMOOTH;
3254bf215546Sopenharmony_ci   else
3255bf215546Sopenharmony_ci      interpolation = INTERP_MODE_NONE;
3256bf215546Sopenharmony_ci
3257bf215546Sopenharmony_ci   validate_interpolation_qualifier(state, loc,
3258bf215546Sopenharmony_ci                                    interpolation,
3259bf215546Sopenharmony_ci                                    qual, var_type, mode);
3260bf215546Sopenharmony_ci
3261bf215546Sopenharmony_ci   return interpolation;
3262bf215546Sopenharmony_ci}
3263bf215546Sopenharmony_ci
3264bf215546Sopenharmony_ci
3265bf215546Sopenharmony_cistatic void
3266bf215546Sopenharmony_ciapply_explicit_location(const struct ast_type_qualifier *qual,
3267bf215546Sopenharmony_ci                        ir_variable *var,
3268bf215546Sopenharmony_ci                        struct _mesa_glsl_parse_state *state,
3269bf215546Sopenharmony_ci                        YYLTYPE *loc)
3270bf215546Sopenharmony_ci{
3271bf215546Sopenharmony_ci   bool fail = false;
3272bf215546Sopenharmony_ci
3273bf215546Sopenharmony_ci   unsigned qual_location;
3274bf215546Sopenharmony_ci   if (!process_qualifier_constant(state, loc, "location", qual->location,
3275bf215546Sopenharmony_ci                                   &qual_location)) {
3276bf215546Sopenharmony_ci      return;
3277bf215546Sopenharmony_ci   }
3278bf215546Sopenharmony_ci
3279bf215546Sopenharmony_ci   /* Checks for GL_ARB_explicit_uniform_location. */
3280bf215546Sopenharmony_ci   if (qual->flags.q.uniform) {
3281bf215546Sopenharmony_ci      if (!state->check_explicit_uniform_location_allowed(loc, var))
3282bf215546Sopenharmony_ci         return;
3283bf215546Sopenharmony_ci
3284bf215546Sopenharmony_ci      const struct gl_constants *consts = state->consts;
3285bf215546Sopenharmony_ci      unsigned max_loc = qual_location + var->type->uniform_locations() - 1;
3286bf215546Sopenharmony_ci
3287bf215546Sopenharmony_ci      if (max_loc >= consts->MaxUserAssignableUniformLocations) {
3288bf215546Sopenharmony_ci         _mesa_glsl_error(loc, state, "location(s) consumed by uniform %s "
3289bf215546Sopenharmony_ci                          ">= MAX_UNIFORM_LOCATIONS (%u)", var->name,
3290bf215546Sopenharmony_ci                          consts->MaxUserAssignableUniformLocations);
3291bf215546Sopenharmony_ci         return;
3292bf215546Sopenharmony_ci      }
3293bf215546Sopenharmony_ci
3294bf215546Sopenharmony_ci      var->data.explicit_location = true;
3295bf215546Sopenharmony_ci      var->data.location = qual_location;
3296bf215546Sopenharmony_ci      return;
3297bf215546Sopenharmony_ci   }
3298bf215546Sopenharmony_ci
3299bf215546Sopenharmony_ci   /* Between GL_ARB_explicit_attrib_location an
3300bf215546Sopenharmony_ci    * GL_ARB_separate_shader_objects, the inputs and outputs of any shader
3301bf215546Sopenharmony_ci    * stage can be assigned explicit locations.  The checking here associates
3302bf215546Sopenharmony_ci    * the correct extension with the correct stage's input / output:
3303bf215546Sopenharmony_ci    *
3304bf215546Sopenharmony_ci    *                     input            output
3305bf215546Sopenharmony_ci    *                     -----            ------
3306bf215546Sopenharmony_ci    * vertex              explicit_loc     sso
3307bf215546Sopenharmony_ci    * tess control        sso              sso
3308bf215546Sopenharmony_ci    * tess eval           sso              sso
3309bf215546Sopenharmony_ci    * geometry            sso              sso
3310bf215546Sopenharmony_ci    * fragment            sso              explicit_loc
3311bf215546Sopenharmony_ci    */
3312bf215546Sopenharmony_ci   switch (state->stage) {
3313bf215546Sopenharmony_ci   case MESA_SHADER_VERTEX:
3314bf215546Sopenharmony_ci      if (var->data.mode == ir_var_shader_in) {
3315bf215546Sopenharmony_ci         if (!state->check_explicit_attrib_location_allowed(loc, var))
3316bf215546Sopenharmony_ci            return;
3317bf215546Sopenharmony_ci
3318bf215546Sopenharmony_ci         break;
3319bf215546Sopenharmony_ci      }
3320bf215546Sopenharmony_ci
3321bf215546Sopenharmony_ci      if (var->data.mode == ir_var_shader_out) {
3322bf215546Sopenharmony_ci         if (!state->check_separate_shader_objects_allowed(loc, var))
3323bf215546Sopenharmony_ci            return;
3324bf215546Sopenharmony_ci
3325bf215546Sopenharmony_ci         break;
3326bf215546Sopenharmony_ci      }
3327bf215546Sopenharmony_ci
3328bf215546Sopenharmony_ci      fail = true;
3329bf215546Sopenharmony_ci      break;
3330bf215546Sopenharmony_ci
3331bf215546Sopenharmony_ci   case MESA_SHADER_TESS_CTRL:
3332bf215546Sopenharmony_ci   case MESA_SHADER_TESS_EVAL:
3333bf215546Sopenharmony_ci   case MESA_SHADER_GEOMETRY:
3334bf215546Sopenharmony_ci      if (var->data.mode == ir_var_shader_in || var->data.mode == ir_var_shader_out) {
3335bf215546Sopenharmony_ci         if (!state->check_separate_shader_objects_allowed(loc, var))
3336bf215546Sopenharmony_ci            return;
3337bf215546Sopenharmony_ci
3338bf215546Sopenharmony_ci         break;
3339bf215546Sopenharmony_ci      }
3340bf215546Sopenharmony_ci
3341bf215546Sopenharmony_ci      fail = true;
3342bf215546Sopenharmony_ci      break;
3343bf215546Sopenharmony_ci
3344bf215546Sopenharmony_ci   case MESA_SHADER_FRAGMENT:
3345bf215546Sopenharmony_ci      if (var->data.mode == ir_var_shader_in) {
3346bf215546Sopenharmony_ci         if (!state->check_separate_shader_objects_allowed(loc, var))
3347bf215546Sopenharmony_ci            return;
3348bf215546Sopenharmony_ci
3349bf215546Sopenharmony_ci         break;
3350bf215546Sopenharmony_ci      }
3351bf215546Sopenharmony_ci
3352bf215546Sopenharmony_ci      if (var->data.mode == ir_var_shader_out) {
3353bf215546Sopenharmony_ci         if (!state->check_explicit_attrib_location_allowed(loc, var))
3354bf215546Sopenharmony_ci            return;
3355bf215546Sopenharmony_ci
3356bf215546Sopenharmony_ci         break;
3357bf215546Sopenharmony_ci      }
3358bf215546Sopenharmony_ci
3359bf215546Sopenharmony_ci      fail = true;
3360bf215546Sopenharmony_ci      break;
3361bf215546Sopenharmony_ci
3362bf215546Sopenharmony_ci   case MESA_SHADER_COMPUTE:
3363bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state,
3364bf215546Sopenharmony_ci                       "compute shader variables cannot be given "
3365bf215546Sopenharmony_ci                       "explicit locations");
3366bf215546Sopenharmony_ci      return;
3367bf215546Sopenharmony_ci   default:
3368bf215546Sopenharmony_ci      fail = true;
3369bf215546Sopenharmony_ci      break;
3370bf215546Sopenharmony_ci   };
3371bf215546Sopenharmony_ci
3372bf215546Sopenharmony_ci   if (fail) {
3373bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state,
3374bf215546Sopenharmony_ci                       "%s cannot be given an explicit location in %s shader",
3375bf215546Sopenharmony_ci                       mode_string(var),
3376bf215546Sopenharmony_ci      _mesa_shader_stage_to_string(state->stage));
3377bf215546Sopenharmony_ci   } else {
3378bf215546Sopenharmony_ci      var->data.explicit_location = true;
3379bf215546Sopenharmony_ci
3380bf215546Sopenharmony_ci      switch (state->stage) {
3381bf215546Sopenharmony_ci      case MESA_SHADER_VERTEX:
3382bf215546Sopenharmony_ci         var->data.location = (var->data.mode == ir_var_shader_in)
3383bf215546Sopenharmony_ci            ? (qual_location + VERT_ATTRIB_GENERIC0)
3384bf215546Sopenharmony_ci            : (qual_location + VARYING_SLOT_VAR0);
3385bf215546Sopenharmony_ci         break;
3386bf215546Sopenharmony_ci
3387bf215546Sopenharmony_ci      case MESA_SHADER_TESS_CTRL:
3388bf215546Sopenharmony_ci      case MESA_SHADER_TESS_EVAL:
3389bf215546Sopenharmony_ci      case MESA_SHADER_GEOMETRY:
3390bf215546Sopenharmony_ci         if (var->data.patch)
3391bf215546Sopenharmony_ci            var->data.location = qual_location + VARYING_SLOT_PATCH0;
3392bf215546Sopenharmony_ci         else
3393bf215546Sopenharmony_ci            var->data.location = qual_location + VARYING_SLOT_VAR0;
3394bf215546Sopenharmony_ci         break;
3395bf215546Sopenharmony_ci
3396bf215546Sopenharmony_ci      case MESA_SHADER_FRAGMENT:
3397bf215546Sopenharmony_ci         var->data.location = (var->data.mode == ir_var_shader_out)
3398bf215546Sopenharmony_ci            ? (qual_location + FRAG_RESULT_DATA0)
3399bf215546Sopenharmony_ci            : (qual_location + VARYING_SLOT_VAR0);
3400bf215546Sopenharmony_ci         break;
3401bf215546Sopenharmony_ci      default:
3402bf215546Sopenharmony_ci         assert(!"Unexpected shader type");
3403bf215546Sopenharmony_ci         break;
3404bf215546Sopenharmony_ci      }
3405bf215546Sopenharmony_ci
3406bf215546Sopenharmony_ci      /* Check if index was set for the uniform instead of the function */
3407bf215546Sopenharmony_ci      if (qual->flags.q.explicit_index && qual->is_subroutine_decl()) {
3408bf215546Sopenharmony_ci         _mesa_glsl_error(loc, state, "an index qualifier can only be "
3409bf215546Sopenharmony_ci                          "used with subroutine functions");
3410bf215546Sopenharmony_ci         return;
3411bf215546Sopenharmony_ci      }
3412bf215546Sopenharmony_ci
3413bf215546Sopenharmony_ci      unsigned qual_index;
3414bf215546Sopenharmony_ci      if (qual->flags.q.explicit_index &&
3415bf215546Sopenharmony_ci          process_qualifier_constant(state, loc, "index", qual->index,
3416bf215546Sopenharmony_ci                                     &qual_index)) {
3417bf215546Sopenharmony_ci         /* From the GLSL 4.30 specification, section 4.4.2 (Output
3418bf215546Sopenharmony_ci          * Layout Qualifiers):
3419bf215546Sopenharmony_ci          *
3420bf215546Sopenharmony_ci          * "It is also a compile-time error if a fragment shader
3421bf215546Sopenharmony_ci          *  sets a layout index to less than 0 or greater than 1."
3422bf215546Sopenharmony_ci          *
3423bf215546Sopenharmony_ci          * Older specifications don't mandate a behavior; we take
3424bf215546Sopenharmony_ci          * this as a clarification and always generate the error.
3425bf215546Sopenharmony_ci          */
3426bf215546Sopenharmony_ci         if (qual_index > 1) {
3427bf215546Sopenharmony_ci            _mesa_glsl_error(loc, state,
3428bf215546Sopenharmony_ci                             "explicit index may only be 0 or 1");
3429bf215546Sopenharmony_ci         } else {
3430bf215546Sopenharmony_ci            var->data.explicit_index = true;
3431bf215546Sopenharmony_ci            var->data.index = qual_index;
3432bf215546Sopenharmony_ci         }
3433bf215546Sopenharmony_ci      }
3434bf215546Sopenharmony_ci   }
3435bf215546Sopenharmony_ci}
3436bf215546Sopenharmony_ci
3437bf215546Sopenharmony_cistatic bool
3438bf215546Sopenharmony_civalidate_storage_for_sampler_image_types(ir_variable *var,
3439bf215546Sopenharmony_ci                                         struct _mesa_glsl_parse_state *state,
3440bf215546Sopenharmony_ci                                         YYLTYPE *loc)
3441bf215546Sopenharmony_ci{
3442bf215546Sopenharmony_ci   /* From section 4.1.7 of the GLSL 4.40 spec:
3443bf215546Sopenharmony_ci    *
3444bf215546Sopenharmony_ci    *    "[Opaque types] can only be declared as function
3445bf215546Sopenharmony_ci    *     parameters or uniform-qualified variables."
3446bf215546Sopenharmony_ci    *
3447bf215546Sopenharmony_ci    * From section 4.1.7 of the ARB_bindless_texture spec:
3448bf215546Sopenharmony_ci    *
3449bf215546Sopenharmony_ci    *    "Samplers may be declared as shader inputs and outputs, as uniform
3450bf215546Sopenharmony_ci    *     variables, as temporary variables, and as function parameters."
3451bf215546Sopenharmony_ci    *
3452bf215546Sopenharmony_ci    * From section 4.1.X of the ARB_bindless_texture spec:
3453bf215546Sopenharmony_ci    *
3454bf215546Sopenharmony_ci    *    "Images may be declared as shader inputs and outputs, as uniform
3455bf215546Sopenharmony_ci    *     variables, as temporary variables, and as function parameters."
3456bf215546Sopenharmony_ci    */
3457bf215546Sopenharmony_ci   if (state->has_bindless()) {
3458bf215546Sopenharmony_ci      if (var->data.mode != ir_var_auto &&
3459bf215546Sopenharmony_ci          var->data.mode != ir_var_uniform &&
3460bf215546Sopenharmony_ci          var->data.mode != ir_var_shader_in &&
3461bf215546Sopenharmony_ci          var->data.mode != ir_var_shader_out &&
3462bf215546Sopenharmony_ci          var->data.mode != ir_var_function_in &&
3463bf215546Sopenharmony_ci          var->data.mode != ir_var_function_out &&
3464bf215546Sopenharmony_ci          var->data.mode != ir_var_function_inout) {
3465bf215546Sopenharmony_ci         _mesa_glsl_error(loc, state, "bindless image/sampler variables may "
3466bf215546Sopenharmony_ci                         "only be declared as shader inputs and outputs, as "
3467bf215546Sopenharmony_ci                         "uniform variables, as temporary variables and as "
3468bf215546Sopenharmony_ci                         "function parameters");
3469bf215546Sopenharmony_ci         return false;
3470bf215546Sopenharmony_ci      }
3471bf215546Sopenharmony_ci   } else {
3472bf215546Sopenharmony_ci      if (var->data.mode != ir_var_uniform &&
3473bf215546Sopenharmony_ci          var->data.mode != ir_var_function_in) {
3474bf215546Sopenharmony_ci         _mesa_glsl_error(loc, state, "image/sampler variables may only be "
3475bf215546Sopenharmony_ci                          "declared as function parameters or "
3476bf215546Sopenharmony_ci                          "uniform-qualified global variables");
3477bf215546Sopenharmony_ci         return false;
3478bf215546Sopenharmony_ci      }
3479bf215546Sopenharmony_ci   }
3480bf215546Sopenharmony_ci   return true;
3481bf215546Sopenharmony_ci}
3482bf215546Sopenharmony_ci
3483bf215546Sopenharmony_cistatic bool
3484bf215546Sopenharmony_civalidate_memory_qualifier_for_type(struct _mesa_glsl_parse_state *state,
3485bf215546Sopenharmony_ci                                   YYLTYPE *loc,
3486bf215546Sopenharmony_ci                                   const struct ast_type_qualifier *qual,
3487bf215546Sopenharmony_ci                                   const glsl_type *type)
3488bf215546Sopenharmony_ci{
3489bf215546Sopenharmony_ci   /* From Section 4.10 (Memory Qualifiers) of the GLSL 4.50 spec:
3490bf215546Sopenharmony_ci    *
3491bf215546Sopenharmony_ci    * "Memory qualifiers are only supported in the declarations of image
3492bf215546Sopenharmony_ci    *  variables, buffer variables, and shader storage blocks; it is an error
3493bf215546Sopenharmony_ci    *  to use such qualifiers in any other declarations.
3494bf215546Sopenharmony_ci    */
3495bf215546Sopenharmony_ci   if (!type->is_image() && !qual->flags.q.buffer) {
3496bf215546Sopenharmony_ci      if (qual->flags.q.read_only ||
3497bf215546Sopenharmony_ci          qual->flags.q.write_only ||
3498bf215546Sopenharmony_ci          qual->flags.q.coherent ||
3499bf215546Sopenharmony_ci          qual->flags.q._volatile ||
3500bf215546Sopenharmony_ci          qual->flags.q.restrict_flag) {
3501bf215546Sopenharmony_ci         _mesa_glsl_error(loc, state, "memory qualifiers may only be applied "
3502bf215546Sopenharmony_ci                          "in the declarations of image variables, buffer "
3503bf215546Sopenharmony_ci                          "variables, and shader storage blocks");
3504bf215546Sopenharmony_ci         return false;
3505bf215546Sopenharmony_ci      }
3506bf215546Sopenharmony_ci   }
3507bf215546Sopenharmony_ci   return true;
3508bf215546Sopenharmony_ci}
3509bf215546Sopenharmony_ci
3510bf215546Sopenharmony_cistatic bool
3511bf215546Sopenharmony_civalidate_image_format_qualifier_for_type(struct _mesa_glsl_parse_state *state,
3512bf215546Sopenharmony_ci                                         YYLTYPE *loc,
3513bf215546Sopenharmony_ci                                         const struct ast_type_qualifier *qual,
3514bf215546Sopenharmony_ci                                         const glsl_type *type)
3515bf215546Sopenharmony_ci{
3516bf215546Sopenharmony_ci   /* From section 4.4.6.2 (Format Layout Qualifiers) of the GLSL 4.50 spec:
3517bf215546Sopenharmony_ci    *
3518bf215546Sopenharmony_ci    * "Format layout qualifiers can be used on image variable declarations
3519bf215546Sopenharmony_ci    *  (those declared with a basic type  having “image ” in its keyword)."
3520bf215546Sopenharmony_ci    */
3521bf215546Sopenharmony_ci   if (!type->is_image() && qual->flags.q.explicit_image_format) {
3522bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state, "format layout qualifiers may only be "
3523bf215546Sopenharmony_ci                       "applied to images");
3524bf215546Sopenharmony_ci      return false;
3525bf215546Sopenharmony_ci   }
3526bf215546Sopenharmony_ci   return true;
3527bf215546Sopenharmony_ci}
3528bf215546Sopenharmony_ci
3529bf215546Sopenharmony_cistatic void
3530bf215546Sopenharmony_ciapply_image_qualifier_to_variable(const struct ast_type_qualifier *qual,
3531bf215546Sopenharmony_ci                                  ir_variable *var,
3532bf215546Sopenharmony_ci                                  struct _mesa_glsl_parse_state *state,
3533bf215546Sopenharmony_ci                                  YYLTYPE *loc)
3534bf215546Sopenharmony_ci{
3535bf215546Sopenharmony_ci   const glsl_type *base_type = var->type->without_array();
3536bf215546Sopenharmony_ci
3537bf215546Sopenharmony_ci   if (!validate_image_format_qualifier_for_type(state, loc, qual, base_type) ||
3538bf215546Sopenharmony_ci       !validate_memory_qualifier_for_type(state, loc, qual, base_type))
3539bf215546Sopenharmony_ci      return;
3540bf215546Sopenharmony_ci
3541bf215546Sopenharmony_ci   if (!base_type->is_image())
3542bf215546Sopenharmony_ci      return;
3543bf215546Sopenharmony_ci
3544bf215546Sopenharmony_ci   if (!validate_storage_for_sampler_image_types(var, state, loc))
3545bf215546Sopenharmony_ci      return;
3546bf215546Sopenharmony_ci
3547bf215546Sopenharmony_ci   var->data.memory_read_only |= qual->flags.q.read_only;
3548bf215546Sopenharmony_ci   var->data.memory_write_only |= qual->flags.q.write_only;
3549bf215546Sopenharmony_ci   var->data.memory_coherent |= qual->flags.q.coherent;
3550bf215546Sopenharmony_ci   var->data.memory_volatile |= qual->flags.q._volatile;
3551bf215546Sopenharmony_ci   var->data.memory_restrict |= qual->flags.q.restrict_flag;
3552bf215546Sopenharmony_ci
3553bf215546Sopenharmony_ci   if (qual->flags.q.explicit_image_format) {
3554bf215546Sopenharmony_ci      if (var->data.mode == ir_var_function_in) {
3555bf215546Sopenharmony_ci         _mesa_glsl_error(loc, state, "format qualifiers cannot be used on "
3556bf215546Sopenharmony_ci                          "image function parameters");
3557bf215546Sopenharmony_ci      }
3558bf215546Sopenharmony_ci
3559bf215546Sopenharmony_ci      if (qual->image_base_type != base_type->sampled_type) {
3560bf215546Sopenharmony_ci         _mesa_glsl_error(loc, state, "format qualifier doesn't match the base "
3561bf215546Sopenharmony_ci                          "data type of the image");
3562bf215546Sopenharmony_ci      }
3563bf215546Sopenharmony_ci
3564bf215546Sopenharmony_ci      var->data.image_format = qual->image_format;
3565bf215546Sopenharmony_ci   } else if (state->has_image_load_formatted()) {
3566bf215546Sopenharmony_ci      if (var->data.mode == ir_var_uniform &&
3567bf215546Sopenharmony_ci          state->EXT_shader_image_load_formatted_warn) {
3568bf215546Sopenharmony_ci         _mesa_glsl_warning(loc, state, "GL_EXT_image_load_formatted used");
3569bf215546Sopenharmony_ci      }
3570bf215546Sopenharmony_ci   } else {
3571bf215546Sopenharmony_ci      if (var->data.mode == ir_var_uniform) {
3572bf215546Sopenharmony_ci         if (state->es_shader ||
3573bf215546Sopenharmony_ci             !(state->is_version(420, 310) || state->ARB_shader_image_load_store_enable)) {
3574bf215546Sopenharmony_ci            _mesa_glsl_error(loc, state, "all image uniforms must have a "
3575bf215546Sopenharmony_ci                             "format layout qualifier");
3576bf215546Sopenharmony_ci         } else if (!qual->flags.q.write_only) {
3577bf215546Sopenharmony_ci            _mesa_glsl_error(loc, state, "image uniforms not qualified with "
3578bf215546Sopenharmony_ci                             "`writeonly' must have a format layout qualifier");
3579bf215546Sopenharmony_ci         }
3580bf215546Sopenharmony_ci      }
3581bf215546Sopenharmony_ci      var->data.image_format = PIPE_FORMAT_NONE;
3582bf215546Sopenharmony_ci   }
3583bf215546Sopenharmony_ci
3584bf215546Sopenharmony_ci   /* From page 70 of the GLSL ES 3.1 specification:
3585bf215546Sopenharmony_ci    *
3586bf215546Sopenharmony_ci    * "Except for image variables qualified with the format qualifiers r32f,
3587bf215546Sopenharmony_ci    *  r32i, and r32ui, image variables must specify either memory qualifier
3588bf215546Sopenharmony_ci    *  readonly or the memory qualifier writeonly."
3589bf215546Sopenharmony_ci    */
3590bf215546Sopenharmony_ci   if (state->es_shader &&
3591bf215546Sopenharmony_ci       var->data.image_format != PIPE_FORMAT_R32_FLOAT &&
3592bf215546Sopenharmony_ci       var->data.image_format != PIPE_FORMAT_R32_SINT &&
3593bf215546Sopenharmony_ci       var->data.image_format != PIPE_FORMAT_R32_UINT &&
3594bf215546Sopenharmony_ci       !var->data.memory_read_only &&
3595bf215546Sopenharmony_ci       !var->data.memory_write_only) {
3596bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state, "image variables of format other than r32f, "
3597bf215546Sopenharmony_ci                       "r32i or r32ui must be qualified `readonly' or "
3598bf215546Sopenharmony_ci                       "`writeonly'");
3599bf215546Sopenharmony_ci   }
3600bf215546Sopenharmony_ci}
3601bf215546Sopenharmony_ci
3602bf215546Sopenharmony_cistatic inline const char*
3603bf215546Sopenharmony_ciget_layout_qualifier_string(bool origin_upper_left, bool pixel_center_integer)
3604bf215546Sopenharmony_ci{
3605bf215546Sopenharmony_ci   if (origin_upper_left && pixel_center_integer)
3606bf215546Sopenharmony_ci      return "origin_upper_left, pixel_center_integer";
3607bf215546Sopenharmony_ci   else if (origin_upper_left)
3608bf215546Sopenharmony_ci      return "origin_upper_left";
3609bf215546Sopenharmony_ci   else if (pixel_center_integer)
3610bf215546Sopenharmony_ci      return "pixel_center_integer";
3611bf215546Sopenharmony_ci   else
3612bf215546Sopenharmony_ci      return " ";
3613bf215546Sopenharmony_ci}
3614bf215546Sopenharmony_ci
3615bf215546Sopenharmony_cistatic inline bool
3616bf215546Sopenharmony_ciis_conflicting_fragcoord_redeclaration(struct _mesa_glsl_parse_state *state,
3617bf215546Sopenharmony_ci                                       const struct ast_type_qualifier *qual)
3618bf215546Sopenharmony_ci{
3619bf215546Sopenharmony_ci   /* If gl_FragCoord was previously declared, and the qualifiers were
3620bf215546Sopenharmony_ci    * different in any way, return true.
3621bf215546Sopenharmony_ci    */
3622bf215546Sopenharmony_ci   if (state->fs_redeclares_gl_fragcoord) {
3623bf215546Sopenharmony_ci      return (state->fs_pixel_center_integer != qual->flags.q.pixel_center_integer
3624bf215546Sopenharmony_ci         || state->fs_origin_upper_left != qual->flags.q.origin_upper_left);
3625bf215546Sopenharmony_ci   }
3626bf215546Sopenharmony_ci
3627bf215546Sopenharmony_ci   return false;
3628bf215546Sopenharmony_ci}
3629bf215546Sopenharmony_ci
3630bf215546Sopenharmony_cistatic inline bool
3631bf215546Sopenharmony_ciis_conflicting_layer_redeclaration(struct _mesa_glsl_parse_state *state,
3632bf215546Sopenharmony_ci                                   const struct ast_type_qualifier *qual)
3633bf215546Sopenharmony_ci{
3634bf215546Sopenharmony_ci   if (state->redeclares_gl_layer) {
3635bf215546Sopenharmony_ci      return state->layer_viewport_relative != qual->flags.q.viewport_relative;
3636bf215546Sopenharmony_ci   }
3637bf215546Sopenharmony_ci   return false;
3638bf215546Sopenharmony_ci}
3639bf215546Sopenharmony_ci
3640bf215546Sopenharmony_cistatic inline void
3641bf215546Sopenharmony_civalidate_array_dimensions(const glsl_type *t,
3642bf215546Sopenharmony_ci                          struct _mesa_glsl_parse_state *state,
3643bf215546Sopenharmony_ci                          YYLTYPE *loc) {
3644bf215546Sopenharmony_ci   if (t->is_array()) {
3645bf215546Sopenharmony_ci      t = t->fields.array;
3646bf215546Sopenharmony_ci      while (t->is_array()) {
3647bf215546Sopenharmony_ci         if (t->is_unsized_array()) {
3648bf215546Sopenharmony_ci            _mesa_glsl_error(loc, state,
3649bf215546Sopenharmony_ci                             "only the outermost array dimension can "
3650bf215546Sopenharmony_ci                             "be unsized",
3651bf215546Sopenharmony_ci                             t->name);
3652bf215546Sopenharmony_ci            break;
3653bf215546Sopenharmony_ci         }
3654bf215546Sopenharmony_ci         t = t->fields.array;
3655bf215546Sopenharmony_ci      }
3656bf215546Sopenharmony_ci   }
3657bf215546Sopenharmony_ci}
3658bf215546Sopenharmony_ci
3659bf215546Sopenharmony_cistatic void
3660bf215546Sopenharmony_ciapply_bindless_qualifier_to_variable(const struct ast_type_qualifier *qual,
3661bf215546Sopenharmony_ci                                     ir_variable *var,
3662bf215546Sopenharmony_ci                                     struct _mesa_glsl_parse_state *state,
3663bf215546Sopenharmony_ci                                     YYLTYPE *loc)
3664bf215546Sopenharmony_ci{
3665bf215546Sopenharmony_ci   bool has_local_qualifiers = qual->flags.q.bindless_sampler ||
3666bf215546Sopenharmony_ci                               qual->flags.q.bindless_image ||
3667bf215546Sopenharmony_ci                               qual->flags.q.bound_sampler ||
3668bf215546Sopenharmony_ci                               qual->flags.q.bound_image;
3669bf215546Sopenharmony_ci
3670bf215546Sopenharmony_ci   /* The ARB_bindless_texture spec says:
3671bf215546Sopenharmony_ci    *
3672bf215546Sopenharmony_ci    * "Modify Section 4.4.6 Opaque-Uniform Layout Qualifiers of the GLSL 4.30
3673bf215546Sopenharmony_ci    *  spec"
3674bf215546Sopenharmony_ci    *
3675bf215546Sopenharmony_ci    * "If these layout qualifiers are applied to other types of default block
3676bf215546Sopenharmony_ci    *  uniforms, or variables with non-uniform storage, a compile-time error
3677bf215546Sopenharmony_ci    *  will be generated."
3678bf215546Sopenharmony_ci    */
3679bf215546Sopenharmony_ci   if (has_local_qualifiers && !qual->flags.q.uniform) {
3680bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state, "ARB_bindless_texture layout qualifiers "
3681bf215546Sopenharmony_ci                       "can only be applied to default block uniforms or "
3682bf215546Sopenharmony_ci                       "variables with uniform storage");
3683bf215546Sopenharmony_ci      return;
3684bf215546Sopenharmony_ci   }
3685bf215546Sopenharmony_ci
3686bf215546Sopenharmony_ci   /* The ARB_bindless_texture spec doesn't state anything in this situation,
3687bf215546Sopenharmony_ci    * but it makes sense to only allow bindless_sampler/bound_sampler for
3688bf215546Sopenharmony_ci    * sampler types, and respectively bindless_image/bound_image for image
3689bf215546Sopenharmony_ci    * types.
3690bf215546Sopenharmony_ci    */
3691bf215546Sopenharmony_ci   if ((qual->flags.q.bindless_sampler || qual->flags.q.bound_sampler) &&
3692bf215546Sopenharmony_ci       !var->type->contains_sampler()) {
3693bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state, "bindless_sampler or bound_sampler can only "
3694bf215546Sopenharmony_ci                       "be applied to sampler types");
3695bf215546Sopenharmony_ci      return;
3696bf215546Sopenharmony_ci   }
3697bf215546Sopenharmony_ci
3698bf215546Sopenharmony_ci   if ((qual->flags.q.bindless_image || qual->flags.q.bound_image) &&
3699bf215546Sopenharmony_ci       !var->type->contains_image()) {
3700bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state, "bindless_image or bound_image can only be "
3701bf215546Sopenharmony_ci                       "applied to image types");
3702bf215546Sopenharmony_ci      return;
3703bf215546Sopenharmony_ci   }
3704bf215546Sopenharmony_ci
3705bf215546Sopenharmony_ci   /* The bindless_sampler/bindless_image (and respectively
3706bf215546Sopenharmony_ci    * bound_sampler/bound_image) layout qualifiers can be set at global and at
3707bf215546Sopenharmony_ci    * local scope.
3708bf215546Sopenharmony_ci    */
3709bf215546Sopenharmony_ci   if (var->type->contains_sampler() || var->type->contains_image()) {
3710bf215546Sopenharmony_ci      var->data.bindless = qual->flags.q.bindless_sampler ||
3711bf215546Sopenharmony_ci                           qual->flags.q.bindless_image ||
3712bf215546Sopenharmony_ci                           state->bindless_sampler_specified ||
3713bf215546Sopenharmony_ci                           state->bindless_image_specified;
3714bf215546Sopenharmony_ci
3715bf215546Sopenharmony_ci      var->data.bound = qual->flags.q.bound_sampler ||
3716bf215546Sopenharmony_ci                        qual->flags.q.bound_image ||
3717bf215546Sopenharmony_ci                        state->bound_sampler_specified ||
3718bf215546Sopenharmony_ci                        state->bound_image_specified;
3719bf215546Sopenharmony_ci   }
3720bf215546Sopenharmony_ci}
3721bf215546Sopenharmony_ci
3722bf215546Sopenharmony_cistatic void
3723bf215546Sopenharmony_ciapply_layout_qualifier_to_variable(const struct ast_type_qualifier *qual,
3724bf215546Sopenharmony_ci                                   ir_variable *var,
3725bf215546Sopenharmony_ci                                   struct _mesa_glsl_parse_state *state,
3726bf215546Sopenharmony_ci                                   YYLTYPE *loc)
3727bf215546Sopenharmony_ci{
3728bf215546Sopenharmony_ci   if (var->name != NULL && strcmp(var->name, "gl_FragCoord") == 0) {
3729bf215546Sopenharmony_ci
3730bf215546Sopenharmony_ci      /* Section 4.3.8.1, page 39 of GLSL 1.50 spec says:
3731bf215546Sopenharmony_ci       *
3732bf215546Sopenharmony_ci       *    "Within any shader, the first redeclarations of gl_FragCoord
3733bf215546Sopenharmony_ci       *     must appear before any use of gl_FragCoord."
3734bf215546Sopenharmony_ci       *
3735bf215546Sopenharmony_ci       * Generate a compiler error if above condition is not met by the
3736bf215546Sopenharmony_ci       * fragment shader.
3737bf215546Sopenharmony_ci       */
3738bf215546Sopenharmony_ci      ir_variable *earlier = state->symbols->get_variable("gl_FragCoord");
3739bf215546Sopenharmony_ci      if (earlier != NULL &&
3740bf215546Sopenharmony_ci          earlier->data.used &&
3741bf215546Sopenharmony_ci          !state->fs_redeclares_gl_fragcoord) {
3742bf215546Sopenharmony_ci         _mesa_glsl_error(loc, state,
3743bf215546Sopenharmony_ci                          "gl_FragCoord used before its first redeclaration "
3744bf215546Sopenharmony_ci                          "in fragment shader");
3745bf215546Sopenharmony_ci      }
3746bf215546Sopenharmony_ci
3747bf215546Sopenharmony_ci      /* Make sure all gl_FragCoord redeclarations specify the same layout
3748bf215546Sopenharmony_ci       * qualifiers.
3749bf215546Sopenharmony_ci       */
3750bf215546Sopenharmony_ci      if (is_conflicting_fragcoord_redeclaration(state, qual)) {
3751bf215546Sopenharmony_ci         const char *const qual_string =
3752bf215546Sopenharmony_ci            get_layout_qualifier_string(qual->flags.q.origin_upper_left,
3753bf215546Sopenharmony_ci                                        qual->flags.q.pixel_center_integer);
3754bf215546Sopenharmony_ci
3755bf215546Sopenharmony_ci         const char *const state_string =
3756bf215546Sopenharmony_ci            get_layout_qualifier_string(state->fs_origin_upper_left,
3757bf215546Sopenharmony_ci                                        state->fs_pixel_center_integer);
3758bf215546Sopenharmony_ci
3759bf215546Sopenharmony_ci         _mesa_glsl_error(loc, state,
3760bf215546Sopenharmony_ci                          "gl_FragCoord redeclared with different layout "
3761bf215546Sopenharmony_ci                          "qualifiers (%s) and (%s) ",
3762bf215546Sopenharmony_ci                          state_string,
3763bf215546Sopenharmony_ci                          qual_string);
3764bf215546Sopenharmony_ci      }
3765bf215546Sopenharmony_ci      state->fs_origin_upper_left = qual->flags.q.origin_upper_left;
3766bf215546Sopenharmony_ci      state->fs_pixel_center_integer = qual->flags.q.pixel_center_integer;
3767bf215546Sopenharmony_ci      state->fs_redeclares_gl_fragcoord_with_no_layout_qualifiers =
3768bf215546Sopenharmony_ci         !qual->flags.q.origin_upper_left && !qual->flags.q.pixel_center_integer;
3769bf215546Sopenharmony_ci      state->fs_redeclares_gl_fragcoord =
3770bf215546Sopenharmony_ci         state->fs_origin_upper_left ||
3771bf215546Sopenharmony_ci         state->fs_pixel_center_integer ||
3772bf215546Sopenharmony_ci         state->fs_redeclares_gl_fragcoord_with_no_layout_qualifiers;
3773bf215546Sopenharmony_ci   }
3774bf215546Sopenharmony_ci
3775bf215546Sopenharmony_ci   if ((qual->flags.q.origin_upper_left || qual->flags.q.pixel_center_integer)
3776bf215546Sopenharmony_ci       && (strcmp(var->name, "gl_FragCoord") != 0)) {
3777bf215546Sopenharmony_ci      const char *const qual_string = (qual->flags.q.origin_upper_left)
3778bf215546Sopenharmony_ci         ? "origin_upper_left" : "pixel_center_integer";
3779bf215546Sopenharmony_ci
3780bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state,
3781bf215546Sopenharmony_ci                       "layout qualifier `%s' can only be applied to "
3782bf215546Sopenharmony_ci                       "fragment shader input `gl_FragCoord'",
3783bf215546Sopenharmony_ci                       qual_string);
3784bf215546Sopenharmony_ci   }
3785bf215546Sopenharmony_ci
3786bf215546Sopenharmony_ci   if (qual->flags.q.explicit_location) {
3787bf215546Sopenharmony_ci      apply_explicit_location(qual, var, state, loc);
3788bf215546Sopenharmony_ci
3789bf215546Sopenharmony_ci      if (qual->flags.q.explicit_component) {
3790bf215546Sopenharmony_ci         unsigned qual_component;
3791bf215546Sopenharmony_ci         if (process_qualifier_constant(state, loc, "component",
3792bf215546Sopenharmony_ci                                        qual->component, &qual_component)) {
3793bf215546Sopenharmony_ci            validate_component_layout_for_type(state, loc, var->type,
3794bf215546Sopenharmony_ci                                               qual_component);
3795bf215546Sopenharmony_ci            var->data.explicit_component = true;
3796bf215546Sopenharmony_ci            var->data.location_frac = qual_component;
3797bf215546Sopenharmony_ci         }
3798bf215546Sopenharmony_ci      }
3799bf215546Sopenharmony_ci   } else if (qual->flags.q.explicit_index) {
3800bf215546Sopenharmony_ci      if (!qual->subroutine_list)
3801bf215546Sopenharmony_ci         _mesa_glsl_error(loc, state,
3802bf215546Sopenharmony_ci                          "explicit index requires explicit location");
3803bf215546Sopenharmony_ci   } else if (qual->flags.q.explicit_component) {
3804bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state,
3805bf215546Sopenharmony_ci                       "explicit component requires explicit location");
3806bf215546Sopenharmony_ci   }
3807bf215546Sopenharmony_ci
3808bf215546Sopenharmony_ci   if (qual->flags.q.explicit_binding) {
3809bf215546Sopenharmony_ci      apply_explicit_binding(state, loc, var, var->type, qual);
3810bf215546Sopenharmony_ci   }
3811bf215546Sopenharmony_ci
3812bf215546Sopenharmony_ci   if (state->stage == MESA_SHADER_GEOMETRY &&
3813bf215546Sopenharmony_ci       qual->flags.q.out && qual->flags.q.stream) {
3814bf215546Sopenharmony_ci      unsigned qual_stream;
3815bf215546Sopenharmony_ci      if (process_qualifier_constant(state, loc, "stream", qual->stream,
3816bf215546Sopenharmony_ci                                     &qual_stream) &&
3817bf215546Sopenharmony_ci          validate_stream_qualifier(loc, state, qual_stream)) {
3818bf215546Sopenharmony_ci         var->data.stream = qual_stream;
3819bf215546Sopenharmony_ci      }
3820bf215546Sopenharmony_ci   }
3821bf215546Sopenharmony_ci
3822bf215546Sopenharmony_ci   if (qual->flags.q.out && qual->flags.q.xfb_buffer) {
3823bf215546Sopenharmony_ci      unsigned qual_xfb_buffer;
3824bf215546Sopenharmony_ci      if (process_qualifier_constant(state, loc, "xfb_buffer",
3825bf215546Sopenharmony_ci                                     qual->xfb_buffer, &qual_xfb_buffer) &&
3826bf215546Sopenharmony_ci          validate_xfb_buffer_qualifier(loc, state, qual_xfb_buffer)) {
3827bf215546Sopenharmony_ci         var->data.xfb_buffer = qual_xfb_buffer;
3828bf215546Sopenharmony_ci         if (qual->flags.q.explicit_xfb_buffer)
3829bf215546Sopenharmony_ci            var->data.explicit_xfb_buffer = true;
3830bf215546Sopenharmony_ci      }
3831bf215546Sopenharmony_ci   }
3832bf215546Sopenharmony_ci
3833bf215546Sopenharmony_ci   if (qual->flags.q.explicit_xfb_offset) {
3834bf215546Sopenharmony_ci      unsigned qual_xfb_offset;
3835bf215546Sopenharmony_ci      unsigned component_size = var->type->contains_double() ? 8 : 4;
3836bf215546Sopenharmony_ci
3837bf215546Sopenharmony_ci      if (process_qualifier_constant(state, loc, "xfb_offset",
3838bf215546Sopenharmony_ci                                     qual->offset, &qual_xfb_offset) &&
3839bf215546Sopenharmony_ci          validate_xfb_offset_qualifier(loc, state, (int) qual_xfb_offset,
3840bf215546Sopenharmony_ci                                        var->type, component_size)) {
3841bf215546Sopenharmony_ci         var->data.offset = qual_xfb_offset;
3842bf215546Sopenharmony_ci         var->data.explicit_xfb_offset = true;
3843bf215546Sopenharmony_ci      }
3844bf215546Sopenharmony_ci   }
3845bf215546Sopenharmony_ci
3846bf215546Sopenharmony_ci   if (qual->flags.q.explicit_xfb_stride) {
3847bf215546Sopenharmony_ci      unsigned qual_xfb_stride;
3848bf215546Sopenharmony_ci      if (process_qualifier_constant(state, loc, "xfb_stride",
3849bf215546Sopenharmony_ci                                     qual->xfb_stride, &qual_xfb_stride)) {
3850bf215546Sopenharmony_ci         var->data.xfb_stride = qual_xfb_stride;
3851bf215546Sopenharmony_ci         var->data.explicit_xfb_stride = true;
3852bf215546Sopenharmony_ci      }
3853bf215546Sopenharmony_ci   }
3854bf215546Sopenharmony_ci
3855bf215546Sopenharmony_ci   if (var->type->contains_atomic()) {
3856bf215546Sopenharmony_ci      if (var->data.mode == ir_var_uniform) {
3857bf215546Sopenharmony_ci         if (var->data.explicit_binding) {
3858bf215546Sopenharmony_ci            unsigned *offset =
3859bf215546Sopenharmony_ci               &state->atomic_counter_offsets[var->data.binding];
3860bf215546Sopenharmony_ci
3861bf215546Sopenharmony_ci            if (*offset % ATOMIC_COUNTER_SIZE)
3862bf215546Sopenharmony_ci               _mesa_glsl_error(loc, state,
3863bf215546Sopenharmony_ci                                "misaligned atomic counter offset");
3864bf215546Sopenharmony_ci
3865bf215546Sopenharmony_ci            var->data.offset = *offset;
3866bf215546Sopenharmony_ci            *offset += var->type->atomic_size();
3867bf215546Sopenharmony_ci
3868bf215546Sopenharmony_ci         } else {
3869bf215546Sopenharmony_ci            _mesa_glsl_error(loc, state,
3870bf215546Sopenharmony_ci                             "atomic counters require explicit binding point");
3871bf215546Sopenharmony_ci         }
3872bf215546Sopenharmony_ci      } else if (var->data.mode != ir_var_function_in) {
3873bf215546Sopenharmony_ci         _mesa_glsl_error(loc, state, "atomic counters may only be declared as "
3874bf215546Sopenharmony_ci                          "function parameters or uniform-qualified "
3875bf215546Sopenharmony_ci                          "global variables");
3876bf215546Sopenharmony_ci      }
3877bf215546Sopenharmony_ci   }
3878bf215546Sopenharmony_ci
3879bf215546Sopenharmony_ci   if (var->type->contains_sampler() &&
3880bf215546Sopenharmony_ci       !validate_storage_for_sampler_image_types(var, state, loc))
3881bf215546Sopenharmony_ci      return;
3882bf215546Sopenharmony_ci
3883bf215546Sopenharmony_ci   /* Is the 'layout' keyword used with parameters that allow relaxed checking.
3884bf215546Sopenharmony_ci    * Many implementations of GL_ARB_fragment_coord_conventions_enable and some
3885bf215546Sopenharmony_ci    * implementations (only Mesa?) GL_ARB_explicit_attrib_location_enable
3886bf215546Sopenharmony_ci    * allowed the layout qualifier to be used with 'varying' and 'attribute'.
3887bf215546Sopenharmony_ci    * These extensions and all following extensions that add the 'layout'
3888bf215546Sopenharmony_ci    * keyword have been modified to require the use of 'in' or 'out'.
3889bf215546Sopenharmony_ci    *
3890bf215546Sopenharmony_ci    * The following extension do not allow the deprecated keywords:
3891bf215546Sopenharmony_ci    *
3892bf215546Sopenharmony_ci    *    GL_AMD_conservative_depth
3893bf215546Sopenharmony_ci    *    GL_ARB_conservative_depth
3894bf215546Sopenharmony_ci    *    GL_ARB_gpu_shader5
3895bf215546Sopenharmony_ci    *    GL_ARB_separate_shader_objects
3896bf215546Sopenharmony_ci    *    GL_ARB_tessellation_shader
3897bf215546Sopenharmony_ci    *    GL_ARB_transform_feedback3
3898bf215546Sopenharmony_ci    *    GL_ARB_uniform_buffer_object
3899bf215546Sopenharmony_ci    *
3900bf215546Sopenharmony_ci    * It is unknown whether GL_EXT_shader_image_load_store or GL_NV_gpu_shader5
3901bf215546Sopenharmony_ci    * allow layout with the deprecated keywords.
3902bf215546Sopenharmony_ci    */
3903bf215546Sopenharmony_ci   const bool relaxed_layout_qualifier_checking =
3904bf215546Sopenharmony_ci      state->ARB_fragment_coord_conventions_enable;
3905bf215546Sopenharmony_ci
3906bf215546Sopenharmony_ci   const bool uses_deprecated_qualifier = qual->flags.q.attribute
3907bf215546Sopenharmony_ci      || qual->flags.q.varying;
3908bf215546Sopenharmony_ci   if (qual->has_layout() && uses_deprecated_qualifier) {
3909bf215546Sopenharmony_ci      if (relaxed_layout_qualifier_checking) {
3910bf215546Sopenharmony_ci         _mesa_glsl_warning(loc, state,
3911bf215546Sopenharmony_ci                            "`layout' qualifier may not be used with "
3912bf215546Sopenharmony_ci                            "`attribute' or `varying'");
3913bf215546Sopenharmony_ci      } else {
3914bf215546Sopenharmony_ci         _mesa_glsl_error(loc, state,
3915bf215546Sopenharmony_ci                          "`layout' qualifier may not be used with "
3916bf215546Sopenharmony_ci                          "`attribute' or `varying'");
3917bf215546Sopenharmony_ci      }
3918bf215546Sopenharmony_ci   }
3919bf215546Sopenharmony_ci
3920bf215546Sopenharmony_ci   /* Layout qualifiers for gl_FragDepth, which are enabled by extension
3921bf215546Sopenharmony_ci    * AMD_conservative_depth.
3922bf215546Sopenharmony_ci    */
3923bf215546Sopenharmony_ci   if (qual->flags.q.depth_type
3924bf215546Sopenharmony_ci       && !state->is_version(420, 0)
3925bf215546Sopenharmony_ci       && !state->AMD_conservative_depth_enable
3926bf215546Sopenharmony_ci       && !state->ARB_conservative_depth_enable) {
3927bf215546Sopenharmony_ci       _mesa_glsl_error(loc, state,
3928bf215546Sopenharmony_ci                        "extension GL_AMD_conservative_depth or "
3929bf215546Sopenharmony_ci                        "GL_ARB_conservative_depth must be enabled "
3930bf215546Sopenharmony_ci                        "to use depth layout qualifiers");
3931bf215546Sopenharmony_ci   } else if (qual->flags.q.depth_type
3932bf215546Sopenharmony_ci              && strcmp(var->name, "gl_FragDepth") != 0) {
3933bf215546Sopenharmony_ci       _mesa_glsl_error(loc, state,
3934bf215546Sopenharmony_ci                        "depth layout qualifiers can be applied only to "
3935bf215546Sopenharmony_ci                        "gl_FragDepth");
3936bf215546Sopenharmony_ci   }
3937bf215546Sopenharmony_ci
3938bf215546Sopenharmony_ci   switch (qual->depth_type) {
3939bf215546Sopenharmony_ci   case ast_depth_any:
3940bf215546Sopenharmony_ci      var->data.depth_layout = ir_depth_layout_any;
3941bf215546Sopenharmony_ci      break;
3942bf215546Sopenharmony_ci   case ast_depth_greater:
3943bf215546Sopenharmony_ci      var->data.depth_layout = ir_depth_layout_greater;
3944bf215546Sopenharmony_ci      break;
3945bf215546Sopenharmony_ci   case ast_depth_less:
3946bf215546Sopenharmony_ci      var->data.depth_layout = ir_depth_layout_less;
3947bf215546Sopenharmony_ci      break;
3948bf215546Sopenharmony_ci   case ast_depth_unchanged:
3949bf215546Sopenharmony_ci      var->data.depth_layout = ir_depth_layout_unchanged;
3950bf215546Sopenharmony_ci      break;
3951bf215546Sopenharmony_ci   default:
3952bf215546Sopenharmony_ci      var->data.depth_layout = ir_depth_layout_none;
3953bf215546Sopenharmony_ci      break;
3954bf215546Sopenharmony_ci   }
3955bf215546Sopenharmony_ci
3956bf215546Sopenharmony_ci   if (qual->flags.q.std140 ||
3957bf215546Sopenharmony_ci       qual->flags.q.std430 ||
3958bf215546Sopenharmony_ci       qual->flags.q.packed ||
3959bf215546Sopenharmony_ci       qual->flags.q.shared) {
3960bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state,
3961bf215546Sopenharmony_ci                       "uniform and shader storage block layout qualifiers "
3962bf215546Sopenharmony_ci                       "std140, std430, packed, and shared can only be "
3963bf215546Sopenharmony_ci                       "applied to uniform or shader storage blocks, not "
3964bf215546Sopenharmony_ci                       "members");
3965bf215546Sopenharmony_ci   }
3966bf215546Sopenharmony_ci
3967bf215546Sopenharmony_ci   if (qual->flags.q.row_major || qual->flags.q.column_major) {
3968bf215546Sopenharmony_ci      validate_matrix_layout_for_type(state, loc, var->type, var);
3969bf215546Sopenharmony_ci   }
3970bf215546Sopenharmony_ci
3971bf215546Sopenharmony_ci   /* From section 4.4.1.3 of the GLSL 4.50 specification (Fragment Shader
3972bf215546Sopenharmony_ci    * Inputs):
3973bf215546Sopenharmony_ci    *
3974bf215546Sopenharmony_ci    *  "Fragment shaders also allow the following layout qualifier on in only
3975bf215546Sopenharmony_ci    *   (not with variable declarations)
3976bf215546Sopenharmony_ci    *     layout-qualifier-id
3977bf215546Sopenharmony_ci    *        early_fragment_tests
3978bf215546Sopenharmony_ci    *   [...]"
3979bf215546Sopenharmony_ci    */
3980bf215546Sopenharmony_ci   if (qual->flags.q.early_fragment_tests) {
3981bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state, "early_fragment_tests layout qualifier only "
3982bf215546Sopenharmony_ci                       "valid in fragment shader input layout declaration.");
3983bf215546Sopenharmony_ci   }
3984bf215546Sopenharmony_ci
3985bf215546Sopenharmony_ci   if (qual->flags.q.inner_coverage) {
3986bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state, "inner_coverage layout qualifier only "
3987bf215546Sopenharmony_ci                       "valid in fragment shader input layout declaration.");
3988bf215546Sopenharmony_ci   }
3989bf215546Sopenharmony_ci
3990bf215546Sopenharmony_ci   if (qual->flags.q.post_depth_coverage) {
3991bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state, "post_depth_coverage layout qualifier only "
3992bf215546Sopenharmony_ci                       "valid in fragment shader input layout declaration.");
3993bf215546Sopenharmony_ci   }
3994bf215546Sopenharmony_ci
3995bf215546Sopenharmony_ci   if (state->has_bindless())
3996bf215546Sopenharmony_ci      apply_bindless_qualifier_to_variable(qual, var, state, loc);
3997bf215546Sopenharmony_ci
3998bf215546Sopenharmony_ci   if (qual->flags.q.pixel_interlock_ordered ||
3999bf215546Sopenharmony_ci       qual->flags.q.pixel_interlock_unordered ||
4000bf215546Sopenharmony_ci       qual->flags.q.sample_interlock_ordered ||
4001bf215546Sopenharmony_ci       qual->flags.q.sample_interlock_unordered) {
4002bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state, "interlock layout qualifiers: "
4003bf215546Sopenharmony_ci                       "pixel_interlock_ordered, pixel_interlock_unordered, "
4004bf215546Sopenharmony_ci                       "sample_interlock_ordered and sample_interlock_unordered, "
4005bf215546Sopenharmony_ci                       "only valid in fragment shader input layout declaration.");
4006bf215546Sopenharmony_ci   }
4007bf215546Sopenharmony_ci
4008bf215546Sopenharmony_ci   if (var->name != NULL && strcmp(var->name, "gl_Layer") == 0) {
4009bf215546Sopenharmony_ci      if (is_conflicting_layer_redeclaration(state, qual)) {
4010bf215546Sopenharmony_ci         _mesa_glsl_error(loc, state, "gl_Layer redeclaration with "
4011bf215546Sopenharmony_ci                          "different viewport_relative setting than earlier");
4012bf215546Sopenharmony_ci      }
4013bf215546Sopenharmony_ci      state->redeclares_gl_layer = true;
4014bf215546Sopenharmony_ci      if (qual->flags.q.viewport_relative) {
4015bf215546Sopenharmony_ci         state->layer_viewport_relative = true;
4016bf215546Sopenharmony_ci      }
4017bf215546Sopenharmony_ci   } else if (qual->flags.q.viewport_relative) {
4018bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state,
4019bf215546Sopenharmony_ci                       "viewport_relative qualifier "
4020bf215546Sopenharmony_ci                       "can only be applied to gl_Layer.");
4021bf215546Sopenharmony_ci   }
4022bf215546Sopenharmony_ci}
4023bf215546Sopenharmony_ci
4024bf215546Sopenharmony_cistatic void
4025bf215546Sopenharmony_ciapply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
4026bf215546Sopenharmony_ci                                 ir_variable *var,
4027bf215546Sopenharmony_ci                                 struct _mesa_glsl_parse_state *state,
4028bf215546Sopenharmony_ci                                 YYLTYPE *loc,
4029bf215546Sopenharmony_ci                                 bool is_parameter)
4030bf215546Sopenharmony_ci{
4031bf215546Sopenharmony_ci   STATIC_ASSERT(sizeof(qual->flags.q) <= sizeof(qual->flags.i));
4032bf215546Sopenharmony_ci
4033bf215546Sopenharmony_ci   if (qual->flags.q.invariant) {
4034bf215546Sopenharmony_ci      if (var->data.used) {
4035bf215546Sopenharmony_ci         _mesa_glsl_error(loc, state,
4036bf215546Sopenharmony_ci                          "variable `%s' may not be redeclared "
4037bf215546Sopenharmony_ci                          "`invariant' after being used",
4038bf215546Sopenharmony_ci                          var->name);
4039bf215546Sopenharmony_ci      } else {
4040bf215546Sopenharmony_ci         var->data.explicit_invariant = true;
4041bf215546Sopenharmony_ci         var->data.invariant = true;
4042bf215546Sopenharmony_ci      }
4043bf215546Sopenharmony_ci   }
4044bf215546Sopenharmony_ci
4045bf215546Sopenharmony_ci   if (qual->flags.q.precise) {
4046bf215546Sopenharmony_ci      if (var->data.used) {
4047bf215546Sopenharmony_ci         _mesa_glsl_error(loc, state,
4048bf215546Sopenharmony_ci                          "variable `%s' may not be redeclared "
4049bf215546Sopenharmony_ci                          "`precise' after being used",
4050bf215546Sopenharmony_ci                          var->name);
4051bf215546Sopenharmony_ci      } else {
4052bf215546Sopenharmony_ci         var->data.precise = 1;
4053bf215546Sopenharmony_ci      }
4054bf215546Sopenharmony_ci   }
4055bf215546Sopenharmony_ci
4056bf215546Sopenharmony_ci   if (qual->is_subroutine_decl() && !qual->flags.q.uniform) {
4057bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state,
4058bf215546Sopenharmony_ci                       "`subroutine' may only be applied to uniforms, "
4059bf215546Sopenharmony_ci                       "subroutine type declarations, or function definitions");
4060bf215546Sopenharmony_ci   }
4061bf215546Sopenharmony_ci
4062bf215546Sopenharmony_ci   if (qual->flags.q.constant || qual->flags.q.attribute
4063bf215546Sopenharmony_ci       || qual->flags.q.uniform
4064bf215546Sopenharmony_ci       || (qual->flags.q.varying && (state->stage == MESA_SHADER_FRAGMENT)))
4065bf215546Sopenharmony_ci      var->data.read_only = 1;
4066bf215546Sopenharmony_ci
4067bf215546Sopenharmony_ci   if (qual->flags.q.centroid)
4068bf215546Sopenharmony_ci      var->data.centroid = 1;
4069bf215546Sopenharmony_ci
4070bf215546Sopenharmony_ci   if (qual->flags.q.sample)
4071bf215546Sopenharmony_ci      var->data.sample = 1;
4072bf215546Sopenharmony_ci
4073bf215546Sopenharmony_ci   /* Precision qualifiers do not hold any meaning in Desktop GLSL */
4074bf215546Sopenharmony_ci   if (state->es_shader) {
4075bf215546Sopenharmony_ci      var->data.precision =
4076bf215546Sopenharmony_ci         select_gles_precision(qual->precision, var->type, state, loc);
4077bf215546Sopenharmony_ci   }
4078bf215546Sopenharmony_ci
4079bf215546Sopenharmony_ci   if (qual->flags.q.patch)
4080bf215546Sopenharmony_ci      var->data.patch = 1;
4081bf215546Sopenharmony_ci
4082bf215546Sopenharmony_ci   if (qual->flags.q.attribute && state->stage != MESA_SHADER_VERTEX) {
4083bf215546Sopenharmony_ci      var->type = glsl_type::error_type;
4084bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state,
4085bf215546Sopenharmony_ci                       "`attribute' variables may not be declared in the "
4086bf215546Sopenharmony_ci                       "%s shader",
4087bf215546Sopenharmony_ci                       _mesa_shader_stage_to_string(state->stage));
4088bf215546Sopenharmony_ci   }
4089bf215546Sopenharmony_ci
4090bf215546Sopenharmony_ci   /* Disallow layout qualifiers which may only appear on layout declarations. */
4091bf215546Sopenharmony_ci   if (qual->flags.q.prim_type) {
4092bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state,
4093bf215546Sopenharmony_ci                       "Primitive type may only be specified on GS input or output "
4094bf215546Sopenharmony_ci                       "layout declaration, not on variables.");
4095bf215546Sopenharmony_ci   }
4096bf215546Sopenharmony_ci
4097bf215546Sopenharmony_ci   /* Section 6.1.1 (Function Calling Conventions) of the GLSL 1.10 spec says:
4098bf215546Sopenharmony_ci    *
4099bf215546Sopenharmony_ci    *     "However, the const qualifier cannot be used with out or inout."
4100bf215546Sopenharmony_ci    *
4101bf215546Sopenharmony_ci    * The same section of the GLSL 4.40 spec further clarifies this saying:
4102bf215546Sopenharmony_ci    *
4103bf215546Sopenharmony_ci    *     "The const qualifier cannot be used with out or inout, or a
4104bf215546Sopenharmony_ci    *     compile-time error results."
4105bf215546Sopenharmony_ci    */
4106bf215546Sopenharmony_ci   if (is_parameter && qual->flags.q.constant && qual->flags.q.out) {
4107bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state,
4108bf215546Sopenharmony_ci                       "`const' may not be applied to `out' or `inout' "
4109bf215546Sopenharmony_ci                       "function parameters");
4110bf215546Sopenharmony_ci   }
4111bf215546Sopenharmony_ci
4112bf215546Sopenharmony_ci   /* If there is no qualifier that changes the mode of the variable, leave
4113bf215546Sopenharmony_ci    * the setting alone.
4114bf215546Sopenharmony_ci    */
4115bf215546Sopenharmony_ci   assert(var->data.mode != ir_var_temporary);
4116bf215546Sopenharmony_ci   if (qual->flags.q.in && qual->flags.q.out)
4117bf215546Sopenharmony_ci      var->data.mode = is_parameter ? ir_var_function_inout : ir_var_shader_out;
4118bf215546Sopenharmony_ci   else if (qual->flags.q.in)
4119bf215546Sopenharmony_ci      var->data.mode = is_parameter ? ir_var_function_in : ir_var_shader_in;
4120bf215546Sopenharmony_ci   else if (qual->flags.q.attribute
4121bf215546Sopenharmony_ci            || (qual->flags.q.varying && (state->stage == MESA_SHADER_FRAGMENT)))
4122bf215546Sopenharmony_ci      var->data.mode = ir_var_shader_in;
4123bf215546Sopenharmony_ci   else if (qual->flags.q.out)
4124bf215546Sopenharmony_ci      var->data.mode = is_parameter ? ir_var_function_out : ir_var_shader_out;
4125bf215546Sopenharmony_ci   else if (qual->flags.q.varying && (state->stage == MESA_SHADER_VERTEX))
4126bf215546Sopenharmony_ci      var->data.mode = ir_var_shader_out;
4127bf215546Sopenharmony_ci   else if (qual->flags.q.uniform)
4128bf215546Sopenharmony_ci      var->data.mode = ir_var_uniform;
4129bf215546Sopenharmony_ci   else if (qual->flags.q.buffer)
4130bf215546Sopenharmony_ci      var->data.mode = ir_var_shader_storage;
4131bf215546Sopenharmony_ci   else if (qual->flags.q.shared_storage)
4132bf215546Sopenharmony_ci      var->data.mode = ir_var_shader_shared;
4133bf215546Sopenharmony_ci
4134bf215546Sopenharmony_ci   if (!is_parameter && state->stage == MESA_SHADER_FRAGMENT) {
4135bf215546Sopenharmony_ci      if (state->has_framebuffer_fetch()) {
4136bf215546Sopenharmony_ci         if (state->is_version(130, 300))
4137bf215546Sopenharmony_ci            var->data.fb_fetch_output = qual->flags.q.in && qual->flags.q.out;
4138bf215546Sopenharmony_ci         else
4139bf215546Sopenharmony_ci            var->data.fb_fetch_output = (strcmp(var->name, "gl_LastFragData") == 0);
4140bf215546Sopenharmony_ci      }
4141bf215546Sopenharmony_ci
4142bf215546Sopenharmony_ci      if (state->has_framebuffer_fetch_zs() &&
4143bf215546Sopenharmony_ci          (strcmp(var->name, "gl_LastFragDepthARM") == 0 ||
4144bf215546Sopenharmony_ci           strcmp(var->name, "gl_LastFragStencilARM") == 0)) {
4145bf215546Sopenharmony_ci         var->data.fb_fetch_output = 1;
4146bf215546Sopenharmony_ci      }
4147bf215546Sopenharmony_ci   }
4148bf215546Sopenharmony_ci
4149bf215546Sopenharmony_ci   if (var->data.fb_fetch_output)
4150bf215546Sopenharmony_ci      var->data.assigned = true;
4151bf215546Sopenharmony_ci
4152bf215546Sopenharmony_ci   if (var->is_fb_fetch_color_output()) {
4153bf215546Sopenharmony_ci      var->data.memory_coherent = !qual->flags.q.non_coherent;
4154bf215546Sopenharmony_ci
4155bf215546Sopenharmony_ci      /* From the EXT_shader_framebuffer_fetch spec:
4156bf215546Sopenharmony_ci       *
4157bf215546Sopenharmony_ci       *   "It is an error to declare an inout fragment output not qualified
4158bf215546Sopenharmony_ci       *    with layout(noncoherent) if the GL_EXT_shader_framebuffer_fetch
4159bf215546Sopenharmony_ci       *    extension hasn't been enabled."
4160bf215546Sopenharmony_ci       */
4161bf215546Sopenharmony_ci      if (var->data.memory_coherent &&
4162bf215546Sopenharmony_ci          !state->EXT_shader_framebuffer_fetch_enable)
4163bf215546Sopenharmony_ci         _mesa_glsl_error(loc, state,
4164bf215546Sopenharmony_ci                          "invalid declaration of framebuffer fetch output not "
4165bf215546Sopenharmony_ci                          "qualified with layout(noncoherent)");
4166bf215546Sopenharmony_ci
4167bf215546Sopenharmony_ci   } else {
4168bf215546Sopenharmony_ci      /* From the EXT_shader_framebuffer_fetch spec:
4169bf215546Sopenharmony_ci       *
4170bf215546Sopenharmony_ci       *   "Fragment outputs declared inout may specify the following layout
4171bf215546Sopenharmony_ci       *    qualifier: [...] noncoherent"
4172bf215546Sopenharmony_ci       */
4173bf215546Sopenharmony_ci      if (qual->flags.q.non_coherent)
4174bf215546Sopenharmony_ci         _mesa_glsl_error(loc, state,
4175bf215546Sopenharmony_ci                          "invalid layout(noncoherent) qualifier not part of "
4176bf215546Sopenharmony_ci                          "framebuffer fetch output declaration");
4177bf215546Sopenharmony_ci   }
4178bf215546Sopenharmony_ci
4179bf215546Sopenharmony_ci   if (!is_parameter && is_varying_var(var, state->stage)) {
4180bf215546Sopenharmony_ci      /* User-defined ins/outs are not permitted in compute shaders. */
4181bf215546Sopenharmony_ci      if (state->stage == MESA_SHADER_COMPUTE) {
4182bf215546Sopenharmony_ci         _mesa_glsl_error(loc, state,
4183bf215546Sopenharmony_ci                          "user-defined input and output variables are not "
4184bf215546Sopenharmony_ci                          "permitted in compute shaders");
4185bf215546Sopenharmony_ci      }
4186bf215546Sopenharmony_ci
4187bf215546Sopenharmony_ci      /* This variable is being used to link data between shader stages (in
4188bf215546Sopenharmony_ci       * pre-glsl-1.30 parlance, it's a "varying").  Check that it has a type
4189bf215546Sopenharmony_ci       * that is allowed for such purposes.
4190bf215546Sopenharmony_ci       *
4191bf215546Sopenharmony_ci       * From page 25 (page 31 of the PDF) of the GLSL 1.10 spec:
4192bf215546Sopenharmony_ci       *
4193bf215546Sopenharmony_ci       *     "The varying qualifier can be used only with the data types
4194bf215546Sopenharmony_ci       *     float, vec2, vec3, vec4, mat2, mat3, and mat4, or arrays of
4195bf215546Sopenharmony_ci       *     these."
4196bf215546Sopenharmony_ci       *
4197bf215546Sopenharmony_ci       * This was relaxed in GLSL version 1.30 and GLSL ES version 3.00.  From
4198bf215546Sopenharmony_ci       * page 31 (page 37 of the PDF) of the GLSL 1.30 spec:
4199bf215546Sopenharmony_ci       *
4200bf215546Sopenharmony_ci       *     "Fragment inputs can only be signed and unsigned integers and
4201bf215546Sopenharmony_ci       *     integer vectors, float, floating-point vectors, matrices, or
4202bf215546Sopenharmony_ci       *     arrays of these. Structures cannot be input.
4203bf215546Sopenharmony_ci       *
4204bf215546Sopenharmony_ci       * Similar text exists in the section on vertex shader outputs.
4205bf215546Sopenharmony_ci       *
4206bf215546Sopenharmony_ci       * Similar text exists in the GLSL ES 3.00 spec, except that the GLSL ES
4207bf215546Sopenharmony_ci       * 3.00 spec allows structs as well.  Varying structs are also allowed
4208bf215546Sopenharmony_ci       * in GLSL 1.50.
4209bf215546Sopenharmony_ci       *
4210bf215546Sopenharmony_ci       * From section 4.3.4 of the ARB_bindless_texture spec:
4211bf215546Sopenharmony_ci       *
4212bf215546Sopenharmony_ci       *     "(modify third paragraph of the section to allow sampler and image
4213bf215546Sopenharmony_ci       *     types) ...  Vertex shader inputs can only be float,
4214bf215546Sopenharmony_ci       *     single-precision floating-point scalars, single-precision
4215bf215546Sopenharmony_ci       *     floating-point vectors, matrices, signed and unsigned integers
4216bf215546Sopenharmony_ci       *     and integer vectors, sampler and image types."
4217bf215546Sopenharmony_ci       *
4218bf215546Sopenharmony_ci       * From section 4.3.6 of the ARB_bindless_texture spec:
4219bf215546Sopenharmony_ci       *
4220bf215546Sopenharmony_ci       *     "Output variables can only be floating-point scalars,
4221bf215546Sopenharmony_ci       *     floating-point vectors, matrices, signed or unsigned integers or
4222bf215546Sopenharmony_ci       *     integer vectors, sampler or image types, or arrays or structures
4223bf215546Sopenharmony_ci       *     of any these."
4224bf215546Sopenharmony_ci       */
4225bf215546Sopenharmony_ci      switch (var->type->without_array()->base_type) {
4226bf215546Sopenharmony_ci      case GLSL_TYPE_FLOAT:
4227bf215546Sopenharmony_ci         /* Ok in all GLSL versions */
4228bf215546Sopenharmony_ci         break;
4229bf215546Sopenharmony_ci      case GLSL_TYPE_UINT:
4230bf215546Sopenharmony_ci      case GLSL_TYPE_INT:
4231bf215546Sopenharmony_ci         if (state->is_version(130, 300) || state->EXT_gpu_shader4_enable)
4232bf215546Sopenharmony_ci            break;
4233bf215546Sopenharmony_ci         _mesa_glsl_error(loc, state,
4234bf215546Sopenharmony_ci                          "varying variables must be of base type float in %s",
4235bf215546Sopenharmony_ci                          state->get_version_string());
4236bf215546Sopenharmony_ci         break;
4237bf215546Sopenharmony_ci      case GLSL_TYPE_STRUCT:
4238bf215546Sopenharmony_ci         if (state->is_version(150, 300))
4239bf215546Sopenharmony_ci            break;
4240bf215546Sopenharmony_ci         _mesa_glsl_error(loc, state,
4241bf215546Sopenharmony_ci                          "varying variables may not be of type struct");
4242bf215546Sopenharmony_ci         break;
4243bf215546Sopenharmony_ci      case GLSL_TYPE_DOUBLE:
4244bf215546Sopenharmony_ci      case GLSL_TYPE_UINT64:
4245bf215546Sopenharmony_ci      case GLSL_TYPE_INT64:
4246bf215546Sopenharmony_ci         break;
4247bf215546Sopenharmony_ci      case GLSL_TYPE_SAMPLER:
4248bf215546Sopenharmony_ci      case GLSL_TYPE_TEXTURE:
4249bf215546Sopenharmony_ci      case GLSL_TYPE_IMAGE:
4250bf215546Sopenharmony_ci         if (state->has_bindless())
4251bf215546Sopenharmony_ci            break;
4252bf215546Sopenharmony_ci         FALLTHROUGH;
4253bf215546Sopenharmony_ci      default:
4254bf215546Sopenharmony_ci         _mesa_glsl_error(loc, state, "illegal type for a varying variable");
4255bf215546Sopenharmony_ci         break;
4256bf215546Sopenharmony_ci      }
4257bf215546Sopenharmony_ci   }
4258bf215546Sopenharmony_ci
4259bf215546Sopenharmony_ci   if (state->all_invariant && var->data.mode == ir_var_shader_out) {
4260bf215546Sopenharmony_ci      var->data.explicit_invariant = true;
4261bf215546Sopenharmony_ci      var->data.invariant = true;
4262bf215546Sopenharmony_ci   }
4263bf215546Sopenharmony_ci
4264bf215546Sopenharmony_ci   var->data.interpolation =
4265bf215546Sopenharmony_ci      interpret_interpolation_qualifier(qual, var->type,
4266bf215546Sopenharmony_ci                                        (ir_variable_mode) var->data.mode,
4267bf215546Sopenharmony_ci                                        state, loc);
4268bf215546Sopenharmony_ci
4269bf215546Sopenharmony_ci   /* Does the declaration use the deprecated 'attribute' or 'varying'
4270bf215546Sopenharmony_ci    * keywords?
4271bf215546Sopenharmony_ci    */
4272bf215546Sopenharmony_ci   const bool uses_deprecated_qualifier = qual->flags.q.attribute
4273bf215546Sopenharmony_ci      || qual->flags.q.varying;
4274bf215546Sopenharmony_ci
4275bf215546Sopenharmony_ci
4276bf215546Sopenharmony_ci   /* Validate auxiliary storage qualifiers */
4277bf215546Sopenharmony_ci
4278bf215546Sopenharmony_ci   /* From section 4.3.4 of the GLSL 1.30 spec:
4279bf215546Sopenharmony_ci    *    "It is an error to use centroid in in a vertex shader."
4280bf215546Sopenharmony_ci    *
4281bf215546Sopenharmony_ci    * From section 4.3.4 of the GLSL ES 3.00 spec:
4282bf215546Sopenharmony_ci    *    "It is an error to use centroid in or interpolation qualifiers in
4283bf215546Sopenharmony_ci    *    a vertex shader input."
4284bf215546Sopenharmony_ci    */
4285bf215546Sopenharmony_ci
4286bf215546Sopenharmony_ci   /* Section 4.3.6 of the GLSL 1.30 specification states:
4287bf215546Sopenharmony_ci    * "It is an error to use centroid out in a fragment shader."
4288bf215546Sopenharmony_ci    *
4289bf215546Sopenharmony_ci    * The GL_ARB_shading_language_420pack extension specification states:
4290bf215546Sopenharmony_ci    * "It is an error to use auxiliary storage qualifiers or interpolation
4291bf215546Sopenharmony_ci    *  qualifiers on an output in a fragment shader."
4292bf215546Sopenharmony_ci    */
4293bf215546Sopenharmony_ci   if (qual->flags.q.sample && (!is_varying_var(var, state->stage) || uses_deprecated_qualifier)) {
4294bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state,
4295bf215546Sopenharmony_ci                       "sample qualifier may only be used on `in` or `out` "
4296bf215546Sopenharmony_ci                       "variables between shader stages");
4297bf215546Sopenharmony_ci   }
4298bf215546Sopenharmony_ci   if (qual->flags.q.centroid && !is_varying_var(var, state->stage)) {
4299bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state,
4300bf215546Sopenharmony_ci                       "centroid qualifier may only be used with `in', "
4301bf215546Sopenharmony_ci                       "`out' or `varying' variables between shader stages");
4302bf215546Sopenharmony_ci   }
4303bf215546Sopenharmony_ci
4304bf215546Sopenharmony_ci   if (qual->flags.q.shared_storage && state->stage != MESA_SHADER_COMPUTE) {
4305bf215546Sopenharmony_ci      _mesa_glsl_error(loc, state,
4306bf215546Sopenharmony_ci                       "the shared storage qualifiers can only be used with "
4307bf215546Sopenharmony_ci                       "compute shaders");
4308bf215546Sopenharmony_ci   }
4309bf215546Sopenharmony_ci
4310bf215546Sopenharmony_ci   apply_image_qualifier_to_variable(qual, var, state, loc);
4311bf215546Sopenharmony_ci}
4312bf215546Sopenharmony_ci
4313bf215546Sopenharmony_ci/**
4314bf215546Sopenharmony_ci * Get the variable that is being redeclared by this declaration or if it
4315bf215546Sopenharmony_ci * does not exist, the current declared variable.
4316bf215546Sopenharmony_ci *
4317bf215546Sopenharmony_ci * Semantic checks to verify the validity of the redeclaration are also
4318bf215546Sopenharmony_ci * performed.  If semantic checks fail, compilation error will be emitted via
4319bf215546Sopenharmony_ci * \c _mesa_glsl_error, but a non-\c NULL pointer will still be returned.
4320bf215546Sopenharmony_ci *
4321bf215546Sopenharmony_ci * \returns
4322bf215546Sopenharmony_ci * A pointer to an existing variable in the current scope if the declaration
4323bf215546Sopenharmony_ci * is a redeclaration, current variable otherwise. \c is_declared boolean
4324bf215546Sopenharmony_ci * will return \c true if the declaration is a redeclaration, \c false
4325bf215546Sopenharmony_ci * otherwise.
4326bf215546Sopenharmony_ci */
4327bf215546Sopenharmony_cistatic ir_variable *
4328bf215546Sopenharmony_ciget_variable_being_redeclared(ir_variable **var_ptr, YYLTYPE loc,
4329bf215546Sopenharmony_ci                              struct _mesa_glsl_parse_state *state,
4330bf215546Sopenharmony_ci                              bool allow_all_redeclarations,
4331bf215546Sopenharmony_ci                              bool *is_redeclaration)
4332bf215546Sopenharmony_ci{
4333bf215546Sopenharmony_ci   ir_variable *var = *var_ptr;
4334bf215546Sopenharmony_ci
4335bf215546Sopenharmony_ci   /* Check if this declaration is actually a re-declaration, either to
4336bf215546Sopenharmony_ci    * resize an array or add qualifiers to an existing variable.
4337bf215546Sopenharmony_ci    *
4338bf215546Sopenharmony_ci    * This is allowed for variables in the current scope, or when at
4339bf215546Sopenharmony_ci    * global scope (for built-ins in the implicit outer scope).
4340bf215546Sopenharmony_ci    */
4341bf215546Sopenharmony_ci   ir_variable *earlier = state->symbols->get_variable(var->name);
4342bf215546Sopenharmony_ci   if (earlier == NULL ||
4343bf215546Sopenharmony_ci       (state->current_function != NULL &&
4344bf215546Sopenharmony_ci       !state->symbols->name_declared_this_scope(var->name))) {
4345bf215546Sopenharmony_ci      *is_redeclaration = false;
4346bf215546Sopenharmony_ci      return var;
4347bf215546Sopenharmony_ci   }
4348bf215546Sopenharmony_ci
4349bf215546Sopenharmony_ci   *is_redeclaration = true;
4350bf215546Sopenharmony_ci
4351bf215546Sopenharmony_ci   if (earlier->data.how_declared == ir_var_declared_implicitly) {
4352bf215546Sopenharmony_ci      /* Verify that the redeclaration of a built-in does not change the
4353bf215546Sopenharmony_ci       * storage qualifier.  There are a couple special cases.
4354bf215546Sopenharmony_ci       *
4355bf215546Sopenharmony_ci       * 1. Some built-in variables that are defined as 'in' in the
4356bf215546Sopenharmony_ci       *    specification are implemented as system values.  Allow
4357bf215546Sopenharmony_ci       *    ir_var_system_value -> ir_var_shader_in.
4358bf215546Sopenharmony_ci       *
4359bf215546Sopenharmony_ci       * 2. gl_LastFragData is implemented as a ir_var_shader_out, but the
4360bf215546Sopenharmony_ci       *    specification requires that redeclarations omit any qualifier.
4361bf215546Sopenharmony_ci       *    Allow ir_var_shader_out -> ir_var_auto for this one variable.
4362bf215546Sopenharmony_ci       */
4363bf215546Sopenharmony_ci      if (earlier->data.mode != var->data.mode &&
4364bf215546Sopenharmony_ci          !(earlier->data.mode == ir_var_system_value &&
4365bf215546Sopenharmony_ci            var->data.mode == ir_var_shader_in) &&
4366bf215546Sopenharmony_ci          !(strcmp(var->name, "gl_LastFragData") == 0 &&
4367bf215546Sopenharmony_ci            var->data.mode == ir_var_auto)) {
4368bf215546Sopenharmony_ci         _mesa_glsl_error(&loc, state,
4369bf215546Sopenharmony_ci                          "redeclaration cannot change qualification of `%s'",
4370bf215546Sopenharmony_ci                          var->name);
4371bf215546Sopenharmony_ci      }
4372bf215546Sopenharmony_ci   }
4373bf215546Sopenharmony_ci
4374bf215546Sopenharmony_ci   /* From page 24 (page 30 of the PDF) of the GLSL 1.50 spec,
4375bf215546Sopenharmony_ci    *
4376bf215546Sopenharmony_ci    * "It is legal to declare an array without a size and then
4377bf215546Sopenharmony_ci    *  later re-declare the same name as an array of the same
4378bf215546Sopenharmony_ci    *  type and specify a size."
4379bf215546Sopenharmony_ci    */
4380bf215546Sopenharmony_ci   if (earlier->type->is_unsized_array() && var->type->is_array()
4381bf215546Sopenharmony_ci       && (var->type->fields.array == earlier->type->fields.array)) {
4382bf215546Sopenharmony_ci      const int size = var->type->array_size();
4383bf215546Sopenharmony_ci      check_builtin_array_max_size(var->name, size, loc, state);
4384bf215546Sopenharmony_ci      if ((size > 0) && (size <= earlier->data.max_array_access)) {
4385bf215546Sopenharmony_ci         _mesa_glsl_error(& loc, state, "array size must be > %u due to "
4386bf215546Sopenharmony_ci                          "previous access",
4387bf215546Sopenharmony_ci                          earlier->data.max_array_access);
4388bf215546Sopenharmony_ci      }
4389bf215546Sopenharmony_ci
4390bf215546Sopenharmony_ci      earlier->type = var->type;
4391bf215546Sopenharmony_ci      delete var;
4392bf215546Sopenharmony_ci      var = NULL;
4393bf215546Sopenharmony_ci      *var_ptr = NULL;
4394bf215546Sopenharmony_ci   } else if (earlier->type != var->type) {
4395bf215546Sopenharmony_ci      _mesa_glsl_error(&loc, state,
4396bf215546Sopenharmony_ci                       "redeclaration of `%s' has incorrect type",
4397bf215546Sopenharmony_ci                       var->name);
4398bf215546Sopenharmony_ci   } else if ((state->ARB_fragment_coord_conventions_enable ||
4399bf215546Sopenharmony_ci              state->is_version(150, 0))
4400bf215546Sopenharmony_ci              && strcmp(var->name, "gl_FragCoord") == 0) {
4401bf215546Sopenharmony_ci      /* Allow redeclaration of gl_FragCoord for ARB_fcc layout
4402bf215546Sopenharmony_ci       * qualifiers.
4403bf215546Sopenharmony_ci       *
4404bf215546Sopenharmony_ci       * We don't really need to do anything here, just allow the
4405bf215546Sopenharmony_ci       * redeclaration. Any error on the gl_FragCoord is handled on the ast
4406bf215546Sopenharmony_ci       * level at apply_layout_qualifier_to_variable using the
4407bf215546Sopenharmony_ci       * ast_type_qualifier and _mesa_glsl_parse_state, or later at
4408bf215546Sopenharmony_ci       * linker.cpp.
4409bf215546Sopenharmony_ci       */
4410bf215546Sopenharmony_ci      /* According to section 4.3.7 of the GLSL 1.30 spec,
4411bf215546Sopenharmony_ci       * the following built-in varaibles can be redeclared with an
4412bf215546Sopenharmony_ci       * interpolation qualifier:
4413bf215546Sopenharmony_ci       *    * gl_FrontColor
4414bf215546Sopenharmony_ci       *    * gl_BackColor
4415bf215546Sopenharmony_ci       *    * gl_FrontSecondaryColor
4416bf215546Sopenharmony_ci       *    * gl_BackSecondaryColor
4417bf215546Sopenharmony_ci       *    * gl_Color
4418bf215546Sopenharmony_ci       *    * gl_SecondaryColor
4419bf215546Sopenharmony_ci       */
4420bf215546Sopenharmony_ci   } else if (state->is_version(130, 0)
4421bf215546Sopenharmony_ci              && (strcmp(var->name, "gl_FrontColor") == 0
4422bf215546Sopenharmony_ci                  || strcmp(var->name, "gl_BackColor") == 0
4423bf215546Sopenharmony_ci                  || strcmp(var->name, "gl_FrontSecondaryColor") == 0
4424bf215546Sopenharmony_ci                  || strcmp(var->name, "gl_BackSecondaryColor") == 0
4425bf215546Sopenharmony_ci                  || strcmp(var->name, "gl_Color") == 0
4426bf215546Sopenharmony_ci                  || strcmp(var->name, "gl_SecondaryColor") == 0)) {
4427bf215546Sopenharmony_ci      earlier->data.interpolation = var->data.interpolation;
4428bf215546Sopenharmony_ci
4429bf215546Sopenharmony_ci      /* Layout qualifiers for gl_FragDepth. */
4430bf215546Sopenharmony_ci   } else if ((state->is_version(420, 0) ||
4431bf215546Sopenharmony_ci               state->AMD_conservative_depth_enable ||
4432bf215546Sopenharmony_ci               state->ARB_conservative_depth_enable)
4433bf215546Sopenharmony_ci              && strcmp(var->name, "gl_FragDepth") == 0) {
4434bf215546Sopenharmony_ci
4435bf215546Sopenharmony_ci      /** From the AMD_conservative_depth spec:
4436bf215546Sopenharmony_ci       *     Within any shader, the first redeclarations of gl_FragDepth
4437bf215546Sopenharmony_ci       *     must appear before any use of gl_FragDepth.
4438bf215546Sopenharmony_ci       */
4439bf215546Sopenharmony_ci      if (earlier->data.used) {
4440bf215546Sopenharmony_ci         _mesa_glsl_error(&loc, state,
4441bf215546Sopenharmony_ci                          "the first redeclaration of gl_FragDepth "
4442bf215546Sopenharmony_ci                          "must appear before any use of gl_FragDepth");
4443bf215546Sopenharmony_ci      }
4444bf215546Sopenharmony_ci
4445bf215546Sopenharmony_ci      /* Prevent inconsistent redeclaration of depth layout qualifier. */
4446bf215546Sopenharmony_ci      if (earlier->data.depth_layout != ir_depth_layout_none
4447bf215546Sopenharmony_ci          && earlier->data.depth_layout != var->data.depth_layout) {
4448bf215546Sopenharmony_ci            _mesa_glsl_error(&loc, state,
4449bf215546Sopenharmony_ci                             "gl_FragDepth: depth layout is declared here "
4450bf215546Sopenharmony_ci                             "as '%s, but it was previously declared as "
4451bf215546Sopenharmony_ci                             "'%s'",
4452bf215546Sopenharmony_ci                             depth_layout_string(var->data.depth_layout),
4453bf215546Sopenharmony_ci                             depth_layout_string(earlier->data.depth_layout));
4454bf215546Sopenharmony_ci      }
4455bf215546Sopenharmony_ci
4456bf215546Sopenharmony_ci      earlier->data.depth_layout = var->data.depth_layout;
4457bf215546Sopenharmony_ci
4458bf215546Sopenharmony_ci   } else if (state->has_framebuffer_fetch() &&
4459bf215546Sopenharmony_ci              strcmp(var->name, "gl_LastFragData") == 0 &&
4460bf215546Sopenharmony_ci              var->data.mode == ir_var_auto) {
4461bf215546Sopenharmony_ci      /* According to the EXT_shader_framebuffer_fetch spec:
4462bf215546Sopenharmony_ci       *
4463bf215546Sopenharmony_ci       *   "By default, gl_LastFragData is declared with the mediump precision
4464bf215546Sopenharmony_ci       *    qualifier. This can be changed by redeclaring the corresponding
4465bf215546Sopenharmony_ci       *    variables with the desired precision qualifier."
4466bf215546Sopenharmony_ci       *
4467bf215546Sopenharmony_ci       *   "Fragment shaders may specify the following layout qualifier only for
4468bf215546Sopenharmony_ci       *    redeclaring the built-in gl_LastFragData array [...]: noncoherent"
4469bf215546Sopenharmony_ci       */
4470bf215546Sopenharmony_ci      earlier->data.precision = var->data.precision;
4471bf215546Sopenharmony_ci      earlier->data.memory_coherent = var->data.memory_coherent;
4472bf215546Sopenharmony_ci
4473bf215546Sopenharmony_ci   } else if (state->NV_viewport_array2_enable &&
4474bf215546Sopenharmony_ci              strcmp(var->name, "gl_Layer") == 0 &&
4475bf215546Sopenharmony_ci              earlier->data.how_declared == ir_var_declared_implicitly) {
4476bf215546Sopenharmony_ci      /* No need to do anything, just allow it. Qualifier is stored in state */
4477bf215546Sopenharmony_ci
4478bf215546Sopenharmony_ci   } else if (state->is_version(0, 300) &&
4479bf215546Sopenharmony_ci              state->has_separate_shader_objects() &&
4480bf215546Sopenharmony_ci              (strcmp(var->name, "gl_Position") == 0 ||
4481bf215546Sopenharmony_ci              strcmp(var->name, "gl_PointSize") == 0)) {
4482bf215546Sopenharmony_ci
4483bf215546Sopenharmony_ci       /*  EXT_separate_shader_objects spec says:
4484bf215546Sopenharmony_ci       *
4485bf215546Sopenharmony_ci       *  "The following vertex shader outputs may be redeclared
4486bf215546Sopenharmony_ci       *   at global scope to specify a built-in output interface,
4487bf215546Sopenharmony_ci       *   with or without special qualifiers:
4488bf215546Sopenharmony_ci       *
4489bf215546Sopenharmony_ci       *    gl_Position
4490bf215546Sopenharmony_ci       *    gl_PointSize
4491bf215546Sopenharmony_ci       *
4492bf215546Sopenharmony_ci       *    When compiling shaders using either of the above variables,
4493bf215546Sopenharmony_ci       *    both such variables must be redeclared prior to use."
4494bf215546Sopenharmony_ci       */
4495bf215546Sopenharmony_ci      if (earlier->data.used) {
4496bf215546Sopenharmony_ci         _mesa_glsl_error(&loc, state, "the first redeclaration of "
4497bf215546Sopenharmony_ci                         "%s must appear before any use", var->name);
4498bf215546Sopenharmony_ci      }
4499bf215546Sopenharmony_ci   } else if ((earlier->data.how_declared == ir_var_declared_implicitly &&
4500bf215546Sopenharmony_ci               state->allow_builtin_variable_redeclaration) ||
4501bf215546Sopenharmony_ci              allow_all_redeclarations) {
4502bf215546Sopenharmony_ci      /* Allow verbatim redeclarations of built-in variables. Not explicitly
4503bf215546Sopenharmony_ci       * valid, but some applications do it.
4504bf215546Sopenharmony_ci       */
4505bf215546Sopenharmony_ci   } else {
4506bf215546Sopenharmony_ci      _mesa_glsl_error(&loc, state, "`%s' redeclared", var->name);
4507bf215546Sopenharmony_ci   }
4508bf215546Sopenharmony_ci
4509bf215546Sopenharmony_ci   return earlier;
4510bf215546Sopenharmony_ci}
4511bf215546Sopenharmony_ci
4512bf215546Sopenharmony_ci/**
4513bf215546Sopenharmony_ci * Generate the IR for an initializer in a variable declaration
4514bf215546Sopenharmony_ci */
4515bf215546Sopenharmony_cistatic ir_rvalue *
4516bf215546Sopenharmony_ciprocess_initializer(ir_variable *var, ast_declaration *decl,
4517bf215546Sopenharmony_ci                    ast_fully_specified_type *type,
4518bf215546Sopenharmony_ci                    exec_list *initializer_instructions,
4519bf215546Sopenharmony_ci                    struct _mesa_glsl_parse_state *state)
4520bf215546Sopenharmony_ci{
4521bf215546Sopenharmony_ci   void *mem_ctx = state;
4522bf215546Sopenharmony_ci   ir_rvalue *result = NULL;
4523bf215546Sopenharmony_ci
4524bf215546Sopenharmony_ci   YYLTYPE initializer_loc = decl->initializer->get_location();
4525bf215546Sopenharmony_ci
4526bf215546Sopenharmony_ci   /* From page 24 (page 30 of the PDF) of the GLSL 1.10 spec:
4527bf215546Sopenharmony_ci    *
4528bf215546Sopenharmony_ci    *    "All uniform variables are read-only and are initialized either
4529bf215546Sopenharmony_ci    *    directly by an application via API commands, or indirectly by
4530bf215546Sopenharmony_ci    *    OpenGL."
4531bf215546Sopenharmony_ci    */
4532bf215546Sopenharmony_ci   if (var->data.mode == ir_var_uniform) {
4533bf215546Sopenharmony_ci      state->check_version(120, 0, &initializer_loc,
4534bf215546Sopenharmony_ci                           "cannot initialize uniform %s",
4535bf215546Sopenharmony_ci                           var->name);
4536bf215546Sopenharmony_ci   }
4537bf215546Sopenharmony_ci
4538bf215546Sopenharmony_ci   /* Section 4.3.7 "Buffer Variables" of the GLSL 4.30 spec:
4539bf215546Sopenharmony_ci    *
4540bf215546Sopenharmony_ci    *    "Buffer variables cannot have initializers."
4541bf215546Sopenharmony_ci    */
4542bf215546Sopenharmony_ci   if (var->data.mode == ir_var_shader_storage) {
4543bf215546Sopenharmony_ci      _mesa_glsl_error(&initializer_loc, state,
4544bf215546Sopenharmony_ci                       "cannot initialize buffer variable %s",
4545bf215546Sopenharmony_ci                       var->name);
4546bf215546Sopenharmony_ci   }
4547bf215546Sopenharmony_ci
4548bf215546Sopenharmony_ci   /* From section 4.1.7 of the GLSL 4.40 spec:
4549bf215546Sopenharmony_ci    *
4550bf215546Sopenharmony_ci    *    "Opaque variables [...] are initialized only through the
4551bf215546Sopenharmony_ci    *     OpenGL API; they cannot be declared with an initializer in a
4552bf215546Sopenharmony_ci    *     shader."
4553bf215546Sopenharmony_ci    *
4554bf215546Sopenharmony_ci    * From section 4.1.7 of the ARB_bindless_texture spec:
4555bf215546Sopenharmony_ci    *
4556bf215546Sopenharmony_ci    *    "Samplers may be declared as shader inputs and outputs, as uniform
4557bf215546Sopenharmony_ci    *     variables, as temporary variables, and as function parameters."
4558bf215546Sopenharmony_ci    *
4559bf215546Sopenharmony_ci    * From section 4.1.X of the ARB_bindless_texture spec:
4560bf215546Sopenharmony_ci    *
4561bf215546Sopenharmony_ci    *    "Images may be declared as shader inputs and outputs, as uniform
4562bf215546Sopenharmony_ci    *     variables, as temporary variables, and as function parameters."
4563bf215546Sopenharmony_ci    */
4564bf215546Sopenharmony_ci   if (var->type->contains_atomic() ||
4565bf215546Sopenharmony_ci       (!state->has_bindless() && var->type->contains_opaque())) {
4566bf215546Sopenharmony_ci      _mesa_glsl_error(&initializer_loc, state,
4567bf215546Sopenharmony_ci                       "cannot initialize %s variable %s",
4568bf215546Sopenharmony_ci                       var->name, state->has_bindless() ? "atomic" : "opaque");
4569bf215546Sopenharmony_ci   }
4570bf215546Sopenharmony_ci
4571bf215546Sopenharmony_ci   if ((var->data.mode == ir_var_shader_in) && (state->current_function == NULL)) {
4572bf215546Sopenharmony_ci      _mesa_glsl_error(&initializer_loc, state,
4573bf215546Sopenharmony_ci                       "cannot initialize %s shader input / %s %s",
4574bf215546Sopenharmony_ci                       _mesa_shader_stage_to_string(state->stage),
4575bf215546Sopenharmony_ci                       (state->stage == MESA_SHADER_VERTEX)
4576bf215546Sopenharmony_ci                       ? "attribute" : "varying",
4577bf215546Sopenharmony_ci                       var->name);
4578bf215546Sopenharmony_ci   }
4579bf215546Sopenharmony_ci
4580bf215546Sopenharmony_ci   if (var->data.mode == ir_var_shader_out && state->current_function == NULL) {
4581bf215546Sopenharmony_ci      _mesa_glsl_error(&initializer_loc, state,
4582bf215546Sopenharmony_ci                       "cannot initialize %s shader output %s",
4583bf215546Sopenharmony_ci                       _mesa_shader_stage_to_string(state->stage),
4584bf215546Sopenharmony_ci                       var->name);
4585bf215546Sopenharmony_ci   }
4586bf215546Sopenharmony_ci
4587bf215546Sopenharmony_ci   /* If the initializer is an ast_aggregate_initializer, recursively store
4588bf215546Sopenharmony_ci    * type information from the LHS into it, so that its hir() function can do
4589bf215546Sopenharmony_ci    * type checking.
4590bf215546Sopenharmony_ci    */
4591bf215546Sopenharmony_ci   if (decl->initializer->oper == ast_aggregate)
4592bf215546Sopenharmony_ci      _mesa_ast_set_aggregate_type(var->type, decl->initializer);
4593bf215546Sopenharmony_ci
4594bf215546Sopenharmony_ci   ir_dereference *const lhs = new(state) ir_dereference_variable(var);
4595bf215546Sopenharmony_ci   ir_rvalue *rhs = decl->initializer->hir(initializer_instructions, state);
4596bf215546Sopenharmony_ci
4597bf215546Sopenharmony_ci   /* Calculate the constant value if this is a const or uniform
4598bf215546Sopenharmony_ci    * declaration.
4599bf215546Sopenharmony_ci    *
4600bf215546Sopenharmony_ci    * Section 4.3 (Storage Qualifiers) of the GLSL ES 1.00.17 spec says:
4601bf215546Sopenharmony_ci    *
4602bf215546Sopenharmony_ci    *     "Declarations of globals without a storage qualifier, or with
4603bf215546Sopenharmony_ci    *     just the const qualifier, may include initializers, in which case
4604bf215546Sopenharmony_ci    *     they will be initialized before the first line of main() is
4605bf215546Sopenharmony_ci    *     executed.  Such initializers must be a constant expression."
4606bf215546Sopenharmony_ci    *
4607bf215546Sopenharmony_ci    * The same section of the GLSL ES 3.00.4 spec has similar language.
4608bf215546Sopenharmony_ci    */
4609bf215546Sopenharmony_ci   if (type->qualifier.flags.q.constant
4610bf215546Sopenharmony_ci       || type->qualifier.flags.q.uniform
4611bf215546Sopenharmony_ci       || (state->es_shader && state->current_function == NULL)) {
4612bf215546Sopenharmony_ci      ir_rvalue *new_rhs = validate_assignment(state, initializer_loc,
4613bf215546Sopenharmony_ci                                               lhs, rhs, true);
4614bf215546Sopenharmony_ci      if (new_rhs != NULL) {
4615bf215546Sopenharmony_ci         rhs = new_rhs;
4616bf215546Sopenharmony_ci
4617bf215546Sopenharmony_ci         /* Section 4.3.3 (Constant Expressions) of the GLSL ES 3.00.4 spec
4618bf215546Sopenharmony_ci          * says:
4619bf215546Sopenharmony_ci          *
4620bf215546Sopenharmony_ci          *     "A constant expression is one of
4621bf215546Sopenharmony_ci          *
4622bf215546Sopenharmony_ci          *        ...
4623bf215546Sopenharmony_ci          *
4624bf215546Sopenharmony_ci          *        - an expression formed by an operator on operands that are
4625bf215546Sopenharmony_ci          *          all constant expressions, including getting an element of
4626bf215546Sopenharmony_ci          *          a constant array, or a field of a constant structure, or
4627bf215546Sopenharmony_ci          *          components of a constant vector.  However, the sequence
4628bf215546Sopenharmony_ci          *          operator ( , ) and the assignment operators ( =, +=, ...)
4629bf215546Sopenharmony_ci          *          are not included in the operators that can create a
4630bf215546Sopenharmony_ci          *          constant expression."
4631bf215546Sopenharmony_ci          *
4632bf215546Sopenharmony_ci          * Section 12.43 (Sequence operator and constant expressions) says:
4633bf215546Sopenharmony_ci          *
4634bf215546Sopenharmony_ci          *     "Should the following construct be allowed?
4635bf215546Sopenharmony_ci          *
4636bf215546Sopenharmony_ci          *         float a[2,3];
4637bf215546Sopenharmony_ci          *
4638bf215546Sopenharmony_ci          *     The expression within the brackets uses the sequence operator
4639bf215546Sopenharmony_ci          *     (',') and returns the integer 3 so the construct is declaring
4640bf215546Sopenharmony_ci          *     a single-dimensional array of size 3.  In some languages, the
4641bf215546Sopenharmony_ci          *     construct declares a two-dimensional array.  It would be
4642bf215546Sopenharmony_ci          *     preferable to make this construct illegal to avoid confusion.
4643bf215546Sopenharmony_ci          *
4644bf215546Sopenharmony_ci          *     One possibility is to change the definition of the sequence
4645bf215546Sopenharmony_ci          *     operator so that it does not return a constant-expression and
4646bf215546Sopenharmony_ci          *     hence cannot be used to declare an array size.
4647bf215546Sopenharmony_ci          *
4648bf215546Sopenharmony_ci          *     RESOLUTION: The result of a sequence operator is not a
4649bf215546Sopenharmony_ci          *     constant-expression."
4650bf215546Sopenharmony_ci          *
4651bf215546Sopenharmony_ci          * Section 4.3.3 (Constant Expressions) of the GLSL 4.30.9 spec
4652bf215546Sopenharmony_ci          * contains language almost identical to the section 4.3.3 in the
4653bf215546Sopenharmony_ci          * GLSL ES 3.00.4 spec.  This is a new limitation for these GLSL
4654bf215546Sopenharmony_ci          * versions.
4655bf215546Sopenharmony_ci          */
4656bf215546Sopenharmony_ci         ir_constant *constant_value =
4657bf215546Sopenharmony_ci            rhs->constant_expression_value(mem_ctx);
4658bf215546Sopenharmony_ci
4659bf215546Sopenharmony_ci         if (!constant_value ||
4660bf215546Sopenharmony_ci             (state->is_version(430, 300) &&
4661bf215546Sopenharmony_ci              decl->initializer->has_sequence_subexpression())) {
4662bf215546Sopenharmony_ci            const char *const variable_mode =
4663bf215546Sopenharmony_ci               (type->qualifier.flags.q.constant)
4664bf215546Sopenharmony_ci               ? "const"
4665bf215546Sopenharmony_ci               : ((type->qualifier.flags.q.uniform) ? "uniform" : "global");
4666bf215546Sopenharmony_ci
4667bf215546Sopenharmony_ci            /* If ARB_shading_language_420pack is enabled, initializers of
4668bf215546Sopenharmony_ci             * const-qualified local variables do not have to be constant
4669bf215546Sopenharmony_ci             * expressions. Const-qualified global variables must still be
4670bf215546Sopenharmony_ci             * initialized with constant expressions.
4671bf215546Sopenharmony_ci             */
4672bf215546Sopenharmony_ci            if (!state->has_420pack()
4673bf215546Sopenharmony_ci                || state->current_function == NULL) {
4674bf215546Sopenharmony_ci               _mesa_glsl_error(& initializer_loc, state,
4675bf215546Sopenharmony_ci                                "initializer of %s variable `%s' must be a "
4676bf215546Sopenharmony_ci                                "constant expression",
4677bf215546Sopenharmony_ci                                variable_mode,
4678bf215546Sopenharmony_ci                                decl->identifier);
4679bf215546Sopenharmony_ci               if (var->type->is_numeric()) {
4680bf215546Sopenharmony_ci                  /* Reduce cascading errors. */
4681bf215546Sopenharmony_ci                  var->constant_value = type->qualifier.flags.q.constant
4682bf215546Sopenharmony_ci                     ? ir_constant::zero(state, var->type) : NULL;
4683bf215546Sopenharmony_ci               }
4684bf215546Sopenharmony_ci            }
4685bf215546Sopenharmony_ci         } else {
4686bf215546Sopenharmony_ci            rhs = constant_value;
4687bf215546Sopenharmony_ci            var->constant_value = type->qualifier.flags.q.constant
4688bf215546Sopenharmony_ci               ? constant_value : NULL;
4689bf215546Sopenharmony_ci         }
4690bf215546Sopenharmony_ci      } else {
4691bf215546Sopenharmony_ci         if (var->type->is_numeric()) {
4692bf215546Sopenharmony_ci            /* Reduce cascading errors. */
4693bf215546Sopenharmony_ci            rhs = var->constant_value = type->qualifier.flags.q.constant
4694bf215546Sopenharmony_ci               ? ir_constant::zero(state, var->type) : NULL;
4695bf215546Sopenharmony_ci         }
4696bf215546Sopenharmony_ci      }
4697bf215546Sopenharmony_ci   }
4698bf215546Sopenharmony_ci
4699bf215546Sopenharmony_ci   if (rhs && !rhs->type->is_error()) {
4700bf215546Sopenharmony_ci      bool temp = var->data.read_only;
4701bf215546Sopenharmony_ci      if (type->qualifier.flags.q.constant)
4702bf215546Sopenharmony_ci         var->data.read_only = false;
4703bf215546Sopenharmony_ci
4704bf215546Sopenharmony_ci      /* Never emit code to initialize a uniform.
4705bf215546Sopenharmony_ci       */
4706bf215546Sopenharmony_ci      const glsl_type *initializer_type;
4707bf215546Sopenharmony_ci      bool error_emitted = false;
4708bf215546Sopenharmony_ci      if (!type->qualifier.flags.q.uniform) {
4709bf215546Sopenharmony_ci         error_emitted =
4710bf215546Sopenharmony_ci            do_assignment(initializer_instructions, state,
4711bf215546Sopenharmony_ci                          NULL, lhs, rhs,
4712bf215546Sopenharmony_ci                          &result, true, true,
4713bf215546Sopenharmony_ci                          type->get_location());
4714bf215546Sopenharmony_ci         initializer_type = result->type;
4715bf215546Sopenharmony_ci      } else
4716bf215546Sopenharmony_ci         initializer_type = rhs->type;
4717bf215546Sopenharmony_ci
4718bf215546Sopenharmony_ci      if (!error_emitted) {
4719bf215546Sopenharmony_ci         var->constant_initializer = rhs->constant_expression_value(mem_ctx);
4720bf215546Sopenharmony_ci         var->data.has_initializer = true;
4721bf215546Sopenharmony_ci         var->data.is_implicit_initializer = false;
4722bf215546Sopenharmony_ci
4723bf215546Sopenharmony_ci         /* If the declared variable is an unsized array, it must inherrit
4724bf215546Sopenharmony_ci         * its full type from the initializer.  A declaration such as
4725bf215546Sopenharmony_ci         *
4726bf215546Sopenharmony_ci         *     uniform float a[] = float[](1.0, 2.0, 3.0, 3.0);
4727bf215546Sopenharmony_ci         *
4728bf215546Sopenharmony_ci         * becomes
4729bf215546Sopenharmony_ci         *
4730bf215546Sopenharmony_ci         *     uniform float a[4] = float[](1.0, 2.0, 3.0, 3.0);
4731bf215546Sopenharmony_ci         *
4732bf215546Sopenharmony_ci         * The assignment generated in the if-statement (below) will also
4733bf215546Sopenharmony_ci         * automatically handle this case for non-uniforms.
4734bf215546Sopenharmony_ci         *
4735bf215546Sopenharmony_ci         * If the declared variable is not an array, the types must
4736bf215546Sopenharmony_ci         * already match exactly.  As a result, the type assignment
4737bf215546Sopenharmony_ci         * here can be done unconditionally.  For non-uniforms the call
4738bf215546Sopenharmony_ci         * to do_assignment can change the type of the initializer (via
4739bf215546Sopenharmony_ci         * the implicit conversion rules).  For uniforms the initializer
4740bf215546Sopenharmony_ci         * must be a constant expression, and the type of that expression
4741bf215546Sopenharmony_ci         * was validated above.
4742bf215546Sopenharmony_ci         */
4743bf215546Sopenharmony_ci         var->type = initializer_type;
4744bf215546Sopenharmony_ci      }
4745bf215546Sopenharmony_ci
4746bf215546Sopenharmony_ci      var->data.read_only = temp;
4747bf215546Sopenharmony_ci   }
4748bf215546Sopenharmony_ci
4749bf215546Sopenharmony_ci   return result;
4750bf215546Sopenharmony_ci}
4751bf215546Sopenharmony_ci
4752bf215546Sopenharmony_cistatic void
4753bf215546Sopenharmony_civalidate_layout_qualifier_vertex_count(struct _mesa_glsl_parse_state *state,
4754bf215546Sopenharmony_ci                                       YYLTYPE loc, ir_variable *var,
4755bf215546Sopenharmony_ci                                       unsigned num_vertices,
4756bf215546Sopenharmony_ci                                       unsigned *size,
4757bf215546Sopenharmony_ci                                       const char *var_category)
4758bf215546Sopenharmony_ci{
4759bf215546Sopenharmony_ci   if (var->type->is_unsized_array()) {
4760bf215546Sopenharmony_ci      /* Section 4.3.8.1 (Input Layout Qualifiers) of the GLSL 1.50 spec says:
4761bf215546Sopenharmony_ci       *
4762bf215546Sopenharmony_ci       *   All geometry shader input unsized array declarations will be
4763bf215546Sopenharmony_ci       *   sized by an earlier input layout qualifier, when present, as per
4764bf215546Sopenharmony_ci       *   the following table.
4765bf215546Sopenharmony_ci       *
4766bf215546Sopenharmony_ci       * Followed by a table mapping each allowed input layout qualifier to
4767bf215546Sopenharmony_ci       * the corresponding input length.
4768bf215546Sopenharmony_ci       *
4769bf215546Sopenharmony_ci       * Similarly for tessellation control shader outputs.
4770bf215546Sopenharmony_ci       */
4771bf215546Sopenharmony_ci      if (num_vertices != 0)
4772bf215546Sopenharmony_ci         var->type = glsl_type::get_array_instance(var->type->fields.array,
4773bf215546Sopenharmony_ci                                                   num_vertices);
4774bf215546Sopenharmony_ci   } else {
4775bf215546Sopenharmony_ci      /* Section 4.3.8.1 (Input Layout Qualifiers) of the GLSL 1.50 spec
4776bf215546Sopenharmony_ci       * includes the following examples of compile-time errors:
4777bf215546Sopenharmony_ci       *
4778bf215546Sopenharmony_ci       *   // code sequence within one shader...
4779bf215546Sopenharmony_ci       *   in vec4 Color1[];    // size unknown
4780bf215546Sopenharmony_ci       *   ...Color1.length()...// illegal, length() unknown
4781bf215546Sopenharmony_ci       *   in vec4 Color2[2];   // size is 2
4782bf215546Sopenharmony_ci       *   ...Color1.length()...// illegal, Color1 still has no size
4783bf215546Sopenharmony_ci       *   in vec4 Color3[3];   // illegal, input sizes are inconsistent
4784bf215546Sopenharmony_ci       *   layout(lines) in;    // legal, input size is 2, matching
4785bf215546Sopenharmony_ci       *   in vec4 Color4[3];   // illegal, contradicts layout
4786bf215546Sopenharmony_ci       *   ...
4787bf215546Sopenharmony_ci       *
4788bf215546Sopenharmony_ci       * To detect the case illustrated by Color3, we verify that the size of
4789bf215546Sopenharmony_ci       * an explicitly-sized array matches the size of any previously declared
4790bf215546Sopenharmony_ci       * explicitly-sized array.  To detect the case illustrated by Color4, we
4791bf215546Sopenharmony_ci       * verify that the size of an explicitly-sized array is consistent with
4792bf215546Sopenharmony_ci       * any previously declared input layout.
4793bf215546Sopenharmony_ci       */
4794bf215546Sopenharmony_ci      if (num_vertices != 0 && var->type->length != num_vertices) {
4795bf215546Sopenharmony_ci         _mesa_glsl_error(&loc, state,
4796bf215546Sopenharmony_ci                          "%s size contradicts previously declared layout "
4797bf215546Sopenharmony_ci                          "(size is %u, but layout requires a size of %u)",
4798bf215546Sopenharmony_ci                          var_category, var->type->length, num_vertices);
4799bf215546Sopenharmony_ci      } else if (*size != 0 && var->type->length != *size) {
4800bf215546Sopenharmony_ci         _mesa_glsl_error(&loc, state,
4801bf215546Sopenharmony_ci                          "%s sizes are inconsistent (size is %u, but a "
4802bf215546Sopenharmony_ci                          "previous declaration has size %u)",
4803bf215546Sopenharmony_ci                          var_category, var->type->length, *size);
4804bf215546Sopenharmony_ci      } else {
4805bf215546Sopenharmony_ci         *size = var->type->length;
4806bf215546Sopenharmony_ci      }
4807bf215546Sopenharmony_ci   }
4808bf215546Sopenharmony_ci}
4809bf215546Sopenharmony_ci
4810bf215546Sopenharmony_cistatic void
4811bf215546Sopenharmony_cihandle_tess_ctrl_shader_output_decl(struct _mesa_glsl_parse_state *state,
4812bf215546Sopenharmony_ci                                    YYLTYPE loc, ir_variable *var)
4813bf215546Sopenharmony_ci{
4814bf215546Sopenharmony_ci   unsigned num_vertices = 0;
4815bf215546Sopenharmony_ci
4816bf215546Sopenharmony_ci   if (state->tcs_output_vertices_specified) {
4817bf215546Sopenharmony_ci      if (!state->out_qualifier->vertices->
4818bf215546Sopenharmony_ci             process_qualifier_constant(state, "vertices",
4819bf215546Sopenharmony_ci                                        &num_vertices, false)) {
4820bf215546Sopenharmony_ci         return;
4821bf215546Sopenharmony_ci      }
4822bf215546Sopenharmony_ci
4823bf215546Sopenharmony_ci      if (num_vertices > state->Const.MaxPatchVertices) {
4824bf215546Sopenharmony_ci         _mesa_glsl_error(&loc, state, "vertices (%d) exceeds "
4825bf215546Sopenharmony_ci                          "GL_MAX_PATCH_VERTICES", num_vertices);
4826bf215546Sopenharmony_ci         return;
4827bf215546Sopenharmony_ci      }
4828bf215546Sopenharmony_ci   }
4829bf215546Sopenharmony_ci
4830bf215546Sopenharmony_ci   if (!var->type->is_array() && !var->data.patch) {
4831bf215546Sopenharmony_ci      _mesa_glsl_error(&loc, state,
4832bf215546Sopenharmony_ci                       "tessellation control shader outputs must be arrays");
4833bf215546Sopenharmony_ci
4834bf215546Sopenharmony_ci      /* To avoid cascading failures, short circuit the checks below. */
4835bf215546Sopenharmony_ci      return;
4836bf215546Sopenharmony_ci   }
4837bf215546Sopenharmony_ci
4838bf215546Sopenharmony_ci   if (var->data.patch)
4839bf215546Sopenharmony_ci      return;
4840bf215546Sopenharmony_ci
4841bf215546Sopenharmony_ci   validate_layout_qualifier_vertex_count(state, loc, var, num_vertices,
4842bf215546Sopenharmony_ci                                          &state->tcs_output_size,
4843bf215546Sopenharmony_ci                                          "tessellation control shader output");
4844bf215546Sopenharmony_ci}
4845bf215546Sopenharmony_ci
4846bf215546Sopenharmony_ci/**
4847bf215546Sopenharmony_ci * Do additional processing necessary for tessellation control/evaluation shader
4848bf215546Sopenharmony_ci * input declarations. This covers both interface block arrays and bare input
4849bf215546Sopenharmony_ci * variables.
4850bf215546Sopenharmony_ci */
4851bf215546Sopenharmony_cistatic void
4852bf215546Sopenharmony_cihandle_tess_shader_input_decl(struct _mesa_glsl_parse_state *state,
4853bf215546Sopenharmony_ci                              YYLTYPE loc, ir_variable *var)
4854bf215546Sopenharmony_ci{
4855bf215546Sopenharmony_ci   if (!var->type->is_array() && !var->data.patch) {
4856bf215546Sopenharmony_ci      _mesa_glsl_error(&loc, state,
4857bf215546Sopenharmony_ci                       "per-vertex tessellation shader inputs must be arrays");
4858bf215546Sopenharmony_ci      /* Avoid cascading failures. */
4859bf215546Sopenharmony_ci      return;
4860bf215546Sopenharmony_ci   }
4861bf215546Sopenharmony_ci
4862bf215546Sopenharmony_ci   if (var->data.patch)
4863bf215546Sopenharmony_ci      return;
4864bf215546Sopenharmony_ci
4865bf215546Sopenharmony_ci   /* The ARB_tessellation_shader spec says:
4866bf215546Sopenharmony_ci    *
4867bf215546Sopenharmony_ci    *    "Declaring an array size is optional.  If no size is specified, it
4868bf215546Sopenharmony_ci    *     will be taken from the implementation-dependent maximum patch size
4869bf215546Sopenharmony_ci    *     (gl_MaxPatchVertices).  If a size is specified, it must match the
4870bf215546Sopenharmony_ci    *     maximum patch size; otherwise, a compile or link error will occur."
4871bf215546Sopenharmony_ci    *
4872bf215546Sopenharmony_ci    * This text appears twice, once for TCS inputs, and again for TES inputs.
4873bf215546Sopenharmony_ci    */
4874bf215546Sopenharmony_ci   if (var->type->is_unsized_array()) {
4875bf215546Sopenharmony_ci      var->type = glsl_type::get_array_instance(var->type->fields.array,
4876bf215546Sopenharmony_ci            state->Const.MaxPatchVertices);
4877bf215546Sopenharmony_ci   } else if (var->type->length != state->Const.MaxPatchVertices) {
4878bf215546Sopenharmony_ci      _mesa_glsl_error(&loc, state,
4879bf215546Sopenharmony_ci                       "per-vertex tessellation shader input arrays must be "
4880bf215546Sopenharmony_ci                       "sized to gl_MaxPatchVertices (%d).",
4881bf215546Sopenharmony_ci                       state->Const.MaxPatchVertices);
4882bf215546Sopenharmony_ci   }
4883bf215546Sopenharmony_ci}
4884bf215546Sopenharmony_ci
4885bf215546Sopenharmony_ci
4886bf215546Sopenharmony_ci/**
4887bf215546Sopenharmony_ci * Do additional processing necessary for geometry shader input declarations
4888bf215546Sopenharmony_ci * (this covers both interface blocks arrays and bare input variables).
4889bf215546Sopenharmony_ci */
4890bf215546Sopenharmony_cistatic void
4891bf215546Sopenharmony_cihandle_geometry_shader_input_decl(struct _mesa_glsl_parse_state *state,
4892bf215546Sopenharmony_ci                                  YYLTYPE loc, ir_variable *var)
4893bf215546Sopenharmony_ci{
4894bf215546Sopenharmony_ci   unsigned num_vertices = 0;
4895bf215546Sopenharmony_ci
4896bf215546Sopenharmony_ci   if (state->gs_input_prim_type_specified) {
4897bf215546Sopenharmony_ci      num_vertices = vertices_per_prim(state->in_qualifier->prim_type);
4898bf215546Sopenharmony_ci   }
4899bf215546Sopenharmony_ci
4900bf215546Sopenharmony_ci   /* Geometry shader input variables must be arrays.  Caller should have
4901bf215546Sopenharmony_ci    * reported an error for this.
4902bf215546Sopenharmony_ci    */
4903bf215546Sopenharmony_ci   if (!var->type->is_array()) {
4904bf215546Sopenharmony_ci      assert(state->error);
4905bf215546Sopenharmony_ci
4906bf215546Sopenharmony_ci      /* To avoid cascading failures, short circuit the checks below. */
4907bf215546Sopenharmony_ci      return;
4908bf215546Sopenharmony_ci   }
4909bf215546Sopenharmony_ci
4910bf215546Sopenharmony_ci   validate_layout_qualifier_vertex_count(state, loc, var, num_vertices,
4911bf215546Sopenharmony_ci                                          &state->gs_input_size,
4912bf215546Sopenharmony_ci                                          "geometry shader input");
4913bf215546Sopenharmony_ci}
4914bf215546Sopenharmony_ci
4915bf215546Sopenharmony_cistatic void
4916bf215546Sopenharmony_civalidate_identifier(const char *identifier, YYLTYPE loc,
4917bf215546Sopenharmony_ci                    struct _mesa_glsl_parse_state *state)
4918bf215546Sopenharmony_ci{
4919bf215546Sopenharmony_ci   /* From page 15 (page 21 of the PDF) of the GLSL 1.10 spec,
4920bf215546Sopenharmony_ci    *
4921bf215546Sopenharmony_ci    *   "Identifiers starting with "gl_" are reserved for use by
4922bf215546Sopenharmony_ci    *   OpenGL, and may not be declared in a shader as either a
4923bf215546Sopenharmony_ci    *   variable or a function."
4924bf215546Sopenharmony_ci    */
4925bf215546Sopenharmony_ci   if (is_gl_identifier(identifier)) {
4926bf215546Sopenharmony_ci      _mesa_glsl_error(&loc, state,
4927bf215546Sopenharmony_ci                       "identifier `%s' uses reserved `gl_' prefix",
4928bf215546Sopenharmony_ci                       identifier);
4929bf215546Sopenharmony_ci   } else if (strstr(identifier, "__")) {
4930bf215546Sopenharmony_ci      /* From page 14 (page 20 of the PDF) of the GLSL 1.10
4931bf215546Sopenharmony_ci       * spec:
4932bf215546Sopenharmony_ci       *
4933bf215546Sopenharmony_ci       *     "In addition, all identifiers containing two
4934bf215546Sopenharmony_ci       *      consecutive underscores (__) are reserved as
4935bf215546Sopenharmony_ci       *      possible future keywords."
4936bf215546Sopenharmony_ci       *
4937bf215546Sopenharmony_ci       * The intention is that names containing __ are reserved for internal
4938bf215546Sopenharmony_ci       * use by the implementation, and names prefixed with GL_ are reserved
4939bf215546Sopenharmony_ci       * for use by Khronos.  Names simply containing __ are dangerous to use,
4940bf215546Sopenharmony_ci       * but should be allowed.
4941bf215546Sopenharmony_ci       *
4942bf215546Sopenharmony_ci       * A future version of the GLSL specification will clarify this.
4943bf215546Sopenharmony_ci       */
4944bf215546Sopenharmony_ci      _mesa_glsl_warning(&loc, state,
4945bf215546Sopenharmony_ci                         "identifier `%s' uses reserved `__' string",
4946bf215546Sopenharmony_ci                         identifier);
4947bf215546Sopenharmony_ci   }
4948bf215546Sopenharmony_ci}
4949bf215546Sopenharmony_ci
4950bf215546Sopenharmony_ciir_rvalue *
4951bf215546Sopenharmony_ciast_declarator_list::hir(exec_list *instructions,
4952bf215546Sopenharmony_ci                         struct _mesa_glsl_parse_state *state)
4953bf215546Sopenharmony_ci{
4954bf215546Sopenharmony_ci   void *ctx = state;
4955bf215546Sopenharmony_ci   const struct glsl_type *decl_type;
4956bf215546Sopenharmony_ci   const char *type_name = NULL;
4957bf215546Sopenharmony_ci   ir_rvalue *result = NULL;
4958bf215546Sopenharmony_ci   YYLTYPE loc = this->get_location();
4959bf215546Sopenharmony_ci
4960bf215546Sopenharmony_ci   /* From page 46 (page 52 of the PDF) of the GLSL 1.50 spec:
4961bf215546Sopenharmony_ci    *
4962bf215546Sopenharmony_ci    *     "To ensure that a particular output variable is invariant, it is
4963bf215546Sopenharmony_ci    *     necessary to use the invariant qualifier. It can either be used to
4964bf215546Sopenharmony_ci    *     qualify a previously declared variable as being invariant
4965bf215546Sopenharmony_ci    *
4966bf215546Sopenharmony_ci    *         invariant gl_Position; // make existing gl_Position be invariant"
4967bf215546Sopenharmony_ci    *
4968bf215546Sopenharmony_ci    * In these cases the parser will set the 'invariant' flag in the declarator
4969bf215546Sopenharmony_ci    * list, and the type will be NULL.
4970bf215546Sopenharmony_ci    */
4971bf215546Sopenharmony_ci   if (this->invariant) {
4972bf215546Sopenharmony_ci      assert(this->type == NULL);
4973bf215546Sopenharmony_ci
4974bf215546Sopenharmony_ci      if (state->current_function != NULL) {
4975bf215546Sopenharmony_ci         _mesa_glsl_error(& loc, state,
4976bf215546Sopenharmony_ci                          "all uses of `invariant' keyword must be at global "
4977bf215546Sopenharmony_ci                          "scope");
4978bf215546Sopenharmony_ci      }
4979bf215546Sopenharmony_ci
4980bf215546Sopenharmony_ci      foreach_list_typed (ast_declaration, decl, link, &this->declarations) {
4981bf215546Sopenharmony_ci         assert(decl->array_specifier == NULL);
4982bf215546Sopenharmony_ci         assert(decl->initializer == NULL);
4983bf215546Sopenharmony_ci
4984bf215546Sopenharmony_ci         ir_variable *const earlier =
4985bf215546Sopenharmony_ci            state->symbols->get_variable(decl->identifier);
4986bf215546Sopenharmony_ci         if (earlier == NULL) {
4987bf215546Sopenharmony_ci            _mesa_glsl_error(& loc, state,
4988bf215546Sopenharmony_ci                             "undeclared variable `%s' cannot be marked "
4989bf215546Sopenharmony_ci                             "invariant", decl->identifier);
4990bf215546Sopenharmony_ci         } else if (!is_allowed_invariant(earlier, state)) {
4991bf215546Sopenharmony_ci            _mesa_glsl_error(&loc, state,
4992bf215546Sopenharmony_ci                             "`%s' cannot be marked invariant; interfaces between "
4993bf215546Sopenharmony_ci                             "shader stages only.", decl->identifier);
4994bf215546Sopenharmony_ci         } else if (earlier->data.used) {
4995bf215546Sopenharmony_ci            _mesa_glsl_error(& loc, state,
4996bf215546Sopenharmony_ci                            "variable `%s' may not be redeclared "
4997bf215546Sopenharmony_ci                            "`invariant' after being used",
4998bf215546Sopenharmony_ci                            earlier->name);
4999bf215546Sopenharmony_ci         } else {
5000bf215546Sopenharmony_ci            earlier->data.explicit_invariant = true;
5001bf215546Sopenharmony_ci            earlier->data.invariant = true;
5002bf215546Sopenharmony_ci         }
5003bf215546Sopenharmony_ci      }
5004bf215546Sopenharmony_ci
5005bf215546Sopenharmony_ci      /* Invariant redeclarations do not have r-values.
5006bf215546Sopenharmony_ci       */
5007bf215546Sopenharmony_ci      return NULL;
5008bf215546Sopenharmony_ci   }
5009bf215546Sopenharmony_ci
5010bf215546Sopenharmony_ci   if (this->precise) {
5011bf215546Sopenharmony_ci      assert(this->type == NULL);
5012bf215546Sopenharmony_ci
5013bf215546Sopenharmony_ci      foreach_list_typed (ast_declaration, decl, link, &this->declarations) {
5014bf215546Sopenharmony_ci         assert(decl->array_specifier == NULL);
5015bf215546Sopenharmony_ci         assert(decl->initializer == NULL);
5016bf215546Sopenharmony_ci
5017bf215546Sopenharmony_ci         ir_variable *const earlier =
5018bf215546Sopenharmony_ci            state->symbols->get_variable(decl->identifier);
5019bf215546Sopenharmony_ci         if (earlier == NULL) {
5020bf215546Sopenharmony_ci            _mesa_glsl_error(& loc, state,
5021bf215546Sopenharmony_ci                             "undeclared variable `%s' cannot be marked "
5022bf215546Sopenharmony_ci                             "precise", decl->identifier);
5023bf215546Sopenharmony_ci         } else if (state->current_function != NULL &&
5024bf215546Sopenharmony_ci                    !state->symbols->name_declared_this_scope(decl->identifier)) {
5025bf215546Sopenharmony_ci            /* Note: we have to check if we're in a function, since
5026bf215546Sopenharmony_ci             * builtins are treated as having come from another scope.
5027bf215546Sopenharmony_ci             */
5028bf215546Sopenharmony_ci            _mesa_glsl_error(& loc, state,
5029bf215546Sopenharmony_ci                             "variable `%s' from an outer scope may not be "
5030bf215546Sopenharmony_ci                             "redeclared `precise' in this scope",
5031bf215546Sopenharmony_ci                             earlier->name);
5032bf215546Sopenharmony_ci         } else if (earlier->data.used) {
5033bf215546Sopenharmony_ci            _mesa_glsl_error(& loc, state,
5034bf215546Sopenharmony_ci                             "variable `%s' may not be redeclared "
5035bf215546Sopenharmony_ci                             "`precise' after being used",
5036bf215546Sopenharmony_ci                             earlier->name);
5037bf215546Sopenharmony_ci         } else {
5038bf215546Sopenharmony_ci            earlier->data.precise = true;
5039bf215546Sopenharmony_ci         }
5040bf215546Sopenharmony_ci      }
5041bf215546Sopenharmony_ci
5042bf215546Sopenharmony_ci      /* Precise redeclarations do not have r-values either. */
5043bf215546Sopenharmony_ci      return NULL;
5044bf215546Sopenharmony_ci   }
5045bf215546Sopenharmony_ci
5046bf215546Sopenharmony_ci   assert(this->type != NULL);
5047bf215546Sopenharmony_ci   assert(!this->invariant);
5048bf215546Sopenharmony_ci   assert(!this->precise);
5049bf215546Sopenharmony_ci
5050bf215546Sopenharmony_ci   /* GL_EXT_shader_image_load_store base type uses GLSL_TYPE_VOID as a special value to
5051bf215546Sopenharmony_ci    * indicate that it needs to be updated later (see glsl_parser.yy).
5052bf215546Sopenharmony_ci    * This is done here, based on the layout qualifier and the type of the image var
5053bf215546Sopenharmony_ci    */
5054bf215546Sopenharmony_ci   if (this->type->qualifier.flags.q.explicit_image_format &&
5055bf215546Sopenharmony_ci         this->type->specifier->type->is_image() &&
5056bf215546Sopenharmony_ci         this->type->qualifier.image_base_type == GLSL_TYPE_VOID) {
5057bf215546Sopenharmony_ci      /*     "The ARB_shader_image_load_store says:
5058bf215546Sopenharmony_ci       *     If both extensions are enabled in the shading language, the "size*" layout
5059bf215546Sopenharmony_ci       *     qualifiers are treated as format qualifiers, and are mapped to equivalent
5060bf215546Sopenharmony_ci       *     format qualifiers in the table below, according to the type of image
5061bf215546Sopenharmony_ci       *     variable.
5062bf215546Sopenharmony_ci       *                     image*    iimage*   uimage*
5063bf215546Sopenharmony_ci       *                     --------  --------  --------
5064bf215546Sopenharmony_ci       *       size1x8       n/a       r8i       r8ui
5065bf215546Sopenharmony_ci       *       size1x16      r16f      r16i      r16ui
5066bf215546Sopenharmony_ci       *       size1x32      r32f      r32i      r32ui
5067bf215546Sopenharmony_ci       *       size2x32      rg32f     rg32i     rg32ui
5068bf215546Sopenharmony_ci       *       size4x32      rgba32f   rgba32i   rgba32ui"
5069bf215546Sopenharmony_ci       */
5070bf215546Sopenharmony_ci      if (strncmp(this->type->specifier->type_name, "image", strlen("image")) == 0) {
5071bf215546Sopenharmony_ci         switch (this->type->qualifier.image_format) {
5072bf215546Sopenharmony_ci         case PIPE_FORMAT_R8_SINT:
5073bf215546Sopenharmony_ci            /* The GL_EXT_shader_image_load_store spec says:
5074bf215546Sopenharmony_ci             *    A layout of "size1x8" is illegal for image variables associated
5075bf215546Sopenharmony_ci             *    with floating-point data types.
5076bf215546Sopenharmony_ci             */
5077bf215546Sopenharmony_ci            _mesa_glsl_error(& loc, state,
5078bf215546Sopenharmony_ci                             "size1x8 is illegal for image variables "
5079bf215546Sopenharmony_ci                             "with floating-point data types.");
5080bf215546Sopenharmony_ci            return NULL;
5081bf215546Sopenharmony_ci         case PIPE_FORMAT_R16_SINT:
5082bf215546Sopenharmony_ci            this->type->qualifier.image_format = PIPE_FORMAT_R16_FLOAT;
5083bf215546Sopenharmony_ci            break;
5084bf215546Sopenharmony_ci         case PIPE_FORMAT_R32_SINT:
5085bf215546Sopenharmony_ci            this->type->qualifier.image_format = PIPE_FORMAT_R32_FLOAT;
5086bf215546Sopenharmony_ci            break;
5087bf215546Sopenharmony_ci         case PIPE_FORMAT_R32G32_SINT:
5088bf215546Sopenharmony_ci            this->type->qualifier.image_format = PIPE_FORMAT_R32G32_FLOAT;
5089bf215546Sopenharmony_ci            break;
5090bf215546Sopenharmony_ci         case PIPE_FORMAT_R32G32B32A32_SINT:
5091bf215546Sopenharmony_ci            this->type->qualifier.image_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
5092bf215546Sopenharmony_ci            break;
5093bf215546Sopenharmony_ci         default:
5094bf215546Sopenharmony_ci            unreachable("Unknown image format");
5095bf215546Sopenharmony_ci         }
5096bf215546Sopenharmony_ci         this->type->qualifier.image_base_type = GLSL_TYPE_FLOAT;
5097bf215546Sopenharmony_ci      } else if (strncmp(this->type->specifier->type_name, "uimage", strlen("uimage")) == 0) {
5098bf215546Sopenharmony_ci         switch (this->type->qualifier.image_format) {
5099bf215546Sopenharmony_ci         case PIPE_FORMAT_R8_SINT:
5100bf215546Sopenharmony_ci            this->type->qualifier.image_format = PIPE_FORMAT_R8_UINT;
5101bf215546Sopenharmony_ci            break;
5102bf215546Sopenharmony_ci         case PIPE_FORMAT_R16_SINT:
5103bf215546Sopenharmony_ci            this->type->qualifier.image_format = PIPE_FORMAT_R16_UINT;
5104bf215546Sopenharmony_ci            break;
5105bf215546Sopenharmony_ci         case PIPE_FORMAT_R32_SINT:
5106bf215546Sopenharmony_ci            this->type->qualifier.image_format = PIPE_FORMAT_R32_UINT;
5107bf215546Sopenharmony_ci            break;
5108bf215546Sopenharmony_ci         case PIPE_FORMAT_R32G32_SINT:
5109bf215546Sopenharmony_ci            this->type->qualifier.image_format = PIPE_FORMAT_R32G32_UINT;
5110bf215546Sopenharmony_ci            break;
5111bf215546Sopenharmony_ci         case PIPE_FORMAT_R32G32B32A32_SINT:
5112bf215546Sopenharmony_ci            this->type->qualifier.image_format = PIPE_FORMAT_R32G32B32A32_UINT;
5113bf215546Sopenharmony_ci            break;
5114bf215546Sopenharmony_ci         default:
5115bf215546Sopenharmony_ci            unreachable("Unknown image format");
5116bf215546Sopenharmony_ci         }
5117bf215546Sopenharmony_ci         this->type->qualifier.image_base_type = GLSL_TYPE_UINT;
5118bf215546Sopenharmony_ci      } else if (strncmp(this->type->specifier->type_name, "iimage", strlen("iimage")) == 0) {
5119bf215546Sopenharmony_ci         this->type->qualifier.image_base_type = GLSL_TYPE_INT;
5120bf215546Sopenharmony_ci      } else {
5121bf215546Sopenharmony_ci         assert(false);
5122bf215546Sopenharmony_ci      }
5123bf215546Sopenharmony_ci   }
5124bf215546Sopenharmony_ci
5125bf215546Sopenharmony_ci   /* The type specifier may contain a structure definition.  Process that
5126bf215546Sopenharmony_ci    * before any of the variable declarations.
5127bf215546Sopenharmony_ci    */
5128bf215546Sopenharmony_ci   (void) this->type->specifier->hir(instructions, state);
5129bf215546Sopenharmony_ci
5130bf215546Sopenharmony_ci   decl_type = this->type->glsl_type(& type_name, state);
5131bf215546Sopenharmony_ci
5132bf215546Sopenharmony_ci   /* Section 4.3.7 "Buffer Variables" of the GLSL 4.30 spec:
5133bf215546Sopenharmony_ci    *    "Buffer variables may only be declared inside interface blocks
5134bf215546Sopenharmony_ci    *    (section 4.3.9 “Interface Blocks”), which are then referred to as
5135bf215546Sopenharmony_ci    *    shader storage blocks. It is a compile-time error to declare buffer
5136bf215546Sopenharmony_ci    *    variables at global scope (outside a block)."
5137bf215546Sopenharmony_ci    */
5138bf215546Sopenharmony_ci   if (type->qualifier.flags.q.buffer && !decl_type->is_interface()) {
5139bf215546Sopenharmony_ci      _mesa_glsl_error(&loc, state,
5140bf215546Sopenharmony_ci                       "buffer variables cannot be declared outside "
5141bf215546Sopenharmony_ci                       "interface blocks");
5142bf215546Sopenharmony_ci   }
5143bf215546Sopenharmony_ci
5144bf215546Sopenharmony_ci   /* An offset-qualified atomic counter declaration sets the default
5145bf215546Sopenharmony_ci    * offset for the next declaration within the same atomic counter
5146bf215546Sopenharmony_ci    * buffer.
5147bf215546Sopenharmony_ci    */
5148bf215546Sopenharmony_ci   if (decl_type && decl_type->contains_atomic()) {
5149bf215546Sopenharmony_ci      if (type->qualifier.flags.q.explicit_binding &&
5150bf215546Sopenharmony_ci          type->qualifier.flags.q.explicit_offset) {
5151bf215546Sopenharmony_ci         unsigned qual_binding;
5152bf215546Sopenharmony_ci         unsigned qual_offset;
5153bf215546Sopenharmony_ci         if (process_qualifier_constant(state, &loc, "binding",
5154bf215546Sopenharmony_ci                                        type->qualifier.binding,
5155bf215546Sopenharmony_ci                                        &qual_binding)
5156bf215546Sopenharmony_ci             && process_qualifier_constant(state, &loc, "offset",
5157bf215546Sopenharmony_ci                                        type->qualifier.offset,
5158bf215546Sopenharmony_ci                                        &qual_offset)) {
5159bf215546Sopenharmony_ci            if (qual_binding < ARRAY_SIZE(state->atomic_counter_offsets))
5160bf215546Sopenharmony_ci               state->atomic_counter_offsets[qual_binding] = qual_offset;
5161bf215546Sopenharmony_ci         }
5162bf215546Sopenharmony_ci      }
5163bf215546Sopenharmony_ci
5164bf215546Sopenharmony_ci      ast_type_qualifier allowed_atomic_qual_mask;
5165bf215546Sopenharmony_ci      allowed_atomic_qual_mask.flags.i = 0;
5166bf215546Sopenharmony_ci      allowed_atomic_qual_mask.flags.q.explicit_binding = 1;
5167bf215546Sopenharmony_ci      allowed_atomic_qual_mask.flags.q.explicit_offset = 1;
5168bf215546Sopenharmony_ci      allowed_atomic_qual_mask.flags.q.uniform = 1;
5169bf215546Sopenharmony_ci
5170bf215546Sopenharmony_ci      type->qualifier.validate_flags(&loc, state, allowed_atomic_qual_mask,
5171bf215546Sopenharmony_ci                                     "invalid layout qualifier for",
5172bf215546Sopenharmony_ci                                     "atomic_uint");
5173bf215546Sopenharmony_ci   }
5174bf215546Sopenharmony_ci
5175bf215546Sopenharmony_ci   if (this->declarations.is_empty()) {
5176bf215546Sopenharmony_ci      /* If there is no structure involved in the program text, there are two
5177bf215546Sopenharmony_ci       * possible scenarios:
5178bf215546Sopenharmony_ci       *
5179bf215546Sopenharmony_ci       * - The program text contained something like 'vec4;'.  This is an
5180bf215546Sopenharmony_ci       *   empty declaration.  It is valid but weird.  Emit a warning.
5181bf215546Sopenharmony_ci       *
5182bf215546Sopenharmony_ci       * - The program text contained something like 'S;' and 'S' is not the
5183bf215546Sopenharmony_ci       *   name of a known structure type.  This is both invalid and weird.
5184bf215546Sopenharmony_ci       *   Emit an error.
5185bf215546Sopenharmony_ci       *
5186bf215546Sopenharmony_ci       * - The program text contained something like 'mediump float;'
5187bf215546Sopenharmony_ci       *   when the programmer probably meant 'precision mediump
5188bf215546Sopenharmony_ci       *   float;' Emit a warning with a description of what they
5189bf215546Sopenharmony_ci       *   probably meant to do.
5190bf215546Sopenharmony_ci       *
5191bf215546Sopenharmony_ci       * Note that if decl_type is NULL and there is a structure involved,
5192bf215546Sopenharmony_ci       * there must have been some sort of error with the structure.  In this
5193bf215546Sopenharmony_ci       * case we assume that an error was already generated on this line of
5194bf215546Sopenharmony_ci       * code for the structure.  There is no need to generate an additional,
5195bf215546Sopenharmony_ci       * confusing error.
5196bf215546Sopenharmony_ci       */
5197bf215546Sopenharmony_ci      assert(this->type->specifier->structure == NULL || decl_type != NULL
5198bf215546Sopenharmony_ci             || state->error);
5199bf215546Sopenharmony_ci
5200bf215546Sopenharmony_ci      if (decl_type == NULL) {
5201bf215546Sopenharmony_ci         _mesa_glsl_error(&loc, state,
5202bf215546Sopenharmony_ci                          "invalid type `%s' in empty declaration",
5203bf215546Sopenharmony_ci                          type_name);
5204bf215546Sopenharmony_ci      } else {
5205bf215546Sopenharmony_ci         if (decl_type->is_array()) {
5206bf215546Sopenharmony_ci            /* From Section 13.22 (Array Declarations) of the GLSL ES 3.2
5207bf215546Sopenharmony_ci             * spec:
5208bf215546Sopenharmony_ci             *
5209bf215546Sopenharmony_ci             *    "... any declaration that leaves the size undefined is
5210bf215546Sopenharmony_ci             *    disallowed as this would add complexity and there are no
5211bf215546Sopenharmony_ci             *    use-cases."
5212bf215546Sopenharmony_ci             */
5213bf215546Sopenharmony_ci            if (state->es_shader && decl_type->is_unsized_array()) {
5214bf215546Sopenharmony_ci               _mesa_glsl_error(&loc, state, "array size must be explicitly "
5215bf215546Sopenharmony_ci                                "or implicitly defined");
5216bf215546Sopenharmony_ci            }
5217bf215546Sopenharmony_ci
5218bf215546Sopenharmony_ci            /* From Section 4.12 (Empty Declarations) of the GLSL 4.5 spec:
5219bf215546Sopenharmony_ci             *
5220bf215546Sopenharmony_ci             *    "The combinations of types and qualifiers that cause
5221bf215546Sopenharmony_ci             *    compile-time or link-time errors are the same whether or not
5222bf215546Sopenharmony_ci             *    the declaration is empty."
5223bf215546Sopenharmony_ci             */
5224bf215546Sopenharmony_ci            validate_array_dimensions(decl_type, state, &loc);
5225bf215546Sopenharmony_ci         }
5226bf215546Sopenharmony_ci
5227bf215546Sopenharmony_ci         if (decl_type->is_atomic_uint()) {
5228bf215546Sopenharmony_ci            /* Empty atomic counter declarations are allowed and useful
5229bf215546Sopenharmony_ci             * to set the default offset qualifier.
5230bf215546Sopenharmony_ci             */
5231bf215546Sopenharmony_ci            return NULL;
5232bf215546Sopenharmony_ci         } else if (this->type->qualifier.precision != ast_precision_none) {
5233bf215546Sopenharmony_ci            if (this->type->specifier->structure != NULL) {
5234bf215546Sopenharmony_ci               _mesa_glsl_error(&loc, state,
5235bf215546Sopenharmony_ci                                "precision qualifiers can't be applied "
5236bf215546Sopenharmony_ci                                "to structures");
5237bf215546Sopenharmony_ci            } else {
5238bf215546Sopenharmony_ci               static const char *const precision_names[] = {
5239bf215546Sopenharmony_ci                  "highp",
5240bf215546Sopenharmony_ci                  "highp",
5241bf215546Sopenharmony_ci                  "mediump",
5242bf215546Sopenharmony_ci                  "lowp"
5243bf215546Sopenharmony_ci               };
5244bf215546Sopenharmony_ci
5245bf215546Sopenharmony_ci               _mesa_glsl_warning(&loc, state,
5246bf215546Sopenharmony_ci                                  "empty declaration with precision "
5247bf215546Sopenharmony_ci                                  "qualifier, to set the default precision, "
5248bf215546Sopenharmony_ci                                  "use `precision %s %s;'",
5249bf215546Sopenharmony_ci                                  precision_names[this->type->
5250bf215546Sopenharmony_ci                                     qualifier.precision],
5251bf215546Sopenharmony_ci                                  type_name);
5252bf215546Sopenharmony_ci            }
5253bf215546Sopenharmony_ci         } else if (this->type->specifier->structure == NULL) {
5254bf215546Sopenharmony_ci            _mesa_glsl_warning(&loc, state, "empty declaration");
5255bf215546Sopenharmony_ci         }
5256bf215546Sopenharmony_ci      }
5257bf215546Sopenharmony_ci   }
5258bf215546Sopenharmony_ci
5259bf215546Sopenharmony_ci   foreach_list_typed (ast_declaration, decl, link, &this->declarations) {
5260bf215546Sopenharmony_ci      const struct glsl_type *var_type;
5261bf215546Sopenharmony_ci      ir_variable *var;
5262bf215546Sopenharmony_ci      const char *identifier = decl->identifier;
5263bf215546Sopenharmony_ci      /* FINISHME: Emit a warning if a variable declaration shadows a
5264bf215546Sopenharmony_ci       * FINISHME: declaration at a higher scope.
5265bf215546Sopenharmony_ci       */
5266bf215546Sopenharmony_ci
5267bf215546Sopenharmony_ci      if ((decl_type == NULL) || decl_type->is_void()) {
5268bf215546Sopenharmony_ci         if (type_name != NULL) {
5269bf215546Sopenharmony_ci            _mesa_glsl_error(& loc, state,
5270bf215546Sopenharmony_ci                             "invalid type `%s' in declaration of `%s'",
5271bf215546Sopenharmony_ci                             type_name, decl->identifier);
5272bf215546Sopenharmony_ci         } else {
5273bf215546Sopenharmony_ci            _mesa_glsl_error(& loc, state,
5274bf215546Sopenharmony_ci                             "invalid type in declaration of `%s'",
5275bf215546Sopenharmony_ci                             decl->identifier);
5276bf215546Sopenharmony_ci         }
5277bf215546Sopenharmony_ci         continue;
5278bf215546Sopenharmony_ci      }
5279bf215546Sopenharmony_ci
5280bf215546Sopenharmony_ci      if (this->type->qualifier.is_subroutine_decl()) {
5281bf215546Sopenharmony_ci         const glsl_type *t;
5282bf215546Sopenharmony_ci         const char *name;
5283bf215546Sopenharmony_ci
5284bf215546Sopenharmony_ci         t = state->symbols->get_type(this->type->specifier->type_name);
5285bf215546Sopenharmony_ci         if (!t)
5286bf215546Sopenharmony_ci            _mesa_glsl_error(& loc, state,
5287bf215546Sopenharmony_ci                             "invalid type in declaration of `%s'",
5288bf215546Sopenharmony_ci                             decl->identifier);
5289bf215546Sopenharmony_ci         name = ralloc_asprintf(ctx, "%s_%s", _mesa_shader_stage_to_subroutine_prefix(state->stage), decl->identifier);
5290bf215546Sopenharmony_ci
5291bf215546Sopenharmony_ci         identifier = name;
5292bf215546Sopenharmony_ci
5293bf215546Sopenharmony_ci      }
5294bf215546Sopenharmony_ci      var_type = process_array_type(&loc, decl_type, decl->array_specifier,
5295bf215546Sopenharmony_ci                                    state);
5296bf215546Sopenharmony_ci
5297bf215546Sopenharmony_ci      var = new(ctx) ir_variable(var_type, identifier, ir_var_auto);
5298bf215546Sopenharmony_ci
5299bf215546Sopenharmony_ci      /* The 'varying in' and 'varying out' qualifiers can only be used with
5300bf215546Sopenharmony_ci       * ARB_geometry_shader4 and EXT_geometry_shader4, which we don't support
5301bf215546Sopenharmony_ci       * yet.
5302bf215546Sopenharmony_ci       */
5303bf215546Sopenharmony_ci      if (this->type->qualifier.flags.q.varying) {
5304bf215546Sopenharmony_ci         if (this->type->qualifier.flags.q.in) {
5305bf215546Sopenharmony_ci            _mesa_glsl_error(& loc, state,
5306bf215546Sopenharmony_ci                             "`varying in' qualifier in declaration of "
5307bf215546Sopenharmony_ci                             "`%s' only valid for geometry shaders using "
5308bf215546Sopenharmony_ci                             "ARB_geometry_shader4 or EXT_geometry_shader4",
5309bf215546Sopenharmony_ci                             decl->identifier);
5310bf215546Sopenharmony_ci         } else if (this->type->qualifier.flags.q.out) {
5311bf215546Sopenharmony_ci            _mesa_glsl_error(& loc, state,
5312bf215546Sopenharmony_ci                             "`varying out' qualifier in declaration of "
5313bf215546Sopenharmony_ci                             "`%s' only valid for geometry shaders using "
5314bf215546Sopenharmony_ci                             "ARB_geometry_shader4 or EXT_geometry_shader4",
5315bf215546Sopenharmony_ci                             decl->identifier);
5316bf215546Sopenharmony_ci         }
5317bf215546Sopenharmony_ci      }
5318bf215546Sopenharmony_ci
5319bf215546Sopenharmony_ci      /* From page 22 (page 28 of the PDF) of the GLSL 1.10 specification;
5320bf215546Sopenharmony_ci       *
5321bf215546Sopenharmony_ci       *     "Global variables can only use the qualifiers const,
5322bf215546Sopenharmony_ci       *     attribute, uniform, or varying. Only one may be
5323bf215546Sopenharmony_ci       *     specified.
5324bf215546Sopenharmony_ci       *
5325bf215546Sopenharmony_ci       *     Local variables can only use the qualifier const."
5326bf215546Sopenharmony_ci       *
5327bf215546Sopenharmony_ci       * This is relaxed in GLSL 1.30 and GLSL ES 3.00.  It is also relaxed by
5328bf215546Sopenharmony_ci       * any extension that adds the 'layout' keyword.
5329bf215546Sopenharmony_ci       */
5330bf215546Sopenharmony_ci      if (!state->is_version(130, 300)
5331bf215546Sopenharmony_ci          && !state->has_explicit_attrib_location()
5332bf215546Sopenharmony_ci          && !state->has_separate_shader_objects()
5333bf215546Sopenharmony_ci          && !state->ARB_fragment_coord_conventions_enable) {
5334bf215546Sopenharmony_ci         /* GL_EXT_gpu_shader4 only allows "varying out" on fragment shader
5335bf215546Sopenharmony_ci          * outputs. (the varying flag is not set by the parser)
5336bf215546Sopenharmony_ci          */
5337bf215546Sopenharmony_ci         if (this->type->qualifier.flags.q.out &&
5338bf215546Sopenharmony_ci             (!state->EXT_gpu_shader4_enable ||
5339bf215546Sopenharmony_ci              state->stage != MESA_SHADER_FRAGMENT)) {
5340bf215546Sopenharmony_ci            _mesa_glsl_error(& loc, state,
5341bf215546Sopenharmony_ci                             "`out' qualifier in declaration of `%s' "
5342bf215546Sopenharmony_ci                             "only valid for function parameters in %s",
5343bf215546Sopenharmony_ci                             decl->identifier, state->get_version_string());
5344bf215546Sopenharmony_ci         }
5345bf215546Sopenharmony_ci         if (this->type->qualifier.flags.q.in) {
5346bf215546Sopenharmony_ci            _mesa_glsl_error(& loc, state,
5347bf215546Sopenharmony_ci                             "`in' qualifier in declaration of `%s' "
5348bf215546Sopenharmony_ci                             "only valid for function parameters in %s",
5349bf215546Sopenharmony_ci                             decl->identifier, state->get_version_string());
5350bf215546Sopenharmony_ci         }
5351bf215546Sopenharmony_ci         /* FINISHME: Test for other invalid qualifiers. */
5352bf215546Sopenharmony_ci      }
5353bf215546Sopenharmony_ci
5354bf215546Sopenharmony_ci      apply_type_qualifier_to_variable(& this->type->qualifier, var, state,
5355bf215546Sopenharmony_ci                                       & loc, false);
5356bf215546Sopenharmony_ci      apply_layout_qualifier_to_variable(&this->type->qualifier, var, state,
5357bf215546Sopenharmony_ci                                         &loc);
5358bf215546Sopenharmony_ci
5359bf215546Sopenharmony_ci      if ((state->zero_init & (1u << var->data.mode)) &&
5360bf215546Sopenharmony_ci          (var->type->is_numeric() || var->type->is_boolean())) {
5361bf215546Sopenharmony_ci         const ir_constant_data data = { { 0 } };
5362bf215546Sopenharmony_ci         var->data.has_initializer = true;
5363bf215546Sopenharmony_ci         var->data.is_implicit_initializer = true;
5364bf215546Sopenharmony_ci         var->constant_initializer = new(var) ir_constant(var->type, &data);
5365bf215546Sopenharmony_ci      }
5366bf215546Sopenharmony_ci
5367bf215546Sopenharmony_ci      if (this->type->qualifier.flags.q.invariant) {
5368bf215546Sopenharmony_ci         if (!is_allowed_invariant(var, state)) {
5369bf215546Sopenharmony_ci            _mesa_glsl_error(&loc, state,
5370bf215546Sopenharmony_ci                             "`%s' cannot be marked invariant; interfaces between "
5371bf215546Sopenharmony_ci                             "shader stages only", var->name);
5372bf215546Sopenharmony_ci         }
5373bf215546Sopenharmony_ci      }
5374bf215546Sopenharmony_ci
5375bf215546Sopenharmony_ci      if (state->current_function != NULL) {
5376bf215546Sopenharmony_ci         const char *mode = NULL;
5377bf215546Sopenharmony_ci         const char *extra = "";
5378bf215546Sopenharmony_ci
5379bf215546Sopenharmony_ci         /* There is no need to check for 'inout' here because the parser will
5380bf215546Sopenharmony_ci          * only allow that in function parameter lists.
5381bf215546Sopenharmony_ci          */
5382bf215546Sopenharmony_ci         if (this->type->qualifier.flags.q.attribute) {
5383bf215546Sopenharmony_ci            mode = "attribute";
5384bf215546Sopenharmony_ci         } else if (this->type->qualifier.is_subroutine_decl()) {
5385bf215546Sopenharmony_ci            mode = "subroutine uniform";
5386bf215546Sopenharmony_ci         } else if (this->type->qualifier.flags.q.uniform) {
5387bf215546Sopenharmony_ci            mode = "uniform";
5388bf215546Sopenharmony_ci         } else if (this->type->qualifier.flags.q.varying) {
5389bf215546Sopenharmony_ci            mode = "varying";
5390bf215546Sopenharmony_ci         } else if (this->type->qualifier.flags.q.in) {
5391bf215546Sopenharmony_ci            mode = "in";
5392bf215546Sopenharmony_ci            extra = " or in function parameter list";
5393bf215546Sopenharmony_ci         } else if (this->type->qualifier.flags.q.out) {
5394bf215546Sopenharmony_ci            mode = "out";
5395bf215546Sopenharmony_ci            extra = " or in function parameter list";
5396bf215546Sopenharmony_ci         }
5397bf215546Sopenharmony_ci
5398bf215546Sopenharmony_ci         if (mode) {
5399bf215546Sopenharmony_ci            _mesa_glsl_error(& loc, state,
5400bf215546Sopenharmony_ci                             "%s variable `%s' must be declared at "
5401bf215546Sopenharmony_ci                             "global scope%s",
5402bf215546Sopenharmony_ci                             mode, var->name, extra);
5403bf215546Sopenharmony_ci         }
5404bf215546Sopenharmony_ci      } else if (var->data.mode == ir_var_shader_in) {
5405bf215546Sopenharmony_ci         var->data.read_only = true;
5406bf215546Sopenharmony_ci
5407bf215546Sopenharmony_ci         if (state->stage == MESA_SHADER_VERTEX) {
5408bf215546Sopenharmony_ci            /* From page 31 (page 37 of the PDF) of the GLSL 1.50 spec:
5409bf215546Sopenharmony_ci             *
5410bf215546Sopenharmony_ci             *    "Vertex shader inputs can only be float, floating-point
5411bf215546Sopenharmony_ci             *    vectors, matrices, signed and unsigned integers and integer
5412bf215546Sopenharmony_ci             *    vectors. Vertex shader inputs can also form arrays of these
5413bf215546Sopenharmony_ci             *    types, but not structures."
5414bf215546Sopenharmony_ci             *
5415bf215546Sopenharmony_ci             * From page 31 (page 27 of the PDF) of the GLSL 1.30 spec:
5416bf215546Sopenharmony_ci             *
5417bf215546Sopenharmony_ci             *    "Vertex shader inputs can only be float, floating-point
5418bf215546Sopenharmony_ci             *    vectors, matrices, signed and unsigned integers and integer
5419bf215546Sopenharmony_ci             *    vectors. They cannot be arrays or structures."
5420bf215546Sopenharmony_ci             *
5421bf215546Sopenharmony_ci             * From page 23 (page 29 of the PDF) of the GLSL 1.20 spec:
5422bf215546Sopenharmony_ci             *
5423bf215546Sopenharmony_ci             *    "The attribute qualifier can be used only with float,
5424bf215546Sopenharmony_ci             *    floating-point vectors, and matrices. Attribute variables
5425bf215546Sopenharmony_ci             *    cannot be declared as arrays or structures."
5426bf215546Sopenharmony_ci             *
5427bf215546Sopenharmony_ci             * From page 33 (page 39 of the PDF) of the GLSL ES 3.00 spec:
5428bf215546Sopenharmony_ci             *
5429bf215546Sopenharmony_ci             *    "Vertex shader inputs can only be float, floating-point
5430bf215546Sopenharmony_ci             *    vectors, matrices, signed and unsigned integers and integer
5431bf215546Sopenharmony_ci             *    vectors. Vertex shader inputs cannot be arrays or
5432bf215546Sopenharmony_ci             *    structures."
5433bf215546Sopenharmony_ci             *
5434bf215546Sopenharmony_ci             * From section 4.3.4 of the ARB_bindless_texture spec:
5435bf215546Sopenharmony_ci             *
5436bf215546Sopenharmony_ci             *    "(modify third paragraph of the section to allow sampler and
5437bf215546Sopenharmony_ci             *    image types) ...  Vertex shader inputs can only be float,
5438bf215546Sopenharmony_ci             *    single-precision floating-point scalars, single-precision
5439bf215546Sopenharmony_ci             *    floating-point vectors, matrices, signed and unsigned
5440bf215546Sopenharmony_ci             *    integers and integer vectors, sampler and image types."
5441bf215546Sopenharmony_ci             */
5442bf215546Sopenharmony_ci            const glsl_type *check_type = var->type->without_array();
5443bf215546Sopenharmony_ci
5444bf215546Sopenharmony_ci            bool error = false;
5445bf215546Sopenharmony_ci            switch (check_type->base_type) {
5446bf215546Sopenharmony_ci            case GLSL_TYPE_FLOAT:
5447bf215546Sopenharmony_ci               break;
5448bf215546Sopenharmony_ci            case GLSL_TYPE_UINT64:
5449bf215546Sopenharmony_ci            case GLSL_TYPE_INT64:
5450bf215546Sopenharmony_ci               break;
5451bf215546Sopenharmony_ci            case GLSL_TYPE_UINT:
5452bf215546Sopenharmony_ci            case GLSL_TYPE_INT:
5453bf215546Sopenharmony_ci               error = !state->is_version(120, 300) && !state->EXT_gpu_shader4_enable;
5454bf215546Sopenharmony_ci               break;
5455bf215546Sopenharmony_ci            case GLSL_TYPE_DOUBLE:
5456bf215546Sopenharmony_ci               error = !state->is_version(410, 0) && !state->ARB_vertex_attrib_64bit_enable;
5457bf215546Sopenharmony_ci               break;
5458bf215546Sopenharmony_ci            case GLSL_TYPE_SAMPLER:
5459bf215546Sopenharmony_ci            case GLSL_TYPE_TEXTURE:
5460bf215546Sopenharmony_ci            case GLSL_TYPE_IMAGE:
5461bf215546Sopenharmony_ci               error = !state->has_bindless();
5462bf215546Sopenharmony_ci               break;
5463bf215546Sopenharmony_ci            default:
5464bf215546Sopenharmony_ci               error = true;
5465bf215546Sopenharmony_ci            }
5466bf215546Sopenharmony_ci
5467bf215546Sopenharmony_ci            if (error) {
5468bf215546Sopenharmony_ci               _mesa_glsl_error(& loc, state,
5469bf215546Sopenharmony_ci                                "vertex shader input / attribute cannot have "
5470bf215546Sopenharmony_ci                                "type %s`%s'",
5471bf215546Sopenharmony_ci                                var->type->is_array() ? "array of " : "",
5472bf215546Sopenharmony_ci                                check_type->name);
5473bf215546Sopenharmony_ci            } else if (var->type->is_array() &&
5474bf215546Sopenharmony_ci                !state->check_version(150, 0, &loc,
5475bf215546Sopenharmony_ci                                      "vertex shader input / attribute "
5476bf215546Sopenharmony_ci                                      "cannot have array type")) {
5477bf215546Sopenharmony_ci            }
5478bf215546Sopenharmony_ci         } else if (state->stage == MESA_SHADER_GEOMETRY) {
5479bf215546Sopenharmony_ci            /* From section 4.3.4 (Inputs) of the GLSL 1.50 spec:
5480bf215546Sopenharmony_ci             *
5481bf215546Sopenharmony_ci             *     Geometry shader input variables get the per-vertex values
5482bf215546Sopenharmony_ci             *     written out by vertex shader output variables of the same
5483bf215546Sopenharmony_ci             *     names. Since a geometry shader operates on a set of
5484bf215546Sopenharmony_ci             *     vertices, each input varying variable (or input block, see
5485bf215546Sopenharmony_ci             *     interface blocks below) needs to be declared as an array.
5486bf215546Sopenharmony_ci             */
5487bf215546Sopenharmony_ci            if (!var->type->is_array()) {
5488bf215546Sopenharmony_ci               _mesa_glsl_error(&loc, state,
5489bf215546Sopenharmony_ci                                "geometry shader inputs must be arrays");
5490bf215546Sopenharmony_ci            }
5491bf215546Sopenharmony_ci
5492bf215546Sopenharmony_ci            handle_geometry_shader_input_decl(state, loc, var);
5493bf215546Sopenharmony_ci         } else if (state->stage == MESA_SHADER_FRAGMENT) {
5494bf215546Sopenharmony_ci            /* From section 4.3.4 (Input Variables) of the GLSL ES 3.10 spec:
5495bf215546Sopenharmony_ci             *
5496bf215546Sopenharmony_ci             *     It is a compile-time error to declare a fragment shader
5497bf215546Sopenharmony_ci             *     input with, or that contains, any of the following types:
5498bf215546Sopenharmony_ci             *
5499bf215546Sopenharmony_ci             *     * A boolean type
5500bf215546Sopenharmony_ci             *     * An opaque type
5501bf215546Sopenharmony_ci             *     * An array of arrays
5502bf215546Sopenharmony_ci             *     * An array of structures
5503bf215546Sopenharmony_ci             *     * A structure containing an array
5504bf215546Sopenharmony_ci             *     * A structure containing a structure
5505bf215546Sopenharmony_ci             */
5506bf215546Sopenharmony_ci            if (state->es_shader) {
5507bf215546Sopenharmony_ci               const glsl_type *check_type = var->type->without_array();
5508bf215546Sopenharmony_ci               if (check_type->is_boolean() ||
5509bf215546Sopenharmony_ci                   check_type->contains_opaque()) {
5510bf215546Sopenharmony_ci                  _mesa_glsl_error(&loc, state,
5511bf215546Sopenharmony_ci                                   "fragment shader input cannot have type %s",
5512bf215546Sopenharmony_ci                                   check_type->name);
5513bf215546Sopenharmony_ci               }
5514bf215546Sopenharmony_ci               if (var->type->is_array() &&
5515bf215546Sopenharmony_ci                   var->type->fields.array->is_array()) {
5516bf215546Sopenharmony_ci                  _mesa_glsl_error(&loc, state,
5517bf215546Sopenharmony_ci                                   "%s shader output "
5518bf215546Sopenharmony_ci                                   "cannot have an array of arrays",
5519bf215546Sopenharmony_ci                                   _mesa_shader_stage_to_string(state->stage));
5520bf215546Sopenharmony_ci               }
5521bf215546Sopenharmony_ci               if (var->type->is_array() &&
5522bf215546Sopenharmony_ci                   var->type->fields.array->is_struct()) {
5523bf215546Sopenharmony_ci                  _mesa_glsl_error(&loc, state,
5524bf215546Sopenharmony_ci                                   "fragment shader input "
5525bf215546Sopenharmony_ci                                   "cannot have an array of structs");
5526bf215546Sopenharmony_ci               }
5527bf215546Sopenharmony_ci               if (var->type->is_struct()) {
5528bf215546Sopenharmony_ci                  for (unsigned i = 0; i < var->type->length; i++) {
5529bf215546Sopenharmony_ci                     if (var->type->fields.structure[i].type->is_array() ||
5530bf215546Sopenharmony_ci                         var->type->fields.structure[i].type->is_struct())
5531bf215546Sopenharmony_ci                        _mesa_glsl_error(&loc, state,
5532bf215546Sopenharmony_ci                                         "fragment shader input cannot have "
5533bf215546Sopenharmony_ci                                         "a struct that contains an "
5534bf215546Sopenharmony_ci                                         "array or struct");
5535bf215546Sopenharmony_ci                  }
5536bf215546Sopenharmony_ci               }
5537bf215546Sopenharmony_ci            }
5538bf215546Sopenharmony_ci         } else if (state->stage == MESA_SHADER_TESS_CTRL ||
5539bf215546Sopenharmony_ci                    state->stage == MESA_SHADER_TESS_EVAL) {
5540bf215546Sopenharmony_ci            handle_tess_shader_input_decl(state, loc, var);
5541bf215546Sopenharmony_ci         }
5542bf215546Sopenharmony_ci      } else if (var->data.mode == ir_var_shader_out) {
5543bf215546Sopenharmony_ci         const glsl_type *check_type = var->type->without_array();
5544bf215546Sopenharmony_ci
5545bf215546Sopenharmony_ci         /* From section 4.3.6 (Output variables) of the GLSL 4.40 spec:
5546bf215546Sopenharmony_ci          *
5547bf215546Sopenharmony_ci          *     It is a compile-time error to declare a fragment shader output
5548bf215546Sopenharmony_ci          *     that contains any of the following:
5549bf215546Sopenharmony_ci          *
5550bf215546Sopenharmony_ci          *     * A Boolean type (bool, bvec2 ...)
5551bf215546Sopenharmony_ci          *     * A double-precision scalar or vector (double, dvec2 ...)
5552bf215546Sopenharmony_ci          *     * An opaque type
5553bf215546Sopenharmony_ci          *     * Any matrix type
5554bf215546Sopenharmony_ci          *     * A structure
5555bf215546Sopenharmony_ci          */
5556bf215546Sopenharmony_ci         if (state->stage == MESA_SHADER_FRAGMENT) {
5557bf215546Sopenharmony_ci            if (check_type->is_struct() || check_type->is_matrix())
5558bf215546Sopenharmony_ci               _mesa_glsl_error(&loc, state,
5559bf215546Sopenharmony_ci                                "fragment shader output "
5560bf215546Sopenharmony_ci                                "cannot have struct or matrix type");
5561bf215546Sopenharmony_ci            switch (check_type->base_type) {
5562bf215546Sopenharmony_ci            case GLSL_TYPE_UINT:
5563bf215546Sopenharmony_ci            case GLSL_TYPE_INT:
5564bf215546Sopenharmony_ci            case GLSL_TYPE_FLOAT:
5565bf215546Sopenharmony_ci               break;
5566bf215546Sopenharmony_ci            default:
5567bf215546Sopenharmony_ci               _mesa_glsl_error(&loc, state,
5568bf215546Sopenharmony_ci                                "fragment shader output cannot have "
5569bf215546Sopenharmony_ci                                "type %s", check_type->name);
5570bf215546Sopenharmony_ci            }
5571bf215546Sopenharmony_ci         }
5572bf215546Sopenharmony_ci
5573bf215546Sopenharmony_ci         /* From section 4.3.6 (Output Variables) of the GLSL ES 3.10 spec:
5574bf215546Sopenharmony_ci          *
5575bf215546Sopenharmony_ci          *     It is a compile-time error to declare a vertex shader output
5576bf215546Sopenharmony_ci          *     with, or that contains, any of the following types:
5577bf215546Sopenharmony_ci          *
5578bf215546Sopenharmony_ci          *     * A boolean type
5579bf215546Sopenharmony_ci          *     * An opaque type
5580bf215546Sopenharmony_ci          *     * An array of arrays
5581bf215546Sopenharmony_ci          *     * An array of structures
5582bf215546Sopenharmony_ci          *     * A structure containing an array
5583bf215546Sopenharmony_ci          *     * A structure containing a structure
5584bf215546Sopenharmony_ci          *
5585bf215546Sopenharmony_ci          *     It is a compile-time error to declare a fragment shader output
5586bf215546Sopenharmony_ci          *     with, or that contains, any of the following types:
5587bf215546Sopenharmony_ci          *
5588bf215546Sopenharmony_ci          *     * A boolean type
5589bf215546Sopenharmony_ci          *     * An opaque type
5590bf215546Sopenharmony_ci          *     * A matrix
5591bf215546Sopenharmony_ci          *     * A structure
5592bf215546Sopenharmony_ci          *     * An array of array
5593bf215546Sopenharmony_ci          *
5594bf215546Sopenharmony_ci          * ES 3.20 updates this to apply to tessellation and geometry shaders
5595bf215546Sopenharmony_ci          * as well.  Because there are per-vertex arrays in the new stages,
5596bf215546Sopenharmony_ci          * it strikes the "array of..." rules and replaces them with these:
5597bf215546Sopenharmony_ci          *
5598bf215546Sopenharmony_ci          *     * For per-vertex-arrayed variables (applies to tessellation
5599bf215546Sopenharmony_ci          *       control, tessellation evaluation and geometry shaders):
5600bf215546Sopenharmony_ci          *
5601bf215546Sopenharmony_ci          *       * Per-vertex-arrayed arrays of arrays
5602bf215546Sopenharmony_ci          *       * Per-vertex-arrayed arrays of structures
5603bf215546Sopenharmony_ci          *
5604bf215546Sopenharmony_ci          *     * For non-per-vertex-arrayed variables:
5605bf215546Sopenharmony_ci          *
5606bf215546Sopenharmony_ci          *       * An array of arrays
5607bf215546Sopenharmony_ci          *       * An array of structures
5608bf215546Sopenharmony_ci          *
5609bf215546Sopenharmony_ci          * which basically says to unwrap the per-vertex aspect and apply
5610bf215546Sopenharmony_ci          * the old rules.
5611bf215546Sopenharmony_ci          */
5612bf215546Sopenharmony_ci         if (state->es_shader) {
5613bf215546Sopenharmony_ci            if (var->type->is_array() &&
5614bf215546Sopenharmony_ci                var->type->fields.array->is_array()) {
5615bf215546Sopenharmony_ci               _mesa_glsl_error(&loc, state,
5616bf215546Sopenharmony_ci                                "%s shader output "
5617bf215546Sopenharmony_ci                                "cannot have an array of arrays",
5618bf215546Sopenharmony_ci                                _mesa_shader_stage_to_string(state->stage));
5619bf215546Sopenharmony_ci            }
5620bf215546Sopenharmony_ci            if (state->stage <= MESA_SHADER_GEOMETRY) {
5621bf215546Sopenharmony_ci               const glsl_type *type = var->type;
5622bf215546Sopenharmony_ci
5623bf215546Sopenharmony_ci               if (state->stage == MESA_SHADER_TESS_CTRL &&
5624bf215546Sopenharmony_ci                   !var->data.patch && var->type->is_array()) {
5625bf215546Sopenharmony_ci                  type = var->type->fields.array;
5626bf215546Sopenharmony_ci               }
5627bf215546Sopenharmony_ci
5628bf215546Sopenharmony_ci               if (type->is_array() && type->fields.array->is_struct()) {
5629bf215546Sopenharmony_ci                  _mesa_glsl_error(&loc, state,
5630bf215546Sopenharmony_ci                                   "%s shader output cannot have "
5631bf215546Sopenharmony_ci                                   "an array of structs",
5632bf215546Sopenharmony_ci                                   _mesa_shader_stage_to_string(state->stage));
5633bf215546Sopenharmony_ci               }
5634bf215546Sopenharmony_ci               if (type->is_struct()) {
5635bf215546Sopenharmony_ci                  for (unsigned i = 0; i < type->length; i++) {
5636bf215546Sopenharmony_ci                     if (type->fields.structure[i].type->is_array() ||
5637bf215546Sopenharmony_ci                         type->fields.structure[i].type->is_struct())
5638bf215546Sopenharmony_ci                        _mesa_glsl_error(&loc, state,
5639bf215546Sopenharmony_ci                                         "%s shader output cannot have a "
5640bf215546Sopenharmony_ci                                         "struct that contains an "
5641bf215546Sopenharmony_ci                                         "array or struct",
5642bf215546Sopenharmony_ci                                         _mesa_shader_stage_to_string(state->stage));
5643bf215546Sopenharmony_ci                  }
5644bf215546Sopenharmony_ci               }
5645bf215546Sopenharmony_ci            }
5646bf215546Sopenharmony_ci         }
5647bf215546Sopenharmony_ci
5648bf215546Sopenharmony_ci         if (state->stage == MESA_SHADER_TESS_CTRL) {
5649bf215546Sopenharmony_ci            handle_tess_ctrl_shader_output_decl(state, loc, var);
5650bf215546Sopenharmony_ci         }
5651bf215546Sopenharmony_ci      } else if (var->type->contains_subroutine()) {
5652bf215546Sopenharmony_ci         /* declare subroutine uniforms as hidden */
5653bf215546Sopenharmony_ci         var->data.how_declared = ir_var_hidden;
5654bf215546Sopenharmony_ci      }
5655bf215546Sopenharmony_ci
5656bf215546Sopenharmony_ci      /* From section 4.3.4 of the GLSL 4.00 spec:
5657bf215546Sopenharmony_ci       *    "Input variables may not be declared using the patch in qualifier
5658bf215546Sopenharmony_ci       *    in tessellation control or geometry shaders."
5659bf215546Sopenharmony_ci       *
5660bf215546Sopenharmony_ci       * From section 4.3.6 of the GLSL 4.00 spec:
5661bf215546Sopenharmony_ci       *    "It is an error to use patch out in a vertex, tessellation
5662bf215546Sopenharmony_ci       *    evaluation, or geometry shader."
5663bf215546Sopenharmony_ci       *
5664bf215546Sopenharmony_ci       * This doesn't explicitly forbid using them in a fragment shader, but
5665bf215546Sopenharmony_ci       * that's probably just an oversight.
5666bf215546Sopenharmony_ci       */
5667bf215546Sopenharmony_ci      if (state->stage != MESA_SHADER_TESS_EVAL
5668bf215546Sopenharmony_ci          && this->type->qualifier.flags.q.patch
5669bf215546Sopenharmony_ci          && this->type->qualifier.flags.q.in) {
5670bf215546Sopenharmony_ci
5671bf215546Sopenharmony_ci         _mesa_glsl_error(&loc, state, "'patch in' can only be used in a "
5672bf215546Sopenharmony_ci                          "tessellation evaluation shader");
5673bf215546Sopenharmony_ci      }
5674bf215546Sopenharmony_ci
5675bf215546Sopenharmony_ci      if (state->stage != MESA_SHADER_TESS_CTRL
5676bf215546Sopenharmony_ci          && this->type->qualifier.flags.q.patch
5677bf215546Sopenharmony_ci          && this->type->qualifier.flags.q.out) {
5678bf215546Sopenharmony_ci
5679bf215546Sopenharmony_ci         _mesa_glsl_error(&loc, state, "'patch out' can only be used in a "
5680bf215546Sopenharmony_ci                          "tessellation control shader");
5681bf215546Sopenharmony_ci      }
5682bf215546Sopenharmony_ci
5683bf215546Sopenharmony_ci      /* Precision qualifiers exists only in GLSL versions 1.00 and >= 1.30.
5684bf215546Sopenharmony_ci       */
5685bf215546Sopenharmony_ci      if (this->type->qualifier.precision != ast_precision_none) {
5686bf215546Sopenharmony_ci         state->check_precision_qualifiers_allowed(&loc);
5687bf215546Sopenharmony_ci      }
5688bf215546Sopenharmony_ci
5689bf215546Sopenharmony_ci      if (this->type->qualifier.precision != ast_precision_none &&
5690bf215546Sopenharmony_ci          !precision_qualifier_allowed(var->type)) {
5691bf215546Sopenharmony_ci         _mesa_glsl_error(&loc, state,
5692bf215546Sopenharmony_ci                          "precision qualifiers apply only to floating point"
5693bf215546Sopenharmony_ci                          ", integer and opaque types");
5694bf215546Sopenharmony_ci      }
5695bf215546Sopenharmony_ci
5696bf215546Sopenharmony_ci      /* From section 4.1.7 of the GLSL 4.40 spec:
5697bf215546Sopenharmony_ci       *
5698bf215546Sopenharmony_ci       *    "[Opaque types] can only be declared as function
5699bf215546Sopenharmony_ci       *     parameters or uniform-qualified variables."
5700bf215546Sopenharmony_ci       *
5701bf215546Sopenharmony_ci       * From section 4.1.7 of the ARB_bindless_texture spec:
5702bf215546Sopenharmony_ci       *
5703bf215546Sopenharmony_ci       *    "Samplers may be declared as shader inputs and outputs, as uniform
5704bf215546Sopenharmony_ci       *     variables, as temporary variables, and as function parameters."
5705bf215546Sopenharmony_ci       *
5706bf215546Sopenharmony_ci       * From section 4.1.X of the ARB_bindless_texture spec:
5707bf215546Sopenharmony_ci       *
5708bf215546Sopenharmony_ci       *    "Images may be declared as shader inputs and outputs, as uniform
5709bf215546Sopenharmony_ci       *     variables, as temporary variables, and as function parameters."
5710bf215546Sopenharmony_ci       */
5711bf215546Sopenharmony_ci      if (!this->type->qualifier.flags.q.uniform &&
5712bf215546Sopenharmony_ci          (var_type->contains_atomic() ||
5713bf215546Sopenharmony_ci           (!state->has_bindless() && var_type->contains_opaque()))) {
5714bf215546Sopenharmony_ci         _mesa_glsl_error(&loc, state,
5715bf215546Sopenharmony_ci                          "%s variables must be declared uniform",
5716bf215546Sopenharmony_ci                          state->has_bindless() ? "atomic" : "opaque");
5717bf215546Sopenharmony_ci      }
5718bf215546Sopenharmony_ci
5719bf215546Sopenharmony_ci      /* Process the initializer and add its instructions to a temporary
5720bf215546Sopenharmony_ci       * list.  This list will be added to the instruction stream (below) after
5721bf215546Sopenharmony_ci       * the declaration is added.  This is done because in some cases (such as
5722bf215546Sopenharmony_ci       * redeclarations) the declaration may not actually be added to the
5723bf215546Sopenharmony_ci       * instruction stream.
5724bf215546Sopenharmony_ci       */
5725bf215546Sopenharmony_ci      exec_list initializer_instructions;
5726bf215546Sopenharmony_ci
5727bf215546Sopenharmony_ci      /* Examine var name here since var may get deleted in the next call */
5728bf215546Sopenharmony_ci      bool var_is_gl_id = is_gl_identifier(var->name);
5729bf215546Sopenharmony_ci
5730bf215546Sopenharmony_ci      bool is_redeclaration;
5731bf215546Sopenharmony_ci      var = get_variable_being_redeclared(&var, decl->get_location(), state,
5732bf215546Sopenharmony_ci                                          false /* allow_all_redeclarations */,
5733bf215546Sopenharmony_ci                                          &is_redeclaration);
5734bf215546Sopenharmony_ci      if (is_redeclaration) {
5735bf215546Sopenharmony_ci         if (var_is_gl_id &&
5736bf215546Sopenharmony_ci             var->data.how_declared == ir_var_declared_in_block) {
5737bf215546Sopenharmony_ci            _mesa_glsl_error(&loc, state,
5738bf215546Sopenharmony_ci                             "`%s' has already been redeclared using "
5739bf215546Sopenharmony_ci                             "gl_PerVertex", var->name);
5740bf215546Sopenharmony_ci         }
5741bf215546Sopenharmony_ci         var->data.how_declared = ir_var_declared_normally;
5742bf215546Sopenharmony_ci      }
5743bf215546Sopenharmony_ci
5744bf215546Sopenharmony_ci      if (decl->initializer != NULL) {
5745bf215546Sopenharmony_ci         result = process_initializer(var,
5746bf215546Sopenharmony_ci                                      decl, this->type,
5747bf215546Sopenharmony_ci                                      &initializer_instructions, state);
5748bf215546Sopenharmony_ci      } else {
5749bf215546Sopenharmony_ci         validate_array_dimensions(var_type, state, &loc);
5750bf215546Sopenharmony_ci      }
5751bf215546Sopenharmony_ci
5752bf215546Sopenharmony_ci      /* From page 23 (page 29 of the PDF) of the GLSL 1.10 spec:
5753bf215546Sopenharmony_ci       *
5754bf215546Sopenharmony_ci       *     "It is an error to write to a const variable outside of
5755bf215546Sopenharmony_ci       *      its declaration, so they must be initialized when
5756bf215546Sopenharmony_ci       *      declared."
5757bf215546Sopenharmony_ci       */
5758bf215546Sopenharmony_ci      if (this->type->qualifier.flags.q.constant && decl->initializer == NULL) {
5759bf215546Sopenharmony_ci         _mesa_glsl_error(& loc, state,
5760bf215546Sopenharmony_ci                          "const declaration of `%s' must be initialized",
5761bf215546Sopenharmony_ci                          decl->identifier);
5762bf215546Sopenharmony_ci      }
5763bf215546Sopenharmony_ci
5764bf215546Sopenharmony_ci      if (state->es_shader) {
5765bf215546Sopenharmony_ci         const glsl_type *const t = var->type;
5766bf215546Sopenharmony_ci
5767bf215546Sopenharmony_ci         /* Skip the unsized array check for TCS/TES/GS inputs & TCS outputs.
5768bf215546Sopenharmony_ci          *
5769bf215546Sopenharmony_ci          * The GL_OES_tessellation_shader spec says about inputs:
5770bf215546Sopenharmony_ci          *
5771bf215546Sopenharmony_ci          *    "Declaring an array size is optional. If no size is specified,
5772bf215546Sopenharmony_ci          *     it will be taken from the implementation-dependent maximum
5773bf215546Sopenharmony_ci          *     patch size (gl_MaxPatchVertices)."
5774bf215546Sopenharmony_ci          *
5775bf215546Sopenharmony_ci          * and about TCS outputs:
5776bf215546Sopenharmony_ci          *
5777bf215546Sopenharmony_ci          *    "If no size is specified, it will be taken from output patch
5778bf215546Sopenharmony_ci          *     size declared in the shader."
5779bf215546Sopenharmony_ci          *
5780bf215546Sopenharmony_ci          * The GL_OES_geometry_shader spec says:
5781bf215546Sopenharmony_ci          *
5782bf215546Sopenharmony_ci          *    "All geometry shader input unsized array declarations will be
5783bf215546Sopenharmony_ci          *     sized by an earlier input primitive layout qualifier, when
5784bf215546Sopenharmony_ci          *     present, as per the following table."
5785bf215546Sopenharmony_ci          */
5786bf215546Sopenharmony_ci         const bool implicitly_sized =
5787bf215546Sopenharmony_ci            (var->data.mode == ir_var_shader_in &&
5788bf215546Sopenharmony_ci             state->stage >= MESA_SHADER_TESS_CTRL &&
5789bf215546Sopenharmony_ci             state->stage <= MESA_SHADER_GEOMETRY) ||
5790bf215546Sopenharmony_ci            (var->data.mode == ir_var_shader_out &&
5791bf215546Sopenharmony_ci             state->stage == MESA_SHADER_TESS_CTRL);
5792bf215546Sopenharmony_ci
5793bf215546Sopenharmony_ci         if (t->is_unsized_array() && !implicitly_sized)
5794bf215546Sopenharmony_ci            /* Section 10.17 of the GLSL ES 1.00 specification states that
5795bf215546Sopenharmony_ci             * unsized array declarations have been removed from the language.
5796bf215546Sopenharmony_ci             * Arrays that are sized using an initializer are still explicitly
5797bf215546Sopenharmony_ci             * sized.  However, GLSL ES 1.00 does not allow array
5798bf215546Sopenharmony_ci             * initializers.  That is only allowed in GLSL ES 3.00.
5799bf215546Sopenharmony_ci             *
5800bf215546Sopenharmony_ci             * Section 4.1.9 (Arrays) of the GLSL ES 3.00 spec says:
5801bf215546Sopenharmony_ci             *
5802bf215546Sopenharmony_ci             *     "An array type can also be formed without specifying a size
5803bf215546Sopenharmony_ci             *     if the definition includes an initializer:
5804bf215546Sopenharmony_ci             *
5805bf215546Sopenharmony_ci             *         float x[] = float[2] (1.0, 2.0);     // declares an array of size 2
5806bf215546Sopenharmony_ci             *         float y[] = float[] (1.0, 2.0, 3.0); // declares an array of size 3
5807bf215546Sopenharmony_ci             *
5808bf215546Sopenharmony_ci             *         float a[5];
5809bf215546Sopenharmony_ci             *         float b[] = a;"
5810bf215546Sopenharmony_ci             */
5811bf215546Sopenharmony_ci            _mesa_glsl_error(& loc, state,
5812bf215546Sopenharmony_ci                             "unsized array declarations are not allowed in "
5813bf215546Sopenharmony_ci                             "GLSL ES");
5814bf215546Sopenharmony_ci      }
5815bf215546Sopenharmony_ci
5816bf215546Sopenharmony_ci      /* Section 4.4.6.1 Atomic Counter Layout Qualifiers of the GLSL 4.60 spec:
5817bf215546Sopenharmony_ci       *
5818bf215546Sopenharmony_ci       *    "It is a compile-time error to declare an unsized array of
5819bf215546Sopenharmony_ci       *     atomic_uint"
5820bf215546Sopenharmony_ci       */
5821bf215546Sopenharmony_ci      if (var->type->is_unsized_array() &&
5822bf215546Sopenharmony_ci          var->type->without_array()->base_type == GLSL_TYPE_ATOMIC_UINT) {
5823bf215546Sopenharmony_ci         _mesa_glsl_error(& loc, state,
5824bf215546Sopenharmony_ci                          "Unsized array of atomic_uint is not allowed");
5825bf215546Sopenharmony_ci      }
5826bf215546Sopenharmony_ci
5827bf215546Sopenharmony_ci      /* If the declaration is not a redeclaration, there are a few additional
5828bf215546Sopenharmony_ci       * semantic checks that must be applied.  In addition, variable that was
5829bf215546Sopenharmony_ci       * created for the declaration should be added to the IR stream.
5830bf215546Sopenharmony_ci       */
5831bf215546Sopenharmony_ci      if (!is_redeclaration) {
5832bf215546Sopenharmony_ci         validate_identifier(decl->identifier, loc, state);
5833bf215546Sopenharmony_ci
5834bf215546Sopenharmony_ci         /* Add the variable to the symbol table.  Note that the initializer's
5835bf215546Sopenharmony_ci          * IR was already processed earlier (though it hasn't been emitted
5836bf215546Sopenharmony_ci          * yet), without the variable in scope.
5837bf215546Sopenharmony_ci          *
5838bf215546Sopenharmony_ci          * This differs from most C-like languages, but it follows the GLSL
5839bf215546Sopenharmony_ci          * specification.  From page 28 (page 34 of the PDF) of the GLSL 1.50
5840bf215546Sopenharmony_ci          * spec:
5841bf215546Sopenharmony_ci          *
5842bf215546Sopenharmony_ci          *     "Within a declaration, the scope of a name starts immediately
5843bf215546Sopenharmony_ci          *     after the initializer if present or immediately after the name
5844bf215546Sopenharmony_ci          *     being declared if not."
5845bf215546Sopenharmony_ci          */
5846bf215546Sopenharmony_ci         if (!state->symbols->add_variable(var)) {
5847bf215546Sopenharmony_ci            YYLTYPE loc = this->get_location();
5848bf215546Sopenharmony_ci            _mesa_glsl_error(&loc, state, "name `%s' already taken in the "
5849bf215546Sopenharmony_ci                             "current scope", decl->identifier);
5850bf215546Sopenharmony_ci            continue;
5851bf215546Sopenharmony_ci         }
5852bf215546Sopenharmony_ci
5853bf215546Sopenharmony_ci         /* Push the variable declaration to the top.  It means that all the
5854bf215546Sopenharmony_ci          * variable declarations will appear in a funny last-to-first order,
5855bf215546Sopenharmony_ci          * but otherwise we run into trouble if a function is prototyped, a
5856bf215546Sopenharmony_ci          * global var is decled, then the function is defined with usage of
5857bf215546Sopenharmony_ci          * the global var.  See glslparsertest's CorrectModule.frag.
5858bf215546Sopenharmony_ci          */
5859bf215546Sopenharmony_ci         instructions->push_head(var);
5860bf215546Sopenharmony_ci      }
5861bf215546Sopenharmony_ci
5862bf215546Sopenharmony_ci      instructions->append_list(&initializer_instructions);
5863bf215546Sopenharmony_ci   }
5864bf215546Sopenharmony_ci
5865bf215546Sopenharmony_ci
5866bf215546Sopenharmony_ci   /* Generally, variable declarations do not have r-values.  However,
5867bf215546Sopenharmony_ci    * one is used for the declaration in
5868bf215546Sopenharmony_ci    *
5869bf215546Sopenharmony_ci    * while (bool b = some_condition()) {
5870bf215546Sopenharmony_ci    *   ...
5871bf215546Sopenharmony_ci    * }
5872bf215546Sopenharmony_ci    *
5873bf215546Sopenharmony_ci    * so we return the rvalue from the last seen declaration here.
5874bf215546Sopenharmony_ci    */
5875bf215546Sopenharmony_ci   return result;
5876bf215546Sopenharmony_ci}
5877bf215546Sopenharmony_ci
5878bf215546Sopenharmony_ci
5879bf215546Sopenharmony_ciir_rvalue *
5880bf215546Sopenharmony_ciast_parameter_declarator::hir(exec_list *instructions,
5881bf215546Sopenharmony_ci                              struct _mesa_glsl_parse_state *state)
5882bf215546Sopenharmony_ci{
5883bf215546Sopenharmony_ci   void *ctx = state;
5884bf215546Sopenharmony_ci   const struct glsl_type *type;
5885bf215546Sopenharmony_ci   const char *name = NULL;
5886bf215546Sopenharmony_ci   YYLTYPE loc = this->get_location();
5887bf215546Sopenharmony_ci
5888bf215546Sopenharmony_ci   type = this->type->glsl_type(& name, state);
5889bf215546Sopenharmony_ci
5890bf215546Sopenharmony_ci   if (type == NULL) {
5891bf215546Sopenharmony_ci      if (name != NULL) {
5892bf215546Sopenharmony_ci         _mesa_glsl_error(& loc, state,
5893bf215546Sopenharmony_ci                          "invalid type `%s' in declaration of `%s'",
5894bf215546Sopenharmony_ci                          name, this->identifier);
5895bf215546Sopenharmony_ci      } else {
5896bf215546Sopenharmony_ci         _mesa_glsl_error(& loc, state,
5897bf215546Sopenharmony_ci                          "invalid type in declaration of `%s'",
5898bf215546Sopenharmony_ci                          this->identifier);
5899bf215546Sopenharmony_ci      }
5900bf215546Sopenharmony_ci
5901bf215546Sopenharmony_ci      type = glsl_type::error_type;
5902bf215546Sopenharmony_ci   }
5903bf215546Sopenharmony_ci
5904bf215546Sopenharmony_ci   /* From page 62 (page 68 of the PDF) of the GLSL 1.50 spec:
5905bf215546Sopenharmony_ci    *
5906bf215546Sopenharmony_ci    *    "Functions that accept no input arguments need not use void in the
5907bf215546Sopenharmony_ci    *    argument list because prototypes (or definitions) are required and
5908bf215546Sopenharmony_ci    *    therefore there is no ambiguity when an empty argument list "( )" is
5909bf215546Sopenharmony_ci    *    declared. The idiom "(void)" as a parameter list is provided for
5910bf215546Sopenharmony_ci    *    convenience."
5911bf215546Sopenharmony_ci    *
5912bf215546Sopenharmony_ci    * Placing this check here prevents a void parameter being set up
5913bf215546Sopenharmony_ci    * for a function, which avoids tripping up checks for main taking
5914bf215546Sopenharmony_ci    * parameters and lookups of an unnamed symbol.
5915bf215546Sopenharmony_ci    */
5916bf215546Sopenharmony_ci   if (type->is_void()) {
5917bf215546Sopenharmony_ci      if (this->identifier != NULL)
5918bf215546Sopenharmony_ci         _mesa_glsl_error(& loc, state,
5919bf215546Sopenharmony_ci                          "named parameter cannot have type `void'");
5920bf215546Sopenharmony_ci
5921bf215546Sopenharmony_ci      is_void = true;
5922bf215546Sopenharmony_ci      return NULL;
5923bf215546Sopenharmony_ci   }
5924bf215546Sopenharmony_ci
5925bf215546Sopenharmony_ci   if (formal_parameter && (this->identifier == NULL)) {
5926bf215546Sopenharmony_ci      _mesa_glsl_error(& loc, state, "formal parameter lacks a name");
5927bf215546Sopenharmony_ci      return NULL;
5928bf215546Sopenharmony_ci   }
5929bf215546Sopenharmony_ci
5930bf215546Sopenharmony_ci   /* This only handles "vec4 foo[..]".  The earlier specifier->glsl_type(...)
5931bf215546Sopenharmony_ci    * call already handled the "vec4[..] foo" case.
5932bf215546Sopenharmony_ci    */
5933bf215546Sopenharmony_ci   type = process_array_type(&loc, type, this->array_specifier, state);
5934bf215546Sopenharmony_ci
5935bf215546Sopenharmony_ci   if (!type->is_error() && type->is_unsized_array()) {
5936bf215546Sopenharmony_ci      _mesa_glsl_error(&loc, state, "arrays passed as parameters must have "
5937bf215546Sopenharmony_ci                       "a declared size");
5938bf215546Sopenharmony_ci      type = glsl_type::error_type;
5939bf215546Sopenharmony_ci   }
5940bf215546Sopenharmony_ci
5941bf215546Sopenharmony_ci   is_void = false;
5942bf215546Sopenharmony_ci   ir_variable *var = new(ctx)
5943bf215546Sopenharmony_ci      ir_variable(type, this->identifier, ir_var_function_in);
5944bf215546Sopenharmony_ci
5945bf215546Sopenharmony_ci   /* Apply any specified qualifiers to the parameter declaration.  Note that
5946bf215546Sopenharmony_ci    * for function parameters the default mode is 'in'.
5947bf215546Sopenharmony_ci    */
5948bf215546Sopenharmony_ci   apply_type_qualifier_to_variable(& this->type->qualifier, var, state, & loc,
5949bf215546Sopenharmony_ci                                    true);
5950bf215546Sopenharmony_ci
5951bf215546Sopenharmony_ci   if (((1u << var->data.mode) & state->zero_init) &&
5952bf215546Sopenharmony_ci       (var->type->is_numeric() || var->type->is_boolean())) {
5953bf215546Sopenharmony_ci         const ir_constant_data data = { { 0 } };
5954bf215546Sopenharmony_ci         var->data.has_initializer = true;
5955bf215546Sopenharmony_ci         var->data.is_implicit_initializer = true;
5956bf215546Sopenharmony_ci         var->constant_initializer = new(var) ir_constant(var->type, &data);
5957bf215546Sopenharmony_ci   }
5958bf215546Sopenharmony_ci
5959bf215546Sopenharmony_ci   /* From section 4.1.7 of the GLSL 4.40 spec:
5960bf215546Sopenharmony_ci    *
5961bf215546Sopenharmony_ci    *   "Opaque variables cannot be treated as l-values; hence cannot
5962bf215546Sopenharmony_ci    *    be used as out or inout function parameters, nor can they be
5963bf215546Sopenharmony_ci    *    assigned into."
5964bf215546Sopenharmony_ci    *
5965bf215546Sopenharmony_ci    * From section 4.1.7 of the ARB_bindless_texture spec:
5966bf215546Sopenharmony_ci    *
5967bf215546Sopenharmony_ci    *   "Samplers can be used as l-values, so can be assigned into and used
5968bf215546Sopenharmony_ci    *    as "out" and "inout" function parameters."
5969bf215546Sopenharmony_ci    *
5970bf215546Sopenharmony_ci    * From section 4.1.X of the ARB_bindless_texture spec:
5971bf215546Sopenharmony_ci    *
5972bf215546Sopenharmony_ci    *   "Images can be used as l-values, so can be assigned into and used as
5973bf215546Sopenharmony_ci    *    "out" and "inout" function parameters."
5974bf215546Sopenharmony_ci    */
5975bf215546Sopenharmony_ci   if ((var->data.mode == ir_var_function_inout || var->data.mode == ir_var_function_out)
5976bf215546Sopenharmony_ci       && (type->contains_atomic() ||
5977bf215546Sopenharmony_ci           (!state->has_bindless() && type->contains_opaque()))) {
5978bf215546Sopenharmony_ci      _mesa_glsl_error(&loc, state, "out and inout parameters cannot "
5979bf215546Sopenharmony_ci                       "contain %s variables",
5980bf215546Sopenharmony_ci                       state->has_bindless() ? "atomic" : "opaque");
5981bf215546Sopenharmony_ci      type = glsl_type::error_type;
5982bf215546Sopenharmony_ci   }
5983bf215546Sopenharmony_ci
5984bf215546Sopenharmony_ci   /* From page 39 (page 45 of the PDF) of the GLSL 1.10 spec:
5985bf215546Sopenharmony_ci    *
5986bf215546Sopenharmony_ci    *    "When calling a function, expressions that do not evaluate to
5987bf215546Sopenharmony_ci    *     l-values cannot be passed to parameters declared as out or inout."
5988bf215546Sopenharmony_ci    *
5989bf215546Sopenharmony_ci    * From page 32 (page 38 of the PDF) of the GLSL 1.10 spec:
5990bf215546Sopenharmony_ci    *
5991bf215546Sopenharmony_ci    *    "Other binary or unary expressions, non-dereferenced arrays,
5992bf215546Sopenharmony_ci    *     function names, swizzles with repeated fields, and constants
5993bf215546Sopenharmony_ci    *     cannot be l-values."
5994bf215546Sopenharmony_ci    *
5995bf215546Sopenharmony_ci    * So for GLSL 1.10, passing an array as an out or inout parameter is not
5996bf215546Sopenharmony_ci    * allowed.  This restriction is removed in GLSL 1.20, and in GLSL ES.
5997bf215546Sopenharmony_ci    */
5998bf215546Sopenharmony_ci   if ((var->data.mode == ir_var_function_inout || var->data.mode == ir_var_function_out)
5999bf215546Sopenharmony_ci       && type->is_array()
6000bf215546Sopenharmony_ci       && !state->check_version(120, 100, &loc,
6001bf215546Sopenharmony_ci                                "arrays cannot be out or inout parameters")) {
6002bf215546Sopenharmony_ci      type = glsl_type::error_type;
6003bf215546Sopenharmony_ci   }
6004bf215546Sopenharmony_ci
6005bf215546Sopenharmony_ci   instructions->push_tail(var);
6006bf215546Sopenharmony_ci
6007bf215546Sopenharmony_ci   /* Parameter declarations do not have r-values.
6008bf215546Sopenharmony_ci    */
6009bf215546Sopenharmony_ci   return NULL;
6010bf215546Sopenharmony_ci}
6011bf215546Sopenharmony_ci
6012bf215546Sopenharmony_ci
6013bf215546Sopenharmony_civoid
6014bf215546Sopenharmony_ciast_parameter_declarator::parameters_to_hir(exec_list *ast_parameters,
6015bf215546Sopenharmony_ci                                            bool formal,
6016bf215546Sopenharmony_ci                                            exec_list *ir_parameters,
6017bf215546Sopenharmony_ci                                            _mesa_glsl_parse_state *state)
6018bf215546Sopenharmony_ci{
6019bf215546Sopenharmony_ci   ast_parameter_declarator *void_param = NULL;
6020bf215546Sopenharmony_ci   unsigned count = 0;
6021bf215546Sopenharmony_ci
6022bf215546Sopenharmony_ci   foreach_list_typed (ast_parameter_declarator, param, link, ast_parameters) {
6023bf215546Sopenharmony_ci      param->formal_parameter = formal;
6024bf215546Sopenharmony_ci      param->hir(ir_parameters, state);
6025bf215546Sopenharmony_ci
6026bf215546Sopenharmony_ci      if (param->is_void)
6027bf215546Sopenharmony_ci         void_param = param;
6028bf215546Sopenharmony_ci
6029bf215546Sopenharmony_ci      count++;
6030bf215546Sopenharmony_ci   }
6031bf215546Sopenharmony_ci
6032bf215546Sopenharmony_ci   if ((void_param != NULL) && (count > 1)) {
6033bf215546Sopenharmony_ci      YYLTYPE loc = void_param->get_location();
6034bf215546Sopenharmony_ci
6035bf215546Sopenharmony_ci      _mesa_glsl_error(& loc, state,
6036bf215546Sopenharmony_ci                       "`void' parameter must be only parameter");
6037bf215546Sopenharmony_ci   }
6038bf215546Sopenharmony_ci}
6039bf215546Sopenharmony_ci
6040bf215546Sopenharmony_ci
6041bf215546Sopenharmony_civoid
6042bf215546Sopenharmony_ciemit_function(_mesa_glsl_parse_state *state, ir_function *f)
6043bf215546Sopenharmony_ci{
6044bf215546Sopenharmony_ci   /* IR invariants disallow function declarations or definitions
6045bf215546Sopenharmony_ci    * nested within other function definitions.  But there is no
6046bf215546Sopenharmony_ci    * requirement about the relative order of function declarations
6047bf215546Sopenharmony_ci    * and definitions with respect to one another.  So simply insert
6048bf215546Sopenharmony_ci    * the new ir_function block at the end of the toplevel instruction
6049bf215546Sopenharmony_ci    * list.
6050bf215546Sopenharmony_ci    */
6051bf215546Sopenharmony_ci   state->toplevel_ir->push_tail(f);
6052bf215546Sopenharmony_ci}
6053bf215546Sopenharmony_ci
6054bf215546Sopenharmony_ci
6055bf215546Sopenharmony_ciir_rvalue *
6056bf215546Sopenharmony_ciast_function::hir(exec_list *instructions,
6057bf215546Sopenharmony_ci                  struct _mesa_glsl_parse_state *state)
6058bf215546Sopenharmony_ci{
6059bf215546Sopenharmony_ci   void *ctx = state;
6060bf215546Sopenharmony_ci   ir_function *f = NULL;
6061bf215546Sopenharmony_ci   ir_function_signature *sig = NULL;
6062bf215546Sopenharmony_ci   exec_list hir_parameters;
6063bf215546Sopenharmony_ci   YYLTYPE loc = this->get_location();
6064bf215546Sopenharmony_ci
6065bf215546Sopenharmony_ci   const char *const name = identifier;
6066bf215546Sopenharmony_ci
6067bf215546Sopenharmony_ci   /* New functions are always added to the top-level IR instruction stream,
6068bf215546Sopenharmony_ci    * so this instruction list pointer is ignored.  See also emit_function
6069bf215546Sopenharmony_ci    * (called below).
6070bf215546Sopenharmony_ci    */
6071bf215546Sopenharmony_ci   (void) instructions;
6072bf215546Sopenharmony_ci
6073bf215546Sopenharmony_ci   /* From page 21 (page 27 of the PDF) of the GLSL 1.20 spec,
6074bf215546Sopenharmony_ci    *
6075bf215546Sopenharmony_ci    *   "Function declarations (prototypes) cannot occur inside of functions;
6076bf215546Sopenharmony_ci    *   they must be at global scope, or for the built-in functions, outside
6077bf215546Sopenharmony_ci    *   the global scope."
6078bf215546Sopenharmony_ci    *
6079bf215546Sopenharmony_ci    * From page 27 (page 33 of the PDF) of the GLSL ES 1.00.16 spec,
6080bf215546Sopenharmony_ci    *
6081bf215546Sopenharmony_ci    *   "User defined functions may only be defined within the global scope."
6082bf215546Sopenharmony_ci    *
6083bf215546Sopenharmony_ci    * Note that this language does not appear in GLSL 1.10.
6084bf215546Sopenharmony_ci    */
6085bf215546Sopenharmony_ci   if ((state->current_function != NULL) &&
6086bf215546Sopenharmony_ci       state->is_version(120, 100)) {
6087bf215546Sopenharmony_ci      YYLTYPE loc = this->get_location();
6088bf215546Sopenharmony_ci      _mesa_glsl_error(&loc, state,
6089bf215546Sopenharmony_ci                       "declaration of function `%s' not allowed within "
6090bf215546Sopenharmony_ci                       "function body", name);
6091bf215546Sopenharmony_ci   }
6092bf215546Sopenharmony_ci
6093bf215546Sopenharmony_ci   validate_identifier(name, this->get_location(), state);
6094bf215546Sopenharmony_ci
6095bf215546Sopenharmony_ci   /* Convert the list of function parameters to HIR now so that they can be
6096bf215546Sopenharmony_ci    * used below to compare this function's signature with previously seen
6097bf215546Sopenharmony_ci    * signatures for functions with the same name.
6098bf215546Sopenharmony_ci    */
6099bf215546Sopenharmony_ci   ast_parameter_declarator::parameters_to_hir(& this->parameters,
6100bf215546Sopenharmony_ci                                               is_definition,
6101bf215546Sopenharmony_ci                                               & hir_parameters, state);
6102bf215546Sopenharmony_ci
6103bf215546Sopenharmony_ci   const char *return_type_name;
6104bf215546Sopenharmony_ci   const glsl_type *return_type =
6105bf215546Sopenharmony_ci      this->return_type->glsl_type(& return_type_name, state);
6106bf215546Sopenharmony_ci
6107bf215546Sopenharmony_ci   if (!return_type) {
6108bf215546Sopenharmony_ci      YYLTYPE loc = this->get_location();
6109bf215546Sopenharmony_ci      _mesa_glsl_error(&loc, state,
6110bf215546Sopenharmony_ci                       "function `%s' has undeclared return type `%s'",
6111bf215546Sopenharmony_ci                       name, return_type_name);
6112bf215546Sopenharmony_ci      return_type = glsl_type::error_type;
6113bf215546Sopenharmony_ci   }
6114bf215546Sopenharmony_ci
6115bf215546Sopenharmony_ci   /* ARB_shader_subroutine states:
6116bf215546Sopenharmony_ci    *  "Subroutine declarations cannot be prototyped. It is an error to prepend
6117bf215546Sopenharmony_ci    *   subroutine(...) to a function declaration."
6118bf215546Sopenharmony_ci    */
6119bf215546Sopenharmony_ci   if (this->return_type->qualifier.subroutine_list && !is_definition) {
6120bf215546Sopenharmony_ci      YYLTYPE loc = this->get_location();
6121bf215546Sopenharmony_ci      _mesa_glsl_error(&loc, state,
6122bf215546Sopenharmony_ci                       "function declaration `%s' cannot have subroutine prepended",
6123bf215546Sopenharmony_ci                       name);
6124bf215546Sopenharmony_ci   }
6125bf215546Sopenharmony_ci
6126bf215546Sopenharmony_ci   /* From page 56 (page 62 of the PDF) of the GLSL 1.30 spec:
6127bf215546Sopenharmony_ci    * "No qualifier is allowed on the return type of a function."
6128bf215546Sopenharmony_ci    */
6129bf215546Sopenharmony_ci   if (this->return_type->has_qualifiers(state)) {
6130bf215546Sopenharmony_ci      YYLTYPE loc = this->get_location();
6131bf215546Sopenharmony_ci      _mesa_glsl_error(& loc, state,
6132bf215546Sopenharmony_ci                       "function `%s' return type has qualifiers", name);
6133bf215546Sopenharmony_ci   }
6134bf215546Sopenharmony_ci
6135bf215546Sopenharmony_ci   /* Section 6.1 (Function Definitions) of the GLSL 1.20 spec says:
6136bf215546Sopenharmony_ci    *
6137bf215546Sopenharmony_ci    *     "Arrays are allowed as arguments and as the return type. In both
6138bf215546Sopenharmony_ci    *     cases, the array must be explicitly sized."
6139bf215546Sopenharmony_ci    */
6140bf215546Sopenharmony_ci   if (return_type->is_unsized_array()) {
6141bf215546Sopenharmony_ci      YYLTYPE loc = this->get_location();
6142bf215546Sopenharmony_ci      _mesa_glsl_error(& loc, state,
6143bf215546Sopenharmony_ci                       "function `%s' return type array must be explicitly "
6144bf215546Sopenharmony_ci                       "sized", name);
6145bf215546Sopenharmony_ci   }
6146bf215546Sopenharmony_ci
6147bf215546Sopenharmony_ci   /* From Section 6.1 (Function Definitions) of the GLSL 1.00 spec:
6148bf215546Sopenharmony_ci    *
6149bf215546Sopenharmony_ci    *     "Arrays are allowed as arguments, but not as the return type. [...]
6150bf215546Sopenharmony_ci    *      The return type can also be a structure if the structure does not
6151bf215546Sopenharmony_ci    *      contain an array."
6152bf215546Sopenharmony_ci    */
6153bf215546Sopenharmony_ci   if (state->language_version == 100 && return_type->contains_array()) {
6154bf215546Sopenharmony_ci      YYLTYPE loc = this->get_location();
6155bf215546Sopenharmony_ci      _mesa_glsl_error(& loc, state,
6156bf215546Sopenharmony_ci                       "function `%s' return type contains an array", name);
6157bf215546Sopenharmony_ci   }
6158bf215546Sopenharmony_ci
6159bf215546Sopenharmony_ci   /* From section 4.1.7 of the GLSL 4.40 spec:
6160bf215546Sopenharmony_ci    *
6161bf215546Sopenharmony_ci    *    "[Opaque types] can only be declared as function parameters
6162bf215546Sopenharmony_ci    *     or uniform-qualified variables."
6163bf215546Sopenharmony_ci    *
6164bf215546Sopenharmony_ci    * The ARB_bindless_texture spec doesn't clearly state this, but as it says
6165bf215546Sopenharmony_ci    * "Replace Section 4.1.7 (Samplers), p. 25" and, "Replace Section 4.1.X,
6166bf215546Sopenharmony_ci    * (Images)", this should be allowed.
6167bf215546Sopenharmony_ci    */
6168bf215546Sopenharmony_ci   if (return_type->contains_atomic() ||
6169bf215546Sopenharmony_ci       (!state->has_bindless() && return_type->contains_opaque())) {
6170bf215546Sopenharmony_ci      YYLTYPE loc = this->get_location();
6171bf215546Sopenharmony_ci      _mesa_glsl_error(&loc, state,
6172bf215546Sopenharmony_ci                       "function `%s' return type can't contain an %s type",
6173bf215546Sopenharmony_ci                       name, state->has_bindless() ? "atomic" : "opaque");
6174bf215546Sopenharmony_ci   }
6175bf215546Sopenharmony_ci
6176bf215546Sopenharmony_ci   /**/
6177bf215546Sopenharmony_ci   if (return_type->is_subroutine()) {
6178bf215546Sopenharmony_ci      YYLTYPE loc = this->get_location();
6179bf215546Sopenharmony_ci      _mesa_glsl_error(&loc, state,
6180bf215546Sopenharmony_ci                       "function `%s' return type can't be a subroutine type",
6181bf215546Sopenharmony_ci                       name);
6182bf215546Sopenharmony_ci   }
6183bf215546Sopenharmony_ci
6184bf215546Sopenharmony_ci   /* Get the precision for the return type */
6185bf215546Sopenharmony_ci   unsigned return_precision;
6186bf215546Sopenharmony_ci
6187bf215546Sopenharmony_ci   if (state->es_shader) {
6188bf215546Sopenharmony_ci      YYLTYPE loc = this->get_location();
6189bf215546Sopenharmony_ci      return_precision =
6190bf215546Sopenharmony_ci         select_gles_precision(this->return_type->qualifier.precision,
6191bf215546Sopenharmony_ci                               return_type,
6192bf215546Sopenharmony_ci                               state,
6193bf215546Sopenharmony_ci                               &loc);
6194bf215546Sopenharmony_ci   } else {
6195bf215546Sopenharmony_ci      return_precision = GLSL_PRECISION_NONE;
6196bf215546Sopenharmony_ci   }
6197bf215546Sopenharmony_ci
6198bf215546Sopenharmony_ci   /* Create an ir_function if one doesn't already exist. */
6199bf215546Sopenharmony_ci   f = state->symbols->get_function(name);
6200bf215546Sopenharmony_ci   if (f == NULL) {
6201bf215546Sopenharmony_ci      f = new(ctx) ir_function(name);
6202bf215546Sopenharmony_ci      if (!this->return_type->qualifier.is_subroutine_decl()) {
6203bf215546Sopenharmony_ci         if (!state->symbols->add_function(f)) {
6204bf215546Sopenharmony_ci            /* This function name shadows a non-function use of the same name. */
6205bf215546Sopenharmony_ci            YYLTYPE loc = this->get_location();
6206bf215546Sopenharmony_ci            _mesa_glsl_error(&loc, state, "function name `%s' conflicts with "
6207bf215546Sopenharmony_ci                             "non-function", name);
6208bf215546Sopenharmony_ci            return NULL;
6209bf215546Sopenharmony_ci         }
6210bf215546Sopenharmony_ci      }
6211bf215546Sopenharmony_ci      emit_function(state, f);
6212bf215546Sopenharmony_ci   }
6213bf215546Sopenharmony_ci
6214bf215546Sopenharmony_ci   /* From GLSL ES 3.0 spec, chapter 6.1 "Function Definitions", page 71:
6215bf215546Sopenharmony_ci    *
6216bf215546Sopenharmony_ci    * "A shader cannot redefine or overload built-in functions."
6217bf215546Sopenharmony_ci    *
6218bf215546Sopenharmony_ci    * While in GLSL ES 1.0 specification, chapter 8 "Built-in Functions":
6219bf215546Sopenharmony_ci    *
6220bf215546Sopenharmony_ci    * "User code can overload the built-in functions but cannot redefine
6221bf215546Sopenharmony_ci    * them."
6222bf215546Sopenharmony_ci    */
6223bf215546Sopenharmony_ci   if (state->es_shader) {
6224bf215546Sopenharmony_ci      /* Local shader has no exact candidates; check the built-ins. */
6225bf215546Sopenharmony_ci      if (state->language_version >= 300 &&
6226bf215546Sopenharmony_ci          _mesa_glsl_has_builtin_function(state, name)) {
6227bf215546Sopenharmony_ci         YYLTYPE loc = this->get_location();
6228bf215546Sopenharmony_ci         _mesa_glsl_error(& loc, state,
6229bf215546Sopenharmony_ci                          "A shader cannot redefine or overload built-in "
6230bf215546Sopenharmony_ci                          "function `%s' in GLSL ES 3.00", name);
6231bf215546Sopenharmony_ci         return NULL;
6232bf215546Sopenharmony_ci      }
6233bf215546Sopenharmony_ci
6234bf215546Sopenharmony_ci      if (state->language_version == 100) {
6235bf215546Sopenharmony_ci         ir_function_signature *sig =
6236bf215546Sopenharmony_ci            _mesa_glsl_find_builtin_function(state, name, &hir_parameters);
6237bf215546Sopenharmony_ci         if (sig && sig->is_builtin()) {
6238bf215546Sopenharmony_ci            _mesa_glsl_error(& loc, state,
6239bf215546Sopenharmony_ci                             "A shader cannot redefine built-in "
6240bf215546Sopenharmony_ci                             "function `%s' in GLSL ES 1.00", name);
6241bf215546Sopenharmony_ci         }
6242bf215546Sopenharmony_ci      }
6243bf215546Sopenharmony_ci   }
6244bf215546Sopenharmony_ci
6245bf215546Sopenharmony_ci   /* Verify that this function's signature either doesn't match a previously
6246bf215546Sopenharmony_ci    * seen signature for a function with the same name, or, if a match is found,
6247bf215546Sopenharmony_ci    * that the previously seen signature does not have an associated definition.
6248bf215546Sopenharmony_ci    */
6249bf215546Sopenharmony_ci   if (state->es_shader || f->has_user_signature()) {
6250bf215546Sopenharmony_ci      sig = f->exact_matching_signature(state, &hir_parameters);
6251bf215546Sopenharmony_ci      if (sig != NULL) {
6252bf215546Sopenharmony_ci         const char *badvar = sig->qualifiers_match(&hir_parameters);
6253bf215546Sopenharmony_ci         if (badvar != NULL) {
6254bf215546Sopenharmony_ci            YYLTYPE loc = this->get_location();
6255bf215546Sopenharmony_ci
6256bf215546Sopenharmony_ci            _mesa_glsl_error(&loc, state, "function `%s' parameter `%s' "
6257bf215546Sopenharmony_ci                             "qualifiers don't match prototype", name, badvar);
6258bf215546Sopenharmony_ci         }
6259bf215546Sopenharmony_ci
6260bf215546Sopenharmony_ci         if (sig->return_type != return_type) {
6261bf215546Sopenharmony_ci            YYLTYPE loc = this->get_location();
6262bf215546Sopenharmony_ci
6263bf215546Sopenharmony_ci            _mesa_glsl_error(&loc, state, "function `%s' return type doesn't "
6264bf215546Sopenharmony_ci                             "match prototype", name);
6265bf215546Sopenharmony_ci         }
6266bf215546Sopenharmony_ci
6267bf215546Sopenharmony_ci         if (sig->return_precision != return_precision) {
6268bf215546Sopenharmony_ci            YYLTYPE loc = this->get_location();
6269bf215546Sopenharmony_ci
6270bf215546Sopenharmony_ci            _mesa_glsl_error(&loc, state, "function `%s' return type precision "
6271bf215546Sopenharmony_ci                             "doesn't match prototype", name);
6272bf215546Sopenharmony_ci         }
6273bf215546Sopenharmony_ci
6274bf215546Sopenharmony_ci         if (sig->is_defined) {
6275bf215546Sopenharmony_ci            if (is_definition) {
6276bf215546Sopenharmony_ci               YYLTYPE loc = this->get_location();
6277bf215546Sopenharmony_ci               _mesa_glsl_error(& loc, state, "function `%s' redefined", name);
6278bf215546Sopenharmony_ci            } else {
6279bf215546Sopenharmony_ci               /* We just encountered a prototype that exactly matches a
6280bf215546Sopenharmony_ci                * function that's already been defined.  This is redundant,
6281bf215546Sopenharmony_ci                * and we should ignore it.
6282bf215546Sopenharmony_ci                */
6283bf215546Sopenharmony_ci               return NULL;
6284bf215546Sopenharmony_ci            }
6285bf215546Sopenharmony_ci         } else if (state->language_version == 100 && !is_definition) {
6286bf215546Sopenharmony_ci            /* From the GLSL 1.00 spec, section 4.2.7:
6287bf215546Sopenharmony_ci             *
6288bf215546Sopenharmony_ci             *     "A particular variable, structure or function declaration
6289bf215546Sopenharmony_ci             *      may occur at most once within a scope with the exception
6290bf215546Sopenharmony_ci             *      that a single function prototype plus the corresponding
6291bf215546Sopenharmony_ci             *      function definition are allowed."
6292bf215546Sopenharmony_ci             */
6293bf215546Sopenharmony_ci            YYLTYPE loc = this->get_location();
6294bf215546Sopenharmony_ci            _mesa_glsl_error(&loc, state, "function `%s' redeclared", name);
6295bf215546Sopenharmony_ci         }
6296bf215546Sopenharmony_ci      }
6297bf215546Sopenharmony_ci   }
6298bf215546Sopenharmony_ci
6299bf215546Sopenharmony_ci   /* Verify the return type of main() */
6300bf215546Sopenharmony_ci   if (strcmp(name, "main") == 0) {
6301bf215546Sopenharmony_ci      if (! return_type->is_void()) {
6302bf215546Sopenharmony_ci         YYLTYPE loc = this->get_location();
6303bf215546Sopenharmony_ci
6304bf215546Sopenharmony_ci         _mesa_glsl_error(& loc, state, "main() must return void");
6305bf215546Sopenharmony_ci      }
6306bf215546Sopenharmony_ci
6307bf215546Sopenharmony_ci      if (!hir_parameters.is_empty()) {
6308bf215546Sopenharmony_ci         YYLTYPE loc = this->get_location();
6309bf215546Sopenharmony_ci
6310bf215546Sopenharmony_ci         _mesa_glsl_error(& loc, state, "main() must not take any parameters");
6311bf215546Sopenharmony_ci      }
6312bf215546Sopenharmony_ci   }
6313bf215546Sopenharmony_ci
6314bf215546Sopenharmony_ci   /* Finish storing the information about this new function in its signature.
6315bf215546Sopenharmony_ci    */
6316bf215546Sopenharmony_ci   if (sig == NULL) {
6317bf215546Sopenharmony_ci      sig = new(ctx) ir_function_signature(return_type);
6318bf215546Sopenharmony_ci      sig->return_precision = return_precision;
6319bf215546Sopenharmony_ci      f->add_signature(sig);
6320bf215546Sopenharmony_ci   }
6321bf215546Sopenharmony_ci
6322bf215546Sopenharmony_ci   sig->replace_parameters(&hir_parameters);
6323bf215546Sopenharmony_ci   signature = sig;
6324bf215546Sopenharmony_ci
6325bf215546Sopenharmony_ci   if (this->return_type->qualifier.subroutine_list) {
6326bf215546Sopenharmony_ci      int idx;
6327bf215546Sopenharmony_ci
6328bf215546Sopenharmony_ci      if (this->return_type->qualifier.flags.q.explicit_index) {
6329bf215546Sopenharmony_ci         unsigned qual_index;
6330bf215546Sopenharmony_ci         if (process_qualifier_constant(state, &loc, "index",
6331bf215546Sopenharmony_ci                                        this->return_type->qualifier.index,
6332bf215546Sopenharmony_ci                                        &qual_index)) {
6333bf215546Sopenharmony_ci            if (!state->has_explicit_uniform_location()) {
6334bf215546Sopenharmony_ci               _mesa_glsl_error(&loc, state, "subroutine index requires "
6335bf215546Sopenharmony_ci                                "GL_ARB_explicit_uniform_location or "
6336bf215546Sopenharmony_ci                                "GLSL 4.30");
6337bf215546Sopenharmony_ci            } else if (qual_index >= MAX_SUBROUTINES) {
6338bf215546Sopenharmony_ci               _mesa_glsl_error(&loc, state,
6339bf215546Sopenharmony_ci                                "invalid subroutine index (%d) index must "
6340bf215546Sopenharmony_ci                                "be a number between 0 and "
6341bf215546Sopenharmony_ci                                "GL_MAX_SUBROUTINES - 1 (%d)", qual_index,
6342bf215546Sopenharmony_ci                                MAX_SUBROUTINES - 1);
6343bf215546Sopenharmony_ci            } else {
6344bf215546Sopenharmony_ci               f->subroutine_index = qual_index;
6345bf215546Sopenharmony_ci            }
6346bf215546Sopenharmony_ci         }
6347bf215546Sopenharmony_ci      }
6348bf215546Sopenharmony_ci
6349bf215546Sopenharmony_ci      f->num_subroutine_types = this->return_type->qualifier.subroutine_list->declarations.length();
6350bf215546Sopenharmony_ci      f->subroutine_types = ralloc_array(state, const struct glsl_type *,
6351bf215546Sopenharmony_ci                                         f->num_subroutine_types);
6352bf215546Sopenharmony_ci      idx = 0;
6353bf215546Sopenharmony_ci      foreach_list_typed(ast_declaration, decl, link, &this->return_type->qualifier.subroutine_list->declarations) {
6354bf215546Sopenharmony_ci         const struct glsl_type *type;
6355bf215546Sopenharmony_ci         /* the subroutine type must be already declared */
6356bf215546Sopenharmony_ci         type = state->symbols->get_type(decl->identifier);
6357bf215546Sopenharmony_ci         if (!type) {
6358bf215546Sopenharmony_ci            _mesa_glsl_error(& loc, state, "unknown type '%s' in subroutine function definition", decl->identifier);
6359bf215546Sopenharmony_ci         }
6360bf215546Sopenharmony_ci
6361bf215546Sopenharmony_ci         for (int i = 0; i < state->num_subroutine_types; i++) {
6362bf215546Sopenharmony_ci            ir_function *fn = state->subroutine_types[i];
6363bf215546Sopenharmony_ci            ir_function_signature *tsig = NULL;
6364bf215546Sopenharmony_ci
6365bf215546Sopenharmony_ci            if (strcmp(fn->name, decl->identifier))
6366bf215546Sopenharmony_ci               continue;
6367bf215546Sopenharmony_ci
6368bf215546Sopenharmony_ci            tsig = fn->matching_signature(state, &sig->parameters,
6369bf215546Sopenharmony_ci                                          false);
6370bf215546Sopenharmony_ci            if (!tsig) {
6371bf215546Sopenharmony_ci               _mesa_glsl_error(& loc, state, "subroutine type mismatch '%s' - signatures do not match\n", decl->identifier);
6372bf215546Sopenharmony_ci            } else {
6373bf215546Sopenharmony_ci               if (tsig->return_type != sig->return_type) {
6374bf215546Sopenharmony_ci                  _mesa_glsl_error(& loc, state, "subroutine type mismatch '%s' - return types do not match\n", decl->identifier);
6375bf215546Sopenharmony_ci               }
6376bf215546Sopenharmony_ci            }
6377bf215546Sopenharmony_ci         }
6378bf215546Sopenharmony_ci         f->subroutine_types[idx++] = type;
6379bf215546Sopenharmony_ci      }
6380bf215546Sopenharmony_ci      state->subroutines = (ir_function **)reralloc(state, state->subroutines,
6381bf215546Sopenharmony_ci                                                    ir_function *,
6382bf215546Sopenharmony_ci                                                    state->num_subroutines + 1);
6383bf215546Sopenharmony_ci      state->subroutines[state->num_subroutines] = f;
6384bf215546Sopenharmony_ci      state->num_subroutines++;
6385bf215546Sopenharmony_ci
6386bf215546Sopenharmony_ci   }
6387bf215546Sopenharmony_ci
6388bf215546Sopenharmony_ci   if (this->return_type->qualifier.is_subroutine_decl()) {
6389bf215546Sopenharmony_ci      if (!state->symbols->add_type(this->identifier, glsl_type::get_subroutine_instance(this->identifier))) {
6390bf215546Sopenharmony_ci         _mesa_glsl_error(& loc, state, "type '%s' previously defined", this->identifier);
6391bf215546Sopenharmony_ci         return NULL;
6392bf215546Sopenharmony_ci      }
6393bf215546Sopenharmony_ci      state->subroutine_types = (ir_function **)reralloc(state, state->subroutine_types,
6394bf215546Sopenharmony_ci                                                         ir_function *,
6395bf215546Sopenharmony_ci                                                         state->num_subroutine_types + 1);
6396bf215546Sopenharmony_ci      state->subroutine_types[state->num_subroutine_types] = f;
6397bf215546Sopenharmony_ci      state->num_subroutine_types++;
6398bf215546Sopenharmony_ci
6399bf215546Sopenharmony_ci      f->is_subroutine = true;
6400bf215546Sopenharmony_ci   }
6401bf215546Sopenharmony_ci
6402bf215546Sopenharmony_ci   /* Function declarations (prototypes) do not have r-values.
6403bf215546Sopenharmony_ci    */
6404bf215546Sopenharmony_ci   return NULL;
6405bf215546Sopenharmony_ci}
6406bf215546Sopenharmony_ci
6407bf215546Sopenharmony_ci
6408bf215546Sopenharmony_ciir_rvalue *
6409bf215546Sopenharmony_ciast_function_definition::hir(exec_list *instructions,
6410bf215546Sopenharmony_ci                             struct _mesa_glsl_parse_state *state)
6411bf215546Sopenharmony_ci{
6412bf215546Sopenharmony_ci   prototype->is_definition = true;
6413bf215546Sopenharmony_ci   prototype->hir(instructions, state);
6414bf215546Sopenharmony_ci
6415bf215546Sopenharmony_ci   ir_function_signature *signature = prototype->signature;
6416bf215546Sopenharmony_ci   if (signature == NULL)
6417bf215546Sopenharmony_ci      return NULL;
6418bf215546Sopenharmony_ci
6419bf215546Sopenharmony_ci   assert(state->current_function == NULL);
6420bf215546Sopenharmony_ci   state->current_function = signature;
6421bf215546Sopenharmony_ci   state->found_return = false;
6422bf215546Sopenharmony_ci   state->found_begin_interlock = false;
6423bf215546Sopenharmony_ci   state->found_end_interlock = false;
6424bf215546Sopenharmony_ci
6425bf215546Sopenharmony_ci   /* Duplicate parameters declared in the prototype as concrete variables.
6426bf215546Sopenharmony_ci    * Add these to the symbol table.
6427bf215546Sopenharmony_ci    */
6428bf215546Sopenharmony_ci   state->symbols->push_scope();
6429bf215546Sopenharmony_ci   foreach_in_list(ir_variable, var, &signature->parameters) {
6430bf215546Sopenharmony_ci      assert(var->as_variable() != NULL);
6431bf215546Sopenharmony_ci
6432bf215546Sopenharmony_ci      /* The only way a parameter would "exist" is if two parameters have
6433bf215546Sopenharmony_ci       * the same name.
6434bf215546Sopenharmony_ci       */
6435bf215546Sopenharmony_ci      if (state->symbols->name_declared_this_scope(var->name)) {
6436bf215546Sopenharmony_ci         YYLTYPE loc = this->get_location();
6437bf215546Sopenharmony_ci
6438bf215546Sopenharmony_ci         _mesa_glsl_error(& loc, state, "parameter `%s' redeclared", var->name);
6439bf215546Sopenharmony_ci      } else {
6440bf215546Sopenharmony_ci         state->symbols->add_variable(var);
6441bf215546Sopenharmony_ci      }
6442bf215546Sopenharmony_ci   }
6443bf215546Sopenharmony_ci
6444bf215546Sopenharmony_ci   /* Convert the body of the function to HIR. */
6445bf215546Sopenharmony_ci   this->body->hir(&signature->body, state);
6446bf215546Sopenharmony_ci   signature->is_defined = true;
6447bf215546Sopenharmony_ci
6448bf215546Sopenharmony_ci   state->symbols->pop_scope();
6449bf215546Sopenharmony_ci
6450bf215546Sopenharmony_ci   assert(state->current_function == signature);
6451bf215546Sopenharmony_ci   state->current_function = NULL;
6452bf215546Sopenharmony_ci
6453bf215546Sopenharmony_ci   if (!signature->return_type->is_void() && !state->found_return) {
6454bf215546Sopenharmony_ci      YYLTYPE loc = this->get_location();
6455bf215546Sopenharmony_ci      _mesa_glsl_error(& loc, state, "function `%s' has non-void return type "
6456bf215546Sopenharmony_ci                       "%s, but no return statement",
6457bf215546Sopenharmony_ci                       signature->function_name(),
6458bf215546Sopenharmony_ci                       signature->return_type->name);
6459bf215546Sopenharmony_ci   }
6460bf215546Sopenharmony_ci
6461bf215546Sopenharmony_ci   /* Function definitions do not have r-values.
6462bf215546Sopenharmony_ci    */
6463bf215546Sopenharmony_ci   return NULL;
6464bf215546Sopenharmony_ci}
6465bf215546Sopenharmony_ci
6466bf215546Sopenharmony_ci
6467bf215546Sopenharmony_ciir_rvalue *
6468bf215546Sopenharmony_ciast_jump_statement::hir(exec_list *instructions,
6469bf215546Sopenharmony_ci                        struct _mesa_glsl_parse_state *state)
6470bf215546Sopenharmony_ci{
6471bf215546Sopenharmony_ci   void *ctx = state;
6472bf215546Sopenharmony_ci
6473bf215546Sopenharmony_ci   switch (mode) {
6474bf215546Sopenharmony_ci   case ast_return: {
6475bf215546Sopenharmony_ci      ir_return *inst;
6476bf215546Sopenharmony_ci      assert(state->current_function);
6477bf215546Sopenharmony_ci
6478bf215546Sopenharmony_ci      if (opt_return_value) {
6479bf215546Sopenharmony_ci         ir_rvalue *ret = opt_return_value->hir(instructions, state);
6480bf215546Sopenharmony_ci
6481bf215546Sopenharmony_ci         /* The value of the return type can be NULL if the shader says
6482bf215546Sopenharmony_ci          * 'return foo();' and foo() is a function that returns void.
6483bf215546Sopenharmony_ci          *
6484bf215546Sopenharmony_ci          * NOTE: The GLSL spec doesn't say that this is an error.  The type
6485bf215546Sopenharmony_ci          * of the return value is void.  If the return type of the function is
6486bf215546Sopenharmony_ci          * also void, then this should compile without error.  Seriously.
6487bf215546Sopenharmony_ci          */
6488bf215546Sopenharmony_ci         const glsl_type *const ret_type =
6489bf215546Sopenharmony_ci            (ret == NULL) ? glsl_type::void_type : ret->type;
6490bf215546Sopenharmony_ci
6491bf215546Sopenharmony_ci         /* Implicit conversions are not allowed for return values prior to
6492bf215546Sopenharmony_ci          * ARB_shading_language_420pack.
6493bf215546Sopenharmony_ci          */
6494bf215546Sopenharmony_ci         if (state->current_function->return_type != ret_type) {
6495bf215546Sopenharmony_ci            YYLTYPE loc = this->get_location();
6496bf215546Sopenharmony_ci
6497bf215546Sopenharmony_ci            if (state->has_420pack()) {
6498bf215546Sopenharmony_ci               if (!apply_implicit_conversion(state->current_function->return_type,
6499bf215546Sopenharmony_ci                                              ret, state)
6500bf215546Sopenharmony_ci                   || (ret->type != state->current_function->return_type)) {
6501bf215546Sopenharmony_ci                  _mesa_glsl_error(& loc, state,
6502bf215546Sopenharmony_ci                                   "could not implicitly convert return value "
6503bf215546Sopenharmony_ci                                   "to %s, in function `%s'",
6504bf215546Sopenharmony_ci                                   state->current_function->return_type->name,
6505bf215546Sopenharmony_ci                                   state->current_function->function_name());
6506bf215546Sopenharmony_ci               }
6507bf215546Sopenharmony_ci            } else {
6508bf215546Sopenharmony_ci               _mesa_glsl_error(& loc, state,
6509bf215546Sopenharmony_ci                                "`return' with wrong type %s, in function `%s' "
6510bf215546Sopenharmony_ci                                "returning %s",
6511bf215546Sopenharmony_ci                                ret_type->name,
6512bf215546Sopenharmony_ci                                state->current_function->function_name(),
6513bf215546Sopenharmony_ci                                state->current_function->return_type->name);
6514bf215546Sopenharmony_ci            }
6515bf215546Sopenharmony_ci         } else if (state->current_function->return_type->base_type ==
6516bf215546Sopenharmony_ci                    GLSL_TYPE_VOID) {
6517bf215546Sopenharmony_ci            YYLTYPE loc = this->get_location();
6518bf215546Sopenharmony_ci
6519bf215546Sopenharmony_ci            /* The ARB_shading_language_420pack, GLSL ES 3.0, and GLSL 4.20
6520bf215546Sopenharmony_ci             * specs add a clarification:
6521bf215546Sopenharmony_ci             *
6522bf215546Sopenharmony_ci             *    "A void function can only use return without a return argument, even if
6523bf215546Sopenharmony_ci             *     the return argument has void type. Return statements only accept values:
6524bf215546Sopenharmony_ci             *
6525bf215546Sopenharmony_ci             *         void func1() { }
6526bf215546Sopenharmony_ci             *         void func2() { return func1(); } // illegal return statement"
6527bf215546Sopenharmony_ci             */
6528bf215546Sopenharmony_ci            _mesa_glsl_error(& loc, state,
6529bf215546Sopenharmony_ci                             "void functions can only use `return' without a "
6530bf215546Sopenharmony_ci                             "return argument");
6531bf215546Sopenharmony_ci         }
6532bf215546Sopenharmony_ci
6533bf215546Sopenharmony_ci         inst = new(ctx) ir_return(ret);
6534bf215546Sopenharmony_ci      } else {
6535bf215546Sopenharmony_ci         if (state->current_function->return_type->base_type !=
6536bf215546Sopenharmony_ci             GLSL_TYPE_VOID) {
6537bf215546Sopenharmony_ci            YYLTYPE loc = this->get_location();
6538bf215546Sopenharmony_ci
6539bf215546Sopenharmony_ci            _mesa_glsl_error(& loc, state,
6540bf215546Sopenharmony_ci                             "`return' with no value, in function %s returning "
6541bf215546Sopenharmony_ci                             "non-void",
6542bf215546Sopenharmony_ci            state->current_function->function_name());
6543bf215546Sopenharmony_ci         }
6544bf215546Sopenharmony_ci         inst = new(ctx) ir_return;
6545bf215546Sopenharmony_ci      }
6546bf215546Sopenharmony_ci
6547bf215546Sopenharmony_ci      state->found_return = true;
6548bf215546Sopenharmony_ci      instructions->push_tail(inst);
6549bf215546Sopenharmony_ci      break;
6550bf215546Sopenharmony_ci   }
6551bf215546Sopenharmony_ci
6552bf215546Sopenharmony_ci   case ast_discard:
6553bf215546Sopenharmony_ci      if (state->stage != MESA_SHADER_FRAGMENT) {
6554bf215546Sopenharmony_ci         YYLTYPE loc = this->get_location();
6555bf215546Sopenharmony_ci
6556bf215546Sopenharmony_ci         _mesa_glsl_error(& loc, state,
6557bf215546Sopenharmony_ci                          "`discard' may only appear in a fragment shader");
6558bf215546Sopenharmony_ci      }
6559bf215546Sopenharmony_ci      instructions->push_tail(new(ctx) ir_discard);
6560bf215546Sopenharmony_ci      break;
6561bf215546Sopenharmony_ci
6562bf215546Sopenharmony_ci   case ast_break:
6563bf215546Sopenharmony_ci   case ast_continue:
6564bf215546Sopenharmony_ci      if (mode == ast_continue &&
6565bf215546Sopenharmony_ci          state->loop_nesting_ast == NULL) {
6566bf215546Sopenharmony_ci         YYLTYPE loc = this->get_location();
6567bf215546Sopenharmony_ci
6568bf215546Sopenharmony_ci         _mesa_glsl_error(& loc, state, "continue may only appear in a loop");
6569bf215546Sopenharmony_ci      } else if (mode == ast_break &&
6570bf215546Sopenharmony_ci         state->loop_nesting_ast == NULL &&
6571bf215546Sopenharmony_ci         state->switch_state.switch_nesting_ast == NULL) {
6572bf215546Sopenharmony_ci         YYLTYPE loc = this->get_location();
6573bf215546Sopenharmony_ci
6574bf215546Sopenharmony_ci         _mesa_glsl_error(& loc, state,
6575bf215546Sopenharmony_ci                          "break may only appear in a loop or a switch");
6576bf215546Sopenharmony_ci      } else {
6577bf215546Sopenharmony_ci         /* For a loop, inline the for loop expression again, since we don't
6578bf215546Sopenharmony_ci          * know where near the end of the loop body the normal copy of it is
6579bf215546Sopenharmony_ci          * going to be placed.  Same goes for the condition for a do-while
6580bf215546Sopenharmony_ci          * loop.
6581bf215546Sopenharmony_ci          */
6582bf215546Sopenharmony_ci         if (state->loop_nesting_ast != NULL &&
6583bf215546Sopenharmony_ci             mode == ast_continue && !state->switch_state.is_switch_innermost) {
6584bf215546Sopenharmony_ci            if (state->loop_nesting_ast->rest_expression) {
6585bf215546Sopenharmony_ci               clone_ir_list(ctx, instructions,
6586bf215546Sopenharmony_ci                             &state->loop_nesting_ast->rest_instructions);
6587bf215546Sopenharmony_ci            }
6588bf215546Sopenharmony_ci            if (state->loop_nesting_ast->mode ==
6589bf215546Sopenharmony_ci                ast_iteration_statement::ast_do_while) {
6590bf215546Sopenharmony_ci               state->loop_nesting_ast->condition_to_hir(instructions, state);
6591bf215546Sopenharmony_ci            }
6592bf215546Sopenharmony_ci         }
6593bf215546Sopenharmony_ci
6594bf215546Sopenharmony_ci         if (state->switch_state.is_switch_innermost &&
6595bf215546Sopenharmony_ci             mode == ast_continue) {
6596bf215546Sopenharmony_ci            /* Set 'continue_inside' to true. */
6597bf215546Sopenharmony_ci            ir_rvalue *const true_val = new (ctx) ir_constant(true);
6598bf215546Sopenharmony_ci            ir_dereference_variable *deref_continue_inside_var =
6599bf215546Sopenharmony_ci               new(ctx) ir_dereference_variable(state->switch_state.continue_inside);
6600bf215546Sopenharmony_ci            instructions->push_tail(new(ctx) ir_assignment(deref_continue_inside_var,
6601bf215546Sopenharmony_ci                                                           true_val));
6602bf215546Sopenharmony_ci
6603bf215546Sopenharmony_ci            /* Break out from the switch, continue for the loop will
6604bf215546Sopenharmony_ci             * be called right after switch. */
6605bf215546Sopenharmony_ci            ir_loop_jump *const jump =
6606bf215546Sopenharmony_ci               new(ctx) ir_loop_jump(ir_loop_jump::jump_break);
6607bf215546Sopenharmony_ci            instructions->push_tail(jump);
6608bf215546Sopenharmony_ci
6609bf215546Sopenharmony_ci         } else if (state->switch_state.is_switch_innermost &&
6610bf215546Sopenharmony_ci             mode == ast_break) {
6611bf215546Sopenharmony_ci            /* Force break out of switch by inserting a break. */
6612bf215546Sopenharmony_ci            ir_loop_jump *const jump =
6613bf215546Sopenharmony_ci               new(ctx) ir_loop_jump(ir_loop_jump::jump_break);
6614bf215546Sopenharmony_ci            instructions->push_tail(jump);
6615bf215546Sopenharmony_ci         } else {
6616bf215546Sopenharmony_ci            ir_loop_jump *const jump =
6617bf215546Sopenharmony_ci               new(ctx) ir_loop_jump((mode == ast_break)
6618bf215546Sopenharmony_ci                  ? ir_loop_jump::jump_break
6619bf215546Sopenharmony_ci                  : ir_loop_jump::jump_continue);
6620bf215546Sopenharmony_ci            instructions->push_tail(jump);
6621bf215546Sopenharmony_ci         }
6622bf215546Sopenharmony_ci      }
6623bf215546Sopenharmony_ci
6624bf215546Sopenharmony_ci      break;
6625bf215546Sopenharmony_ci   }
6626bf215546Sopenharmony_ci
6627bf215546Sopenharmony_ci   /* Jump instructions do not have r-values.
6628bf215546Sopenharmony_ci    */
6629bf215546Sopenharmony_ci   return NULL;
6630bf215546Sopenharmony_ci}
6631bf215546Sopenharmony_ci
6632bf215546Sopenharmony_ci
6633bf215546Sopenharmony_ciir_rvalue *
6634bf215546Sopenharmony_ciast_demote_statement::hir(exec_list *instructions,
6635bf215546Sopenharmony_ci                          struct _mesa_glsl_parse_state *state)
6636bf215546Sopenharmony_ci{
6637bf215546Sopenharmony_ci   void *ctx = state;
6638bf215546Sopenharmony_ci
6639bf215546Sopenharmony_ci   if (state->stage != MESA_SHADER_FRAGMENT) {
6640bf215546Sopenharmony_ci      YYLTYPE loc = this->get_location();
6641bf215546Sopenharmony_ci
6642bf215546Sopenharmony_ci      _mesa_glsl_error(& loc, state,
6643bf215546Sopenharmony_ci                       "`demote' may only appear in a fragment shader");
6644bf215546Sopenharmony_ci   }
6645bf215546Sopenharmony_ci
6646bf215546Sopenharmony_ci   instructions->push_tail(new(ctx) ir_demote);
6647bf215546Sopenharmony_ci
6648bf215546Sopenharmony_ci   return NULL;
6649bf215546Sopenharmony_ci}
6650bf215546Sopenharmony_ci
6651bf215546Sopenharmony_ci
6652bf215546Sopenharmony_ciir_rvalue *
6653bf215546Sopenharmony_ciast_selection_statement::hir(exec_list *instructions,
6654bf215546Sopenharmony_ci                             struct _mesa_glsl_parse_state *state)
6655bf215546Sopenharmony_ci{
6656bf215546Sopenharmony_ci   void *ctx = state;
6657bf215546Sopenharmony_ci
6658bf215546Sopenharmony_ci   ir_rvalue *const condition = this->condition->hir(instructions, state);
6659bf215546Sopenharmony_ci
6660bf215546Sopenharmony_ci   /* From page 66 (page 72 of the PDF) of the GLSL 1.50 spec:
6661bf215546Sopenharmony_ci    *
6662bf215546Sopenharmony_ci    *    "Any expression whose type evaluates to a Boolean can be used as the
6663bf215546Sopenharmony_ci    *    conditional expression bool-expression. Vector types are not accepted
6664bf215546Sopenharmony_ci    *    as the expression to if."
6665bf215546Sopenharmony_ci    *
6666bf215546Sopenharmony_ci    * The checks are separated so that higher quality diagnostics can be
6667bf215546Sopenharmony_ci    * generated for cases where both rules are violated.
6668bf215546Sopenharmony_ci    */
6669bf215546Sopenharmony_ci   if (!condition->type->is_boolean() || !condition->type->is_scalar()) {
6670bf215546Sopenharmony_ci      YYLTYPE loc = this->condition->get_location();
6671bf215546Sopenharmony_ci
6672bf215546Sopenharmony_ci      _mesa_glsl_error(& loc, state, "if-statement condition must be scalar "
6673bf215546Sopenharmony_ci                       "boolean");
6674bf215546Sopenharmony_ci   }
6675bf215546Sopenharmony_ci
6676bf215546Sopenharmony_ci   ir_if *const stmt = new(ctx) ir_if(condition);
6677bf215546Sopenharmony_ci
6678bf215546Sopenharmony_ci   if (then_statement != NULL) {
6679bf215546Sopenharmony_ci      state->symbols->push_scope();
6680bf215546Sopenharmony_ci      then_statement->hir(& stmt->then_instructions, state);
6681bf215546Sopenharmony_ci      state->symbols->pop_scope();
6682bf215546Sopenharmony_ci   }
6683bf215546Sopenharmony_ci
6684bf215546Sopenharmony_ci   if (else_statement != NULL) {
6685bf215546Sopenharmony_ci      state->symbols->push_scope();
6686bf215546Sopenharmony_ci      else_statement->hir(& stmt->else_instructions, state);
6687bf215546Sopenharmony_ci      state->symbols->pop_scope();
6688bf215546Sopenharmony_ci   }
6689bf215546Sopenharmony_ci
6690bf215546Sopenharmony_ci   instructions->push_tail(stmt);
6691bf215546Sopenharmony_ci
6692bf215546Sopenharmony_ci   /* if-statements do not have r-values.
6693bf215546Sopenharmony_ci    */
6694bf215546Sopenharmony_ci   return NULL;
6695bf215546Sopenharmony_ci}
6696bf215546Sopenharmony_ci
6697bf215546Sopenharmony_ci
6698bf215546Sopenharmony_cistruct case_label {
6699bf215546Sopenharmony_ci   /** Value of the case label. */
6700bf215546Sopenharmony_ci   unsigned value;
6701bf215546Sopenharmony_ci
6702bf215546Sopenharmony_ci   /** Does this label occur after the default? */
6703bf215546Sopenharmony_ci   bool after_default;
6704bf215546Sopenharmony_ci
6705bf215546Sopenharmony_ci   /**
6706bf215546Sopenharmony_ci    * AST for the case label.
6707bf215546Sopenharmony_ci    *
6708bf215546Sopenharmony_ci    * This is only used to generate error messages for duplicate labels.
6709bf215546Sopenharmony_ci    */
6710bf215546Sopenharmony_ci   ast_expression *ast;
6711bf215546Sopenharmony_ci};
6712bf215546Sopenharmony_ci
6713bf215546Sopenharmony_ci/* Used for detection of duplicate case values, compare
6714bf215546Sopenharmony_ci * given contents directly.
6715bf215546Sopenharmony_ci */
6716bf215546Sopenharmony_cistatic bool
6717bf215546Sopenharmony_cicompare_case_value(const void *a, const void *b)
6718bf215546Sopenharmony_ci{
6719bf215546Sopenharmony_ci   return ((struct case_label *) a)->value == ((struct case_label *) b)->value;
6720bf215546Sopenharmony_ci}
6721bf215546Sopenharmony_ci
6722bf215546Sopenharmony_ci
6723bf215546Sopenharmony_ci/* Used for detection of duplicate case values, just
6724bf215546Sopenharmony_ci * returns key contents as is.
6725bf215546Sopenharmony_ci */
6726bf215546Sopenharmony_cistatic unsigned
6727bf215546Sopenharmony_cikey_contents(const void *key)
6728bf215546Sopenharmony_ci{
6729bf215546Sopenharmony_ci   return ((struct case_label *) key)->value;
6730bf215546Sopenharmony_ci}
6731bf215546Sopenharmony_ci
6732bf215546Sopenharmony_civoid
6733bf215546Sopenharmony_ciast_switch_statement::eval_test_expression(exec_list *instructions,
6734bf215546Sopenharmony_ci                                           struct _mesa_glsl_parse_state *state)
6735bf215546Sopenharmony_ci{
6736bf215546Sopenharmony_ci   if (test_val == NULL)
6737bf215546Sopenharmony_ci      test_val = this->test_expression->hir(instructions, state);
6738bf215546Sopenharmony_ci}
6739bf215546Sopenharmony_ci
6740bf215546Sopenharmony_ciir_rvalue *
6741bf215546Sopenharmony_ciast_switch_statement::hir(exec_list *instructions,
6742bf215546Sopenharmony_ci                          struct _mesa_glsl_parse_state *state)
6743bf215546Sopenharmony_ci{
6744bf215546Sopenharmony_ci   void *ctx = state;
6745bf215546Sopenharmony_ci
6746bf215546Sopenharmony_ci   this->eval_test_expression(instructions, state);
6747bf215546Sopenharmony_ci
6748bf215546Sopenharmony_ci   /* From page 66 (page 55 of the PDF) of the GLSL 1.50 spec:
6749bf215546Sopenharmony_ci    *
6750bf215546Sopenharmony_ci    *    "The type of init-expression in a switch statement must be a
6751bf215546Sopenharmony_ci    *     scalar integer."
6752bf215546Sopenharmony_ci    */
6753bf215546Sopenharmony_ci   if (!test_val->type->is_scalar() ||
6754bf215546Sopenharmony_ci       !test_val->type->is_integer_32()) {
6755bf215546Sopenharmony_ci      YYLTYPE loc = this->test_expression->get_location();
6756bf215546Sopenharmony_ci
6757bf215546Sopenharmony_ci      _mesa_glsl_error(& loc,
6758bf215546Sopenharmony_ci                       state,
6759bf215546Sopenharmony_ci                       "switch-statement expression must be scalar "
6760bf215546Sopenharmony_ci                       "integer");
6761bf215546Sopenharmony_ci      return NULL;
6762bf215546Sopenharmony_ci   }
6763bf215546Sopenharmony_ci
6764bf215546Sopenharmony_ci   /* Track the switch-statement nesting in a stack-like manner.
6765bf215546Sopenharmony_ci    */
6766bf215546Sopenharmony_ci   struct glsl_switch_state saved = state->switch_state;
6767bf215546Sopenharmony_ci
6768bf215546Sopenharmony_ci   state->switch_state.is_switch_innermost = true;
6769bf215546Sopenharmony_ci   state->switch_state.switch_nesting_ast = this;
6770bf215546Sopenharmony_ci   state->switch_state.labels_ht =
6771bf215546Sopenharmony_ci         _mesa_hash_table_create(NULL, key_contents,
6772bf215546Sopenharmony_ci                                 compare_case_value);
6773bf215546Sopenharmony_ci   state->switch_state.previous_default = NULL;
6774bf215546Sopenharmony_ci
6775bf215546Sopenharmony_ci   /* Initalize is_fallthru state to false.
6776bf215546Sopenharmony_ci    */
6777bf215546Sopenharmony_ci   ir_rvalue *const is_fallthru_val = new (ctx) ir_constant(false);
6778bf215546Sopenharmony_ci   state->switch_state.is_fallthru_var =
6779bf215546Sopenharmony_ci      new(ctx) ir_variable(glsl_type::bool_type,
6780bf215546Sopenharmony_ci                           "switch_is_fallthru_tmp",
6781bf215546Sopenharmony_ci                           ir_var_temporary);
6782bf215546Sopenharmony_ci   instructions->push_tail(state->switch_state.is_fallthru_var);
6783bf215546Sopenharmony_ci
6784bf215546Sopenharmony_ci   ir_dereference_variable *deref_is_fallthru_var =
6785bf215546Sopenharmony_ci      new(ctx) ir_dereference_variable(state->switch_state.is_fallthru_var);
6786bf215546Sopenharmony_ci   instructions->push_tail(new(ctx) ir_assignment(deref_is_fallthru_var,
6787bf215546Sopenharmony_ci                                                  is_fallthru_val));
6788bf215546Sopenharmony_ci
6789bf215546Sopenharmony_ci   /* Initialize continue_inside state to false.
6790bf215546Sopenharmony_ci    */
6791bf215546Sopenharmony_ci   state->switch_state.continue_inside =
6792bf215546Sopenharmony_ci      new(ctx) ir_variable(glsl_type::bool_type,
6793bf215546Sopenharmony_ci                           "continue_inside_tmp",
6794bf215546Sopenharmony_ci                           ir_var_temporary);
6795bf215546Sopenharmony_ci   instructions->push_tail(state->switch_state.continue_inside);
6796bf215546Sopenharmony_ci
6797bf215546Sopenharmony_ci   ir_rvalue *const false_val = new (ctx) ir_constant(false);
6798bf215546Sopenharmony_ci   ir_dereference_variable *deref_continue_inside_var =
6799bf215546Sopenharmony_ci      new(ctx) ir_dereference_variable(state->switch_state.continue_inside);
6800bf215546Sopenharmony_ci   instructions->push_tail(new(ctx) ir_assignment(deref_continue_inside_var,
6801bf215546Sopenharmony_ci                                                  false_val));
6802bf215546Sopenharmony_ci
6803bf215546Sopenharmony_ci   state->switch_state.run_default =
6804bf215546Sopenharmony_ci      new(ctx) ir_variable(glsl_type::bool_type,
6805bf215546Sopenharmony_ci                             "run_default_tmp",
6806bf215546Sopenharmony_ci                             ir_var_temporary);
6807bf215546Sopenharmony_ci   instructions->push_tail(state->switch_state.run_default);
6808bf215546Sopenharmony_ci
6809bf215546Sopenharmony_ci   /* Loop around the switch is used for flow control. */
6810bf215546Sopenharmony_ci   ir_loop * loop = new(ctx) ir_loop();
6811bf215546Sopenharmony_ci   instructions->push_tail(loop);
6812bf215546Sopenharmony_ci
6813bf215546Sopenharmony_ci   /* Cache test expression.
6814bf215546Sopenharmony_ci    */
6815bf215546Sopenharmony_ci   test_to_hir(&loop->body_instructions, state);
6816bf215546Sopenharmony_ci
6817bf215546Sopenharmony_ci   /* Emit code for body of switch stmt.
6818bf215546Sopenharmony_ci    */
6819bf215546Sopenharmony_ci   body->hir(&loop->body_instructions, state);
6820bf215546Sopenharmony_ci
6821bf215546Sopenharmony_ci   /* Insert a break at the end to exit loop. */
6822bf215546Sopenharmony_ci   ir_loop_jump *jump = new(ctx) ir_loop_jump(ir_loop_jump::jump_break);
6823bf215546Sopenharmony_ci   loop->body_instructions.push_tail(jump);
6824bf215546Sopenharmony_ci
6825bf215546Sopenharmony_ci   /* If we are inside loop, check if continue got called inside switch. */
6826bf215546Sopenharmony_ci   if (state->loop_nesting_ast != NULL) {
6827bf215546Sopenharmony_ci      ir_dereference_variable *deref_continue_inside =
6828bf215546Sopenharmony_ci         new(ctx) ir_dereference_variable(state->switch_state.continue_inside);
6829bf215546Sopenharmony_ci      ir_if *irif = new(ctx) ir_if(deref_continue_inside);
6830bf215546Sopenharmony_ci      ir_loop_jump *jump = new(ctx) ir_loop_jump(ir_loop_jump::jump_continue);
6831bf215546Sopenharmony_ci
6832bf215546Sopenharmony_ci      if (state->loop_nesting_ast != NULL) {
6833bf215546Sopenharmony_ci         if (state->loop_nesting_ast->rest_expression) {
6834bf215546Sopenharmony_ci            clone_ir_list(ctx, &irif->then_instructions,
6835bf215546Sopenharmony_ci                          &state->loop_nesting_ast->rest_instructions);
6836bf215546Sopenharmony_ci         }
6837bf215546Sopenharmony_ci         if (state->loop_nesting_ast->mode ==
6838bf215546Sopenharmony_ci             ast_iteration_statement::ast_do_while) {
6839bf215546Sopenharmony_ci            state->loop_nesting_ast->condition_to_hir(&irif->then_instructions, state);
6840bf215546Sopenharmony_ci         }
6841bf215546Sopenharmony_ci      }
6842bf215546Sopenharmony_ci      irif->then_instructions.push_tail(jump);
6843bf215546Sopenharmony_ci      instructions->push_tail(irif);
6844bf215546Sopenharmony_ci   }
6845bf215546Sopenharmony_ci
6846bf215546Sopenharmony_ci   _mesa_hash_table_destroy(state->switch_state.labels_ht, NULL);
6847bf215546Sopenharmony_ci
6848bf215546Sopenharmony_ci   state->switch_state = saved;
6849bf215546Sopenharmony_ci
6850bf215546Sopenharmony_ci   /* Switch statements do not have r-values. */
6851bf215546Sopenharmony_ci   return NULL;
6852bf215546Sopenharmony_ci}
6853bf215546Sopenharmony_ci
6854bf215546Sopenharmony_ci
6855bf215546Sopenharmony_civoid
6856bf215546Sopenharmony_ciast_switch_statement::test_to_hir(exec_list *instructions,
6857bf215546Sopenharmony_ci                                  struct _mesa_glsl_parse_state *state)
6858bf215546Sopenharmony_ci{
6859bf215546Sopenharmony_ci   void *ctx = state;
6860bf215546Sopenharmony_ci
6861bf215546Sopenharmony_ci   /* set to true to avoid a duplicate "use of uninitialized variable" warning
6862bf215546Sopenharmony_ci    * on the switch test case. The first one would be already raised when
6863bf215546Sopenharmony_ci    * getting the test_expression at ast_switch_statement::hir
6864bf215546Sopenharmony_ci    */
6865bf215546Sopenharmony_ci   test_expression->set_is_lhs(true);
6866bf215546Sopenharmony_ci   /* Cache value of test expression. */
6867bf215546Sopenharmony_ci   this->eval_test_expression(instructions, state);
6868bf215546Sopenharmony_ci
6869bf215546Sopenharmony_ci   state->switch_state.test_var = new(ctx) ir_variable(test_val->type,
6870bf215546Sopenharmony_ci                                                       "switch_test_tmp",
6871bf215546Sopenharmony_ci                                                       ir_var_temporary);
6872bf215546Sopenharmony_ci   ir_dereference_variable *deref_test_var =
6873bf215546Sopenharmony_ci      new(ctx) ir_dereference_variable(state->switch_state.test_var);
6874bf215546Sopenharmony_ci
6875bf215546Sopenharmony_ci   instructions->push_tail(state->switch_state.test_var);
6876bf215546Sopenharmony_ci   instructions->push_tail(new(ctx) ir_assignment(deref_test_var, test_val));
6877bf215546Sopenharmony_ci}
6878bf215546Sopenharmony_ci
6879bf215546Sopenharmony_ci
6880bf215546Sopenharmony_ciir_rvalue *
6881bf215546Sopenharmony_ciast_switch_body::hir(exec_list *instructions,
6882bf215546Sopenharmony_ci                     struct _mesa_glsl_parse_state *state)
6883bf215546Sopenharmony_ci{
6884bf215546Sopenharmony_ci   if (stmts != NULL) {
6885bf215546Sopenharmony_ci      state->symbols->push_scope();
6886bf215546Sopenharmony_ci      stmts->hir(instructions, state);
6887bf215546Sopenharmony_ci      state->symbols->pop_scope();
6888bf215546Sopenharmony_ci   }
6889bf215546Sopenharmony_ci
6890bf215546Sopenharmony_ci   /* Switch bodies do not have r-values. */
6891bf215546Sopenharmony_ci   return NULL;
6892bf215546Sopenharmony_ci}
6893bf215546Sopenharmony_ci
6894bf215546Sopenharmony_ciir_rvalue *
6895bf215546Sopenharmony_ciast_case_statement_list::hir(exec_list *instructions,
6896bf215546Sopenharmony_ci                             struct _mesa_glsl_parse_state *state)
6897bf215546Sopenharmony_ci{
6898bf215546Sopenharmony_ci   exec_list default_case, after_default, tmp;
6899bf215546Sopenharmony_ci
6900bf215546Sopenharmony_ci   foreach_list_typed (ast_case_statement, case_stmt, link, & this->cases) {
6901bf215546Sopenharmony_ci      case_stmt->hir(&tmp, state);
6902bf215546Sopenharmony_ci
6903bf215546Sopenharmony_ci      /* Default case. */
6904bf215546Sopenharmony_ci      if (state->switch_state.previous_default && default_case.is_empty()) {
6905bf215546Sopenharmony_ci         default_case.append_list(&tmp);
6906bf215546Sopenharmony_ci         continue;
6907bf215546Sopenharmony_ci      }
6908bf215546Sopenharmony_ci
6909bf215546Sopenharmony_ci      /* If default case found, append 'after_default' list. */
6910bf215546Sopenharmony_ci      if (!default_case.is_empty())
6911bf215546Sopenharmony_ci         after_default.append_list(&tmp);
6912bf215546Sopenharmony_ci      else
6913bf215546Sopenharmony_ci         instructions->append_list(&tmp);
6914bf215546Sopenharmony_ci   }
6915bf215546Sopenharmony_ci
6916bf215546Sopenharmony_ci   /* Handle the default case. This is done here because default might not be
6917bf215546Sopenharmony_ci    * the last case. We need to add checks against following cases first to see
6918bf215546Sopenharmony_ci    * if default should be chosen or not.
6919bf215546Sopenharmony_ci    */
6920bf215546Sopenharmony_ci   if (!default_case.is_empty()) {
6921bf215546Sopenharmony_ci      ir_factory body(instructions, state);
6922bf215546Sopenharmony_ci
6923bf215546Sopenharmony_ci      ir_expression *cmp = NULL;
6924bf215546Sopenharmony_ci
6925bf215546Sopenharmony_ci      hash_table_foreach(state->switch_state.labels_ht, entry) {
6926bf215546Sopenharmony_ci         const struct case_label *const l = (struct case_label *) entry->data;
6927bf215546Sopenharmony_ci
6928bf215546Sopenharmony_ci         /* If the switch init-value is the value of one of the labels that
6929bf215546Sopenharmony_ci          * occurs after the default case, disable execution of the default
6930bf215546Sopenharmony_ci          * case.
6931bf215546Sopenharmony_ci          */
6932bf215546Sopenharmony_ci         if (l->after_default) {
6933bf215546Sopenharmony_ci            ir_constant *const cnst =
6934bf215546Sopenharmony_ci               state->switch_state.test_var->type->base_type == GLSL_TYPE_UINT
6935bf215546Sopenharmony_ci               ? body.constant(unsigned(l->value))
6936bf215546Sopenharmony_ci               : body.constant(int(l->value));
6937bf215546Sopenharmony_ci
6938bf215546Sopenharmony_ci            cmp = cmp == NULL
6939bf215546Sopenharmony_ci               ? equal(cnst, state->switch_state.test_var)
6940bf215546Sopenharmony_ci               : logic_or(cmp, equal(cnst, state->switch_state.test_var));
6941bf215546Sopenharmony_ci         }
6942bf215546Sopenharmony_ci      }
6943bf215546Sopenharmony_ci
6944bf215546Sopenharmony_ci      if (cmp != NULL)
6945bf215546Sopenharmony_ci         body.emit(assign(state->switch_state.run_default, logic_not(cmp)));
6946bf215546Sopenharmony_ci      else
6947bf215546Sopenharmony_ci         body.emit(assign(state->switch_state.run_default, body.constant(true)));
6948bf215546Sopenharmony_ci
6949bf215546Sopenharmony_ci      /* Append default case and all cases after it. */
6950bf215546Sopenharmony_ci      instructions->append_list(&default_case);
6951bf215546Sopenharmony_ci      instructions->append_list(&after_default);
6952bf215546Sopenharmony_ci   }
6953bf215546Sopenharmony_ci
6954bf215546Sopenharmony_ci   /* Case statements do not have r-values. */
6955bf215546Sopenharmony_ci   return NULL;
6956bf215546Sopenharmony_ci}
6957bf215546Sopenharmony_ci
6958bf215546Sopenharmony_ciir_rvalue *
6959bf215546Sopenharmony_ciast_case_statement::hir(exec_list *instructions,
6960bf215546Sopenharmony_ci                        struct _mesa_glsl_parse_state *state)
6961bf215546Sopenharmony_ci{
6962bf215546Sopenharmony_ci   labels->hir(instructions, state);
6963bf215546Sopenharmony_ci
6964bf215546Sopenharmony_ci   /* Guard case statements depending on fallthru state. */
6965bf215546Sopenharmony_ci   ir_dereference_variable *const deref_fallthru_guard =
6966bf215546Sopenharmony_ci      new(state) ir_dereference_variable(state->switch_state.is_fallthru_var);
6967bf215546Sopenharmony_ci   ir_if *const test_fallthru = new(state) ir_if(deref_fallthru_guard);
6968bf215546Sopenharmony_ci
6969bf215546Sopenharmony_ci   foreach_list_typed (ast_node, stmt, link, & this->stmts)
6970bf215546Sopenharmony_ci      stmt->hir(& test_fallthru->then_instructions, state);
6971bf215546Sopenharmony_ci
6972bf215546Sopenharmony_ci   instructions->push_tail(test_fallthru);
6973bf215546Sopenharmony_ci
6974bf215546Sopenharmony_ci   /* Case statements do not have r-values. */
6975bf215546Sopenharmony_ci   return NULL;
6976bf215546Sopenharmony_ci}
6977bf215546Sopenharmony_ci
6978bf215546Sopenharmony_ci
6979bf215546Sopenharmony_ciir_rvalue *
6980bf215546Sopenharmony_ciast_case_label_list::hir(exec_list *instructions,
6981bf215546Sopenharmony_ci                         struct _mesa_glsl_parse_state *state)
6982bf215546Sopenharmony_ci{
6983bf215546Sopenharmony_ci   foreach_list_typed (ast_case_label, label, link, & this->labels)
6984bf215546Sopenharmony_ci      label->hir(instructions, state);
6985bf215546Sopenharmony_ci
6986bf215546Sopenharmony_ci   /* Case labels do not have r-values. */
6987bf215546Sopenharmony_ci   return NULL;
6988bf215546Sopenharmony_ci}
6989bf215546Sopenharmony_ci
6990bf215546Sopenharmony_ciir_rvalue *
6991bf215546Sopenharmony_ciast_case_label::hir(exec_list *instructions,
6992bf215546Sopenharmony_ci                    struct _mesa_glsl_parse_state *state)
6993bf215546Sopenharmony_ci{
6994bf215546Sopenharmony_ci   ir_factory body(instructions, state);
6995bf215546Sopenharmony_ci
6996bf215546Sopenharmony_ci   ir_variable *const fallthru_var = state->switch_state.is_fallthru_var;
6997bf215546Sopenharmony_ci
6998bf215546Sopenharmony_ci   /* If not default case, ... */
6999bf215546Sopenharmony_ci   if (this->test_value != NULL) {
7000bf215546Sopenharmony_ci      /* Conditionally set fallthru state based on
7001bf215546Sopenharmony_ci       * comparison of cached test expression value to case label.
7002bf215546Sopenharmony_ci       */
7003bf215546Sopenharmony_ci      ir_rvalue *const label_rval = this->test_value->hir(instructions, state);
7004bf215546Sopenharmony_ci      ir_constant *label_const =
7005bf215546Sopenharmony_ci         label_rval->constant_expression_value(body.mem_ctx);
7006bf215546Sopenharmony_ci
7007bf215546Sopenharmony_ci      if (!label_const) {
7008bf215546Sopenharmony_ci         YYLTYPE loc = this->test_value->get_location();
7009bf215546Sopenharmony_ci
7010bf215546Sopenharmony_ci         _mesa_glsl_error(& loc, state,
7011bf215546Sopenharmony_ci                          "switch statement case label must be a "
7012bf215546Sopenharmony_ci                          "constant expression");
7013bf215546Sopenharmony_ci
7014bf215546Sopenharmony_ci         /* Stuff a dummy value in to allow processing to continue. */
7015bf215546Sopenharmony_ci         label_const = body.constant(0);
7016bf215546Sopenharmony_ci      } else {
7017bf215546Sopenharmony_ci         hash_entry *entry =
7018bf215546Sopenharmony_ci               _mesa_hash_table_search(state->switch_state.labels_ht,
7019bf215546Sopenharmony_ci                                       &label_const->value.u[0]);
7020bf215546Sopenharmony_ci
7021bf215546Sopenharmony_ci         if (entry) {
7022bf215546Sopenharmony_ci            const struct case_label *const l =
7023bf215546Sopenharmony_ci               (struct case_label *) entry->data;
7024bf215546Sopenharmony_ci            const ast_expression *const previous_label = l->ast;
7025bf215546Sopenharmony_ci            YYLTYPE loc = this->test_value->get_location();
7026bf215546Sopenharmony_ci
7027bf215546Sopenharmony_ci            _mesa_glsl_error(& loc, state, "duplicate case value");
7028bf215546Sopenharmony_ci
7029bf215546Sopenharmony_ci            loc = previous_label->get_location();
7030bf215546Sopenharmony_ci            _mesa_glsl_error(& loc, state, "this is the previous case label");
7031bf215546Sopenharmony_ci         } else {
7032bf215546Sopenharmony_ci            struct case_label *l = ralloc(state->switch_state.labels_ht,
7033bf215546Sopenharmony_ci                                          struct case_label);
7034bf215546Sopenharmony_ci
7035bf215546Sopenharmony_ci            l->value = label_const->value.u[0];
7036bf215546Sopenharmony_ci            l->after_default = state->switch_state.previous_default != NULL;
7037bf215546Sopenharmony_ci            l->ast = this->test_value;
7038bf215546Sopenharmony_ci
7039bf215546Sopenharmony_ci            _mesa_hash_table_insert(state->switch_state.labels_ht,
7040bf215546Sopenharmony_ci                                    &label_const->value.u[0],
7041bf215546Sopenharmony_ci                                    l);
7042bf215546Sopenharmony_ci         }
7043bf215546Sopenharmony_ci      }
7044bf215546Sopenharmony_ci
7045bf215546Sopenharmony_ci      /* Create an r-value version of the ir_constant label here (after we may
7046bf215546Sopenharmony_ci       * have created a fake one in error cases) that can be passed to
7047bf215546Sopenharmony_ci       * apply_implicit_conversion below.
7048bf215546Sopenharmony_ci       */
7049bf215546Sopenharmony_ci      ir_rvalue *label = label_const;
7050bf215546Sopenharmony_ci
7051bf215546Sopenharmony_ci      ir_rvalue *deref_test_var =
7052bf215546Sopenharmony_ci         new(body.mem_ctx) ir_dereference_variable(state->switch_state.test_var);
7053bf215546Sopenharmony_ci
7054bf215546Sopenharmony_ci      /*
7055bf215546Sopenharmony_ci       * From GLSL 4.40 specification section 6.2 ("Selection"):
7056bf215546Sopenharmony_ci       *
7057bf215546Sopenharmony_ci       *     "The type of the init-expression value in a switch statement must
7058bf215546Sopenharmony_ci       *     be a scalar int or uint. The type of the constant-expression value
7059bf215546Sopenharmony_ci       *     in a case label also must be a scalar int or uint. When any pair
7060bf215546Sopenharmony_ci       *     of these values is tested for "equal value" and the types do not
7061bf215546Sopenharmony_ci       *     match, an implicit conversion will be done to convert the int to a
7062bf215546Sopenharmony_ci       *     uint (see section 4.1.10 “Implicit Conversions”) before the compare
7063bf215546Sopenharmony_ci       *     is done."
7064bf215546Sopenharmony_ci       */
7065bf215546Sopenharmony_ci      if (label->type != state->switch_state.test_var->type) {
7066bf215546Sopenharmony_ci         YYLTYPE loc = this->test_value->get_location();
7067bf215546Sopenharmony_ci
7068bf215546Sopenharmony_ci         const glsl_type *type_a = label->type;
7069bf215546Sopenharmony_ci         const glsl_type *type_b = state->switch_state.test_var->type;
7070bf215546Sopenharmony_ci
7071bf215546Sopenharmony_ci         /* Check if int->uint implicit conversion is supported. */
7072bf215546Sopenharmony_ci         bool integer_conversion_supported =
7073bf215546Sopenharmony_ci            glsl_type::int_type->can_implicitly_convert_to(glsl_type::uint_type,
7074bf215546Sopenharmony_ci                                                           state);
7075bf215546Sopenharmony_ci
7076bf215546Sopenharmony_ci         if ((!type_a->is_integer_32() || !type_b->is_integer_32()) ||
7077bf215546Sopenharmony_ci              !integer_conversion_supported) {
7078bf215546Sopenharmony_ci            _mesa_glsl_error(&loc, state, "type mismatch with switch "
7079bf215546Sopenharmony_ci                             "init-expression and case label (%s != %s)",
7080bf215546Sopenharmony_ci                             type_a->name, type_b->name);
7081bf215546Sopenharmony_ci         } else {
7082bf215546Sopenharmony_ci            /* Conversion of the case label. */
7083bf215546Sopenharmony_ci            if (type_a->base_type == GLSL_TYPE_INT) {
7084bf215546Sopenharmony_ci               if (!apply_implicit_conversion(glsl_type::uint_type,
7085bf215546Sopenharmony_ci                                              label, state))
7086bf215546Sopenharmony_ci                  _mesa_glsl_error(&loc, state, "implicit type conversion error");
7087bf215546Sopenharmony_ci            } else {
7088bf215546Sopenharmony_ci               /* Conversion of the init-expression value. */
7089bf215546Sopenharmony_ci               if (!apply_implicit_conversion(glsl_type::uint_type,
7090bf215546Sopenharmony_ci                                              deref_test_var, state))
7091bf215546Sopenharmony_ci                  _mesa_glsl_error(&loc, state, "implicit type conversion error");
7092bf215546Sopenharmony_ci            }
7093bf215546Sopenharmony_ci         }
7094bf215546Sopenharmony_ci
7095bf215546Sopenharmony_ci         /* If the implicit conversion was allowed, the types will already be
7096bf215546Sopenharmony_ci          * the same.  If the implicit conversion wasn't allowed, smash the
7097bf215546Sopenharmony_ci          * type of the label anyway.  This will prevent the expression
7098bf215546Sopenharmony_ci          * constructor (below) from failing an assertion.
7099bf215546Sopenharmony_ci          */
7100bf215546Sopenharmony_ci         label->type = deref_test_var->type;
7101bf215546Sopenharmony_ci      }
7102bf215546Sopenharmony_ci
7103bf215546Sopenharmony_ci      body.emit(assign(fallthru_var,
7104bf215546Sopenharmony_ci                       logic_or(fallthru_var, equal(label, deref_test_var))));
7105bf215546Sopenharmony_ci   } else { /* default case */
7106bf215546Sopenharmony_ci      if (state->switch_state.previous_default) {
7107bf215546Sopenharmony_ci         YYLTYPE loc = this->get_location();
7108bf215546Sopenharmony_ci         _mesa_glsl_error(& loc, state,
7109bf215546Sopenharmony_ci                          "multiple default labels in one switch");
7110bf215546Sopenharmony_ci
7111bf215546Sopenharmony_ci         loc = state->switch_state.previous_default->get_location();
7112bf215546Sopenharmony_ci         _mesa_glsl_error(& loc, state, "this is the first default label");
7113bf215546Sopenharmony_ci      }
7114bf215546Sopenharmony_ci      state->switch_state.previous_default = this;
7115bf215546Sopenharmony_ci
7116bf215546Sopenharmony_ci      /* Set fallthru condition on 'run_default' bool. */
7117bf215546Sopenharmony_ci      body.emit(assign(fallthru_var,
7118bf215546Sopenharmony_ci                       logic_or(fallthru_var,
7119bf215546Sopenharmony_ci                                state->switch_state.run_default)));
7120bf215546Sopenharmony_ci   }
7121bf215546Sopenharmony_ci
7122bf215546Sopenharmony_ci   /* Case statements do not have r-values. */
7123bf215546Sopenharmony_ci   return NULL;
7124bf215546Sopenharmony_ci}
7125bf215546Sopenharmony_ci
7126bf215546Sopenharmony_civoid
7127bf215546Sopenharmony_ciast_iteration_statement::condition_to_hir(exec_list *instructions,
7128bf215546Sopenharmony_ci                                          struct _mesa_glsl_parse_state *state)
7129bf215546Sopenharmony_ci{
7130bf215546Sopenharmony_ci   void *ctx = state;
7131bf215546Sopenharmony_ci
7132bf215546Sopenharmony_ci   if (condition != NULL) {
7133bf215546Sopenharmony_ci      ir_rvalue *const cond =
7134bf215546Sopenharmony_ci         condition->hir(instructions, state);
7135bf215546Sopenharmony_ci
7136bf215546Sopenharmony_ci      if ((cond == NULL)
7137bf215546Sopenharmony_ci          || !cond->type->is_boolean() || !cond->type->is_scalar()) {
7138bf215546Sopenharmony_ci         YYLTYPE loc = condition->get_location();
7139bf215546Sopenharmony_ci
7140bf215546Sopenharmony_ci         _mesa_glsl_error(& loc, state,
7141bf215546Sopenharmony_ci                          "loop condition must be scalar boolean");
7142bf215546Sopenharmony_ci      } else {
7143bf215546Sopenharmony_ci         /* As the first code in the loop body, generate a block that looks
7144bf215546Sopenharmony_ci          * like 'if (!condition) break;' as the loop termination condition.
7145bf215546Sopenharmony_ci          */
7146bf215546Sopenharmony_ci         ir_rvalue *const not_cond =
7147bf215546Sopenharmony_ci            new(ctx) ir_expression(ir_unop_logic_not, cond);
7148bf215546Sopenharmony_ci
7149bf215546Sopenharmony_ci         ir_if *const if_stmt = new(ctx) ir_if(not_cond);
7150bf215546Sopenharmony_ci
7151bf215546Sopenharmony_ci         ir_jump *const break_stmt =
7152bf215546Sopenharmony_ci            new(ctx) ir_loop_jump(ir_loop_jump::jump_break);
7153bf215546Sopenharmony_ci
7154bf215546Sopenharmony_ci         if_stmt->then_instructions.push_tail(break_stmt);
7155bf215546Sopenharmony_ci         instructions->push_tail(if_stmt);
7156bf215546Sopenharmony_ci      }
7157bf215546Sopenharmony_ci   }
7158bf215546Sopenharmony_ci}
7159bf215546Sopenharmony_ci
7160bf215546Sopenharmony_ci
7161bf215546Sopenharmony_ciir_rvalue *
7162bf215546Sopenharmony_ciast_iteration_statement::hir(exec_list *instructions,
7163bf215546Sopenharmony_ci                             struct _mesa_glsl_parse_state *state)
7164bf215546Sopenharmony_ci{
7165bf215546Sopenharmony_ci   void *ctx = state;
7166bf215546Sopenharmony_ci
7167bf215546Sopenharmony_ci   /* For-loops and while-loops start a new scope, but do-while loops do not.
7168bf215546Sopenharmony_ci    */
7169bf215546Sopenharmony_ci   if (mode != ast_do_while)
7170bf215546Sopenharmony_ci      state->symbols->push_scope();
7171bf215546Sopenharmony_ci
7172bf215546Sopenharmony_ci   if (init_statement != NULL)
7173bf215546Sopenharmony_ci      init_statement->hir(instructions, state);
7174bf215546Sopenharmony_ci
7175bf215546Sopenharmony_ci   ir_loop *const stmt = new(ctx) ir_loop();
7176bf215546Sopenharmony_ci   instructions->push_tail(stmt);
7177bf215546Sopenharmony_ci
7178bf215546Sopenharmony_ci   /* Track the current loop nesting. */
7179bf215546Sopenharmony_ci   ast_iteration_statement *nesting_ast = state->loop_nesting_ast;
7180bf215546Sopenharmony_ci
7181bf215546Sopenharmony_ci   state->loop_nesting_ast = this;
7182bf215546Sopenharmony_ci
7183bf215546Sopenharmony_ci   /* Likewise, indicate that following code is closest to a loop,
7184bf215546Sopenharmony_ci    * NOT closest to a switch.
7185bf215546Sopenharmony_ci    */
7186bf215546Sopenharmony_ci   bool saved_is_switch_innermost = state->switch_state.is_switch_innermost;
7187bf215546Sopenharmony_ci   state->switch_state.is_switch_innermost = false;
7188bf215546Sopenharmony_ci
7189bf215546Sopenharmony_ci   if (mode != ast_do_while)
7190bf215546Sopenharmony_ci      condition_to_hir(&stmt->body_instructions, state);
7191bf215546Sopenharmony_ci
7192bf215546Sopenharmony_ci   if (rest_expression != NULL)
7193bf215546Sopenharmony_ci      rest_expression->hir(&rest_instructions, state);
7194bf215546Sopenharmony_ci
7195bf215546Sopenharmony_ci   if (body != NULL) {
7196bf215546Sopenharmony_ci      if (mode == ast_do_while)
7197bf215546Sopenharmony_ci         state->symbols->push_scope();
7198bf215546Sopenharmony_ci
7199bf215546Sopenharmony_ci      body->hir(& stmt->body_instructions, state);
7200bf215546Sopenharmony_ci
7201bf215546Sopenharmony_ci      if (mode == ast_do_while)
7202bf215546Sopenharmony_ci         state->symbols->pop_scope();
7203bf215546Sopenharmony_ci   }
7204bf215546Sopenharmony_ci
7205bf215546Sopenharmony_ci   if (rest_expression != NULL)
7206bf215546Sopenharmony_ci      stmt->body_instructions.append_list(&rest_instructions);
7207bf215546Sopenharmony_ci
7208bf215546Sopenharmony_ci   if (mode == ast_do_while)
7209bf215546Sopenharmony_ci      condition_to_hir(&stmt->body_instructions, state);
7210bf215546Sopenharmony_ci
7211bf215546Sopenharmony_ci   if (mode != ast_do_while)
7212bf215546Sopenharmony_ci      state->symbols->pop_scope();
7213bf215546Sopenharmony_ci
7214bf215546Sopenharmony_ci   /* Restore previous nesting before returning. */
7215bf215546Sopenharmony_ci   state->loop_nesting_ast = nesting_ast;
7216bf215546Sopenharmony_ci   state->switch_state.is_switch_innermost = saved_is_switch_innermost;
7217bf215546Sopenharmony_ci
7218bf215546Sopenharmony_ci   /* Loops do not have r-values.
7219bf215546Sopenharmony_ci    */
7220bf215546Sopenharmony_ci   return NULL;
7221bf215546Sopenharmony_ci}
7222bf215546Sopenharmony_ci
7223bf215546Sopenharmony_ci
7224bf215546Sopenharmony_ci/**
7225bf215546Sopenharmony_ci * Determine if the given type is valid for establishing a default precision
7226bf215546Sopenharmony_ci * qualifier.
7227bf215546Sopenharmony_ci *
7228bf215546Sopenharmony_ci * From GLSL ES 3.00 section 4.5.4 ("Default Precision Qualifiers"):
7229bf215546Sopenharmony_ci *
7230bf215546Sopenharmony_ci *     "The precision statement
7231bf215546Sopenharmony_ci *
7232bf215546Sopenharmony_ci *         precision precision-qualifier type;
7233bf215546Sopenharmony_ci *
7234bf215546Sopenharmony_ci *     can be used to establish a default precision qualifier. The type field
7235bf215546Sopenharmony_ci *     can be either int or float or any of the sampler types, and the
7236bf215546Sopenharmony_ci *     precision-qualifier can be lowp, mediump, or highp."
7237bf215546Sopenharmony_ci *
7238bf215546Sopenharmony_ci * GLSL ES 1.00 has similar language.  GLSL 1.30 doesn't allow precision
7239bf215546Sopenharmony_ci * qualifiers on sampler types, but this seems like an oversight (since the
7240bf215546Sopenharmony_ci * intention of including these in GLSL 1.30 is to allow compatibility with ES
7241bf215546Sopenharmony_ci * shaders).  So we allow int, float, and all sampler types regardless of GLSL
7242bf215546Sopenharmony_ci * version.
7243bf215546Sopenharmony_ci */
7244bf215546Sopenharmony_cistatic bool
7245bf215546Sopenharmony_ciis_valid_default_precision_type(const struct glsl_type *const type)
7246bf215546Sopenharmony_ci{
7247bf215546Sopenharmony_ci   if (type == NULL)
7248bf215546Sopenharmony_ci      return false;
7249bf215546Sopenharmony_ci
7250bf215546Sopenharmony_ci   switch (type->base_type) {
7251bf215546Sopenharmony_ci   case GLSL_TYPE_INT:
7252bf215546Sopenharmony_ci   case GLSL_TYPE_FLOAT:
7253bf215546Sopenharmony_ci      /* "int" and "float" are valid, but vectors and matrices are not. */
7254bf215546Sopenharmony_ci      return type->vector_elements == 1 && type->matrix_columns == 1;
7255bf215546Sopenharmony_ci   case GLSL_TYPE_SAMPLER:
7256bf215546Sopenharmony_ci   case GLSL_TYPE_TEXTURE:
7257bf215546Sopenharmony_ci   case GLSL_TYPE_IMAGE:
7258bf215546Sopenharmony_ci   case GLSL_TYPE_ATOMIC_UINT:
7259bf215546Sopenharmony_ci      return true;
7260bf215546Sopenharmony_ci   default:
7261bf215546Sopenharmony_ci      return false;
7262bf215546Sopenharmony_ci   }
7263bf215546Sopenharmony_ci}
7264bf215546Sopenharmony_ci
7265bf215546Sopenharmony_ci
7266bf215546Sopenharmony_ciir_rvalue *
7267bf215546Sopenharmony_ciast_type_specifier::hir(exec_list *instructions,
7268bf215546Sopenharmony_ci                        struct _mesa_glsl_parse_state *state)
7269bf215546Sopenharmony_ci{
7270bf215546Sopenharmony_ci   if (this->default_precision == ast_precision_none && this->structure == NULL)
7271bf215546Sopenharmony_ci      return NULL;
7272bf215546Sopenharmony_ci
7273bf215546Sopenharmony_ci   YYLTYPE loc = this->get_location();
7274bf215546Sopenharmony_ci
7275bf215546Sopenharmony_ci   /* If this is a precision statement, check that the type to which it is
7276bf215546Sopenharmony_ci    * applied is either float or int.
7277bf215546Sopenharmony_ci    *
7278bf215546Sopenharmony_ci    * From section 4.5.3 of the GLSL 1.30 spec:
7279bf215546Sopenharmony_ci    *    "The precision statement
7280bf215546Sopenharmony_ci    *       precision precision-qualifier type;
7281bf215546Sopenharmony_ci    *    can be used to establish a default precision qualifier. The type
7282bf215546Sopenharmony_ci    *    field can be either int or float [...].  Any other types or
7283bf215546Sopenharmony_ci    *    qualifiers will result in an error.
7284bf215546Sopenharmony_ci    */
7285bf215546Sopenharmony_ci   if (this->default_precision != ast_precision_none) {
7286bf215546Sopenharmony_ci      if (!state->check_precision_qualifiers_allowed(&loc))
7287bf215546Sopenharmony_ci         return NULL;
7288bf215546Sopenharmony_ci
7289bf215546Sopenharmony_ci      if (this->structure != NULL) {
7290bf215546Sopenharmony_ci         _mesa_glsl_error(&loc, state,
7291bf215546Sopenharmony_ci                          "precision qualifiers do not apply to structures");
7292bf215546Sopenharmony_ci         return NULL;
7293bf215546Sopenharmony_ci      }
7294bf215546Sopenharmony_ci
7295bf215546Sopenharmony_ci      if (this->array_specifier != NULL) {
7296bf215546Sopenharmony_ci         _mesa_glsl_error(&loc, state,
7297bf215546Sopenharmony_ci                          "default precision statements do not apply to "
7298bf215546Sopenharmony_ci                          "arrays");
7299bf215546Sopenharmony_ci         return NULL;
7300bf215546Sopenharmony_ci      }
7301bf215546Sopenharmony_ci
7302bf215546Sopenharmony_ci      const struct glsl_type *const type =
7303bf215546Sopenharmony_ci         state->symbols->get_type(this->type_name);
7304bf215546Sopenharmony_ci      if (!is_valid_default_precision_type(type)) {
7305bf215546Sopenharmony_ci         _mesa_glsl_error(&loc, state,
7306bf215546Sopenharmony_ci                          "default precision statements apply only to "
7307bf215546Sopenharmony_ci                          "float, int, and opaque types");
7308bf215546Sopenharmony_ci         return NULL;
7309bf215546Sopenharmony_ci      }
7310bf215546Sopenharmony_ci
7311bf215546Sopenharmony_ci      if (state->es_shader) {
7312bf215546Sopenharmony_ci         /* Section 4.5.3 (Default Precision Qualifiers) of the GLSL ES 1.00
7313bf215546Sopenharmony_ci          * spec says:
7314bf215546Sopenharmony_ci          *
7315bf215546Sopenharmony_ci          *     "Non-precision qualified declarations will use the precision
7316bf215546Sopenharmony_ci          *     qualifier specified in the most recent precision statement
7317bf215546Sopenharmony_ci          *     that is still in scope. The precision statement has the same
7318bf215546Sopenharmony_ci          *     scoping rules as variable declarations. If it is declared
7319bf215546Sopenharmony_ci          *     inside a compound statement, its effect stops at the end of
7320bf215546Sopenharmony_ci          *     the innermost statement it was declared in. Precision
7321bf215546Sopenharmony_ci          *     statements in nested scopes override precision statements in
7322bf215546Sopenharmony_ci          *     outer scopes. Multiple precision statements for the same basic
7323bf215546Sopenharmony_ci          *     type can appear inside the same scope, with later statements
7324bf215546Sopenharmony_ci          *     overriding earlier statements within that scope."
7325bf215546Sopenharmony_ci          *
7326bf215546Sopenharmony_ci          * Default precision specifications follow the same scope rules as
7327bf215546Sopenharmony_ci          * variables.  So, we can track the state of the default precision
7328bf215546Sopenharmony_ci          * qualifiers in the symbol table, and the rules will just work.  This
7329bf215546Sopenharmony_ci          * is a slight abuse of the symbol table, but it has the semantics
7330bf215546Sopenharmony_ci          * that we want.
7331bf215546Sopenharmony_ci          */
7332bf215546Sopenharmony_ci         state->symbols->add_default_precision_qualifier(this->type_name,
7333bf215546Sopenharmony_ci                                                         this->default_precision);
7334bf215546Sopenharmony_ci      }
7335bf215546Sopenharmony_ci
7336bf215546Sopenharmony_ci      /* FINISHME: Translate precision statements into IR. */
7337bf215546Sopenharmony_ci      return NULL;
7338bf215546Sopenharmony_ci   }
7339bf215546Sopenharmony_ci
7340bf215546Sopenharmony_ci   /* _mesa_ast_set_aggregate_type() sets the <structure> field so that
7341bf215546Sopenharmony_ci    * process_record_constructor() can do type-checking on C-style initializer
7342bf215546Sopenharmony_ci    * expressions of structs, but ast_struct_specifier should only be translated
7343bf215546Sopenharmony_ci    * to HIR if it is declaring the type of a structure.
7344bf215546Sopenharmony_ci    *
7345bf215546Sopenharmony_ci    * The ->is_declaration field is false for initializers of variables
7346bf215546Sopenharmony_ci    * declared separately from the struct's type definition.
7347bf215546Sopenharmony_ci    *
7348bf215546Sopenharmony_ci    *    struct S { ... };              (is_declaration = true)
7349bf215546Sopenharmony_ci    *    struct T { ... } t = { ... };  (is_declaration = true)
7350bf215546Sopenharmony_ci    *    S s = { ... };                 (is_declaration = false)
7351bf215546Sopenharmony_ci    */
7352bf215546Sopenharmony_ci   if (this->structure != NULL && this->structure->is_declaration)
7353bf215546Sopenharmony_ci      return this->structure->hir(instructions, state);
7354bf215546Sopenharmony_ci
7355bf215546Sopenharmony_ci   return NULL;
7356bf215546Sopenharmony_ci}
7357bf215546Sopenharmony_ci
7358bf215546Sopenharmony_ci
7359bf215546Sopenharmony_ci/**
7360bf215546Sopenharmony_ci * Process a structure or interface block tree into an array of structure fields
7361bf215546Sopenharmony_ci *
7362bf215546Sopenharmony_ci * After parsing, where there are some syntax differnces, structures and
7363bf215546Sopenharmony_ci * interface blocks are almost identical.  They are similar enough that the
7364bf215546Sopenharmony_ci * AST for each can be processed the same way into a set of
7365bf215546Sopenharmony_ci * \c glsl_struct_field to describe the members.
7366bf215546Sopenharmony_ci *
7367bf215546Sopenharmony_ci * If we're processing an interface block, var_mode should be the type of the
7368bf215546Sopenharmony_ci * interface block (ir_var_shader_in, ir_var_shader_out, ir_var_uniform or
7369bf215546Sopenharmony_ci * ir_var_shader_storage).  If we're processing a structure, var_mode should be
7370bf215546Sopenharmony_ci * ir_var_auto.
7371bf215546Sopenharmony_ci *
7372bf215546Sopenharmony_ci * \return
7373bf215546Sopenharmony_ci * The number of fields processed.  A pointer to the array structure fields is
7374bf215546Sopenharmony_ci * stored in \c *fields_ret.
7375bf215546Sopenharmony_ci */
7376bf215546Sopenharmony_cistatic unsigned
7377bf215546Sopenharmony_ciast_process_struct_or_iface_block_members(exec_list *instructions,
7378bf215546Sopenharmony_ci                                          struct _mesa_glsl_parse_state *state,
7379bf215546Sopenharmony_ci                                          exec_list *declarations,
7380bf215546Sopenharmony_ci                                          glsl_struct_field **fields_ret,
7381bf215546Sopenharmony_ci                                          bool is_interface,
7382bf215546Sopenharmony_ci                                          enum glsl_matrix_layout matrix_layout,
7383bf215546Sopenharmony_ci                                          bool allow_reserved_names,
7384bf215546Sopenharmony_ci                                          ir_variable_mode var_mode,
7385bf215546Sopenharmony_ci                                          ast_type_qualifier *layout,
7386bf215546Sopenharmony_ci                                          unsigned block_stream,
7387bf215546Sopenharmony_ci                                          unsigned block_xfb_buffer,
7388bf215546Sopenharmony_ci                                          unsigned block_xfb_offset,
7389bf215546Sopenharmony_ci                                          unsigned expl_location,
7390bf215546Sopenharmony_ci                                          unsigned expl_align)
7391bf215546Sopenharmony_ci{
7392bf215546Sopenharmony_ci   unsigned decl_count = 0;
7393bf215546Sopenharmony_ci   unsigned next_offset = 0;
7394bf215546Sopenharmony_ci
7395bf215546Sopenharmony_ci   /* Make an initial pass over the list of fields to determine how
7396bf215546Sopenharmony_ci    * many there are.  Each element in this list is an ast_declarator_list.
7397bf215546Sopenharmony_ci    * This means that we actually need to count the number of elements in the
7398bf215546Sopenharmony_ci    * 'declarations' list in each of the elements.
7399bf215546Sopenharmony_ci    */
7400bf215546Sopenharmony_ci   foreach_list_typed (ast_declarator_list, decl_list, link, declarations) {
7401bf215546Sopenharmony_ci      decl_count += decl_list->declarations.length();
7402bf215546Sopenharmony_ci   }
7403bf215546Sopenharmony_ci
7404bf215546Sopenharmony_ci   /* Allocate storage for the fields and process the field
7405bf215546Sopenharmony_ci    * declarations.  As the declarations are processed, try to also convert
7406bf215546Sopenharmony_ci    * the types to HIR.  This ensures that structure definitions embedded in
7407bf215546Sopenharmony_ci    * other structure definitions or in interface blocks are processed.
7408bf215546Sopenharmony_ci    */
7409bf215546Sopenharmony_ci   glsl_struct_field *const fields = rzalloc_array(state, glsl_struct_field,
7410bf215546Sopenharmony_ci                                                   decl_count);
7411bf215546Sopenharmony_ci
7412bf215546Sopenharmony_ci   bool first_member = true;
7413bf215546Sopenharmony_ci   bool first_member_has_explicit_location = false;
7414bf215546Sopenharmony_ci
7415bf215546Sopenharmony_ci   unsigned i = 0;
7416bf215546Sopenharmony_ci   foreach_list_typed (ast_declarator_list, decl_list, link, declarations) {
7417bf215546Sopenharmony_ci      const char *type_name;
7418bf215546Sopenharmony_ci      YYLTYPE loc = decl_list->get_location();
7419bf215546Sopenharmony_ci
7420bf215546Sopenharmony_ci      decl_list->type->specifier->hir(instructions, state);
7421bf215546Sopenharmony_ci
7422bf215546Sopenharmony_ci      /* Section 4.1.8 (Structures) of the GLSL 1.10 spec says:
7423bf215546Sopenharmony_ci       *
7424bf215546Sopenharmony_ci       *    "Anonymous structures are not supported; so embedded structures
7425bf215546Sopenharmony_ci       *    must have a declarator. A name given to an embedded struct is
7426bf215546Sopenharmony_ci       *    scoped at the same level as the struct it is embedded in."
7427bf215546Sopenharmony_ci       *
7428bf215546Sopenharmony_ci       * The same section of the  GLSL 1.20 spec says:
7429bf215546Sopenharmony_ci       *
7430bf215546Sopenharmony_ci       *    "Anonymous structures are not supported. Embedded structures are
7431bf215546Sopenharmony_ci       *    not supported."
7432bf215546Sopenharmony_ci       *
7433bf215546Sopenharmony_ci       * The GLSL ES 1.00 and 3.00 specs have similar langauge. So, we allow
7434bf215546Sopenharmony_ci       * embedded structures in 1.10 only.
7435bf215546Sopenharmony_ci       */
7436bf215546Sopenharmony_ci      if (state->language_version != 110 &&
7437bf215546Sopenharmony_ci          decl_list->type->specifier->structure != NULL)
7438bf215546Sopenharmony_ci         _mesa_glsl_error(&loc, state,
7439bf215546Sopenharmony_ci                          "embedded structure declarations are not allowed");
7440bf215546Sopenharmony_ci
7441bf215546Sopenharmony_ci      const glsl_type *decl_type =
7442bf215546Sopenharmony_ci         decl_list->type->glsl_type(& type_name, state);
7443bf215546Sopenharmony_ci
7444bf215546Sopenharmony_ci      const struct ast_type_qualifier *const qual =
7445bf215546Sopenharmony_ci         &decl_list->type->qualifier;
7446bf215546Sopenharmony_ci
7447bf215546Sopenharmony_ci      /* From section 4.3.9 of the GLSL 4.40 spec:
7448bf215546Sopenharmony_ci       *
7449bf215546Sopenharmony_ci       *    "[In interface blocks] opaque types are not allowed."
7450bf215546Sopenharmony_ci       *
7451bf215546Sopenharmony_ci       * It should be impossible for decl_type to be NULL here.  Cases that
7452bf215546Sopenharmony_ci       * might naturally lead to decl_type being NULL, especially for the
7453bf215546Sopenharmony_ci       * is_interface case, will have resulted in compilation having
7454bf215546Sopenharmony_ci       * already halted due to a syntax error.
7455bf215546Sopenharmony_ci       */
7456bf215546Sopenharmony_ci      assert(decl_type);
7457bf215546Sopenharmony_ci
7458bf215546Sopenharmony_ci      if (is_interface) {
7459bf215546Sopenharmony_ci         /* From section 4.3.7 of the ARB_bindless_texture spec:
7460bf215546Sopenharmony_ci          *
7461bf215546Sopenharmony_ci          *    "(remove the following bullet from the last list on p. 39,
7462bf215546Sopenharmony_ci          *     thereby permitting sampler types in interface blocks; image
7463bf215546Sopenharmony_ci          *     types are also permitted in blocks by this extension)"
7464bf215546Sopenharmony_ci          *
7465bf215546Sopenharmony_ci          *     * sampler types are not allowed
7466bf215546Sopenharmony_ci          */
7467bf215546Sopenharmony_ci         if (decl_type->contains_atomic() ||
7468bf215546Sopenharmony_ci             (!state->has_bindless() && decl_type->contains_opaque())) {
7469bf215546Sopenharmony_ci            _mesa_glsl_error(&loc, state, "uniform/buffer in non-default "
7470bf215546Sopenharmony_ci                             "interface block contains %s variable",
7471bf215546Sopenharmony_ci                             state->has_bindless() ? "atomic" : "opaque");
7472bf215546Sopenharmony_ci         }
7473bf215546Sopenharmony_ci      } else {
7474bf215546Sopenharmony_ci         if (decl_type->contains_atomic()) {
7475bf215546Sopenharmony_ci            /* From section 4.1.7.3 of the GLSL 4.40 spec:
7476bf215546Sopenharmony_ci             *
7477bf215546Sopenharmony_ci             *    "Members of structures cannot be declared as atomic counter
7478bf215546Sopenharmony_ci             *     types."
7479bf215546Sopenharmony_ci             */
7480bf215546Sopenharmony_ci            _mesa_glsl_error(&loc, state, "atomic counter in structure");
7481bf215546Sopenharmony_ci         }
7482bf215546Sopenharmony_ci
7483bf215546Sopenharmony_ci         if (!state->has_bindless() && decl_type->contains_image()) {
7484bf215546Sopenharmony_ci            /* FINISHME: Same problem as with atomic counters.
7485bf215546Sopenharmony_ci             * FINISHME: Request clarification from Khronos and add
7486bf215546Sopenharmony_ci             * FINISHME: spec quotation here.
7487bf215546Sopenharmony_ci             */
7488bf215546Sopenharmony_ci            _mesa_glsl_error(&loc, state, "image in structure");
7489bf215546Sopenharmony_ci         }
7490bf215546Sopenharmony_ci      }
7491bf215546Sopenharmony_ci
7492bf215546Sopenharmony_ci      if (qual->flags.q.explicit_binding) {
7493bf215546Sopenharmony_ci         _mesa_glsl_error(&loc, state,
7494bf215546Sopenharmony_ci                          "binding layout qualifier cannot be applied "
7495bf215546Sopenharmony_ci                          "to struct or interface block members");
7496bf215546Sopenharmony_ci      }
7497bf215546Sopenharmony_ci
7498bf215546Sopenharmony_ci      if (is_interface) {
7499bf215546Sopenharmony_ci         if (!first_member) {
7500bf215546Sopenharmony_ci            if (!layout->flags.q.explicit_location &&
7501bf215546Sopenharmony_ci                ((first_member_has_explicit_location &&
7502bf215546Sopenharmony_ci                  !qual->flags.q.explicit_location) ||
7503bf215546Sopenharmony_ci                 (!first_member_has_explicit_location &&
7504bf215546Sopenharmony_ci                  qual->flags.q.explicit_location))) {
7505bf215546Sopenharmony_ci               _mesa_glsl_error(&loc, state,
7506bf215546Sopenharmony_ci                                "when block-level location layout qualifier "
7507bf215546Sopenharmony_ci                                "is not supplied either all members must "
7508bf215546Sopenharmony_ci                                "have a location layout qualifier or all "
7509bf215546Sopenharmony_ci                                "members must not have a location layout "
7510bf215546Sopenharmony_ci                                "qualifier");
7511bf215546Sopenharmony_ci            }
7512bf215546Sopenharmony_ci         } else {
7513bf215546Sopenharmony_ci            first_member = false;
7514bf215546Sopenharmony_ci            first_member_has_explicit_location =
7515bf215546Sopenharmony_ci               qual->flags.q.explicit_location;
7516bf215546Sopenharmony_ci         }
7517bf215546Sopenharmony_ci      }
7518bf215546Sopenharmony_ci
7519bf215546Sopenharmony_ci      if (qual->flags.q.std140 ||
7520bf215546Sopenharmony_ci          qual->flags.q.std430 ||
7521bf215546Sopenharmony_ci          qual->flags.q.packed ||
7522bf215546Sopenharmony_ci          qual->flags.q.shared) {
7523bf215546Sopenharmony_ci         _mesa_glsl_error(&loc, state,
7524bf215546Sopenharmony_ci                          "uniform/shader storage block layout qualifiers "
7525bf215546Sopenharmony_ci                          "std140, std430, packed, and shared can only be "
7526bf215546Sopenharmony_ci                          "applied to uniform/shader storage blocks, not "
7527bf215546Sopenharmony_ci                          "members");
7528bf215546Sopenharmony_ci      }
7529bf215546Sopenharmony_ci
7530bf215546Sopenharmony_ci      if (qual->flags.q.constant) {
7531bf215546Sopenharmony_ci         _mesa_glsl_error(&loc, state,
7532bf215546Sopenharmony_ci                          "const storage qualifier cannot be applied "
7533bf215546Sopenharmony_ci                          "to struct or interface block members");
7534bf215546Sopenharmony_ci      }
7535bf215546Sopenharmony_ci
7536bf215546Sopenharmony_ci      validate_memory_qualifier_for_type(state, &loc, qual, decl_type);
7537bf215546Sopenharmony_ci      validate_image_format_qualifier_for_type(state, &loc, qual, decl_type);
7538bf215546Sopenharmony_ci
7539bf215546Sopenharmony_ci      /* From Section 4.4.2.3 (Geometry Outputs) of the GLSL 4.50 spec:
7540bf215546Sopenharmony_ci       *
7541bf215546Sopenharmony_ci       *   "A block member may be declared with a stream identifier, but
7542bf215546Sopenharmony_ci       *   the specified stream must match the stream associated with the
7543bf215546Sopenharmony_ci       *   containing block."
7544bf215546Sopenharmony_ci       */
7545bf215546Sopenharmony_ci      if (qual->flags.q.explicit_stream) {
7546bf215546Sopenharmony_ci         unsigned qual_stream;
7547bf215546Sopenharmony_ci         if (process_qualifier_constant(state, &loc, "stream",
7548bf215546Sopenharmony_ci                                        qual->stream, &qual_stream) &&
7549bf215546Sopenharmony_ci             qual_stream != block_stream) {
7550bf215546Sopenharmony_ci            _mesa_glsl_error(&loc, state, "stream layout qualifier on "
7551bf215546Sopenharmony_ci                             "interface block member does not match "
7552bf215546Sopenharmony_ci                             "the interface block (%u vs %u)", qual_stream,
7553bf215546Sopenharmony_ci                             block_stream);
7554bf215546Sopenharmony_ci         }
7555bf215546Sopenharmony_ci      }
7556bf215546Sopenharmony_ci
7557bf215546Sopenharmony_ci      int xfb_buffer;
7558bf215546Sopenharmony_ci      unsigned explicit_xfb_buffer = 0;
7559bf215546Sopenharmony_ci      if (qual->flags.q.explicit_xfb_buffer) {
7560bf215546Sopenharmony_ci         unsigned qual_xfb_buffer;
7561bf215546Sopenharmony_ci         if (process_qualifier_constant(state, &loc, "xfb_buffer",
7562bf215546Sopenharmony_ci                                        qual->xfb_buffer, &qual_xfb_buffer)) {
7563bf215546Sopenharmony_ci            explicit_xfb_buffer = 1;
7564bf215546Sopenharmony_ci            if (qual_xfb_buffer != block_xfb_buffer)
7565bf215546Sopenharmony_ci               _mesa_glsl_error(&loc, state, "xfb_buffer layout qualifier on "
7566bf215546Sopenharmony_ci                                "interface block member does not match "
7567bf215546Sopenharmony_ci                                "the interface block (%u vs %u)",
7568bf215546Sopenharmony_ci                                qual_xfb_buffer, block_xfb_buffer);
7569bf215546Sopenharmony_ci         }
7570bf215546Sopenharmony_ci         xfb_buffer = (int) qual_xfb_buffer;
7571bf215546Sopenharmony_ci      } else {
7572bf215546Sopenharmony_ci         if (layout)
7573bf215546Sopenharmony_ci            explicit_xfb_buffer = layout->flags.q.explicit_xfb_buffer;
7574bf215546Sopenharmony_ci         xfb_buffer = (int) block_xfb_buffer;
7575bf215546Sopenharmony_ci      }
7576bf215546Sopenharmony_ci
7577bf215546Sopenharmony_ci      int xfb_stride = -1;
7578bf215546Sopenharmony_ci      if (qual->flags.q.explicit_xfb_stride) {
7579bf215546Sopenharmony_ci         unsigned qual_xfb_stride;
7580bf215546Sopenharmony_ci         if (process_qualifier_constant(state, &loc, "xfb_stride",
7581bf215546Sopenharmony_ci                                        qual->xfb_stride, &qual_xfb_stride)) {
7582bf215546Sopenharmony_ci            xfb_stride = (int) qual_xfb_stride;
7583bf215546Sopenharmony_ci         }
7584bf215546Sopenharmony_ci      }
7585bf215546Sopenharmony_ci
7586bf215546Sopenharmony_ci      if (qual->flags.q.uniform && qual->has_interpolation()) {
7587bf215546Sopenharmony_ci         _mesa_glsl_error(&loc, state,
7588bf215546Sopenharmony_ci                          "interpolation qualifiers cannot be used "
7589bf215546Sopenharmony_ci                          "with uniform interface blocks");
7590bf215546Sopenharmony_ci      }
7591bf215546Sopenharmony_ci
7592bf215546Sopenharmony_ci      if ((qual->flags.q.uniform || !is_interface) &&
7593bf215546Sopenharmony_ci          qual->has_auxiliary_storage()) {
7594bf215546Sopenharmony_ci         _mesa_glsl_error(&loc, state,
7595bf215546Sopenharmony_ci                          "auxiliary storage qualifiers cannot be used "
7596bf215546Sopenharmony_ci                          "in uniform blocks or structures.");
7597bf215546Sopenharmony_ci      }
7598bf215546Sopenharmony_ci
7599bf215546Sopenharmony_ci      if (qual->flags.q.row_major || qual->flags.q.column_major) {
7600bf215546Sopenharmony_ci         if (!qual->flags.q.uniform && !qual->flags.q.buffer) {
7601bf215546Sopenharmony_ci            _mesa_glsl_error(&loc, state,
7602bf215546Sopenharmony_ci                             "row_major and column_major can only be "
7603bf215546Sopenharmony_ci                             "applied to interface blocks");
7604bf215546Sopenharmony_ci         } else
7605bf215546Sopenharmony_ci            validate_matrix_layout_for_type(state, &loc, decl_type, NULL);
7606bf215546Sopenharmony_ci      }
7607bf215546Sopenharmony_ci
7608bf215546Sopenharmony_ci      foreach_list_typed (ast_declaration, decl, link,
7609bf215546Sopenharmony_ci                          &decl_list->declarations) {
7610bf215546Sopenharmony_ci         YYLTYPE loc = decl->get_location();
7611bf215546Sopenharmony_ci
7612bf215546Sopenharmony_ci         if (!allow_reserved_names)
7613bf215546Sopenharmony_ci            validate_identifier(decl->identifier, loc, state);
7614bf215546Sopenharmony_ci
7615bf215546Sopenharmony_ci         const struct glsl_type *field_type =
7616bf215546Sopenharmony_ci            process_array_type(&loc, decl_type, decl->array_specifier, state);
7617bf215546Sopenharmony_ci         validate_array_dimensions(field_type, state, &loc);
7618bf215546Sopenharmony_ci         fields[i].type = field_type;
7619bf215546Sopenharmony_ci         fields[i].name = decl->identifier;
7620bf215546Sopenharmony_ci         fields[i].interpolation =
7621bf215546Sopenharmony_ci            interpret_interpolation_qualifier(qual, field_type,
7622bf215546Sopenharmony_ci                                              var_mode, state, &loc);
7623bf215546Sopenharmony_ci         fields[i].centroid = qual->flags.q.centroid ? 1 : 0;
7624bf215546Sopenharmony_ci         fields[i].sample = qual->flags.q.sample ? 1 : 0;
7625bf215546Sopenharmony_ci         fields[i].patch = qual->flags.q.patch ? 1 : 0;
7626bf215546Sopenharmony_ci         fields[i].offset = -1;
7627bf215546Sopenharmony_ci         fields[i].explicit_xfb_buffer = explicit_xfb_buffer;
7628bf215546Sopenharmony_ci         fields[i].xfb_buffer = xfb_buffer;
7629bf215546Sopenharmony_ci         fields[i].xfb_stride = xfb_stride;
7630bf215546Sopenharmony_ci
7631bf215546Sopenharmony_ci         if (qual->flags.q.explicit_location) {
7632bf215546Sopenharmony_ci            unsigned qual_location;
7633bf215546Sopenharmony_ci            if (process_qualifier_constant(state, &loc, "location",
7634bf215546Sopenharmony_ci                                           qual->location, &qual_location)) {
7635bf215546Sopenharmony_ci               fields[i].location = qual_location +
7636bf215546Sopenharmony_ci                  (fields[i].patch ? VARYING_SLOT_PATCH0 : VARYING_SLOT_VAR0);
7637bf215546Sopenharmony_ci               expl_location = fields[i].location +
7638bf215546Sopenharmony_ci                  fields[i].type->count_attribute_slots(false);
7639bf215546Sopenharmony_ci            }
7640bf215546Sopenharmony_ci         } else {
7641bf215546Sopenharmony_ci            if (layout && layout->flags.q.explicit_location) {
7642bf215546Sopenharmony_ci               fields[i].location = expl_location;
7643bf215546Sopenharmony_ci               expl_location += fields[i].type->count_attribute_slots(false);
7644bf215546Sopenharmony_ci            } else {
7645bf215546Sopenharmony_ci               fields[i].location = -1;
7646bf215546Sopenharmony_ci            }
7647bf215546Sopenharmony_ci         }
7648bf215546Sopenharmony_ci
7649bf215546Sopenharmony_ci         if (qual->flags.q.explicit_component) {
7650bf215546Sopenharmony_ci            unsigned qual_component;
7651bf215546Sopenharmony_ci            if (process_qualifier_constant(state, &loc, "component",
7652bf215546Sopenharmony_ci                                           qual->component, &qual_component)) {
7653bf215546Sopenharmony_ci               validate_component_layout_for_type(state, &loc, fields[i].type,
7654bf215546Sopenharmony_ci                                                  qual_component);
7655bf215546Sopenharmony_ci               fields[i].component = qual_component;
7656bf215546Sopenharmony_ci            }
7657bf215546Sopenharmony_ci         } else {
7658bf215546Sopenharmony_ci            fields[i].component = -1;
7659bf215546Sopenharmony_ci         }
7660bf215546Sopenharmony_ci
7661bf215546Sopenharmony_ci         /* Offset can only be used with std430 and std140 layouts an initial
7662bf215546Sopenharmony_ci          * value of 0 is used for error detection.
7663bf215546Sopenharmony_ci          */
7664bf215546Sopenharmony_ci         unsigned align = 0;
7665bf215546Sopenharmony_ci         unsigned size = 0;
7666bf215546Sopenharmony_ci         if (layout) {
7667bf215546Sopenharmony_ci            bool row_major;
7668bf215546Sopenharmony_ci            if (qual->flags.q.row_major ||
7669bf215546Sopenharmony_ci                matrix_layout == GLSL_MATRIX_LAYOUT_ROW_MAJOR) {
7670bf215546Sopenharmony_ci               row_major = true;
7671bf215546Sopenharmony_ci            } else {
7672bf215546Sopenharmony_ci               row_major = false;
7673bf215546Sopenharmony_ci            }
7674bf215546Sopenharmony_ci
7675bf215546Sopenharmony_ci            if(layout->flags.q.std140) {
7676bf215546Sopenharmony_ci               align = field_type->std140_base_alignment(row_major);
7677bf215546Sopenharmony_ci               size = field_type->std140_size(row_major);
7678bf215546Sopenharmony_ci            } else if (layout->flags.q.std430) {
7679bf215546Sopenharmony_ci               align = field_type->std430_base_alignment(row_major);
7680bf215546Sopenharmony_ci               size = field_type->std430_size(row_major);
7681bf215546Sopenharmony_ci            }
7682bf215546Sopenharmony_ci         }
7683bf215546Sopenharmony_ci
7684bf215546Sopenharmony_ci         if (qual->flags.q.explicit_offset) {
7685bf215546Sopenharmony_ci            unsigned qual_offset;
7686bf215546Sopenharmony_ci            if (process_qualifier_constant(state, &loc, "offset",
7687bf215546Sopenharmony_ci                                           qual->offset, &qual_offset)) {
7688bf215546Sopenharmony_ci               if (align != 0 && size != 0) {
7689bf215546Sopenharmony_ci                   if (next_offset > qual_offset)
7690bf215546Sopenharmony_ci                      _mesa_glsl_error(&loc, state, "layout qualifier "
7691bf215546Sopenharmony_ci                                       "offset overlaps previous member");
7692bf215546Sopenharmony_ci
7693bf215546Sopenharmony_ci                  if (qual_offset % align) {
7694bf215546Sopenharmony_ci                     _mesa_glsl_error(&loc, state, "layout qualifier offset "
7695bf215546Sopenharmony_ci                                      "must be a multiple of the base "
7696bf215546Sopenharmony_ci                                      "alignment of %s", field_type->name);
7697bf215546Sopenharmony_ci                  }
7698bf215546Sopenharmony_ci                  fields[i].offset = qual_offset;
7699bf215546Sopenharmony_ci                  next_offset = qual_offset + size;
7700bf215546Sopenharmony_ci               } else {
7701bf215546Sopenharmony_ci                  _mesa_glsl_error(&loc, state, "offset can only be used "
7702bf215546Sopenharmony_ci                                   "with std430 and std140 layouts");
7703bf215546Sopenharmony_ci               }
7704bf215546Sopenharmony_ci            }
7705bf215546Sopenharmony_ci         }
7706bf215546Sopenharmony_ci
7707bf215546Sopenharmony_ci         if (qual->flags.q.explicit_align || expl_align != 0) {
7708bf215546Sopenharmony_ci            unsigned offset = fields[i].offset != -1 ? fields[i].offset :
7709bf215546Sopenharmony_ci               next_offset;
7710bf215546Sopenharmony_ci            if (align == 0 || size == 0) {
7711bf215546Sopenharmony_ci               _mesa_glsl_error(&loc, state, "align can only be used with "
7712bf215546Sopenharmony_ci                                "std430 and std140 layouts");
7713bf215546Sopenharmony_ci            } else if (qual->flags.q.explicit_align) {
7714bf215546Sopenharmony_ci               unsigned member_align;
7715bf215546Sopenharmony_ci               if (process_qualifier_constant(state, &loc, "align",
7716bf215546Sopenharmony_ci                                              qual->align, &member_align)) {
7717bf215546Sopenharmony_ci                  if (member_align == 0 ||
7718bf215546Sopenharmony_ci                      member_align & (member_align - 1)) {
7719bf215546Sopenharmony_ci                     _mesa_glsl_error(&loc, state, "align layout qualifier "
7720bf215546Sopenharmony_ci                                      "is not a power of 2");
7721bf215546Sopenharmony_ci                  } else {
7722bf215546Sopenharmony_ci                     fields[i].offset = glsl_align(offset, member_align);
7723bf215546Sopenharmony_ci                     next_offset = fields[i].offset + size;
7724bf215546Sopenharmony_ci                  }
7725bf215546Sopenharmony_ci               }
7726bf215546Sopenharmony_ci            } else {
7727bf215546Sopenharmony_ci               fields[i].offset = glsl_align(offset, expl_align);
7728bf215546Sopenharmony_ci               next_offset = fields[i].offset + size;
7729bf215546Sopenharmony_ci            }
7730bf215546Sopenharmony_ci         } else if (!qual->flags.q.explicit_offset) {
7731bf215546Sopenharmony_ci            if (align != 0 && size != 0)
7732bf215546Sopenharmony_ci               next_offset = glsl_align(next_offset, align) + size;
7733bf215546Sopenharmony_ci         }
7734bf215546Sopenharmony_ci
7735bf215546Sopenharmony_ci         /* From the ARB_enhanced_layouts spec:
7736bf215546Sopenharmony_ci          *
7737bf215546Sopenharmony_ci          *    "The given offset applies to the first component of the first
7738bf215546Sopenharmony_ci          *    member of the qualified entity.  Then, within the qualified
7739bf215546Sopenharmony_ci          *    entity, subsequent components are each assigned, in order, to
7740bf215546Sopenharmony_ci          *    the next available offset aligned to a multiple of that
7741bf215546Sopenharmony_ci          *    component's size.  Aggregate types are flattened down to the
7742bf215546Sopenharmony_ci          *    component level to get this sequence of components."
7743bf215546Sopenharmony_ci          */
7744bf215546Sopenharmony_ci         if (qual->flags.q.explicit_xfb_offset) {
7745bf215546Sopenharmony_ci            unsigned xfb_offset;
7746bf215546Sopenharmony_ci            if (process_qualifier_constant(state, &loc, "xfb_offset",
7747bf215546Sopenharmony_ci                                           qual->offset, &xfb_offset)) {
7748bf215546Sopenharmony_ci               fields[i].offset = xfb_offset;
7749bf215546Sopenharmony_ci               block_xfb_offset = fields[i].offset +
7750bf215546Sopenharmony_ci                  4 * field_type->component_slots();
7751bf215546Sopenharmony_ci            }
7752bf215546Sopenharmony_ci         } else {
7753bf215546Sopenharmony_ci            if (layout && layout->flags.q.explicit_xfb_offset) {
7754bf215546Sopenharmony_ci               unsigned align = field_type->is_64bit() ? 8 : 4;
7755bf215546Sopenharmony_ci               fields[i].offset = glsl_align(block_xfb_offset, align);
7756bf215546Sopenharmony_ci               block_xfb_offset += 4 * field_type->component_slots();
7757bf215546Sopenharmony_ci            }
7758bf215546Sopenharmony_ci         }
7759bf215546Sopenharmony_ci
7760bf215546Sopenharmony_ci         /* Propogate row- / column-major information down the fields of the
7761bf215546Sopenharmony_ci          * structure or interface block.  Structures need this data because
7762bf215546Sopenharmony_ci          * the structure may contain a structure that contains ... a matrix
7763bf215546Sopenharmony_ci          * that need the proper layout.
7764bf215546Sopenharmony_ci          */
7765bf215546Sopenharmony_ci         if (is_interface && layout &&
7766bf215546Sopenharmony_ci             (layout->flags.q.uniform || layout->flags.q.buffer) &&
7767bf215546Sopenharmony_ci             (field_type->without_array()->is_matrix()
7768bf215546Sopenharmony_ci              || field_type->without_array()->is_struct())) {
7769bf215546Sopenharmony_ci            /* If no layout is specified for the field, inherit the layout
7770bf215546Sopenharmony_ci             * from the block.
7771bf215546Sopenharmony_ci             */
7772bf215546Sopenharmony_ci            fields[i].matrix_layout = matrix_layout;
7773bf215546Sopenharmony_ci
7774bf215546Sopenharmony_ci            if (qual->flags.q.row_major)
7775bf215546Sopenharmony_ci               fields[i].matrix_layout = GLSL_MATRIX_LAYOUT_ROW_MAJOR;
7776bf215546Sopenharmony_ci            else if (qual->flags.q.column_major)
7777bf215546Sopenharmony_ci               fields[i].matrix_layout = GLSL_MATRIX_LAYOUT_COLUMN_MAJOR;
7778bf215546Sopenharmony_ci
7779bf215546Sopenharmony_ci            /* If we're processing an uniform or buffer block, the matrix
7780bf215546Sopenharmony_ci             * layout must be decided by this point.
7781bf215546Sopenharmony_ci             */
7782bf215546Sopenharmony_ci            assert(fields[i].matrix_layout == GLSL_MATRIX_LAYOUT_ROW_MAJOR
7783bf215546Sopenharmony_ci                   || fields[i].matrix_layout == GLSL_MATRIX_LAYOUT_COLUMN_MAJOR);
7784bf215546Sopenharmony_ci         }
7785bf215546Sopenharmony_ci
7786bf215546Sopenharmony_ci         /* Memory qualifiers are allowed on buffer and image variables, while
7787bf215546Sopenharmony_ci          * the format qualifier is only accepted for images.
7788bf215546Sopenharmony_ci          */
7789bf215546Sopenharmony_ci         if (var_mode == ir_var_shader_storage ||
7790bf215546Sopenharmony_ci             field_type->without_array()->is_image()) {
7791bf215546Sopenharmony_ci            /* For readonly and writeonly qualifiers the field definition,
7792bf215546Sopenharmony_ci             * if set, overwrites the layout qualifier.
7793bf215546Sopenharmony_ci             */
7794bf215546Sopenharmony_ci            if (qual->flags.q.read_only || qual->flags.q.write_only) {
7795bf215546Sopenharmony_ci               fields[i].memory_read_only = qual->flags.q.read_only;
7796bf215546Sopenharmony_ci               fields[i].memory_write_only = qual->flags.q.write_only;
7797bf215546Sopenharmony_ci            } else {
7798bf215546Sopenharmony_ci               fields[i].memory_read_only =
7799bf215546Sopenharmony_ci                  layout ? layout->flags.q.read_only : 0;
7800bf215546Sopenharmony_ci               fields[i].memory_write_only =
7801bf215546Sopenharmony_ci                  layout ? layout->flags.q.write_only : 0;
7802bf215546Sopenharmony_ci            }
7803bf215546Sopenharmony_ci
7804bf215546Sopenharmony_ci            /* For other qualifiers, we set the flag if either the layout
7805bf215546Sopenharmony_ci             * qualifier or the field qualifier are set
7806bf215546Sopenharmony_ci             */
7807bf215546Sopenharmony_ci            fields[i].memory_coherent = qual->flags.q.coherent ||
7808bf215546Sopenharmony_ci                                        (layout && layout->flags.q.coherent);
7809bf215546Sopenharmony_ci            fields[i].memory_volatile = qual->flags.q._volatile ||
7810bf215546Sopenharmony_ci                                        (layout && layout->flags.q._volatile);
7811bf215546Sopenharmony_ci            fields[i].memory_restrict = qual->flags.q.restrict_flag ||
7812bf215546Sopenharmony_ci                                        (layout && layout->flags.q.restrict_flag);
7813bf215546Sopenharmony_ci
7814bf215546Sopenharmony_ci            if (field_type->without_array()->is_image()) {
7815bf215546Sopenharmony_ci               if (qual->flags.q.explicit_image_format) {
7816bf215546Sopenharmony_ci                  if (qual->image_base_type !=
7817bf215546Sopenharmony_ci                      field_type->without_array()->sampled_type) {
7818bf215546Sopenharmony_ci                     _mesa_glsl_error(&loc, state, "format qualifier doesn't "
7819bf215546Sopenharmony_ci                                      "match the base data type of the image");
7820bf215546Sopenharmony_ci                  }
7821bf215546Sopenharmony_ci
7822bf215546Sopenharmony_ci                  fields[i].image_format = qual->image_format;
7823bf215546Sopenharmony_ci               } else {
7824bf215546Sopenharmony_ci                  if (!qual->flags.q.write_only) {
7825bf215546Sopenharmony_ci                     _mesa_glsl_error(&loc, state, "image not qualified with "
7826bf215546Sopenharmony_ci                                      "`writeonly' must have a format layout "
7827bf215546Sopenharmony_ci                                      "qualifier");
7828bf215546Sopenharmony_ci                  }
7829bf215546Sopenharmony_ci
7830bf215546Sopenharmony_ci                  fields[i].image_format = PIPE_FORMAT_NONE;
7831bf215546Sopenharmony_ci               }
7832bf215546Sopenharmony_ci            }
7833bf215546Sopenharmony_ci         }
7834bf215546Sopenharmony_ci
7835bf215546Sopenharmony_ci         /* Precision qualifiers do not hold any meaning in Desktop GLSL */
7836bf215546Sopenharmony_ci         if (state->es_shader) {
7837bf215546Sopenharmony_ci            fields[i].precision = select_gles_precision(qual->precision,
7838bf215546Sopenharmony_ci                                                        field_type,
7839bf215546Sopenharmony_ci                                                        state,
7840bf215546Sopenharmony_ci                                                        &loc);
7841bf215546Sopenharmony_ci         } else {
7842bf215546Sopenharmony_ci            fields[i].precision = qual->precision;
7843bf215546Sopenharmony_ci         }
7844bf215546Sopenharmony_ci
7845bf215546Sopenharmony_ci         i++;
7846bf215546Sopenharmony_ci      }
7847bf215546Sopenharmony_ci   }
7848bf215546Sopenharmony_ci
7849bf215546Sopenharmony_ci   assert(i == decl_count);
7850bf215546Sopenharmony_ci
7851bf215546Sopenharmony_ci   *fields_ret = fields;
7852bf215546Sopenharmony_ci   return decl_count;
7853bf215546Sopenharmony_ci}
7854bf215546Sopenharmony_ci
7855bf215546Sopenharmony_ci
7856bf215546Sopenharmony_ciir_rvalue *
7857bf215546Sopenharmony_ciast_struct_specifier::hir(exec_list *instructions,
7858bf215546Sopenharmony_ci                          struct _mesa_glsl_parse_state *state)
7859bf215546Sopenharmony_ci{
7860bf215546Sopenharmony_ci   YYLTYPE loc = this->get_location();
7861bf215546Sopenharmony_ci
7862bf215546Sopenharmony_ci   unsigned expl_location = 0;
7863bf215546Sopenharmony_ci   if (layout && layout->flags.q.explicit_location) {
7864bf215546Sopenharmony_ci      if (!process_qualifier_constant(state, &loc, "location",
7865bf215546Sopenharmony_ci                                      layout->location, &expl_location)) {
7866bf215546Sopenharmony_ci         return NULL;
7867bf215546Sopenharmony_ci      } else {
7868bf215546Sopenharmony_ci         expl_location = VARYING_SLOT_VAR0 + expl_location;
7869bf215546Sopenharmony_ci      }
7870bf215546Sopenharmony_ci   }
7871bf215546Sopenharmony_ci
7872bf215546Sopenharmony_ci   glsl_struct_field *fields;
7873bf215546Sopenharmony_ci   unsigned decl_count =
7874bf215546Sopenharmony_ci      ast_process_struct_or_iface_block_members(instructions,
7875bf215546Sopenharmony_ci                                                state,
7876bf215546Sopenharmony_ci                                                &this->declarations,
7877bf215546Sopenharmony_ci                                                &fields,
7878bf215546Sopenharmony_ci                                                false,
7879bf215546Sopenharmony_ci                                                GLSL_MATRIX_LAYOUT_INHERITED,
7880bf215546Sopenharmony_ci                                                false /* allow_reserved_names */,
7881bf215546Sopenharmony_ci                                                ir_var_auto,
7882bf215546Sopenharmony_ci                                                layout,
7883bf215546Sopenharmony_ci                                                0, /* for interface only */
7884bf215546Sopenharmony_ci                                                0, /* for interface only */
7885bf215546Sopenharmony_ci                                                0, /* for interface only */
7886bf215546Sopenharmony_ci                                                expl_location,
7887bf215546Sopenharmony_ci                                                0 /* for interface only */);
7888bf215546Sopenharmony_ci
7889bf215546Sopenharmony_ci   validate_identifier(this->name, loc, state);
7890bf215546Sopenharmony_ci
7891bf215546Sopenharmony_ci   type = glsl_type::get_struct_instance(fields, decl_count, this->name);
7892bf215546Sopenharmony_ci
7893bf215546Sopenharmony_ci   if (!type->is_anonymous() && !state->symbols->add_type(name, type)) {
7894bf215546Sopenharmony_ci      const glsl_type *match = state->symbols->get_type(name);
7895bf215546Sopenharmony_ci      /* allow struct matching for desktop GL - older UE4 does this */
7896bf215546Sopenharmony_ci      if (match != NULL && state->is_version(130, 0) && match->record_compare(type, true, false))
7897bf215546Sopenharmony_ci         _mesa_glsl_warning(& loc, state, "struct `%s' previously defined", name);
7898bf215546Sopenharmony_ci      else
7899bf215546Sopenharmony_ci         _mesa_glsl_error(& loc, state, "struct `%s' previously defined", name);
7900bf215546Sopenharmony_ci   } else {
7901bf215546Sopenharmony_ci      const glsl_type **s = reralloc(state, state->user_structures,
7902bf215546Sopenharmony_ci                                     const glsl_type *,
7903bf215546Sopenharmony_ci                                     state->num_user_structures + 1);
7904bf215546Sopenharmony_ci      if (s != NULL) {
7905bf215546Sopenharmony_ci         s[state->num_user_structures] = type;
7906bf215546Sopenharmony_ci         state->user_structures = s;
7907bf215546Sopenharmony_ci         state->num_user_structures++;
7908bf215546Sopenharmony_ci      }
7909bf215546Sopenharmony_ci   }
7910bf215546Sopenharmony_ci
7911bf215546Sopenharmony_ci   /* Structure type definitions do not have r-values.
7912bf215546Sopenharmony_ci    */
7913bf215546Sopenharmony_ci   return NULL;
7914bf215546Sopenharmony_ci}
7915bf215546Sopenharmony_ci
7916bf215546Sopenharmony_ci
7917bf215546Sopenharmony_ci/**
7918bf215546Sopenharmony_ci * Visitor class which detects whether a given interface block has been used.
7919bf215546Sopenharmony_ci */
7920bf215546Sopenharmony_ciclass interface_block_usage_visitor : public ir_hierarchical_visitor
7921bf215546Sopenharmony_ci{
7922bf215546Sopenharmony_cipublic:
7923bf215546Sopenharmony_ci   interface_block_usage_visitor(ir_variable_mode mode, const glsl_type *block)
7924bf215546Sopenharmony_ci      : mode(mode), block(block), found(false)
7925bf215546Sopenharmony_ci   {
7926bf215546Sopenharmony_ci   }
7927bf215546Sopenharmony_ci
7928bf215546Sopenharmony_ci   virtual ir_visitor_status visit(ir_dereference_variable *ir)
7929bf215546Sopenharmony_ci   {
7930bf215546Sopenharmony_ci      if (ir->var->data.mode == mode && ir->var->get_interface_type() == block) {
7931bf215546Sopenharmony_ci         found = true;
7932bf215546Sopenharmony_ci         return visit_stop;
7933bf215546Sopenharmony_ci      }
7934bf215546Sopenharmony_ci      return visit_continue;
7935bf215546Sopenharmony_ci   }
7936bf215546Sopenharmony_ci
7937bf215546Sopenharmony_ci   bool usage_found() const
7938bf215546Sopenharmony_ci   {
7939bf215546Sopenharmony_ci      return this->found;
7940bf215546Sopenharmony_ci   }
7941bf215546Sopenharmony_ci
7942bf215546Sopenharmony_ciprivate:
7943bf215546Sopenharmony_ci   ir_variable_mode mode;
7944bf215546Sopenharmony_ci   const glsl_type *block;
7945bf215546Sopenharmony_ci   bool found;
7946bf215546Sopenharmony_ci};
7947bf215546Sopenharmony_ci
7948bf215546Sopenharmony_cistatic bool
7949bf215546Sopenharmony_ciis_unsized_array_last_element(ir_variable *v)
7950bf215546Sopenharmony_ci{
7951bf215546Sopenharmony_ci   const glsl_type *interface_type = v->get_interface_type();
7952bf215546Sopenharmony_ci   int length = interface_type->length;
7953bf215546Sopenharmony_ci
7954bf215546Sopenharmony_ci   assert(v->type->is_unsized_array());
7955bf215546Sopenharmony_ci
7956bf215546Sopenharmony_ci   /* Check if it is the last element of the interface */
7957bf215546Sopenharmony_ci   if (strcmp(interface_type->fields.structure[length-1].name, v->name) == 0)
7958bf215546Sopenharmony_ci      return true;
7959bf215546Sopenharmony_ci   return false;
7960bf215546Sopenharmony_ci}
7961bf215546Sopenharmony_ci
7962bf215546Sopenharmony_cistatic void
7963bf215546Sopenharmony_ciapply_memory_qualifiers(ir_variable *var, glsl_struct_field field)
7964bf215546Sopenharmony_ci{
7965bf215546Sopenharmony_ci   var->data.memory_read_only = field.memory_read_only;
7966bf215546Sopenharmony_ci   var->data.memory_write_only = field.memory_write_only;
7967bf215546Sopenharmony_ci   var->data.memory_coherent = field.memory_coherent;
7968bf215546Sopenharmony_ci   var->data.memory_volatile = field.memory_volatile;
7969bf215546Sopenharmony_ci   var->data.memory_restrict = field.memory_restrict;
7970bf215546Sopenharmony_ci}
7971bf215546Sopenharmony_ci
7972bf215546Sopenharmony_ciir_rvalue *
7973bf215546Sopenharmony_ciast_interface_block::hir(exec_list *instructions,
7974bf215546Sopenharmony_ci                         struct _mesa_glsl_parse_state *state)
7975bf215546Sopenharmony_ci{
7976bf215546Sopenharmony_ci   YYLTYPE loc = this->get_location();
7977bf215546Sopenharmony_ci
7978bf215546Sopenharmony_ci   /* Interface blocks must be declared at global scope */
7979bf215546Sopenharmony_ci   if (state->current_function != NULL) {
7980bf215546Sopenharmony_ci      _mesa_glsl_error(&loc, state,
7981bf215546Sopenharmony_ci                       "Interface block `%s' must be declared "
7982bf215546Sopenharmony_ci                       "at global scope",
7983bf215546Sopenharmony_ci                       this->block_name);
7984bf215546Sopenharmony_ci   }
7985bf215546Sopenharmony_ci
7986bf215546Sopenharmony_ci   /* Validate qualifiers:
7987bf215546Sopenharmony_ci    *
7988bf215546Sopenharmony_ci    * - Layout Qualifiers as per the table in Section 4.4
7989bf215546Sopenharmony_ci    *   ("Layout Qualifiers") of the GLSL 4.50 spec.
7990bf215546Sopenharmony_ci    *
7991bf215546Sopenharmony_ci    * - Memory Qualifiers as per Section 4.10 ("Memory Qualifiers") of the
7992bf215546Sopenharmony_ci    *   GLSL 4.50 spec:
7993bf215546Sopenharmony_ci    *
7994bf215546Sopenharmony_ci    *     "Additionally, memory qualifiers may also be used in the declaration
7995bf215546Sopenharmony_ci    *      of shader storage blocks"
7996bf215546Sopenharmony_ci    *
7997bf215546Sopenharmony_ci    * Note the table in Section 4.4 says std430 is allowed on both uniform and
7998bf215546Sopenharmony_ci    * buffer blocks however Section 4.4.5 (Uniform and Shader Storage Block
7999bf215546Sopenharmony_ci    * Layout Qualifiers) of the GLSL 4.50 spec says:
8000bf215546Sopenharmony_ci    *
8001bf215546Sopenharmony_ci    *    "The std430 qualifier is supported only for shader storage blocks;
8002bf215546Sopenharmony_ci    *    using std430 on a uniform block will result in a compile-time error."
8003bf215546Sopenharmony_ci    */
8004bf215546Sopenharmony_ci   ast_type_qualifier allowed_blk_qualifiers;
8005bf215546Sopenharmony_ci   allowed_blk_qualifiers.flags.i = 0;
8006bf215546Sopenharmony_ci   if (this->layout.flags.q.buffer || this->layout.flags.q.uniform) {
8007bf215546Sopenharmony_ci      allowed_blk_qualifiers.flags.q.shared = 1;
8008bf215546Sopenharmony_ci      allowed_blk_qualifiers.flags.q.packed = 1;
8009bf215546Sopenharmony_ci      allowed_blk_qualifiers.flags.q.std140 = 1;
8010bf215546Sopenharmony_ci      allowed_blk_qualifiers.flags.q.row_major = 1;
8011bf215546Sopenharmony_ci      allowed_blk_qualifiers.flags.q.column_major = 1;
8012bf215546Sopenharmony_ci      allowed_blk_qualifiers.flags.q.explicit_align = 1;
8013bf215546Sopenharmony_ci      allowed_blk_qualifiers.flags.q.explicit_binding = 1;
8014bf215546Sopenharmony_ci      if (this->layout.flags.q.buffer) {
8015bf215546Sopenharmony_ci         allowed_blk_qualifiers.flags.q.buffer = 1;
8016bf215546Sopenharmony_ci         allowed_blk_qualifiers.flags.q.std430 = 1;
8017bf215546Sopenharmony_ci         allowed_blk_qualifiers.flags.q.coherent = 1;
8018bf215546Sopenharmony_ci         allowed_blk_qualifiers.flags.q._volatile = 1;
8019bf215546Sopenharmony_ci         allowed_blk_qualifiers.flags.q.restrict_flag = 1;
8020bf215546Sopenharmony_ci         allowed_blk_qualifiers.flags.q.read_only = 1;
8021bf215546Sopenharmony_ci         allowed_blk_qualifiers.flags.q.write_only = 1;
8022bf215546Sopenharmony_ci      } else {
8023bf215546Sopenharmony_ci         allowed_blk_qualifiers.flags.q.uniform = 1;
8024bf215546Sopenharmony_ci      }
8025bf215546Sopenharmony_ci   } else {
8026bf215546Sopenharmony_ci      /* Interface block */
8027bf215546Sopenharmony_ci      assert(this->layout.flags.q.in || this->layout.flags.q.out);
8028bf215546Sopenharmony_ci
8029bf215546Sopenharmony_ci      allowed_blk_qualifiers.flags.q.explicit_location = 1;
8030bf215546Sopenharmony_ci      if (this->layout.flags.q.out) {
8031bf215546Sopenharmony_ci         allowed_blk_qualifiers.flags.q.out = 1;
8032bf215546Sopenharmony_ci         if (state->stage == MESA_SHADER_GEOMETRY ||
8033bf215546Sopenharmony_ci             state->stage == MESA_SHADER_TESS_CTRL ||
8034bf215546Sopenharmony_ci             state->stage == MESA_SHADER_TESS_EVAL ||
8035bf215546Sopenharmony_ci             state->stage == MESA_SHADER_VERTEX ) {
8036bf215546Sopenharmony_ci            allowed_blk_qualifiers.flags.q.explicit_xfb_offset = 1;
8037bf215546Sopenharmony_ci            allowed_blk_qualifiers.flags.q.explicit_xfb_buffer = 1;
8038bf215546Sopenharmony_ci            allowed_blk_qualifiers.flags.q.xfb_buffer = 1;
8039bf215546Sopenharmony_ci            allowed_blk_qualifiers.flags.q.explicit_xfb_stride = 1;
8040bf215546Sopenharmony_ci            allowed_blk_qualifiers.flags.q.xfb_stride = 1;
8041bf215546Sopenharmony_ci         }
8042bf215546Sopenharmony_ci         if (state->stage == MESA_SHADER_GEOMETRY) {
8043bf215546Sopenharmony_ci            allowed_blk_qualifiers.flags.q.stream = 1;
8044bf215546Sopenharmony_ci            allowed_blk_qualifiers.flags.q.explicit_stream = 1;
8045bf215546Sopenharmony_ci         }
8046bf215546Sopenharmony_ci         if (state->stage == MESA_SHADER_TESS_CTRL) {
8047bf215546Sopenharmony_ci            allowed_blk_qualifiers.flags.q.patch = 1;
8048bf215546Sopenharmony_ci         }
8049bf215546Sopenharmony_ci      } else {
8050bf215546Sopenharmony_ci         allowed_blk_qualifiers.flags.q.in = 1;
8051bf215546Sopenharmony_ci         if (state->stage == MESA_SHADER_TESS_EVAL) {
8052bf215546Sopenharmony_ci            allowed_blk_qualifiers.flags.q.patch = 1;
8053bf215546Sopenharmony_ci         }
8054bf215546Sopenharmony_ci      }
8055bf215546Sopenharmony_ci   }
8056bf215546Sopenharmony_ci
8057bf215546Sopenharmony_ci   this->layout.validate_flags(&loc, state, allowed_blk_qualifiers,
8058bf215546Sopenharmony_ci                               "invalid qualifier for block",
8059bf215546Sopenharmony_ci                               this->block_name);
8060bf215546Sopenharmony_ci
8061bf215546Sopenharmony_ci   enum glsl_interface_packing packing;
8062bf215546Sopenharmony_ci   if (this->layout.flags.q.std140) {
8063bf215546Sopenharmony_ci      packing = GLSL_INTERFACE_PACKING_STD140;
8064bf215546Sopenharmony_ci   } else if (this->layout.flags.q.packed) {
8065bf215546Sopenharmony_ci      packing = GLSL_INTERFACE_PACKING_PACKED;
8066bf215546Sopenharmony_ci   } else if (this->layout.flags.q.std430) {
8067bf215546Sopenharmony_ci      packing = GLSL_INTERFACE_PACKING_STD430;
8068bf215546Sopenharmony_ci   } else {
8069bf215546Sopenharmony_ci      /* The default layout is shared.
8070bf215546Sopenharmony_ci       */
8071bf215546Sopenharmony_ci      packing = GLSL_INTERFACE_PACKING_SHARED;
8072bf215546Sopenharmony_ci   }
8073bf215546Sopenharmony_ci
8074bf215546Sopenharmony_ci   ir_variable_mode var_mode;
8075bf215546Sopenharmony_ci   const char *iface_type_name;
8076bf215546Sopenharmony_ci   if (this->layout.flags.q.in) {
8077bf215546Sopenharmony_ci      var_mode = ir_var_shader_in;
8078bf215546Sopenharmony_ci      iface_type_name = "in";
8079bf215546Sopenharmony_ci   } else if (this->layout.flags.q.out) {
8080bf215546Sopenharmony_ci      var_mode = ir_var_shader_out;
8081bf215546Sopenharmony_ci      iface_type_name = "out";
8082bf215546Sopenharmony_ci   } else if (this->layout.flags.q.uniform) {
8083bf215546Sopenharmony_ci      var_mode = ir_var_uniform;
8084bf215546Sopenharmony_ci      iface_type_name = "uniform";
8085bf215546Sopenharmony_ci   } else if (this->layout.flags.q.buffer) {
8086bf215546Sopenharmony_ci      var_mode = ir_var_shader_storage;
8087bf215546Sopenharmony_ci      iface_type_name = "buffer";
8088bf215546Sopenharmony_ci   } else {
8089bf215546Sopenharmony_ci      var_mode = ir_var_auto;
8090bf215546Sopenharmony_ci      iface_type_name = "UNKNOWN";
8091bf215546Sopenharmony_ci      assert(!"interface block layout qualifier not found!");
8092bf215546Sopenharmony_ci   }
8093bf215546Sopenharmony_ci
8094bf215546Sopenharmony_ci   enum glsl_matrix_layout matrix_layout = GLSL_MATRIX_LAYOUT_INHERITED;
8095bf215546Sopenharmony_ci   if (this->layout.flags.q.row_major)
8096bf215546Sopenharmony_ci      matrix_layout = GLSL_MATRIX_LAYOUT_ROW_MAJOR;
8097bf215546Sopenharmony_ci   else if (this->layout.flags.q.column_major)
8098bf215546Sopenharmony_ci      matrix_layout = GLSL_MATRIX_LAYOUT_COLUMN_MAJOR;
8099bf215546Sopenharmony_ci
8100bf215546Sopenharmony_ci   bool redeclaring_per_vertex = strcmp(this->block_name, "gl_PerVertex") == 0;
8101bf215546Sopenharmony_ci   exec_list declared_variables;
8102bf215546Sopenharmony_ci   glsl_struct_field *fields;
8103bf215546Sopenharmony_ci
8104bf215546Sopenharmony_ci   /* For blocks that accept memory qualifiers (i.e. shader storage), verify
8105bf215546Sopenharmony_ci    * that we don't have incompatible qualifiers
8106bf215546Sopenharmony_ci    */
8107bf215546Sopenharmony_ci   if (this->layout.flags.q.read_only && this->layout.flags.q.write_only) {
8108bf215546Sopenharmony_ci      _mesa_glsl_error(&loc, state,
8109bf215546Sopenharmony_ci                       "Interface block sets both readonly and writeonly");
8110bf215546Sopenharmony_ci   }
8111bf215546Sopenharmony_ci
8112bf215546Sopenharmony_ci   unsigned qual_stream;
8113bf215546Sopenharmony_ci   if (!process_qualifier_constant(state, &loc, "stream", this->layout.stream,
8114bf215546Sopenharmony_ci                                   &qual_stream) ||
8115bf215546Sopenharmony_ci       !validate_stream_qualifier(&loc, state, qual_stream)) {
8116bf215546Sopenharmony_ci      /* If the stream qualifier is invalid it doesn't make sense to continue
8117bf215546Sopenharmony_ci       * on and try to compare stream layouts on member variables against it
8118bf215546Sopenharmony_ci       * so just return early.
8119bf215546Sopenharmony_ci       */
8120bf215546Sopenharmony_ci      return NULL;
8121bf215546Sopenharmony_ci   }
8122bf215546Sopenharmony_ci
8123bf215546Sopenharmony_ci   unsigned qual_xfb_buffer = 0;
8124bf215546Sopenharmony_ci   if (layout.flags.q.xfb_buffer) {
8125bf215546Sopenharmony_ci      if (!process_qualifier_constant(state, &loc, "xfb_buffer",
8126bf215546Sopenharmony_ci                                      layout.xfb_buffer, &qual_xfb_buffer) ||
8127bf215546Sopenharmony_ci          !validate_xfb_buffer_qualifier(&loc, state, qual_xfb_buffer)) {
8128bf215546Sopenharmony_ci         return NULL;
8129bf215546Sopenharmony_ci      }
8130bf215546Sopenharmony_ci   }
8131bf215546Sopenharmony_ci
8132bf215546Sopenharmony_ci   unsigned qual_xfb_offset = 0;
8133bf215546Sopenharmony_ci   if (layout.flags.q.explicit_xfb_offset) {
8134bf215546Sopenharmony_ci      if (!process_qualifier_constant(state, &loc, "xfb_offset",
8135bf215546Sopenharmony_ci                                      layout.offset, &qual_xfb_offset)) {
8136bf215546Sopenharmony_ci         return NULL;
8137bf215546Sopenharmony_ci      }
8138bf215546Sopenharmony_ci   }
8139bf215546Sopenharmony_ci
8140bf215546Sopenharmony_ci   unsigned qual_xfb_stride = 0;
8141bf215546Sopenharmony_ci   if (layout.flags.q.explicit_xfb_stride) {
8142bf215546Sopenharmony_ci      if (!process_qualifier_constant(state, &loc, "xfb_stride",
8143bf215546Sopenharmony_ci                                      layout.xfb_stride, &qual_xfb_stride)) {
8144bf215546Sopenharmony_ci         return NULL;
8145bf215546Sopenharmony_ci      }
8146bf215546Sopenharmony_ci   }
8147bf215546Sopenharmony_ci
8148bf215546Sopenharmony_ci   unsigned expl_location = 0;
8149bf215546Sopenharmony_ci   if (layout.flags.q.explicit_location) {
8150bf215546Sopenharmony_ci      if (!process_qualifier_constant(state, &loc, "location",
8151bf215546Sopenharmony_ci                                      layout.location, &expl_location)) {
8152bf215546Sopenharmony_ci         return NULL;
8153bf215546Sopenharmony_ci      } else {
8154bf215546Sopenharmony_ci         expl_location += this->layout.flags.q.patch ? VARYING_SLOT_PATCH0
8155bf215546Sopenharmony_ci                                                     : VARYING_SLOT_VAR0;
8156bf215546Sopenharmony_ci      }
8157bf215546Sopenharmony_ci   }
8158bf215546Sopenharmony_ci
8159bf215546Sopenharmony_ci   unsigned expl_align = 0;
8160bf215546Sopenharmony_ci   if (layout.flags.q.explicit_align) {
8161bf215546Sopenharmony_ci      if (!process_qualifier_constant(state, &loc, "align",
8162bf215546Sopenharmony_ci                                      layout.align, &expl_align)) {
8163bf215546Sopenharmony_ci         return NULL;
8164bf215546Sopenharmony_ci      } else {
8165bf215546Sopenharmony_ci         if (expl_align == 0 || expl_align & (expl_align - 1)) {
8166bf215546Sopenharmony_ci            _mesa_glsl_error(&loc, state, "align layout qualifier is not a "
8167bf215546Sopenharmony_ci                             "power of 2.");
8168bf215546Sopenharmony_ci            return NULL;
8169bf215546Sopenharmony_ci         }
8170bf215546Sopenharmony_ci      }
8171bf215546Sopenharmony_ci   }
8172bf215546Sopenharmony_ci
8173bf215546Sopenharmony_ci   unsigned int num_variables =
8174bf215546Sopenharmony_ci      ast_process_struct_or_iface_block_members(&declared_variables,
8175bf215546Sopenharmony_ci                                                state,
8176bf215546Sopenharmony_ci                                                &this->declarations,
8177bf215546Sopenharmony_ci                                                &fields,
8178bf215546Sopenharmony_ci                                                true,
8179bf215546Sopenharmony_ci                                                matrix_layout,
8180bf215546Sopenharmony_ci                                                redeclaring_per_vertex,
8181bf215546Sopenharmony_ci                                                var_mode,
8182bf215546Sopenharmony_ci                                                &this->layout,
8183bf215546Sopenharmony_ci                                                qual_stream,
8184bf215546Sopenharmony_ci                                                qual_xfb_buffer,
8185bf215546Sopenharmony_ci                                                qual_xfb_offset,
8186bf215546Sopenharmony_ci                                                expl_location,
8187bf215546Sopenharmony_ci                                                expl_align);
8188bf215546Sopenharmony_ci
8189bf215546Sopenharmony_ci   if (!redeclaring_per_vertex) {
8190bf215546Sopenharmony_ci      validate_identifier(this->block_name, loc, state);
8191bf215546Sopenharmony_ci
8192bf215546Sopenharmony_ci      /* From section 4.3.9 ("Interface Blocks") of the GLSL 4.50 spec:
8193bf215546Sopenharmony_ci       *
8194bf215546Sopenharmony_ci       *     "Block names have no other use within a shader beyond interface
8195bf215546Sopenharmony_ci       *     matching; it is a compile-time error to use a block name at global
8196bf215546Sopenharmony_ci       *     scope for anything other than as a block name."
8197bf215546Sopenharmony_ci       */
8198bf215546Sopenharmony_ci      ir_variable *var = state->symbols->get_variable(this->block_name);
8199bf215546Sopenharmony_ci      if (var && !var->type->is_interface()) {
8200bf215546Sopenharmony_ci         _mesa_glsl_error(&loc, state, "Block name `%s' is "
8201bf215546Sopenharmony_ci                          "already used in the scope.",
8202bf215546Sopenharmony_ci                          this->block_name);
8203bf215546Sopenharmony_ci      }
8204bf215546Sopenharmony_ci   }
8205bf215546Sopenharmony_ci
8206bf215546Sopenharmony_ci   const glsl_type *earlier_per_vertex = NULL;
8207bf215546Sopenharmony_ci   if (redeclaring_per_vertex) {
8208bf215546Sopenharmony_ci      /* Find the previous declaration of gl_PerVertex.  If we're redeclaring
8209bf215546Sopenharmony_ci       * the named interface block gl_in, we can find it by looking at the
8210bf215546Sopenharmony_ci       * previous declaration of gl_in.  Otherwise we can find it by looking
8211bf215546Sopenharmony_ci       * at the previous decalartion of any of the built-in outputs,
8212bf215546Sopenharmony_ci       * e.g. gl_Position.
8213bf215546Sopenharmony_ci       *
8214bf215546Sopenharmony_ci       * Also check that the instance name and array-ness of the redeclaration
8215bf215546Sopenharmony_ci       * are correct.
8216bf215546Sopenharmony_ci       */
8217bf215546Sopenharmony_ci      switch (var_mode) {
8218bf215546Sopenharmony_ci      case ir_var_shader_in:
8219bf215546Sopenharmony_ci         if (ir_variable *earlier_gl_in =
8220bf215546Sopenharmony_ci             state->symbols->get_variable("gl_in")) {
8221bf215546Sopenharmony_ci            earlier_per_vertex = earlier_gl_in->get_interface_type();
8222bf215546Sopenharmony_ci         } else {
8223bf215546Sopenharmony_ci            _mesa_glsl_error(&loc, state,
8224bf215546Sopenharmony_ci                             "redeclaration of gl_PerVertex input not allowed "
8225bf215546Sopenharmony_ci                             "in the %s shader",
8226bf215546Sopenharmony_ci                             _mesa_shader_stage_to_string(state->stage));
8227bf215546Sopenharmony_ci         }
8228bf215546Sopenharmony_ci         if (this->instance_name == NULL ||
8229bf215546Sopenharmony_ci             strcmp(this->instance_name, "gl_in") != 0 || this->array_specifier == NULL ||
8230bf215546Sopenharmony_ci             !this->array_specifier->is_single_dimension()) {
8231bf215546Sopenharmony_ci            _mesa_glsl_error(&loc, state,
8232bf215546Sopenharmony_ci                             "gl_PerVertex input must be redeclared as "
8233bf215546Sopenharmony_ci                             "gl_in[]");
8234bf215546Sopenharmony_ci         }
8235bf215546Sopenharmony_ci         break;
8236bf215546Sopenharmony_ci      case ir_var_shader_out:
8237bf215546Sopenharmony_ci         if (ir_variable *earlier_gl_Position =
8238bf215546Sopenharmony_ci             state->symbols->get_variable("gl_Position")) {
8239bf215546Sopenharmony_ci            earlier_per_vertex = earlier_gl_Position->get_interface_type();
8240bf215546Sopenharmony_ci         } else if (ir_variable *earlier_gl_out =
8241bf215546Sopenharmony_ci               state->symbols->get_variable("gl_out")) {
8242bf215546Sopenharmony_ci            earlier_per_vertex = earlier_gl_out->get_interface_type();
8243bf215546Sopenharmony_ci         } else {
8244bf215546Sopenharmony_ci            _mesa_glsl_error(&loc, state,
8245bf215546Sopenharmony_ci                             "redeclaration of gl_PerVertex output not "
8246bf215546Sopenharmony_ci                             "allowed in the %s shader",
8247bf215546Sopenharmony_ci                             _mesa_shader_stage_to_string(state->stage));
8248bf215546Sopenharmony_ci         }
8249bf215546Sopenharmony_ci         if (state->stage == MESA_SHADER_TESS_CTRL) {
8250bf215546Sopenharmony_ci            if (this->instance_name == NULL ||
8251bf215546Sopenharmony_ci                strcmp(this->instance_name, "gl_out") != 0 || this->array_specifier == NULL) {
8252bf215546Sopenharmony_ci               _mesa_glsl_error(&loc, state,
8253bf215546Sopenharmony_ci                                "gl_PerVertex output must be redeclared as "
8254bf215546Sopenharmony_ci                                "gl_out[]");
8255bf215546Sopenharmony_ci            }
8256bf215546Sopenharmony_ci         } else {
8257bf215546Sopenharmony_ci            if (this->instance_name != NULL) {
8258bf215546Sopenharmony_ci               _mesa_glsl_error(&loc, state,
8259bf215546Sopenharmony_ci                                "gl_PerVertex output may not be redeclared with "
8260bf215546Sopenharmony_ci                                "an instance name");
8261bf215546Sopenharmony_ci            }
8262bf215546Sopenharmony_ci         }
8263bf215546Sopenharmony_ci         break;
8264bf215546Sopenharmony_ci      default:
8265bf215546Sopenharmony_ci         _mesa_glsl_error(&loc, state,
8266bf215546Sopenharmony_ci                          "gl_PerVertex must be declared as an input or an "
8267bf215546Sopenharmony_ci                          "output");
8268bf215546Sopenharmony_ci         break;
8269bf215546Sopenharmony_ci      }
8270bf215546Sopenharmony_ci
8271bf215546Sopenharmony_ci      if (earlier_per_vertex == NULL) {
8272bf215546Sopenharmony_ci         /* An error has already been reported.  Bail out to avoid null
8273bf215546Sopenharmony_ci          * dereferences later in this function.
8274bf215546Sopenharmony_ci          */
8275bf215546Sopenharmony_ci         return NULL;
8276bf215546Sopenharmony_ci      }
8277bf215546Sopenharmony_ci
8278bf215546Sopenharmony_ci      /* Copy locations from the old gl_PerVertex interface block. */
8279bf215546Sopenharmony_ci      for (unsigned i = 0; i < num_variables; i++) {
8280bf215546Sopenharmony_ci         int j = earlier_per_vertex->field_index(fields[i].name);
8281bf215546Sopenharmony_ci         if (j == -1) {
8282bf215546Sopenharmony_ci            _mesa_glsl_error(&loc, state,
8283bf215546Sopenharmony_ci                             "redeclaration of gl_PerVertex must be a subset "
8284bf215546Sopenharmony_ci                             "of the built-in members of gl_PerVertex");
8285bf215546Sopenharmony_ci         } else {
8286bf215546Sopenharmony_ci            fields[i].location =
8287bf215546Sopenharmony_ci               earlier_per_vertex->fields.structure[j].location;
8288bf215546Sopenharmony_ci            fields[i].offset =
8289bf215546Sopenharmony_ci               earlier_per_vertex->fields.structure[j].offset;
8290bf215546Sopenharmony_ci            fields[i].interpolation =
8291bf215546Sopenharmony_ci               earlier_per_vertex->fields.structure[j].interpolation;
8292bf215546Sopenharmony_ci            fields[i].centroid =
8293bf215546Sopenharmony_ci               earlier_per_vertex->fields.structure[j].centroid;
8294bf215546Sopenharmony_ci            fields[i].sample =
8295bf215546Sopenharmony_ci               earlier_per_vertex->fields.structure[j].sample;
8296bf215546Sopenharmony_ci            fields[i].patch =
8297bf215546Sopenharmony_ci               earlier_per_vertex->fields.structure[j].patch;
8298bf215546Sopenharmony_ci            fields[i].precision =
8299bf215546Sopenharmony_ci               earlier_per_vertex->fields.structure[j].precision;
8300bf215546Sopenharmony_ci            fields[i].explicit_xfb_buffer =
8301bf215546Sopenharmony_ci               earlier_per_vertex->fields.structure[j].explicit_xfb_buffer;
8302bf215546Sopenharmony_ci            fields[i].xfb_buffer =
8303bf215546Sopenharmony_ci               earlier_per_vertex->fields.structure[j].xfb_buffer;
8304bf215546Sopenharmony_ci            fields[i].xfb_stride =
8305bf215546Sopenharmony_ci               earlier_per_vertex->fields.structure[j].xfb_stride;
8306bf215546Sopenharmony_ci         }
8307bf215546Sopenharmony_ci      }
8308bf215546Sopenharmony_ci
8309bf215546Sopenharmony_ci      /* From section 7.1 ("Built-in Language Variables") of the GLSL 4.10
8310bf215546Sopenharmony_ci       * spec:
8311bf215546Sopenharmony_ci       *
8312bf215546Sopenharmony_ci       *     If a built-in interface block is redeclared, it must appear in
8313bf215546Sopenharmony_ci       *     the shader before any use of any member included in the built-in
8314bf215546Sopenharmony_ci       *     declaration, or a compilation error will result.
8315bf215546Sopenharmony_ci       *
8316bf215546Sopenharmony_ci       * This appears to be a clarification to the behaviour established for
8317bf215546Sopenharmony_ci       * gl_PerVertex by GLSL 1.50, therefore we implement this behaviour
8318bf215546Sopenharmony_ci       * regardless of GLSL version.
8319bf215546Sopenharmony_ci       */
8320bf215546Sopenharmony_ci      interface_block_usage_visitor v(var_mode, earlier_per_vertex);
8321bf215546Sopenharmony_ci      v.run(instructions);
8322bf215546Sopenharmony_ci      if (v.usage_found()) {
8323bf215546Sopenharmony_ci         _mesa_glsl_error(&loc, state,
8324bf215546Sopenharmony_ci                          "redeclaration of a built-in interface block must "
8325bf215546Sopenharmony_ci                          "appear before any use of any member of the "
8326bf215546Sopenharmony_ci                          "interface block");
8327bf215546Sopenharmony_ci      }
8328bf215546Sopenharmony_ci   }
8329bf215546Sopenharmony_ci
8330bf215546Sopenharmony_ci   const glsl_type *block_type =
8331bf215546Sopenharmony_ci      glsl_type::get_interface_instance(fields,
8332bf215546Sopenharmony_ci                                        num_variables,
8333bf215546Sopenharmony_ci                                        packing,
8334bf215546Sopenharmony_ci                                        matrix_layout ==
8335bf215546Sopenharmony_ci                                           GLSL_MATRIX_LAYOUT_ROW_MAJOR,
8336bf215546Sopenharmony_ci                                        this->block_name);
8337bf215546Sopenharmony_ci
8338bf215546Sopenharmony_ci   unsigned component_size = block_type->contains_double() ? 8 : 4;
8339bf215546Sopenharmony_ci   int xfb_offset =
8340bf215546Sopenharmony_ci      layout.flags.q.explicit_xfb_offset ? (int) qual_xfb_offset : -1;
8341bf215546Sopenharmony_ci   validate_xfb_offset_qualifier(&loc, state, xfb_offset, block_type,
8342bf215546Sopenharmony_ci                                 component_size);
8343bf215546Sopenharmony_ci
8344bf215546Sopenharmony_ci   if (!state->symbols->add_interface(block_type->name, block_type, var_mode)) {
8345bf215546Sopenharmony_ci      YYLTYPE loc = this->get_location();
8346bf215546Sopenharmony_ci      _mesa_glsl_error(&loc, state, "interface block `%s' with type `%s' "
8347bf215546Sopenharmony_ci                       "already taken in the current scope",
8348bf215546Sopenharmony_ci                       this->block_name, iface_type_name);
8349bf215546Sopenharmony_ci   }
8350bf215546Sopenharmony_ci
8351bf215546Sopenharmony_ci   /* Since interface blocks cannot contain statements, it should be
8352bf215546Sopenharmony_ci    * impossible for the block to generate any instructions.
8353bf215546Sopenharmony_ci    */
8354bf215546Sopenharmony_ci   assert(declared_variables.is_empty());
8355bf215546Sopenharmony_ci
8356bf215546Sopenharmony_ci   /* From section 4.3.4 (Inputs) of the GLSL 1.50 spec:
8357bf215546Sopenharmony_ci    *
8358bf215546Sopenharmony_ci    *     Geometry shader input variables get the per-vertex values written
8359bf215546Sopenharmony_ci    *     out by vertex shader output variables of the same names. Since a
8360bf215546Sopenharmony_ci    *     geometry shader operates on a set of vertices, each input varying
8361bf215546Sopenharmony_ci    *     variable (or input block, see interface blocks below) needs to be
8362bf215546Sopenharmony_ci    *     declared as an array.
8363bf215546Sopenharmony_ci    */
8364bf215546Sopenharmony_ci   if (state->stage == MESA_SHADER_GEOMETRY && this->array_specifier == NULL &&
8365bf215546Sopenharmony_ci       var_mode == ir_var_shader_in) {
8366bf215546Sopenharmony_ci      _mesa_glsl_error(&loc, state, "geometry shader inputs must be arrays");
8367bf215546Sopenharmony_ci   } else if ((state->stage == MESA_SHADER_TESS_CTRL ||
8368bf215546Sopenharmony_ci               state->stage == MESA_SHADER_TESS_EVAL) &&
8369bf215546Sopenharmony_ci              !this->layout.flags.q.patch &&
8370bf215546Sopenharmony_ci              this->array_specifier == NULL &&
8371bf215546Sopenharmony_ci              var_mode == ir_var_shader_in) {
8372bf215546Sopenharmony_ci      _mesa_glsl_error(&loc, state, "per-vertex tessellation shader inputs must be arrays");
8373bf215546Sopenharmony_ci   } else if (state->stage == MESA_SHADER_TESS_CTRL &&
8374bf215546Sopenharmony_ci              !this->layout.flags.q.patch &&
8375bf215546Sopenharmony_ci              this->array_specifier == NULL &&
8376bf215546Sopenharmony_ci              var_mode == ir_var_shader_out) {
8377bf215546Sopenharmony_ci      _mesa_glsl_error(&loc, state, "tessellation control shader outputs must be arrays");
8378bf215546Sopenharmony_ci   }
8379bf215546Sopenharmony_ci
8380bf215546Sopenharmony_ci
8381bf215546Sopenharmony_ci   /* Page 39 (page 45 of the PDF) of section 4.3.7 in the GLSL ES 3.00 spec
8382bf215546Sopenharmony_ci    * says:
8383bf215546Sopenharmony_ci    *
8384bf215546Sopenharmony_ci    *     "If an instance name (instance-name) is used, then it puts all the
8385bf215546Sopenharmony_ci    *     members inside a scope within its own name space, accessed with the
8386bf215546Sopenharmony_ci    *     field selector ( . ) operator (analogously to structures)."
8387bf215546Sopenharmony_ci    */
8388bf215546Sopenharmony_ci   if (this->instance_name) {
8389bf215546Sopenharmony_ci      if (redeclaring_per_vertex) {
8390bf215546Sopenharmony_ci         /* When a built-in in an unnamed interface block is redeclared,
8391bf215546Sopenharmony_ci          * get_variable_being_redeclared() calls
8392bf215546Sopenharmony_ci          * check_builtin_array_max_size() to make sure that built-in array
8393bf215546Sopenharmony_ci          * variables aren't redeclared to illegal sizes.  But we're looking
8394bf215546Sopenharmony_ci          * at a redeclaration of a named built-in interface block.  So we
8395bf215546Sopenharmony_ci          * have to manually call check_builtin_array_max_size() for all parts
8396bf215546Sopenharmony_ci          * of the interface that are arrays.
8397bf215546Sopenharmony_ci          */
8398bf215546Sopenharmony_ci         for (unsigned i = 0; i < num_variables; i++) {
8399bf215546Sopenharmony_ci            if (fields[i].type->is_array()) {
8400bf215546Sopenharmony_ci               const unsigned size = fields[i].type->array_size();
8401bf215546Sopenharmony_ci               check_builtin_array_max_size(fields[i].name, size, loc, state);
8402bf215546Sopenharmony_ci            }
8403bf215546Sopenharmony_ci         }
8404bf215546Sopenharmony_ci      } else {
8405bf215546Sopenharmony_ci         validate_identifier(this->instance_name, loc, state);
8406bf215546Sopenharmony_ci      }
8407bf215546Sopenharmony_ci
8408bf215546Sopenharmony_ci      ir_variable *var;
8409bf215546Sopenharmony_ci
8410bf215546Sopenharmony_ci      if (this->array_specifier != NULL) {
8411bf215546Sopenharmony_ci         const glsl_type *block_array_type =
8412bf215546Sopenharmony_ci            process_array_type(&loc, block_type, this->array_specifier, state);
8413bf215546Sopenharmony_ci
8414bf215546Sopenharmony_ci         /* From Section 4.4.1 (Input Layout Qualifiers) of the GLSL 4.50 spec:
8415bf215546Sopenharmony_ci          *
8416bf215546Sopenharmony_ci          *    "For some blocks declared as arrays, the location can only be applied
8417bf215546Sopenharmony_ci          *    at the block level: When a block is declared as an array where
8418bf215546Sopenharmony_ci          *    additional locations are needed for each member for each block array
8419bf215546Sopenharmony_ci          *    element, it is a compile-time error to specify locations on the block
8420bf215546Sopenharmony_ci          *    members. That is, when locations would be under specified by applying
8421bf215546Sopenharmony_ci          *    them on block members, they are not allowed on block members. For
8422bf215546Sopenharmony_ci          *    arrayed interfaces (those generally having an extra level of
8423bf215546Sopenharmony_ci          *    arrayness due to interface expansion), the outer array is stripped
8424bf215546Sopenharmony_ci          *    before applying this rule"
8425bf215546Sopenharmony_ci          *
8426bf215546Sopenharmony_ci          * From 4.4.1 (Input Layout Qualifiers) and
8427bf215546Sopenharmony_ci          * 4.4.2 (Output Layout Qualifiers) of GLSL ES 3.20
8428bf215546Sopenharmony_ci          *
8429bf215546Sopenharmony_ci          *    "If an input is declared as an array of blocks, excluding
8430bf215546Sopenharmony_ci          *     per-vertex-arrays as required for tessellation, it is an error
8431bf215546Sopenharmony_ci          *     to declare a member of the block with a location qualifier."
8432bf215546Sopenharmony_ci          *
8433bf215546Sopenharmony_ci          *    "If an output is declared as an array of blocks, excluding
8434bf215546Sopenharmony_ci          *     per-vertex-arrays as required for tessellation, it is an error
8435bf215546Sopenharmony_ci          *     to declare a member of the block with a location qualifier."
8436bf215546Sopenharmony_ci          */
8437bf215546Sopenharmony_ci         if (!redeclaring_per_vertex &&
8438bf215546Sopenharmony_ci             (state->has_enhanced_layouts() || state->has_shader_io_blocks())) {
8439bf215546Sopenharmony_ci            bool allow_location;
8440bf215546Sopenharmony_ci            switch (state->stage)
8441bf215546Sopenharmony_ci            {
8442bf215546Sopenharmony_ci            case MESA_SHADER_TESS_CTRL:
8443bf215546Sopenharmony_ci               allow_location = this->array_specifier->is_single_dimension();
8444bf215546Sopenharmony_ci               break;
8445bf215546Sopenharmony_ci            case MESA_SHADER_TESS_EVAL:
8446bf215546Sopenharmony_ci            case MESA_SHADER_GEOMETRY:
8447bf215546Sopenharmony_ci               allow_location = (this->array_specifier->is_single_dimension()
8448bf215546Sopenharmony_ci                                 && var_mode == ir_var_shader_in);
8449bf215546Sopenharmony_ci               break;
8450bf215546Sopenharmony_ci            default:
8451bf215546Sopenharmony_ci               allow_location = false;
8452bf215546Sopenharmony_ci               break;
8453bf215546Sopenharmony_ci            }
8454bf215546Sopenharmony_ci
8455bf215546Sopenharmony_ci            if (!allow_location) {
8456bf215546Sopenharmony_ci               for (unsigned i = 0; i < num_variables; i++) {
8457bf215546Sopenharmony_ci                  if (fields[i].location != -1) {
8458bf215546Sopenharmony_ci                     _mesa_glsl_error(&loc, state,
8459bf215546Sopenharmony_ci                                       "explicit member locations are not allowed in "
8460bf215546Sopenharmony_ci                                       "blocks declared as arrays %s shader",
8461bf215546Sopenharmony_ci                                       _mesa_shader_stage_to_string(state->stage));
8462bf215546Sopenharmony_ci                  }
8463bf215546Sopenharmony_ci               }
8464bf215546Sopenharmony_ci            }
8465bf215546Sopenharmony_ci         }
8466bf215546Sopenharmony_ci
8467bf215546Sopenharmony_ci         /* Section 4.3.7 (Interface Blocks) of the GLSL 1.50 spec says:
8468bf215546Sopenharmony_ci          *
8469bf215546Sopenharmony_ci          *     For uniform blocks declared an array, each individual array
8470bf215546Sopenharmony_ci          *     element corresponds to a separate buffer object backing one
8471bf215546Sopenharmony_ci          *     instance of the block. As the array size indicates the number
8472bf215546Sopenharmony_ci          *     of buffer objects needed, uniform block array declarations
8473bf215546Sopenharmony_ci          *     must specify an array size.
8474bf215546Sopenharmony_ci          *
8475bf215546Sopenharmony_ci          * And a few paragraphs later:
8476bf215546Sopenharmony_ci          *
8477bf215546Sopenharmony_ci          *     Geometry shader input blocks must be declared as arrays and
8478bf215546Sopenharmony_ci          *     follow the array declaration and linking rules for all
8479bf215546Sopenharmony_ci          *     geometry shader inputs. All other input and output block
8480bf215546Sopenharmony_ci          *     arrays must specify an array size.
8481bf215546Sopenharmony_ci          *
8482bf215546Sopenharmony_ci          * The same applies to tessellation shaders.
8483bf215546Sopenharmony_ci          *
8484bf215546Sopenharmony_ci          * The upshot of this is that the only circumstance where an
8485bf215546Sopenharmony_ci          * interface array size *doesn't* need to be specified is on a
8486bf215546Sopenharmony_ci          * geometry shader input, tessellation control shader input,
8487bf215546Sopenharmony_ci          * tessellation control shader output, and tessellation evaluation
8488bf215546Sopenharmony_ci          * shader input.
8489bf215546Sopenharmony_ci          */
8490bf215546Sopenharmony_ci         if (block_array_type->is_unsized_array()) {
8491bf215546Sopenharmony_ci            bool allow_inputs = state->stage == MESA_SHADER_GEOMETRY ||
8492bf215546Sopenharmony_ci                                state->stage == MESA_SHADER_TESS_CTRL ||
8493bf215546Sopenharmony_ci                                state->stage == MESA_SHADER_TESS_EVAL;
8494bf215546Sopenharmony_ci            bool allow_outputs = state->stage == MESA_SHADER_TESS_CTRL;
8495bf215546Sopenharmony_ci
8496bf215546Sopenharmony_ci            if (this->layout.flags.q.in) {
8497bf215546Sopenharmony_ci               if (!allow_inputs)
8498bf215546Sopenharmony_ci                  _mesa_glsl_error(&loc, state,
8499bf215546Sopenharmony_ci                                   "unsized input block arrays not allowed in "
8500bf215546Sopenharmony_ci                                   "%s shader",
8501bf215546Sopenharmony_ci                                   _mesa_shader_stage_to_string(state->stage));
8502bf215546Sopenharmony_ci            } else if (this->layout.flags.q.out) {
8503bf215546Sopenharmony_ci               if (!allow_outputs)
8504bf215546Sopenharmony_ci                  _mesa_glsl_error(&loc, state,
8505bf215546Sopenharmony_ci                                   "unsized output block arrays not allowed in "
8506bf215546Sopenharmony_ci                                   "%s shader",
8507bf215546Sopenharmony_ci                                   _mesa_shader_stage_to_string(state->stage));
8508bf215546Sopenharmony_ci            } else {
8509bf215546Sopenharmony_ci               /* by elimination, this is a uniform block array */
8510bf215546Sopenharmony_ci               _mesa_glsl_error(&loc, state,
8511bf215546Sopenharmony_ci                                "unsized uniform block arrays not allowed in "
8512bf215546Sopenharmony_ci                                "%s shader",
8513bf215546Sopenharmony_ci                                _mesa_shader_stage_to_string(state->stage));
8514bf215546Sopenharmony_ci            }
8515bf215546Sopenharmony_ci         }
8516bf215546Sopenharmony_ci
8517bf215546Sopenharmony_ci         /* From section 4.3.9 (Interface Blocks) of the GLSL ES 3.10 spec:
8518bf215546Sopenharmony_ci          *
8519bf215546Sopenharmony_ci          *     * Arrays of arrays of blocks are not allowed
8520bf215546Sopenharmony_ci          */
8521bf215546Sopenharmony_ci         if (state->es_shader && block_array_type->is_array() &&
8522bf215546Sopenharmony_ci             block_array_type->fields.array->is_array()) {
8523bf215546Sopenharmony_ci            _mesa_glsl_error(&loc, state,
8524bf215546Sopenharmony_ci                             "arrays of arrays interface blocks are "
8525bf215546Sopenharmony_ci                             "not allowed");
8526bf215546Sopenharmony_ci         }
8527bf215546Sopenharmony_ci
8528bf215546Sopenharmony_ci         var = new(state) ir_variable(block_array_type,
8529bf215546Sopenharmony_ci                                      this->instance_name,
8530bf215546Sopenharmony_ci                                      var_mode);
8531bf215546Sopenharmony_ci      } else {
8532bf215546Sopenharmony_ci         var = new(state) ir_variable(block_type,
8533bf215546Sopenharmony_ci                                      this->instance_name,
8534bf215546Sopenharmony_ci                                      var_mode);
8535bf215546Sopenharmony_ci      }
8536bf215546Sopenharmony_ci
8537bf215546Sopenharmony_ci      var->data.matrix_layout = matrix_layout == GLSL_MATRIX_LAYOUT_INHERITED
8538bf215546Sopenharmony_ci         ? GLSL_MATRIX_LAYOUT_COLUMN_MAJOR : matrix_layout;
8539bf215546Sopenharmony_ci
8540bf215546Sopenharmony_ci      if (var_mode == ir_var_shader_in || var_mode == ir_var_uniform)
8541bf215546Sopenharmony_ci         var->data.read_only = true;
8542bf215546Sopenharmony_ci
8543bf215546Sopenharmony_ci      var->data.patch = this->layout.flags.q.patch;
8544bf215546Sopenharmony_ci
8545bf215546Sopenharmony_ci      if (state->stage == MESA_SHADER_GEOMETRY && var_mode == ir_var_shader_in)
8546bf215546Sopenharmony_ci         handle_geometry_shader_input_decl(state, loc, var);
8547bf215546Sopenharmony_ci      else if ((state->stage == MESA_SHADER_TESS_CTRL ||
8548bf215546Sopenharmony_ci           state->stage == MESA_SHADER_TESS_EVAL) && var_mode == ir_var_shader_in)
8549bf215546Sopenharmony_ci         handle_tess_shader_input_decl(state, loc, var);
8550bf215546Sopenharmony_ci      else if (state->stage == MESA_SHADER_TESS_CTRL && var_mode == ir_var_shader_out)
8551bf215546Sopenharmony_ci         handle_tess_ctrl_shader_output_decl(state, loc, var);
8552bf215546Sopenharmony_ci
8553bf215546Sopenharmony_ci      for (unsigned i = 0; i < num_variables; i++) {
8554bf215546Sopenharmony_ci         if (var->data.mode == ir_var_shader_storage)
8555bf215546Sopenharmony_ci            apply_memory_qualifiers(var, fields[i]);
8556bf215546Sopenharmony_ci      }
8557bf215546Sopenharmony_ci
8558bf215546Sopenharmony_ci      if (ir_variable *earlier =
8559bf215546Sopenharmony_ci          state->symbols->get_variable(this->instance_name)) {
8560bf215546Sopenharmony_ci         if (!redeclaring_per_vertex) {
8561bf215546Sopenharmony_ci            _mesa_glsl_error(&loc, state, "`%s' redeclared",
8562bf215546Sopenharmony_ci                             this->instance_name);
8563bf215546Sopenharmony_ci         }
8564bf215546Sopenharmony_ci         earlier->data.how_declared = ir_var_declared_normally;
8565bf215546Sopenharmony_ci         earlier->type = var->type;
8566bf215546Sopenharmony_ci         earlier->reinit_interface_type(block_type);
8567bf215546Sopenharmony_ci         delete var;
8568bf215546Sopenharmony_ci      } else {
8569bf215546Sopenharmony_ci         if (this->layout.flags.q.explicit_binding) {
8570bf215546Sopenharmony_ci            apply_explicit_binding(state, &loc, var, var->type,
8571bf215546Sopenharmony_ci                                   &this->layout);
8572bf215546Sopenharmony_ci         }
8573bf215546Sopenharmony_ci
8574bf215546Sopenharmony_ci         var->data.stream = qual_stream;
8575bf215546Sopenharmony_ci         if (layout.flags.q.explicit_location) {
8576bf215546Sopenharmony_ci            var->data.location = expl_location;
8577bf215546Sopenharmony_ci            var->data.explicit_location = true;
8578bf215546Sopenharmony_ci         }
8579bf215546Sopenharmony_ci
8580bf215546Sopenharmony_ci         state->symbols->add_variable(var);
8581bf215546Sopenharmony_ci         instructions->push_tail(var);
8582bf215546Sopenharmony_ci      }
8583bf215546Sopenharmony_ci   } else {
8584bf215546Sopenharmony_ci      /* In order to have an array size, the block must also be declared with
8585bf215546Sopenharmony_ci       * an instance name.
8586bf215546Sopenharmony_ci       */
8587bf215546Sopenharmony_ci      assert(this->array_specifier == NULL);
8588bf215546Sopenharmony_ci
8589bf215546Sopenharmony_ci      for (unsigned i = 0; i < num_variables; i++) {
8590bf215546Sopenharmony_ci         ir_variable *var =
8591bf215546Sopenharmony_ci            new(state) ir_variable(fields[i].type,
8592bf215546Sopenharmony_ci                                   ralloc_strdup(state, fields[i].name),
8593bf215546Sopenharmony_ci                                   var_mode);
8594bf215546Sopenharmony_ci         var->data.interpolation = fields[i].interpolation;
8595bf215546Sopenharmony_ci         var->data.centroid = fields[i].centroid;
8596bf215546Sopenharmony_ci         var->data.sample = fields[i].sample;
8597bf215546Sopenharmony_ci         var->data.patch = fields[i].patch;
8598bf215546Sopenharmony_ci         var->data.stream = qual_stream;
8599bf215546Sopenharmony_ci         var->data.location = fields[i].location;
8600bf215546Sopenharmony_ci
8601bf215546Sopenharmony_ci         if (fields[i].location != -1)
8602bf215546Sopenharmony_ci            var->data.explicit_location = true;
8603bf215546Sopenharmony_ci
8604bf215546Sopenharmony_ci         var->data.explicit_xfb_buffer = fields[i].explicit_xfb_buffer;
8605bf215546Sopenharmony_ci         var->data.xfb_buffer = fields[i].xfb_buffer;
8606bf215546Sopenharmony_ci
8607bf215546Sopenharmony_ci         if (fields[i].offset != -1)
8608bf215546Sopenharmony_ci            var->data.explicit_xfb_offset = true;
8609bf215546Sopenharmony_ci         var->data.offset = fields[i].offset;
8610bf215546Sopenharmony_ci
8611bf215546Sopenharmony_ci         var->init_interface_type(block_type);
8612bf215546Sopenharmony_ci
8613bf215546Sopenharmony_ci         if (var_mode == ir_var_shader_in || var_mode == ir_var_uniform)
8614bf215546Sopenharmony_ci            var->data.read_only = true;
8615bf215546Sopenharmony_ci
8616bf215546Sopenharmony_ci         /* Precision qualifiers do not have any meaning in Desktop GLSL */
8617bf215546Sopenharmony_ci         if (state->es_shader) {
8618bf215546Sopenharmony_ci            var->data.precision =
8619bf215546Sopenharmony_ci               select_gles_precision(fields[i].precision, fields[i].type,
8620bf215546Sopenharmony_ci                                     state, &loc);
8621bf215546Sopenharmony_ci         }
8622bf215546Sopenharmony_ci
8623bf215546Sopenharmony_ci         if (fields[i].matrix_layout == GLSL_MATRIX_LAYOUT_INHERITED) {
8624bf215546Sopenharmony_ci            var->data.matrix_layout = matrix_layout == GLSL_MATRIX_LAYOUT_INHERITED
8625bf215546Sopenharmony_ci               ? GLSL_MATRIX_LAYOUT_COLUMN_MAJOR : matrix_layout;
8626bf215546Sopenharmony_ci         } else {
8627bf215546Sopenharmony_ci            var->data.matrix_layout = fields[i].matrix_layout;
8628bf215546Sopenharmony_ci         }
8629bf215546Sopenharmony_ci
8630bf215546Sopenharmony_ci         if (var->data.mode == ir_var_shader_storage)
8631bf215546Sopenharmony_ci            apply_memory_qualifiers(var, fields[i]);
8632bf215546Sopenharmony_ci
8633bf215546Sopenharmony_ci         /* Examine var name here since var may get deleted in the next call */
8634bf215546Sopenharmony_ci         bool var_is_gl_id = is_gl_identifier(var->name);
8635bf215546Sopenharmony_ci
8636bf215546Sopenharmony_ci         if (redeclaring_per_vertex) {
8637bf215546Sopenharmony_ci            bool is_redeclaration;
8638bf215546Sopenharmony_ci            var =
8639bf215546Sopenharmony_ci               get_variable_being_redeclared(&var, loc, state,
8640bf215546Sopenharmony_ci                                             true /* allow_all_redeclarations */,
8641bf215546Sopenharmony_ci                                             &is_redeclaration);
8642bf215546Sopenharmony_ci            if (!var_is_gl_id || !is_redeclaration) {
8643bf215546Sopenharmony_ci               _mesa_glsl_error(&loc, state,
8644bf215546Sopenharmony_ci                                "redeclaration of gl_PerVertex can only "
8645bf215546Sopenharmony_ci                                "include built-in variables");
8646bf215546Sopenharmony_ci            } else if (var->data.how_declared == ir_var_declared_normally) {
8647bf215546Sopenharmony_ci               _mesa_glsl_error(&loc, state,
8648bf215546Sopenharmony_ci                                "`%s' has already been redeclared",
8649bf215546Sopenharmony_ci                                var->name);
8650bf215546Sopenharmony_ci            } else {
8651bf215546Sopenharmony_ci               var->data.how_declared = ir_var_declared_in_block;
8652bf215546Sopenharmony_ci               var->reinit_interface_type(block_type);
8653bf215546Sopenharmony_ci            }
8654bf215546Sopenharmony_ci            continue;
8655bf215546Sopenharmony_ci         }
8656bf215546Sopenharmony_ci
8657bf215546Sopenharmony_ci         if (state->symbols->get_variable(var->name) != NULL)
8658bf215546Sopenharmony_ci            _mesa_glsl_error(&loc, state, "`%s' redeclared", var->name);
8659bf215546Sopenharmony_ci
8660bf215546Sopenharmony_ci         /* Propagate the "binding" keyword into this UBO/SSBO's fields.
8661bf215546Sopenharmony_ci          * The UBO declaration itself doesn't get an ir_variable unless it
8662bf215546Sopenharmony_ci          * has an instance name.  This is ugly.
8663bf215546Sopenharmony_ci          */
8664bf215546Sopenharmony_ci         if (this->layout.flags.q.explicit_binding) {
8665bf215546Sopenharmony_ci            apply_explicit_binding(state, &loc, var,
8666bf215546Sopenharmony_ci                                   var->get_interface_type(), &this->layout);
8667bf215546Sopenharmony_ci         }
8668bf215546Sopenharmony_ci
8669bf215546Sopenharmony_ci         if (var->type->is_unsized_array()) {
8670bf215546Sopenharmony_ci            if (var->is_in_shader_storage_block() &&
8671bf215546Sopenharmony_ci                is_unsized_array_last_element(var)) {
8672bf215546Sopenharmony_ci               var->data.from_ssbo_unsized_array = true;
8673bf215546Sopenharmony_ci            } else {
8674bf215546Sopenharmony_ci               /* From GLSL ES 3.10 spec, section 4.1.9 "Arrays":
8675bf215546Sopenharmony_ci                *
8676bf215546Sopenharmony_ci                * "If an array is declared as the last member of a shader storage
8677bf215546Sopenharmony_ci                * block and the size is not specified at compile-time, it is
8678bf215546Sopenharmony_ci                * sized at run-time. In all other cases, arrays are sized only
8679bf215546Sopenharmony_ci                * at compile-time."
8680bf215546Sopenharmony_ci                *
8681bf215546Sopenharmony_ci                * In desktop GLSL it is allowed to have unsized-arrays that are
8682bf215546Sopenharmony_ci                * not last, as long as we can determine that they are implicitly
8683bf215546Sopenharmony_ci                * sized.
8684bf215546Sopenharmony_ci                */
8685bf215546Sopenharmony_ci               if (state->es_shader) {
8686bf215546Sopenharmony_ci                  _mesa_glsl_error(&loc, state, "unsized array `%s' "
8687bf215546Sopenharmony_ci                                   "definition: only last member of a shader "
8688bf215546Sopenharmony_ci                                   "storage block can be defined as unsized "
8689bf215546Sopenharmony_ci                                   "array", fields[i].name);
8690bf215546Sopenharmony_ci               }
8691bf215546Sopenharmony_ci            }
8692bf215546Sopenharmony_ci         }
8693bf215546Sopenharmony_ci
8694bf215546Sopenharmony_ci         state->symbols->add_variable(var);
8695bf215546Sopenharmony_ci         instructions->push_tail(var);
8696bf215546Sopenharmony_ci      }
8697bf215546Sopenharmony_ci
8698bf215546Sopenharmony_ci      if (redeclaring_per_vertex && block_type != earlier_per_vertex) {
8699bf215546Sopenharmony_ci         /* From section 7.1 ("Built-in Language Variables") of the GLSL 4.10 spec:
8700bf215546Sopenharmony_ci          *
8701bf215546Sopenharmony_ci          *     It is also a compilation error ... to redeclare a built-in
8702bf215546Sopenharmony_ci          *     block and then use a member from that built-in block that was
8703bf215546Sopenharmony_ci          *     not included in the redeclaration.
8704bf215546Sopenharmony_ci          *
8705bf215546Sopenharmony_ci          * This appears to be a clarification to the behaviour established
8706bf215546Sopenharmony_ci          * for gl_PerVertex by GLSL 1.50, therefore we implement this
8707bf215546Sopenharmony_ci          * behaviour regardless of GLSL version.
8708bf215546Sopenharmony_ci          *
8709bf215546Sopenharmony_ci          * To prevent the shader from using a member that was not included in
8710bf215546Sopenharmony_ci          * the redeclaration, we disable any ir_variables that are still
8711bf215546Sopenharmony_ci          * associated with the old declaration of gl_PerVertex (since we've
8712bf215546Sopenharmony_ci          * already updated all of the variables contained in the new
8713bf215546Sopenharmony_ci          * gl_PerVertex to point to it).
8714bf215546Sopenharmony_ci          *
8715bf215546Sopenharmony_ci          * As a side effect this will prevent
8716bf215546Sopenharmony_ci          * validate_intrastage_interface_blocks() from getting confused and
8717bf215546Sopenharmony_ci          * thinking there are conflicting definitions of gl_PerVertex in the
8718bf215546Sopenharmony_ci          * shader.
8719bf215546Sopenharmony_ci          */
8720bf215546Sopenharmony_ci         foreach_in_list_safe(ir_instruction, node, instructions) {
8721bf215546Sopenharmony_ci            ir_variable *const var = node->as_variable();
8722bf215546Sopenharmony_ci            if (var != NULL &&
8723bf215546Sopenharmony_ci                var->get_interface_type() == earlier_per_vertex &&
8724bf215546Sopenharmony_ci                var->data.mode == var_mode) {
8725bf215546Sopenharmony_ci               if (var->data.how_declared == ir_var_declared_normally) {
8726bf215546Sopenharmony_ci                  _mesa_glsl_error(&loc, state,
8727bf215546Sopenharmony_ci                                   "redeclaration of gl_PerVertex cannot "
8728bf215546Sopenharmony_ci                                   "follow a redeclaration of `%s'",
8729bf215546Sopenharmony_ci                                   var->name);
8730bf215546Sopenharmony_ci               }
8731bf215546Sopenharmony_ci               state->symbols->disable_variable(var->name);
8732bf215546Sopenharmony_ci               var->remove();
8733bf215546Sopenharmony_ci            }
8734bf215546Sopenharmony_ci         }
8735bf215546Sopenharmony_ci      }
8736bf215546Sopenharmony_ci   }
8737bf215546Sopenharmony_ci
8738bf215546Sopenharmony_ci   return NULL;
8739bf215546Sopenharmony_ci}
8740bf215546Sopenharmony_ci
8741bf215546Sopenharmony_ci
8742bf215546Sopenharmony_ciir_rvalue *
8743bf215546Sopenharmony_ciast_tcs_output_layout::hir(exec_list *instructions,
8744bf215546Sopenharmony_ci                           struct _mesa_glsl_parse_state *state)
8745bf215546Sopenharmony_ci{
8746bf215546Sopenharmony_ci   YYLTYPE loc = this->get_location();
8747bf215546Sopenharmony_ci
8748bf215546Sopenharmony_ci   unsigned num_vertices;
8749bf215546Sopenharmony_ci   if (!state->out_qualifier->vertices->
8750bf215546Sopenharmony_ci          process_qualifier_constant(state, "vertices", &num_vertices,
8751bf215546Sopenharmony_ci                                     false)) {
8752bf215546Sopenharmony_ci      /* return here to stop cascading incorrect error messages */
8753bf215546Sopenharmony_ci     return NULL;
8754bf215546Sopenharmony_ci   }
8755bf215546Sopenharmony_ci
8756bf215546Sopenharmony_ci   /* If any shader outputs occurred before this declaration and specified an
8757bf215546Sopenharmony_ci    * array size, make sure the size they specified is consistent with the
8758bf215546Sopenharmony_ci    * primitive type.
8759bf215546Sopenharmony_ci    */
8760bf215546Sopenharmony_ci   if (state->tcs_output_size != 0 && state->tcs_output_size != num_vertices) {
8761bf215546Sopenharmony_ci      _mesa_glsl_error(&loc, state,
8762bf215546Sopenharmony_ci                       "this tessellation control shader output layout "
8763bf215546Sopenharmony_ci                       "specifies %u vertices, but a previous output "
8764bf215546Sopenharmony_ci                       "is declared with size %u",
8765bf215546Sopenharmony_ci                       num_vertices, state->tcs_output_size);
8766bf215546Sopenharmony_ci      return NULL;
8767bf215546Sopenharmony_ci   }
8768bf215546Sopenharmony_ci
8769bf215546Sopenharmony_ci   state->tcs_output_vertices_specified = true;
8770bf215546Sopenharmony_ci
8771bf215546Sopenharmony_ci   /* If any shader outputs occurred before this declaration and did not
8772bf215546Sopenharmony_ci    * specify an array size, their size is determined now.
8773bf215546Sopenharmony_ci    */
8774bf215546Sopenharmony_ci   foreach_in_list (ir_instruction, node, instructions) {
8775bf215546Sopenharmony_ci      ir_variable *var = node->as_variable();
8776bf215546Sopenharmony_ci      if (var == NULL || var->data.mode != ir_var_shader_out)
8777bf215546Sopenharmony_ci         continue;
8778bf215546Sopenharmony_ci
8779bf215546Sopenharmony_ci      /* Note: Not all tessellation control shader output are arrays. */
8780bf215546Sopenharmony_ci      if (!var->type->is_unsized_array() || var->data.patch)
8781bf215546Sopenharmony_ci         continue;
8782bf215546Sopenharmony_ci
8783bf215546Sopenharmony_ci      if (var->data.max_array_access >= (int)num_vertices) {
8784bf215546Sopenharmony_ci         _mesa_glsl_error(&loc, state,
8785bf215546Sopenharmony_ci                          "this tessellation control shader output layout "
8786bf215546Sopenharmony_ci                          "specifies %u vertices, but an access to element "
8787bf215546Sopenharmony_ci                          "%u of output `%s' already exists", num_vertices,
8788bf215546Sopenharmony_ci                          var->data.max_array_access, var->name);
8789bf215546Sopenharmony_ci      } else {
8790bf215546Sopenharmony_ci         var->type = glsl_type::get_array_instance(var->type->fields.array,
8791bf215546Sopenharmony_ci                                                   num_vertices);
8792bf215546Sopenharmony_ci      }
8793bf215546Sopenharmony_ci   }
8794bf215546Sopenharmony_ci
8795bf215546Sopenharmony_ci   return NULL;
8796bf215546Sopenharmony_ci}
8797bf215546Sopenharmony_ci
8798bf215546Sopenharmony_ci
8799bf215546Sopenharmony_ciir_rvalue *
8800bf215546Sopenharmony_ciast_gs_input_layout::hir(exec_list *instructions,
8801bf215546Sopenharmony_ci                         struct _mesa_glsl_parse_state *state)
8802bf215546Sopenharmony_ci{
8803bf215546Sopenharmony_ci   YYLTYPE loc = this->get_location();
8804bf215546Sopenharmony_ci
8805bf215546Sopenharmony_ci   /* Should have been prevented by the parser. */
8806bf215546Sopenharmony_ci   assert(!state->gs_input_prim_type_specified
8807bf215546Sopenharmony_ci          || state->in_qualifier->prim_type == this->prim_type);
8808bf215546Sopenharmony_ci
8809bf215546Sopenharmony_ci   /* If any shader inputs occurred before this declaration and specified an
8810bf215546Sopenharmony_ci    * array size, make sure the size they specified is consistent with the
8811bf215546Sopenharmony_ci    * primitive type.
8812bf215546Sopenharmony_ci    */
8813bf215546Sopenharmony_ci   unsigned num_vertices = vertices_per_prim(this->prim_type);
8814bf215546Sopenharmony_ci   if (state->gs_input_size != 0 && state->gs_input_size != num_vertices) {
8815bf215546Sopenharmony_ci      _mesa_glsl_error(&loc, state,
8816bf215546Sopenharmony_ci                       "this geometry shader input layout implies %u vertices"
8817bf215546Sopenharmony_ci                       " per primitive, but a previous input is declared"
8818bf215546Sopenharmony_ci                       " with size %u", num_vertices, state->gs_input_size);
8819bf215546Sopenharmony_ci      return NULL;
8820bf215546Sopenharmony_ci   }
8821bf215546Sopenharmony_ci
8822bf215546Sopenharmony_ci   state->gs_input_prim_type_specified = true;
8823bf215546Sopenharmony_ci
8824bf215546Sopenharmony_ci   /* If any shader inputs occurred before this declaration and did not
8825bf215546Sopenharmony_ci    * specify an array size, their size is determined now.
8826bf215546Sopenharmony_ci    */
8827bf215546Sopenharmony_ci   foreach_in_list(ir_instruction, node, instructions) {
8828bf215546Sopenharmony_ci      ir_variable *var = node->as_variable();
8829bf215546Sopenharmony_ci      if (var == NULL || var->data.mode != ir_var_shader_in)
8830bf215546Sopenharmony_ci         continue;
8831bf215546Sopenharmony_ci
8832bf215546Sopenharmony_ci      /* Note: gl_PrimitiveIDIn has mode ir_var_shader_in, but it's not an
8833bf215546Sopenharmony_ci       * array; skip it.
8834bf215546Sopenharmony_ci       */
8835bf215546Sopenharmony_ci
8836bf215546Sopenharmony_ci      if (var->type->is_unsized_array()) {
8837bf215546Sopenharmony_ci         if (var->data.max_array_access >= (int)num_vertices) {
8838bf215546Sopenharmony_ci            _mesa_glsl_error(&loc, state,
8839bf215546Sopenharmony_ci                             "this geometry shader input layout implies %u"
8840bf215546Sopenharmony_ci                             " vertices, but an access to element %u of input"
8841bf215546Sopenharmony_ci                             " `%s' already exists", num_vertices,
8842bf215546Sopenharmony_ci                             var->data.max_array_access, var->name);
8843bf215546Sopenharmony_ci         } else {
8844bf215546Sopenharmony_ci            var->type = glsl_type::get_array_instance(var->type->fields.array,
8845bf215546Sopenharmony_ci                                                      num_vertices);
8846bf215546Sopenharmony_ci         }
8847bf215546Sopenharmony_ci      }
8848bf215546Sopenharmony_ci   }
8849bf215546Sopenharmony_ci
8850bf215546Sopenharmony_ci   return NULL;
8851bf215546Sopenharmony_ci}
8852bf215546Sopenharmony_ci
8853bf215546Sopenharmony_ci
8854bf215546Sopenharmony_ciir_rvalue *
8855bf215546Sopenharmony_ciast_cs_input_layout::hir(exec_list *instructions,
8856bf215546Sopenharmony_ci                         struct _mesa_glsl_parse_state *state)
8857bf215546Sopenharmony_ci{
8858bf215546Sopenharmony_ci   YYLTYPE loc = this->get_location();
8859bf215546Sopenharmony_ci
8860bf215546Sopenharmony_ci   /* From the ARB_compute_shader specification:
8861bf215546Sopenharmony_ci    *
8862bf215546Sopenharmony_ci    *     If the local size of the shader in any dimension is greater
8863bf215546Sopenharmony_ci    *     than the maximum size supported by the implementation for that
8864bf215546Sopenharmony_ci    *     dimension, a compile-time error results.
8865bf215546Sopenharmony_ci    *
8866bf215546Sopenharmony_ci    * It is not clear from the spec how the error should be reported if
8867bf215546Sopenharmony_ci    * the total size of the work group exceeds
8868bf215546Sopenharmony_ci    * MAX_COMPUTE_WORK_GROUP_INVOCATIONS, but it seems reasonable to
8869bf215546Sopenharmony_ci    * report it at compile time as well.
8870bf215546Sopenharmony_ci    */
8871bf215546Sopenharmony_ci   GLuint64 total_invocations = 1;
8872bf215546Sopenharmony_ci   unsigned qual_local_size[3];
8873bf215546Sopenharmony_ci   for (int i = 0; i < 3; i++) {
8874bf215546Sopenharmony_ci
8875bf215546Sopenharmony_ci      char *local_size_str = ralloc_asprintf(NULL, "invalid local_size_%c",
8876bf215546Sopenharmony_ci                                             'x' + i);
8877bf215546Sopenharmony_ci      /* Infer a local_size of 1 for unspecified dimensions */
8878bf215546Sopenharmony_ci      if (this->local_size[i] == NULL) {
8879bf215546Sopenharmony_ci         qual_local_size[i] = 1;
8880bf215546Sopenharmony_ci      } else if (!this->local_size[i]->
8881bf215546Sopenharmony_ci             process_qualifier_constant(state, local_size_str,
8882bf215546Sopenharmony_ci                                        &qual_local_size[i], false)) {
8883bf215546Sopenharmony_ci         ralloc_free(local_size_str);
8884bf215546Sopenharmony_ci         return NULL;
8885bf215546Sopenharmony_ci      }
8886bf215546Sopenharmony_ci      ralloc_free(local_size_str);
8887bf215546Sopenharmony_ci
8888bf215546Sopenharmony_ci      if (qual_local_size[i] > state->consts->MaxComputeWorkGroupSize[i]) {
8889bf215546Sopenharmony_ci         _mesa_glsl_error(&loc, state,
8890bf215546Sopenharmony_ci                          "local_size_%c exceeds MAX_COMPUTE_WORK_GROUP_SIZE"
8891bf215546Sopenharmony_ci                          " (%d)", 'x' + i,
8892bf215546Sopenharmony_ci                          state->consts->MaxComputeWorkGroupSize[i]);
8893bf215546Sopenharmony_ci         break;
8894bf215546Sopenharmony_ci      }
8895bf215546Sopenharmony_ci      total_invocations *= qual_local_size[i];
8896bf215546Sopenharmony_ci      if (total_invocations >
8897bf215546Sopenharmony_ci          state->consts->MaxComputeWorkGroupInvocations) {
8898bf215546Sopenharmony_ci         _mesa_glsl_error(&loc, state,
8899bf215546Sopenharmony_ci                          "product of local_sizes exceeds "
8900bf215546Sopenharmony_ci                          "MAX_COMPUTE_WORK_GROUP_INVOCATIONS (%d)",
8901bf215546Sopenharmony_ci                          state->consts->MaxComputeWorkGroupInvocations);
8902bf215546Sopenharmony_ci         break;
8903bf215546Sopenharmony_ci      }
8904bf215546Sopenharmony_ci   }
8905bf215546Sopenharmony_ci
8906bf215546Sopenharmony_ci   /* If any compute input layout declaration preceded this one, make sure it
8907bf215546Sopenharmony_ci    * was consistent with this one.
8908bf215546Sopenharmony_ci    */
8909bf215546Sopenharmony_ci   if (state->cs_input_local_size_specified) {
8910bf215546Sopenharmony_ci      for (int i = 0; i < 3; i++) {
8911bf215546Sopenharmony_ci         if (state->cs_input_local_size[i] != qual_local_size[i]) {
8912bf215546Sopenharmony_ci            _mesa_glsl_error(&loc, state,
8913bf215546Sopenharmony_ci                             "compute shader input layout does not match"
8914bf215546Sopenharmony_ci                             " previous declaration");
8915bf215546Sopenharmony_ci            return NULL;
8916bf215546Sopenharmony_ci         }
8917bf215546Sopenharmony_ci      }
8918bf215546Sopenharmony_ci   }
8919bf215546Sopenharmony_ci
8920bf215546Sopenharmony_ci   /* The ARB_compute_variable_group_size spec says:
8921bf215546Sopenharmony_ci    *
8922bf215546Sopenharmony_ci    *     If a compute shader including a *local_size_variable* qualifier also
8923bf215546Sopenharmony_ci    *     declares a fixed local group size using the *local_size_x*,
8924bf215546Sopenharmony_ci    *     *local_size_y*, or *local_size_z* qualifiers, a compile-time error
8925bf215546Sopenharmony_ci    *     results
8926bf215546Sopenharmony_ci    */
8927bf215546Sopenharmony_ci   if (state->cs_input_local_size_variable_specified) {
8928bf215546Sopenharmony_ci      _mesa_glsl_error(&loc, state,
8929bf215546Sopenharmony_ci                       "compute shader can't include both a variable and a "
8930bf215546Sopenharmony_ci                       "fixed local group size");
8931bf215546Sopenharmony_ci      return NULL;
8932bf215546Sopenharmony_ci   }
8933bf215546Sopenharmony_ci
8934bf215546Sopenharmony_ci   state->cs_input_local_size_specified = true;
8935bf215546Sopenharmony_ci   for (int i = 0; i < 3; i++)
8936bf215546Sopenharmony_ci      state->cs_input_local_size[i] = qual_local_size[i];
8937bf215546Sopenharmony_ci
8938bf215546Sopenharmony_ci   /* We may now declare the built-in constant gl_WorkGroupSize (see
8939bf215546Sopenharmony_ci    * builtin_variable_generator::generate_constants() for why we didn't
8940bf215546Sopenharmony_ci    * declare it earlier).
8941bf215546Sopenharmony_ci    */
8942bf215546Sopenharmony_ci   ir_variable *var = new(state->symbols)
8943bf215546Sopenharmony_ci      ir_variable(glsl_type::uvec3_type, "gl_WorkGroupSize", ir_var_auto);
8944bf215546Sopenharmony_ci   var->data.how_declared = ir_var_declared_implicitly;
8945bf215546Sopenharmony_ci   var->data.read_only = true;
8946bf215546Sopenharmony_ci   instructions->push_tail(var);
8947bf215546Sopenharmony_ci   state->symbols->add_variable(var);
8948bf215546Sopenharmony_ci   ir_constant_data data;
8949bf215546Sopenharmony_ci   memset(&data, 0, sizeof(data));
8950bf215546Sopenharmony_ci   for (int i = 0; i < 3; i++)
8951bf215546Sopenharmony_ci      data.u[i] = qual_local_size[i];
8952bf215546Sopenharmony_ci   var->constant_value = new(var) ir_constant(glsl_type::uvec3_type, &data);
8953bf215546Sopenharmony_ci   var->constant_initializer =
8954bf215546Sopenharmony_ci      new(var) ir_constant(glsl_type::uvec3_type, &data);
8955bf215546Sopenharmony_ci   var->data.has_initializer = true;
8956bf215546Sopenharmony_ci   var->data.is_implicit_initializer = false;
8957bf215546Sopenharmony_ci
8958bf215546Sopenharmony_ci   return NULL;
8959bf215546Sopenharmony_ci}
8960bf215546Sopenharmony_ci
8961bf215546Sopenharmony_ci
8962bf215546Sopenharmony_cistatic void
8963bf215546Sopenharmony_cidetect_conflicting_assignments(struct _mesa_glsl_parse_state *state,
8964bf215546Sopenharmony_ci                               exec_list *instructions)
8965bf215546Sopenharmony_ci{
8966bf215546Sopenharmony_ci   bool gl_FragColor_assigned = false;
8967bf215546Sopenharmony_ci   bool gl_FragData_assigned = false;
8968bf215546Sopenharmony_ci   bool gl_FragSecondaryColor_assigned = false;
8969bf215546Sopenharmony_ci   bool gl_FragSecondaryData_assigned = false;
8970bf215546Sopenharmony_ci   bool user_defined_fs_output_assigned = false;
8971bf215546Sopenharmony_ci   ir_variable *user_defined_fs_output = NULL;
8972bf215546Sopenharmony_ci
8973bf215546Sopenharmony_ci   /* It would be nice to have proper location information. */
8974bf215546Sopenharmony_ci   YYLTYPE loc;
8975bf215546Sopenharmony_ci   memset(&loc, 0, sizeof(loc));
8976bf215546Sopenharmony_ci
8977bf215546Sopenharmony_ci   foreach_in_list(ir_instruction, node, instructions) {
8978bf215546Sopenharmony_ci      ir_variable *var = node->as_variable();
8979bf215546Sopenharmony_ci
8980bf215546Sopenharmony_ci      if (!var || !var->data.assigned)
8981bf215546Sopenharmony_ci         continue;
8982bf215546Sopenharmony_ci
8983bf215546Sopenharmony_ci      if (strcmp(var->name, "gl_FragColor") == 0) {
8984bf215546Sopenharmony_ci         gl_FragColor_assigned = true;
8985bf215546Sopenharmony_ci         if (!var->constant_initializer && state->zero_init) {
8986bf215546Sopenharmony_ci            const ir_constant_data data = { { 0 } };
8987bf215546Sopenharmony_ci            var->data.has_initializer = true;
8988bf215546Sopenharmony_ci            var->data.is_implicit_initializer = true;
8989bf215546Sopenharmony_ci            var->constant_initializer = new(var) ir_constant(var->type, &data);
8990bf215546Sopenharmony_ci         }
8991bf215546Sopenharmony_ci      }
8992bf215546Sopenharmony_ci      else if (strcmp(var->name, "gl_FragData") == 0)
8993bf215546Sopenharmony_ci         gl_FragData_assigned = true;
8994bf215546Sopenharmony_ci        else if (strcmp(var->name, "gl_SecondaryFragColorEXT") == 0)
8995bf215546Sopenharmony_ci         gl_FragSecondaryColor_assigned = true;
8996bf215546Sopenharmony_ci        else if (strcmp(var->name, "gl_SecondaryFragDataEXT") == 0)
8997bf215546Sopenharmony_ci         gl_FragSecondaryData_assigned = true;
8998bf215546Sopenharmony_ci      else if (!is_gl_identifier(var->name)) {
8999bf215546Sopenharmony_ci         if (state->stage == MESA_SHADER_FRAGMENT &&
9000bf215546Sopenharmony_ci             var->data.mode == ir_var_shader_out) {
9001bf215546Sopenharmony_ci            user_defined_fs_output_assigned = true;
9002bf215546Sopenharmony_ci            user_defined_fs_output = var;
9003bf215546Sopenharmony_ci         }
9004bf215546Sopenharmony_ci      }
9005bf215546Sopenharmony_ci   }
9006bf215546Sopenharmony_ci
9007bf215546Sopenharmony_ci   /* From the GLSL 1.30 spec:
9008bf215546Sopenharmony_ci    *
9009bf215546Sopenharmony_ci    *     "If a shader statically assigns a value to gl_FragColor, it
9010bf215546Sopenharmony_ci    *      may not assign a value to any element of gl_FragData. If a
9011bf215546Sopenharmony_ci    *      shader statically writes a value to any element of
9012bf215546Sopenharmony_ci    *      gl_FragData, it may not assign a value to
9013bf215546Sopenharmony_ci    *      gl_FragColor. That is, a shader may assign values to either
9014bf215546Sopenharmony_ci    *      gl_FragColor or gl_FragData, but not both. Multiple shaders
9015bf215546Sopenharmony_ci    *      linked together must also consistently write just one of
9016bf215546Sopenharmony_ci    *      these variables.  Similarly, if user declared output
9017bf215546Sopenharmony_ci    *      variables are in use (statically assigned to), then the
9018bf215546Sopenharmony_ci    *      built-in variables gl_FragColor and gl_FragData may not be
9019bf215546Sopenharmony_ci    *      assigned to. These incorrect usages all generate compile
9020bf215546Sopenharmony_ci    *      time errors."
9021bf215546Sopenharmony_ci    */
9022bf215546Sopenharmony_ci   if (gl_FragColor_assigned && gl_FragData_assigned) {
9023bf215546Sopenharmony_ci      _mesa_glsl_error(&loc, state, "fragment shader writes to both "
9024bf215546Sopenharmony_ci                       "`gl_FragColor' and `gl_FragData'");
9025bf215546Sopenharmony_ci   } else if (gl_FragColor_assigned && user_defined_fs_output_assigned) {
9026bf215546Sopenharmony_ci      _mesa_glsl_error(&loc, state, "fragment shader writes to both "
9027bf215546Sopenharmony_ci                       "`gl_FragColor' and `%s'",
9028bf215546Sopenharmony_ci                       user_defined_fs_output->name);
9029bf215546Sopenharmony_ci   } else if (gl_FragSecondaryColor_assigned && gl_FragSecondaryData_assigned) {
9030bf215546Sopenharmony_ci      _mesa_glsl_error(&loc, state, "fragment shader writes to both "
9031bf215546Sopenharmony_ci                       "`gl_FragSecondaryColorEXT' and"
9032bf215546Sopenharmony_ci                       " `gl_FragSecondaryDataEXT'");
9033bf215546Sopenharmony_ci   } else if (gl_FragColor_assigned && gl_FragSecondaryData_assigned) {
9034bf215546Sopenharmony_ci      _mesa_glsl_error(&loc, state, "fragment shader writes to both "
9035bf215546Sopenharmony_ci                       "`gl_FragColor' and"
9036bf215546Sopenharmony_ci                       " `gl_FragSecondaryDataEXT'");
9037bf215546Sopenharmony_ci   } else if (gl_FragData_assigned && gl_FragSecondaryColor_assigned) {
9038bf215546Sopenharmony_ci      _mesa_glsl_error(&loc, state, "fragment shader writes to both "
9039bf215546Sopenharmony_ci                       "`gl_FragData' and"
9040bf215546Sopenharmony_ci                       " `gl_FragSecondaryColorEXT'");
9041bf215546Sopenharmony_ci   } else if (gl_FragData_assigned && user_defined_fs_output_assigned) {
9042bf215546Sopenharmony_ci      _mesa_glsl_error(&loc, state, "fragment shader writes to both "
9043bf215546Sopenharmony_ci                       "`gl_FragData' and `%s'",
9044bf215546Sopenharmony_ci                       user_defined_fs_output->name);
9045bf215546Sopenharmony_ci   }
9046bf215546Sopenharmony_ci
9047bf215546Sopenharmony_ci   if ((gl_FragSecondaryColor_assigned || gl_FragSecondaryData_assigned) &&
9048bf215546Sopenharmony_ci       !state->EXT_blend_func_extended_enable) {
9049bf215546Sopenharmony_ci      _mesa_glsl_error(&loc, state,
9050bf215546Sopenharmony_ci                       "Dual source blending requires EXT_blend_func_extended");
9051bf215546Sopenharmony_ci   }
9052bf215546Sopenharmony_ci}
9053bf215546Sopenharmony_ci
9054bf215546Sopenharmony_cistatic void
9055bf215546Sopenharmony_civerify_subroutine_associated_funcs(struct _mesa_glsl_parse_state *state)
9056bf215546Sopenharmony_ci{
9057bf215546Sopenharmony_ci   YYLTYPE loc;
9058bf215546Sopenharmony_ci   memset(&loc, 0, sizeof(loc));
9059bf215546Sopenharmony_ci
9060bf215546Sopenharmony_ci   /* Section 6.1.2 (Subroutines) of the GLSL 4.00 spec says:
9061bf215546Sopenharmony_ci    *
9062bf215546Sopenharmony_ci    *   "A program will fail to compile or link if any shader
9063bf215546Sopenharmony_ci    *    or stage contains two or more functions with the same
9064bf215546Sopenharmony_ci    *    name if the name is associated with a subroutine type."
9065bf215546Sopenharmony_ci    */
9066bf215546Sopenharmony_ci
9067bf215546Sopenharmony_ci   for (int i = 0; i < state->num_subroutines; i++) {
9068bf215546Sopenharmony_ci      unsigned definitions = 0;
9069bf215546Sopenharmony_ci      ir_function *fn = state->subroutines[i];
9070bf215546Sopenharmony_ci      /* Calculate number of function definitions with the same name */
9071bf215546Sopenharmony_ci      foreach_in_list(ir_function_signature, sig, &fn->signatures) {
9072bf215546Sopenharmony_ci         if (sig->is_defined) {
9073bf215546Sopenharmony_ci            if (++definitions > 1) {
9074bf215546Sopenharmony_ci               _mesa_glsl_error(&loc, state,
9075bf215546Sopenharmony_ci                     "%s shader contains two or more function "
9076bf215546Sopenharmony_ci                     "definitions with name `%s', which is "
9077bf215546Sopenharmony_ci                     "associated with a subroutine type.\n",
9078bf215546Sopenharmony_ci                     _mesa_shader_stage_to_string(state->stage),
9079bf215546Sopenharmony_ci                     fn->name);
9080bf215546Sopenharmony_ci               return;
9081bf215546Sopenharmony_ci            }
9082bf215546Sopenharmony_ci         }
9083bf215546Sopenharmony_ci      }
9084bf215546Sopenharmony_ci   }
9085bf215546Sopenharmony_ci}
9086bf215546Sopenharmony_ci
9087bf215546Sopenharmony_cistatic void
9088bf215546Sopenharmony_ciremove_per_vertex_blocks(exec_list *instructions,
9089bf215546Sopenharmony_ci                         _mesa_glsl_parse_state *state, ir_variable_mode mode)
9090bf215546Sopenharmony_ci{
9091bf215546Sopenharmony_ci   /* Find the gl_PerVertex interface block of the appropriate (in/out) mode,
9092bf215546Sopenharmony_ci    * if it exists in this shader type.
9093bf215546Sopenharmony_ci    */
9094bf215546Sopenharmony_ci   const glsl_type *per_vertex = NULL;
9095bf215546Sopenharmony_ci   switch (mode) {
9096bf215546Sopenharmony_ci   case ir_var_shader_in:
9097bf215546Sopenharmony_ci      if (ir_variable *gl_in = state->symbols->get_variable("gl_in"))
9098bf215546Sopenharmony_ci         per_vertex = gl_in->get_interface_type();
9099bf215546Sopenharmony_ci      break;
9100bf215546Sopenharmony_ci   case ir_var_shader_out:
9101bf215546Sopenharmony_ci      if (ir_variable *gl_Position =
9102bf215546Sopenharmony_ci          state->symbols->get_variable("gl_Position")) {
9103bf215546Sopenharmony_ci         per_vertex = gl_Position->get_interface_type();
9104bf215546Sopenharmony_ci      }
9105bf215546Sopenharmony_ci      break;
9106bf215546Sopenharmony_ci   default:
9107bf215546Sopenharmony_ci      assert(!"Unexpected mode");
9108bf215546Sopenharmony_ci      break;
9109bf215546Sopenharmony_ci   }
9110bf215546Sopenharmony_ci
9111bf215546Sopenharmony_ci   /* If we didn't find a built-in gl_PerVertex interface block, then we don't
9112bf215546Sopenharmony_ci    * need to do anything.
9113bf215546Sopenharmony_ci    */
9114bf215546Sopenharmony_ci   if (per_vertex == NULL)
9115bf215546Sopenharmony_ci      return;
9116bf215546Sopenharmony_ci
9117bf215546Sopenharmony_ci   /* If the interface block is used by the shader, then we don't need to do
9118bf215546Sopenharmony_ci    * anything.
9119bf215546Sopenharmony_ci    */
9120bf215546Sopenharmony_ci   interface_block_usage_visitor v(mode, per_vertex);
9121bf215546Sopenharmony_ci   v.run(instructions);
9122bf215546Sopenharmony_ci   if (v.usage_found())
9123bf215546Sopenharmony_ci      return;
9124bf215546Sopenharmony_ci
9125bf215546Sopenharmony_ci   /* Remove any ir_variable declarations that refer to the interface block
9126bf215546Sopenharmony_ci    * we're removing.
9127bf215546Sopenharmony_ci    */
9128bf215546Sopenharmony_ci   foreach_in_list_safe(ir_instruction, node, instructions) {
9129bf215546Sopenharmony_ci      ir_variable *const var = node->as_variable();
9130bf215546Sopenharmony_ci      if (var != NULL && var->get_interface_type() == per_vertex &&
9131bf215546Sopenharmony_ci          var->data.mode == mode) {
9132bf215546Sopenharmony_ci         state->symbols->disable_variable(var->name);
9133bf215546Sopenharmony_ci         var->remove();
9134bf215546Sopenharmony_ci      }
9135bf215546Sopenharmony_ci   }
9136bf215546Sopenharmony_ci}
9137bf215546Sopenharmony_ci
9138bf215546Sopenharmony_ciir_rvalue *
9139bf215546Sopenharmony_ciast_warnings_toggle::hir(exec_list *,
9140bf215546Sopenharmony_ci                         struct _mesa_glsl_parse_state *state)
9141bf215546Sopenharmony_ci{
9142bf215546Sopenharmony_ci   state->warnings_enabled = enable;
9143bf215546Sopenharmony_ci   return NULL;
9144bf215546Sopenharmony_ci}
9145