summaryrefslogtreecommitdiffstats
path: root/gfx/angle/checkout/src/compiler/translator/ParseContext.h
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/angle/checkout/src/compiler/translator/ParseContext.h')
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ParseContext.h818
1 files changed, 818 insertions, 0 deletions
diff --git a/gfx/angle/checkout/src/compiler/translator/ParseContext.h b/gfx/angle/checkout/src/compiler/translator/ParseContext.h
new file mode 100644
index 0000000000..666f5e3851
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ParseContext.h
@@ -0,0 +1,818 @@
+//
+// 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,
+ const 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);
+
+ bool getFragmentPrecisionHigh() const
+ {
+ return mFragmentPrecisionHighOnESSL1 || mShaderVersion >= 300;
+ }
+ void setFragmentPrecisionHighOnESSL1(bool fragmentPrecisionHigh)
+ {
+ mFragmentPrecisionHighOnESSL1 = fragmentPrecisionHigh;
+ }
+
+ bool isEarlyFragmentTestsSpecified() const { return mEarlyFragmentTestsSpecified; }
+ bool hasDiscard() const { return mHasDiscard; }
+ bool isSampleQualifierSpecified() const { return mSampleQualifierSpecified; }
+
+ 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; }
+
+ const std::map<int, TLayoutImageInternalFormat> &pixelLocalStorageBindings() const
+ {
+ return mPLSBindings;
+ }
+
+ 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 checkArrayOfArraysInOut(const TSourceLoc &line,
+ const TPublicType &elementType,
+ const TType &arrayType);
+ 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 checkCanUseLayoutQualifier(const TSourceLoc &location);
+ bool 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);
+ void checkTCSOutVarIndexIsValid(TIntermBinary *binaryExpression, const TSourceLoc &location);
+
+ void checkAdvancedBlendEquationsNotSpecified(
+ const TSourceLoc &location,
+ const AdvancedBlendEquations &advancedBlendEquations,
+ const TQualifier &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);
+
+ // For built-ins that can be redeclared, adjusts the type qualifier so transformations can
+ // identify them correctly.
+ void adjustRedeclaredBuiltInType(const ImmutableString &identifier, TType *type);
+
+ // 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,
+ const TVector<unsigned int> *arraySizes,
+ const TSourceLoc &arraySizesLine);
+
+ 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 parseVertices(int intValue,
+ const TSourceLoc &intValueLine,
+ const std::string &intValueString,
+ int *numVertices);
+ 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 checkTextureOffset(TIntermAggregate *functionCall);
+ void checkImageMemoryAccessForBuiltinFunctions(TIntermAggregate *functionCall);
+ void checkImageMemoryAccessForUserDefinedFunctions(const TFunction *functionDefinition,
+ const TIntermAggregate *functionCall);
+ void checkAtomicMemoryBuiltinFunctions(TIntermAggregate *functionCall);
+ void checkInterpolationFS(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;
+ }
+ int getTessControlShaderOutputVertices() const { return mTessControlShaderOutputVertices; }
+ TLayoutTessEvaluationType getTessEvaluationShaderInputPrimitiveType() const
+ {
+ return mTessEvaluationShaderInputPrimitiveType;
+ }
+ TLayoutTessEvaluationType getTessEvaluationShaderInputVertexSpacingType() const
+ {
+ return mTessEvaluationShaderInputVertexSpacingType;
+ }
+ TLayoutTessEvaluationType getTessEvaluationShaderInputOrderingType() const
+ {
+ return mTessEvaluationShaderInputOrderingType;
+ }
+ TLayoutTessEvaluationType getTessEvaluationShaderInputPointType() const
+ {
+ return mTessEvaluationShaderInputPointType;
+ }
+
+ const TVector<TType *> &getDeferredArrayTypesToSize() const
+ {
+ return mDeferredArrayTypesToSize;
+ }
+
+ void markShaderHasPrecise() { mHasAnyPreciseType = true; }
+ bool hasAnyPreciseType() const { return mHasAnyPreciseType; }
+ AdvancedBlendEquations getAdvancedBlendEquations() const { return mAdvancedBlendEquations; }
+
+ 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 checkPixelLocalStorageBindingIsValid(const TSourceLoc &, const TType &);
+
+ void checkUniformLocationInRange(const TSourceLoc &location,
+ int objectLocationCount,
+ const TLayoutQualifier &layoutQualifier);
+ void checkAttributeLocationInRange(const TSourceLoc &location,
+ int objectLocationCount,
+ const TLayoutQualifier &layoutQualifier);
+
+ void checkYuvIsNotSpecified(const TSourceLoc &location, bool yuv);
+
+ void checkEarlyFragmentTestsIsNotSpecified(const TSourceLoc &location, bool earlyFragmentTests);
+
+ void checkNoncoherentIsSpecified(const TSourceLoc &location, bool noncoherent);
+
+ void checkNoncoherentIsNotSpecified(const TSourceLoc &location, bool noncoherent);
+
+ bool checkUnsizedArrayConstructorArgumentDimensionality(const TIntermSequence &arguments,
+ TType type,
+ const TSourceLoc &line);
+
+ void checkCombinedClipCullDistanceIsValid(const TSourceLoc &line,
+ const ImmutableString &identifier,
+ const int arraySize);
+
+ // Check texture offset is within range.
+ void checkSingleTextureOffset(const TSourceLoc &line,
+ const TConstantUnion *values,
+ size_t size,
+ int minOffsetValue,
+ int maxOffsetValue);
+
+ // Will set the size of the outermost array according to geometry shader input layout.
+ void checkGeometryShaderInputAndSetArraySize(const TSourceLoc &location,
+ const ImmutableString &token,
+ TType *type);
+
+ // Similar, for tessellation shaders.
+ void checkTessellationShaderUnsizedArraysAndSetSize(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);
+
+ bool parseTessControlShaderOutputLayoutQualifier(const TTypeQualifier &typeQualifier);
+ bool parseTessEvaluationShaderInputLayoutQualifier(const TTypeQualifier &typeQualifier);
+
+ // Certain operations become illegal only iff the shader declares pixel local storage uniforms.
+ enum class PLSIllegalOperations
+ {
+ // When polyfilled with shader images, pixel local storage requires early_fragment_tests,
+ // which causes discard to interact differently with the depth and stencil tests.
+ //
+ // To ensure identical behavior across all backends (some of which may not have access to
+ // early_fragment_tests), we disallow discard if pixel local storage uniforms have been
+ // declared.
+ Discard,
+
+ // ARB_fragment_shader_interlock functions cannot be called within flow control, which
+ // includes any code that might execute after a return statement. To keep things simple, and
+ // since these "interlock" calls are automatically injected by the compiler inside of
+ // main(), we disallow return from main() if pixel local storage uniforms have been
+ // declared.
+ ReturnFromMain,
+
+ // When polyfilled with shader images, pixel local storage requires early_fragment_tests,
+ // which causes assignments to gl_FragDepth(EXT) and gl_SampleMask to be ignored.
+ //
+ // To ensure identical behavior across all backends, we disallow assignment to these values
+ // if pixel local storage uniforms have been declared.
+ AssignFragDepth,
+ AssignSampleMask
+ };
+
+ // Generates an error if any pixel local storage uniforms have been declared (more specifically,
+ // if mPLSBindings is not empty).
+ //
+ // If no pixel local storage uniforms have been declared, and if the PLS extension is enabled,
+ // saves the potential error to mPLSPotentialErrors in case we encounter a PLS uniform later.
+ void errorIfPLSDeclared(const TSourceLoc &, PLSIllegalOperations);
+
+ // 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/fragment/geometry/etc shader
+ ShShaderSpec mShaderSpec; // The language specification compiler conforms to - GLES/WebGL/etc.
+ 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.
+ bool mEarlyFragmentTestsSpecified; // true if |layout(early_fragment_tests) in| is specified.
+ bool mHasDiscard; // true if |discard| is encountered in the shader.
+ bool mSampleQualifierSpecified; // true if the |sample| qualifier is used.
+ 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 mMaxVertexAttribs;
+ int mMaxAtomicCounterBindings;
+ int mMaxShaderStorageBufferBindings;
+
+ // keeps track whether we are declaring / defining a function
+ bool mDeclaringFunction;
+
+ // keeps track whether we are declaring / defining the function main().
+ bool mDeclaringMain;
+
+ // Track the state of each atomic counter binding.
+ std::map<int, AtomicCounterBindingState> mAtomicCounterBindingStates;
+
+ // Track the format of each pixel local storage binding.
+ std::map<int, TLayoutImageInternalFormat> mPLSBindings;
+
+ // Potential errors to generate immediately upon encountering a pixel local storage uniform.
+ std::vector<std::tuple<const TSourceLoc, PLSIllegalOperations>> mPLSPotentialErrors;
+
+ // Track the geometry shader global parameters declared in layout.
+ TLayoutPrimitiveType mGeometryShaderInputPrimitiveType;
+ TLayoutPrimitiveType mGeometryShaderOutputPrimitiveType;
+ int mGeometryShaderInvocations;
+ int mGeometryShaderMaxVertices;
+ int mMaxGeometryShaderInvocations;
+ int mMaxGeometryShaderMaxVertices;
+ unsigned int mGeometryInputArraySize;
+
+ int mMaxPatchVertices;
+ int mTessControlShaderOutputVertices;
+ TLayoutTessEvaluationType mTessEvaluationShaderInputPrimitiveType;
+ TLayoutTessEvaluationType mTessEvaluationShaderInputVertexSpacingType;
+ TLayoutTessEvaluationType mTessEvaluationShaderInputOrderingType;
+ TLayoutTessEvaluationType mTessEvaluationShaderInputPointType;
+ // List of array declarations without an explicit size that have come before layout(vertices=N).
+ // Once the vertex count is specified, these arrays are sized.
+ TVector<TType *> mDeferredArrayTypesToSize;
+ // Whether the |precise| keyword has been seen in the shader.
+ bool mHasAnyPreciseType;
+
+ AdvancedBlendEquations mAdvancedBlendEquations;
+
+ // 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_