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