// // Both test and if necessary, spit out an error, to see if the node is really // an l-value that can be operated on this way. // // Returns true if the was an error. // bool TParseContext::lValueErrorCheck(int line, const char* op, TIntermTyped* node) { TIntermSymbol* symNode = node->getAsSymbolNode(); TIntermBinary* binaryNode = node->getAsBinaryNode(); if (binaryNode) { bool errorReturn; switch(binaryNode->getOp()) { case EOpIndexDirect: case EOpIndexIndirect: case EOpIndexDirectStruct: return lValueErrorCheck(line, op, binaryNode->getLeft()); case EOpVectorSwizzle: errorReturn = lValueErrorCheck(line, op, binaryNode->getLeft()); if (!errorReturn) { int offset[4] = {0,0,0,0}; TIntermTyped* rightNode = binaryNode->getRight(); TIntermAggregate *aggrNode = rightNode->getAsAggregate(); for (TIntermSequence::iterator p = aggrNode->getSequence().begin(); p != aggrNode->getSequence().end(); p++) { int value = (*p)->getAsTyped()->getAsConstantUnion()->getUnionArrayPointer()->getIConst(); offset[value]++; if (offset[value] > 1) { error(line, " l-value of swizzle cannot have duplicate components", op, "", ""); return true; } } } return errorReturn; default: break; } error(line, " l-value required", op, "", ""); return true; } const char* symbol = 0; if (symNode != 0) symbol = symNode->getSymbol().c_str(); const char* message = 0; switch (node->getQualifier()) { case EvqConst: message = "can't modify a const"; break; case EvqConstReadOnly: message = "can't modify a const"; break; case EvqAttribute: message = "can't modify an attribute"; break; case EvqUniform: message = "can't modify a uniform"; break; case EvqVaryingIn: message = "can't modify a varying"; break; case EvqInput: message = "can't modify an input"; break; case EvqFragCoord: message = "can't modify gl_FragCoord"; break; case EvqFrontFacing: message = "can't modify gl_FrontFacing"; break; case EvqPointCoord: message = "can't modify gl_PointCoord"; break; default: // // Type that can't be written to? // switch (node->getBasicType()) { case EbtSampler2D: case EbtSamplerCube: message = "can't modify a sampler"; break; case EbtVoid: message = "can't modify void"; break; default: break; } } if (message == 0 && binaryNode == 0 && symNode == 0) { error(line, " l-value required", op, "", ""); return true; } // // Everything else is okay, no error. // if (message == 0) return false; // // If we get here, we have an error and a message. // if (symNode) error(line, " l-value required", op, "\"%s\" (%s)", symbol, message); else error(line, " l-value required", op, "(%s)", message); return true; }
// // Both test and if necessary, spit out an error, to see if the node is really // an l-value that can be operated on this way. // // Returns true if there was an error. // bool TParseContextBase::lValueErrorCheck(const TSourceLoc& loc, const char* op, TIntermTyped* node) { TIntermBinary* binaryNode = node->getAsBinaryNode(); if (binaryNode) { switch(binaryNode->getOp()) { case EOpIndexDirect: case EOpIndexIndirect: // fall through case EOpIndexDirectStruct: // fall through case EOpVectorSwizzle: case EOpMatrixSwizzle: return lValueErrorCheck(loc, op, binaryNode->getLeft()); default: break; } error(loc, " l-value required", op, "", ""); return true; } const char* symbol = nullptr; TIntermSymbol* symNode = node->getAsSymbolNode(); if (symNode != nullptr) symbol = symNode->getName().c_str(); const char* message = nullptr; switch (node->getQualifier().storage) { case EvqConst: message = "can't modify a const"; break; case EvqConstReadOnly: message = "can't modify a const"; break; case EvqUniform: message = "can't modify a uniform"; break; case EvqBuffer: if (node->getQualifier().readonly) message = "can't modify a readonly buffer"; break; default: // // Type that can't be written to? // switch (node->getBasicType()) { case EbtSampler: message = "can't modify a sampler"; break; case EbtAtomicUint: message = "can't modify an atomic_uint"; break; case EbtVoid: message = "can't modify void"; break; default: break; } } if (message == nullptr && binaryNode == nullptr && symNode == nullptr) { error(loc, " l-value required", op, "", ""); return true; } // // Everything else is okay, no error. // if (message == nullptr) return false; // // If we get here, we have an error and a message. // if (symNode) error(loc, " l-value required", op, "\"%s\" (%s)", symbol, message); else error(loc, " l-value required", op, "(%s)", message); return true; }