1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include "ParseHelper.h" 16 17 #include <limits> 18 #include <stdarg.h> 19 #include <stdio.h> 20 21 #include "glslang.h" 22 #include "preprocessor/SourceLocation.h" 23 #include "ValidateSwitch.h" 24 25 /////////////////////////////////////////////////////////////////////// 26 // 27 // Sub- vector and matrix fields 28 // 29 //////////////////////////////////////////////////////////////////////// 30 31 namespace 32 { 33 bool IsVaryingOut(TQualifier qualifier) 34 { 35 switch(qualifier) 36 { 37 case EvqVaryingOut: 38 case EvqSmoothOut: 39 case EvqFlatOut: 40 case EvqCentroidOut: 41 case EvqVertexOut: 42 return true; 43 44 default: break; 45 } 46 47 return false; 48 } 49 50 bool IsVaryingIn(TQualifier qualifier) 51 { 52 switch(qualifier) 53 { 54 case EvqVaryingIn: 55 case EvqSmoothIn: 56 case EvqFlatIn: 57 case EvqCentroidIn: 58 case EvqFragmentIn: 59 return true; 60 61 default: break; 62 } 63 64 return false; 65 } 66 67 bool IsVarying(TQualifier qualifier) 68 { 69 return IsVaryingIn(qualifier) || IsVaryingOut(qualifier); 70 } 71 72 bool IsAssignment(TOperator op) 73 { 74 switch(op) 75 { 76 case EOpPostIncrement: 77 case EOpPostDecrement: 78 case EOpPreIncrement: 79 case EOpPreDecrement: 80 case EOpAssign: 81 case EOpAddAssign: 82 case EOpSubAssign: 83 case EOpMulAssign: 84 case EOpVectorTimesMatrixAssign: 85 case EOpVectorTimesScalarAssign: 86 case EOpMatrixTimesScalarAssign: 87 case EOpMatrixTimesMatrixAssign: 88 case EOpDivAssign: 89 case EOpIModAssign: 90 case EOpBitShiftLeftAssign: 91 case EOpBitShiftRightAssign: 92 case EOpBitwiseAndAssign: 93 case EOpBitwiseXorAssign: 94 case EOpBitwiseOrAssign: 95 return true; 96 default: 97 return false; 98 } 99 } 100 } 101 102 // 103 // Look at a '.' field selector string and change it into offsets 104 // for a vector. 105 // 106 bool TParseContext::parseVectorFields(const TString& compString, int vecSize, TVectorFields& fields, const TSourceLoc &line) 107 { 108 fields.num = (int) compString.size(); 109 if (fields.num > 4) { 110 error(line, "illegal vector field selection", compString.c_str()); 111 return false; 112 } 113 114 enum { 115 exyzw, 116 ergba, 117 estpq 118 } fieldSet[4]; 119 120 for (int i = 0; i < fields.num; ++i) { 121 switch (compString[i]) { 122 case 'x': 123 fields.offsets[i] = 0; 124 fieldSet[i] = exyzw; 125 break; 126 case 'r': 127 fields.offsets[i] = 0; 128 fieldSet[i] = ergba; 129 break; 130 case 's': 131 fields.offsets[i] = 0; 132 fieldSet[i] = estpq; 133 break; 134 case 'y': 135 fields.offsets[i] = 1; 136 fieldSet[i] = exyzw; 137 break; 138 case 'g': 139 fields.offsets[i] = 1; 140 fieldSet[i] = ergba; 141 break; 142 case 't': 143 fields.offsets[i] = 1; 144 fieldSet[i] = estpq; 145 break; 146 case 'z': 147 fields.offsets[i] = 2; 148 fieldSet[i] = exyzw; 149 break; 150 case 'b': 151 fields.offsets[i] = 2; 152 fieldSet[i] = ergba; 153 break; 154 case 'p': 155 fields.offsets[i] = 2; 156 fieldSet[i] = estpq; 157 break; 158 case 'w': 159 fields.offsets[i] = 3; 160 fieldSet[i] = exyzw; 161 break; 162 case 'a': 163 fields.offsets[i] = 3; 164 fieldSet[i] = ergba; 165 break; 166 case 'q': 167 fields.offsets[i] = 3; 168 fieldSet[i] = estpq; 169 break; 170 default: 171 error(line, "illegal vector field selection", compString.c_str()); 172 return false; 173 } 174 } 175 176 for (int i = 0; i < fields.num; ++i) { 177 if (fields.offsets[i] >= vecSize) { 178 error(line, "vector field selection out of range", compString.c_str()); 179 return false; 180 } 181 182 if (i > 0) { 183 if (fieldSet[i] != fieldSet[i-1]) { 184 error(line, "illegal - vector component fields not from the same set", compString.c_str()); 185 return false; 186 } 187 } 188 } 189 190 return true; 191 } 192 193 /////////////////////////////////////////////////////////////////////// 194 // 195 // Errors 196 // 197 //////////////////////////////////////////////////////////////////////// 198 199 // 200 // Track whether errors have occurred. 201 // 202 void TParseContext::recover() 203 { 204 } 205 206 // 207 // Used by flex/bison to output all syntax and parsing errors. 208 // 209 void TParseContext::error(const TSourceLoc& loc, 210 const char* reason, const char* token, 211 const char* extraInfo) 212 { 213 pp::SourceLocation srcLoc(loc.first_file, loc.first_line); 214 mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, 215 srcLoc, reason, token, extraInfo); 216 217 } 218 219 void TParseContext::warning(const TSourceLoc& loc, 220 const char* reason, const char* token, 221 const char* extraInfo) { 222 pp::SourceLocation srcLoc(loc.first_file, loc.first_line); 223 mDiagnostics.writeInfo(pp::Diagnostics::PP_WARNING, 224 srcLoc, reason, token, extraInfo); 225 } 226 227 void TParseContext::trace(const char* str) 228 { 229 mDiagnostics.writeDebug(str); 230 } 231 232 // 233 // Same error message for all places assignments don't work. 234 // 235 void TParseContext::assignError(const TSourceLoc &line, const char* op, TString left, TString right) 236 { 237 std::stringstream extraInfoStream; 238 extraInfoStream << "cannot convert from '" << right << "' to '" << left << "'"; 239 std::string extraInfo = extraInfoStream.str(); 240 error(line, "", op, extraInfo.c_str()); 241 } 242 243 // 244 // Same error message for all places unary operations don't work. 245 // 246 void TParseContext::unaryOpError(const TSourceLoc &line, const char* op, TString operand) 247 { 248 std::stringstream extraInfoStream; 249 extraInfoStream << "no operation '" << op << "' exists that takes an operand of type " << operand 250 << " (or there is no acceptable conversion)"; 251 std::string extraInfo = extraInfoStream.str(); 252 error(line, " wrong operand type", op, extraInfo.c_str()); 253 } 254 255 // 256 // Same error message for all binary operations don't work. 257 // 258 void TParseContext::binaryOpError(const TSourceLoc &line, const char* op, TString left, TString right) 259 { 260 std::stringstream extraInfoStream; 261 extraInfoStream << "no operation '" << op << "' exists that takes a left-hand operand of type '" << left 262 << "' and a right operand of type '" << right << "' (or there is no acceptable conversion)"; 263 std::string extraInfo = extraInfoStream.str(); 264 error(line, " wrong operand types ", op, extraInfo.c_str()); 265 } 266 267 bool TParseContext::precisionErrorCheck(const TSourceLoc &line, TPrecision precision, TBasicType type){ 268 if (!mChecksPrecisionErrors) 269 return false; 270 switch( type ){ 271 case EbtFloat: 272 if( precision == EbpUndefined ){ 273 error( line, "No precision specified for (float)", "" ); 274 return true; 275 } 276 break; 277 case EbtInt: 278 if( precision == EbpUndefined ){ 279 error( line, "No precision specified (int)", "" ); 280 return true; 281 } 282 break; 283 default: 284 return false; 285 } 286 return false; 287 } 288 289 // 290 // Both test and if necessary, spit out an error, to see if the node is really 291 // an l-value that can be operated on this way. 292 // 293 // Returns true if the was an error. 294 // 295 bool TParseContext::lValueErrorCheck(const TSourceLoc &line, const char* op, TIntermTyped* node) 296 { 297 TIntermSymbol* symNode = node->getAsSymbolNode(); 298 TIntermBinary* binaryNode = node->getAsBinaryNode(); 299 300 if (binaryNode) { 301 bool errorReturn; 302 303 switch(binaryNode->getOp()) { 304 case EOpIndexDirect: 305 case EOpIndexIndirect: 306 case EOpIndexDirectStruct: 307 return lValueErrorCheck(line, op, binaryNode->getLeft()); 308 case EOpVectorSwizzle: 309 errorReturn = lValueErrorCheck(line, op, binaryNode->getLeft()); 310 if (!errorReturn) { 311 int offset[4] = {0,0,0,0}; 312 313 TIntermTyped* rightNode = binaryNode->getRight(); 314 TIntermAggregate *aggrNode = rightNode->getAsAggregate(); 315 316 for (TIntermSequence::iterator p = aggrNode->getSequence().begin(); 317 p != aggrNode->getSequence().end(); p++) { 318 int value = (*p)->getAsTyped()->getAsConstantUnion()->getIConst(0); 319 offset[value]++; 320 if (offset[value] > 1) { 321 error(line, " l-value of swizzle cannot have duplicate components", op); 322 323 return true; 324 } 325 } 326 } 327 328 return errorReturn; 329 case EOpIndexDirectInterfaceBlock: 330 default: 331 break; 332 } 333 error(line, " l-value required", op); 334 335 return true; 336 } 337 338 339 const char* symbol = 0; 340 if (symNode != 0) 341 symbol = symNode->getSymbol().c_str(); 342 343 const char* message = 0; 344 switch (node->getQualifier()) { 345 case EvqConstExpr: message = "can't modify a const"; break; 346 case EvqConstReadOnly: message = "can't modify a const"; break; 347 case EvqAttribute: message = "can't modify an attribute"; break; 348 case EvqFragmentIn: message = "can't modify an input"; break; 349 case EvqVertexIn: message = "can't modify an input"; break; 350 case EvqUniform: message = "can't modify a uniform"; break; 351 case EvqSmoothIn: 352 case EvqFlatIn: 353 case EvqCentroidIn: 354 case EvqVaryingIn: message = "can't modify a varying"; break; 355 case EvqInput: message = "can't modify an input"; break; 356 case EvqFragCoord: message = "can't modify gl_FragCoord"; break; 357 case EvqFrontFacing: message = "can't modify gl_FrontFacing"; break; 358 case EvqPointCoord: message = "can't modify gl_PointCoord"; break; 359 case EvqInstanceID: message = "can't modify gl_InstanceID"; break; 360 case EvqVertexID: message = "can't modify gl_VertexID"; break; 361 default: 362 363 // 364 // Type that can't be written to? 365 // 366 if(IsSampler(node->getBasicType())) 367 { 368 message = "can't modify a sampler"; 369 } 370 else if(node->getBasicType() == EbtVoid) 371 { 372 message = "can't modify void"; 373 } 374 } 375 376 if (message == 0 && binaryNode == 0 && symNode == 0) { 377 error(line, " l-value required", op); 378 379 return true; 380 } 381 382 383 // 384 // Everything else is okay, no error. 385 // 386 if (message == 0) 387 return false; 388 389 // 390 // If we get here, we have an error and a message. 391 // 392 if (symNode) { 393 std::stringstream extraInfoStream; 394 extraInfoStream << "\"" << symbol << "\" (" << message << ")"; 395 std::string extraInfo = extraInfoStream.str(); 396 error(line, " l-value required", op, extraInfo.c_str()); 397 } 398 else { 399 std::stringstream extraInfoStream; 400 extraInfoStream << "(" << message << ")"; 401 std::string extraInfo = extraInfoStream.str(); 402 error(line, " l-value required", op, extraInfo.c_str()); 403 } 404 405 return true; 406 } 407 408 // 409 // Both test, and if necessary spit out an error, to see if the node is really 410 // a constant. 411 // 412 // Returns true if the was an error. 413 // 414 bool TParseContext::constErrorCheck(TIntermTyped* node) 415 { 416 if (node->getQualifier() == EvqConstExpr) 417 return false; 418 419 error(node->getLine(), "constant expression required", ""); 420 421 return true; 422 } 423 424 // 425 // Both test, and if necessary spit out an error, to see if the node is really 426 // an integer. 427 // 428 // Returns true if the was an error. 429 // 430 bool TParseContext::integerErrorCheck(TIntermTyped* node, const char* token) 431 { 432 if (node->isScalarInt()) 433 return false; 434 435 error(node->getLine(), "integer expression required", token); 436 437 return true; 438 } 439 440 // 441 // Both test, and if necessary spit out an error, to see if we are currently 442 // globally scoped. 443 // 444 // Returns true if the was an error. 445 // 446 bool TParseContext::globalErrorCheck(const TSourceLoc &line, bool global, const char* token) 447 { 448 if (global) 449 return false; 450 451 error(line, "only allowed at global scope", token); 452 453 return true; 454 } 455 456 // 457 // For now, keep it simple: if it starts "gl_", it's reserved, independent 458 // of scope. Except, if the symbol table is at the built-in push-level, 459 // which is when we are parsing built-ins. 460 // Also checks for "webgl_" and "_webgl_" reserved identifiers if parsing a 461 // webgl shader. 462 // 463 // Returns true if there was an error. 464 // 465 bool TParseContext::reservedErrorCheck(const TSourceLoc &line, const TString& identifier) 466 { 467 static const char* reservedErrMsg = "reserved built-in name"; 468 if (!symbolTable.atBuiltInLevel()) { 469 if (identifier.compare(0, 3, "gl_") == 0) { 470 error(line, reservedErrMsg, "gl_"); 471 return true; 472 } 473 if (identifier.find("__") != TString::npos) { 474 error(line, "identifiers containing two consecutive underscores (__) are reserved as possible future keywords", identifier.c_str()); 475 return true; 476 } 477 } 478 479 return false; 480 } 481 482 // 483 // Make sure there is enough data provided to the constructor to build 484 // something of the type of the constructor. Also returns the type of 485 // the constructor. 486 // 487 // Returns true if there was an error in construction. 488 // 489 bool TParseContext::constructorErrorCheck(const TSourceLoc &line, TIntermNode* node, TFunction& function, TOperator op, TType* type) 490 { 491 *type = function.getReturnType(); 492 493 bool constructingMatrix = false; 494 switch(op) { 495 case EOpConstructMat2: 496 case EOpConstructMat2x3: 497 case EOpConstructMat2x4: 498 case EOpConstructMat3x2: 499 case EOpConstructMat3: 500 case EOpConstructMat3x4: 501 case EOpConstructMat4x2: 502 case EOpConstructMat4x3: 503 case EOpConstructMat4: 504 constructingMatrix = true; 505 break; 506 default: 507 break; 508 } 509 510 // 511 // Note: It's okay to have too many components available, but not okay to have unused 512 // arguments. 'full' will go to true when enough args have been seen. If we loop 513 // again, there is an extra argument, so 'overfull' will become true. 514 // 515 516 size_t size = 0; 517 bool full = false; 518 bool overFull = false; 519 bool matrixInMatrix = false; 520 bool arrayArg = false; 521 for (size_t i = 0; i < function.getParamCount(); ++i) { 522 const TParameter& param = function.getParam(i); 523 size += param.type->getObjectSize(); 524 525 if (constructingMatrix && param.type->isMatrix()) 526 matrixInMatrix = true; 527 if (full) 528 overFull = true; 529 if (op != EOpConstructStruct && !type->isArray() && size >= type->getObjectSize()) 530 full = true; 531 if (param.type->isArray()) 532 arrayArg = true; 533 } 534 535 if(type->isArray()) { 536 if(type->getArraySize() == 0) { 537 type->setArraySize(function.getParamCount()); 538 } else if(type->getArraySize() != (int)function.getParamCount()) { 539 error(line, "array constructor needs one argument per array element", "constructor"); 540 return true; 541 } 542 } 543 544 if (arrayArg && op != EOpConstructStruct) { 545 error(line, "constructing from a non-dereferenced array", "constructor"); 546 return true; 547 } 548 549 if (matrixInMatrix && !type->isArray()) { 550 if (function.getParamCount() != 1) { 551 error(line, "constructing matrix from matrix can only take one argument", "constructor"); 552 return true; 553 } 554 } 555 556 if (overFull) { 557 error(line, "too many arguments", "constructor"); 558 return true; 559 } 560 561 if (op == EOpConstructStruct && !type->isArray() && type->getStruct()->fields().size() != function.getParamCount()) { 562 error(line, "Number of constructor parameters does not match the number of structure fields", "constructor"); 563 return true; 564 } 565 566 if (!type->isMatrix() || !matrixInMatrix) { 567 if ((op != EOpConstructStruct && size != 1 && size < type->getObjectSize()) || 568 (op == EOpConstructStruct && size < type->getObjectSize())) { 569 error(line, "not enough data provided for construction", "constructor"); 570 return true; 571 } 572 } 573 574 TIntermTyped *typed = node ? node->getAsTyped() : 0; 575 if (typed == 0) { 576 error(line, "constructor argument does not have a type", "constructor"); 577 return true; 578 } 579 if (op != EOpConstructStruct && IsSampler(typed->getBasicType())) { 580 error(line, "cannot convert a sampler", "constructor"); 581 return true; 582 } 583 if (typed->getBasicType() == EbtVoid) { 584 error(line, "cannot convert a void", "constructor"); 585 return true; 586 } 587 588 return false; 589 } 590 591 // This function checks to see if a void variable has been declared and raise an error message for such a case 592 // 593 // returns true in case of an error 594 // 595 bool TParseContext::voidErrorCheck(const TSourceLoc &line, const TString& identifier, const TBasicType& type) 596 { 597 if(type == EbtVoid) { 598 error(line, "illegal use of type 'void'", identifier.c_str()); 599 return true; 600 } 601 602 return false; 603 } 604 605 // This function checks to see if the node (for the expression) contains a scalar boolean expression or not 606 // 607 // returns true in case of an error 608 // 609 bool TParseContext::boolErrorCheck(const TSourceLoc &line, const TIntermTyped* type) 610 { 611 if (type->getBasicType() != EbtBool || type->isArray() || type->isMatrix() || type->isVector()) { 612 error(line, "boolean expression expected", ""); 613 return true; 614 } 615 616 return false; 617 } 618 619 // This function checks to see if the node (for the expression) contains a scalar boolean expression or not 620 // 621 // returns true in case of an error 622 // 623 bool TParseContext::boolErrorCheck(const TSourceLoc &line, const TPublicType& pType) 624 { 625 if (pType.type != EbtBool || pType.array || (pType.primarySize > 1) || (pType.secondarySize > 1)) { 626 error(line, "boolean expression expected", ""); 627 return true; 628 } 629 630 return false; 631 } 632 633 bool TParseContext::samplerErrorCheck(const TSourceLoc &line, const TPublicType& pType, const char* reason) 634 { 635 if (pType.type == EbtStruct) { 636 if (containsSampler(*pType.userDef)) { 637 error(line, reason, getBasicString(pType.type), "(structure contains a sampler)"); 638 639 return true; 640 } 641 642 return false; 643 } else if (IsSampler(pType.type)) { 644 error(line, reason, getBasicString(pType.type)); 645 646 return true; 647 } 648 649 return false; 650 } 651 652 bool TParseContext::structQualifierErrorCheck(const TSourceLoc &line, const TPublicType& pType) 653 { 654 switch(pType.qualifier) 655 { 656 case EvqVaryingOut: 657 case EvqSmooth: 658 case EvqFlat: 659 case EvqCentroidOut: 660 case EvqVaryingIn: 661 case EvqSmoothIn: 662 case EvqFlatIn: 663 case EvqCentroidIn: 664 case EvqAttribute: 665 case EvqVertexIn: 666 case EvqFragmentOut: 667 if(pType.type == EbtStruct) 668 { 669 error(line, "cannot be used with a structure", getQualifierString(pType.qualifier)); 670 671 return true; 672 } 673 break; 674 default: 675 break; 676 } 677 678 if (pType.qualifier != EvqUniform && samplerErrorCheck(line, pType, "samplers must be uniform")) 679 return true; 680 681 // check for layout qualifier issues 682 if (pType.qualifier != EvqVertexIn && pType.qualifier != EvqFragmentOut && 683 layoutLocationErrorCheck(line, pType.layoutQualifier)) 684 { 685 return true; 686 } 687 688 return false; 689 } 690 691 // These checks are common for all declarations starting a declarator list, and declarators that follow an empty 692 // declaration. 693 // 694 bool TParseContext::singleDeclarationErrorCheck(const TPublicType &publicType, const TSourceLoc &identifierLocation) 695 { 696 switch(publicType.qualifier) 697 { 698 case EvqVaryingIn: 699 case EvqVaryingOut: 700 case EvqAttribute: 701 case EvqVertexIn: 702 case EvqFragmentOut: 703 if(publicType.type == EbtStruct) 704 { 705 error(identifierLocation, "cannot be used with a structure", 706 getQualifierString(publicType.qualifier)); 707 return true; 708 } 709 710 default: break; 711 } 712 713 if(publicType.qualifier != EvqUniform && samplerErrorCheck(identifierLocation, publicType, 714 "samplers must be uniform")) 715 { 716 return true; 717 } 718 719 // check for layout qualifier issues 720 const TLayoutQualifier layoutQualifier = publicType.layoutQualifier; 721 722 if(layoutQualifier.matrixPacking != EmpUnspecified) 723 { 724 error(identifierLocation, "layout qualifier", getMatrixPackingString(layoutQualifier.matrixPacking), 725 "only valid for interface blocks"); 726 return true; 727 } 728 729 if(layoutQualifier.blockStorage != EbsUnspecified) 730 { 731 error(identifierLocation, "layout qualifier", getBlockStorageString(layoutQualifier.blockStorage), 732 "only valid for interface blocks"); 733 return true; 734 } 735 736 if(publicType.qualifier != EvqVertexIn && publicType.qualifier != EvqFragmentOut && 737 layoutLocationErrorCheck(identifierLocation, publicType.layoutQualifier)) 738 { 739 return true; 740 } 741 742 return false; 743 } 744 745 bool TParseContext::layoutLocationErrorCheck(const TSourceLoc &location, const TLayoutQualifier &layoutQualifier) 746 { 747 if(layoutQualifier.location != -1) 748 { 749 error(location, "invalid layout qualifier:", "location", "only valid on program inputs and outputs"); 750 return true; 751 } 752 753 return false; 754 } 755 756 bool TParseContext::locationDeclaratorListCheck(const TSourceLoc& line, const TPublicType &pType) 757 { 758 if(pType.layoutQualifier.location != -1) 759 { 760 error(line, "location must only be specified for a single input or output variable", "location"); 761 return true; 762 } 763 764 return false; 765 } 766 767 bool TParseContext::parameterSamplerErrorCheck(const TSourceLoc &line, TQualifier qualifier, const TType& type) 768 { 769 if ((qualifier == EvqOut || qualifier == EvqInOut) && 770 type.getBasicType() != EbtStruct && IsSampler(type.getBasicType())) { 771 error(line, "samplers cannot be output parameters", type.getBasicString()); 772 return true; 773 } 774 775 return false; 776 } 777 778 bool TParseContext::containsSampler(TType& type) 779 { 780 if (IsSampler(type.getBasicType())) 781 return true; 782 783 if (type.getBasicType() == EbtStruct || type.isInterfaceBlock()) { 784 for(const auto &field : type.getStruct()->fields()) { 785 if (containsSampler(*(field->type()))) 786 return true; 787 } 788 } 789 790 return false; 791 } 792 793 // 794 // Do size checking for an array type's size. 795 // 796 // Returns true if there was an error. 797 // 798 bool TParseContext::arraySizeErrorCheck(const TSourceLoc &line, TIntermTyped* expr, int& size) 799 { 800 TIntermConstantUnion* constant = expr->getAsConstantUnion(); 801 802 if (expr->getQualifier() != EvqConstExpr || constant == 0 || !constant->isScalarInt()) 803 { 804 error(line, "array size must be a constant integer expression", ""); 805 size = 1; 806 return true; 807 } 808 809 if (constant->getBasicType() == EbtUInt) 810 { 811 unsigned int uintSize = constant->getUConst(0); 812 if (uintSize > static_cast<unsigned int>(std::numeric_limits<int>::max())) 813 { 814 error(line, "array size too large", ""); 815 size = 1; 816 return true; 817 } 818 819 size = static_cast<int>(uintSize); 820 } 821 else 822 { 823 size = constant->getIConst(0); 824 825 if (size < 0) 826 { 827 error(line, "array size must be non-negative", ""); 828 size = 1; 829 return true; 830 } 831 } 832 833 if(size == 0) 834 { 835 error(line, "array size must be greater than zero", ""); 836 return true; 837 } 838 839 return false; 840 } 841 842 // 843 // See if this qualifier can be an array. 844 // 845 // Returns true if there is an error. 846 // 847 bool TParseContext::arrayQualifierErrorCheck(const TSourceLoc &line, TPublicType type) 848 { 849 if ((type.qualifier == EvqAttribute) || (type.qualifier == EvqVertexIn) || (type.qualifier == EvqConstExpr && mShaderVersion < 300)) { 850 error(line, "cannot declare arrays of this qualifier", TType(type).getCompleteString().c_str()); 851 return true; 852 } 853 854 return false; 855 } 856 857 // 858 // See if this type can be an array. 859 // 860 // Returns true if there is an error. 861 // 862 bool TParseContext::arrayTypeErrorCheck(const TSourceLoc &line, TPublicType type) 863 { 864 // 865 // Can the type be an array? 866 // 867 if (type.array) { 868 error(line, "cannot declare arrays of arrays", TType(type).getCompleteString().c_str()); 869 return true; 870 } 871 872 // In ESSL1.00 shaders, structs cannot be varying (section 4.3.5). This is checked elsewhere. 873 // In ESSL3.00 shaders, struct inputs/outputs are allowed but not arrays of structs (section 4.3.4). 874 if(mShaderVersion >= 300 && type.type == EbtStruct && IsVarying(type.qualifier)) 875 { 876 error(line, "cannot declare arrays of structs of this qualifier", 877 TType(type).getCompleteString().c_str()); 878 return true; 879 } 880 881 return false; 882 } 883 884 bool TParseContext::arraySetMaxSize(TIntermSymbol *node, TType* type, int size, bool updateFlag, const TSourceLoc &line) 885 { 886 bool builtIn = false; 887 TSymbol* symbol = symbolTable.find(node->getSymbol(), mShaderVersion, &builtIn); 888 if (symbol == 0) { 889 error(line, " undeclared identifier", node->getSymbol().c_str()); 890 return true; 891 } 892 TVariable* variable = static_cast<TVariable*>(symbol); 893 894 type->setArrayInformationType(variable->getArrayInformationType()); 895 variable->updateArrayInformationType(type); 896 897 // special casing to test index value of gl_FragData. If the accessed index is >= gl_MaxDrawBuffers 898 // its an error 899 if (node->getSymbol() == "gl_FragData") { 900 TSymbol* fragData = symbolTable.find("gl_MaxDrawBuffers", mShaderVersion, &builtIn); 901 ASSERT(fragData); 902 903 int fragDataValue = static_cast<TVariable*>(fragData)->getConstPointer()[0].getIConst(); 904 if (fragDataValue <= size) { 905 error(line, "", "[", "gl_FragData can only have a max array size of up to gl_MaxDrawBuffers"); 906 return true; 907 } 908 } 909 910 // we dont want to update the maxArraySize when this flag is not set, we just want to include this 911 // node type in the chain of node types so that its updated when a higher maxArraySize comes in. 912 if (!updateFlag) 913 return false; 914 915 size++; 916 variable->getType().setMaxArraySize(size); 917 type->setMaxArraySize(size); 918 TType* tt = type; 919 920 while(tt->getArrayInformationType() != 0) { 921 tt = tt->getArrayInformationType(); 922 tt->setMaxArraySize(size); 923 } 924 925 return false; 926 } 927 928 // 929 // Enforce non-initializer type/qualifier rules. 930 // 931 // Returns true if there was an error. 932 // 933 bool TParseContext::nonInitConstErrorCheck(const TSourceLoc &line, TString& identifier, TPublicType& type, bool array) 934 { 935 if (type.qualifier == EvqConstExpr) 936 { 937 // Make the qualifier make sense. 938 type.qualifier = EvqTemporary; 939 940 if (array) 941 { 942 error(line, "arrays may not be declared constant since they cannot be initialized", identifier.c_str()); 943 } 944 else if (type.isStructureContainingArrays()) 945 { 946 error(line, "structures containing arrays may not be declared constant since they cannot be initialized", identifier.c_str()); 947 } 948 else 949 { 950 error(line, "variables with qualifier 'const' must be initialized", identifier.c_str()); 951 } 952 953 return true; 954 } 955 956 return false; 957 } 958 959 // 960 // Do semantic checking for a variable declaration that has no initializer, 961 // and update the symbol table. 962 // 963 // Returns true if there was an error. 964 // 965 bool TParseContext::nonInitErrorCheck(const TSourceLoc &line, const TString& identifier, TPublicType& type) 966 { 967 if(type.qualifier == EvqConstExpr) 968 { 969 // Make the qualifier make sense. 970 type.qualifier = EvqTemporary; 971 972 // Generate informative error messages for ESSL1. 973 // In ESSL3 arrays and structures containing arrays can be constant. 974 if(mShaderVersion < 300 && type.isStructureContainingArrays()) 975 { 976 error(line, 977 "structures containing arrays may not be declared constant since they cannot be initialized", 978 identifier.c_str()); 979 } 980 else 981 { 982 error(line, "variables with qualifier 'const' must be initialized", identifier.c_str()); 983 } 984 985 return true; 986 } 987 if(type.isUnsizedArray()) 988 { 989 error(line, "implicitly sized arrays need to be initialized", identifier.c_str()); 990 return true; 991 } 992 return false; 993 } 994 995 // Do some simple checks that are shared between all variable declarations, 996 // and update the symbol table. 997 // 998 // Returns true if declaring the variable succeeded. 999 // 1000 bool TParseContext::declareVariable(const TSourceLoc &line, const TString &identifier, const TType &type, 1001 TVariable **variable) 1002 { 1003 ASSERT((*variable) == nullptr); 1004 1005 // gl_LastFragData may be redeclared with a new precision qualifier 1006 if(type.isArray() && identifier.compare(0, 15, "gl_LastFragData") == 0) 1007 { 1008 const TVariable *maxDrawBuffers = 1009 static_cast<const TVariable *>(symbolTable.findBuiltIn("gl_MaxDrawBuffers", mShaderVersion)); 1010 if(type.getArraySize() != maxDrawBuffers->getConstPointer()->getIConst()) 1011 { 1012 error(line, "redeclaration of gl_LastFragData with size != gl_MaxDrawBuffers", identifier.c_str()); 1013 return false; 1014 } 1015 } 1016 1017 if(reservedErrorCheck(line, identifier)) 1018 return false; 1019 1020 (*variable) = new TVariable(&identifier, type); 1021 if(!symbolTable.declare(*variable)) 1022 { 1023 error(line, "redefinition", identifier.c_str()); 1024 delete (*variable); 1025 (*variable) = nullptr; 1026 return false; 1027 } 1028 1029 if(voidErrorCheck(line, identifier, type.getBasicType())) 1030 return false; 1031 1032 return true; 1033 } 1034 1035 bool TParseContext::paramErrorCheck(const TSourceLoc &line, TQualifier qualifier, TQualifier paramQualifier, TType* type) 1036 { 1037 if (qualifier != EvqConstReadOnly && qualifier != EvqTemporary) { 1038 error(line, "qualifier not allowed on function parameter", getQualifierString(qualifier)); 1039 return true; 1040 } 1041 if (qualifier == EvqConstReadOnly && paramQualifier != EvqIn) { 1042 error(line, "qualifier not allowed with ", getQualifierString(qualifier), getQualifierString(paramQualifier)); 1043 return true; 1044 } 1045 1046 if (qualifier == EvqConstReadOnly) 1047 type->setQualifier(EvqConstReadOnly); 1048 else 1049 type->setQualifier(paramQualifier); 1050 1051 return false; 1052 } 1053 1054 bool TParseContext::extensionErrorCheck(const TSourceLoc &line, const TString& extension) 1055 { 1056 const TExtensionBehavior& extBehavior = extensionBehavior(); 1057 TExtensionBehavior::const_iterator iter = extBehavior.find(extension.c_str()); 1058 if (iter == extBehavior.end()) { 1059 error(line, "extension", extension.c_str(), "is not supported"); 1060 return true; 1061 } 1062 // In GLSL ES, an extension's default behavior is "disable". 1063 if (iter->second == EBhDisable || iter->second == EBhUndefined) { 1064 error(line, "extension", extension.c_str(), "is disabled"); 1065 return true; 1066 } 1067 if (iter->second == EBhWarn) { 1068 warning(line, "extension", extension.c_str(), "is being used"); 1069 return false; 1070 } 1071 1072 return false; 1073 } 1074 1075 bool TParseContext::functionCallLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *aggregate) 1076 { 1077 for(size_t i = 0; i < fnCandidate->getParamCount(); ++i) 1078 { 1079 TQualifier qual = fnCandidate->getParam(i).type->getQualifier(); 1080 if(qual == EvqOut || qual == EvqInOut) 1081 { 1082 TIntermTyped *node = (aggregate->getSequence())[i]->getAsTyped(); 1083 if(lValueErrorCheck(node->getLine(), "assign", node)) 1084 { 1085 error(node->getLine(), 1086 "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error"); 1087 recover(); 1088 return true; 1089 } 1090 } 1091 } 1092 return false; 1093 } 1094 1095 void TParseContext::es3InvariantErrorCheck(const TQualifier qualifier, const TSourceLoc &invariantLocation) 1096 { 1097 switch(qualifier) 1098 { 1099 case EvqVaryingOut: 1100 case EvqSmoothOut: 1101 case EvqFlatOut: 1102 case EvqCentroidOut: 1103 case EvqVertexOut: 1104 case EvqFragmentOut: 1105 break; 1106 default: 1107 error(invariantLocation, "Only out variables can be invariant.", "invariant"); 1108 recover(); 1109 break; 1110 } 1111 } 1112 1113 bool TParseContext::supportsExtension(const char* extension) 1114 { 1115 const TExtensionBehavior& extbehavior = extensionBehavior(); 1116 TExtensionBehavior::const_iterator iter = extbehavior.find(extension); 1117 return (iter != extbehavior.end()); 1118 } 1119 1120 void TParseContext::handleExtensionDirective(const TSourceLoc &line, const char* extName, const char* behavior) 1121 { 1122 pp::SourceLocation loc(line.first_file, line.first_line); 1123 mDirectiveHandler.handleExtension(loc, extName, behavior); 1124 } 1125 1126 void TParseContext::handlePragmaDirective(const TSourceLoc &line, const char* name, const char* value, bool stdgl) 1127 { 1128 pp::SourceLocation loc(line.first_file, line.first_line); 1129 mDirectiveHandler.handlePragma(loc, name, value, stdgl); 1130 } 1131 1132 ///////////////////////////////////////////////////////////////////////////////// 1133 // 1134 // Non-Errors. 1135 // 1136 ///////////////////////////////////////////////////////////////////////////////// 1137 1138 const TVariable *TParseContext::getNamedVariable(const TSourceLoc &location, 1139 const TString *name, 1140 const TSymbol *symbol) 1141 { 1142 const TVariable *variable = nullptr; 1143 1144 if(!symbol) 1145 { 1146 error(location, "undeclared identifier", name->c_str()); 1147 recover(); 1148 } 1149 else if(!symbol->isVariable()) 1150 { 1151 error(location, "variable expected", name->c_str()); 1152 recover(); 1153 } 1154 else 1155 { 1156 variable = static_cast<const TVariable*>(symbol); 1157 1158 if(symbolTable.findBuiltIn(variable->getName(), mShaderVersion)) 1159 { 1160 recover(); 1161 } 1162 1163 // Reject shaders using both gl_FragData and gl_FragColor 1164 TQualifier qualifier = variable->getType().getQualifier(); 1165 if(qualifier == EvqFragData) 1166 { 1167 mUsesFragData = true; 1168 } 1169 else if(qualifier == EvqFragColor) 1170 { 1171 mUsesFragColor = true; 1172 } 1173 1174 // This validation is not quite correct - it's only an error to write to 1175 // both FragData and FragColor. For simplicity, and because users shouldn't 1176 // be rewarded for reading from undefined variables, return an error 1177 // if they are both referenced, rather than assigned. 1178 if(mUsesFragData && mUsesFragColor) 1179 { 1180 error(location, "cannot use both gl_FragData and gl_FragColor", name->c_str()); 1181 recover(); 1182 } 1183 } 1184 1185 if(!variable) 1186 { 1187 TType type(EbtFloat, EbpUndefined); 1188 TVariable *fakeVariable = new TVariable(name, type); 1189 symbolTable.declare(fakeVariable); 1190 variable = fakeVariable; 1191 } 1192 1193 return variable; 1194 } 1195 1196 // 1197 // Look up a function name in the symbol table, and make sure it is a function. 1198 // 1199 // Return the function symbol if found, otherwise 0. 1200 // 1201 const TFunction* TParseContext::findFunction(const TSourceLoc &line, TFunction* call, bool *builtIn) 1202 { 1203 // First find by unmangled name to check whether the function name has been 1204 // hidden by a variable name or struct typename. 1205 const TSymbol* symbol = symbolTable.find(call->getName(), mShaderVersion, builtIn); 1206 if (!symbol || symbol->isFunction()) { 1207 symbol = symbolTable.find(call->getMangledName(), mShaderVersion, builtIn); 1208 } 1209 1210 if (!symbol) { 1211 error(line, "no matching overloaded function found", call->getName().c_str()); 1212 return nullptr; 1213 } 1214 1215 if (!symbol->isFunction()) { 1216 error(line, "function name expected", call->getName().c_str()); 1217 return nullptr; 1218 } 1219 1220 return static_cast<const TFunction*>(symbol); 1221 } 1222 1223 // 1224 // Initializers show up in several places in the grammar. Have one set of 1225 // code to handle them here. 1226 // 1227 bool TParseContext::executeInitializer(const TSourceLoc& line, const TString& identifier, const TPublicType& pType, 1228 TIntermTyped *initializer, TIntermNode **intermNode) 1229 { 1230 ASSERT(intermNode != nullptr); 1231 TType type = TType(pType); 1232 1233 if(type.isUnsizedArray()) 1234 { 1235 // We have not checked yet whether the initializer actually is an array or not. 1236 if(initializer->isArray()) 1237 { 1238 type.setArraySize(initializer->getArraySize()); 1239 } 1240 else 1241 { 1242 // Having a non-array initializer for an unsized array will result in an error later, 1243 // so we don't generate an error message here. 1244 type.setArraySize(1u); 1245 } 1246 } 1247 1248 TVariable *variable = nullptr; 1249 if(!declareVariable(line, identifier, type, &variable)) 1250 { 1251 return true; 1252 } 1253 1254 if(symbolTable.atGlobalLevel() && initializer->getQualifier() != EvqConstExpr) 1255 { 1256 error(line, "global variable initializers must be constant expressions", "="); 1257 return true; 1258 } 1259 1260 // 1261 // identifier must be of type constant, a global, or a temporary 1262 // 1263 TQualifier qualifier = type.getQualifier(); 1264 if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal) && (qualifier != EvqConstExpr)) { 1265 error(line, " cannot initialize this type of qualifier ", variable->getType().getQualifierString()); 1266 return true; 1267 } 1268 // 1269 // test for and propagate constant 1270 // 1271 1272 if (qualifier == EvqConstExpr) { 1273 if (qualifier != initializer->getQualifier()) { 1274 std::stringstream extraInfoStream; 1275 extraInfoStream << "'" << variable->getType().getCompleteString() << "'"; 1276 std::string extraInfo = extraInfoStream.str(); 1277 error(line, " assigning non-constant to", "=", extraInfo.c_str()); 1278 variable->getType().setQualifier(EvqTemporary); 1279 return true; 1280 } 1281 1282 if (type != initializer->getType()) { 1283 error(line, " non-matching types for const initializer ", 1284 variable->getType().getQualifierString()); 1285 variable->getType().setQualifier(EvqTemporary); 1286 return true; 1287 } 1288 1289 if (initializer->getAsConstantUnion()) { 1290 variable->shareConstPointer(initializer->getAsConstantUnion()->getUnionArrayPointer()); 1291 } else if (initializer->getAsSymbolNode()) { 1292 const TSymbol* symbol = symbolTable.find(initializer->getAsSymbolNode()->getSymbol(), 0); 1293 const TVariable* tVar = static_cast<const TVariable*>(symbol); 1294 1295 ConstantUnion* constArray = tVar->getConstPointer(); 1296 variable->shareConstPointer(constArray); 1297 } 1298 } 1299 1300 // Constants which aren't indexable arrays get propagated by value 1301 // and thus don't need to initialize the symbol. 1302 if (variable->isConstant() && !(type.isArray() && type.getArraySize() > 1)) 1303 { 1304 *intermNode = nullptr; 1305 } 1306 else 1307 { 1308 TIntermSymbol* intermSymbol = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), line); 1309 *intermNode = createAssign(EOpInitialize, intermSymbol, initializer, line); 1310 if(*intermNode == nullptr) { 1311 assignError(line, "=", intermSymbol->getCompleteString(), initializer->getCompleteString()); 1312 return true; 1313 } 1314 } 1315 1316 return false; 1317 } 1318 1319 TPublicType TParseContext::addFullySpecifiedType(TQualifier qualifier, bool invariant, TLayoutQualifier layoutQualifier, const TPublicType &typeSpecifier) 1320 { 1321 TPublicType returnType = typeSpecifier; 1322 returnType.qualifier = qualifier; 1323 returnType.invariant = invariant; 1324 returnType.layoutQualifier = layoutQualifier; 1325 1326 if(mShaderVersion < 300) 1327 { 1328 if(typeSpecifier.array) 1329 { 1330 error(typeSpecifier.line, "not supported", "first-class array"); 1331 returnType.clearArrayness(); 1332 } 1333 1334 if(qualifier == EvqAttribute && (typeSpecifier.type == EbtBool || typeSpecifier.type == EbtInt)) 1335 { 1336 error(typeSpecifier.line, "cannot be bool or int", getQualifierString(qualifier)); 1337 recover(); 1338 } 1339 1340 if((qualifier == EvqVaryingIn || qualifier == EvqVaryingOut) && 1341 (typeSpecifier.type == EbtBool || typeSpecifier.type == EbtInt)) 1342 { 1343 error(typeSpecifier.line, "cannot be bool or int", getQualifierString(qualifier)); 1344 recover(); 1345 } 1346 } 1347 else 1348 { 1349 if(!returnType.layoutQualifier.isEmpty()) 1350 { 1351 globalErrorCheck(typeSpecifier.line, symbolTable.atGlobalLevel(), "layout"); 1352 } 1353 1354 if(IsVarying(returnType.qualifier) || returnType.qualifier == EvqVertexIn || returnType.qualifier == EvqFragmentOut) 1355 { 1356 checkInputOutputTypeIsValidES3(returnType.qualifier, typeSpecifier, typeSpecifier.line); 1357 } 1358 } 1359 1360 return returnType; 1361 } 1362 1363 void TParseContext::checkInputOutputTypeIsValidES3(const TQualifier qualifier, 1364 const TPublicType &type, 1365 const TSourceLoc &qualifierLocation) 1366 { 1367 // An input/output variable can never be bool or a sampler. Samplers are checked elsewhere. 1368 if(type.type == EbtBool) 1369 { 1370 error(qualifierLocation, "cannot be bool", getQualifierString(qualifier)); 1371 } 1372 1373 // Specific restrictions apply for vertex shader inputs and fragment shader outputs. 1374 switch(qualifier) 1375 { 1376 case EvqVertexIn: 1377 // ESSL 3.00 section 4.3.4 1378 if(type.array) 1379 { 1380 error(qualifierLocation, "cannot be array", getQualifierString(qualifier)); 1381 } 1382 // Vertex inputs with a struct type are disallowed in singleDeclarationErrorCheck 1383 return; 1384 case EvqFragmentOut: 1385 // ESSL 3.00 section 4.3.6 1386 if(type.isMatrix()) 1387 { 1388 error(qualifierLocation, "cannot be matrix", getQualifierString(qualifier)); 1389 } 1390 // Fragment outputs with a struct type are disallowed in singleDeclarationErrorCheck 1391 return; 1392 default: 1393 break; 1394 } 1395 1396 // Vertex shader outputs / fragment shader inputs have a different, slightly more lenient set of 1397 // restrictions. 1398 bool typeContainsIntegers = (type.type == EbtInt || type.type == EbtUInt || 1399 type.isStructureContainingType(EbtInt) || 1400 type.isStructureContainingType(EbtUInt)); 1401 if(typeContainsIntegers && qualifier != EvqFlatIn && qualifier != EvqFlatOut) 1402 { 1403 error(qualifierLocation, "must use 'flat' interpolation here", getQualifierString(qualifier)); 1404 } 1405 1406 if(type.type == EbtStruct) 1407 { 1408 // ESSL 3.00 sections 4.3.4 and 4.3.6. 1409 // These restrictions are only implied by the ESSL 3.00 spec, but 1410 // the ESSL 3.10 spec lists these restrictions explicitly. 1411 if(type.array) 1412 { 1413 error(qualifierLocation, "cannot be an array of structures", getQualifierString(qualifier)); 1414 } 1415 if(type.isStructureContainingArrays()) 1416 { 1417 error(qualifierLocation, "cannot be a structure containing an array", getQualifierString(qualifier)); 1418 } 1419 if(type.isStructureContainingType(EbtStruct)) 1420 { 1421 error(qualifierLocation, "cannot be a structure containing a structure", getQualifierString(qualifier)); 1422 } 1423 if(type.isStructureContainingType(EbtBool)) 1424 { 1425 error(qualifierLocation, "cannot be a structure containing a bool", getQualifierString(qualifier)); 1426 } 1427 } 1428 } 1429 1430 TIntermAggregate *TParseContext::parseSingleDeclaration(TPublicType &publicType, 1431 const TSourceLoc &identifierOrTypeLocation, 1432 const TString &identifier) 1433 { 1434 TIntermSymbol *symbol = intermediate.addSymbol(0, identifier, TType(publicType), identifierOrTypeLocation); 1435 1436 bool emptyDeclaration = (identifier == ""); 1437 1438 mDeferredSingleDeclarationErrorCheck = emptyDeclaration; 1439 1440 if(emptyDeclaration) 1441 { 1442 if(publicType.isUnsizedArray()) 1443 { 1444 // ESSL3 spec section 4.1.9: Array declaration which leaves the size unspecified is an error. 1445 // It is assumed that this applies to empty declarations as well. 1446 error(identifierOrTypeLocation, "empty array declaration needs to specify a size", identifier.c_str()); 1447 } 1448 } 1449 else 1450 { 1451 if(singleDeclarationErrorCheck(publicType, identifierOrTypeLocation)) 1452 recover(); 1453 1454 if(nonInitErrorCheck(identifierOrTypeLocation, identifier, publicType)) 1455 recover(); 1456 1457 TVariable *variable = nullptr; 1458 if(!declareVariable(identifierOrTypeLocation, identifier, TType(publicType), &variable)) 1459 recover(); 1460 1461 if(variable && symbol) 1462 symbol->setId(variable->getUniqueId()); 1463 } 1464 1465 return intermediate.makeAggregate(symbol, identifierOrTypeLocation); 1466 } 1467 1468 TIntermAggregate *TParseContext::parseSingleArrayDeclaration(TPublicType &publicType, 1469 const TSourceLoc &identifierLocation, 1470 const TString &identifier, 1471 const TSourceLoc &indexLocation, 1472 TIntermTyped *indexExpression) 1473 { 1474 mDeferredSingleDeclarationErrorCheck = false; 1475 1476 if(singleDeclarationErrorCheck(publicType, identifierLocation)) 1477 recover(); 1478 1479 if(nonInitErrorCheck(identifierLocation, identifier, publicType)) 1480 recover(); 1481 1482 if(arrayTypeErrorCheck(indexLocation, publicType) || arrayQualifierErrorCheck(indexLocation, publicType)) 1483 { 1484 recover(); 1485 } 1486 1487 TType arrayType(publicType); 1488 1489 int size = 0; 1490 if(arraySizeErrorCheck(identifierLocation, indexExpression, size)) 1491 { 1492 recover(); 1493 } 1494 // Make the type an array even if size check failed. 1495 // This ensures useless error messages regarding the variable's non-arrayness won't follow. 1496 arrayType.setArraySize(size); 1497 1498 TVariable *variable = nullptr; 1499 if(!declareVariable(identifierLocation, identifier, arrayType, &variable)) 1500 recover(); 1501 1502 TIntermSymbol *symbol = intermediate.addSymbol(0, identifier, arrayType, identifierLocation); 1503 if(variable && symbol) 1504 symbol->setId(variable->getUniqueId()); 1505 1506 return intermediate.makeAggregate(symbol, identifierLocation); 1507 } 1508 1509 TIntermAggregate *TParseContext::parseSingleInitDeclaration(const TPublicType &publicType, 1510 const TSourceLoc &identifierLocation, 1511 const TString &identifier, 1512 const TSourceLoc &initLocation, 1513 TIntermTyped *initializer) 1514 { 1515 mDeferredSingleDeclarationErrorCheck = false; 1516 1517 if(singleDeclarationErrorCheck(publicType, identifierLocation)) 1518 recover(); 1519 1520 TIntermNode *intermNode = nullptr; 1521 if(!executeInitializer(identifierLocation, identifier, publicType, initializer, &intermNode)) 1522 { 1523 // 1524 // Build intermediate representation 1525 // 1526 return intermNode ? intermediate.makeAggregate(intermNode, initLocation) : nullptr; 1527 } 1528 else 1529 { 1530 recover(); 1531 return nullptr; 1532 } 1533 } 1534 1535 TIntermAggregate *TParseContext::parseSingleArrayInitDeclaration(TPublicType &publicType, 1536 const TSourceLoc &identifierLocation, 1537 const TString &identifier, 1538 const TSourceLoc &indexLocation, 1539 TIntermTyped *indexExpression, 1540 const TSourceLoc &initLocation, 1541 TIntermTyped *initializer) 1542 { 1543 mDeferredSingleDeclarationErrorCheck = false; 1544 1545 if(singleDeclarationErrorCheck(publicType, identifierLocation)) 1546 recover(); 1547 1548 if(arrayTypeErrorCheck(indexLocation, publicType) || arrayQualifierErrorCheck(indexLocation, publicType)) 1549 { 1550 recover(); 1551 } 1552 1553 TPublicType arrayType(publicType); 1554 1555 int size = 0; 1556 // If indexExpression is nullptr, then the array will eventually get its size implicitly from the initializer. 1557 if(indexExpression != nullptr && arraySizeErrorCheck(identifierLocation, indexExpression, size)) 1558 { 1559 recover(); 1560 } 1561 // Make the type an array even if size check failed. 1562 // This ensures useless error messages regarding the variable's non-arrayness won't follow. 1563 arrayType.setArray(true, size); 1564 1565 // initNode will correspond to the whole of "type b[n] = initializer". 1566 TIntermNode *initNode = nullptr; 1567 if(!executeInitializer(identifierLocation, identifier, arrayType, initializer, &initNode)) 1568 { 1569 return initNode ? intermediate.makeAggregate(initNode, initLocation) : nullptr; 1570 } 1571 else 1572 { 1573 recover(); 1574 return nullptr; 1575 } 1576 } 1577 1578 TIntermAggregate *TParseContext::parseInvariantDeclaration(const TSourceLoc &invariantLoc, 1579 const TSourceLoc &identifierLoc, 1580 const TString *identifier, 1581 const TSymbol *symbol) 1582 { 1583 // invariant declaration 1584 if(globalErrorCheck(invariantLoc, symbolTable.atGlobalLevel(), "invariant varying")) 1585 { 1586 recover(); 1587 } 1588 1589 if(!symbol) 1590 { 1591 error(identifierLoc, "undeclared identifier declared as invariant", identifier->c_str()); 1592 recover(); 1593 return nullptr; 1594 } 1595 else 1596 { 1597 const TString kGlFrontFacing("gl_FrontFacing"); 1598 if(*identifier == kGlFrontFacing) 1599 { 1600 error(identifierLoc, "identifier should not be declared as invariant", identifier->c_str()); 1601 recover(); 1602 return nullptr; 1603 } 1604 symbolTable.addInvariantVarying(std::string(identifier->c_str())); 1605 const TVariable *variable = getNamedVariable(identifierLoc, identifier, symbol); 1606 ASSERT(variable); 1607 const TType &type = variable->getType(); 1608 TIntermSymbol *intermSymbol = intermediate.addSymbol(variable->getUniqueId(), 1609 *identifier, type, identifierLoc); 1610 1611 TIntermAggregate *aggregate = intermediate.makeAggregate(intermSymbol, identifierLoc); 1612 aggregate->setOp(EOpInvariantDeclaration); 1613 return aggregate; 1614 } 1615 } 1616 1617 TIntermAggregate *TParseContext::parseDeclarator(TPublicType &publicType, TIntermAggregate *aggregateDeclaration, 1618 const TSourceLoc &identifierLocation, const TString &identifier) 1619 { 1620 // If the declaration starting this declarator list was empty (example: int,), some checks were not performed. 1621 if(mDeferredSingleDeclarationErrorCheck) 1622 { 1623 if(singleDeclarationErrorCheck(publicType, identifierLocation)) 1624 recover(); 1625 mDeferredSingleDeclarationErrorCheck = false; 1626 } 1627 1628 if(locationDeclaratorListCheck(identifierLocation, publicType)) 1629 recover(); 1630 1631 if(nonInitErrorCheck(identifierLocation, identifier, publicType)) 1632 recover(); 1633 1634 TVariable *variable = nullptr; 1635 if(!declareVariable(identifierLocation, identifier, TType(publicType), &variable)) 1636 recover(); 1637 1638 TIntermSymbol *symbol = intermediate.addSymbol(0, identifier, TType(publicType), identifierLocation); 1639 if(variable && symbol) 1640 symbol->setId(variable->getUniqueId()); 1641 1642 return intermediate.growAggregate(aggregateDeclaration, symbol, identifierLocation); 1643 } 1644 1645 TIntermAggregate *TParseContext::parseArrayDeclarator(TPublicType &publicType, TIntermAggregate *aggregateDeclaration, 1646 const TSourceLoc &identifierLocation, const TString &identifier, 1647 const TSourceLoc &arrayLocation, TIntermTyped *indexExpression) 1648 { 1649 // If the declaration starting this declarator list was empty (example: int,), some checks were not performed. 1650 if(mDeferredSingleDeclarationErrorCheck) 1651 { 1652 if(singleDeclarationErrorCheck(publicType, identifierLocation)) 1653 recover(); 1654 mDeferredSingleDeclarationErrorCheck = false; 1655 } 1656 1657 if(locationDeclaratorListCheck(identifierLocation, publicType)) 1658 recover(); 1659 1660 if(nonInitErrorCheck(identifierLocation, identifier, publicType)) 1661 recover(); 1662 1663 if(arrayTypeErrorCheck(arrayLocation, publicType) || arrayQualifierErrorCheck(arrayLocation, publicType)) 1664 { 1665 recover(); 1666 } 1667 else 1668 { 1669 TType arrayType = TType(publicType); 1670 int size = 0; 1671 if(arraySizeErrorCheck(arrayLocation, indexExpression, size)) 1672 { 1673 recover(); 1674 } 1675 arrayType.setArraySize(size); 1676 1677 TVariable *variable = nullptr; 1678 if(!declareVariable(identifierLocation, identifier, arrayType, &variable)) 1679 recover(); 1680 1681 TIntermSymbol *symbol = intermediate.addSymbol(0, identifier, arrayType, identifierLocation); 1682 if(variable && symbol) 1683 symbol->setId(variable->getUniqueId()); 1684 1685 return intermediate.growAggregate(aggregateDeclaration, symbol, identifierLocation); 1686 } 1687 1688 return nullptr; 1689 } 1690 1691 TIntermAggregate *TParseContext::parseInitDeclarator(const TPublicType &publicType, TIntermAggregate *aggregateDeclaration, 1692 const TSourceLoc &identifierLocation, const TString &identifier, 1693 const TSourceLoc &initLocation, TIntermTyped *initializer) 1694 { 1695 // If the declaration starting this declarator list was empty (example: int,), some checks were not performed. 1696 if(mDeferredSingleDeclarationErrorCheck) 1697 { 1698 if(singleDeclarationErrorCheck(publicType, identifierLocation)) 1699 recover(); 1700 mDeferredSingleDeclarationErrorCheck = false; 1701 } 1702 1703 if(locationDeclaratorListCheck(identifierLocation, publicType)) 1704 recover(); 1705 1706 TIntermNode *intermNode = nullptr; 1707 if(!executeInitializer(identifierLocation, identifier, publicType, initializer, &intermNode)) 1708 { 1709 // 1710 // build the intermediate representation 1711 // 1712 if(intermNode) 1713 { 1714 return intermediate.growAggregate(aggregateDeclaration, intermNode, initLocation); 1715 } 1716 else 1717 { 1718 return aggregateDeclaration; 1719 } 1720 } 1721 else 1722 { 1723 recover(); 1724 return nullptr; 1725 } 1726 } 1727 1728 TIntermAggregate *TParseContext::parseArrayInitDeclarator(const TPublicType &publicType, 1729 TIntermAggregate *aggregateDeclaration, 1730 const TSourceLoc &identifierLocation, 1731 const TString &identifier, 1732 const TSourceLoc &indexLocation, 1733 TIntermTyped *indexExpression, 1734 const TSourceLoc &initLocation, TIntermTyped *initializer) 1735 { 1736 // If the declaration starting this declarator list was empty (example: int,), some checks were not performed. 1737 if(mDeferredSingleDeclarationErrorCheck) 1738 { 1739 if(singleDeclarationErrorCheck(publicType, identifierLocation)) 1740 recover(); 1741 mDeferredSingleDeclarationErrorCheck = false; 1742 } 1743 1744 if(locationDeclaratorListCheck(identifierLocation, publicType)) 1745 recover(); 1746 1747 if(arrayTypeErrorCheck(indexLocation, publicType) || arrayQualifierErrorCheck(indexLocation, publicType)) 1748 { 1749 recover(); 1750 } 1751 1752 TPublicType arrayType(publicType); 1753 1754 int size = 0; 1755 // If indexExpression is nullptr, then the array will eventually get its size implicitly from the initializer. 1756 if(indexExpression != nullptr && arraySizeErrorCheck(identifierLocation, indexExpression, size)) 1757 { 1758 recover(); 1759 } 1760 // Make the type an array even if size check failed. 1761 // This ensures useless error messages regarding the variable's non-arrayness won't follow. 1762 arrayType.setArray(true, size); 1763 1764 // initNode will correspond to the whole of "b[n] = initializer". 1765 TIntermNode *initNode = nullptr; 1766 if(!executeInitializer(identifierLocation, identifier, arrayType, initializer, &initNode)) 1767 { 1768 if(initNode) 1769 { 1770 return intermediate.growAggregate(aggregateDeclaration, initNode, initLocation); 1771 } 1772 else 1773 { 1774 return aggregateDeclaration; 1775 } 1776 } 1777 else 1778 { 1779 recover(); 1780 return nullptr; 1781 } 1782 } 1783 1784 void TParseContext::parseGlobalLayoutQualifier(const TPublicType &typeQualifier) 1785 { 1786 if(mShaderVersion < 300) 1787 { 1788 error(typeQualifier.line, "layout qualifiers supported in GLSL ES 3.00 only", "layout"); 1789 recover(); 1790 return; 1791 } 1792 1793 if(typeQualifier.qualifier != EvqUniform) 1794 { 1795 error(typeQualifier.line, "invalid qualifier:", getQualifierString(typeQualifier.qualifier), "global layout must be uniform"); 1796 recover(); 1797 return; 1798 } 1799 1800 const TLayoutQualifier layoutQualifier = typeQualifier.layoutQualifier; 1801 ASSERT(!layoutQualifier.isEmpty()); 1802 1803 if(layoutLocationErrorCheck(typeQualifier.line, typeQualifier.layoutQualifier)) 1804 { 1805 recover(); 1806 return; 1807 } 1808 1809 if(layoutQualifier.matrixPacking != EmpUnspecified) 1810 { 1811 mDefaultMatrixPacking = layoutQualifier.matrixPacking; 1812 } 1813 1814 if(layoutQualifier.blockStorage != EbsUnspecified) 1815 { 1816 mDefaultBlockStorage = layoutQualifier.blockStorage; 1817 } 1818 } 1819 1820 TIntermAggregate *TParseContext::addFunctionPrototypeDeclaration(const TFunction &function, const TSourceLoc &location) 1821 { 1822 // Note: symbolTableFunction could be the same as function if this is the first declaration. 1823 // Either way the instance in the symbol table is used to track whether the function is declared 1824 // multiple times. 1825 TFunction *symbolTableFunction = 1826 static_cast<TFunction *>(symbolTable.find(function.getMangledName(), getShaderVersion())); 1827 if(symbolTableFunction->hasPrototypeDeclaration() && mShaderVersion == 100) 1828 { 1829 // ESSL 1.00.17 section 4.2.7. 1830 // Doesn't apply to ESSL 3.00.4: see section 4.2.3. 1831 error(location, "duplicate function prototype declarations are not allowed", "function"); 1832 recover(); 1833 } 1834 symbolTableFunction->setHasPrototypeDeclaration(); 1835 1836 TIntermAggregate *prototype = new TIntermAggregate; 1837 prototype->setType(function.getReturnType()); 1838 prototype->setName(function.getMangledName()); 1839 1840 for(size_t i = 0; i < function.getParamCount(); i++) 1841 { 1842 const TParameter ¶m = function.getParam(i); 1843 if(param.name != 0) 1844 { 1845 TVariable variable(param.name, *param.type); 1846 1847 TIntermSymbol *paramSymbol = intermediate.addSymbol( 1848 variable.getUniqueId(), variable.getName(), variable.getType(), location); 1849 prototype = intermediate.growAggregate(prototype, paramSymbol, location); 1850 } 1851 else 1852 { 1853 TIntermSymbol *paramSymbol = intermediate.addSymbol(0, "", *param.type, location); 1854 prototype = intermediate.growAggregate(prototype, paramSymbol, location); 1855 } 1856 } 1857 1858 prototype->setOp(EOpPrototype); 1859 1860 symbolTable.pop(); 1861 1862 if(!symbolTable.atGlobalLevel()) 1863 { 1864 // ESSL 3.00.4 section 4.2.4. 1865 error(location, "local function prototype declarations are not allowed", "function"); 1866 recover(); 1867 } 1868 1869 return prototype; 1870 } 1871 1872 TIntermAggregate *TParseContext::addFunctionDefinition(const TFunction &function, TIntermAggregate *functionPrototype, TIntermAggregate *functionBody, const TSourceLoc &location) 1873 { 1874 //?? Check that all paths return a value if return type != void ? 1875 // May be best done as post process phase on intermediate code 1876 if(mCurrentFunctionType->getBasicType() != EbtVoid && !mFunctionReturnsValue) 1877 { 1878 error(location, "function does not return a value:", "", function.getName().c_str()); 1879 recover(); 1880 } 1881 1882 TIntermAggregate *aggregate = intermediate.growAggregate(functionPrototype, functionBody, location); 1883 intermediate.setAggregateOperator(aggregate, EOpFunction, location); 1884 aggregate->setName(function.getMangledName().c_str()); 1885 aggregate->setType(function.getReturnType()); 1886 1887 // store the pragma information for debug and optimize and other vendor specific 1888 // information. This information can be queried from the parse tree 1889 aggregate->setOptimize(pragma().optimize); 1890 aggregate->setDebug(pragma().debug); 1891 1892 if(functionBody && functionBody->getAsAggregate()) 1893 aggregate->setEndLine(functionBody->getAsAggregate()->getEndLine()); 1894 1895 symbolTable.pop(); 1896 return aggregate; 1897 } 1898 1899 void TParseContext::parseFunctionPrototype(const TSourceLoc &location, TFunction *function, TIntermAggregate **aggregateOut) 1900 { 1901 const TSymbol *builtIn = symbolTable.findBuiltIn(function->getMangledName(), getShaderVersion()); 1902 1903 if(builtIn) 1904 { 1905 error(location, "built-in functions cannot be redefined", function->getName().c_str()); 1906 recover(); 1907 } 1908 1909 TFunction *prevDec = static_cast<TFunction *>(symbolTable.find(function->getMangledName(), getShaderVersion())); 1910 // 1911 // Note: 'prevDec' could be 'function' if this is the first time we've seen function 1912 // as it would have just been put in the symbol table. Otherwise, we're looking up 1913 // an earlier occurance. 1914 // 1915 if(prevDec->isDefined()) 1916 { 1917 // Then this function already has a body. 1918 error(location, "function already has a body", function->getName().c_str()); 1919 recover(); 1920 } 1921 prevDec->setDefined(); 1922 // 1923 // Overload the unique ID of the definition to be the same unique ID as the declaration. 1924 // Eventually we will probably want to have only a single definition and just swap the 1925 // arguments to be the definition's arguments. 1926 // 1927 function->setUniqueId(prevDec->getUniqueId()); 1928 1929 // Raise error message if main function takes any parameters or return anything other than void 1930 if(function->getName() == "main") 1931 { 1932 if(function->getParamCount() > 0) 1933 { 1934 error(location, "function cannot take any parameter(s)", function->getName().c_str()); 1935 recover(); 1936 } 1937 if(function->getReturnType().getBasicType() != EbtVoid) 1938 { 1939 error(location, "", function->getReturnType().getBasicString(), "main function cannot return a value"); 1940 recover(); 1941 } 1942 } 1943 1944 // 1945 // Remember the return type for later checking for RETURN statements. 1946 // 1947 mCurrentFunctionType = &(prevDec->getReturnType()); 1948 mFunctionReturnsValue = false; 1949 1950 // 1951 // Insert parameters into the symbol table. 1952 // If the parameter has no name, it's not an error, just don't insert it 1953 // (could be used for unused args). 1954 // 1955 // Also, accumulate the list of parameters into the HIL, so lower level code 1956 // knows where to find parameters. 1957 // 1958 TIntermAggregate *paramNodes = new TIntermAggregate; 1959 for(size_t i = 0; i < function->getParamCount(); i++) 1960 { 1961 const TParameter ¶m = function->getParam(i); 1962 if(param.name != 0) 1963 { 1964 TVariable *variable = new TVariable(param.name, *param.type); 1965 // 1966 // Insert the parameters with name in the symbol table. 1967 // 1968 if(!symbolTable.declare(variable)) 1969 { 1970 error(location, "redefinition", variable->getName().c_str()); 1971 recover(); 1972 paramNodes = intermediate.growAggregate( 1973 paramNodes, intermediate.addSymbol(0, "", *param.type, location), location); 1974 continue; 1975 } 1976 1977 // 1978 // Add the parameter to the HIL 1979 // 1980 TIntermSymbol *symbol = intermediate.addSymbol( 1981 variable->getUniqueId(), variable->getName(), variable->getType(), location); 1982 1983 paramNodes = intermediate.growAggregate(paramNodes, symbol, location); 1984 } 1985 else 1986 { 1987 paramNodes = intermediate.growAggregate( 1988 paramNodes, intermediate.addSymbol(0, "", *param.type, location), location); 1989 } 1990 } 1991 intermediate.setAggregateOperator(paramNodes, EOpParameters, location); 1992 *aggregateOut = paramNodes; 1993 setLoopNestingLevel(0); 1994 } 1995 1996 TFunction *TParseContext::parseFunctionDeclarator(const TSourceLoc &location, TFunction *function) 1997 { 1998 // 1999 // We don't know at this point whether this is a function definition or a prototype. 2000 // The definition production code will check for redefinitions. 2001 // In the case of ESSL 1.00 the prototype production code will also check for redeclarations. 2002 // 2003 // Return types and parameter qualifiers must match in all redeclarations, so those are checked 2004 // here. 2005 // 2006 TFunction *prevDec = static_cast<TFunction *>(symbolTable.find(function->getMangledName(), getShaderVersion())); 2007 if(getShaderVersion() >= 300 && symbolTable.hasUnmangledBuiltIn(function->getName().c_str())) 2008 { 2009 // With ESSL 3.00, names of built-in functions cannot be redeclared as functions. 2010 // Therefore overloading or redefining builtin functions is an error. 2011 error(location, "Name of a built-in function cannot be redeclared as function", function->getName().c_str()); 2012 } 2013 else if(prevDec) 2014 { 2015 if(prevDec->getReturnType() != function->getReturnType()) 2016 { 2017 error(location, "overloaded functions must have the same return type", 2018 function->getReturnType().getBasicString()); 2019 recover(); 2020 } 2021 for(size_t i = 0; i < prevDec->getParamCount(); ++i) 2022 { 2023 if(prevDec->getParam(i).type->getQualifier() != function->getParam(i).type->getQualifier()) 2024 { 2025 error(location, "overloaded functions must have the same parameter qualifiers", 2026 function->getParam(i).type->getQualifierString()); 2027 recover(); 2028 } 2029 } 2030 } 2031 2032 // 2033 // Check for previously declared variables using the same name. 2034 // 2035 TSymbol *prevSym = symbolTable.find(function->getName(), getShaderVersion()); 2036 if(prevSym) 2037 { 2038 if(!prevSym->isFunction()) 2039 { 2040 error(location, "redefinition", function->getName().c_str(), "function"); 2041 recover(); 2042 } 2043 } 2044 else 2045 { 2046 // Insert the unmangled name to detect potential future redefinition as a variable. 2047 TFunction *unmangledFunction = new TFunction(NewPoolTString(function->getName().c_str()), function->getReturnType()); 2048 symbolTable.getOuterLevel()->insertUnmangled(unmangledFunction); 2049 } 2050 2051 // We're at the inner scope level of the function's arguments and body statement. 2052 // Add the function prototype to the surrounding scope instead. 2053 symbolTable.getOuterLevel()->insert(function); 2054 2055 // 2056 // If this is a redeclaration, it could also be a definition, in which case, we want to use the 2057 // variable names from this one, and not the one that's 2058 // being redeclared. So, pass back up this declaration, not the one in the symbol table. 2059 // 2060 return function; 2061 } 2062 2063 TFunction *TParseContext::addConstructorFunc(const TPublicType &publicTypeIn) 2064 { 2065 TPublicType publicType = publicTypeIn; 2066 TOperator op = EOpNull; 2067 if(publicType.userDef) 2068 { 2069 op = EOpConstructStruct; 2070 } 2071 else 2072 { 2073 op = TypeToConstructorOperator(TType(publicType)); 2074 if(op == EOpNull) 2075 { 2076 error(publicType.line, "cannot construct this type", getBasicString(publicType.type)); 2077 recover(); 2078 publicType.type = EbtFloat; 2079 op = EOpConstructFloat; 2080 } 2081 } 2082 2083 TString tempString; 2084 TType type(publicType); 2085 return new TFunction(&tempString, type, op); 2086 } 2087 2088 // This function is used to test for the correctness of the parameters passed to various constructor functions 2089 // and also convert them to the right datatype if it is allowed and required. 2090 // 2091 // Returns 0 for an error or the constructed node (aggregate or typed) for no error. 2092 // 2093 TIntermTyped* TParseContext::addConstructor(TIntermNode* arguments, const TType* type, TOperator op, TFunction* fnCall, const TSourceLoc &line) 2094 { 2095 TIntermAggregate *aggregateArguments = arguments->getAsAggregate(); 2096 2097 if(!aggregateArguments) 2098 { 2099 aggregateArguments = new TIntermAggregate; 2100 aggregateArguments->getSequence().push_back(arguments); 2101 } 2102 2103 if(type->isArray()) 2104 { 2105 // GLSL ES 3.00 section 5.4.4: Each argument must be the same type as the element type of 2106 // the array. 2107 for(TIntermNode *&argNode : aggregateArguments->getSequence()) 2108 { 2109 const TType &argType = argNode->getAsTyped()->getType(); 2110 // It has already been checked that the argument is not an array. 2111 ASSERT(!argType.isArray()); 2112 if(!argType.sameElementType(*type)) 2113 { 2114 error(line, "Array constructor argument has an incorrect type", "Error"); 2115 return nullptr; 2116 } 2117 } 2118 } 2119 else if(op == EOpConstructStruct) 2120 { 2121 const TFieldList &fields = type->getStruct()->fields(); 2122 TIntermSequence &args = aggregateArguments->getSequence(); 2123 2124 for(size_t i = 0; i < fields.size(); i++) 2125 { 2126 if(args[i]->getAsTyped()->getType() != *fields[i]->type()) 2127 { 2128 error(line, "Structure constructor arguments do not match structure fields", "Error"); 2129 recover(); 2130 2131 return nullptr; 2132 } 2133 } 2134 } 2135 2136 // Turn the argument list itself into a constructor 2137 TIntermAggregate *constructor = intermediate.setAggregateOperator(aggregateArguments, op, line); 2138 TIntermTyped *constConstructor = foldConstConstructor(constructor, *type); 2139 if(constConstructor) 2140 { 2141 return constConstructor; 2142 } 2143 2144 return constructor; 2145 } 2146 2147 TIntermTyped* TParseContext::foldConstConstructor(TIntermAggregate* aggrNode, const TType& type) 2148 { 2149 aggrNode->setType(type); 2150 if (aggrNode->isConstantFoldable()) { 2151 bool returnVal = false; 2152 ConstantUnion* unionArray = new ConstantUnion[type.getObjectSize()]; 2153 if (aggrNode->getSequence().size() == 1) { 2154 returnVal = intermediate.parseConstTree(aggrNode->getLine(), aggrNode, unionArray, aggrNode->getOp(), type, true); 2155 } 2156 else { 2157 returnVal = intermediate.parseConstTree(aggrNode->getLine(), aggrNode, unionArray, aggrNode->getOp(), type); 2158 } 2159 if (returnVal) 2160 return nullptr; 2161 2162 return intermediate.addConstantUnion(unionArray, type, aggrNode->getLine()); 2163 } 2164 2165 return nullptr; 2166 } 2167 2168 // 2169 // This function returns the tree representation for the vector field(s) being accessed from contant vector. 2170 // If only one component of vector is accessed (v.x or v[0] where v is a contant vector), then a contant node is 2171 // returned, else an aggregate node is returned (for v.xy). The input to this function could either be the symbol 2172 // node or it could be the intermediate tree representation of accessing fields in a constant structure or column of 2173 // a constant matrix. 2174 // 2175 TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTyped* node, const TSourceLoc &line) 2176 { 2177 TIntermTyped* typedNode; 2178 TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion(); 2179 2180 ConstantUnion *unionArray; 2181 if (tempConstantNode) { 2182 unionArray = tempConstantNode->getUnionArrayPointer(); 2183 2184 if (!unionArray) { 2185 return node; 2186 } 2187 } else { // The node has to be either a symbol node or an aggregate node or a tempConstant node, else, its an error 2188 error(line, "Cannot offset into the vector", "Error"); 2189 recover(); 2190 2191 return nullptr; 2192 } 2193 2194 ConstantUnion* constArray = new ConstantUnion[fields.num]; 2195 2196 int objSize = static_cast<int>(node->getType().getObjectSize()); 2197 for (int i = 0; i < fields.num; i++) { 2198 if (fields.offsets[i] >= objSize) { 2199 std::stringstream extraInfoStream; 2200 extraInfoStream << "vector field selection out of range '" << fields.offsets[i] << "'"; 2201 std::string extraInfo = extraInfoStream.str(); 2202 error(line, "", "[", extraInfo.c_str()); 2203 recover(); 2204 fields.offsets[i] = 0; 2205 } 2206 2207 constArray[i] = unionArray[fields.offsets[i]]; 2208 2209 } 2210 2211 TType type(node->getType().getBasicType(), node->getType().getPrecision(), EvqConstExpr, fields.num); 2212 typedNode = intermediate.addConstantUnion(constArray, type, line); 2213 return typedNode; 2214 } 2215 2216 // 2217 // This function returns the column being accessed from a constant matrix. The values are retrieved from 2218 // the symbol table and parse-tree is built for a vector (each column of a matrix is a vector). The input 2219 // to the function could either be a symbol node (m[0] where m is a constant matrix)that represents a 2220 // constant matrix or it could be the tree representation of the constant matrix (s.m1[0] where s is a constant structure) 2221 // 2222 TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, const TSourceLoc &line) 2223 { 2224 TIntermTyped* typedNode; 2225 TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion(); 2226 2227 if (index >= node->getType().getNominalSize()) { 2228 std::stringstream extraInfoStream; 2229 extraInfoStream << "matrix field selection out of range '" << index << "'"; 2230 std::string extraInfo = extraInfoStream.str(); 2231 error(line, "", "[", extraInfo.c_str()); 2232 recover(); 2233 index = 0; 2234 } 2235 2236 if (tempConstantNode) { 2237 ConstantUnion* unionArray = tempConstantNode->getUnionArrayPointer(); 2238 int size = tempConstantNode->getType().getNominalSize(); 2239 typedNode = intermediate.addConstantUnion(&unionArray[size*index], tempConstantNode->getType(), line); 2240 } else { 2241 error(line, "Cannot offset into the matrix", "Error"); 2242 recover(); 2243 2244 return nullptr; 2245 } 2246 2247 return typedNode; 2248 } 2249 2250 2251 // 2252 // This function returns an element of an array accessed from a constant array. The values are retrieved from 2253 // the symbol table and parse-tree is built for the type of the element. The input 2254 // to the function could either be a symbol node (a[0] where a is a constant array)that represents a 2255 // constant array or it could be the tree representation of the constant array (s.a1[0] where s is a constant structure) 2256 // 2257 TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, const TSourceLoc &line) 2258 { 2259 TIntermTyped* typedNode; 2260 TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion(); 2261 TType arrayElementType = node->getType(); 2262 arrayElementType.clearArrayness(); 2263 2264 if (index >= node->getType().getArraySize()) { 2265 std::stringstream extraInfoStream; 2266 extraInfoStream << "array field selection out of range '" << index << "'"; 2267 std::string extraInfo = extraInfoStream.str(); 2268 error(line, "", "[", extraInfo.c_str()); 2269 recover(); 2270 index = 0; 2271 } 2272 2273 size_t arrayElementSize = arrayElementType.getObjectSize(); 2274 2275 if (tempConstantNode) { 2276 ConstantUnion* unionArray = tempConstantNode->getUnionArrayPointer(); 2277 typedNode = intermediate.addConstantUnion(&unionArray[arrayElementSize * index], tempConstantNode->getType(), line); 2278 } else { 2279 error(line, "Cannot offset into the array", "Error"); 2280 recover(); 2281 2282 return nullptr; 2283 } 2284 2285 return typedNode; 2286 } 2287 2288 2289 // 2290 // This function returns the value of a particular field inside a constant structure from the symbol table. 2291 // If there is an embedded/nested struct, it appropriately calls addConstStructNested or addConstStructFromAggr 2292 // function and returns the parse-tree with the values of the embedded/nested struct. 2293 // 2294 TIntermTyped* TParseContext::addConstStruct(const TString& identifier, TIntermTyped* node, const TSourceLoc &line) 2295 { 2296 const TFieldList &fields = node->getType().getStruct()->fields(); 2297 TIntermTyped *typedNode; 2298 size_t instanceSize = 0; 2299 TIntermConstantUnion *tempConstantNode = node->getAsConstantUnion(); 2300 2301 for(const auto &field : fields) { 2302 if (field->name() == identifier) { 2303 break; 2304 } else { 2305 instanceSize += field->type()->getObjectSize(); 2306 } 2307 } 2308 2309 if (tempConstantNode) { 2310 ConstantUnion* constArray = tempConstantNode->getUnionArrayPointer(); 2311 2312 typedNode = intermediate.addConstantUnion(constArray+instanceSize, tempConstantNode->getType(), line); // type will be changed in the calling function 2313 } else { 2314 error(line, "Cannot offset into the structure", "Error"); 2315 recover(); 2316 2317 return nullptr; 2318 } 2319 2320 return typedNode; 2321 } 2322 2323 // 2324 // Interface/uniform blocks 2325 // 2326 TIntermAggregate* TParseContext::addInterfaceBlock(const TPublicType& typeQualifier, const TSourceLoc& nameLine, const TString& blockName, TFieldList* fieldList, 2327 const TString* instanceName, const TSourceLoc& instanceLine, TIntermTyped* arrayIndex, const TSourceLoc& arrayIndexLine) 2328 { 2329 if(reservedErrorCheck(nameLine, blockName)) 2330 recover(); 2331 2332 if(typeQualifier.qualifier != EvqUniform) 2333 { 2334 error(typeQualifier.line, "invalid qualifier:", getQualifierString(typeQualifier.qualifier), "interface blocks must be uniform"); 2335 recover(); 2336 } 2337 2338 TLayoutQualifier blockLayoutQualifier = typeQualifier.layoutQualifier; 2339 if(layoutLocationErrorCheck(typeQualifier.line, blockLayoutQualifier)) 2340 { 2341 recover(); 2342 } 2343 2344 if(blockLayoutQualifier.matrixPacking == EmpUnspecified) 2345 { 2346 blockLayoutQualifier.matrixPacking = mDefaultMatrixPacking; 2347 } 2348 2349 if(blockLayoutQualifier.blockStorage == EbsUnspecified) 2350 { 2351 blockLayoutQualifier.blockStorage = mDefaultBlockStorage; 2352 } 2353 2354 TSymbol* blockNameSymbol = new TSymbol(&blockName); 2355 if(!symbolTable.declare(blockNameSymbol)) { 2356 error(nameLine, "redefinition", blockName.c_str(), "interface block name"); 2357 recover(); 2358 } 2359 2360 // check for sampler types and apply layout qualifiers 2361 for(const auto &field : *fieldList) { 2362 TType* fieldType = field->type(); 2363 if(IsSampler(fieldType->getBasicType())) { 2364 error(field->line(), "unsupported type", fieldType->getBasicString(), "sampler types are not allowed in interface blocks"); 2365 recover(); 2366 } 2367 2368 const TQualifier qualifier = fieldType->getQualifier(); 2369 switch(qualifier) 2370 { 2371 case EvqGlobal: 2372 case EvqUniform: 2373 break; 2374 default: 2375 error(field->line(), "invalid qualifier on interface block member", getQualifierString(qualifier)); 2376 recover(); 2377 break; 2378 } 2379 2380 // check layout qualifiers 2381 TLayoutQualifier fieldLayoutQualifier = fieldType->getLayoutQualifier(); 2382 if(layoutLocationErrorCheck(field->line(), fieldLayoutQualifier)) 2383 { 2384 recover(); 2385 } 2386 2387 if(fieldLayoutQualifier.blockStorage != EbsUnspecified) 2388 { 2389 error(field->line(), "invalid layout qualifier:", getBlockStorageString(fieldLayoutQualifier.blockStorage), "cannot be used here"); 2390 recover(); 2391 } 2392 2393 if(fieldLayoutQualifier.matrixPacking == EmpUnspecified) 2394 { 2395 fieldLayoutQualifier.matrixPacking = blockLayoutQualifier.matrixPacking; 2396 } 2397 else if(!fieldType->isMatrix() && (fieldType->getBasicType() != EbtStruct)) 2398 { 2399 warning(field->line(), "extraneous layout qualifier:", getMatrixPackingString(fieldLayoutQualifier.matrixPacking), "only has an effect on matrix types"); 2400 } 2401 2402 fieldType->setLayoutQualifier(fieldLayoutQualifier); 2403 2404 // Recursively propagate the matrix packing setting down to all block/structure members 2405 fieldType->setMatrixPackingIfUnspecified(fieldLayoutQualifier.matrixPacking); 2406 } 2407 2408 // add array index 2409 int arraySize = 0; 2410 if(arrayIndex) 2411 { 2412 if(arraySizeErrorCheck(arrayIndexLine, arrayIndex, arraySize)) 2413 recover(); 2414 } 2415 2416 TInterfaceBlock* interfaceBlock = new TInterfaceBlock(&blockName, fieldList, instanceName, arraySize, blockLayoutQualifier); 2417 TType interfaceBlockType(interfaceBlock, typeQualifier.qualifier, blockLayoutQualifier, arraySize); 2418 2419 TString symbolName = ""; 2420 int symbolId = 0; 2421 2422 if(!instanceName) 2423 { 2424 // define symbols for the members of the interface block 2425 for(const auto &field : *fieldList) 2426 { 2427 TType* fieldType = field->type(); 2428 2429 // set parent pointer of the field variable 2430 fieldType->setInterfaceBlock(interfaceBlock); 2431 2432 TVariable* fieldVariable = new TVariable(&field->name(), *fieldType); 2433 fieldVariable->setQualifier(typeQualifier.qualifier); 2434 2435 if(!symbolTable.declare(fieldVariable)) { 2436 error(field->line(), "redefinition", field->name().c_str(), "interface block member name"); 2437 recover(); 2438 } 2439 } 2440 } 2441 else 2442 { 2443 if(reservedErrorCheck(nameLine, *instanceName)) 2444 recover(); 2445 2446 // add a symbol for this interface block 2447 TVariable* instanceTypeDef = new TVariable(instanceName, interfaceBlockType, false); 2448 instanceTypeDef->setQualifier(typeQualifier.qualifier); 2449 2450 if(!symbolTable.declare(instanceTypeDef)) { 2451 error(instanceLine, "redefinition", instanceName->c_str(), "interface block instance name"); 2452 recover(); 2453 } 2454 2455 symbolId = instanceTypeDef->getUniqueId(); 2456 symbolName = instanceTypeDef->getName(); 2457 } 2458 2459 TIntermAggregate *aggregate = intermediate.makeAggregate(intermediate.addSymbol(symbolId, symbolName, interfaceBlockType, typeQualifier.line), nameLine); 2460 aggregate->setOp(EOpDeclaration); 2461 2462 exitStructDeclaration(); 2463 return aggregate; 2464 } 2465 2466 // 2467 // Parse an array index expression 2468 // 2469 TIntermTyped *TParseContext::addIndexExpression(TIntermTyped *baseExpression, const TSourceLoc &location, TIntermTyped *indexExpression) 2470 { 2471 TIntermTyped *indexedExpression = nullptr; 2472 2473 if(!baseExpression->isArray() && !baseExpression->isMatrix() && !baseExpression->isVector()) 2474 { 2475 if(baseExpression->getAsSymbolNode()) 2476 { 2477 error(location, " left of '[' is not of type array, matrix, or vector ", 2478 baseExpression->getAsSymbolNode()->getSymbol().c_str()); 2479 } 2480 else 2481 { 2482 error(location, " left of '[' is not of type array, matrix, or vector ", "expression"); 2483 } 2484 recover(); 2485 } 2486 2487 TIntermConstantUnion *indexConstantUnion = indexExpression->getAsConstantUnion(); 2488 2489 if(indexExpression->getQualifier() == EvqConstExpr && indexConstantUnion) // TODO: Qualifier check redundant? 2490 { 2491 int index = indexConstantUnion->getIConst(0); 2492 if(index < 0) 2493 { 2494 std::stringstream infoStream; 2495 infoStream << index; 2496 std::string info = infoStream.str(); 2497 error(location, "negative index", info.c_str()); 2498 recover(); 2499 index = 0; 2500 } 2501 if(baseExpression->getType().getQualifier() == EvqConstExpr && baseExpression->getAsConstantUnion()) // TODO: Qualifier check redundant? 2502 { 2503 if(baseExpression->isArray()) 2504 { 2505 // constant folding for arrays 2506 indexedExpression = addConstArrayNode(index, baseExpression, location); 2507 } 2508 else if(baseExpression->isVector()) 2509 { 2510 // constant folding for vectors 2511 TVectorFields fields; 2512 fields.num = 1; 2513 fields.offsets[0] = index; // need to do it this way because v.xy sends fields integer array 2514 indexedExpression = addConstVectorNode(fields, baseExpression, location); 2515 } 2516 else if(baseExpression->isMatrix()) 2517 { 2518 // constant folding for matrices 2519 indexedExpression = addConstMatrixNode(index, baseExpression, location); 2520 } 2521 } 2522 else 2523 { 2524 int safeIndex = -1; 2525 2526 if(baseExpression->isArray()) 2527 { 2528 if(index >= baseExpression->getType().getArraySize()) 2529 { 2530 std::stringstream extraInfoStream; 2531 extraInfoStream << "array index out of range '" << index << "'"; 2532 std::string extraInfo = extraInfoStream.str(); 2533 error(location, "", "[", extraInfo.c_str()); 2534 recover(); 2535 safeIndex = baseExpression->getType().getArraySize() - 1; 2536 } 2537 } 2538 else if((baseExpression->isVector() || baseExpression->isMatrix()) && 2539 baseExpression->getType().getNominalSize() <= index) 2540 { 2541 std::stringstream extraInfoStream; 2542 extraInfoStream << "field selection out of range '" << index << "'"; 2543 std::string extraInfo = extraInfoStream.str(); 2544 error(location, "", "[", extraInfo.c_str()); 2545 recover(); 2546 safeIndex = baseExpression->getType().getNominalSize() - 1; 2547 } 2548 2549 // Don't modify the data of the previous constant union, because it can point 2550 // to builtins, like gl_MaxDrawBuffers. Instead use a new sanitized object. 2551 if(safeIndex != -1) 2552 { 2553 ConstantUnion *safeConstantUnion = new ConstantUnion(); 2554 safeConstantUnion->setIConst(safeIndex); 2555 indexConstantUnion->replaceConstantUnion(safeConstantUnion); 2556 } 2557 2558 indexedExpression = intermediate.addIndex(EOpIndexDirect, baseExpression, indexExpression, location); 2559 } 2560 } 2561 else 2562 { 2563 if(baseExpression->isInterfaceBlock()) 2564 { 2565 error(location, "", 2566 "[", "array indexes for interface blocks arrays must be constant integral expressions"); 2567 recover(); 2568 } 2569 else if(baseExpression->getQualifier() == EvqFragmentOut) 2570 { 2571 error(location, "", "[", "array indexes for fragment outputs must be constant integral expressions"); 2572 recover(); 2573 } 2574 2575 indexedExpression = intermediate.addIndex(EOpIndexIndirect, baseExpression, indexExpression, location); 2576 } 2577 2578 if(indexedExpression == 0) 2579 { 2580 ConstantUnion *unionArray = new ConstantUnion[1]; 2581 unionArray->setFConst(0.0f); 2582 indexedExpression = intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpHigh, EvqConstExpr), location); 2583 } 2584 else if(baseExpression->isArray()) 2585 { 2586 const TType &baseType = baseExpression->getType(); 2587 if(baseType.getStruct()) 2588 { 2589 TType copyOfType(baseType.getStruct()); 2590 indexedExpression->setType(copyOfType); 2591 } 2592 else if(baseType.isInterfaceBlock()) 2593 { 2594 TType copyOfType(baseType.getInterfaceBlock(), EvqTemporary, baseType.getLayoutQualifier(), 0); 2595 indexedExpression->setType(copyOfType); 2596 } 2597 else 2598 { 2599 indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), 2600 EvqTemporary, static_cast<unsigned char>(baseExpression->getNominalSize()), 2601 static_cast<unsigned char>(baseExpression->getSecondarySize()))); 2602 } 2603 2604 if(baseExpression->getType().getQualifier() == EvqConstExpr) 2605 { 2606 indexedExpression->getTypePointer()->setQualifier(EvqConstExpr); 2607 } 2608 } 2609 else if(baseExpression->isMatrix()) 2610 { 2611 TQualifier qualifier = baseExpression->getType().getQualifier() == EvqConstExpr ? EvqConstExpr : EvqTemporary; 2612 indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), 2613 qualifier, static_cast<unsigned char>(baseExpression->getSecondarySize()))); 2614 } 2615 else if(baseExpression->isVector()) 2616 { 2617 TQualifier qualifier = baseExpression->getType().getQualifier() == EvqConstExpr ? EvqConstExpr : EvqTemporary; 2618 indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), qualifier)); 2619 } 2620 else 2621 { 2622 indexedExpression->setType(baseExpression->getType()); 2623 } 2624 2625 return indexedExpression; 2626 } 2627 2628 TIntermTyped *TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpression, const TSourceLoc &dotLocation, 2629 const TString &fieldString, const TSourceLoc &fieldLocation) 2630 { 2631 TIntermTyped *indexedExpression = nullptr; 2632 2633 if(baseExpression->isArray()) 2634 { 2635 error(fieldLocation, "cannot apply dot operator to an array", "."); 2636 recover(); 2637 } 2638 2639 if(baseExpression->isVector()) 2640 { 2641 TVectorFields fields; 2642 if(!parseVectorFields(fieldString, baseExpression->getNominalSize(), fields, fieldLocation)) 2643 { 2644 fields.num = 1; 2645 fields.offsets[0] = 0; 2646 recover(); 2647 } 2648 2649 if(baseExpression->getAsConstantUnion()) 2650 { 2651 // constant folding for vector fields 2652 indexedExpression = addConstVectorNode(fields, baseExpression, fieldLocation); 2653 if(indexedExpression == 0) 2654 { 2655 recover(); 2656 indexedExpression = baseExpression; 2657 } 2658 } 2659 else 2660 { 2661 TString vectorString = fieldString; 2662 TIntermTyped *index = intermediate.addSwizzle(fields, fieldLocation); 2663 indexedExpression = intermediate.addIndex(EOpVectorSwizzle, baseExpression, index, dotLocation); 2664 indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), 2665 baseExpression->getQualifier() == EvqConstExpr ? EvqConstExpr : EvqTemporary, (unsigned char)vectorString.size())); 2666 } 2667 } 2668 else if(baseExpression->getBasicType() == EbtStruct) 2669 { 2670 bool fieldFound = false; 2671 const TFieldList &fields = baseExpression->getType().getStruct()->fields(); 2672 if(fields.empty()) 2673 { 2674 error(dotLocation, "structure has no fields", "Internal Error"); 2675 recover(); 2676 indexedExpression = baseExpression; 2677 } 2678 else 2679 { 2680 unsigned int i; 2681 for(i = 0; i < fields.size(); ++i) 2682 { 2683 if(fields[i]->name() == fieldString) 2684 { 2685 fieldFound = true; 2686 break; 2687 } 2688 } 2689 if(fieldFound) 2690 { 2691 if(baseExpression->getType().getQualifier() == EvqConstExpr) 2692 { 2693 indexedExpression = addConstStruct(fieldString, baseExpression, dotLocation); 2694 if(indexedExpression == 0) 2695 { 2696 recover(); 2697 indexedExpression = baseExpression; 2698 } 2699 else 2700 { 2701 indexedExpression->setType(*fields[i]->type()); 2702 // change the qualifier of the return type, not of the structure field 2703 // as the structure definition is shared between various structures. 2704 indexedExpression->getTypePointer()->setQualifier(EvqConstExpr); 2705 } 2706 } 2707 else 2708 { 2709 TIntermTyped *index = TIntermTyped::CreateIndexNode(i); 2710 index->setLine(fieldLocation); 2711 indexedExpression = intermediate.addIndex(EOpIndexDirectStruct, baseExpression, index, dotLocation); 2712 indexedExpression->setType(*fields[i]->type()); 2713 } 2714 } 2715 else 2716 { 2717 error(dotLocation, " no such field in structure", fieldString.c_str()); 2718 recover(); 2719 indexedExpression = baseExpression; 2720 } 2721 } 2722 } 2723 else if(baseExpression->isInterfaceBlock()) 2724 { 2725 bool fieldFound = false; 2726 const TFieldList &fields = baseExpression->getType().getInterfaceBlock()->fields(); 2727 if(fields.empty()) 2728 { 2729 error(dotLocation, "interface block has no fields", "Internal Error"); 2730 recover(); 2731 indexedExpression = baseExpression; 2732 } 2733 else 2734 { 2735 unsigned int i; 2736 for(i = 0; i < fields.size(); ++i) 2737 { 2738 if(fields[i]->name() == fieldString) 2739 { 2740 fieldFound = true; 2741 break; 2742 } 2743 } 2744 if(fieldFound) 2745 { 2746 ConstantUnion *unionArray = new ConstantUnion[1]; 2747 unionArray->setIConst(i); 2748 TIntermTyped *index = intermediate.addConstantUnion(unionArray, *fields[i]->type(), fieldLocation); 2749 indexedExpression = intermediate.addIndex(EOpIndexDirectInterfaceBlock, baseExpression, index, 2750 dotLocation); 2751 indexedExpression->setType(*fields[i]->type()); 2752 } 2753 else 2754 { 2755 error(dotLocation, " no such field in interface block", fieldString.c_str()); 2756 recover(); 2757 indexedExpression = baseExpression; 2758 } 2759 } 2760 } 2761 else 2762 { 2763 if(mShaderVersion < 300) 2764 { 2765 error(dotLocation, " field selection requires structure or vector on left hand side", 2766 fieldString.c_str()); 2767 } 2768 else 2769 { 2770 error(dotLocation, 2771 " field selection requires structure, vector, or interface block on left hand side", 2772 fieldString.c_str()); 2773 } 2774 recover(); 2775 indexedExpression = baseExpression; 2776 } 2777 2778 return indexedExpression; 2779 } 2780 2781 TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine) 2782 { 2783 TLayoutQualifier qualifier; 2784 2785 qualifier.location = -1; 2786 qualifier.matrixPacking = EmpUnspecified; 2787 qualifier.blockStorage = EbsUnspecified; 2788 2789 if(qualifierType == "shared") 2790 { 2791 qualifier.blockStorage = EbsShared; 2792 } 2793 else if(qualifierType == "packed") 2794 { 2795 qualifier.blockStorage = EbsPacked; 2796 } 2797 else if(qualifierType == "std140") 2798 { 2799 qualifier.blockStorage = EbsStd140; 2800 } 2801 else if(qualifierType == "row_major") 2802 { 2803 qualifier.matrixPacking = EmpRowMajor; 2804 } 2805 else if(qualifierType == "column_major") 2806 { 2807 qualifier.matrixPacking = EmpColumnMajor; 2808 } 2809 else if(qualifierType == "location") 2810 { 2811 error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str(), "location requires an argument"); 2812 recover(); 2813 } 2814 else 2815 { 2816 error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str()); 2817 recover(); 2818 } 2819 2820 return qualifier; 2821 } 2822 2823 TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine, const TString &intValueString, int intValue, const TSourceLoc& intValueLine) 2824 { 2825 TLayoutQualifier qualifier; 2826 2827 qualifier.location = -1; // -1 isn't a valid location, it means the value isn't set. Negative values are checked lower in this function. 2828 qualifier.matrixPacking = EmpUnspecified; 2829 qualifier.blockStorage = EbsUnspecified; 2830 2831 if (qualifierType != "location") 2832 { 2833 error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str(), "only location may have arguments"); 2834 recover(); 2835 } 2836 else 2837 { 2838 // must check that location is non-negative 2839 if (intValue < 0) 2840 { 2841 error(intValueLine, "out of range:", intValueString.c_str(), "location must be non-negative"); 2842 recover(); 2843 } 2844 else 2845 { 2846 qualifier.location = intValue; 2847 } 2848 } 2849 2850 return qualifier; 2851 } 2852 2853 TLayoutQualifier TParseContext::joinLayoutQualifiers(TLayoutQualifier leftQualifier, TLayoutQualifier rightQualifier) 2854 { 2855 TLayoutQualifier joinedQualifier = leftQualifier; 2856 2857 if (rightQualifier.location != -1) 2858 { 2859 joinedQualifier.location = rightQualifier.location; 2860 } 2861 if(rightQualifier.matrixPacking != EmpUnspecified) 2862 { 2863 joinedQualifier.matrixPacking = rightQualifier.matrixPacking; 2864 } 2865 if(rightQualifier.blockStorage != EbsUnspecified) 2866 { 2867 joinedQualifier.blockStorage = rightQualifier.blockStorage; 2868 } 2869 2870 return joinedQualifier; 2871 } 2872 2873 2874 TPublicType TParseContext::joinInterpolationQualifiers(const TSourceLoc &interpolationLoc, TQualifier interpolationQualifier, 2875 const TSourceLoc &storageLoc, TQualifier storageQualifier) 2876 { 2877 TQualifier mergedQualifier = EvqSmoothIn; 2878 2879 if(storageQualifier == EvqFragmentIn) { 2880 if(interpolationQualifier == EvqSmooth) 2881 mergedQualifier = EvqSmoothIn; 2882 else if(interpolationQualifier == EvqFlat) 2883 mergedQualifier = EvqFlatIn; 2884 else UNREACHABLE(interpolationQualifier); 2885 } 2886 else if(storageQualifier == EvqCentroidIn) { 2887 if(interpolationQualifier == EvqSmooth) 2888 mergedQualifier = EvqCentroidIn; 2889 else if(interpolationQualifier == EvqFlat) 2890 mergedQualifier = EvqFlatIn; 2891 else UNREACHABLE(interpolationQualifier); 2892 } 2893 else if(storageQualifier == EvqVertexOut) { 2894 if(interpolationQualifier == EvqSmooth) 2895 mergedQualifier = EvqSmoothOut; 2896 else if(interpolationQualifier == EvqFlat) 2897 mergedQualifier = EvqFlatOut; 2898 else UNREACHABLE(interpolationQualifier); 2899 } 2900 else if(storageQualifier == EvqCentroidOut) { 2901 if(interpolationQualifier == EvqSmooth) 2902 mergedQualifier = EvqCentroidOut; 2903 else if(interpolationQualifier == EvqFlat) 2904 mergedQualifier = EvqFlatOut; 2905 else UNREACHABLE(interpolationQualifier); 2906 } 2907 else { 2908 error(interpolationLoc, "interpolation qualifier requires a fragment 'in' or vertex 'out' storage qualifier", getQualifierString(interpolationQualifier)); 2909 recover(); 2910 2911 mergedQualifier = storageQualifier; 2912 } 2913 2914 TPublicType type; 2915 type.setBasic(EbtVoid, mergedQualifier, storageLoc); 2916 return type; 2917 } 2918 2919 TFieldList *TParseContext::addStructDeclaratorList(const TPublicType &typeSpecifier, TFieldList *fieldList) 2920 { 2921 if(voidErrorCheck(typeSpecifier.line, (*fieldList)[0]->name(), typeSpecifier.type)) 2922 { 2923 recover(); 2924 } 2925 2926 for(const auto &field : *fieldList) 2927 { 2928 // 2929 // Careful not to replace already known aspects of type, like array-ness 2930 // 2931 TType *type = field->type(); 2932 type->setBasicType(typeSpecifier.type); 2933 type->setNominalSize(typeSpecifier.primarySize); 2934 type->setSecondarySize(typeSpecifier.secondarySize); 2935 type->setPrecision(typeSpecifier.precision); 2936 type->setQualifier(typeSpecifier.qualifier); 2937 type->setLayoutQualifier(typeSpecifier.layoutQualifier); 2938 2939 // don't allow arrays of arrays 2940 if(type->isArray()) 2941 { 2942 if(arrayTypeErrorCheck(typeSpecifier.line, typeSpecifier)) 2943 recover(); 2944 } 2945 if(typeSpecifier.array) 2946 type->setArraySize(typeSpecifier.arraySize); 2947 if(typeSpecifier.userDef) 2948 { 2949 type->setStruct(typeSpecifier.userDef->getStruct()); 2950 } 2951 2952 if(structNestingErrorCheck(typeSpecifier.line, *field)) 2953 { 2954 recover(); 2955 } 2956 } 2957 2958 return fieldList; 2959 } 2960 2961 TPublicType TParseContext::addStructure(const TSourceLoc &structLine, const TSourceLoc &nameLine, 2962 const TString *structName, TFieldList *fieldList) 2963 { 2964 TStructure *structure = new TStructure(structName, fieldList); 2965 TType *structureType = new TType(structure); 2966 2967 // Store a bool in the struct if we're at global scope, to allow us to 2968 // skip the local struct scoping workaround in HLSL. 2969 structure->setUniqueId(TSymbolTableLevel::nextUniqueId()); 2970 structure->setAtGlobalScope(symbolTable.atGlobalLevel()); 2971 2972 if(!structName->empty()) 2973 { 2974 if(reservedErrorCheck(nameLine, *structName)) 2975 { 2976 recover(); 2977 } 2978 TVariable *userTypeDef = new TVariable(structName, *structureType, true); 2979 if(!symbolTable.declare(userTypeDef)) 2980 { 2981 error(nameLine, "redefinition", structName->c_str(), "struct"); 2982 recover(); 2983 } 2984 } 2985 2986 // ensure we do not specify any storage qualifiers on the struct members 2987 for(const auto &field : *fieldList) 2988 { 2989 const TQualifier qualifier = field->type()->getQualifier(); 2990 switch(qualifier) 2991 { 2992 case EvqGlobal: 2993 case EvqTemporary: 2994 break; 2995 default: 2996 error(field->line(), "invalid qualifier on struct member", getQualifierString(qualifier)); 2997 recover(); 2998 break; 2999 } 3000 } 3001 3002 TPublicType publicType; 3003 publicType.setBasic(EbtStruct, EvqTemporary, structLine); 3004 publicType.userDef = structureType; 3005 exitStructDeclaration(); 3006 3007 return publicType; 3008 } 3009 3010 bool TParseContext::enterStructDeclaration(const TSourceLoc &line, const TString& identifier) 3011 { 3012 ++mStructNestingLevel; 3013 3014 // Embedded structure definitions are not supported per GLSL ES spec. 3015 // They aren't allowed in GLSL either, but we need to detect this here 3016 // so we don't rely on the GLSL compiler to catch it. 3017 if (mStructNestingLevel > 1) { 3018 error(line, "", "Embedded struct definitions are not allowed"); 3019 return true; 3020 } 3021 3022 return false; 3023 } 3024 3025 void TParseContext::exitStructDeclaration() 3026 { 3027 --mStructNestingLevel; 3028 } 3029 3030 bool TParseContext::structNestingErrorCheck(const TSourceLoc &line, const TField &field) 3031 { 3032 static const int kWebGLMaxStructNesting = 4; 3033 3034 if(field.type()->getBasicType() != EbtStruct) 3035 { 3036 return false; 3037 } 3038 3039 // We're already inside a structure definition at this point, so add 3040 // one to the field's struct nesting. 3041 if(1 + field.type()->getDeepestStructNesting() > kWebGLMaxStructNesting) 3042 { 3043 std::stringstream reasonStream; 3044 reasonStream << "Reference of struct type " 3045 << field.type()->getStruct()->name().c_str() 3046 << " exceeds maximum allowed nesting level of " 3047 << kWebGLMaxStructNesting; 3048 std::string reason = reasonStream.str(); 3049 error(line, reason.c_str(), field.name().c_str(), ""); 3050 return true; 3051 } 3052 3053 return false; 3054 } 3055 3056 TIntermTyped *TParseContext::createUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc, const TType *funcReturnType) 3057 { 3058 if(child == nullptr) 3059 { 3060 return nullptr; 3061 } 3062 3063 switch(op) 3064 { 3065 case EOpLogicalNot: 3066 if(child->getBasicType() != EbtBool || 3067 child->isMatrix() || 3068 child->isArray() || 3069 child->isVector()) 3070 { 3071 return nullptr; 3072 } 3073 break; 3074 case EOpBitwiseNot: 3075 if((child->getBasicType() != EbtInt && child->getBasicType() != EbtUInt) || 3076 child->isMatrix() || 3077 child->isArray()) 3078 { 3079 return nullptr; 3080 } 3081 break; 3082 case EOpPostIncrement: 3083 case EOpPreIncrement: 3084 case EOpPostDecrement: 3085 case EOpPreDecrement: 3086 case EOpNegative: 3087 if(child->getBasicType() == EbtStruct || 3088 child->getBasicType() == EbtBool || 3089 child->isArray()) 3090 { 3091 return nullptr; 3092 } 3093 // Operators for built-ins are already type checked against their prototype. 3094 default: 3095 break; 3096 } 3097 3098 return intermediate.addUnaryMath(op, child, loc, funcReturnType); 3099 } 3100 3101 TIntermTyped *TParseContext::addUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc) 3102 { 3103 TIntermTyped *node = createUnaryMath(op, child, loc, nullptr); 3104 if(node == nullptr) 3105 { 3106 unaryOpError(loc, getOperatorString(op), child->getCompleteString()); 3107 recover(); 3108 return child; 3109 } 3110 return node; 3111 } 3112 3113 TIntermTyped *TParseContext::addUnaryMathLValue(TOperator op, TIntermTyped *child, const TSourceLoc &loc) 3114 { 3115 if(lValueErrorCheck(loc, getOperatorString(op), child)) 3116 recover(); 3117 return addUnaryMath(op, child, loc); 3118 } 3119 3120 bool TParseContext::binaryOpCommonCheck(TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc) 3121 { 3122 if(left->isArray() || right->isArray()) 3123 { 3124 if(mShaderVersion < 300) 3125 { 3126 error(loc, "Invalid operation for arrays", getOperatorString(op)); 3127 return false; 3128 } 3129 3130 if(left->isArray() != right->isArray()) 3131 { 3132 error(loc, "array / non-array mismatch", getOperatorString(op)); 3133 return false; 3134 } 3135 3136 switch(op) 3137 { 3138 case EOpEqual: 3139 case EOpNotEqual: 3140 case EOpAssign: 3141 case EOpInitialize: 3142 break; 3143 default: 3144 error(loc, "Invalid operation for arrays", getOperatorString(op)); 3145 return false; 3146 } 3147 // At this point, size of implicitly sized arrays should be resolved. 3148 if(left->getArraySize() != right->getArraySize()) 3149 { 3150 error(loc, "array size mismatch", getOperatorString(op)); 3151 return false; 3152 } 3153 } 3154 3155 // Check ops which require integer / ivec parameters 3156 bool isBitShift = false; 3157 switch(op) 3158 { 3159 case EOpBitShiftLeft: 3160 case EOpBitShiftRight: 3161 case EOpBitShiftLeftAssign: 3162 case EOpBitShiftRightAssign: 3163 // Unsigned can be bit-shifted by signed and vice versa, but we need to 3164 // check that the basic type is an integer type. 3165 isBitShift = true; 3166 if(!IsInteger(left->getBasicType()) || !IsInteger(right->getBasicType())) 3167 { 3168 return false; 3169 } 3170 break; 3171 case EOpBitwiseAnd: 3172 case EOpBitwiseXor: 3173 case EOpBitwiseOr: 3174 case EOpBitwiseAndAssign: 3175 case EOpBitwiseXorAssign: 3176 case EOpBitwiseOrAssign: 3177 // It is enough to check the type of only one operand, since later it 3178 // is checked that the operand types match. 3179 if(!IsInteger(left->getBasicType())) 3180 { 3181 return false; 3182 } 3183 break; 3184 default: 3185 break; 3186 } 3187 3188 // GLSL ES 1.00 and 3.00 do not support implicit type casting. 3189 // So the basic type should usually match. 3190 if(!isBitShift && left->getBasicType() != right->getBasicType()) 3191 { 3192 return false; 3193 } 3194 3195 // Check that type sizes match exactly on ops that require that. 3196 // Also check restrictions for structs that contain arrays or samplers. 3197 switch(op) 3198 { 3199 case EOpAssign: 3200 case EOpInitialize: 3201 case EOpEqual: 3202 case EOpNotEqual: 3203 // ESSL 1.00 sections 5.7, 5.8, 5.9 3204 if(mShaderVersion < 300 && left->getType().isStructureContainingArrays()) 3205 { 3206 error(loc, "undefined operation for structs containing arrays", getOperatorString(op)); 3207 return false; 3208 } 3209 // Samplers as l-values are disallowed also in ESSL 3.00, see section 4.1.7, 3210 // we interpret the spec so that this extends to structs containing samplers, 3211 // similarly to ESSL 1.00 spec. 3212 if((mShaderVersion < 300 || op == EOpAssign || op == EOpInitialize) && 3213 left->getType().isStructureContainingSamplers()) 3214 { 3215 error(loc, "undefined operation for structs containing samplers", getOperatorString(op)); 3216 return false; 3217 } 3218 case EOpLessThan: 3219 case EOpGreaterThan: 3220 case EOpLessThanEqual: 3221 case EOpGreaterThanEqual: 3222 if((left->getNominalSize() != right->getNominalSize()) || 3223 (left->getSecondarySize() != right->getSecondarySize())) 3224 { 3225 return false; 3226 } 3227 break; 3228 case EOpAdd: 3229 case EOpSub: 3230 case EOpDiv: 3231 case EOpIMod: 3232 case EOpBitShiftLeft: 3233 case EOpBitShiftRight: 3234 case EOpBitwiseAnd: 3235 case EOpBitwiseXor: 3236 case EOpBitwiseOr: 3237 case EOpAddAssign: 3238 case EOpSubAssign: 3239 case EOpDivAssign: 3240 case EOpIModAssign: 3241 case EOpBitShiftLeftAssign: 3242 case EOpBitShiftRightAssign: 3243 case EOpBitwiseAndAssign: 3244 case EOpBitwiseXorAssign: 3245 case EOpBitwiseOrAssign: 3246 if((left->isMatrix() && right->isVector()) || (left->isVector() && right->isMatrix())) 3247 { 3248 return false; 3249 } 3250 3251 // Are the sizes compatible? 3252 if(left->getNominalSize() != right->getNominalSize() || left->getSecondarySize() != right->getSecondarySize()) 3253 { 3254 // If the nominal sizes of operands do not match: 3255 // One of them must be a scalar. 3256 if(!left->isScalar() && !right->isScalar()) 3257 return false; 3258 3259 // In the case of compound assignment other than multiply-assign, 3260 // the right side needs to be a scalar. Otherwise a vector/matrix 3261 // would be assigned to a scalar. A scalar can't be shifted by a 3262 // vector either. 3263 if(!right->isScalar() && (IsAssignment(op) || op == EOpBitShiftLeft || op == EOpBitShiftRight)) 3264 return false; 3265 } 3266 break; 3267 default: 3268 break; 3269 } 3270 3271 return true; 3272 } 3273 3274 TIntermSwitch *TParseContext::addSwitch(TIntermTyped *init, TIntermAggregate *statementList, const TSourceLoc &loc) 3275 { 3276 TBasicType switchType = init->getBasicType(); 3277 if((switchType != EbtInt && switchType != EbtUInt) || 3278 init->isMatrix() || 3279 init->isArray() || 3280 init->isVector()) 3281 { 3282 error(init->getLine(), "init-expression in a switch statement must be a scalar integer", "switch"); 3283 recover(); 3284 return nullptr; 3285 } 3286 3287 if(statementList) 3288 { 3289 if(!ValidateSwitch::validate(switchType, this, statementList, loc)) 3290 { 3291 recover(); 3292 return nullptr; 3293 } 3294 } 3295 3296 TIntermSwitch *node = intermediate.addSwitch(init, statementList, loc); 3297 if(node == nullptr) 3298 { 3299 error(loc, "erroneous switch statement", "switch"); 3300 recover(); 3301 return nullptr; 3302 } 3303 return node; 3304 } 3305 3306 TIntermCase *TParseContext::addCase(TIntermTyped *condition, const TSourceLoc &loc) 3307 { 3308 if(mSwitchNestingLevel == 0) 3309 { 3310 error(loc, "case labels need to be inside switch statements", "case"); 3311 recover(); 3312 return nullptr; 3313 } 3314 if(condition == nullptr) 3315 { 3316 error(loc, "case label must have a condition", "case"); 3317 recover(); 3318 return nullptr; 3319 } 3320 if((condition->getBasicType() != EbtInt && condition->getBasicType() != EbtUInt) || 3321 condition->isMatrix() || 3322 condition->isArray() || 3323 condition->isVector()) 3324 { 3325 error(condition->getLine(), "case label must be a scalar integer", "case"); 3326 recover(); 3327 } 3328 TIntermConstantUnion *conditionConst = condition->getAsConstantUnion(); 3329 if(conditionConst == nullptr) 3330 { 3331 error(condition->getLine(), "case label must be constant", "case"); 3332 recover(); 3333 } 3334 TIntermCase *node = intermediate.addCase(condition, loc); 3335 if(node == nullptr) 3336 { 3337 error(loc, "erroneous case statement", "case"); 3338 recover(); 3339 return nullptr; 3340 } 3341 return node; 3342 } 3343 3344 TIntermCase *TParseContext::addDefault(const TSourceLoc &loc) 3345 { 3346 if(mSwitchNestingLevel == 0) 3347 { 3348 error(loc, "default labels need to be inside switch statements", "default"); 3349 recover(); 3350 return nullptr; 3351 } 3352 TIntermCase *node = intermediate.addCase(nullptr, loc); 3353 if(node == nullptr) 3354 { 3355 error(loc, "erroneous default statement", "default"); 3356 recover(); 3357 return nullptr; 3358 } 3359 return node; 3360 } 3361 TIntermTyped *TParseContext::createAssign(TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc) 3362 { 3363 if(binaryOpCommonCheck(op, left, right, loc)) 3364 { 3365 return intermediate.addAssign(op, left, right, loc); 3366 } 3367 return nullptr; 3368 } 3369 3370 TIntermTyped *TParseContext::addAssign(TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc) 3371 { 3372 TIntermTyped *node = createAssign(op, left, right, loc); 3373 if(node == nullptr) 3374 { 3375 assignError(loc, "assign", left->getCompleteString(), right->getCompleteString()); 3376 recover(); 3377 return left; 3378 } 3379 return node; 3380 } 3381 3382 TIntermTyped *TParseContext::addBinaryMathInternal(TOperator op, TIntermTyped *left, TIntermTyped *right, 3383 const TSourceLoc &loc) 3384 { 3385 if(!binaryOpCommonCheck(op, left, right, loc)) 3386 return nullptr; 3387 3388 switch(op) 3389 { 3390 case EOpEqual: 3391 case EOpNotEqual: 3392 break; 3393 case EOpLessThan: 3394 case EOpGreaterThan: 3395 case EOpLessThanEqual: 3396 case EOpGreaterThanEqual: 3397 ASSERT(!left->isArray() && !right->isArray()); 3398 if(left->isMatrix() || left->isVector() || 3399 left->getBasicType() == EbtStruct) 3400 { 3401 return nullptr; 3402 } 3403 break; 3404 case EOpLogicalOr: 3405 case EOpLogicalXor: 3406 case EOpLogicalAnd: 3407 ASSERT(!left->isArray() && !right->isArray()); 3408 if(left->getBasicType() != EbtBool || 3409 left->isMatrix() || left->isVector()) 3410 { 3411 return nullptr; 3412 } 3413 break; 3414 case EOpAdd: 3415 case EOpSub: 3416 case EOpDiv: 3417 case EOpMul: 3418 ASSERT(!left->isArray() && !right->isArray()); 3419 if(left->getBasicType() == EbtStruct || left->getBasicType() == EbtBool) 3420 { 3421 return nullptr; 3422 } 3423 break; 3424 case EOpIMod: 3425 ASSERT(!left->isArray() && !right->isArray()); 3426 // Note that this is only for the % operator, not for mod() 3427 if(left->getBasicType() == EbtStruct || left->getBasicType() == EbtBool || left->getBasicType() == EbtFloat) 3428 { 3429 return nullptr; 3430 } 3431 break; 3432 // Note that for bitwise ops, type checking is done in promote() to 3433 // share code between ops and compound assignment 3434 default: 3435 break; 3436 } 3437 3438 return intermediate.addBinaryMath(op, left, right, loc); 3439 } 3440 3441 TIntermTyped *TParseContext::addBinaryMath(TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc) 3442 { 3443 TIntermTyped *node = addBinaryMathInternal(op, left, right, loc); 3444 if(node == 0) 3445 { 3446 binaryOpError(loc, getOperatorString(op), left->getCompleteString(), right->getCompleteString()); 3447 recover(); 3448 return left; 3449 } 3450 return node; 3451 } 3452 3453 TIntermTyped *TParseContext::addBinaryMathBooleanResult(TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc) 3454 { 3455 TIntermTyped *node = addBinaryMathInternal(op, left, right, loc); 3456 if(node == 0) 3457 { 3458 binaryOpError(loc, getOperatorString(op), left->getCompleteString(), right->getCompleteString()); 3459 recover(); 3460 ConstantUnion *unionArray = new ConstantUnion[1]; 3461 unionArray->setBConst(false); 3462 return intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConstExpr), loc); 3463 } 3464 return node; 3465 } 3466 3467 TIntermBranch *TParseContext::addBranch(TOperator op, const TSourceLoc &loc) 3468 { 3469 switch(op) 3470 { 3471 case EOpContinue: 3472 if(mLoopNestingLevel <= 0) 3473 { 3474 error(loc, "continue statement only allowed in loops", ""); 3475 recover(); 3476 } 3477 break; 3478 case EOpBreak: 3479 if(mLoopNestingLevel <= 0 && mSwitchNestingLevel <= 0) 3480 { 3481 error(loc, "break statement only allowed in loops and switch statements", ""); 3482 recover(); 3483 } 3484 break; 3485 case EOpReturn: 3486 if(mCurrentFunctionType->getBasicType() != EbtVoid) 3487 { 3488 error(loc, "non-void function must return a value", "return"); 3489 recover(); 3490 } 3491 break; 3492 default: 3493 // No checks for discard 3494 break; 3495 } 3496 return intermediate.addBranch(op, loc); 3497 } 3498 3499 TIntermBranch *TParseContext::addBranch(TOperator op, TIntermTyped *returnValue, const TSourceLoc &loc) 3500 { 3501 ASSERT(op == EOpReturn); 3502 mFunctionReturnsValue = true; 3503 if(mCurrentFunctionType->getBasicType() == EbtVoid) 3504 { 3505 error(loc, "void function cannot return a value", "return"); 3506 recover(); 3507 } 3508 else if(*mCurrentFunctionType != returnValue->getType()) 3509 { 3510 error(loc, "function return is not matching type:", "return"); 3511 recover(); 3512 } 3513 return intermediate.addBranch(op, returnValue, loc); 3514 } 3515 3516 TIntermTyped *TParseContext::addFunctionCallOrMethod(TFunction *fnCall, TIntermNode *paramNode, TIntermNode *thisNode, const TSourceLoc &loc, bool *fatalError) 3517 { 3518 *fatalError = false; 3519 TOperator op = fnCall->getBuiltInOp(); 3520 TIntermTyped *callNode = nullptr; 3521 3522 if(thisNode != nullptr) 3523 { 3524 ConstantUnion *unionArray = new ConstantUnion[1]; 3525 int arraySize = 0; 3526 TIntermTyped *typedThis = thisNode->getAsTyped(); 3527 if(fnCall->getName() != "length") 3528 { 3529 error(loc, "invalid method", fnCall->getName().c_str()); 3530 recover(); 3531 } 3532 else if(paramNode != nullptr) 3533 { 3534 error(loc, "method takes no parameters", "length"); 3535 recover(); 3536 } 3537 else if(typedThis == nullptr || !typedThis->isArray()) 3538 { 3539 error(loc, "length can only be called on arrays", "length"); 3540 recover(); 3541 } 3542 else 3543 { 3544 arraySize = typedThis->getArraySize(); 3545 } 3546 unionArray->setIConst(arraySize); 3547 callNode = intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConstExpr), loc); 3548 } 3549 else if(op != EOpNull) 3550 { 3551 // 3552 // Then this should be a constructor. 3553 // Don't go through the symbol table for constructors. 3554 // Their parameters will be verified algorithmically. 3555 // 3556 TType type(EbtVoid, EbpUndefined); // use this to get the type back 3557 if(!constructorErrorCheck(loc, paramNode, *fnCall, op, &type)) 3558 { 3559 // 3560 // It's a constructor, of type 'type'. 3561 // 3562 callNode = addConstructor(paramNode, &type, op, fnCall, loc); 3563 } 3564 3565 if(callNode == nullptr) 3566 { 3567 recover(); 3568 callNode = intermediate.setAggregateOperator(nullptr, op, loc); 3569 } 3570 } 3571 else 3572 { 3573 // 3574 // Not a constructor. Find it in the symbol table. 3575 // 3576 const TFunction *fnCandidate; 3577 bool builtIn; 3578 fnCandidate = findFunction(loc, fnCall, &builtIn); 3579 if(fnCandidate) 3580 { 3581 // 3582 // A declared function. 3583 // 3584 if(builtIn && !fnCandidate->getExtension().empty() && 3585 extensionErrorCheck(loc, fnCandidate->getExtension())) 3586 { 3587 recover(); 3588 } 3589 op = fnCandidate->getBuiltInOp(); 3590 if(builtIn && op != EOpNull) 3591 { 3592 // 3593 // A function call mapped to a built-in operation. 3594 // 3595 if(fnCandidate->getParamCount() == 1) 3596 { 3597 // 3598 // Treat it like a built-in unary operator. 3599 // 3600 callNode = createUnaryMath(op, paramNode->getAsTyped(), loc, &fnCandidate->getReturnType()); 3601 if(callNode == nullptr) 3602 { 3603 std::stringstream extraInfoStream; 3604 extraInfoStream << "built in unary operator function. Type: " 3605 << static_cast<TIntermTyped*>(paramNode)->getCompleteString(); 3606 std::string extraInfo = extraInfoStream.str(); 3607 error(paramNode->getLine(), " wrong operand type", "Internal Error", extraInfo.c_str()); 3608 *fatalError = true; 3609 return nullptr; 3610 } 3611 } 3612 else 3613 { 3614 TIntermAggregate *aggregate = intermediate.setAggregateOperator(paramNode, op, loc); 3615 aggregate->setType(fnCandidate->getReturnType()); 3616 3617 // Some built-in functions have out parameters too. 3618 functionCallLValueErrorCheck(fnCandidate, aggregate); 3619 3620 callNode = aggregate; 3621 3622 if(fnCandidate->getParamCount() == 2) 3623 { 3624 TIntermSequence ¶meters = paramNode->getAsAggregate()->getSequence(); 3625 TIntermTyped *left = parameters[0]->getAsTyped(); 3626 TIntermTyped *right = parameters[1]->getAsTyped(); 3627 3628 TIntermConstantUnion *leftTempConstant = left->getAsConstantUnion(); 3629 TIntermConstantUnion *rightTempConstant = right->getAsConstantUnion(); 3630 if (leftTempConstant && rightTempConstant) 3631 { 3632 TIntermTyped *typedReturnNode = leftTempConstant->fold(op, rightTempConstant, infoSink()); 3633 3634 if(typedReturnNode) 3635 { 3636 callNode = typedReturnNode; 3637 } 3638 } 3639 } 3640 } 3641 } 3642 else 3643 { 3644 // This is a real function call 3645 3646 TIntermAggregate *aggregate = intermediate.setAggregateOperator(paramNode, EOpFunctionCall, loc); 3647 aggregate->setType(fnCandidate->getReturnType()); 3648 3649 // this is how we know whether the given function is a builtIn function or a user defined function 3650 // if builtIn == false, it's a userDefined -> could be an overloaded builtIn function also 3651 // if builtIn == true, it's definitely a builtIn function with EOpNull 3652 if(!builtIn) 3653 aggregate->setUserDefined(); 3654 aggregate->setName(fnCandidate->getMangledName()); 3655 3656 callNode = aggregate; 3657 3658 functionCallLValueErrorCheck(fnCandidate, aggregate); 3659 } 3660 } 3661 else 3662 { 3663 // error message was put out by findFunction() 3664 // Put on a dummy node for error recovery 3665 ConstantUnion *unionArray = new ConstantUnion[1]; 3666 unionArray->setFConst(0.0f); 3667 callNode = intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConstExpr), loc); 3668 recover(); 3669 } 3670 } 3671 delete fnCall; 3672 return callNode; 3673 } 3674 3675 TIntermTyped *TParseContext::addTernarySelection(TIntermTyped *cond, TIntermTyped *trueBlock, TIntermTyped *falseBlock, const TSourceLoc &loc) 3676 { 3677 if(boolErrorCheck(loc, cond)) 3678 recover(); 3679 3680 if(trueBlock->getType() != falseBlock->getType()) 3681 { 3682 binaryOpError(loc, ":", trueBlock->getCompleteString(), falseBlock->getCompleteString()); 3683 recover(); 3684 return falseBlock; 3685 } 3686 // ESSL1 sections 5.2 and 5.7: 3687 // ESSL3 section 5.7: 3688 // Ternary operator is not among the operators allowed for structures/arrays. 3689 if(trueBlock->isArray() || trueBlock->getBasicType() == EbtStruct) 3690 { 3691 error(loc, "ternary operator is not allowed for structures or arrays", ":"); 3692 recover(); 3693 return falseBlock; 3694 } 3695 return intermediate.addSelection(cond, trueBlock, falseBlock, loc); 3696 } 3697 3698 // 3699 // Parse an array of strings using yyparse. 3700 // 3701 // Returns 0 for success. 3702 // 3703 int PaParseStrings(int count, const char* const string[], const int length[], 3704 TParseContext* context) { 3705 if ((count == 0) || !string) 3706 return 1; 3707 3708 if (glslang_initialize(context)) 3709 return 1; 3710 3711 int error = glslang_scan(count, string, length, context); 3712 if (!error) 3713 error = glslang_parse(context); 3714 3715 glslang_finalize(context); 3716 3717 return (error == 0) && (context->numErrors() == 0) ? 0 : 1; 3718 } 3719 3720 3721 3722