| // |
| // Copyright 2002 The ANGLE Project Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| // |
| #ifndef COMPILER_TRANSLATOR_PARSECONTEXT_H_ |
| #define COMPILER_TRANSLATOR_PARSECONTEXT_H_ |
| |
| #include "compiler/preprocessor/Preprocessor.h" |
| #include "compiler/translator/Compiler.h" |
| #include "compiler/translator/Declarator.h" |
| #include "compiler/translator/Diagnostics.h" |
| #include "compiler/translator/DirectiveHandler.h" |
| #include "compiler/translator/FunctionLookup.h" |
| #include "compiler/translator/QualifierTypes.h" |
| #include "compiler/translator/SymbolTable.h" |
| |
| namespace sh |
| { |
| |
| struct TMatrixFields |
| { |
| bool wholeRow; |
| bool wholeCol; |
| int row; |
| int col; |
| }; |
| |
| // |
| // The following are extra variables needed during parsing, grouped together so |
| // they can be passed to the parser without needing a global. |
| // |
| class TParseContext : angle::NonCopyable |
| { |
| public: |
| TParseContext(TSymbolTable &symt, |
| TExtensionBehavior &ext, |
| sh::GLenum type, |
| ShShaderSpec spec, |
| ShCompileOptions options, |
| bool checksPrecErrors, |
| TDiagnostics *diagnostics, |
| const ShBuiltInResources &resources, |
| ShShaderOutput outputType); |
| ~TParseContext(); |
| |
| bool anyMultiviewExtensionAvailable(); |
| const angle::pp::Preprocessor &getPreprocessor() const { return mPreprocessor; } |
| angle::pp::Preprocessor &getPreprocessor() { return mPreprocessor; } |
| void *getScanner() const { return mScanner; } |
| void setScanner(void *scanner) { mScanner = scanner; } |
| int getShaderVersion() const { return mShaderVersion; } |
| sh::GLenum getShaderType() const { return mShaderType; } |
| ShShaderSpec getShaderSpec() const { return mShaderSpec; } |
| int numErrors() const { return mDiagnostics->numErrors(); } |
| void error(const TSourceLoc &loc, const char *reason, const char *token); |
| void error(const TSourceLoc &loc, const char *reason, const ImmutableString &token); |
| void warning(const TSourceLoc &loc, const char *reason, const char *token); |
| |
| // If isError is false, a warning will be reported instead. |
| void outOfRangeError(bool isError, |
| const TSourceLoc &loc, |
| const char *reason, |
| const char *token); |
| |
| TIntermBlock *getTreeRoot() const { return mTreeRoot; } |
| void setTreeRoot(TIntermBlock *treeRoot) { mTreeRoot = treeRoot; } |
| |
| bool getFragmentPrecisionHigh() const |
| { |
| return mFragmentPrecisionHighOnESSL1 || mShaderVersion >= 300; |
| } |
| void setFragmentPrecisionHighOnESSL1(bool fragmentPrecisionHigh) |
| { |
| mFragmentPrecisionHighOnESSL1 = fragmentPrecisionHigh; |
| } |
| |
| void setLoopNestingLevel(int loopNestintLevel) { mLoopNestingLevel = loopNestintLevel; } |
| |
| void incrLoopNestingLevel() { ++mLoopNestingLevel; } |
| void decrLoopNestingLevel() { --mLoopNestingLevel; } |
| |
| void incrSwitchNestingLevel() { ++mSwitchNestingLevel; } |
| void decrSwitchNestingLevel() { --mSwitchNestingLevel; } |
| |
| bool isComputeShaderLocalSizeDeclared() const { return mComputeShaderLocalSizeDeclared; } |
| sh::WorkGroupSize getComputeShaderLocalSize() const; |
| |
| int getNumViews() const { return mNumViews; } |
| |
| void enterFunctionDeclaration() { mDeclaringFunction = true; } |
| |
| void exitFunctionDeclaration() { mDeclaringFunction = false; } |
| |
| bool declaringFunction() const { return mDeclaringFunction; } |
| |
| TIntermConstantUnion *addScalarLiteral(const TConstantUnion *constantUnion, |
| const TSourceLoc &line); |
| |
| // This method is guaranteed to succeed, even if no variable with 'name' exists. |
| const TVariable *getNamedVariable(const TSourceLoc &location, |
| const ImmutableString &name, |
| const TSymbol *symbol); |
| TIntermTyped *parseVariableIdentifier(const TSourceLoc &location, |
| const ImmutableString &name, |
| const TSymbol *symbol); |
| |
| // Look at a '.' field selector string and change it into offsets for a vector. |
| bool parseVectorFields(const TSourceLoc &line, |
| const ImmutableString &compString, |
| int vecSize, |
| TVector<int> *fieldOffsets); |
| |
| void assignError(const TSourceLoc &line, const char *op, const TType &left, const TType &right); |
| void unaryOpError(const TSourceLoc &line, const char *op, const TType &operand); |
| void binaryOpError(const TSourceLoc &line, |
| const char *op, |
| const TType &left, |
| const TType &right); |
| |
| // Check functions - the ones that return bool return false if an error was generated. |
| |
| bool checkIsNotReserved(const TSourceLoc &line, const ImmutableString &identifier); |
| void checkPrecisionSpecified(const TSourceLoc &line, TPrecision precision, TBasicType type); |
| bool checkCanBeLValue(const TSourceLoc &line, const char *op, TIntermTyped *node); |
| void checkIsConst(TIntermTyped *node); |
| void checkIsScalarInteger(TIntermTyped *node, const char *token); |
| bool checkIsAtGlobalLevel(const TSourceLoc &line, const char *token); |
| bool checkConstructorArguments(const TSourceLoc &line, |
| const TIntermSequence &arguments, |
| const TType &type); |
| |
| // Returns a sanitized array size to use (the size is at least 1). |
| unsigned int checkIsValidArraySize(const TSourceLoc &line, TIntermTyped *expr); |
| bool checkIsValidQualifierForArray(const TSourceLoc &line, const TPublicType &elementQualifier); |
| bool checkArrayElementIsNotArray(const TSourceLoc &line, const TPublicType &elementType); |
| bool checkIsNonVoid(const TSourceLoc &line, |
| const ImmutableString &identifier, |
| const TBasicType &type); |
| bool checkIsScalarBool(const TSourceLoc &line, const TIntermTyped *type); |
| void checkIsScalarBool(const TSourceLoc &line, const TPublicType &pType); |
| bool checkIsNotOpaqueType(const TSourceLoc &line, |
| const TTypeSpecifierNonArray &pType, |
| const char *reason); |
| void checkDeclaratorLocationIsNotSpecified(const TSourceLoc &line, const TPublicType &pType); |
| void checkLocationIsNotSpecified(const TSourceLoc &location, |
| const TLayoutQualifier &layoutQualifier); |
| void checkStd430IsForShaderStorageBlock(const TSourceLoc &location, |
| const TLayoutBlockStorage &blockStorage, |
| const TQualifier &qualifier); |
| void checkIsParameterQualifierValid(const TSourceLoc &line, |
| const TTypeQualifierBuilder &typeQualifierBuilder, |
| TType *type); |
| |
| // Check if at least one of the specified extensions can be used, and generate error/warning as |
| // appropriate according to the spec. |
| // This function is only needed for a few different small constant sizes of extension array, and |
| // we want to avoid unnecessary dynamic allocations. That's why checkCanUseOneOfExtensions is a |
| // template function rather than one taking a vector. |
| template <size_t size> |
| bool checkCanUseOneOfExtensions(const TSourceLoc &line, |
| const std::array<TExtension, size> &extensions); |
| bool checkCanUseExtension(const TSourceLoc &line, TExtension extension); |
| |
| // Done for all declarations, whether empty or not. |
| void declarationQualifierErrorCheck(const sh::TQualifier qualifier, |
| const sh::TLayoutQualifier &layoutQualifier, |
| const TSourceLoc &location); |
| // Done for the first non-empty declarator in a declaration. |
| void nonEmptyDeclarationErrorCheck(const TPublicType &publicType, |
| const TSourceLoc &identifierLocation); |
| // Done only for empty declarations. |
| void emptyDeclarationErrorCheck(const TType &type, const TSourceLoc &location); |
| |
| void checkLayoutQualifierSupported(const TSourceLoc &location, |
| const ImmutableString &layoutQualifierName, |
| int versionRequired); |
| bool checkWorkGroupSizeIsNotSpecified(const TSourceLoc &location, |
| const TLayoutQualifier &layoutQualifier); |
| void functionCallRValueLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *fnCall); |
| void checkInvariantVariableQualifier(bool invariant, |
| const TQualifier qualifier, |
| const TSourceLoc &invariantLocation); |
| void checkInputOutputTypeIsValidES3(const TQualifier qualifier, |
| const TPublicType &type, |
| const TSourceLoc &qualifierLocation); |
| void checkLocalVariableConstStorageQualifier(const TQualifierWrapperBase &qualifier); |
| const TPragma &pragma() const { return mDirectiveHandler.pragma(); } |
| const TExtensionBehavior &extensionBehavior() const |
| { |
| return mDirectiveHandler.extensionBehavior(); |
| } |
| |
| bool isExtensionEnabled(TExtension extension) const; |
| void handleExtensionDirective(const TSourceLoc &loc, const char *extName, const char *behavior); |
| void handlePragmaDirective(const TSourceLoc &loc, |
| const char *name, |
| const char *value, |
| bool stdgl); |
| |
| // Returns true on success. *initNode may still be nullptr on success in case the initialization |
| // is not needed in the AST. |
| bool executeInitializer(const TSourceLoc &line, |
| const ImmutableString &identifier, |
| TType *type, |
| TIntermTyped *initializer, |
| TIntermBinary **initNode); |
| TIntermNode *addConditionInitializer(const TPublicType &pType, |
| const ImmutableString &identifier, |
| TIntermTyped *initializer, |
| const TSourceLoc &loc); |
| TIntermNode *addLoop(TLoopType type, |
| TIntermNode *init, |
| TIntermNode *cond, |
| TIntermTyped *expr, |
| TIntermNode *body, |
| const TSourceLoc &loc); |
| |
| // For "if" test nodes. There are three children: a condition, a true path, and a false path. |
| // The two paths are in TIntermNodePair code. |
| TIntermNode *addIfElse(TIntermTyped *cond, TIntermNodePair code, const TSourceLoc &loc); |
| |
| void addFullySpecifiedType(TPublicType *typeSpecifier); |
| TPublicType addFullySpecifiedType(const TTypeQualifierBuilder &typeQualifierBuilder, |
| const TPublicType &typeSpecifier); |
| |
| TIntermDeclaration *parseSingleDeclaration(TPublicType &publicType, |
| const TSourceLoc &identifierOrTypeLocation, |
| const ImmutableString &identifier); |
| TIntermDeclaration *parseSingleArrayDeclaration(TPublicType &elementType, |
| const TSourceLoc &identifierLocation, |
| const ImmutableString &identifier, |
| const TSourceLoc &indexLocation, |
| const TVector<unsigned int> &arraySizes); |
| TIntermDeclaration *parseSingleInitDeclaration(const TPublicType &publicType, |
| const TSourceLoc &identifierLocation, |
| const ImmutableString &identifier, |
| const TSourceLoc &initLocation, |
| TIntermTyped *initializer); |
| |
| // Parse a declaration like "type a[n] = initializer" |
| // Note that this does not apply to declarations like "type[n] a = initializer" |
| TIntermDeclaration *parseSingleArrayInitDeclaration(TPublicType &elementType, |
| const TSourceLoc &identifierLocation, |
| const ImmutableString &identifier, |
| const TSourceLoc &indexLocation, |
| const TVector<unsigned int> &arraySizes, |
| const TSourceLoc &initLocation, |
| TIntermTyped *initializer); |
| |
| TIntermGlobalQualifierDeclaration *parseGlobalQualifierDeclaration( |
| const TTypeQualifierBuilder &typeQualifierBuilder, |
| const TSourceLoc &identifierLoc, |
| const ImmutableString &identifier, |
| const TSymbol *symbol); |
| |
| void parseDeclarator(TPublicType &publicType, |
| const TSourceLoc &identifierLocation, |
| const ImmutableString &identifier, |
| TIntermDeclaration *declarationOut); |
| void parseArrayDeclarator(TPublicType &elementType, |
| const TSourceLoc &identifierLocation, |
| const ImmutableString &identifier, |
| const TSourceLoc &arrayLocation, |
| const TVector<unsigned int> &arraySizes, |
| TIntermDeclaration *declarationOut); |
| void parseInitDeclarator(const TPublicType &publicType, |
| const TSourceLoc &identifierLocation, |
| const ImmutableString &identifier, |
| const TSourceLoc &initLocation, |
| TIntermTyped *initializer, |
| TIntermDeclaration *declarationOut); |
| |
| // Parse a declarator like "a[n] = initializer" |
| void parseArrayInitDeclarator(const TPublicType &elementType, |
| const TSourceLoc &identifierLocation, |
| const ImmutableString &identifier, |
| const TSourceLoc &indexLocation, |
| const TVector<unsigned int> &arraySizes, |
| const TSourceLoc &initLocation, |
| TIntermTyped *initializer, |
| TIntermDeclaration *declarationOut); |
| |
| TIntermNode *addEmptyStatement(const TSourceLoc &location); |
| |
| void parseDefaultPrecisionQualifier(const TPrecision precision, |
| const TPublicType &type, |
| const TSourceLoc &loc); |
| void parseGlobalLayoutQualifier(const TTypeQualifierBuilder &typeQualifierBuilder); |
| |
| TIntermFunctionPrototype *addFunctionPrototypeDeclaration(const TFunction &parsedFunction, |
| const TSourceLoc &location); |
| TIntermFunctionDefinition *addFunctionDefinition(TIntermFunctionPrototype *functionPrototype, |
| TIntermBlock *functionBody, |
| const TSourceLoc &location); |
| void parseFunctionDefinitionHeader(const TSourceLoc &location, |
| const TFunction *function, |
| TIntermFunctionPrototype **prototypeOut); |
| TFunction *parseFunctionDeclarator(const TSourceLoc &location, TFunction *function); |
| TFunction *parseFunctionHeader(const TPublicType &type, |
| const ImmutableString &name, |
| const TSourceLoc &location); |
| |
| TFunctionLookup *addNonConstructorFunc(const ImmutableString &name, const TSymbol *symbol); |
| TFunctionLookup *addConstructorFunc(const TPublicType &publicType); |
| |
| TParameter parseParameterDeclarator(const TPublicType &publicType, |
| const ImmutableString &name, |
| const TSourceLoc &nameLoc); |
| |
| TParameter parseParameterArrayDeclarator(const ImmutableString &name, |
| const TSourceLoc &nameLoc, |
| const TVector<unsigned int> &arraySizes, |
| const TSourceLoc &arrayLoc, |
| TPublicType *elementType); |
| |
| TIntermTyped *addIndexExpression(TIntermTyped *baseExpression, |
| const TSourceLoc &location, |
| TIntermTyped *indexExpression); |
| TIntermTyped *addFieldSelectionExpression(TIntermTyped *baseExpression, |
| const TSourceLoc &dotLocation, |
| const ImmutableString &fieldString, |
| const TSourceLoc &fieldLocation); |
| |
| // Parse declarator for a single field |
| TDeclarator *parseStructDeclarator(const ImmutableString &identifier, const TSourceLoc &loc); |
| TDeclarator *parseStructArrayDeclarator(const ImmutableString &identifier, |
| const TSourceLoc &loc, |
| const TVector<unsigned int> *arraySizes); |
| |
| void checkDoesNotHaveDuplicateFieldName(const TFieldList::const_iterator begin, |
| const TFieldList::const_iterator end, |
| const ImmutableString &name, |
| const TSourceLoc &location); |
| TFieldList *addStructFieldList(TFieldList *fields, const TSourceLoc &location); |
| TFieldList *combineStructFieldLists(TFieldList *processedFields, |
| const TFieldList *newlyAddedFields, |
| const TSourceLoc &location); |
| TFieldList *addStructDeclaratorListWithQualifiers( |
| const TTypeQualifierBuilder &typeQualifierBuilder, |
| TPublicType *typeSpecifier, |
| const TDeclaratorList *declaratorList); |
| TFieldList *addStructDeclaratorList(const TPublicType &typeSpecifier, |
| const TDeclaratorList *declaratorList); |
| TTypeSpecifierNonArray addStructure(const TSourceLoc &structLine, |
| const TSourceLoc &nameLine, |
| const ImmutableString &structName, |
| TFieldList *fieldList); |
| |
| TIntermDeclaration *addInterfaceBlock(const TTypeQualifierBuilder &typeQualifierBuilder, |
| const TSourceLoc &nameLine, |
| const ImmutableString &blockName, |
| TFieldList *fieldList, |
| const ImmutableString &instanceName, |
| const TSourceLoc &instanceLine, |
| TIntermTyped *arrayIndex, |
| const TSourceLoc &arrayIndexLine); |
| |
| void parseLocalSize(const ImmutableString &qualifierType, |
| const TSourceLoc &qualifierTypeLine, |
| int intValue, |
| const TSourceLoc &intValueLine, |
| const std::string &intValueString, |
| size_t index, |
| sh::WorkGroupSize *localSize); |
| void parseNumViews(int intValue, |
| const TSourceLoc &intValueLine, |
| const std::string &intValueString, |
| int *numViews); |
| void parseInvocations(int intValue, |
| const TSourceLoc &intValueLine, |
| const std::string &intValueString, |
| int *numInvocations); |
| void parseMaxVertices(int intValue, |
| const TSourceLoc &intValueLine, |
| const std::string &intValueString, |
| int *numMaxVertices); |
| void parseIndexLayoutQualifier(int intValue, |
| const TSourceLoc &intValueLine, |
| const std::string &intValueString, |
| int *index); |
| TLayoutQualifier parseLayoutQualifier(const ImmutableString &qualifierType, |
| const TSourceLoc &qualifierTypeLine); |
| TLayoutQualifier parseLayoutQualifier(const ImmutableString &qualifierType, |
| const TSourceLoc &qualifierTypeLine, |
| int intValue, |
| const TSourceLoc &intValueLine); |
| TTypeQualifierBuilder *createTypeQualifierBuilder(const TSourceLoc &loc); |
| TStorageQualifierWrapper *parseGlobalStorageQualifier(TQualifier qualifier, |
| const TSourceLoc &loc); |
| TStorageQualifierWrapper *parseVaryingQualifier(const TSourceLoc &loc); |
| TStorageQualifierWrapper *parseInQualifier(const TSourceLoc &loc); |
| TStorageQualifierWrapper *parseOutQualifier(const TSourceLoc &loc); |
| TStorageQualifierWrapper *parseInOutQualifier(const TSourceLoc &loc); |
| TLayoutQualifier joinLayoutQualifiers(TLayoutQualifier leftQualifier, |
| TLayoutQualifier rightQualifier, |
| const TSourceLoc &rightQualifierLocation); |
| |
| // Performs an error check for embedded struct declarations. |
| void enterStructDeclaration(const TSourceLoc &line, const ImmutableString &identifier); |
| void exitStructDeclaration(); |
| |
| void checkIsBelowStructNestingLimit(const TSourceLoc &line, const TField &field); |
| |
| TIntermSwitch *addSwitch(TIntermTyped *init, |
| TIntermBlock *statementList, |
| const TSourceLoc &loc); |
| TIntermCase *addCase(TIntermTyped *condition, const TSourceLoc &loc); |
| TIntermCase *addDefault(const TSourceLoc &loc); |
| |
| TIntermTyped *addUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc); |
| TIntermTyped *addUnaryMathLValue(TOperator op, TIntermTyped *child, const TSourceLoc &loc); |
| TIntermTyped *addBinaryMath(TOperator op, |
| TIntermTyped *left, |
| TIntermTyped *right, |
| const TSourceLoc &loc); |
| TIntermTyped *addBinaryMathBooleanResult(TOperator op, |
| TIntermTyped *left, |
| TIntermTyped *right, |
| const TSourceLoc &loc); |
| TIntermTyped *addAssign(TOperator op, |
| TIntermTyped *left, |
| TIntermTyped *right, |
| const TSourceLoc &loc); |
| |
| TIntermTyped *addComma(TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc); |
| |
| TIntermBranch *addBranch(TOperator op, const TSourceLoc &loc); |
| TIntermBranch *addBranch(TOperator op, TIntermTyped *expression, const TSourceLoc &loc); |
| |
| void appendStatement(TIntermBlock *block, TIntermNode *statement); |
| |
| void checkTextureGather(TIntermAggregate *functionCall); |
| void checkTextureOffsetConst(TIntermAggregate *functionCall); |
| void checkImageMemoryAccessForBuiltinFunctions(TIntermAggregate *functionCall); |
| void checkImageMemoryAccessForUserDefinedFunctions(const TFunction *functionDefinition, |
| const TIntermAggregate *functionCall); |
| void checkAtomicMemoryBuiltinFunctions(TIntermAggregate *functionCall); |
| |
| // fnCall is only storing the built-in op, and function name or constructor type. arguments |
| // has the arguments. |
| TIntermTyped *addFunctionCallOrMethod(TFunctionLookup *fnCall, const TSourceLoc &loc); |
| |
| TIntermTyped *addTernarySelection(TIntermTyped *cond, |
| TIntermTyped *trueExpression, |
| TIntermTyped *falseExpression, |
| const TSourceLoc &line); |
| |
| int getGeometryShaderMaxVertices() const { return mGeometryShaderMaxVertices; } |
| int getGeometryShaderInvocations() const |
| { |
| return (mGeometryShaderInvocations > 0) ? mGeometryShaderInvocations : 1; |
| } |
| TLayoutPrimitiveType getGeometryShaderInputPrimitiveType() const |
| { |
| return mGeometryShaderInputPrimitiveType; |
| } |
| TLayoutPrimitiveType getGeometryShaderOutputPrimitiveType() const |
| { |
| return mGeometryShaderOutputPrimitiveType; |
| } |
| |
| ShShaderOutput getOutputType() const { return mOutputType; } |
| |
| // TODO(jmadill): make this private |
| TSymbolTable &symbolTable; // symbol table that goes with the language currently being parsed |
| |
| private: |
| class AtomicCounterBindingState; |
| constexpr static size_t kAtomicCounterSize = 4; |
| // UNIFORM_ARRAY_STRIDE for atomic counter arrays is an implementation-dependent value which |
| // can be queried after a program is linked according to ES 3.10 section 7.7.1. This is |
| // controversial with the offset inheritance as described in ESSL 3.10 section 4.4.6. Currently |
| // we treat it as always 4 in favour of the original interpretation in |
| // "ARB_shader_atomic_counters". |
| // TODO(jie.a.chen@intel.com): Double check this once the spec vagueness is resolved. |
| // Note that there may be tests in AtomicCounter_test that will need to be updated as well. |
| constexpr static size_t kAtomicCounterArrayStride = 4; |
| |
| void markStaticReadIfSymbol(TIntermNode *node); |
| |
| // Returns a clamped index. If it prints out an error message, the token is "[]". |
| int checkIndexLessThan(bool outOfRangeIndexIsError, |
| const TSourceLoc &location, |
| int index, |
| int arraySize, |
| const char *reason); |
| |
| bool declareVariable(const TSourceLoc &line, |
| const ImmutableString &identifier, |
| const TType *type, |
| TVariable **variable); |
| |
| void checkCanBeDeclaredWithoutInitializer(const TSourceLoc &line, |
| const ImmutableString &identifier, |
| TType *type); |
| |
| TParameter parseParameterDeclarator(TType *type, |
| const ImmutableString &name, |
| const TSourceLoc &nameLoc); |
| |
| bool checkIsValidTypeAndQualifierForArray(const TSourceLoc &indexLocation, |
| const TPublicType &elementType); |
| // Done for all atomic counter declarations, whether empty or not. |
| void atomicCounterQualifierErrorCheck(const TPublicType &publicType, |
| const TSourceLoc &location); |
| |
| // Assumes that multiplication op has already been set based on the types. |
| bool isMultiplicationTypeCombinationValid(TOperator op, const TType &left, const TType &right); |
| |
| void checkOutParameterIsNotOpaqueType(const TSourceLoc &line, |
| TQualifier qualifier, |
| const TType &type); |
| |
| void checkInternalFormatIsNotSpecified(const TSourceLoc &location, |
| TLayoutImageInternalFormat internalFormat); |
| void checkMemoryQualifierIsNotSpecified(const TMemoryQualifier &memoryQualifier, |
| const TSourceLoc &location); |
| void checkAtomicCounterOffsetDoesNotOverlap(bool forceAppend, |
| const TSourceLoc &loc, |
| TType *type); |
| void checkAtomicCounterOffsetAlignment(const TSourceLoc &location, const TType &type); |
| |
| void checkIndexIsNotSpecified(const TSourceLoc &location, int index); |
| void checkBindingIsValid(const TSourceLoc &identifierLocation, const TType &type); |
| void checkBindingIsNotSpecified(const TSourceLoc &location, int binding); |
| void checkOffsetIsNotSpecified(const TSourceLoc &location, int offset); |
| void checkImageBindingIsValid(const TSourceLoc &location, |
| int binding, |
| int arrayTotalElementCount); |
| void checkSamplerBindingIsValid(const TSourceLoc &location, |
| int binding, |
| int arrayTotalElementCount); |
| void checkBlockBindingIsValid(const TSourceLoc &location, |
| const TQualifier &qualifier, |
| int binding, |
| int arraySize); |
| void checkAtomicCounterBindingIsValid(const TSourceLoc &location, int binding); |
| |
| void checkUniformLocationInRange(const TSourceLoc &location, |
| int objectLocationCount, |
| const TLayoutQualifier &layoutQualifier); |
| |
| void checkYuvIsNotSpecified(const TSourceLoc &location, bool yuv); |
| |
| bool checkUnsizedArrayConstructorArgumentDimensionality(const TIntermSequence &arguments, |
| TType type, |
| const TSourceLoc &line); |
| |
| // Will set the size of the outermost array according to geometry shader input layout. |
| void checkGeometryShaderInputAndSetArraySize(const TSourceLoc &location, |
| const ImmutableString &token, |
| TType *type); |
| |
| // Will size any unsized array type so unsized arrays won't need to be taken into account |
| // further along the line in parsing. |
| void checkIsNotUnsizedArray(const TSourceLoc &line, |
| const char *errorMessage, |
| const ImmutableString &token, |
| TType *arrayType); |
| |
| TIntermTyped *addBinaryMathInternal(TOperator op, |
| TIntermTyped *left, |
| TIntermTyped *right, |
| const TSourceLoc &loc); |
| TIntermTyped *createUnaryMath(TOperator op, |
| TIntermTyped *child, |
| const TSourceLoc &loc, |
| const TFunction *func); |
| |
| TIntermTyped *addMethod(TFunctionLookup *fnCall, const TSourceLoc &loc); |
| TIntermTyped *addConstructor(TFunctionLookup *fnCall, const TSourceLoc &line); |
| TIntermTyped *addNonConstructorFunctionCall(TFunctionLookup *fnCall, const TSourceLoc &loc); |
| |
| // Return either the original expression or the folded version of the expression in case the |
| // folded node will validate the same way during subsequent parsing. |
| TIntermTyped *expressionOrFoldedResult(TIntermTyped *expression); |
| |
| // Return true if the checks pass |
| bool binaryOpCommonCheck(TOperator op, |
| TIntermTyped *left, |
| TIntermTyped *right, |
| const TSourceLoc &loc); |
| |
| TIntermFunctionPrototype *createPrototypeNodeFromFunction(const TFunction &function, |
| const TSourceLoc &location, |
| bool insertParametersToSymbolTable); |
| |
| void setAtomicCounterBindingDefaultOffset(const TPublicType &declaration, |
| const TSourceLoc &location); |
| |
| bool checkPrimitiveTypeMatchesTypeQualifier(const TTypeQualifier &typeQualifier); |
| bool parseGeometryShaderInputLayoutQualifier(const TTypeQualifier &typeQualifier); |
| bool parseGeometryShaderOutputLayoutQualifier(const TTypeQualifier &typeQualifier); |
| void setGeometryShaderInputArraySize(unsigned int inputArraySize, const TSourceLoc &line); |
| |
| // Set to true when the last/current declarator list was started with an empty declaration. The |
| // non-empty declaration error check will need to be performed if the empty declaration is |
| // followed by a declarator. |
| bool mDeferredNonEmptyDeclarationErrorCheck; |
| |
| sh::GLenum mShaderType; // vertex or fragment language (future: pack or unpack) |
| ShShaderSpec mShaderSpec; // The language specification compiler conforms to - GLES2 or WebGL. |
| ShCompileOptions mCompileOptions; // Options passed to TCompiler |
| int mShaderVersion; |
| TIntermBlock *mTreeRoot; // root of parse tree being created |
| int mLoopNestingLevel; // 0 if outside all loops |
| int mStructNestingLevel; // incremented while parsing a struct declaration |
| int mSwitchNestingLevel; // 0 if outside all switch statements |
| const TType |
| *mCurrentFunctionType; // the return type of the function that's currently being parsed |
| bool mFunctionReturnsValue; // true if a non-void function has a return |
| bool mChecksPrecisionErrors; // true if an error will be generated when a variable is declared |
| // without precision, explicit or implicit. |
| bool mFragmentPrecisionHighOnESSL1; // true if highp precision is supported when compiling |
| // ESSL1. |
| TLayoutMatrixPacking mDefaultUniformMatrixPacking; |
| TLayoutBlockStorage mDefaultUniformBlockStorage; |
| TLayoutMatrixPacking mDefaultBufferMatrixPacking; |
| TLayoutBlockStorage mDefaultBufferBlockStorage; |
| TString mHashErrMsg; |
| TDiagnostics *mDiagnostics; |
| TDirectiveHandler mDirectiveHandler; |
| angle::pp::Preprocessor mPreprocessor; |
| void *mScanner; |
| int mMinProgramTexelOffset; |
| int mMaxProgramTexelOffset; |
| |
| int mMinProgramTextureGatherOffset; |
| int mMaxProgramTextureGatherOffset; |
| |
| // keep track of local group size declared in layout. It should be declared only once. |
| bool mComputeShaderLocalSizeDeclared; |
| sh::WorkGroupSize mComputeShaderLocalSize; |
| // keep track of number of views declared in layout. |
| int mNumViews; |
| int mMaxNumViews; |
| int mMaxImageUnits; |
| int mMaxCombinedTextureImageUnits; |
| int mMaxUniformLocations; |
| int mMaxUniformBufferBindings; |
| int mMaxAtomicCounterBindings; |
| int mMaxShaderStorageBufferBindings; |
| |
| // keeps track whether we are declaring / defining a function |
| bool mDeclaringFunction; |
| |
| // Track the state of each atomic counter binding. |
| std::map<int, AtomicCounterBindingState> mAtomicCounterBindingStates; |
| |
| // Track the geometry shader global parameters declared in layout. |
| TLayoutPrimitiveType mGeometryShaderInputPrimitiveType; |
| TLayoutPrimitiveType mGeometryShaderOutputPrimitiveType; |
| int mGeometryShaderInvocations; |
| int mGeometryShaderMaxVertices; |
| int mMaxGeometryShaderInvocations; |
| int mMaxGeometryShaderMaxVertices; |
| |
| // Track when we add new scope for func body in ESSL 1.00 spec |
| bool mFunctionBodyNewScope; |
| |
| ShShaderOutput mOutputType; |
| }; |
| |
| int PaParseStrings(size_t count, |
| const char *const string[], |
| const int length[], |
| TParseContext *context); |
| |
| } // namespace sh |
| |
| #endif // COMPILER_TRANSLATOR_PARSECONTEXT_H_ |