blob: a7fe95d83110cdceedcd3129b00b202b76e6ff31 [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
Nicolas Capens16004fc2014-06-11 11:29:11 -04002// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
Geoff Lang0a73dd82014-11-19 16:18:08 -05006#ifndef COMPILER_TRANSLATOR_PARSECONTEXT_H_
7#define COMPILER_TRANSLATOR_PARSECONTEXT_H_
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00008
Jamie Madilld4a3a312014-06-25 16:04:56 -04009#include "compiler/translator/Compiler.h"
Geoff Lang17732822013-08-29 13:46:49 -040010#include "compiler/translator/Diagnostics.h"
11#include "compiler/translator/DirectiveHandler.h"
Jamie Madillb1a85f42014-08-19 15:23:24 -040012#include "compiler/translator/Intermediate.h"
Geoff Lang17732822013-08-29 13:46:49 -040013#include "compiler/translator/SymbolTable.h"
Martin Radev70866b82016-07-22 15:27:42 +030014#include "compiler/translator/QualifierTypes.h"
daniel@transgaming.comb401a922012-10-26 18:58:24 +000015#include "compiler/preprocessor/Preprocessor.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000016
Jamie Madill45bcc782016-11-07 13:58:48 -050017namespace sh
18{
19
Jamie Madill06145232015-05-13 13:10:01 -040020struct TMatrixFields
21{
daniel@transgaming.com0578f812010-05-17 09:58:39 +000022 bool wholeRow;
23 bool wholeCol;
24 int row;
25 int col;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000026};
27
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000028//
29// The following are extra variables needed during parsing, grouped together so
30// they can be passed to the parser without needing a global.
31//
Jamie Madill6e06b1f2015-05-14 10:01:17 -040032class TParseContext : angle::NonCopyable
Jamie Madill06145232015-05-13 13:10:01 -040033{
Jamie Madill6e06b1f2015-05-14 10:01:17 -040034 public:
Jamie Madill06145232015-05-13 13:10:01 -040035 TParseContext(TSymbolTable &symt,
36 TExtensionBehavior &ext,
Jamie Madill06145232015-05-13 13:10:01 -040037 sh::GLenum type,
38 ShShaderSpec spec,
Qiankun Miao7ebb97f2016-09-08 18:01:50 +080039 ShCompileOptions options,
Jamie Madill06145232015-05-13 13:10:01 -040040 bool checksPrecErrors,
Olli Etuaho77ba4082016-12-16 12:01:18 +000041 TDiagnostics *diagnostics,
Jamie Madillacb4b812016-11-07 13:50:29 -050042 const ShBuiltInResources &resources);
jchen104cdac9e2017-05-08 11:01:20 +080043 ~TParseContext();
Jamie Madill06145232015-05-13 13:10:01 -040044
Jamie Madill6e06b1f2015-05-14 10:01:17 -040045 const pp::Preprocessor &getPreprocessor() const { return mPreprocessor; }
46 pp::Preprocessor &getPreprocessor() { return mPreprocessor; }
47 void *getScanner() const { return mScanner; }
48 void setScanner(void *scanner) { mScanner = scanner; }
49 int getShaderVersion() const { return mShaderVersion; }
50 sh::GLenum getShaderType() const { return mShaderType; }
51 ShShaderSpec getShaderSpec() const { return mShaderSpec; }
Olli Etuaho77ba4082016-12-16 12:01:18 +000052 int numErrors() const { return mDiagnostics->numErrors(); }
Olli Etuaho4de340a2016-12-16 09:32:03 +000053 void error(const TSourceLoc &loc, const char *reason, const char *token);
54 void warning(const TSourceLoc &loc, const char *reason, const char *token);
Jamie Madill14e95b32015-05-07 10:10:41 -040055
Olli Etuaho7c3848e2015-11-04 13:19:17 +020056 // If isError is false, a warning will be reported instead.
57 void outOfRangeError(bool isError,
58 const TSourceLoc &loc,
59 const char *reason,
Olli Etuaho4de340a2016-12-16 09:32:03 +000060 const char *token);
Olli Etuaho7c3848e2015-11-04 13:19:17 +020061
Olli Etuaho6d40bbd2016-09-30 13:49:38 +010062 TIntermBlock *getTreeRoot() const { return mTreeRoot; }
63 void setTreeRoot(TIntermBlock *treeRoot) { mTreeRoot = treeRoot; }
Jamie Madill6e06b1f2015-05-14 10:01:17 -040064
Olli Etuahoa6996682015-10-12 14:32:30 +030065 bool getFragmentPrecisionHigh() const
Jamie Madill6e06b1f2015-05-14 10:01:17 -040066 {
Olli Etuahoa6996682015-10-12 14:32:30 +030067 return mFragmentPrecisionHighOnESSL1 || mShaderVersion >= 300;
68 }
69 void setFragmentPrecisionHighOnESSL1(bool fragmentPrecisionHigh)
70 {
71 mFragmentPrecisionHighOnESSL1 = fragmentPrecisionHigh;
Jamie Madill6e06b1f2015-05-14 10:01:17 -040072 }
73
Jamie Madilld7b1ab52016-12-12 14:42:19 -050074 void setLoopNestingLevel(int loopNestintLevel) { mLoopNestingLevel = loopNestintLevel; }
Jamie Madill6e06b1f2015-05-14 10:01:17 -040075
Jamie Madill6e06b1f2015-05-14 10:01:17 -040076 void incrLoopNestingLevel() { ++mLoopNestingLevel; }
77 void decrLoopNestingLevel() { --mLoopNestingLevel; }
78
79 void incrSwitchNestingLevel() { ++mSwitchNestingLevel; }
80 void decrSwitchNestingLevel() { --mSwitchNestingLevel; }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000081
Martin Radev802abe02016-08-04 17:48:32 +030082 bool isComputeShaderLocalSizeDeclared() const { return mComputeShaderLocalSizeDeclared; }
Martin Radev4c4c8e72016-08-04 12:25:34 +030083 sh::WorkGroupSize getComputeShaderLocalSize() const;
Martin Radev802abe02016-08-04 17:48:32 +030084
Olli Etuaho09b04a22016-12-15 13:30:26 +000085 int getNumViews() const { return mNumViews; }
86
Martin Radev70866b82016-07-22 15:27:42 +030087 void enterFunctionDeclaration() { mDeclaringFunction = true; }
88
89 void exitFunctionDeclaration() { mDeclaringFunction = false; }
90
91 bool declaringFunction() const { return mDeclaringFunction; }
92
Jamie Madill5c097022014-08-20 16:38:32 -040093 // This method is guaranteed to succeed, even if no variable with 'name' exists.
Jamie Madilld7b1ab52016-12-12 14:42:19 -050094 const TVariable *getNamedVariable(const TSourceLoc &location,
95 const TString *name,
96 const TSymbol *symbol);
Olli Etuaho82c29ed2015-11-03 13:06:54 +020097 TIntermTyped *parseVariableIdentifier(const TSourceLoc &location,
98 const TString *name,
99 const TSymbol *symbol);
Jamie Madill5c097022014-08-20 16:38:32 -0400100
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500101 bool parseVectorFields(const TString &, int vecSize, TVectorFields &, const TSourceLoc &line);
alokp@chromium.org75fe6b72011-08-14 05:31:22 +0000102
Jamie Madill06145232015-05-13 13:10:01 -0400103 void assignError(const TSourceLoc &line, const char *op, TString left, TString right);
104 void unaryOpError(const TSourceLoc &line, const char *op, TString operand);
105 void binaryOpError(const TSourceLoc &line, const char *op, TString left, TString right);
Olli Etuaho856c4972016-08-08 11:38:39 +0300106
Olli Etuaho8a176262016-08-16 14:23:01 +0300107 // Check functions - the ones that return bool return false if an error was generated.
108
Olli Etuaho856c4972016-08-08 11:38:39 +0300109 bool checkIsNotReserved(const TSourceLoc &line, const TString &identifier);
110 void checkPrecisionSpecified(const TSourceLoc &line, TPrecision precision, TBasicType type);
111 bool checkCanBeLValue(const TSourceLoc &line, const char *op, TIntermTyped *node);
112 void checkIsConst(TIntermTyped *node);
113 void checkIsScalarInteger(TIntermTyped *node, const char *token);
Qiankun Miaof69682b2016-08-16 14:50:42 +0800114 bool checkIsAtGlobalLevel(const TSourceLoc &line, const char *token);
Olli Etuaho856c4972016-08-08 11:38:39 +0300115 bool checkConstructorArguments(const TSourceLoc &line,
Olli Etuahoaf6fc1b2017-01-26 17:45:35 -0800116 const TIntermSequence *arguments,
Olli Etuaho856c4972016-08-08 11:38:39 +0300117 const TType &type);
118
119 // Returns a sanitized array size to use (the size is at least 1).
120 unsigned int checkIsValidArraySize(const TSourceLoc &line, TIntermTyped *expr);
Olli Etuaho8a176262016-08-16 14:23:01 +0300121 bool checkIsValidQualifierForArray(const TSourceLoc &line, const TPublicType &elementQualifier);
122 bool checkIsValidTypeForArray(const TSourceLoc &line, const TPublicType &elementType);
Olli Etuaho856c4972016-08-08 11:38:39 +0300123 bool checkIsNonVoid(const TSourceLoc &line, const TString &identifier, const TBasicType &type);
124 void checkIsScalarBool(const TSourceLoc &line, const TIntermTyped *type);
125 void checkIsScalarBool(const TSourceLoc &line, const TPublicType &pType);
jchen10cc2a10e2017-05-03 14:05:12 +0800126 bool checkIsNotOpaqueType(const TSourceLoc &line,
127 const TTypeSpecifierNonArray &pType,
128 const char *reason);
Olli Etuaho856c4972016-08-08 11:38:39 +0300129 void checkDeclaratorLocationIsNotSpecified(const TSourceLoc &line, const TPublicType &pType);
130 void checkLocationIsNotSpecified(const TSourceLoc &location,
131 const TLayoutQualifier &layoutQualifier);
Olli Etuaho856c4972016-08-08 11:38:39 +0300132 void checkIsParameterQualifierValid(const TSourceLoc &line,
Martin Radev70866b82016-07-22 15:27:42 +0300133 const TTypeQualifierBuilder &typeQualifierBuilder,
Olli Etuaho856c4972016-08-08 11:38:39 +0300134 TType *type);
135 bool checkCanUseExtension(const TSourceLoc &line, const TString &extension);
Olli Etuahobb7e5a72017-04-24 10:16:44 +0300136
137 // Done for all declarations, whether empty or not.
138 void declarationQualifierErrorCheck(const sh::TQualifier qualifier,
139 const sh::TLayoutQualifier &layoutQualifier,
140 const TSourceLoc &location);
141 // Done for the first non-empty declarator in a declaration.
142 void nonEmptyDeclarationErrorCheck(const TPublicType &publicType,
143 const TSourceLoc &identifierLocation);
144 // Done only for empty declarations.
Martin Radevb8b01222016-11-20 23:25:53 +0200145 void emptyDeclarationErrorCheck(const TPublicType &publicType, const TSourceLoc &location);
Olli Etuahobb7e5a72017-04-24 10:16:44 +0300146
Olli Etuaho856c4972016-08-08 11:38:39 +0300147 void checkLayoutQualifierSupported(const TSourceLoc &location,
148 const TString &layoutQualifierName,
149 int versionRequired);
150 bool checkWorkGroupSizeIsNotSpecified(const TSourceLoc &location,
151 const TLayoutQualifier &layoutQualifier);
Olli Etuaho856c4972016-08-08 11:38:39 +0300152 void functionCallLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *fnCall);
Martin Radev70866b82016-07-22 15:27:42 +0300153 void checkInvariantVariableQualifier(bool invariant,
154 const TQualifier qualifier,
155 const TSourceLoc &invariantLocation);
Olli Etuaho856c4972016-08-08 11:38:39 +0300156 void checkInputOutputTypeIsValidES3(const TQualifier qualifier,
157 const TPublicType &type,
158 const TSourceLoc &qualifierLocation);
Martin Radev2cc85b32016-08-05 16:22:53 +0300159 void checkLocalVariableConstStorageQualifier(const TQualifierWrapperBase &qualifier);
Jamie Madill6e06b1f2015-05-14 10:01:17 -0400160 const TPragma &pragma() const { return mDirectiveHandler.pragma(); }
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500161 const TExtensionBehavior &extensionBehavior() const
162 {
163 return mDirectiveHandler.extensionBehavior();
164 }
Jamie Madill06145232015-05-13 13:10:01 -0400165 bool supportsExtension(const char *extension);
166 bool isExtensionEnabled(const char *extension) const;
Olli Etuaho95468d12017-05-04 11:14:34 +0300167 bool isMultiviewExtensionEnabled() const
168 {
169 return mMultiviewAvailable &&
170 (isExtensionEnabled("GL_OVR_multiview") || isExtensionEnabled("GL_OVR_multiview2"));
171 }
Jamie Madill06145232015-05-13 13:10:01 -0400172 void handleExtensionDirective(const TSourceLoc &loc, const char *extName, const char *behavior);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500173 void handlePragmaDirective(const TSourceLoc &loc,
174 const char *name,
175 const char *value,
176 bool stdgl);
alokp@chromium.org75fe6b72011-08-14 05:31:22 +0000177
Olli Etuaho914b79a2017-06-19 16:03:19 +0300178 // Returns true on success. *initNode may still be nullptr on success in case the initialization
179 // is not needed in the AST.
Jamie Madill06145232015-05-13 13:10:01 -0400180 bool executeInitializer(const TSourceLoc &line,
181 const TString &identifier,
182 const TPublicType &pType,
183 TIntermTyped *initializer,
Olli Etuaho13389b62016-10-16 11:48:18 +0100184 TIntermBinary **initNode);
Olli Etuaho914b79a2017-06-19 16:03:19 +0300185 TIntermNode *addConditionInitializer(const TPublicType &pType,
186 const TString &identifier,
187 TIntermTyped *initializer,
188 const TSourceLoc &loc);
189 TIntermNode *addLoop(TLoopType type,
190 TIntermNode *init,
191 TIntermNode *cond,
192 TIntermTyped *expr,
193 TIntermNode *body,
194 const TSourceLoc &loc);
alokp@chromium.org75fe6b72011-08-14 05:31:22 +0000195
Olli Etuahocce89652017-06-19 16:04:09 +0300196 // For "if" test nodes. There are three children: a condition, a true path, and a false path.
197 // The two paths are in TIntermNodePair code.
198 TIntermNode *addIfElse(TIntermTyped *cond, TIntermNodePair code, const TSourceLoc &loc);
199
Olli Etuaho0e3aee32016-10-27 12:56:38 +0100200 void addFullySpecifiedType(TPublicType *typeSpecifier);
Martin Radev70866b82016-07-22 15:27:42 +0300201 TPublicType addFullySpecifiedType(const TTypeQualifierBuilder &typeQualifierBuilder,
Jamie Madill06145232015-05-13 13:10:01 -0400202 const TPublicType &typeSpecifier);
Olli Etuahoe7847b02015-03-16 11:56:12 +0200203
Olli Etuaho13389b62016-10-16 11:48:18 +0100204 TIntermDeclaration *parseSingleDeclaration(TPublicType &publicType,
205 const TSourceLoc &identifierOrTypeLocation,
206 const TString &identifier);
207 TIntermDeclaration *parseSingleArrayDeclaration(TPublicType &publicType,
208 const TSourceLoc &identifierLocation,
209 const TString &identifier,
210 const TSourceLoc &indexLocation,
211 TIntermTyped *indexExpression);
212 TIntermDeclaration *parseSingleInitDeclaration(const TPublicType &publicType,
213 const TSourceLoc &identifierLocation,
214 const TString &identifier,
215 const TSourceLoc &initLocation,
216 TIntermTyped *initializer);
Jamie Madill47e3ec02014-08-20 16:38:33 -0400217
Olli Etuaho3875ffd2015-04-10 16:45:14 +0300218 // Parse a declaration like "type a[n] = initializer"
219 // Note that this does not apply to declarations like "type[n] a = initializer"
Olli Etuaho13389b62016-10-16 11:48:18 +0100220 TIntermDeclaration *parseSingleArrayInitDeclaration(TPublicType &publicType,
221 const TSourceLoc &identifierLocation,
222 const TString &identifier,
223 const TSourceLoc &indexLocation,
224 TIntermTyped *indexExpression,
225 const TSourceLoc &initLocation,
226 TIntermTyped *initializer);
Olli Etuaho3875ffd2015-04-10 16:45:14 +0300227
Olli Etuahobf4e1b72016-12-09 11:30:15 +0000228 TIntermInvariantDeclaration *parseInvariantDeclaration(
229 const TTypeQualifierBuilder &typeQualifierBuilder,
230 const TSourceLoc &identifierLoc,
231 const TString *identifier,
232 const TSymbol *symbol);
Olli Etuahoe7847b02015-03-16 11:56:12 +0200233
Olli Etuaho13389b62016-10-16 11:48:18 +0100234 void parseDeclarator(TPublicType &publicType,
235 const TSourceLoc &identifierLocation,
236 const TString &identifier,
237 TIntermDeclaration *declarationOut);
238 void parseArrayDeclarator(TPublicType &publicType,
239 const TSourceLoc &identifierLocation,
240 const TString &identifier,
241 const TSourceLoc &arrayLocation,
242 TIntermTyped *indexExpression,
243 TIntermDeclaration *declarationOut);
244 void parseInitDeclarator(const TPublicType &publicType,
245 const TSourceLoc &identifierLocation,
246 const TString &identifier,
247 const TSourceLoc &initLocation,
248 TIntermTyped *initializer,
249 TIntermDeclaration *declarationOut);
Olli Etuahoe7847b02015-03-16 11:56:12 +0200250
Olli Etuaho3875ffd2015-04-10 16:45:14 +0300251 // Parse a declarator like "a[n] = initializer"
Olli Etuaho13389b62016-10-16 11:48:18 +0100252 void parseArrayInitDeclarator(const TPublicType &publicType,
253 const TSourceLoc &identifierLocation,
254 const TString &identifier,
255 const TSourceLoc &indexLocation,
256 TIntermTyped *indexExpression,
257 const TSourceLoc &initLocation,
258 TIntermTyped *initializer,
259 TIntermDeclaration *declarationOut);
Olli Etuaho3875ffd2015-04-10 16:45:14 +0300260
Olli Etuahocce89652017-06-19 16:04:09 +0300261 void parseDefaultPrecisionQualifier(const TPrecision precision,
262 const TPublicType &type,
263 const TSourceLoc &loc);
Martin Radev70866b82016-07-22 15:27:42 +0300264 void parseGlobalLayoutQualifier(const TTypeQualifierBuilder &typeQualifierBuilder);
Olli Etuahocce89652017-06-19 16:04:09 +0300265
Olli Etuaho16c745a2017-01-16 17:02:27 +0000266 TIntermFunctionPrototype *addFunctionPrototypeDeclaration(const TFunction &parsedFunction,
267 const TSourceLoc &location);
Olli Etuaho8ad9e752017-01-16 19:55:20 +0000268 TIntermFunctionDefinition *addFunctionDefinition(TIntermFunctionPrototype *functionPrototype,
Olli Etuaho336b1472016-10-05 16:37:55 +0100269 TIntermBlock *functionBody,
270 const TSourceLoc &location);
Olli Etuaho476197f2016-10-11 13:59:08 +0100271 void parseFunctionDefinitionHeader(const TSourceLoc &location,
272 TFunction **function,
Olli Etuaho8ad9e752017-01-16 19:55:20 +0000273 TIntermFunctionPrototype **prototypeOut);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500274 TFunction *parseFunctionDeclarator(const TSourceLoc &location, TFunction *function);
Olli Etuaho9de84a52016-06-14 17:36:01 +0300275 TFunction *parseFunctionHeader(const TPublicType &type,
276 const TString *name,
277 const TSourceLoc &location);
Olli Etuahocce89652017-06-19 16:04:09 +0300278 TFunction *addNonConstructorFunc(const TString *name, const TSourceLoc &loc);
Jamie Madill06145232015-05-13 13:10:01 -0400279 TFunction *addConstructorFunc(const TPublicType &publicType);
Olli Etuahocce89652017-06-19 16:04:09 +0300280 TParameter parseParameterDeclarator(const TPublicType &publicType,
281 const TString *name,
282 const TSourceLoc &nameLoc);
283 TParameter parseParameterArrayDeclarator(const TString *identifier,
284 const TSourceLoc &identifierLoc,
285 TIntermTyped *arraySize,
286 const TSourceLoc &arrayLoc,
287 TPublicType *type);
Olli Etuaho90892fb2016-07-14 14:44:51 +0300288
Jamie Madill06145232015-05-13 13:10:01 -0400289 TIntermTyped *addIndexExpression(TIntermTyped *baseExpression,
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500290 const TSourceLoc &location,
Jamie Madill06145232015-05-13 13:10:01 -0400291 TIntermTyped *indexExpression);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500292 TIntermTyped *addFieldSelectionExpression(TIntermTyped *baseExpression,
Jamie Madill06145232015-05-13 13:10:01 -0400293 const TSourceLoc &dotLocation,
294 const TString &fieldString,
295 const TSourceLoc &fieldLocation);
shannonwoods@chromium.orga9100882013-05-30 00:11:39 +0000296
Olli Etuahocce89652017-06-19 16:04:09 +0300297 // Parse declarator for a single field
298 TField *parseStructDeclarator(TString *identifier, const TSourceLoc &loc);
299 TField *parseStructArrayDeclarator(TString *identifier,
300 const TSourceLoc &loc,
301 TIntermTyped *arraySize,
302 const TSourceLoc &arraySizeLoc);
303
Olli Etuaho4de340a2016-12-16 09:32:03 +0000304 TFieldList *combineStructFieldLists(TFieldList *processedFields,
305 const TFieldList *newlyAddedFields,
306 const TSourceLoc &location);
Martin Radev70866b82016-07-22 15:27:42 +0300307 TFieldList *addStructDeclaratorListWithQualifiers(
308 const TTypeQualifierBuilder &typeQualifierBuilder,
309 TPublicType *typeSpecifier,
310 TFieldList *fieldList);
Jamie Madill06145232015-05-13 13:10:01 -0400311 TFieldList *addStructDeclaratorList(const TPublicType &typeSpecifier, TFieldList *fieldList);
Martin Radev4a9cd802016-09-01 16:51:51 +0300312 TTypeSpecifierNonArray addStructure(const TSourceLoc &structLine,
313 const TSourceLoc &nameLine,
314 const TString *structName,
315 TFieldList *fieldList);
kbr@chromium.org476541f2011-10-27 21:14:51 +0000316
Olli Etuaho13389b62016-10-16 11:48:18 +0100317 TIntermDeclaration *addInterfaceBlock(const TTypeQualifierBuilder &typeQualifierBuilder,
318 const TSourceLoc &nameLine,
319 const TString &blockName,
320 TFieldList *fieldList,
321 const TString *instanceName,
322 const TSourceLoc &instanceLine,
323 TIntermTyped *arrayIndex,
324 const TSourceLoc &arrayIndexLine);
shannonwoods@chromium.org5668c5d2013-05-30 00:11:48 +0000325
Martin Radev802abe02016-08-04 17:48:32 +0300326 void parseLocalSize(const TString &qualifierType,
327 const TSourceLoc &qualifierTypeLine,
328 int intValue,
329 const TSourceLoc &intValueLine,
330 const std::string &intValueString,
331 size_t index,
Martin Radev4c4c8e72016-08-04 12:25:34 +0300332 sh::WorkGroupSize *localSize);
Olli Etuaho09b04a22016-12-15 13:30:26 +0000333 void parseNumViews(int intValue,
334 const TSourceLoc &intValueLine,
335 const std::string &intValueString,
336 int *numViews);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500337 TLayoutQualifier parseLayoutQualifier(const TString &qualifierType,
338 const TSourceLoc &qualifierTypeLine);
Jamie Madill06145232015-05-13 13:10:01 -0400339 TLayoutQualifier parseLayoutQualifier(const TString &qualifierType,
340 const TSourceLoc &qualifierTypeLine,
Jamie Madill06145232015-05-13 13:10:01 -0400341 int intValue,
342 const TSourceLoc &intValueLine);
Olli Etuaho613b9592016-09-05 12:05:53 +0300343 TTypeQualifierBuilder *createTypeQualifierBuilder(const TSourceLoc &loc);
Olli Etuahocce89652017-06-19 16:04:09 +0300344 TStorageQualifierWrapper *parseGlobalStorageQualifier(TQualifier qualifier,
345 const TSourceLoc &loc);
346 TStorageQualifierWrapper *parseVaryingQualifier(const TSourceLoc &loc);
347 TStorageQualifierWrapper *parseInQualifier(const TSourceLoc &loc);
348 TStorageQualifierWrapper *parseOutQualifier(const TSourceLoc &loc);
349 TStorageQualifierWrapper *parseInOutQualifier(const TSourceLoc &loc);
Martin Radev802abe02016-08-04 17:48:32 +0300350 TLayoutQualifier joinLayoutQualifiers(TLayoutQualifier leftQualifier,
351 TLayoutQualifier rightQualifier,
352 const TSourceLoc &rightQualifierLocation);
shannonwoods@chromium.org302adfe2013-05-30 00:21:06 +0000353
kbr@chromium.org476541f2011-10-27 21:14:51 +0000354 // Performs an error check for embedded struct declarations.
Olli Etuaho383b7912016-08-05 11:22:59 +0300355 void enterStructDeclaration(const TSourceLoc &line, const TString &identifier);
kbr@chromium.org476541f2011-10-27 21:14:51 +0000356 void exitStructDeclaration();
357
Olli Etuaho8a176262016-08-16 14:23:01 +0300358 void checkIsBelowStructNestingLimit(const TSourceLoc &line, const TField &field);
Olli Etuaho09b22472015-02-11 11:47:26 +0200359
Olli Etuaho6d40bbd2016-09-30 13:49:38 +0100360 TIntermSwitch *addSwitch(TIntermTyped *init,
361 TIntermBlock *statementList,
362 const TSourceLoc &loc);
Olli Etuahoa3a36662015-02-17 13:46:51 +0200363 TIntermCase *addCase(TIntermTyped *condition, const TSourceLoc &loc);
364 TIntermCase *addDefault(const TSourceLoc &loc);
365
Jamie Madill06145232015-05-13 13:10:01 -0400366 TIntermTyped *addUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc);
367 TIntermTyped *addUnaryMathLValue(TOperator op, TIntermTyped *child, const TSourceLoc &loc);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500368 TIntermTyped *addBinaryMath(TOperator op,
369 TIntermTyped *left,
370 TIntermTyped *right,
371 const TSourceLoc &loc);
372 TIntermTyped *addBinaryMathBooleanResult(TOperator op,
373 TIntermTyped *left,
374 TIntermTyped *right,
375 const TSourceLoc &loc);
376 TIntermTyped *addAssign(TOperator op,
377 TIntermTyped *left,
378 TIntermTyped *right,
379 const TSourceLoc &loc);
Olli Etuaho49300862015-02-20 14:54:49 +0200380
Olli Etuaho0b2d2dc2015-11-04 16:35:32 +0200381 TIntermTyped *addComma(TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc);
382
Olli Etuaho49300862015-02-20 14:54:49 +0200383 TIntermBranch *addBranch(TOperator op, const TSourceLoc &loc);
Olli Etuahocce89652017-06-19 16:04:09 +0300384 TIntermBranch *addBranch(TOperator op, TIntermTyped *expression, const TSourceLoc &loc);
Olli Etuahoc4ba3be2015-03-02 14:42:24 +0200385
Olli Etuahoe1a94c62015-11-16 17:35:25 +0200386 void checkTextureOffsetConst(TIntermAggregate *functionCall);
Martin Radev2cc85b32016-08-05 16:22:53 +0300387 void checkImageMemoryAccessForBuiltinFunctions(TIntermAggregate *functionCall);
388 void checkImageMemoryAccessForUserDefinedFunctions(const TFunction *functionDefinition,
389 const TIntermAggregate *functionCall);
Olli Etuahoaf6fc1b2017-01-26 17:45:35 -0800390 TIntermSequence *createEmptyArgumentsList();
Olli Etuaho72d10202017-01-19 15:58:30 +0000391
Olli Etuahoaf6fc1b2017-01-26 17:45:35 -0800392 // fnCall is only storing the built-in op, and function name or constructor type. arguments
Olli Etuaho72d10202017-01-19 15:58:30 +0000393 // has the arguments.
Jamie Madill06145232015-05-13 13:10:01 -0400394 TIntermTyped *addFunctionCallOrMethod(TFunction *fnCall,
Olli Etuahoaf6fc1b2017-01-26 17:45:35 -0800395 TIntermSequence *arguments,
Jamie Madill06145232015-05-13 13:10:01 -0400396 TIntermNode *thisNode,
Olli Etuaho72d10202017-01-19 15:58:30 +0000397 const TSourceLoc &loc);
Olli Etuahofc1806e2015-03-17 13:03:11 +0200398
Olli Etuahod0bad2c2016-09-09 18:01:16 +0300399 TIntermTyped *addTernarySelection(TIntermTyped *cond,
400 TIntermTyped *trueExpression,
401 TIntermTyped *falseExpression,
402 const TSourceLoc &line);
Olli Etuaho52901742015-04-15 13:42:45 +0300403
Jamie Madill6e06b1f2015-05-14 10:01:17 -0400404 // TODO(jmadill): make these private
Olli Etuahof119a262016-08-19 15:54:22 +0300405 TIntermediate intermediate; // to build a parse tree
Jamie Madill6e06b1f2015-05-14 10:01:17 -0400406 TSymbolTable &symbolTable; // symbol table that goes with the language currently being parsed
407
Olli Etuahofc1806e2015-03-17 13:03:11 +0200408 private:
jchen104cdac9e2017-05-08 11:01:20 +0800409 class AtomicCounterBindingState;
410 constexpr static size_t kAtomicCounterSize = 4;
411 // UNIFORM_ARRAY_STRIDE for atomic counter arrays is an implementation-dependent value which
412 // can be queried after a program is linked according to ES 3.10 section 7.7.1. This is
413 // controversial with the offset inheritance as described in ESSL 3.10 section 4.4.6. Currently
414 // we treat it as always 4 in favour of the original interpretation in
415 // "ARB_shader_atomic_counters".
416 // TODO(jie.a.chen@intel.com): Double check this once the spec vagueness is resolved.
417 constexpr static size_t kAtomicCounterArrayStride = 4;
418
Olli Etuaho4de340a2016-12-16 09:32:03 +0000419 // Returns a clamped index. If it prints out an error message, the token is "[]".
Olli Etuaho90892fb2016-07-14 14:44:51 +0300420 int checkIndexOutOfRange(bool outOfRangeIndexIsError,
421 const TSourceLoc &location,
422 int index,
423 int arraySize,
Olli Etuaho4de340a2016-12-16 09:32:03 +0000424 const char *reason);
Olli Etuaho90892fb2016-07-14 14:44:51 +0300425
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500426 bool declareVariable(const TSourceLoc &line,
427 const TString &identifier,
428 const TType &type,
429 TVariable **variable);
Olli Etuaho2935c582015-04-08 14:32:06 +0300430
Olli Etuaho856c4972016-08-08 11:38:39 +0300431 void checkCanBeDeclaredWithoutInitializer(const TSourceLoc &line,
432 const TString &identifier,
433 TPublicType *type);
Olli Etuaho376f1b52015-04-13 13:23:41 +0300434
Olli Etuaho8a176262016-08-16 14:23:01 +0300435 bool checkIsValidTypeAndQualifierForArray(const TSourceLoc &indexLocation,
436 const TPublicType &elementType);
jchen104cdac9e2017-05-08 11:01:20 +0800437 // Done for all atomic counter declarations, whether empty or not.
438 void atomicCounterQualifierErrorCheck(const TPublicType &publicType,
439 const TSourceLoc &location);
Olli Etuaho8a176262016-08-16 14:23:01 +0300440
Olli Etuaho1dded802016-08-18 18:13:13 +0300441 // Assumes that multiplication op has already been set based on the types.
442 bool isMultiplicationTypeCombinationValid(TOperator op, const TType &left, const TType &right);
443
Martin Radev2cc85b32016-08-05 16:22:53 +0300444 void checkOutParameterIsNotOpaqueType(const TSourceLoc &line,
445 TQualifier qualifier,
446 const TType &type);
Martin Radev2cc85b32016-08-05 16:22:53 +0300447
Olli Etuaho43364892017-02-13 16:00:12 +0000448 void checkInternalFormatIsNotSpecified(const TSourceLoc &location,
449 TLayoutImageInternalFormat internalFormat);
450 void checkMemoryQualifierIsNotSpecified(const TMemoryQualifier &memoryQualifier,
451 const TSourceLoc &location);
jchen104cdac9e2017-05-08 11:01:20 +0800452 void checkAtomicCounterOffsetIsNotOverlapped(TPublicType &publicType,
453 size_t size,
454 bool forceAppend,
455 const TSourceLoc &loc,
456 TType &type);
Olli Etuaho43364892017-02-13 16:00:12 +0000457 void checkBindingIsValid(const TSourceLoc &identifierLocation, const TType &type);
458 void checkBindingIsNotSpecified(const TSourceLoc &location, int binding);
jchen104cdac9e2017-05-08 11:01:20 +0800459 void checkOffsetIsNotSpecified(const TSourceLoc &location, int offset);
Olli Etuaho43364892017-02-13 16:00:12 +0000460 void checkImageBindingIsValid(const TSourceLoc &location, int binding, int arraySize);
461 void checkSamplerBindingIsValid(const TSourceLoc &location, int binding, int arraySize);
jchen10af713a22017-04-19 09:10:56 +0800462 void checkBlockBindingIsValid(const TSourceLoc &location, int binding, int arraySize);
jchen104cdac9e2017-05-08 11:01:20 +0800463 void checkAtomicCounterBindingIsValid(const TSourceLoc &location, int binding);
Olli Etuaho43364892017-02-13 16:00:12 +0000464
Olli Etuaho6ca2b652017-02-19 18:05:10 +0000465 void checkUniformLocationInRange(const TSourceLoc &location,
466 int objectLocationCount,
467 const TLayoutQualifier &layoutQualifier);
468
Andrei Volykhina5527072017-03-22 16:46:30 +0300469 void checkYuvIsNotSpecified(const TSourceLoc &location, bool yuv);
470
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500471 TIntermTyped *addBinaryMathInternal(TOperator op,
472 TIntermTyped *left,
473 TIntermTyped *right,
474 const TSourceLoc &loc);
Olli Etuaho13389b62016-10-16 11:48:18 +0100475 TIntermBinary *createAssign(TOperator op,
476 TIntermTyped *left,
477 TIntermTyped *right,
478 const TSourceLoc &loc);
Olli Etuahoaf6fc1b2017-01-26 17:45:35 -0800479 TIntermTyped *createUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc);
480
481 TIntermTyped *addMethod(TFunction *fnCall,
482 TIntermSequence *arguments,
483 TIntermNode *thisNode,
484 const TSourceLoc &loc);
485 TIntermTyped *addConstructor(TIntermSequence *arguments,
Olli Etuahoaf6fc1b2017-01-26 17:45:35 -0800486 TType type,
487 const TSourceLoc &line);
488 TIntermTyped *addNonConstructorFunctionCall(TFunction *fnCall,
489 TIntermSequence *arguments,
490 const TSourceLoc &loc);
Olli Etuahod6b14282015-03-17 14:31:35 +0200491
Olli Etuaho47fd36a2015-03-19 14:22:24 +0200492 // Return true if the checks pass
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500493 bool binaryOpCommonCheck(TOperator op,
494 TIntermTyped *left,
495 TIntermTyped *right,
496 const TSourceLoc &loc);
Olli Etuahofa33d582015-04-09 14:33:12 +0300497
Olli Etuaho8ad9e752017-01-16 19:55:20 +0000498 TIntermFunctionPrototype *createPrototypeNodeFromFunction(const TFunction &function,
499 const TSourceLoc &location,
500 bool insertParametersToSymbolTable);
501
jchen104cdac9e2017-05-08 11:01:20 +0800502 void setAtomicCounterBindingDefaultOffset(const TPublicType &declaration,
503 const TSourceLoc &location);
504
Olli Etuahobb7e5a72017-04-24 10:16:44 +0300505 // Set to true when the last/current declarator list was started with an empty declaration. The
506 // non-empty declaration error check will need to be performed if the empty declaration is
507 // followed by a declarator.
508 bool mDeferredNonEmptyDeclarationErrorCheck;
Jamie Madill6e06b1f2015-05-14 10:01:17 -0400509
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500510 sh::GLenum mShaderType; // vertex or fragment language (future: pack or unpack)
Qiankun Miao7ebb97f2016-09-08 18:01:50 +0800511 ShShaderSpec mShaderSpec; // The language specification compiler conforms to - GLES2 or WebGL.
512 ShCompileOptions mCompileOptions; // Options passed to TCompiler
Jamie Madill6e06b1f2015-05-14 10:01:17 -0400513 int mShaderVersion;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500514 TIntermBlock *mTreeRoot; // root of parse tree being created
515 int mLoopNestingLevel; // 0 if outside all loops
516 int mStructNestingLevel; // incremented while parsing a struct declaration
517 int mSwitchNestingLevel; // 0 if outside all switch statements
Qiankun Miao7ebb97f2016-09-08 18:01:50 +0800518 const TType
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500519 *mCurrentFunctionType; // the return type of the function that's currently being parsed
520 bool mFunctionReturnsValue; // true if a non-void function has a return
Qiankun Miao7ebb97f2016-09-08 18:01:50 +0800521 bool mChecksPrecisionErrors; // true if an error will be generated when a variable is declared
522 // without precision, explicit or implicit.
Olli Etuahoa6996682015-10-12 14:32:30 +0300523 bool mFragmentPrecisionHighOnESSL1; // true if highp precision is supported when compiling
524 // ESSL1.
Jamie Madill6e06b1f2015-05-14 10:01:17 -0400525 TLayoutMatrixPacking mDefaultMatrixPacking;
526 TLayoutBlockStorage mDefaultBlockStorage;
527 TString mHashErrMsg;
Olli Etuaho77ba4082016-12-16 12:01:18 +0000528 TDiagnostics *mDiagnostics;
Jamie Madill6e06b1f2015-05-14 10:01:17 -0400529 TDirectiveHandler mDirectiveHandler;
530 pp::Preprocessor mPreprocessor;
531 void *mScanner;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500532 bool mUsesFragData; // track if we are using both gl_FragData and gl_FragColor
Jamie Madill14e95b32015-05-07 10:10:41 -0400533 bool mUsesFragColor;
Kimmo Kinnunenb18609b2015-07-16 14:13:11 +0300534 bool mUsesSecondaryOutputs; // Track if we are using either gl_SecondaryFragData or
535 // gl_Secondary FragColor or both.
Olli Etuahoe1a94c62015-11-16 17:35:25 +0200536 int mMinProgramTexelOffset;
537 int mMaxProgramTexelOffset;
Martin Radev802abe02016-08-04 17:48:32 +0300538
Olli Etuaho09b04a22016-12-15 13:30:26 +0000539 bool mMultiviewAvailable;
540
Martin Radev802abe02016-08-04 17:48:32 +0300541 // keep track of local group size declared in layout. It should be declared only once.
542 bool mComputeShaderLocalSizeDeclared;
Martin Radev4c4c8e72016-08-04 12:25:34 +0300543 sh::WorkGroupSize mComputeShaderLocalSize;
Olli Etuaho09b04a22016-12-15 13:30:26 +0000544 // keep track of number of views declared in layout.
545 int mNumViews;
546 int mMaxNumViews;
Olli Etuaho43364892017-02-13 16:00:12 +0000547 int mMaxImageUnits;
548 int mMaxCombinedTextureImageUnits;
Olli Etuaho6ca2b652017-02-19 18:05:10 +0000549 int mMaxUniformLocations;
jchen10af713a22017-04-19 09:10:56 +0800550 int mMaxUniformBufferBindings;
jchen104cdac9e2017-05-08 11:01:20 +0800551 int mMaxAtomicCounterBindings;
552
Martin Radev70866b82016-07-22 15:27:42 +0300553 // keeps track whether we are declaring / defining a function
554 bool mDeclaringFunction;
jchen104cdac9e2017-05-08 11:01:20 +0800555
556 // Track the state of each atomic counter binding.
557 std::map<int, AtomicCounterBindingState> mAtomicCounterBindingStates;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000558};
559
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500560int PaParseStrings(size_t count,
561 const char *const string[],
562 const int length[],
563 TParseContext *context);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000564
Jamie Madill45bcc782016-11-07 13:58:48 -0500565} // namespace sh
566
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500567#endif // COMPILER_TRANSLATOR_PARSECONTEXT_H_