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