tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ParseContext.h (43364B)


      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();
     48    const angle::pp::Preprocessor &getPreprocessor() const { return mPreprocessor; }
     49    angle::pp::Preprocessor &getPreprocessor() { return mPreprocessor; }
     50    void *getScanner() const { return mScanner; }
     51    void setScanner(void *scanner) { mScanner = scanner; }
     52    int getShaderVersion() const { return mShaderVersion; }
     53    sh::GLenum getShaderType() const { return mShaderType; }
     54    ShShaderSpec getShaderSpec() const { return mShaderSpec; }
     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 
     66    TIntermBlock *getTreeRoot() const { return mTreeRoot; }
     67    void setTreeRoot(TIntermBlock *treeRoot);
     68 
     69    bool getFragmentPrecisionHigh() const
     70    {
     71        return mFragmentPrecisionHighOnESSL1 || mShaderVersion >= 300;
     72    }
     73    void setFragmentPrecisionHighOnESSL1(bool fragmentPrecisionHigh)
     74    {
     75        mFragmentPrecisionHighOnESSL1 = fragmentPrecisionHigh;
     76    }
     77 
     78    bool isEarlyFragmentTestsSpecified() const { return mEarlyFragmentTestsSpecified; }
     79    bool hasDiscard() const { return mHasDiscard; }
     80    bool isSampleQualifierSpecified() const { return mSampleQualifierSpecified; }
     81 
     82    void setLoopNestingLevel(int loopNestintLevel) { mLoopNestingLevel = loopNestintLevel; }
     83 
     84    void incrLoopNestingLevel() { ++mLoopNestingLevel; }
     85    void decrLoopNestingLevel() { --mLoopNestingLevel; }
     86 
     87    void incrSwitchNestingLevel() { ++mSwitchNestingLevel; }
     88    void decrSwitchNestingLevel() { --mSwitchNestingLevel; }
     89 
     90    bool isComputeShaderLocalSizeDeclared() const { return mComputeShaderLocalSizeDeclared; }
     91    sh::WorkGroupSize getComputeShaderLocalSize() const;
     92 
     93    int getNumViews() const { return mNumViews; }
     94 
     95    const std::map<int, TLayoutImageInternalFormat> &pixelLocalStorageBindings() const
     96    {
     97        return mPLSBindings;
     98    }
     99 
    100    void enterFunctionDeclaration() { mDeclaringFunction = true; }
    101 
    102    void exitFunctionDeclaration() { mDeclaringFunction = false; }
    103 
    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 
    208    const TPragma &pragma() const { return mDirectiveHandler.pragma(); }
    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 ImmutableString &identifier, TType *type);
    224 
    225    // Returns true on success. *initNode may still be nullptr on success in case the initialization
    226    // is not needed in the AST.
    227    bool executeInitializer(const TSourceLoc &line,
    228                            const ImmutableString &identifier,
    229                            TType *type,
    230                            TIntermTyped *initializer,
    231                            TIntermBinary **initNode);
    232    TIntermNode *addConditionInitializer(const TPublicType &pType,
    233                                         const ImmutableString &identifier,
    234                                         TIntermTyped *initializer,
    235                                         const TSourceLoc &loc);
    236    TIntermNode *addLoop(TLoopType type,
    237                         TIntermNode *init,
    238                         TIntermNode *cond,
    239                         TIntermTyped *expr,
    240                         TIntermNode *body,
    241                         const TSourceLoc &loc);
    242 
    243    // For "if" test nodes. There are three children: a condition, a true path, and a false path.
    244    // The two paths are in TIntermNodePair code.
    245    TIntermNode *addIfElse(TIntermTyped *cond, TIntermNodePair code, const TSourceLoc &loc);
    246 
    247    void addFullySpecifiedType(TPublicType *typeSpecifier);
    248    TPublicType addFullySpecifiedType(const TTypeQualifierBuilder &typeQualifierBuilder,
    249                                      const TPublicType &typeSpecifier);
    250 
    251    TIntermDeclaration *parseSingleDeclaration(TPublicType &publicType,
    252                                               const TSourceLoc &identifierOrTypeLocation,
    253                                               const ImmutableString &identifier);
    254    TIntermDeclaration *parseSingleArrayDeclaration(TPublicType &elementType,
    255                                                    const TSourceLoc &identifierLocation,
    256                                                    const ImmutableString &identifier,
    257                                                    const TSourceLoc &indexLocation,
    258                                                    const TVector<unsigned int> &arraySizes);
    259    TIntermDeclaration *parseSingleInitDeclaration(const TPublicType &publicType,
    260                                                   const TSourceLoc &identifierLocation,
    261                                                   const ImmutableString &identifier,
    262                                                   const TSourceLoc &initLocation,
    263                                                   TIntermTyped *initializer);
    264 
    265    // Parse a declaration like "type a[n] = initializer"
    266    // Note that this does not apply to declarations like "type[n] a = initializer"
    267    TIntermDeclaration *parseSingleArrayInitDeclaration(TPublicType &elementType,
    268                                                        const TSourceLoc &identifierLocation,
    269                                                        const ImmutableString &identifier,
    270                                                        const TSourceLoc &indexLocation,
    271                                                        const TVector<unsigned int> &arraySizes,
    272                                                        const TSourceLoc &initLocation,
    273                                                        TIntermTyped *initializer);
    274 
    275    TIntermGlobalQualifierDeclaration *parseGlobalQualifierDeclaration(
    276        const TTypeQualifierBuilder &typeQualifierBuilder,
    277        const TSourceLoc &identifierLoc,
    278        const ImmutableString &identifier,
    279        const TSymbol *symbol);
    280 
    281    void parseDeclarator(TPublicType &publicType,
    282                         const TSourceLoc &identifierLocation,
    283                         const ImmutableString &identifier,
    284                         TIntermDeclaration *declarationOut);
    285    void parseArrayDeclarator(TPublicType &elementType,
    286                              const TSourceLoc &identifierLocation,
    287                              const ImmutableString &identifier,
    288                              const TSourceLoc &arrayLocation,
    289                              const TVector<unsigned int> &arraySizes,
    290                              TIntermDeclaration *declarationOut);
    291    void parseInitDeclarator(const TPublicType &publicType,
    292                             const TSourceLoc &identifierLocation,
    293                             const ImmutableString &identifier,
    294                             const TSourceLoc &initLocation,
    295                             TIntermTyped *initializer,
    296                             TIntermDeclaration *declarationOut);
    297 
    298    // Parse a declarator like "a[n] = initializer"
    299    void parseArrayInitDeclarator(const TPublicType &elementType,
    300                                  const TSourceLoc &identifierLocation,
    301                                  const ImmutableString &identifier,
    302                                  const TSourceLoc &indexLocation,
    303                                  const TVector<unsigned int> &arraySizes,
    304                                  const TSourceLoc &initLocation,
    305                                  TIntermTyped *initializer,
    306                                  TIntermDeclaration *declarationOut);
    307 
    308    TIntermNode *addEmptyStatement(const TSourceLoc &location);
    309 
    310    void parseDefaultPrecisionQualifier(const TPrecision precision,
    311                                        const TPublicType &type,
    312                                        const TSourceLoc &loc);
    313    void parseGlobalLayoutQualifier(const TTypeQualifierBuilder &typeQualifierBuilder);
    314 
    315    TIntermFunctionPrototype *addFunctionPrototypeDeclaration(const TFunction &parsedFunction,
    316                                                              const TSourceLoc &location);
    317    TIntermFunctionDefinition *addFunctionDefinition(TIntermFunctionPrototype *functionPrototype,
    318                                                     TIntermBlock *functionBody,
    319                                                     const TSourceLoc &location);
    320    void parseFunctionDefinitionHeader(const TSourceLoc &location,
    321                                       const TFunction *function,
    322                                       TIntermFunctionPrototype **prototypeOut);
    323    TFunction *parseFunctionDeclarator(const TSourceLoc &location, TFunction *function);
    324    TFunction *parseFunctionHeader(const TPublicType &type,
    325                                   const ImmutableString &name,
    326                                   const TSourceLoc &location);
    327 
    328    TFunctionLookup *addNonConstructorFunc(const ImmutableString &name, const TSymbol *symbol);
    329    TFunctionLookup *addConstructorFunc(const TPublicType &publicType);
    330 
    331    TParameter parseParameterDeclarator(const TPublicType &publicType,
    332                                        const ImmutableString &name,
    333                                        const TSourceLoc &nameLoc);
    334 
    335    TParameter parseParameterArrayDeclarator(const ImmutableString &name,
    336                                             const TSourceLoc &nameLoc,
    337                                             const TVector<unsigned int> &arraySizes,
    338                                             const TSourceLoc &arrayLoc,
    339                                             TPublicType *elementType);
    340 
    341    TIntermTyped *addIndexExpression(TIntermTyped *baseExpression,
    342                                     const TSourceLoc &location,
    343                                     TIntermTyped *indexExpression);
    344    TIntermTyped *addFieldSelectionExpression(TIntermTyped *baseExpression,
    345                                              const TSourceLoc &dotLocation,
    346                                              const ImmutableString &fieldString,
    347                                              const TSourceLoc &fieldLocation);
    348 
    349    // Parse declarator for a single field
    350    TDeclarator *parseStructDeclarator(const ImmutableString &identifier, const TSourceLoc &loc);
    351    TDeclarator *parseStructArrayDeclarator(const ImmutableString &identifier,
    352                                            const TSourceLoc &loc,
    353                                            const TVector<unsigned int> *arraySizes);
    354 
    355    void checkDoesNotHaveDuplicateFieldName(const TFieldList::const_iterator begin,
    356                                            const TFieldList::const_iterator end,
    357                                            const ImmutableString &name,
    358                                            const TSourceLoc &location);
    359    TFieldList *addStructFieldList(TFieldList *fields, const TSourceLoc &location);
    360    TFieldList *combineStructFieldLists(TFieldList *processedFields,
    361                                        const TFieldList *newlyAddedFields,
    362                                        const TSourceLoc &location);
    363    TFieldList *addStructDeclaratorListWithQualifiers(
    364        const TTypeQualifierBuilder &typeQualifierBuilder,
    365        TPublicType *typeSpecifier,
    366        const TDeclaratorList *declaratorList);
    367    TFieldList *addStructDeclaratorList(const TPublicType &typeSpecifier,
    368                                        const TDeclaratorList *declaratorList);
    369    TTypeSpecifierNonArray addStructure(const TSourceLoc &structLine,
    370                                        const TSourceLoc &nameLine,
    371                                        const ImmutableString &structName,
    372                                        TFieldList *fieldList);
    373 
    374    TIntermDeclaration *addInterfaceBlock(const TTypeQualifierBuilder &typeQualifierBuilder,
    375                                          const TSourceLoc &nameLine,
    376                                          const ImmutableString &blockName,
    377                                          TFieldList *fieldList,
    378                                          const ImmutableString &instanceName,
    379                                          const TSourceLoc &instanceLine,
    380                                          const TVector<unsigned int> *arraySizes,
    381                                          const TSourceLoc &arraySizesLine);
    382 
    383    void parseLocalSize(const ImmutableString &qualifierType,
    384                        const TSourceLoc &qualifierTypeLine,
    385                        int intValue,
    386                        const TSourceLoc &intValueLine,
    387                        const std::string &intValueString,
    388                        size_t index,
    389                        sh::WorkGroupSize *localSize);
    390    void parseNumViews(int intValue,
    391                       const TSourceLoc &intValueLine,
    392                       const std::string &intValueString,
    393                       int *numViews);
    394    void parseInvocations(int intValue,
    395                          const TSourceLoc &intValueLine,
    396                          const std::string &intValueString,
    397                          int *numInvocations);
    398    void parseMaxVertices(int intValue,
    399                          const TSourceLoc &intValueLine,
    400                          const std::string &intValueString,
    401                          int *numMaxVertices);
    402    void parseVertices(int intValue,
    403                       const TSourceLoc &intValueLine,
    404                       const std::string &intValueString,
    405                       int *numVertices);
    406    void parseIndexLayoutQualifier(int intValue,
    407                                   const TSourceLoc &intValueLine,
    408                                   const std::string &intValueString,
    409                                   int *index);
    410    TLayoutQualifier parseLayoutQualifier(const ImmutableString &qualifierType,
    411                                          const TSourceLoc &qualifierTypeLine);
    412    TLayoutQualifier parseLayoutQualifier(const ImmutableString &qualifierType,
    413                                          const TSourceLoc &qualifierTypeLine,
    414                                          int intValue,
    415                                          const TSourceLoc &intValueLine);
    416    TTypeQualifierBuilder *createTypeQualifierBuilder(const TSourceLoc &loc);
    417    TStorageQualifierWrapper *parseGlobalStorageQualifier(TQualifier qualifier,
    418                                                          const TSourceLoc &loc);
    419    TStorageQualifierWrapper *parseVaryingQualifier(const TSourceLoc &loc);
    420    TStorageQualifierWrapper *parseInQualifier(const TSourceLoc &loc);
    421    TStorageQualifierWrapper *parseOutQualifier(const TSourceLoc &loc);
    422    TStorageQualifierWrapper *parseInOutQualifier(const TSourceLoc &loc);
    423    TLayoutQualifier joinLayoutQualifiers(TLayoutQualifier leftQualifier,
    424                                          TLayoutQualifier rightQualifier,
    425                                          const TSourceLoc &rightQualifierLocation);
    426 
    427    // Performs an error check for embedded struct declarations.
    428    void enterStructDeclaration(const TSourceLoc &line, const ImmutableString &identifier);
    429    void exitStructDeclaration();
    430 
    431    void checkIsBelowStructNestingLimit(const TSourceLoc &line, const TField &field);
    432 
    433    TIntermSwitch *addSwitch(TIntermTyped *init,
    434                             TIntermBlock *statementList,
    435                             const TSourceLoc &loc);
    436    TIntermCase *addCase(TIntermTyped *condition, const TSourceLoc &loc);
    437    TIntermCase *addDefault(const TSourceLoc &loc);
    438 
    439    TIntermTyped *addUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc);
    440    TIntermTyped *addUnaryMathLValue(TOperator op, TIntermTyped *child, const TSourceLoc &loc);
    441    TIntermTyped *addBinaryMath(TOperator op,
    442                                TIntermTyped *left,
    443                                TIntermTyped *right,
    444                                const TSourceLoc &loc);
    445    TIntermTyped *addBinaryMathBooleanResult(TOperator op,
    446                                             TIntermTyped *left,
    447                                             TIntermTyped *right,
    448                                             const TSourceLoc &loc);
    449    TIntermTyped *addAssign(TOperator op,
    450                            TIntermTyped *left,
    451                            TIntermTyped *right,
    452                            const TSourceLoc &loc);
    453 
    454    TIntermTyped *addComma(TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc);
    455 
    456    TIntermBranch *addBranch(TOperator op, const TSourceLoc &loc);
    457    TIntermBranch *addBranch(TOperator op, TIntermTyped *expression, const TSourceLoc &loc);
    458 
    459    void appendStatement(TIntermBlock *block, TIntermNode *statement);
    460 
    461    void checkTextureGather(TIntermAggregate *functionCall);
    462    void checkTextureOffset(TIntermAggregate *functionCall);
    463    void checkImageMemoryAccessForBuiltinFunctions(TIntermAggregate *functionCall);
    464    void checkImageMemoryAccessForUserDefinedFunctions(const TFunction *functionDefinition,
    465                                                       const TIntermAggregate *functionCall);
    466    void checkAtomicMemoryBuiltinFunctions(TIntermAggregate *functionCall);
    467    void checkInterpolationFS(TIntermAggregate *functionCall);
    468 
    469    // fnCall is only storing the built-in op, and function name or constructor type. arguments
    470    // has the arguments.
    471    TIntermTyped *addFunctionCallOrMethod(TFunctionLookup *fnCall, const TSourceLoc &loc);
    472 
    473    TIntermTyped *addTernarySelection(TIntermTyped *cond,
    474                                      TIntermTyped *trueExpression,
    475                                      TIntermTyped *falseExpression,
    476                                      const TSourceLoc &line);
    477 
    478    int getGeometryShaderMaxVertices() const { return mGeometryShaderMaxVertices; }
    479    int getGeometryShaderInvocations() const
    480    {
    481        return (mGeometryShaderInvocations > 0) ? mGeometryShaderInvocations : 1;
    482    }
    483    TLayoutPrimitiveType getGeometryShaderInputPrimitiveType() const
    484    {
    485        return mGeometryShaderInputPrimitiveType;
    486    }
    487    TLayoutPrimitiveType getGeometryShaderOutputPrimitiveType() const
    488    {
    489        return mGeometryShaderOutputPrimitiveType;
    490    }
    491    int getTessControlShaderOutputVertices() const { return mTessControlShaderOutputVertices; }
    492    TLayoutTessEvaluationType getTessEvaluationShaderInputPrimitiveType() const
    493    {
    494        return mTessEvaluationShaderInputPrimitiveType;
    495    }
    496    TLayoutTessEvaluationType getTessEvaluationShaderInputVertexSpacingType() const
    497    {
    498        return mTessEvaluationShaderInputVertexSpacingType;
    499    }
    500    TLayoutTessEvaluationType getTessEvaluationShaderInputOrderingType() const
    501    {
    502        return mTessEvaluationShaderInputOrderingType;
    503    }
    504    TLayoutTessEvaluationType getTessEvaluationShaderInputPointType() const
    505    {
    506        return mTessEvaluationShaderInputPointType;
    507    }
    508 
    509    const TVector<TType *> &getDeferredArrayTypesToSize() const
    510    {
    511        return mDeferredArrayTypesToSize;
    512    }
    513 
    514    void markShaderHasPrecise() { mHasAnyPreciseType = true; }
    515    bool hasAnyPreciseType() const { return mHasAnyPreciseType; }
    516    AdvancedBlendEquations getAdvancedBlendEquations() const { return mAdvancedBlendEquations; }
    517 
    518    ShShaderOutput getOutputType() const { return mOutputType; }
    519 
    520    // TODO(jmadill): make this private
    521    TSymbolTable &symbolTable;  // symbol table that goes with the language currently being parsed
    522 
    523  private:
    524    class AtomicCounterBindingState;
    525    constexpr static size_t kAtomicCounterSize = 4;
    526    // UNIFORM_ARRAY_STRIDE for atomic counter arrays is an implementation-dependent value which
    527    // can be queried after a program is linked according to ES 3.10 section 7.7.1. This is
    528    // controversial with the offset inheritance as described in ESSL 3.10 section 4.4.6. Currently
    529    // we treat it as always 4 in favour of the original interpretation in
    530    // "ARB_shader_atomic_counters".
    531    // TODO(jie.a.chen@intel.com): Double check this once the spec vagueness is resolved.
    532    // Note that there may be tests in AtomicCounter_test that will need to be updated as well.
    533    constexpr static size_t kAtomicCounterArrayStride = 4;
    534 
    535    void markStaticReadIfSymbol(TIntermNode *node);
    536 
    537    // Returns a clamped index. If it prints out an error message, the token is "[]".
    538    int checkIndexLessThan(bool outOfRangeIndexIsError,
    539                           const TSourceLoc &location,
    540                           int index,
    541                           int arraySize,
    542                           const char *reason);
    543 
    544    bool declareVariable(const TSourceLoc &line,
    545                         const ImmutableString &identifier,
    546                         const TType *type,
    547                         TVariable **variable);
    548 
    549    void checkCanBeDeclaredWithoutInitializer(const TSourceLoc &line,
    550                                              const ImmutableString &identifier,
    551                                              TType *type);
    552 
    553    TParameter parseParameterDeclarator(TType *type,
    554                                        const ImmutableString &name,
    555                                        const TSourceLoc &nameLoc);
    556 
    557    bool checkIsValidTypeAndQualifierForArray(const TSourceLoc &indexLocation,
    558                                              const TPublicType &elementType);
    559    // Done for all atomic counter declarations, whether empty or not.
    560    void atomicCounterQualifierErrorCheck(const TPublicType &publicType,
    561                                          const TSourceLoc &location);
    562 
    563    // Assumes that multiplication op has already been set based on the types.
    564    bool isMultiplicationTypeCombinationValid(TOperator op, const TType &left, const TType &right);
    565 
    566    void checkOutParameterIsNotOpaqueType(const TSourceLoc &line,
    567                                          TQualifier qualifier,
    568                                          const TType &type);
    569 
    570    void checkInternalFormatIsNotSpecified(const TSourceLoc &location,
    571                                           TLayoutImageInternalFormat internalFormat);
    572    void checkMemoryQualifierIsNotSpecified(const TMemoryQualifier &memoryQualifier,
    573                                            const TSourceLoc &location);
    574    void checkAtomicCounterOffsetDoesNotOverlap(bool forceAppend,
    575                                                const TSourceLoc &loc,
    576                                                TType *type);
    577    void checkAtomicCounterOffsetAlignment(const TSourceLoc &location, const TType &type);
    578 
    579    void checkIndexIsNotSpecified(const TSourceLoc &location, int index);
    580    void checkBindingIsValid(const TSourceLoc &identifierLocation, const TType &type);
    581    void checkBindingIsNotSpecified(const TSourceLoc &location, int binding);
    582    void checkOffsetIsNotSpecified(const TSourceLoc &location, int offset);
    583    void checkImageBindingIsValid(const TSourceLoc &location,
    584                                  int binding,
    585                                  int arrayTotalElementCount);
    586    void checkSamplerBindingIsValid(const TSourceLoc &location,
    587                                    int binding,
    588                                    int arrayTotalElementCount);
    589    void checkBlockBindingIsValid(const TSourceLoc &location,
    590                                  const TQualifier &qualifier,
    591                                  int binding,
    592                                  int arraySize);
    593    void checkAtomicCounterBindingIsValid(const TSourceLoc &location, int binding);
    594    void checkPixelLocalStorageBindingIsValid(const TSourceLoc &, const TType &);
    595 
    596    void checkUniformLocationInRange(const TSourceLoc &location,
    597                                     int objectLocationCount,
    598                                     const TLayoutQualifier &layoutQualifier);
    599    void checkAttributeLocationInRange(const TSourceLoc &location,
    600                                       int objectLocationCount,
    601                                       const TLayoutQualifier &layoutQualifier);
    602 
    603    void checkYuvIsNotSpecified(const TSourceLoc &location, bool yuv);
    604 
    605    void checkEarlyFragmentTestsIsNotSpecified(const TSourceLoc &location, bool earlyFragmentTests);
    606 
    607    void checkNoncoherentIsSpecified(const TSourceLoc &location, bool noncoherent);
    608 
    609    void checkNoncoherentIsNotSpecified(const TSourceLoc &location, bool noncoherent);
    610 
    611    bool checkUnsizedArrayConstructorArgumentDimensionality(const TIntermSequence &arguments,
    612                                                            TType type,
    613                                                            const TSourceLoc &line);
    614 
    615    void checkCombinedClipCullDistanceIsValid(const TSourceLoc &line,
    616                                              const ImmutableString &identifier,
    617                                              const int arraySize);
    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 
    708    // Generates an error if any pixel local storage uniforms have been declared (more specifically,
    709    // if mPLSBindings is not empty).
    710    //
    711    // If no pixel local storage uniforms have been declared, and if the PLS extension is enabled,
    712    // saves the potential error to mPLSPotentialErrors in case we encounter a PLS uniform later.
    713    void errorIfPLSDeclared(const TSourceLoc &, PLSIllegalOperations);
    714 
    715    // Set to true when the last/current declarator list was started with an empty declaration. The
    716    // non-empty declaration error check will need to be performed if the empty declaration is
    717    // followed by a declarator.
    718    bool mDeferredNonEmptyDeclarationErrorCheck;
    719 
    720    sh::GLenum mShaderType;    // vertex/fragment/geometry/etc shader
    721    ShShaderSpec mShaderSpec;  // The language specification compiler conforms to - GLES/WebGL/etc.
    722    ShCompileOptions mCompileOptions;  // Options passed to TCompiler
    723    int mShaderVersion;
    724    TIntermBlock *mTreeRoot;  // root of parse tree being created
    725    int mLoopNestingLevel;    // 0 if outside all loops
    726    int mStructNestingLevel;  // incremented while parsing a struct declaration
    727    int mSwitchNestingLevel;  // 0 if outside all switch statements
    728    const TType
    729        *mCurrentFunctionType;    // the return type of the function that's currently being parsed
    730    bool mFunctionReturnsValue;   // true if a non-void function has a return
    731    bool mChecksPrecisionErrors;  // true if an error will be generated when a variable is declared
    732                                  // without precision, explicit or implicit.
    733    bool mFragmentPrecisionHighOnESSL1;  // true if highp precision is supported when compiling
    734                                         // ESSL1.
    735    bool mEarlyFragmentTestsSpecified;   // true if |layout(early_fragment_tests) in| is specified.
    736    bool mHasDiscard;                    // true if |discard| is encountered in the shader.
    737    bool mSampleQualifierSpecified;      // true if the |sample| qualifier is used.
    738    TLayoutMatrixPacking mDefaultUniformMatrixPacking;
    739    TLayoutBlockStorage mDefaultUniformBlockStorage;
    740    TLayoutMatrixPacking mDefaultBufferMatrixPacking;
    741    TLayoutBlockStorage mDefaultBufferBlockStorage;
    742    TString mHashErrMsg;
    743    TDiagnostics *mDiagnostics;
    744    TDirectiveHandler mDirectiveHandler;
    745    angle::pp::Preprocessor mPreprocessor;
    746    void *mScanner;
    747    int mMinProgramTexelOffset;
    748    int mMaxProgramTexelOffset;
    749 
    750    int mMinProgramTextureGatherOffset;
    751    int mMaxProgramTextureGatherOffset;
    752 
    753    // keep track of local group size declared in layout. It should be declared only once.
    754    bool mComputeShaderLocalSizeDeclared;
    755    sh::WorkGroupSize mComputeShaderLocalSize;
    756    // keep track of number of views declared in layout.
    757    int mNumViews;
    758    int mMaxNumViews;
    759    int mMaxImageUnits;
    760    int mMaxCombinedTextureImageUnits;
    761    int mMaxUniformLocations;
    762    int mMaxUniformBufferBindings;
    763    int mMaxVertexAttribs;
    764    int mMaxAtomicCounterBindings;
    765    int mMaxShaderStorageBufferBindings;
    766 
    767    // keeps track whether we are declaring / defining a function
    768    bool mDeclaringFunction;
    769 
    770    // keeps track whether we are declaring / defining the function main().
    771    bool mDeclaringMain;
    772 
    773    // Track the state of each atomic counter binding.
    774    std::map<int, AtomicCounterBindingState> mAtomicCounterBindingStates;
    775 
    776    // Track the format of each pixel local storage binding.
    777    std::map<int, TLayoutImageInternalFormat> mPLSBindings;
    778 
    779    // Potential errors to generate immediately upon encountering a pixel local storage uniform.
    780    std::vector<std::tuple<const TSourceLoc, PLSIllegalOperations>> mPLSPotentialErrors;
    781 
    782    // Track the geometry shader global parameters declared in layout.
    783    TLayoutPrimitiveType mGeometryShaderInputPrimitiveType;
    784    TLayoutPrimitiveType mGeometryShaderOutputPrimitiveType;
    785    int mGeometryShaderInvocations;
    786    int mGeometryShaderMaxVertices;
    787    int mMaxGeometryShaderInvocations;
    788    int mMaxGeometryShaderMaxVertices;
    789    unsigned int mGeometryInputArraySize;
    790 
    791    int mMaxPatchVertices;
    792    int mTessControlShaderOutputVertices;
    793    TLayoutTessEvaluationType mTessEvaluationShaderInputPrimitiveType;
    794    TLayoutTessEvaluationType mTessEvaluationShaderInputVertexSpacingType;
    795    TLayoutTessEvaluationType mTessEvaluationShaderInputOrderingType;
    796    TLayoutTessEvaluationType mTessEvaluationShaderInputPointType;
    797    // List of array declarations without an explicit size that have come before layout(vertices=N).
    798    // Once the vertex count is specified, these arrays are sized.
    799    TVector<TType *> mDeferredArrayTypesToSize;
    800    // Whether the |precise| keyword has been seen in the shader.
    801    bool mHasAnyPreciseType;
    802 
    803    AdvancedBlendEquations mAdvancedBlendEquations;
    804 
    805    // Track when we add new scope for func body in ESSL 1.00 spec
    806    bool mFunctionBodyNewScope;
    807 
    808    ShShaderOutput mOutputType;
    809 };
    810 
    811 int PaParseStrings(size_t count,
    812                   const char *const string[],
    813                   const int length[],
    814                   TParseContext *context);
    815 
    816 }  // namespace sh
    817 
    818 #endif  // COMPILER_TRANSLATOR_PARSECONTEXT_H_