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