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