• 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                   const 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; }
67     void setTreeRoot(TIntermBlock *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 
usesDerivatives()78     bool usesDerivatives() const { return mUsesDerivatives; }
isEarlyFragmentTestsSpecified()79     bool isEarlyFragmentTestsSpecified() const { return mEarlyFragmentTestsSpecified; }
hasDiscard()80     bool hasDiscard() const { return mHasDiscard; }
isSampleQualifierSpecified()81     bool isSampleQualifierSpecified() const { return mSampleQualifierSpecified; }
82 
setLoopNestingLevel(int loopNestintLevel)83     void setLoopNestingLevel(int loopNestintLevel) { mLoopNestingLevel = loopNestintLevel; }
84 
incrLoopNestingLevel(const TSourceLoc & line)85     void incrLoopNestingLevel(const TSourceLoc &line)
86     {
87         ++mLoopNestingLevel;
88         checkNestingLevel(line);
89     }
decrLoopNestingLevel()90     void decrLoopNestingLevel() { --mLoopNestingLevel; }
91 
incrSwitchNestingLevel(const TSourceLoc & line)92     void incrSwitchNestingLevel(const TSourceLoc &line)
93     {
94         ++mSwitchNestingLevel;
95         checkNestingLevel(line);
96     }
decrSwitchNestingLevel()97     void decrSwitchNestingLevel() { --mSwitchNestingLevel; }
98 
isComputeShaderLocalSizeDeclared()99     bool isComputeShaderLocalSizeDeclared() const { return mComputeShaderLocalSizeDeclared; }
100     sh::WorkGroupSize getComputeShaderLocalSize() const;
101 
getNumViews()102     int getNumViews() const { return mNumViews; }
103 
pixelLocalStorageBindings()104     const std::map<int, TLayoutImageInternalFormat> &pixelLocalStorageBindings() const
105     {
106         return mPLSBindings;
107     }
108 
enterFunctionDeclaration()109     void enterFunctionDeclaration() { mDeclaringFunction = true; }
110 
exitFunctionDeclaration()111     void exitFunctionDeclaration() { mDeclaringFunction = false; }
112 
declaringFunction()113     bool declaringFunction() const { return mDeclaringFunction; }
114 
115     TIntermConstantUnion *addScalarLiteral(const TConstantUnion *constantUnion,
116                                            const TSourceLoc &line);
117 
118     // This method is guaranteed to succeed, even if no variable with 'name' exists.
119     const TVariable *getNamedVariable(const TSourceLoc &location,
120                                       const ImmutableString &name,
121                                       const TSymbol *symbol);
122     TIntermTyped *parseVariableIdentifier(const TSourceLoc &location,
123                                           const ImmutableString &name,
124                                           const TSymbol *symbol);
125 
126     // Look at a '.' field selector string and change it into offsets for a vector.
127     bool parseVectorFields(const TSourceLoc &line,
128                            const ImmutableString &compString,
129                            int vecSize,
130                            TVector<int> *fieldOffsets);
131 
132     void assignError(const TSourceLoc &line, const char *op, const TType &left, const TType &right);
133     void unaryOpError(const TSourceLoc &line, const char *op, const TType &operand);
134     void binaryOpError(const TSourceLoc &line,
135                        const char *op,
136                        const TType &left,
137                        const TType &right);
138 
139     // Check functions - the ones that return bool return false if an error was generated.
140 
141     bool checkIsNotReserved(const TSourceLoc &line, const ImmutableString &identifier);
142     void checkPrecisionSpecified(const TSourceLoc &line, TPrecision precision, TBasicType type);
143     bool checkCanBeLValue(const TSourceLoc &line, const char *op, TIntermTyped *node);
144     void checkIsConst(TIntermTyped *node);
145     void checkIsScalarInteger(TIntermTyped *node, const char *token);
146     bool checkIsAtGlobalLevel(const TSourceLoc &line, const char *token);
147     bool checkConstructorArguments(const TSourceLoc &line,
148                                    const TIntermSequence &arguments,
149                                    const TType &type);
150 
151     // Returns a sanitized array size to use (the size is at least 1).
152     unsigned int checkIsValidArraySize(const TSourceLoc &line, TIntermTyped *expr);
153     bool checkIsValidArrayDimension(const TSourceLoc &line, TVector<unsigned int> *arraySizes);
154     bool checkIsValidQualifierForArray(const TSourceLoc &line, const TPublicType &elementQualifier);
155     bool checkArrayElementIsNotArray(const TSourceLoc &line, const TPublicType &elementType);
156     bool checkArrayOfArraysInOut(const TSourceLoc &line,
157                                  const TPublicType &elementType,
158                                  const TType &arrayType);
159     bool checkIsNonVoid(const TSourceLoc &line,
160                         const ImmutableString &identifier,
161                         const TBasicType &type);
162     bool checkIsScalarBool(const TSourceLoc &line, const TIntermTyped *type);
163     void checkIsScalarBool(const TSourceLoc &line, const TPublicType &pType);
164     bool checkIsNotOpaqueType(const TSourceLoc &line,
165                               const TTypeSpecifierNonArray &pType,
166                               const char *reason);
167     void checkDeclaratorLocationIsNotSpecified(const TSourceLoc &line, const TPublicType &pType);
168     void checkLocationIsNotSpecified(const TSourceLoc &location,
169                                      const TLayoutQualifier &layoutQualifier);
170     void checkStd430IsForShaderStorageBlock(const TSourceLoc &location,
171                                             const TLayoutBlockStorage &blockStorage,
172                                             const TQualifier &qualifier);
173     void checkIsParameterQualifierValid(const TSourceLoc &line,
174                                         const TTypeQualifierBuilder &typeQualifierBuilder,
175                                         TType *type);
176 
177     // Check if at least one of the specified extensions can be used, and generate error/warning as
178     // appropriate according to the spec.
179     // This function is only needed for a few different small constant sizes of extension array, and
180     // we want to avoid unnecessary dynamic allocations. That's why checkCanUseOneOfExtensions is a
181     // template function rather than one taking a vector.
182     template <size_t size>
183     bool checkCanUseOneOfExtensions(const TSourceLoc &line,
184                                     const std::array<TExtension, size> &extensions);
185     bool checkCanUseExtension(const TSourceLoc &line, TExtension extension);
186 
187     // Done for all declarations, whether empty or not.
188     void declarationQualifierErrorCheck(const sh::TQualifier qualifier,
189                                         const sh::TLayoutQualifier &layoutQualifier,
190                                         const TSourceLoc &location);
191     // Done for the first non-empty declarator in a declaration.
192     void nonEmptyDeclarationErrorCheck(const TPublicType &publicType,
193                                        const TSourceLoc &identifierLocation);
194     // Done only for empty declarations.
195     void emptyDeclarationErrorCheck(const TType &type, const TSourceLoc &location);
196 
197     void checkCanUseLayoutQualifier(const TSourceLoc &location);
198     bool checkLayoutQualifierSupported(const TSourceLoc &location,
199                                        const ImmutableString &layoutQualifierName,
200                                        int versionRequired);
201     bool checkWorkGroupSizeIsNotSpecified(const TSourceLoc &location,
202                                           const TLayoutQualifier &layoutQualifier);
203     void functionCallRValueLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *fnCall);
204     void checkInvariantVariableQualifier(bool invariant,
205                                          const TQualifier qualifier,
206                                          const TSourceLoc &invariantLocation);
207     void checkInputOutputTypeIsValidES3(const TQualifier qualifier,
208                                         const TPublicType &type,
209                                         const TSourceLoc &qualifierLocation);
210     void checkLocalVariableConstStorageQualifier(const TQualifierWrapperBase &qualifier);
211     void checkTCSOutVarIndexIsValid(TIntermBinary *binaryExpression, const TSourceLoc &location);
212 
213     void checkAdvancedBlendEquationsNotSpecified(
214         const TSourceLoc &location,
215         const AdvancedBlendEquations &advancedBlendEquations,
216         const TQualifier &qualifier);
217 
pragma()218     const TPragma &pragma() const { return mDirectiveHandler.pragma(); }
extensionBehavior()219     const TExtensionBehavior &extensionBehavior() const
220     {
221         return mDirectiveHandler.extensionBehavior();
222     }
223 
224     bool isExtensionEnabled(TExtension extension) const;
225     void handleExtensionDirective(const TSourceLoc &loc, const char *extName, const char *behavior);
226     void handlePragmaDirective(const TSourceLoc &loc,
227                                const char *name,
228                                const char *value,
229                                bool stdgl);
230 
231     // For built-ins that can be redeclared, adjusts the type qualifier so transformations can
232     // identify them correctly.
233     void adjustRedeclaredBuiltInType(const TSourceLoc &line,
234                                      const ImmutableString &identifier,
235                                      TType *type);
236 
237     // Returns true on success. *initNode may still be nullptr on success in case the initialization
238     // is not needed in the AST.
239     bool executeInitializer(const TSourceLoc &line,
240                             const ImmutableString &identifier,
241                             TType *type,
242                             TIntermTyped *initializer,
243                             TIntermBinary **initNode);
244     TIntermNode *addConditionInitializer(const TPublicType &pType,
245                                          const ImmutableString &identifier,
246                                          TIntermTyped *initializer,
247                                          const TSourceLoc &loc);
248     TIntermNode *addLoop(TLoopType type,
249                          TIntermNode *init,
250                          TIntermNode *cond,
251                          TIntermTyped *expr,
252                          TIntermNode *body,
253                          const TSourceLoc &loc);
254 
255     // For "if" test nodes. There are three children: a condition, a true path, and a false path.
256     // The two paths are in TIntermNodePair code.
257     TIntermNode *addIfElse(TIntermTyped *cond, TIntermNodePair code, const TSourceLoc &loc);
258 
259     void addFullySpecifiedType(TPublicType *typeSpecifier);
260     TPublicType addFullySpecifiedType(const TTypeQualifierBuilder &typeQualifierBuilder,
261                                       const TPublicType &typeSpecifier);
262 
263     TIntermDeclaration *parseSingleDeclaration(TPublicType &publicType,
264                                                const TSourceLoc &identifierOrTypeLocation,
265                                                const ImmutableString &identifier);
266     TIntermDeclaration *parseSingleArrayDeclaration(TPublicType &elementType,
267                                                     const TSourceLoc &identifierLocation,
268                                                     const ImmutableString &identifier,
269                                                     const TSourceLoc &indexLocation,
270                                                     const TVector<unsigned int> &arraySizes);
271     TIntermDeclaration *parseSingleInitDeclaration(const TPublicType &publicType,
272                                                    const TSourceLoc &identifierLocation,
273                                                    const ImmutableString &identifier,
274                                                    const TSourceLoc &initLocation,
275                                                    TIntermTyped *initializer);
276 
277     // Parse a declaration like "type a[n] = initializer"
278     // Note that this does not apply to declarations like "type[n] a = initializer"
279     TIntermDeclaration *parseSingleArrayInitDeclaration(TPublicType &elementType,
280                                                         const TSourceLoc &identifierLocation,
281                                                         const ImmutableString &identifier,
282                                                         const TSourceLoc &indexLocation,
283                                                         const TVector<unsigned int> &arraySizes,
284                                                         const TSourceLoc &initLocation,
285                                                         TIntermTyped *initializer);
286 
287     TIntermGlobalQualifierDeclaration *parseGlobalQualifierDeclaration(
288         const TTypeQualifierBuilder &typeQualifierBuilder,
289         const TSourceLoc &identifierLoc,
290         const ImmutableString &identifier,
291         const TSymbol *symbol);
292 
293     void parseDeclarator(TPublicType &publicType,
294                          const TSourceLoc &identifierLocation,
295                          const ImmutableString &identifier,
296                          TIntermDeclaration *declarationOut);
297     void parseArrayDeclarator(TPublicType &elementType,
298                               const TSourceLoc &identifierLocation,
299                               const ImmutableString &identifier,
300                               const TSourceLoc &arrayLocation,
301                               const TVector<unsigned int> &arraySizes,
302                               TIntermDeclaration *declarationOut);
303     void parseInitDeclarator(const TPublicType &publicType,
304                              const TSourceLoc &identifierLocation,
305                              const ImmutableString &identifier,
306                              const TSourceLoc &initLocation,
307                              TIntermTyped *initializer,
308                              TIntermDeclaration *declarationOut);
309 
310     // Parse a declarator like "a[n] = initializer"
311     void parseArrayInitDeclarator(const TPublicType &elementType,
312                                   const TSourceLoc &identifierLocation,
313                                   const ImmutableString &identifier,
314                                   const TSourceLoc &indexLocation,
315                                   const TVector<unsigned int> &arraySizes,
316                                   const TSourceLoc &initLocation,
317                                   TIntermTyped *initializer,
318                                   TIntermDeclaration *declarationOut);
319 
320     TIntermNode *addEmptyStatement(const TSourceLoc &location);
321 
322     void parseDefaultPrecisionQualifier(const TPrecision precision,
323                                         const TPublicType &type,
324                                         const TSourceLoc &loc);
325     void parseGlobalLayoutQualifier(const TTypeQualifierBuilder &typeQualifierBuilder);
326 
327     TIntermFunctionPrototype *addFunctionPrototypeDeclaration(const TFunction &parsedFunction,
328                                                               const TSourceLoc &location);
329     TIntermFunctionDefinition *addFunctionDefinition(TIntermFunctionPrototype *functionPrototype,
330                                                      TIntermBlock *functionBody,
331                                                      const TSourceLoc &location);
332     void parseFunctionDefinitionHeader(const TSourceLoc &location,
333                                        const TFunction *function,
334                                        TIntermFunctionPrototype **prototypeOut);
335     TFunction *parseFunctionDeclarator(const TSourceLoc &location, TFunction *function);
336     TFunction *parseFunctionHeader(const TPublicType &type,
337                                    const ImmutableString &name,
338                                    const TSourceLoc &location);
339 
340     TFunctionLookup *addNonConstructorFunc(const ImmutableString &name, const TSymbol *symbol);
341     TFunctionLookup *addConstructorFunc(const TPublicType &publicType);
342 
343     TParameter parseParameterDeclarator(const TPublicType &publicType,
344                                         const ImmutableString &name,
345                                         const TSourceLoc &nameLoc);
346 
347     TParameter parseParameterArrayDeclarator(const ImmutableString &name,
348                                              const TSourceLoc &nameLoc,
349                                              const TVector<unsigned int> &arraySizes,
350                                              const TSourceLoc &arrayLoc,
351                                              TPublicType *elementType);
352 
353     TIntermTyped *addIndexExpression(TIntermTyped *baseExpression,
354                                      const TSourceLoc &location,
355                                      TIntermTyped *indexExpression);
356     TIntermTyped *addFieldSelectionExpression(TIntermTyped *baseExpression,
357                                               const TSourceLoc &dotLocation,
358                                               const ImmutableString &fieldString,
359                                               const TSourceLoc &fieldLocation);
360 
361     // Parse declarator for a single field
362     TDeclarator *parseStructDeclarator(const ImmutableString &identifier, const TSourceLoc &loc);
363     TDeclarator *parseStructArrayDeclarator(const ImmutableString &identifier,
364                                             const TSourceLoc &loc,
365                                             const TVector<unsigned int> *arraySizes);
366 
367     void checkDoesNotHaveDuplicateFieldNames(const TFieldList *fields, const TSourceLoc &location);
368     void checkDoesNotHaveTooManyFields(const ImmutableString &name,
369                                        const TFieldList *fields,
370                                        const TSourceLoc &location);
371     TFieldList *addStructFieldList(TFieldList *fields, const TSourceLoc &location);
372     TFieldList *combineStructFieldLists(TFieldList *processedFields,
373                                         const TFieldList *newlyAddedFields,
374                                         const TSourceLoc &location);
375     TFieldList *addStructDeclaratorListWithQualifiers(
376         const TTypeQualifierBuilder &typeQualifierBuilder,
377         TPublicType *typeSpecifier,
378         const TDeclaratorList *declaratorList);
379     TFieldList *addStructDeclaratorList(const TPublicType &typeSpecifier,
380                                         const TDeclaratorList *declaratorList);
381     TTypeSpecifierNonArray addStructure(const TSourceLoc &structLine,
382                                         const TSourceLoc &nameLine,
383                                         const ImmutableString &structName,
384                                         TFieldList *fieldList);
385 
386     TIntermDeclaration *addInterfaceBlock(const TTypeQualifierBuilder &typeQualifierBuilder,
387                                           const TSourceLoc &nameLine,
388                                           const ImmutableString &blockName,
389                                           TFieldList *fieldList,
390                                           const ImmutableString &instanceName,
391                                           const TSourceLoc &instanceLine,
392                                           const TVector<unsigned int> *arraySizes,
393                                           const TSourceLoc &arraySizesLine);
394 
395     void parseLocalSize(const ImmutableString &qualifierType,
396                         const TSourceLoc &qualifierTypeLine,
397                         int intValue,
398                         const TSourceLoc &intValueLine,
399                         const std::string &intValueString,
400                         size_t index,
401                         sh::WorkGroupSize *localSize);
402     void parseNumViews(int intValue,
403                        const TSourceLoc &intValueLine,
404                        const std::string &intValueString,
405                        int *numViews);
406     void parseInvocations(int intValue,
407                           const TSourceLoc &intValueLine,
408                           const std::string &intValueString,
409                           int *numInvocations);
410     void parseMaxVertices(int intValue,
411                           const TSourceLoc &intValueLine,
412                           const std::string &intValueString,
413                           int *numMaxVertices);
414     void parseVertices(int intValue,
415                        const TSourceLoc &intValueLine,
416                        const std::string &intValueString,
417                        int *numVertices);
418     void parseIndexLayoutQualifier(int intValue,
419                                    const TSourceLoc &intValueLine,
420                                    const std::string &intValueString,
421                                    int *index);
422     TLayoutQualifier parseLayoutQualifier(const ImmutableString &qualifierType,
423                                           const TSourceLoc &qualifierTypeLine);
424     TLayoutQualifier parseLayoutQualifier(const ImmutableString &qualifierType,
425                                           const TSourceLoc &qualifierTypeLine,
426                                           int intValue,
427                                           const TSourceLoc &intValueLine);
428     TTypeQualifierBuilder *createTypeQualifierBuilder(const TSourceLoc &loc);
429     TStorageQualifierWrapper *parseGlobalStorageQualifier(TQualifier qualifier,
430                                                           const TSourceLoc &loc);
431     TStorageQualifierWrapper *parseVaryingQualifier(const TSourceLoc &loc);
432     TStorageQualifierWrapper *parseInQualifier(const TSourceLoc &loc);
433     TStorageQualifierWrapper *parseOutQualifier(const TSourceLoc &loc);
434     TStorageQualifierWrapper *parseInOutQualifier(const TSourceLoc &loc);
435     TLayoutQualifier joinLayoutQualifiers(TLayoutQualifier leftQualifier,
436                                           TLayoutQualifier rightQualifier,
437                                           const TSourceLoc &rightQualifierLocation);
438 
439     // Performs an error check for embedded struct declarations.
440     void enterStructDeclaration(const TSourceLoc &line, const ImmutableString &identifier);
441     void exitStructDeclaration();
442 
443     void checkIsBelowStructNestingLimit(const TSourceLoc &line, const TField &field);
444 
445     TIntermSwitch *addSwitch(TIntermTyped *init,
446                              TIntermBlock *statementList,
447                              const TSourceLoc &loc);
448     TIntermCase *addCase(TIntermTyped *condition, const TSourceLoc &loc);
449     TIntermCase *addDefault(const TSourceLoc &loc);
450 
451     TIntermTyped *addUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc);
452     TIntermTyped *addUnaryMathLValue(TOperator op, TIntermTyped *child, const TSourceLoc &loc);
453     TIntermTyped *addBinaryMath(TOperator op,
454                                 TIntermTyped *left,
455                                 TIntermTyped *right,
456                                 const TSourceLoc &loc);
457     TIntermTyped *addBinaryMathBooleanResult(TOperator op,
458                                              TIntermTyped *left,
459                                              TIntermTyped *right,
460                                              const TSourceLoc &loc);
461     TIntermTyped *addAssign(TOperator op,
462                             TIntermTyped *left,
463                             TIntermTyped *right,
464                             const TSourceLoc &loc);
465 
466     TIntermTyped *addComma(TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc);
467 
468     TIntermBranch *addBranch(TOperator op, const TSourceLoc &loc);
469     TIntermBranch *addBranch(TOperator op, TIntermTyped *expression, const TSourceLoc &loc);
470 
471     void appendStatement(TIntermBlock *block, TIntermNode *statement);
472 
473     void checkTextureGather(TIntermAggregate *functionCall);
474     void checkTextureOffset(TIntermAggregate *functionCall);
475     void checkImageMemoryAccessForBuiltinFunctions(TIntermAggregate *functionCall);
476     void checkImageMemoryAccessForUserDefinedFunctions(const TFunction *functionDefinition,
477                                                        const TIntermAggregate *functionCall);
478     void checkAtomicMemoryBuiltinFunctions(TIntermAggregate *functionCall);
479     void checkInterpolationFS(TIntermAggregate *functionCall);
480 
481     // fnCall is only storing the built-in op, and function name or constructor type. arguments
482     // has the arguments.
483     TIntermTyped *addFunctionCallOrMethod(TFunctionLookup *fnCall, const TSourceLoc &loc);
484 
485     TIntermTyped *addTernarySelection(TIntermTyped *cond,
486                                       TIntermTyped *trueExpression,
487                                       TIntermTyped *falseExpression,
488                                       const TSourceLoc &line);
489 
getGeometryShaderMaxVertices()490     int getGeometryShaderMaxVertices() const { return mGeometryShaderMaxVertices; }
getGeometryShaderInvocations()491     int getGeometryShaderInvocations() const
492     {
493         return (mGeometryShaderInvocations > 0) ? mGeometryShaderInvocations : 1;
494     }
getGeometryShaderInputPrimitiveType()495     TLayoutPrimitiveType getGeometryShaderInputPrimitiveType() const
496     {
497         return mGeometryShaderInputPrimitiveType;
498     }
getGeometryShaderOutputPrimitiveType()499     TLayoutPrimitiveType getGeometryShaderOutputPrimitiveType() const
500     {
501         return mGeometryShaderOutputPrimitiveType;
502     }
getTessControlShaderOutputVertices()503     int getTessControlShaderOutputVertices() const { return mTessControlShaderOutputVertices; }
getTessEvaluationShaderInputPrimitiveType()504     TLayoutTessEvaluationType getTessEvaluationShaderInputPrimitiveType() const
505     {
506         return mTessEvaluationShaderInputPrimitiveType;
507     }
getTessEvaluationShaderInputVertexSpacingType()508     TLayoutTessEvaluationType getTessEvaluationShaderInputVertexSpacingType() const
509     {
510         return mTessEvaluationShaderInputVertexSpacingType;
511     }
getTessEvaluationShaderInputOrderingType()512     TLayoutTessEvaluationType getTessEvaluationShaderInputOrderingType() const
513     {
514         return mTessEvaluationShaderInputOrderingType;
515     }
getTessEvaluationShaderInputPointType()516     TLayoutTessEvaluationType getTessEvaluationShaderInputPointType() const
517     {
518         return mTessEvaluationShaderInputPointType;
519     }
520 
getDeferredArrayTypesToSize()521     const TVector<TType *> &getDeferredArrayTypesToSize() const
522     {
523         return mDeferredArrayTypesToSize;
524     }
525 
markShaderHasPrecise()526     void markShaderHasPrecise() { mHasAnyPreciseType = true; }
hasAnyPreciseType()527     bool hasAnyPreciseType() const { return mHasAnyPreciseType; }
getAdvancedBlendEquations()528     AdvancedBlendEquations getAdvancedBlendEquations() const { return mAdvancedBlendEquations; }
529 
getOutputType()530     ShShaderOutput getOutputType() const { return mOutputType; }
531 
getMaxExpressionComplexity()532     size_t getMaxExpressionComplexity() const { return mMaxExpressionComplexity; }
getMaxStatementDepth()533     size_t getMaxStatementDepth() const { return mMaxStatementDepth; }
534 
535     // TODO(jmadill): make this private
536     TSymbolTable &symbolTable;  // symbol table that goes with the language currently being parsed
537 
538   private:
539     class AtomicCounterBindingState;
540     constexpr static size_t kAtomicCounterSize = 4;
541     // UNIFORM_ARRAY_STRIDE for atomic counter arrays is an implementation-dependent value which
542     // can be queried after a program is linked according to ES 3.10 section 7.7.1. This is
543     // controversial with the offset inheritance as described in ESSL 3.10 section 4.4.6. Currently
544     // we treat it as always 4 in favour of the original interpretation in
545     // "ARB_shader_atomic_counters".
546     // TODO(jie.a.chen@intel.com): Double check this once the spec vagueness is resolved.
547     // Note that there may be tests in AtomicCounter_test that will need to be updated as well.
548     constexpr static size_t kAtomicCounterArrayStride = 4;
549 
550     void markStaticReadIfSymbol(TIntermNode *node);
551 
552     // Returns a clamped index. If it prints out an error message, the token is "[]".
553     int checkIndexLessThan(bool outOfRangeIndexIsError,
554                            const TSourceLoc &location,
555                            int index,
556                            unsigned int arraySize,
557                            const char *reason);
558 
559     bool declareVariable(const TSourceLoc &line,
560                          const ImmutableString &identifier,
561                          const TType *type,
562                          TVariable **variable);
563 
564     void checkNestingLevel(const TSourceLoc &line);
565 
566     void checkCanBeDeclaredWithoutInitializer(const TSourceLoc &line,
567                                               const ImmutableString &identifier,
568                                               TType *type);
569 
570     TParameter parseParameterDeclarator(TType *type,
571                                         const ImmutableString &name,
572                                         const TSourceLoc &nameLoc);
573 
574     bool checkIsValidTypeAndQualifierForArray(const TSourceLoc &indexLocation,
575                                               const TPublicType &elementType);
576     // Done for all atomic counter declarations, whether empty or not.
577     void atomicCounterQualifierErrorCheck(const TPublicType &publicType,
578                                           const TSourceLoc &location);
579 
580     // Assumes that multiplication op has already been set based on the types.
581     bool isMultiplicationTypeCombinationValid(TOperator op, const TType &left, const TType &right);
582 
583     void checkOutParameterIsNotOpaqueType(const TSourceLoc &line,
584                                           TQualifier qualifier,
585                                           const TType &type);
586 
587     void checkInternalFormatIsNotSpecified(const TSourceLoc &location,
588                                            TLayoutImageInternalFormat internalFormat);
589     void checkMemoryQualifierIsNotSpecified(const TMemoryQualifier &memoryQualifier,
590                                             const TSourceLoc &location);
591     void checkAtomicCounterOffsetDoesNotOverlap(bool forceAppend,
592                                                 const TSourceLoc &loc,
593                                                 TType *type);
594     void checkAtomicCounterOffsetAlignment(const TSourceLoc &location, const TType &type);
595 
596     void checkIndexIsNotSpecified(const TSourceLoc &location, int index);
597     void checkBindingIsValid(const TSourceLoc &identifierLocation, const TType &type);
598     void checkBindingIsNotSpecified(const TSourceLoc &location, int binding);
599     void checkOffsetIsNotSpecified(const TSourceLoc &location, int offset);
600     void checkImageBindingIsValid(const TSourceLoc &location,
601                                   int binding,
602                                   int arrayTotalElementCount);
603     void checkSamplerBindingIsValid(const TSourceLoc &location,
604                                     int binding,
605                                     int arrayTotalElementCount);
606     void checkBlockBindingIsValid(const TSourceLoc &location,
607                                   const TQualifier &qualifier,
608                                   int binding,
609                                   int arraySize);
610     void checkAtomicCounterBindingIsValid(const TSourceLoc &location, int binding);
611     void checkPixelLocalStorageBindingIsValid(const TSourceLoc &, const TType &);
612 
613     void checkUniformLocationInRange(const TSourceLoc &location,
614                                      int objectLocationCount,
615                                      const TLayoutQualifier &layoutQualifier);
616     void checkAttributeLocationInRange(const TSourceLoc &location,
617                                        int objectLocationCount,
618                                        const TLayoutQualifier &layoutQualifier);
619 
620     void checkDepthIsNotSpecified(const TSourceLoc &location, TLayoutDepth depth);
621 
622     void checkYuvIsNotSpecified(const TSourceLoc &location, bool yuv);
623 
624     void checkEarlyFragmentTestsIsNotSpecified(const TSourceLoc &location, bool earlyFragmentTests);
625 
626     void checkNoncoherentIsSpecified(const TSourceLoc &location, bool noncoherent);
627 
628     void checkNoncoherentIsNotSpecified(const TSourceLoc &location, bool noncoherent);
629 
630     bool checkUnsizedArrayConstructorArgumentDimensionality(const TIntermSequence &arguments,
631                                                             TType type,
632                                                             const TSourceLoc &line);
633 
634     // Check texture offset is within range.
635     void checkSingleTextureOffset(const TSourceLoc &line,
636                                   const TConstantUnion *values,
637                                   size_t size,
638                                   int minOffsetValue,
639                                   int maxOffsetValue);
640 
641     // Will set the size of the outermost array according to geometry shader input layout.
642     void checkGeometryShaderInputAndSetArraySize(const TSourceLoc &location,
643                                                  const ImmutableString &token,
644                                                  TType *type);
645 
646     // Similar, for tessellation shaders.
647     void checkTessellationShaderUnsizedArraysAndSetSize(const TSourceLoc &location,
648                                                         const ImmutableString &token,
649                                                         TType *type);
650 
651     // Will size any unsized array type so unsized arrays won't need to be taken into account
652     // further along the line in parsing.
653     void checkIsNotUnsizedArray(const TSourceLoc &line,
654                                 const char *errorMessage,
655                                 const ImmutableString &token,
656                                 TType *arrayType);
657 
658     TIntermTyped *addBinaryMathInternal(TOperator op,
659                                         TIntermTyped *left,
660                                         TIntermTyped *right,
661                                         const TSourceLoc &loc);
662     TIntermTyped *createUnaryMath(TOperator op,
663                                   TIntermTyped *child,
664                                   const TSourceLoc &loc,
665                                   const TFunction *func);
666 
667     TIntermTyped *addMethod(TFunctionLookup *fnCall, const TSourceLoc &loc);
668     TIntermTyped *addConstructor(TFunctionLookup *fnCall, const TSourceLoc &line);
669     TIntermTyped *addNonConstructorFunctionCallImpl(TFunctionLookup *fnCall, const TSourceLoc &loc);
670     TIntermTyped *addNonConstructorFunctionCall(TFunctionLookup *fnCall, const TSourceLoc &loc);
671 
672     // Return either the original expression or the folded version of the expression in case the
673     // folded node will validate the same way during subsequent parsing.
674     TIntermTyped *expressionOrFoldedResult(TIntermTyped *expression);
675 
676     // Return true if the checks pass
677     bool binaryOpCommonCheck(TOperator op,
678                              TIntermTyped *left,
679                              TIntermTyped *right,
680                              const TSourceLoc &loc);
681 
682     TIntermFunctionPrototype *createPrototypeNodeFromFunction(const TFunction &function,
683                                                               const TSourceLoc &location,
684                                                               bool insertParametersToSymbolTable);
685 
686     void setAtomicCounterBindingDefaultOffset(const TPublicType &declaration,
687                                               const TSourceLoc &location);
688 
689     bool checkPrimitiveTypeMatchesTypeQualifier(const TTypeQualifier &typeQualifier);
690     bool parseGeometryShaderInputLayoutQualifier(const TTypeQualifier &typeQualifier);
691     bool parseGeometryShaderOutputLayoutQualifier(const TTypeQualifier &typeQualifier);
692     void setGeometryShaderInputArraySize(unsigned int inputArraySize, const TSourceLoc &line);
693 
694     bool parseTessControlShaderOutputLayoutQualifier(const TTypeQualifier &typeQualifier);
695     bool parseTessEvaluationShaderInputLayoutQualifier(const TTypeQualifier &typeQualifier);
696 
697     // Certain operations become illegal only iff the shader declares pixel local storage uniforms.
698     enum class PLSIllegalOperations
699     {
700         // When polyfilled with shader images, pixel local storage requires early_fragment_tests,
701         // which causes discard to interact differently with the depth and stencil tests.
702         //
703         // To ensure identical behavior across all backends (some of which may not have access to
704         // early_fragment_tests), we disallow discard if pixel local storage uniforms have been
705         // declared.
706         Discard,
707 
708         // ARB_fragment_shader_interlock functions cannot be called within flow control, which
709         // includes any code that might execute after a return statement. To keep things simple, and
710         // since these "interlock" calls are automatically injected by the compiler inside of
711         // main(), we disallow return from main() if pixel local storage uniforms have been
712         // declared.
713         ReturnFromMain,
714 
715         // When polyfilled with shader images, pixel local storage requires early_fragment_tests,
716         // which causes assignments to gl_FragDepth(EXT) and gl_SampleMask to be ignored.
717         //
718         // To ensure identical behavior across all backends, we disallow assignment to these values
719         // if pixel local storage uniforms have been declared.
720         AssignFragDepth,
721         AssignSampleMask,
722 
723         // EXT_blend_func_extended may restrict the number of draw buffers with a nonzero output
724         // index, which can invalidate a PLS implementation.
725         FragDataIndexNonzero,
726 
727         // KHR_blend_equation_advanced is incompatible with multiple draw buffers, which is a
728         // required feature for many PLS implementations.
729         EnableAdvancedBlendEquation,
730     };
731 
732     // Generates an error if any pixel local storage uniforms have been declared (more specifically,
733     // if mPLSBindings is not empty).
734     //
735     // If no pixel local storage uniforms have been declared, and if the PLS extension is enabled,
736     // saves the potential error to mPLSPotentialErrors in case we encounter a PLS uniform later.
737     void errorIfPLSDeclared(const TSourceLoc &, PLSIllegalOperations);
738 
739     // Set to true when the last/current declarator list was started with an empty declaration. The
740     // non-empty declaration error check will need to be performed if the empty declaration is
741     // followed by a declarator.
742     bool mDeferredNonEmptyDeclarationErrorCheck;
743 
744     sh::GLenum mShaderType;    // vertex/fragment/geometry/etc shader
745     ShShaderSpec mShaderSpec;  // The language specification compiler conforms to - GLES/WebGL/etc.
746     ShCompileOptions mCompileOptions;  // Options passed to TCompiler
747     int mShaderVersion;
748     TIntermBlock *mTreeRoot;  // root of parse tree being created
749     int mLoopNestingLevel;    // 0 if outside all loops
750     int mStructNestingLevel;  // incremented while parsing a struct declaration
751     int mSwitchNestingLevel;  // 0 if outside all switch statements
752     const TType
753         *mCurrentFunctionType;    // the return type of the function that's currently being parsed
754     bool mFunctionReturnsValue;   // true if a non-void function has a return
755     bool mChecksPrecisionErrors;  // true if an error will be generated when a variable is declared
756                                   // without precision, explicit or implicit.
757     bool mFragmentPrecisionHighOnESSL1;  // true if highp precision is supported when compiling
758                                          // ESSL1.
759     bool mEarlyFragmentTestsSpecified;   // true if layout(early_fragment_tests) in; is specified.
760     bool mHasDiscard;                    // true if |discard| is encountered in the shader.
761     bool mSampleQualifierSpecified;      // true if the |sample| qualifier is used
762     bool mPositionRedeclaredForSeparateShaderObject;       // true if EXT_separate_shader_objects is
763                                                            // enabled and gl_Position is redefined.
764     bool mPointSizeRedeclaredForSeparateShaderObject;      // true if EXT_separate_shader_objects is
765                                                            // enabled and gl_PointSize is redefined.
766     bool mPositionOrPointSizeUsedForSeparateShaderObject;  // true if gl_Position or gl_PointSize
767                                                            // has been referenced.
768     bool mUsesDerivatives;  // true if screen-space derivatives are used implicitly or explicitly
769     TLayoutMatrixPacking mDefaultUniformMatrixPacking;
770     TLayoutBlockStorage mDefaultUniformBlockStorage;
771     TLayoutMatrixPacking mDefaultBufferMatrixPacking;
772     TLayoutBlockStorage mDefaultBufferBlockStorage;
773     TString mHashErrMsg;
774     TDiagnostics *mDiagnostics;
775     TDirectiveHandler mDirectiveHandler;
776     angle::pp::Preprocessor mPreprocessor;
777     void *mScanner;
778     const size_t mMaxExpressionComplexity;
779     const size_t mMaxStatementDepth;
780     int mMinProgramTexelOffset;
781     int mMaxProgramTexelOffset;
782 
783     int mMinProgramTextureGatherOffset;
784     int mMaxProgramTextureGatherOffset;
785 
786     // keep track of local group size declared in layout. It should be declared only once.
787     bool mComputeShaderLocalSizeDeclared;
788     sh::WorkGroupSize mComputeShaderLocalSize;
789     // keep track of number of views declared in layout.
790     int mNumViews;
791     int mMaxNumViews;
792     int mMaxImageUnits;
793     int mMaxCombinedTextureImageUnits;
794     int mMaxUniformLocations;
795     int mMaxUniformBufferBindings;
796     int mMaxVertexAttribs;
797     int mMaxAtomicCounterBindings;
798     int mMaxShaderStorageBufferBindings;
799 
800     // keeps track whether we are declaring / defining a function
801     bool mDeclaringFunction;
802 
803     // keeps track whether we are declaring / defining the function main().
804     bool mDeclaringMain;
805 
806     // Track the state of each atomic counter binding.
807     std::map<int, AtomicCounterBindingState> mAtomicCounterBindingStates;
808 
809     // Track the format of each pixel local storage binding.
810     std::map<int, TLayoutImageInternalFormat> mPLSBindings;
811 
812     // Potential errors to generate immediately upon encountering a pixel local storage uniform.
813     std::vector<std::tuple<const TSourceLoc, PLSIllegalOperations>> mPLSPotentialErrors;
814 
815     // Track the geometry shader global parameters declared in layout.
816     TLayoutPrimitiveType mGeometryShaderInputPrimitiveType;
817     TLayoutPrimitiveType mGeometryShaderOutputPrimitiveType;
818     int mGeometryShaderInvocations;
819     int mGeometryShaderMaxVertices;
820     int mMaxGeometryShaderInvocations;
821     int mMaxGeometryShaderMaxVertices;
822     unsigned int mGeometryInputArraySize;
823 
824     int mMaxPatchVertices;
825     int mTessControlShaderOutputVertices;
826     TLayoutTessEvaluationType mTessEvaluationShaderInputPrimitiveType;
827     TLayoutTessEvaluationType mTessEvaluationShaderInputVertexSpacingType;
828     TLayoutTessEvaluationType mTessEvaluationShaderInputOrderingType;
829     TLayoutTessEvaluationType mTessEvaluationShaderInputPointType;
830     // List of array declarations without an explicit size that have come before layout(vertices=N).
831     // Once the vertex count is specified, these arrays are sized.
832     TVector<TType *> mDeferredArrayTypesToSize;
833     // Whether the |precise| keyword has been seen in the shader.
834     bool mHasAnyPreciseType;
835 
836     AdvancedBlendEquations mAdvancedBlendEquations;
837 
838     // Track when we add new scope for func body in ESSL 1.00 spec
839     bool mFunctionBodyNewScope;
840 
841     ShShaderOutput mOutputType;
842 };
843 
844 int PaParseStrings(size_t count,
845                    const char *const string[],
846                    const int length[],
847                    TParseContext *context);
848 
849 }  // namespace sh
850 
851 #endif  // COMPILER_TRANSLATOR_PARSECONTEXT_H_
852