Commit 383b791a by Olli Etuaho Committed by Commit Bot

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