blob: 8ebf2d1f641568bb6d61e98227fe462f20042e84 [file] [log] [blame]
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001/*
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002//
Nicolas Capens44cc79f2014-01-03 10:57:22 -05003// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004// Use of this source code is governed by a BSD-style license that can be
5// found in the LICENSE file.
6//
7
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00008This file contains the Yacc grammar for GLSL ES.
9Based on ANSI C Yacc grammar:
10http://www.lysator.liu.se/c/ANSI-C-grammar-y.html
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000011
alokp@chromium.org75fe6b72011-08-14 05:31:22 +000012IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh,
alokp@chromium.org044a5cf2010-11-12 15:42:16 +000013WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h).
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000014*/
15
alokp@chromium.org044a5cf2010-11-12 15:42:16 +000016%{
17//
Jamie Madill5c55caf2014-02-18 15:27:18 -050018// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
alokp@chromium.org044a5cf2010-11-12 15:42:16 +000019// Use of this source code is governed by a BSD-style license that can be
20// found in the LICENSE file.
21//
22
alokp@chromium.org75fe6b72011-08-14 05:31:22 +000023// This file is auto-generated by generate_parser.sh. DO NOT EDIT!
alokp@chromium.org044a5cf2010-11-12 15:42:16 +000024
apatrick@chromium.org536888b2012-01-25 02:10:25 +000025// Ignore errors in auto-generated code.
26#if defined(__GNUC__)
apatrick@chromium.orga1d80592012-01-25 21:52:10 +000027#pragma GCC diagnostic ignored "-Wunused-function"
apatrick@chromium.org536888b2012-01-25 02:10:25 +000028#pragma GCC diagnostic ignored "-Wunused-variable"
apatrick@chromium.orge057c5d2012-01-26 19:18:24 +000029#pragma GCC diagnostic ignored "-Wswitch-enum"
apatrick@chromium.org536888b2012-01-25 02:10:25 +000030#elif defined(_MSC_VER)
31#pragma warning(disable: 4065)
apatrick@chromium.orga1d80592012-01-25 21:52:10 +000032#pragma warning(disable: 4189)
33#pragma warning(disable: 4505)
34#pragma warning(disable: 4701)
apatrick@chromium.org536888b2012-01-25 02:10:25 +000035#endif
36
Geoff Lang17732822013-08-29 13:46:49 -040037#include "compiler/translator/SymbolTable.h"
Jamie Madill6b9cb252013-10-17 10:45:47 -040038#include "compiler/translator/ParseContext.h"
alokp@chromium.orgea0e1af2010-03-22 19:33:14 +000039#include "GLSLANG/ShaderLang.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000040
daniel@transgaming.comb3077d02013-01-11 04:12:09 +000041#define YYENABLE_NLS 0
daniel@transgaming.comb3077d02013-01-11 04:12:09 +000042
alokp@chromium.org044a5cf2010-11-12 15:42:16 +000043#define YYLEX_PARAM context->scanner
alokp@chromium.org044a5cf2010-11-12 15:42:16 +000044
shannonwoods@chromium.org5668c5d2013-05-30 00:11:48 +000045%}
alokp@chromium.org044a5cf2010-11-12 15:42:16 +000046%expect 1 /* One shift reduce conflict because of if | else */
47%pure-parser
48%parse-param {TParseContext* context}
Jamie Madill075edd82013-07-08 13:30:19 -040049%locations
50
51%code requires {
52#define YYLTYPE TSourceLoc
53#define YYLTYPE_IS_DECLARED 1
54}
alokp@chromium.org044a5cf2010-11-12 15:42:16 +000055
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000056%union {
57 struct {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000058 union {
59 TString *string;
60 float f;
61 int i;
shannonwoods@chromium.orgc8100b82013-05-30 00:20:34 +000062 unsigned int u;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000063 bool b;
64 };
65 TSymbol* symbol;
66 } lex;
67 struct {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000068 TOperator op;
69 union {
70 TIntermNode* intermNode;
71 TIntermNodePair nodePair;
72 TIntermTyped* intermTypedNode;
73 TIntermAggregate* intermAggregate;
74 };
75 union {
76 TPublicType type;
77 TPrecision precision;
Jamie Madilla5efff92013-06-06 11:56:47 -040078 TLayoutQualifier layoutQualifier;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000079 TQualifier qualifier;
80 TFunction* function;
81 TParameter param;
Jamie Madill98493dd2013-07-08 14:39:03 -040082 TField* field;
83 TFieldList* fieldList;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000084 };
85 } interm;
86}
87
88%{
Alok Priyadarshi0b67bfb2013-09-23 14:56:59 -040089extern int yylex(YYSTYPE* yylval, YYLTYPE* yylloc, void* yyscanner);
Jamie Madill075edd82013-07-08 13:30:19 -040090extern void yyerror(YYLTYPE* yylloc, TParseContext* context, const char* reason);
91
92#define YYLLOC_DEFAULT(Current, Rhs, N) \
93 do { \
94 if (YYID(N)) { \
95 (Current).first_file = YYRHSLOC(Rhs, 1).first_file; \
96 (Current).first_line = YYRHSLOC(Rhs, 1).first_line; \
97 (Current).last_file = YYRHSLOC(Rhs, N).last_file; \
98 (Current).last_line = YYRHSLOC(Rhs, N).last_line; \
99 } \
100 else { \
101 (Current).first_file = YYRHSLOC(Rhs, 0).last_file; \
102 (Current).first_line = YYRHSLOC(Rhs, 0).last_line; \
103 (Current).last_file = YYRHSLOC(Rhs, 0).last_file; \
104 (Current).last_line = YYRHSLOC(Rhs, 0).last_line; \
105 } \
106 } while (0)
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000107
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000108#define VERTEX_ONLY(S, L) { \
109 if (context->shaderType != SH_VERTEX_SHADER) { \
maxvujovic@gmail.comc6b3b3c2012-06-27 22:49:39 +0000110 context->error(L, " supported in vertex shaders only ", S); \
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000111 context->recover(); \
112 } \
113}
114
115#define FRAG_ONLY(S, L) { \
116 if (context->shaderType != SH_FRAGMENT_SHADER) { \
maxvujovic@gmail.comc6b3b3c2012-06-27 22:49:39 +0000117 context->error(L, " supported in fragment shaders only ", S); \
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000118 context->recover(); \
119 } \
120}
shannon.woods%transgaming.com@gtempaccount.com5524db02013-04-13 03:38:16 +0000121
122#define ES2_ONLY(S, L) { \
123 if (context->shaderVersion != 100) { \
124 context->error(L, " supported in GLSL ES 1.00 only ", S); \
125 context->recover(); \
126 } \
127}
128
shannonwoods@chromium.org5668c5d2013-05-30 00:11:48 +0000129#define ES3_ONLY(TOKEN, LINE, REASON) { \
shannon.woods%transgaming.com@gtempaccount.com5524db02013-04-13 03:38:16 +0000130 if (context->shaderVersion != 300) { \
shannonwoods@chromium.org5668c5d2013-05-30 00:11:48 +0000131 context->error(LINE, REASON " supported in GLSL ES 3.00 only ", TOKEN); \
shannon.woods%transgaming.com@gtempaccount.com5524db02013-04-13 03:38:16 +0000132 context->recover(); \
133 } \
134}
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000135%}
136
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000137%token <lex> INVARIANT HIGH_PRECISION MEDIUM_PRECISION LOW_PRECISION PRECISION
shannonwoods@chromium.org6b709912013-05-30 00:20:04 +0000138%token <lex> ATTRIBUTE CONST_QUAL BOOL_TYPE FLOAT_TYPE INT_TYPE UINT_TYPE
shannon.woods%transgaming.com@gtempaccount.com5524db02013-04-13 03:38:16 +0000139%token <lex> BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN SWITCH CASE DEFAULT
shannonwoods@chromium.org8c788e82013-05-30 00:20:21 +0000140%token <lex> BVEC2 BVEC3 BVEC4 IVEC2 IVEC3 IVEC4 VEC2 VEC3 VEC4 UVEC2 UVEC3 UVEC4
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000141%token <lex> MATRIX2 MATRIX3 MATRIX4 IN_QUAL OUT_QUAL INOUT_QUAL UNIFORM VARYING
shannonwoods@chromium.org9bd22fa2013-05-30 00:18:47 +0000142%token <lex> MATRIX2x3 MATRIX3x2 MATRIX2x4 MATRIX4x2 MATRIX3x4 MATRIX4x3
shannon.woods%transgaming.com@gtempaccount.com5524db02013-04-13 03:38:16 +0000143%token <lex> CENTROID FLAT SMOOTH
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000144%token <lex> STRUCT VOID_TYPE WHILE
Nicolas Capensfc2e6b92013-06-24 16:13:26 -0400145%token <lex> SAMPLER2D SAMPLERCUBE SAMPLER_EXTERNAL_OES SAMPLER2DRECT SAMPLER2DARRAY
146%token <lex> ISAMPLER2D ISAMPLER3D ISAMPLERCUBE ISAMPLER2DARRAY
147%token <lex> USAMPLER2D USAMPLER3D USAMPLERCUBE USAMPLER2DARRAY
Nicolas Capens2a1d8a32013-07-18 11:49:40 -0400148%token <lex> SAMPLER3D SAMPLER3DRECT SAMPLER2DSHADOW SAMPLERCUBESHADOW SAMPLER2DARRAYSHADOW
shannonwoods@chromium.org302adfe2013-05-30 00:21:06 +0000149%token <lex> LAYOUT
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000150
shannonwoods@chromium.orgc8100b82013-05-30 00:20:34 +0000151%token <lex> IDENTIFIER TYPE_NAME FLOATCONSTANT INTCONSTANT UINTCONSTANT BOOLCONSTANT
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000152%token <lex> FIELD_SELECTION
153%token <lex> LEFT_OP RIGHT_OP
154%token <lex> INC_OP DEC_OP LE_OP GE_OP EQ_OP NE_OP
155%token <lex> AND_OP OR_OP XOR_OP MUL_ASSIGN DIV_ASSIGN ADD_ASSIGN
156%token <lex> MOD_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN XOR_ASSIGN OR_ASSIGN
157%token <lex> SUB_ASSIGN
158
159%token <lex> LEFT_PAREN RIGHT_PAREN LEFT_BRACKET RIGHT_BRACKET LEFT_BRACE RIGHT_BRACE DOT
160%token <lex> COMMA COLON EQUAL SEMICOLON BANG DASH TILDE PLUS STAR SLASH PERCENT
161%token <lex> LEFT_ANGLE RIGHT_ANGLE VERTICAL_BAR CARET AMPERSAND QUESTION
162
Jamie Madill78eb5df2013-05-24 16:34:05 -0400163%type <lex> identifier
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000164%type <interm> assignment_operator unary_operator
165%type <interm.intermTypedNode> variable_identifier primary_expression postfix_expression
166%type <interm.intermTypedNode> expression integer_expression assignment_expression
167%type <interm.intermTypedNode> unary_expression multiplicative_expression additive_expression
168%type <interm.intermTypedNode> relational_expression equality_expression
169%type <interm.intermTypedNode> conditional_expression constant_expression
170%type <interm.intermTypedNode> logical_or_expression logical_xor_expression logical_and_expression
171%type <interm.intermTypedNode> shift_expression and_expression exclusive_or_expression inclusive_or_expression
172%type <interm.intermTypedNode> function_call initializer condition conditionopt
173
174%type <interm.intermNode> translation_unit function_definition
175%type <interm.intermNode> statement simple_statement
176%type <interm.intermAggregate> statement_list compound_statement
177%type <interm.intermNode> declaration_statement selection_statement expression_statement
178%type <interm.intermNode> declaration external_declaration
179%type <interm.intermNode> for_init_statement compound_statement_no_new_scope
180%type <interm.nodePair> selection_rest_statement for_rest_statement
daniel@transgaming.com83dc5a72012-03-09 21:57:07 +0000181%type <interm.intermNode> iteration_statement jump_statement statement_no_new_scope statement_with_scope
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000182%type <interm> single_declaration init_declarator_list
183
184%type <interm> parameter_declaration parameter_declarator parameter_type_specifier
shannon.woods%transgaming.com@gtempaccount.com2226e042013-04-13 03:38:26 +0000185%type <interm.qualifier> parameter_qualifier parameter_type_qualifier
Jamie Madilla5efff92013-06-06 11:56:47 -0400186%type <interm.layoutQualifier> layout_qualifier layout_qualifier_id_list layout_qualifier_id
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000187
188%type <interm.precision> precision_qualifier
shannon.woods%transgaming.com@gtempaccount.com6f273e32013-04-13 03:41:15 +0000189%type <interm.type> type_qualifier fully_specified_type type_specifier storage_qualifier interpolation_qualifier
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000190%type <interm.type> type_specifier_no_prec type_specifier_nonarray
191%type <interm.type> struct_specifier
Jamie Madill98493dd2013-07-08 14:39:03 -0400192%type <interm.field> struct_declarator
193%type <interm.fieldList> struct_declarator_list struct_declaration struct_declaration_list
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000194%type <interm.function> function_header function_declarator function_identifier
195%type <interm.function> function_header_with_parameters function_call_header
196%type <interm> function_call_header_with_parameters function_call_header_no_parameters function_call_generic function_prototype
197%type <interm> function_call_or_method
198
shannonwoods@chromium.org5668c5d2013-05-30 00:11:48 +0000199%type <lex> enter_struct
200
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000201%start translation_unit
202%%
203
Jamie Madill78eb5df2013-05-24 16:34:05 -0400204identifier
205 : IDENTIFIER
206 | TYPE_NAME
207
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000208variable_identifier
209 : IDENTIFIER {
210 // The symbol table search was done in the lexical phase
Nicolas Capens44cc79f2014-01-03 10:57:22 -0500211 const TSymbol *symbol = $1.symbol;
212 const TVariable *variable = 0;
213
214 if (!symbol)
215 {
Jamie Madill075edd82013-07-08 13:30:19 -0400216 context->error(@1, "undeclared identifier", $1.string->c_str());
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000217 context->recover();
Nicolas Capens44cc79f2014-01-03 10:57:22 -0500218 }
219 else if (!symbol->isVariable())
220 {
221 context->error(@1, "variable expected", $1.string->c_str());
222 context->recover();
223 }
224 else
225 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000226 variable = static_cast<const TVariable*>(symbol);
Jamie Madill2aeb26a2013-07-08 14:02:55 -0400227
Nicolas Capensaaaec132013-07-18 11:23:57 -0400228 if (context->symbolTable.findBuiltIn(variable->getName(), context->shaderVersion) &&
Jamie Madill2aeb26a2013-07-08 14:02:55 -0400229 !variable->getExtension().empty() &&
Nicolas Capens44cc79f2014-01-03 10:57:22 -0500230 context->extensionErrorCheck(@1, variable->getExtension()))
231 {
Jamie Madill2aeb26a2013-07-08 14:02:55 -0400232 context->recover();
233 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000234 }
235
Nicolas Capens44cc79f2014-01-03 10:57:22 -0500236 if (!variable)
237 {
238 TType type(EbtFloat, EbpUndefined);
239 TVariable *fakeVariable = new TVariable($1.string, type);
240 context->symbolTable.declare(*fakeVariable);
241 variable = fakeVariable;
242 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000243
Nicolas Capens44cc79f2014-01-03 10:57:22 -0500244 if (variable->getType().getQualifier() == EvqConst)
245 {
alokp@chromium.org256b7512010-05-05 16:51:49 +0000246 ConstantUnion* constArray = variable->getConstPointer();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000247 TType t(variable->getType());
Jamie Madill075edd82013-07-08 13:30:19 -0400248 $$ = context->intermediate.addConstantUnion(constArray, t, @1);
Nicolas Capens44cc79f2014-01-03 10:57:22 -0500249 }
250 else
251 {
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000252 $$ = context->intermediate.addSymbol(variable->getUniqueId(),
Nicolas Capens44cc79f2014-01-03 10:57:22 -0500253 variable->getName(),
254 variable->getType(),
255 @1);
256 }
257
258 // don't delete $1.string, it's used by error recovery, and the pool
259 // pop will reclaim the memory
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000260 }
261 ;
262
263primary_expression
264 : variable_identifier {
265 $$ = $1;
266 }
267 | INTCONSTANT {
alokp@chromium.org256b7512010-05-05 16:51:49 +0000268 ConstantUnion *unionArray = new ConstantUnion[1];
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000269 unionArray->setIConst($1.i);
Jamie Madill075edd82013-07-08 13:30:19 -0400270 $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), @1);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000271 }
shannonwoods@chromium.orgc8100b82013-05-30 00:20:34 +0000272 | UINTCONSTANT {
273 ConstantUnion *unionArray = new ConstantUnion[1];
274 unionArray->setUConst($1.u);
Jamie Madill075edd82013-07-08 13:30:19 -0400275 $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtUInt, EbpUndefined, EvqConst), @1);
shannonwoods@chromium.orgc8100b82013-05-30 00:20:34 +0000276 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000277 | FLOATCONSTANT {
alokp@chromium.org256b7512010-05-05 16:51:49 +0000278 ConstantUnion *unionArray = new ConstantUnion[1];
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000279 unionArray->setFConst($1.f);
Jamie Madill075edd82013-07-08 13:30:19 -0400280 $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConst), @1);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000281 }
282 | BOOLCONSTANT {
alokp@chromium.org256b7512010-05-05 16:51:49 +0000283 ConstantUnion *unionArray = new ConstantUnion[1];
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000284 unionArray->setBConst($1.b);
Jamie Madill075edd82013-07-08 13:30:19 -0400285 $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @1);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000286 }
287 | LEFT_PAREN expression RIGHT_PAREN {
288 $$ = $2;
289 }
290 ;
291
292postfix_expression
293 : primary_expression {
294 $$ = $1;
295 }
296 | postfix_expression LEFT_BRACKET integer_expression RIGHT_BRACKET {
Jamie Madill075edd82013-07-08 13:30:19 -0400297 $$ = context->addIndexExpression($1, @2, $3);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000298 }
299 | function_call {
300 $$ = $1;
301 }
Jamie Madillf8dc4fb2013-05-24 16:34:06 -0400302 | postfix_expression DOT identifier {
Jamie Madill075edd82013-07-08 13:30:19 -0400303 $$ = context->addFieldSelectionExpression($1, @2, *$3.string, @3);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000304 }
305 | postfix_expression INC_OP {
Jamie Madill075edd82013-07-08 13:30:19 -0400306 if (context->lValueErrorCheck(@2, "++", $1))
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000307 context->recover();
Jamie Madill075edd82013-07-08 13:30:19 -0400308 $$ = context->intermediate.addUnaryMath(EOpPostIncrement, $1, @2);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000309 if ($$ == 0) {
Jamie Madill075edd82013-07-08 13:30:19 -0400310 context->unaryOpError(@2, "++", $1->getCompleteString());
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000311 context->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000312 $$ = $1;
313 }
314 }
315 | postfix_expression DEC_OP {
Jamie Madill075edd82013-07-08 13:30:19 -0400316 if (context->lValueErrorCheck(@2, "--", $1))
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000317 context->recover();
Jamie Madill075edd82013-07-08 13:30:19 -0400318 $$ = context->intermediate.addUnaryMath(EOpPostDecrement, $1, @2);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000319 if ($$ == 0) {
Jamie Madill075edd82013-07-08 13:30:19 -0400320 context->unaryOpError(@2, "--", $1->getCompleteString());
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000321 context->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000322 $$ = $1;
323 }
324 }
325 ;
326
327integer_expression
328 : expression {
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000329 if (context->integerErrorCheck($1, "[]"))
330 context->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000331 $$ = $1;
332 }
333 ;
334
335function_call
336 : function_call_or_method {
337 TFunction* fnCall = $1.function;
338 TOperator op = fnCall->getBuiltInOp();
339
daniel@transgaming.com998dd9f2010-03-16 05:38:01 +0000340 if (op != EOpNull)
341 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000342 //
343 // Then this should be a constructor.
344 // Don't go through the symbol table for constructors.
345 // Their parameters will be verified algorithmically.
346 //
daniel@transgaming.coma5d76232010-05-17 09:58:47 +0000347 TType type(EbtVoid, EbpUndefined); // use this to get the type back
Jamie Madill075edd82013-07-08 13:30:19 -0400348 if (context->constructorErrorCheck(@1, $1.intermNode, *fnCall, op, &type)) {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000349 $$ = 0;
350 } else {
351 //
352 // It's a constructor, of type 'type'.
353 //
Jamie Madill075edd82013-07-08 13:30:19 -0400354 $$ = context->addConstructor($1.intermNode, &type, op, fnCall, @1);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000355 }
356
357 if ($$ == 0) {
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000358 context->recover();
Jamie Madill075edd82013-07-08 13:30:19 -0400359 $$ = context->intermediate.setAggregateOperator(0, op, @1);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000360 }
361 $$->setType(type);
362 } else {
363 //
364 // Not a constructor. Find it in the symbol table.
365 //
366 const TFunction* fnCandidate;
367 bool builtIn;
Jamie Madill075edd82013-07-08 13:30:19 -0400368 fnCandidate = context->findFunction(@1, fnCall, context->shaderVersion, &builtIn);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000369 if (fnCandidate) {
370 //
alokp@chromium.org8815d7f2010-09-09 17:30:03 +0000371 // A declared function.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000372 //
alokp@chromium.org8815d7f2010-09-09 17:30:03 +0000373 if (builtIn && !fnCandidate->getExtension().empty() &&
Jamie Madill075edd82013-07-08 13:30:19 -0400374 context->extensionErrorCheck(@1, fnCandidate->getExtension())) {
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000375 context->recover();
alokp@chromium.org8815d7f2010-09-09 17:30:03 +0000376 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000377 op = fnCandidate->getBuiltInOp();
378 if (builtIn && op != EOpNull) {
379 //
380 // A function call mapped to a built-in operation.
381 //
382 if (fnCandidate->getParamCount() == 1) {
383 //
384 // Treat it like a built-in unary operator.
385 //
Jamie Madill075edd82013-07-08 13:30:19 -0400386 $$ = context->intermediate.addUnaryMath(op, $1.intermNode, @1);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000387 if ($$ == 0) {
maxvujovic@gmail.comc6b3b3c2012-06-27 22:49:39 +0000388 std::stringstream extraInfoStream;
389 extraInfoStream << "built in unary operator function. Type: " << static_cast<TIntermTyped*>($1.intermNode)->getCompleteString();
390 std::string extraInfo = extraInfoStream.str();
391 context->error($1.intermNode->getLine(), " wrong operand type", "Internal Error", extraInfo.c_str());
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000392 YYERROR;
393 }
394 } else {
Jamie Madill075edd82013-07-08 13:30:19 -0400395 $$ = context->intermediate.setAggregateOperator($1.intermAggregate, op, @1);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000396 }
397 } else {
398 // This is a real function call
399
Jamie Madill075edd82013-07-08 13:30:19 -0400400 $$ = context->intermediate.setAggregateOperator($1.intermAggregate, EOpFunctionCall, @1);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000401 $$->setType(fnCandidate->getReturnType());
402
403 // this is how we know whether the given function is a builtIn function or a user defined function
404 // if builtIn == false, it's a userDefined -> could be an overloaded builtIn function also
405 // if builtIn == true, it's definitely a builtIn function with EOpNull
406 if (!builtIn)
407 $$->getAsAggregate()->setUserDefined();
408 $$->getAsAggregate()->setName(fnCandidate->getMangledName());
409
410 TQualifier qual;
shannon.woods@transgaming.comd64b3da2013-02-28 23:19:26 +0000411 for (size_t i = 0; i < fnCandidate->getParamCount(); ++i) {
alokp@chromium.orgb19403a2010-09-08 17:56:26 +0000412 qual = fnCandidate->getParam(i).type->getQualifier();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000413 if (qual == EvqOut || qual == EvqInOut) {
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000414 if (context->lValueErrorCheck($$->getLine(), "assign", $$->getAsAggregate()->getSequence()[i]->getAsTyped())) {
maxvujovic@gmail.comc6b3b3c2012-06-27 22:49:39 +0000415 context->error($1.intermNode->getLine(), "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error");
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000416 context->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000417 }
418 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000419 }
420 }
421 $$->setType(fnCandidate->getReturnType());
422 } else {
423 // error message was put out by PaFindFunction()
424 // Put on a dummy node for error recovery
alokp@chromium.org256b7512010-05-05 16:51:49 +0000425 ConstantUnion *unionArray = new ConstantUnion[1];
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000426 unionArray->setFConst(0.0f);
Jamie Madill075edd82013-07-08 13:30:19 -0400427 $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConst), @1);
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000428 context->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000429 }
430 }
431 delete fnCall;
432 }
433 ;
434
435function_call_or_method
436 : function_call_generic {
437 $$ = $1;
438 }
439 | postfix_expression DOT function_call_generic {
Jamie Madill075edd82013-07-08 13:30:19 -0400440 context->error(@3, "methods are not supported", "");
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000441 context->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000442 $$ = $3;
443 }
444 ;
445
446function_call_generic
447 : function_call_header_with_parameters RIGHT_PAREN {
448 $$ = $1;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000449 }
450 | function_call_header_no_parameters RIGHT_PAREN {
451 $$ = $1;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000452 }
453 ;
454
455function_call_header_no_parameters
456 : function_call_header VOID_TYPE {
457 $$.function = $1;
458 $$.intermNode = 0;
459 }
460 | function_call_header {
461 $$.function = $1;
462 $$.intermNode = 0;
463 }
464 ;
465
466function_call_header_with_parameters
467 : function_call_header assignment_expression {
468 TParameter param = { 0, new TType($2->getType()) };
469 $1->addParameter(param);
470 $$.function = $1;
471 $$.intermNode = $2;
472 }
473 | function_call_header_with_parameters COMMA assignment_expression {
474 TParameter param = { 0, new TType($3->getType()) };
475 $1.function->addParameter(param);
476 $$.function = $1.function;
Jamie Madill075edd82013-07-08 13:30:19 -0400477 $$.intermNode = context->intermediate.growAggregate($1.intermNode, $3, @2);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000478 }
479 ;
480
481function_call_header
482 : function_identifier LEFT_PAREN {
483 $$ = $1;
484 }
485 ;
486
487// Grammar Note: Constructors look like functions, but are recognized as types.
488
489function_identifier
zmo@google.comdc4b4f82011-06-17 00:42:53 +0000490 : type_specifier_nonarray {
shannonwoods@chromium.org18851132013-05-30 00:19:54 +0000491 $$ = context->addConstructorFunc($1);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000492 }
493 | IDENTIFIER {
Jamie Madill075edd82013-07-08 13:30:19 -0400494 if (context->reservedErrorCheck(@1, *$1.string))
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000495 context->recover();
daniel@transgaming.coma5d76232010-05-17 09:58:47 +0000496 TType type(EbtVoid, EbpUndefined);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000497 TFunction *function = new TFunction($1.string, type);
498 $$ = function;
499 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000500 ;
501
502unary_expression
503 : postfix_expression {
504 $$ = $1;
505 }
506 | INC_OP unary_expression {
Jamie Madill075edd82013-07-08 13:30:19 -0400507 if (context->lValueErrorCheck(@1, "++", $2))
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000508 context->recover();
Jamie Madill075edd82013-07-08 13:30:19 -0400509 $$ = context->intermediate.addUnaryMath(EOpPreIncrement, $2, @1);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000510 if ($$ == 0) {
Jamie Madill075edd82013-07-08 13:30:19 -0400511 context->unaryOpError(@1, "++", $2->getCompleteString());
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000512 context->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000513 $$ = $2;
514 }
515 }
516 | DEC_OP unary_expression {
Jamie Madill075edd82013-07-08 13:30:19 -0400517 if (context->lValueErrorCheck(@1, "--", $2))
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000518 context->recover();
Jamie Madill075edd82013-07-08 13:30:19 -0400519 $$ = context->intermediate.addUnaryMath(EOpPreDecrement, $2, @1);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000520 if ($$ == 0) {
Jamie Madill075edd82013-07-08 13:30:19 -0400521 context->unaryOpError(@1, "--", $2->getCompleteString());
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000522 context->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000523 $$ = $2;
524 }
525 }
526 | unary_operator unary_expression {
527 if ($1.op != EOpNull) {
Jamie Madill075edd82013-07-08 13:30:19 -0400528 $$ = context->intermediate.addUnaryMath($1.op, $2, @1);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000529 if ($$ == 0) {
530 const char* errorOp = "";
531 switch($1.op) {
532 case EOpNegative: errorOp = "-"; break;
533 case EOpLogicalNot: errorOp = "!"; break;
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000534 default: break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000535 }
Jamie Madill075edd82013-07-08 13:30:19 -0400536 context->unaryOpError(@1, errorOp, $2->getCompleteString());
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000537 context->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000538 $$ = $2;
539 }
540 } else
541 $$ = $2;
542 }
543 ;
544// Grammar Note: No traditional style type casts.
545
546unary_operator
Jamie Madill075edd82013-07-08 13:30:19 -0400547 : PLUS { $$.op = EOpNull; }
548 | DASH { $$.op = EOpNegative; }
549 | BANG { $$.op = EOpLogicalNot; }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000550 ;
551// Grammar Note: No '*' or '&' unary ops. Pointers are not supported.
552
553multiplicative_expression
554 : unary_expression { $$ = $1; }
555 | multiplicative_expression STAR unary_expression {
Jamie Madill075edd82013-07-08 13:30:19 -0400556 $$ = context->intermediate.addBinaryMath(EOpMul, $1, $3, @2);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000557 if ($$ == 0) {
Jamie Madill075edd82013-07-08 13:30:19 -0400558 context->binaryOpError(@2, "*", $1->getCompleteString(), $3->getCompleteString());
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000559 context->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000560 $$ = $1;
561 }
562 }
563 | multiplicative_expression SLASH unary_expression {
Jamie Madill075edd82013-07-08 13:30:19 -0400564 $$ = context->intermediate.addBinaryMath(EOpDiv, $1, $3, @2);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000565 if ($$ == 0) {
Jamie Madill075edd82013-07-08 13:30:19 -0400566 context->binaryOpError(@2, "/", $1->getCompleteString(), $3->getCompleteString());
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000567 context->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000568 $$ = $1;
569 }
570 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000571 ;
572
573additive_expression
574 : multiplicative_expression { $$ = $1; }
575 | additive_expression PLUS multiplicative_expression {
Jamie Madill075edd82013-07-08 13:30:19 -0400576 $$ = context->intermediate.addBinaryMath(EOpAdd, $1, $3, @2);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000577 if ($$ == 0) {
Jamie Madill075edd82013-07-08 13:30:19 -0400578 context->binaryOpError(@2, "+", $1->getCompleteString(), $3->getCompleteString());
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000579 context->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000580 $$ = $1;
581 }
582 }
583 | additive_expression DASH multiplicative_expression {
Jamie Madill075edd82013-07-08 13:30:19 -0400584 $$ = context->intermediate.addBinaryMath(EOpSub, $1, $3, @2);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000585 if ($$ == 0) {
Jamie Madill075edd82013-07-08 13:30:19 -0400586 context->binaryOpError(@2, "-", $1->getCompleteString(), $3->getCompleteString());
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000587 context->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000588 $$ = $1;
589 }
590 }
591 ;
592
593shift_expression
594 : additive_expression { $$ = $1; }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000595 ;
596
597relational_expression
598 : shift_expression { $$ = $1; }
599 | relational_expression LEFT_ANGLE shift_expression {
Jamie Madill075edd82013-07-08 13:30:19 -0400600 $$ = context->intermediate.addBinaryMath(EOpLessThan, $1, $3, @2);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000601 if ($$ == 0) {
Jamie Madill075edd82013-07-08 13:30:19 -0400602 context->binaryOpError(@2, "<", $1->getCompleteString(), $3->getCompleteString());
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000603 context->recover();
alokp@chromium.org256b7512010-05-05 16:51:49 +0000604 ConstantUnion *unionArray = new ConstantUnion[1];
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000605 unionArray->setBConst(false);
Jamie Madill075edd82013-07-08 13:30:19 -0400606 $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000607 }
608 }
609 | relational_expression RIGHT_ANGLE shift_expression {
Jamie Madill075edd82013-07-08 13:30:19 -0400610 $$ = context->intermediate.addBinaryMath(EOpGreaterThan, $1, $3, @2);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000611 if ($$ == 0) {
Jamie Madill075edd82013-07-08 13:30:19 -0400612 context->binaryOpError(@2, ">", $1->getCompleteString(), $3->getCompleteString());
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000613 context->recover();
alokp@chromium.org256b7512010-05-05 16:51:49 +0000614 ConstantUnion *unionArray = new ConstantUnion[1];
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000615 unionArray->setBConst(false);
Jamie Madill075edd82013-07-08 13:30:19 -0400616 $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000617 }
618 }
619 | relational_expression LE_OP shift_expression {
Jamie Madill075edd82013-07-08 13:30:19 -0400620 $$ = context->intermediate.addBinaryMath(EOpLessThanEqual, $1, $3, @2);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000621 if ($$ == 0) {
Jamie Madill075edd82013-07-08 13:30:19 -0400622 context->binaryOpError(@2, "<=", $1->getCompleteString(), $3->getCompleteString());
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000623 context->recover();
alokp@chromium.org256b7512010-05-05 16:51:49 +0000624 ConstantUnion *unionArray = new ConstantUnion[1];
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000625 unionArray->setBConst(false);
Jamie Madill075edd82013-07-08 13:30:19 -0400626 $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000627 }
628 }
629 | relational_expression GE_OP shift_expression {
Jamie Madill075edd82013-07-08 13:30:19 -0400630 $$ = context->intermediate.addBinaryMath(EOpGreaterThanEqual, $1, $3, @2);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000631 if ($$ == 0) {
Jamie Madill075edd82013-07-08 13:30:19 -0400632 context->binaryOpError(@2, ">=", $1->getCompleteString(), $3->getCompleteString());
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000633 context->recover();
alokp@chromium.org256b7512010-05-05 16:51:49 +0000634 ConstantUnion *unionArray = new ConstantUnion[1];
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000635 unionArray->setBConst(false);
Jamie Madill075edd82013-07-08 13:30:19 -0400636 $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000637 }
638 }
639 ;
640
641equality_expression
642 : relational_expression { $$ = $1; }
643 | equality_expression EQ_OP relational_expression {
Jamie Madill075edd82013-07-08 13:30:19 -0400644 $$ = context->intermediate.addBinaryMath(EOpEqual, $1, $3, @2);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000645 if ($$ == 0) {
Jamie Madill075edd82013-07-08 13:30:19 -0400646 context->binaryOpError(@2, "==", $1->getCompleteString(), $3->getCompleteString());
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000647 context->recover();
alokp@chromium.org256b7512010-05-05 16:51:49 +0000648 ConstantUnion *unionArray = new ConstantUnion[1];
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000649 unionArray->setBConst(false);
Jamie Madill075edd82013-07-08 13:30:19 -0400650 $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
alokp@chromium.org8f0f24a2010-09-01 21:06:24 +0000651 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000652 }
653 | equality_expression NE_OP relational_expression {
Jamie Madill075edd82013-07-08 13:30:19 -0400654 $$ = context->intermediate.addBinaryMath(EOpNotEqual, $1, $3, @2);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000655 if ($$ == 0) {
Jamie Madill075edd82013-07-08 13:30:19 -0400656 context->binaryOpError(@2, "!=", $1->getCompleteString(), $3->getCompleteString());
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000657 context->recover();
alokp@chromium.org256b7512010-05-05 16:51:49 +0000658 ConstantUnion *unionArray = new ConstantUnion[1];
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000659 unionArray->setBConst(false);
Jamie Madill075edd82013-07-08 13:30:19 -0400660 $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
alokp@chromium.org8f0f24a2010-09-01 21:06:24 +0000661 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000662 }
663 ;
664
665and_expression
666 : equality_expression { $$ = $1; }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000667 ;
668
669exclusive_or_expression
670 : and_expression { $$ = $1; }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000671 ;
672
673inclusive_or_expression
674 : exclusive_or_expression { $$ = $1; }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000675 ;
676
677logical_and_expression
678 : inclusive_or_expression { $$ = $1; }
679 | logical_and_expression AND_OP inclusive_or_expression {
Jamie Madill075edd82013-07-08 13:30:19 -0400680 $$ = context->intermediate.addBinaryMath(EOpLogicalAnd, $1, $3, @2);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000681 if ($$ == 0) {
Jamie Madill075edd82013-07-08 13:30:19 -0400682 context->binaryOpError(@2, "&&", $1->getCompleteString(), $3->getCompleteString());
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000683 context->recover();
alokp@chromium.org256b7512010-05-05 16:51:49 +0000684 ConstantUnion *unionArray = new ConstantUnion[1];
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000685 unionArray->setBConst(false);
Jamie Madill075edd82013-07-08 13:30:19 -0400686 $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000687 }
688 }
689 ;
690
691logical_xor_expression
692 : logical_and_expression { $$ = $1; }
693 | logical_xor_expression XOR_OP logical_and_expression {
Jamie Madill075edd82013-07-08 13:30:19 -0400694 $$ = context->intermediate.addBinaryMath(EOpLogicalXor, $1, $3, @2);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000695 if ($$ == 0) {
Jamie Madill075edd82013-07-08 13:30:19 -0400696 context->binaryOpError(@2, "^^", $1->getCompleteString(), $3->getCompleteString());
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000697 context->recover();
alokp@chromium.org256b7512010-05-05 16:51:49 +0000698 ConstantUnion *unionArray = new ConstantUnion[1];
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000699 unionArray->setBConst(false);
Jamie Madill075edd82013-07-08 13:30:19 -0400700 $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000701 }
702 }
703 ;
704
705logical_or_expression
706 : logical_xor_expression { $$ = $1; }
707 | logical_or_expression OR_OP logical_xor_expression {
Jamie Madill075edd82013-07-08 13:30:19 -0400708 $$ = context->intermediate.addBinaryMath(EOpLogicalOr, $1, $3, @2);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000709 if ($$ == 0) {
Jamie Madill075edd82013-07-08 13:30:19 -0400710 context->binaryOpError(@2, "||", $1->getCompleteString(), $3->getCompleteString());
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000711 context->recover();
alokp@chromium.org256b7512010-05-05 16:51:49 +0000712 ConstantUnion *unionArray = new ConstantUnion[1];
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000713 unionArray->setBConst(false);
Jamie Madill075edd82013-07-08 13:30:19 -0400714 $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000715 }
716 }
717 ;
718
719conditional_expression
720 : logical_or_expression { $$ = $1; }
721 | logical_or_expression QUESTION expression COLON assignment_expression {
Jamie Madill075edd82013-07-08 13:30:19 -0400722 if (context->boolErrorCheck(@2, $1))
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000723 context->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000724
Jamie Madill075edd82013-07-08 13:30:19 -0400725 $$ = context->intermediate.addSelection($1, $3, $5, @2);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000726 if ($3->getType() != $5->getType())
727 $$ = 0;
728
729 if ($$ == 0) {
Jamie Madill075edd82013-07-08 13:30:19 -0400730 context->binaryOpError(@2, ":", $3->getCompleteString(), $5->getCompleteString());
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000731 context->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000732 $$ = $5;
733 }
734 }
735 ;
736
737assignment_expression
738 : conditional_expression { $$ = $1; }
739 | unary_expression assignment_operator assignment_expression {
Jamie Madill075edd82013-07-08 13:30:19 -0400740 if (context->lValueErrorCheck(@2, "assign", $1))
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000741 context->recover();
Jamie Madill075edd82013-07-08 13:30:19 -0400742 $$ = context->intermediate.addAssign($2.op, $1, $3, @2);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000743 if ($$ == 0) {
Jamie Madill075edd82013-07-08 13:30:19 -0400744 context->assignError(@2, "assign", $1->getCompleteString(), $3->getCompleteString());
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000745 context->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000746 $$ = $1;
alokp@chromium.org8f0f24a2010-09-01 21:06:24 +0000747 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000748 }
749 ;
750
751assignment_operator
Jamie Madill28b97422013-07-08 14:01:38 -0400752 : EQUAL { $$.op = EOpAssign; }
753 | MUL_ASSIGN { $$.op = EOpMulAssign; }
754 | DIV_ASSIGN { $$.op = EOpDivAssign; }
755 | ADD_ASSIGN { $$.op = EOpAddAssign; }
756 | SUB_ASSIGN { $$.op = EOpSubAssign; }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000757 ;
758
759expression
760 : assignment_expression {
761 $$ = $1;
762 }
763 | expression COMMA assignment_expression {
Jamie Madill075edd82013-07-08 13:30:19 -0400764 $$ = context->intermediate.addComma($1, $3, @2);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000765 if ($$ == 0) {
Jamie Madill075edd82013-07-08 13:30:19 -0400766 context->binaryOpError(@2, ",", $1->getCompleteString(), $3->getCompleteString());
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000767 context->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000768 $$ = $3;
769 }
770 }
771 ;
772
773constant_expression
774 : conditional_expression {
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000775 if (context->constErrorCheck($1))
776 context->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000777 $$ = $1;
778 }
779 ;
780
shannonwoods@chromium.org5668c5d2013-05-30 00:11:48 +0000781enter_struct
782 : IDENTIFIER LEFT_BRACE {
Jamie Madill075edd82013-07-08 13:30:19 -0400783 if (context->enterStructDeclaration(@1, *$1.string))
shannonwoods@chromium.org5668c5d2013-05-30 00:11:48 +0000784 context->recover();
785 $$ = $1;
786 }
787 ;
788
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000789declaration
daniel@transgaming.comd1acd1e2010-04-13 03:25:57 +0000790 : function_prototype SEMICOLON {
791 TFunction &function = *($1.function);
792
793 TIntermAggregate *prototype = new TIntermAggregate;
794 prototype->setType(function.getReturnType());
795 prototype->setName(function.getName());
796
shannon.woods@transgaming.comd64b3da2013-02-28 23:19:26 +0000797 for (size_t i = 0; i < function.getParamCount(); i++)
daniel@transgaming.comd1acd1e2010-04-13 03:25:57 +0000798 {
alokp@chromium.orgb19403a2010-09-08 17:56:26 +0000799 const TParameter &param = function.getParam(i);
daniel@transgaming.comd1acd1e2010-04-13 03:25:57 +0000800 if (param.name != 0)
801 {
alokp@chromium.orgae829e32013-05-06 19:14:11 +0000802 TVariable variable(param.name, *param.type);
daniel@transgaming.comd1acd1e2010-04-13 03:25:57 +0000803
Jamie Madill075edd82013-07-08 13:30:19 -0400804 prototype = context->intermediate.growAggregate(prototype, context->intermediate.addSymbol(variable.getUniqueId(), variable.getName(), variable.getType(), @1), @1);
daniel@transgaming.comd1acd1e2010-04-13 03:25:57 +0000805 }
806 else
807 {
Jamie Madill075edd82013-07-08 13:30:19 -0400808 prototype = context->intermediate.growAggregate(prototype, context->intermediate.addSymbol(0, "", *param.type, @1), @1);
daniel@transgaming.comd1acd1e2010-04-13 03:25:57 +0000809 }
810 }
811
alokp@chromium.org58e54292010-08-24 21:40:03 +0000812 prototype->setOp(EOpPrototype);
daniel@transgaming.comd1acd1e2010-04-13 03:25:57 +0000813 $$ = prototype;
daniel@transgaming.com5dd6d092012-03-20 20:10:28 +0000814
815 context->symbolTable.pop();
daniel@transgaming.comd1acd1e2010-04-13 03:25:57 +0000816 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000817 | init_declarator_list SEMICOLON {
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000818 if ($1.intermAggregate)
alokp@chromium.org58e54292010-08-24 21:40:03 +0000819 $1.intermAggregate->setOp(EOpDeclaration);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000820 $$ = $1.intermAggregate;
821 }
822 | PRECISION precision_qualifier type_specifier_no_prec SEMICOLON {
shannon.woods%transgaming.com@gtempaccount.comcbb6b6a2013-04-13 03:27:47 +0000823 if (($2 == EbpHigh) && (context->shaderType == SH_FRAGMENT_SHADER) && !context->fragmentPrecisionHigh) {
Jamie Madill075edd82013-07-08 13:30:19 -0400824 context->error(@1, "precision is not supported in fragment shader", "highp");
shannon.woods%transgaming.com@gtempaccount.comcbb6b6a2013-04-13 03:27:47 +0000825 context->recover();
826 }
shannon.woods@transgaming.comd25a6b32013-02-28 23:19:13 +0000827 if (!context->symbolTable.setDefaultPrecision( $3, $2 )) {
Jamie Madill075edd82013-07-08 13:30:19 -0400828 context->error(@1, "illegal type argument for default precision qualifier", getBasicString($3.type));
shannon.woods@transgaming.comd25a6b32013-02-28 23:19:13 +0000829 context->recover();
830 }
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000831 $$ = 0;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000832 }
shannonwoods@chromium.org5668c5d2013-05-30 00:11:48 +0000833 | type_qualifier enter_struct struct_declaration_list RIGHT_BRACE SEMICOLON {
Jamie Madill075edd82013-07-08 13:30:19 -0400834 ES3_ONLY(getQualifierString($1.qualifier), @1, "interface blocks");
Jamie Madill98493dd2013-07-08 14:39:03 -0400835 $$ = context->addInterfaceBlock($1, @2, *$2.string, $3, NULL, @$, NULL, @$);
shannonwoods@chromium.org5668c5d2013-05-30 00:11:48 +0000836 }
837 | type_qualifier enter_struct struct_declaration_list RIGHT_BRACE IDENTIFIER SEMICOLON {
Jamie Madill075edd82013-07-08 13:30:19 -0400838 ES3_ONLY(getQualifierString($1.qualifier), @1, "interface blocks");
Jamie Madill98493dd2013-07-08 14:39:03 -0400839 $$ = context->addInterfaceBlock($1, @2, *$2.string, $3, $5.string, @5, NULL, @$);
shannonwoods@chromium.org5668c5d2013-05-30 00:11:48 +0000840 }
841 | type_qualifier enter_struct struct_declaration_list RIGHT_BRACE IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET SEMICOLON {
Jamie Madill075edd82013-07-08 13:30:19 -0400842 ES3_ONLY(getQualifierString($1.qualifier), @1, "interface blocks");
Jamie Madill98493dd2013-07-08 14:39:03 -0400843 $$ = context->addInterfaceBlock($1, @2, *$2.string, $3, $5.string, @5, $7, @6);
shannonwoods@chromium.org5668c5d2013-05-30 00:11:48 +0000844 }
Jamie Madilla295edf2013-06-06 11:56:48 -0400845 | type_qualifier SEMICOLON {
846 context->parseGlobalLayoutQualifier($1);
847 $$ = 0;
848 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000849 ;
850
851function_prototype
852 : function_declarator RIGHT_PAREN {
853 //
854 // Multiple declarations of the same function are allowed.
855 //
856 // If this is a definition, the definition production code will check for redefinitions
857 // (we don't know at this point if it's a definition or not).
858 //
859 // Redeclarations are allowed. But, return types and parameter qualifiers must match.
860 //
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000861 TFunction* prevDec = static_cast<TFunction*>(context->symbolTable.find($1->getMangledName(), context->shaderVersion));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000862 if (prevDec) {
863 if (prevDec->getReturnType() != $1->getReturnType()) {
Jamie Madill075edd82013-07-08 13:30:19 -0400864 context->error(@2, "overloaded functions must have the same return type", $1->getReturnType().getBasicString());
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000865 context->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000866 }
shannon.woods@transgaming.comd64b3da2013-02-28 23:19:26 +0000867 for (size_t i = 0; i < prevDec->getParamCount(); ++i) {
alokp@chromium.orgb19403a2010-09-08 17:56:26 +0000868 if (prevDec->getParam(i).type->getQualifier() != $1->getParam(i).type->getQualifier()) {
Jamie Madill075edd82013-07-08 13:30:19 -0400869 context->error(@2, "overloaded functions must have the same parameter qualifiers", $1->getParam(i).type->getQualifierString());
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000870 context->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000871 }
872 }
873 }
874
875 //
Nicolas Capensd4a9b8d2013-07-18 11:01:22 -0400876 // Check for previously declared variables using the same name.
877 //
878 TSymbol *prevSym = context->symbolTable.find($1->getName(), context->shaderVersion);
879 if (prevSym)
880 {
881 if (!prevSym->isFunction())
882 {
883 context->error(@2, "redefinition", $1->getName().c_str(), "function");
884 context->recover();
885 }
886 }
887 else
888 {
889 // Insert the unmangled name to detect potential future redefinition as a variable.
890 context->symbolTable.getOuterLevel()->insert($1->getName(), *$1);
891 }
892
893 //
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000894 // If this is a redeclaration, it could also be a definition,
895 // in which case, we want to use the variable names from this one, and not the one that's
896 // being redeclared. So, pass back up this declaration, not the one in the symbol table.
897 //
898 $$.function = $1;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000899
daniel@transgaming.com5dd6d092012-03-20 20:10:28 +0000900 // We're at the inner scope level of the function's arguments and body statement.
901 // Add the function prototype to the surrounding scope instead.
902 context->symbolTable.getOuterLevel()->insert(*$$.function);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000903 }
904 ;
905
906function_declarator
907 : function_header {
908 $$ = $1;
909 }
910 | function_header_with_parameters {
911 $$ = $1;
912 }
913 ;
914
915
916function_header_with_parameters
917 : function_header parameter_declaration {
918 // Add the parameter
919 $$ = $1;
920 if ($2.param.type->getBasicType() != EbtVoid)
921 $1->addParameter($2.param);
922 else
923 delete $2.param.type;
924 }
925 | function_header_with_parameters COMMA parameter_declaration {
926 //
927 // Only first parameter of one-parameter functions can be void
928 // The check for named parameters not being void is done in parameter_declarator
929 //
930 if ($3.param.type->getBasicType() == EbtVoid) {
931 //
932 // This parameter > first is void
933 //
Jamie Madill075edd82013-07-08 13:30:19 -0400934 context->error(@2, "cannot be an argument type except for '(void)'", "void");
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000935 context->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000936 delete $3.param.type;
937 } else {
938 // Add the parameter
939 $$ = $1;
940 $1->addParameter($3.param);
941 }
942 }
943 ;
944
945function_header
946 : fully_specified_type IDENTIFIER LEFT_PAREN {
947 if ($1.qualifier != EvqGlobal && $1.qualifier != EvqTemporary) {
Jamie Madill075edd82013-07-08 13:30:19 -0400948 context->error(@2, "no qualifiers allowed for function return", getQualifierString($1.qualifier));
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000949 context->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000950 }
951 // make sure a sampler is not involved as well...
Jamie Madill075edd82013-07-08 13:30:19 -0400952 if (context->structQualifierErrorCheck(@2, $1))
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000953 context->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000954
955 // Add the function as a prototype after parsing it (we do not support recursion)
956 TFunction *function;
957 TType type($1);
958 function = new TFunction($2.string, type);
959 $$ = function;
daniel@transgaming.com5dd6d092012-03-20 20:10:28 +0000960
961 context->symbolTable.push();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000962 }
963 ;
964
965parameter_declarator
966 // Type + name
Jamie Madill78eb5df2013-05-24 16:34:05 -0400967 : type_specifier identifier {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000968 if ($1.type == EbtVoid) {
Jamie Madill075edd82013-07-08 13:30:19 -0400969 context->error(@2, "illegal use of type 'void'", $2.string->c_str());
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000970 context->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000971 }
Jamie Madill075edd82013-07-08 13:30:19 -0400972 if (context->reservedErrorCheck(@2, *$2.string))
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000973 context->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000974 TParameter param = {$2.string, new TType($1)};
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000975 $$.param = param;
976 }
Jamie Madill78eb5df2013-05-24 16:34:05 -0400977 | type_specifier identifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000978 // Check that we can make an array out of this type
Jamie Madill075edd82013-07-08 13:30:19 -0400979 if (context->arrayTypeErrorCheck(@3, $1))
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000980 context->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000981
Jamie Madill075edd82013-07-08 13:30:19 -0400982 if (context->reservedErrorCheck(@2, *$2.string))
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000983 context->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000984
985 int size;
Jamie Madill075edd82013-07-08 13:30:19 -0400986 if (context->arraySizeErrorCheck(@3, $4, size))
alokp@chromium.org044a5cf2010-11-12 15:42:16 +0000987 context->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000988 $1.setArray(true, size);
989
990 TType* type = new TType($1);
991 TParameter param = { $2.string, type };
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000992 $$.param = param;
993 }
994 ;
995
996parameter_declaration
997 //
998 // The only parameter qualifier a parameter can have are
999 // IN_QUAL, OUT_QUAL, INOUT_QUAL, or CONST.
1000 //
1001
1002 //
1003 // Type + name
1004 //
shannon.woods%transgaming.com@gtempaccount.com2226e042013-04-13 03:38:26 +00001005 : parameter_type_qualifier parameter_qualifier parameter_declarator {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001006 $$ = $3;
Jamie Madill075edd82013-07-08 13:30:19 -04001007 if (context->paramErrorCheck(@3, $1, $2, $$.param.type))
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001008 context->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001009 }
1010 | parameter_qualifier parameter_declarator {
1011 $$ = $2;
Jamie Madill075edd82013-07-08 13:30:19 -04001012 if (context->parameterSamplerErrorCheck(@2, $1, *$2.param.type))
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001013 context->recover();
Jamie Madill075edd82013-07-08 13:30:19 -04001014 if (context->paramErrorCheck(@2, EvqTemporary, $1, $$.param.type))
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001015 context->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001016 }
1017 //
1018 // Only type
1019 //
shannon.woods%transgaming.com@gtempaccount.com2226e042013-04-13 03:38:26 +00001020 | parameter_type_qualifier parameter_qualifier parameter_type_specifier {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001021 $$ = $3;
Jamie Madill075edd82013-07-08 13:30:19 -04001022 if (context->paramErrorCheck(@3, $1, $2, $$.param.type))
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001023 context->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001024 }
1025 | parameter_qualifier parameter_type_specifier {
1026 $$ = $2;
Jamie Madill075edd82013-07-08 13:30:19 -04001027 if (context->parameterSamplerErrorCheck(@2, $1, *$2.param.type))
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001028 context->recover();
Jamie Madill075edd82013-07-08 13:30:19 -04001029 if (context->paramErrorCheck(@2, EvqTemporary, $1, $$.param.type))
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001030 context->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001031 }
1032 ;
1033
1034parameter_qualifier
1035 : /* empty */ {
1036 $$ = EvqIn;
1037 }
1038 | IN_QUAL {
1039 $$ = EvqIn;
1040 }
1041 | OUT_QUAL {
1042 $$ = EvqOut;
1043 }
1044 | INOUT_QUAL {
1045 $$ = EvqInOut;
1046 }
1047 ;
1048
1049parameter_type_specifier
1050 : type_specifier {
1051 TParameter param = { 0, new TType($1) };
1052 $$.param = param;
1053 }
1054 ;
1055
1056init_declarator_list
1057 : single_declaration {
1058 $$ = $1;
1059 }
Jamie Madill78eb5df2013-05-24 16:34:05 -04001060 | init_declarator_list COMMA identifier {
Jamie Madill502d66f2013-06-20 11:55:52 -04001061 $$ = $1;
Jamie Madill075edd82013-07-08 13:30:19 -04001062 $$.intermAggregate = context->parseDeclarator($$.type, $1.intermAggregate, $3.symbol, @3, *$3.string);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001063 }
Jamie Madill78eb5df2013-05-24 16:34:05 -04001064 | init_declarator_list COMMA identifier LEFT_BRACKET RIGHT_BRACKET {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001065 $$ = $1;
Jamie Madill075edd82013-07-08 13:30:19 -04001066 context->parseArrayDeclarator($$.type, @3, *$3.string, @4, NULL, NULL);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001067 }
Jamie Madill78eb5df2013-05-24 16:34:05 -04001068 | init_declarator_list COMMA identifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001069 $$ = $1;
Jamie Madill075edd82013-07-08 13:30:19 -04001070 $$.intermAggregate = context->parseArrayDeclarator($$.type, @3, *$3.string, @4, $1.intermNode, $5);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001071 }
Jamie Madill78eb5df2013-05-24 16:34:05 -04001072 | init_declarator_list COMMA identifier EQUAL initializer {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001073 $$ = $1;
Jamie Madill075edd82013-07-08 13:30:19 -04001074 $$.intermAggregate = context->parseInitDeclarator($$.type, $1.intermAggregate, @3, *$3.string, @4, $5);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001075 }
1076 ;
1077
1078single_declaration
1079 : fully_specified_type {
1080 $$.type = $1;
Jamie Madill075edd82013-07-08 13:30:19 -04001081 $$.intermAggregate = context->parseSingleDeclaration($$.type, @1, "");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001082 }
Jamie Madill78eb5df2013-05-24 16:34:05 -04001083 | fully_specified_type identifier {
Jamie Madill60ed9812013-06-06 11:56:46 -04001084 $$.type = $1;
Jamie Madill075edd82013-07-08 13:30:19 -04001085 $$.intermAggregate = context->parseSingleDeclaration($$.type, @2, *$2.string);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001086 }
Jamie Madill78eb5df2013-05-24 16:34:05 -04001087 | fully_specified_type identifier LEFT_BRACKET RIGHT_BRACKET {
Jamie Madill075edd82013-07-08 13:30:19 -04001088 context->error(@2, "unsized array declarations not supported", $2.string->c_str());
kbr@chromium.org04277b82011-06-02 18:41:26 +00001089 context->recover();
1090
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001091 $$.type = $1;
Jamie Madill075edd82013-07-08 13:30:19 -04001092 $$.intermAggregate = context->parseSingleDeclaration($$.type, @2, *$2.string);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001093 }
Jamie Madill78eb5df2013-05-24 16:34:05 -04001094 | fully_specified_type identifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001095 $$.type = $1;
Jamie Madill075edd82013-07-08 13:30:19 -04001096 $$.intermAggregate = context->parseSingleArrayDeclaration($$.type, @2, *$2.string, @3, $4);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001097 }
Jamie Madill78eb5df2013-05-24 16:34:05 -04001098 | fully_specified_type identifier EQUAL initializer {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001099 $$.type = $1;
Jamie Madill075edd82013-07-08 13:30:19 -04001100 $$.intermAggregate = context->parseSingleInitDeclaration($$.type, @2, *$2.string, @3, $4);
daniel@transgaming.com0578f812010-05-17 09:58:39 +00001101 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001102 | INVARIANT IDENTIFIER {
Jamie Madill075edd82013-07-08 13:30:19 -04001103 VERTEX_ONLY("invariant declaration", @1);
1104 if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "invariant varying"))
daniel@transgaming.comeec8efc2012-03-09 21:57:49 +00001105 context->recover();
Jamie Madill075edd82013-07-08 13:30:19 -04001106 $$.type.setBasic(EbtInvariant, EvqInvariantVaryingOut, @2);
daniel@transgaming.comeec8efc2012-03-09 21:57:49 +00001107 if (!$2.symbol)
1108 {
Jamie Madill075edd82013-07-08 13:30:19 -04001109 context->error(@2, "undeclared identifier declared as invariant", $2.string->c_str());
daniel@transgaming.comeec8efc2012-03-09 21:57:49 +00001110 context->recover();
1111
1112 $$.intermAggregate = 0;
1113 }
1114 else
1115 {
Jamie Madill075edd82013-07-08 13:30:19 -04001116 TIntermSymbol *symbol = context->intermediate.addSymbol(0, *$2.string, TType($$.type), @2);
1117 $$.intermAggregate = context->intermediate.makeAggregate(symbol, @2);
daniel@transgaming.comeec8efc2012-03-09 21:57:49 +00001118 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001119 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001120 ;
1121
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001122fully_specified_type
1123 : type_specifier {
1124 $$ = $1;
1125
1126 if ($1.array) {
Jamie Madill075edd82013-07-08 13:30:19 -04001127 context->error(@1, "not supported", "first-class array");
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001128 context->recover();
alokp@chromium.org8f0f24a2010-09-01 21:06:24 +00001129 $1.setArray(false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001130 }
1131 }
1132 | type_qualifier type_specifier {
Jamie Madilla5efff92013-06-06 11:56:47 -04001133 $$ = context->addFullySpecifiedType($1.qualifier, $1.layoutQualifier, $2);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001134 }
1135 ;
1136
shannon.woods%transgaming.com@gtempaccount.com6f273e32013-04-13 03:41:15 +00001137interpolation_qualifier
1138 : SMOOTH {
1139 $$.qualifier = EvqSmooth;
shannon.woods%transgaming.com@gtempaccount.com6f273e32013-04-13 03:41:15 +00001140 }
1141 | FLAT {
1142 $$.qualifier = EvqFlat;
shannon.woods%transgaming.com@gtempaccount.com6f273e32013-04-13 03:41:15 +00001143 }
1144 ;
1145
shannon.woods%transgaming.com@gtempaccount.com2226e042013-04-13 03:38:26 +00001146parameter_type_qualifier
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001147 : CONST_QUAL {
shannon.woods%transgaming.com@gtempaccount.com2226e042013-04-13 03:38:26 +00001148 $$ = EvqConst;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001149 }
shannon.woods%transgaming.com@gtempaccount.com2226e042013-04-13 03:38:26 +00001150 ;
1151
1152type_qualifier
1153 : ATTRIBUTE {
Jamie Madill075edd82013-07-08 13:30:19 -04001154 VERTEX_ONLY("attribute", @1);
1155 ES2_ONLY("attribute", @1);
1156 if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "attribute"))
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001157 context->recover();
Jamie Madill075edd82013-07-08 13:30:19 -04001158 $$.setBasic(EbtVoid, EvqAttribute, @1);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001159 }
1160 | VARYING {
Jamie Madill075edd82013-07-08 13:30:19 -04001161 ES2_ONLY("varying", @1);
1162 if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "varying"))
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001163 context->recover();
1164 if (context->shaderType == SH_VERTEX_SHADER)
Jamie Madill075edd82013-07-08 13:30:19 -04001165 $$.setBasic(EbtVoid, EvqVaryingOut, @1);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001166 else
Jamie Madill075edd82013-07-08 13:30:19 -04001167 $$.setBasic(EbtVoid, EvqVaryingIn, @1);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001168 }
1169 | INVARIANT VARYING {
Jamie Madill075edd82013-07-08 13:30:19 -04001170 ES2_ONLY("varying", @1);
1171 if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "invariant varying"))
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001172 context->recover();
1173 if (context->shaderType == SH_VERTEX_SHADER)
Jamie Madill075edd82013-07-08 13:30:19 -04001174 $$.setBasic(EbtVoid, EvqInvariantVaryingOut, @1);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001175 else
Jamie Madill075edd82013-07-08 13:30:19 -04001176 $$.setBasic(EbtVoid, EvqInvariantVaryingIn, @1);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001177 }
shannon.woods%transgaming.com@gtempaccount.com6f273e32013-04-13 03:41:15 +00001178 | storage_qualifier {
Jamie Madill12bea0a2014-04-11 13:33:55 -04001179 if ($1.qualifier != EvqConst && !context->symbolTable.atGlobalLevel()) {
1180 context->error(@1, "Local variables can only use the const storage qualifier.", getQualifierString($1.qualifier));
1181 context->recover();
1182 } else {
1183 $$.setBasic(EbtVoid, $1.qualifier, @1);
1184 }
shannon.woods%transgaming.com@gtempaccount.com2226e042013-04-13 03:38:26 +00001185 }
shannon.woods%transgaming.com@gtempaccount.com6f273e32013-04-13 03:41:15 +00001186 | interpolation_qualifier storage_qualifier {
Jamie Madillf2e0f9b2013-08-26 16:39:42 -04001187 $$ = context->joinInterpolationQualifiers(@1, $1.qualifier, @2, $2.qualifier);
shannon.woods%transgaming.com@gtempaccount.com6f273e32013-04-13 03:41:15 +00001188 }
1189 | interpolation_qualifier {
Jamie Madill075edd82013-07-08 13:30:19 -04001190 context->error(@1, "interpolation qualifier requires a fragment 'in' or vertex 'out' storage qualifier", getInterpolationString($1.qualifier));
shannon.woods%transgaming.com@gtempaccount.com6f273e32013-04-13 03:41:15 +00001191 context->recover();
1192
1193 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
Jamie Madill075edd82013-07-08 13:30:19 -04001194 $$.setBasic(EbtVoid, qual, @1);
shannon.woods%transgaming.com@gtempaccount.com6f273e32013-04-13 03:41:15 +00001195 }
shannonwoods@chromium.org302adfe2013-05-30 00:21:06 +00001196 | layout_qualifier {
1197 $$.qualifier = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
1198 $$.layoutQualifier = $1;
1199 }
1200 | layout_qualifier storage_qualifier {
Jamie Madill075edd82013-07-08 13:30:19 -04001201 $$.setBasic(EbtVoid, $2.qualifier, @2);
shannonwoods@chromium.org302adfe2013-05-30 00:21:06 +00001202 $$.layoutQualifier = $1;
1203 }
shannon.woods%transgaming.com@gtempaccount.com2226e042013-04-13 03:38:26 +00001204 ;
1205
1206storage_qualifier
1207 : CONST_QUAL {
1208 $$.qualifier = EvqConst;
shannon.woods%transgaming.com@gtempaccount.com2226e042013-04-13 03:38:26 +00001209 }
1210 | IN_QUAL {
Jamie Madill075edd82013-07-08 13:30:19 -04001211 ES3_ONLY("in", @1, "storage qualifier");
Jamie Madill19571812013-08-12 15:26:34 -07001212 $$.qualifier = (context->shaderType == SH_FRAGMENT_SHADER) ? EvqFragmentIn : EvqVertexIn;
shannon.woods%transgaming.com@gtempaccount.com2226e042013-04-13 03:38:26 +00001213 }
1214 | OUT_QUAL {
Jamie Madill075edd82013-07-08 13:30:19 -04001215 ES3_ONLY("out", @1, "storage qualifier");
Jamie Madill19571812013-08-12 15:26:34 -07001216 $$.qualifier = (context->shaderType == SH_FRAGMENT_SHADER) ? EvqFragmentOut : EvqVertexOut;
shannon.woods%transgaming.com@gtempaccount.com2226e042013-04-13 03:38:26 +00001217 }
1218 | CENTROID IN_QUAL {
Jamie Madill075edd82013-07-08 13:30:19 -04001219 ES3_ONLY("centroid in", @1, "storage qualifier");
Jamie Madill6c239462013-06-06 11:56:45 -04001220 if (context->shaderType == SH_VERTEX_SHADER)
1221 {
Jamie Madill075edd82013-07-08 13:30:19 -04001222 context->error(@1, "invalid storage qualifier", "it is an error to use 'centroid in' in the vertex shader");
Jamie Madill6c239462013-06-06 11:56:45 -04001223 context->recover();
1224 }
Jamie Madill19571812013-08-12 15:26:34 -07001225 $$.qualifier = (context->shaderType == SH_FRAGMENT_SHADER) ? EvqCentroidIn : EvqVertexIn;
shannon.woods%transgaming.com@gtempaccount.com2226e042013-04-13 03:38:26 +00001226 }
shannon.woods%transgaming.com@gtempaccount.com6f273e32013-04-13 03:41:15 +00001227 | CENTROID OUT_QUAL {
Jamie Madill075edd82013-07-08 13:30:19 -04001228 ES3_ONLY("centroid out", @1, "storage qualifier");
Jamie Madill6c239462013-06-06 11:56:45 -04001229 if (context->shaderType == SH_FRAGMENT_SHADER)
1230 {
Jamie Madill075edd82013-07-08 13:30:19 -04001231 context->error(@1, "invalid storage qualifier", "it is an error to use 'centroid out' in the fragment shader");
Jamie Madill6c239462013-06-06 11:56:45 -04001232 context->recover();
1233 }
Jamie Madill19571812013-08-12 15:26:34 -07001234 $$.qualifier = (context->shaderType == SH_FRAGMENT_SHADER) ? EvqFragmentOut : EvqCentroidOut;
shannon.woods%transgaming.com@gtempaccount.com2226e042013-04-13 03:38:26 +00001235 }
shannon.woods%transgaming.com@gtempaccount.com6f273e32013-04-13 03:41:15 +00001236 | UNIFORM {
Jamie Madill075edd82013-07-08 13:30:19 -04001237 if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "uniform"))
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001238 context->recover();
shannon.woods%transgaming.com@gtempaccount.com2226e042013-04-13 03:38:26 +00001239 $$.qualifier = EvqUniform;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001240 }
1241 ;
1242
1243type_specifier
1244 : type_specifier_no_prec {
daniel@transgaming.com0578f812010-05-17 09:58:39 +00001245 $$ = $1;
zmo@google.comdc4b4f82011-06-17 00:42:53 +00001246
1247 if ($$.precision == EbpUndefined) {
1248 $$.precision = context->symbolTable.getDefaultPrecision($1.type);
Jamie Madill075edd82013-07-08 13:30:19 -04001249 if (context->precisionErrorCheck(@1, $$.precision, $1.type)) {
zmo@google.comdc4b4f82011-06-17 00:42:53 +00001250 context->recover();
1251 }
1252 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001253 }
1254 | precision_qualifier type_specifier_no_prec {
daniel@transgaming.com0578f812010-05-17 09:58:39 +00001255 $$ = $2;
daniel@transgaming.coma5d76232010-05-17 09:58:47 +00001256 $$.precision = $1;
Zhenyao Moed14b792014-05-08 11:21:07 -07001257
Jamie Madill74be6a82014-05-29 14:33:28 -04001258 if (!SupportsPrecision($2.type)) {
Zhenyao Moed14b792014-05-08 11:21:07 -07001259 context->error(@1, "illegal type for precision qualifier", getBasicString($2.type));
1260 context->recover();
1261 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001262 }
1263 ;
1264
1265precision_qualifier
1266 : HIGH_PRECISION {
daniel@transgaming.com0578f812010-05-17 09:58:39 +00001267 $$ = EbpHigh;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001268 }
1269 | MEDIUM_PRECISION {
daniel@transgaming.com0578f812010-05-17 09:58:39 +00001270 $$ = EbpMedium;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001271 }
1272 | LOW_PRECISION {
daniel@transgaming.com0578f812010-05-17 09:58:39 +00001273 $$ = EbpLow;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001274 }
1275 ;
1276
shannonwoods@chromium.org302adfe2013-05-30 00:21:06 +00001277layout_qualifier
1278 : LAYOUT LEFT_PAREN layout_qualifier_id_list RIGHT_PAREN {
Jamie Madill075edd82013-07-08 13:30:19 -04001279 ES3_ONLY("layout", @1, "qualifier");
shannonwoods@chromium.org302adfe2013-05-30 00:21:06 +00001280 $$ = $3;
1281 }
1282 ;
1283
1284layout_qualifier_id_list
1285 : layout_qualifier_id {
Jamie Madilla5efff92013-06-06 11:56:47 -04001286 $$ = $1;
shannonwoods@chromium.org302adfe2013-05-30 00:21:06 +00001287 }
1288 | layout_qualifier_id_list COMMA layout_qualifier_id {
Jamie Madilla5efff92013-06-06 11:56:47 -04001289 $$ = context->joinLayoutQualifiers($1, $3);
shannonwoods@chromium.org302adfe2013-05-30 00:21:06 +00001290 }
1291 ;
1292
1293layout_qualifier_id
1294 : IDENTIFIER {
Jamie Madill075edd82013-07-08 13:30:19 -04001295 $$ = context->parseLayoutQualifier(*$1.string, @1);
shannonwoods@chromium.org302adfe2013-05-30 00:21:06 +00001296 }
1297 | IDENTIFIER EQUAL INTCONSTANT {
Jamie Madill075edd82013-07-08 13:30:19 -04001298 $$ = context->parseLayoutQualifier(*$1.string, @1, *$3.string, $3.i, @3);
shannonwoods@chromium.org302adfe2013-05-30 00:21:06 +00001299 }
1300 | IDENTIFIER EQUAL UINTCONSTANT {
Jamie Madill075edd82013-07-08 13:30:19 -04001301 $$ = context->parseLayoutQualifier(*$1.string, @1, *$3.string, $3.i, @3);
shannonwoods@chromium.org302adfe2013-05-30 00:21:06 +00001302 }
1303 ;
1304
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001305type_specifier_no_prec
1306 : type_specifier_nonarray {
1307 $$ = $1;
1308 }
1309 | type_specifier_nonarray LEFT_BRACKET constant_expression RIGHT_BRACKET {
1310 $$ = $1;
1311
Jamie Madill075edd82013-07-08 13:30:19 -04001312 if (context->arrayTypeErrorCheck(@2, $1))
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001313 context->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001314 else {
1315 int size;
Jamie Madill075edd82013-07-08 13:30:19 -04001316 if (context->arraySizeErrorCheck(@2, $3, size))
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001317 context->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001318 $$.setArray(true, size);
1319 }
1320 }
1321 ;
1322
1323type_specifier_nonarray
1324 : VOID_TYPE {
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001325 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
Jamie Madill075edd82013-07-08 13:30:19 -04001326 $$.setBasic(EbtVoid, qual, @1);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001327 }
1328 | FLOAT_TYPE {
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001329 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
Jamie Madill075edd82013-07-08 13:30:19 -04001330 $$.setBasic(EbtFloat, qual, @1);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001331 }
1332 | INT_TYPE {
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001333 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
Jamie Madill075edd82013-07-08 13:30:19 -04001334 $$.setBasic(EbtInt, qual, @1);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001335 }
shannonwoods@chromium.org6b709912013-05-30 00:20:04 +00001336 | UINT_TYPE {
1337 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
Jamie Madill075edd82013-07-08 13:30:19 -04001338 $$.setBasic(EbtUInt, qual, @1);
shannonwoods@chromium.org6b709912013-05-30 00:20:04 +00001339 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001340 | BOOL_TYPE {
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001341 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
Jamie Madill075edd82013-07-08 13:30:19 -04001342 $$.setBasic(EbtBool, qual, @1);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001343 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001344 | VEC2 {
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001345 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
Jamie Madill075edd82013-07-08 13:30:19 -04001346 $$.setBasic(EbtFloat, qual, @1);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001347 $$.setAggregate(2);
1348 }
1349 | VEC3 {
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001350 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
Jamie Madill075edd82013-07-08 13:30:19 -04001351 $$.setBasic(EbtFloat, qual, @1);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001352 $$.setAggregate(3);
1353 }
1354 | VEC4 {
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001355 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
Jamie Madill075edd82013-07-08 13:30:19 -04001356 $$.setBasic(EbtFloat, qual, @1);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001357 $$.setAggregate(4);
1358 }
1359 | BVEC2 {
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001360 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
Jamie Madill075edd82013-07-08 13:30:19 -04001361 $$.setBasic(EbtBool, qual, @1);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001362 $$.setAggregate(2);
1363 }
1364 | BVEC3 {
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001365 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
Jamie Madill075edd82013-07-08 13:30:19 -04001366 $$.setBasic(EbtBool, qual, @1);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001367 $$.setAggregate(3);
1368 }
1369 | BVEC4 {
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001370 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
Jamie Madill075edd82013-07-08 13:30:19 -04001371 $$.setBasic(EbtBool, qual, @1);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001372 $$.setAggregate(4);
1373 }
1374 | IVEC2 {
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001375 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
Jamie Madill075edd82013-07-08 13:30:19 -04001376 $$.setBasic(EbtInt, qual, @1);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001377 $$.setAggregate(2);
1378 }
1379 | IVEC3 {
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001380 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
Jamie Madill075edd82013-07-08 13:30:19 -04001381 $$.setBasic(EbtInt, qual, @1);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001382 $$.setAggregate(3);
1383 }
1384 | IVEC4 {
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001385 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
Jamie Madill075edd82013-07-08 13:30:19 -04001386 $$.setBasic(EbtInt, qual, @1);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001387 $$.setAggregate(4);
1388 }
shannonwoods@chromium.org8c788e82013-05-30 00:20:21 +00001389 | UVEC2 {
1390 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
Jamie Madill075edd82013-07-08 13:30:19 -04001391 $$.setBasic(EbtUInt, qual, @1);
shannonwoods@chromium.org8c788e82013-05-30 00:20:21 +00001392 $$.setAggregate(2);
1393 }
1394 | UVEC3 {
1395 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
Jamie Madill075edd82013-07-08 13:30:19 -04001396 $$.setBasic(EbtUInt, qual, @1);
shannonwoods@chromium.org8c788e82013-05-30 00:20:21 +00001397 $$.setAggregate(3);
1398 }
1399 | UVEC4 {
1400 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
Jamie Madill075edd82013-07-08 13:30:19 -04001401 $$.setBasic(EbtUInt, qual, @1);
shannonwoods@chromium.org8c788e82013-05-30 00:20:21 +00001402 $$.setAggregate(4);
1403 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001404 | MATRIX2 {
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001405 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
Jamie Madill075edd82013-07-08 13:30:19 -04001406 $$.setBasic(EbtFloat, qual, @1);
shannonwoods@chromium.org09e09882013-05-30 00:18:25 +00001407 $$.setMatrix(2, 2);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001408 }
1409 | MATRIX3 {
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001410 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
Jamie Madill075edd82013-07-08 13:30:19 -04001411 $$.setBasic(EbtFloat, qual, @1);
shannonwoods@chromium.org09e09882013-05-30 00:18:25 +00001412 $$.setMatrix(3, 3);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001413 }
1414 | MATRIX4 {
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001415 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
Jamie Madill075edd82013-07-08 13:30:19 -04001416 $$.setBasic(EbtFloat, qual, @1);
shannonwoods@chromium.org09e09882013-05-30 00:18:25 +00001417 $$.setMatrix(4, 4);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001418 }
shannonwoods@chromium.org9bd22fa2013-05-30 00:18:47 +00001419 | MATRIX2x3 {
1420 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
Jamie Madill075edd82013-07-08 13:30:19 -04001421 $$.setBasic(EbtFloat, qual, @1);
shannonwoods@chromium.org9bd22fa2013-05-30 00:18:47 +00001422 $$.setMatrix(2, 3);
1423 }
1424 | MATRIX3x2 {
1425 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
Jamie Madill075edd82013-07-08 13:30:19 -04001426 $$.setBasic(EbtFloat, qual, @1);
shannonwoods@chromium.org9bd22fa2013-05-30 00:18:47 +00001427 $$.setMatrix(3, 2);
1428 }
1429 | MATRIX2x4 {
1430 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
Jamie Madill075edd82013-07-08 13:30:19 -04001431 $$.setBasic(EbtFloat, qual, @1);
shannonwoods@chromium.org9bd22fa2013-05-30 00:18:47 +00001432 $$.setMatrix(2, 4);
1433 }
1434 | MATRIX4x2 {
1435 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
Jamie Madill075edd82013-07-08 13:30:19 -04001436 $$.setBasic(EbtFloat, qual, @1);
shannonwoods@chromium.org9bd22fa2013-05-30 00:18:47 +00001437 $$.setMatrix(4, 2);
1438 }
1439 | MATRIX3x4 {
1440 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
Jamie Madill075edd82013-07-08 13:30:19 -04001441 $$.setBasic(EbtFloat, qual, @1);
shannonwoods@chromium.org9bd22fa2013-05-30 00:18:47 +00001442 $$.setMatrix(3, 4);
1443 }
1444 | MATRIX4x3 {
1445 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
Jamie Madill075edd82013-07-08 13:30:19 -04001446 $$.setBasic(EbtFloat, qual, @1);
shannonwoods@chromium.org9bd22fa2013-05-30 00:18:47 +00001447 $$.setMatrix(4, 3);
1448 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001449 | SAMPLER2D {
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001450 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
Jamie Madill075edd82013-07-08 13:30:19 -04001451 $$.setBasic(EbtSampler2D, qual, @1);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001452 }
Nicolas Capens28043ba2013-06-24 16:01:53 -04001453 | SAMPLER3D {
1454 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
Jamie Madill075edd82013-07-08 13:30:19 -04001455 $$.setBasic(EbtSampler3D, qual, @1);
Nicolas Capens28043ba2013-06-24 16:01:53 -04001456 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001457 | SAMPLERCUBE {
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001458 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
Jamie Madill075edd82013-07-08 13:30:19 -04001459 $$.setBasic(EbtSamplerCube, qual, @1);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001460 }
Nicolas Capensfc2e6b92013-06-24 16:13:26 -04001461 | SAMPLER2DARRAY {
1462 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
Jamie Madill075edd82013-07-08 13:30:19 -04001463 $$.setBasic(EbtSampler2DArray, qual, @1);
Nicolas Capensfc2e6b92013-06-24 16:13:26 -04001464 }
Nicolas Capensd273c272013-06-24 15:36:48 -04001465 | ISAMPLER2D {
1466 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
Jamie Madill075edd82013-07-08 13:30:19 -04001467 $$.setBasic(EbtISampler2D, qual, @1);
Nicolas Capensd273c272013-06-24 15:36:48 -04001468 }
Nicolas Capens28043ba2013-06-24 16:01:53 -04001469 | ISAMPLER3D {
1470 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
Jamie Madill075edd82013-07-08 13:30:19 -04001471 $$.setBasic(EbtISampler3D, qual, @1);
Nicolas Capens28043ba2013-06-24 16:01:53 -04001472 }
Nicolas Capensd273c272013-06-24 15:36:48 -04001473 | ISAMPLERCUBE {
1474 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
Jamie Madill075edd82013-07-08 13:30:19 -04001475 $$.setBasic(EbtISamplerCube, qual, @1);
Nicolas Capensd273c272013-06-24 15:36:48 -04001476 }
Nicolas Capensfc2e6b92013-06-24 16:13:26 -04001477 | ISAMPLER2DARRAY {
1478 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
Jamie Madill075edd82013-07-08 13:30:19 -04001479 $$.setBasic(EbtISampler2DArray, qual, @1);
Nicolas Capensfc2e6b92013-06-24 16:13:26 -04001480 }
Nicolas Capens9e3a3f42013-06-24 15:54:32 -04001481 | USAMPLER2D {
1482 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
Jamie Madill075edd82013-07-08 13:30:19 -04001483 $$.setBasic(EbtUSampler2D, qual, @1);
Nicolas Capens9e3a3f42013-06-24 15:54:32 -04001484 }
Nicolas Capens28043ba2013-06-24 16:01:53 -04001485 | USAMPLER3D {
1486 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
Jamie Madill075edd82013-07-08 13:30:19 -04001487 $$.setBasic(EbtUSampler3D, qual, @1);
Nicolas Capens28043ba2013-06-24 16:01:53 -04001488 }
Nicolas Capens9e3a3f42013-06-24 15:54:32 -04001489 | USAMPLERCUBE {
1490 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
Jamie Madill075edd82013-07-08 13:30:19 -04001491 $$.setBasic(EbtUSamplerCube, qual, @1);
Nicolas Capens9e3a3f42013-06-24 15:54:32 -04001492 }
Nicolas Capensfc2e6b92013-06-24 16:13:26 -04001493 | USAMPLER2DARRAY {
1494 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
Jamie Madill075edd82013-07-08 13:30:19 -04001495 $$.setBasic(EbtUSampler2DArray, qual, @1);
Nicolas Capensfc2e6b92013-06-24 16:13:26 -04001496 }
Nicolas Capens2a1d8a32013-07-18 11:49:40 -04001497 | SAMPLER2DSHADOW {
1498 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
1499 $$.setBasic(EbtSampler2DShadow, qual, @1);
1500 }
1501 | SAMPLERCUBESHADOW {
1502 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
1503 $$.setBasic(EbtSamplerCubeShadow, qual, @1);
1504 }
1505 | SAMPLER2DARRAYSHADOW {
1506 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
1507 $$.setBasic(EbtSampler2DArrayShadow, qual, @1);
1508 }
zmo@google.com09c323a2011-08-12 18:22:25 +00001509 | SAMPLER_EXTERNAL_OES {
1510 if (!context->supportsExtension("GL_OES_EGL_image_external")) {
Jamie Madill075edd82013-07-08 13:30:19 -04001511 context->error(@1, "unsupported type", "samplerExternalOES");
zmo@google.com09c323a2011-08-12 18:22:25 +00001512 context->recover();
1513 }
zmo@google.com09c323a2011-08-12 18:22:25 +00001514 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
Jamie Madill075edd82013-07-08 13:30:19 -04001515 $$.setBasic(EbtSamplerExternalOES, qual, @1);
zmo@google.com09c323a2011-08-12 18:22:25 +00001516 }
kbr@chromium.org205fef32011-11-22 20:50:02 +00001517 | SAMPLER2DRECT {
1518 if (!context->supportsExtension("GL_ARB_texture_rectangle")) {
Jamie Madill075edd82013-07-08 13:30:19 -04001519 context->error(@1, "unsupported type", "sampler2DRect");
kbr@chromium.org205fef32011-11-22 20:50:02 +00001520 context->recover();
1521 }
kbr@chromium.org205fef32011-11-22 20:50:02 +00001522 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
Jamie Madill075edd82013-07-08 13:30:19 -04001523 $$.setBasic(EbtSampler2DRect, qual, @1);
kbr@chromium.org205fef32011-11-22 20:50:02 +00001524 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001525 | struct_specifier {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001526 $$ = $1;
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001527 $$.qualifier = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001528 }
1529 | TYPE_NAME {
1530 //
1531 // This is for user defined type names. The lexical phase looked up the
1532 // type.
1533 //
1534 TType& structure = static_cast<TVariable*>($1.symbol)->getType();
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001535 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
Jamie Madill075edd82013-07-08 13:30:19 -04001536 $$.setBasic(EbtStruct, qual, @1);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001537 $$.userDef = &structure;
1538 }
1539 ;
1540
1541struct_specifier
Jamie Madill075edd82013-07-08 13:30:19 -04001542 : STRUCT identifier LEFT_BRACE { if (context->enterStructDeclaration(@2, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE {
Jamie Madill98493dd2013-07-08 14:39:03 -04001543 $$ = context->addStructure(@1, @2, $2.string, $5);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001544 }
Jamie Madill075edd82013-07-08 13:30:19 -04001545 | STRUCT LEFT_BRACE { if (context->enterStructDeclaration(@2, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE {
Jamie Madill98493dd2013-07-08 14:39:03 -04001546 $$ = context->addStructure(@1, @$, NewPoolTString(""), $4);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001547 }
1548 ;
1549
1550struct_declaration_list
1551 : struct_declaration {
1552 $$ = $1;
1553 }
1554 | struct_declaration_list struct_declaration {
1555 $$ = $1;
Jamie Madill98493dd2013-07-08 14:39:03 -04001556 for (size_t i = 0; i < $2->size(); ++i) {
1557 TField* field = (*$2)[i];
1558 for (size_t j = 0; j < $$->size(); ++j) {
1559 if ((*$$)[j]->name() == field->name()) {
1560 context->error(@2, "duplicate field name in structure:", "struct", field->name().c_str());
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001561 context->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001562 }
1563 }
Jamie Madill98493dd2013-07-08 14:39:03 -04001564 $$->push_back(field);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001565 }
1566 }
1567 ;
1568
1569struct_declaration
1570 : type_specifier struct_declarator_list SEMICOLON {
shannonwoods@chromium.orga9100882013-05-30 00:11:39 +00001571 $$ = context->addStructDeclaratorList($1, $2);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001572 }
shannonwoods@chromium.org5668c5d2013-05-30 00:11:48 +00001573 | type_qualifier type_specifier struct_declarator_list SEMICOLON {
1574 // ES3 Only, but errors should be handled elsewhere
1575 $2.qualifier = $1.qualifier;
Jamie Madilla5efff92013-06-06 11:56:47 -04001576 $2.layoutQualifier = $1.layoutQualifier;
shannonwoods@chromium.org5668c5d2013-05-30 00:11:48 +00001577 $$ = context->addStructDeclaratorList($2, $3);
1578 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001579 ;
1580
1581struct_declarator_list
1582 : struct_declarator {
Jamie Madill98493dd2013-07-08 14:39:03 -04001583 $$ = NewPoolTFieldList();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001584 $$->push_back($1);
1585 }
1586 | struct_declarator_list COMMA struct_declarator {
1587 $$->push_back($3);
1588 }
1589 ;
1590
1591struct_declarator
Jamie Madill78eb5df2013-05-24 16:34:05 -04001592 : identifier {
Jamie Madill075edd82013-07-08 13:30:19 -04001593 if (context->reservedErrorCheck(@1, *$1.string))
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001594 context->recover();
alokp@chromium.orga3009882010-07-21 18:54:37 +00001595
Jamie Madill98493dd2013-07-08 14:39:03 -04001596 TType* type = new TType(EbtVoid, EbpUndefined);
1597 $$ = new TField(type, $1.string, @1);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001598 }
Jamie Madill78eb5df2013-05-24 16:34:05 -04001599 | identifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
Jamie Madill075edd82013-07-08 13:30:19 -04001600 if (context->reservedErrorCheck(@1, *$1.string))
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001601 context->recover();
alokp@chromium.orga3009882010-07-21 18:54:37 +00001602
Jamie Madill98493dd2013-07-08 14:39:03 -04001603 TType* type = new TType(EbtVoid, EbpUndefined);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001604 int size;
Jamie Madill98493dd2013-07-08 14:39:03 -04001605 if (context->arraySizeErrorCheck(@3, $3, size))
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001606 context->recover();
Jamie Madill98493dd2013-07-08 14:39:03 -04001607 type->setArraySize(size);
1608
1609 $$ = new TField(type, $1.string, @1);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001610 }
1611 ;
1612
1613initializer
1614 : assignment_expression { $$ = $1; }
1615 ;
1616
1617declaration_statement
1618 : declaration { $$ = $1; }
1619 ;
1620
1621statement
1622 : compound_statement { $$ = $1; }
1623 | simple_statement { $$ = $1; }
1624 ;
1625
1626// Grammar Note: No labeled statements; 'goto' is not supported.
1627
1628simple_statement
1629 : declaration_statement { $$ = $1; }
1630 | expression_statement { $$ = $1; }
1631 | selection_statement { $$ = $1; }
1632 | iteration_statement { $$ = $1; }
1633 | jump_statement { $$ = $1; }
1634 ;
1635
1636compound_statement
1637 : LEFT_BRACE RIGHT_BRACE { $$ = 0; }
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001638 | LEFT_BRACE { context->symbolTable.push(); } statement_list { context->symbolTable.pop(); } RIGHT_BRACE {
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001639 if ($3 != 0) {
alokp@chromium.org58e54292010-08-24 21:40:03 +00001640 $3->setOp(EOpSequence);
Jamie Madill075edd82013-07-08 13:30:19 -04001641 $3->setLine(@$);
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001642 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001643 $$ = $3;
1644 }
1645 ;
1646
1647statement_no_new_scope
1648 : compound_statement_no_new_scope { $$ = $1; }
1649 | simple_statement { $$ = $1; }
1650 ;
1651
daniel@transgaming.com83dc5a72012-03-09 21:57:07 +00001652statement_with_scope
daniel@transgaming.comeec8efc2012-03-09 21:57:49 +00001653 : { context->symbolTable.push(); } compound_statement_no_new_scope { context->symbolTable.pop(); $$ = $2; }
1654 | { context->symbolTable.push(); } simple_statement { context->symbolTable.pop(); $$ = $2; }
1655 ;
daniel@transgaming.com83dc5a72012-03-09 21:57:07 +00001656
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001657compound_statement_no_new_scope
1658 // Statement that doesn't create a new scope, for selection_statement, iteration_statement
1659 : LEFT_BRACE RIGHT_BRACE {
1660 $$ = 0;
1661 }
1662 | LEFT_BRACE statement_list RIGHT_BRACE {
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001663 if ($2) {
alokp@chromium.org58e54292010-08-24 21:40:03 +00001664 $2->setOp(EOpSequence);
Jamie Madill075edd82013-07-08 13:30:19 -04001665 $2->setLine(@$);
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001666 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001667 $$ = $2;
1668 }
1669 ;
1670
1671statement_list
1672 : statement {
Jamie Madill075edd82013-07-08 13:30:19 -04001673 $$ = context->intermediate.makeAggregate($1, @$);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001674 }
1675 | statement_list statement {
Jamie Madill075edd82013-07-08 13:30:19 -04001676 $$ = context->intermediate.growAggregate($1, $2, @$);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001677 }
1678 ;
1679
1680expression_statement
1681 : SEMICOLON { $$ = 0; }
1682 | expression SEMICOLON { $$ = static_cast<TIntermNode*>($1); }
1683 ;
1684
1685selection_statement
1686 : IF LEFT_PAREN expression RIGHT_PAREN selection_rest_statement {
Jamie Madill075edd82013-07-08 13:30:19 -04001687 if (context->boolErrorCheck(@1, $3))
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001688 context->recover();
Jamie Madill075edd82013-07-08 13:30:19 -04001689 $$ = context->intermediate.addSelection($3, $5, @1);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001690 }
1691 ;
1692
1693selection_rest_statement
daniel@transgaming.com83dc5a72012-03-09 21:57:07 +00001694 : statement_with_scope ELSE statement_with_scope {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001695 $$.node1 = $1;
1696 $$.node2 = $3;
1697 }
daniel@transgaming.com83dc5a72012-03-09 21:57:07 +00001698 | statement_with_scope {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001699 $$.node1 = $1;
1700 $$.node2 = 0;
1701 }
1702 ;
1703
1704// Grammar Note: No 'switch'. Switch statements not supported.
1705
1706condition
1707 // In 1996 c++ draft, conditions can include single declarations
1708 : expression {
1709 $$ = $1;
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001710 if (context->boolErrorCheck($1->getLine(), $1))
1711 context->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001712 }
Jamie Madill78eb5df2013-05-24 16:34:05 -04001713 | fully_specified_type identifier EQUAL initializer {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001714 TIntermNode* intermNode;
Jamie Madill075edd82013-07-08 13:30:19 -04001715 if (context->structQualifierErrorCheck(@2, $1))
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001716 context->recover();
Jamie Madill075edd82013-07-08 13:30:19 -04001717 if (context->boolErrorCheck(@2, $1))
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001718 context->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001719
Jamie Madill075edd82013-07-08 13:30:19 -04001720 if (!context->executeInitializer(@2, *$2.string, $1, $4, intermNode))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001721 $$ = $4;
1722 else {
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001723 context->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001724 $$ = 0;
1725 }
1726 }
1727 ;
1728
1729iteration_statement
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001730 : WHILE LEFT_PAREN { context->symbolTable.push(); ++context->loopNestingLevel; } condition RIGHT_PAREN statement_no_new_scope {
1731 context->symbolTable.pop();
Jamie Madill075edd82013-07-08 13:30:19 -04001732 $$ = context->intermediate.addLoop(ELoopWhile, 0, $4, 0, $6, @1);
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001733 --context->loopNestingLevel;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001734 }
daniel@transgaming.com83dc5a72012-03-09 21:57:07 +00001735 | DO { ++context->loopNestingLevel; } statement_with_scope WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON {
Jamie Madill075edd82013-07-08 13:30:19 -04001736 if (context->boolErrorCheck(@8, $6))
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001737 context->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001738
Jamie Madill075edd82013-07-08 13:30:19 -04001739 $$ = context->intermediate.addLoop(ELoopDoWhile, 0, $6, 0, $3, @4);
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001740 --context->loopNestingLevel;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001741 }
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001742 | FOR LEFT_PAREN { context->symbolTable.push(); ++context->loopNestingLevel; } for_init_statement for_rest_statement RIGHT_PAREN statement_no_new_scope {
1743 context->symbolTable.pop();
Jamie Madill075edd82013-07-08 13:30:19 -04001744 $$ = context->intermediate.addLoop(ELoopFor, $4, reinterpret_cast<TIntermTyped*>($5.node1), reinterpret_cast<TIntermTyped*>($5.node2), $7, @1);
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001745 --context->loopNestingLevel;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001746 }
1747 ;
1748
1749for_init_statement
1750 : expression_statement {
1751 $$ = $1;
1752 }
1753 | declaration_statement {
1754 $$ = $1;
1755 }
1756 ;
1757
1758conditionopt
1759 : condition {
1760 $$ = $1;
1761 }
1762 | /* May be null */ {
1763 $$ = 0;
1764 }
1765 ;
1766
1767for_rest_statement
1768 : conditionopt SEMICOLON {
1769 $$.node1 = $1;
1770 $$.node2 = 0;
1771 }
1772 | conditionopt SEMICOLON expression {
1773 $$.node1 = $1;
1774 $$.node2 = $3;
1775 }
1776 ;
1777
1778jump_statement
1779 : CONTINUE SEMICOLON {
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001780 if (context->loopNestingLevel <= 0) {
Jamie Madill075edd82013-07-08 13:30:19 -04001781 context->error(@1, "continue statement only allowed in loops", "");
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001782 context->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001783 }
Jamie Madill075edd82013-07-08 13:30:19 -04001784 $$ = context->intermediate.addBranch(EOpContinue, @1);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001785 }
1786 | BREAK SEMICOLON {
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001787 if (context->loopNestingLevel <= 0) {
Jamie Madill075edd82013-07-08 13:30:19 -04001788 context->error(@1, "break statement only allowed in loops", "");
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001789 context->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001790 }
Jamie Madill075edd82013-07-08 13:30:19 -04001791 $$ = context->intermediate.addBranch(EOpBreak, @1);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001792 }
1793 | RETURN SEMICOLON {
Jamie Madill075edd82013-07-08 13:30:19 -04001794 $$ = context->intermediate.addBranch(EOpReturn, @1);
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001795 if (context->currentFunctionType->getBasicType() != EbtVoid) {
Jamie Madill075edd82013-07-08 13:30:19 -04001796 context->error(@1, "non-void function must return a value", "return");
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001797 context->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001798 }
1799 }
1800 | RETURN expression SEMICOLON {
Jamie Madill075edd82013-07-08 13:30:19 -04001801 $$ = context->intermediate.addBranch(EOpReturn, $2, @1);
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001802 context->functionReturnsValue = true;
1803 if (context->currentFunctionType->getBasicType() == EbtVoid) {
Jamie Madill075edd82013-07-08 13:30:19 -04001804 context->error(@1, "void function cannot return a value", "return");
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001805 context->recover();
1806 } else if (*(context->currentFunctionType) != $2->getType()) {
Jamie Madill075edd82013-07-08 13:30:19 -04001807 context->error(@1, "function return is not matching type:", "return");
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001808 context->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001809 }
1810 }
1811 | DISCARD SEMICOLON {
Jamie Madill075edd82013-07-08 13:30:19 -04001812 FRAG_ONLY("discard", @1);
1813 $$ = context->intermediate.addBranch(EOpKill, @1);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001814 }
1815 ;
1816
1817// Grammar Note: No 'goto'. Gotos are not supported.
1818
1819translation_unit
1820 : external_declaration {
1821 $$ = $1;
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001822 context->treeRoot = $$;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001823 }
1824 | translation_unit external_declaration {
Jamie Madill075edd82013-07-08 13:30:19 -04001825 $$ = context->intermediate.growAggregate($1, $2, @$);
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001826 context->treeRoot = $$;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001827 }
1828 ;
1829
1830external_declaration
1831 : function_definition {
1832 $$ = $1;
1833 }
1834 | declaration {
1835 $$ = $1;
1836 }
1837 ;
1838
1839function_definition
1840 : function_prototype {
alokp@chromium.orgb19403a2010-09-08 17:56:26 +00001841 TFunction* function = $1.function;
daniel@transgaming.coma8833e92012-07-11 20:37:16 +00001842
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +00001843 const TSymbol *builtIn = context->symbolTable.findBuiltIn(function->getMangledName(), context->shaderVersion);
daniel@transgaming.coma8833e92012-07-11 20:37:16 +00001844
1845 if (builtIn)
1846 {
Jamie Madill075edd82013-07-08 13:30:19 -04001847 context->error(@1, "built-in functions cannot be redefined", function->getName().c_str());
daniel@transgaming.coma8833e92012-07-11 20:37:16 +00001848 context->recover();
1849 }
1850
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +00001851 TFunction* prevDec = static_cast<TFunction*>(context->symbolTable.find(function->getMangledName(), context->shaderVersion));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001852 //
1853 // Note: 'prevDec' could be 'function' if this is the first time we've seen function
1854 // as it would have just been put in the symbol table. Otherwise, we're looking up
1855 // an earlier occurance.
1856 //
1857 if (prevDec->isDefined()) {
1858 //
1859 // Then this function already has a body.
1860 //
Jamie Madill075edd82013-07-08 13:30:19 -04001861 context->error(@1, "function already has a body", function->getName().c_str());
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001862 context->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001863 }
1864 prevDec->setDefined();
1865
1866 //
1867 // Raise error message if main function takes any parameters or return anything other than void
1868 //
alokp@chromium.orgb19403a2010-09-08 17:56:26 +00001869 if (function->getName() == "main") {
1870 if (function->getParamCount() > 0) {
Jamie Madill075edd82013-07-08 13:30:19 -04001871 context->error(@1, "function cannot take any parameter(s)", function->getName().c_str());
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001872 context->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001873 }
alokp@chromium.orgb19403a2010-09-08 17:56:26 +00001874 if (function->getReturnType().getBasicType() != EbtVoid) {
Jamie Madill075edd82013-07-08 13:30:19 -04001875 context->error(@1, "", function->getReturnType().getBasicString(), "main function cannot return a value");
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001876 context->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001877 }
1878 }
1879
1880 //
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001881 // Remember the return type for later checking for RETURN statements.
1882 //
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001883 context->currentFunctionType = &(prevDec->getReturnType());
1884 context->functionReturnsValue = false;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001885
1886 //
1887 // Insert parameters into the symbol table.
1888 // If the parameter has no name, it's not an error, just don't insert it
1889 // (could be used for unused args).
1890 //
1891 // Also, accumulate the list of parameters into the HIL, so lower level code
1892 // knows where to find parameters.
1893 //
1894 TIntermAggregate* paramNodes = new TIntermAggregate;
shannon.woods@transgaming.comd64b3da2013-02-28 23:19:26 +00001895 for (size_t i = 0; i < function->getParamCount(); i++) {
alokp@chromium.orgb19403a2010-09-08 17:56:26 +00001896 const TParameter& param = function->getParam(i);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001897 if (param.name != 0) {
1898 TVariable *variable = new TVariable(param.name, *param.type);
1899 //
1900 // Insert the parameters with name in the symbol table.
1901 //
shannonwoods@chromium.org1c848092013-05-30 00:02:34 +00001902 if (! context->symbolTable.declare(*variable)) {
Jamie Madill075edd82013-07-08 13:30:19 -04001903 context->error(@1, "redefinition", variable->getName().c_str());
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001904 context->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001905 delete variable;
1906 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001907
1908 //
1909 // Add the parameter to the HIL
1910 //
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001911 paramNodes = context->intermediate.growAggregate(
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001912 paramNodes,
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001913 context->intermediate.addSymbol(variable->getUniqueId(),
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001914 variable->getName(),
Jamie Madill075edd82013-07-08 13:30:19 -04001915 variable->getType(), @1),
1916 @1);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001917 } else {
Jamie Madill075edd82013-07-08 13:30:19 -04001918 paramNodes = context->intermediate.growAggregate(paramNodes, context->intermediate.addSymbol(0, "", *param.type, @1), @1);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001919 }
1920 }
Jamie Madill075edd82013-07-08 13:30:19 -04001921 context->intermediate.setAggregateOperator(paramNodes, EOpParameters, @1);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001922 $1.intermAggregate = paramNodes;
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001923 context->loopNestingLevel = 0;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001924 }
1925 compound_statement_no_new_scope {
1926 //?? Check that all paths return a value if return type != void ?
1927 // May be best done as post process phase on intermediate code
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001928 if (context->currentFunctionType->getBasicType() != EbtVoid && ! context->functionReturnsValue) {
Jamie Madill075edd82013-07-08 13:30:19 -04001929 context->error(@1, "function does not return a value:", "", $1.function->getName().c_str());
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001930 context->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001931 }
daniel@transgaming.com5dd6d092012-03-20 20:10:28 +00001932
Jamie Madill075edd82013-07-08 13:30:19 -04001933 $$ = context->intermediate.growAggregate($1.intermAggregate, $3, @$);
1934 context->intermediate.setAggregateOperator($$, EOpFunction, @1);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001935 $$->getAsAggregate()->setName($1.function->getMangledName().c_str());
1936 $$->getAsAggregate()->setType($1.function->getReturnType());
1937
1938 // store the pragma information for debug and optimize and other vendor specific
1939 // information. This information can be queried from the parse tree
alokp@chromium.org8b851c62012-06-15 16:25:11 +00001940 $$->getAsAggregate()->setOptimize(context->pragma().optimize);
1941 $$->getAsAggregate()->setDebug(context->pragma().debug);
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001942
daniel@transgaming.com5dd6d092012-03-20 20:10:28 +00001943 context->symbolTable.pop();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001944 }
1945 ;
1946
1947%%
alokp@chromium.org044a5cf2010-11-12 15:42:16 +00001948
1949int glslang_parse(TParseContext* context) {
1950 return yyparse(context);
1951}