Remove recover() from ParseContext

This call is a no-op. The shader parser is intended to almost always
recover from errors, so including it doesn't clarify the code either.
It's simpler to remove it entirely.

BUG=angleproject:911
TEST=angle_unittests

Change-Id: I0feae097c2807c8e9559672e7a3d50a2fc4fbdea
Reviewed-on: https://chromium-review.googlesource.com/367040
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
index 33ec5bb..b23ee52 100644
--- a/src/compiler/translator/ParseContext.cpp
+++ b/src/compiler/translator/ParseContext.cpp
@@ -132,12 +132,6 @@
 //
 ////////////////////////////////////////////////////////////////////////
 
-//
-// Track whether errors have occurred.
-//
-void TParseContext::recover()
-{
-}
 
 //
 // Used by flex/bison to output all syntax and parsing errors.
@@ -173,7 +167,6 @@
     if (isError)
     {
         error(loc, reason, token, extraInfo);
-        recover();
     }
     else
     {
@@ -220,33 +213,32 @@
     error(line, " wrong operand types ", op, extraInfo.c_str());
 }
 
-bool TParseContext::precisionErrorCheck(const TSourceLoc &line,
+void TParseContext::precisionErrorCheck(const TSourceLoc &line,
                                         TPrecision precision,
                                         TBasicType type)
 {
     if (!mChecksPrecisionErrors)
-        return false;
+        return;
     if (precision == EbpUndefined)
     {
         switch (type)
         {
             case EbtFloat:
                 error(line, "No precision specified for (float)", "");
-                return true;
+                return;
             case EbtInt:
             case EbtUInt:
                 UNREACHABLE();  // there's always a predeclared qualifier
                 error(line, "No precision specified (int)", "");
-                return true;
+                return;
             default:
                 if (IsSampler(type))
                 {
                     error(line, "No precision specified (sampler)", "");
-                    return true;
+                    return;
                 }
         }
     }
-    return false;
 }
 
 //
@@ -409,55 +401,36 @@
     return true;
 }
 
-//
 // 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::constErrorCheck(TIntermTyped *node)
 {
-    if (node->getQualifier() == EvqConst)
-        return false;
-
-    error(node->getLine(), "constant expression required", "");
-
-    return true;
+    if (node->getQualifier() != 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::integerErrorCheck(TIntermTyped *node, const char *token)
 {
-    if (node->isScalarInt())
-        return false;
-
-    error(node->getLine(), "integer expression required", token);
-
-    return true;
+    if (!node->isScalarInt())
+    {
+        error(node->getLine(), "integer expression required", token);
+    }
 }
 
-//
 // 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(const TSourceLoc &line, bool global, const char *token)
+void TParseContext::globalErrorCheck(const TSourceLoc &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);
+    }
 }
 
-//
 // For now, keep it simple:  if it starts "gl_", it's reserved, independent
 // of scope.  Except, if the symbol table is at the built-in push-level,
 // which is when we are parsing built-ins.
@@ -671,35 +644,23 @@
 }
 
 // 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(const TSourceLoc &line, const TIntermTyped *type)
+// or not.
+void TParseContext::boolErrorCheck(const TSourceLoc &line, const TIntermTyped *type)
 {
     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(const TSourceLoc &line, const TPublicType &pType)
+// or not.
+void TParseContext::boolErrorCheck(const TSourceLoc &line, const TPublicType &pType)
 {
     if (pType.type != EbtBool || pType.isAggregate())
     {
         error(line, "boolean expression expected", "");
-        return true;
     }
-
-    return false;
 }
 
 bool TParseContext::samplerErrorCheck(const TSourceLoc &line,
@@ -727,19 +688,16 @@
     return false;
 }
 
-bool TParseContext::locationDeclaratorListCheck(const TSourceLoc &line, const TPublicType &pType)
+void TParseContext::locationDeclaratorListCheck(const TSourceLoc &line, const TPublicType &pType)
 {
     if (pType.layoutQualifier.location != -1)
     {
         error(line, "location must only be specified for a single input or output variable",
               "location");
-        return true;
     }
-
-    return false;
 }
 
-bool TParseContext::parameterSamplerErrorCheck(const TSourceLoc &line,
+void TParseContext::parameterSamplerErrorCheck(const TSourceLoc &line,
                                                TQualifier qualifier,
                                                const TType &type)
 {
@@ -747,10 +705,7 @@
         IsSampler(type.getBasicType()))
     {
         error(line, "samplers cannot be output parameters", type.getBasicString());
-        return true;
     }
-
-    return false;
 }
 
 bool TParseContext::containsSampler(const TType &type)
@@ -771,12 +726,8 @@
     return false;
 }
 
-//
 // Do size checking for an array type's size.
-//
-// Returns true if there was an error.
-//
-bool TParseContext::arraySizeErrorCheck(const TSourceLoc &line, TIntermTyped *expr, int &size)
+void TParseContext::arraySizeErrorCheck(const TSourceLoc &line, TIntermTyped *expr, int &size)
 {
     TIntermConstantUnion *constant = expr->getAsConstantUnion();
 
@@ -787,7 +738,7 @@
     {
         error(line, "array size must be a constant integer expression", "");
         size = 1;
-        return true;
+        return;
     }
 
     unsigned int unsignedSize = 0;
@@ -805,7 +756,7 @@
         {
             error(line, "array size must be non-negative", "");
             size = 1;
-            return true;
+            return;
         }
 
         unsignedSize = static_cast<unsigned int>(size);
@@ -815,7 +766,7 @@
     {
         error(line, "array size must be greater than zero", "");
         size = 1;
-        return true;
+        return;
     }
 
     // The size of arrays is restricted here to prevent issues further down the
@@ -827,13 +778,10 @@
     {
         error(line, "array size too large", "");
         size = 1;
-        return true;
+        return;
     }
-
-    return false;
 }
 
-//
 // See if this qualifier can be an array.
 //
 // Returns true if there is an error.
@@ -851,7 +799,6 @@
     return false;
 }
 
-//
 // See if this type can be an array.
 //
 // Returns true if there is an error.
@@ -879,12 +826,8 @@
     return false;
 }
 
-//
 // Enforce non-initializer type/qualifier rules.
-//
-// Returns true if there was an error.
-//
-bool TParseContext::nonInitErrorCheck(const TSourceLoc &line,
+void TParseContext::nonInitErrorCheck(const TSourceLoc &line,
                                       const TString &identifier,
                                       TPublicType *type)
 {
@@ -907,15 +850,12 @@
         {
             error(line, "variables with qualifier 'const' must be initialized", identifier.c_str());
         }
-
-        return true;
+        return;
     }
     if (type->isUnsizedArray())
     {
         error(line, "implicitly sized arrays need to be initialized", identifier.c_str());
-        return true;
     }
-    return false;
 }
 
 // Do some simple checks that are shared between all variable declarations,
@@ -969,7 +909,7 @@
     return true;
 }
 
-bool TParseContext::paramErrorCheck(const TSourceLoc &line,
+void TParseContext::paramErrorCheck(const TSourceLoc &line,
                                     TQualifier qualifier,
                                     TQualifier paramQualifier,
                                     TType *type)
@@ -977,21 +917,19 @@
     if (qualifier != EvqConst && qualifier != EvqTemporary)
     {
         error(line, "qualifier not allowed on function parameter", getQualifierString(qualifier));
-        return true;
+        return;
     }
     if (qualifier == EvqConst && paramQualifier != EvqIn)
     {
         error(line, "qualifier not allowed with ", getQualifierString(qualifier),
               getQualifierString(paramQualifier));
-        return true;
+        return;
     }
 
     if (qualifier == EvqConst)
         type->setQualifier(EvqConstReadOnly);
     else
         type->setQualifier(paramQualifier);
-
-    return false;
 }
 
 bool TParseContext::extensionErrorCheck(const TSourceLoc &line, const TString &extension)
@@ -1020,8 +958,7 @@
 
 // These checks are common for all declarations starting a declarator list, and declarators that
 // follow an empty declaration.
-//
-bool TParseContext::singleDeclarationErrorCheck(const TPublicType &publicType,
+void TParseContext::singleDeclarationErrorCheck(const TPublicType &publicType,
                                                 const TSourceLoc &identifierLocation)
 {
     switch (publicType.qualifier)
@@ -1036,7 +973,7 @@
             {
                 error(identifierLocation, "cannot be used with a structure",
                       getQualifierString(publicType.qualifier));
-                return true;
+                return;
             }
 
         default:
@@ -1046,7 +983,7 @@
     if (publicType.qualifier != EvqUniform &&
         samplerErrorCheck(identifierLocation, publicType, "samplers must be uniform"))
     {
-        return true;
+        return;
     }
 
     // check for layout qualifier issues
@@ -1057,7 +994,7 @@
         error(identifierLocation, "layout qualifier",
               getMatrixPackingString(layoutQualifier.matrixPacking),
               "only valid for interface blocks");
-        return true;
+        return;
     }
 
     if (layoutQualifier.blockStorage != EbsUnspecified)
@@ -1065,29 +1002,23 @@
         error(identifierLocation, "layout qualifier",
               getBlockStorageString(layoutQualifier.blockStorage),
               "only valid for interface blocks");
-        return true;
+        return;
     }
 
-    if (publicType.qualifier != EvqVertexIn && publicType.qualifier != EvqFragmentOut &&
-        layoutLocationErrorCheck(identifierLocation, publicType.layoutQualifier))
+    if (publicType.qualifier != EvqVertexIn && publicType.qualifier != EvqFragmentOut)
     {
-        return true;
+        layoutLocationErrorCheck(identifierLocation, publicType.layoutQualifier);
     }
-
-    return false;
 }
 
-bool TParseContext::layoutLocationErrorCheck(const TSourceLoc &location,
+void TParseContext::layoutLocationErrorCheck(const TSourceLoc &location,
                                              const TLayoutQualifier &layoutQualifier)
 {
     if (layoutQualifier.location != -1)
     {
         error(location, "invalid layout qualifier:", "location",
               "only valid on program inputs and outputs");
-        return true;
     }
-
-    return false;
 }
 
 void TParseContext::layoutSupportedErrorCheck(const TSourceLoc &location,
@@ -1098,7 +1029,6 @@
     if (mShaderVersion < versionRequired)
     {
         error(location, "invalid layout qualifier:", layoutQualifierName.c_str(), "not supported");
-        recover();
     }
 }
 
@@ -1119,7 +1049,7 @@
     return false;
 }
 
-bool TParseContext::functionCallLValueErrorCheck(const TFunction *fnCandidate,
+void TParseContext::functionCallLValueErrorCheck(const TFunction *fnCandidate,
                                                  TIntermAggregate *aggregate)
 {
     for (size_t i = 0; i < fnCandidate->getParamCount(); ++i)
@@ -1132,12 +1062,10 @@
             {
                 error(node->getLine(),
                       "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error");
-                recover();
-                return true;
+                return;
             }
         }
     }
-    return false;
 }
 
 void TParseContext::es3InvariantErrorCheck(const TQualifier qualifier,
@@ -1146,7 +1074,6 @@
     if (!sh::IsVaryingOut(qualifier) && qualifier != EvqFragmentOut)
     {
         error(invariantLocation, "Only out variables can be invariant.", "invariant");
-        recover();
     }
 }
 
@@ -1215,22 +1142,19 @@
     if (!symbol)
     {
         error(location, "undeclared identifier", name->c_str());
-        recover();
     }
     else if (!symbol->isVariable())
     {
         error(location, "variable expected", name->c_str());
-        recover();
     }
     else
     {
         variable = static_cast<const TVariable *>(symbol);
 
         if (symbolTable.findBuiltIn(variable->getName(), mShaderVersion) &&
-            !variable->getExtension().empty() &&
-            extensionErrorCheck(location, variable->getExtension()))
+            !variable->getExtension().empty())
         {
-            recover();
+            extensionErrorCheck(location, variable->getExtension());
         }
 
         // Reject shaders using both gl_FragData and gl_FragColor
@@ -1262,7 +1186,6 @@
                     " and (gl_FragColor, gl_SecondaryFragColorEXT)";
             }
             error(location, errorMessage, name->c_str());
-            recover();
         }
 
         // GLSL ES 3.1 Revision 4, 7.1.3 Compute Shader Special Variables
@@ -1463,17 +1386,13 @@
     returnType.invariant       = invariant;
     returnType.layoutQualifier = layoutQualifier;
 
-    if (layoutWorkGroupSizeErrorCheck(typeSpecifier.line, layoutQualifier))
-    {
-        recover();
-    }
+    layoutWorkGroupSizeErrorCheck(typeSpecifier.line, layoutQualifier);
 
     if (mShaderVersion < 300)
     {
         if (typeSpecifier.array)
         {
             error(typeSpecifier.line, "not supported", "first-class array");
-            recover();
             returnType.clearArrayness();
         }
 
@@ -1481,24 +1400,19 @@
             (typeSpecifier.type == EbtBool || typeSpecifier.type == EbtInt))
         {
             error(typeSpecifier.line, "cannot be bool or int", getQualifierString(qualifier));
-            recover();
         }
 
         if ((qualifier == EvqVaryingIn || qualifier == EvqVaryingOut) &&
             (typeSpecifier.type == EbtBool || typeSpecifier.type == EbtInt))
         {
             error(typeSpecifier.line, "cannot be bool or int", getQualifierString(qualifier));
-            recover();
         }
     }
     else
     {
         if (!layoutQualifier.isEmpty())
         {
-            if (globalErrorCheck(typeSpecifier.line, symbolTable.atGlobalLevel(), "layout"))
-            {
-                recover();
-            }
+            globalErrorCheck(typeSpecifier.line, symbolTable.atGlobalLevel(), "layout");
         }
         if (sh::IsVarying(qualifier) || qualifier == EvqVertexIn || qualifier == EvqFragmentOut)
         {
@@ -1508,7 +1422,6 @@
         {
             error(typeSpecifier.line, "'in' can be only used to specify the local group size",
                   "in");
-            recover();
         }
     }
 
@@ -1523,7 +1436,6 @@
     if (type.type == EbtBool)
     {
         error(qualifierLocation, "cannot be bool", getQualifierString(qualifier));
-        recover();
     }
 
     // Specific restrictions apply for vertex shader inputs and fragment shader outputs.
@@ -1534,7 +1446,6 @@
             if (type.array)
             {
                 error(qualifierLocation, "cannot be array", getQualifierString(qualifier));
-                recover();
             }
             // Vertex inputs with a struct type are disallowed in singleDeclarationErrorCheck
             return;
@@ -1543,7 +1454,6 @@
             if (type.isMatrix())
             {
                 error(qualifierLocation, "cannot be matrix", getQualifierString(qualifier));
-                recover();
             }
             // Fragment outputs with a struct type are disallowed in singleDeclarationErrorCheck
             return;
@@ -1560,7 +1470,6 @@
     {
         error(qualifierLocation, "must use 'flat' interpolation here",
               getQualifierString(qualifier));
-        recover();
     }
 
     if (type.type == EbtStruct)
@@ -1572,25 +1481,21 @@
         {
             error(qualifierLocation, "cannot be an array of structures",
                   getQualifierString(qualifier));
-            recover();
         }
         if (type.isStructureContainingArrays())
         {
             error(qualifierLocation, "cannot be a structure containing an array",
                   getQualifierString(qualifier));
-            recover();
         }
         if (type.isStructureContainingType(EbtStruct))
         {
             error(qualifierLocation, "cannot be a structure containing a structure",
                   getQualifierString(qualifier));
-            recover();
         }
         if (type.isStructureContainingType(EbtBool))
         {
             error(qualifierLocation, "cannot be a structure containing a bool",
                   getQualifierString(qualifier));
-            recover();
         }
     }
 }
@@ -1618,15 +1523,12 @@
     }
     else
     {
-        if (singleDeclarationErrorCheck(publicType, identifierOrTypeLocation))
-            recover();
+        singleDeclarationErrorCheck(publicType, identifierOrTypeLocation);
 
-        if (nonInitErrorCheck(identifierOrTypeLocation, identifier, &publicType))
-            recover();
+        nonInitErrorCheck(identifierOrTypeLocation, identifier, &publicType);
 
         TVariable *variable = nullptr;
-        if (!declareVariable(identifierOrTypeLocation, identifier, TType(publicType), &variable))
-            recover();
+        declareVariable(identifierOrTypeLocation, identifier, TType(publicType), &variable);
 
         if (variable && symbol)
             symbol->setId(variable->getUniqueId());
@@ -1643,32 +1545,25 @@
 {
     mDeferredSingleDeclarationErrorCheck = false;
 
-    if (singleDeclarationErrorCheck(publicType, identifierLocation))
-        recover();
+    singleDeclarationErrorCheck(publicType, identifierLocation);
 
-    if (nonInitErrorCheck(identifierLocation, identifier, &publicType))
-        recover();
+    nonInitErrorCheck(identifierLocation, identifier, &publicType);
 
-    if (arrayTypeErrorCheck(indexLocation, publicType) ||
-        arrayQualifierErrorCheck(indexLocation, publicType))
+    if (!arrayTypeErrorCheck(indexLocation, publicType))
     {
-        recover();
+        arrayQualifierErrorCheck(indexLocation, publicType);
     }
 
     TType arrayType(publicType);
 
     int size;
-    if (arraySizeErrorCheck(identifierLocation, indexExpression, size))
-    {
-        recover();
-    }
+    arraySizeErrorCheck(identifierLocation, indexExpression, size);
     // Make the type an array even if size check failed.
     // This ensures useless error messages regarding the variable's non-arrayness won't follow.
     arrayType.setArraySize(size);
 
     TVariable *variable = nullptr;
-    if (!declareVariable(identifierLocation, identifier, arrayType, &variable))
-        recover();
+    declareVariable(identifierLocation, identifier, arrayType, &variable);
 
     TIntermSymbol *symbol = intermediate.addSymbol(0, identifier, arrayType, identifierLocation);
     if (variable && symbol)
@@ -1685,8 +1580,7 @@
 {
     mDeferredSingleDeclarationErrorCheck = false;
 
-    if (singleDeclarationErrorCheck(publicType, identifierLocation))
-        recover();
+    singleDeclarationErrorCheck(publicType, identifierLocation);
 
     TIntermNode *intermNode = nullptr;
     if (!executeInitializer(identifierLocation, identifier, publicType, initializer, &intermNode))
@@ -1698,7 +1592,6 @@
     }
     else
     {
-        recover();
         return nullptr;
     }
 }
@@ -1714,13 +1607,11 @@
 {
     mDeferredSingleDeclarationErrorCheck = false;
 
-    if (singleDeclarationErrorCheck(publicType, identifierLocation))
-        recover();
+    singleDeclarationErrorCheck(publicType, identifierLocation);
 
-    if (arrayTypeErrorCheck(indexLocation, publicType) ||
-        arrayQualifierErrorCheck(indexLocation, publicType))
+    if (!arrayTypeErrorCheck(indexLocation, publicType))
     {
-        recover();
+        arrayQualifierErrorCheck(indexLocation, publicType);
     }
 
     TPublicType arrayType(publicType);
@@ -1728,10 +1619,9 @@
     int size = 0;
     // If indexExpression is nullptr, then the array will eventually get its size implicitly from
     // the initializer.
-    if (indexExpression != nullptr &&
-        arraySizeErrorCheck(identifierLocation, indexExpression, size))
+    if (indexExpression != nullptr)
     {
-        recover();
+        arraySizeErrorCheck(identifierLocation, indexExpression, size);
     }
     // Make the type an array even if size check failed.
     // This ensures useless error messages regarding the variable's non-arrayness won't follow.
@@ -1745,7 +1635,6 @@
     }
     else
     {
-        recover();
         return nullptr;
     }
 }
@@ -1756,15 +1645,11 @@
                                                            const TSymbol *symbol)
 {
     // invariant declaration
-    if (globalErrorCheck(invariantLoc, symbolTable.atGlobalLevel(), "invariant varying"))
-    {
-        recover();
-    }
+    globalErrorCheck(invariantLoc, symbolTable.atGlobalLevel(), "invariant varying");
 
     if (!symbol)
     {
         error(identifierLoc, "undeclared identifier declared as invariant", identifier->c_str());
-        recover();
         return nullptr;
     }
     else
@@ -1774,7 +1659,6 @@
         {
             error(identifierLoc, "identifier should not be declared as invariant",
                   identifier->c_str());
-            recover();
             return nullptr;
         }
         symbolTable.addInvariantVarying(std::string(identifier->c_str()));
@@ -1799,20 +1683,16 @@
     // not performed.
     if (mDeferredSingleDeclarationErrorCheck)
     {
-        if (singleDeclarationErrorCheck(publicType, identifierLocation))
-            recover();
+        singleDeclarationErrorCheck(publicType, identifierLocation);
         mDeferredSingleDeclarationErrorCheck = false;
     }
 
-    if (locationDeclaratorListCheck(identifierLocation, publicType))
-        recover();
+    locationDeclaratorListCheck(identifierLocation, publicType);
 
-    if (nonInitErrorCheck(identifierLocation, identifier, &publicType))
-        recover();
+    nonInitErrorCheck(identifierLocation, identifier, &publicType);
 
     TVariable *variable = nullptr;
-    if (!declareVariable(identifierLocation, identifier, TType(publicType), &variable))
-        recover();
+    declareVariable(identifierLocation, identifier, TType(publicType), &variable);
 
     TIntermSymbol *symbol =
         intermediate.addSymbol(0, identifier, TType(publicType), identifierLocation);
@@ -1833,35 +1713,24 @@
     // not performed.
     if (mDeferredSingleDeclarationErrorCheck)
     {
-        if (singleDeclarationErrorCheck(publicType, identifierLocation))
-            recover();
+        singleDeclarationErrorCheck(publicType, identifierLocation);
         mDeferredSingleDeclarationErrorCheck = false;
     }
 
-    if (locationDeclaratorListCheck(identifierLocation, publicType))
-        recover();
+    locationDeclaratorListCheck(identifierLocation, publicType);
 
-    if (nonInitErrorCheck(identifierLocation, identifier, &publicType))
-        recover();
+    nonInitErrorCheck(identifierLocation, identifier, &publicType);
 
-    if (arrayTypeErrorCheck(arrayLocation, publicType) ||
-        arrayQualifierErrorCheck(arrayLocation, publicType))
-    {
-        recover();
-    }
-    else
+    if (!arrayTypeErrorCheck(arrayLocation, publicType) &&
+        !arrayQualifierErrorCheck(arrayLocation, publicType))
     {
         TType arrayType = TType(publicType);
         int size;
-        if (arraySizeErrorCheck(arrayLocation, indexExpression, size))
-        {
-            recover();
-        }
+        arraySizeErrorCheck(arrayLocation, indexExpression, size);
         arrayType.setArraySize(size);
 
         TVariable *variable = nullptr;
-        if (!declareVariable(identifierLocation, identifier, arrayType, &variable))
-            recover();
+        declareVariable(identifierLocation, identifier, arrayType, &variable);
 
         TIntermSymbol *symbol =
             intermediate.addSymbol(0, identifier, arrayType, identifierLocation);
@@ -1885,13 +1754,11 @@
     // not performed.
     if (mDeferredSingleDeclarationErrorCheck)
     {
-        if (singleDeclarationErrorCheck(publicType, identifierLocation))
-            recover();
+        singleDeclarationErrorCheck(publicType, identifierLocation);
         mDeferredSingleDeclarationErrorCheck = false;
     }
 
-    if (locationDeclaratorListCheck(identifierLocation, publicType))
-        recover();
+    locationDeclaratorListCheck(identifierLocation, publicType);
 
     TIntermNode *intermNode = nullptr;
     if (!executeInitializer(identifierLocation, identifier, publicType, initializer, &intermNode))
@@ -1910,7 +1777,6 @@
     }
     else
     {
-        recover();
         return nullptr;
     }
 }
@@ -1928,18 +1794,15 @@
     // not performed.
     if (mDeferredSingleDeclarationErrorCheck)
     {
-        if (singleDeclarationErrorCheck(publicType, identifierLocation))
-            recover();
+        singleDeclarationErrorCheck(publicType, identifierLocation);
         mDeferredSingleDeclarationErrorCheck = false;
     }
 
-    if (locationDeclaratorListCheck(identifierLocation, publicType))
-        recover();
+    locationDeclaratorListCheck(identifierLocation, publicType);
 
-    if (arrayTypeErrorCheck(indexLocation, publicType) ||
-        arrayQualifierErrorCheck(indexLocation, publicType))
+    if (!arrayTypeErrorCheck(indexLocation, publicType))
     {
-        recover();
+        arrayQualifierErrorCheck(indexLocation, publicType);
     }
 
     TPublicType arrayType(publicType);
@@ -1947,10 +1810,9 @@
     int size = 0;
     // If indexExpression is nullptr, then the array will eventually get its size implicitly from
     // the initializer.
-    if (indexExpression != nullptr &&
-        arraySizeErrorCheck(identifierLocation, indexExpression, size))
+    if (indexExpression != nullptr)
     {
-        recover();
+        arraySizeErrorCheck(identifierLocation, indexExpression, size);
     }
     // Make the type an array even if size check failed.
     // This ensures useless error messages regarding the variable's non-arrayness won't follow.
@@ -1971,28 +1833,24 @@
     }
     else
     {
-        recover();
         return nullptr;
     }
 }
 
 void TParseContext::parseGlobalLayoutQualifier(const TPublicType &typeQualifier)
 {
-
     const TLayoutQualifier layoutQualifier = typeQualifier.layoutQualifier;
 
     // It should never be the case, but some strange parser errors can send us here.
     if (layoutQualifier.isEmpty())
     {
         error(typeQualifier.line, "Error during layout qualifier parsing.", "?");
-        recover();
         return;
     }
 
     if (!layoutQualifier.isCombinationValid())
     {
         error(typeQualifier.line, "invalid combination:", "layout");
-        recover();
         return;
     }
 
@@ -2003,21 +1861,18 @@
         {
             error(typeQualifier.line, "Work group size does not match the previous declaration",
                   "layout");
-            recover();
             return;
         }
 
         if (mShaderVersion < 310)
         {
             error(typeQualifier.line, "in type qualifier supported in GLSL ES 3.10 only", "layout");
-            recover();
             return;
         }
 
         if (!layoutQualifier.isGroupSizeSpecified())
         {
             error(typeQualifier.line, "No local work group size specified", "layout");
-            recover();
             return;
         }
 
@@ -2043,7 +1898,6 @@
 
                     error(typeQualifier.line, "invalid value:", getLocalSizeString(i),
                           errorMessage.c_str());
-                    recover();
                     return;
                 }
             }
@@ -2056,7 +1910,6 @@
 
         if (layoutWorkGroupSizeErrorCheck(typeQualifier.line, typeQualifier.layoutQualifier))
         {
-            recover();
             return;
         }
 
@@ -2064,7 +1917,6 @@
         {
             error(typeQualifier.line, "invalid qualifier:",
                   getQualifierString(typeQualifier.qualifier), "global layout must be uniform");
-            recover();
             return;
         }
 
@@ -2072,15 +1924,10 @@
         {
             error(typeQualifier.line, "layout qualifiers supported in GLSL ES 3.00 and above",
                   "layout");
-            recover();
             return;
         }
 
-        if (layoutLocationErrorCheck(typeQualifier.line, typeQualifier.layoutQualifier))
-        {
-            recover();
-            return;
-        }
+        layoutLocationErrorCheck(typeQualifier.line, typeQualifier.layoutQualifier);
 
         if (layoutQualifier.matrixPacking != EmpUnspecified)
         {
@@ -2107,7 +1954,6 @@
         // ESSL 1.00.17 section 4.2.7.
         // Doesn't apply to ESSL 3.00.4: see section 4.2.3.
         error(location, "duplicate function prototype declarations are not allowed", "function");
-        recover();
     }
     symbolTableFunction->setHasPrototypeDeclaration();
 
@@ -2142,7 +1988,6 @@
     {
         // ESSL 3.00.4 section 4.2.4.
         error(location, "local function prototype declarations are not allowed", "function");
-        recover();
     }
 
     return prototype;
@@ -2158,7 +2003,6 @@
     if (mCurrentFunctionType->getBasicType() != EbtVoid && !mFunctionReturnsValue)
     {
         error(location, "function does not return a value:", "", function.getName().c_str());
-        recover();
     }
 
     TIntermAggregate *aggregate =
@@ -2182,7 +2026,6 @@
     if (builtIn)
     {
         error(location, "built-in functions cannot be redefined", function->getName().c_str());
-        recover();
     }
 
     TFunction *prevDec =
@@ -2196,7 +2039,6 @@
     {
         // Then this function already has a body.
         error(location, "function already has a body", function->getName().c_str());
-        recover();
     }
     prevDec->setDefined();
     //
@@ -2212,13 +2054,11 @@
         if (function->getParamCount() > 0)
         {
             error(location, "function cannot take any parameter(s)", function->getName().c_str());
-            recover();
         }
         if (function->getReturnType().getBasicType() != EbtVoid)
         {
             error(location, "", function->getReturnType().getBasicString(),
                   "main function cannot return a value");
-            recover();
         }
     }
 
@@ -2249,7 +2089,6 @@
             if (!symbolTable.declare(variable))
             {
                 error(location, "redefinition", variable->getName().c_str());
-                recover();
                 paramNodes = intermediate.growAggregate(
                     paramNodes, intermediate.addSymbol(0, "", *param.type, location), location);
                 continue;
@@ -2293,7 +2132,6 @@
         // Therefore overloading or redefining builtin functions is an error.
         error(location, "Name of a built-in function cannot be redeclared as function",
               function->getName().c_str());
-        recover();
     }
     else if (prevDec)
     {
@@ -2301,7 +2139,6 @@
         {
             error(location, "overloaded functions must have the same return type",
                   function->getReturnType().getBasicString());
-            recover();
         }
         for (size_t i = 0; i < prevDec->getParamCount(); ++i)
         {
@@ -2310,7 +2147,6 @@
             {
                 error(location, "overloaded functions must have the same parameter qualifiers",
                       function->getParam(i).type->getQualifierString());
-                recover();
             }
         }
     }
@@ -2324,7 +2160,6 @@
         if (!prevSym->isFunction())
         {
             error(location, "redefinition", function->getName().c_str(), "function");
-            recover();
         }
     }
     else
@@ -2355,18 +2190,13 @@
     {
         error(location, "no qualifiers allowed for function return",
               getQualifierString(type.qualifier));
-        recover();
     }
     if (!type.layoutQualifier.isEmpty())
     {
         error(location, "no qualifiers allowed for function return", "layout");
-        recover();
     }
     // make sure a sampler is not involved as well...
-    if (samplerErrorCheck(location, type, "samplers can't be function return values"))
-    {
-        recover();
-    }
+    samplerErrorCheck(location, type, "samplers can't be function return values");
     if (mShaderVersion < 300)
     {
         // Array return values are forbidden, but there's also no valid syntax for declaring array
@@ -2378,7 +2208,6 @@
             // ESSL 1.00.17 section 6.1 Function Definitions
             error(location, "structures containing arrays can't be function return values",
                   TType(type).getCompleteString().c_str());
-            recover();
         }
     }
 
@@ -2393,7 +2222,6 @@
     {
         error(publicType.line, "constructor can't be a structure definition",
               getBasicString(publicType.type));
-        recover();
     }
 
     TOperator op = EOpNull;
@@ -2407,7 +2235,6 @@
         if (op == EOpNull)
         {
             error(publicType.line, "cannot construct this type", getBasicString(publicType.type));
-            recover();
             publicType.type = EbtFloat;
             op              = EOpConstructFloat;
         }
@@ -2445,7 +2272,6 @@
             if (!argType.sameElementType(*type))
             {
                 error(line, "Array constructor argument has an incorrect type", "Error");
-                recover();
                 return nullptr;
             }
         }
@@ -2461,7 +2287,6 @@
             {
                 error(line, "Structure constructor arguments do not match structure fields",
                       "Error");
-                recover();
 
                 return 0;
             }
@@ -2579,9 +2404,7 @@
     else
     {
         error(line, "Cannot offset into the structure", "Error");
-        recover();
-
-        return 0;
+        return nullptr;
     }
 
     return typedNode;
@@ -2599,21 +2422,16 @@
                                                    TIntermTyped *arrayIndex,
                                                    const TSourceLoc &arrayIndexLine)
 {
-    if (reservedErrorCheck(nameLine, blockName))
-        recover();
+    reservedErrorCheck(nameLine, blockName);
 
     if (typeQualifier.qualifier != EvqUniform)
     {
         error(typeQualifier.line, "invalid qualifier:", getQualifierString(typeQualifier.qualifier),
               "interface blocks must be uniform");
-        recover();
     }
 
     TLayoutQualifier blockLayoutQualifier = typeQualifier.layoutQualifier;
-    if (layoutLocationErrorCheck(typeQualifier.line, blockLayoutQualifier))
-    {
-        recover();
-    }
+    layoutLocationErrorCheck(typeQualifier.line, blockLayoutQualifier);
 
     if (blockLayoutQualifier.matrixPacking == EmpUnspecified)
     {
@@ -2625,16 +2443,12 @@
         blockLayoutQualifier.blockStorage = mDefaultBlockStorage;
     }
 
-    if (layoutWorkGroupSizeErrorCheck(nameLine, blockLayoutQualifier))
-    {
-        recover();
-    }
+    layoutWorkGroupSizeErrorCheck(nameLine, blockLayoutQualifier);
 
     TSymbol *blockNameSymbol = new TInterfaceBlockName(&blockName);
     if (!symbolTable.declare(blockNameSymbol))
     {
         error(nameLine, "redefinition", blockName.c_str(), "interface block name");
-        recover();
     }
 
     // check for sampler types and apply layout qualifiers
@@ -2646,7 +2460,6 @@
         {
             error(field->line(), "unsupported type", fieldType->getBasicString(),
                   "sampler types are not allowed in interface blocks");
-            recover();
         }
 
         const TQualifier qualifier = fieldType->getQualifier();
@@ -2658,22 +2471,17 @@
             default:
                 error(field->line(), "invalid qualifier on interface block member",
                       getQualifierString(qualifier));
-                recover();
                 break;
         }
 
         // check layout qualifiers
         TLayoutQualifier fieldLayoutQualifier = fieldType->getLayoutQualifier();
-        if (layoutLocationErrorCheck(field->line(), fieldLayoutQualifier))
-        {
-            recover();
-        }
+        layoutLocationErrorCheck(field->line(), fieldLayoutQualifier);
 
         if (fieldLayoutQualifier.blockStorage != EbsUnspecified)
         {
             error(field->line(), "invalid layout qualifier:",
                   getBlockStorageString(fieldLayoutQualifier.blockStorage), "cannot be used here");
-            recover();
         }
 
         if (fieldLayoutQualifier.matrixPacking == EmpUnspecified)
@@ -2694,8 +2502,7 @@
     int arraySize = 0;
     if (arrayIndex != NULL)
     {
-        if (arraySizeErrorCheck(arrayIndexLine, arrayIndex, arraySize))
-            recover();
+        arraySizeErrorCheck(arrayIndexLine, arrayIndex, arraySize);
     }
 
     TInterfaceBlock *interfaceBlock =
@@ -2724,14 +2531,12 @@
             {
                 error(field->line(), "redefinition", field->name().c_str(),
                       "interface block member name");
-                recover();
             }
         }
     }
     else
     {
-        if (reservedErrorCheck(instanceLine, *instanceName))
-            recover();
+        reservedErrorCheck(instanceLine, *instanceName);
 
         // add a symbol for this interface block
         TVariable *instanceTypeDef = new TVariable(instanceName, interfaceBlockType, false);
@@ -2741,7 +2546,6 @@
         {
             error(instanceLine, "redefinition", instanceName->c_str(),
                   "interface block instance name");
-            recover();
         }
 
         symbolId   = instanceTypeDef->getUniqueId();
@@ -2757,7 +2561,7 @@
     return aggregate;
 }
 
-bool TParseContext::enterStructDeclaration(const TSourceLoc &line, const TString &identifier)
+void TParseContext::enterStructDeclaration(const TSourceLoc &line, const TString &identifier)
 {
     ++mStructNestingLevel;
 
@@ -2767,10 +2571,7 @@
     if (mStructNestingLevel > 1)
     {
         error(line, "", "Embedded struct definitions are not allowed");
-        return true;
     }
-
-    return false;
 }
 
 void TParseContext::exitStructDeclaration()
@@ -2831,7 +2632,6 @@
         {
             error(location, " left of '[' is not of type array, matrix, or vector ", "expression");
         }
-        recover();
     }
 
     TIntermConstantUnion *indexConstantUnion = indexExpression->getAsConstantUnion();
@@ -2847,18 +2647,15 @@
             error(
                 location, "", "[",
                 "array indexes for interface blocks arrays must be constant integral expressions");
-            recover();
         }
         else if (baseExpression->getQualifier() == EvqFragmentOut)
         {
             error(location, "", "[",
                   "array indexes for fragment outputs must be constant integral expressions");
-            recover();
         }
         else if (mShaderSpec == SH_WEBGL2_SPEC && baseExpression->getQualifier() == EvqFragData)
         {
             error(location, "", "[", "array index for gl_FragData must be constant zero");
-            recover();
         }
     }
 
@@ -2929,7 +2726,6 @@
                         {
                             error(location, "", "[",
                                   "array index for gl_FragData must be constant zero");
-                            recover();
                         }
                         safeIndex = 0;
                     }
@@ -3047,7 +2843,6 @@
     if (baseExpression->isArray())
     {
         error(fieldLocation, "cannot apply dot operator to an array", ".");
-        recover();
     }
 
     if (baseExpression->isVector())
@@ -3058,7 +2853,6 @@
         {
             fields.num        = 1;
             fields.offsets[0] = 0;
-            recover();
         }
 
         if (baseExpression->getAsConstantUnion())
@@ -3075,7 +2869,6 @@
         }
         if (indexedExpression == nullptr)
         {
-            recover();
             indexedExpression = baseExpression;
         }
         else
@@ -3093,7 +2886,6 @@
         if (fields.empty())
         {
             error(dotLocation, "structure has no fields", "Internal Error");
-            recover();
             indexedExpression = baseExpression;
         }
         else
@@ -3114,7 +2906,6 @@
                     indexedExpression = addConstStruct(fieldString, baseExpression, dotLocation);
                     if (indexedExpression == 0)
                     {
-                        recover();
                         indexedExpression = baseExpression;
                     }
                     else
@@ -3136,7 +2927,6 @@
             else
             {
                 error(dotLocation, " no such field in structure", fieldString.c_str());
-                recover();
                 indexedExpression = baseExpression;
             }
         }
@@ -3148,7 +2938,6 @@
         if (fields.empty())
         {
             error(dotLocation, "interface block has no fields", "Internal Error");
-            recover();
             indexedExpression = baseExpression;
         }
         else
@@ -3175,7 +2964,6 @@
             else
             {
                 error(dotLocation, " no such field in interface block", fieldString.c_str());
-                recover();
                 indexedExpression = baseExpression;
             }
         }
@@ -3194,7 +2982,6 @@
                   "side",
                   fieldString.c_str());
         }
-        recover();
         indexedExpression = baseExpression;
     }
 
@@ -3239,12 +3026,10 @@
     {
         error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str(),
               "location requires an argument");
-        recover();
     }
     else
     {
         error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str());
-        recover();
     }
 
     return qualifier;
@@ -3263,7 +3048,6 @@
     {
         std::string errorMessage = std::string(getLocalSizeString(index)) + " must be positive";
         error(intValueLine, "out of range:", intValueString.c_str(), errorMessage.c_str());
-        recover();
     }
     (*localSize)[index] = intValue;
 }
@@ -3284,7 +3068,6 @@
         {
             error(intValueLine, "out of range:", intValueString.c_str(),
                   "location must be non-negative");
-            recover();
         }
         else
         {
@@ -3309,7 +3092,6 @@
     else
     {
         error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str());
-        recover();
     }
 
     return qualifier;
@@ -3344,7 +3126,6 @@
                 error(rightQualifierLocation,
                       "Cannot have multiple different work group size specifiers",
                       getLocalSizeString(i));
-                recover();
             }
             joinedQualifier.localSize[i] = rightQualifier.localSize[i];
         }
@@ -3401,7 +3182,6 @@
         error(interpolationLoc,
               "interpolation qualifier requires a fragment 'in' or vertex 'out' storage qualifier",
               getInterpolationString(interpolationQualifier));
-        recover();
 
         mergedQualifier = storageQualifier;
     }
@@ -3414,15 +3194,9 @@
 TFieldList *TParseContext::addStructDeclaratorList(const TPublicType &typeSpecifier,
                                                    TFieldList *fieldList)
 {
-    if (voidErrorCheck(typeSpecifier.line, (*fieldList)[0]->name(), typeSpecifier.type))
-    {
-        recover();
-    }
+    voidErrorCheck(typeSpecifier.line, (*fieldList)[0]->name(), typeSpecifier.type);
 
-    if (layoutWorkGroupSizeErrorCheck(typeSpecifier.line, typeSpecifier.layoutQualifier))
-    {
-        recover();
-    }
+    layoutWorkGroupSizeErrorCheck(typeSpecifier.line, typeSpecifier.layoutQualifier);
 
     for (unsigned int i = 0; i < fieldList->size(); ++i)
     {
@@ -3440,8 +3214,7 @@
         // don't allow arrays of arrays
         if (type->isArray())
         {
-            if (arrayTypeErrorCheck(typeSpecifier.line, typeSpecifier))
-                recover();
+            arrayTypeErrorCheck(typeSpecifier.line, typeSpecifier);
         }
         if (typeSpecifier.array)
             type->setArraySize(typeSpecifier.arraySize);
@@ -3450,10 +3223,7 @@
             type->setStruct(typeSpecifier.userDef->getStruct());
         }
 
-        if (structNestingErrorCheck(typeSpecifier.line, *(*fieldList)[i]))
-        {
-            recover();
-        }
+        structNestingErrorCheck(typeSpecifier.line, *(*fieldList)[i]);
     }
 
     return fieldList;
@@ -3474,15 +3244,11 @@
 
     if (!structName->empty())
     {
-        if (reservedErrorCheck(nameLine, *structName))
-        {
-            recover();
-        }
+        reservedErrorCheck(nameLine, *structName);
         TVariable *userTypeDef = new TVariable(structName, *structureType, true);
         if (!symbolTable.declare(userTypeDef))
         {
             error(nameLine, "redefinition", structName->c_str(), "struct");
-            recover();
         }
     }
 
@@ -3499,7 +3265,6 @@
             default:
                 error(field.line(), "invalid qualifier on struct member",
                       getQualifierString(qualifier));
-                recover();
                 break;
         }
     }
@@ -3523,7 +3288,6 @@
     {
         error(init->getLine(), "init-expression in a switch statement must be a scalar integer",
               "switch");
-        recover();
         return nullptr;
     }
 
@@ -3531,7 +3295,6 @@
     {
         if (!ValidateSwitch::validate(switchType, this, statementList, loc))
         {
-            recover();
             return nullptr;
         }
     }
@@ -3540,7 +3303,6 @@
     if (node == nullptr)
     {
         error(loc, "erroneous switch statement", "switch");
-        recover();
         return nullptr;
     }
     return node;
@@ -3551,20 +3313,17 @@
     if (mSwitchNestingLevel == 0)
     {
         error(loc, "case labels need to be inside switch statements", "case");
-        recover();
         return nullptr;
     }
     if (condition == nullptr)
     {
         error(loc, "case label must have a condition", "case");
-        recover();
         return nullptr;
     }
     if ((condition->getBasicType() != EbtInt && condition->getBasicType() != EbtUInt) ||
         condition->isMatrix() || condition->isArray() || condition->isVector())
     {
         error(condition->getLine(), "case label must be a scalar integer", "case");
-        recover();
     }
     TIntermConstantUnion *conditionConst = condition->getAsConstantUnion();
     // TODO(oetuaho@nvidia.com): Get rid of the conditionConst == nullptr check once all constant
@@ -3573,13 +3332,11 @@
     if (condition->getQualifier() != EvqConst || conditionConst == nullptr)
     {
         error(condition->getLine(), "case label must be constant", "case");
-        recover();
     }
     TIntermCase *node = intermediate.addCase(condition, loc);
     if (node == nullptr)
     {
         error(loc, "erroneous case statement", "case");
-        recover();
         return nullptr;
     }
     return node;
@@ -3590,14 +3347,12 @@
     if (mSwitchNestingLevel == 0)
     {
         error(loc, "default labels need to be inside switch statements", "default");
-        recover();
         return nullptr;
     }
     TIntermCase *node = intermediate.addCase(nullptr, loc);
     if (node == nullptr)
     {
         error(loc, "erroneous default statement", "default");
-        recover();
         return nullptr;
     }
     return node;
@@ -3654,7 +3409,6 @@
     if (node == nullptr)
     {
         unaryOpError(loc, GetOperatorString(op), child->getCompleteString());
-        recover();
         return child;
     }
     return node;
@@ -3664,8 +3418,7 @@
                                                 TIntermTyped *child,
                                                 const TSourceLoc &loc)
 {
-    if (lValueErrorCheck(loc, GetOperatorString(op), child))
-        recover();
+    lValueErrorCheck(loc, GetOperatorString(op), child);
     return addUnaryMath(op, child, loc);
 }
 
@@ -3858,7 +3611,6 @@
     {
         binaryOpError(loc, GetOperatorString(op), left->getCompleteString(),
                       right->getCompleteString());
-        recover();
         return left;
     }
     return node;
@@ -3874,7 +3626,6 @@
     {
         binaryOpError(loc, GetOperatorString(op), left->getCompleteString(),
                       right->getCompleteString());
-        recover();
         TConstantUnion *unionArray = new TConstantUnion[1];
         unionArray->setBConst(false);
         return intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst),
@@ -3904,7 +3655,6 @@
     if (node == nullptr)
     {
         assignError(loc, "assign", left->getCompleteString(), right->getCompleteString());
-        recover();
         return left;
     }
     return node;
@@ -3924,7 +3674,6 @@
         error(loc,
               "sequence operator is not allowed for void, arrays, or structs containing arrays",
               ",");
-        recover();
     }
 
     return intermediate.addComma(left, right, loc, mShaderVersion);
@@ -3938,21 +3687,18 @@
             if (mLoopNestingLevel <= 0)
             {
                 error(loc, "continue statement only allowed in loops", "");
-                recover();
             }
             break;
         case EOpBreak:
             if (mLoopNestingLevel <= 0 && mSwitchNestingLevel <= 0)
             {
                 error(loc, "break statement only allowed in loops and switch statements", "");
-                recover();
             }
             break;
         case EOpReturn:
             if (mCurrentFunctionType->getBasicType() != EbtVoid)
             {
                 error(loc, "non-void function must return a value", "return");
-                recover();
             }
             break;
         default:
@@ -3971,12 +3717,10 @@
     if (mCurrentFunctionType->getBasicType() == EbtVoid)
     {
         error(loc, "void function cannot return a value", "return");
-        recover();
     }
     else if (*mCurrentFunctionType != returnValue->getType())
     {
         error(loc, "function return is not matching type:", "return");
-        recover();
     }
     return intermediate.addBranch(op, returnValue, loc);
 }
@@ -4010,7 +3754,6 @@
             TString unmangledName = TFunction::unmangleName(name);
             error(functionCall->getLine(), "Texture offset must be a constant expression",
                   unmangledName.c_str());
-            recover();
         }
         else
         {
@@ -4027,7 +3770,6 @@
                     std::string token = tokenStream.str();
                     error(offset->getLine(), "Texture offset value out of valid range",
                           token.c_str());
-                    recover();
                 }
             }
         }
@@ -4052,17 +3794,14 @@
         if (fnCall->getName() != "length")
         {
             error(loc, "invalid method", fnCall->getName().c_str());
-            recover();
         }
         else if (paramNode != nullptr)
         {
             error(loc, "method takes no parameters", "length");
-            recover();
         }
         else if (typedThis == nullptr || !typedThis->isArray())
         {
             error(loc, "length can only be called on arrays", "length");
-            recover();
         }
         else
         {
@@ -4080,7 +3819,6 @@
                 // length method applied".
                 error(loc, "length can only be called on array names, not on array expressions",
                       "length");
-                recover();
             }
         }
         unionArray->setIConst(arraySize);
@@ -4105,7 +3843,6 @@
 
         if (callNode == nullptr)
         {
-            recover();
             callNode = intermediate.setAggregateOperator(nullptr, op, loc);
         }
         callNode->setType(type);
@@ -4123,10 +3860,9 @@
             //
             // A declared function.
             //
-            if (builtIn && !fnCandidate->getExtension().empty() &&
-                extensionErrorCheck(loc, fnCandidate->getExtension()))
+            if (builtIn && !fnCandidate->getExtension().empty())
             {
-                recover();
+                extensionErrorCheck(loc, fnCandidate->getExtension());
             }
             op = fnCandidate->getBuiltInOp();
             if (builtIn && op != EOpNull)
@@ -4221,7 +3957,6 @@
             unionArray->setFConst(0.0f);
             callNode = intermediate.addConstantUnion(unionArray,
                                                      TType(EbtFloat, EbpUndefined, EvqConst), loc);
-            recover();
         }
     }
     return callNode;
@@ -4232,13 +3967,11 @@
                                                  TIntermTyped *falseBlock,
                                                  const TSourceLoc &loc)
 {
-    if (boolErrorCheck(loc, cond))
-        recover();
+    boolErrorCheck(loc, cond);
 
     if (trueBlock->getType() != falseBlock->getType())
     {
         binaryOpError(loc, ":", trueBlock->getCompleteString(), falseBlock->getCompleteString());
-        recover();
         return falseBlock;
     }
     // ESSL1 sections 5.2 and 5.7:
@@ -4247,7 +3980,6 @@
     if (trueBlock->isArray() || trueBlock->getBasicType() == EbtStruct)
     {
         error(loc, "ternary operator is not allowed for structures or arrays", ":");
-        recover();
         return falseBlock;
     }
     // WebGL2 section 5.26, the following results in an error:
@@ -4255,7 +3987,6 @@
     if (mShaderSpec == SH_WEBGL2_SPEC && trueBlock->getBasicType() == EbtVoid)
     {
         error(loc, "ternary operator is not allowed for void", ":");
-        recover();
         return falseBlock;
     }
 
diff --git a/src/compiler/translator/ParseContext.h b/src/compiler/translator/ParseContext.h
index ce71488..642af34 100644
--- a/src/compiler/translator/ParseContext.h
+++ b/src/compiler/translator/ParseContext.h
@@ -92,7 +92,6 @@
                          const char *token,
                          const char *extraInfo = "");
 
-    void recover();
     TIntermNode *getTreeRoot() const { return mTreeRoot; }
     void setTreeRoot(TIntermNode *treeRoot) { mTreeRoot = treeRoot; }
 
@@ -131,35 +130,42 @@
     void assignError(const TSourceLoc &line, const char *op, TString left, TString right);
     void unaryOpError(const TSourceLoc &line, const char *op, TString operand);
     void binaryOpError(const TSourceLoc &line, const char *op, TString left, TString right);
-    bool precisionErrorCheck(const TSourceLoc &line, TPrecision precision, TBasicType type);
+    void precisionErrorCheck(const TSourceLoc &line, TPrecision precision, TBasicType type);
     bool lValueErrorCheck(const TSourceLoc &line, const char *op, TIntermTyped*);
-    bool constErrorCheck(TIntermTyped *node);
-    bool integerErrorCheck(TIntermTyped *node, const char *token);
-    bool globalErrorCheck(const TSourceLoc &line, bool global, const char *token);
+    void constErrorCheck(TIntermTyped *node);
+    void integerErrorCheck(TIntermTyped *node, const char *token);
+    void globalErrorCheck(const TSourceLoc &line, bool global, const char *token);
     bool constructorErrorCheck(const TSourceLoc &line,
                                TIntermNode *argumentsNode,
                                TFunction &function,
                                TOperator op,
                                TType *type);
-    bool arraySizeErrorCheck(const TSourceLoc &line, TIntermTyped *expr, int &size);
+    void arraySizeErrorCheck(const TSourceLoc &line, TIntermTyped *expr, int &size);
     bool arrayQualifierErrorCheck(const TSourceLoc &line, const TPublicType &type);
     bool arrayTypeErrorCheck(const TSourceLoc &line, const TPublicType &type);
     bool voidErrorCheck(const TSourceLoc &line, const TString &identifier, const TBasicType &type);
-    bool boolErrorCheck(const TSourceLoc&, const TIntermTyped*);
-    bool boolErrorCheck(const TSourceLoc&, const TPublicType&);
+    void boolErrorCheck(const TSourceLoc &, const TIntermTyped *);
+    void boolErrorCheck(const TSourceLoc &, const TPublicType &);
     bool samplerErrorCheck(const TSourceLoc &line, const TPublicType &pType, const char *reason);
-    bool locationDeclaratorListCheck(const TSourceLoc &line, const TPublicType &pType);
-    bool parameterSamplerErrorCheck(const TSourceLoc &line, TQualifier qualifier, const TType &type);
-    bool paramErrorCheck(const TSourceLoc &line, TQualifier qualifier, TQualifier paramQualifier, TType *type);
+    void locationDeclaratorListCheck(const TSourceLoc &line, const TPublicType &pType);
+    void parameterSamplerErrorCheck(const TSourceLoc &line,
+                                    TQualifier qualifier,
+                                    const TType &type);
+    void paramErrorCheck(const TSourceLoc &line,
+                         TQualifier qualifier,
+                         TQualifier paramQualifier,
+                         TType *type);
     bool extensionErrorCheck(const TSourceLoc &line, const TString&);
-    bool singleDeclarationErrorCheck(const TPublicType &publicType, const TSourceLoc &identifierLocation);
-    bool layoutLocationErrorCheck(const TSourceLoc &location, const TLayoutQualifier &layoutQualifier);
+    void singleDeclarationErrorCheck(const TPublicType &publicType,
+                                     const TSourceLoc &identifierLocation);
+    void layoutLocationErrorCheck(const TSourceLoc &location,
+                                  const TLayoutQualifier &layoutQualifier);
     void layoutSupportedErrorCheck(const TSourceLoc &location,
                                    const TString &layoutQualifierName,
                                    int versionRequired);
     bool layoutWorkGroupSizeErrorCheck(const TSourceLoc &location,
                                        const TLayoutQualifier &layoutQualifier);
-    bool functionCallLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *);
+    void functionCallLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *);
     void es3InvariantErrorCheck(const TQualifier qualifier, const TSourceLoc &invariantLocation);
     void es3InputOutputTypeCheck(const TQualifier qualifier,
                                  const TPublicType &type,
@@ -309,9 +315,7 @@
                                             const TSourceLoc &storageLoc, TQualifier storageQualifier);
 
     // Performs an error check for embedded struct declarations.
-    // Returns true if an error was raised due to the declaration of
-    // this struct.
-    bool enterStructDeclaration(const TSourceLoc &line, const TString &identifier);
+    void enterStructDeclaration(const TSourceLoc &line, const TString &identifier);
     void exitStructDeclaration();
 
     bool structNestingErrorCheck(const TSourceLoc &line, const TField &field);
@@ -371,7 +375,7 @@
 
     bool declareVariable(const TSourceLoc &line, const TString &identifier, const TType &type, TVariable **variable);
 
-    bool nonInitErrorCheck(const TSourceLoc &line, const TString &identifier, TPublicType *type);
+    void nonInitErrorCheck(const TSourceLoc &line, const TString &identifier, TPublicType *type);
 
     TIntermTyped *addBinaryMathInternal(
         TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc);
diff --git a/src/compiler/translator/glslang.l b/src/compiler/translator/glslang.l
index a4a2961..7fe2893 100644
--- a/src/compiler/translator/glslang.l
+++ b/src/compiler/translator/glslang.l
@@ -392,7 +392,6 @@
 <FIELDS>[ \t\v\f\r] {}
 <FIELDS>. {
     yyextra->error(*yylloc, "Illegal character at fieldname start", yytext, "");
-    yyextra->recover();
     return 0;
 }
 
@@ -437,7 +436,6 @@
     struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
 
     yyextra->error(*yylloc, "Illegal use of reserved word", yytext, "");
-    yyextra->recover();
     return 0;
 }
 
@@ -487,7 +485,6 @@
     if (context->getShaderVersion() < 300)
     {
         context->error(*yylloc, "Unsigned integers are unsupported prior to GLSL ES 3.00", yytext, "");
-        context->recover();
         return 0;
     }
 
@@ -504,7 +501,6 @@
     if (context->getShaderVersion() < 300)
     {
         context->error(*yylloc, "Floating-point suffix unsupported prior to GLSL ES 3.00", yytext);
-        context->recover();
         return 0;
     }
 
@@ -518,7 +514,6 @@
 
 void yyerror(YYLTYPE* lloc, TParseContext* context, void *scanner, const char* reason) {
     context->error(*lloc, reason, yyget_text(scanner));
-    context->recover();
 }
 
 int int_constant(TParseContext *context) {
diff --git a/src/compiler/translator/glslang.y b/src/compiler/translator/glslang.y
index 102e373..62f3d78 100644
--- a/src/compiler/translator/glslang.y
+++ b/src/compiler/translator/glslang.y
@@ -115,49 +115,42 @@
 #define VERTEX_ONLY(S, L) {  \
     if (context->getShaderType() != GL_VERTEX_SHADER) {  \
         context->error(L, " supported in vertex shaders only ", S);  \
-        context->recover();  \
     }  \
 }
 
 #define FRAG_ONLY(S, L) {  \
     if (context->getShaderType() != GL_FRAGMENT_SHADER) {  \
         context->error(L, " supported in fragment shaders only ", S);  \
-        context->recover();  \
     }  \
 }
 
 #define COMPUTE_ONLY(S, L) {  \
     if (context->getShaderType() != GL_COMPUTE_SHADER) {  \
         context->error(L, " supported in compute shaders only ", S);  \
-        context->recover();  \
     }  \
 }
 
 #define NON_COMPUTE_ONLY(S, L) {  \
     if (context->getShaderType() != GL_VERTEX_SHADER && context->getShaderType() != GL_FRAGMENT_SHADER) {  \
         context->error(L, " supported in vertex and fragment shaders only ", S);  \
-        context->recover();  \
     }  \
 }
 
 #define ES2_ONLY(S, L) {  \
     if (context->getShaderVersion() != 100) {  \
         context->error(L, " supported in GLSL ES 1.00 only ", S);  \
-        context->recover();  \
     }  \
 }
 
 #define ES3_OR_NEWER(TOKEN, LINE, REASON) {  \
     if (context->getShaderVersion() < 300) {  \
         context->error(LINE, REASON " supported in GLSL ES 3.00 and above only ", TOKEN);  \
-        context->recover();  \
     }  \
 }
 
 #define ES3_1_ONLY(TOKEN, LINE, REASON) {  \
     if (context->getShaderVersion() != 310) {  \
         context->error(LINE, REASON " supported in GLSL ES 3.10 only ", TOKEN);  \
-        context->recover();  \
     }  \
 }
 %}
@@ -297,8 +290,7 @@
 
 integer_expression
     : expression {
-        if (context->integerErrorCheck($1, "[]"))
-            context->recover();
+        context->integerErrorCheck($1, "[]");
         $$ = $1;
     }
     ;
@@ -377,15 +369,13 @@
         $$ = context->addConstructorFunc($1);
     }
     | IDENTIFIER {
-        if (context->reservedErrorCheck(@1, *$1.string))
-            context->recover();
+        context->reservedErrorCheck(@1, *$1.string);
         const TType *type = TCache::getType(EbtVoid, EbpUndefined);
         TFunction *function = new TFunction($1.string, type);
         $$ = function;
     }
     | FIELD_SELECTION {
-        if (context->reservedErrorCheck(@1, *$1.string))
-            context->recover();
+        context->reservedErrorCheck(@1, *$1.string);
         const TType *type = TCache::getType(EbtVoid, EbpUndefined);
         TFunction *function = new TFunction($1.string, type);
         $$ = function;
@@ -539,8 +529,7 @@
 assignment_expression
     : conditional_expression { $$ = $1; }
     | unary_expression assignment_operator assignment_expression {
-        if (context->lValueErrorCheck(@2, "assign", $1))
-            context->recover();
+        context->lValueErrorCheck(@2, "assign", $1);
         $$ = context->addAssign($2.op, $1, $3, @2);
     }
     ;
@@ -588,16 +577,14 @@
 
 constant_expression
     : conditional_expression {
-        if (context->constErrorCheck($1))
-            context->recover();
+        context->constErrorCheck($1);
         $$ = $1;
     }
     ;
 
 enter_struct
     : IDENTIFIER LEFT_BRACE {
-        if (context->enterStructDeclaration(@1, *$1.string))
-            context->recover();
+        context->enterStructDeclaration(@1, *$1.string);
         $$ = $1;
     }
     ;
@@ -615,11 +602,9 @@
     | PRECISION precision_qualifier type_specifier_no_prec SEMICOLON {
         if (($2 == EbpHigh) && (context->getShaderType() == GL_FRAGMENT_SHADER) && !context->getFragmentPrecisionHigh()) {
             context->error(@1, "precision is not supported in fragment shader", "highp");
-            context->recover();
         }
         if (!context->symbolTable.setDefaultPrecision( $3, $2 )) {
             context->error(@1, "illegal type argument for default precision qualifier", getBasicString($3.type));
-            context->recover();
         }
         $$ = 0;
     }
@@ -676,7 +661,6 @@
             // This parameter > first is void
             //
             context->error(@2, "cannot be an argument type except for '(void)'", "void");
-            context->recover();
             delete $3.param.type;
         } else {
             // Add the parameter
@@ -699,24 +683,20 @@
     : type_specifier identifier {
         if ($1.type == EbtVoid) {
             context->error(@2, "illegal use of type 'void'", $2.string->c_str());
-            context->recover();
         }
-        if (context->reservedErrorCheck(@2, *$2.string))
-            context->recover();
+        context->reservedErrorCheck(@2, *$2.string);
         TParameter param = {$2.string, new TType($1)};
         $$.param = param;
     }
     | type_specifier identifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
         // Check that we can make an array out of this type
-        if (context->arrayTypeErrorCheck(@3, $1))
-            context->recover();
+        context->arrayTypeErrorCheck(@3, $1);
 
-        if (context->reservedErrorCheck(@2, *$2.string))
-            context->recover();
+        context->reservedErrorCheck(@2, *$2.string);
 
         int size;
-        if (context->arraySizeErrorCheck(@3, $4, size))
-            context->recover();
+        context->arraySizeErrorCheck(@3, $4, size);
+
         $1.setArraySize(size);
 
         TType* type = new TType($1);
@@ -736,30 +716,24 @@
     //
     : parameter_type_qualifier parameter_qualifier parameter_declarator {
         $$ = $3;
-        if (context->paramErrorCheck(@3, $1, $2, $$.param.type))
-            context->recover();
+        context->paramErrorCheck(@3, $1, $2, $$.param.type);
     }
     | parameter_qualifier parameter_declarator {
         $$ = $2;
-        if (context->parameterSamplerErrorCheck(@2, $1, *$2.param.type))
-            context->recover();
-        if (context->paramErrorCheck(@2, EvqTemporary, $1, $$.param.type))
-            context->recover();
+        context->parameterSamplerErrorCheck(@2, $1, *$2.param.type);
+        context->paramErrorCheck(@2, EvqTemporary, $1, $$.param.type);
     }
     //
     // Only type
     //
     | parameter_type_qualifier parameter_qualifier parameter_type_specifier {
         $$ = $3;
-        if (context->paramErrorCheck(@3, $1, $2, $$.param.type))
-            context->recover();
+        context->paramErrorCheck(@3, $1, $2, $$.param.type);
     }
     | parameter_qualifier parameter_type_specifier {
         $$ = $2;
-        if (context->parameterSamplerErrorCheck(@2, $1, *$2.param.type))
-            context->recover();
-        if (context->paramErrorCheck(@2, EvqTemporary, $1, $$.param.type))
-            context->recover();
+        context->parameterSamplerErrorCheck(@2, $1, *$2.param.type);
+        context->paramErrorCheck(@2, EvqTemporary, $1, $$.param.type);
     }
     ;
 
@@ -881,14 +855,12 @@
     : ATTRIBUTE {
         VERTEX_ONLY("attribute", @1);
         ES2_ONLY("attribute", @1);
-        if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "attribute"))
-            context->recover();
+        context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "attribute");
         $$.setBasic(EbtVoid, EvqAttribute, @1);
     }
     | VARYING {
         ES2_ONLY("varying", @1);
-        if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "varying"))
-            context->recover();
+        context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "varying");
         if (context->getShaderType() == GL_VERTEX_SHADER)
             $$.setBasic(EbtVoid, EvqVaryingOut, @1);
         else
@@ -896,8 +868,7 @@
     }
     | INVARIANT VARYING {
         ES2_ONLY("varying", @1);
-        if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "invariant varying"))
-            context->recover();
+        context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "invariant varying");
         if (context->getShaderType() == GL_VERTEX_SHADER)
             $$.setBasic(EbtVoid, EvqVaryingOut, @1);
         else
@@ -908,7 +879,6 @@
         if ($1.qualifier != EvqConst && !context->symbolTable.atGlobalLevel())
         {
             context->error(@1, "Local variables can only use the const storage qualifier.", getQualifierString($1.qualifier));
-            context->recover();
         }
         $$.setBasic(EbtVoid, $1.qualifier, @1);
     }
@@ -917,7 +887,6 @@
     }
     | interpolation_qualifier {
         context->error(@1, "interpolation qualifier requires a fragment 'in' or vertex 'out' storage qualifier", getInterpolationString($1.qualifier));
-        context->recover();
 
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
         $$.setBasic(EbtVoid, qual, @1);
@@ -978,8 +947,7 @@
         $$.qualifier = EvqCentroidOut;
     }
     | UNIFORM {
-        if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "uniform"))
-            context->recover();
+        context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "uniform");
         $$.qualifier = EvqUniform;
     }
     ;
@@ -990,9 +958,7 @@
 
         if ($$.precision == EbpUndefined) {
             $$.precision = context->symbolTable.getDefaultPrecision($1.type);
-            if (context->precisionErrorCheck(@1, $$.precision, $1.type)) {
-                context->recover();
-            }
+            context->precisionErrorCheck(@1, $$.precision, $1.type);
         }
     }
     | precision_qualifier type_specifier_no_prec {
@@ -1001,7 +967,6 @@
 
         if (!SupportsPrecision($2.type)) {
             context->error(@1, "illegal type for precision qualifier", getBasicString($2.type));
-            context->recover();
         }
     }
     ;
@@ -1058,12 +1023,10 @@
     | type_specifier_nonarray LEFT_BRACKET constant_expression RIGHT_BRACKET {
         $$ = $1;
 
-        if (context->arrayTypeErrorCheck(@2, $1))
-            context->recover();
-        else {
+        if (!context->arrayTypeErrorCheck(@2, $1))
+        {
             int size;
-            if (context->arraySizeErrorCheck(@2, $3, size))
-                context->recover();
+            context->arraySizeErrorCheck(@2, $3, size);
             $$.setArraySize(size);
         }
     }
@@ -1259,7 +1222,6 @@
         if (!context->supportsExtension("GL_OES_EGL_image_external") &&
             !context->supportsExtension("GL_NV_EGL_stream_consumer_external")) {
             context->error(@1, "unsupported type", "samplerExternalOES");
-            context->recover();
         }
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
         $$.setBasic(EbtSamplerExternalOES, qual, @1);
@@ -1267,7 +1229,6 @@
     | SAMPLER2DRECT {
         if (!context->supportsExtension("GL_ARB_texture_rectangle")) {
             context->error(@1, "unsupported type", "sampler2DRect");
-            context->recover();
         }
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
         $$.setBasic(EbtSampler2DRect, qual, @1);
@@ -1289,10 +1250,10 @@
     ;
 
 struct_specifier
-    : STRUCT identifier LEFT_BRACE { if (context->enterStructDeclaration(@2, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE {
+    : STRUCT identifier LEFT_BRACE { context->enterStructDeclaration(@2, *$2.string); } struct_declaration_list RIGHT_BRACE {
         $$ = context->addStructure(@1, @2, $2.string, $5);
     }
-    | STRUCT LEFT_BRACE { if (context->enterStructDeclaration(@2, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE {
+    | STRUCT LEFT_BRACE { context->enterStructDeclaration(@2, *$2.string); } struct_declaration_list RIGHT_BRACE {
         $$ = context->addStructure(@1, @$, NewPoolTString(""), $4);
     }
     ;
@@ -1308,7 +1269,6 @@
             for (size_t j = 0; j < $$->size(); ++j) {
                 if ((*$$)[j]->name() == field->name()) {
                     context->error(@2, "duplicate field name in structure:", "struct", field->name().c_str());
-                    context->recover();
                 }
             }
             $$->push_back(field);
@@ -1340,20 +1300,17 @@
 
 struct_declarator
     : identifier {
-        if (context->reservedErrorCheck(@1, *$1.string))
-            context->recover();
+        context->reservedErrorCheck(@1, *$1.string);
 
         TType* type = new TType(EbtVoid, EbpUndefined);
         $$ = new TField(type, $1.string, @1);
     }
     | identifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
-        if (context->reservedErrorCheck(@1, *$1.string))
-            context->recover();
+        context->reservedErrorCheck(@1, *$1.string);
 
         TType* type = new TType(EbtVoid, EbpUndefined);
         int size;
-        if (context->arraySizeErrorCheck(@3, $3, size))
-            context->recover();
+        context->arraySizeErrorCheck(@3, $3, size);
         type->setArraySize(size);
 
         $$ = new TField(type, $1.string, @1);
@@ -1436,8 +1393,7 @@
 
 selection_statement
     : IF LEFT_PAREN expression RIGHT_PAREN selection_rest_statement {
-        if (context->boolErrorCheck(@1, $3))
-            context->recover();
+        context->boolErrorCheck(@1, $3);
         $$ = context->intermediate.addSelection($3, $5, @1);
     }
     ;
@@ -1473,18 +1429,15 @@
     // In 1996 c++ draft, conditions can include single declarations
     : expression {
         $$ = $1;
-        if (context->boolErrorCheck($1->getLine(), $1))
-            context->recover();
+        context->boolErrorCheck($1->getLine(), $1);
     }
     | fully_specified_type identifier EQUAL initializer {
         TIntermNode *intermNode;
-        if (context->boolErrorCheck(@2, $1))
-            context->recover();
+        context->boolErrorCheck(@2, $1);
 
         if (!context->executeInitializer(@2, *$2.string, $1, $4, &intermNode))
             $$ = $4;
         else {
-            context->recover();
             $$ = 0;
         }
     }
@@ -1497,8 +1450,7 @@
         context->decrLoopNestingLevel();
     }
     | DO { context->incrLoopNestingLevel(); } statement_with_scope WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON {
-        if (context->boolErrorCheck(@8, $6))
-            context->recover();
+        context->boolErrorCheck(@8, $6);
 
         $$ = context->intermediate.addLoop(ELoopDoWhile, 0, $6, 0, $3, @4);
         context->decrLoopNestingLevel();
diff --git a/src/compiler/translator/glslang_lex.cpp b/src/compiler/translator/glslang_lex.cpp
index ff6c2d6..8ad7b14 100644
--- a/src/compiler/translator/glslang_lex.cpp
+++ b/src/compiler/translator/glslang_lex.cpp
@@ -2075,7 +2075,6 @@
 YY_RULE_SETUP
 {
     yyextra->error(*yylloc, "Illegal character at fieldname start", yytext, "");
-    yyextra->recover();
     return 0;
 }
 	YY_BREAK
@@ -3275,7 +3274,6 @@
     struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
 
     yyextra->error(*yylloc, "Illegal use of reserved word", yytext, "");
-    yyextra->recover();
     return 0;
 }
 
@@ -3325,7 +3323,6 @@
     if (context->getShaderVersion() < 300)
     {
         context->error(*yylloc, "Unsigned integers are unsupported prior to GLSL ES 3.00", yytext, "");
-        context->recover();
         return 0;
     }
 
@@ -3342,7 +3339,6 @@
     if (context->getShaderVersion() < 300)
     {
         context->error(*yylloc, "Floating-point suffix unsupported prior to GLSL ES 3.00", yytext);
-        context->recover();
         return 0;
     }
 
@@ -3356,7 +3352,6 @@
 
 void yyerror(YYLTYPE* lloc, TParseContext* context, void *scanner, const char* reason) {
     context->error(*lloc, reason, yyget_text(scanner));
-    context->recover();
 }
 
 int int_constant(TParseContext *context) {
diff --git a/src/compiler/translator/glslang_tab.cpp b/src/compiler/translator/glslang_tab.cpp
index 101bcd3..5510ba7 100644
--- a/src/compiler/translator/glslang_tab.cpp
+++ b/src/compiler/translator/glslang_tab.cpp
@@ -359,49 +359,42 @@
 #define VERTEX_ONLY(S, L) {  \
     if (context->getShaderType() != GL_VERTEX_SHADER) {  \
         context->error(L, " supported in vertex shaders only ", S);  \
-        context->recover();  \
     }  \
 }
 
 #define FRAG_ONLY(S, L) {  \
     if (context->getShaderType() != GL_FRAGMENT_SHADER) {  \
         context->error(L, " supported in fragment shaders only ", S);  \
-        context->recover();  \
     }  \
 }
 
 #define COMPUTE_ONLY(S, L) {  \
     if (context->getShaderType() != GL_COMPUTE_SHADER) {  \
         context->error(L, " supported in compute shaders only ", S);  \
-        context->recover();  \
     }  \
 }
 
-#define DRAW_ONLY(S, L) {  \
+#define NON_COMPUTE_ONLY(S, L) {  \
     if (context->getShaderType() != GL_VERTEX_SHADER && context->getShaderType() != GL_FRAGMENT_SHADER) {  \
         context->error(L, " supported in vertex and fragment shaders only ", S);  \
-        context->recover();  \
     }  \
 }
 
 #define ES2_ONLY(S, L) {  \
     if (context->getShaderVersion() != 100) {  \
         context->error(L, " supported in GLSL ES 1.00 only ", S);  \
-        context->recover();  \
     }  \
 }
 
 #define ES3_OR_NEWER(TOKEN, LINE, REASON) {  \
     if (context->getShaderVersion() < 300) {  \
         context->error(LINE, REASON " supported in GLSL ES 3.00 and above only ", TOKEN);  \
-        context->recover();  \
     }  \
 }
 
 #define ES3_1_ONLY(TOKEN, LINE, REASON) {  \
     if (context->getShaderVersion() != 310) {  \
         context->error(LINE, REASON " supported in GLSL ES 3.10 only ", TOKEN);  \
-        context->recover();  \
     }  \
 }
 
@@ -717,34 +710,34 @@
   /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
-       0,   235,   235,   236,   239,   249,   252,   257,   262,   267,
-     272,   278,   281,   284,   287,   290,   293,   299,   307,   318,
-     322,   330,   333,   339,   343,   350,   356,   365,   373,   379,
-     386,   396,   399,   402,   405,   415,   416,   417,   418,   426,
-     427,   430,   433,   440,   441,   444,   450,   451,   455,   462,
-     463,   466,   469,   472,   478,   479,   482,   488,   489,   496,
-     497,   504,   505,   512,   513,   519,   520,   526,   527,   533,
-     534,   540,   541,   549,   550,   551,   552,   556,   557,   558,
-     562,   566,   570,   574,   581,   584,   590,   598,   606,   609,
-     615,   626,   630,   634,   638,   645,   651,   654,   661,   669,
-     690,   699,   709,   737,   742,   752,   757,   767,   770,   773,
-     776,   782,   789,   792,   796,   800,   805,   810,   817,   821,
-     825,   829,   834,   839,   843,   850,   860,   866,   869,   875,
-     881,   888,   897,   907,   915,   918,   925,   929,   933,   938,
-     946,   949,   965,   970,   975,   980,   988,   998,  1010,  1013,
-    1016,  1022,  1029,  1032,  1038,  1041,  1044,  1050,  1053,  1058,
-    1073,  1077,  1081,  1085,  1089,  1093,  1098,  1103,  1108,  1113,
-    1118,  1123,  1128,  1133,  1138,  1143,  1148,  1153,  1158,  1163,
-    1168,  1173,  1178,  1183,  1188,  1193,  1198,  1202,  1206,  1210,
-    1214,  1218,  1222,  1226,  1230,  1234,  1238,  1242,  1246,  1250,
-    1254,  1258,  1267,  1275,  1279,  1292,  1292,  1295,  1295,  1301,
-    1304,  1320,  1323,  1332,  1336,  1342,  1349,  1364,  1368,  1372,
-    1373,  1379,  1380,  1381,  1382,  1383,  1384,  1385,  1389,  1390,
-    1390,  1390,  1400,  1401,  1405,  1405,  1406,  1406,  1411,  1414,
-    1424,  1427,  1433,  1434,  1438,  1446,  1450,  1457,  1457,  1464,
-    1467,  1474,  1479,  1494,  1494,  1499,  1499,  1506,  1506,  1514,
-    1517,  1523,  1526,  1532,  1536,  1543,  1546,  1549,  1552,  1555,
-    1564,  1568,  1575,  1578,  1584,  1584
+       0,   228,   228,   229,   232,   242,   245,   250,   255,   260,
+     265,   271,   274,   277,   280,   283,   286,   292,   299,   310,
+     314,   322,   325,   331,   335,   342,   348,   357,   365,   371,
+     377,   386,   389,   392,   395,   405,   406,   407,   408,   416,
+     417,   420,   423,   430,   431,   434,   440,   441,   445,   452,
+     453,   456,   459,   462,   468,   469,   472,   478,   479,   486,
+     487,   494,   495,   502,   503,   509,   510,   516,   517,   523,
+     524,   530,   531,   538,   539,   540,   541,   545,   546,   547,
+     551,   555,   559,   563,   570,   573,   579,   586,   593,   596,
+     602,   611,   615,   619,   623,   630,   636,   639,   646,   654,
+     674,   683,   691,   717,   721,   729,   733,   741,   744,   747,
+     750,   756,   763,   766,   770,   774,   779,   784,   791,   795,
+     799,   803,   808,   813,   817,   824,   834,   840,   843,   849,
+     855,   861,   869,   878,   885,   888,   894,   898,   902,   907,
+     915,   918,   934,   939,   944,   949,   956,   964,   975,   978,
+     981,   987,   994,   997,  1003,  1006,  1009,  1015,  1018,  1023,
+    1036,  1040,  1044,  1048,  1052,  1056,  1061,  1066,  1071,  1076,
+    1081,  1086,  1091,  1096,  1101,  1106,  1111,  1116,  1121,  1126,
+    1131,  1136,  1141,  1146,  1151,  1156,  1161,  1165,  1169,  1173,
+    1177,  1181,  1185,  1189,  1193,  1197,  1201,  1205,  1209,  1213,
+    1217,  1221,  1229,  1236,  1240,  1253,  1253,  1256,  1256,  1262,
+    1265,  1280,  1283,  1292,  1296,  1302,  1308,  1321,  1325,  1329,
+    1330,  1336,  1337,  1338,  1339,  1340,  1341,  1342,  1346,  1347,
+    1347,  1347,  1357,  1358,  1362,  1362,  1363,  1363,  1368,  1371,
+    1381,  1384,  1390,  1391,  1395,  1402,  1406,  1413,  1413,  1420,
+    1423,  1430,  1434,  1447,  1447,  1452,  1452,  1458,  1458,  1466,
+    1469,  1475,  1478,  1484,  1488,  1495,  1498,  1501,  1504,  1507,
+    1516,  1520,  1527,  1530,  1536,  1536
 };
 #endif
 
@@ -2494,8 +2487,7 @@
   case 17:
 
     {
-        if (context->integerErrorCheck((yyvsp[0].interm.intermTypedNode), "[]"))
-            context->recover();
+        context->integerErrorCheck((yyvsp[0].interm.intermTypedNode), "[]");
         (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
     }
 
@@ -2611,8 +2603,7 @@
   case 29:
 
     {
-        if (context->reservedErrorCheck((yylsp[0]), *(yyvsp[0].lex).string))
-            context->recover();
+        context->reservedErrorCheck((yylsp[0]), *(yyvsp[0].lex).string);
         const TType *type = TCache::getType(EbtVoid, EbpUndefined);
         TFunction *function = new TFunction((yyvsp[0].lex).string, type);
         (yyval.interm.function) = function;
@@ -2623,8 +2614,7 @@
   case 30:
 
     {
-        if (context->reservedErrorCheck((yylsp[0]), *(yyvsp[0].lex).string))
-            context->recover();
+        context->reservedErrorCheck((yylsp[0]), *(yyvsp[0].lex).string);
         const TType *type = TCache::getType(EbtVoid, EbpUndefined);
         TFunction *function = new TFunction((yyvsp[0].lex).string, type);
         (yyval.interm.function) = function;
@@ -2941,8 +2931,7 @@
   case 72:
 
     {
-        if (context->lValueErrorCheck((yylsp[-1]), "assign", (yyvsp[-2].interm.intermTypedNode)))
-            context->recover();
+        context->lValueErrorCheck((yylsp[-1]), "assign", (yyvsp[-2].interm.intermTypedNode));
         (yyval.interm.intermTypedNode) = context->addAssign((yyvsp[-1].interm).op, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
     }
 
@@ -3051,8 +3040,7 @@
   case 86:
 
     {
-        if (context->constErrorCheck((yyvsp[0].interm.intermTypedNode)))
-            context->recover();
+        context->constErrorCheck((yyvsp[0].interm.intermTypedNode));
         (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
     }
 
@@ -3061,8 +3049,7 @@
   case 87:
 
     {
-        if (context->enterStructDeclaration((yylsp[-1]), *(yyvsp[-1].lex).string))
-            context->recover();
+        context->enterStructDeclaration((yylsp[-1]), *(yyvsp[-1].lex).string);
         (yyval.lex) = (yyvsp[-1].lex);
     }
 
@@ -3092,11 +3079,9 @@
     {
         if (((yyvsp[-2].interm.precision) == EbpHigh) && (context->getShaderType() == GL_FRAGMENT_SHADER) && !context->getFragmentPrecisionHigh()) {
             context->error((yylsp[-3]), "precision is not supported in fragment shader", "highp");
-            context->recover();
         }
         if (!context->symbolTable.setDefaultPrecision( (yyvsp[-1].interm.type), (yyvsp[-2].interm.precision) )) {
             context->error((yylsp[-3]), "illegal type argument for default precision qualifier", getBasicString((yyvsp[-1].interm.type).type));
-            context->recover();
         }
         (yyval.interm.intermNode) = 0;
     }
@@ -3188,7 +3173,6 @@
             // This parameter > first is void
             //
             context->error((yylsp[-1]), "cannot be an argument type except for '(void)'", "void");
-            context->recover();
             delete (yyvsp[0].interm).param.type;
         } else {
             // Add the parameter
@@ -3214,10 +3198,8 @@
     {
         if ((yyvsp[-1].interm.type).type == EbtVoid) {
             context->error((yylsp[0]), "illegal use of type 'void'", (yyvsp[0].lex).string->c_str());
-            context->recover();
         }
-        if (context->reservedErrorCheck((yylsp[0]), *(yyvsp[0].lex).string))
-            context->recover();
+        context->reservedErrorCheck((yylsp[0]), *(yyvsp[0].lex).string);
         TParameter param = {(yyvsp[0].lex).string, new TType((yyvsp[-1].interm.type))};
         (yyval.interm).param = param;
     }
@@ -3228,15 +3210,13 @@
 
     {
         // Check that we can make an array out of this type
-        if (context->arrayTypeErrorCheck((yylsp[-2]), (yyvsp[-4].interm.type)))
-            context->recover();
+        context->arrayTypeErrorCheck((yylsp[-2]), (yyvsp[-4].interm.type));
 
-        if (context->reservedErrorCheck((yylsp[-3]), *(yyvsp[-3].lex).string))
-            context->recover();
+        context->reservedErrorCheck((yylsp[-3]), *(yyvsp[-3].lex).string);
 
         int size;
-        if (context->arraySizeErrorCheck((yylsp[-2]), (yyvsp[-1].interm.intermTypedNode), size))
-            context->recover();
+        context->arraySizeErrorCheck((yylsp[-2]), (yyvsp[-1].interm.intermTypedNode), size);
+
         (yyvsp[-4].interm.type).setArraySize(size);
 
         TType* type = new TType((yyvsp[-4].interm.type));
@@ -3250,8 +3230,7 @@
 
     {
         (yyval.interm) = (yyvsp[0].interm);
-        if (context->paramErrorCheck((yylsp[0]), (yyvsp[-2].interm.qualifier), (yyvsp[-1].interm.qualifier), (yyval.interm).param.type))
-            context->recover();
+        context->paramErrorCheck((yylsp[0]), (yyvsp[-2].interm.qualifier), (yyvsp[-1].interm.qualifier), (yyval.interm).param.type);
     }
 
     break;
@@ -3260,10 +3239,8 @@
 
     {
         (yyval.interm) = (yyvsp[0].interm);
-        if (context->parameterSamplerErrorCheck((yylsp[0]), (yyvsp[-1].interm.qualifier), *(yyvsp[0].interm).param.type))
-            context->recover();
-        if (context->paramErrorCheck((yylsp[0]), EvqTemporary, (yyvsp[-1].interm.qualifier), (yyval.interm).param.type))
-            context->recover();
+        context->parameterSamplerErrorCheck((yylsp[0]), (yyvsp[-1].interm.qualifier), *(yyvsp[0].interm).param.type);
+        context->paramErrorCheck((yylsp[0]), EvqTemporary, (yyvsp[-1].interm.qualifier), (yyval.interm).param.type);
     }
 
     break;
@@ -3272,8 +3249,7 @@
 
     {
         (yyval.interm) = (yyvsp[0].interm);
-        if (context->paramErrorCheck((yylsp[0]), (yyvsp[-2].interm.qualifier), (yyvsp[-1].interm.qualifier), (yyval.interm).param.type))
-            context->recover();
+        context->paramErrorCheck((yylsp[0]), (yyvsp[-2].interm.qualifier), (yyvsp[-1].interm.qualifier), (yyval.interm).param.type);
     }
 
     break;
@@ -3282,10 +3258,8 @@
 
     {
         (yyval.interm) = (yyvsp[0].interm);
-        if (context->parameterSamplerErrorCheck((yylsp[0]), (yyvsp[-1].interm.qualifier), *(yyvsp[0].interm).param.type))
-            context->recover();
-        if (context->paramErrorCheck((yylsp[0]), EvqTemporary, (yyvsp[-1].interm.qualifier), (yyval.interm).param.type))
-            context->recover();
+        context->parameterSamplerErrorCheck((yylsp[0]), (yyvsp[-1].interm.qualifier), *(yyvsp[0].interm).param.type);
+        context->paramErrorCheck((yylsp[0]), EvqTemporary, (yyvsp[-1].interm.qualifier), (yyval.interm).param.type);
     }
 
     break;
@@ -3503,8 +3477,7 @@
     {
         VERTEX_ONLY("attribute", (yylsp[0]));
         ES2_ONLY("attribute", (yylsp[0]));
-        if (context->globalErrorCheck((yylsp[0]), context->symbolTable.atGlobalLevel(), "attribute"))
-            context->recover();
+        context->globalErrorCheck((yylsp[0]), context->symbolTable.atGlobalLevel(), "attribute");
         (yyval.interm.type).setBasic(EbtVoid, EvqAttribute, (yylsp[0]));
     }
 
@@ -3514,8 +3487,7 @@
 
     {
         ES2_ONLY("varying", (yylsp[0]));
-        if (context->globalErrorCheck((yylsp[0]), context->symbolTable.atGlobalLevel(), "varying"))
-            context->recover();
+        context->globalErrorCheck((yylsp[0]), context->symbolTable.atGlobalLevel(), "varying");
         if (context->getShaderType() == GL_VERTEX_SHADER)
             (yyval.interm.type).setBasic(EbtVoid, EvqVaryingOut, (yylsp[0]));
         else
@@ -3528,8 +3500,7 @@
 
     {
         ES2_ONLY("varying", (yylsp[-1]));
-        if (context->globalErrorCheck((yylsp[-1]), context->symbolTable.atGlobalLevel(), "invariant varying"))
-            context->recover();
+        context->globalErrorCheck((yylsp[-1]), context->symbolTable.atGlobalLevel(), "invariant varying");
         if (context->getShaderType() == GL_VERTEX_SHADER)
             (yyval.interm.type).setBasic(EbtVoid, EvqVaryingOut, (yylsp[-1]));
         else
@@ -3545,7 +3516,6 @@
         if ((yyvsp[0].interm.type).qualifier != EvqConst && !context->symbolTable.atGlobalLevel())
         {
             context->error((yylsp[0]), "Local variables can only use the const storage qualifier.", getQualifierString((yyvsp[0].interm.type).qualifier));
-            context->recover();
         }
         (yyval.interm.type).setBasic(EbtVoid, (yyvsp[0].interm.type).qualifier, (yylsp[0]));
     }
@@ -3564,7 +3534,6 @@
 
     {
         context->error((yylsp[0]), "interpolation qualifier requires a fragment 'in' or vertex 'out' storage qualifier", getInterpolationString((yyvsp[0].interm.type).qualifier));
-        context->recover();
 
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
         (yyval.interm.type).setBasic(EbtVoid, qual, (yylsp[0]));
@@ -3643,7 +3612,7 @@
 
     {
         ES3_OR_NEWER("out", (yylsp[0]), "storage qualifier");
-        DRAW_ONLY("out", (yylsp[0]));
+        NON_COMPUTE_ONLY("out", (yylsp[0]));
         (yyval.interm.type).qualifier = (context->getShaderType() == GL_FRAGMENT_SHADER) ? EvqFragmentOut : EvqVertexOut;
     }
 
@@ -3672,8 +3641,7 @@
   case 145:
 
     {
-        if (context->globalErrorCheck((yylsp[0]), context->symbolTable.atGlobalLevel(), "uniform"))
-            context->recover();
+        context->globalErrorCheck((yylsp[0]), context->symbolTable.atGlobalLevel(), "uniform");
         (yyval.interm.type).qualifier = EvqUniform;
     }
 
@@ -3686,9 +3654,7 @@
 
         if ((yyval.interm.type).precision == EbpUndefined) {
             (yyval.interm.type).precision = context->symbolTable.getDefaultPrecision((yyvsp[0].interm.type).type);
-            if (context->precisionErrorCheck((yylsp[0]), (yyval.interm.type).precision, (yyvsp[0].interm.type).type)) {
-                context->recover();
-            }
+            context->precisionErrorCheck((yylsp[0]), (yyval.interm.type).precision, (yyvsp[0].interm.type).type);
         }
     }
 
@@ -3702,7 +3668,6 @@
 
         if (!SupportsPrecision((yyvsp[0].interm.type).type)) {
             context->error((yylsp[-1]), "illegal type for precision qualifier", getBasicString((yyvsp[0].interm.type).type));
-            context->recover();
         }
     }
 
@@ -3804,12 +3769,10 @@
     {
         (yyval.interm.type) = (yyvsp[-3].interm.type);
 
-        if (context->arrayTypeErrorCheck((yylsp[-2]), (yyvsp[-3].interm.type)))
-            context->recover();
-        else {
+        if (!context->arrayTypeErrorCheck((yylsp[-2]), (yyvsp[-3].interm.type)))
+        {
             int size;
-            if (context->arraySizeErrorCheck((yylsp[-2]), (yyvsp[-1].interm.intermTypedNode), size))
-                context->recover();
+            context->arraySizeErrorCheck((yylsp[-2]), (yyvsp[-1].interm.intermTypedNode), size);
             (yyval.interm.type).setArraySize(size);
         }
     }
@@ -4212,7 +4175,6 @@
         if (!context->supportsExtension("GL_OES_EGL_image_external") &&
             !context->supportsExtension("GL_NV_EGL_stream_consumer_external")) {
             context->error((yylsp[0]), "unsupported type", "samplerExternalOES");
-            context->recover();
         }
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
         (yyval.interm.type).setBasic(EbtSamplerExternalOES, qual, (yylsp[0]));
@@ -4225,7 +4187,6 @@
     {
         if (!context->supportsExtension("GL_ARB_texture_rectangle")) {
             context->error((yylsp[0]), "unsupported type", "sampler2DRect");
-            context->recover();
         }
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
         (yyval.interm.type).setBasic(EbtSampler2DRect, qual, (yylsp[0]));
@@ -4259,7 +4220,7 @@
 
   case 205:
 
-    { if (context->enterStructDeclaration((yylsp[-1]), *(yyvsp[-1].lex).string)) context->recover(); }
+    { context->enterStructDeclaration((yylsp[-1]), *(yyvsp[-1].lex).string); }
 
     break;
 
@@ -4273,7 +4234,7 @@
 
   case 207:
 
-    { if (context->enterStructDeclaration((yylsp[0]), *(yyvsp[0].lex).string)) context->recover(); }
+    { context->enterStructDeclaration((yylsp[0]), *(yyvsp[0].lex).string); }
 
     break;
 
@@ -4302,7 +4263,6 @@
             for (size_t j = 0; j < (yyval.interm.fieldList)->size(); ++j) {
                 if ((*(yyval.interm.fieldList))[j]->name() == field->name()) {
                     context->error((yylsp[0]), "duplicate field name in structure:", "struct", field->name().c_str());
-                    context->recover();
                 }
             }
             (yyval.interm.fieldList)->push_back(field);
@@ -4350,8 +4310,7 @@
   case 215:
 
     {
-        if (context->reservedErrorCheck((yylsp[0]), *(yyvsp[0].lex).string))
-            context->recover();
+        context->reservedErrorCheck((yylsp[0]), *(yyvsp[0].lex).string);
 
         TType* type = new TType(EbtVoid, EbpUndefined);
         (yyval.interm.field) = new TField(type, (yyvsp[0].lex).string, (yylsp[0]));
@@ -4362,13 +4321,11 @@
   case 216:
 
     {
-        if (context->reservedErrorCheck((yylsp[-3]), *(yyvsp[-3].lex).string))
-            context->recover();
+        context->reservedErrorCheck((yylsp[-3]), *(yyvsp[-3].lex).string);
 
         TType* type = new TType(EbtVoid, EbpUndefined);
         int size;
-        if (context->arraySizeErrorCheck((yylsp[-1]), (yyvsp[-1].interm.intermTypedNode), size))
-            context->recover();
+        context->arraySizeErrorCheck((yylsp[-1]), (yyvsp[-1].interm.intermTypedNode), size);
         type->setArraySize(size);
 
         (yyval.interm.field) = new TField(type, (yyvsp[-3].lex).string, (yylsp[-3]));
@@ -4559,8 +4516,7 @@
   case 244:
 
     {
-        if (context->boolErrorCheck((yylsp[-4]), (yyvsp[-2].interm.intermTypedNode)))
-            context->recover();
+        context->boolErrorCheck((yylsp[-4]), (yyvsp[-2].interm.intermTypedNode));
         (yyval.interm.intermNode) = context->intermediate.addSelection((yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.nodePair), (yylsp[-4]));
     }
 
@@ -4619,8 +4575,7 @@
 
     {
         (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
-        if (context->boolErrorCheck((yyvsp[0].interm.intermTypedNode)->getLine(), (yyvsp[0].interm.intermTypedNode)))
-            context->recover();
+        context->boolErrorCheck((yyvsp[0].interm.intermTypedNode)->getLine(), (yyvsp[0].interm.intermTypedNode));
     }
 
     break;
@@ -4629,13 +4584,11 @@
 
     {
         TIntermNode *intermNode;
-        if (context->boolErrorCheck((yylsp[-2]), (yyvsp[-3].interm.type)))
-            context->recover();
+        context->boolErrorCheck((yylsp[-2]), (yyvsp[-3].interm.type));
 
         if (!context->executeInitializer((yylsp[-2]), *(yyvsp[-2].lex).string, (yyvsp[-3].interm.type), (yyvsp[0].interm.intermTypedNode), &intermNode))
             (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
         else {
-            context->recover();
             (yyval.interm.intermTypedNode) = 0;
         }
     }
@@ -4667,8 +4620,7 @@
   case 256:
 
     {
-        if (context->boolErrorCheck((yylsp[0]), (yyvsp[-2].interm.intermTypedNode)))
-            context->recover();
+        context->boolErrorCheck((yylsp[0]), (yyvsp[-2].interm.intermTypedNode));
 
         (yyval.interm.intermNode) = context->intermediate.addLoop(ELoopDoWhile, 0, (yyvsp[-2].interm.intermTypedNode), 0, (yyvsp[-5].interm.intermNode), (yylsp[-4]));
         context->decrLoopNestingLevel();