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/translator/Compiler.h"
10 #include "compiler/translator/Diagnostics.h"
11 #include "compiler/translator/DirectiveHandler.h"
12 #include "compiler/translator/SymbolTable.h"
13 #include "compiler/translator/QualifierTypes.h"
14 #include "compiler/preprocessor/Preprocessor.h"
15 
16 namespace sh
17 {
18 
19 struct TMatrixFields
20 {
21     bool wholeRow;
22     bool wholeCol;
23     int row;
24     int col;
25 };
26 
27 //
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 //
31 class TParseContext : angle::NonCopyable
32 {
33   public:
34     TParseContext(TSymbolTable &symt,
35                   TExtensionBehavior &ext,
36                   sh::GLenum type,
37                   ShShaderSpec spec,
38                   ShCompileOptions options,
39                   bool checksPrecErrors,
40                   TDiagnostics *diagnostics,
41                   const ShBuiltInResources &resources);
42     ~TParseContext();
43 
getPreprocessor()44     const pp::Preprocessor &getPreprocessor() const { return mPreprocessor; }
getPreprocessor()45     pp::Preprocessor &getPreprocessor() { return mPreprocessor; }
getScanner()46     void *getScanner() const { return mScanner; }
setScanner(void * scanner)47     void setScanner(void *scanner) { mScanner = scanner; }
getShaderVersion()48     int getShaderVersion() const { return mShaderVersion; }
getShaderType()49     sh::GLenum getShaderType() const { return mShaderType; }
getShaderSpec()50     ShShaderSpec getShaderSpec() const { return mShaderSpec; }
numErrors()51     int numErrors() const { return mDiagnostics->numErrors(); }
52     void error(const TSourceLoc &loc, const char *reason, const char *token);
53     void warning(const TSourceLoc &loc, const char *reason, const char *token);
54 
55     // If isError is false, a warning will be reported instead.
56     void outOfRangeError(bool isError,
57                          const TSourceLoc &loc,
58                          const char *reason,
59                          const char *token);
60 
getTreeRoot()61     TIntermBlock *getTreeRoot() const { return mTreeRoot; }
setTreeRoot(TIntermBlock * treeRoot)62     void setTreeRoot(TIntermBlock *treeRoot) { mTreeRoot = treeRoot; }
63 
getFragmentPrecisionHigh()64     bool getFragmentPrecisionHigh() const
65     {
66         return mFragmentPrecisionHighOnESSL1 || mShaderVersion >= 300;
67     }
setFragmentPrecisionHighOnESSL1(bool fragmentPrecisionHigh)68     void setFragmentPrecisionHighOnESSL1(bool fragmentPrecisionHigh)
69     {
70         mFragmentPrecisionHighOnESSL1 = fragmentPrecisionHigh;
71     }
72 
setLoopNestingLevel(int loopNestintLevel)73     void setLoopNestingLevel(int loopNestintLevel) { mLoopNestingLevel = loopNestintLevel; }
74 
incrLoopNestingLevel()75     void incrLoopNestingLevel() { ++mLoopNestingLevel; }
decrLoopNestingLevel()76     void decrLoopNestingLevel() { --mLoopNestingLevel; }
77 
incrSwitchNestingLevel()78     void incrSwitchNestingLevel() { ++mSwitchNestingLevel; }
decrSwitchNestingLevel()79     void decrSwitchNestingLevel() { --mSwitchNestingLevel; }
80 
isComputeShaderLocalSizeDeclared()81     bool isComputeShaderLocalSizeDeclared() const { return mComputeShaderLocalSizeDeclared; }
82     sh::WorkGroupSize getComputeShaderLocalSize() const;
83 
getNumViews()84     int getNumViews() const { return mNumViews; }
85 
enterFunctionDeclaration()86     void enterFunctionDeclaration() { mDeclaringFunction = true; }
87 
exitFunctionDeclaration()88     void exitFunctionDeclaration() { mDeclaringFunction = false; }
89 
declaringFunction()90     bool declaringFunction() const { return mDeclaringFunction; }
91 
92     TIntermConstantUnion *addScalarLiteral(const TConstantUnion *constantUnion,
93                                            const TSourceLoc &line);
94 
95     // This method is guaranteed to succeed, even if no variable with 'name' exists.
96     const TVariable *getNamedVariable(const TSourceLoc &location,
97                                       const TString *name,
98                                       const TSymbol *symbol);
99     TIntermTyped *parseVariableIdentifier(const TSourceLoc &location,
100                                           const TString *name,
101                                           const TSymbol *symbol);
102 
103     // 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);
108 
109     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);
112 
113     // Check functions - the ones that return bool return false if an error was generated.
114 
115     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);
120     bool checkIsAtGlobalLevel(const TSourceLoc &line, const char *token);
121     bool checkConstructorArguments(const TSourceLoc &line,
122                                    const TIntermSequence *arguments,
123                                    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);
127     bool checkIsValidQualifierForArray(const TSourceLoc &line, const TPublicType &elementQualifier);
128     bool checkArrayElementIsNotArray(const TSourceLoc &line, const TPublicType &elementType);
129     bool checkIsNonVoid(const TSourceLoc &line, const TString &identifier, const TBasicType &type);
130     bool checkIsScalarBool(const TSourceLoc &line, const TIntermTyped *type);
131     void checkIsScalarBool(const TSourceLoc &line, const TPublicType &pType);
132     bool checkIsNotOpaqueType(const TSourceLoc &line,
133                               const TTypeSpecifierNonArray &pType,
134                               const char *reason);
135     void checkDeclaratorLocationIsNotSpecified(const TSourceLoc &line, const TPublicType &pType);
136     void checkLocationIsNotSpecified(const TSourceLoc &location,
137                                      const TLayoutQualifier &layoutQualifier);
138     void checkStd430IsForShaderStorageBlock(const TSourceLoc &location,
139                                             const TLayoutBlockStorage &blockStorage,
140                                             const TQualifier &qualifier);
141     void checkIsParameterQualifierValid(const TSourceLoc &line,
142                                         const TTypeQualifierBuilder &typeQualifierBuilder,
143                                         TType *type);
144 
145     // Check if at least one of the specified extensions can be used, and generate error/warning as
146     // appropriate according to the spec.
147     // This function is only needed for a few different small constant sizes of extension array, and
148     // we want to avoid unnecessary dynamic allocations. That's why checkCanUseOneOfExtensions is a
149     // template function rather than one taking a vector.
150     template <size_t size>
151     bool checkCanUseOneOfExtensions(const TSourceLoc &line,
152                                     const std::array<TExtension, size> &extensions);
153     bool checkCanUseExtension(const TSourceLoc &line, TExtension extension);
154 
155     // Done for all declarations, whether empty or not.
156     void declarationQualifierErrorCheck(const sh::TQualifier qualifier,
157                                         const sh::TLayoutQualifier &layoutQualifier,
158                                         const TSourceLoc &location);
159     // Done for the first non-empty declarator in a declaration.
160     void nonEmptyDeclarationErrorCheck(const TPublicType &publicType,
161                                        const TSourceLoc &identifierLocation);
162     // Done only for empty declarations.
163     void emptyDeclarationErrorCheck(const TType &type, const TSourceLoc &location);
164 
165     void checkLayoutQualifierSupported(const TSourceLoc &location,
166                                        const TString &layoutQualifierName,
167                                        int versionRequired);
168     bool checkWorkGroupSizeIsNotSpecified(const TSourceLoc &location,
169                                           const TLayoutQualifier &layoutQualifier);
170     void functionCallRValueLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *fnCall);
171     void checkInvariantVariableQualifier(bool invariant,
172                                          const TQualifier qualifier,
173                                          const TSourceLoc &invariantLocation);
174     void checkInputOutputTypeIsValidES3(const TQualifier qualifier,
175                                         const TPublicType &type,
176                                         const TSourceLoc &qualifierLocation);
177     void checkLocalVariableConstStorageQualifier(const TQualifierWrapperBase &qualifier);
pragma()178     const TPragma &pragma() const { return mDirectiveHandler.pragma(); }
extensionBehavior()179     const TExtensionBehavior &extensionBehavior() const
180     {
181         return mDirectiveHandler.extensionBehavior();
182     }
183 
184     bool isExtensionEnabled(TExtension extension) const;
185     void handleExtensionDirective(const TSourceLoc &loc, const char *extName, const char *behavior);
186     void handlePragmaDirective(const TSourceLoc &loc,
187                                const char *name,
188                                const char *value,
189                                bool stdgl);
190 
191     // Returns true on success. *initNode may still be nullptr on success in case the initialization
192     // is not needed in the AST.
193     bool executeInitializer(const TSourceLoc &line,
194                             const TString &identifier,
195                             TType type,
196                             TIntermTyped *initializer,
197                             TIntermBinary **initNode);
198     TIntermNode *addConditionInitializer(const TPublicType &pType,
199                                          const TString &identifier,
200                                          TIntermTyped *initializer,
201                                          const TSourceLoc &loc);
202     TIntermNode *addLoop(TLoopType type,
203                          TIntermNode *init,
204                          TIntermNode *cond,
205                          TIntermTyped *expr,
206                          TIntermNode *body,
207                          const TSourceLoc &loc);
208 
209     // For "if" test nodes. There are three children: a condition, a true path, and a false path.
210     // The two paths are in TIntermNodePair code.
211     TIntermNode *addIfElse(TIntermTyped *cond, TIntermNodePair code, const TSourceLoc &loc);
212 
213     void addFullySpecifiedType(TPublicType *typeSpecifier);
214     TPublicType addFullySpecifiedType(const TTypeQualifierBuilder &typeQualifierBuilder,
215                                       const TPublicType &typeSpecifier);
216 
217     TIntermDeclaration *parseSingleDeclaration(TPublicType &publicType,
218                                                const TSourceLoc &identifierOrTypeLocation,
219                                                const TString &identifier);
220     TIntermDeclaration *parseSingleArrayDeclaration(TPublicType &elementType,
221                                                     const TSourceLoc &identifierLocation,
222                                                     const TString &identifier,
223                                                     const TSourceLoc &indexLocation,
224                                                     const TVector<unsigned int> &arraySizes);
225     TIntermDeclaration *parseSingleInitDeclaration(const TPublicType &publicType,
226                                                    const TSourceLoc &identifierLocation,
227                                                    const TString &identifier,
228                                                    const TSourceLoc &initLocation,
229                                                    TIntermTyped *initializer);
230 
231     // Parse a declaration like "type a[n] = initializer"
232     // Note that this does not apply to declarations like "type[n] a = initializer"
233     TIntermDeclaration *parseSingleArrayInitDeclaration(TPublicType &elementType,
234                                                         const TSourceLoc &identifierLocation,
235                                                         const TString &identifier,
236                                                         const TSourceLoc &indexLocation,
237                                                         const TVector<unsigned int> &arraySizes,
238                                                         const TSourceLoc &initLocation,
239                                                         TIntermTyped *initializer);
240 
241     TIntermInvariantDeclaration *parseInvariantDeclaration(
242         const TTypeQualifierBuilder &typeQualifierBuilder,
243         const TSourceLoc &identifierLoc,
244         const TString *identifier,
245         const TSymbol *symbol);
246 
247     void parseDeclarator(TPublicType &publicType,
248                          const TSourceLoc &identifierLocation,
249                          const TString &identifier,
250                          TIntermDeclaration *declarationOut);
251     void parseArrayDeclarator(TPublicType &elementType,
252                               const TSourceLoc &identifierLocation,
253                               const TString &identifier,
254                               const TSourceLoc &arrayLocation,
255                               const TVector<unsigned int> &arraySizes,
256                               TIntermDeclaration *declarationOut);
257     void parseInitDeclarator(const TPublicType &publicType,
258                              const TSourceLoc &identifierLocation,
259                              const TString &identifier,
260                              const TSourceLoc &initLocation,
261                              TIntermTyped *initializer,
262                              TIntermDeclaration *declarationOut);
263 
264     // Parse a declarator like "a[n] = initializer"
265     void parseArrayInitDeclarator(const TPublicType &elementType,
266                                   const TSourceLoc &identifierLocation,
267                                   const TString &identifier,
268                                   const TSourceLoc &indexLocation,
269                                   const TVector<unsigned int> &arraySizes,
270                                   const TSourceLoc &initLocation,
271                                   TIntermTyped *initializer,
272                                   TIntermDeclaration *declarationOut);
273 
274     TIntermNode *addEmptyStatement(const TSourceLoc &location);
275 
276     void parseDefaultPrecisionQualifier(const TPrecision precision,
277                                         const TPublicType &type,
278                                         const TSourceLoc &loc);
279     void parseGlobalLayoutQualifier(const TTypeQualifierBuilder &typeQualifierBuilder);
280 
281     TIntermFunctionPrototype *addFunctionPrototypeDeclaration(const TFunction &parsedFunction,
282                                                               const TSourceLoc &location);
283     TIntermFunctionDefinition *addFunctionDefinition(TIntermFunctionPrototype *functionPrototype,
284                                                      TIntermBlock *functionBody,
285                                                      const TSourceLoc &location);
286     void parseFunctionDefinitionHeader(const TSourceLoc &location,
287                                        TFunction **function,
288                                        TIntermFunctionPrototype **prototypeOut);
289     TFunction *parseFunctionDeclarator(const TSourceLoc &location, TFunction *function);
290     TFunction *parseFunctionHeader(const TPublicType &type,
291                                    const TString *name,
292                                    const TSourceLoc &location);
293     TFunction *addNonConstructorFunc(const TString *name, const TSourceLoc &loc);
294     TFunction *addConstructorFunc(const TPublicType &publicType);
295     TParameter parseParameterDeclarator(const TPublicType &publicType,
296                                         const TString *name,
297                                         const TSourceLoc &nameLoc);
298 
299     TParameter parseParameterArrayDeclarator(const TString *name,
300                                              const TSourceLoc &nameLoc,
301                                              const TVector<unsigned int> &arraySizes,
302                                              const TSourceLoc &arrayLoc,
303                                              TPublicType *elementType);
304 
305     TIntermTyped *addIndexExpression(TIntermTyped *baseExpression,
306                                      const TSourceLoc &location,
307                                      TIntermTyped *indexExpression);
308     TIntermTyped *addFieldSelectionExpression(TIntermTyped *baseExpression,
309                                               const TSourceLoc &dotLocation,
310                                               const TString &fieldString,
311                                               const TSourceLoc &fieldLocation);
312 
313     // Parse declarator for a single field
314     TField *parseStructDeclarator(TString *identifier, const TSourceLoc &loc);
315     TField *parseStructArrayDeclarator(TString *identifier,
316                                        const TSourceLoc &loc,
317                                        const TVector<unsigned int> &arraySizes,
318                                        const TSourceLoc &arraySizeLoc);
319 
320     void checkDoesNotHaveDuplicateFieldName(const TFieldList::const_iterator begin,
321                                             const TFieldList::const_iterator end,
322                                             const TString &name,
323                                             const TSourceLoc &location);
324     TFieldList *addStructFieldList(TFieldList *fields, const TSourceLoc &location);
325     TFieldList *combineStructFieldLists(TFieldList *processedFields,
326                                         const TFieldList *newlyAddedFields,
327                                         const TSourceLoc &location);
328     TFieldList *addStructDeclaratorListWithQualifiers(
329         const TTypeQualifierBuilder &typeQualifierBuilder,
330         TPublicType *typeSpecifier,
331         TFieldList *fieldList);
332     TFieldList *addStructDeclaratorList(const TPublicType &typeSpecifier, TFieldList *fieldList);
333     TTypeSpecifierNonArray addStructure(const TSourceLoc &structLine,
334                                         const TSourceLoc &nameLine,
335                                         const TString *structName,
336                                         TFieldList *fieldList);
337 
338     TIntermDeclaration *addInterfaceBlock(const TTypeQualifierBuilder &typeQualifierBuilder,
339                                           const TSourceLoc &nameLine,
340                                           const TString &blockName,
341                                           TFieldList *fieldList,
342                                           const TString *instanceName,
343                                           const TSourceLoc &instanceLine,
344                                           TIntermTyped *arrayIndex,
345                                           const TSourceLoc &arrayIndexLine);
346 
347     void parseLocalSize(const TString &qualifierType,
348                         const TSourceLoc &qualifierTypeLine,
349                         int intValue,
350                         const TSourceLoc &intValueLine,
351                         const std::string &intValueString,
352                         size_t index,
353                         sh::WorkGroupSize *localSize);
354     void parseNumViews(int intValue,
355                        const TSourceLoc &intValueLine,
356                        const std::string &intValueString,
357                        int *numViews);
358     void parseInvocations(int intValue,
359                           const TSourceLoc &intValueLine,
360                           const std::string &intValueString,
361                           int *numInvocations);
362     void parseMaxVertices(int intValue,
363                           const TSourceLoc &intValueLine,
364                           const std::string &intValueString,
365                           int *numMaxVertices);
366     TLayoutQualifier parseLayoutQualifier(const TString &qualifierType,
367                                           const TSourceLoc &qualifierTypeLine);
368     TLayoutQualifier parseLayoutQualifier(const TString &qualifierType,
369                                           const TSourceLoc &qualifierTypeLine,
370                                           int intValue,
371                                           const TSourceLoc &intValueLine);
372     TTypeQualifierBuilder *createTypeQualifierBuilder(const TSourceLoc &loc);
373     TStorageQualifierWrapper *parseGlobalStorageQualifier(TQualifier qualifier,
374                                                           const TSourceLoc &loc);
375     TStorageQualifierWrapper *parseVaryingQualifier(const TSourceLoc &loc);
376     TStorageQualifierWrapper *parseInQualifier(const TSourceLoc &loc);
377     TStorageQualifierWrapper *parseOutQualifier(const TSourceLoc &loc);
378     TStorageQualifierWrapper *parseInOutQualifier(const TSourceLoc &loc);
379     TLayoutQualifier joinLayoutQualifiers(TLayoutQualifier leftQualifier,
380                                           TLayoutQualifier rightQualifier,
381                                           const TSourceLoc &rightQualifierLocation);
382 
383     // Performs an error check for embedded struct declarations.
384     void enterStructDeclaration(const TSourceLoc &line, const TString &identifier);
385     void exitStructDeclaration();
386 
387     void checkIsBelowStructNestingLimit(const TSourceLoc &line, const TField &field);
388 
389     TIntermSwitch *addSwitch(TIntermTyped *init,
390                              TIntermBlock *statementList,
391                              const TSourceLoc &loc);
392     TIntermCase *addCase(TIntermTyped *condition, const TSourceLoc &loc);
393     TIntermCase *addDefault(const TSourceLoc &loc);
394 
395     TIntermTyped *addUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc);
396     TIntermTyped *addUnaryMathLValue(TOperator op, TIntermTyped *child, const TSourceLoc &loc);
397     TIntermTyped *addBinaryMath(TOperator op,
398                                 TIntermTyped *left,
399                                 TIntermTyped *right,
400                                 const TSourceLoc &loc);
401     TIntermTyped *addBinaryMathBooleanResult(TOperator op,
402                                              TIntermTyped *left,
403                                              TIntermTyped *right,
404                                              const TSourceLoc &loc);
405     TIntermTyped *addAssign(TOperator op,
406                             TIntermTyped *left,
407                             TIntermTyped *right,
408                             const TSourceLoc &loc);
409 
410     TIntermTyped *addComma(TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc);
411 
412     TIntermBranch *addBranch(TOperator op, const TSourceLoc &loc);
413     TIntermBranch *addBranch(TOperator op, TIntermTyped *expression, const TSourceLoc &loc);
414 
415     void checkTextureGather(TIntermAggregate *functionCall);
416     void checkTextureOffsetConst(TIntermAggregate *functionCall);
417     void checkImageMemoryAccessForBuiltinFunctions(TIntermAggregate *functionCall);
418     void checkImageMemoryAccessForUserDefinedFunctions(const TFunction *functionDefinition,
419                                                        const TIntermAggregate *functionCall);
420     void checkAtomicMemoryBuiltinFunctions(TIntermAggregate *functionCall);
421     TIntermSequence *createEmptyArgumentsList();
422 
423     // fnCall is only storing the built-in op, and function name or constructor type. arguments
424     // has the arguments.
425     TIntermTyped *addFunctionCallOrMethod(TFunction *fnCall,
426                                           TIntermSequence *arguments,
427                                           TIntermNode *thisNode,
428                                           const TSourceLoc &loc);
429 
430     TIntermTyped *addTernarySelection(TIntermTyped *cond,
431                                       TIntermTyped *trueExpression,
432                                       TIntermTyped *falseExpression,
433                                       const TSourceLoc &line);
434 
getGeometryShaderMaxVertices()435     int getGeometryShaderMaxVertices() const { return mGeometryShaderMaxVertices; }
getGeometryShaderInvocations()436     int getGeometryShaderInvocations() const
437     {
438         return (mGeometryShaderInvocations > 0) ? mGeometryShaderInvocations : 1;
439     }
getGeometryShaderInputPrimitiveType()440     TLayoutPrimitiveType getGeometryShaderInputPrimitiveType() const
441     {
442         return mGeometryShaderInputPrimitiveType;
443     }
getGeometryShaderOutputPrimitiveType()444     TLayoutPrimitiveType getGeometryShaderOutputPrimitiveType() const
445     {
446         return mGeometryShaderOutputPrimitiveType;
447     }
448 
449     // TODO(jmadill): make this private
450     TSymbolTable &symbolTable;   // symbol table that goes with the language currently being parsed
451 
452   private:
453     class AtomicCounterBindingState;
454     constexpr static size_t kAtomicCounterSize = 4;
455     // UNIFORM_ARRAY_STRIDE for atomic counter arrays is an implementation-dependent value which
456     // can be queried after a program is linked according to ES 3.10 section 7.7.1. This is
457     // controversial with the offset inheritance as described in ESSL 3.10 section 4.4.6. Currently
458     // we treat it as always 4 in favour of the original interpretation in
459     // "ARB_shader_atomic_counters".
460     // TODO(jie.a.chen@intel.com): Double check this once the spec vagueness is resolved.
461     // Note that there may be tests in AtomicCounter_test that will need to be updated as well.
462     constexpr static size_t kAtomicCounterArrayStride = 4;
463 
464     // Returns a clamped index. If it prints out an error message, the token is "[]".
465     int checkIndexLessThan(bool outOfRangeIndexIsError,
466                            const TSourceLoc &location,
467                            int index,
468                            int arraySize,
469                            const char *reason);
470 
471     bool declareVariable(const TSourceLoc &line,
472                          const TString &identifier,
473                          const TType &type,
474                          TVariable **variable);
475 
476     void checkCanBeDeclaredWithoutInitializer(const TSourceLoc &line,
477                                               const TString &identifier,
478                                               TType *type);
479 
480     TParameter parseParameterDeclarator(TType *type,
481                                         const TString *name,
482                                         const TSourceLoc &nameLoc);
483 
484     bool checkIsValidTypeAndQualifierForArray(const TSourceLoc &indexLocation,
485                                               const TPublicType &elementType);
486     // Done for all atomic counter declarations, whether empty or not.
487     void atomicCounterQualifierErrorCheck(const TPublicType &publicType,
488                                           const TSourceLoc &location);
489 
490     // Assumes that multiplication op has already been set based on the types.
491     bool isMultiplicationTypeCombinationValid(TOperator op, const TType &left, const TType &right);
492 
493     void checkOutParameterIsNotOpaqueType(const TSourceLoc &line,
494                                           TQualifier qualifier,
495                                           const TType &type);
496 
497     void checkInternalFormatIsNotSpecified(const TSourceLoc &location,
498                                            TLayoutImageInternalFormat internalFormat);
499     void checkMemoryQualifierIsNotSpecified(const TMemoryQualifier &memoryQualifier,
500                                             const TSourceLoc &location);
501     void checkAtomicCounterOffsetDoesNotOverlap(bool forceAppend,
502                                                 const TSourceLoc &loc,
503                                                 TType *type);
504     void checkBindingIsValid(const TSourceLoc &identifierLocation, const TType &type);
505     void checkBindingIsNotSpecified(const TSourceLoc &location, int binding);
506     void checkOffsetIsNotSpecified(const TSourceLoc &location, int offset);
507     void checkImageBindingIsValid(const TSourceLoc &location,
508                                   int binding,
509                                   int arrayTotalElementCount);
510     void checkSamplerBindingIsValid(const TSourceLoc &location,
511                                     int binding,
512                                     int arrayTotalElementCount);
513     void checkBlockBindingIsValid(const TSourceLoc &location,
514                                   const TQualifier &qualifier,
515                                   int binding,
516                                   int arraySize);
517     void checkAtomicCounterBindingIsValid(const TSourceLoc &location, int binding);
518 
519     void checkUniformLocationInRange(const TSourceLoc &location,
520                                      int objectLocationCount,
521                                      const TLayoutQualifier &layoutQualifier);
522 
523     void checkYuvIsNotSpecified(const TSourceLoc &location, bool yuv);
524 
525     bool checkUnsizedArrayConstructorArgumentDimensionality(TIntermSequence *arguments,
526                                                             TType type,
527                                                             const TSourceLoc &line);
528 
529     // Will set the size of the outermost array according to geometry shader input layout.
530     void checkGeometryShaderInputAndSetArraySize(const TSourceLoc &location,
531                                                  const char *token,
532                                                  TType *type);
533 
534     // Will size any unsized array type so unsized arrays won't need to be taken into account
535     // further along the line in parsing.
536     void checkIsNotUnsizedArray(const TSourceLoc &line,
537                                 const char *errorMessage,
538                                 const char *token,
539                                 TType *arrayType);
540 
541     TIntermTyped *addBinaryMathInternal(TOperator op,
542                                         TIntermTyped *left,
543                                         TIntermTyped *right,
544                                         const TSourceLoc &loc);
545     TIntermBinary *createAssign(TOperator op,
546                                 TIntermTyped *left,
547                                 TIntermTyped *right,
548                                 const TSourceLoc &loc);
549     TIntermTyped *createUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc);
550 
551     TIntermTyped *addMethod(TFunction *fnCall,
552                             TIntermSequence *arguments,
553                             TIntermNode *thisNode,
554                             const TSourceLoc &loc);
555     TIntermTyped *addConstructor(TIntermSequence *arguments,
556                                  TType type,
557                                  const TSourceLoc &line);
558     TIntermTyped *addNonConstructorFunctionCall(TFunction *fnCall,
559                                                 TIntermSequence *arguments,
560                                                 const TSourceLoc &loc);
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     // Track if all input array sizes are same and matches the latter input primitive declaration.
647     unsigned int mGeometryShaderInputArraySize;
648 };
649 
650 int PaParseStrings(size_t count,
651                    const char *const string[],
652                    const int length[],
653                    TParseContext *context);
654 
655 }  // namespace sh
656 
657 #endif  // COMPILER_TRANSLATOR_PARSECONTEXT_H_
658