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