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