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