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