glcpp: Avoid unnecessary call to strlen
[mesa.git] / src / compiler / glsl / glsl_lexer.ll
1 %{
2 /*
3 * Copyright © 2008, 2009 Intel Corporation
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24 #include <ctype.h>
25 #include <limits.h>
26 #include "util/strtod.h"
27 #include "ast.h"
28 #include "glsl_parser_extras.h"
29 #include "glsl_parser.h"
30
31 static int classify_identifier(struct _mesa_glsl_parse_state *, const char *);
32
33 #ifdef _MSC_VER
34 #define YY_NO_UNISTD_H
35 #endif
36
37 #define YY_NO_INPUT
38 #define YY_USER_ACTION \
39 do { \
40 yylloc->first_column = yycolumn + 1; \
41 yylloc->first_line = yylloc->last_line = yylineno + 1; \
42 yycolumn += yyleng; \
43 yylloc->last_column = yycolumn + 1; \
44 } while(0);
45
46 #define YY_USER_INIT yylineno = 0; yycolumn = 0; yylloc->source = 0;
47
48 /* A macro for handling reserved words and keywords across language versions.
49 *
50 * Certain words start out as identifiers, become reserved words in
51 * later language revisions, and finally become language keywords.
52 * This may happen at different times in desktop GLSL and GLSL ES.
53 *
54 * For example, consider the following lexer rule:
55 * samplerBuffer KEYWORD(130, 0, 140, 0, SAMPLERBUFFER)
56 *
57 * This means that "samplerBuffer" will be treated as:
58 * - a keyword (SAMPLERBUFFER token) ...in GLSL >= 1.40
59 * - a reserved word - error ...in GLSL >= 1.30
60 * - an identifier ...in GLSL < 1.30 or GLSL ES
61 */
62 #define KEYWORD(reserved_glsl, reserved_glsl_es, \
63 allowed_glsl, allowed_glsl_es, token) \
64 KEYWORD_WITH_ALT(reserved_glsl, reserved_glsl_es, \
65 allowed_glsl, allowed_glsl_es, false, token)
66
67 /**
68 * Like the KEYWORD macro, but the word is also treated as a keyword
69 * if the given boolean expression is true.
70 */
71 #define KEYWORD_WITH_ALT(reserved_glsl, reserved_glsl_es, \
72 allowed_glsl, allowed_glsl_es, \
73 alt_expr, token) \
74 do { \
75 if (yyextra->is_version(allowed_glsl, allowed_glsl_es) \
76 || (alt_expr)) { \
77 return token; \
78 } else if (yyextra->is_version(reserved_glsl, \
79 reserved_glsl_es)) { \
80 _mesa_glsl_error(yylloc, yyextra, \
81 "illegal use of reserved word `%s'", yytext); \
82 return ERROR_TOK; \
83 } else { \
84 /* We're not doing linear_strdup here, to avoid an implicit \
85 * call on strlen() for the length of the string, as this is \
86 * already found by flex and stored in yyleng */ \
87 void *mem_ctx = yyextra->linalloc; \
88 char *id = (char *) linear_alloc_child(mem_ctx, yyleng + 1); \
89 memcpy(id, yytext, yyleng + 1); \
90 yylval->identifier = id; \
91 return classify_identifier(yyextra, yytext); \
92 } \
93 } while (0)
94
95 /**
96 * A macro for handling keywords that have been present in GLSL since
97 * its origin, but were changed into reserved words in GLSL 3.00 ES.
98 */
99 #define DEPRECATED_ES_KEYWORD(token) \
100 do { \
101 if (yyextra->is_version(0, 300)) { \
102 _mesa_glsl_error(yylloc, yyextra, \
103 "illegal use of reserved word `%s'", yytext); \
104 return ERROR_TOK; \
105 } else { \
106 return token; \
107 } \
108 } while (0)
109
110 static int
111 literal_integer(char *text, int len, struct _mesa_glsl_parse_state *state,
112 YYSTYPE *lval, YYLTYPE *lloc, int base)
113 {
114 bool is_uint = (text[len - 1] == 'u' ||
115 text[len - 1] == 'U');
116 bool is_long = (text[len - 1] == 'l' || text[len - 1] == 'L');
117 const char *digits = text;
118
119 if (is_long)
120 is_uint = (text[len - 2] == 'u' && text[len - 1] == 'l') ||
121 (text[len - 2] == 'U' && text[len - 1] == 'L');
122 /* Skip "0x" */
123 if (base == 16)
124 digits += 2;
125
126 unsigned long long value = strtoull(digits, NULL, base);
127
128 if (is_long)
129 lval->n64 = (int64_t)value;
130 else
131 lval->n = (int)value;
132
133 if (is_long && !is_uint && base == 10 && value > (uint64_t)LLONG_MAX + 1) {
134 /* Tries to catch unintentionally providing a negative value. */
135 _mesa_glsl_warning(lloc, state,
136 "signed literal value `%s' is interpreted as %lld",
137 text, lval->n64);
138 } else if (!is_long && value > UINT_MAX) {
139 /* Note that signed 0xffffffff is valid, not out of range! */
140 if (state->is_version(130, 300)) {
141 _mesa_glsl_error(lloc, state,
142 "literal value `%s' out of range", text);
143 } else {
144 _mesa_glsl_warning(lloc, state,
145 "literal value `%s' out of range", text);
146 }
147 } else if (base == 10 && !is_uint && (unsigned)value > (unsigned)INT_MAX + 1) {
148 /* Tries to catch unintentionally providing a negative value.
149 * Note that -2147483648 is parsed as -(2147483648), so we don't
150 * want to warn for INT_MAX.
151 */
152 _mesa_glsl_warning(lloc, state,
153 "signed literal value `%s' is interpreted as %d",
154 text, lval->n);
155 }
156 if (is_long)
157 return is_uint ? UINT64CONSTANT : INT64CONSTANT;
158 else
159 return is_uint ? UINTCONSTANT : INTCONSTANT;
160 }
161
162 #define LITERAL_INTEGER(base) \
163 literal_integer(yytext, yyleng, yyextra, yylval, yylloc, base)
164
165 %}
166
167 %option bison-bridge bison-locations reentrant noyywrap
168 %option nounput noyy_top_state
169 %option never-interactive
170 %option prefix="_mesa_glsl_lexer_"
171 %option extra-type="struct _mesa_glsl_parse_state *"
172 %option warn nodefault
173
174 /* Note: When adding any start conditions to this list, you must also
175 * update the "Internal compiler error" catch-all rule near the end of
176 * this file. */
177 %x PP PRAGMA
178
179 DEC_INT [1-9][0-9]*
180 HEX_INT 0[xX][0-9a-fA-F]+
181 OCT_INT 0[0-7]*
182 INT ({DEC_INT}|{HEX_INT}|{OCT_INT})
183 SPC [ \t]*
184 SPCP [ \t]+
185 HASH ^{SPC}#{SPC}
186 %%
187
188 [ \r\t]+ ;
189
190 /* Preprocessor tokens. */
191 ^[ \t]*#[ \t]*$ ;
192 ^[ \t]*#[ \t]*version { BEGIN PP; return VERSION_TOK; }
193 ^[ \t]*#[ \t]*extension { BEGIN PP; return EXTENSION; }
194 {HASH}line{SPCP}{INT}{SPCP}{INT}{SPC}$ {
195 /* Eat characters until the first digit is
196 * encountered
197 */
198 char *ptr = yytext;
199 while (!isdigit(*ptr))
200 ptr++;
201
202 /* Subtract one from the line number because
203 * yylineno is zero-based instead of
204 * one-based.
205 */
206 yylineno = strtol(ptr, &ptr, 0) - 1;
207
208 /* From GLSL 3.30 and GLSL ES on, after processing the
209 * line directive (including its new-line), the implementation
210 * will behave as if it is compiling at the line number passed
211 * as argument. It was line number + 1 in older specifications.
212 */
213 if (yyextra->is_version(330, 100))
214 yylineno--;
215
216 yylloc->source = strtol(ptr, NULL, 0);
217 }
218 {HASH}line{SPCP}{INT}{SPC}$ {
219 /* Eat characters until the first digit is
220 * encountered
221 */
222 char *ptr = yytext;
223 while (!isdigit(*ptr))
224 ptr++;
225
226 /* Subtract one from the line number because
227 * yylineno is zero-based instead of
228 * one-based.
229 */
230 yylineno = strtol(ptr, &ptr, 0) - 1;
231
232 /* From GLSL 3.30 and GLSL ES on, after processing the
233 * line directive (including its new-line), the implementation
234 * will behave as if it is compiling at the line number passed
235 * as argument. It was line number + 1 in older specifications.
236 */
237 if (yyextra->is_version(330, 100))
238 yylineno--;
239 }
240 ^{SPC}#{SPC}pragma{SPCP}debug{SPC}\({SPC}on{SPC}\) {
241 BEGIN PP;
242 return PRAGMA_DEBUG_ON;
243 }
244 ^{SPC}#{SPC}pragma{SPCP}debug{SPC}\({SPC}off{SPC}\) {
245 BEGIN PP;
246 return PRAGMA_DEBUG_OFF;
247 }
248 ^{SPC}#{SPC}pragma{SPCP}optimize{SPC}\({SPC}on{SPC}\) {
249 BEGIN PP;
250 return PRAGMA_OPTIMIZE_ON;
251 }
252 ^{SPC}#{SPC}pragma{SPCP}optimize{SPC}\({SPC}off{SPC}\) {
253 BEGIN PP;
254 return PRAGMA_OPTIMIZE_OFF;
255 }
256 ^{SPC}#{SPC}pragma{SPCP}STDGL{SPCP}invariant{SPC}\({SPC}all{SPC}\) {
257 BEGIN PP;
258 return PRAGMA_INVARIANT_ALL;
259 }
260 ^{SPC}#{SPC}pragma{SPCP} { BEGIN PRAGMA; }
261
262 <PRAGMA>\n { BEGIN 0; yylineno++; yycolumn = 0; }
263 <PRAGMA>. { }
264
265 <PP>\/\/[^\n]* { }
266 <PP>[ \t\r]* { }
267 <PP>: return COLON;
268 <PP>[_a-zA-Z][_a-zA-Z0-9]* {
269 /* We're not doing linear_strdup here, to avoid an implicit call
270 * on strlen() for the length of the string, as this is already
271 * found by flex and stored in yyleng
272 */
273 void *mem_ctx = yyextra->linalloc;
274 char *id = (char *) linear_alloc_child(mem_ctx, yyleng + 1);
275 memcpy(id, yytext, yyleng + 1);
276 yylval->identifier = id;
277 return IDENTIFIER;
278 }
279 <PP>[1-9][0-9]* {
280 yylval->n = strtol(yytext, NULL, 10);
281 return INTCONSTANT;
282 }
283 <PP>0 {
284 yylval->n = 0;
285 return INTCONSTANT;
286 }
287 <PP>\n { BEGIN 0; yylineno++; yycolumn = 0; return EOL; }
288 <PP>. { return yytext[0]; }
289
290 \n { yylineno++; yycolumn = 0; }
291
292 attribute DEPRECATED_ES_KEYWORD(ATTRIBUTE);
293 const return CONST_TOK;
294 bool return BOOL_TOK;
295 float return FLOAT_TOK;
296 int return INT_TOK;
297 uint KEYWORD(130, 300, 130, 300, UINT_TOK);
298
299 break return BREAK;
300 continue return CONTINUE;
301 do return DO;
302 while return WHILE;
303 else return ELSE;
304 for return FOR;
305 if return IF;
306 discard return DISCARD;
307 return return RETURN;
308
309 bvec2 return BVEC2;
310 bvec3 return BVEC3;
311 bvec4 return BVEC4;
312 ivec2 return IVEC2;
313 ivec3 return IVEC3;
314 ivec4 return IVEC4;
315 uvec2 KEYWORD(130, 300, 130, 300, UVEC2);
316 uvec3 KEYWORD(130, 300, 130, 300, UVEC3);
317 uvec4 KEYWORD(130, 300, 130, 300, UVEC4);
318 vec2 return VEC2;
319 vec3 return VEC3;
320 vec4 return VEC4;
321 mat2 return MAT2X2;
322 mat3 return MAT3X3;
323 mat4 return MAT4X4;
324 mat2x2 KEYWORD(120, 300, 120, 300, MAT2X2);
325 mat2x3 KEYWORD(120, 300, 120, 300, MAT2X3);
326 mat2x4 KEYWORD(120, 300, 120, 300, MAT2X4);
327 mat3x2 KEYWORD(120, 300, 120, 300, MAT3X2);
328 mat3x3 KEYWORD(120, 300, 120, 300, MAT3X3);
329 mat3x4 KEYWORD(120, 300, 120, 300, MAT3X4);
330 mat4x2 KEYWORD(120, 300, 120, 300, MAT4X2);
331 mat4x3 KEYWORD(120, 300, 120, 300, MAT4X3);
332 mat4x4 KEYWORD(120, 300, 120, 300, MAT4X4);
333
334 in return IN_TOK;
335 out return OUT_TOK;
336 inout return INOUT_TOK;
337 uniform return UNIFORM;
338 buffer KEYWORD_WITH_ALT(0, 0, 430, 310, yyextra->ARB_shader_storage_buffer_object_enable, BUFFER);
339 varying DEPRECATED_ES_KEYWORD(VARYING);
340 centroid KEYWORD(120, 300, 120, 300, CENTROID);
341 invariant KEYWORD(120, 100, 120, 100, INVARIANT);
342 flat KEYWORD(130, 100, 130, 300, FLAT);
343 smooth KEYWORD(130, 300, 130, 300, SMOOTH);
344 noperspective KEYWORD(130, 300, 130, 0, NOPERSPECTIVE);
345 patch KEYWORD_WITH_ALT(0, 300, 400, 320, yyextra->has_tessellation_shader(), PATCH);
346
347 sampler1D DEPRECATED_ES_KEYWORD(SAMPLER1D);
348 sampler2D return SAMPLER2D;
349 sampler3D return SAMPLER3D;
350 samplerCube return SAMPLERCUBE;
351 sampler1DArray KEYWORD(130, 300, 130, 0, SAMPLER1DARRAY);
352 sampler2DArray KEYWORD(130, 300, 130, 300, SAMPLER2DARRAY);
353 sampler1DShadow DEPRECATED_ES_KEYWORD(SAMPLER1DSHADOW);
354 sampler2DShadow return SAMPLER2DSHADOW;
355 samplerCubeShadow KEYWORD(130, 300, 130, 300, SAMPLERCUBESHADOW);
356 sampler1DArrayShadow KEYWORD(130, 300, 130, 0, SAMPLER1DARRAYSHADOW);
357 sampler2DArrayShadow KEYWORD(130, 300, 130, 300, SAMPLER2DARRAYSHADOW);
358 isampler1D KEYWORD(130, 300, 130, 0, ISAMPLER1D);
359 isampler2D KEYWORD(130, 300, 130, 300, ISAMPLER2D);
360 isampler3D KEYWORD(130, 300, 130, 300, ISAMPLER3D);
361 isamplerCube KEYWORD(130, 300, 130, 300, ISAMPLERCUBE);
362 isampler1DArray KEYWORD(130, 300, 130, 0, ISAMPLER1DARRAY);
363 isampler2DArray KEYWORD(130, 300, 130, 300, ISAMPLER2DARRAY);
364 usampler1D KEYWORD(130, 300, 130, 0, USAMPLER1D);
365 usampler2D KEYWORD(130, 300, 130, 300, USAMPLER2D);
366 usampler3D KEYWORD(130, 300, 130, 300, USAMPLER3D);
367 usamplerCube KEYWORD(130, 300, 130, 300, USAMPLERCUBE);
368 usampler1DArray KEYWORD(130, 300, 130, 0, USAMPLER1DARRAY);
369 usampler2DArray KEYWORD(130, 300, 130, 300, USAMPLER2DARRAY);
370
371 /* additional keywords in ARB_texture_multisample, included in GLSL 1.50 */
372 /* these are reserved but not defined in GLSL 3.00 */
373 /* [iu]sampler2DMS are defined in GLSL ES 3.10 */
374 sampler2DMS KEYWORD_WITH_ALT(150, 300, 150, 310, yyextra->ARB_texture_multisample_enable, SAMPLER2DMS);
375 isampler2DMS KEYWORD_WITH_ALT(150, 300, 150, 310, yyextra->ARB_texture_multisample_enable, ISAMPLER2DMS);
376 usampler2DMS KEYWORD_WITH_ALT(150, 300, 150, 310, yyextra->ARB_texture_multisample_enable, USAMPLER2DMS);
377 sampler2DMSArray KEYWORD_WITH_ALT(150, 300, 150, 320, yyextra->ARB_texture_multisample_enable || yyextra->OES_texture_storage_multisample_2d_array_enable, SAMPLER2DMSARRAY);
378 isampler2DMSArray KEYWORD_WITH_ALT(150, 300, 150, 320, yyextra->ARB_texture_multisample_enable || yyextra->OES_texture_storage_multisample_2d_array_enable, ISAMPLER2DMSARRAY);
379 usampler2DMSArray KEYWORD_WITH_ALT(150, 300, 150, 320, yyextra->ARB_texture_multisample_enable || yyextra->OES_texture_storage_multisample_2d_array_enable, USAMPLER2DMSARRAY);
380
381 /* keywords available with ARB_texture_cube_map_array_enable extension on desktop GLSL */
382 samplerCubeArray KEYWORD_WITH_ALT(400, 310, 400, 320, yyextra->ARB_texture_cube_map_array_enable || yyextra->OES_texture_cube_map_array_enable || yyextra->EXT_texture_cube_map_array_enable, SAMPLERCUBEARRAY);
383 isamplerCubeArray KEYWORD_WITH_ALT(400, 310, 400, 320, yyextra->ARB_texture_cube_map_array_enable || yyextra->OES_texture_cube_map_array_enable || yyextra->EXT_texture_cube_map_array_enable, ISAMPLERCUBEARRAY);
384 usamplerCubeArray KEYWORD_WITH_ALT(400, 310, 400, 320, yyextra->ARB_texture_cube_map_array_enable || yyextra->OES_texture_cube_map_array_enable || yyextra->EXT_texture_cube_map_array_enable, USAMPLERCUBEARRAY);
385 samplerCubeArrayShadow KEYWORD_WITH_ALT(400, 310, 400, 320, yyextra->ARB_texture_cube_map_array_enable || yyextra->OES_texture_cube_map_array_enable || yyextra->EXT_texture_cube_map_array_enable, SAMPLERCUBEARRAYSHADOW);
386
387 samplerExternalOES {
388 if (yyextra->OES_EGL_image_external_enable)
389 return SAMPLEREXTERNALOES;
390 else
391 return IDENTIFIER;
392 }
393
394 /* keywords available with ARB_gpu_shader5 */
395 precise KEYWORD_WITH_ALT(400, 310, 400, 320, yyextra->ARB_gpu_shader5_enable || yyextra->EXT_gpu_shader5_enable || yyextra->OES_gpu_shader5_enable, PRECISE);
396
397 /* keywords available with ARB_shader_image_load_store */
398 image1D KEYWORD_WITH_ALT(130, 300, 420, 0, yyextra->ARB_shader_image_load_store_enable, IMAGE1D);
399 image2D KEYWORD_WITH_ALT(130, 300, 420, 310, yyextra->ARB_shader_image_load_store_enable, IMAGE2D);
400 image3D KEYWORD_WITH_ALT(130, 300, 420, 310, yyextra->ARB_shader_image_load_store_enable, IMAGE3D);
401 image2DRect KEYWORD_WITH_ALT(130, 300, 420, 0, yyextra->ARB_shader_image_load_store_enable, IMAGE2DRECT);
402 imageCube KEYWORD_WITH_ALT(130, 300, 420, 310, yyextra->ARB_shader_image_load_store_enable, IMAGECUBE);
403 imageBuffer KEYWORD_WITH_ALT(130, 300, 420, 320, yyextra->ARB_shader_image_load_store_enable || yyextra->EXT_texture_buffer_enable || yyextra->OES_texture_buffer_enable, IMAGEBUFFER);
404 image1DArray KEYWORD_WITH_ALT(130, 300, 420, 0, yyextra->ARB_shader_image_load_store_enable, IMAGE1DARRAY);
405 image2DArray KEYWORD_WITH_ALT(130, 300, 420, 310, yyextra->ARB_shader_image_load_store_enable, IMAGE2DARRAY);
406 imageCubeArray KEYWORD_WITH_ALT(130, 300, 420, 320, yyextra->ARB_shader_image_load_store_enable || yyextra->OES_texture_cube_map_array_enable || yyextra->EXT_texture_cube_map_array_enable, IMAGECUBEARRAY);
407 image2DMS KEYWORD_WITH_ALT(130, 300, 420, 0, yyextra->ARB_shader_image_load_store_enable, IMAGE2DMS);
408 image2DMSArray KEYWORD_WITH_ALT(130, 300, 420, 0, yyextra->ARB_shader_image_load_store_enable, IMAGE2DMSARRAY);
409 iimage1D KEYWORD_WITH_ALT(130, 300, 420, 0, yyextra->ARB_shader_image_load_store_enable, IIMAGE1D);
410 iimage2D KEYWORD_WITH_ALT(130, 300, 420, 310, yyextra->ARB_shader_image_load_store_enable, IIMAGE2D);
411 iimage3D KEYWORD_WITH_ALT(130, 300, 420, 310, yyextra->ARB_shader_image_load_store_enable, IIMAGE3D);
412 iimage2DRect KEYWORD_WITH_ALT(130, 300, 420, 0, yyextra->ARB_shader_image_load_store_enable, IIMAGE2DRECT);
413 iimageCube KEYWORD_WITH_ALT(130, 300, 420, 310, yyextra->ARB_shader_image_load_store_enable, IIMAGECUBE);
414 iimageBuffer KEYWORD_WITH_ALT(130, 300, 420, 320, yyextra->ARB_shader_image_load_store_enable || yyextra->EXT_texture_buffer_enable || yyextra->OES_texture_buffer_enable, IIMAGEBUFFER);
415 iimage1DArray KEYWORD_WITH_ALT(130, 300, 420, 0, yyextra->ARB_shader_image_load_store_enable, IIMAGE1DARRAY);
416 iimage2DArray KEYWORD_WITH_ALT(130, 300, 420, 310, yyextra->ARB_shader_image_load_store_enable, IIMAGE2DARRAY);
417 iimageCubeArray KEYWORD_WITH_ALT(130, 300, 420, 320, yyextra->ARB_shader_image_load_store_enable || yyextra->OES_texture_cube_map_array_enable || yyextra->EXT_texture_cube_map_array_enable, IIMAGECUBEARRAY);
418 iimage2DMS KEYWORD_WITH_ALT(130, 300, 420, 0, yyextra->ARB_shader_image_load_store_enable, IIMAGE2DMS);
419 iimage2DMSArray KEYWORD_WITH_ALT(130, 300, 420, 0, yyextra->ARB_shader_image_load_store_enable, IIMAGE2DMSARRAY);
420 uimage1D KEYWORD_WITH_ALT(130, 300, 420, 0, yyextra->ARB_shader_image_load_store_enable, UIMAGE1D);
421 uimage2D KEYWORD_WITH_ALT(130, 300, 420, 310, yyextra->ARB_shader_image_load_store_enable, UIMAGE2D);
422 uimage3D KEYWORD_WITH_ALT(130, 300, 420, 310, yyextra->ARB_shader_image_load_store_enable, UIMAGE3D);
423 uimage2DRect KEYWORD_WITH_ALT(130, 300, 420, 0, yyextra->ARB_shader_image_load_store_enable, UIMAGE2DRECT);
424 uimageCube KEYWORD_WITH_ALT(130, 300, 420, 310, yyextra->ARB_shader_image_load_store_enable, UIMAGECUBE);
425 uimageBuffer KEYWORD_WITH_ALT(130, 300, 420, 320, yyextra->ARB_shader_image_load_store_enable || yyextra->EXT_texture_buffer_enable || yyextra->OES_texture_buffer_enable, UIMAGEBUFFER);
426 uimage1DArray KEYWORD_WITH_ALT(130, 300, 420, 0, yyextra->ARB_shader_image_load_store_enable, UIMAGE1DARRAY);
427 uimage2DArray KEYWORD_WITH_ALT(130, 300, 420, 310, yyextra->ARB_shader_image_load_store_enable, UIMAGE2DARRAY);
428 uimageCubeArray KEYWORD_WITH_ALT(130, 300, 420, 320, yyextra->ARB_shader_image_load_store_enable || yyextra->OES_texture_cube_map_array_enable || yyextra->EXT_texture_cube_map_array_enable, UIMAGECUBEARRAY);
429 uimage2DMS KEYWORD_WITH_ALT(130, 300, 420, 0, yyextra->ARB_shader_image_load_store_enable, UIMAGE2DMS);
430 uimage2DMSArray KEYWORD_WITH_ALT(130, 300, 420, 0, yyextra->ARB_shader_image_load_store_enable, UIMAGE2DMSARRAY);
431 image1DShadow KEYWORD(130, 300, 0, 0, IMAGE1DSHADOW);
432 image2DShadow KEYWORD(130, 300, 0, 0, IMAGE2DSHADOW);
433 image1DArrayShadow KEYWORD(130, 300, 0, 0, IMAGE1DARRAYSHADOW);
434 image2DArrayShadow KEYWORD(130, 300, 0, 0, IMAGE2DARRAYSHADOW);
435
436 coherent KEYWORD_WITH_ALT(420, 300, 420, 310, yyextra->ARB_shader_image_load_store_enable || yyextra->ARB_shader_storage_buffer_object_enable, COHERENT);
437 volatile KEYWORD_WITH_ALT(110, 100, 420, 310, yyextra->ARB_shader_image_load_store_enable || yyextra->ARB_shader_storage_buffer_object_enable, VOLATILE);
438 restrict KEYWORD_WITH_ALT(420, 300, 420, 310, yyextra->ARB_shader_image_load_store_enable || yyextra->ARB_shader_storage_buffer_object_enable, RESTRICT);
439 readonly KEYWORD_WITH_ALT(420, 300, 420, 310, yyextra->ARB_shader_image_load_store_enable || yyextra->ARB_shader_storage_buffer_object_enable, READONLY);
440 writeonly KEYWORD_WITH_ALT(420, 300, 420, 310, yyextra->ARB_shader_image_load_store_enable || yyextra->ARB_shader_storage_buffer_object_enable, WRITEONLY);
441
442 atomic_uint KEYWORD_WITH_ALT(420, 300, 420, 310, yyextra->ARB_shader_atomic_counters_enable, ATOMIC_UINT);
443
444 shared KEYWORD_WITH_ALT(430, 310, 430, 310, yyextra->ARB_compute_shader_enable, SHARED);
445
446 struct return STRUCT;
447 void return VOID_TOK;
448
449 layout {
450 if ((yyextra->is_version(140, 300))
451 || yyextra->AMD_conservative_depth_enable
452 || yyextra->ARB_conservative_depth_enable
453 || yyextra->ARB_explicit_attrib_location_enable
454 || yyextra->ARB_explicit_uniform_location_enable
455 || yyextra->has_separate_shader_objects()
456 || yyextra->ARB_uniform_buffer_object_enable
457 || yyextra->ARB_fragment_coord_conventions_enable
458 || yyextra->ARB_shading_language_420pack_enable
459 || yyextra->ARB_compute_shader_enable
460 || yyextra->ARB_tessellation_shader_enable) {
461 return LAYOUT_TOK;
462 } else {
463 /* We're not doing linear_strdup here, to avoid an implicit call
464 * on strlen() for the length of the string, as this is already
465 * found by flex and stored in yyleng
466 */
467 void *mem_ctx = yyextra->linalloc;
468 char *id = (char *) linear_alloc_child(mem_ctx, yyleng + 1);
469 memcpy(id, yytext, yyleng + 1);
470 yylval->identifier = id;
471 return classify_identifier(yyextra, yytext);
472 }
473 }
474
475 \+\+ return INC_OP;
476 -- return DEC_OP;
477 \<= return LE_OP;
478 >= return GE_OP;
479 == return EQ_OP;
480 != return NE_OP;
481 && return AND_OP;
482 \|\| return OR_OP;
483 "^^" return XOR_OP;
484 "<<" return LEFT_OP;
485 ">>" return RIGHT_OP;
486
487 \*= return MUL_ASSIGN;
488 \/= return DIV_ASSIGN;
489 \+= return ADD_ASSIGN;
490 \%= return MOD_ASSIGN;
491 \<\<= return LEFT_ASSIGN;
492 >>= return RIGHT_ASSIGN;
493 &= return AND_ASSIGN;
494 "^=" return XOR_ASSIGN;
495 \|= return OR_ASSIGN;
496 -= return SUB_ASSIGN;
497
498 [1-9][0-9]*([uU]|[lL]|ul|UL)? {
499 return LITERAL_INTEGER(10);
500 }
501 0[xX][0-9a-fA-F]+([uU]|[lL]|ul|UL)? {
502 return LITERAL_INTEGER(16);
503 }
504 0[0-7]*([uU]|[lL]|ul|UL)? {
505 return LITERAL_INTEGER(8);
506 }
507
508 [0-9]+\.[0-9]+([eE][+-]?[0-9]+)?[fF]? |
509 \.[0-9]+([eE][+-]?[0-9]+)?[fF]? |
510 [0-9]+\.([eE][+-]?[0-9]+)?[fF]? |
511 [0-9]+[eE][+-]?[0-9]+[fF]? {
512 struct _mesa_glsl_parse_state *state = yyextra;
513 char suffix = yytext[strlen(yytext) - 1];
514 if (!state->is_version(120, 300) &&
515 (suffix == 'f' || suffix == 'F')) {
516 _mesa_glsl_warning(yylloc, state,
517 "Float suffixes are invalid in GLSL 1.10");
518 }
519 yylval->real = _mesa_strtof(yytext, NULL);
520 return FLOATCONSTANT;
521 }
522
523 [0-9]+\.[0-9]+([eE][+-]?[0-9]+)?(lf|LF) |
524 \.[0-9]+([eE][+-]?[0-9]+)?(lf|LF) |
525 [0-9]+\.([eE][+-]?[0-9]+)?(lf|LF) |
526 [0-9]+[eE][+-]?[0-9]+(lf|LF) {
527 if (!yyextra->is_version(400, 0) &&
528 !yyextra->ARB_gpu_shader_fp64_enable)
529 return ERROR_TOK;
530 yylval->dreal = _mesa_strtod(yytext, NULL);
531 return DOUBLECONSTANT;
532 }
533
534 true {
535 yylval->n = 1;
536 return BOOLCONSTANT;
537 }
538 false {
539 yylval->n = 0;
540 return BOOLCONSTANT;
541 }
542
543
544 /* Reserved words in GLSL 1.10. */
545 asm KEYWORD(110, 100, 0, 0, ASM);
546 class KEYWORD(110, 100, 0, 0, CLASS);
547 union KEYWORD(110, 100, 0, 0, UNION);
548 enum KEYWORD(110, 100, 0, 0, ENUM);
549 typedef KEYWORD(110, 100, 0, 0, TYPEDEF);
550 template KEYWORD(110, 100, 0, 0, TEMPLATE);
551 this KEYWORD(110, 100, 0, 0, THIS);
552 packed KEYWORD_WITH_ALT(110, 100, 140, 300, yyextra->ARB_uniform_buffer_object_enable, PACKED_TOK);
553 goto KEYWORD(110, 100, 0, 0, GOTO);
554 switch KEYWORD(110, 100, 130, 300, SWITCH);
555 default KEYWORD(110, 100, 130, 300, DEFAULT);
556 inline KEYWORD(110, 100, 0, 0, INLINE_TOK);
557 noinline KEYWORD(110, 100, 0, 0, NOINLINE);
558 public KEYWORD(110, 100, 0, 0, PUBLIC_TOK);
559 static KEYWORD(110, 100, 0, 0, STATIC);
560 extern KEYWORD(110, 100, 0, 0, EXTERN);
561 external KEYWORD(110, 100, 0, 0, EXTERNAL);
562 interface KEYWORD(110, 100, 0, 0, INTERFACE);
563 long KEYWORD(110, 100, 0, 0, LONG_TOK);
564 short KEYWORD(110, 100, 0, 0, SHORT_TOK);
565 double KEYWORD_WITH_ALT(110, 100, 400, 0, yyextra->ARB_gpu_shader_fp64_enable, DOUBLE_TOK);
566 half KEYWORD(110, 100, 0, 0, HALF);
567 fixed KEYWORD(110, 100, 0, 0, FIXED_TOK);
568 unsigned KEYWORD(110, 100, 0, 0, UNSIGNED);
569 input KEYWORD(110, 100, 0, 0, INPUT_TOK);
570 output KEYWORD(110, 100, 0, 0, OUTPUT);
571 hvec2 KEYWORD(110, 100, 0, 0, HVEC2);
572 hvec3 KEYWORD(110, 100, 0, 0, HVEC3);
573 hvec4 KEYWORD(110, 100, 0, 0, HVEC4);
574 dvec2 KEYWORD_WITH_ALT(110, 100, 400, 0, yyextra->ARB_gpu_shader_fp64_enable, DVEC2);
575 dvec3 KEYWORD_WITH_ALT(110, 100, 400, 0, yyextra->ARB_gpu_shader_fp64_enable, DVEC3);
576 dvec4 KEYWORD_WITH_ALT(110, 100, 400, 0, yyextra->ARB_gpu_shader_fp64_enable, DVEC4);
577 dmat2 KEYWORD_WITH_ALT(110, 100, 400, 0, yyextra->ARB_gpu_shader_fp64_enable, DMAT2X2);
578 dmat3 KEYWORD_WITH_ALT(110, 100, 400, 0, yyextra->ARB_gpu_shader_fp64_enable, DMAT3X3);
579 dmat4 KEYWORD_WITH_ALT(110, 100, 400, 0, yyextra->ARB_gpu_shader_fp64_enable, DMAT4X4);
580 dmat2x2 KEYWORD_WITH_ALT(110, 100, 400, 0, yyextra->ARB_gpu_shader_fp64_enable, DMAT2X2);
581 dmat2x3 KEYWORD_WITH_ALT(110, 100, 400, 0, yyextra->ARB_gpu_shader_fp64_enable, DMAT2X3);
582 dmat2x4 KEYWORD_WITH_ALT(110, 100, 400, 0, yyextra->ARB_gpu_shader_fp64_enable, DMAT2X4);
583 dmat3x2 KEYWORD_WITH_ALT(110, 100, 400, 0, yyextra->ARB_gpu_shader_fp64_enable, DMAT3X2);
584 dmat3x3 KEYWORD_WITH_ALT(110, 100, 400, 0, yyextra->ARB_gpu_shader_fp64_enable, DMAT3X3);
585 dmat3x4 KEYWORD_WITH_ALT(110, 100, 400, 0, yyextra->ARB_gpu_shader_fp64_enable, DMAT3X4);
586 dmat4x2 KEYWORD_WITH_ALT(110, 100, 400, 0, yyextra->ARB_gpu_shader_fp64_enable, DMAT4X2);
587 dmat4x3 KEYWORD_WITH_ALT(110, 100, 400, 0, yyextra->ARB_gpu_shader_fp64_enable, DMAT4X3);
588 dmat4x4 KEYWORD_WITH_ALT(110, 100, 400, 0, yyextra->ARB_gpu_shader_fp64_enable, DMAT4X4);
589 fvec2 KEYWORD(110, 100, 0, 0, FVEC2);
590 fvec3 KEYWORD(110, 100, 0, 0, FVEC3);
591 fvec4 KEYWORD(110, 100, 0, 0, FVEC4);
592 sampler2DRect DEPRECATED_ES_KEYWORD(SAMPLER2DRECT);
593 sampler3DRect KEYWORD(110, 100, 0, 0, SAMPLER3DRECT);
594 sampler2DRectShadow DEPRECATED_ES_KEYWORD(SAMPLER2DRECTSHADOW);
595 sizeof KEYWORD(110, 100, 0, 0, SIZEOF);
596 cast KEYWORD(110, 100, 0, 0, CAST);
597 namespace KEYWORD(110, 100, 0, 0, NAMESPACE);
598 using KEYWORD(110, 100, 0, 0, USING);
599
600 /* Additional reserved words in GLSL 1.20. */
601 lowp KEYWORD(120, 100, 130, 100, LOWP);
602 mediump KEYWORD(120, 100, 130, 100, MEDIUMP);
603 highp KEYWORD(120, 100, 130, 100, HIGHP);
604 precision KEYWORD(120, 100, 130, 100, PRECISION);
605
606 /* Additional reserved words in GLSL 1.30. */
607 case KEYWORD(130, 300, 130, 300, CASE);
608 common KEYWORD(130, 300, 0, 0, COMMON);
609 partition KEYWORD(130, 300, 0, 0, PARTITION);
610 active KEYWORD(130, 300, 0, 0, ACTIVE);
611 superp KEYWORD(130, 100, 0, 0, SUPERP);
612 samplerBuffer KEYWORD_WITH_ALT(130, 300, 140, 320, yyextra->EXT_texture_buffer_enable || yyextra->OES_texture_buffer_enable, SAMPLERBUFFER);
613 filter KEYWORD(130, 300, 0, 0, FILTER);
614 row_major KEYWORD_WITH_ALT(130, 0, 140, 0, yyextra->ARB_uniform_buffer_object_enable && !yyextra->es_shader, ROW_MAJOR);
615
616 /* Additional reserved words in GLSL 1.40 */
617 isampler2DRect KEYWORD(140, 300, 140, 0, ISAMPLER2DRECT);
618 usampler2DRect KEYWORD(140, 300, 140, 0, USAMPLER2DRECT);
619 isamplerBuffer KEYWORD_WITH_ALT(140, 300, 140, 320, yyextra->EXT_texture_buffer_enable || yyextra->OES_texture_buffer_enable, ISAMPLERBUFFER);
620 usamplerBuffer KEYWORD_WITH_ALT(140, 300, 140, 320, yyextra->EXT_texture_buffer_enable || yyextra->OES_texture_buffer_enable, USAMPLERBUFFER);
621
622 /* Additional reserved words in GLSL ES 3.00 */
623 resource KEYWORD(420, 300, 0, 0, RESOURCE);
624 sample KEYWORD_WITH_ALT(400, 300, 400, 320, yyextra->ARB_gpu_shader5_enable || yyextra->OES_shader_multisample_interpolation_enable, SAMPLE);
625 subroutine KEYWORD_WITH_ALT(400, 300, 400, 0, yyextra->ARB_shader_subroutine_enable, SUBROUTINE);
626
627 /* Additional words for ARB_gpu_shader_int64 */
628 int64_t KEYWORD_WITH_ALT(0, 0, 0, 0, yyextra->ARB_gpu_shader_int64_enable, INT64_TOK);
629 i64vec2 KEYWORD_WITH_ALT(0, 0, 0, 0, yyextra->ARB_gpu_shader_int64_enable, I64VEC2);
630 i64vec3 KEYWORD_WITH_ALT(0, 0, 0, 0, yyextra->ARB_gpu_shader_int64_enable, I64VEC3);
631 i64vec4 KEYWORD_WITH_ALT(0, 0, 0, 0, yyextra->ARB_gpu_shader_int64_enable, I64VEC4);
632
633 uint64_t KEYWORD_WITH_ALT(0, 0, 0, 0, yyextra->ARB_gpu_shader_int64_enable, UINT64_TOK);
634 u64vec2 KEYWORD_WITH_ALT(0, 0, 0, 0, yyextra->ARB_gpu_shader_int64_enable, U64VEC2);
635 u64vec3 KEYWORD_WITH_ALT(0, 0, 0, 0, yyextra->ARB_gpu_shader_int64_enable, U64VEC3);
636 u64vec4 KEYWORD_WITH_ALT(0, 0, 0, 0, yyextra->ARB_gpu_shader_int64_enable, U64VEC4);
637
638 [_a-zA-Z][_a-zA-Z0-9]* {
639 struct _mesa_glsl_parse_state *state = yyextra;
640 void *ctx = state->linalloc;
641 if (state->es_shader && yyleng > 1024) {
642 _mesa_glsl_error(yylloc, state,
643 "Identifier `%s' exceeds 1024 characters",
644 yytext);
645 } else {
646 /* We're not doing linear_strdup here, to avoid an implicit call
647 * on strlen() for the length of the string, as this is already
648 * found by flex and stored in yyleng
649 */
650 char *id = (char *) linear_alloc_child(ctx, yyleng + 1);
651 memcpy(id, yytext, yyleng + 1);
652 yylval->identifier = id;
653 }
654 return classify_identifier(state, yytext);
655 }
656
657 \. { struct _mesa_glsl_parse_state *state = yyextra;
658 state->is_field = true;
659 return DOT_TOK; }
660
661 . { return yytext[0]; }
662
663 %%
664
665 int
666 classify_identifier(struct _mesa_glsl_parse_state *state, const char *name)
667 {
668 if (state->is_field) {
669 state->is_field = false;
670 return FIELD_SELECTION;
671 }
672 if (state->symbols->get_variable(name) || state->symbols->get_function(name))
673 return IDENTIFIER;
674 else if (state->symbols->get_type(name))
675 return TYPE_IDENTIFIER;
676 else
677 return NEW_IDENTIFIER;
678 }
679
680 void
681 _mesa_glsl_lexer_ctor(struct _mesa_glsl_parse_state *state, const char *string)
682 {
683 yylex_init_extra(state, & state->scanner);
684 yy_scan_string(string, state->scanner);
685 }
686
687 void
688 _mesa_glsl_lexer_dtor(struct _mesa_glsl_parse_state *state)
689 {
690 yylex_destroy(state->scanner);
691 }