• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2002 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 #ifndef COMPILER_TRANSLATOR_PARSECONTEXT_H_
7 #define COMPILER_TRANSLATOR_PARSECONTEXT_H_
8 
9 #include "compiler/preprocessor/Preprocessor.h"
10 #include "compiler/translator/Compiler.h"
11 #include "compiler/translator/Declarator.h"
12 #include "compiler/translator/Diagnostics.h"
13 #include "compiler/translator/DirectiveHandler.h"
14 #include "compiler/translator/FunctionLookup.h"
15 #include "compiler/translator/QualifierTypes.h"
16 #include "compiler/translator/SymbolTable.h"
17 
18 namespace sh
19 {
20 
21 struct TMatrixFields
22 {
23     bool wholeRow;
24     bool wholeCol;
25     int row;
26     int col;
27 };
28 
29 //
30 // The following are extra variables needed during parsing, grouped together so
31 // they can be passed to the parser without needing a global.
32 //
33 class TParseContext : angle::NonCopyable
34 {
35   public:
36     TParseContext(TSymbolTable &symt,
37                   TExtensionBehavior &ext,
38                   sh::GLenum type,
39                   ShShaderSpec spec,
40                   ShCompileOptions options,
41                   bool checksPrecErrors,
42                   TDiagnostics *diagnostics,
43                   const ShBuiltInResources &resources);
44     ~TParseContext();
45 
46     bool anyMultiviewExtensionAvailable();
getPreprocessor()47     const angle::pp::Preprocessor &getPreprocessor() const { return mPreprocessor; }
getPreprocessor()48     angle::pp::Preprocessor &getPreprocessor() { return mPreprocessor; }
getScanner()49     void *getScanner() const { return mScanner; }
setScanner(void * scanner)50     void setScanner(void *scanner) { mScanner = scanner; }
getShaderVersion()51     int getShaderVersion() const { return mShaderVersion; }
getShaderType()52     sh::GLenum getShaderType() const { return mShaderType; }
getShaderSpec()53     ShShaderSpec getShaderSpec() const { return mShaderSpec; }
numErrors()54     int numErrors() const { return mDiagnostics->numErrors(); }
55     void error(const TSourceLoc &loc, const char *reason, const char *token);
56     void error(const TSourceLoc &loc, const char *reason, const ImmutableString &token);
57     void warning(const TSourceLoc &loc, const char *reason, const char *token);
58 
59     // If isError is false, a warning will be reported instead.
60     void outOfRangeError(bool isError,
61                          const TSourceLoc &loc,
62                          const char *reason,
63                          const char *token);
64 
getTreeRoot()65     TIntermBlock *getTreeRoot() const { return mTreeRoot; }
setTreeRoot(TIntermBlock * treeRoot)66     void setTreeRoot(TIntermBlock *treeRoot) { mTreeRoot = treeRoot; }
67 
getFragmentPrecisionHigh()68     bool getFragmentPrecisionHigh() const
69     {
70         return mFragmentPrecisionHighOnESSL1 || mShaderVersion >= 300;
71     }
setFragmentPrecisionHighOnESSL1(bool fragmentPrecisionHigh)72     void setFragmentPrecisionHighOnESSL1(bool fragmentPrecisionHigh)
73     {
74         mFragmentPrecisionHighOnESSL1 = fragmentPrecisionHigh;
75     }
76 
setLoopNestingLevel(int loopNestintLevel)77     void setLoopNestingLevel(int loopNestintLevel) { mLoopNestingLevel = loopNestintLevel; }
78 
incrLoopNestingLevel()79     void incrLoopNestingLevel() { ++mLoopNestingLevel; }
decrLoopNestingLevel()80     void decrLoopNestingLevel() { --mLoopNestingLevel; }
81 
incrSwitchNestingLevel()82     void incrSwitchNestingLevel() { ++mSwitchNestingLevel; }
decrSwitchNestingLevel()83     void decrSwitchNestingLevel() { --mSwitchNestingLevel; }
84 
isComputeShaderLocalSizeDeclared()85     bool isComputeShaderLocalSizeDeclared() const { return mComputeShaderLocalSizeDeclared; }
86     sh::WorkGroupSize getComputeShaderLocalSize() const;
87 
getNumViews()88     int getNumViews() const { return mNumViews; }
89 
enterFunctionDeclaration()90     void enterFunctionDeclaration() { mDeclaringFunction = true; }
91 
exitFunctionDeclaration()92     void exitFunctionDeclaration() { mDeclaringFunction = false; }
93 
declaringFunction()94     bool declaringFunction() const { return mDeclaringFunction; }
95 
96     TIntermConstantUnion *addScalarLiteral(const TConstantUnion *constantUnion,
97                                            const TSourceLoc &line);
98 
99     // This method is guaranteed to succeed, even if no variable with 'name' exists.
100     const TVariable *getNamedVariable(const TSourceLoc &location,
101                                       const ImmutableString &name,
102                                       const TSymbol *symbol);
103     TIntermTyped *parseVariableIdentifier(const TSourceLoc &location,
104                                           const ImmutableString &name,
105                                           const TSymbol *symbol);
106 
107     // Look at a '.' field selector string and change it into offsets for a vector.
108     bool parseVectorFields(const TSourceLoc &line,
109                            const ImmutableString &compString,
110                            int vecSize,
111                            TVector<int> *fieldOffsets);
112 
113     void assignError(const TSourceLoc &line, const char *op, const TType &left, const TType &right);
114     void unaryOpError(const TSourceLoc &line, const char *op, const TType &operand);
115     void binaryOpError(const TSourceLoc &line,
116                        const char *op,
117                        const TType &left,
118                        const TType &right);
119 
120     // Check functions - the ones that return bool return false if an error was generated.
121 
122     bool checkIsNotReserved(const TSourceLoc &line, const ImmutableString &identifier);
123     void checkPrecisionSpecified(const TSourceLoc &line, TPrecision precision, TBasicType type);
124     bool checkCanBeLValue(const TSourceLoc &line, const char *op, TIntermTyped *node);
125     void checkIsConst(TIntermTyped *node);
126     void checkIsScalarInteger(TIntermTyped *node, const char *token);
127     bool checkIsAtGlobalLevel(const TSourceLoc &line, const char *token);
128     bool checkConstructorArguments(const TSourceLoc &line,
129                                    const TIntermSequence &arguments,
130                                    const TType &type);
131 
132     // Returns a sanitized array size to use (the size is at least 1).
133     unsigned int checkIsValidArraySize(const TSourceLoc &line, TIntermTyped *expr);
134     bool checkIsValidQualifierForArray(const TSourceLoc &line, const TPublicType &elementQualifier);
135     bool checkArrayElementIsNotArray(const TSourceLoc &line, const TPublicType &elementType);
136     bool checkIsNonVoid(const TSourceLoc &line,
137                         const ImmutableString &identifier,
138                         const TBasicType &type);
139     bool checkIsScalarBool(const TSourceLoc &line, const TIntermTyped *type);
140     void checkIsScalarBool(const TSourceLoc &line, const TPublicType &pType);
141     bool checkIsNotOpaqueType(const TSourceLoc &line,
142                               const TTypeSpecifierNonArray &pType,
143                               const char *reason);
144     void checkDeclaratorLocationIsNotSpecified(const TSourceLoc &line, const TPublicType &pType);
145     void checkLocationIsNotSpecified(const TSourceLoc &location,
146                                      const TLayoutQualifier &layoutQualifier);
147     void checkStd430IsForShaderStorageBlock(const TSourceLoc &location,
148                                             const TLayoutBlockStorage &blockStorage,
149                                             const TQualifier &qualifier);
150     void checkIsParameterQualifierValid(const TSourceLoc &line,
151                                         const TTypeQualifierBuilder &typeQualifierBuilder,
152                                         TType *type);
153 
154     // Check if at least one of the specified extensions can be used, and generate error/warning as
155     // appropriate according to the spec.
156     // This function is only needed for a few different small constant sizes of extension array, and
157     // we want to avoid unnecessary dynamic allocations. That's why checkCanUseOneOfExtensions is a
158     // template function rather than one taking a vector.
159     template <size_t size>
160     bool checkCanUseOneOfExtensions(const TSourceLoc &line,
161                                     const std::array<TExtension, size> &extensions);
162     bool checkCanUseExtension(const TSourceLoc &line, TExtension extension);
163 
164     // Done for all declarations, whether empty or not.
165     void declarationQualifierErrorCheck(const sh::TQualifier qualifier,
166                                         const sh::TLayoutQualifier &layoutQualifier,
167                                         const TSourceLoc &location);
168     // Done for the first non-empty declarator in a declaration.
169     void nonEmptyDeclarationErrorCheck(const TPublicType &publicType,
170                                        const TSourceLoc &identifierLocation);
171     // Done only for empty declarations.
172     void emptyDeclarationErrorCheck(const TType &type, const TSourceLoc &location);
173 
174     void checkLayoutQualifierSupported(const TSourceLoc &location,
175                                        const ImmutableString &layoutQualifierName,
176                                        int versionRequired);
177     bool checkWorkGroupSizeIsNotSpecified(const TSourceLoc &location,
178                                           const TLayoutQualifier &layoutQualifier);
179     void functionCallRValueLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *fnCall);
180     void checkInvariantVariableQualifier(bool invariant,
181                                          const TQualifier qualifier,
182                                          const TSourceLoc &invariantLocation);
183     void checkInputOutputTypeIsValidES3(const TQualifier qualifier,
184                                         const TPublicType &type,
185                                         const TSourceLoc &qualifierLocation);
186     void checkLocalVariableConstStorageQualifier(const TQualifierWrapperBase &qualifier);
pragma()187     const TPragma &pragma() const { return mDirectiveHandler.pragma(); }
extensionBehavior()188     const TExtensionBehavior &extensionBehavior() const
189     {
190         return mDirectiveHandler.extensionBehavior();
191     }
192 
193     bool isExtensionEnabled(TExtension extension) const;
194     void handleExtensionDirective(const TSourceLoc &loc, const char *extName, const char *behavior);
195     void handlePragmaDirective(const TSourceLoc &loc,
196                                const char *name,
197                                const char *value,
198                                bool stdgl);
199 
200     // Returns true on success. *initNode may still be nullptr on success in case the initialization
201     // is not needed in the AST.
202     bool executeInitializer(const TSourceLoc &line,
203                             const ImmutableString &identifier,
204                             TType *type,
205                             TIntermTyped *initializer,
206                             TIntermBinary **initNode);
207     TIntermNode *addConditionInitializer(const TPublicType &pType,
208                                          const ImmutableString &identifier,
209                                          TIntermTyped *initializer,
210                                          const TSourceLoc &loc);
211     TIntermNode *addLoop(TLoopType type,
212                          TIntermNode *init,
213                          TIntermNode *cond,
214                          TIntermTyped *expr,
215                          TIntermNode *body,
216                          const TSourceLoc &loc);
217 
218     // For "if" test nodes. There are three children: a condition, a true path, and a false path.
219     // The two paths are in TIntermNodePair code.
220     TIntermNode *addIfElse(TIntermTyped *cond, TIntermNodePair code, const TSourceLoc &loc);
221 
222     void addFullySpecifiedType(TPublicType *typeSpecifier);
223     TPublicType addFullySpecifiedType(const TTypeQualifierBuilder &typeQualifierBuilder,
224                                       const TPublicType &typeSpecifier);
225 
226     TIntermDeclaration *parseSingleDeclaration(TPublicType &publicType,
227                                                const TSourceLoc &identifierOrTypeLocation,
228                                                const ImmutableString &identifier);
229     TIntermDeclaration *parseSingleArrayDeclaration(TPublicType &elementType,
230                                                     const TSourceLoc &identifierLocation,
231                                                     const ImmutableString &identifier,
232                                                     const TSourceLoc &indexLocation,
233                                                     const TVector<unsigned int> &arraySizes);
234     TIntermDeclaration *parseSingleInitDeclaration(const TPublicType &publicType,
235                                                    const TSourceLoc &identifierLocation,
236                                                    const ImmutableString &identifier,
237                                                    const TSourceLoc &initLocation,
238                                                    TIntermTyped *initializer);
239 
240     // Parse a declaration like "type a[n] = initializer"
241     // Note that this does not apply to declarations like "type[n] a = initializer"
242     TIntermDeclaration *parseSingleArrayInitDeclaration(TPublicType &elementType,
243                                                         const TSourceLoc &identifierLocation,
244                                                         const ImmutableString &identifier,
245                                                         const TSourceLoc &indexLocation,
246                                                         const TVector<unsigned int> &arraySizes,
247                                                         const TSourceLoc &initLocation,
248                                                         TIntermTyped *initializer);
249 
250     TIntermInvariantDeclaration *parseInvariantDeclaration(
251         const TTypeQualifierBuilder &typeQualifierBuilder,
252         const TSourceLoc &identifierLoc,
253         const ImmutableString &identifier,
254         const TSymbol *symbol);
255 
256     void parseDeclarator(TPublicType &publicType,
257                          const TSourceLoc &identifierLocation,
258                          const ImmutableString &identifier,
259                          TIntermDeclaration *declarationOut);
260     void parseArrayDeclarator(TPublicType &elementType,
261                               const TSourceLoc &identifierLocation,
262                               const ImmutableString &identifier,
263                               const TSourceLoc &arrayLocation,
264                               const TVector<unsigned int> &arraySizes,
265                               TIntermDeclaration *declarationOut);
266     void parseInitDeclarator(const TPublicType &publicType,
267                              const TSourceLoc &identifierLocation,
268                              const ImmutableString &identifier,
269                              const TSourceLoc &initLocation,
270                              TIntermTyped *initializer,
271                              TIntermDeclaration *declarationOut);
272 
273     // Parse a declarator like "a[n] = initializer"
274     void parseArrayInitDeclarator(const TPublicType &elementType,
275                                   const TSourceLoc &identifierLocation,
276                                   const ImmutableString &identifier,
277                                   const TSourceLoc &indexLocation,
278                                   const TVector<unsigned int> &arraySizes,
279                                   const TSourceLoc &initLocation,
280                                   TIntermTyped *initializer,
281                                   TIntermDeclaration *declarationOut);
282 
283     TIntermNode *addEmptyStatement(const TSourceLoc &location);
284 
285     void parseDefaultPrecisionQualifier(const TPrecision precision,
286                                         const TPublicType &type,
287                                         const TSourceLoc &loc);
288     void parseGlobalLayoutQualifier(const TTypeQualifierBuilder &typeQualifierBuilder);
289 
290     TIntermFunctionPrototype *addFunctionPrototypeDeclaration(const TFunction &parsedFunction,
291                                                               const TSourceLoc &location);
292     TIntermFunctionDefinition *addFunctionDefinition(TIntermFunctionPrototype *functionPrototype,
293                                                      TIntermBlock *functionBody,
294                                                      const TSourceLoc &location);
295     void parseFunctionDefinitionHeader(const TSourceLoc &location,
296                                        const TFunction *function,
297                                        TIntermFunctionPrototype **prototypeOut);
298     TFunction *parseFunctionDeclarator(const TSourceLoc &location, TFunction *function);
299     TFunction *parseFunctionHeader(const TPublicType &type,
300                                    const ImmutableString &name,
301                                    const TSourceLoc &location);
302 
303     TFunctionLookup *addNonConstructorFunc(const ImmutableString &name, const TSymbol *symbol);
304     TFunctionLookup *addConstructorFunc(const TPublicType &publicType);
305 
306     TParameter parseParameterDeclarator(const TPublicType &publicType,
307                                         const ImmutableString &name,
308                                         const TSourceLoc &nameLoc);
309 
310     TParameter parseParameterArrayDeclarator(const ImmutableString &name,
311                                              const TSourceLoc &nameLoc,
312                                              const TVector<unsigned int> &arraySizes,
313                                              const TSourceLoc &arrayLoc,
314                                              TPublicType *elementType);
315 
316     TIntermTyped *addIndexExpression(TIntermTyped *baseExpression,
317                                      const TSourceLoc &location,
318                                      TIntermTyped *indexExpression);
319     TIntermTyped *addFieldSelectionExpression(TIntermTyped *baseExpression,
320                                               const TSourceLoc &dotLocation,
321                                               const ImmutableString &fieldString,
322                                               const TSourceLoc &fieldLocation);
323 
324     // Parse declarator for a single field
325     TDeclarator *parseStructDeclarator(const ImmutableString &identifier, const TSourceLoc &loc);
326     TDeclarator *parseStructArrayDeclarator(const ImmutableString &identifier,
327                                             const TSourceLoc &loc,
328                                             const TVector<unsigned int> *arraySizes);
329 
330     void checkDoesNotHaveDuplicateFieldName(const TFieldList::const_iterator begin,
331                                             const TFieldList::const_iterator end,
332                                             const ImmutableString &name,
333                                             const TSourceLoc &location);
334     TFieldList *addStructFieldList(TFieldList *fields, const TSourceLoc &location);
335     TFieldList *combineStructFieldLists(TFieldList *processedFields,
336                                         const TFieldList *newlyAddedFields,
337                                         const TSourceLoc &location);
338     TFieldList *addStructDeclaratorListWithQualifiers(
339         const TTypeQualifierBuilder &typeQualifierBuilder,
340         TPublicType *typeSpecifier,
341         const TDeclaratorList *declaratorList);
342     TFieldList *addStructDeclaratorList(const TPublicType &typeSpecifier,
343                                         const TDeclaratorList *declaratorList);
344     TTypeSpecifierNonArray addStructure(const TSourceLoc &structLine,
345                                         const TSourceLoc &nameLine,
346                                         const ImmutableString &structName,
347                                         TFieldList *fieldList);
348 
349     TIntermDeclaration *addInterfaceBlock(const TTypeQualifierBuilder &typeQualifierBuilder,
350                                           const TSourceLoc &nameLine,
351                                           const ImmutableString &blockName,
352                                           TFieldList *fieldList,
353                                           const ImmutableString &instanceName,
354                                           const TSourceLoc &instanceLine,
355                                           TIntermTyped *arrayIndex,
356                                           const TSourceLoc &arrayIndexLine);
357 
358     void parseLocalSize(const ImmutableString &qualifierType,
359                         const TSourceLoc &qualifierTypeLine,
360                         int intValue,
361                         const TSourceLoc &intValueLine,
362                         const std::string &intValueString,
363                         size_t index,
364                         sh::WorkGroupSize *localSize);
365     void parseNumViews(int intValue,
366                        const TSourceLoc &intValueLine,
367                        const std::string &intValueString,
368                        int *numViews);
369     void parseInvocations(int intValue,
370                           const TSourceLoc &intValueLine,
371                           const std::string &intValueString,
372                           int *numInvocations);
373     void parseMaxVertices(int intValue,
374                           const TSourceLoc &intValueLine,
375                           const std::string &intValueString,
376                           int *numMaxVertices);
377     void parseIndexLayoutQualifier(int intValue,
378                                    const TSourceLoc &intValueLine,
379                                    const std::string &intValueString,
380                                    int *index);
381     TLayoutQualifier parseLayoutQualifier(const ImmutableString &qualifierType,
382                                           const TSourceLoc &qualifierTypeLine);
383     TLayoutQualifier parseLayoutQualifier(const ImmutableString &qualifierType,
384                                           const TSourceLoc &qualifierTypeLine,
385                                           int intValue,
386                                           const TSourceLoc &intValueLine);
387     TTypeQualifierBuilder *createTypeQualifierBuilder(const TSourceLoc &loc);
388     TStorageQualifierWrapper *parseGlobalStorageQualifier(TQualifier qualifier,
389                                                           const TSourceLoc &loc);
390     TStorageQualifierWrapper *parseVaryingQualifier(const TSourceLoc &loc);
391     TStorageQualifierWrapper *parseInQualifier(const TSourceLoc &loc);
392     TStorageQualifierWrapper *parseOutQualifier(const TSourceLoc &loc);
393     TStorageQualifierWrapper *parseInOutQualifier(const TSourceLoc &loc);
394     TLayoutQualifier joinLayoutQualifiers(TLayoutQualifier leftQualifier,
395                                           TLayoutQualifier rightQualifier,
396                                           const TSourceLoc &rightQualifierLocation);
397 
398     // Performs an error check for embedded struct declarations.
399     void enterStructDeclaration(const TSourceLoc &line, const ImmutableString &identifier);
400     void exitStructDeclaration();
401 
402     void checkIsBelowStructNestingLimit(const TSourceLoc &line, const TField &field);
403 
404     TIntermSwitch *addSwitch(TIntermTyped *init,
405                              TIntermBlock *statementList,
406                              const TSourceLoc &loc);
407     TIntermCase *addCase(TIntermTyped *condition, const TSourceLoc &loc);
408     TIntermCase *addDefault(const TSourceLoc &loc);
409 
410     TIntermTyped *addUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc);
411     TIntermTyped *addUnaryMathLValue(TOperator op, TIntermTyped *child, const TSourceLoc &loc);
412     TIntermTyped *addBinaryMath(TOperator op,
413                                 TIntermTyped *left,
414                                 TIntermTyped *right,
415                                 const TSourceLoc &loc);
416     TIntermTyped *addBinaryMathBooleanResult(TOperator op,
417                                              TIntermTyped *left,
418                                              TIntermTyped *right,
419                                              const TSourceLoc &loc);
420     TIntermTyped *addAssign(TOperator op,
421                             TIntermTyped *left,
422                             TIntermTyped *right,
423                             const TSourceLoc &loc);
424 
425     TIntermTyped *addComma(TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc);
426 
427     TIntermBranch *addBranch(TOperator op, const TSourceLoc &loc);
428     TIntermBranch *addBranch(TOperator op, TIntermTyped *expression, const TSourceLoc &loc);
429 
430     void appendStatement(TIntermBlock *block, TIntermNode *statement);
431 
432     void checkTextureGather(TIntermAggregate *functionCall);
433     void checkTextureOffsetConst(TIntermAggregate *functionCall);
434     void checkImageMemoryAccessForBuiltinFunctions(TIntermAggregate *functionCall);
435     void checkImageMemoryAccessForUserDefinedFunctions(const TFunction *functionDefinition,
436                                                        const TIntermAggregate *functionCall);
437     void checkAtomicMemoryBuiltinFunctions(TIntermAggregate *functionCall);
438 
439     // fnCall is only storing the built-in op, and function name or constructor type. arguments
440     // has the arguments.
441     TIntermTyped *addFunctionCallOrMethod(TFunctionLookup *fnCall, const TSourceLoc &loc);
442 
443     TIntermTyped *addTernarySelection(TIntermTyped *cond,
444                                       TIntermTyped *trueExpression,
445                                       TIntermTyped *falseExpression,
446                                       const TSourceLoc &line);
447 
getGeometryShaderMaxVertices()448     int getGeometryShaderMaxVertices() const { return mGeometryShaderMaxVertices; }
getGeometryShaderInvocations()449     int getGeometryShaderInvocations() const
450     {
451         return (mGeometryShaderInvocations > 0) ? mGeometryShaderInvocations : 1;
452     }
getGeometryShaderInputPrimitiveType()453     TLayoutPrimitiveType getGeometryShaderInputPrimitiveType() const
454     {
455         return mGeometryShaderInputPrimitiveType;
456     }
getGeometryShaderOutputPrimitiveType()457     TLayoutPrimitiveType getGeometryShaderOutputPrimitiveType() const
458     {
459         return mGeometryShaderOutputPrimitiveType;
460     }
461 
462     // TODO(jmadill): make this private
463     TSymbolTable &symbolTable;  // symbol table that goes with the language currently being parsed
464 
465   private:
466     class AtomicCounterBindingState;
467     constexpr static size_t kAtomicCounterSize = 4;
468     // UNIFORM_ARRAY_STRIDE for atomic counter arrays is an implementation-dependent value which
469     // can be queried after a program is linked according to ES 3.10 section 7.7.1. This is
470     // controversial with the offset inheritance as described in ESSL 3.10 section 4.4.6. Currently
471     // we treat it as always 4 in favour of the original interpretation in
472     // "ARB_shader_atomic_counters".
473     // TODO(jie.a.chen@intel.com): Double check this once the spec vagueness is resolved.
474     // Note that there may be tests in AtomicCounter_test that will need to be updated as well.
475     constexpr static size_t kAtomicCounterArrayStride = 4;
476 
477     void markStaticReadIfSymbol(TIntermNode *node);
478 
479     // Returns a clamped index. If it prints out an error message, the token is "[]".
480     int checkIndexLessThan(bool outOfRangeIndexIsError,
481                            const TSourceLoc &location,
482                            int index,
483                            int arraySize,
484                            const char *reason);
485 
486     bool declareVariable(const TSourceLoc &line,
487                          const ImmutableString &identifier,
488                          const TType *type,
489                          TVariable **variable);
490 
491     void checkCanBeDeclaredWithoutInitializer(const TSourceLoc &line,
492                                               const ImmutableString &identifier,
493                                               TType *type);
494 
495     TParameter parseParameterDeclarator(TType *type,
496                                         const ImmutableString &name,
497                                         const TSourceLoc &nameLoc);
498 
499     bool checkIsValidTypeAndQualifierForArray(const TSourceLoc &indexLocation,
500                                               const TPublicType &elementType);
501     // Done for all atomic counter declarations, whether empty or not.
502     void atomicCounterQualifierErrorCheck(const TPublicType &publicType,
503                                           const TSourceLoc &location);
504 
505     // Assumes that multiplication op has already been set based on the types.
506     bool isMultiplicationTypeCombinationValid(TOperator op, const TType &left, const TType &right);
507 
508     void checkOutParameterIsNotOpaqueType(const TSourceLoc &line,
509                                           TQualifier qualifier,
510                                           const TType &type);
511 
512     void checkInternalFormatIsNotSpecified(const TSourceLoc &location,
513                                            TLayoutImageInternalFormat internalFormat);
514     void checkMemoryQualifierIsNotSpecified(const TMemoryQualifier &memoryQualifier,
515                                             const TSourceLoc &location);
516     void checkAtomicCounterOffsetDoesNotOverlap(bool forceAppend,
517                                                 const TSourceLoc &loc,
518                                                 TType *type);
519     void checkAtomicCounterOffsetAlignment(const TSourceLoc &location, const TType &type);
520 
521     void checkIndexIsNotSpecified(const TSourceLoc &location, int index);
522     void checkBindingIsValid(const TSourceLoc &identifierLocation, const TType &type);
523     void checkBindingIsNotSpecified(const TSourceLoc &location, int binding);
524     void checkOffsetIsNotSpecified(const TSourceLoc &location, int offset);
525     void checkImageBindingIsValid(const TSourceLoc &location,
526                                   int binding,
527                                   int arrayTotalElementCount);
528     void checkSamplerBindingIsValid(const TSourceLoc &location,
529                                     int binding,
530                                     int arrayTotalElementCount);
531     void checkBlockBindingIsValid(const TSourceLoc &location,
532                                   const TQualifier &qualifier,
533                                   int binding,
534                                   int arraySize);
535     void checkAtomicCounterBindingIsValid(const TSourceLoc &location, int binding);
536 
537     void checkUniformLocationInRange(const TSourceLoc &location,
538                                      int objectLocationCount,
539                                      const TLayoutQualifier &layoutQualifier);
540 
541     void checkYuvIsNotSpecified(const TSourceLoc &location, bool yuv);
542 
543     bool checkUnsizedArrayConstructorArgumentDimensionality(const TIntermSequence &arguments,
544                                                             TType type,
545                                                             const TSourceLoc &line);
546 
547     // Will set the size of the outermost array according to geometry shader input layout.
548     void checkGeometryShaderInputAndSetArraySize(const TSourceLoc &location,
549                                                  const ImmutableString &token,
550                                                  TType *type);
551 
552     // Will size any unsized array type so unsized arrays won't need to be taken into account
553     // further along the line in parsing.
554     void checkIsNotUnsizedArray(const TSourceLoc &line,
555                                 const char *errorMessage,
556                                 const ImmutableString &token,
557                                 TType *arrayType);
558 
559     TIntermTyped *addBinaryMathInternal(TOperator op,
560                                         TIntermTyped *left,
561                                         TIntermTyped *right,
562                                         const TSourceLoc &loc);
563     TIntermTyped *createUnaryMath(TOperator op,
564                                   TIntermTyped *child,
565                                   const TSourceLoc &loc,
566                                   const TFunction *func);
567 
568     TIntermTyped *addMethod(TFunctionLookup *fnCall, const TSourceLoc &loc);
569     TIntermTyped *addConstructor(TFunctionLookup *fnCall, const TSourceLoc &line);
570     TIntermTyped *addNonConstructorFunctionCall(TFunctionLookup *fnCall, const TSourceLoc &loc);
571 
572     // Return either the original expression or the folded version of the expression in case the
573     // folded node will validate the same way during subsequent parsing.
574     TIntermTyped *expressionOrFoldedResult(TIntermTyped *expression);
575 
576     // Return true if the checks pass
577     bool binaryOpCommonCheck(TOperator op,
578                              TIntermTyped *left,
579                              TIntermTyped *right,
580                              const TSourceLoc &loc);
581 
582     TIntermFunctionPrototype *createPrototypeNodeFromFunction(const TFunction &function,
583                                                               const TSourceLoc &location,
584                                                               bool insertParametersToSymbolTable);
585 
586     void setAtomicCounterBindingDefaultOffset(const TPublicType &declaration,
587                                               const TSourceLoc &location);
588 
589     bool checkPrimitiveTypeMatchesTypeQualifier(const TTypeQualifier &typeQualifier);
590     bool parseGeometryShaderInputLayoutQualifier(const TTypeQualifier &typeQualifier);
591     bool parseGeometryShaderOutputLayoutQualifier(const TTypeQualifier &typeQualifier);
592     void setGeometryShaderInputArraySize(unsigned int inputArraySize, const TSourceLoc &line);
593 
594     // Set to true when the last/current declarator list was started with an empty declaration. The
595     // non-empty declaration error check will need to be performed if the empty declaration is
596     // followed by a declarator.
597     bool mDeferredNonEmptyDeclarationErrorCheck;
598 
599     sh::GLenum mShaderType;    // vertex or fragment language (future: pack or unpack)
600     ShShaderSpec mShaderSpec;  // The language specification compiler conforms to - GLES2 or WebGL.
601     ShCompileOptions mCompileOptions;  // Options passed to TCompiler
602     int mShaderVersion;
603     TIntermBlock *mTreeRoot;  // root of parse tree being created
604     int mLoopNestingLevel;    // 0 if outside all loops
605     int mStructNestingLevel;  // incremented while parsing a struct declaration
606     int mSwitchNestingLevel;  // 0 if outside all switch statements
607     const TType
608         *mCurrentFunctionType;    // the return type of the function that's currently being parsed
609     bool mFunctionReturnsValue;   // true if a non-void function has a return
610     bool mChecksPrecisionErrors;  // true if an error will be generated when a variable is declared
611                                   // without precision, explicit or implicit.
612     bool mFragmentPrecisionHighOnESSL1;  // true if highp precision is supported when compiling
613                                          // ESSL1.
614     TLayoutMatrixPacking mDefaultUniformMatrixPacking;
615     TLayoutBlockStorage mDefaultUniformBlockStorage;
616     TLayoutMatrixPacking mDefaultBufferMatrixPacking;
617     TLayoutBlockStorage mDefaultBufferBlockStorage;
618     TString mHashErrMsg;
619     TDiagnostics *mDiagnostics;
620     TDirectiveHandler mDirectiveHandler;
621     angle::pp::Preprocessor mPreprocessor;
622     void *mScanner;
623     int mMinProgramTexelOffset;
624     int mMaxProgramTexelOffset;
625 
626     int mMinProgramTextureGatherOffset;
627     int mMaxProgramTextureGatherOffset;
628 
629     // keep track of local group size declared in layout. It should be declared only once.
630     bool mComputeShaderLocalSizeDeclared;
631     sh::WorkGroupSize mComputeShaderLocalSize;
632     // keep track of number of views declared in layout.
633     int mNumViews;
634     int mMaxNumViews;
635     int mMaxImageUnits;
636     int mMaxCombinedTextureImageUnits;
637     int mMaxUniformLocations;
638     int mMaxUniformBufferBindings;
639     int mMaxAtomicCounterBindings;
640     int mMaxShaderStorageBufferBindings;
641 
642     // keeps track whether we are declaring / defining a function
643     bool mDeclaringFunction;
644 
645     // Track the state of each atomic counter binding.
646     std::map<int, AtomicCounterBindingState> mAtomicCounterBindingStates;
647 
648     // Track the geometry shader global parameters declared in layout.
649     TLayoutPrimitiveType mGeometryShaderInputPrimitiveType;
650     TLayoutPrimitiveType mGeometryShaderOutputPrimitiveType;
651     int mGeometryShaderInvocations;
652     int mGeometryShaderMaxVertices;
653     int mMaxGeometryShaderInvocations;
654     int mMaxGeometryShaderMaxVertices;
655 
656     // Track when we add new scope for func body in ESSL 1.00 spec
657     bool mFunctionBodyNewScope;
658 };
659 
660 int PaParseStrings(size_t count,
661                    const char *const string[],
662                    const int length[],
663                    TParseContext *context);
664 
665 }  // namespace sh
666 
667 #endif  // COMPILER_TRANSLATOR_PARSECONTEXT_H_
668