glsl: Rework lexer keyword handling in preparation for GLSL 3.00 ES.
authorPaul Berry <stereotype441@gmail.com>
Thu, 2 Aug 2012 02:04:59 +0000 (19:04 -0700)
committerIan Romanick <ian.d.romanick@intel.com>
Thu, 6 Dec 2012 20:13:21 +0000 (12:13 -0800)
This patch expands the lexer KEYWORD macro to take two additional
arguments: the GLSL ES versions in which the given keyword was first
reserved, and supported, respectively.  This will allow us to
trivially add support for GLSL 3.00 ES keywords, even though the set
of GLSL 3.00 ES keywords is neither a subset or a superset of the
keywords corresponding to any desktop GLSL version.

The new KEYWORD macro makes use of the
_mesa_glsl_parse_state::is_version() function, so it accepts 0 as
meaning "unsupported" (rather than 999, which we used previously).

Note that a few keywords ("packed" and "row_major") are supported
*either* when GLSL 1.40 is in use or when ARB_uniform_buffer_obj
support is enabled.  Previously, we handled these by cleverly taking
advantage of the fact that the KEYWORD macro didn't parenthesize its
arguments in the usual way.  Now they are handled more
straightforwardly, with a new macro, KEYWORD_WITH_ALT.

Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Acked-by: Carl Worth <cworth@cworth.org>
src/glsl/glsl_lexer.ll

index d2c8c317454578f34ab15bfbd82d161cd28b77b5..ef1402bfcccc8025900112061b810c36567494eb 100644 (file)
@@ -48,20 +48,34 @@ static int classify_identifier(struct _mesa_glsl_parse_state *, const char *);
  *
  * Certain words start out as identifiers, become reserved words in
  * later language revisions, and finally become language keywords.
+ * This may happen at different times in desktop GLSL and GLSL ES.
  *
  * For example, consider the following lexer rule:
- * samplerBuffer       KEYWORD(130, 140, SAMPLERBUFFER)
+ * samplerBuffer       KEYWORD(130, 0, 140, 0, SAMPLERBUFFER)
  *
  * This means that "samplerBuffer" will be treated as:
  * - a keyword (SAMPLERBUFFER token)         ...in GLSL >= 1.40
  * - a reserved word - error                 ...in GLSL >= 1.30
- * - an identifier                           ...in GLSL <  1.30
+ * - an identifier                           ...in GLSL <  1.30 or GLSL ES
  */
-#define KEYWORD(reserved_version, allowed_version, token)              \
+#define KEYWORD(reserved_glsl, reserved_glsl_es,                       \
+                allowed_glsl, allowed_glsl_es, token)                  \
+   KEYWORD_WITH_ALT(reserved_glsl, reserved_glsl_es,                   \
+                    allowed_glsl, allowed_glsl_es, false, token)
+
+/**
+ * Like the KEYWORD macro, but the word is also treated as a keyword
+ * if the given boolean expression is true.
+ */
+#define KEYWORD_WITH_ALT(reserved_glsl, reserved_glsl_es,              \
+                         allowed_glsl, allowed_glsl_es,                        \
+                         alt_expr, token)                              \
    do {                                                                        \
-      if (yyextra->language_version >= allowed_version) {              \
+      if (yyextra->is_version(allowed_glsl, allowed_glsl_es)           \
+          || alt_expr) {                                               \
         return token;                                                  \
-      } else if (yyextra->language_version >= reserved_version) {      \
+      } else if (yyextra->is_version(reserved_glsl,                    \
+                                     reserved_glsl_es)) {              \
         _mesa_glsl_error(yylloc, yyextra,                              \
                          "Illegal use of reserved word `%s'", yytext); \
         return ERROR_TOK;                                              \
@@ -71,16 +85,6 @@ static int classify_identifier(struct _mesa_glsl_parse_state *, const char *);
       }                                                                        \
    } while (0)
 
-/* The ES macro can be used in KEYWORD checks:
- *
- *    word      KEYWORD(110 || ES, 400, TOKEN)
- * ...means the word is reserved in GLSL ES 1.00, while
- *
- *    word      KEYWORD(110, 130 || ES, TOKEN)
- * ...means the word is a legal keyword in GLSL ES 1.00.
- */
-#define ES yyextra->es_shader
-
 static int
 literal_integer(char *text, int len, struct _mesa_glsl_parse_state *state,
                YYSTYPE *lval, YYLTYPE *lloc, int base)
@@ -224,7 +228,7 @@ const               return CONST_TOK;
 bool           return BOOL_TOK;
 float          return FLOAT_TOK;
 int            return INT_TOK;
-uint           KEYWORD(130, 130, UINT_TOK);
+uint           KEYWORD(130, 0, 130, 0, UINT_TOK);
 
 break          return BREAK;
 continue       return CONTINUE;
@@ -242,59 +246,59 @@ bvec4             return BVEC4;
 ivec2          return IVEC2;
 ivec3          return IVEC3;
 ivec4          return IVEC4;
-uvec2          KEYWORD(130, 130, UVEC2);
-uvec3          KEYWORD(130, 130, UVEC3);
-uvec4          KEYWORD(130, 130, UVEC4);
+uvec2          KEYWORD(130, 0, 130, 0, UVEC2);
+uvec3          KEYWORD(130, 0, 130, 0, UVEC3);
+uvec4          KEYWORD(130, 0, 130, 0, UVEC4);
 vec2           return VEC2;
 vec3           return VEC3;
 vec4           return VEC4;
 mat2           return MAT2X2;
 mat3           return MAT3X3;
 mat4           return MAT4X4;
-mat2x2         KEYWORD(120, 120, MAT2X2);
-mat2x3         KEYWORD(120, 120, MAT2X3);
-mat2x4         KEYWORD(120, 120, MAT2X4);
-mat3x2         KEYWORD(120, 120, MAT3X2);
-mat3x3         KEYWORD(120, 120, MAT3X3);
-mat3x4         KEYWORD(120, 120, MAT3X4);
-mat4x2         KEYWORD(120, 120, MAT4X2);
-mat4x3         KEYWORD(120, 120, MAT4X3);
-mat4x4         KEYWORD(120, 120, MAT4X4);
+mat2x2         KEYWORD(120, 0, 120, 0, MAT2X2);
+mat2x3         KEYWORD(120, 0, 120, 0, MAT2X3);
+mat2x4         KEYWORD(120, 0, 120, 0, MAT2X4);
+mat3x2         KEYWORD(120, 0, 120, 0, MAT3X2);
+mat3x3         KEYWORD(120, 0, 120, 0, MAT3X3);
+mat3x4         KEYWORD(120, 0, 120, 0, MAT3X4);
+mat4x2         KEYWORD(120, 0, 120, 0, MAT4X2);
+mat4x3         KEYWORD(120, 0, 120, 0, MAT4X3);
+mat4x4         KEYWORD(120, 0, 120, 0, MAT4X4);
 
 in             return IN_TOK;
 out            return OUT_TOK;
 inout          return INOUT_TOK;
 uniform                return UNIFORM;
 varying                return VARYING;
-centroid       KEYWORD(120, 120, CENTROID);
-invariant      KEYWORD(120 || ES, 120 || ES, INVARIANT);
-flat           KEYWORD(130 || ES, 130, FLAT);
-smooth         KEYWORD(130, 130, SMOOTH);
-noperspective  KEYWORD(130, 130, NOPERSPECTIVE);
+centroid       KEYWORD(120, 0, 120, 0, CENTROID);
+invariant      KEYWORD(120, 100, 120, 100, INVARIANT);
+flat           KEYWORD(130, 100, 130, 0, FLAT);
+smooth         KEYWORD(130, 0, 130, 0, SMOOTH);
+noperspective  KEYWORD(130, 0, 130, 0, NOPERSPECTIVE);
 
 sampler1D      return SAMPLER1D;
 sampler2D      return SAMPLER2D;
 sampler3D      return SAMPLER3D;
 samplerCube    return SAMPLERCUBE;
-sampler1DArray KEYWORD(130, 130, SAMPLER1DARRAY);
-sampler2DArray KEYWORD(130, 130, SAMPLER2DARRAY);
+sampler1DArray KEYWORD(130, 0, 130, 0, SAMPLER1DARRAY);
+sampler2DArray KEYWORD(130, 0, 130, 0, SAMPLER2DARRAY);
 sampler1DShadow        return SAMPLER1DSHADOW;
 sampler2DShadow        return SAMPLER2DSHADOW;
-samplerCubeShadow      KEYWORD(130, 130, SAMPLERCUBESHADOW);
-sampler1DArrayShadow   KEYWORD(130, 130, SAMPLER1DARRAYSHADOW);
-sampler2DArrayShadow   KEYWORD(130, 130, SAMPLER2DARRAYSHADOW);
-isampler1D             KEYWORD(130, 130, ISAMPLER1D);
-isampler2D             KEYWORD(130, 130, ISAMPLER2D);
-isampler3D             KEYWORD(130, 130, ISAMPLER3D);
-isamplerCube           KEYWORD(130, 130, ISAMPLERCUBE);
-isampler1DArray                KEYWORD(130, 130, ISAMPLER1DARRAY);
-isampler2DArray                KEYWORD(130, 130, ISAMPLER2DARRAY);
-usampler1D             KEYWORD(130, 130, USAMPLER1D);
-usampler2D             KEYWORD(130, 130, USAMPLER2D);
-usampler3D             KEYWORD(130, 130, USAMPLER3D);
-usamplerCube           KEYWORD(130, 130, USAMPLERCUBE);
-usampler1DArray                KEYWORD(130, 130, USAMPLER1DARRAY);
-usampler2DArray                KEYWORD(130, 130, USAMPLER2DARRAY);
+samplerCubeShadow      KEYWORD(130, 0, 130, 0, SAMPLERCUBESHADOW);
+sampler1DArrayShadow   KEYWORD(130, 0, 130, 0, SAMPLER1DARRAYSHADOW);
+sampler2DArrayShadow   KEYWORD(130, 0, 130, 0, SAMPLER2DARRAYSHADOW);
+isampler1D             KEYWORD(130, 0, 130, 0, ISAMPLER1D);
+isampler2D             KEYWORD(130, 0, 130, 0, ISAMPLER2D);
+isampler3D             KEYWORD(130, 0, 130, 0, ISAMPLER3D);
+isamplerCube           KEYWORD(130, 0, 130, 0, ISAMPLERCUBE);
+isampler1DArray                KEYWORD(130, 0, 130, 0, ISAMPLER1DARRAY);
+isampler2DArray                KEYWORD(130, 0, 130, 0, ISAMPLER2DARRAY);
+usampler1D             KEYWORD(130, 0, 130, 0, USAMPLER1D);
+usampler2D             KEYWORD(130, 0, 130, 0, USAMPLER2D);
+usampler3D             KEYWORD(130, 0, 130, 0, USAMPLER3D);
+usamplerCube           KEYWORD(130, 0, 130, 0, USAMPLERCUBE);
+usampler1DArray                KEYWORD(130, 0, 130, 0, USAMPLER1DARRAY);
+usampler2DArray                KEYWORD(130, 0, 130, 0, USAMPLER2DARRAY);
 
 samplerCubeArray       {
                          if (yyextra->ARB_texture_cube_map_array_enable)
@@ -411,96 +415,96 @@ false                     {
 
 
     /* Reserved words in GLSL 1.10. */
-asm            KEYWORD(110 || ES, 999, ASM);
-class          KEYWORD(110 || ES, 999, CLASS);
-union          KEYWORD(110 || ES, 999, UNION);
-enum           KEYWORD(110 || ES, 999, ENUM);
-typedef                KEYWORD(110 || ES, 999, TYPEDEF);
-template       KEYWORD(110 || ES, 999, TEMPLATE);
-this           KEYWORD(110 || ES, 999, THIS);
-packed         KEYWORD(110 || ES, 140 || yyextra->ARB_uniform_buffer_object_enable, PACKED_TOK);
-goto           KEYWORD(110 || ES, 999, GOTO);
-switch         KEYWORD(110 || ES, 130, SWITCH);
-default                KEYWORD(110 || ES, 130, DEFAULT);
-inline         KEYWORD(110 || ES, 999, INLINE_TOK);
-noinline       KEYWORD(110 || ES, 999, NOINLINE);
-volatile       KEYWORD(110 || ES, 999, VOLATILE);
-public         KEYWORD(110 || ES, 999, PUBLIC_TOK);
-static         KEYWORD(110 || ES, 999, STATIC);
-extern         KEYWORD(110 || ES, 999, EXTERN);
-external       KEYWORD(110 || ES, 999, EXTERNAL);
-interface      KEYWORD(110 || ES, 999, INTERFACE);
-long           KEYWORD(110 || ES, 999, LONG_TOK);
-short          KEYWORD(110 || ES, 999, SHORT_TOK);
-double         KEYWORD(110 || ES, 400, DOUBLE_TOK);
-half           KEYWORD(110 || ES, 999, HALF);
-fixed          KEYWORD(110 || ES, 999, FIXED_TOK);
-unsigned       KEYWORD(110 || ES, 999, UNSIGNED);
-input          KEYWORD(110 || ES, 999, INPUT_TOK);
-output         KEYWORD(110 || ES, 999, OUTPUT);
-hvec2          KEYWORD(110 || ES, 999, HVEC2);
-hvec3          KEYWORD(110 || ES, 999, HVEC3);
-hvec4          KEYWORD(110 || ES, 999, HVEC4);
-dvec2          KEYWORD(110 || ES, 400, DVEC2);
-dvec3          KEYWORD(110 || ES, 400, DVEC3);
-dvec4          KEYWORD(110 || ES, 400, DVEC4);
-fvec2          KEYWORD(110 || ES, 999, FVEC2);
-fvec3          KEYWORD(110 || ES, 999, FVEC3);
-fvec4          KEYWORD(110 || ES, 999, FVEC4);
+asm            KEYWORD(110, 100, 0, 0, ASM);
+class          KEYWORD(110, 100, 0, 0, CLASS);
+union          KEYWORD(110, 100, 0, 0, UNION);
+enum           KEYWORD(110, 100, 0, 0, ENUM);
+typedef                KEYWORD(110, 100, 0, 0, TYPEDEF);
+template       KEYWORD(110, 100, 0, 0, TEMPLATE);
+this           KEYWORD(110, 100, 0, 0, THIS);
+packed         KEYWORD_WITH_ALT(110, 100, 140, 0, yyextra->ARB_uniform_buffer_object_enable, PACKED_TOK);
+goto           KEYWORD(110, 100, 0, 0, GOTO);
+switch         KEYWORD(110, 100, 130, 0, SWITCH);
+default                KEYWORD(110, 100, 130, 0, DEFAULT);
+inline         KEYWORD(110, 100, 0, 0, INLINE_TOK);
+noinline       KEYWORD(110, 100, 0, 0, NOINLINE);
+volatile       KEYWORD(110, 100, 0, 0, VOLATILE);
+public         KEYWORD(110, 100, 0, 0, PUBLIC_TOK);
+static         KEYWORD(110, 100, 0, 0, STATIC);
+extern         KEYWORD(110, 100, 0, 0, EXTERN);
+external       KEYWORD(110, 100, 0, 0, EXTERNAL);
+interface      KEYWORD(110, 100, 0, 0, INTERFACE);
+long           KEYWORD(110, 100, 0, 0, LONG_TOK);
+short          KEYWORD(110, 100, 0, 0, SHORT_TOK);
+double         KEYWORD(110, 100, 400, 0, DOUBLE_TOK);
+half           KEYWORD(110, 100, 0, 0, HALF);
+fixed          KEYWORD(110, 100, 0, 0, FIXED_TOK);
+unsigned       KEYWORD(110, 100, 0, 0, UNSIGNED);
+input          KEYWORD(110, 100, 0, 0, INPUT_TOK);
+output         KEYWORD(110, 100, 0, 0, OUTPUT);
+hvec2          KEYWORD(110, 100, 0, 0, HVEC2);
+hvec3          KEYWORD(110, 100, 0, 0, HVEC3);
+hvec4          KEYWORD(110, 100, 0, 0, HVEC4);
+dvec2          KEYWORD(110, 100, 400, 0, DVEC2);
+dvec3          KEYWORD(110, 100, 400, 0, DVEC3);
+dvec4          KEYWORD(110, 100, 400, 0, DVEC4);
+fvec2          KEYWORD(110, 100, 0, 0, FVEC2);
+fvec3          KEYWORD(110, 100, 0, 0, FVEC3);
+fvec4          KEYWORD(110, 100, 0, 0, FVEC4);
 sampler2DRect          return SAMPLER2DRECT;
-sampler3DRect          KEYWORD(110 || ES, 999, SAMPLER3DRECT);
+sampler3DRect          KEYWORD(110, 100, 0, 0, SAMPLER3DRECT);
 sampler2DRectShadow    return SAMPLER2DRECTSHADOW;
-sizeof         KEYWORD(110 || ES, 999, SIZEOF);
-cast           KEYWORD(110 || ES, 999, CAST);
-namespace      KEYWORD(110 || ES, 999, NAMESPACE);
-using          KEYWORD(110 || ES, 999, USING);
+sizeof         KEYWORD(110, 100, 0, 0, SIZEOF);
+cast           KEYWORD(110, 100, 0, 0, CAST);
+namespace      KEYWORD(110, 100, 0, 0, NAMESPACE);
+using          KEYWORD(110, 100, 0, 0, USING);
 
     /* Additional reserved words in GLSL 1.20. */
-lowp           KEYWORD(120, 130 || ES, LOWP);
-mediump                KEYWORD(120, 130 || ES, MEDIUMP);
-highp          KEYWORD(120, 130 || ES, HIGHP);
-precision      KEYWORD(120, 130 || ES, PRECISION);
+lowp           KEYWORD(120, 100, 130, 100, LOWP);
+mediump                KEYWORD(120, 100, 130, 100, MEDIUMP);
+highp          KEYWORD(120, 100, 130, 100, HIGHP);
+precision      KEYWORD(120, 100, 130, 100, PRECISION);
 
     /* Additional reserved words in GLSL 1.30. */
-case           KEYWORD(130, 130, CASE);
-common         KEYWORD(130, 999, COMMON);
-partition      KEYWORD(130, 999, PARTITION);
-active         KEYWORD(130, 999, ACTIVE);
-superp         KEYWORD(130 || ES, 999, SUPERP);
-samplerBuffer  KEYWORD(130, 140, SAMPLERBUFFER);
-filter         KEYWORD(130, 999, FILTER);
-image1D                KEYWORD(130, 999, IMAGE1D);
-image2D                KEYWORD(130, 999, IMAGE2D);
-image3D                KEYWORD(130, 999, IMAGE3D);
-imageCube      KEYWORD(130, 999, IMAGECUBE);
-iimage1D       KEYWORD(130, 999, IIMAGE1D);
-iimage2D       KEYWORD(130, 999, IIMAGE2D);
-iimage3D       KEYWORD(130, 999, IIMAGE3D);
-iimageCube     KEYWORD(130, 999, IIMAGECUBE);
-uimage1D       KEYWORD(130, 999, UIMAGE1D);
-uimage2D       KEYWORD(130, 999, UIMAGE2D);
-uimage3D       KEYWORD(130, 999, UIMAGE3D);
-uimageCube     KEYWORD(130, 999, UIMAGECUBE);
-image1DArray   KEYWORD(130, 999, IMAGE1DARRAY);
-image2DArray   KEYWORD(130, 999, IMAGE2DARRAY);
-iimage1DArray  KEYWORD(130, 999, IIMAGE1DARRAY);
-iimage2DArray  KEYWORD(130, 999, IIMAGE2DARRAY);
-uimage1DArray  KEYWORD(130, 999, UIMAGE1DARRAY);
-uimage2DArray  KEYWORD(130, 999, UIMAGE2DARRAY);
-image1DShadow  KEYWORD(130, 999, IMAGE1DSHADOW);
-image2DShadow  KEYWORD(130, 999, IMAGE2DSHADOW);
-image1DArrayShadow KEYWORD(130, 999, IMAGE1DARRAYSHADOW);
-image2DArrayShadow KEYWORD(130, 999, IMAGE2DARRAYSHADOW);
-imageBuffer    KEYWORD(130, 999, IMAGEBUFFER);
-iimageBuffer   KEYWORD(130, 999, IIMAGEBUFFER);
-uimageBuffer   KEYWORD(130, 999, UIMAGEBUFFER);
-row_major      KEYWORD(130, 140 || yyextra->ARB_uniform_buffer_object_enable, ROW_MAJOR);
+case           KEYWORD(130, 0, 130, 0, CASE);
+common         KEYWORD(130, 0, 0, 0, COMMON);
+partition      KEYWORD(130, 0, 0, 0, PARTITION);
+active         KEYWORD(130, 0, 0, 0, ACTIVE);
+superp         KEYWORD(130, 100, 0, 0, SUPERP);
+samplerBuffer  KEYWORD(130, 0, 140, 0, SAMPLERBUFFER);
+filter         KEYWORD(130, 0, 0, 0, FILTER);
+image1D                KEYWORD(130, 0, 0, 0, IMAGE1D);
+image2D                KEYWORD(130, 0, 0, 0, IMAGE2D);
+image3D                KEYWORD(130, 0, 0, 0, IMAGE3D);
+imageCube      KEYWORD(130, 0, 0, 0, IMAGECUBE);
+iimage1D       KEYWORD(130, 0, 0, 0, IIMAGE1D);
+iimage2D       KEYWORD(130, 0, 0, 0, IIMAGE2D);
+iimage3D       KEYWORD(130, 0, 0, 0, IIMAGE3D);
+iimageCube     KEYWORD(130, 0, 0, 0, IIMAGECUBE);
+uimage1D       KEYWORD(130, 0, 0, 0, UIMAGE1D);
+uimage2D       KEYWORD(130, 0, 0, 0, UIMAGE2D);
+uimage3D       KEYWORD(130, 0, 0, 0, UIMAGE3D);
+uimageCube     KEYWORD(130, 0, 0, 0, UIMAGECUBE);
+image1DArray   KEYWORD(130, 0, 0, 0, IMAGE1DARRAY);
+image2DArray   KEYWORD(130, 0, 0, 0, IMAGE2DARRAY);
+iimage1DArray  KEYWORD(130, 0, 0, 0, IIMAGE1DARRAY);
+iimage2DArray  KEYWORD(130, 0, 0, 0, IIMAGE2DARRAY);
+uimage1DArray  KEYWORD(130, 0, 0, 0, UIMAGE1DARRAY);
+uimage2DArray  KEYWORD(130, 0, 0, 0, UIMAGE2DARRAY);
+image1DShadow  KEYWORD(130, 0, 0, 0, IMAGE1DSHADOW);
+image2DShadow  KEYWORD(130, 0, 0, 0, IMAGE2DSHADOW);
+image1DArrayShadow KEYWORD(130, 0, 0, 0, IMAGE1DARRAYSHADOW);
+image2DArrayShadow KEYWORD(130, 0, 0, 0, IMAGE2DARRAYSHADOW);
+imageBuffer    KEYWORD(130, 0, 0, 0, IMAGEBUFFER);
+iimageBuffer   KEYWORD(130, 0, 0, 0, IIMAGEBUFFER);
+uimageBuffer   KEYWORD(130, 0, 0, 0, UIMAGEBUFFER);
+row_major      KEYWORD_WITH_ALT(130, 0, 140, 0, yyextra->ARB_uniform_buffer_object_enable, ROW_MAJOR);
 
     /* Additional reserved words in GLSL 1.40 */
-isampler2DRect KEYWORD(140, 140, ISAMPLER2DRECT);
-usampler2DRect KEYWORD(140, 140, USAMPLER2DRECT);
-isamplerBuffer KEYWORD(140, 140, ISAMPLERBUFFER);
-usamplerBuffer KEYWORD(140, 140, USAMPLERBUFFER);
+isampler2DRect KEYWORD(140, 0, 140, 0, ISAMPLER2DRECT);
+usampler2DRect KEYWORD(140, 0, 140, 0, USAMPLER2DRECT);
+isamplerBuffer KEYWORD(140, 0, 140, 0, ISAMPLERBUFFER);
+usamplerBuffer KEYWORD(140, 0, 140, 0, USAMPLERBUFFER);
 
 [_a-zA-Z][_a-zA-Z0-9]* {
                            struct _mesa_glsl_parse_state *state = yyextra;