blob: 12924d1c9ca60a59d6536ba9f28dc81cccf2a89f [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"
Geoff Lang17732822013-08-29 13:46:49 -040012#include "compiler/translator/SymbolTable.h"
Martin Radev70866b82016-07-22 15:27:42 +030013#include "compiler/translator/QualifierTypes.h"
daniel@transgaming.comb401a922012-10-26 18:58:24 +000014#include "compiler/preprocessor/Preprocessor.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000015
Jamie Madill45bcc782016-11-07 13:58:48 -050016namespace sh
17{
18
Jamie Madill06145232015-05-13 13:10:01 -040019struct TMatrixFields
20{
daniel@transgaming.com0578f812010-05-17 09:58:39 +000021 bool wholeRow;
22 bool wholeCol;
23 int row;
24 int col;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000025};
26
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000027//
28// The following are extra variables needed during parsing, grouped together so
29// they can be passed to the parser without needing a global.
30//
Jamie Madill6e06b1f2015-05-14 10:01:17 -040031class TParseContext : angle::NonCopyable
Jamie Madill06145232015-05-13 13:10:01 -040032{
Jamie Madill6e06b1f2015-05-14 10:01:17 -040033 public:
Jamie Madill06145232015-05-13 13:10:01 -040034 TParseContext(TSymbolTable &symt,
35 TExtensionBehavior &ext,
Jamie Madill06145232015-05-13 13:10:01 -040036 sh::GLenum type,
37 ShShaderSpec spec,
Qiankun Miao7ebb97f2016-09-08 18:01:50 +080038 ShCompileOptions options,
Jamie Madill06145232015-05-13 13:10:01 -040039 bool checksPrecErrors,
Olli Etuaho77ba4082016-12-16 12:01:18 +000040 TDiagnostics *diagnostics,
Jamie Madillacb4b812016-11-07 13:50:29 -050041 const ShBuiltInResources &resources);
jchen104cdac9e2017-05-08 11:01:20 +080042 ~TParseContext();
Jamie Madill06145232015-05-13 13:10:01 -040043
Jamie Madill6e06b1f2015-05-14 10:01:17 -040044 const pp::Preprocessor &getPreprocessor() const { return mPreprocessor; }
45 pp::Preprocessor &getPreprocessor() { return mPreprocessor; }
46 void *getScanner() const { return mScanner; }
47 void setScanner(void *scanner) { mScanner = scanner; }
48 int getShaderVersion() const { return mShaderVersion; }
49 sh::GLenum getShaderType() const { return mShaderType; }
50 ShShaderSpec getShaderSpec() const { return mShaderSpec; }
Olli Etuaho77ba4082016-12-16 12:01:18 +000051 int numErrors() const { return mDiagnostics->numErrors(); }
Olli Etuaho4de340a2016-12-16 09:32:03 +000052 void error(const TSourceLoc &loc, const char *reason, const char *token);
53 void warning(const TSourceLoc &loc, const char *reason, const char *token);
Jamie Madill14e95b32015-05-07 10:10:41 -040054
Olli Etuaho7c3848e2015-11-04 13:19:17 +020055 // If isError is false, a warning will be reported instead.
56 void outOfRangeError(bool isError,
57 const TSourceLoc &loc,
58 const char *reason,
Olli Etuaho4de340a2016-12-16 09:32:03 +000059 const char *token);
Olli Etuaho7c3848e2015-11-04 13:19:17 +020060
Olli Etuaho6d40bbd2016-09-30 13:49:38 +010061 TIntermBlock *getTreeRoot() const { return mTreeRoot; }
62 void setTreeRoot(TIntermBlock *treeRoot) { mTreeRoot = treeRoot; }
Jamie Madill6e06b1f2015-05-14 10:01:17 -040063
Olli Etuahoa6996682015-10-12 14:32:30 +030064 bool getFragmentPrecisionHigh() const
Jamie Madill6e06b1f2015-05-14 10:01:17 -040065 {
Olli Etuahoa6996682015-10-12 14:32:30 +030066 return mFragmentPrecisionHighOnESSL1 || mShaderVersion >= 300;
67 }
68 void setFragmentPrecisionHighOnESSL1(bool fragmentPrecisionHigh)
69 {
70 mFragmentPrecisionHighOnESSL1 = fragmentPrecisionHigh;
Jamie Madill6e06b1f2015-05-14 10:01:17 -040071 }
72
Jamie Madilld7b1ab52016-12-12 14:42:19 -050073 void setLoopNestingLevel(int loopNestintLevel) { mLoopNestingLevel = loopNestintLevel; }
Jamie Madill6e06b1f2015-05-14 10:01:17 -040074
Jamie Madill6e06b1f2015-05-14 10:01:17 -040075 void incrLoopNestingLevel() { ++mLoopNestingLevel; }
76 void decrLoopNestingLevel() { --mLoopNestingLevel; }
77
78 void incrSwitchNestingLevel() { ++mSwitchNestingLevel; }
79 void decrSwitchNestingLevel() { --mSwitchNestingLevel; }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000080
Martin Radev802abe02016-08-04 17:48:32 +030081 bool isComputeShaderLocalSizeDeclared() const { return mComputeShaderLocalSizeDeclared; }
Martin Radev4c4c8e72016-08-04 12:25:34 +030082 sh::WorkGroupSize getComputeShaderLocalSize() const;
Martin Radev802abe02016-08-04 17:48:32 +030083
Olli Etuaho09b04a22016-12-15 13:30:26 +000084 int getNumViews() const { return mNumViews; }
85
Martin Radev70866b82016-07-22 15:27:42 +030086 void enterFunctionDeclaration() { mDeclaringFunction = true; }
87
88 void exitFunctionDeclaration() { mDeclaringFunction = false; }
89
90 bool declaringFunction() const { return mDeclaringFunction; }
91
Olli Etuaho56229f12017-07-10 14:16:33 +030092 TIntermConstantUnion *addScalarLiteral(const TConstantUnion *constantUnion,
93 const TSourceLoc &line);
94
Jamie Madill5c097022014-08-20 16:38:32 -040095 // This method is guaranteed to succeed, even if no variable with 'name' exists.
Jamie Madilld7b1ab52016-12-12 14:42:19 -050096 const TVariable *getNamedVariable(const TSourceLoc &location,
97 const TString *name,
98 const TSymbol *symbol);
Olli Etuaho82c29ed2015-11-03 13:06:54 +020099 TIntermTyped *parseVariableIdentifier(const TSourceLoc &location,
100 const TString *name,
101 const TSymbol *symbol);
Jamie Madill5c097022014-08-20 16:38:32 -0400102
Olli Etuahoeb7f90f2017-07-07 17:25:23 +0300103 // Look at a '.' field selector string and change it into offsets for a vector.
104 bool parseVectorFields(const TSourceLoc &line,
105 const TString &compString,
106 int vecSize,
107 TVector<int> *fieldOffsets);
alokp@chromium.org75fe6b72011-08-14 05:31:22 +0000108
Jamie Madill06145232015-05-13 13:10:01 -0400109 void assignError(const TSourceLoc &line, const char *op, TString left, TString right);
110 void unaryOpError(const TSourceLoc &line, const char *op, TString operand);
111 void binaryOpError(const TSourceLoc &line, const char *op, TString left, TString right);
Olli Etuaho856c4972016-08-08 11:38:39 +0300112
Olli Etuaho8a176262016-08-16 14:23:01 +0300113 // Check functions - the ones that return bool return false if an error was generated.
114
Olli Etuaho856c4972016-08-08 11:38:39 +0300115 bool checkIsNotReserved(const TSourceLoc &line, const TString &identifier);
116 void checkPrecisionSpecified(const TSourceLoc &line, TPrecision precision, TBasicType type);
117 bool checkCanBeLValue(const TSourceLoc &line, const char *op, TIntermTyped *node);
118 void checkIsConst(TIntermTyped *node);
119 void checkIsScalarInteger(TIntermTyped *node, const char *token);
Qiankun Miaof69682b2016-08-16 14:50:42 +0800120 bool checkIsAtGlobalLevel(const TSourceLoc &line, const char *token);
Olli Etuaho856c4972016-08-08 11:38:39 +0300121 bool checkConstructorArguments(const TSourceLoc &line,
Olli Etuahoaf6fc1b2017-01-26 17:45:35 -0800122 const TIntermSequence *arguments,
Olli Etuaho856c4972016-08-08 11:38:39 +0300123 const TType &type);
124
125 // Returns a sanitized array size to use (the size is at least 1).
126 unsigned int checkIsValidArraySize(const TSourceLoc &line, TIntermTyped *expr);
Olli Etuaho8a176262016-08-16 14:23:01 +0300127 bool checkIsValidQualifierForArray(const TSourceLoc &line, const TPublicType &elementQualifier);
Olli Etuahoe0803872017-08-23 15:30:23 +0300128 bool checkArrayElementIsNotArray(const TSourceLoc &line, const TPublicType &elementType);
Olli Etuaho856c4972016-08-08 11:38:39 +0300129 bool checkIsNonVoid(const TSourceLoc &line, const TString &identifier, const TBasicType &type);
Olli Etuaho56229f12017-07-10 14:16:33 +0300130 bool checkIsScalarBool(const TSourceLoc &line, const TIntermTyped *type);
Olli Etuaho856c4972016-08-08 11:38:39 +0300131 void checkIsScalarBool(const TSourceLoc &line, const TPublicType &pType);
jchen10cc2a10e2017-05-03 14:05:12 +0800132 bool checkIsNotOpaqueType(const TSourceLoc &line,
133 const TTypeSpecifierNonArray &pType,
134 const char *reason);
Olli Etuaho856c4972016-08-08 11:38:39 +0300135 void checkDeclaratorLocationIsNotSpecified(const TSourceLoc &line, const TPublicType &pType);
136 void checkLocationIsNotSpecified(const TSourceLoc &location,
137 const TLayoutQualifier &layoutQualifier);
Qin Jiajiaca68d982017-09-18 16:41:56 +0800138 void checkStd430IsForShaderStorageBlock(const TSourceLoc &location,
139 const TLayoutBlockStorage &blockStorage,
140 const TQualifier &qualifier);
Olli Etuaho856c4972016-08-08 11:38:39 +0300141 void checkIsParameterQualifierValid(const TSourceLoc &line,
Martin Radev70866b82016-07-22 15:27:42 +0300142 const TTypeQualifierBuilder &typeQualifierBuilder,
Olli Etuaho856c4972016-08-08 11:38:39 +0300143 TType *type);
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300144 bool checkCanUseExtension(const TSourceLoc &line, TExtension extension);
Olli Etuahobb7e5a72017-04-24 10:16:44 +0300145
146 // Done for all declarations, whether empty or not.
147 void declarationQualifierErrorCheck(const sh::TQualifier qualifier,
148 const sh::TLayoutQualifier &layoutQualifier,
149 const TSourceLoc &location);
150 // Done for the first non-empty declarator in a declaration.
151 void nonEmptyDeclarationErrorCheck(const TPublicType &publicType,
152 const TSourceLoc &identifierLocation);
153 // Done only for empty declarations.
Olli Etuaho55bde912017-10-25 13:41:13 +0300154 void emptyDeclarationErrorCheck(const TType &type, const TSourceLoc &location);
Olli Etuahobb7e5a72017-04-24 10:16:44 +0300155
Olli Etuaho856c4972016-08-08 11:38:39 +0300156 void checkLayoutQualifierSupported(const TSourceLoc &location,
157 const TString &layoutQualifierName,
158 int versionRequired);
159 bool checkWorkGroupSizeIsNotSpecified(const TSourceLoc &location,
160 const TLayoutQualifier &layoutQualifier);
Jiajia Qinbc585152017-06-23 15:42:17 +0800161 void functionCallRValueLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *fnCall);
Martin Radev70866b82016-07-22 15:27:42 +0300162 void checkInvariantVariableQualifier(bool invariant,
163 const TQualifier qualifier,
164 const TSourceLoc &invariantLocation);
Olli Etuaho856c4972016-08-08 11:38:39 +0300165 void checkInputOutputTypeIsValidES3(const TQualifier qualifier,
166 const TPublicType &type,
167 const TSourceLoc &qualifierLocation);
Martin Radev2cc85b32016-08-05 16:22:53 +0300168 void checkLocalVariableConstStorageQualifier(const TQualifierWrapperBase &qualifier);
Jamie Madill6e06b1f2015-05-14 10:01:17 -0400169 const TPragma &pragma() const { return mDirectiveHandler.pragma(); }
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500170 const TExtensionBehavior &extensionBehavior() const
171 {
172 return mDirectiveHandler.extensionBehavior();
173 }
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300174 bool supportsExtension(TExtension extension);
175 bool isExtensionEnabled(TExtension extension) const;
Jamie Madill06145232015-05-13 13:10:01 -0400176 void handleExtensionDirective(const TSourceLoc &loc, const char *extName, const char *behavior);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500177 void handlePragmaDirective(const TSourceLoc &loc,
178 const char *name,
179 const char *value,
180 bool stdgl);
alokp@chromium.org75fe6b72011-08-14 05:31:22 +0000181
Olli Etuaho914b79a2017-06-19 16:03:19 +0300182 // Returns true on success. *initNode may still be nullptr on success in case the initialization
183 // is not needed in the AST.
Jamie Madill06145232015-05-13 13:10:01 -0400184 bool executeInitializer(const TSourceLoc &line,
185 const TString &identifier,
Olli Etuaho55bde912017-10-25 13:41:13 +0300186 TType type,
Jamie Madill06145232015-05-13 13:10:01 -0400187 TIntermTyped *initializer,
Olli Etuaho13389b62016-10-16 11:48:18 +0100188 TIntermBinary **initNode);
Olli Etuaho914b79a2017-06-19 16:03:19 +0300189 TIntermNode *addConditionInitializer(const TPublicType &pType,
190 const TString &identifier,
191 TIntermTyped *initializer,
192 const TSourceLoc &loc);
193 TIntermNode *addLoop(TLoopType type,
194 TIntermNode *init,
195 TIntermNode *cond,
196 TIntermTyped *expr,
197 TIntermNode *body,
198 const TSourceLoc &loc);
alokp@chromium.org75fe6b72011-08-14 05:31:22 +0000199
Olli Etuahocce89652017-06-19 16:04:09 +0300200 // For "if" test nodes. There are three children: a condition, a true path, and a false path.
201 // The two paths are in TIntermNodePair code.
202 TIntermNode *addIfElse(TIntermTyped *cond, TIntermNodePair code, const TSourceLoc &loc);
203
Olli Etuaho0e3aee32016-10-27 12:56:38 +0100204 void addFullySpecifiedType(TPublicType *typeSpecifier);
Martin Radev70866b82016-07-22 15:27:42 +0300205 TPublicType addFullySpecifiedType(const TTypeQualifierBuilder &typeQualifierBuilder,
Jamie Madill06145232015-05-13 13:10:01 -0400206 const TPublicType &typeSpecifier);
Olli Etuahoe7847b02015-03-16 11:56:12 +0200207
Olli Etuaho13389b62016-10-16 11:48:18 +0100208 TIntermDeclaration *parseSingleDeclaration(TPublicType &publicType,
209 const TSourceLoc &identifierOrTypeLocation,
210 const TString &identifier);
Olli Etuaho55bde912017-10-25 13:41:13 +0300211 TIntermDeclaration *parseSingleArrayDeclaration(TPublicType &elementType,
Olli Etuaho13389b62016-10-16 11:48:18 +0100212 const TSourceLoc &identifierLocation,
213 const TString &identifier,
214 const TSourceLoc &indexLocation,
Olli Etuaho55bde912017-10-25 13:41:13 +0300215 unsigned int arraySize);
Olli Etuaho13389b62016-10-16 11:48:18 +0100216 TIntermDeclaration *parseSingleInitDeclaration(const TPublicType &publicType,
217 const TSourceLoc &identifierLocation,
218 const TString &identifier,
219 const TSourceLoc &initLocation,
220 TIntermTyped *initializer);
Jamie Madill47e3ec02014-08-20 16:38:33 -0400221
Olli Etuaho3875ffd2015-04-10 16:45:14 +0300222 // Parse a declaration like "type a[n] = initializer"
223 // Note that this does not apply to declarations like "type[n] a = initializer"
Olli Etuaho55bde912017-10-25 13:41:13 +0300224 TIntermDeclaration *parseSingleArrayInitDeclaration(TPublicType &elementType,
Olli Etuaho13389b62016-10-16 11:48:18 +0100225 const TSourceLoc &identifierLocation,
226 const TString &identifier,
227 const TSourceLoc &indexLocation,
Olli Etuaho55bde912017-10-25 13:41:13 +0300228 unsigned int arraySize,
Olli Etuaho13389b62016-10-16 11:48:18 +0100229 const TSourceLoc &initLocation,
230 TIntermTyped *initializer);
Olli Etuaho3875ffd2015-04-10 16:45:14 +0300231
Olli Etuahobf4e1b72016-12-09 11:30:15 +0000232 TIntermInvariantDeclaration *parseInvariantDeclaration(
233 const TTypeQualifierBuilder &typeQualifierBuilder,
234 const TSourceLoc &identifierLoc,
235 const TString *identifier,
236 const TSymbol *symbol);
Olli Etuahoe7847b02015-03-16 11:56:12 +0200237
Olli Etuaho13389b62016-10-16 11:48:18 +0100238 void parseDeclarator(TPublicType &publicType,
239 const TSourceLoc &identifierLocation,
240 const TString &identifier,
241 TIntermDeclaration *declarationOut);
Olli Etuaho55bde912017-10-25 13:41:13 +0300242 void parseArrayDeclarator(TPublicType &elementType,
Olli Etuaho13389b62016-10-16 11:48:18 +0100243 const TSourceLoc &identifierLocation,
244 const TString &identifier,
245 const TSourceLoc &arrayLocation,
Olli Etuaho55bde912017-10-25 13:41:13 +0300246 unsigned int arraySize,
Olli Etuaho13389b62016-10-16 11:48:18 +0100247 TIntermDeclaration *declarationOut);
248 void parseInitDeclarator(const TPublicType &publicType,
249 const TSourceLoc &identifierLocation,
250 const TString &identifier,
251 const TSourceLoc &initLocation,
252 TIntermTyped *initializer,
253 TIntermDeclaration *declarationOut);
Olli Etuahoe7847b02015-03-16 11:56:12 +0200254
Olli Etuaho3875ffd2015-04-10 16:45:14 +0300255 // Parse a declarator like "a[n] = initializer"
Olli Etuaho55bde912017-10-25 13:41:13 +0300256 void parseArrayInitDeclarator(const TPublicType &elementType,
Olli Etuaho13389b62016-10-16 11:48:18 +0100257 const TSourceLoc &identifierLocation,
258 const TString &identifier,
259 const TSourceLoc &indexLocation,
Olli Etuaho55bde912017-10-25 13:41:13 +0300260 unsigned int arraySize,
Olli Etuaho13389b62016-10-16 11:48:18 +0100261 const TSourceLoc &initLocation,
262 TIntermTyped *initializer,
263 TIntermDeclaration *declarationOut);
Olli Etuaho3875ffd2015-04-10 16:45:14 +0300264
Olli Etuahob8ee9dd2017-10-30 12:43:27 +0200265 TIntermNode *addEmptyStatement(const TSourceLoc &location);
266
Olli Etuahocce89652017-06-19 16:04:09 +0300267 void parseDefaultPrecisionQualifier(const TPrecision precision,
268 const TPublicType &type,
269 const TSourceLoc &loc);
Martin Radev70866b82016-07-22 15:27:42 +0300270 void parseGlobalLayoutQualifier(const TTypeQualifierBuilder &typeQualifierBuilder);
Olli Etuahocce89652017-06-19 16:04:09 +0300271
Olli Etuaho16c745a2017-01-16 17:02:27 +0000272 TIntermFunctionPrototype *addFunctionPrototypeDeclaration(const TFunction &parsedFunction,
273 const TSourceLoc &location);
Olli Etuaho8ad9e752017-01-16 19:55:20 +0000274 TIntermFunctionDefinition *addFunctionDefinition(TIntermFunctionPrototype *functionPrototype,
Olli Etuaho336b1472016-10-05 16:37:55 +0100275 TIntermBlock *functionBody,
276 const TSourceLoc &location);
Olli Etuaho476197f2016-10-11 13:59:08 +0100277 void parseFunctionDefinitionHeader(const TSourceLoc &location,
278 TFunction **function,
Olli Etuaho8ad9e752017-01-16 19:55:20 +0000279 TIntermFunctionPrototype **prototypeOut);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500280 TFunction *parseFunctionDeclarator(const TSourceLoc &location, TFunction *function);
Olli Etuaho9de84a52016-06-14 17:36:01 +0300281 TFunction *parseFunctionHeader(const TPublicType &type,
282 const TString *name,
283 const TSourceLoc &location);
Olli Etuahocce89652017-06-19 16:04:09 +0300284 TFunction *addNonConstructorFunc(const TString *name, const TSourceLoc &loc);
Jamie Madill06145232015-05-13 13:10:01 -0400285 TFunction *addConstructorFunc(const TPublicType &publicType);
Olli Etuahocce89652017-06-19 16:04:09 +0300286 TParameter parseParameterDeclarator(const TPublicType &publicType,
287 const TString *name,
288 const TSourceLoc &nameLoc);
Olli Etuaho55bde912017-10-25 13:41:13 +0300289
290 TParameter parseParameterArrayDeclarator(const TString *name,
291 const TSourceLoc &nameLoc,
292 unsigned int arraySize,
Olli Etuahocce89652017-06-19 16:04:09 +0300293 const TSourceLoc &arrayLoc,
Olli Etuaho55bde912017-10-25 13:41:13 +0300294 TPublicType *elementType);
Olli Etuaho90892fb2016-07-14 14:44:51 +0300295
Jamie Madill06145232015-05-13 13:10:01 -0400296 TIntermTyped *addIndexExpression(TIntermTyped *baseExpression,
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500297 const TSourceLoc &location,
Jamie Madill06145232015-05-13 13:10:01 -0400298 TIntermTyped *indexExpression);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500299 TIntermTyped *addFieldSelectionExpression(TIntermTyped *baseExpression,
Jamie Madill06145232015-05-13 13:10:01 -0400300 const TSourceLoc &dotLocation,
301 const TString &fieldString,
302 const TSourceLoc &fieldLocation);
shannonwoods@chromium.orga9100882013-05-30 00:11:39 +0000303
Olli Etuahocce89652017-06-19 16:04:09 +0300304 // Parse declarator for a single field
305 TField *parseStructDeclarator(TString *identifier, const TSourceLoc &loc);
306 TField *parseStructArrayDeclarator(TString *identifier,
307 const TSourceLoc &loc,
Olli Etuaho4ddae352017-10-26 16:20:18 +0300308 unsigned int arraySize,
Olli Etuahocce89652017-06-19 16:04:09 +0300309 const TSourceLoc &arraySizeLoc);
310
Olli Etuaho722bfb52017-10-26 17:00:11 +0300311 void checkDoesNotHaveDuplicateFieldName(const TFieldList::const_iterator begin,
312 const TFieldList::const_iterator end,
313 const TString &name,
314 const TSourceLoc &location);
315 TFieldList *addStructFieldList(TFieldList *fields, const TSourceLoc &location);
Olli Etuaho4de340a2016-12-16 09:32:03 +0000316 TFieldList *combineStructFieldLists(TFieldList *processedFields,
317 const TFieldList *newlyAddedFields,
318 const TSourceLoc &location);
Martin Radev70866b82016-07-22 15:27:42 +0300319 TFieldList *addStructDeclaratorListWithQualifiers(
320 const TTypeQualifierBuilder &typeQualifierBuilder,
321 TPublicType *typeSpecifier,
322 TFieldList *fieldList);
Jamie Madill06145232015-05-13 13:10:01 -0400323 TFieldList *addStructDeclaratorList(const TPublicType &typeSpecifier, TFieldList *fieldList);
Martin Radev4a9cd802016-09-01 16:51:51 +0300324 TTypeSpecifierNonArray addStructure(const TSourceLoc &structLine,
325 const TSourceLoc &nameLine,
326 const TString *structName,
327 TFieldList *fieldList);
kbr@chromium.org476541f2011-10-27 21:14:51 +0000328
Olli Etuaho13389b62016-10-16 11:48:18 +0100329 TIntermDeclaration *addInterfaceBlock(const TTypeQualifierBuilder &typeQualifierBuilder,
330 const TSourceLoc &nameLine,
331 const TString &blockName,
332 TFieldList *fieldList,
333 const TString *instanceName,
334 const TSourceLoc &instanceLine,
335 TIntermTyped *arrayIndex,
336 const TSourceLoc &arrayIndexLine);
shannonwoods@chromium.org5668c5d2013-05-30 00:11:48 +0000337
Martin Radev802abe02016-08-04 17:48:32 +0300338 void parseLocalSize(const TString &qualifierType,
339 const TSourceLoc &qualifierTypeLine,
340 int intValue,
341 const TSourceLoc &intValueLine,
342 const std::string &intValueString,
343 size_t index,
Martin Radev4c4c8e72016-08-04 12:25:34 +0300344 sh::WorkGroupSize *localSize);
Olli Etuaho09b04a22016-12-15 13:30:26 +0000345 void parseNumViews(int intValue,
346 const TSourceLoc &intValueLine,
347 const std::string &intValueString,
348 int *numViews);
Shaob5cc1192017-07-06 10:47:20 +0800349 void parseInvocations(int intValue,
350 const TSourceLoc &intValueLine,
351 const std::string &intValueString,
352 int *numInvocations);
353 void parseMaxVertices(int intValue,
354 const TSourceLoc &intValueLine,
355 const std::string &intValueString,
356 int *numMaxVertices);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500357 TLayoutQualifier parseLayoutQualifier(const TString &qualifierType,
358 const TSourceLoc &qualifierTypeLine);
Jamie Madill06145232015-05-13 13:10:01 -0400359 TLayoutQualifier parseLayoutQualifier(const TString &qualifierType,
360 const TSourceLoc &qualifierTypeLine,
Jamie Madill06145232015-05-13 13:10:01 -0400361 int intValue,
362 const TSourceLoc &intValueLine);
Olli Etuaho613b9592016-09-05 12:05:53 +0300363 TTypeQualifierBuilder *createTypeQualifierBuilder(const TSourceLoc &loc);
Olli Etuahocce89652017-06-19 16:04:09 +0300364 TStorageQualifierWrapper *parseGlobalStorageQualifier(TQualifier qualifier,
365 const TSourceLoc &loc);
366 TStorageQualifierWrapper *parseVaryingQualifier(const TSourceLoc &loc);
367 TStorageQualifierWrapper *parseInQualifier(const TSourceLoc &loc);
368 TStorageQualifierWrapper *parseOutQualifier(const TSourceLoc &loc);
369 TStorageQualifierWrapper *parseInOutQualifier(const TSourceLoc &loc);
Martin Radev802abe02016-08-04 17:48:32 +0300370 TLayoutQualifier joinLayoutQualifiers(TLayoutQualifier leftQualifier,
371 TLayoutQualifier rightQualifier,
372 const TSourceLoc &rightQualifierLocation);
shannonwoods@chromium.org302adfe2013-05-30 00:21:06 +0000373
kbr@chromium.org476541f2011-10-27 21:14:51 +0000374 // Performs an error check for embedded struct declarations.
Olli Etuaho383b7912016-08-05 11:22:59 +0300375 void enterStructDeclaration(const TSourceLoc &line, const TString &identifier);
kbr@chromium.org476541f2011-10-27 21:14:51 +0000376 void exitStructDeclaration();
377
Olli Etuaho8a176262016-08-16 14:23:01 +0300378 void checkIsBelowStructNestingLimit(const TSourceLoc &line, const TField &field);
Olli Etuaho09b22472015-02-11 11:47:26 +0200379
Olli Etuaho6d40bbd2016-09-30 13:49:38 +0100380 TIntermSwitch *addSwitch(TIntermTyped *init,
381 TIntermBlock *statementList,
382 const TSourceLoc &loc);
Olli Etuahoa3a36662015-02-17 13:46:51 +0200383 TIntermCase *addCase(TIntermTyped *condition, const TSourceLoc &loc);
384 TIntermCase *addDefault(const TSourceLoc &loc);
385
Jamie Madill06145232015-05-13 13:10:01 -0400386 TIntermTyped *addUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc);
387 TIntermTyped *addUnaryMathLValue(TOperator op, TIntermTyped *child, const TSourceLoc &loc);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500388 TIntermTyped *addBinaryMath(TOperator op,
389 TIntermTyped *left,
390 TIntermTyped *right,
391 const TSourceLoc &loc);
392 TIntermTyped *addBinaryMathBooleanResult(TOperator op,
393 TIntermTyped *left,
394 TIntermTyped *right,
395 const TSourceLoc &loc);
396 TIntermTyped *addAssign(TOperator op,
397 TIntermTyped *left,
398 TIntermTyped *right,
399 const TSourceLoc &loc);
Olli Etuaho49300862015-02-20 14:54:49 +0200400
Olli Etuaho0b2d2dc2015-11-04 16:35:32 +0200401 TIntermTyped *addComma(TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc);
402
Olli Etuaho49300862015-02-20 14:54:49 +0200403 TIntermBranch *addBranch(TOperator op, const TSourceLoc &loc);
Olli Etuahocce89652017-06-19 16:04:09 +0300404 TIntermBranch *addBranch(TOperator op, TIntermTyped *expression, const TSourceLoc &loc);
Olli Etuahoc4ba3be2015-03-02 14:42:24 +0200405
Martin Radev84aa2dc2017-09-11 15:51:02 +0300406 void checkTextureGather(TIntermAggregate *functionCall);
Olli Etuahoe1a94c62015-11-16 17:35:25 +0200407 void checkTextureOffsetConst(TIntermAggregate *functionCall);
Martin Radev2cc85b32016-08-05 16:22:53 +0300408 void checkImageMemoryAccessForBuiltinFunctions(TIntermAggregate *functionCall);
409 void checkImageMemoryAccessForUserDefinedFunctions(const TFunction *functionDefinition,
410 const TIntermAggregate *functionCall);
Olli Etuahoaf6fc1b2017-01-26 17:45:35 -0800411 TIntermSequence *createEmptyArgumentsList();
Olli Etuaho72d10202017-01-19 15:58:30 +0000412
Olli Etuahoaf6fc1b2017-01-26 17:45:35 -0800413 // fnCall is only storing the built-in op, and function name or constructor type. arguments
Olli Etuaho72d10202017-01-19 15:58:30 +0000414 // has the arguments.
Jamie Madill06145232015-05-13 13:10:01 -0400415 TIntermTyped *addFunctionCallOrMethod(TFunction *fnCall,
Olli Etuahoaf6fc1b2017-01-26 17:45:35 -0800416 TIntermSequence *arguments,
Jamie Madill06145232015-05-13 13:10:01 -0400417 TIntermNode *thisNode,
Olli Etuaho72d10202017-01-19 15:58:30 +0000418 const TSourceLoc &loc);
Olli Etuahofc1806e2015-03-17 13:03:11 +0200419
Olli Etuahod0bad2c2016-09-09 18:01:16 +0300420 TIntermTyped *addTernarySelection(TIntermTyped *cond,
421 TIntermTyped *trueExpression,
422 TIntermTyped *falseExpression,
423 const TSourceLoc &line);
Olli Etuaho52901742015-04-15 13:42:45 +0300424
Shaob5cc1192017-07-06 10:47:20 +0800425 int getGeometryShaderMaxVertices() const { return mGeometryShaderMaxVertices; }
426 int getGeometryShaderInvocations() const
427 {
428 return (mGeometryShaderInvocations > 0) ? mGeometryShaderInvocations : 1;
429 }
430 TLayoutPrimitiveType getGeometryShaderInputPrimitiveType() const
431 {
432 return mGeometryShaderInputPrimitiveType;
433 }
434 TLayoutPrimitiveType getGeometryShaderOutputPrimitiveType() const
435 {
436 return mGeometryShaderOutputPrimitiveType;
437 }
438
Olli Etuaho56229f12017-07-10 14:16:33 +0300439 // TODO(jmadill): make this private
Jamie Madill6e06b1f2015-05-14 10:01:17 -0400440 TSymbolTable &symbolTable; // symbol table that goes with the language currently being parsed
441
Olli Etuahofc1806e2015-03-17 13:03:11 +0200442 private:
jchen104cdac9e2017-05-08 11:01:20 +0800443 class AtomicCounterBindingState;
444 constexpr static size_t kAtomicCounterSize = 4;
445 // UNIFORM_ARRAY_STRIDE for atomic counter arrays is an implementation-dependent value which
446 // can be queried after a program is linked according to ES 3.10 section 7.7.1. This is
447 // controversial with the offset inheritance as described in ESSL 3.10 section 4.4.6. Currently
448 // we treat it as always 4 in favour of the original interpretation in
449 // "ARB_shader_atomic_counters".
450 // TODO(jie.a.chen@intel.com): Double check this once the spec vagueness is resolved.
Olli Etuaho55bc9052017-10-25 17:33:06 +0300451 // Note that there may be tests in AtomicCounter_test that will need to be updated as well.
jchen104cdac9e2017-05-08 11:01:20 +0800452 constexpr static size_t kAtomicCounterArrayStride = 4;
453
Olli Etuaho4de340a2016-12-16 09:32:03 +0000454 // Returns a clamped index. If it prints out an error message, the token is "[]".
Olli Etuaho90892fb2016-07-14 14:44:51 +0300455 int checkIndexOutOfRange(bool outOfRangeIndexIsError,
456 const TSourceLoc &location,
457 int index,
458 int arraySize,
Olli Etuaho4de340a2016-12-16 09:32:03 +0000459 const char *reason);
Olli Etuaho90892fb2016-07-14 14:44:51 +0300460
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500461 bool declareVariable(const TSourceLoc &line,
462 const TString &identifier,
463 const TType &type,
464 TVariable **variable);
Olli Etuaho2935c582015-04-08 14:32:06 +0300465
Olli Etuaho856c4972016-08-08 11:38:39 +0300466 void checkCanBeDeclaredWithoutInitializer(const TSourceLoc &line,
467 const TString &identifier,
Olli Etuaho55bde912017-10-25 13:41:13 +0300468 TType *type);
469
470 TParameter parseParameterDeclarator(TType *type,
471 const TString *name,
472 const TSourceLoc &nameLoc);
Olli Etuaho376f1b52015-04-13 13:23:41 +0300473
Olli Etuaho8a176262016-08-16 14:23:01 +0300474 bool checkIsValidTypeAndQualifierForArray(const TSourceLoc &indexLocation,
475 const TPublicType &elementType);
jchen104cdac9e2017-05-08 11:01:20 +0800476 // Done for all atomic counter declarations, whether empty or not.
477 void atomicCounterQualifierErrorCheck(const TPublicType &publicType,
478 const TSourceLoc &location);
Olli Etuaho8a176262016-08-16 14:23:01 +0300479
Olli Etuaho1dded802016-08-18 18:13:13 +0300480 // Assumes that multiplication op has already been set based on the types.
481 bool isMultiplicationTypeCombinationValid(TOperator op, const TType &left, const TType &right);
482
Martin Radev2cc85b32016-08-05 16:22:53 +0300483 void checkOutParameterIsNotOpaqueType(const TSourceLoc &line,
484 TQualifier qualifier,
485 const TType &type);
Martin Radev2cc85b32016-08-05 16:22:53 +0300486
Olli Etuaho43364892017-02-13 16:00:12 +0000487 void checkInternalFormatIsNotSpecified(const TSourceLoc &location,
488 TLayoutImageInternalFormat internalFormat);
489 void checkMemoryQualifierIsNotSpecified(const TMemoryQualifier &memoryQualifier,
490 const TSourceLoc &location);
Olli Etuaho55bc9052017-10-25 17:33:06 +0300491 void checkAtomicCounterOffsetDoesNotOverlap(bool forceAppend,
492 const TSourceLoc &loc,
493 TType *type);
Olli Etuaho43364892017-02-13 16:00:12 +0000494 void checkBindingIsValid(const TSourceLoc &identifierLocation, const TType &type);
495 void checkBindingIsNotSpecified(const TSourceLoc &location, int binding);
jchen104cdac9e2017-05-08 11:01:20 +0800496 void checkOffsetIsNotSpecified(const TSourceLoc &location, int offset);
Olli Etuaho96f6adf2017-08-16 11:18:54 +0300497 void checkImageBindingIsValid(const TSourceLoc &location,
498 int binding,
499 int arrayTotalElementCount);
500 void checkSamplerBindingIsValid(const TSourceLoc &location,
501 int binding,
502 int arrayTotalElementCount);
Jiajia Qinbc585152017-06-23 15:42:17 +0800503 void checkBlockBindingIsValid(const TSourceLoc &location,
504 const TQualifier &qualifier,
505 int binding,
506 int arraySize);
jchen104cdac9e2017-05-08 11:01:20 +0800507 void checkAtomicCounterBindingIsValid(const TSourceLoc &location, int binding);
Olli Etuaho43364892017-02-13 16:00:12 +0000508
Olli Etuaho6ca2b652017-02-19 18:05:10 +0000509 void checkUniformLocationInRange(const TSourceLoc &location,
510 int objectLocationCount,
511 const TLayoutQualifier &layoutQualifier);
512
Andrei Volykhina5527072017-03-22 16:46:30 +0300513 void checkYuvIsNotSpecified(const TSourceLoc &location, bool yuv);
514
Olli Etuaho96f6adf2017-08-16 11:18:54 +0300515 bool checkUnsizedArrayConstructorArgumentDimensionality(TIntermSequence *arguments,
516 TType type,
517 const TSourceLoc &line);
518
Olli Etuaho454c34c2017-10-25 16:35:56 +0300519 // Will set the size of the outermost array according to geometry shader input layout.
520 void checkGeometryShaderInputAndSetArraySize(const TSourceLoc &location,
521 const char *token,
522 TType *type);
523
Olli Etuaho55bde912017-10-25 13:41:13 +0300524 // Will size any unsized array type so unsized arrays won't need to be taken into account
525 // further along the line in parsing.
526 void checkIsNotUnsizedArray(const TSourceLoc &line,
527 const char *errorMessage,
528 const char *token,
529 TType *arrayType);
530
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500531 TIntermTyped *addBinaryMathInternal(TOperator op,
532 TIntermTyped *left,
533 TIntermTyped *right,
534 const TSourceLoc &loc);
Olli Etuaho13389b62016-10-16 11:48:18 +0100535 TIntermBinary *createAssign(TOperator op,
536 TIntermTyped *left,
537 TIntermTyped *right,
538 const TSourceLoc &loc);
Olli Etuahoaf6fc1b2017-01-26 17:45:35 -0800539 TIntermTyped *createUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc);
540
541 TIntermTyped *addMethod(TFunction *fnCall,
542 TIntermSequence *arguments,
543 TIntermNode *thisNode,
544 const TSourceLoc &loc);
545 TIntermTyped *addConstructor(TIntermSequence *arguments,
Olli Etuahoaf6fc1b2017-01-26 17:45:35 -0800546 TType type,
547 const TSourceLoc &line);
548 TIntermTyped *addNonConstructorFunctionCall(TFunction *fnCall,
549 TIntermSequence *arguments,
550 const TSourceLoc &loc);
Olli Etuahod6b14282015-03-17 14:31:35 +0200551
Olli Etuaho47fd36a2015-03-19 14:22:24 +0200552 // Return true if the checks pass
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500553 bool binaryOpCommonCheck(TOperator op,
554 TIntermTyped *left,
555 TIntermTyped *right,
556 const TSourceLoc &loc);
Olli Etuahofa33d582015-04-09 14:33:12 +0300557
Olli Etuaho8ad9e752017-01-16 19:55:20 +0000558 TIntermFunctionPrototype *createPrototypeNodeFromFunction(const TFunction &function,
559 const TSourceLoc &location,
560 bool insertParametersToSymbolTable);
561
jchen104cdac9e2017-05-08 11:01:20 +0800562 void setAtomicCounterBindingDefaultOffset(const TPublicType &declaration,
563 const TSourceLoc &location);
564
Shaob5cc1192017-07-06 10:47:20 +0800565 bool checkPrimitiveTypeMatchesTypeQualifier(const TTypeQualifier &typeQualifier);
566 bool parseGeometryShaderInputLayoutQualifier(const TTypeQualifier &typeQualifier);
567 bool parseGeometryShaderOutputLayoutQualifier(const TTypeQualifier &typeQualifier);
Jiawei Shao8e4b3552017-08-30 14:20:58 +0800568 void setGeometryShaderInputArraySize(unsigned int inputArraySize, const TSourceLoc &line);
Shaob5cc1192017-07-06 10:47:20 +0800569
Olli Etuahobb7e5a72017-04-24 10:16:44 +0300570 // Set to true when the last/current declarator list was started with an empty declaration. The
571 // non-empty declaration error check will need to be performed if the empty declaration is
572 // followed by a declarator.
573 bool mDeferredNonEmptyDeclarationErrorCheck;
Jamie Madill6e06b1f2015-05-14 10:01:17 -0400574
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500575 sh::GLenum mShaderType; // vertex or fragment language (future: pack or unpack)
Qiankun Miao7ebb97f2016-09-08 18:01:50 +0800576 ShShaderSpec mShaderSpec; // The language specification compiler conforms to - GLES2 or WebGL.
577 ShCompileOptions mCompileOptions; // Options passed to TCompiler
Jamie Madill6e06b1f2015-05-14 10:01:17 -0400578 int mShaderVersion;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500579 TIntermBlock *mTreeRoot; // root of parse tree being created
580 int mLoopNestingLevel; // 0 if outside all loops
581 int mStructNestingLevel; // incremented while parsing a struct declaration
582 int mSwitchNestingLevel; // 0 if outside all switch statements
Qiankun Miao7ebb97f2016-09-08 18:01:50 +0800583 const TType
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500584 *mCurrentFunctionType; // the return type of the function that's currently being parsed
585 bool mFunctionReturnsValue; // true if a non-void function has a return
Qiankun Miao7ebb97f2016-09-08 18:01:50 +0800586 bool mChecksPrecisionErrors; // true if an error will be generated when a variable is declared
587 // without precision, explicit or implicit.
Olli Etuahoa6996682015-10-12 14:32:30 +0300588 bool mFragmentPrecisionHighOnESSL1; // true if highp precision is supported when compiling
589 // ESSL1.
Jiajia Qinbc585152017-06-23 15:42:17 +0800590 TLayoutMatrixPacking mDefaultUniformMatrixPacking;
591 TLayoutBlockStorage mDefaultUniformBlockStorage;
592 TLayoutMatrixPacking mDefaultBufferMatrixPacking;
593 TLayoutBlockStorage mDefaultBufferBlockStorage;
Jamie Madill6e06b1f2015-05-14 10:01:17 -0400594 TString mHashErrMsg;
Olli Etuaho77ba4082016-12-16 12:01:18 +0000595 TDiagnostics *mDiagnostics;
Jamie Madill6e06b1f2015-05-14 10:01:17 -0400596 TDirectiveHandler mDirectiveHandler;
597 pp::Preprocessor mPreprocessor;
598 void *mScanner;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500599 bool mUsesFragData; // track if we are using both gl_FragData and gl_FragColor
Jamie Madill14e95b32015-05-07 10:10:41 -0400600 bool mUsesFragColor;
Kimmo Kinnunenb18609b2015-07-16 14:13:11 +0300601 bool mUsesSecondaryOutputs; // Track if we are using either gl_SecondaryFragData or
602 // gl_Secondary FragColor or both.
Olli Etuahoe1a94c62015-11-16 17:35:25 +0200603 int mMinProgramTexelOffset;
604 int mMaxProgramTexelOffset;
Martin Radev802abe02016-08-04 17:48:32 +0300605
Martin Radev84aa2dc2017-09-11 15:51:02 +0300606 int mMinProgramTextureGatherOffset;
607 int mMaxProgramTextureGatherOffset;
608
Martin Radev802abe02016-08-04 17:48:32 +0300609 // keep track of local group size declared in layout. It should be declared only once.
610 bool mComputeShaderLocalSizeDeclared;
Martin Radev4c4c8e72016-08-04 12:25:34 +0300611 sh::WorkGroupSize mComputeShaderLocalSize;
Olli Etuaho09b04a22016-12-15 13:30:26 +0000612 // keep track of number of views declared in layout.
613 int mNumViews;
614 int mMaxNumViews;
Olli Etuaho43364892017-02-13 16:00:12 +0000615 int mMaxImageUnits;
616 int mMaxCombinedTextureImageUnits;
Olli Etuaho6ca2b652017-02-19 18:05:10 +0000617 int mMaxUniformLocations;
jchen10af713a22017-04-19 09:10:56 +0800618 int mMaxUniformBufferBindings;
jchen104cdac9e2017-05-08 11:01:20 +0800619 int mMaxAtomicCounterBindings;
Jiajia Qinbc585152017-06-23 15:42:17 +0800620 int mMaxShaderStorageBufferBindings;
jchen104cdac9e2017-05-08 11:01:20 +0800621
Martin Radev70866b82016-07-22 15:27:42 +0300622 // keeps track whether we are declaring / defining a function
623 bool mDeclaringFunction;
jchen104cdac9e2017-05-08 11:01:20 +0800624
625 // Track the state of each atomic counter binding.
626 std::map<int, AtomicCounterBindingState> mAtomicCounterBindingStates;
Shaob5cc1192017-07-06 10:47:20 +0800627
628 // Track the geometry shader global parameters declared in layout.
629 TLayoutPrimitiveType mGeometryShaderInputPrimitiveType;
630 TLayoutPrimitiveType mGeometryShaderOutputPrimitiveType;
631 int mGeometryShaderInvocations;
632 int mGeometryShaderMaxVertices;
633 int mMaxGeometryShaderInvocations;
634 int mMaxGeometryShaderMaxVertices;
Jiawei Shao8e4b3552017-08-30 14:20:58 +0800635
636 // Track if all input array sizes are same and matches the latter input primitive declaration.
637 unsigned int mGeometryShaderInputArraySize;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000638};
639
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500640int PaParseStrings(size_t count,
641 const char *const string[],
642 const int length[],
643 TParseContext *context);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000644
Jamie Madill45bcc782016-11-07 13:58:48 -0500645} // namespace sh
646
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500647#endif // COMPILER_TRANSLATOR_PARSECONTEXT_H_