1 // 2 // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. 3 // Copyright (C) 2016 Google, Inc. 4 // 5 // All rights reserved. 6 // 7 // Redistribution and use in source and binary forms, with or without 8 // modification, are permitted provided that the following conditions 9 // are met: 10 // 11 // Redistributions of source code must retain the above copyright 12 // notice, this list of conditions and the following disclaimer. 13 // 14 // Redistributions in binary form must reproduce the above 15 // copyright notice, this list of conditions and the following 16 // disclaimer in the documentation and/or other materials provided 17 // with the distribution. 18 // 19 // Neither the name of 3Dlabs Inc. Ltd. nor the names of its 20 // contributors may be used to endorse or promote products derived 21 // from this software without specific prior written permission. 22 // 23 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 26 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 27 // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 28 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 29 // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 30 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 31 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 33 // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34 // POSSIBILITY OF SUCH DAMAGE. 35 // 36 37 // Implement the TParseContextBase class. 38 39 #include <cstdarg> 40 41 #include "ParseHelper.h" 42 43 extern int yyparse(glslang::TParseContext*); 44 45 namespace glslang { 46 47 // 48 // Used to output syntax, parsing, and semantic errors. 49 // 50 51 void TParseContextBase::outputMessage(const TSourceLoc& loc, const char* szReason, 52 const char* szToken, 53 const char* szExtraInfoFormat, 54 TPrefixType prefix, va_list args) 55 { 56 const int maxSize = MaxTokenLength + 200; 57 char szExtraInfo[maxSize]; 58 59 safe_vsprintf(szExtraInfo, maxSize, szExtraInfoFormat, args); 60 61 infoSink.info.prefix(prefix); 62 infoSink.info.location(loc); 63 infoSink.info << "'" << szToken << "' : " << szReason << " " << szExtraInfo << "\n"; 64 65 if (prefix == EPrefixError) { 66 ++numErrors; 67 } 68 } 69 70 void C_DECL TParseContextBase::error(const TSourceLoc& loc, const char* szReason, const char* szToken, 71 const char* szExtraInfoFormat, ...) 72 { 73 if (messages & EShMsgOnlyPreprocessor) 74 return; 75 va_list args; 76 va_start(args, szExtraInfoFormat); 77 outputMessage(loc, szReason, szToken, szExtraInfoFormat, EPrefixError, args); 78 va_end(args); 79 80 if ((messages & EShMsgCascadingErrors) == 0) 81 currentScanner->setEndOfInput(); 82 } 83 84 void C_DECL TParseContextBase::warn(const TSourceLoc& loc, const char* szReason, const char* szToken, 85 const char* szExtraInfoFormat, ...) 86 { 87 if (suppressWarnings()) 88 return; 89 va_list args; 90 va_start(args, szExtraInfoFormat); 91 outputMessage(loc, szReason, szToken, szExtraInfoFormat, EPrefixWarning, args); 92 va_end(args); 93 } 94 95 void C_DECL TParseContextBase::ppError(const TSourceLoc& loc, const char* szReason, const char* szToken, 96 const char* szExtraInfoFormat, ...) 97 { 98 va_list args; 99 va_start(args, szExtraInfoFormat); 100 outputMessage(loc, szReason, szToken, szExtraInfoFormat, EPrefixError, args); 101 va_end(args); 102 103 if ((messages & EShMsgCascadingErrors) == 0) 104 currentScanner->setEndOfInput(); 105 } 106 107 void C_DECL TParseContextBase::ppWarn(const TSourceLoc& loc, const char* szReason, const char* szToken, 108 const char* szExtraInfoFormat, ...) 109 { 110 va_list args; 111 va_start(args, szExtraInfoFormat); 112 outputMessage(loc, szReason, szToken, szExtraInfoFormat, EPrefixWarning, args); 113 va_end(args); 114 } 115 116 // 117 // Both test and if necessary, spit out an error, to see if the node is really 118 // an l-value that can be operated on this way. 119 // 120 // Returns true if there was an error. 121 // 122 bool TParseContextBase::lValueErrorCheck(const TSourceLoc& loc, const char* op, TIntermTyped* node) 123 { 124 TIntermBinary* binaryNode = node->getAsBinaryNode(); 125 126 if (binaryNode) { 127 switch(binaryNode->getOp()) { 128 case EOpIndexDirect: 129 case EOpIndexIndirect: // fall through 130 case EOpIndexDirectStruct: // fall through 131 case EOpVectorSwizzle: 132 case EOpMatrixSwizzle: 133 return lValueErrorCheck(loc, op, binaryNode->getLeft()); 134 default: 135 break; 136 } 137 error(loc, " l-value required", op, "", ""); 138 139 return true; 140 } 141 142 const char* symbol = nullptr; 143 TIntermSymbol* symNode = node->getAsSymbolNode(); 144 if (symNode != nullptr) 145 symbol = symNode->getName().c_str(); 146 147 const char* message = nullptr; 148 switch (node->getQualifier().storage) { 149 case EvqConst: message = "can't modify a const"; break; 150 case EvqConstReadOnly: message = "can't modify a const"; break; 151 case EvqUniform: message = "can't modify a uniform"; break; 152 case EvqBuffer: 153 if (node->getQualifier().readonly) 154 message = "can't modify a readonly buffer"; 155 break; 156 #ifdef NV_EXTENSIONS 157 case EvqHitAttrNV: 158 if (language != EShLangIntersectNV) 159 message = "cannot modify hitAttributeNV in this stage"; 160 break; 161 #endif 162 163 default: 164 // 165 // Type that can't be written to? 166 // 167 switch (node->getBasicType()) { 168 case EbtSampler: 169 message = "can't modify a sampler"; 170 break; 171 case EbtAtomicUint: 172 message = "can't modify an atomic_uint"; 173 break; 174 case EbtVoid: 175 message = "can't modify void"; 176 break; 177 #ifdef NV_EXTENSIONS 178 case EbtAccStructNV: 179 message = "can't modify accelerationStructureNV"; 180 break; 181 #endif 182 default: 183 break; 184 } 185 } 186 187 if (message == nullptr && binaryNode == nullptr && symNode == nullptr) { 188 error(loc, " l-value required", op, "", ""); 189 190 return true; 191 } 192 193 // 194 // Everything else is okay, no error. 195 // 196 if (message == nullptr) 197 return false; 198 199 // 200 // If we get here, we have an error and a message. 201 // 202 if (symNode) 203 error(loc, " l-value required", op, "\"%s\" (%s)", symbol, message); 204 else 205 error(loc, " l-value required", op, "(%s)", message); 206 207 return true; 208 } 209 210 // Test for and give an error if the node can't be read from. 211 void TParseContextBase::rValueErrorCheck(const TSourceLoc& loc, const char* op, TIntermTyped* node) 212 { 213 if (! node) 214 return; 215 216 TIntermBinary* binaryNode = node->getAsBinaryNode(); 217 if (binaryNode) { 218 switch(binaryNode->getOp()) { 219 case EOpIndexDirect: 220 case EOpIndexIndirect: 221 case EOpIndexDirectStruct: 222 case EOpVectorSwizzle: 223 case EOpMatrixSwizzle: 224 rValueErrorCheck(loc, op, binaryNode->getLeft()); 225 default: 226 break; 227 } 228 229 return; 230 } 231 232 TIntermSymbol* symNode = node->getAsSymbolNode(); 233 if (symNode && symNode->getQualifier().writeonly) 234 error(loc, "can't read from writeonly object: ", op, symNode->getName().c_str()); 235 } 236 237 // Add 'symbol' to the list of deferred linkage symbols, which 238 // are later processed in finish(), at which point the symbol 239 // must still be valid. 240 // It is okay if the symbol's type will be subsequently edited; 241 // the modifications will be tracked. 242 // Order is preserved, to avoid creating novel forward references. 243 void TParseContextBase::trackLinkage(TSymbol& symbol) 244 { 245 if (!parsingBuiltins) 246 linkageSymbols.push_back(&symbol); 247 } 248 249 // Ensure index is in bounds, correct if necessary. 250 // Give an error if not. 251 void TParseContextBase::checkIndex(const TSourceLoc& loc, const TType& type, int& index) 252 { 253 if (index < 0) { 254 error(loc, "", "[", "index out of range '%d'", index); 255 index = 0; 256 } else if (type.isArray()) { 257 if (type.isSizedArray() && index >= type.getOuterArraySize()) { 258 error(loc, "", "[", "array index out of range '%d'", index); 259 index = type.getOuterArraySize() - 1; 260 } 261 } else if (type.isVector()) { 262 if (index >= type.getVectorSize()) { 263 error(loc, "", "[", "vector index out of range '%d'", index); 264 index = type.getVectorSize() - 1; 265 } 266 } else if (type.isMatrix()) { 267 if (index >= type.getMatrixCols()) { 268 error(loc, "", "[", "matrix index out of range '%d'", index); 269 index = type.getMatrixCols() - 1; 270 } 271 } 272 } 273 274 // Make a shared symbol have a non-shared version that can be edited by the current 275 // compile, such that editing its type will not change the shared version and will 276 // effect all nodes already sharing it (non-shallow type), 277 // or adopting its full type after being edited (shallow type). 278 void TParseContextBase::makeEditable(TSymbol*& symbol) 279 { 280 // copyUp() does a deep copy of the type. 281 symbol = symbolTable.copyUp(symbol); 282 283 // Save it (deferred, so it can be edited first) in the AST for linker use. 284 if (symbol) 285 trackLinkage(*symbol); 286 } 287 288 // Return a writable version of the variable 'name'. 289 // 290 // Return nullptr if 'name' is not found. This should mean 291 // something is seriously wrong (e.g., compiler asking self for 292 // built-in that doesn't exist). 293 TVariable* TParseContextBase::getEditableVariable(const char* name) 294 { 295 bool builtIn; 296 TSymbol* symbol = symbolTable.find(name, &builtIn); 297 298 assert(symbol != nullptr); 299 if (symbol == nullptr) 300 return nullptr; 301 302 if (builtIn) 303 makeEditable(symbol); 304 305 return symbol->getAsVariable(); 306 } 307 308 // Select the best matching function for 'call' from 'candidateList'. 309 // 310 // Assumptions 311 // 312 // There is no exact match, so a selection algorithm needs to run. That is, the 313 // language-specific handler should check for exact match first, to 314 // decide what to do, before calling this selector. 315 // 316 // Input 317 // 318 // * list of candidate signatures to select from 319 // * the call 320 // * a predicate function convertible(from, to) that says whether or not type 321 // 'from' can implicitly convert to type 'to' (it includes the case of what 322 // the calling language would consider a matching type with no conversion 323 // needed) 324 // * a predicate function better(from1, from2, to1, to2) that says whether or 325 // not a conversion from <-> to2 is considered better than a conversion 326 // from <-> to1 (both in and out directions need testing, as declared by the 327 // formal parameter) 328 // 329 // Output 330 // 331 // * best matching candidate (or none, if no viable candidates found) 332 // * whether there was a tie for the best match (ambiguous overload selection, 333 // caller's choice for how to report) 334 // 335 const TFunction* TParseContextBase::selectFunction( 336 const TVector<const TFunction*> candidateList, 337 const TFunction& call, 338 std::function<bool(const TType& from, const TType& to, TOperator op, int arg)> convertible, 339 std::function<bool(const TType& from, const TType& to1, const TType& to2)> better, 340 /* output */ bool& tie) 341 { 342 // 343 // Operation 344 // 345 // 1. Prune the input list of candidates down to a list of viable candidates, 346 // where each viable candidate has 347 // 348 // * at least as many parameters as there are calling arguments, with any 349 // remaining parameters being optional or having default values 350 // * each parameter is true under convertible(A, B), where A is the calling 351 // type for in and B is the formal type, and in addition, for out B is the 352 // calling type and A is the formal type 353 // 354 // 2. If there are no viable candidates, return with no match. 355 // 356 // 3. If there is only one viable candidate, it is the best match. 357 // 358 // 4. If there are multiple viable candidates, select the first viable candidate 359 // as the incumbent. Compare the incumbent to the next viable candidate, and if 360 // that candidate is better (bullets below), make it the incumbent. Repeat, with 361 // a linear walk through the viable candidate list. The final incumbent will be 362 // returned as the best match. A viable candidate is better than the incumbent if 363 // 364 // * it has a function argument with a better(...) conversion than the incumbent, 365 // for all directions needed by in and out 366 // * the incumbent has no argument with a better(...) conversion then the 367 // candidate, for either in or out (as needed) 368 // 369 // 5. Check for ambiguity by comparing the best match against all other viable 370 // candidates. If any other viable candidate has a function argument with a 371 // better(...) conversion than the best candidate (for either in or out 372 // directions), return that there was a tie for best. 373 // 374 375 tie = false; 376 377 // 1. prune to viable... 378 TVector<const TFunction*> viableCandidates; 379 for (auto it = candidateList.begin(); it != candidateList.end(); ++it) { 380 const TFunction& candidate = *(*it); 381 382 // to even be a potential match, number of arguments must be >= the number of 383 // fixed (non-default) parameters, and <= the total (including parameter with defaults). 384 if (call.getParamCount() < candidate.getFixedParamCount() || 385 call.getParamCount() > candidate.getParamCount()) 386 continue; 387 388 // see if arguments are convertible 389 bool viable = true; 390 391 // The call can have fewer parameters than the candidate, if some have defaults. 392 const int paramCount = std::min(call.getParamCount(), candidate.getParamCount()); 393 for (int param = 0; param < paramCount; ++param) { 394 if (candidate[param].type->getQualifier().isParamInput()) { 395 if (! convertible(*call[param].type, *candidate[param].type, candidate.getBuiltInOp(), param)) { 396 viable = false; 397 break; 398 } 399 } 400 if (candidate[param].type->getQualifier().isParamOutput()) { 401 if (! convertible(*candidate[param].type, *call[param].type, candidate.getBuiltInOp(), param)) { 402 viable = false; 403 break; 404 } 405 } 406 } 407 408 if (viable) 409 viableCandidates.push_back(&candidate); 410 } 411 412 // 2. none viable... 413 if (viableCandidates.size() == 0) 414 return nullptr; 415 416 // 3. only one viable... 417 if (viableCandidates.size() == 1) 418 return viableCandidates.front(); 419 420 // 4. find best... 421 const auto betterParam = [&call, &better](const TFunction& can1, const TFunction& can2) -> bool { 422 // is call -> can2 better than call -> can1 for any parameter 423 bool hasBetterParam = false; 424 for (int param = 0; param < call.getParamCount(); ++param) { 425 if (better(*call[param].type, *can1[param].type, *can2[param].type)) { 426 hasBetterParam = true; 427 break; 428 } 429 } 430 return hasBetterParam; 431 }; 432 433 const auto equivalentParams = [&call, &better](const TFunction& can1, const TFunction& can2) -> bool { 434 // is call -> can2 equivalent to call -> can1 for all the call parameters? 435 for (int param = 0; param < call.getParamCount(); ++param) { 436 if (better(*call[param].type, *can1[param].type, *can2[param].type) || 437 better(*call[param].type, *can2[param].type, *can1[param].type)) 438 return false; 439 } 440 return true; 441 }; 442 443 const TFunction* incumbent = viableCandidates.front(); 444 for (auto it = viableCandidates.begin() + 1; it != viableCandidates.end(); ++it) { 445 const TFunction& candidate = *(*it); 446 if (betterParam(*incumbent, candidate) && ! betterParam(candidate, *incumbent)) 447 incumbent = &candidate; 448 } 449 450 // 5. ambiguity... 451 for (auto it = viableCandidates.begin(); it != viableCandidates.end(); ++it) { 452 if (incumbent == *it) 453 continue; 454 const TFunction& candidate = *(*it); 455 456 // In the case of default parameters, it may have an identical initial set, which is 457 // also ambiguous 458 if (betterParam(*incumbent, candidate) || equivalentParams(*incumbent, candidate)) 459 tie = true; 460 } 461 462 return incumbent; 463 } 464 465 // 466 // Look at a '.' field selector string and change it into numerical selectors 467 // for a vector or scalar. 468 // 469 // Always return some form of swizzle, so the result is always usable. 470 // 471 void TParseContextBase::parseSwizzleSelector(const TSourceLoc& loc, const TString& compString, int vecSize, 472 TSwizzleSelectors<TVectorSelector>& selector) 473 { 474 // Too long? 475 if (compString.size() > MaxSwizzleSelectors) 476 error(loc, "vector swizzle too long", compString.c_str(), ""); 477 478 // Use this to test that all swizzle characters are from the same swizzle-namespace-set 479 enum { 480 exyzw, 481 ergba, 482 estpq, 483 } fieldSet[MaxSwizzleSelectors]; 484 485 // Decode the swizzle string. 486 int size = std::min(MaxSwizzleSelectors, (int)compString.size()); 487 for (int i = 0; i < size; ++i) { 488 switch (compString[i]) { 489 case 'x': 490 selector.push_back(0); 491 fieldSet[i] = exyzw; 492 break; 493 case 'r': 494 selector.push_back(0); 495 fieldSet[i] = ergba; 496 break; 497 case 's': 498 selector.push_back(0); 499 fieldSet[i] = estpq; 500 break; 501 502 case 'y': 503 selector.push_back(1); 504 fieldSet[i] = exyzw; 505 break; 506 case 'g': 507 selector.push_back(1); 508 fieldSet[i] = ergba; 509 break; 510 case 't': 511 selector.push_back(1); 512 fieldSet[i] = estpq; 513 break; 514 515 case 'z': 516 selector.push_back(2); 517 fieldSet[i] = exyzw; 518 break; 519 case 'b': 520 selector.push_back(2); 521 fieldSet[i] = ergba; 522 break; 523 case 'p': 524 selector.push_back(2); 525 fieldSet[i] = estpq; 526 break; 527 528 case 'w': 529 selector.push_back(3); 530 fieldSet[i] = exyzw; 531 break; 532 case 'a': 533 selector.push_back(3); 534 fieldSet[i] = ergba; 535 break; 536 case 'q': 537 selector.push_back(3); 538 fieldSet[i] = estpq; 539 break; 540 541 default: 542 error(loc, "unknown swizzle selection", compString.c_str(), ""); 543 break; 544 } 545 } 546 547 // Additional error checking. 548 for (int i = 0; i < selector.size(); ++i) { 549 if (selector[i] >= vecSize) { 550 error(loc, "vector swizzle selection out of range", compString.c_str(), ""); 551 selector.resize(i); 552 break; 553 } 554 555 if (i > 0 && fieldSet[i] != fieldSet[i-1]) { 556 error(loc, "vector swizzle selectors not from the same set", compString.c_str(), ""); 557 selector.resize(i); 558 break; 559 } 560 } 561 562 // Ensure it is valid. 563 if (selector.size() == 0) 564 selector.push_back(0); 565 } 566 567 // 568 // Make the passed-in variable information become a member of the 569 // global uniform block. If this doesn't exist yet, make it. 570 // 571 void TParseContextBase::growGlobalUniformBlock(const TSourceLoc& loc, TType& memberType, const TString& memberName, TTypeList* typeList) 572 { 573 // Make the global block, if not yet made. 574 if (globalUniformBlock == nullptr) { 575 TQualifier blockQualifier; 576 blockQualifier.clear(); 577 blockQualifier.storage = EvqUniform; 578 TType blockType(new TTypeList, *NewPoolTString(getGlobalUniformBlockName()), blockQualifier); 579 setUniformBlockDefaults(blockType); 580 globalUniformBlock = new TVariable(NewPoolTString(""), blockType, true); 581 firstNewMember = 0; 582 } 583 584 // Update with binding and set 585 globalUniformBlock->getWritableType().getQualifier().layoutBinding = globalUniformBinding; 586 globalUniformBlock->getWritableType().getQualifier().layoutSet = globalUniformSet; 587 588 // Add the requested member as a member to the global block. 589 TType* type = new TType; 590 type->shallowCopy(memberType); 591 type->setFieldName(memberName); 592 if (typeList) 593 type->setStruct(typeList); 594 TTypeLoc typeLoc = {type, loc}; 595 globalUniformBlock->getType().getWritableStruct()->push_back(typeLoc); 596 597 // Insert into the symbol table. 598 if (firstNewMember == 0) { 599 // This is the first request; we need a normal symbol table insert 600 if (symbolTable.insert(*globalUniformBlock)) 601 trackLinkage(*globalUniformBlock); 602 else 603 error(loc, "failed to insert the global constant buffer", "uniform", ""); 604 } else { 605 // This is a follow-on request; we need to amend the first insert 606 symbolTable.amend(*globalUniformBlock, firstNewMember); 607 } 608 609 ++firstNewMember; 610 } 611 612 void TParseContextBase::finish() 613 { 614 if (parsingBuiltins) 615 return; 616 617 // Transfer the linkage symbols to AST nodes, preserving order. 618 TIntermAggregate* linkage = new TIntermAggregate; 619 for (auto i = linkageSymbols.begin(); i != linkageSymbols.end(); ++i) 620 intermediate.addSymbolLinkageNode(linkage, **i); 621 intermediate.addSymbolLinkageNodes(linkage, getLanguage(), symbolTable); 622 } 623 624 } // end namespace glslang 625