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