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