glsl: fix missing breaks in equals(ir_texture,..)
[mesa.git] / src / glsl / glsl_parser.yy
index 2c339add62af43e75252020e9f44a5721f49f15c..ada3690f609093a8d8097da4c2547cfe29a2f47c 100644 (file)
@@ -43,6 +43,32 @@ _mesa_glsl_lex(YYSTYPE *val, YYLTYPE *loc, _mesa_glsl_parse_state *state)
 {
    return _mesa_glsl_lexer_lex(val, loc, state->scanner);
 }
+
+static bool match_layout_qualifier(const char *s1, const char *s2,
+                                   _mesa_glsl_parse_state *state)
+{
+   /* From the GLSL 1.50 spec, section 4.3.8 (Layout Qualifiers):
+    *
+    *     "The tokens in any layout-qualifier-id-list ... are not case
+    *     sensitive, unless explicitly noted otherwise."
+    *
+    * The text "unless explicitly noted otherwise" appears to be
+    * vacuous--no desktop GLSL spec (up through GLSL 4.40) notes
+    * otherwise.
+    *
+    * However, the GLSL ES 3.00 spec says, in section 4.3.8 (Layout
+    * Qualifiers):
+    *
+    *     "As for other identifiers, they are case sensitive."
+    *
+    * So we need to do a case-sensitive or a case-insensitive match,
+    * depending on whether we are compiling for GLSL ES.
+    */
+   if (state->es_shader)
+      return strcmp(s1, s2);
+   else
+      return strcasecmp(s1, s2);
+}
 %}
 
 %expect 0
@@ -118,6 +144,7 @@ _mesa_glsl_lex(YYSTYPE *val, YYLTYPE *loc, _mesa_glsl_parse_state *state)
 %token SAMPLER2DMS ISAMPLER2DMS USAMPLER2DMS
 %token SAMPLER2DMSARRAY ISAMPLER2DMSARRAY USAMPLER2DMSARRAY
 %token SAMPLEREXTERNALOES
+%token ATOMIC_UINT
 %token STRUCT VOID_TOK WHILE
 %token <identifier> IDENTIFIER TYPE_IDENTIFIER NEW_IDENTIFIER
 %type <identifier> any_identifier
@@ -147,7 +174,7 @@ _mesa_glsl_lex(YYSTYPE *val, YYLTYPE *loc, _mesa_glsl_parse_state *state)
 %token HVEC2 HVEC3 HVEC4 DVEC2 DVEC3 DVEC4 FVEC2 FVEC3 FVEC4
 %token SAMPLER3DRECT
 %token SIZEOF CAST NAMESPACE USING
-%token COHERENT RESTRICT READONLY WRITEONLY RESOURCE ATOMIC_UINT PATCH SAMPLE
+%token COHERENT RESTRICT READONLY WRITEONLY RESOURCE PATCH SAMPLE
 %token SUBROUTINE
 
 %token ERROR_TOK
@@ -1158,10 +1185,12 @@ layout_qualifier_id:
       memset(& $$, 0, sizeof($$));
 
       /* Layout qualifiers for ARB_fragment_coord_conventions. */
-      if (!$$.flags.i && state->ARB_fragment_coord_conventions_enable) {
-         if (strcmp($1, "origin_upper_left") == 0) {
+      if (!$$.flags.i && (state->ARB_fragment_coord_conventions_enable ||
+                          state->is_version(150, 0))) {
+         if (match_layout_qualifier($1, "origin_upper_left", state) == 0) {
             $$.flags.q.origin_upper_left = 1;
-         } else if (strcmp($1, "pixel_center_integer") == 0) {
+         } else if (match_layout_qualifier($1, "pixel_center_integer",
+                                           state) == 0) {
             $$.flags.q.pixel_center_integer = 1;
          }
 
@@ -1176,13 +1205,14 @@ layout_qualifier_id:
       if (!$$.flags.i &&
           (state->AMD_conservative_depth_enable ||
            state->ARB_conservative_depth_enable)) {
-         if (strcmp($1, "depth_any") == 0) {
+         if (match_layout_qualifier($1, "depth_any", state) == 0) {
             $$.flags.q.depth_any = 1;
-         } else if (strcmp($1, "depth_greater") == 0) {
+         } else if (match_layout_qualifier($1, "depth_greater", state) == 0) {
             $$.flags.q.depth_greater = 1;
-         } else if (strcmp($1, "depth_less") == 0) {
+         } else if (match_layout_qualifier($1, "depth_less", state) == 0) {
             $$.flags.q.depth_less = 1;
-         } else if (strcmp($1, "depth_unchanged") == 0) {
+         } else if (match_layout_qualifier($1, "depth_unchanged",
+                                           state) == 0) {
             $$.flags.q.depth_unchanged = 1;
          }
 
@@ -1199,21 +1229,33 @@ layout_qualifier_id:
       }
 
       /* See also interface_block_layout_qualifier. */
-      if (!$$.flags.i && state->ARB_uniform_buffer_object_enable) {
-         if (strcmp($1, "std140") == 0) {
+      if (!$$.flags.i && state->has_uniform_buffer_objects()) {
+         if (match_layout_qualifier($1, "std140", state) == 0) {
             $$.flags.q.std140 = 1;
-         } else if (strcmp($1, "shared") == 0) {
+         } else if (match_layout_qualifier($1, "shared", state) == 0) {
             $$.flags.q.shared = 1;
-         } else if (strcmp($1, "column_major") == 0) {
+         } else if (match_layout_qualifier($1, "column_major", state) == 0) {
             $$.flags.q.column_major = 1;
          /* "row_major" is a reserved word in GLSL 1.30+. Its token is parsed
           * below in the interface_block_layout_qualifier rule.
           *
           * It is not a reserved word in GLSL ES 3.00, so it's handled here as
           * an identifier.
+          *
+          * Also, this takes care of alternate capitalizations of
+          * "row_major" (which is necessary because layout qualifiers
+          * are case-insensitive in desktop GLSL).
           */
-         } else if (strcmp($1, "row_major") == 0) {
+         } else if (match_layout_qualifier($1, "row_major", state) == 0) {
             $$.flags.q.row_major = 1;
+         /* "packed" is a reserved word in GLSL, and its token is
+          * parsed below in the interface_block_layout_qualifier rule.
+          * However, we must take care of alternate capitalizations of
+          * "packed", because layout qualifiers are case-insensitive
+          * in desktop GLSL.
+          */
+         } else if (match_layout_qualifier($1, "packed", state) == 0) {
+           $$.flags.q.packed = 1;
          }
 
          if ($$.flags.i && state->ARB_uniform_buffer_object_warn) {
@@ -1238,7 +1280,7 @@ layout_qualifier_id:
                  { "triangle_strip", GL_TRIANGLE_STRIP },
          };
          for (unsigned i = 0; i < Elements(map); i++) {
-            if (strcmp($1, map[i].s) == 0) {
+            if (match_layout_qualifier($1, map[i].s, state) == 0) {
                $$.flags.q.prim_type = 1;
                $$.prim_type = map[i].e;
                break;
@@ -1261,39 +1303,42 @@ layout_qualifier_id:
    {
       memset(& $$, 0, sizeof($$));
 
-      if (state->ARB_explicit_attrib_location_enable) {
-         if (strcmp("location", $1) == 0) {
-            $$.flags.q.explicit_location = 1;
+      if (match_layout_qualifier("location", $1, state) == 0) {
+         $$.flags.q.explicit_location = 1;
 
-            if ($3 >= 0) {
-               $$.location = $3;
-            } else {
-               _mesa_glsl_error(& @3, state,
-                                "invalid location %d specified", $3);
-               YYERROR;
-            }
+         if ($3 >= 0) {
+            $$.location = $3;
+         } else {
+             _mesa_glsl_error(& @3, state, "invalid location %d specified", $3);
+             YYERROR;
          }
+      }
 
-         if (strcmp("index", $1) == 0) {
-            $$.flags.q.explicit_index = 1;
+      if (match_layout_qualifier("index", $1, state) == 0) {
+         $$.flags.q.explicit_index = 1;
 
-            if ($3 >= 0) {
-               $$.index = $3;
-            } else {
-               _mesa_glsl_error(& @3, state,
-                                "invalid index %d specified", $3);
-               YYERROR;
-            }
+         if ($3 >= 0) {
+            $$.index = $3;
+         } else {
+            _mesa_glsl_error(& @3, state, "invalid index %d specified", $3);
+            YYERROR;
          }
       }
 
-      if (state->ARB_shading_language_420pack_enable &&
-          strcmp("binding", $1) == 0) {
+      if ((state->ARB_shading_language_420pack_enable ||
+           state->ARB_shader_atomic_counters_enable) &&
+          match_layout_qualifier("binding", $1, state) == 0) {
          $$.flags.q.explicit_binding = 1;
          $$.binding = $3;
       }
 
-      if (strcmp("max_vertices", $1) == 0) {
+      if (state->ARB_shader_atomic_counters_enable &&
+          match_layout_qualifier("offset", $1, state) == 0) {
+         $$.flags.q.explicit_offset = 1;
+         $$.offset = $3;
+      }
+
+      if (match_layout_qualifier("max_vertices", $1, state) == 0) {
          $$.flags.q.max_vertices = 1;
 
          if ($3 < 0) {
@@ -1327,7 +1372,7 @@ layout_qualifier_id:
    {
       $$ = $1;
       /* Layout qualifiers for ARB_uniform_buffer_object. */
-      if ($$.flags.q.uniform && !state->ARB_uniform_buffer_object_enable) {
+      if ($$.flags.q.uniform && !state->has_uniform_buffer_objects()) {
          _mesa_glsl_error(& @1, state,
                           "#version 140 / GL_ARB_uniform_buffer_object "
                           "layout qualifier `%s' is used", $1);
@@ -1343,6 +1388,10 @@ layout_qualifier_id:
  * (due to them being reserved keywords) instead of identifiers like
  * most qualifiers.  See the any_identifier path of
  * layout_qualifier_id for the others.
+ *
+ * Note that since layout qualifiers are case-insensitive in desktop
+ * GLSL, all of these qualifiers need to be handled as identifiers as
+ * well (by the any_identifier path of layout_qualifier_id).
  */
 interface_block_layout_qualifier:
    ROW_MAJOR
@@ -1662,6 +1711,7 @@ basic_type_specifier_nonarray:
    | SAMPLER2DMSARRAY       { $$ = "sampler2DMSArray"; }
    | ISAMPLER2DMSARRAY      { $$ = "isampler2DMSArray"; }
    | USAMPLER2DMSARRAY      { $$ = "usampler2DMSArray"; }
+   | ATOMIC_UINT            { $$ = "atomic_uint"; }
    ;
 
 precision_qualifier:
@@ -1713,13 +1763,17 @@ struct_declaration_list:
    ;
 
 struct_declaration:
-   type_specifier struct_declarator_list ';'
+   fully_specified_type struct_declarator_list ';'
    {
       void *ctx = state;
-      ast_fully_specified_type *type = new(ctx) ast_fully_specified_type();
+      ast_fully_specified_type *const type = $1;
       type->set_location(yylloc);
 
-      type->specifier = $1;
+      if (type->qualifier.flags.i != 0)
+         _mesa_glsl_error(&@1, state,
+                         "only precision qualifiers may be applied to "
+                         "structure members");
+
       $$ = new(ctx) ast_declarator_list(type);
       $$->set_location(yylloc);
 
@@ -1747,6 +1801,12 @@ struct_declarator:
       $$ = new(ctx) ast_declaration($1, false, NULL, NULL);
       $$->set_location(yylloc);
    }
+   | any_identifier '[' ']'
+   {
+      void *ctx = state;
+      $$ = new(ctx) ast_declaration($1, true, NULL, NULL);
+      $$->set_location(yylloc);
+   }
    | any_identifier '[' constant_expression ']'
    {
       void *ctx = state;
@@ -2133,7 +2193,7 @@ basic_interface_block:
       block->declarations.push_degenerate_list_at_head(& $4->link);
 
       if ($1.flags.q.uniform) {
-         if (!state->ARB_uniform_buffer_object_enable) {
+         if (!state->has_uniform_buffer_objects()) {
             _mesa_glsl_error(& @1, state,
                              "#version 140 / GL_ARB_uniform_buffer_object "
                              "required for defining uniform blocks");
@@ -2243,25 +2303,22 @@ instance_name_opt:
    /* empty */
    {
       $$ = new(state) ast_interface_block(*state->default_uniform_qualifier,
-                                          NULL, NULL);
+                                          NULL, false, NULL);
    }
    | NEW_IDENTIFIER
    {
       $$ = new(state) ast_interface_block(*state->default_uniform_qualifier,
-                                          $1, NULL);
+                                          $1, false, NULL);
    }
    | NEW_IDENTIFIER '[' constant_expression ']'
    {
       $$ = new(state) ast_interface_block(*state->default_uniform_qualifier,
-                                          $1, $3);
+                                          $1, true, $3);
    }
    | NEW_IDENTIFIER '[' ']'
    {
-      _mesa_glsl_error(& @1, state,
-                       "instance block arrays must be explicitly sized");
-
       $$ = new(state) ast_interface_block(*state->default_uniform_qualifier,
-                                          $1, NULL);
+                                          $1, true, NULL);
    }
    ;
 
@@ -2297,7 +2354,6 @@ member_declaration:
 
       $$ = new(ctx) ast_declarator_list(type);
       $$->set_location(yylloc);
-      $$->ubo_qualifiers_valid = true;
 
       $$->declarations.push_degenerate_list_at_head(& $2->link);
    }
@@ -2315,6 +2371,7 @@ layout_defaults:
    | layout_qualifier IN_TOK ';'
    {
       void *ctx = state;
+      $$ = NULL;
       if (state->target != geometry_shader) {
          _mesa_glsl_error(& @1, state,
                           "input layout qualifiers only valid in "
@@ -2323,8 +2380,22 @@ layout_defaults:
          _mesa_glsl_error(& @1, state,
                           "input layout qualifiers must specify a primitive"
                           " type");
+      } else {
+         /* Make sure this is a valid input primitive type. */
+         switch ($1.prim_type) {
+         case GL_POINTS:
+         case GL_LINES:
+         case GL_LINES_ADJACENCY:
+         case GL_TRIANGLES:
+         case GL_TRIANGLES_ADJACENCY:
+            $$ = new(ctx) ast_gs_input_layout(@1, $1.prim_type);
+            break;
+         default:
+            _mesa_glsl_error(&@1, state,
+                             "invalid geometry shader input primitive type");
+            break;
+         }
       }
-      $$ = new(ctx) ast_gs_input_layout(@1, $1.prim_type);
    }
 
    | layout_qualifier OUT_TOK ';'
@@ -2333,8 +2404,22 @@ layout_defaults:
          _mesa_glsl_error(& @1, state,
                           "out layout qualifiers only valid in "
                           "geometry shaders");
-      } else if (!state->out_qualifier->merge_qualifier(& @1, state, $1)) {
-         YYERROR;
+      } else {
+         if ($1.flags.q.prim_type) {
+            /* Make sure this is a valid output primitive type. */
+            switch ($1.prim_type) {
+            case GL_POINTS:
+            case GL_LINE_STRIP:
+            case GL_TRIANGLE_STRIP:
+               break;
+            default:
+               _mesa_glsl_error(&@1, state, "invalid geometry shader output "
+                                "primitive type");
+               break;
+            }
+         }
+         if (!state->out_qualifier->merge_qualifier(& @1, state, $1))
+            YYERROR;
       }
       $$ = NULL;
    }