glsl: Rework lexer keyword handling in preparation for GLSL 3.00 ES.

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>
This commit is contained in:
Paul Berry
2012-08-01 19:04:59 -07:00
committed by Ian Romanick
parent 0d9bba6e43
commit 948e5dda67

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