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