xref: /aosp_15_r20/external/angle/src/compiler/translator/glslang.y (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 /*
2 //
3 // Copyright 2002 The ANGLE Project Authors. All rights reserved.
4 // Use of this source code is governed by a BSD-style license that can be
5 // found in the LICENSE file.
6 //
7 
8 This file contains the Yacc grammar for GLSL ES.
9 Based on ANSI C Yacc grammar:
10 http://www.lysator.liu.se/c/ANSI-C-grammar-y.html
11 
12 IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN scripts/run_code_generation.py
13 WHICH GENERATES THE GLSL ES PARSER (glslang_tab_autogen.cpp AND glslang_tab_autogen.h).
14 */
15 
16 %{
17 // GENERATED FILE - DO NOT EDIT.
18 // Generated by generate_parser.py from glslang.y
19 //
20 // Copyright 2019 The ANGLE Project Authors. All rights reserved.
21 // Use of this source code is governed by a BSD-style license that can be
22 // found in the LICENSE file.
23 //
24 // glslang.y:
25 //   Parser for the OpenGL shading language.
26 
27 // Ignore errors in auto-generated code.
28 #if defined(__GNUC__)
29 #pragma GCC diagnostic ignored "-Wunused-function"
30 #pragma GCC diagnostic ignored "-Wunused-variable"
31 #pragma GCC diagnostic ignored "-Wswitch-enum"
32 #elif defined(_MSC_VER)
33 #pragma warning(disable: 4065)
34 #pragma warning(disable: 4189)
35 #pragma warning(disable: 4244)
36 #pragma warning(disable: 4505)
37 #pragma warning(disable: 4701)
38 #pragma warning(disable: 4702)
39 #endif
40 #if defined(__clang__)
41 #pragma clang diagnostic ignored "-Wunreachable-code"
42 #pragma clang diagnostic ignored "-Wunused-but-set-variable"
43 #endif
44 
45 #include "angle_gl.h"
46 #include "compiler/translator/Declarator.h"
47 #include "compiler/translator/SymbolTable.h"
48 #include "compiler/translator/ParseContext.h"
49 #include "GLSLANG/ShaderLang.h"
50 
51 #define YYENABLE_NLS 0
52 
53 using namespace sh;
54 
55 %}
56 %expect 1 /* One shift reduce conflict because of if | else */
57 %parse-param {TParseContext* context}
58 %param   {void *scanner}
59 %define api.pure full
60 %locations
61 
62 %code requires {
63 #define YYLTYPE TSourceLoc
64 #define YYLTYPE_IS_DECLARED 1
65 #define YYLTYPE_IS_TRIVIAL 1
66 }
67 
68 %union {
69     struct {
70         union {
71             const char *string;  // pool allocated.
72             float f;
73             int i;
74             unsigned int u;
75             bool b;
76         };
77         const TSymbol* symbol;
78     } lex;
79     struct {
80         TOperator op;
81         union {
82             TIntermNode *intermNode;
83             TIntermNodePair nodePair;
84             TIntermTyped *intermTypedNode;
85             TIntermAggregate *intermAggregate;
86             TIntermBlock *intermBlock;
87             TIntermDeclaration *intermDeclaration;
88             TIntermFunctionPrototype *intermFunctionPrototype;
89             TIntermSwitch *intermSwitch;
90             TIntermCase *intermCase;
91         };
92         union {
93             TVector<unsigned int> *arraySizes;
94             TTypeSpecifierNonArray typeSpecifierNonArray;
95             TPublicType type;
96             TPrecision precision;
97             TLayoutQualifier layoutQualifier;
98             TQualifier qualifier;
99             TFunction *function;
100             TFunctionLookup *functionLookup;
101             TParameter param;
102             TDeclarator *declarator;
103             TDeclaratorList *declaratorList;
104             TFieldList *fieldList;
105             TQualifierWrapperBase *qualifierWrapper;
106             TTypeQualifierBuilder *typeQualifierBuilder;
107         };
108     } interm;
109 }
110 
111 %{
112 extern int yylex(YYSTYPE* yylval, YYLTYPE* yylloc, void* yyscanner);
113 extern void yyerror(YYLTYPE* yylloc, TParseContext* context, void *scanner, const char* reason);
114 
115 #define YYLLOC_DEFAULT(Current, Rhs, N)                      \
116   do {                                                       \
117       if (N) {                                         \
118         (Current).first_file = YYRHSLOC(Rhs, 1).first_file;  \
119         (Current).first_line = YYRHSLOC(Rhs, 1).first_line;  \
120         (Current).last_file = YYRHSLOC(Rhs, N).last_file;    \
121         (Current).last_line = YYRHSLOC(Rhs, N).last_line;    \
122       }                                                      \
123       else {                                                 \
124         (Current).first_file = YYRHSLOC(Rhs, 0).last_file;   \
125         (Current).first_line = YYRHSLOC(Rhs, 0).last_line;   \
126         (Current).last_file = YYRHSLOC(Rhs, 0).last_file;    \
127         (Current).last_line = YYRHSLOC(Rhs, 0).last_line;    \
128       }                                                      \
129   } while (0)
130 
131 #define VERTEX_ONLY(S, L) do {  \
132     if (context->getShaderType() != GL_VERTEX_SHADER) {  \
133         context->error(L, " supported in vertex shaders only", S);  \
134     }  \
135 } while (0)
136 
137 #define COMPUTE_ONLY(S, L) do {  \
138     if (context->getShaderType() != GL_COMPUTE_SHADER) {  \
139         context->error(L, " supported in compute shaders only", S);  \
140     }  \
141 } while (0)
142 
143 #define ES2_ONLY(S, L) do {  \
144     if (context->getShaderVersion() != 100) {  \
145         context->error(L, " supported in GLSL ES 1.00 only", S);  \
146     }  \
147 } while (0)
148 
149 #define ES3_OR_NEWER(TOKEN, LINE, REASON) do {  \
150     if (context->getShaderVersion() < 300) {  \
151         context->error(LINE, REASON " supported in GLSL ES 3.00 and above only", TOKEN);  \
152     }  \
153 } while (0)
154 
155 #define ES3_1_OR_NEWER(TOKEN, LINE, REASON) do {  \
156     if (context->getShaderVersion() < 310) {  \
157         context->error(LINE, REASON " supported in GLSL ES 3.10 and above only", TOKEN);  \
158     }  \
159 } while (0)
160 %}
161 
162 %token <lex> INVARIANT PRECISE HIGH_PRECISION MEDIUM_PRECISION LOW_PRECISION PRECISION
163 %token <lex> ATTRIBUTE CONST_QUAL BOOL_TYPE FLOAT_TYPE INT_TYPE UINT_TYPE
164 %token <lex> BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN SWITCH CASE DEFAULT
165 %token <lex> BVEC2 BVEC3 BVEC4 IVEC2 IVEC3 IVEC4 VEC2 VEC3 VEC4 UVEC2 UVEC3 UVEC4
166 %token <lex> MATRIX2 MATRIX3 MATRIX4 IN_QUAL OUT_QUAL INOUT_QUAL UNIFORM BUFFER VARYING
167 %token <lex> MATRIX2x3 MATRIX3x2 MATRIX2x4 MATRIX4x2 MATRIX3x4 MATRIX4x3
168 %token <lex> SAMPLE CENTROID FLAT SMOOTH NOPERSPECTIVE PATCH
169 %token <lex> READONLY WRITEONLY COHERENT RESTRICT VOLATILE SHARED
170 %token <lex> STRUCT VOID_TYPE WHILE
171 %token <lex> SAMPLER2D SAMPLERCUBE SAMPLER_EXTERNAL_OES SAMPLER2DRECT SAMPLER2DARRAY
172 %token <lex> ISAMPLER2D ISAMPLER3D ISAMPLERCUBE ISAMPLER2DARRAY
173 %token <lex> USAMPLER2D USAMPLER3D USAMPLERCUBE USAMPLER2DARRAY
174 %token <lex> SAMPLER2DMS ISAMPLER2DMS USAMPLER2DMS
175 %token <lex> SAMPLER2DMSARRAY ISAMPLER2DMSARRAY USAMPLER2DMSARRAY
176 %token <lex> SAMPLER3D SAMPLER3DRECT SAMPLER2DSHADOW SAMPLERCUBESHADOW SAMPLER2DARRAYSHADOW SAMPLERVIDEOWEBGL
177 %token <lex> SAMPLERCUBEARRAYOES SAMPLERCUBEARRAYSHADOWOES ISAMPLERCUBEARRAYOES USAMPLERCUBEARRAYOES
178 %token <lex> SAMPLERCUBEARRAYEXT SAMPLERCUBEARRAYSHADOWEXT ISAMPLERCUBEARRAYEXT USAMPLERCUBEARRAYEXT
179 %token <lex> SAMPLERBUFFER ISAMPLERBUFFER USAMPLERBUFFER
180 %token <lex> SAMPLEREXTERNAL2DY2YEXT
181 %token <lex> IMAGE2D IIMAGE2D UIMAGE2D IMAGE3D IIMAGE3D UIMAGE3D IMAGE2DARRAY IIMAGE2DARRAY UIMAGE2DARRAY
182 %token <lex> IMAGECUBE IIMAGECUBE UIMAGECUBE
183 %token <lex> IMAGECUBEARRAYOES IIMAGECUBEARRAYOES UIMAGECUBEARRAYOES
184 %token <lex> IMAGECUBEARRAYEXT IIMAGECUBEARRAYEXT UIMAGECUBEARRAYEXT
185 %token <lex> IMAGEBUFFER IIMAGEBUFFER UIMAGEBUFFER
186 %token <lex> ATOMICUINT
187 %token <lex> PIXELLOCALANGLE IPIXELLOCALANGLE UPIXELLOCALANGLE
188 %token <lex> LAYOUT
189 %token <lex> YUVCSCSTANDARDEXT YUVCSCSTANDARDEXTCONSTANT
190 
191 %token <lex> IDENTIFIER TYPE_NAME FLOATCONSTANT INTCONSTANT UINTCONSTANT BOOLCONSTANT
192 %token <lex> FIELD_SELECTION
193 %token <lex> LEFT_OP RIGHT_OP
194 %token <lex> INC_OP DEC_OP LE_OP GE_OP EQ_OP NE_OP
195 %token <lex> AND_OP OR_OP XOR_OP MUL_ASSIGN DIV_ASSIGN ADD_ASSIGN
196 %token <lex> MOD_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN XOR_ASSIGN OR_ASSIGN
197 %token <lex> SUB_ASSIGN
198 
199 %token <lex> LEFT_PAREN RIGHT_PAREN LEFT_BRACKET RIGHT_BRACKET LEFT_BRACE RIGHT_BRACE DOT
200 %token <lex> COMMA COLON EQUAL SEMICOLON BANG DASH TILDE PLUS STAR SLASH PERCENT
201 %token <lex> LEFT_ANGLE RIGHT_ANGLE VERTICAL_BAR CARET AMPERSAND QUESTION
202 
203 %type <lex> identifier
204 %type <interm.op> assignment_operator unary_operator
205 %type <interm.intermTypedNode> variable_identifier primary_expression postfix_expression
206 %type <interm.intermTypedNode> expression integer_expression assignment_expression
207 %type <interm.intermTypedNode> unary_expression multiplicative_expression additive_expression
208 %type <interm.intermTypedNode> relational_expression equality_expression
209 %type <interm.intermTypedNode> conditional_expression constant_expression
210 %type <interm.intermTypedNode> logical_or_expression logical_xor_expression logical_and_expression
211 %type <interm.intermTypedNode> shift_expression and_expression exclusive_or_expression inclusive_or_expression
212 %type <interm.intermTypedNode> function_call initializer
213 
214 %type <interm.intermNode> condition conditionopt
215 %type <interm.intermBlock> translation_unit
216 %type <interm.intermNode> function_definition statement simple_statement
217 %type <interm.intermBlock> statement_list compound_statement_with_scope compound_statement_no_new_scope
218 %type <interm.intermNode> declaration_statement selection_statement expression_statement
219 %type <interm.intermNode> declaration external_declaration
220 %type <interm.intermNode> for_init_statement
221 %type <interm.nodePair> selection_rest_statement for_rest_statement
222 %type <interm.intermSwitch> switch_statement
223 %type <interm.intermCase> case_label
224 %type <interm.intermNode> iteration_statement jump_statement statement_no_new_scope statement_with_scope
225 %type <interm> single_declaration init_declarator_list
226 
227 %type <interm.param> parameter_declaration parameter_declarator
228 %type <interm.layoutQualifier> layout_qualifier_id_list layout_qualifier_id
229 
230 // Note: array_specifier guaranteed to be non-null.
231 %type <interm.arraySizes> array_specifier
232 
233 %type <interm.type> fully_specified_type type_specifier parameter_type_specifier
234 
235 %type <interm.precision> precision_qualifier
236 %type <interm.layoutQualifier> layout_qualifier
237 %type <interm.qualifier> interpolation_qualifier
238 %type <interm.qualifierWrapper> storage_qualifier single_type_qualifier invariant_qualifier precise_qualifier
239 %type <interm.typeQualifierBuilder> type_qualifier
240 
241 %type <interm.typeSpecifierNonArray> type_specifier_nonarray struct_specifier
242 %type <interm.type> type_specifier_no_prec
243 %type <interm.declarator> struct_declarator
244 %type <interm.declaratorList> struct_declarator_list
245 %type <interm.fieldList> struct_declaration struct_declaration_list
246 %type <interm.function> function_header function_declarator
247 %type <interm.function> function_header_with_parameters
248 %type <interm.functionLookup> function_identifier function_call_header
249 %type <interm.functionLookup> function_call_header_with_parameters function_call_header_no_parameters
250 %type <interm.functionLookup> function_call_generic function_call_or_method
251 %type <interm> function_prototype
252 
253 %type <lex> enter_struct
254 
255 %start translation_unit
256 %%
257 
258 identifier
259     : IDENTIFIER
260     | TYPE_NAME
261 
262 variable_identifier
263     : IDENTIFIER {
264         // The symbol table search was done in the lexical phase
265         $$ = context->parseVariableIdentifier(@1, ImmutableString($1.string), $1.symbol);
266     }
267     ;
268 
269 primary_expression
270     : variable_identifier {
271         $$ = $1;
272     }
273     | INTCONSTANT {
274         TConstantUnion *unionArray = new TConstantUnion[1];
275         unionArray->setIConst($1.i);
276         $$ = context->addScalarLiteral(unionArray, @1);
277     }
278     | UINTCONSTANT {
279         TConstantUnion *unionArray = new TConstantUnion[1];
280         unionArray->setUConst($1.u);
281         $$ = context->addScalarLiteral(unionArray, @1);
282     }
283     | FLOATCONSTANT {
284         TConstantUnion *unionArray = new TConstantUnion[1];
285         unionArray->setFConst($1.f);
286         $$ = context->addScalarLiteral(unionArray, @1);
287     }
288     | BOOLCONSTANT {
289         TConstantUnion *unionArray = new TConstantUnion[1];
290         unionArray->setBConst($1.b);
291         $$ = context->addScalarLiteral(unionArray, @1);
292     }
293     | YUVCSCSTANDARDEXTCONSTANT {
294         if (!context->checkCanUseExtension(@1, TExtension::EXT_YUV_target))
295         {
296            context->error(@1, "unsupported value", ImmutableString($1.string));
297         }
298         TConstantUnion *unionArray = new TConstantUnion[1];
299         unionArray->setYuvCscStandardEXTConst(getYuvCscStandardEXT(ImmutableString($1.string)));
300         $$ = context->addScalarLiteral(unionArray, @1);
301     }
302     | LEFT_PAREN expression RIGHT_PAREN {
303         $$ = $2;
304     }
305     ;
306 
307 postfix_expression
308     : primary_expression {
309         $$ = $1;
310     }
311     | postfix_expression LEFT_BRACKET integer_expression RIGHT_BRACKET {
312         $$ = context->addIndexExpression($1, @2, $3);
313     }
314     | function_call {
315         $$ = $1;
316     }
317     | postfix_expression DOT FIELD_SELECTION {
318         $$ = context->addFieldSelectionExpression($1, @2, ImmutableString($3.string), @3);
319     }
320     | postfix_expression INC_OP {
321         $$ = context->addUnaryMathLValue(EOpPostIncrement, $1, @2);
322     }
323     | postfix_expression DEC_OP {
324         $$ = context->addUnaryMathLValue(EOpPostDecrement, $1, @2);
325     }
326     ;
327 
328 integer_expression
329     : expression {
330         context->checkIsScalarInteger($1, "[]");
331         $$ = $1;
332     }
333     ;
334 
335 function_call
336     : function_call_or_method {
337         $$ = context->addFunctionCallOrMethod($1, @1);
338     }
339     ;
340 
341 function_call_or_method
342     : function_call_generic {
343         $$ = $1;
344     }
345     | postfix_expression DOT function_call_generic {
346         ES3_OR_NEWER("", @3, "methods");
347         $$ = $3;
348         $$->setThisNode($1);
349     }
350     ;
351 
352 function_call_generic
353     : function_call_header_with_parameters RIGHT_PAREN {
354         $$ = $1;
355     }
356     | function_call_header_no_parameters RIGHT_PAREN {
357         $$ = $1;
358     }
359     ;
360 
361 function_call_header_no_parameters
362     : function_call_header VOID_TYPE {
363         $$ = $1;
364     }
365     | function_call_header {
366         $$ = $1;
367     }
368     ;
369 
370 function_call_header_with_parameters
371     : function_call_header assignment_expression {
372         $$ = $1;
373         $$->addArgument($2);
374     }
375     | function_call_header_with_parameters COMMA assignment_expression {
376         $$ = $1;
377         $$->addArgument($3);
378     }
379     ;
380 
381 function_call_header
382     : function_identifier LEFT_PAREN {
383         $$ = $1;
384     }
385     ;
386 
387 // Grammar Note:  Constructors look like functions, but are recognized as types.
388 
389 function_identifier
390     : type_specifier_no_prec {
391         $$ = context->addConstructorFunc($1);
392     }
393     | IDENTIFIER {
394         $$ = context->addNonConstructorFunc(ImmutableString($1.string), $1.symbol);
395     }
396     | FIELD_SELECTION {
397         $$ = context->addNonConstructorFunc(ImmutableString($1.string), $1.symbol);
398     }
399     ;
400 
401 unary_expression
402     : postfix_expression {
403         $$ = $1;
404     }
405     | INC_OP unary_expression {
406         $$ = context->addUnaryMathLValue(EOpPreIncrement, $2, @1);
407     }
408     | DEC_OP unary_expression {
409         $$ = context->addUnaryMathLValue(EOpPreDecrement, $2, @1);
410     }
411     | unary_operator unary_expression {
412         $$ = context->addUnaryMath($1, $2, @1);
413     }
414     ;
415 // Grammar Note:  No traditional style type casts.
416 
417 unary_operator
418     : PLUS  { $$ = EOpPositive; }
419     | DASH  { $$ = EOpNegative; }
420     | BANG  { $$ = EOpLogicalNot; }
421     | TILDE {
422         ES3_OR_NEWER("~", @$, "bit-wise operator");
423         $$ = EOpBitwiseNot;
424     }
425     ;
426 // Grammar Note:  No '*' or '&' unary ops.  Pointers are not supported.
427 
428 multiplicative_expression
429     : unary_expression { $$ = $1; }
430     | multiplicative_expression STAR unary_expression {
431         $$ = context->addBinaryMath(EOpMul, $1, $3, @2);
432     }
433     | multiplicative_expression SLASH unary_expression {
434         $$ = context->addBinaryMath(EOpDiv, $1, $3, @2);
435     }
436     | multiplicative_expression PERCENT unary_expression {
437         ES3_OR_NEWER("%", @2, "integer modulus operator");
438         $$ = context->addBinaryMath(EOpIMod, $1, $3, @2);
439     }
440     ;
441 
442 additive_expression
443     : multiplicative_expression { $$ = $1; }
444     | additive_expression PLUS multiplicative_expression {
445         $$ = context->addBinaryMath(EOpAdd, $1, $3, @2);
446     }
447     | additive_expression DASH multiplicative_expression {
448         $$ = context->addBinaryMath(EOpSub, $1, $3, @2);
449     }
450     ;
451 
452 shift_expression
453     : additive_expression { $$ = $1; }
454     | shift_expression LEFT_OP additive_expression {
455         ES3_OR_NEWER("<<", @2, "bit-wise operator");
456         $$ = context->addBinaryMath(EOpBitShiftLeft, $1, $3, @2);
457     }
458     | shift_expression RIGHT_OP additive_expression {
459         ES3_OR_NEWER(">>", @2, "bit-wise operator");
460         $$ = context->addBinaryMath(EOpBitShiftRight, $1, $3, @2);
461     }
462     ;
463 
464 relational_expression
465     : shift_expression { $$ = $1; }
466     | relational_expression LEFT_ANGLE shift_expression {
467         $$ = context->addBinaryMathBooleanResult(EOpLessThan, $1, $3, @2);
468     }
469     | relational_expression RIGHT_ANGLE shift_expression  {
470         $$ = context->addBinaryMathBooleanResult(EOpGreaterThan, $1, $3, @2);
471     }
472     | relational_expression LE_OP shift_expression  {
473         $$ = context->addBinaryMathBooleanResult(EOpLessThanEqual, $1, $3, @2);
474     }
475     | relational_expression GE_OP shift_expression  {
476         $$ = context->addBinaryMathBooleanResult(EOpGreaterThanEqual, $1, $3, @2);
477     }
478     ;
479 
480 equality_expression
481     : relational_expression { $$ = $1; }
482     | equality_expression EQ_OP relational_expression  {
483         $$ = context->addBinaryMathBooleanResult(EOpEqual, $1, $3, @2);
484     }
485     | equality_expression NE_OP relational_expression {
486         $$ = context->addBinaryMathBooleanResult(EOpNotEqual, $1, $3, @2);
487     }
488     ;
489 
490 and_expression
491     : equality_expression { $$ = $1; }
492     | and_expression AMPERSAND equality_expression {
493         ES3_OR_NEWER("&", @2, "bit-wise operator");
494         $$ = context->addBinaryMath(EOpBitwiseAnd, $1, $3, @2);
495     }
496     ;
497 
498 exclusive_or_expression
499     : and_expression { $$ = $1; }
500     | exclusive_or_expression CARET and_expression {
501         ES3_OR_NEWER("^", @2, "bit-wise operator");
502         $$ = context->addBinaryMath(EOpBitwiseXor, $1, $3, @2);
503     }
504     ;
505 
506 inclusive_or_expression
507     : exclusive_or_expression { $$ = $1; }
508     | inclusive_or_expression VERTICAL_BAR exclusive_or_expression {
509         ES3_OR_NEWER("|", @2, "bit-wise operator");
510         $$ = context->addBinaryMath(EOpBitwiseOr, $1, $3, @2);
511     }
512     ;
513 
514 logical_and_expression
515     : inclusive_or_expression { $$ = $1; }
516     | logical_and_expression AND_OP inclusive_or_expression {
517         $$ = context->addBinaryMathBooleanResult(EOpLogicalAnd, $1, $3, @2);
518     }
519     ;
520 
521 logical_xor_expression
522     : logical_and_expression { $$ = $1; }
523     | logical_xor_expression XOR_OP logical_and_expression  {
524         $$ = context->addBinaryMathBooleanResult(EOpLogicalXor, $1, $3, @2);
525     }
526     ;
527 
528 logical_or_expression
529     : logical_xor_expression { $$ = $1; }
530     | logical_or_expression OR_OP logical_xor_expression  {
531         $$ = context->addBinaryMathBooleanResult(EOpLogicalOr, $1, $3, @2);
532     }
533     ;
534 
535 conditional_expression
536     : logical_or_expression { $$ = $1; }
537     | logical_or_expression QUESTION expression COLON assignment_expression {
538         $$ = context->addTernarySelection($1, $3, $5, @2);
539     }
540     ;
541 
542 assignment_expression
543     : conditional_expression { $$ = $1; }
544     | unary_expression assignment_operator assignment_expression {
545         $$ = context->addAssign($2, $1, $3, @2);
546     }
547     ;
548 
549 assignment_operator
550     : EQUAL        { $$ = EOpAssign; }
551     | MUL_ASSIGN   { $$ = EOpMulAssign; }
552     | DIV_ASSIGN   { $$ = EOpDivAssign; }
553     | MOD_ASSIGN   {
554         ES3_OR_NEWER("%=", @$, "integer modulus operator");
555         $$ = EOpIModAssign;
556     }
557     | ADD_ASSIGN   { $$ = EOpAddAssign; }
558     | SUB_ASSIGN   { $$ = EOpSubAssign; }
559     | LEFT_ASSIGN {
560         ES3_OR_NEWER("<<=", @$, "bit-wise operator");
561         $$ = EOpBitShiftLeftAssign;
562     }
563     | RIGHT_ASSIGN {
564         ES3_OR_NEWER(">>=", @$, "bit-wise operator");
565         $$ = EOpBitShiftRightAssign;
566     }
567     | AND_ASSIGN {
568         ES3_OR_NEWER("&=", @$, "bit-wise operator");
569         $$ = EOpBitwiseAndAssign;
570     }
571     | XOR_ASSIGN {
572         ES3_OR_NEWER("^=", @$, "bit-wise operator");
573         $$ = EOpBitwiseXorAssign;
574     }
575     | OR_ASSIGN {
576         ES3_OR_NEWER("|=", @$, "bit-wise operator");
577         $$ = EOpBitwiseOrAssign;
578     }
579     ;
580 
581 expression
582     : assignment_expression {
583         $$ = $1;
584     }
585     | expression COMMA assignment_expression {
586         $$ = context->addComma($1, $3, @2);
587     }
588     ;
589 
590 constant_expression
591     : conditional_expression {
592         context->checkIsConst($1);
593         $$ = $1;
594     }
595     ;
596 
597 enter_struct
598     : IDENTIFIER LEFT_BRACE {
599         context->enterStructDeclaration(@1, ImmutableString($1.string));
600         $$ = $1;
601     }
602     ;
603 
604 declaration
605     : function_prototype SEMICOLON {
606         $$ = context->addFunctionPrototypeDeclaration(*($1.function), @1);
607     }
608     | init_declarator_list SEMICOLON {
609         $$ = $1.intermDeclaration;
610     }
611     | PRECISION precision_qualifier type_specifier_no_prec SEMICOLON {
612         context->parseDefaultPrecisionQualifier($2, $3, @1);
613         $$ = nullptr;
614     }
615     | type_qualifier enter_struct struct_declaration_list RIGHT_BRACE SEMICOLON {
616         ES3_OR_NEWER(ImmutableString($2.string), @1, "interface blocks");
617         $$ = context->addInterfaceBlock(*$1, @2, ImmutableString($2.string), $3, kEmptyImmutableString, @$, NULL, @$);
618     }
619     | type_qualifier enter_struct struct_declaration_list RIGHT_BRACE IDENTIFIER SEMICOLON {
620         ES3_OR_NEWER(ImmutableString($2.string), @1, "interface blocks");
621         $$ = context->addInterfaceBlock(*$1, @2, ImmutableString($2.string), $3, ImmutableString($5.string), @5, NULL, @$);
622     }
623     | type_qualifier enter_struct struct_declaration_list RIGHT_BRACE IDENTIFIER array_specifier SEMICOLON {
624         ES3_OR_NEWER(ImmutableString($2.string), @1, "interface blocks");
625         $$ = context->addInterfaceBlock(*$1, @2, ImmutableString($2.string), $3, ImmutableString($5.string), @5, $6, @6);
626     }
627     | type_qualifier SEMICOLON {
628         context->parseGlobalLayoutQualifier(*$1);
629         $$ = nullptr;
630     }
631     | type_qualifier IDENTIFIER SEMICOLON // e.g. to qualify an existing variable as invariant or precise
632     {
633         $$ = context->parseGlobalQualifierDeclaration(*$1, @2, ImmutableString($2.string), $2.symbol);
634     }
635     ;
636 
637 function_prototype
638     : function_declarator RIGHT_PAREN  {
639         $$.function = context->parseFunctionDeclarator(@2, $1);
640         context->exitFunctionDeclaration();
641     }
642     ;
643 
644 function_declarator
645     : function_header {
646         $$ = $1;
647     }
648     | function_header_with_parameters {
649         $$ = $1;
650     }
651     ;
652 
653 
654 function_header_with_parameters
655     : function_header parameter_declaration {
656         // Add the parameter
657         $$ = $1;
658         if ($2.type.getBasicType() != EbtVoid)
659         {
660             $1->addParameter($2.createVariable(&context->symbolTable));
661         }
662         else
663         {
664             // Remember that void was seen, so error can be generated if another parameter is seen.
665             $1->setHasVoidParameter();
666         }
667     }
668     | function_header_with_parameters COMMA parameter_declaration {
669         $$ = $1;
670         // Only first parameter of one-parameter functions can be void
671         // The check for named parameters not being void is done in parameter_declarator
672         if ($3.type.getBasicType() == EbtVoid)
673         {
674             // This parameter > first is void
675             context->error(@2, "cannot be a parameter type except for '(void)'", "void");
676         }
677         else
678         {
679             if ($1->hasVoidParameter())
680             {
681                 // Only first parameter of one-parameter functions can be void.  This check prevents
682                 // (void, non_void) parameters.
683                 context->error(@2, "cannot be a parameter type except for '(void)'", "void");
684             }
685             $1->addParameter($3.createVariable(&context->symbolTable));
686         }
687     }
688     ;
689 
690 function_header
691     : fully_specified_type IDENTIFIER LEFT_PAREN {
692         $$ = context->parseFunctionHeader($1, ImmutableString($2.string), @2);
693 
694         context->symbolTable.push();
695         context->enterFunctionDeclaration();
696     }
697     ;
698 
699 parameter_declarator
700     // Type + name
701     : type_specifier identifier {
702         $$ = context->parseParameterDeclarator($1, ImmutableString($2.string), @2);
703     }
704     | type_specifier identifier array_specifier {
705         $$ = context->parseParameterArrayDeclarator($1, ImmutableString($2.string), @2, $3, @3);
706     }
707     ;
708 
709 parameter_declaration
710     : type_qualifier parameter_declarator {
711         $$ = $2;
712         context->parseParameterQualifier(@2, *$1, $$.type);
713     }
714     | parameter_declarator {
715         $$ = $1;
716         $$.type.setQualifier(EvqParamIn);
717     }
718     | type_qualifier parameter_type_specifier {
719         $$ = context->parseParameterDeclarator($2, kEmptyImmutableString, @2);
720         context->parseParameterQualifier(@2, *$1, $$.type);
721     }
722     | parameter_type_specifier {
723         $$ = context->parseParameterDeclarator($1, kEmptyImmutableString, @1);
724         $$.type.setQualifier(EvqParamIn);
725     }
726     ;
727 
728 parameter_type_specifier
729     : type_specifier {
730         $$ = $1;
731     }
732     ;
733 
734 init_declarator_list
735     : single_declaration {
736         $$ = $1;
737     }
738     | init_declarator_list COMMA identifier {
739         $$ = $1;
740         context->parseDeclarator($$.type, @3, ImmutableString($3.string), $$.intermDeclaration);
741     }
742     | init_declarator_list COMMA identifier array_specifier {
743         $$ = $1;
744         context->parseArrayDeclarator($$.type, @3, ImmutableString($3.string), @4, *($4), $$.intermDeclaration);
745     }
746     | init_declarator_list COMMA identifier array_specifier EQUAL initializer {
747         ES3_OR_NEWER("=", @5, "first-class arrays (array initializer)");
748         $$ = $1;
749         context->parseArrayInitDeclarator($$.type, @3, ImmutableString($3.string), @4, *($4), @5, $6, $$.intermDeclaration);
750     }
751     | init_declarator_list COMMA identifier EQUAL initializer {
752         $$ = $1;
753         context->parseInitDeclarator($$.type, @3, ImmutableString($3.string), @4, $5, $$.intermDeclaration);
754     }
755     ;
756 
757 single_declaration
758     : fully_specified_type {
759         $$.type = $1;
760         $$.intermDeclaration = context->parseSingleDeclaration($$.type, @1, kEmptyImmutableString);
761     }
762     | fully_specified_type identifier {
763         $$.type = $1;
764         $$.intermDeclaration = context->parseSingleDeclaration($$.type, @2, ImmutableString($2.string));
765     }
766     | fully_specified_type identifier array_specifier {
767         $$.type = $1;
768         $$.intermDeclaration = context->parseSingleArrayDeclaration($$.type, @2, ImmutableString($2.string), @3, *($3));
769     }
770     | fully_specified_type identifier array_specifier EQUAL initializer {
771         ES3_OR_NEWER("[]", @3, "first-class arrays (array initializer)");
772         $$.type = $1;
773         $$.intermDeclaration = context->parseSingleArrayInitDeclaration($$.type, @2, ImmutableString($2.string), @3, *($3), @4, $5);
774     }
775     | fully_specified_type identifier EQUAL initializer {
776         $$.type = $1;
777         $$.intermDeclaration = context->parseSingleInitDeclaration($$.type, @2, ImmutableString($2.string), @3, $4);
778     }
779     ;
780 
781 fully_specified_type
782     : type_specifier {
783         context->addFullySpecifiedType(&$1);
784         $$ = $1;
785     }
786     | type_qualifier type_specifier {
787         $$ = context->addFullySpecifiedType(*$1, $2);
788     }
789     ;
790 
791 interpolation_qualifier
792     : SMOOTH {
793         $$ = EvqSmooth;
794     }
795     | FLAT {
796         $$ = EvqFlat;
797     }
798     | NOPERSPECTIVE {
799         if (!context->checkCanUseExtension(@1, TExtension::NV_shader_noperspective_interpolation))
800         {
801             context->error(@1, "unsupported interpolation qualifier", "noperspective");
802         }
803         $$ = EvqNoPerspective;
804     }
805     ;
806 
807 type_qualifier
808     : single_type_qualifier {
809         $$ = context->createTypeQualifierBuilder(@1);
810         $$->appendQualifier($1);
811     }
812     | type_qualifier single_type_qualifier {
813         $$ = $1;
814         $$->appendQualifier($2);
815     }
816     ;
817 
818 invariant_qualifier
819     : INVARIANT {
820         // empty
821     }
822     ;
823 
824 precise_qualifier
825     : PRECISE {
826         context->markShaderHasPrecise();
827     }
828     ;
829 
830 single_type_qualifier
831     : storage_qualifier {
832         context->checkLocalVariableConstStorageQualifier(*$1);
833         $$ = $1;
834     }
835     | layout_qualifier {
836         context->checkIsAtGlobalLevel(@1, "layout");
837         $$ = new TLayoutQualifierWrapper($1, @1);
838     }
839     | precision_qualifier {
840         $$ = new TPrecisionQualifierWrapper($1, @1);
841     }
842     | interpolation_qualifier {
843         $$ = new TInterpolationQualifierWrapper($1, @1);
844     }
845     | invariant_qualifier {
846         context->checkIsAtGlobalLevel(@1, "invariant");
847         $$ = new TInvariantQualifierWrapper(@1);
848     }
849     | precise_qualifier {
850         $$ = new TPreciseQualifierWrapper(@1);
851     }
852     ;
853 
854 
855 storage_qualifier
856     :
857     ATTRIBUTE {
858         VERTEX_ONLY("attribute", @1);
859         ES2_ONLY("attribute", @1);
860         $$ = context->parseGlobalStorageQualifier(EvqAttribute, @1);
861     }
862     | VARYING {
863         ES2_ONLY("varying", @1);
864         $$ = context->parseVaryingQualifier(@1);
865     }
866     | CONST_QUAL {
867         $$ = new TStorageQualifierWrapper(EvqConst, @1);
868     }
869     | IN_QUAL {
870         $$ = context->parseInQualifier(@1);
871     }
872     | OUT_QUAL {
873         $$ = context->parseOutQualifier(@1);
874     }
875     | INOUT_QUAL {
876         $$ = context->parseInOutQualifier(@1);
877     }
878     | CENTROID {
879         ES3_OR_NEWER("centroid", @1, "storage qualifier");
880         $$ = new TStorageQualifierWrapper(EvqCentroid, @1);
881     }
882     | PATCH {
883         constexpr std::array<TExtension, 2u> extensions{ { TExtension::OES_tessellation_shader,
884                                                            TExtension::EXT_tessellation_shader } };
885         if (context->getShaderVersion() < 320
886         && !context->checkCanUseOneOfExtensions(@1, extensions))
887         {
888             context->error(@1, "unsupported storage qualifier", "patch");
889         }
890         $$ = new TStorageQualifierWrapper(EvqPatch, @1);
891     }
892     | UNIFORM {
893         $$ = context->parseGlobalStorageQualifier(EvqUniform, @1);
894     }
895     | BUFFER {
896         ES3_1_OR_NEWER("buffer", @1, "storage qualifier");
897         $$ = context->parseGlobalStorageQualifier(EvqBuffer, @1);
898     }
899     | READONLY {
900         $$ = new TMemoryQualifierWrapper(EvqReadOnly, @1);
901     }
902     | WRITEONLY {
903         $$ = new TMemoryQualifierWrapper(EvqWriteOnly, @1);
904     }
905     | COHERENT {
906         $$ = new TMemoryQualifierWrapper(EvqCoherent, @1);
907     }
908     | RESTRICT {
909         $$ = new TMemoryQualifierWrapper(EvqRestrict, @1);
910     }
911     | VOLATILE {
912         $$ = new TMemoryQualifierWrapper(EvqVolatile, @1);
913     }
914     | SHARED {
915         COMPUTE_ONLY("shared", @1);
916         $$ = context->parseGlobalStorageQualifier(EvqShared, @1);
917     }
918     | SAMPLE {
919         ES3_OR_NEWER("sample", @1, "storage qualifier");
920         $$ = new TStorageQualifierWrapper(EvqSample, @1);
921     }
922     ;
923 
924 type_specifier
925     : type_specifier_no_prec {
926         $$ = $1;
927         $$.precision = context->symbolTable.getDefaultPrecision($1.getBasicType());
928     }
929     ;
930 
931 precision_qualifier
932     : HIGH_PRECISION {
933         $$ = EbpHigh;
934     }
935     | MEDIUM_PRECISION {
936         $$ = EbpMedium;
937     }
938     | LOW_PRECISION  {
939         $$ = EbpLow;
940     }
941     ;
942 
943 layout_qualifier
944     : LAYOUT LEFT_PAREN layout_qualifier_id_list RIGHT_PAREN {
945         context->checkCanUseLayoutQualifier(@1);
946         $$ = $3;
947     }
948     ;
949 
950 layout_qualifier_id_list
951     : layout_qualifier_id {
952         $$ = $1;
953     }
954     | layout_qualifier_id_list COMMA layout_qualifier_id {
955         $$ = context->joinLayoutQualifiers($1, $3, @3);
956     }
957     ;
958 
959 layout_qualifier_id
960     : IDENTIFIER {
961         $$ = context->parseLayoutQualifier(ImmutableString($1.string), @1);
962     }
963     | IDENTIFIER EQUAL INTCONSTANT {
964         $$ = context->parseLayoutQualifier(ImmutableString($1.string), @1, $3.i, @3);
965     }
966     | IDENTIFIER EQUAL UINTCONSTANT {
967         $$ = context->parseLayoutQualifier(ImmutableString($1.string), @1, $3.i, @3);
968     }
969     | SHARED {
970         $$ = context->parseLayoutQualifier(ImmutableString("shared"), @1);
971     }
972     ;
973 
974 type_specifier_no_prec
975     : type_specifier_nonarray {
976         $$.initialize($1, (context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary));
977     }
978     | type_specifier_nonarray array_specifier {
979         $$.initialize($1, (context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary));
980         $$.setArraySizes($2);
981     }
982     ;
983 
984 array_specifier
985     : LEFT_BRACKET RIGHT_BRACKET {
986         ES3_OR_NEWER("[]", @1, "implicitly sized array");
987         $$ = new TVector<unsigned int>();
988         $$->push_back(0u);
989     }
990     | LEFT_BRACKET constant_expression RIGHT_BRACKET {
991         $$ = new TVector<unsigned int>();
992         unsigned int size = context->checkIsValidArraySize(@1, $2);
993         // Make the type an array even if size check failed.
994         // This ensures useless error messages regarding a variable's non-arrayness won't follow.
995         $$->push_back(size);
996     }
997     | array_specifier LEFT_BRACKET RIGHT_BRACKET {
998         ES3_1_OR_NEWER("[]", @2, "arrays of arrays");
999         $$ = $1;
1000         $$->insert($$->begin(), 0u);
1001         if (!context->checkIsValidArrayDimension(@2, $$)) {
1002             YYABORT;
1003         }
1004     }
1005     | array_specifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
1006         ES3_1_OR_NEWER("[]", @2, "arrays of arrays");
1007         $$ = $1;
1008         unsigned int size = context->checkIsValidArraySize(@2, $3);
1009         // Make the type an array even if size check failed.
1010         // This ensures useless error messages regarding a variable's non-arrayness won't follow.
1011         $$->insert($$->begin(), size);
1012         if (!context->checkIsValidArrayDimension(@2, $$)) {
1013             YYABORT;
1014         }
1015     }
1016     ;
1017 
1018 type_specifier_nonarray
1019     : VOID_TYPE {
1020         $$.initialize(EbtVoid, @1);
1021     }
1022     | FLOAT_TYPE {
1023         $$.initialize(EbtFloat, @1);
1024     }
1025     | INT_TYPE {
1026         $$.initialize(EbtInt, @1);
1027     }
1028     | UINT_TYPE {
1029         $$.initialize(EbtUInt, @1);
1030     }
1031     | BOOL_TYPE {
1032         $$.initialize(EbtBool, @1);
1033     }
1034     | VEC2 {
1035         $$.initialize(EbtFloat, @1);
1036         $$.setAggregate(2);
1037     }
1038     | VEC3 {
1039         $$.initialize(EbtFloat, @1);
1040         $$.setAggregate(3);
1041     }
1042     | VEC4 {
1043         $$.initialize(EbtFloat, @1);
1044         $$.setAggregate(4);
1045     }
1046     | BVEC2 {
1047         $$.initialize(EbtBool, @1);
1048         $$.setAggregate(2);
1049     }
1050     | BVEC3 {
1051         $$.initialize(EbtBool, @1);
1052         $$.setAggregate(3);
1053     }
1054     | BVEC4 {
1055         $$.initialize(EbtBool, @1);
1056         $$.setAggregate(4);
1057     }
1058     | IVEC2 {
1059         $$.initialize(EbtInt, @1);
1060         $$.setAggregate(2);
1061     }
1062     | IVEC3 {
1063         $$.initialize(EbtInt, @1);
1064         $$.setAggregate(3);
1065     }
1066     | IVEC4 {
1067         $$.initialize(EbtInt, @1);
1068         $$.setAggregate(4);
1069     }
1070     | UVEC2 {
1071         $$.initialize(EbtUInt, @1);
1072         $$.setAggregate(2);
1073     }
1074     | UVEC3 {
1075         $$.initialize(EbtUInt, @1);
1076         $$.setAggregate(3);
1077     }
1078     | UVEC4 {
1079         $$.initialize(EbtUInt, @1);
1080         $$.setAggregate(4);
1081     }
1082     | MATRIX2 {
1083         $$.initialize(EbtFloat, @1);
1084         $$.setMatrix(2, 2);
1085     }
1086     | MATRIX3 {
1087         $$.initialize(EbtFloat, @1);
1088         $$.setMatrix(3, 3);
1089     }
1090     | MATRIX4 {
1091         $$.initialize(EbtFloat, @1);
1092         $$.setMatrix(4, 4);
1093     }
1094     | MATRIX2x3 {
1095         $$.initialize(EbtFloat, @1);
1096         $$.setMatrix(2, 3);
1097     }
1098     | MATRIX3x2 {
1099         $$.initialize(EbtFloat, @1);
1100         $$.setMatrix(3, 2);
1101     }
1102     | MATRIX2x4 {
1103         $$.initialize(EbtFloat, @1);
1104         $$.setMatrix(2, 4);
1105     }
1106     | MATRIX4x2 {
1107         $$.initialize(EbtFloat, @1);
1108         $$.setMatrix(4, 2);
1109     }
1110     | MATRIX3x4 {
1111         $$.initialize(EbtFloat, @1);
1112         $$.setMatrix(3, 4);
1113     }
1114     | MATRIX4x3 {
1115         $$.initialize(EbtFloat, @1);
1116         $$.setMatrix(4, 3);
1117     }
1118     | YUVCSCSTANDARDEXT {
1119         if (!context->checkCanUseExtension(@1, TExtension::EXT_YUV_target))
1120         {
1121             context->error(@1, "unsupported type", "yuvCscStandardEXT");
1122         }
1123         $$.initialize(EbtYuvCscStandardEXT, @1);
1124     }
1125     | SAMPLER2D {
1126         $$.initialize(EbtSampler2D, @1);
1127     }
1128     | SAMPLER3D {
1129         $$.initialize(EbtSampler3D, @1);
1130     }
1131     | SAMPLERCUBE {
1132         $$.initialize(EbtSamplerCube, @1);
1133     }
1134     | SAMPLER2DARRAY {
1135         $$.initialize(EbtSampler2DArray, @1);
1136     }
1137     | SAMPLER2DMS {
1138         $$.initialize(EbtSampler2DMS, @1);
1139     }
1140     | SAMPLER2DMSARRAY {
1141         $$.initialize(EbtSampler2DMSArray, @1);
1142     }
1143     | SAMPLERCUBEARRAYOES {
1144         if (context->getShaderVersion() < 320
1145         && !context->checkCanUseExtension(@1, TExtension::OES_texture_cube_map_array))
1146         {
1147             context->error(@1, "unsupported type", "__samplerCubeArray");
1148         }
1149         $$.initialize(EbtSamplerCubeArray, @1);
1150     }
1151     | SAMPLERCUBEARRAYEXT {
1152         if (context->getShaderVersion() < 320
1153         && !context->checkCanUseExtension(@1, TExtension::EXT_texture_cube_map_array))
1154         {
1155             context->error(@1, "unsupported type", "__samplerCubeArray");
1156         }
1157         $$.initialize(EbtSamplerCubeArray, @1);
1158     }
1159     | SAMPLERBUFFER {
1160         constexpr std::array<TExtension, 2u> extensions{ { TExtension::OES_texture_buffer,
1161                                                            TExtension::EXT_texture_buffer } };
1162         if (context->getShaderVersion() < 320
1163         && !context->checkCanUseOneOfExtensions(@1, extensions))
1164         {
1165             context->error(@1, "unsupported type", "__samplerBuffer");
1166         }
1167         $$.initialize(EbtSamplerBuffer, @1);
1168     }
1169     | ISAMPLER2D {
1170         $$.initialize(EbtISampler2D, @1);
1171     }
1172     | ISAMPLER3D {
1173         $$.initialize(EbtISampler3D, @1);
1174     }
1175     | ISAMPLERCUBE {
1176         $$.initialize(EbtISamplerCube, @1);
1177     }
1178     | ISAMPLER2DARRAY {
1179         $$.initialize(EbtISampler2DArray, @1);
1180     }
1181     | ISAMPLER2DMS {
1182         $$.initialize(EbtISampler2DMS, @1);
1183     }
1184     | ISAMPLER2DMSARRAY {
1185         $$.initialize(EbtISampler2DMSArray, @1);
1186     }
1187     | ISAMPLERCUBEARRAYOES {
1188         if (context->getShaderVersion() < 320
1189         && !context->checkCanUseExtension(@1, TExtension::OES_texture_cube_map_array))
1190         {
1191             context->error(@1, "unsupported type", "__isamplerCubeArray");
1192         }
1193         $$.initialize(EbtISamplerCubeArray, @1);
1194     }
1195     | ISAMPLERCUBEARRAYEXT {
1196         if (context->getShaderVersion() < 320
1197         && !context->checkCanUseExtension(@1, TExtension::EXT_texture_cube_map_array))
1198         {
1199             context->error(@1, "unsupported type", "__isamplerCubeArray");
1200         }
1201         $$.initialize(EbtISamplerCubeArray, @1);
1202     }
1203     | ISAMPLERBUFFER {
1204         constexpr std::array<TExtension, 2u> extensions{ { TExtension::OES_texture_buffer,
1205                                                            TExtension::EXT_texture_buffer } };
1206         if (context->getShaderVersion() < 320
1207         && !context->checkCanUseOneOfExtensions(@1, extensions))
1208         {
1209             context->error(@1, "unsupported type", "__isamplerBuffer");
1210         }
1211         $$.initialize(EbtISamplerBuffer, @1);
1212     }
1213     | USAMPLER2D {
1214         $$.initialize(EbtUSampler2D, @1);
1215     }
1216     | USAMPLER3D {
1217         $$.initialize(EbtUSampler3D, @1);
1218     }
1219     | USAMPLERCUBE {
1220         $$.initialize(EbtUSamplerCube, @1);
1221     }
1222     | USAMPLER2DARRAY {
1223         $$.initialize(EbtUSampler2DArray, @1);
1224     }
1225     | USAMPLER2DMS {
1226         $$.initialize(EbtUSampler2DMS, @1);
1227     }
1228     | USAMPLER2DMSARRAY {
1229         $$.initialize(EbtUSampler2DMSArray, @1);
1230     }
1231     | USAMPLERCUBEARRAYOES {
1232         if (context->getShaderVersion() < 320
1233         && !context->checkCanUseExtension(@1, TExtension::OES_texture_cube_map_array))
1234         {
1235             context->error(@1, "unsupported type", "__usamplerCubeArray");
1236         }
1237         $$.initialize(EbtUSamplerCubeArray, @1);
1238     }
1239     | USAMPLERCUBEARRAYEXT {
1240         if (context->getShaderVersion() < 320
1241         && !context->checkCanUseExtension(@1, TExtension::EXT_texture_cube_map_array))
1242         {
1243             context->error(@1, "unsupported type", "__usamplerCubeArray");
1244         }
1245         $$.initialize(EbtUSamplerCubeArray, @1);
1246     }
1247     | USAMPLERBUFFER {
1248         constexpr std::array<TExtension, 2u> extensions{ { TExtension::OES_texture_buffer,
1249                                                            TExtension::EXT_texture_buffer } };
1250         if (context->getShaderVersion() < 320
1251         && !context->checkCanUseOneOfExtensions(@1, extensions))
1252         {
1253             context->error(@1, "unsupported type", "__usamplerBuffer");
1254         }
1255         $$.initialize(EbtUSamplerBuffer, @1);
1256     }
1257     | SAMPLER2DSHADOW {
1258         $$.initialize(EbtSampler2DShadow, @1);
1259     }
1260     | SAMPLERCUBESHADOW {
1261         $$.initialize(EbtSamplerCubeShadow, @1);
1262     }
1263     | SAMPLER2DARRAYSHADOW {
1264         $$.initialize(EbtSampler2DArrayShadow, @1);
1265     }
1266     | SAMPLERCUBEARRAYSHADOWOES {
1267         if (context->getShaderVersion() < 320
1268         && !context->checkCanUseExtension(@1, TExtension::OES_texture_cube_map_array))
1269         {
1270             context->error(@1, "unsupported type", "__samplerCubeArrayShadow");
1271         }
1272         $$.initialize(EbtSamplerCubeArrayShadow, @1);
1273     }
1274     | SAMPLERCUBEARRAYSHADOWEXT {
1275         if (context->getShaderVersion() < 320
1276         && !context->checkCanUseExtension(@1, TExtension::EXT_texture_cube_map_array))
1277         {
1278             context->error(@1, "unsupported type", "__samplerCubeArrayShadow");
1279         }
1280         $$.initialize(EbtSamplerCubeArrayShadow, @1);
1281     }
1282     | SAMPLERVIDEOWEBGL {
1283         if (!context->checkCanUseExtension(@1, TExtension::WEBGL_video_texture))
1284         {
1285             context->error(@1, "unsupported type", "samplerVideoWEBGL");
1286         }
1287         $$.initialize(EbtSamplerVideoWEBGL, @1);
1288     }
1289     | SAMPLER_EXTERNAL_OES {
1290         constexpr std::array<TExtension, 3u> extensions{ { TExtension::NV_EGL_stream_consumer_external,
1291                                                            TExtension::OES_EGL_image_external_essl3,
1292                                                            TExtension::OES_EGL_image_external } };
1293         if (!context->checkCanUseOneOfExtensions(@1, extensions))
1294         {
1295             context->error(@1, "unsupported type", "samplerExternalOES");
1296         }
1297         $$.initialize(EbtSamplerExternalOES, @1);
1298     }
1299     | SAMPLEREXTERNAL2DY2YEXT {
1300         if (!context->checkCanUseExtension(@1, TExtension::EXT_YUV_target))
1301         {
1302             context->error(@1, "unsupported type", "__samplerExternal2DY2YEXT");
1303         }
1304         $$.initialize(EbtSamplerExternal2DY2YEXT, @1);
1305     }
1306     | SAMPLER2DRECT {
1307         if (!context->checkCanUseExtension(@1, TExtension::ARB_texture_rectangle))
1308         {
1309             context->error(@1, "unsupported type", "sampler2DRect");
1310         }
1311         $$.initialize(EbtSampler2DRect, @1);
1312     }
1313     | IMAGE2D {
1314         $$.initialize(EbtImage2D, @1);
1315     }
1316     | IIMAGE2D {
1317         $$.initialize(EbtIImage2D, @1);
1318     }
1319     | UIMAGE2D {
1320         $$.initialize(EbtUImage2D, @1);
1321     }
1322     | IMAGE3D {
1323         $$.initialize(EbtImage3D, @1);
1324     }
1325     | IIMAGE3D {
1326         $$.initialize(EbtIImage3D, @1);
1327     }
1328     | UIMAGE3D {
1329         $$.initialize(EbtUImage3D, @1);
1330     }
1331     | IMAGE2DARRAY {
1332         $$.initialize(EbtImage2DArray, @1);
1333     }
1334     | IIMAGE2DARRAY {
1335         $$.initialize(EbtIImage2DArray, @1);
1336     }
1337     | UIMAGE2DARRAY {
1338         $$.initialize(EbtUImage2DArray, @1);
1339     }
1340     | IMAGECUBE {
1341         $$.initialize(EbtImageCube, @1);
1342     }
1343     | IIMAGECUBE {
1344         $$.initialize(EbtIImageCube, @1);
1345     }
1346     | UIMAGECUBE {
1347         $$.initialize(EbtUImageCube, @1);
1348     }
1349     | IMAGECUBEARRAYOES {
1350         if (context->getShaderVersion() < 320
1351         && !context->checkCanUseExtension(@1, TExtension::OES_texture_cube_map_array))
1352         {
1353             context->error(@1, "unsupported type", "__imageCubeArray");
1354         }
1355         $$.initialize(EbtImageCubeArray, @1);
1356     }
1357     | IMAGECUBEARRAYEXT {
1358         if (context->getShaderVersion() < 320
1359         && !context->checkCanUseExtension(@1, TExtension::EXT_texture_cube_map_array))
1360         {
1361             context->error(@1, "unsupported type", "__imageCubeArray");
1362         }
1363         $$.initialize(EbtImageCubeArray, @1);
1364     }
1365     | IIMAGECUBEARRAYOES {
1366         if (context->getShaderVersion() < 320
1367         && !context->checkCanUseExtension(@1, TExtension::OES_texture_cube_map_array))
1368         {
1369             context->error(@1, "unsupported type", "__iimageCubeArray");
1370         }
1371         $$.initialize(EbtIImageCubeArray, @1);
1372     }
1373     | IIMAGECUBEARRAYEXT {
1374         if (context->getShaderVersion() < 320
1375         && !context->checkCanUseExtension(@1, TExtension::EXT_texture_cube_map_array))
1376         {
1377             context->error(@1, "unsupported type", "__iimageCubeArray");
1378         }
1379         $$.initialize(EbtIImageCubeArray, @1);
1380     }
1381     | UIMAGECUBEARRAYOES {
1382        if (context->getShaderVersion() < 320
1383        && !context->checkCanUseExtension(@1, TExtension::OES_texture_cube_map_array))
1384         {
1385             context->error(@1, "unsupported type", "__uimageCubeArray");
1386         }
1387         $$.initialize(EbtUImageCubeArray, @1);
1388     }
1389     | UIMAGECUBEARRAYEXT {
1390        if (context->getShaderVersion() < 320
1391        && !context->checkCanUseExtension(@1, TExtension::EXT_texture_cube_map_array))
1392         {
1393             context->error(@1, "unsupported type", "__uimageCubeArray");
1394         }
1395         $$.initialize(EbtUImageCubeArray, @1);
1396     }
1397     | IMAGEBUFFER {
1398         constexpr std::array<TExtension, 2u> extensions{ { TExtension::OES_texture_buffer,
1399                                                            TExtension::EXT_texture_buffer } };
1400         if (context->getShaderVersion() < 320
1401         && !context->checkCanUseOneOfExtensions(@1, extensions))
1402         {
1403             context->error(@1, "unsupported type", "__imageBuffer");
1404         }
1405         $$.initialize(EbtImageBuffer, @1);
1406     }
1407     | IIMAGEBUFFER {
1408         constexpr std::array<TExtension, 2u> extensions{ { TExtension::OES_texture_buffer,
1409                                                            TExtension::EXT_texture_buffer } };
1410         if (context->getShaderVersion() < 320
1411         && !context->checkCanUseOneOfExtensions(@1, extensions))
1412         {
1413             context->error(@1, "unsupported type", "__iimageBuffer");
1414         }
1415         $$.initialize(EbtIImageBuffer, @1);
1416     }
1417     | UIMAGEBUFFER {
1418         constexpr std::array<TExtension, 2u> extensions{ { TExtension::OES_texture_buffer,
1419                                                            TExtension::EXT_texture_buffer } };
1420         if (context->getShaderVersion() < 320
1421         && !context->checkCanUseOneOfExtensions(@1, extensions))
1422         {
1423             context->error(@1, "unsupported type", "__uimageBuffer");
1424         }
1425         $$.initialize(EbtUImageBuffer, @1);
1426     }
1427     | ATOMICUINT {
1428         $$.initialize(EbtAtomicCounter, @1);
1429     }
1430     | PIXELLOCALANGLE {
1431         if (!context->checkCanUseExtension(@1, TExtension::ANGLE_shader_pixel_local_storage))
1432         {
1433             context->error(@1, "unsupported type", "__pixelLocalANGLE");
1434         }
1435         $$.initialize(EbtPixelLocalANGLE, @1);
1436     }
1437     | IPIXELLOCALANGLE {
1438         if (!context->checkCanUseExtension(@1, TExtension::ANGLE_shader_pixel_local_storage))
1439         {
1440             context->error(@1, "unsupported type", "__ipixelLocalANGLE");
1441         }
1442         $$.initialize(EbtIPixelLocalANGLE, @1);
1443     }
1444     | UPIXELLOCALANGLE {
1445         if (!context->checkCanUseExtension(@1, TExtension::ANGLE_shader_pixel_local_storage))
1446         {
1447             context->error(@1, "unsupported type", "__upixelLocalANGLE");
1448         }
1449         $$.initialize(EbtUPixelLocalANGLE, @1);
1450     }
1451     | struct_specifier {
1452         $$ = $1;
1453     }
1454     | TYPE_NAME {
1455         // This is for user defined type names. The lexical phase looked up the type.
1456         const TStructure *structure = static_cast<const TStructure*>($1.symbol);
1457         // Temporary check until VK and Metal backends support type name like gl_DepthRangeParameters.
1458         context->checkIsNotReserved(@1, ImmutableString($1.string));
1459         $$.initializeStruct(structure, false, @1);
1460     }
1461     ;
1462 
1463 struct_specifier
1464     : STRUCT identifier LEFT_BRACE { context->enterStructDeclaration(@2, ImmutableString($2.string)); } struct_declaration_list RIGHT_BRACE {
1465         $$ = context->addStructure(@1, @2, ImmutableString($2.string), $5);
1466     }
1467     | STRUCT LEFT_BRACE { context->enterStructDeclaration(@2, kEmptyImmutableString); } struct_declaration_list RIGHT_BRACE {
1468         $$ = context->addStructure(@1, @$, kEmptyImmutableString, $4);
1469     }
1470     ;
1471 
1472 struct_declaration_list
1473     : struct_declaration {
1474         $$ = context->addStructFieldList($1, @1);
1475     }
1476     | struct_declaration_list struct_declaration {
1477         $$ = context->combineStructFieldLists($1, $2, @2);
1478     }
1479     ;
1480 
1481 struct_declaration
1482     : type_specifier struct_declarator_list SEMICOLON {
1483         $$ = context->addStructDeclaratorList($1, $2);
1484     }
1485     | type_qualifier type_specifier struct_declarator_list SEMICOLON {
1486         // ES3 Only, but errors should be handled elsewhere
1487         $$ = context->addStructDeclaratorListWithQualifiers(*$1, &$2, $3);
1488     }
1489     ;
1490 
1491 struct_declarator_list
1492     : struct_declarator {
1493         $$ = new TDeclaratorList();
1494         $$->push_back($1);
1495     }
1496     | struct_declarator_list COMMA struct_declarator {
1497         $$->push_back($3);
1498     }
1499     ;
1500 
1501 struct_declarator
1502     : identifier {
1503         $$ = context->parseStructDeclarator(ImmutableString($1.string), @1);
1504     }
1505     | identifier array_specifier {
1506         $$ = context->parseStructArrayDeclarator(ImmutableString($1.string), @1, $2);
1507     }
1508     ;
1509 
1510 initializer
1511     : assignment_expression { $$ = $1; }
1512     ;
1513 
1514 declaration_statement
1515     : declaration { $$ = $1; }
1516     ;
1517 
1518 statement
1519     : compound_statement_with_scope { $$ = $1; }
1520     | simple_statement              { $$ = $1; }
1521     ;
1522 
1523 // Grammar Note:  Labeled statements for SWITCH only; 'goto' is not supported.
1524 
1525 simple_statement
1526     : declaration_statement { $$ = $1; }
1527     | expression_statement  { $$ = $1; }
1528     | selection_statement   { $$ = $1; }
1529     | switch_statement      { $$ = $1; }
1530     | case_label            { $$ = $1; }
1531     | iteration_statement   { $$ = $1; }
1532     | jump_statement        { $$ = $1; }
1533     ;
1534 
1535 compound_statement_with_scope
1536     : LEFT_BRACE RIGHT_BRACE {
1537         $$ = new TIntermBlock();
1538         $$->setLine(@$);
1539     }
1540     | LEFT_BRACE { context->symbolTable.push(); } statement_list { context->symbolTable.pop(); } RIGHT_BRACE {
1541         $3->setLine(@$);
1542         $$ = $3;
1543     }
1544     ;
1545 
1546 statement_no_new_scope
1547     : compound_statement_no_new_scope { $$ = $1; }
1548     | simple_statement                { $$ = $1; }
1549     ;
1550 
1551 statement_with_scope
1552     : { context->symbolTable.push(); } compound_statement_no_new_scope { context->symbolTable.pop(); $$ = $2; }
1553     | { context->symbolTable.push(); } simple_statement                { context->symbolTable.pop(); $$ = $2; }
1554     ;
1555 
1556 compound_statement_no_new_scope
1557     // Statement that doesn't create a new scope for iteration_statement, function definition (scope is created for parameters)
1558     : LEFT_BRACE RIGHT_BRACE {
1559         $$ = new TIntermBlock();
1560         $$->setLine(@$);
1561     }
1562     | LEFT_BRACE statement_list RIGHT_BRACE {
1563         $2->setLine(@$);
1564         $$ = $2;
1565     }
1566     ;
1567 
1568 statement_list
1569     : statement {
1570         $$ = new TIntermBlock();
1571         context->appendStatement($$, $1);
1572     }
1573     | statement_list statement {
1574         $$ = $1;
1575         context->appendStatement($$, $2);
1576     }
1577     ;
1578 
1579 expression_statement
1580     : SEMICOLON  { $$ = context->addEmptyStatement(@$); }
1581     | expression SEMICOLON  {
1582         context->checkIsValidExpressionStatement(@$, $1);
1583         $$ = $1;
1584     }
1585     ;
1586 
1587 selection_statement
1588     : IF LEFT_PAREN expression RIGHT_PAREN selection_rest_statement {
1589         $$ = context->addIfElse($3, $5, @1);
1590     }
1591     ;
1592 
1593 selection_rest_statement
1594     : statement_with_scope ELSE statement_with_scope {
1595         $$.node1 = $1;
1596         $$.node2 = $3;
1597     }
1598     | statement_with_scope {
1599         $$.node1 = $1;
1600         $$.node2 = nullptr;
1601     }
1602     ;
1603 
1604 // Note that we've diverged from the spec grammar here a bit for the sake of simplicity.
1605 // We're reusing compound_statement_with_scope instead of having separate rules for switch.
1606 switch_statement
1607     : SWITCH LEFT_PAREN expression RIGHT_PAREN { context->incrSwitchNestingLevel(@1); } compound_statement_with_scope {
1608         $$ = context->addSwitch($3, $6, @1);
1609         context->decrSwitchNestingLevel();
1610     }
1611     ;
1612 
1613 case_label
1614     : CASE constant_expression COLON {
1615         $$ = context->addCase($2, @1);
1616     }
1617     | DEFAULT COLON {
1618         $$ = context->addDefault(@1);
1619     }
1620     ;
1621 
1622 condition
1623     : expression {
1624         $$ = $1;
1625         context->checkIsScalarBool($1->getLine(), $1);
1626     }
1627     | fully_specified_type identifier EQUAL initializer {
1628         $$ = context->addConditionInitializer($1, ImmutableString($2.string), $4, @2);
1629     }
1630     ;
1631 
1632 iteration_statement
1633     : WHILE LEFT_PAREN { context->symbolTable.push(); context->incrLoopNestingLevel(@1); } condition RIGHT_PAREN statement_no_new_scope {
1634         context->symbolTable.pop();
1635         $$ = context->addLoop(ELoopWhile, 0, $4, 0, $6, @1);
1636         context->decrLoopNestingLevel();
1637     }
1638     | DO { context->incrLoopNestingLevel(@1); } statement_with_scope WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON {
1639         $$ = context->addLoop(ELoopDoWhile, 0, $6, 0, $3, @4);
1640         context->decrLoopNestingLevel();
1641     }
1642     | FOR LEFT_PAREN { context->symbolTable.push(); context->incrLoopNestingLevel(@1); } for_init_statement for_rest_statement RIGHT_PAREN statement_no_new_scope {
1643         context->symbolTable.pop();
1644         $$ = context->addLoop(ELoopFor, $4, $5.node1, reinterpret_cast<TIntermTyped*>($5.node2), $7, @1);
1645         context->decrLoopNestingLevel();
1646     }
1647     ;
1648 
1649 for_init_statement
1650     : expression_statement {
1651         $$ = $1;
1652     }
1653     | declaration_statement {
1654         $$ = $1;
1655     }
1656     ;
1657 
1658 conditionopt
1659     : condition {
1660         $$ = $1;
1661     }
1662     | /* May be null */ {
1663         $$ = nullptr;
1664     }
1665     ;
1666 
1667 for_rest_statement
1668     : conditionopt SEMICOLON {
1669         $$.node1 = $1;
1670         $$.node2 = 0;
1671     }
1672     | conditionopt SEMICOLON expression  {
1673         $$.node1 = $1;
1674         $$.node2 = $3;
1675     }
1676     ;
1677 
1678 jump_statement
1679     : CONTINUE SEMICOLON {
1680         $$ = context->addBranch(EOpContinue, @1);
1681     }
1682     | BREAK SEMICOLON {
1683         $$ = context->addBranch(EOpBreak, @1);
1684     }
1685     | RETURN SEMICOLON {
1686         $$ = context->addBranch(EOpReturn, @1);
1687     }
1688     | RETURN expression SEMICOLON {
1689         $$ = context->addBranch(EOpReturn, $2, @1);
1690     }
1691     | DISCARD SEMICOLON {
1692         $$ = context->addBranch(EOpKill, @1);
1693     }
1694     ;
1695 
1696 // Grammar Note:  No 'goto'.  Gotos are not supported.
1697 
1698 translation_unit
1699     : external_declaration {
1700         $$ = new TIntermBlock();
1701         $$->setLine(@$);
1702         $$->appendStatement($1);
1703         context->setTreeRoot($$);
1704     }
1705     | translation_unit external_declaration {
1706         $$->appendStatement($2);
1707     }
1708     ;
1709 
1710 external_declaration
1711     : function_definition {
1712         $$ = $1;
1713     }
1714     | declaration {
1715         $$ = $1;
1716     }
1717     ;
1718 
1719 function_definition
1720     : function_prototype {
1721         context->parseFunctionDefinitionHeader(@1, $1.function, &($1.intermFunctionPrototype));
1722     }
1723     compound_statement_no_new_scope {
1724         $$ = context->addFunctionDefinition($1.intermFunctionPrototype, $3, @1);
1725     }
1726     ;
1727 
1728 %%
1729 
1730 int glslang_parse(TParseContext* context) {
1731     return yyparse(context, context->getScanner());
1732 }
1733