Home | History | Annotate | Download | only in MachineIndependent
      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