Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5563 | serge | 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 |
||
25 | #include |
||
26 | #include |
||
27 | #include |
||
28 | |||
29 | #include "ast.h" |
||
30 | #include "glsl_parser_extras.h" |
||
31 | #include "glsl_types.h" |
||
32 | #include "main/context.h" |
||
33 | |||
34 | #undef yyerror |
||
35 | |||
36 | static void yyerror(YYLTYPE *loc, _mesa_glsl_parse_state *st, const char *msg) |
||
37 | { |
||
38 | _mesa_glsl_error(loc, st, "%s", msg); |
||
39 | } |
||
40 | |||
41 | static int |
||
42 | _mesa_glsl_lex(YYSTYPE *val, YYLTYPE *loc, _mesa_glsl_parse_state *state) |
||
43 | { |
||
44 | return _mesa_glsl_lexer_lex(val, loc, state->scanner); |
||
45 | } |
||
46 | %} |
||
47 | |||
48 | %expect 0 |
||
49 | |||
50 | %pure-parser |
||
51 | %error-verbose |
||
52 | |||
53 | %locations |
||
54 | %initial-action { |
||
55 | @$.first_line = 1; |
||
56 | @$.first_column = 1; |
||
57 | @$.last_line = 1; |
||
58 | @$.last_column = 1; |
||
59 | @$.source = 0; |
||
60 | } |
||
61 | |||
62 | %lex-param {struct _mesa_glsl_parse_state *state} |
||
63 | %parse-param {struct _mesa_glsl_parse_state *state} |
||
64 | |||
65 | %union { |
||
66 | int n; |
||
67 | float real; |
||
68 | const char *identifier; |
||
69 | |||
70 | struct ast_type_qualifier type_qualifier; |
||
71 | |||
72 | ast_node *node; |
||
73 | ast_type_specifier *type_specifier; |
||
74 | ast_fully_specified_type *fully_specified_type; |
||
75 | ast_function *function; |
||
76 | ast_parameter_declarator *parameter_declarator; |
||
77 | ast_function_definition *function_definition; |
||
78 | ast_compound_statement *compound_statement; |
||
79 | ast_expression *expression; |
||
80 | ast_declarator_list *declarator_list; |
||
81 | ast_struct_specifier *struct_specifier; |
||
82 | ast_declaration *declaration; |
||
83 | ast_switch_body *switch_body; |
||
84 | ast_case_label *case_label; |
||
85 | ast_case_label_list *case_label_list; |
||
86 | ast_case_statement *case_statement; |
||
87 | ast_case_statement_list *case_statement_list; |
||
88 | ast_interface_block *interface_block; |
||
89 | |||
90 | struct { |
||
91 | ast_node *cond; |
||
92 | ast_expression *rest; |
||
93 | } for_rest_statement; |
||
94 | |||
95 | struct { |
||
96 | ast_node *then_statement; |
||
97 | ast_node *else_statement; |
||
98 | } selection_rest_statement; |
||
99 | } |
||
100 | |||
101 | %token ATTRIBUTE CONST_TOK BOOL_TOK FLOAT_TOK INT_TOK UINT_TOK |
||
102 | %token BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN SWITCH CASE DEFAULT |
||
103 | %token BVEC2 BVEC3 BVEC4 IVEC2 IVEC3 IVEC4 UVEC2 UVEC3 UVEC4 VEC2 VEC3 VEC4 |
||
104 | %token CENTROID IN_TOK OUT_TOK INOUT_TOK UNIFORM VARYING |
||
105 | %token NOPERSPECTIVE FLAT SMOOTH |
||
106 | %token MAT2X2 MAT2X3 MAT2X4 |
||
107 | %token MAT3X2 MAT3X3 MAT3X4 |
||
108 | %token MAT4X2 MAT4X3 MAT4X4 |
||
109 | %token SAMPLER1D SAMPLER2D SAMPLER3D SAMPLERCUBE SAMPLER1DSHADOW SAMPLER2DSHADOW |
||
110 | %token SAMPLERCUBESHADOW SAMPLER1DARRAY SAMPLER2DARRAY SAMPLER1DARRAYSHADOW |
||
111 | %token SAMPLER2DARRAYSHADOW SAMPLERCUBEARRAY SAMPLERCUBEARRAYSHADOW |
||
112 | %token ISAMPLER1D ISAMPLER2D ISAMPLER3D ISAMPLERCUBE |
||
113 | %token ISAMPLER1DARRAY ISAMPLER2DARRAY ISAMPLERCUBEARRAY |
||
114 | %token USAMPLER1D USAMPLER2D USAMPLER3D USAMPLERCUBE USAMPLER1DARRAY |
||
115 | %token USAMPLER2DARRAY USAMPLERCUBEARRAY |
||
116 | %token SAMPLER2DRECT ISAMPLER2DRECT USAMPLER2DRECT SAMPLER2DRECTSHADOW |
||
117 | %token SAMPLERBUFFER ISAMPLERBUFFER USAMPLERBUFFER |
||
118 | %token SAMPLER2DMS ISAMPLER2DMS USAMPLER2DMS |
||
119 | %token SAMPLER2DMSARRAY ISAMPLER2DMSARRAY USAMPLER2DMSARRAY |
||
120 | %token SAMPLEREXTERNALOES |
||
121 | %token STRUCT VOID_TOK WHILE |
||
122 | %token |
||
123 | %type |
||
124 | %type |
||
125 | %token |
||
126 | %token |
||
127 | %token |
||
128 | %token LEFT_OP RIGHT_OP |
||
129 | %token INC_OP DEC_OP LE_OP GE_OP EQ_OP NE_OP |
||
130 | %token AND_OP OR_OP XOR_OP MUL_ASSIGN DIV_ASSIGN ADD_ASSIGN |
||
131 | %token MOD_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN XOR_ASSIGN OR_ASSIGN |
||
132 | %token SUB_ASSIGN |
||
133 | %token INVARIANT |
||
134 | %token LOWP MEDIUMP HIGHP SUPERP PRECISION |
||
135 | |||
136 | %token VERSION_TOK EXTENSION LINE COLON EOL INTERFACE OUTPUT |
||
137 | %token PRAGMA_DEBUG_ON PRAGMA_DEBUG_OFF |
||
138 | %token PRAGMA_OPTIMIZE_ON PRAGMA_OPTIMIZE_OFF |
||
139 | %token PRAGMA_INVARIANT_ALL |
||
140 | %token LAYOUT_TOK |
||
141 | |||
142 | /* Reserved words that are not actually used in the grammar. |
||
143 | */ |
||
144 | %token ASM CLASS UNION ENUM TYPEDEF TEMPLATE THIS PACKED_TOK GOTO |
||
145 | %token INLINE_TOK NOINLINE VOLATILE PUBLIC_TOK STATIC EXTERN EXTERNAL |
||
146 | %token LONG_TOK SHORT_TOK DOUBLE_TOK HALF FIXED_TOK UNSIGNED INPUT_TOK OUPTUT |
||
147 | %token HVEC2 HVEC3 HVEC4 DVEC2 DVEC3 DVEC4 FVEC2 FVEC3 FVEC4 |
||
148 | %token SAMPLER3DRECT |
||
149 | %token SIZEOF CAST NAMESPACE USING |
||
150 | %token COHERENT RESTRICT READONLY WRITEONLY RESOURCE ATOMIC_UINT PATCH SAMPLE |
||
151 | %token SUBROUTINE |
||
152 | |||
153 | %token ERROR_TOK |
||
154 | |||
155 | %token COMMON PARTITION ACTIVE FILTER |
||
156 | %token IMAGE1D IMAGE2D IMAGE3D IMAGECUBE IMAGE1DARRAY IMAGE2DARRAY |
||
157 | %token IIMAGE1D IIMAGE2D IIMAGE3D IIMAGECUBE IIMAGE1DARRAY IIMAGE2DARRAY |
||
158 | %token UIMAGE1D UIMAGE2D UIMAGE3D UIMAGECUBE UIMAGE1DARRAY UIMAGE2DARRAY |
||
159 | %token IMAGE1DSHADOW IMAGE2DSHADOW IMAGEBUFFER IIMAGEBUFFER UIMAGEBUFFER |
||
160 | %token IMAGE1DARRAYSHADOW IMAGE2DARRAYSHADOW |
||
161 | %token ROW_MAJOR |
||
162 | |||
163 | %type |
||
164 | %type |
||
165 | %type |
||
166 | %type |
||
167 | %type |
||
168 | %type |
||
169 | %type |
||
170 | %type |
||
171 | %type |
||
172 | %type |
||
173 | %type |
||
174 | %type |
||
175 | %type |
||
176 | %type |
||
177 | %type |
||
178 | %type |
||
179 | %type |
||
180 | %type |
||
181 | %type |
||
182 | %type |
||
183 | %type |
||
184 | %type |
||
185 | %type |
||
186 | %type |
||
187 | %type |
||
188 | %type |
||
189 | %type |
||
190 | %type |
||
191 | %type |
||
192 | %type |
||
193 | %type |
||
194 | %type |
||
195 | %type |
||
196 | %type |
||
197 | %type |
||
198 | %type |
||
199 | %type |
||
200 | %type |
||
201 | %type |
||
202 | %type |
||
203 | %type |
||
204 | %type |
||
205 | %type |
||
206 | %type |
||
207 | %type |
||
208 | %type |
||
209 | %type |
||
210 | %type |
||
211 | %type |
||
212 | %type |
||
213 | %type |
||
214 | %type |
||
215 | %type |
||
216 | %type |
||
217 | %type |
||
218 | %type |
||
219 | %type |
||
220 | %type |
||
221 | %type |
||
222 | %type |
||
223 | %type |
||
224 | %type |
||
225 | %type |
||
226 | %type |
||
227 | %type |
||
228 | %type |
||
229 | %type |
||
230 | %type |
||
231 | %type |
||
232 | %type |
||
233 | %type |
||
234 | %type |
||
235 | %type |
||
236 | %type |
||
237 | %type |
||
238 | %type |
||
239 | %type |
||
240 | %type |
||
241 | %type |
||
242 | %type |
||
243 | %type |
||
244 | %type |
||
245 | %type |
||
246 | %type |
||
247 | %type |
||
248 | %type |
||
249 | %type |
||
250 | %type |
||
251 | %type |
||
252 | %type |
||
253 | %type |
||
254 | %type |
||
255 | %type |
||
256 | %type |
||
257 | |||
258 | %right THEN ELSE |
||
259 | %% |
||
260 | |||
261 | translation_unit: |
||
262 | version_statement extension_statement_list |
||
263 | { |
||
264 | _mesa_glsl_initialize_types(state); |
||
265 | } |
||
266 | external_declaration_list |
||
267 | { |
||
268 | delete state->symbols; |
||
269 | state->symbols = new(ralloc_parent(state)) glsl_symbol_table; |
||
270 | _mesa_glsl_initialize_types(state); |
||
271 | } |
||
272 | ; |
||
273 | |||
274 | version_statement: |
||
275 | /* blank - no #version specified: defaults are already set */ |
||
276 | | VERSION_TOK INTCONSTANT EOL |
||
277 | { |
||
278 | state->process_version_directive(&@2, $2, NULL); |
||
279 | if (state->error) { |
||
280 | YYERROR; |
||
281 | } |
||
282 | } |
||
283 | | VERSION_TOK INTCONSTANT any_identifier EOL |
||
284 | { |
||
285 | state->process_version_directive(&@2, $2, $3); |
||
286 | if (state->error) { |
||
287 | YYERROR; |
||
288 | } |
||
289 | } |
||
290 | ; |
||
291 | |||
292 | pragma_statement: |
||
293 | PRAGMA_DEBUG_ON EOL |
||
294 | | PRAGMA_DEBUG_OFF EOL |
||
295 | | PRAGMA_OPTIMIZE_ON EOL |
||
296 | | PRAGMA_OPTIMIZE_OFF EOL |
||
297 | | PRAGMA_INVARIANT_ALL EOL |
||
298 | { |
||
299 | if (!state->is_version(120, 100)) { |
||
300 | _mesa_glsl_warning(& @1, state, |
||
301 | "pragma `invariant(all)' not supported in %s " |
||
302 | "(GLSL ES 1.00 or GLSL 1.20 required).", |
||
303 | state->get_version_string()); |
||
304 | } else { |
||
305 | state->all_invariant = true; |
||
306 | } |
||
307 | } |
||
308 | ; |
||
309 | |||
310 | extension_statement_list: |
||
311 | |||
312 | | extension_statement_list extension_statement |
||
313 | ; |
||
314 | |||
315 | any_identifier: |
||
316 | IDENTIFIER |
||
317 | | TYPE_IDENTIFIER |
||
318 | | NEW_IDENTIFIER |
||
319 | ; |
||
320 | |||
321 | extension_statement: |
||
322 | EXTENSION any_identifier COLON any_identifier EOL |
||
323 | { |
||
324 | if (!_mesa_glsl_process_extension($2, & @2, $4, & @4, state)) { |
||
325 | YYERROR; |
||
326 | } |
||
327 | } |
||
328 | ; |
||
329 | |||
330 | external_declaration_list: |
||
331 | external_declaration |
||
332 | { |
||
333 | /* FINISHME: The NULL test is required because pragmas are set to |
||
334 | * FINISHME: NULL. (See production rule for external_declaration.) |
||
335 | */ |
||
336 | if ($1 != NULL) |
||
337 | state->translation_unit.push_tail(& $1->link); |
||
338 | } |
||
339 | | external_declaration_list external_declaration |
||
340 | { |
||
341 | /* FINISHME: The NULL test is required because pragmas are set to |
||
342 | * FINISHME: NULL. (See production rule for external_declaration.) |
||
343 | */ |
||
344 | if ($2 != NULL) |
||
345 | state->translation_unit.push_tail(& $2->link); |
||
346 | } |
||
347 | ; |
||
348 | |||
349 | variable_identifier: |
||
350 | IDENTIFIER |
||
351 | | NEW_IDENTIFIER |
||
352 | ; |
||
353 | |||
354 | primary_expression: |
||
355 | variable_identifier |
||
356 | { |
||
357 | void *ctx = state; |
||
358 | $$ = new(ctx) ast_expression(ast_identifier, NULL, NULL, NULL); |
||
359 | $$->set_location(yylloc); |
||
360 | $$->primary_expression.identifier = $1; |
||
361 | } |
||
362 | | INTCONSTANT |
||
363 | { |
||
364 | void *ctx = state; |
||
365 | $$ = new(ctx) ast_expression(ast_int_constant, NULL, NULL, NULL); |
||
366 | $$->set_location(yylloc); |
||
367 | $$->primary_expression.int_constant = $1; |
||
368 | } |
||
369 | | UINTCONSTANT |
||
370 | { |
||
371 | void *ctx = state; |
||
372 | $$ = new(ctx) ast_expression(ast_uint_constant, NULL, NULL, NULL); |
||
373 | $$->set_location(yylloc); |
||
374 | $$->primary_expression.uint_constant = $1; |
||
375 | } |
||
376 | | FLOATCONSTANT |
||
377 | { |
||
378 | void *ctx = state; |
||
379 | $$ = new(ctx) ast_expression(ast_float_constant, NULL, NULL, NULL); |
||
380 | $$->set_location(yylloc); |
||
381 | $$->primary_expression.float_constant = $1; |
||
382 | } |
||
383 | | BOOLCONSTANT |
||
384 | { |
||
385 | void *ctx = state; |
||
386 | $$ = new(ctx) ast_expression(ast_bool_constant, NULL, NULL, NULL); |
||
387 | $$->set_location(yylloc); |
||
388 | $$->primary_expression.bool_constant = $1; |
||
389 | } |
||
390 | | '(' expression ')' |
||
391 | { |
||
392 | $$ = $2; |
||
393 | } |
||
394 | ; |
||
395 | |||
396 | postfix_expression: |
||
397 | primary_expression |
||
398 | | postfix_expression '[' integer_expression ']' |
||
399 | { |
||
400 | void *ctx = state; |
||
401 | $$ = new(ctx) ast_expression(ast_array_index, $1, $3, NULL); |
||
402 | $$->set_location(yylloc); |
||
403 | } |
||
404 | | function_call |
||
405 | { |
||
406 | $$ = $1; |
||
407 | } |
||
408 | | postfix_expression '.' any_identifier |
||
409 | { |
||
410 | void *ctx = state; |
||
411 | $$ = new(ctx) ast_expression(ast_field_selection, $1, NULL, NULL); |
||
412 | $$->set_location(yylloc); |
||
413 | $$->primary_expression.identifier = $3; |
||
414 | } |
||
415 | | postfix_expression INC_OP |
||
416 | { |
||
417 | void *ctx = state; |
||
418 | $$ = new(ctx) ast_expression(ast_post_inc, $1, NULL, NULL); |
||
419 | $$->set_location(yylloc); |
||
420 | } |
||
421 | | postfix_expression DEC_OP |
||
422 | { |
||
423 | void *ctx = state; |
||
424 | $$ = new(ctx) ast_expression(ast_post_dec, $1, NULL, NULL); |
||
425 | $$->set_location(yylloc); |
||
426 | } |
||
427 | ; |
||
428 | |||
429 | integer_expression: |
||
430 | expression |
||
431 | ; |
||
432 | |||
433 | function_call: |
||
434 | function_call_or_method |
||
435 | ; |
||
436 | |||
437 | function_call_or_method: |
||
438 | function_call_generic |
||
439 | | postfix_expression '.' method_call_generic |
||
440 | { |
||
441 | void *ctx = state; |
||
442 | $$ = new(ctx) ast_expression(ast_field_selection, $1, $3, NULL); |
||
443 | $$->set_location(yylloc); |
||
444 | } |
||
445 | ; |
||
446 | |||
447 | function_call_generic: |
||
448 | function_call_header_with_parameters ')' |
||
449 | | function_call_header_no_parameters ')' |
||
450 | ; |
||
451 | |||
452 | function_call_header_no_parameters: |
||
453 | function_call_header VOID_TOK |
||
454 | | function_call_header |
||
455 | ; |
||
456 | |||
457 | function_call_header_with_parameters: |
||
458 | function_call_header assignment_expression |
||
459 | { |
||
460 | $$ = $1; |
||
461 | $$->set_location(yylloc); |
||
462 | $$->expressions.push_tail(& $2->link); |
||
463 | } |
||
464 | | function_call_header_with_parameters ',' assignment_expression |
||
465 | { |
||
466 | $$ = $1; |
||
467 | $$->set_location(yylloc); |
||
468 | $$->expressions.push_tail(& $3->link); |
||
469 | } |
||
470 | ; |
||
471 | |||
472 | // Grammar Note: Constructors look like functions, but lexical |
||
473 | // analysis recognized most of them as keywords. They are now |
||
474 | // recognized through "type_specifier". |
||
475 | function_call_header: |
||
476 | function_identifier '(' |
||
477 | ; |
||
478 | |||
479 | function_identifier: |
||
480 | type_specifier |
||
481 | { |
||
482 | void *ctx = state; |
||
483 | $$ = new(ctx) ast_function_expression($1); |
||
484 | $$->set_location(yylloc); |
||
485 | } |
||
486 | | variable_identifier |
||
487 | { |
||
488 | void *ctx = state; |
||
489 | ast_expression *callee = new(ctx) ast_expression($1); |
||
490 | $$ = new(ctx) ast_function_expression(callee); |
||
491 | $$->set_location(yylloc); |
||
492 | } |
||
493 | | FIELD_SELECTION |
||
494 | { |
||
495 | void *ctx = state; |
||
496 | ast_expression *callee = new(ctx) ast_expression($1); |
||
497 | $$ = new(ctx) ast_function_expression(callee); |
||
498 | $$->set_location(yylloc); |
||
499 | } |
||
500 | ; |
||
501 | |||
502 | method_call_generic: |
||
503 | method_call_header_with_parameters ')' |
||
504 | | method_call_header_no_parameters ')' |
||
505 | ; |
||
506 | |||
507 | method_call_header_no_parameters: |
||
508 | method_call_header VOID_TOK |
||
509 | | method_call_header |
||
510 | ; |
||
511 | |||
512 | method_call_header_with_parameters: |
||
513 | method_call_header assignment_expression |
||
514 | { |
||
515 | $$ = $1; |
||
516 | $$->set_location(yylloc); |
||
517 | $$->expressions.push_tail(& $2->link); |
||
518 | } |
||
519 | | method_call_header_with_parameters ',' assignment_expression |
||
520 | { |
||
521 | $$ = $1; |
||
522 | $$->set_location(yylloc); |
||
523 | $$->expressions.push_tail(& $3->link); |
||
524 | } |
||
525 | ; |
||
526 | |||
527 | // Grammar Note: Constructors look like methods, but lexical |
||
528 | // analysis recognized most of them as keywords. They are now |
||
529 | // recognized through "type_specifier". |
||
530 | method_call_header: |
||
531 | variable_identifier '(' |
||
532 | { |
||
533 | void *ctx = state; |
||
534 | ast_expression *callee = new(ctx) ast_expression($1); |
||
535 | $$ = new(ctx) ast_function_expression(callee); |
||
536 | $$->set_location(yylloc); |
||
537 | } |
||
538 | ; |
||
539 | |||
540 | // Grammar Note: No traditional style type casts. |
||
541 | unary_expression: |
||
542 | postfix_expression |
||
543 | | INC_OP unary_expression |
||
544 | { |
||
545 | void *ctx = state; |
||
546 | $$ = new(ctx) ast_expression(ast_pre_inc, $2, NULL, NULL); |
||
547 | $$->set_location(yylloc); |
||
548 | } |
||
549 | | DEC_OP unary_expression |
||
550 | { |
||
551 | void *ctx = state; |
||
552 | $$ = new(ctx) ast_expression(ast_pre_dec, $2, NULL, NULL); |
||
553 | $$->set_location(yylloc); |
||
554 | } |
||
555 | | unary_operator unary_expression |
||
556 | { |
||
557 | void *ctx = state; |
||
558 | $$ = new(ctx) ast_expression($1, $2, NULL, NULL); |
||
559 | $$->set_location(yylloc); |
||
560 | } |
||
561 | ; |
||
562 | |||
563 | // Grammar Note: No '*' or '&' unary ops. Pointers are not supported. |
||
564 | unary_operator: |
||
565 | '+' { $$ = ast_plus; } |
||
566 | | '-' { $$ = ast_neg; } |
||
567 | | '!' { $$ = ast_logic_not; } |
||
568 | | '~' { $$ = ast_bit_not; } |
||
569 | ; |
||
570 | |||
571 | multiplicative_expression: |
||
572 | unary_expression |
||
573 | | multiplicative_expression '*' unary_expression |
||
574 | { |
||
575 | void *ctx = state; |
||
576 | $$ = new(ctx) ast_expression_bin(ast_mul, $1, $3); |
||
577 | $$->set_location(yylloc); |
||
578 | } |
||
579 | | multiplicative_expression '/' unary_expression |
||
580 | { |
||
581 | void *ctx = state; |
||
582 | $$ = new(ctx) ast_expression_bin(ast_div, $1, $3); |
||
583 | $$->set_location(yylloc); |
||
584 | } |
||
585 | | multiplicative_expression '%' unary_expression |
||
586 | { |
||
587 | void *ctx = state; |
||
588 | $$ = new(ctx) ast_expression_bin(ast_mod, $1, $3); |
||
589 | $$->set_location(yylloc); |
||
590 | } |
||
591 | ; |
||
592 | |||
593 | additive_expression: |
||
594 | multiplicative_expression |
||
595 | | additive_expression '+' multiplicative_expression |
||
596 | { |
||
597 | void *ctx = state; |
||
598 | $$ = new(ctx) ast_expression_bin(ast_add, $1, $3); |
||
599 | $$->set_location(yylloc); |
||
600 | } |
||
601 | | additive_expression '-' multiplicative_expression |
||
602 | { |
||
603 | void *ctx = state; |
||
604 | $$ = new(ctx) ast_expression_bin(ast_sub, $1, $3); |
||
605 | $$->set_location(yylloc); |
||
606 | } |
||
607 | ; |
||
608 | |||
609 | shift_expression: |
||
610 | additive_expression |
||
611 | | shift_expression LEFT_OP additive_expression |
||
612 | { |
||
613 | void *ctx = state; |
||
614 | $$ = new(ctx) ast_expression_bin(ast_lshift, $1, $3); |
||
615 | $$->set_location(yylloc); |
||
616 | } |
||
617 | | shift_expression RIGHT_OP additive_expression |
||
618 | { |
||
619 | void *ctx = state; |
||
620 | $$ = new(ctx) ast_expression_bin(ast_rshift, $1, $3); |
||
621 | $$->set_location(yylloc); |
||
622 | } |
||
623 | ; |
||
624 | |||
625 | relational_expression: |
||
626 | shift_expression |
||
627 | | relational_expression '<' shift_expression |
||
628 | { |
||
629 | void *ctx = state; |
||
630 | $$ = new(ctx) ast_expression_bin(ast_less, $1, $3); |
||
631 | $$->set_location(yylloc); |
||
632 | } |
||
633 | | relational_expression '>' shift_expression |
||
634 | { |
||
635 | void *ctx = state; |
||
636 | $$ = new(ctx) ast_expression_bin(ast_greater, $1, $3); |
||
637 | $$->set_location(yylloc); |
||
638 | } |
||
639 | | relational_expression LE_OP shift_expression |
||
640 | { |
||
641 | void *ctx = state; |
||
642 | $$ = new(ctx) ast_expression_bin(ast_lequal, $1, $3); |
||
643 | $$->set_location(yylloc); |
||
644 | } |
||
645 | | relational_expression GE_OP shift_expression |
||
646 | { |
||
647 | void *ctx = state; |
||
648 | $$ = new(ctx) ast_expression_bin(ast_gequal, $1, $3); |
||
649 | $$->set_location(yylloc); |
||
650 | } |
||
651 | ; |
||
652 | |||
653 | equality_expression: |
||
654 | relational_expression |
||
655 | | equality_expression EQ_OP relational_expression |
||
656 | { |
||
657 | void *ctx = state; |
||
658 | $$ = new(ctx) ast_expression_bin(ast_equal, $1, $3); |
||
659 | $$->set_location(yylloc); |
||
660 | } |
||
661 | | equality_expression NE_OP relational_expression |
||
662 | { |
||
663 | void *ctx = state; |
||
664 | $$ = new(ctx) ast_expression_bin(ast_nequal, $1, $3); |
||
665 | $$->set_location(yylloc); |
||
666 | } |
||
667 | ; |
||
668 | |||
669 | and_expression: |
||
670 | equality_expression |
||
671 | | and_expression '&' equality_expression |
||
672 | { |
||
673 | void *ctx = state; |
||
674 | $$ = new(ctx) ast_expression_bin(ast_bit_and, $1, $3); |
||
675 | $$->set_location(yylloc); |
||
676 | } |
||
677 | ; |
||
678 | |||
679 | exclusive_or_expression: |
||
680 | and_expression |
||
681 | | exclusive_or_expression '^' and_expression |
||
682 | { |
||
683 | void *ctx = state; |
||
684 | $$ = new(ctx) ast_expression_bin(ast_bit_xor, $1, $3); |
||
685 | $$->set_location(yylloc); |
||
686 | } |
||
687 | ; |
||
688 | |||
689 | inclusive_or_expression: |
||
690 | exclusive_or_expression |
||
691 | | inclusive_or_expression '|' exclusive_or_expression |
||
692 | { |
||
693 | void *ctx = state; |
||
694 | $$ = new(ctx) ast_expression_bin(ast_bit_or, $1, $3); |
||
695 | $$->set_location(yylloc); |
||
696 | } |
||
697 | ; |
||
698 | |||
699 | logical_and_expression: |
||
700 | inclusive_or_expression |
||
701 | | logical_and_expression AND_OP inclusive_or_expression |
||
702 | { |
||
703 | void *ctx = state; |
||
704 | $$ = new(ctx) ast_expression_bin(ast_logic_and, $1, $3); |
||
705 | $$->set_location(yylloc); |
||
706 | } |
||
707 | ; |
||
708 | |||
709 | logical_xor_expression: |
||
710 | logical_and_expression |
||
711 | | logical_xor_expression XOR_OP logical_and_expression |
||
712 | { |
||
713 | void *ctx = state; |
||
714 | $$ = new(ctx) ast_expression_bin(ast_logic_xor, $1, $3); |
||
715 | $$->set_location(yylloc); |
||
716 | } |
||
717 | ; |
||
718 | |||
719 | logical_or_expression: |
||
720 | logical_xor_expression |
||
721 | | logical_or_expression OR_OP logical_xor_expression |
||
722 | { |
||
723 | void *ctx = state; |
||
724 | $$ = new(ctx) ast_expression_bin(ast_logic_or, $1, $3); |
||
725 | $$->set_location(yylloc); |
||
726 | } |
||
727 | ; |
||
728 | |||
729 | conditional_expression: |
||
730 | logical_or_expression |
||
731 | | logical_or_expression '?' expression ':' assignment_expression |
||
732 | { |
||
733 | void *ctx = state; |
||
734 | $$ = new(ctx) ast_expression(ast_conditional, $1, $3, $5); |
||
735 | $$->set_location(yylloc); |
||
736 | } |
||
737 | ; |
||
738 | |||
739 | assignment_expression: |
||
740 | conditional_expression |
||
741 | | unary_expression assignment_operator assignment_expression |
||
742 | { |
||
743 | void *ctx = state; |
||
744 | $$ = new(ctx) ast_expression($2, $1, $3, NULL); |
||
745 | $$->set_location(yylloc); |
||
746 | } |
||
747 | ; |
||
748 | |||
749 | assignment_operator: |
||
750 | '=' { $$ = ast_assign; } |
||
751 | | MUL_ASSIGN { $$ = ast_mul_assign; } |
||
752 | | DIV_ASSIGN { $$ = ast_div_assign; } |
||
753 | | MOD_ASSIGN { $$ = ast_mod_assign; } |
||
754 | | ADD_ASSIGN { $$ = ast_add_assign; } |
||
755 | | SUB_ASSIGN { $$ = ast_sub_assign; } |
||
756 | | LEFT_ASSIGN { $$ = ast_ls_assign; } |
||
757 | | RIGHT_ASSIGN { $$ = ast_rs_assign; } |
||
758 | | AND_ASSIGN { $$ = ast_and_assign; } |
||
759 | | XOR_ASSIGN { $$ = ast_xor_assign; } |
||
760 | | OR_ASSIGN { $$ = ast_or_assign; } |
||
761 | ; |
||
762 | |||
763 | expression: |
||
764 | assignment_expression |
||
765 | { |
||
766 | $$ = $1; |
||
767 | } |
||
768 | | expression ',' assignment_expression |
||
769 | { |
||
770 | void *ctx = state; |
||
771 | if ($1->oper != ast_sequence) { |
||
772 | $$ = new(ctx) ast_expression(ast_sequence, NULL, NULL, NULL); |
||
773 | $$->set_location(yylloc); |
||
774 | $$->expressions.push_tail(& $1->link); |
||
775 | } else { |
||
776 | $$ = $1; |
||
777 | } |
||
778 | |||
779 | $$->expressions.push_tail(& $3->link); |
||
780 | } |
||
781 | ; |
||
782 | |||
783 | constant_expression: |
||
784 | conditional_expression |
||
785 | ; |
||
786 | |||
787 | declaration: |
||
788 | function_prototype ';' |
||
789 | { |
||
790 | state->symbols->pop_scope(); |
||
791 | $$ = $1; |
||
792 | } |
||
793 | | init_declarator_list ';' |
||
794 | { |
||
795 | $$ = $1; |
||
796 | } |
||
797 | | PRECISION precision_qualifier type_specifier ';' |
||
798 | { |
||
799 | $3->default_precision = $2; |
||
800 | $$ = $3; |
||
801 | } |
||
802 | | interface_block |
||
803 | { |
||
804 | $$ = $1; |
||
805 | } |
||
806 | ; |
||
807 | |||
808 | function_prototype: |
||
809 | function_declarator ')' |
||
810 | ; |
||
811 | |||
812 | function_declarator: |
||
813 | function_header |
||
814 | | function_header_with_parameters |
||
815 | ; |
||
816 | |||
817 | function_header_with_parameters: |
||
818 | function_header parameter_declaration |
||
819 | { |
||
820 | $$ = $1; |
||
821 | $$->parameters.push_tail(& $2->link); |
||
822 | } |
||
823 | | function_header_with_parameters ',' parameter_declaration |
||
824 | { |
||
825 | $$ = $1; |
||
826 | $$->parameters.push_tail(& $3->link); |
||
827 | } |
||
828 | ; |
||
829 | |||
830 | function_header: |
||
831 | fully_specified_type variable_identifier '(' |
||
832 | { |
||
833 | void *ctx = state; |
||
834 | $$ = new(ctx) ast_function(); |
||
835 | $$->set_location(yylloc); |
||
836 | $$->return_type = $1; |
||
837 | $$->identifier = $2; |
||
838 | |||
839 | state->symbols->add_function(new(state) ir_function($2)); |
||
840 | state->symbols->push_scope(); |
||
841 | } |
||
842 | ; |
||
843 | |||
844 | parameter_declarator: |
||
845 | type_specifier any_identifier |
||
846 | { |
||
847 | void *ctx = state; |
||
848 | $$ = new(ctx) ast_parameter_declarator(); |
||
849 | $$->set_location(yylloc); |
||
850 | $$->type = new(ctx) ast_fully_specified_type(); |
||
851 | $$->type->set_location(yylloc); |
||
852 | $$->type->specifier = $1; |
||
853 | $$->identifier = $2; |
||
854 | } |
||
855 | | type_specifier any_identifier '[' constant_expression ']' |
||
856 | { |
||
857 | void *ctx = state; |
||
858 | $$ = new(ctx) ast_parameter_declarator(); |
||
859 | $$->set_location(yylloc); |
||
860 | $$->type = new(ctx) ast_fully_specified_type(); |
||
861 | $$->type->set_location(yylloc); |
||
862 | $$->type->specifier = $1; |
||
863 | $$->identifier = $2; |
||
864 | $$->is_array = true; |
||
865 | $$->array_size = $4; |
||
866 | } |
||
867 | ; |
||
868 | |||
869 | parameter_declaration: |
||
870 | parameter_qualifier parameter_declarator |
||
871 | { |
||
872 | $$ = $2; |
||
873 | $$->type->qualifier = $1; |
||
874 | } |
||
875 | | parameter_qualifier parameter_type_specifier |
||
876 | { |
||
877 | void *ctx = state; |
||
878 | $$ = new(ctx) ast_parameter_declarator(); |
||
879 | $$->set_location(yylloc); |
||
880 | $$->type = new(ctx) ast_fully_specified_type(); |
||
881 | $$->type->qualifier = $1; |
||
882 | $$->type->specifier = $2; |
||
883 | } |
||
884 | ; |
||
885 | |||
886 | parameter_qualifier: |
||
887 | /* empty */ |
||
888 | { |
||
889 | memset(& $$, 0, sizeof($$)); |
||
890 | } |
||
891 | | CONST_TOK parameter_qualifier |
||
892 | { |
||
893 | if ($2.flags.q.constant) |
||
894 | _mesa_glsl_error(&@1, state, "duplicate const qualifier.\n"); |
||
895 | |||
896 | $$ = $2; |
||
897 | $$.flags.q.constant = 1; |
||
898 | } |
||
899 | | parameter_direction_qualifier parameter_qualifier |
||
900 | { |
||
901 | if (($1.flags.q.in || $1.flags.q.out) && ($2.flags.q.in || $2.flags.q.out)) |
||
902 | _mesa_glsl_error(&@1, state, "duplicate in/out/inout qualifier\n"); |
||
903 | |||
904 | if (!state->ARB_shading_language_420pack_enable && $2.flags.q.constant) |
||
905 | _mesa_glsl_error(&@1, state, "const must be specified before " |
||
906 | "in/out/inout.\n"); |
||
907 | |||
908 | $$ = $1; |
||
909 | $$.merge_qualifier(&@1, state, $2); |
||
910 | } |
||
911 | | precision_qualifier parameter_qualifier |
||
912 | { |
||
913 | if ($2.precision != ast_precision_none) |
||
914 | _mesa_glsl_error(&@1, state, "Duplicate precision qualifier.\n"); |
||
915 | |||
916 | if (!state->ARB_shading_language_420pack_enable && $2.flags.i != 0) |
||
917 | _mesa_glsl_error(&@1, state, "Precision qualifiers must come last.\n"); |
||
918 | |||
919 | $$ = $2; |
||
920 | $$.precision = $1; |
||
921 | } |
||
922 | |||
923 | parameter_direction_qualifier: |
||
924 | IN_TOK |
||
925 | { |
||
926 | memset(& $$, 0, sizeof($$)); |
||
927 | $$.flags.q.in = 1; |
||
928 | } |
||
929 | | OUT_TOK |
||
930 | { |
||
931 | memset(& $$, 0, sizeof($$)); |
||
932 | $$.flags.q.out = 1; |
||
933 | } |
||
934 | | INOUT_TOK |
||
935 | { |
||
936 | memset(& $$, 0, sizeof($$)); |
||
937 | $$.flags.q.in = 1; |
||
938 | $$.flags.q.out = 1; |
||
939 | } |
||
940 | ; |
||
941 | |||
942 | parameter_type_specifier: |
||
943 | type_specifier |
||
944 | ; |
||
945 | |||
946 | init_declarator_list: |
||
947 | single_declaration |
||
948 | | init_declarator_list ',' any_identifier |
||
949 | { |
||
950 | void *ctx = state; |
||
951 | ast_declaration *decl = new(ctx) ast_declaration($3, false, NULL, NULL); |
||
952 | decl->set_location(yylloc); |
||
953 | |||
954 | $$ = $1; |
||
955 | $$->declarations.push_tail(&decl->link); |
||
956 | state->symbols->add_variable(new(state) ir_variable(NULL, $3, ir_var_auto)); |
||
957 | } |
||
958 | | init_declarator_list ',' any_identifier '[' ']' |
||
959 | { |
||
960 | void *ctx = state; |
||
961 | ast_declaration *decl = new(ctx) ast_declaration($3, true, NULL, NULL); |
||
962 | decl->set_location(yylloc); |
||
963 | |||
964 | $$ = $1; |
||
965 | $$->declarations.push_tail(&decl->link); |
||
966 | state->symbols->add_variable(new(state) ir_variable(NULL, $3, ir_var_auto)); |
||
967 | } |
||
968 | | init_declarator_list ',' any_identifier '[' constant_expression ']' |
||
969 | { |
||
970 | void *ctx = state; |
||
971 | ast_declaration *decl = new(ctx) ast_declaration($3, true, $5, NULL); |
||
972 | decl->set_location(yylloc); |
||
973 | |||
974 | $$ = $1; |
||
975 | $$->declarations.push_tail(&decl->link); |
||
976 | state->symbols->add_variable(new(state) ir_variable(NULL, $3, ir_var_auto)); |
||
977 | } |
||
978 | | init_declarator_list ',' any_identifier '[' ']' '=' initializer |
||
979 | { |
||
980 | void *ctx = state; |
||
981 | ast_declaration *decl = new(ctx) ast_declaration($3, true, NULL, $7); |
||
982 | decl->set_location(yylloc); |
||
983 | |||
984 | $$ = $1; |
||
985 | $$->declarations.push_tail(&decl->link); |
||
986 | state->symbols->add_variable(new(state) ir_variable(NULL, $3, ir_var_auto)); |
||
987 | if ($7->oper == ast_aggregate) { |
||
988 | ast_aggregate_initializer *ai = (ast_aggregate_initializer *)$7; |
||
989 | ast_type_specifier *type = new(ctx) ast_type_specifier($1->type->specifier, true, NULL); |
||
990 | _mesa_ast_set_aggregate_type(type, ai, state); |
||
991 | } |
||
992 | } |
||
993 | | init_declarator_list ',' any_identifier '[' constant_expression ']' '=' initializer |
||
994 | { |
||
995 | void *ctx = state; |
||
996 | ast_declaration *decl = new(ctx) ast_declaration($3, true, $5, $8); |
||
997 | decl->set_location(yylloc); |
||
998 | |||
999 | $$ = $1; |
||
1000 | $$->declarations.push_tail(&decl->link); |
||
1001 | state->symbols->add_variable(new(state) ir_variable(NULL, $3, ir_var_auto)); |
||
1002 | if ($8->oper == ast_aggregate) { |
||
1003 | ast_aggregate_initializer *ai = (ast_aggregate_initializer *)$8; |
||
1004 | ast_type_specifier *type = new(ctx) ast_type_specifier($1->type->specifier, true, $5); |
||
1005 | _mesa_ast_set_aggregate_type(type, ai, state); |
||
1006 | } |
||
1007 | } |
||
1008 | | init_declarator_list ',' any_identifier '=' initializer |
||
1009 | { |
||
1010 | void *ctx = state; |
||
1011 | ast_declaration *decl = new(ctx) ast_declaration($3, false, NULL, $5); |
||
1012 | decl->set_location(yylloc); |
||
1013 | |||
1014 | $$ = $1; |
||
1015 | $$->declarations.push_tail(&decl->link); |
||
1016 | state->symbols->add_variable(new(state) ir_variable(NULL, $3, ir_var_auto)); |
||
1017 | if ($5->oper == ast_aggregate) { |
||
1018 | ast_aggregate_initializer *ai = (ast_aggregate_initializer *)$5; |
||
1019 | _mesa_ast_set_aggregate_type($1->type->specifier, ai, state); |
||
1020 | } |
||
1021 | } |
||
1022 | ; |
||
1023 | |||
1024 | // Grammar Note: No 'enum', or 'typedef'. |
||
1025 | single_declaration: |
||
1026 | fully_specified_type |
||
1027 | { |
||
1028 | void *ctx = state; |
||
1029 | /* Empty declaration list is valid. */ |
||
1030 | $$ = new(ctx) ast_declarator_list($1); |
||
1031 | $$->set_location(yylloc); |
||
1032 | } |
||
1033 | | fully_specified_type any_identifier |
||
1034 | { |
||
1035 | void *ctx = state; |
||
1036 | ast_declaration *decl = new(ctx) ast_declaration($2, false, NULL, NULL); |
||
1037 | |||
1038 | $$ = new(ctx) ast_declarator_list($1); |
||
1039 | $$->set_location(yylloc); |
||
1040 | $$->declarations.push_tail(&decl->link); |
||
1041 | } |
||
1042 | | fully_specified_type any_identifier '[' ']' |
||
1043 | { |
||
1044 | void *ctx = state; |
||
1045 | ast_declaration *decl = new(ctx) ast_declaration($2, true, NULL, NULL); |
||
1046 | |||
1047 | $$ = new(ctx) ast_declarator_list($1); |
||
1048 | $$->set_location(yylloc); |
||
1049 | $$->declarations.push_tail(&decl->link); |
||
1050 | } |
||
1051 | | fully_specified_type any_identifier '[' constant_expression ']' |
||
1052 | { |
||
1053 | void *ctx = state; |
||
1054 | ast_declaration *decl = new(ctx) ast_declaration($2, true, $4, NULL); |
||
1055 | |||
1056 | $$ = new(ctx) ast_declarator_list($1); |
||
1057 | $$->set_location(yylloc); |
||
1058 | $$->declarations.push_tail(&decl->link); |
||
1059 | } |
||
1060 | | fully_specified_type any_identifier '[' ']' '=' initializer |
||
1061 | { |
||
1062 | void *ctx = state; |
||
1063 | ast_declaration *decl = new(ctx) ast_declaration($2, true, NULL, $6); |
||
1064 | |||
1065 | $$ = new(ctx) ast_declarator_list($1); |
||
1066 | $$->set_location(yylloc); |
||
1067 | $$->declarations.push_tail(&decl->link); |
||
1068 | if ($6->oper == ast_aggregate) { |
||
1069 | ast_aggregate_initializer *ai = (ast_aggregate_initializer *)$6; |
||
1070 | ast_type_specifier *type = new(ctx) ast_type_specifier($1->specifier, true, NULL); |
||
1071 | _mesa_ast_set_aggregate_type(type, ai, state); |
||
1072 | } |
||
1073 | } |
||
1074 | | fully_specified_type any_identifier '[' constant_expression ']' '=' initializer |
||
1075 | { |
||
1076 | void *ctx = state; |
||
1077 | ast_declaration *decl = new(ctx) ast_declaration($2, true, $4, $7); |
||
1078 | |||
1079 | $$ = new(ctx) ast_declarator_list($1); |
||
1080 | $$->set_location(yylloc); |
||
1081 | $$->declarations.push_tail(&decl->link); |
||
1082 | if ($7->oper == ast_aggregate) { |
||
1083 | ast_aggregate_initializer *ai = (ast_aggregate_initializer *)$7; |
||
1084 | ast_type_specifier *type = new(ctx) ast_type_specifier($1->specifier, true, $4); |
||
1085 | _mesa_ast_set_aggregate_type(type, ai, state); |
||
1086 | } |
||
1087 | } |
||
1088 | | fully_specified_type any_identifier '=' initializer |
||
1089 | { |
||
1090 | void *ctx = state; |
||
1091 | ast_declaration *decl = new(ctx) ast_declaration($2, false, NULL, $4); |
||
1092 | |||
1093 | $$ = new(ctx) ast_declarator_list($1); |
||
1094 | $$->set_location(yylloc); |
||
1095 | $$->declarations.push_tail(&decl->link); |
||
1096 | if ($4->oper == ast_aggregate) { |
||
1097 | _mesa_ast_set_aggregate_type($1->specifier, $4, state); |
||
1098 | } |
||
1099 | } |
||
1100 | | INVARIANT variable_identifier // Vertex only. |
||
1101 | { |
||
1102 | void *ctx = state; |
||
1103 | ast_declaration *decl = new(ctx) ast_declaration($2, false, NULL, NULL); |
||
1104 | |||
1105 | $$ = new(ctx) ast_declarator_list(NULL); |
||
1106 | $$->set_location(yylloc); |
||
1107 | $$->invariant = true; |
||
1108 | |||
1109 | $$->declarations.push_tail(&decl->link); |
||
1110 | } |
||
1111 | ; |
||
1112 | |||
1113 | fully_specified_type: |
||
1114 | type_specifier |
||
1115 | { |
||
1116 | void *ctx = state; |
||
1117 | $$ = new(ctx) ast_fully_specified_type(); |
||
1118 | $$->set_location(yylloc); |
||
1119 | $$->specifier = $1; |
||
1120 | } |
||
1121 | | type_qualifier type_specifier |
||
1122 | { |
||
1123 | void *ctx = state; |
||
1124 | $$ = new(ctx) ast_fully_specified_type(); |
||
1125 | $$->set_location(yylloc); |
||
1126 | $$->qualifier = $1; |
||
1127 | $$->specifier = $2; |
||
1128 | } |
||
1129 | ; |
||
1130 | |||
1131 | layout_qualifier: |
||
1132 | LAYOUT_TOK '(' layout_qualifier_id_list ')' |
||
1133 | { |
||
1134 | $$ = $3; |
||
1135 | } |
||
1136 | ; |
||
1137 | |||
1138 | layout_qualifier_id_list: |
||
1139 | layout_qualifier_id |
||
1140 | | layout_qualifier_id_list ',' layout_qualifier_id |
||
1141 | { |
||
1142 | $$ = $1; |
||
1143 | if (!$$.merge_qualifier(& @3, state, $3)) { |
||
1144 | YYERROR; |
||
1145 | } |
||
1146 | } |
||
1147 | ; |
||
1148 | |||
1149 | integer_constant: |
||
1150 | INTCONSTANT { $$ = $1; } |
||
1151 | | UINTCONSTANT { $$ = $1; } |
||
1152 | ; |
||
1153 | |||
1154 | layout_qualifier_id: |
||
1155 | any_identifier |
||
1156 | { |
||
1157 | memset(& $$, 0, sizeof($$)); |
||
1158 | |||
1159 | /* Layout qualifiers for ARB_fragment_coord_conventions. */ |
||
1160 | if (!$$.flags.i && state->ARB_fragment_coord_conventions_enable) { |
||
1161 | if (strcmp($1, "origin_upper_left") == 0) { |
||
1162 | $$.flags.q.origin_upper_left = 1; |
||
1163 | } else if (strcmp($1, "pixel_center_integer") == 0) { |
||
1164 | $$.flags.q.pixel_center_integer = 1; |
||
1165 | } |
||
1166 | |||
1167 | if ($$.flags.i && state->ARB_fragment_coord_conventions_warn) { |
||
1168 | _mesa_glsl_warning(& @1, state, |
||
1169 | "GL_ARB_fragment_coord_conventions layout " |
||
1170 | "identifier `%s' used\n", $1); |
||
1171 | } |
||
1172 | } |
||
1173 | |||
1174 | /* Layout qualifiers for AMD/ARB_conservative_depth. */ |
||
1175 | if (!$$.flags.i && |
||
1176 | (state->AMD_conservative_depth_enable || |
||
1177 | state->ARB_conservative_depth_enable)) { |
||
1178 | if (strcmp($1, "depth_any") == 0) { |
||
1179 | $$.flags.q.depth_any = 1; |
||
1180 | } else if (strcmp($1, "depth_greater") == 0) { |
||
1181 | $$.flags.q.depth_greater = 1; |
||
1182 | } else if (strcmp($1, "depth_less") == 0) { |
||
1183 | $$.flags.q.depth_less = 1; |
||
1184 | } else if (strcmp($1, "depth_unchanged") == 0) { |
||
1185 | $$.flags.q.depth_unchanged = 1; |
||
1186 | } |
||
1187 | |||
1188 | if ($$.flags.i && state->AMD_conservative_depth_warn) { |
||
1189 | _mesa_glsl_warning(& @1, state, |
||
1190 | "GL_AMD_conservative_depth " |
||
1191 | "layout qualifier `%s' is used\n", $1); |
||
1192 | } |
||
1193 | if ($$.flags.i && state->ARB_conservative_depth_warn) { |
||
1194 | _mesa_glsl_warning(& @1, state, |
||
1195 | "GL_ARB_conservative_depth " |
||
1196 | "layout qualifier `%s' is used\n", $1); |
||
1197 | } |
||
1198 | } |
||
1199 | |||
1200 | /* See also interface_block_layout_qualifier. */ |
||
1201 | if (!$$.flags.i && state->ARB_uniform_buffer_object_enable) { |
||
1202 | if (strcmp($1, "std140") == 0) { |
||
1203 | $$.flags.q.std140 = 1; |
||
1204 | } else if (strcmp($1, "shared") == 0) { |
||
1205 | $$.flags.q.shared = 1; |
||
1206 | } else if (strcmp($1, "column_major") == 0) { |
||
1207 | $$.flags.q.column_major = 1; |
||
1208 | /* "row_major" is a reserved word in GLSL 1.30+. Its token is parsed |
||
1209 | * below in the interface_block_layout_qualifier rule. |
||
1210 | * |
||
1211 | * It is not a reserved word in GLSL ES 3.00, so it's handled here as |
||
1212 | * an identifier. |
||
1213 | */ |
||
1214 | } else if (strcmp($1, "row_major") == 0) { |
||
1215 | $$.flags.q.row_major = 1; |
||
1216 | } |
||
1217 | |||
1218 | if ($$.flags.i && state->ARB_uniform_buffer_object_warn) { |
||
1219 | _mesa_glsl_warning(& @1, state, |
||
1220 | "#version 140 / GL_ARB_uniform_buffer_object " |
||
1221 | "layout qualifier `%s' is used\n", $1); |
||
1222 | } |
||
1223 | } |
||
1224 | |||
1225 | if (!$$.flags.i) { |
||
1226 | _mesa_glsl_error(& @1, state, "unrecognized layout identifier " |
||
1227 | "`%s'\n", $1); |
||
1228 | YYERROR; |
||
1229 | } |
||
1230 | } |
||
1231 | | any_identifier '=' integer_constant |
||
1232 | { |
||
1233 | memset(& $$, 0, sizeof($$)); |
||
1234 | |||
1235 | if (state->ARB_explicit_attrib_location_enable) { |
||
1236 | if (strcmp("location", $1) == 0) { |
||
1237 | $$.flags.q.explicit_location = 1; |
||
1238 | |||
1239 | if ($3 >= 0) { |
||
1240 | $$.location = $3; |
||
1241 | } else { |
||
1242 | _mesa_glsl_error(& @3, state, |
||
1243 | "invalid location %d specified\n", $3); |
||
1244 | YYERROR; |
||
1245 | } |
||
1246 | } |
||
1247 | |||
1248 | if (strcmp("index", $1) == 0) { |
||
1249 | $$.flags.q.explicit_index = 1; |
||
1250 | |||
1251 | if ($3 >= 0) { |
||
1252 | $$.index = $3; |
||
1253 | } else { |
||
1254 | _mesa_glsl_error(& @3, state, |
||
1255 | "invalid index %d specified\n", $3); |
||
1256 | YYERROR; |
||
1257 | } |
||
1258 | } |
||
1259 | } |
||
1260 | |||
1261 | if (state->ARB_shading_language_420pack_enable && |
||
1262 | strcmp("binding", $1) == 0) { |
||
1263 | $$.flags.q.explicit_binding = 1; |
||
1264 | $$.binding = $3; |
||
1265 | } |
||
1266 | |||
1267 | /* If the identifier didn't match any known layout identifiers, |
||
1268 | * emit an error. |
||
1269 | */ |
||
1270 | if (!$$.flags.i) { |
||
1271 | _mesa_glsl_error(& @1, state, "unrecognized layout identifier " |
||
1272 | "`%s'\n", $1); |
||
1273 | YYERROR; |
||
1274 | } else if (state->ARB_explicit_attrib_location_warn) { |
||
1275 | _mesa_glsl_warning(& @1, state, |
||
1276 | "GL_ARB_explicit_attrib_location layout " |
||
1277 | "identifier `%s' used\n", $1); |
||
1278 | } |
||
1279 | } |
||
1280 | | interface_block_layout_qualifier |
||
1281 | { |
||
1282 | $$ = $1; |
||
1283 | /* Layout qualifiers for ARB_uniform_buffer_object. */ |
||
1284 | if ($$.flags.q.uniform && !state->ARB_uniform_buffer_object_enable) { |
||
1285 | _mesa_glsl_error(& @1, state, |
||
1286 | "#version 140 / GL_ARB_uniform_buffer_object " |
||
1287 | "layout qualifier `%s' is used\n", $1); |
||
1288 | } else if ($$.flags.q.uniform && state->ARB_uniform_buffer_object_warn) { |
||
1289 | _mesa_glsl_warning(& @1, state, |
||
1290 | "#version 140 / GL_ARB_uniform_buffer_object " |
||
1291 | "layout qualifier `%s' is used\n", $1); |
||
1292 | } |
||
1293 | } |
||
1294 | ; |
||
1295 | |||
1296 | /* This is a separate language rule because we parse these as tokens |
||
1297 | * (due to them being reserved keywords) instead of identifiers like |
||
1298 | * most qualifiers. See the any_identifier path of |
||
1299 | * layout_qualifier_id for the others. |
||
1300 | */ |
||
1301 | interface_block_layout_qualifier: |
||
1302 | ROW_MAJOR |
||
1303 | { |
||
1304 | memset(& $$, 0, sizeof($$)); |
||
1305 | $$.flags.q.row_major = 1; |
||
1306 | } |
||
1307 | | PACKED_TOK |
||
1308 | { |
||
1309 | memset(& $$, 0, sizeof($$)); |
||
1310 | $$.flags.q.packed = 1; |
||
1311 | } |
||
1312 | ; |
||
1313 | |||
1314 | interpolation_qualifier: |
||
1315 | SMOOTH |
||
1316 | { |
||
1317 | memset(& $$, 0, sizeof($$)); |
||
1318 | $$.flags.q.smooth = 1; |
||
1319 | } |
||
1320 | | FLAT |
||
1321 | { |
||
1322 | memset(& $$, 0, sizeof($$)); |
||
1323 | $$.flags.q.flat = 1; |
||
1324 | } |
||
1325 | | NOPERSPECTIVE |
||
1326 | { |
||
1327 | memset(& $$, 0, sizeof($$)); |
||
1328 | $$.flags.q.noperspective = 1; |
||
1329 | } |
||
1330 | ; |
||
1331 | |||
1332 | type_qualifier: |
||
1333 | /* Single qualifiers */ |
||
1334 | INVARIANT |
||
1335 | { |
||
1336 | memset(& $$, 0, sizeof($$)); |
||
1337 | $$.flags.q.invariant = 1; |
||
1338 | } |
||
1339 | | auxiliary_storage_qualifier |
||
1340 | | storage_qualifier |
||
1341 | | interpolation_qualifier |
||
1342 | | layout_qualifier |
||
1343 | | precision_qualifier |
||
1344 | { |
||
1345 | memset(&$$, 0, sizeof($$)); |
||
1346 | $$.precision = $1; |
||
1347 | } |
||
1348 | |||
1349 | /* Multiple qualifiers: |
||
1350 | * In GLSL 4.20, these can be specified in any order. In earlier versions, |
||
1351 | * they appear in this order (see GLSL 1.50 section 4.7 & comments below): |
||
1352 | * |
||
1353 | * invariant interpolation auxiliary storage precision ...or... |
||
1354 | * layout storage precision |
||
1355 | * |
||
1356 | * Each qualifier's rule ensures that the accumulated qualifiers on the right |
||
1357 | * side don't contain any that must appear on the left hand side. |
||
1358 | * For example, when processing a storage qualifier, we check that there are |
||
1359 | * no auxiliary, interpolation, layout, or invariant qualifiers to the right. |
||
1360 | */ |
||
1361 | | INVARIANT type_qualifier |
||
1362 | { |
||
1363 | if ($2.flags.q.invariant) |
||
1364 | _mesa_glsl_error(&@1, state, "Duplicate \"invariant\" qualifier.\n"); |
||
1365 | |||
1366 | if ($2.has_layout()) { |
||
1367 | _mesa_glsl_error(&@1, state, |
||
1368 | "\"invariant\" cannot be used with layout(...).\n"); |
||
1369 | } |
||
1370 | |||
1371 | $$ = $2; |
||
1372 | $$.flags.q.invariant = 1; |
||
1373 | } |
||
1374 | | interpolation_qualifier type_qualifier |
||
1375 | { |
||
1376 | /* Section 4.3 of the GLSL 1.40 specification states: |
||
1377 | * "...qualified with one of these interpolation qualifiers" |
||
1378 | * |
||
1379 | * GLSL 1.30 claims to allow "one or more", but insists that: |
||
1380 | * "These interpolation qualifiers may only precede the qualifiers in, |
||
1381 | * centroid in, out, or centroid out in a declaration." |
||
1382 | * |
||
1383 | * ...which means that e.g. smooth can't precede smooth, so there can be |
||
1384 | * only one after all, and the 1.40 text is a clarification, not a change. |
||
1385 | */ |
||
1386 | if ($2.has_interpolation()) |
||
1387 | _mesa_glsl_error(&@1, state, "Duplicate interpolation qualifier.\n"); |
||
1388 | |||
1389 | if ($2.has_layout()) { |
||
1390 | _mesa_glsl_error(&@1, state, "Interpolation qualifiers cannot be used " |
||
1391 | "with layout(...).\n"); |
||
1392 | } |
||
1393 | |||
1394 | if (!state->ARB_shading_language_420pack_enable && $2.flags.q.invariant) { |
||
1395 | _mesa_glsl_error(&@1, state, "Interpolation qualifiers must come " |
||
1396 | "after \"invariant\".\n"); |
||
1397 | } |
||
1398 | |||
1399 | $$ = $1; |
||
1400 | $$.merge_qualifier(&@1, state, $2); |
||
1401 | } |
||
1402 | | layout_qualifier type_qualifier |
||
1403 | { |
||
1404 | /* The GLSL 1.50 grammar indicates that a layout(...) declaration can be |
||
1405 | * used standalone or immediately before a storage qualifier. It cannot |
||
1406 | * be used with interpolation qualifiers or invariant. There does not |
||
1407 | * appear to be any text indicating that it must come before the storage |
||
1408 | * qualifier, but always seems to in examples. |
||
1409 | */ |
||
1410 | if (!state->ARB_shading_language_420pack_enable && $2.has_layout()) |
||
1411 | _mesa_glsl_error(&@1, state, "Duplicate layout(...) qualifiers.\n"); |
||
1412 | |||
1413 | if ($2.flags.q.invariant) |
||
1414 | _mesa_glsl_error(&@1, state, "layout(...) cannot be used with " |
||
1415 | "the \"invariant\" qualifier\n"); |
||
1416 | |||
1417 | if ($2.has_interpolation()) { |
||
1418 | _mesa_glsl_error(&@1, state, "layout(...) cannot be used with " |
||
1419 | "interpolation qualifiers.\n"); |
||
1420 | } |
||
1421 | |||
1422 | $$ = $1; |
||
1423 | $$.merge_qualifier(&@1, state, $2); |
||
1424 | } |
||
1425 | | auxiliary_storage_qualifier type_qualifier |
||
1426 | { |
||
1427 | if ($2.has_auxiliary_storage()) { |
||
1428 | _mesa_glsl_error(&@1, state, |
||
1429 | "Duplicate auxiliary storage qualifier (centroid).\n"); |
||
1430 | } |
||
1431 | |||
1432 | if (!state->ARB_shading_language_420pack_enable && |
||
1433 | ($2.flags.q.invariant || $2.has_interpolation() || $2.has_layout())) { |
||
1434 | _mesa_glsl_error(&@1, state, "Auxiliary storage qualifiers must come " |
||
1435 | "just before storage qualifiers.\n"); |
||
1436 | } |
||
1437 | $$ = $1; |
||
1438 | $$.flags.i |= $2.flags.i; |
||
1439 | } |
||
1440 | | storage_qualifier type_qualifier |
||
1441 | { |
||
1442 | /* Section 4.3 of the GLSL 1.20 specification states: |
||
1443 | * "Variable declarations may have a storage qualifier specified..." |
||
1444 | * 1.30 clarifies this to "may have one storage qualifier". |
||
1445 | */ |
||
1446 | if ($2.has_storage()) |
||
1447 | _mesa_glsl_error(&@1, state, "Duplicate storage qualifier.\n"); |
||
1448 | |||
1449 | if (!state->ARB_shading_language_420pack_enable && |
||
1450 | ($2.flags.q.invariant || $2.has_interpolation() || $2.has_layout() || |
||
1451 | $2.has_auxiliary_storage())) { |
||
1452 | _mesa_glsl_error(&@1, state, "Storage qualifiers must come after " |
||
1453 | "invariant, interpolation, layout and auxiliary " |
||
1454 | "storage qualifiers.\n"); |
||
1455 | } |
||
1456 | |||
1457 | $$ = $1; |
||
1458 | $$.merge_qualifier(&@1, state, $2); |
||
1459 | } |
||
1460 | | precision_qualifier type_qualifier |
||
1461 | { |
||
1462 | if ($2.precision != ast_precision_none) |
||
1463 | _mesa_glsl_error(&@1, state, "Duplicate precision qualifier.\n"); |
||
1464 | |||
1465 | if (!state->ARB_shading_language_420pack_enable && $2.flags.i != 0) |
||
1466 | _mesa_glsl_error(&@1, state, "Precision qualifiers must come last.\n"); |
||
1467 | |||
1468 | $$ = $2; |
||
1469 | $$.precision = $1; |
||
1470 | } |
||
1471 | ; |
||
1472 | |||
1473 | auxiliary_storage_qualifier: |
||
1474 | CENTROID |
||
1475 | { |
||
1476 | memset(& $$, 0, sizeof($$)); |
||
1477 | $$.flags.q.centroid = 1; |
||
1478 | } |
||
1479 | /* TODO: "sample" and "patch" also go here someday. */ |
||
1480 | |||
1481 | storage_qualifier: |
||
1482 | CONST_TOK |
||
1483 | { |
||
1484 | memset(& $$, 0, sizeof($$)); |
||
1485 | $$.flags.q.constant = 1; |
||
1486 | } |
||
1487 | | ATTRIBUTE |
||
1488 | { |
||
1489 | memset(& $$, 0, sizeof($$)); |
||
1490 | $$.flags.q.attribute = 1; |
||
1491 | } |
||
1492 | | VARYING |
||
1493 | { |
||
1494 | memset(& $$, 0, sizeof($$)); |
||
1495 | $$.flags.q.varying = 1; |
||
1496 | } |
||
1497 | | IN_TOK |
||
1498 | { |
||
1499 | memset(& $$, 0, sizeof($$)); |
||
1500 | $$.flags.q.in = 1; |
||
1501 | } |
||
1502 | | OUT_TOK |
||
1503 | { |
||
1504 | memset(& $$, 0, sizeof($$)); |
||
1505 | $$.flags.q.out = 1; |
||
1506 | } |
||
1507 | | UNIFORM |
||
1508 | { |
||
1509 | memset(& $$, 0, sizeof($$)); |
||
1510 | $$.flags.q.uniform = 1; |
||
1511 | } |
||
1512 | ; |
||
1513 | |||
1514 | type_specifier: |
||
1515 | type_specifier_nonarray |
||
1516 | | type_specifier_nonarray '[' ']' |
||
1517 | { |
||
1518 | $$ = $1; |
||
1519 | $$->is_array = true; |
||
1520 | $$->array_size = NULL; |
||
1521 | } |
||
1522 | | type_specifier_nonarray '[' constant_expression ']' |
||
1523 | { |
||
1524 | $$ = $1; |
||
1525 | $$->is_array = true; |
||
1526 | $$->array_size = $3; |
||
1527 | } |
||
1528 | ; |
||
1529 | |||
1530 | type_specifier_nonarray: |
||
1531 | basic_type_specifier_nonarray |
||
1532 | { |
||
1533 | void *ctx = state; |
||
1534 | $$ = new(ctx) ast_type_specifier($1); |
||
1535 | $$->set_location(yylloc); |
||
1536 | } |
||
1537 | | struct_specifier |
||
1538 | { |
||
1539 | void *ctx = state; |
||
1540 | $$ = new(ctx) ast_type_specifier($1); |
||
1541 | $$->set_location(yylloc); |
||
1542 | } |
||
1543 | | TYPE_IDENTIFIER |
||
1544 | { |
||
1545 | void *ctx = state; |
||
1546 | $$ = new(ctx) ast_type_specifier($1); |
||
1547 | $$->set_location(yylloc); |
||
1548 | } |
||
1549 | ; |
||
1550 | |||
1551 | basic_type_specifier_nonarray: |
||
1552 | VOID_TOK { $$ = "void"; } |
||
1553 | | FLOAT_TOK { $$ = "float"; } |
||
1554 | | INT_TOK { $$ = "int"; } |
||
1555 | | UINT_TOK { $$ = "uint"; } |
||
1556 | | BOOL_TOK { $$ = "bool"; } |
||
1557 | | VEC2 { $$ = "vec2"; } |
||
1558 | | VEC3 { $$ = "vec3"; } |
||
1559 | | VEC4 { $$ = "vec4"; } |
||
1560 | | BVEC2 { $$ = "bvec2"; } |
||
1561 | | BVEC3 { $$ = "bvec3"; } |
||
1562 | | BVEC4 { $$ = "bvec4"; } |
||
1563 | | IVEC2 { $$ = "ivec2"; } |
||
1564 | | IVEC3 { $$ = "ivec3"; } |
||
1565 | | IVEC4 { $$ = "ivec4"; } |
||
1566 | | UVEC2 { $$ = "uvec2"; } |
||
1567 | | UVEC3 { $$ = "uvec3"; } |
||
1568 | | UVEC4 { $$ = "uvec4"; } |
||
1569 | | MAT2X2 { $$ = "mat2"; } |
||
1570 | | MAT2X3 { $$ = "mat2x3"; } |
||
1571 | | MAT2X4 { $$ = "mat2x4"; } |
||
1572 | | MAT3X2 { $$ = "mat3x2"; } |
||
1573 | | MAT3X3 { $$ = "mat3"; } |
||
1574 | | MAT3X4 { $$ = "mat3x4"; } |
||
1575 | | MAT4X2 { $$ = "mat4x2"; } |
||
1576 | | MAT4X3 { $$ = "mat4x3"; } |
||
1577 | | MAT4X4 { $$ = "mat4"; } |
||
1578 | | SAMPLER1D { $$ = "sampler1D"; } |
||
1579 | | SAMPLER2D { $$ = "sampler2D"; } |
||
1580 | | SAMPLER2DRECT { $$ = "sampler2DRect"; } |
||
1581 | | SAMPLER3D { $$ = "sampler3D"; } |
||
1582 | | SAMPLERCUBE { $$ = "samplerCube"; } |
||
1583 | | SAMPLEREXTERNALOES { $$ = "samplerExternalOES"; } |
||
1584 | | SAMPLER1DSHADOW { $$ = "sampler1DShadow"; } |
||
1585 | | SAMPLER2DSHADOW { $$ = "sampler2DShadow"; } |
||
1586 | | SAMPLER2DRECTSHADOW { $$ = "sampler2DRectShadow"; } |
||
1587 | | SAMPLERCUBESHADOW { $$ = "samplerCubeShadow"; } |
||
1588 | | SAMPLER1DARRAY { $$ = "sampler1DArray"; } |
||
1589 | | SAMPLER2DARRAY { $$ = "sampler2DArray"; } |
||
1590 | | SAMPLER1DARRAYSHADOW { $$ = "sampler1DArrayShadow"; } |
||
1591 | | SAMPLER2DARRAYSHADOW { $$ = "sampler2DArrayShadow"; } |
||
1592 | | SAMPLERBUFFER { $$ = "samplerBuffer"; } |
||
1593 | | SAMPLERCUBEARRAY { $$ = "samplerCubeArray"; } |
||
1594 | | SAMPLERCUBEARRAYSHADOW { $$ = "samplerCubeArrayShadow"; } |
||
1595 | | ISAMPLER1D { $$ = "isampler1D"; } |
||
1596 | | ISAMPLER2D { $$ = "isampler2D"; } |
||
1597 | | ISAMPLER2DRECT { $$ = "isampler2DRect"; } |
||
1598 | | ISAMPLER3D { $$ = "isampler3D"; } |
||
1599 | | ISAMPLERCUBE { $$ = "isamplerCube"; } |
||
1600 | | ISAMPLER1DARRAY { $$ = "isampler1DArray"; } |
||
1601 | | ISAMPLER2DARRAY { $$ = "isampler2DArray"; } |
||
1602 | | ISAMPLERBUFFER { $$ = "isamplerBuffer"; } |
||
1603 | | ISAMPLERCUBEARRAY { $$ = "isamplerCubeArray"; } |
||
1604 | | USAMPLER1D { $$ = "usampler1D"; } |
||
1605 | | USAMPLER2D { $$ = "usampler2D"; } |
||
1606 | | USAMPLER2DRECT { $$ = "usampler2DRect"; } |
||
1607 | | USAMPLER3D { $$ = "usampler3D"; } |
||
1608 | | USAMPLERCUBE { $$ = "usamplerCube"; } |
||
1609 | | USAMPLER1DARRAY { $$ = "usampler1DArray"; } |
||
1610 | | USAMPLER2DARRAY { $$ = "usampler2DArray"; } |
||
1611 | | USAMPLERBUFFER { $$ = "usamplerBuffer"; } |
||
1612 | | USAMPLERCUBEARRAY { $$ = "usamplerCubeArray"; } |
||
1613 | | SAMPLER2DMS { $$ = "sampler2DMS"; } |
||
1614 | | ISAMPLER2DMS { $$ = "isampler2DMS"; } |
||
1615 | | USAMPLER2DMS { $$ = "usampler2DMS"; } |
||
1616 | | SAMPLER2DMSARRAY { $$ = "sampler2DMSArray"; } |
||
1617 | | ISAMPLER2DMSARRAY { $$ = "isampler2DMSArray"; } |
||
1618 | | USAMPLER2DMSARRAY { $$ = "usampler2DMSArray"; } |
||
1619 | ; |
||
1620 | |||
1621 | precision_qualifier: |
||
1622 | HIGHP |
||
1623 | { |
||
1624 | state->check_precision_qualifiers_allowed(&@1); |
||
1625 | $$ = ast_precision_high; |
||
1626 | } |
||
1627 | | MEDIUMP |
||
1628 | { |
||
1629 | state->check_precision_qualifiers_allowed(&@1); |
||
1630 | $$ = ast_precision_medium; |
||
1631 | } |
||
1632 | | LOWP |
||
1633 | { |
||
1634 | state->check_precision_qualifiers_allowed(&@1); |
||
1635 | $$ = ast_precision_low; |
||
1636 | } |
||
1637 | ; |
||
1638 | |||
1639 | struct_specifier: |
||
1640 | STRUCT any_identifier '{' struct_declaration_list '}' |
||
1641 | { |
||
1642 | void *ctx = state; |
||
1643 | $$ = new(ctx) ast_struct_specifier($2, $4); |
||
1644 | $$->set_location(yylloc); |
||
1645 | state->symbols->add_type($2, glsl_type::void_type); |
||
1646 | state->symbols->add_type_ast($2, new(ctx) ast_type_specifier($$)); |
||
1647 | } |
||
1648 | | STRUCT '{' struct_declaration_list '}' |
||
1649 | { |
||
1650 | void *ctx = state; |
||
1651 | $$ = new(ctx) ast_struct_specifier(NULL, $3); |
||
1652 | $$->set_location(yylloc); |
||
1653 | } |
||
1654 | ; |
||
1655 | |||
1656 | struct_declaration_list: |
||
1657 | struct_declaration |
||
1658 | { |
||
1659 | $$ = $1; |
||
1660 | $1->link.self_link(); |
||
1661 | } |
||
1662 | | struct_declaration_list struct_declaration |
||
1663 | { |
||
1664 | $$ = $1; |
||
1665 | $$->link.insert_before(& $2->link); |
||
1666 | } |
||
1667 | ; |
||
1668 | |||
1669 | struct_declaration: |
||
1670 | fully_specified_type struct_declarator_list ';' |
||
1671 | { |
||
1672 | void *ctx = state; |
||
1673 | ast_fully_specified_type *const type = $1; |
||
1674 | type->set_location(yylloc); |
||
1675 | |||
1676 | if (type->qualifier.flags.i != 0) |
||
1677 | _mesa_glsl_error(&@1, state, |
||
1678 | "only precision qualifiers may be applied to " |
||
1679 | "structure members"); |
||
1680 | |||
1681 | $$ = new(ctx) ast_declarator_list(type); |
||
1682 | $$->set_location(yylloc); |
||
1683 | |||
1684 | $$->declarations.push_degenerate_list_at_head(& $2->link); |
||
1685 | } |
||
1686 | ; |
||
1687 | |||
1688 | struct_declarator_list: |
||
1689 | struct_declarator |
||
1690 | { |
||
1691 | $$ = $1; |
||
1692 | $1->link.self_link(); |
||
1693 | } |
||
1694 | | struct_declarator_list ',' struct_declarator |
||
1695 | { |
||
1696 | $$ = $1; |
||
1697 | $$->link.insert_before(& $3->link); |
||
1698 | } |
||
1699 | ; |
||
1700 | |||
1701 | struct_declarator: |
||
1702 | any_identifier |
||
1703 | { |
||
1704 | void *ctx = state; |
||
1705 | $$ = new(ctx) ast_declaration($1, false, NULL, NULL); |
||
1706 | $$->set_location(yylloc); |
||
1707 | } |
||
1708 | | any_identifier '[' constant_expression ']' |
||
1709 | { |
||
1710 | void *ctx = state; |
||
1711 | $$ = new(ctx) ast_declaration($1, true, $3, NULL); |
||
1712 | $$->set_location(yylloc); |
||
1713 | } |
||
1714 | ; |
||
1715 | |||
1716 | initializer: |
||
1717 | assignment_expression |
||
1718 | | '{' initializer_list '}' |
||
1719 | { |
||
1720 | $$ = $2; |
||
1721 | } |
||
1722 | | '{' initializer_list ',' '}' |
||
1723 | { |
||
1724 | $$ = $2; |
||
1725 | } |
||
1726 | ; |
||
1727 | |||
1728 | initializer_list: |
||
1729 | initializer |
||
1730 | { |
||
1731 | void *ctx = state; |
||
1732 | $$ = new(ctx) ast_aggregate_initializer(); |
||
1733 | $$->set_location(yylloc); |
||
1734 | $$->expressions.push_tail(& $1->link); |
||
1735 | } |
||
1736 | | initializer_list ',' initializer |
||
1737 | { |
||
1738 | $1->expressions.push_tail(& $3->link); |
||
1739 | } |
||
1740 | ; |
||
1741 | |||
1742 | declaration_statement: |
||
1743 | declaration |
||
1744 | ; |
||
1745 | |||
1746 | // Grammar Note: labeled statements for SWITCH only; 'goto' is not |
||
1747 | // supported. |
||
1748 | statement: |
||
1749 | compound_statement { $$ = (ast_node *) $1; } |
||
1750 | | simple_statement |
||
1751 | ; |
||
1752 | |||
1753 | simple_statement: |
||
1754 | declaration_statement |
||
1755 | | expression_statement |
||
1756 | | selection_statement |
||
1757 | | switch_statement |
||
1758 | | iteration_statement |
||
1759 | | jump_statement |
||
1760 | ; |
||
1761 | |||
1762 | compound_statement: |
||
1763 | '{' '}' |
||
1764 | { |
||
1765 | void *ctx = state; |
||
1766 | $$ = new(ctx) ast_compound_statement(true, NULL); |
||
1767 | $$->set_location(yylloc); |
||
1768 | } |
||
1769 | | '{' |
||
1770 | { |
||
1771 | state->symbols->push_scope(); |
||
1772 | } |
||
1773 | statement_list '}' |
||
1774 | { |
||
1775 | void *ctx = state; |
||
1776 | $$ = new(ctx) ast_compound_statement(true, $3); |
||
1777 | $$->set_location(yylloc); |
||
1778 | state->symbols->pop_scope(); |
||
1779 | } |
||
1780 | ; |
||
1781 | |||
1782 | statement_no_new_scope: |
||
1783 | compound_statement_no_new_scope { $$ = (ast_node *) $1; } |
||
1784 | | simple_statement |
||
1785 | ; |
||
1786 | |||
1787 | compound_statement_no_new_scope: |
||
1788 | '{' '}' |
||
1789 | { |
||
1790 | void *ctx = state; |
||
1791 | $$ = new(ctx) ast_compound_statement(false, NULL); |
||
1792 | $$->set_location(yylloc); |
||
1793 | } |
||
1794 | | '{' statement_list '}' |
||
1795 | { |
||
1796 | void *ctx = state; |
||
1797 | $$ = new(ctx) ast_compound_statement(false, $2); |
||
1798 | $$->set_location(yylloc); |
||
1799 | } |
||
1800 | ; |
||
1801 | |||
1802 | statement_list: |
||
1803 | statement |
||
1804 | { |
||
1805 | if ($1 == NULL) { |
||
1806 | _mesa_glsl_error(& @1, state, " |
||
1807 | assert($1 != NULL); |
||
1808 | } |
||
1809 | |||
1810 | $$ = $1; |
||
1811 | $$->link.self_link(); |
||
1812 | } |
||
1813 | | statement_list statement |
||
1814 | { |
||
1815 | if ($2 == NULL) { |
||
1816 | _mesa_glsl_error(& @2, state, " |
||
1817 | assert($2 != NULL); |
||
1818 | } |
||
1819 | $$ = $1; |
||
1820 | $$->link.insert_before(& $2->link); |
||
1821 | } |
||
1822 | ; |
||
1823 | |||
1824 | expression_statement: |
||
1825 | ';' |
||
1826 | { |
||
1827 | void *ctx = state; |
||
1828 | $$ = new(ctx) ast_expression_statement(NULL); |
||
1829 | $$->set_location(yylloc); |
||
1830 | } |
||
1831 | | expression ';' |
||
1832 | { |
||
1833 | void *ctx = state; |
||
1834 | $$ = new(ctx) ast_expression_statement($1); |
||
1835 | $$->set_location(yylloc); |
||
1836 | } |
||
1837 | ; |
||
1838 | |||
1839 | selection_statement: |
||
1840 | IF '(' expression ')' selection_rest_statement |
||
1841 | { |
||
1842 | $$ = new(state) ast_selection_statement($3, $5.then_statement, |
||
1843 | $5.else_statement); |
||
1844 | $$->set_location(yylloc); |
||
1845 | } |
||
1846 | ; |
||
1847 | |||
1848 | selection_rest_statement: |
||
1849 | statement ELSE statement |
||
1850 | { |
||
1851 | $$.then_statement = $1; |
||
1852 | $$.else_statement = $3; |
||
1853 | } |
||
1854 | | statement %prec THEN |
||
1855 | { |
||
1856 | $$.then_statement = $1; |
||
1857 | $$.else_statement = NULL; |
||
1858 | } |
||
1859 | ; |
||
1860 | |||
1861 | condition: |
||
1862 | expression |
||
1863 | { |
||
1864 | $$ = (ast_node *) $1; |
||
1865 | } |
||
1866 | | fully_specified_type any_identifier '=' initializer |
||
1867 | { |
||
1868 | void *ctx = state; |
||
1869 | ast_declaration *decl = new(ctx) ast_declaration($2, false, NULL, $4); |
||
1870 | ast_declarator_list *declarator = new(ctx) ast_declarator_list($1); |
||
1871 | decl->set_location(yylloc); |
||
1872 | declarator->set_location(yylloc); |
||
1873 | |||
1874 | declarator->declarations.push_tail(&decl->link); |
||
1875 | $$ = declarator; |
||
1876 | } |
||
1877 | ; |
||
1878 | |||
1879 | /* |
||
1880 | * siwtch_statement grammar is based on the syntax described in the body |
||
1881 | * of the GLSL spec, not in it's appendix!!! |
||
1882 | */ |
||
1883 | switch_statement: |
||
1884 | SWITCH '(' expression ')' switch_body |
||
1885 | { |
||
1886 | $$ = new(state) ast_switch_statement($3, $5); |
||
1887 | $$->set_location(yylloc); |
||
1888 | } |
||
1889 | ; |
||
1890 | |||
1891 | switch_body: |
||
1892 | '{' '}' |
||
1893 | { |
||
1894 | $$ = new(state) ast_switch_body(NULL); |
||
1895 | $$->set_location(yylloc); |
||
1896 | } |
||
1897 | | '{' case_statement_list '}' |
||
1898 | { |
||
1899 | $$ = new(state) ast_switch_body($2); |
||
1900 | $$->set_location(yylloc); |
||
1901 | } |
||
1902 | ; |
||
1903 | |||
1904 | case_label: |
||
1905 | CASE expression ':' |
||
1906 | { |
||
1907 | $$ = new(state) ast_case_label($2); |
||
1908 | $$->set_location(yylloc); |
||
1909 | } |
||
1910 | | DEFAULT ':' |
||
1911 | { |
||
1912 | $$ = new(state) ast_case_label(NULL); |
||
1913 | $$->set_location(yylloc); |
||
1914 | } |
||
1915 | ; |
||
1916 | |||
1917 | case_label_list: |
||
1918 | case_label |
||
1919 | { |
||
1920 | ast_case_label_list *labels = new(state) ast_case_label_list(); |
||
1921 | |||
1922 | labels->labels.push_tail(& $1->link); |
||
1923 | $$ = labels; |
||
1924 | $$->set_location(yylloc); |
||
1925 | } |
||
1926 | | case_label_list case_label |
||
1927 | { |
||
1928 | $$ = $1; |
||
1929 | $$->labels.push_tail(& $2->link); |
||
1930 | } |
||
1931 | ; |
||
1932 | |||
1933 | case_statement: |
||
1934 | case_label_list statement |
||
1935 | { |
||
1936 | ast_case_statement *stmts = new(state) ast_case_statement($1); |
||
1937 | stmts->set_location(yylloc); |
||
1938 | |||
1939 | stmts->stmts.push_tail(& $2->link); |
||
1940 | $$ = stmts; |
||
1941 | } |
||
1942 | | case_statement statement |
||
1943 | { |
||
1944 | $$ = $1; |
||
1945 | $$->stmts.push_tail(& $2->link); |
||
1946 | } |
||
1947 | ; |
||
1948 | |||
1949 | case_statement_list: |
||
1950 | case_statement |
||
1951 | { |
||
1952 | ast_case_statement_list *cases= new(state) ast_case_statement_list(); |
||
1953 | cases->set_location(yylloc); |
||
1954 | |||
1955 | cases->cases.push_tail(& $1->link); |
||
1956 | $$ = cases; |
||
1957 | } |
||
1958 | | case_statement_list case_statement |
||
1959 | { |
||
1960 | $$ = $1; |
||
1961 | $$->cases.push_tail(& $2->link); |
||
1962 | } |
||
1963 | ; |
||
1964 | |||
1965 | iteration_statement: |
||
1966 | WHILE '(' condition ')' statement_no_new_scope |
||
1967 | { |
||
1968 | void *ctx = state; |
||
1969 | $$ = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_while, |
||
1970 | NULL, $3, NULL, $5); |
||
1971 | $$->set_location(yylloc); |
||
1972 | } |
||
1973 | | DO statement WHILE '(' expression ')' ';' |
||
1974 | { |
||
1975 | void *ctx = state; |
||
1976 | $$ = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_do_while, |
||
1977 | NULL, $5, NULL, $2); |
||
1978 | $$->set_location(yylloc); |
||
1979 | } |
||
1980 | | FOR '(' for_init_statement for_rest_statement ')' statement_no_new_scope |
||
1981 | { |
||
1982 | void *ctx = state; |
||
1983 | $$ = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_for, |
||
1984 | $3, $4.cond, $4.rest, $6); |
||
1985 | $$->set_location(yylloc); |
||
1986 | } |
||
1987 | ; |
||
1988 | |||
1989 | for_init_statement: |
||
1990 | expression_statement |
||
1991 | | declaration_statement |
||
1992 | ; |
||
1993 | |||
1994 | conditionopt: |
||
1995 | condition |
||
1996 | | /* empty */ |
||
1997 | { |
||
1998 | $$ = NULL; |
||
1999 | } |
||
2000 | ; |
||
2001 | |||
2002 | for_rest_statement: |
||
2003 | conditionopt ';' |
||
2004 | { |
||
2005 | $$.cond = $1; |
||
2006 | $$.rest = NULL; |
||
2007 | } |
||
2008 | | conditionopt ';' expression |
||
2009 | { |
||
2010 | $$.cond = $1; |
||
2011 | $$.rest = $3; |
||
2012 | } |
||
2013 | ; |
||
2014 | |||
2015 | // Grammar Note: No 'goto'. Gotos are not supported. |
||
2016 | jump_statement: |
||
2017 | CONTINUE ';' |
||
2018 | { |
||
2019 | void *ctx = state; |
||
2020 | $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_continue, NULL); |
||
2021 | $$->set_location(yylloc); |
||
2022 | } |
||
2023 | | BREAK ';' |
||
2024 | { |
||
2025 | void *ctx = state; |
||
2026 | $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_break, NULL); |
||
2027 | $$->set_location(yylloc); |
||
2028 | } |
||
2029 | | RETURN ';' |
||
2030 | { |
||
2031 | void *ctx = state; |
||
2032 | $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_return, NULL); |
||
2033 | $$->set_location(yylloc); |
||
2034 | } |
||
2035 | | RETURN expression ';' |
||
2036 | { |
||
2037 | void *ctx = state; |
||
2038 | $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_return, $2); |
||
2039 | $$->set_location(yylloc); |
||
2040 | } |
||
2041 | | DISCARD ';' // Fragment shader only. |
||
2042 | { |
||
2043 | void *ctx = state; |
||
2044 | $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_discard, NULL); |
||
2045 | $$->set_location(yylloc); |
||
2046 | } |
||
2047 | ; |
||
2048 | |||
2049 | external_declaration: |
||
2050 | function_definition { $$ = $1; } |
||
2051 | | declaration { $$ = $1; } |
||
2052 | | pragma_statement { $$ = NULL; } |
||
2053 | | layout_defaults { $$ = NULL; } |
||
2054 | ; |
||
2055 | |||
2056 | function_definition: |
||
2057 | function_prototype compound_statement_no_new_scope |
||
2058 | { |
||
2059 | void *ctx = state; |
||
2060 | $$ = new(ctx) ast_function_definition(); |
||
2061 | $$->set_location(yylloc); |
||
2062 | $$->prototype = $1; |
||
2063 | $$->body = $2; |
||
2064 | |||
2065 | state->symbols->pop_scope(); |
||
2066 | } |
||
2067 | ; |
||
2068 | |||
2069 | /* layout_qualifieropt is packed into this rule */ |
||
2070 | interface_block: |
||
2071 | basic_interface_block |
||
2072 | { |
||
2073 | $$ = $1; |
||
2074 | } |
||
2075 | | layout_qualifier basic_interface_block |
||
2076 | { |
||
2077 | ast_interface_block *block = $2; |
||
2078 | if (!block->layout.merge_qualifier(& @1, state, $1)) { |
||
2079 | YYERROR; |
||
2080 | } |
||
2081 | $$ = block; |
||
2082 | } |
||
2083 | ; |
||
2084 | |||
2085 | basic_interface_block: |
||
2086 | interface_qualifier NEW_IDENTIFIER '{' member_list '}' instance_name_opt ';' |
||
2087 | { |
||
2088 | ast_interface_block *const block = $6; |
||
2089 | |||
2090 | block->block_name = $2; |
||
2091 | block->declarations.push_degenerate_list_at_head(& $4->link); |
||
2092 | |||
2093 | if ($1.flags.q.uniform) { |
||
2094 | if (!state->ARB_uniform_buffer_object_enable) { |
||
2095 | _mesa_glsl_error(& @1, state, |
||
2096 | "#version 140 / GL_ARB_uniform_buffer_object " |
||
2097 | "required for defining uniform blocks\n"); |
||
2098 | } else if (state->ARB_uniform_buffer_object_warn) { |
||
2099 | _mesa_glsl_warning(& @1, state, |
||
2100 | "#version 140 / GL_ARB_uniform_buffer_object " |
||
2101 | "required for defining uniform blocks\n"); |
||
2102 | } |
||
2103 | } else { |
||
2104 | if (state->es_shader || state->language_version < 150) { |
||
2105 | _mesa_glsl_error(& @1, state, |
||
2106 | "#version 150 required for using " |
||
2107 | "interface blocks.\n"); |
||
2108 | } |
||
2109 | } |
||
2110 | |||
2111 | /* From the GLSL 1.50.11 spec, section 4.3.7 ("Interface Blocks"): |
||
2112 | * "It is illegal to have an input block in a vertex shader |
||
2113 | * or an output block in a fragment shader" |
||
2114 | */ |
||
2115 | if ((state->target == vertex_shader) && $1.flags.q.in) { |
||
2116 | _mesa_glsl_error(& @1, state, |
||
2117 | "`in' interface block is not allowed for " |
||
2118 | "a vertex shader\n"); |
||
2119 | } else if ((state->target == fragment_shader) && $1.flags.q.out) { |
||
2120 | _mesa_glsl_error(& @1, state, |
||
2121 | "`out' interface block is not allowed for " |
||
2122 | "a fragment shader\n"); |
||
2123 | } |
||
2124 | |||
2125 | /* Since block arrays require names, and both features are added in |
||
2126 | * the same language versions, we don't have to explicitly |
||
2127 | * version-check both things. |
||
2128 | */ |
||
2129 | if (block->instance_name != NULL) { |
||
2130 | state->check_version(150, 300, & @1, "interface blocks with " |
||
2131 | "an instance name are not allowed"); |
||
2132 | } |
||
2133 | |||
2134 | unsigned interface_type_mask; |
||
2135 | struct ast_type_qualifier temp_type_qualifier; |
||
2136 | |||
2137 | /* Get a bitmask containing only the in/out/uniform flags, allowing us |
||
2138 | * to ignore other irrelevant flags like interpolation qualifiers. |
||
2139 | */ |
||
2140 | temp_type_qualifier.flags.i = 0; |
||
2141 | temp_type_qualifier.flags.q.uniform = true; |
||
2142 | temp_type_qualifier.flags.q.in = true; |
||
2143 | temp_type_qualifier.flags.q.out = true; |
||
2144 | interface_type_mask = temp_type_qualifier.flags.i; |
||
2145 | |||
2146 | /* Get the block's interface qualifier. The interface_qualifier |
||
2147 | * production rule guarantees that only one bit will be set (and |
||
2148 | * it will be in/out/uniform). |
||
2149 | */ |
||
2150 | unsigned block_interface_qualifier = $1.flags.i; |
||
2151 | |||
2152 | block->layout.flags.i |= block_interface_qualifier; |
||
2153 | |||
2154 | foreach_list_typed (ast_declarator_list, member, link, &block->declarations) { |
||
2155 | ast_type_qualifier& qualifier = member->type->qualifier; |
||
2156 | if ((qualifier.flags.i & interface_type_mask) == 0) { |
||
2157 | /* GLSLangSpec.1.50.11, 4.3.7 (Interface Blocks): |
||
2158 | * "If no optional qualifier is used in a member declaration, the |
||
2159 | * qualifier of the variable is just in, out, or uniform as declared |
||
2160 | * by interface-qualifier." |
||
2161 | */ |
||
2162 | qualifier.flags.i |= block_interface_qualifier; |
||
2163 | } else if ((qualifier.flags.i & interface_type_mask) != |
||
2164 | block_interface_qualifier) { |
||
2165 | /* GLSLangSpec.1.50.11, 4.3.7 (Interface Blocks): |
||
2166 | * "If optional qualifiers are used, they can include interpolation |
||
2167 | * and storage qualifiers and they must declare an input, output, |
||
2168 | * or uniform variable consistent with the interface qualifier of |
||
2169 | * the block." |
||
2170 | */ |
||
2171 | _mesa_glsl_error(& @1, state, |
||
2172 | "uniform/in/out qualifier on " |
||
2173 | "interface block member does not match " |
||
2174 | "the interface block\n"); |
||
2175 | } |
||
2176 | } |
||
2177 | |||
2178 | $$ = block; |
||
2179 | } |
||
2180 | ; |
||
2181 | |||
2182 | interface_qualifier: |
||
2183 | IN_TOK |
||
2184 | { |
||
2185 | memset(& $$, 0, sizeof($$)); |
||
2186 | $$.flags.q.in = 1; |
||
2187 | } |
||
2188 | | OUT_TOK |
||
2189 | { |
||
2190 | memset(& $$, 0, sizeof($$)); |
||
2191 | $$.flags.q.out = 1; |
||
2192 | } |
||
2193 | | UNIFORM |
||
2194 | { |
||
2195 | memset(& $$, 0, sizeof($$)); |
||
2196 | $$.flags.q.uniform = 1; |
||
2197 | } |
||
2198 | ; |
||
2199 | |||
2200 | instance_name_opt: |
||
2201 | /* empty */ |
||
2202 | { |
||
2203 | $$ = new(state) ast_interface_block(*state->default_uniform_qualifier, |
||
2204 | NULL, NULL); |
||
2205 | } |
||
2206 | | NEW_IDENTIFIER |
||
2207 | { |
||
2208 | $$ = new(state) ast_interface_block(*state->default_uniform_qualifier, |
||
2209 | $1, NULL); |
||
2210 | } |
||
2211 | | NEW_IDENTIFIER '[' constant_expression ']' |
||
2212 | { |
||
2213 | $$ = new(state) ast_interface_block(*state->default_uniform_qualifier, |
||
2214 | $1, $3); |
||
2215 | } |
||
2216 | | NEW_IDENTIFIER '[' ']' |
||
2217 | { |
||
2218 | _mesa_glsl_error(& @1, state, |
||
2219 | "instance block arrays must be explicitly sized\n"); |
||
2220 | |||
2221 | $$ = new(state) ast_interface_block(*state->default_uniform_qualifier, |
||
2222 | $1, NULL); |
||
2223 | } |
||
2224 | ; |
||
2225 | |||
2226 | member_list: |
||
2227 | member_declaration |
||
2228 | { |
||
2229 | $$ = $1; |
||
2230 | $1->link.self_link(); |
||
2231 | } |
||
2232 | | member_declaration member_list |
||
2233 | { |
||
2234 | $$ = $1; |
||
2235 | $2->link.insert_before(& $$->link); |
||
2236 | } |
||
2237 | ; |
||
2238 | |||
2239 | member_declaration: |
||
2240 | fully_specified_type struct_declarator_list ';' |
||
2241 | { |
||
2242 | void *ctx = state; |
||
2243 | ast_fully_specified_type *type = $1; |
||
2244 | type->set_location(yylloc); |
||
2245 | |||
2246 | if (type->qualifier.flags.q.attribute) { |
||
2247 | _mesa_glsl_error(& @1, state, |
||
2248 | "keyword 'attribute' cannot be used with " |
||
2249 | "interface block member\n"); |
||
2250 | } else if (type->qualifier.flags.q.varying) { |
||
2251 | _mesa_glsl_error(& @1, state, |
||
2252 | "keyword 'varying' cannot be used with " |
||
2253 | "interface block member\n"); |
||
2254 | } |
||
2255 | |||
2256 | $$ = new(ctx) ast_declarator_list(type); |
||
2257 | $$->set_location(yylloc); |
||
2258 | |||
2259 | $$->declarations.push_degenerate_list_at_head(& $2->link); |
||
2260 | } |
||
2261 | ; |
||
2262 | |||
2263 | layout_defaults: |
||
2264 | layout_qualifier UNIFORM ';' |
||
2265 | { |
||
2266 | if (!state->default_uniform_qualifier->merge_qualifier(& @1, state, $1)) { |
||
2267 | YYERROR; |
||
2268 | } |
||
2269 | }>'> |