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