diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index d62a6b08..45a16896 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -43,7 +43,7 @@ TParseContext::TParseContext(TSymbolTable& symt, TIntermediate& interm, int v, EProfile p, EShLanguage L, TInfoSink& is, bool fc, EShMessages m) : intermediate(interm), symbolTable(symt), infoSink(is), language(L), treeRoot(0), - recoveredFromError(false), numErrors(0), lexAfterType(false), loopNestingLevel(0), + numErrors(0), lexAfterType(false), loopNestingLevel(0), inTypeParen(false), version(v), profile(p), forwardCompatible(fc), messages(m), contextPragma(true, false) @@ -97,6 +97,8 @@ const char* TParseContext::getPreamble() // Look at a '.' field selector string and change it into offsets // for a vector. // +// Returns true if there is no error. +// bool TParseContext::parseVectorFields(const TString& compString, int vecSize, TVectorFields& fields, int line) { fields.num = (int) compString.size(); @@ -192,15 +194,7 @@ bool TParseContext::parseVectorFields(const TString& compString, int vecSize, TV //////////////////////////////////////////////////////////////////////// // -// Track whether errors have occurred. -// -void TParseContext::recover() -{ - recoveredFromError = true; -} - -// -// Used by flex/bison to output all syntax and parsing errors. +// Used to output syntax, parsing, and semantic errors. // void C_DECL TParseContext::error(TSourceLoc nLine, const char *szReason, const char *szToken, const char *szExtraInfoFormat, ...) @@ -242,10 +236,8 @@ TIntermTyped* TParseContext::handleVariable(int line, TSymbol* symbol, TString* // The symbol table search was done in the lexical phase, but // if this is a new symbol, it wouldn't have found it. const TVariable* variable = symbol ? symbol->getAsVariable() : 0; - if (symbol && ! variable) { + if (symbol && ! variable) error(line, "variable name expected", string->c_str(), ""); - recover(); - } if (! variable) variable = new TVariable(string, TType(EbtVoid)); @@ -299,7 +291,7 @@ void TParseContext::binaryOpError(int line, const char* op, TString left, TStrin // it was not found as a variable in the symbol table. If so, give the error // message and insert a dummy variable in the symbol table to prevent future errors. // -void TParseContext::variableErrorCheck(TIntermTyped*& nodePtr) +void TParseContext::variableCheck(TIntermTyped*& nodePtr) { TIntermSymbol* symbol = nodePtr->getAsSymbolNode(); if (! symbol) @@ -307,7 +299,6 @@ void TParseContext::variableErrorCheck(TIntermTyped*& nodePtr) if (symbol->getType().getBasicType() == EbtVoid) { error(symbol->getLine(), "undeclared identifier", symbol->getSymbol().c_str(), ""); - recover(); // Add to symbol table to prevent future error messages on the same name @@ -437,48 +428,32 @@ bool TParseContext::lValueErrorCheck(int line, const char* op, TIntermTyped* nod // Both test, and if necessary spit out an error, to see if the node is really // a constant. // -// Returns true if the was an error. -// -bool TParseContext::constErrorCheck(TIntermTyped* node) +void TParseContext::constCheck(TIntermTyped* node) { - if (node->getQualifier().storage == EvqConst) - return false; - - error(node->getLine(), "constant expression required", "", ""); - - return true; + if (node->getQualifier().storage != EvqConst) + error(node->getLine(), "constant expression required", "", ""); } // // Both test, and if necessary spit out an error, to see if the node is really // an integer. // -// Returns true if the was an error. -// -bool TParseContext::integerErrorCheck(TIntermTyped* node, const char* token) +void TParseContext::integerCheck(TIntermTyped* node, const char* token) { if ((node->getBasicType() == EbtInt || node->getBasicType() == EbtUint) && node->isScalar() && ! node->isArray()) - return false; + return; error(node->getLine(), "scalar integer expression required", token, ""); - - return true; } // // Both test, and if necessary spit out an error, to see if we are currently // globally scoped. // -// Returns true if the was an error. -// -bool TParseContext::globalErrorCheck(int line, bool global, const char* token) +void TParseContext::globalCheck(int line, bool global, const char* token) { - if (global) - return false; - - error(line, "only allowed at global scope", token, ""); - - return true; + if (! global) + error(line, "only allowed at global scope", token, ""); } // @@ -486,8 +461,6 @@ bool TParseContext::globalErrorCheck(int line, bool global, const char* token) // of scope. Except, if the symbol table is at the built-in push-level, // which is when we are parsing built-ins. // -// Returns true if there was an error. -// bool TParseContext::reservedErrorCheck(int line, const TString& identifier) { if (!symbolTable.atBuiltInLevel()) { @@ -513,7 +486,7 @@ bool TParseContext::reservedErrorCheck(int line, const TString& identifier) // // Returns true if there was an error in construction. // -bool TParseContext::constructorErrorCheck(int line, TIntermNode* node, TFunction& function, TOperator op, TType* type) +bool TParseContext::constructorError(int line, TIntermNode* node, TFunction& function, TOperator op, TType* type) { *type = function.getReturnType(); @@ -640,32 +613,18 @@ bool TParseContext::voidErrorCheck(int line, const TString& identifier, const TP return false; } -// This function checks to see if the node (for the expression) contains a scalar boolean expression or not -// -// returns true in case of an error -// -bool TParseContext::boolErrorCheck(int line, const TIntermTyped* type) +// Checks to see if the node (for the expression) contains a scalar boolean expression or not +void TParseContext::boolCheck(int line, const TIntermTyped* type) { - if (type->getBasicType() != EbtBool || type->isArray() || type->isMatrix() || type->isVector()) { + if (type->getBasicType() != EbtBool || type->isArray() || type->isMatrix() || type->isVector()) error(line, "boolean expression expected", "", ""); - return true; - } - - return false; } // This function checks to see if the node (for the expression) contains a scalar boolean expression or not -// -// returns true in case of an error -// -bool TParseContext::boolErrorCheck(int line, const TPublicType& pType) +void TParseContext::boolCheck(int line, const TPublicType& pType) { - if (pType.basicType != EbtBool || pType.arraySizes || pType.matrixCols > 1 || (pType.vectorSize > 1)) { + if (pType.basicType != EbtBool || pType.arraySizes || pType.matrixCols > 1 || (pType.vectorSize > 1)) error(line, "boolean expression expected", "", ""); - return true; - } - - return false; } bool TParseContext::samplerErrorCheck(int line, const TPublicType& pType, const char* reason) @@ -687,10 +646,10 @@ bool TParseContext::samplerErrorCheck(int line, const TPublicType& pType, const return false; } -bool TParseContext::globalQualifierFixAndErrorCheck(int line, TQualifier& qualifier, const TPublicType& publicType) +void TParseContext::globalQualifierFix(int line, TQualifier& qualifier, const TPublicType& publicType) { if (! symbolTable.atGlobalLevel()) - return false; + return; // First, move from parameter qualifiers to shader in/out qualifiers @@ -712,7 +671,7 @@ bool TParseContext::globalQualifierFixAndErrorCheck(int line, TQualifier& qualif qualifier.storage = EvqVaryingIn; error(line, "cannot use 'inout' at global scope", "", ""); - return true; + return; default: break; } @@ -720,22 +679,24 @@ bool TParseContext::globalQualifierFixAndErrorCheck(int line, TQualifier& qualif // Do non-in/out error checks if (qualifier.storage != EvqUniform && samplerErrorCheck(line, publicType, "samplers and images must be uniform")) - return true; + return; if (qualifier.storage != EvqVaryingIn && qualifier.storage != EvqVaryingOut) - return false; + return; // now, knowing it is a shader in/out, do all the in/out semantic checks if (publicType.basicType == EbtBool) { error(line, "cannot be bool", getStorageQualifierString(qualifier.storage), ""); - return true; + + return; } if (language == EShLangVertex && qualifier.storage == EvqVaryingIn) { if (publicType.basicType == EbtStruct) { error(line, "cannot be a structure or array", getStorageQualifierString(qualifier.storage), ""); - return true; + + return; } if (publicType.arraySizes) { requireProfile(line, (EProfileMask)~EEsProfileMask, "vertex input arrays"); @@ -747,7 +708,8 @@ bool TParseContext::globalQualifierFixAndErrorCheck(int line, TQualifier& qualif profileRequires(line, EEsProfile, 300, 0, "fragment shader output"); if (publicType.basicType == EbtStruct) { error(line, "cannot be a structure", getStorageQualifierString(qualifier.storage), ""); - return true; + + return; } } @@ -757,7 +719,7 @@ bool TParseContext::globalQualifierFixAndErrorCheck(int line, TQualifier& qualif language != EShLangFragment && qualifier.storage == EvqVaryingOut && ! qualifier.flat) { error(line, "must be qualified as 'flat'", getStorageQualifierString(qualifier.storage), TType::getBasicString(publicType.basicType)); - return true; + return; } } @@ -765,10 +727,8 @@ bool TParseContext::globalQualifierFixAndErrorCheck(int line, TQualifier& qualif (qualifier.isAuxillary() || qualifier.isInterpolation() || qualifier.isMemory() || qualifier.invariant)) { error(line, "vertex input cannot be further qualified", "", ""); - return true; + return; } - - return false; } // @@ -776,9 +736,7 @@ bool TParseContext::globalQualifierFixAndErrorCheck(int line, TQualifier& qualif // If there is duplication, issue error messages, unless 'force' // is specified, which means to just override default settings. // -// Return true if there was an error. -// -bool TParseContext::mergeQualifiersErrorCheck(int line, TPublicType& dst, const TPublicType& src, bool force) +void TParseContext::mergeQualifiers(int line, TPublicType& dst, const TPublicType& src, bool force) { bool bad = false; @@ -825,8 +783,6 @@ bool TParseContext::mergeQualifiersErrorCheck(int line, TPublicType& dst, const if (bad) error(line, "replicated qualifiers", "", ""); - - return bad; } void TParseContext::setDefaultPrecision(int line, TPublicType& publicType, TPrecisionQualifier qualifier) @@ -844,18 +800,12 @@ void TParseContext::setDefaultPrecision(int line, TPublicType& publicType, TPrec } error(line, "cannot apply precision statement to this type; use 'float', 'int' or a sampler type", TType::getBasicString(basicType), ""); - recover(); } -bool TParseContext::parameterSamplerErrorCheck(int line, TStorageQualifier qualifier, const TType& type) +void TParseContext::parameterSamplerCheck(int line, TStorageQualifier qualifier, const TType& type) { - if ((qualifier == EvqOut || qualifier == EvqInOut) && - type.getBasicType() != EbtStruct && type.getBasicType() == EbtSampler) { + if ((qualifier == EvqOut || qualifier == EvqInOut) && type.getBasicType() != EbtStruct && type.getBasicType() == EbtSampler) error(line, "samplers cannot be output parameters", type.getCompleteTypeString().c_str(), ""); - return true; - } - - return false; } bool TParseContext::containsSampler(const TType& type) @@ -904,15 +854,14 @@ bool TParseContext::insertBuiltInArrayAtGlobalLevel() // // Do size checking for an array type's size. // -// Returns true if there was an error. -// -bool TParseContext::arraySizeErrorCheck(int line, TIntermTyped* expr, int& size) +void TParseContext::arraySizeCheck(int line, TIntermTyped* expr, int& size) { TIntermConstantUnion* constant = expr->getAsConstantUnion(); if (constant == 0 || (constant->getBasicType() != EbtInt && constant->getBasicType() != EbtUint)) { error(line, "array size must be a constant integer expression", "", ""); size = 1; - return true; + + return; } size = constant->getUnionArrayPointer()->getIConst(); @@ -920,10 +869,9 @@ bool TParseContext::arraySizeErrorCheck(int line, TIntermTyped* expr, int& size) if (size <= 0) { error(line, "array size must be a positive integer", "", ""); size = 1; - return true; - } - return false; + return; + } } // @@ -931,7 +879,7 @@ bool TParseContext::arraySizeErrorCheck(int line, TIntermTyped* expr, int& size) // // Returns true if there is an error. // -bool TParseContext::arrayQualifierErrorCheck(int line, const TPublicType& type) +bool TParseContext::arrayQualifierError(int line, const TPublicType& type) { if (type.qualifier.storage == EvqConst) profileRequires(line, ENoProfile, 120, "GL_3DL_array_objects", "const array"); @@ -947,18 +895,12 @@ bool TParseContext::arrayQualifierErrorCheck(int line, const TPublicType& type) // // Require array to have size // -// Returns true if there is an error. -// -bool TParseContext::arraySizeRequiredErrorCheck(int line, int& size) +void TParseContext::arraySizeRequiredCheck(int line, int& size) { if (size == 0) { error(line, "array size required", "", ""); size = 1; - - return true; } - - return false; } // @@ -967,9 +909,7 @@ bool TParseContext::arraySizeRequiredErrorCheck(int line, int& size) // // size == 0 means no specified size. // -// Returns true if there was an error. -// -bool TParseContext::arrayErrorCheck(int line, TString& identifier, const TPublicType& type, TVariable*& variable) +void TParseContext::arrayCheck(int line, TString& identifier, const TPublicType& type, TVariable*& variable) { // // Don't check for reserved word use until after we know it's not in the symbol table, @@ -980,42 +920,43 @@ bool TParseContext::arrayErrorCheck(int line, TString& identifier, const TPublic TSymbol* symbol = symbolTable.find(identifier, 0, &sameScope); if (symbol == 0 || !sameScope) { if (reservedErrorCheck(line, identifier)) - return true; + return; variable = new TVariable(&identifier, TType(type)); if (! symbolTable.insert(*variable)) { delete variable; error(line, "INTERNAL ERROR inserting new symbol", identifier.c_str(), ""); - return true; + + return; } } else { variable = symbol->getAsVariable(); if (! variable) { error(line, "array variable name expected", identifier.c_str(), ""); - return true; + return; } if (! variable->getType().isArray()) { error(line, "redeclaring non-array as array", identifier.c_str(), ""); - return true; + return; } if (variable->getType().getArraySize() > 0) { error(line, "redeclaration of array with size", identifier.c_str(), ""); - return true; + return; } if (! variable->getType().sameElementType(TType(type))) { error(line, "redeclaration of array with a different type", identifier.c_str(), ""); - return true; + return; } TType* t = variable->getArrayInformationType(); while (t != 0) { if (t->getMaxArraySize() > type.arraySizes->front()) { error(line, "higher index value already used for the array", identifier.c_str(), ""); - return true; + return; } t->setArraySizes(type.arraySizes); t = t->getArrayInformationType(); @@ -1024,10 +965,7 @@ bool TParseContext::arrayErrorCheck(int line, TString& identifier, const TPublic variable->getType().setArraySizes(type.arraySizes); } - if (voidErrorCheck(line, identifier, type)) - return true; - - return false; + voidErrorCheck(line, identifier, type); } bool TParseContext::arraySetMaxSize(TIntermSymbol *node, TType* type, int size, bool updateFlag, TSourceLoc line) @@ -1084,9 +1022,7 @@ bool TParseContext::arraySetMaxSize(TIntermSymbol *node, TType* type, int size, // // Enforce non-initializer type/qualifier rules. // -// Returns true if there was an error. -// -bool TParseContext::nonInitConstErrorCheck(int line, TString& identifier, TPublicType& type) +void TParseContext::nonInitConstCheck(int line, TString& identifier, TPublicType& type) { // // Make the qualifier make sense. @@ -1094,56 +1030,45 @@ bool TParseContext::nonInitConstErrorCheck(int line, TString& identifier, TPubli if (type.qualifier.storage == EvqConst) { type.qualifier.storage = EvqTemporary; error(line, "variables with qualifier 'const' must be initialized", identifier.c_str(), ""); - return true; } - - return false; } // // Do semantic checking for a variable declaration that has no initializer, // and update the symbol table. // -// Returns true if there was an error. -// -bool TParseContext::nonInitErrorCheck(int line, TString& identifier, TPublicType& type) +void TParseContext::nonInitCheck(int line, TString& identifier, TPublicType& type) { - if (reservedErrorCheck(line, identifier)) - recover(); + reservedErrorCheck(line, identifier); TVariable* variable = new TVariable(&identifier, TType(type)); if (! symbolTable.insert(*variable)) { error(line, "redefinition", variable->getName().c_str(), ""); delete variable; - return true; - } - - if (voidErrorCheck(line, identifier, type)) - return true; - - return false; + } else + voidErrorCheck(line, identifier, type); } -bool TParseContext::paramErrorCheck(int line, TStorageQualifier qualifier, TType* type) +void TParseContext::paramCheck(int line, TStorageQualifier qualifier, TType* type) { switch (qualifier) { case EvqConst: case EvqConstReadOnly: type->getQualifier().storage = EvqConstReadOnly; - return false; + break; case EvqIn: case EvqOut: case EvqInOut: type->getQualifier().storage = qualifier; - return false; + break; case EvqTemporary: type->getQualifier().storage = EvqIn; - return false; + break; default: type->getQualifier().storage = EvqIn; error(line, "qualifier not allowed on function parameter", getStorageQualifierString(qualifier), ""); - return true; + break; } } @@ -1242,8 +1167,8 @@ const TFunction* TParseContext::findFunction(int line, TFunction* call, bool *bu // Initializers show up in several places in the grammar. Have one set of // code to handle them here. // -bool TParseContext::executeInitializer(TSourceLoc line, TString& identifier, TPublicType& pType, - TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable) +bool TParseContext::executeInitializerError(TSourceLoc line, TString& identifier, TPublicType& pType, + TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable) { TType type(pType); @@ -1482,7 +1407,6 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T default: error(line, "unsupported construction", "", ""); - recover(); return 0; } @@ -1515,8 +1439,7 @@ TIntermTyped* TParseContext::constructStruct(TIntermNode* node, const TType& typ if (! converted || converted->getType() != type) { error(line, "", "constructor", "cannot convert parameter %d from '%s' to '%s'", paramCount, node->getAsTyped()->getType().getCompleteTypeString().c_str(), type.getCompleteTypeString().c_str()); - recover(); - + return 0; } @@ -1530,19 +1453,14 @@ void TParseContext::addBlock(int line, TPublicType& publicType, const TString& b { // First, error checks - if (reservedErrorCheck(line, blockName)) { - recover(); - + if (reservedErrorCheck(line, blockName)) return; - } - if (instanceName && reservedErrorCheck(line, *instanceName)) { - recover(); + if (instanceName && reservedErrorCheck(line, *instanceName)) return; - } + if (publicType.basicType != EbtVoid) { error(line, "interface blocks cannot be declared with a type", blockName.c_str(), ""); - recover(); return; } @@ -1551,7 +1469,6 @@ void TParseContext::addBlock(int line, TPublicType& publicType, const TString& b profileRequires(line, EEsProfile, 300, 0, "uniform block"); } else { error(line, "only uniform interface blocks are supported", blockName.c_str(), ""); - recover(); return; } @@ -1559,23 +1476,14 @@ void TParseContext::addBlock(int line, TPublicType& publicType, const TString& b // check for qualifiers and types that don't belong within a block for (unsigned int member = 0; member < typeList.size(); ++member) { TQualifier memberQualifier = typeList[member].type->getQualifier(); - if (memberQualifier.storage != EvqTemporary && memberQualifier.storage != EvqGlobal && - memberQualifier.storage != publicType.qualifier.storage) { + if (memberQualifier.storage != EvqTemporary && memberQualifier.storage != EvqGlobal && memberQualifier.storage != publicType.qualifier.storage) error(line, "member storage qualifier cannot contradict block storage qualifier", typeList[member].type->getFieldName().c_str(), ""); - recover(); - } - if (publicType.qualifier.storage == EvqUniform) { - if (memberQualifier.isInterpolation() || memberQualifier.isAuxillary()) { - error(line, "member of uniform block cannot have an auxillary or interpolation qualifier", typeList[member].type->getFieldName().c_str(), ""); - recover(); - } - } + if (publicType.qualifier.storage == EvqUniform && memberQualifier.isInterpolation() || memberQualifier.isAuxillary()) + error(line, "member of uniform block cannot have an auxillary or interpolation qualifier", typeList[member].type->getFieldName().c_str(), ""); TBasicType basicType = typeList[member].type->getBasicType(); - if (basicType == EbtSampler) { + if (basicType == EbtSampler) error(line, "member of block cannot be a sampler type", typeList[member].type->getFieldName().c_str(), ""); - recover(); - } } // Make default block qualification, and adjust the member qualifications @@ -1597,7 +1505,6 @@ void TParseContext::addBlock(int line, TPublicType& publicType, const TString& b TVariable* userTypeDef = new TVariable(&blockName, blockType, true); if (! symbolTable.insert(*userTypeDef)) { error(line, "redefinition", blockName.c_str(), "block name"); - recover(); return; } @@ -1614,7 +1521,6 @@ void TParseContext::addBlock(int line, TPublicType& publicType, const TString& b error(line, "nameless block contains a member that already has a name at global scope", blockName.c_str(), ""); else error(line, "block instance name redefinition", variable->getName().c_str(), ""); - recover(); return; } @@ -1631,10 +1537,8 @@ void TParseContext::wrapupSwitchSubsequence(TIntermAggregate* statements, TInter TIntermSequence* switchSequence = switchSequenceStack.back(); if (statements) { - if (switchSequence->size() == 0) { + if (switchSequence->size() == 0) error(statements->getLine(), "cannot have statements before first case/default label", "switch", ""); - recover(); - } statements->setOperator(EOpSequence); switchSequence->push_back(statements); } @@ -1657,10 +1561,8 @@ TIntermNode* TParseContext::addSwitch(int line, TIntermTyped* expression, TInter if (expression == 0 || expression->getBasicType() != EbtInt && expression->getBasicType() != EbtUint || - expression->getType().isArray() || expression->getType().isMatrix() || expression->getType().isVector()) { + expression->getType().isArray() || expression->getType().isMatrix() || expression->getType().isVector()) error(line, "condition must be a scalar integer expression", "switch", ""); - recover(); - } // If there is nothing to do, drop the switch but still execute the expression TIntermSequence* switchSequence = switchSequenceStack.back(); @@ -1669,7 +1571,6 @@ TIntermNode* TParseContext::addSwitch(int line, TIntermTyped* expression, TInter if (lastStatements == 0) { error(line, "last case/default label must be followed by statements", "switch", ""); - recover(); return expression; } @@ -1708,10 +1609,8 @@ void TParseContext::updateDefaults(int line, const TPublicType& publicType, cons } } - if (cantHaveId && id) { + if (cantHaveId && id) error(line, "cannot set global layout qualifiers on uniform variable, use just 'uniform' or a block", id->c_str(), ""); - recover(); - } } // @@ -1732,13 +1631,11 @@ TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTy if (!unionArray) { // this error message should never be raised infoSink.info.message(EPrefixInternalError, "constUnion not initialized in addConstVectorNode function", line); - recover(); return node; } } else { // The node has to be either a symbol node or an aggregate node or a tempConstant node, else, its an error error(line, "Cannot offset into the vector", "Error", ""); - recover(); return 0; } @@ -1748,14 +1645,13 @@ TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTy for (int i = 0; i < fields.num; i++) { if (fields.offsets[i] >= node->getType().getObjectSize()) { error(line, "", "[", "vector index out of range '%d'", fields.offsets[i]); - recover(); fields.offsets[i] = 0; } constArray[i] = unionArray[fields.offsets[i]]; - } typedNode = intermediate.addConstantUnion(constArray, node->getType(), line); + return typedNode; } @@ -1772,7 +1668,6 @@ TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, T if (index >= node->getType().getMatrixCols()) { error(line, "", "[", "matrix field selection out of range '%d'", index); - recover(); index = 0; } @@ -1783,7 +1678,6 @@ TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, T typedNode = intermediate.addConstantUnion(&unionArray[size*index], tempConstantNode->getType(), line); } else { error(line, "Cannot offset into the matrix", "Error", ""); - recover(); return 0; } @@ -1808,7 +1702,6 @@ TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TS if (index >= node->getType().getArraySize() || index < 0) { error(line, "", "[", "array index '%d' out of range", index); - recover(); index = 0; } @@ -1819,7 +1712,6 @@ TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TS typedNode = intermediate.addConstantUnion(&unionArray[arrayElementSize * index], tempConstantNode->getType(), line); } else { error(line, "Cannot offset into the array", "Error", ""); - recover(); return 0; } @@ -1855,7 +1747,6 @@ TIntermTyped* TParseContext::addConstStruct(TString& identifier, TIntermTyped* n typedNode = intermediate.addConstantUnion(constArray+instanceSize, tempConstantNode->getType(), line); // type will be changed in the calling function } else { error(line, "Cannot offset into the structure", "Error", ""); - recover(); return 0; } diff --git a/glslang/MachineIndependent/ParseHelper.h b/glslang/MachineIndependent/ParseHelper.h index 07ebc960..b5370a57 100644 --- a/glslang/MachineIndependent/ParseHelper.h +++ b/glslang/MachineIndependent/ParseHelper.h @@ -74,8 +74,7 @@ struct TParseContext { TInfoSink& infoSink; EShLanguage language; // vertex or fragment language TIntermNode* treeRoot; // root of parse tree being created - bool recoveredFromError; // true if a parse error has occurred, but we continue to parse - int numErrors; + int numErrors; // number of compile-time errors encountered bool lexAfterType; // true if we've recognized a type, so can only be looking for an identifier int loopNestingLevel; // 0 if outside all loops TList switchSequenceStack; // case, node, case, case, node, ...; ensure only one node between cases; stack of them for nesting @@ -101,45 +100,44 @@ struct TParseContext { void C_DECL error(TSourceLoc, const char *szReason, const char *szToken, const char *szExtraInfoFormat, ...); bool reservedErrorCheck(int line, const TString& identifier); - void recover(); TIntermTyped* handleVariable(int line, TSymbol* symbol, TString* string); bool parseVectorFields(const TString&, int vecSize, TVectorFields&, int line); void assignError(int line, const char* op, TString left, TString right); void unaryOpError(int line, const char* op, TString operand); void binaryOpError(int line, const char* op, TString left, TString right); - void variableErrorCheck(TIntermTyped*& nodePtr); + void variableCheck(TIntermTyped*& nodePtr); bool lValueErrorCheck(int line, const char* op, TIntermTyped*); - bool constErrorCheck(TIntermTyped* node); - bool integerErrorCheck(TIntermTyped* node, const char* token); - bool globalErrorCheck(int line, bool global, const char* token); - bool constructorErrorCheck(int line, TIntermNode*, TFunction&, TOperator, TType*); - bool arraySizeErrorCheck(int line, TIntermTyped* expr, int& size); - bool arrayQualifierErrorCheck(int line, const TPublicType&); - bool arraySizeRequiredErrorCheck(int line, int& size); - bool arrayErrorCheck(int line, TString& identifier, const TPublicType&, TVariable*& variable); + void constCheck(TIntermTyped* node); + void integerCheck(TIntermTyped* node, const char* token); + void globalCheck(int line, bool global, const char* token); + bool constructorError(int line, TIntermNode*, TFunction&, TOperator, TType*); + void arraySizeCheck(int line, TIntermTyped* expr, int& size); + bool arrayQualifierError(int line, const TPublicType&); + void arraySizeRequiredCheck(int line, int& size); + void arrayCheck(int line, TString& identifier, const TPublicType&, TVariable*& variable); bool insertBuiltInArrayAtGlobalLevel(); bool voidErrorCheck(int, const TString&, const TPublicType&); - bool boolErrorCheck(int, const TIntermTyped*); - bool boolErrorCheck(int, const TPublicType&); + void boolCheck(int, const TIntermTyped*); + void boolCheck(int, const TPublicType&); bool samplerErrorCheck(int line, const TPublicType& pType, const char* reason); - bool globalQualifierFixAndErrorCheck(int line, TQualifier&, const TPublicType&); + void globalQualifierFix(int line, TQualifier&, const TPublicType&); bool structQualifierErrorCheck(int line, const TPublicType& pType); - bool mergeQualifiersErrorCheck(int line, TPublicType& dst, const TPublicType& src, bool force); + void mergeQualifiers(int line, TPublicType& dst, const TPublicType& src, bool force); void setDefaultPrecision(int line, TPublicType&, TPrecisionQualifier); - bool parameterSamplerErrorCheck(int line, TStorageQualifier qualifier, const TType& type); + void parameterSamplerCheck(int line, TStorageQualifier qualifier, const TType& type); bool containsSampler(const TType& type); - bool nonInitConstErrorCheck(int line, TString& identifier, TPublicType& type); - bool nonInitErrorCheck(int line, TString& identifier, TPublicType& type); - bool paramErrorCheck(int line, TStorageQualifier qualifier, TType* type); + void nonInitConstCheck(int line, TString& identifier, TPublicType& type); + void nonInitCheck(int line, TString& identifier, TPublicType& type); + void paramCheck(int line, TStorageQualifier qualifier, TType* type); void setLayoutQualifier(int line, TPublicType&, TString&); void setLayoutQualifier(int line, TPublicType&, TString&, int); void mergeLayoutQualifiers(int line, TQualifier& dest, const TQualifier& src); const TFunction* findFunction(int line, TFunction* pfnCall, bool *builtIn = 0); - bool executeInitializer(TSourceLoc line, TString& identifier, TPublicType& pType, - TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable = 0); + bool executeInitializerError(TSourceLoc line, TString& identifier, TPublicType& pType, + TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable = 0); TIntermTyped* addConstructor(TIntermNode*, const TType&, TOperator, TFunction*, TSourceLoc); TIntermTyped* constructStruct(TIntermNode*, const TType&, int, TSourceLoc); TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermNode*, TSourceLoc, bool subset); @@ -153,6 +151,7 @@ struct TParseContext { TIntermTyped* addConstStruct(TString& , TIntermTyped*, TSourceLoc); bool arraySetMaxSize(TIntermSymbol*, TType*, int, bool, TSourceLoc); + void requireProfile(int line, EProfileMask profileMask, const char *featureDesc); void requireStage(int line, EShLanguageMask languageMask, const char *featureDesc); void profileRequires(int line, EProfile callingProfile, int minVersion, int numExtensions, const char* extensions[], const char *featureDesc); diff --git a/glslang/MachineIndependent/Versions.cpp b/glslang/MachineIndependent/Versions.cpp index 3ea068a3..9bb38b4c 100644 --- a/glslang/MachineIndependent/Versions.cpp +++ b/glslang/MachineIndependent/Versions.cpp @@ -66,10 +66,8 @@ const char* ProfileName[EProfileCount] = { // void TParseContext::requireProfile(int line, EProfileMask profileMask, const char *featureDesc) { - if (((1 << profile) & profileMask) == 0) { + if (((1 << profile) & profileMask) == 0) error(line, "not supported with this profile:", featureDesc, ProfileName[profile]); - recover(); - } } // @@ -79,10 +77,8 @@ void TParseContext::requireProfile(int line, EProfileMask profileMask, const cha // void TParseContext::requireStage(int line, EShLanguageMask languageMask, const char *featureDesc) { - if (((1 << language) & languageMask) == 0) { + if (((1 << language) & languageMask) == 0) error(line, "not supported in this stage:", featureDesc, StageName[language]); - recover(); - } } // @@ -112,10 +108,8 @@ void TParseContext::profileRequires(int line, EProfile callingProfile, int minVe } } - if (! okay) { + if (! okay) error(line, "not supported for this version or the enabled extensions", featureDesc, ""); - recover(); - } } } @@ -133,13 +127,11 @@ void TParseContext::checkDeprecated(int line, EProfile callingProfile, int depVe { if (profile == callingProfile) { if (version >= depVersion) { - if (forwardCompatible) { + if (forwardCompatible) error(line, "deprecated, may be removed in future release", featureDesc, ""); - recover(); - } else if (! (messages & EShMsgSuppressWarnings)) { + else if (! (messages & EShMsgSuppressWarnings)) infoSink.info.message(EPrefixWarning, (TString(featureDesc) + " deprecated in version " + String(depVersion) + "; may be removed in future release").c_str(), line); - } } } } @@ -156,7 +148,6 @@ void TParseContext::requireNotRemoved(int line, EProfile callingProfile, int rem char buf[maxSize]; snprintf(buf, maxSize, "%s profile; removed in version %d", ProfileName[profile], removedVersion); error(line, "no longer supported in", featureDesc, buf); - recover(); } } } diff --git a/glslang/MachineIndependent/glslang.l b/glslang/MachineIndependent/glslang.l index bfb33c0a..60a2dbad 100644 --- a/glslang/MachineIndependent/glslang.l +++ b/glslang/MachineIndependent/glslang.l @@ -536,12 +536,12 @@ int yy_input(char* buf, int max_size); 0[xX]{H}+ { pyylval->lex.line = yylineno; pyylval->lex.i = strtoul(yytext, 0, 0); return INTCONSTANT; } 0{O}+ { pyylval->lex.line = yylineno; pyylval->lex.i = strtoul(yytext, 0, 0); return INTCONSTANT; } -0{D}+ { pyylval->lex.line = yylineno; parseContext.error(yylineno, "Invalid Octal number.", yytext, "", ""); parseContext.recover(); return 0;} +0{D}+ { pyylval->lex.line = yylineno; parseContext.error(yylineno, "Invalid Octal number.", yytext, "", ""); return 0;} {D}+ { pyylval->lex.line = yylineno; pyylval->lex.i = strtoul(yytext, 0, 0); return INTCONSTANT; } 0[xX]{H}+{U} { pyylval->lex.line = yylineno; pyylval->lex.u = strtoul(yytext, 0, 0); return UINTCONSTANT; } 0{O}+{U} { pyylval->lex.line = yylineno; pyylval->lex.u = strtoul(yytext, 0, 0); return UINTCONSTANT; } -0{D}+{U} { pyylval->lex.line = yylineno; parseContext.error(yylineno, "Invalid Octal number.", yytext, "", ""); parseContext.recover(); return 0;} +0{D}+{U} { pyylval->lex.line = yylineno; parseContext.error(yylineno, "Invalid Octal number.", yytext, "", ""); return 0;} {D}+{U} { pyylval->lex.line = yylineno; pyylval->lex.u = strtoul(yytext, 0, 0); return UINTCONSTANT; } {D}+{F} { pyylval->lex.line = yylineno; pyylval->lex.d = atof(yytext); return FLOATCONSTANT; } @@ -657,7 +657,7 @@ int PaParseStrings(char* argv[], int strLen[], int argc, TParseContext& parseCon for (int i = 0; i < argc; ++i) { if (! argv[i]) { parseContextLocal.error(0, "Null shader source string", "", ""); - parseContextLocal.recover(); + return 1; } } @@ -709,7 +709,7 @@ int PaParseStrings(char* argv[], int strLen[], int argc, TParseContext& parseCon ret = yyparse((void*)(&parseContextLocal)); #endif delete writeablePreamble; - if (cpp->CompileError == 1 || parseContextLocal.recoveredFromError || parseContextLocal.numErrors > 0) + if (cpp->CompileError == 1 || parseContextLocal.numErrors > 0) return 1; else return 0; @@ -725,20 +725,15 @@ void yyerror(const char *s) TParseContext& pc = *((TParseContext *)cpp->pC); if (pc.AfterEOF) { - if (cpp->tokensBeforeEOF == 1) { + if (cpp->tokensBeforeEOF == 1) GlobalParseContext->error(yylineno, "", "pre-mature EOF", s, ""); - GlobalParseContext->recover(); - } - } else { + } else GlobalParseContext->error(yylineno, "", yytext, s, ""); - GlobalParseContext->recover(); - } } void PaReservedWord() { GlobalParseContext->error(yylineno, "Reserved word.", yytext, "", ""); - GlobalParseContext->recover(); } int PaIdentOrType(const char* yytext, TParseContext& parseContextLocal, YYSTYPE* pyylval) @@ -907,6 +902,7 @@ int Pa2ndGenerationImage(TParseContext& pc, int line, const char* text, YYSTYPE* return PaIdentOrType(text, pc, pyylval); } +// TODO: CPP: is this dead code? Combine with other comment parsers. int PaParseComment(int& lineno, TParseContext& parseContextLocal) { int transitionFlag = 0; @@ -926,14 +922,14 @@ int PaParseComment(int& lineno, TParseContext& parseContextLocal) } break; case EOF : - /* Raise error message here */ parseContextLocal.error(yylineno, "End of shader found before end of comment.", "", "", ""); - GlobalParseContext->recover(); + return YY_NULL; default : /* Any other character will be a part of the comment */ transitionFlag = 0; } } + return 1; } @@ -959,7 +955,6 @@ void ShPpErrorToInfoLog(const char *msg) TParseContext& pc = *((TParseContext *)cpp->pC); pc.error(yylineno, "", "Preprocessor", msg, ""); - GlobalParseContext->recover(); } // return 1 if error diff --git a/glslang/MachineIndependent/glslang.y b/glslang/MachineIndependent/glslang.y index 3a10d122..12e6ab92 100644 --- a/glslang/MachineIndependent/glslang.y +++ b/glslang/MachineIndependent/glslang.y @@ -263,13 +263,12 @@ postfix_expression $$ = $1; } | postfix_expression LEFT_BRACKET integer_expression RIGHT_BRACKET { - parseContext.variableErrorCheck($1); + parseContext.variableCheck($1); if (!$1->isArray() && !$1->isMatrix() && !$1->isVector()) { if ($1->getAsSymbolNode()) parseContext.error($2.line, " left of '[' is not of type array, matrix, or vector ", $1->getAsSymbolNode()->getSymbol().c_str(), ""); else parseContext.error($2.line, " left of '[' is not of type array, matrix, or vector ", "expression", ""); - parseContext.recover(); } if ($1->getType().getQualifier().storage == EvqConst && $3->getQualifier().storage == EvqConst) { if ($1->isArray()) { // constant folding for arrays @@ -286,32 +285,24 @@ postfix_expression if ($3->getQualifier().storage == EvqConst) { int index = $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst(); if (! $1->isArray() && ($1->isVector() && $1->getType().getVectorSize() <= index || - $1->isMatrix() && $1->getType().getMatrixCols() <= index)) { + $1->isMatrix() && $1->getType().getMatrixCols() <= index)) parseContext.error($2.line, "", "[", "index out of range '%d'", $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst()); - parseContext.recover(); - } else { + else { if ($1->isArray()) { if ($1->getType().getArraySize() == 0) { - if ($1->getType().getMaxArraySize() <= $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst()) { - if (parseContext.arraySetMaxSize($1->getAsSymbolNode(), $1->getTypePointer(), $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst(), true, $2.line)) - parseContext.recover(); - } else { - if (parseContext.arraySetMaxSize($1->getAsSymbolNode(), $1->getTypePointer(), 0, false, $2.line)) - parseContext.recover(); - } + if ($1->getType().getMaxArraySize() <= $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst()) + parseContext.arraySetMaxSize($1->getAsSymbolNode(), $1->getTypePointer(), $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst(), true, $2.line); + else + parseContext.arraySetMaxSize($1->getAsSymbolNode(), $1->getTypePointer(), 0, false, $2.line); } else if ( $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst() >= $1->getType().getArraySize() || - $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst() < 0) { + $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst() < 0) parseContext.error($2.line, "", "[", "array index out of range '%d'", $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst()); - parseContext.recover(); - } } $$ = parseContext.intermediate.addIndex(EOpIndexDirect, $1, $3, $2.line); } } else { - if ($1->isArray() && $1->getType().getArraySize() == 0) { + if ($1->isArray() && $1->getType().getArraySize() == 0) parseContext.error($2.line, "", "[", "array must be redeclared with a size before being indexed with a variable"); - parseContext.recover(); - } if ($1->getBasicType() == EbtBlock) parseContext.requireProfile($1->getLine(), static_cast(~EEsProfileMask), "variable indexing block array"); @@ -334,7 +325,7 @@ postfix_expression $$ = $1; } | postfix_expression DOT FIELD_SELECTION { - parseContext.variableErrorCheck($1); + parseContext.variableCheck($1); if ($1->isArray()) { // // It can only be a method (e.g., length), which can't be resolved until @@ -348,7 +339,6 @@ postfix_expression $$ = parseContext.intermediate.addMethod($1, TType(EbtInt), $3.string, $2.line); } else { parseContext.error($3.line, "only the length method is supported for array", $3.string->c_str(), ""); - parseContext.recover(); $$ = $1; } } else if ($1->isVector()) { @@ -356,15 +346,12 @@ postfix_expression if (! parseContext.parseVectorFields(*$3.string, $1->getVectorSize(), fields, $3.line)) { fields.num = 1; fields.offsets[0] = 0; - parseContext.recover(); } if ($1->getType().getQualifier().storage == EvqConst) { // constant folding for vector fields $$ = parseContext.addConstVectorNode(fields, $1, $3.line); - if ($$ == 0) { - parseContext.recover(); + if ($$ == 0) $$ = $1; - } else $$->setType(TType($1->getBasicType(), EvqConst, (int) (*$3.string).size())); } else { @@ -381,15 +368,13 @@ postfix_expression $$->setType(TType($1->getBasicType(), EvqTemporary, $1->getType().getQualifier().precision, (int) vectorString.size())); } } - } else if ($1->isMatrix()) { + } else if ($1->isMatrix()) parseContext.error($2.line, "field selection not allowed on matrix", ".", ""); - parseContext.recover(); - } else if ($1->getBasicType() == EbtStruct || $1->getBasicType() == EbtBlock) { + else if ($1->getBasicType() == EbtStruct || $1->getBasicType() == EbtBlock) { bool fieldFound = false; TTypeList* fields = $1->getType().getStruct(); if (fields == 0) { parseContext.error($2.line, "structure has no fields", "Internal Error", ""); - parseContext.recover(); $$ = $1; } else { unsigned int i; @@ -402,10 +387,9 @@ postfix_expression if (fieldFound) { if ($1->getType().getQualifier().storage == EvqConst) { $$ = parseContext.addConstStruct(*$3.string, $1, $2.line); - if ($$ == 0) { - parseContext.recover(); + if ($$ == 0) $$ = $1; - } else { + else { $$->setType(*(*fields)[i].type); // change the qualifier of the return type, not of the structure field // as the structure definition is shared between various structures. @@ -420,36 +404,30 @@ postfix_expression } } else { parseContext.error($2.line, " no such field in structure", $3.string->c_str(), ""); - parseContext.recover(); $$ = $1; } } } else { parseContext.error($2.line, " dot operator requires structure, array, vector, or matrix on left hand side", $3.string->c_str(), ""); - parseContext.recover(); $$ = $1; } // don't delete $3.string, it's from the pool } | postfix_expression INC_OP { - parseContext.variableErrorCheck($1); - if (parseContext.lValueErrorCheck($2.line, "++", $1)) - parseContext.recover(); + parseContext.variableCheck($1); + parseContext.lValueErrorCheck($2.line, "++", $1); $$ = parseContext.intermediate.addUnaryMath(EOpPostIncrement, $1, $2.line); if ($$ == 0) { parseContext.unaryOpError($2.line, "++", $1->getCompleteString()); - parseContext.recover(); $$ = $1; } } | postfix_expression DEC_OP { - parseContext.variableErrorCheck($1); - if (parseContext.lValueErrorCheck($2.line, "--", $1)) - parseContext.recover(); + parseContext.variableCheck($1); + parseContext.lValueErrorCheck($2.line, "--", $1); $$ = parseContext.intermediate.addUnaryMath(EOpPostDecrement, $1, $2.line); if ($$ == 0) { parseContext.unaryOpError($2.line, "--", $1->getCompleteString()); - parseContext.recover(); $$ = $1; } } @@ -457,8 +435,7 @@ postfix_expression integer_expression : expression { - if (parseContext.integerErrorCheck($1, "[]")) - parseContext.recover(); + parseContext.integerCheck($1, "[]"); $$ = $1; } ; @@ -472,7 +449,6 @@ function_call int length; if ($1.intermNode->getAsTyped() == 0 || ! $1.intermNode->getAsTyped()->getType().isArray() || $1.intermNode->getAsTyped()->getType().getArraySize() == 0) { parseContext.error($1.line, "", fnCall->getName().c_str(), "array must be declared with a size before using this method"); - parseContext.recover(); length = 1; } else length = $1.intermNode->getAsTyped()->getType().getArraySize(); @@ -487,19 +463,19 @@ function_call // Their parameters will be verified algorithmically. // TType type(EbtVoid); // use this to get the type back - if (parseContext.constructorErrorCheck($1.line, $1.intermNode, *fnCall, op, &type)) { + if (parseContext.constructorError($1.line, $1.intermNode, *fnCall, op, &type)) { $$ = 0; } else { // // It's a constructor, of type 'type'. // $$ = parseContext.addConstructor($1.intermNode, type, op, fnCall, $1.line); + if ($$ == 0) + parseContext.error($1.line, "cannot construct with these arguments", type.getCompleteString().c_str(), ""); } - if ($$ == 0) { - parseContext.recover(); + if ($$ == 0) $$ = parseContext.intermediate.setAggregateOperator(0, op, type, $1.line); - } } else { // // Not a constructor. Find it in the symbol table. @@ -538,10 +514,8 @@ function_call for (int i = 0; i < fnCandidate->getParamCount(); ++i) { qual = (*fnCandidate)[i].type->getQualifier().storage; if (qual == EvqOut || qual == EvqInOut) { - if (parseContext.lValueErrorCheck($$->getLine(), "assign", $$->getAsAggregate()->getSequence()[i]->getAsTyped())) { + if (parseContext.lValueErrorCheck($$->getLine(), "assign", $$->getAsAggregate()->getSequence()[i]->getAsTyped())) parseContext.error($1.intermNode->getLine(), "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error", ""); - parseContext.recover(); - } } qualifierList.push_back(qual); } @@ -557,7 +531,6 @@ function_call constUnion *unionArray = new constUnion[1]; unionArray->setDConst(0.0); $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtFloat, EvqConst), $1.line); - parseContext.recover(); } } delete fnCall; @@ -743,7 +716,6 @@ function_identifier } if (op == EOpNull) { parseContext.error($1.line, "cannot construct this type", TType::getBasicString($1.basicType), ""); - parseContext.recover(); $1.basicType = EbtFloat; op = EOpConstructFloat; } @@ -765,21 +737,16 @@ function_identifier if (method->getObject()->isArray()) { $$.function = new TFunction(&method->getMethodName(), TType(EbtInt), EOpArrayLength); $$.intermNode = method->getObject(); - } else { + } else parseContext.error(method->getLine(), "only arrays have methods", "", ""); - parseContext.recover(); - } } else { TIntermSymbol* symbol = $1->getAsSymbolNode(); if (symbol) { - if (parseContext.reservedErrorCheck(symbol->getLine(), symbol->getSymbol())) - parseContext.recover(); + parseContext.reservedErrorCheck(symbol->getLine(), symbol->getSymbol()); TFunction *function = new TFunction(&symbol->getSymbol(), TType(EbtVoid)); $$.function = function; - } else { + } else parseContext.error($1->getLine(), "function call, method or subroutine call expected", "", ""); - parseContext.recover(); - } } if ($$.function == 0) { @@ -792,26 +759,22 @@ function_identifier unary_expression : postfix_expression { - parseContext.variableErrorCheck($1); + parseContext.variableCheck($1); $$ = $1; } | INC_OP unary_expression { - if (parseContext.lValueErrorCheck($1.line, "++", $2)) - parseContext.recover(); + parseContext.lValueErrorCheck($1.line, "++", $2); $$ = parseContext.intermediate.addUnaryMath(EOpPreIncrement, $2, $1.line); if ($$ == 0) { parseContext.unaryOpError($1.line, "++", $2->getCompleteString()); - parseContext.recover(); $$ = $2; } } | DEC_OP unary_expression { - if (parseContext.lValueErrorCheck($1.line, "--", $2)) - parseContext.recover(); + parseContext.lValueErrorCheck($1.line, "--", $2); $$ = parseContext.intermediate.addUnaryMath(EOpPreDecrement, $2, $1.line); if ($$ == 0) { parseContext.unaryOpError($1.line, "--", $2->getCompleteString()); - parseContext.recover(); $$ = $2; } } @@ -827,7 +790,6 @@ unary_expression default: break; // some compilers want this } parseContext.unaryOpError($1.line, errorOp, $2->getCompleteString()); - parseContext.recover(); $$ = $2; } } else @@ -850,7 +812,6 @@ multiplicative_expression $$ = parseContext.intermediate.addBinaryMath(EOpMul, $1, $3, $2.line); if ($$ == 0) { parseContext.binaryOpError($2.line, "*", $1->getCompleteString(), $3->getCompleteString()); - parseContext.recover(); $$ = $1; } } @@ -858,7 +819,6 @@ multiplicative_expression $$ = parseContext.intermediate.addBinaryMath(EOpDiv, $1, $3, $2.line); if ($$ == 0) { parseContext.binaryOpError($2.line, "/", $1->getCompleteString(), $3->getCompleteString()); - parseContext.recover(); $$ = $1; } } @@ -866,7 +826,6 @@ multiplicative_expression $$ = parseContext.intermediate.addBinaryMath(EOpMod, $1, $3, $2.line); if ($$ == 0) { parseContext.binaryOpError($2.line, "%", $1->getCompleteString(), $3->getCompleteString()); - parseContext.recover(); $$ = $1; } } @@ -878,7 +837,6 @@ additive_expression $$ = parseContext.intermediate.addBinaryMath(EOpAdd, $1, $3, $2.line); if ($$ == 0) { parseContext.binaryOpError($2.line, "+", $1->getCompleteString(), $3->getCompleteString()); - parseContext.recover(); $$ = $1; } } @@ -886,7 +844,6 @@ additive_expression $$ = parseContext.intermediate.addBinaryMath(EOpSub, $1, $3, $2.line); if ($$ == 0) { parseContext.binaryOpError($2.line, "-", $1->getCompleteString(), $3->getCompleteString()); - parseContext.recover(); $$ = $1; } } @@ -899,7 +856,6 @@ shift_expression $$ = parseContext.intermediate.addBinaryMath(EOpLeftShift, $1, $3, $2.line); if ($$ == 0) { parseContext.binaryOpError($2.line, "<<", $1->getCompleteString(), $3->getCompleteString()); - parseContext.recover(); $$ = $1; } } @@ -908,7 +864,6 @@ shift_expression $$ = parseContext.intermediate.addBinaryMath(EOpRightShift, $1, $3, $2.line); if ($$ == 0) { parseContext.binaryOpError($2.line, ">>", $1->getCompleteString(), $3->getCompleteString()); - parseContext.recover(); $$ = $1; } } @@ -920,7 +875,6 @@ relational_expression $$ = parseContext.intermediate.addBinaryMath(EOpLessThan, $1, $3, $2.line); if ($$ == 0) { parseContext.binaryOpError($2.line, "<", $1->getCompleteString(), $3->getCompleteString()); - parseContext.recover(); constUnion *unionArray = new constUnion[1]; unionArray->setBConst(false); $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.line); @@ -930,7 +884,6 @@ relational_expression $$ = parseContext.intermediate.addBinaryMath(EOpGreaterThan, $1, $3, $2.line); if ($$ == 0) { parseContext.binaryOpError($2.line, ">", $1->getCompleteString(), $3->getCompleteString()); - parseContext.recover(); constUnion *unionArray = new constUnion[1]; unionArray->setBConst(false); $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.line); @@ -940,7 +893,6 @@ relational_expression $$ = parseContext.intermediate.addBinaryMath(EOpLessThanEqual, $1, $3, $2.line); if ($$ == 0) { parseContext.binaryOpError($2.line, "<=", $1->getCompleteString(), $3->getCompleteString()); - parseContext.recover(); constUnion *unionArray = new constUnion[1]; unionArray->setBConst(false); $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.line); @@ -950,7 +902,6 @@ relational_expression $$ = parseContext.intermediate.addBinaryMath(EOpGreaterThanEqual, $1, $3, $2.line); if ($$ == 0) { parseContext.binaryOpError($2.line, ">=", $1->getCompleteString(), $3->getCompleteString()); - parseContext.recover(); constUnion *unionArray = new constUnion[1]; unionArray->setBConst(false); $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.line); @@ -964,7 +915,6 @@ equality_expression $$ = parseContext.intermediate.addBinaryMath(EOpEqual, $1, $3, $2.line); if ($$ == 0) { parseContext.binaryOpError($2.line, "==", $1->getCompleteString(), $3->getCompleteString()); - parseContext.recover(); constUnion *unionArray = new constUnion[1]; unionArray->setBConst(false); $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.line); @@ -975,7 +925,6 @@ equality_expression $$ = parseContext.intermediate.addBinaryMath(EOpNotEqual, $1, $3, $2.line); if ($$ == 0) { parseContext.binaryOpError($2.line, "!=", $1->getCompleteString(), $3->getCompleteString()); - parseContext.recover(); constUnion *unionArray = new constUnion[1]; unionArray->setBConst(false); $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.line); @@ -991,7 +940,6 @@ and_expression $$ = parseContext.intermediate.addBinaryMath(EOpAnd, $1, $3, $2.line); if ($$ == 0) { parseContext.binaryOpError($2.line, "&", $1->getCompleteString(), $3->getCompleteString()); - parseContext.recover(); $$ = $1; } } @@ -1004,7 +952,6 @@ exclusive_or_expression $$ = parseContext.intermediate.addBinaryMath(EOpExclusiveOr, $1, $3, $2.line); if ($$ == 0) { parseContext.binaryOpError($2.line, "^", $1->getCompleteString(), $3->getCompleteString()); - parseContext.recover(); $$ = $1; } } @@ -1017,7 +964,6 @@ inclusive_or_expression $$ = parseContext.intermediate.addBinaryMath(EOpInclusiveOr, $1, $3, $2.line); if ($$ == 0) { parseContext.binaryOpError($2.line, "|", $1->getCompleteString(), $3->getCompleteString()); - parseContext.recover(); $$ = $1; } } @@ -1029,7 +975,6 @@ logical_and_expression $$ = parseContext.intermediate.addBinaryMath(EOpLogicalAnd, $1, $3, $2.line); if ($$ == 0) { parseContext.binaryOpError($2.line, "&&", $1->getCompleteString(), $3->getCompleteString()); - parseContext.recover(); constUnion *unionArray = new constUnion[1]; unionArray->setBConst(false); $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.line); @@ -1043,7 +988,6 @@ logical_xor_expression $$ = parseContext.intermediate.addBinaryMath(EOpLogicalXor, $1, $3, $2.line); if ($$ == 0) { parseContext.binaryOpError($2.line, "^^", $1->getCompleteString(), $3->getCompleteString()); - parseContext.recover(); constUnion *unionArray = new constUnion[1]; unionArray->setBConst(false); $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.line); @@ -1057,7 +1001,6 @@ logical_or_expression $$ = parseContext.intermediate.addBinaryMath(EOpLogicalOr, $1, $3, $2.line); if ($$ == 0) { parseContext.binaryOpError($2.line, "||", $1->getCompleteString(), $3->getCompleteString()); - parseContext.recover(); constUnion *unionArray = new constUnion[1]; unionArray->setBConst(false); $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.line); @@ -1068,13 +1011,11 @@ logical_or_expression conditional_expression : logical_or_expression { $$ = $1; } | logical_or_expression QUESTION expression COLON assignment_expression { - if (parseContext.boolErrorCheck($2.line, $1)) - parseContext.recover(); + parseContext.boolCheck($2.line, $1); $$ = parseContext.intermediate.addSelection($1, $3, $5, $2.line); if ($$ == 0) { parseContext.binaryOpError($2.line, ":", $3->getCompleteString(), $5->getCompleteString()); - parseContext.recover(); $$ = $5; } } @@ -1083,12 +1024,10 @@ conditional_expression assignment_expression : conditional_expression { $$ = $1; } | unary_expression assignment_operator assignment_expression { - if (parseContext.lValueErrorCheck($2.line, "assign", $1)) - parseContext.recover(); + parseContext.lValueErrorCheck($2.line, "assign", $1); $$ = parseContext.intermediate.addAssign($2.op, $1, $3, $2.line); if ($$ == 0) { parseContext.assignError($2.line, "assign", $1->getCompleteString(), $3->getCompleteString()); - parseContext.recover(); $$ = $1; } else if (($1->isArray() || $3->isArray())) parseContext.profileRequires($2.line, ENoProfile, 120, "GL_3DL_array_objects", "="); @@ -1132,7 +1071,6 @@ expression $$ = parseContext.intermediate.addComma($1, $3, $2.line); if ($$ == 0) { parseContext.binaryOpError($2.line, ",", $1->getCompleteString(), $3->getCompleteString()); - parseContext.recover(); $$ = $3; } } @@ -1140,8 +1078,7 @@ expression constant_expression : conditional_expression { - if (parseContext.constErrorCheck($1)) - parseContext.recover(); + parseContext.constCheck($1); $$ = $1; } ; @@ -1224,14 +1161,10 @@ function_prototype if (prevDec) { if (prevDec->getReturnType() != $1->getReturnType()) { parseContext.error($2.line, "overloaded functions must have the same return type", $1->getReturnType().getCompleteTypeString().c_str(), ""); - parseContext.recover(); } for (int i = 0; i < prevDec->getParamCount(); ++i) { - if ((*prevDec)[i].type->getQualifier().storage != (*$1)[i].type->getQualifier().storage) { - parseContext.error($2.line, "overloaded functions must have the same parameter qualifiers", - (*$1)[i].type->getStorageQualifierString(), ""); - parseContext.recover(); - } + if ((*prevDec)[i].type->getQualifier().storage != (*$1)[i].type->getQualifier().storage) + parseContext.error($2.line, "overloaded functions must have the same parameter qualifiers", (*$1)[i].type->getStorageQualifierString(), ""); } } @@ -1243,10 +1176,8 @@ function_prototype $$.function = $1; $$.line = $2.line; - if (! parseContext.symbolTable.insert(*$$.function)) { + if (! parseContext.symbolTable.insert(*$$.function)) parseContext.error($2.line, "illegal redeclaration", $$.function->getName().c_str(), ""); - parseContext.recover(); - } } ; @@ -1279,7 +1210,6 @@ function_header_with_parameters // This parameter > first is void // parseContext.error($2.line, "cannot be an argument type except for '(void)'", "void", ""); - parseContext.recover(); delete $3.param.type; } else { // Add the parameter @@ -1294,7 +1224,6 @@ function_header if ($1.qualifier.storage != EvqGlobal && $1.qualifier.storage != EvqTemporary) { parseContext.error($2.line, "no qualifiers allowed for function return", getStorageQualifierString($1.qualifier.storage), ""); - parseContext.recover(); } // Add the function as a prototype after parsing it (we do not support recursion) @@ -1314,10 +1243,8 @@ parameter_declarator } if ($1.basicType == EbtVoid) { parseContext.error($2.line, "illegal use of type 'void'", $2.string->c_str(), ""); - parseContext.recover(); } - if (parseContext.reservedErrorCheck($2.line, *$2.string)) - parseContext.recover(); + parseContext.reservedErrorCheck($2.line, *$2.string); TParameter param = {$2.string, new TType($1)}; $$.line = $2.line; @@ -1329,11 +1256,8 @@ parameter_declarator parseContext.profileRequires($1.line, EEsProfile, 300, 0, "arrayed type"); } - if (parseContext.arraySizeRequiredErrorCheck($3.line, $3.arraySizes->front())) - parseContext.recover(); - - if (parseContext.reservedErrorCheck($2.line, *$2.string)) - parseContext.recover(); + parseContext.arraySizeRequiredCheck($3.line, $3.arraySizes->front()); + parseContext.reservedErrorCheck($2.line, *$2.string); $1.arraySizes = $3.arraySizes; @@ -1352,18 +1276,14 @@ parameter_declaration if ($1.qualifier.precision != EpqNone) $$.param.type->getQualifier().precision = $1.qualifier.precision; - if (parseContext.parameterSamplerErrorCheck($2.line, $1.qualifier.storage, *$$.param.type)) - parseContext.recover(); - if (parseContext.paramErrorCheck($1.line, $1.qualifier.storage, $$.param.type)) - parseContext.recover(); + parseContext.parameterSamplerCheck($2.line, $1.qualifier.storage, *$$.param.type); + parseContext.paramCheck($1.line, $1.qualifier.storage, $$.param.type); } | parameter_declarator { $$ = $1; - if (parseContext.parameterSamplerErrorCheck($1.line, EvqIn, *$1.param.type)) - parseContext.recover(); - if (parseContext.paramErrorCheck($1.line, EvqTemporary, $$.param.type)) - parseContext.recover(); + parseContext.parameterSamplerCheck($1.line, EvqIn, *$1.param.type); + parseContext.paramCheck($1.line, EvqTemporary, $$.param.type); } // // Without name @@ -1373,18 +1293,14 @@ parameter_declaration if ($1.qualifier.precision != EpqNone) $$.param.type->getQualifier().precision = $1.qualifier.precision; - if (parseContext.parameterSamplerErrorCheck($2.line, $1.qualifier.storage, *$$.param.type)) - parseContext.recover(); - if (parseContext.paramErrorCheck($1.line, $1.qualifier.storage, $$.param.type)) - parseContext.recover(); + parseContext.parameterSamplerCheck($2.line, $1.qualifier.storage, *$$.param.type); + parseContext.paramCheck($1.line, $1.qualifier.storage, $$.param.type); } | parameter_type_specifier { $$ = $1; - if (parseContext.parameterSamplerErrorCheck($1.line, EvqIn, *$1.param.type)) - parseContext.recover(); - if (parseContext.paramErrorCheck($1.line, EvqTemporary, $$.param.type)) - parseContext.recover(); + parseContext.parameterSamplerCheck($1.line, EvqIn, *$1.param.type); + parseContext.paramCheck($1.line, EvqTemporary, $$.param.type); } ; @@ -1401,43 +1317,33 @@ init_declarator_list } | init_declarator_list COMMA IDENTIFIER { $$ = $1; - if (parseContext.nonInitConstErrorCheck($3.line, *$3.string, $$.type)) - parseContext.recover(); - - if (parseContext.nonInitErrorCheck($3.line, *$3.string, $$.type)) - parseContext.recover(); + parseContext.nonInitConstCheck($3.line, *$3.string, $$.type); + parseContext.nonInitCheck($3.line, *$3.string, $$.type); } | init_declarator_list COMMA IDENTIFIER array_specifier { - if (parseContext.nonInitConstErrorCheck($3.line, *$3.string, $1.type)) - parseContext.recover(); + parseContext.nonInitConstCheck($3.line, *$3.string, $1.type); $$ = $1; - if (parseContext.arrayQualifierErrorCheck($4.line, $1.type)) - parseContext.recover(); - else { + if (! parseContext.arrayQualifierError($4.line, $1.type)) { $1.type.arraySizes = $4.arraySizes; TVariable* variable; - if (parseContext.arrayErrorCheck($4.line, *$3.string, $1.type, variable)) - parseContext.recover(); + parseContext.arrayCheck($4.line, *$3.string, $1.type, variable); } } | init_declarator_list COMMA IDENTIFIER array_specifier EQUAL initializer { $$ = $1; TVariable* variable = 0; - if (parseContext.arrayQualifierErrorCheck($4.line, $1.type)) - parseContext.recover(); - else { + if (! parseContext.arrayQualifierError($4.line, $1.type)) { $1.type.arraySizes = $4.arraySizes; - if (parseContext.arrayErrorCheck($4.line, *$3.string, $1.type, variable)) - parseContext.recover(); + parseContext.arrayCheck($4.line, *$3.string, $1.type, variable); } parseContext.profileRequires($5.line, ENoProfile, 120, "GL_3DL_array_objects", "initializer"); TIntermNode* intermNode; - if (!parseContext.executeInitializer($3.line, *$3.string, $1.type, $6, intermNode, variable)) { + if (! parseContext.executeInitializerError($3.line, *$3.string, $1.type, $6, intermNode, variable)) { // // build the intermediate representation // @@ -1445,16 +1351,14 @@ init_declarator_list $$.intermAggregate = parseContext.intermediate.growAggregate($1.intermNode, intermNode, $5.line); else $$.intermAggregate = $1.intermAggregate; - } else { - parseContext.recover(); + } else $$.intermAggregate = 0; - } } | init_declarator_list COMMA IDENTIFIER EQUAL initializer { $$ = $1; TIntermNode* intermNode; - if (!parseContext.executeInitializer($3.line, *$3.string, $1.type, $5, intermNode)) { + if (!parseContext.executeInitializerError($3.line, *$3.string, $1.type, $5, intermNode)) { // // build the intermediate representation // @@ -1462,10 +1366,8 @@ init_declarator_list $$.intermAggregate = parseContext.intermediate.growAggregate($1.intermNode, intermNode, $4.line); else $$.intermAggregate = $1.intermAggregate; - } else { - parseContext.recover(); + } else $$.intermAggregate = 0; - } } ; @@ -1479,28 +1381,21 @@ single_declaration $$.intermAggregate = 0; $$.type = $1; - if (parseContext.nonInitConstErrorCheck($2.line, *$2.string, $$.type)) - parseContext.recover(); - - if (parseContext.nonInitErrorCheck($2.line, *$2.string, $$.type)) - parseContext.recover(); + parseContext.nonInitConstCheck($2.line, *$2.string, $$.type); + parseContext.nonInitCheck($2.line, *$2.string, $$.type); parseContext.updateDefaults($2.line, $$.type, $2.string); } | fully_specified_type IDENTIFIER array_specifier { $$.intermAggregate = 0; - if (parseContext.nonInitConstErrorCheck($2.line, *$2.string, $1)) - parseContext.recover(); + parseContext.nonInitConstCheck($2.line, *$2.string, $1); $$.type = $1; - if (parseContext.arrayQualifierErrorCheck($3.line, $1)) - parseContext.recover(); - else { + if (! parseContext.arrayQualifierError($3.line, $1)) { $1.arraySizes = $3.arraySizes; TVariable* variable; - if (parseContext.arrayErrorCheck($3.line, *$2.string, $1, variable)) - parseContext.recover(); + parseContext.arrayCheck($3.line, *$2.string, $1, variable); } parseContext.updateDefaults($2.line, $$.type, $2.string); } @@ -1509,18 +1404,15 @@ single_declaration $$.type = $1; TVariable* variable = 0; - if (parseContext.arrayQualifierErrorCheck($3.line, $1)) - parseContext.recover(); - else { + if (! parseContext.arrayQualifierError($3.line, $1)) { $1.arraySizes = $3.arraySizes; - if (parseContext.arrayErrorCheck($3.line, *$2.string, $1, variable)) - parseContext.recover(); + parseContext.arrayCheck($3.line, *$2.string, $1, variable); } parseContext.profileRequires($4.line, ENoProfile, 120, "GL_3DL_array_objects", "initializer"); TIntermNode* intermNode; - if (!parseContext.executeInitializer($2.line, *$2.string, $1, $5, intermNode, variable)) { + if (!parseContext.executeInitializerError($2.line, *$2.string, $1, $5, intermNode, variable)) { // // Build intermediate representation // @@ -1528,16 +1420,14 @@ single_declaration $$.intermAggregate = parseContext.intermediate.makeAggregate(intermNode, $4.line); else $$.intermAggregate = 0; - } else { - parseContext.recover(); + } else $$.intermAggregate = 0; - } } | fully_specified_type IDENTIFIER EQUAL initializer { $$.type = $1; TIntermNode* intermNode; - if (!parseContext.executeInitializer($2.line, *$2.string, $1, $4, intermNode)) { + if (!parseContext.executeInitializerError($2.line, *$2.string, $1, $4, intermNode)) { // // Build intermediate representation // @@ -1545,10 +1435,8 @@ single_declaration $$.intermAggregate = parseContext.intermediate.makeAggregate(intermNode, $3.line); else $$.intermAggregate = 0; - } else { - parseContext.recover(); + } else $$.intermAggregate = 0; - } } // Grammar Note: No 'enum', or 'typedef'. @@ -1563,21 +1451,17 @@ fully_specified_type } } | type_qualifier type_specifier { - if (parseContext.globalQualifierFixAndErrorCheck($1.line, $1.qualifier, $2)) - parseContext.recover(); + parseContext.globalQualifierFix($1.line, $1.qualifier, $2); if ($2.arraySizes) { parseContext.profileRequires($2.line, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type"); parseContext.profileRequires($2.line, EEsProfile, 300, 0, "arrayed type"); } - if ($2.arraySizes && parseContext.arrayQualifierErrorCheck($2.line, $1)) { - parseContext.recover(); + if ($2.arraySizes && parseContext.arrayQualifierError($2.line, $1)) $2.arraySizes = 0; - } - if (parseContext.mergeQualifiersErrorCheck($2.line, $2, $1, true)) - parseContext.recover(); + parseContext.mergeQualifiers($2.line, $2, $1, true); $$ = $2; @@ -1596,24 +1480,21 @@ invariant_qualifier interpolation_qualifier : SMOOTH { - if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "smooth")) - parseContext.recover(); + parseContext.globalCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "smooth"); parseContext.profileRequires($1.line, ENoProfile, 130, 0, "smooth"); parseContext.profileRequires($1.line, EEsProfile, 300, 0, "smooth"); $$.init($1.line); $$.qualifier.smooth = true; } | FLAT { - if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "flat")) - parseContext.recover(); + parseContext.globalCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "flat"); parseContext.profileRequires($1.line, ENoProfile, 130, 0, "flat"); parseContext.profileRequires($1.line, EEsProfile, 300, 0, "flat"); $$.init($1.line); $$.qualifier.flat = true; } | NOPERSPECTIVE { - if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "noperspective")) - parseContext.recover(); + parseContext.globalCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "noperspective"); parseContext.requireProfile($1.line, static_cast(~EEsProfileMask), "noperspective"); parseContext.profileRequires($1.line, ENoProfile, 130, 0, "noperspective"); $$.init($1.line); @@ -1667,8 +1548,7 @@ type_qualifier if ($$.basicType == EbtVoid) $$.basicType = $2.basicType; - if (parseContext.mergeQualifiersErrorCheck($$.line, $$, $2, false)) - parseContext.recover(); + parseContext.mergeQualifiers($$.line, $$, $2, false); } ; @@ -1708,8 +1588,7 @@ storage_qualifier parseContext.requireNotRemoved($1.line, ECoreProfile, 420, "attribute"); parseContext.requireNotRemoved($1.line, EEsProfile, 300, "attribute"); - if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "attribute")) - parseContext.recover(); + parseContext.globalCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "attribute"); $$.init($1.line); $$.qualifier.storage = EvqVaryingIn; @@ -1720,8 +1599,7 @@ storage_qualifier parseContext.requireNotRemoved($1.line, ECoreProfile, 420, "varying"); parseContext.requireNotRemoved($1.line, EEsProfile, 300, "varying"); - if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "varying")) - parseContext.recover(); + parseContext.globalCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "varying"); $$.init($1.line); if (parseContext.language == EShLangVertex) @@ -1730,52 +1608,44 @@ storage_qualifier $$.qualifier.storage = EvqVaryingIn; } | INOUT { - if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "out")) - parseContext.recover(); + parseContext.globalCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "out"); $$.init($1.line); $$.qualifier.storage = EvqInOut; } | IN { - if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "in")) - parseContext.recover(); + parseContext.globalCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "in"); $$.init($1.line); $$.qualifier.storage = EvqIn; } | OUT { - if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "out")) - parseContext.recover(); + parseContext.globalCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "out"); $$.init($1.line); $$.qualifier.storage = EvqOut; } | CENTROID { parseContext.profileRequires($1.line, ENoProfile, 120, 0, "centroid"); parseContext.profileRequires($1.line, EEsProfile, 300, 0, "centroid"); - if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "centroid")) - parseContext.recover(); + parseContext.globalCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "centroid"); $$.init($1.line); $$.qualifier.centroid = true; } | PATCH { - if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "patch")) - parseContext.recover(); + parseContext.globalCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "patch"); $$.init($1.line); $$.qualifier.patch = true; } | SAMPLE { - if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "sample")) - parseContext.recover(); + parseContext.globalCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "sample"); $$.init($1.line); $$.qualifier.sample = true; } | UNIFORM { - if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "uniform")) - parseContext.recover(); + parseContext.globalCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "uniform"); $$.init($1.line); $$.qualifier.storage = EvqUniform; } | BUFFER { - if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "buffer")) - parseContext.recover(); + parseContext.globalCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "buffer"); $$.init($1.line); $$.qualifier.storage = EvqUniform; // TODO: 4.0 functionality: implement BUFFER } @@ -1807,14 +1677,12 @@ storage_qualifier $$.qualifier.writeonly = true; } | SUBROUTINE { - if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "subroutine")) - parseContext.recover(); + parseContext.globalCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "subroutine"); $$.init($1.line); $$.qualifier.storage = EvqUniform; } | SUBROUTINE LEFT_PAREN type_name_list RIGHT_PAREN { - if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "subroutine")) - parseContext.recover(); + parseContext.globalCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "subroutine"); $$.init($1.line); $$.qualifier.storage = EvqUniform; // TODO: 4.0 semantics: subroutines @@ -1854,8 +1722,7 @@ array_specifier $$.arraySizes = NewPoolTArraySizes(); int size; - if (parseContext.arraySizeErrorCheck($2->getLine(), $2, size)) - parseContext.recover(); + parseContext.arraySizeCheck($2->getLine(), $2, size); $$.arraySizes->push_back(size); } | array_specifier LEFT_BRACKET RIGHT_BRACKET { @@ -1866,8 +1733,7 @@ array_specifier $$ = $1; int size; - if (parseContext.arraySizeErrorCheck($3->getLine(), $3, size)) - parseContext.recover(); + parseContext.arraySizeCheck($3->getLine(), $3, size); $$.arraySizes->push_back(size); } ; @@ -2504,10 +2370,8 @@ type_specifier_nonarray $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtStruct; $$.userDef = &structure; - } else { + } else parseContext.error($1.line, "expected type name", $1.string->c_str(), ""); - parseContext.recover(); - } } ; @@ -2541,10 +2405,8 @@ struct_specifier TType* structure = new TType($4, *$2.string); TVariable* userTypeDef = new TVariable($2.string, *structure, true); - if (! parseContext.symbolTable.insert(*userTypeDef)) { + if (! parseContext.symbolTable.insert(*userTypeDef)) parseContext.error($2.line, "redefinition", $2.string->c_str(), "struct"); - parseContext.recover(); - } $$.init($1.line); $$.basicType = EbtStruct; $$.userDef = structure; @@ -2565,10 +2427,8 @@ struct_declaration_list $$ = $1; for (unsigned int i = 0; i < $2->size(); ++i) { for (unsigned int j = 0; j < $$->size(); ++j) { - if ((*$$)[j].type->getFieldName() == (*$2)[i].type->getFieldName()) { + if ((*$$)[j].type->getFieldName() == (*$2)[i].type->getFieldName()) parseContext.error((*$2)[i].line, "duplicate member name:", "", (*$2)[i].type->getFieldName().c_str()); - parseContext.recover(); - } } $$->push_back((*$2)[i]); } @@ -2584,9 +2444,8 @@ struct_declaration $$ = $2; - if (parseContext.voidErrorCheck($1.line, (*$2)[0].type->getFieldName(), $1)) { - parseContext.recover(); - } + parseContext.voidErrorCheck($1.line, (*$2)[0].type->getFieldName(), $1); + for (unsigned int i = 0; i < $$->size(); ++i) (*$$)[i].type->mergeType($1); } @@ -2598,10 +2457,9 @@ struct_declaration $$ = $3; - if (parseContext.voidErrorCheck($2.line, (*$3)[0].type->getFieldName(), $2)) - parseContext.recover(); - if (parseContext.mergeQualifiersErrorCheck($2.line, $2, $1, true)) - parseContext.recover(); + parseContext.voidErrorCheck($2.line, (*$3)[0].type->getFieldName(), $2); + parseContext.mergeQualifiers($2.line, $2, $1, true); + for (unsigned int i = 0; i < $$->size(); ++i) (*$$)[i].type->mergeType($2); } @@ -2728,8 +2586,7 @@ expression_statement selection_statement : IF LEFT_PAREN expression RIGHT_PAREN selection_rest_statement { - if (parseContext.boolErrorCheck($1.line, $3)) - parseContext.recover(); + parseContext.boolCheck($1.line, $3); $$ = parseContext.intermediate.addSelection($3, $5, $1.line); } ; @@ -2749,20 +2606,16 @@ condition // In 1996 c++ draft, conditions can include single declarations : expression { $$ = $1; - if (parseContext.boolErrorCheck($1->getLine(), $1)) - parseContext.recover(); + parseContext.boolCheck($1->getLine(), $1); } | fully_specified_type IDENTIFIER EQUAL initializer { TIntermNode* intermNode; - if (parseContext.boolErrorCheck($2.line, $1)) - parseContext.recover(); + parseContext.boolCheck($2.line, $1); - if (!parseContext.executeInitializer($2.line, *$2.string, $1, $4, intermNode)) - $$ = $4; - else { - parseContext.recover(); + if (parseContext.executeInitializerError($2.line, *$2.string, $1, $4, intermNode)) $$ = 0; - } + else + $$ = $4; } ; @@ -2807,8 +2660,7 @@ iteration_statement --parseContext.loopNestingLevel; } | DO { ++parseContext.loopNestingLevel; } statement WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON { - if (parseContext.boolErrorCheck($8.line, $6)) - parseContext.recover(); + parseContext.boolCheck($8.line, $6); $$ = parseContext.intermediate.addLoop($3, $6, 0, false, $4.line); --parseContext.loopNestingLevel; @@ -2860,36 +2712,27 @@ for_rest_statement jump_statement : CONTINUE SEMICOLON { - if (parseContext.loopNestingLevel <= 0) { + if (parseContext.loopNestingLevel <= 0) parseContext.error($1.line, "continue statement only allowed in loops", "", ""); - parseContext.recover(); - } $$ = parseContext.intermediate.addBranch(EOpContinue, $1.line); } | BREAK SEMICOLON { - if (parseContext.loopNestingLevel + parseContext.switchSequenceStack.size() <= 0) { + if (parseContext.loopNestingLevel + parseContext.switchSequenceStack.size() <= 0) parseContext.error($1.line, "break statement only allowed in switch and loops", "", ""); - parseContext.recover(); - } $$ = parseContext.intermediate.addBranch(EOpBreak, $1.line); } | RETURN SEMICOLON { $$ = parseContext.intermediate.addBranch(EOpReturn, $1.line); - if (parseContext.currentFunctionType->getBasicType() != EbtVoid) { + if (parseContext.currentFunctionType->getBasicType() != EbtVoid) parseContext.error($1.line, "non-void function must return a value", "return", ""); - parseContext.recover(); - } } | RETURN expression SEMICOLON { $$ = parseContext.intermediate.addBranch(EOpReturn, $2, $1.line); parseContext.functionReturnsValue = true; - if (parseContext.currentFunctionType->getBasicType() == EbtVoid) { + if (parseContext.currentFunctionType->getBasicType() == EbtVoid) parseContext.error($1.line, "void function cannot return a value", "return", ""); - parseContext.recover(); - } else if (*(parseContext.currentFunctionType) != $2->getType()) { + else if (*(parseContext.currentFunctionType) != $2->getType()) parseContext.error($1.line, "function return is not matching type:", "return", ""); - parseContext.recover(); - } } | DISCARD SEMICOLON { parseContext.requireStage($1.line, EShLangFragmentMask, "discard"); @@ -2925,10 +2768,8 @@ function_definition TSymbol* symbol = parseContext.symbolTable.find(function.getMangledName()); TFunction* prevDec = symbol ? symbol->getAsFunction() : 0; - if (! prevDec) { + if (! prevDec) parseContext.error($1.line, "can't find function name", function.getName().c_str(), ""); - parseContext.recover(); - } // // Note: 'prevDec' could be 'function' if this is the first time we've seen function @@ -2940,7 +2781,6 @@ function_definition // Then this function already has a body. // parseContext.error($1.line, "function already has a body", function.getName().c_str(), ""); - parseContext.recover(); } if (prevDec) { prevDec->setDefined(); @@ -2956,14 +2796,10 @@ function_definition // Raise error message if main function takes any parameters or return anything other than void // if (function.getName() == "main") { - if (function.getParamCount() > 0) { + if (function.getParamCount() > 0) parseContext.error($1.line, "function cannot take any parameter(s)", function.getName().c_str(), ""); - parseContext.recover(); - } - if (function.getReturnType().getBasicType() != EbtVoid) { + if (function.getReturnType().getBasicType() != EbtVoid) parseContext.error($1.line, "", function.getReturnType().getCompleteTypeString().c_str(), "main function cannot return a value"); - parseContext.recover(); - } } // @@ -2989,7 +2825,6 @@ function_definition // if (! parseContext.symbolTable.insert(*variable)) { parseContext.error($1.line, "redefinition", variable->getName().c_str(), ""); - parseContext.recover(); delete variable; } // @@ -3016,10 +2851,8 @@ function_definition } compound_statement_no_new_scope { // May be best done as post process phase on intermediate code - if (parseContext.currentFunctionType->getBasicType() != EbtVoid && ! parseContext.functionReturnsValue) { + if (parseContext.currentFunctionType->getBasicType() != EbtVoid && ! parseContext.functionReturnsValue) parseContext.error($1.line, "function does not return a value:", "", $1.function->getName().c_str()); - parseContext.recover(); - } parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); $$ = parseContext.intermediate.growAggregate($1.intermAggregate, $3, 0); parseContext.intermediate.setAggregateOperator($$, EOpFunction, $1.function->getReturnType(), $1.line);