Commit c6b3b3c7 by maxvujovic@gmail.com

Fix the compiler warnings on WebKit ports when updating ANGLE in WebKit.

Remove the varargs used for extra info formatting in the error() and warning() methods of ParseHelper. Use std::stringstream for formatting instead. Review URL: http://codereview.appspot.com/6310067/ git-svn-id: https://angleproject.googlecode.com/svn/trunk@1170 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 432d6fc4
...@@ -2235,6 +2235,8 @@ TString OutputHLSL::typeString(const TType &type) ...@@ -2235,6 +2235,8 @@ TString OutputHLSL::typeString(const TType &type)
return "samplerCUBE"; return "samplerCUBE";
case EbtSamplerExternalOES: case EbtSamplerExternalOES:
return "sampler2D"; return "sampler2D";
default:
break;
} }
} }
......
...@@ -26,7 +26,7 @@ bool TParseContext::parseVectorFields(const TString& compString, int vecSize, TV ...@@ -26,7 +26,7 @@ bool TParseContext::parseVectorFields(const TString& compString, int vecSize, TV
{ {
fields.num = (int) compString.size(); fields.num = (int) compString.size();
if (fields.num > 4) { if (fields.num > 4) {
error(line, "illegal vector field selection", compString.c_str(), ""); error(line, "illegal vector field selection", compString.c_str());
return false; return false;
} }
...@@ -88,20 +88,20 @@ bool TParseContext::parseVectorFields(const TString& compString, int vecSize, TV ...@@ -88,20 +88,20 @@ bool TParseContext::parseVectorFields(const TString& compString, int vecSize, TV
fieldSet[i] = estpq; fieldSet[i] = estpq;
break; break;
default: default:
error(line, "illegal vector field selection", compString.c_str(), ""); error(line, "illegal vector field selection", compString.c_str());
return false; return false;
} }
} }
for (int i = 0; i < fields.num; ++i) { for (int i = 0; i < fields.num; ++i) {
if (fields.offsets[i] >= vecSize) { if (fields.offsets[i] >= vecSize) {
error(line, "vector field selection out of range", compString.c_str(), ""); error(line, "vector field selection out of range", compString.c_str());
return false; return false;
} }
if (i > 0) { if (i > 0) {
if (fieldSet[i] != fieldSet[i-1]) { if (fieldSet[i] != fieldSet[i-1]) {
error(line, "illegal - vector component fields not from the same set", compString.c_str(), ""); error(line, "illegal - vector component fields not from the same set", compString.c_str());
return false; return false;
} }
} }
...@@ -123,20 +123,20 @@ bool TParseContext::parseMatrixFields(const TString& compString, int matSize, TM ...@@ -123,20 +123,20 @@ bool TParseContext::parseMatrixFields(const TString& compString, int matSize, TM
fields.col = -1; fields.col = -1;
if (compString.size() != 2) { if (compString.size() != 2) {
error(line, "illegal length of matrix field selection", compString.c_str(), ""); error(line, "illegal length of matrix field selection", compString.c_str());
return false; return false;
} }
if (compString[0] == '_') { if (compString[0] == '_') {
if (compString[1] < '0' || compString[1] > '3') { if (compString[1] < '0' || compString[1] > '3') {
error(line, "illegal matrix field selection", compString.c_str(), ""); error(line, "illegal matrix field selection", compString.c_str());
return false; return false;
} }
fields.wholeCol = true; fields.wholeCol = true;
fields.col = compString[1] - '0'; fields.col = compString[1] - '0';
} else if (compString[1] == '_') { } else if (compString[1] == '_') {
if (compString[0] < '0' || compString[0] > '3') { if (compString[0] < '0' || compString[0] > '3') {
error(line, "illegal matrix field selection", compString.c_str(), ""); error(line, "illegal matrix field selection", compString.c_str());
return false; return false;
} }
fields.wholeRow = true; fields.wholeRow = true;
...@@ -144,7 +144,7 @@ bool TParseContext::parseMatrixFields(const TString& compString, int matSize, TM ...@@ -144,7 +144,7 @@ bool TParseContext::parseMatrixFields(const TString& compString, int matSize, TM
} else { } else {
if (compString[0] < '0' || compString[0] > '3' || if (compString[0] < '0' || compString[0] > '3' ||
compString[1] < '0' || compString[1] > '3') { compString[1] < '0' || compString[1] > '3') {
error(line, "illegal matrix field selection", compString.c_str(), ""); error(line, "illegal matrix field selection", compString.c_str());
return false; return false;
} }
fields.row = compString[0] - '0'; fields.row = compString[0] - '0';
...@@ -152,7 +152,7 @@ bool TParseContext::parseMatrixFields(const TString& compString, int matSize, TM ...@@ -152,7 +152,7 @@ bool TParseContext::parseMatrixFields(const TString& compString, int matSize, TM
} }
if (fields.row >= matSize || fields.col >= matSize) { if (fields.row >= matSize || fields.col >= matSize) {
error(line, "matrix field selection out of range", compString.c_str(), ""); error(line, "matrix field selection out of range", compString.c_str());
return false; return false;
} }
...@@ -177,36 +177,23 @@ void TParseContext::recover() ...@@ -177,36 +177,23 @@ void TParseContext::recover()
// //
void TParseContext::error(TSourceLoc loc, void TParseContext::error(TSourceLoc loc,
const char* reason, const char* token, const char* reason, const char* token,
const char* extraInfoFormat, ...) const char* extraInfo)
{ {
char extraInfo[512];
va_list marker;
va_start(marker, extraInfoFormat);
vsnprintf(extraInfo, sizeof(extraInfo), extraInfoFormat, marker);
pp::SourceLocation srcLoc; pp::SourceLocation srcLoc;
DecodeSourceLoc(loc, &srcLoc.file, &srcLoc.line); DecodeSourceLoc(loc, &srcLoc.file, &srcLoc.line);
diagnostics.writeInfo(pp::Diagnostics::ERROR, diagnostics.writeInfo(pp::Diagnostics::ERROR,
srcLoc, reason, token, extraInfo); srcLoc, reason, token, extraInfo);
va_end(marker);
++numErrors; ++numErrors;
} }
void TParseContext::warning(TSourceLoc loc, void TParseContext::warning(TSourceLoc loc,
const char* reason, const char* token, const char* reason, const char* token,
const char* extraInfoFormat, ...) { const char* extraInfo) {
char extraInfo[512];
va_list marker;
va_start(marker, extraInfoFormat);
vsnprintf(extraInfo, sizeof(extraInfo), extraInfoFormat, marker);
pp::SourceLocation srcLoc; pp::SourceLocation srcLoc;
DecodeSourceLoc(loc, &srcLoc.file, &srcLoc.line); DecodeSourceLoc(loc, &srcLoc.file, &srcLoc.line);
diagnostics.writeInfo(pp::Diagnostics::WARNING, diagnostics.writeInfo(pp::Diagnostics::WARNING,
srcLoc, reason, token, extraInfo); srcLoc, reason, token, extraInfo);
va_end(marker);
} }
void TParseContext::trace(const char* str) void TParseContext::trace(const char* str)
...@@ -219,8 +206,10 @@ void TParseContext::trace(const char* str) ...@@ -219,8 +206,10 @@ void TParseContext::trace(const char* str)
// //
void TParseContext::assignError(int line, const char* op, TString left, TString right) void TParseContext::assignError(int line, const char* op, TString left, TString right)
{ {
error(line, "", op, "cannot convert from '%s' to '%s'", std::stringstream extraInfoStream;
right.c_str(), left.c_str()); extraInfoStream << "cannot convert from '" << right << "' to '" << left << "'";
std::string extraInfo = extraInfoStream.str();
error(line, "", op, extraInfo.c_str());
} }
// //
...@@ -228,9 +217,11 @@ void TParseContext::assignError(int line, const char* op, TString left, TString ...@@ -228,9 +217,11 @@ void TParseContext::assignError(int line, const char* op, TString left, TString
// //
void TParseContext::unaryOpError(int line, const char* op, TString operand) void TParseContext::unaryOpError(int line, const char* op, TString operand)
{ {
error(line, " wrong operand type", op, std::stringstream extraInfoStream;
"no operation '%s' exists that takes an operand of type %s (or there is no acceptable conversion)", extraInfoStream << "no operation '" << op << "' exists that takes an operand of type " << operand
op, operand.c_str()); << " (or there is no acceptable conversion)";
std::string extraInfo = extraInfoStream.str();
error(line, " wrong operand type", op, extraInfo.c_str());
} }
// //
...@@ -238,10 +229,11 @@ void TParseContext::unaryOpError(int line, const char* op, TString operand) ...@@ -238,10 +229,11 @@ void TParseContext::unaryOpError(int line, const char* op, TString operand)
// //
void TParseContext::binaryOpError(int line, const char* op, TString left, TString right) void TParseContext::binaryOpError(int line, const char* op, TString left, TString right)
{ {
error(line, " wrong operand types ", op, std::stringstream extraInfoStream;
"no operation '%s' exists that takes a left-hand operand of type '%s' and " extraInfoStream << "no operation '" << op << "' exists that takes a left-hand operand of type '" << left
"a right operand of type '%s' (or there is no acceptable conversion)", << "' and a right operand of type '" << right << "' (or there is no acceptable conversion)";
op, left.c_str(), right.c_str()); std::string extraInfo = extraInfoStream.str();
error(line, " wrong operand types ", op, extraInfo.c_str());
} }
bool TParseContext::precisionErrorCheck(int line, TPrecision precision, TBasicType type){ bool TParseContext::precisionErrorCheck(int line, TPrecision precision, TBasicType type){
...@@ -250,13 +242,13 @@ bool TParseContext::precisionErrorCheck(int line, TPrecision precision, TBasicTy ...@@ -250,13 +242,13 @@ bool TParseContext::precisionErrorCheck(int line, TPrecision precision, TBasicTy
switch( type ){ switch( type ){
case EbtFloat: case EbtFloat:
if( precision == EbpUndefined ){ if( precision == EbpUndefined ){
error( line, "No precision specified for (float)", "", "" ); error( line, "No precision specified for (float)", "" );
return true; return true;
} }
break; break;
case EbtInt: case EbtInt:
if( precision == EbpUndefined ){ if( precision == EbpUndefined ){
error( line, "No precision specified (int)", "", "" ); error( line, "No precision specified (int)", "" );
return true; return true;
} }
break; break;
...@@ -298,7 +290,7 @@ bool TParseContext::lValueErrorCheck(int line, const char* op, TIntermTyped* nod ...@@ -298,7 +290,7 @@ bool TParseContext::lValueErrorCheck(int line, const char* op, TIntermTyped* nod
int value = (*p)->getAsTyped()->getAsConstantUnion()->getUnionArrayPointer()->getIConst(); int value = (*p)->getAsTyped()->getAsConstantUnion()->getUnionArrayPointer()->getIConst();
offset[value]++; offset[value]++;
if (offset[value] > 1) { if (offset[value] > 1) {
error(line, " l-value of swizzle cannot have duplicate components", op, "", ""); error(line, " l-value of swizzle cannot have duplicate components", op);
return true; return true;
} }
...@@ -309,7 +301,7 @@ bool TParseContext::lValueErrorCheck(int line, const char* op, TIntermTyped* nod ...@@ -309,7 +301,7 @@ bool TParseContext::lValueErrorCheck(int line, const char* op, TIntermTyped* nod
default: default:
break; break;
} }
error(line, " l-value required", op, "", ""); error(line, " l-value required", op);
return true; return true;
} }
...@@ -349,7 +341,7 @@ bool TParseContext::lValueErrorCheck(int line, const char* op, TIntermTyped* nod ...@@ -349,7 +341,7 @@ bool TParseContext::lValueErrorCheck(int line, const char* op, TIntermTyped* nod
} }
if (message == 0 && binaryNode == 0 && symNode == 0) { if (message == 0 && binaryNode == 0 && symNode == 0) {
error(line, " l-value required", op, "", ""); error(line, " l-value required", op);
return true; return true;
} }
...@@ -364,10 +356,18 @@ bool TParseContext::lValueErrorCheck(int line, const char* op, TIntermTyped* nod ...@@ -364,10 +356,18 @@ bool TParseContext::lValueErrorCheck(int line, const char* op, TIntermTyped* nod
// //
// If we get here, we have an error and a message. // If we get here, we have an error and a message.
// //
if (symNode) if (symNode) {
error(line, " l-value required", op, "\"%s\" (%s)", symbol, message); std::stringstream extraInfoStream;
else extraInfoStream << "\"" << symbol << "\" (" << message << ")";
error(line, " l-value required", op, "(%s)", message); std::string extraInfo = extraInfoStream.str();
error(line, " l-value required", op, extraInfo.c_str());
}
else {
std::stringstream extraInfoStream;
extraInfoStream << "(" << message << ")";
std::string extraInfo = extraInfoStream.str();
error(line, " l-value required", op, extraInfo.c_str());
}
return true; return true;
} }
...@@ -383,7 +383,7 @@ bool TParseContext::constErrorCheck(TIntermTyped* node) ...@@ -383,7 +383,7 @@ bool TParseContext::constErrorCheck(TIntermTyped* node)
if (node->getQualifier() == EvqConst) if (node->getQualifier() == EvqConst)
return false; return false;
error(node->getLine(), "constant expression required", "", ""); error(node->getLine(), "constant expression required", "");
return true; return true;
} }
...@@ -399,7 +399,7 @@ bool TParseContext::integerErrorCheck(TIntermTyped* node, const char* token) ...@@ -399,7 +399,7 @@ bool TParseContext::integerErrorCheck(TIntermTyped* node, const char* token)
if (node->getBasicType() == EbtInt && node->getNominalSize() == 1) if (node->getBasicType() == EbtInt && node->getNominalSize() == 1)
return false; return false;
error(node->getLine(), "integer expression required", token, ""); error(node->getLine(), "integer expression required", token);
return true; return true;
} }
...@@ -415,7 +415,7 @@ bool TParseContext::globalErrorCheck(int line, bool global, const char* token) ...@@ -415,7 +415,7 @@ bool TParseContext::globalErrorCheck(int line, bool global, const char* token)
if (global) if (global)
return false; return false;
error(line, "only allowed at global scope", token, ""); error(line, "only allowed at global scope", token);
return true; return true;
} }
...@@ -434,25 +434,25 @@ bool TParseContext::reservedErrorCheck(int line, const TString& identifier) ...@@ -434,25 +434,25 @@ bool TParseContext::reservedErrorCheck(int line, const TString& identifier)
static const char* reservedErrMsg = "reserved built-in name"; static const char* reservedErrMsg = "reserved built-in name";
if (!symbolTable.atBuiltInLevel()) { if (!symbolTable.atBuiltInLevel()) {
if (identifier.compare(0, 3, "gl_") == 0) { if (identifier.compare(0, 3, "gl_") == 0) {
error(line, reservedErrMsg, "gl_", ""); error(line, reservedErrMsg, "gl_");
return true; return true;
} }
if (isWebGLBasedSpec(shaderSpec)) { if (isWebGLBasedSpec(shaderSpec)) {
if (identifier.compare(0, 6, "webgl_") == 0) { if (identifier.compare(0, 6, "webgl_") == 0) {
error(line, reservedErrMsg, "webgl_", ""); error(line, reservedErrMsg, "webgl_");
return true; return true;
} }
if (identifier.compare(0, 7, "_webgl_") == 0) { if (identifier.compare(0, 7, "_webgl_") == 0) {
error(line, reservedErrMsg, "_webgl_", ""); error(line, reservedErrMsg, "_webgl_");
return true; return true;
} }
if (shaderSpec == SH_CSS_SHADERS_SPEC && identifier.compare(0, 4, "css_") == 0) { if (shaderSpec == SH_CSS_SHADERS_SPEC && identifier.compare(0, 4, "css_") == 0) {
error(line, reservedErrMsg, "css_", ""); error(line, reservedErrMsg, "css_");
return true; return true;
} }
} }
if (identifier.find("__") != TString::npos) { if (identifier.find("__") != TString::npos) {
error(line, "identifiers containing two consecutive underscores (__) are reserved as possible future keywords", identifier.c_str(), "", ""); error(line, "identifiers containing two consecutive underscores (__) are reserved as possible future keywords", identifier.c_str());
return true; return true;
} }
} }
...@@ -514,51 +514,51 @@ bool TParseContext::constructorErrorCheck(int line, TIntermNode* node, TFunction ...@@ -514,51 +514,51 @@ bool TParseContext::constructorErrorCheck(int line, TIntermNode* node, TFunction
type->setQualifier(EvqConst); type->setQualifier(EvqConst);
if (type->isArray() && type->getArraySize() != function.getParamCount()) { if (type->isArray() && type->getArraySize() != function.getParamCount()) {
error(line, "array constructor needs one argument per array element", "constructor", ""); error(line, "array constructor needs one argument per array element", "constructor");
return true; return true;
} }
if (arrayArg && op != EOpConstructStruct) { if (arrayArg && op != EOpConstructStruct) {
error(line, "constructing from a non-dereferenced array", "constructor", ""); error(line, "constructing from a non-dereferenced array", "constructor");
return true; return true;
} }
if (matrixInMatrix && !type->isArray()) { if (matrixInMatrix && !type->isArray()) {
if (function.getParamCount() != 1) { if (function.getParamCount() != 1) {
error(line, "constructing matrix from matrix can only take one argument", "constructor", ""); error(line, "constructing matrix from matrix can only take one argument", "constructor");
return true; return true;
} }
} }
if (overFull) { if (overFull) {
error(line, "too many arguments", "constructor", ""); error(line, "too many arguments", "constructor");
return true; return true;
} }
if (op == EOpConstructStruct && !type->isArray() && int(type->getStruct()->size()) != function.getParamCount()) { if (op == EOpConstructStruct && !type->isArray() && int(type->getStruct()->size()) != function.getParamCount()) {
error(line, "Number of constructor parameters does not match the number of structure fields", "constructor", ""); error(line, "Number of constructor parameters does not match the number of structure fields", "constructor");
return true; return true;
} }
if (!type->isMatrix() || !matrixInMatrix) { if (!type->isMatrix() || !matrixInMatrix) {
if ((op != EOpConstructStruct && size != 1 && size < type->getObjectSize()) || if ((op != EOpConstructStruct && size != 1 && size < type->getObjectSize()) ||
(op == EOpConstructStruct && size < type->getObjectSize())) { (op == EOpConstructStruct && size < type->getObjectSize())) {
error(line, "not enough data provided for construction", "constructor", ""); error(line, "not enough data provided for construction", "constructor");
return true; return true;
} }
} }
TIntermTyped *typed = node ? node->getAsTyped() : 0; TIntermTyped *typed = node ? node->getAsTyped() : 0;
if (typed == 0) { if (typed == 0) {
error(line, "constructor argument does not have a type", "constructor", ""); error(line, "constructor argument does not have a type", "constructor");
return true; return true;
} }
if (op != EOpConstructStruct && IsSampler(typed->getBasicType())) { if (op != EOpConstructStruct && IsSampler(typed->getBasicType())) {
error(line, "cannot convert a sampler", "constructor", ""); error(line, "cannot convert a sampler", "constructor");
return true; return true;
} }
if (typed->getBasicType() == EbtVoid) { if (typed->getBasicType() == EbtVoid) {
error(line, "cannot convert a void", "constructor", ""); error(line, "cannot convert a void", "constructor");
return true; return true;
} }
...@@ -572,7 +572,7 @@ bool TParseContext::constructorErrorCheck(int line, TIntermNode* node, TFunction ...@@ -572,7 +572,7 @@ bool TParseContext::constructorErrorCheck(int line, TIntermNode* node, TFunction
bool TParseContext::voidErrorCheck(int line, const TString& identifier, const TPublicType& pubType) bool TParseContext::voidErrorCheck(int line, const TString& identifier, const TPublicType& pubType)
{ {
if (pubType.type == EbtVoid) { if (pubType.type == EbtVoid) {
error(line, "illegal use of type 'void'", identifier.c_str(), ""); error(line, "illegal use of type 'void'", identifier.c_str());
return true; return true;
} }
...@@ -586,7 +586,7 @@ bool TParseContext::voidErrorCheck(int line, const TString& identifier, const TP ...@@ -586,7 +586,7 @@ bool TParseContext::voidErrorCheck(int line, const TString& identifier, const TP
bool TParseContext::boolErrorCheck(int line, const TIntermTyped* type) bool TParseContext::boolErrorCheck(int line, const TIntermTyped* type)
{ {
if (type->getBasicType() != EbtBool || type->isArray() || type->isMatrix() || type->isVector()) { if (type->getBasicType() != EbtBool || type->isArray() || type->isMatrix() || type->isVector()) {
error(line, "boolean expression expected", "", ""); error(line, "boolean expression expected", "");
return true; return true;
} }
...@@ -600,7 +600,7 @@ bool TParseContext::boolErrorCheck(int line, const TIntermTyped* type) ...@@ -600,7 +600,7 @@ bool TParseContext::boolErrorCheck(int line, const TIntermTyped* type)
bool TParseContext::boolErrorCheck(int line, const TPublicType& pType) bool TParseContext::boolErrorCheck(int line, const TPublicType& pType)
{ {
if (pType.type != EbtBool || pType.array || pType.matrix || (pType.size > 1)) { if (pType.type != EbtBool || pType.array || pType.matrix || (pType.size > 1)) {
error(line, "boolean expression expected", "", ""); error(line, "boolean expression expected", "");
return true; return true;
} }
...@@ -618,7 +618,7 @@ bool TParseContext::samplerErrorCheck(int line, const TPublicType& pType, const ...@@ -618,7 +618,7 @@ bool TParseContext::samplerErrorCheck(int line, const TPublicType& pType, const
return false; return false;
} else if (IsSampler(pType.type)) { } else if (IsSampler(pType.type)) {
error(line, reason, getBasicString(pType.type), ""); error(line, reason, getBasicString(pType.type));
return true; return true;
} }
...@@ -630,7 +630,7 @@ bool TParseContext::structQualifierErrorCheck(int line, const TPublicType& pType ...@@ -630,7 +630,7 @@ bool TParseContext::structQualifierErrorCheck(int line, const TPublicType& pType
{ {
if ((pType.qualifier == EvqVaryingIn || pType.qualifier == EvqVaryingOut || pType.qualifier == EvqAttribute) && if ((pType.qualifier == EvqVaryingIn || pType.qualifier == EvqVaryingOut || pType.qualifier == EvqAttribute) &&
pType.type == EbtStruct) { pType.type == EbtStruct) {
error(line, "cannot be used with a structure", getQualifierString(pType.qualifier), ""); error(line, "cannot be used with a structure", getQualifierString(pType.qualifier));
return true; return true;
} }
...@@ -645,7 +645,7 @@ bool TParseContext::parameterSamplerErrorCheck(int line, TQualifier qualifier, c ...@@ -645,7 +645,7 @@ bool TParseContext::parameterSamplerErrorCheck(int line, TQualifier qualifier, c
{ {
if ((qualifier == EvqOut || qualifier == EvqInOut) && if ((qualifier == EvqOut || qualifier == EvqInOut) &&
type.getBasicType() != EbtStruct && IsSampler(type.getBasicType())) { type.getBasicType() != EbtStruct && IsSampler(type.getBasicType())) {
error(line, "samplers cannot be output parameters", type.getBasicString(), ""); error(line, "samplers cannot be output parameters", type.getBasicString());
return true; return true;
} }
...@@ -677,14 +677,14 @@ bool TParseContext::arraySizeErrorCheck(int line, TIntermTyped* expr, int& size) ...@@ -677,14 +677,14 @@ bool TParseContext::arraySizeErrorCheck(int line, TIntermTyped* expr, int& size)
{ {
TIntermConstantUnion* constant = expr->getAsConstantUnion(); TIntermConstantUnion* constant = expr->getAsConstantUnion();
if (constant == 0 || constant->getBasicType() != EbtInt) { if (constant == 0 || constant->getBasicType() != EbtInt) {
error(line, "array size must be a constant integer expression", "", ""); error(line, "array size must be a constant integer expression", "");
return true; return true;
} }
size = constant->getUnionArrayPointer()->getIConst(); size = constant->getUnionArrayPointer()->getIConst();
if (size <= 0) { if (size <= 0) {
error(line, "array size must be a positive integer", "", ""); error(line, "array size must be a positive integer", "");
size = 1; size = 1;
return true; return true;
} }
...@@ -700,7 +700,7 @@ bool TParseContext::arraySizeErrorCheck(int line, TIntermTyped* expr, int& size) ...@@ -700,7 +700,7 @@ bool TParseContext::arraySizeErrorCheck(int line, TIntermTyped* expr, int& size)
bool TParseContext::arrayQualifierErrorCheck(int line, TPublicType type) bool TParseContext::arrayQualifierErrorCheck(int line, TPublicType type)
{ {
if ((type.qualifier == EvqAttribute) || (type.qualifier == EvqConst)) { if ((type.qualifier == EvqAttribute) || (type.qualifier == EvqConst)) {
error(line, "cannot declare arrays of this qualifier", TType(type).getCompleteString().c_str(), ""); error(line, "cannot declare arrays of this qualifier", TType(type).getCompleteString().c_str());
return true; return true;
} }
...@@ -718,7 +718,7 @@ bool TParseContext::arrayTypeErrorCheck(int line, TPublicType type) ...@@ -718,7 +718,7 @@ bool TParseContext::arrayTypeErrorCheck(int line, TPublicType type)
// Can the type be an array? // Can the type be an array?
// //
if (type.array) { if (type.array) {
error(line, "cannot declare arrays of arrays", TType(type).getCompleteString().c_str(), ""); error(line, "cannot declare arrays of arrays", TType(type).getCompleteString().c_str());
return true; return true;
} }
...@@ -754,34 +754,34 @@ bool TParseContext::arrayErrorCheck(int line, TString& identifier, TPublicType t ...@@ -754,34 +754,34 @@ bool TParseContext::arrayErrorCheck(int line, TString& identifier, TPublicType t
if (! symbolTable.insert(*variable)) { if (! symbolTable.insert(*variable)) {
delete variable; delete variable;
error(line, "INTERNAL ERROR inserting new symbol", identifier.c_str(), ""); error(line, "INTERNAL ERROR inserting new symbol", identifier.c_str());
return true; return true;
} }
} else { } else {
if (! symbol->isVariable()) { if (! symbol->isVariable()) {
error(line, "variable expected", identifier.c_str(), ""); error(line, "variable expected", identifier.c_str());
return true; return true;
} }
variable = static_cast<TVariable*>(symbol); variable = static_cast<TVariable*>(symbol);
if (! variable->getType().isArray()) { if (! variable->getType().isArray()) {
error(line, "redeclaring non-array as array", identifier.c_str(), ""); error(line, "redeclaring non-array as array", identifier.c_str());
return true; return true;
} }
if (variable->getType().getArraySize() > 0) { if (variable->getType().getArraySize() > 0) {
error(line, "redeclaration of array with size", identifier.c_str(), ""); error(line, "redeclaration of array with size", identifier.c_str());
return true; return true;
} }
if (! variable->getType().sameElementType(TType(type))) { if (! variable->getType().sameElementType(TType(type))) {
error(line, "redeclaration of array with a different type", identifier.c_str(), ""); error(line, "redeclaration of array with a different type", identifier.c_str());
return true; return true;
} }
TType* t = variable->getArrayInformationType(); TType* t = variable->getArrayInformationType();
while (t != 0) { while (t != 0) {
if (t->getMaxArraySize() > type.arraySize) { if (t->getMaxArraySize() > type.arraySize) {
error(line, "higher index value already used for the array", identifier.c_str(), ""); error(line, "higher index value already used for the array", identifier.c_str());
return true; return true;
} }
t->setArraySize(type.arraySize); t->setArraySize(type.arraySize);
...@@ -803,7 +803,7 @@ bool TParseContext::arraySetMaxSize(TIntermSymbol *node, TType* type, int size, ...@@ -803,7 +803,7 @@ bool TParseContext::arraySetMaxSize(TIntermSymbol *node, TType* type, int size,
bool builtIn = false; bool builtIn = false;
TSymbol* symbol = symbolTable.find(node->getSymbol(), &builtIn); TSymbol* symbol = symbolTable.find(node->getSymbol(), &builtIn);
if (symbol == 0) { if (symbol == 0) {
error(line, " undeclared identifier", node->getSymbol().c_str(), ""); error(line, " undeclared identifier", node->getSymbol().c_str());
return true; return true;
} }
TVariable* variable = static_cast<TVariable*>(symbol); TVariable* variable = static_cast<TVariable*>(symbol);
...@@ -819,7 +819,7 @@ bool TParseContext::arraySetMaxSize(TIntermSymbol *node, TType* type, int size, ...@@ -819,7 +819,7 @@ bool TParseContext::arraySetMaxSize(TIntermSymbol *node, TType* type, int size,
int fragDataValue = static_cast<TVariable*>(fragData)->getConstPointer()[0].getIConst(); int fragDataValue = static_cast<TVariable*>(fragData)->getConstPointer()[0].getIConst();
if (fragDataValue <= size) { if (fragDataValue <= size) {
error(line, "", "[", "gl_FragData can only have a max array size of up to gl_MaxDrawBuffers", ""); error(line, "", "[", "gl_FragData can only have a max array size of up to gl_MaxDrawBuffers");
return true; return true;
} }
} }
...@@ -854,7 +854,7 @@ bool TParseContext::nonInitConstErrorCheck(int line, TString& identifier, TPubli ...@@ -854,7 +854,7 @@ bool TParseContext::nonInitConstErrorCheck(int line, TString& identifier, TPubli
// //
if (type.qualifier == EvqConst) { if (type.qualifier == EvqConst) {
type.qualifier = EvqTemporary; type.qualifier = EvqTemporary;
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 true; return true;
} }
...@@ -875,7 +875,7 @@ bool TParseContext::nonInitErrorCheck(int line, TString& identifier, TPublicType ...@@ -875,7 +875,7 @@ bool TParseContext::nonInitErrorCheck(int line, TString& identifier, TPublicType
variable = new TVariable(&identifier, TType(type)); variable = new TVariable(&identifier, TType(type));
if (! symbolTable.insert(*variable)) { if (! symbolTable.insert(*variable)) {
error(line, "redefinition", variable->getName().c_str(), ""); error(line, "redefinition", variable->getName().c_str());
delete variable; delete variable;
variable = 0; variable = 0;
return true; return true;
...@@ -890,7 +890,7 @@ bool TParseContext::nonInitErrorCheck(int line, TString& identifier, TPublicType ...@@ -890,7 +890,7 @@ bool TParseContext::nonInitErrorCheck(int line, TString& identifier, TPublicType
bool TParseContext::paramErrorCheck(int line, TQualifier qualifier, TQualifier paramQualifier, TType* type) bool TParseContext::paramErrorCheck(int line, TQualifier qualifier, TQualifier paramQualifier, TType* type)
{ {
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 true;
} }
if (qualifier == EvqConst && paramQualifier != EvqIn) { if (qualifier == EvqConst && paramQualifier != EvqIn) {
...@@ -969,12 +969,12 @@ const TFunction* TParseContext::findFunction(int line, TFunction* call, bool *bu ...@@ -969,12 +969,12 @@ const TFunction* TParseContext::findFunction(int line, TFunction* call, bool *bu
} }
if (symbol == 0) { if (symbol == 0) {
error(line, "no matching overloaded function found", call->getName().c_str(), ""); error(line, "no matching overloaded function found", call->getName().c_str());
return 0; return 0;
} }
if (!symbol->isFunction()) { if (!symbol->isFunction()) {
error(line, "function name expected", call->getName().c_str(), ""); error(line, "function name expected", call->getName().c_str());
return 0; return 0;
} }
...@@ -1002,7 +1002,7 @@ bool TParseContext::executeInitializer(TSourceLoc line, TString& identifier, TPu ...@@ -1002,7 +1002,7 @@ bool TParseContext::executeInitializer(TSourceLoc line, TString& identifier, TPu
// //
variable = new TVariable(&identifier, type); variable = new TVariable(&identifier, type);
if (! symbolTable.insert(*variable)) { if (! symbolTable.insert(*variable)) {
error(line, "redefinition", variable->getName().c_str(), ""); error(line, "redefinition", variable->getName().c_str());
return true; return true;
// don't delete variable, it's used by error recovery, and the pool // don't delete variable, it's used by error recovery, and the pool
// pop will take care of the memory // pop will take care of the memory
...@@ -1014,7 +1014,7 @@ bool TParseContext::executeInitializer(TSourceLoc line, TString& identifier, TPu ...@@ -1014,7 +1014,7 @@ bool TParseContext::executeInitializer(TSourceLoc line, TString& identifier, TPu
// //
TQualifier qualifier = variable->getType().getQualifier(); TQualifier qualifier = variable->getType().getQualifier();
if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal) && (qualifier != EvqConst)) { if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal) && (qualifier != EvqConst)) {
error(line, " cannot initialize this type of qualifier ", variable->getType().getQualifierString(), ""); error(line, " cannot initialize this type of qualifier ", variable->getType().getQualifierString());
return true; return true;
} }
// //
...@@ -1023,13 +1023,16 @@ bool TParseContext::executeInitializer(TSourceLoc line, TString& identifier, TPu ...@@ -1023,13 +1023,16 @@ bool TParseContext::executeInitializer(TSourceLoc line, TString& identifier, TPu
if (qualifier == EvqConst) { if (qualifier == EvqConst) {
if (qualifier != initializer->getType().getQualifier()) { if (qualifier != initializer->getType().getQualifier()) {
error(line, " assigning non-constant to", "=", "'%s'", variable->getType().getCompleteString().c_str()); std::stringstream extraInfoStream;
extraInfoStream << "'" << variable->getType().getCompleteString() << "'";
std::string extraInfo = extraInfoStream.str();
error(line, " assigning non-constant to", "=", extraInfo.c_str());
variable->getType().setQualifier(EvqTemporary); variable->getType().setQualifier(EvqTemporary);
return true; return true;
} }
if (type != initializer->getType()) { if (type != initializer->getType()) {
error(line, " non-matching types for const initializer ", error(line, " non-matching types for const initializer ",
variable->getType().getQualifierString(), ""); variable->getType().getQualifierString());
variable->getType().setQualifier(EvqTemporary); variable->getType().setQualifier(EvqTemporary);
return true; return true;
} }
...@@ -1048,7 +1051,10 @@ bool TParseContext::executeInitializer(TSourceLoc line, TString& identifier, TPu ...@@ -1048,7 +1051,10 @@ bool TParseContext::executeInitializer(TSourceLoc line, TString& identifier, TPu
ConstantUnion* constArray = tVar->getConstPointer(); ConstantUnion* constArray = tVar->getConstPointer();
variable->shareConstPointer(constArray); variable->shareConstPointer(constArray);
} else { } else {
error(line, " cannot assign to", "=", "'%s'", variable->getType().getCompleteString().c_str()); std::stringstream extraInfoStream;
extraInfoStream << "'" << variable->getType().getCompleteString() << "'";
std::string extraInfo = extraInfoStream.str();
error(line, " cannot assign to", "=", extraInfo.c_str());
variable->getType().setQualifier(EvqTemporary); variable->getType().setQualifier(EvqTemporary);
return true; return true;
} }
...@@ -1233,14 +1239,14 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType* type, TOperator op, T ...@@ -1233,14 +1239,14 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType* type, TOperator op, T
break; break;
default: default:
error(line, "unsupported construction", "", ""); error(line, "unsupported construction", "");
recover(); recover();
return 0; return 0;
} }
newNode = intermediate.addUnaryMath(basicOp, node, node->getLine(), symbolTable); newNode = intermediate.addUnaryMath(basicOp, node, node->getLine(), symbolTable);
if (newNode == 0) { if (newNode == 0) {
error(line, "can't convert", "constructor", ""); error(line, "can't convert", "constructor");
return 0; return 0;
} }
...@@ -1269,8 +1275,12 @@ TIntermTyped* TParseContext::constructStruct(TIntermNode* node, TType* type, int ...@@ -1269,8 +1275,12 @@ TIntermTyped* TParseContext::constructStruct(TIntermNode* node, TType* type, int
else else
return intermediate.setAggregateOperator(node->getAsTyped(), EOpConstructStruct, line); return intermediate.setAggregateOperator(node->getAsTyped(), EOpConstructStruct, line);
} else { } else {
error(line, "", "constructor", "cannot convert parameter %d from '%s' to '%s'", paramCount, std::stringstream extraInfoStream;
node->getAsTyped()->getType().getBasicString(), type->getBasicString()); extraInfoStream << "cannot convert parameter " << paramCount
<< " from '" << node->getAsTyped()->getType().getBasicString()
<< "' to '" << type->getBasicString() << "'";
std::string extraInfo = extraInfoStream.str();
error(line, "", "constructor", extraInfo.c_str());
recover(); recover();
} }
...@@ -1298,7 +1308,7 @@ TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTy ...@@ -1298,7 +1308,7 @@ TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTy
return node; return node;
} }
} else { // The node has to be either a symbol node or an aggregate node or a tempConstant node, else, its an error } else { // The node has to be either a symbol node or an aggregate node or a tempConstant node, else, its an error
error(line, "Cannot offset into the vector", "Error", ""); error(line, "Cannot offset into the vector", "Error");
recover(); recover();
return 0; return 0;
...@@ -1308,7 +1318,10 @@ TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTy ...@@ -1308,7 +1318,10 @@ TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTy
for (int i = 0; i < fields.num; i++) { for (int i = 0; i < fields.num; i++) {
if (fields.offsets[i] >= node->getType().getObjectSize()) { if (fields.offsets[i] >= node->getType().getObjectSize()) {
error(line, "", "[", "vector field selection out of range '%d'", fields.offsets[i]); std::stringstream extraInfoStream;
extraInfoStream << "vector field selection out of range '" << fields.offsets[i] << "'";
std::string extraInfo = extraInfoStream.str();
error(line, "", "[", extraInfo.c_str());
recover(); recover();
fields.offsets[i] = 0; fields.offsets[i] = 0;
} }
...@@ -1332,7 +1345,10 @@ TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, T ...@@ -1332,7 +1345,10 @@ TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, T
TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion(); TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
if (index >= node->getType().getNominalSize()) { if (index >= node->getType().getNominalSize()) {
error(line, "", "[", "matrix field selection out of range '%d'", index); std::stringstream extraInfoStream;
extraInfoStream << "matrix field selection out of range '" << index << "'";
std::string extraInfo = extraInfoStream.str();
error(line, "", "[", extraInfo.c_str());
recover(); recover();
index = 0; index = 0;
} }
...@@ -1342,7 +1358,7 @@ TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, T ...@@ -1342,7 +1358,7 @@ TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, T
int size = tempConstantNode->getType().getNominalSize(); int size = tempConstantNode->getType().getNominalSize();
typedNode = intermediate.addConstantUnion(&unionArray[size*index], tempConstantNode->getType(), line); typedNode = intermediate.addConstantUnion(&unionArray[size*index], tempConstantNode->getType(), line);
} else { } else {
error(line, "Cannot offset into the matrix", "Error", ""); error(line, "Cannot offset into the matrix", "Error");
recover(); recover();
return 0; return 0;
...@@ -1366,7 +1382,10 @@ TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TS ...@@ -1366,7 +1382,10 @@ TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TS
arrayElementType.clearArrayness(); arrayElementType.clearArrayness();
if (index >= node->getType().getArraySize()) { if (index >= node->getType().getArraySize()) {
error(line, "", "[", "array field selection out of range '%d'", index); std::stringstream extraInfoStream;
extraInfoStream << "array field selection out of range '" << index << "'";
std::string extraInfo = extraInfoStream.str();
error(line, "", "[", extraInfo.c_str());
recover(); recover();
index = 0; index = 0;
} }
...@@ -1377,7 +1396,7 @@ TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TS ...@@ -1377,7 +1396,7 @@ TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TS
ConstantUnion* unionArray = tempConstantNode->getUnionArrayPointer(); ConstantUnion* unionArray = tempConstantNode->getUnionArrayPointer();
typedNode = intermediate.addConstantUnion(&unionArray[arrayElementSize * index], tempConstantNode->getType(), line); typedNode = intermediate.addConstantUnion(&unionArray[arrayElementSize * index], tempConstantNode->getType(), line);
} else { } else {
error(line, "Cannot offset into the array", "Error", ""); error(line, "Cannot offset into the array", "Error");
recover(); recover();
return 0; return 0;
...@@ -1413,7 +1432,7 @@ TIntermTyped* TParseContext::addConstStruct(TString& identifier, TIntermTyped* n ...@@ -1413,7 +1432,7 @@ TIntermTyped* TParseContext::addConstStruct(TString& identifier, TIntermTyped* n
typedNode = intermediate.addConstantUnion(constArray+instanceSize, tempConstantNode->getType(), line); // type will be changed in the calling function typedNode = intermediate.addConstantUnion(constArray+instanceSize, tempConstantNode->getType(), line); // type will be changed in the calling function
} else { } else {
error(line, "Cannot offset into the structure", "Error", ""); error(line, "Cannot offset into the structure", "Error");
recover(); recover();
return 0; return 0;
...@@ -1430,7 +1449,7 @@ bool TParseContext::enterStructDeclaration(int line, const TString& identifier) ...@@ -1430,7 +1449,7 @@ bool TParseContext::enterStructDeclaration(int line, const TString& identifier)
// They aren't allowed in GLSL either, but we need to detect this here // They aren't allowed in GLSL either, but we need to detect this here
// so we don't rely on the GLSL compiler to catch it. // so we don't rely on the GLSL compiler to catch it.
if (structNestingLevel > 1) { if (structNestingLevel > 1) {
error(line, "", "Embedded struct definitions are not allowed", ""); error(line, "", "Embedded struct definitions are not allowed");
return true; return true;
} }
...@@ -1461,8 +1480,11 @@ bool TParseContext::structNestingErrorCheck(TSourceLoc line, const TType& fieldT ...@@ -1461,8 +1480,11 @@ bool TParseContext::structNestingErrorCheck(TSourceLoc line, const TType& fieldT
// We're already inside a structure definition at this point, so add // We're already inside a structure definition at this point, so add
// one to the field's struct nesting. // one to the field's struct nesting.
if (1 + fieldType.getDeepestStructNesting() > kWebGLMaxStructNesting) { if (1 + fieldType.getDeepestStructNesting() > kWebGLMaxStructNesting) {
error(line, "", "", "Reference of struct type %s exceeds maximum struct nesting of %d", std::stringstream extraInfoStream;
fieldType.getTypeName().c_str(), kWebGLMaxStructNesting); extraInfoStream << "Reference of struct type " << fieldType.getTypeName()
<< " exceeds maximum struct nesting of " << kWebGLMaxStructNesting;
std::string extraInfo = extraInfoStream.str();
error(line, "", "", extraInfo.c_str());
return true; return true;
} }
......
...@@ -69,9 +69,9 @@ struct TParseContext { ...@@ -69,9 +69,9 @@ struct TParseContext {
TInfoSink& infoSink() { return diagnostics.infoSink(); } TInfoSink& infoSink() { return diagnostics.infoSink(); }
void error(TSourceLoc loc, const char *reason, const char* token, void error(TSourceLoc loc, const char *reason, const char* token,
const char* extraInfoFormat, ...); const char* extraInfo="");
void warning(TSourceLoc loc, const char* reason, const char* token, void warning(TSourceLoc loc, const char* reason, const char* token,
const char* extraInfoFormat, ...); const char* extraInfo="");
void trace(const char* str); void trace(const char* str);
void recover(); void recover();
......
...@@ -205,7 +205,7 @@ O [0-7] ...@@ -205,7 +205,7 @@ O [0-7]
0[xX]{H}+ { yylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); } 0[xX]{H}+ { yylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
0{O}+ { yylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); } 0{O}+ { yylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
0{D}+ { context->error(yylineno, "Invalid Octal number.", yytext, "", ""); context->recover(); return 0;} 0{D}+ { context->error(yylineno, "Invalid Octal number.", yytext); context->recover(); return 0;}
{D}+ { yylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); } {D}+ { yylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
{D}+{E} { yylval->lex.f = static_cast<float>(atof_dot(yytext)); return(FLOATCONSTANT); } {D}+{E} { yylval->lex.f = static_cast<float>(atof_dot(yytext)); return(FLOATCONSTANT); }
...@@ -295,20 +295,20 @@ void CPPDebugLogMsg(const char *msg) ...@@ -295,20 +295,20 @@ void CPPDebugLogMsg(const char *msg)
void CPPWarningToInfoLog(const char *msg) void CPPWarningToInfoLog(const char *msg)
{ {
SETUP_CONTEXT(cpp); SETUP_CONTEXT(cpp);
context->warning(yylineno, msg, "", ""); context->warning(yylineno, msg, "");
} }
void CPPShInfoLogMsg(const char *msg) void CPPShInfoLogMsg(const char *msg)
{ {
SETUP_CONTEXT(cpp); SETUP_CONTEXT(cpp);
context->error(yylineno, msg, "", ""); context->error(yylineno, msg, "");
context->recover(); context->recover();
} }
void CPPErrorToInfoLog(const char *msg) void CPPErrorToInfoLog(const char *msg)
{ {
SETUP_CONTEXT(cpp); SETUP_CONTEXT(cpp);
context->error(yylineno, msg, "", ""); context->error(yylineno, msg, "");
context->recover(); context->recover();
} }
...@@ -371,7 +371,7 @@ void HandlePragma(const char **tokens, int numTokens) ...@@ -371,7 +371,7 @@ void HandlePragma(const char **tokens, int numTokens)
context->handlePragmaDirective(yylineno, tokens[0], tokens[2]); context->handlePragmaDirective(yylineno, tokens[0], tokens[2]);
} }
void StoreStr(char *string) void StoreStr(const char *string)
{ {
SETUP_CONTEXT(cpp); SETUP_CONTEXT(cpp);
TString strSrc; TString strSrc;
...@@ -450,9 +450,9 @@ void yyerror(TParseContext* context, const char* reason) { ...@@ -450,9 +450,9 @@ void yyerror(TParseContext* context, const char* reason) {
struct yyguts_t* yyg = (struct yyguts_t*) context->scanner; struct yyguts_t* yyg = (struct yyguts_t*) context->scanner;
if (context->AfterEOF) { if (context->AfterEOF) {
context->error(yylineno, reason, "unexpected EOF", ""); context->error(yylineno, reason, "unexpected EOF");
} else { } else {
context->error(yylineno, reason, yytext, ""); context->error(yylineno, reason, yytext);
} }
context->recover(); context->recover();
} }
......
...@@ -84,21 +84,21 @@ extern void yyerror(TParseContext* context, const char* reason); ...@@ -84,21 +84,21 @@ extern void yyerror(TParseContext* context, const char* reason);
#define FRAG_VERT_ONLY(S, L) { \ #define FRAG_VERT_ONLY(S, L) { \
if (context->shaderType != SH_FRAGMENT_SHADER && \ if (context->shaderType != SH_FRAGMENT_SHADER && \
context->shaderType != SH_VERTEX_SHADER) { \ context->shaderType != SH_VERTEX_SHADER) { \
context->error(L, " supported in vertex/fragment shaders only ", S, "", ""); \ context->error(L, " supported in vertex/fragment shaders only ", S); \
context->recover(); \ context->recover(); \
} \ } \
} }
#define VERTEX_ONLY(S, L) { \ #define VERTEX_ONLY(S, L) { \
if (context->shaderType != SH_VERTEX_SHADER) { \ if (context->shaderType != SH_VERTEX_SHADER) { \
context->error(L, " supported in vertex shaders only ", S, "", ""); \ context->error(L, " supported in vertex shaders only ", S); \
context->recover(); \ context->recover(); \
} \ } \
} }
#define FRAG_ONLY(S, L) { \ #define FRAG_ONLY(S, L) { \
if (context->shaderType != SH_FRAGMENT_SHADER) { \ if (context->shaderType != SH_FRAGMENT_SHADER) { \
context->error(L, " supported in fragment shaders only ", S, "", ""); \ context->error(L, " supported in fragment shaders only ", S); \
context->recover(); \ context->recover(); \
} \ } \
} }
...@@ -167,7 +167,7 @@ variable_identifier ...@@ -167,7 +167,7 @@ variable_identifier
const TSymbol* symbol = $1.symbol; const TSymbol* symbol = $1.symbol;
const TVariable* variable; const TVariable* variable;
if (symbol == 0) { if (symbol == 0) {
context->error($1.line, "undeclared identifier", $1.string->c_str(), ""); context->error($1.line, "undeclared identifier", $1.string->c_str());
context->recover(); context->recover();
TType type(EbtFloat, EbpUndefined); TType type(EbtFloat, EbpUndefined);
TVariable* fakeVariable = new TVariable($1.string, type); TVariable* fakeVariable = new TVariable($1.string, type);
...@@ -176,7 +176,7 @@ variable_identifier ...@@ -176,7 +176,7 @@ variable_identifier
} else { } else {
// This identifier can only be a variable type symbol // This identifier can only be a variable type symbol
if (! symbol->isVariable()) { if (! symbol->isVariable()) {
context->error($1.line, "variable expected", $1.string->c_str(), ""); context->error($1.line, "variable expected", $1.string->c_str());
context->recover(); context->recover();
} }
variable = static_cast<const TVariable*>(symbol); variable = static_cast<const TVariable*>(symbol);
...@@ -206,7 +206,7 @@ primary_expression ...@@ -206,7 +206,7 @@ primary_expression
// check for overflow for constants // check for overflow for constants
// //
if (abs($1.i) >= (1 << 16)) { if (abs($1.i) >= (1 << 16)) {
context->error($1.line, " integer constant overflow", "", ""); context->error($1.line, " integer constant overflow", "");
context->recover(); context->recover();
} }
ConstantUnion *unionArray = new ConstantUnion[1]; ConstantUnion *unionArray = new ConstantUnion[1];
...@@ -235,9 +235,9 @@ postfix_expression ...@@ -235,9 +235,9 @@ postfix_expression
| postfix_expression LEFT_BRACKET integer_expression RIGHT_BRACKET { | postfix_expression LEFT_BRACKET integer_expression RIGHT_BRACKET {
if (!$1->isArray() && !$1->isMatrix() && !$1->isVector()) { if (!$1->isArray() && !$1->isMatrix() && !$1->isVector()) {
if ($1->getAsSymbolNode()) if ($1->getAsSymbolNode())
context->error($2.line, " left of '[' is not of type array, matrix, or vector ", $1->getAsSymbolNode()->getSymbol().c_str(), ""); context->error($2.line, " left of '[' is not of type array, matrix, or vector ", $1->getAsSymbolNode()->getSymbol().c_str());
else else
context->error($2.line, " left of '[' is not of type array, matrix, or vector ", "expression", ""); context->error($2.line, " left of '[' is not of type array, matrix, or vector ", "expression");
context->recover(); context->recover();
} }
if ($1->getType().getQualifier() == EvqConst && $3->getQualifier() == EvqConst) { if ($1->getType().getQualifier() == EvqConst && $3->getQualifier() == EvqConst) {
...@@ -254,7 +254,10 @@ postfix_expression ...@@ -254,7 +254,10 @@ postfix_expression
} else { } else {
if ($3->getQualifier() == EvqConst) { if ($3->getQualifier() == EvqConst) {
if (($1->isVector() || $1->isMatrix()) && $1->getType().getNominalSize() <= $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst() && !$1->isArray() ) { if (($1->isVector() || $1->isMatrix()) && $1->getType().getNominalSize() <= $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst() && !$1->isArray() ) {
context->error($2.line, "", "[", "field selection out of range '%d'", $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst()); std::stringstream extraInfoStream;
extraInfoStream << "field selection out of range '" << $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst() << "'";
std::string extraInfo = extraInfoStream.str();
context->error($2.line, "", "[", extraInfo.c_str());
context->recover(); context->recover();
} else { } else {
if ($1->isArray()) { if ($1->isArray()) {
...@@ -267,7 +270,10 @@ postfix_expression ...@@ -267,7 +270,10 @@ postfix_expression
context->recover(); context->recover();
} }
} else if ( $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst() >= $1->getType().getArraySize()) { } else if ( $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst() >= $1->getType().getArraySize()) {
context->error($2.line, "", "[", "array index out of range '%d'", $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst()); std::stringstream extraInfoStream;
extraInfoStream << "array index out of range '" << $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst() << "'";
std::string extraInfo = extraInfoStream.str();
context->error($2.line, "", "[", extraInfo.c_str());
context->recover(); context->recover();
} }
} }
...@@ -310,7 +316,7 @@ postfix_expression ...@@ -310,7 +316,7 @@ postfix_expression
} }
| postfix_expression DOT FIELD_SELECTION { | postfix_expression DOT FIELD_SELECTION {
if ($1->isArray()) { if ($1->isArray()) {
context->error($3.line, "cannot apply dot operator to an array", ".", ""); context->error($3.line, "cannot apply dot operator to an array", ".");
context->recover(); context->recover();
} }
...@@ -355,7 +361,7 @@ postfix_expression ...@@ -355,7 +361,7 @@ postfix_expression
} }
if (fields.wholeRow || fields.wholeCol) { if (fields.wholeRow || fields.wholeCol) {
context->error($2.line, " non-scalar fields not implemented yet", ".", ""); context->error($2.line, " non-scalar fields not implemented yet", ".");
context->recover(); context->recover();
ConstantUnion *unionArray = new ConstantUnion[1]; ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setIConst(0); unionArray->setIConst(0);
...@@ -373,7 +379,7 @@ postfix_expression ...@@ -373,7 +379,7 @@ postfix_expression
bool fieldFound = false; bool fieldFound = false;
const TTypeList* fields = $1->getType().getStruct(); const TTypeList* fields = $1->getType().getStruct();
if (fields == 0) { if (fields == 0) {
context->error($2.line, "structure has no fields", "Internal Error", ""); context->error($2.line, "structure has no fields", "Internal Error");
context->recover(); context->recover();
$$ = $1; $$ = $1;
} else { } else {
...@@ -405,13 +411,13 @@ postfix_expression ...@@ -405,13 +411,13 @@ postfix_expression
$$->setType(*(*fields)[i].type); $$->setType(*(*fields)[i].type);
} }
} else { } else {
context->error($2.line, " no such field in structure", $3.string->c_str(), ""); context->error($2.line, " no such field in structure", $3.string->c_str());
context->recover(); context->recover();
$$ = $1; $$ = $1;
} }
} }
} else { } else {
context->error($2.line, " field selection requires structure, vector, or matrix on left hand side", $3.string->c_str(), ""); context->error($2.line, " field selection requires structure, vector, or matrix on left hand side", $3.string->c_str());
context->recover(); context->recover();
$$ = $1; $$ = $1;
} }
...@@ -500,9 +506,10 @@ function_call ...@@ -500,9 +506,10 @@ function_call
// //
$$ = context->intermediate.addUnaryMath(op, $1.intermNode, 0, context->symbolTable); $$ = context->intermediate.addUnaryMath(op, $1.intermNode, 0, context->symbolTable);
if ($$ == 0) { if ($$ == 0) {
context->error($1.intermNode->getLine(), " wrong operand type", "Internal Error", std::stringstream extraInfoStream;
"built in unary operator function. Type: %s", extraInfoStream << "built in unary operator function. Type: " << static_cast<TIntermTyped*>($1.intermNode)->getCompleteString();
static_cast<TIntermTyped*>($1.intermNode)->getCompleteString().c_str()); std::string extraInfo = extraInfoStream.str();
context->error($1.intermNode->getLine(), " wrong operand type", "Internal Error", extraInfo.c_str());
YYERROR; YYERROR;
} }
} else { } else {
...@@ -526,7 +533,7 @@ function_call ...@@ -526,7 +533,7 @@ function_call
qual = fnCandidate->getParam(i).type->getQualifier(); qual = fnCandidate->getParam(i).type->getQualifier();
if (qual == EvqOut || qual == EvqInOut) { if (qual == EvqOut || qual == EvqInOut) {
if (context->lValueErrorCheck($$->getLine(), "assign", $$->getAsAggregate()->getSequence()[i]->getAsTyped())) { if (context->lValueErrorCheck($$->getLine(), "assign", $$->getAsAggregate()->getSequence()[i]->getAsTyped())) {
context->error($1.intermNode->getLine(), "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error", ""); context->error($1.intermNode->getLine(), "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error");
context->recover(); context->recover();
} }
} }
...@@ -551,7 +558,7 @@ function_call_or_method ...@@ -551,7 +558,7 @@ function_call_or_method
$$ = $1; $$ = $1;
} }
| postfix_expression DOT function_call_generic { | postfix_expression DOT function_call_generic {
context->error($3.line, "methods are not supported", "", ""); context->error($3.line, "methods are not supported", "");
context->recover(); context->recover();
$$ = $3; $$ = $3;
} }
...@@ -647,7 +654,7 @@ function_identifier ...@@ -647,7 +654,7 @@ function_identifier
default: break; default: break;
} }
if (op == EOpNull) { if (op == EOpNull) {
context->error($1.line, "cannot construct this type", getBasicString($1.type), ""); context->error($1.line, "cannot construct this type", getBasicString($1.type));
context->recover(); context->recover();
$1.type = EbtFloat; $1.type = EbtFloat;
op = EOpConstructFloat; op = EOpConstructFloat;
...@@ -1007,12 +1014,12 @@ function_prototype ...@@ -1007,12 +1014,12 @@ function_prototype
TFunction* prevDec = static_cast<TFunction*>(context->symbolTable.find($1->getMangledName())); TFunction* prevDec = static_cast<TFunction*>(context->symbolTable.find($1->getMangledName()));
if (prevDec) { if (prevDec) {
if (prevDec->getReturnType() != $1->getReturnType()) { if (prevDec->getReturnType() != $1->getReturnType()) {
context->error($2.line, "overloaded functions must have the same return type", $1->getReturnType().getBasicString(), ""); context->error($2.line, "overloaded functions must have the same return type", $1->getReturnType().getBasicString());
context->recover(); context->recover();
} }
for (int i = 0; i < prevDec->getParamCount(); ++i) { for (int i = 0; i < prevDec->getParamCount(); ++i) {
if (prevDec->getParam(i).type->getQualifier() != $1->getParam(i).type->getQualifier()) { if (prevDec->getParam(i).type->getQualifier() != $1->getParam(i).type->getQualifier()) {
context->error($2.line, "overloaded functions must have the same parameter qualifiers", $1->getParam(i).type->getQualifierString(), ""); context->error($2.line, "overloaded functions must have the same parameter qualifiers", $1->getParam(i).type->getQualifierString());
context->recover(); context->recover();
} }
} }
...@@ -1060,7 +1067,7 @@ function_header_with_parameters ...@@ -1060,7 +1067,7 @@ function_header_with_parameters
// //
// This parameter > first is void // This parameter > first is void
// //
context->error($2.line, "cannot be an argument type except for '(void)'", "void", ""); context->error($2.line, "cannot be an argument type except for '(void)'", "void");
context->recover(); context->recover();
delete $3.param.type; delete $3.param.type;
} else { } else {
...@@ -1074,7 +1081,7 @@ function_header_with_parameters ...@@ -1074,7 +1081,7 @@ function_header_with_parameters
function_header function_header
: fully_specified_type IDENTIFIER LEFT_PAREN { : fully_specified_type IDENTIFIER LEFT_PAREN {
if ($1.qualifier != EvqGlobal && $1.qualifier != EvqTemporary) { if ($1.qualifier != EvqGlobal && $1.qualifier != EvqTemporary) {
context->error($2.line, "no qualifiers allowed for function return", getQualifierString($1.qualifier), ""); context->error($2.line, "no qualifiers allowed for function return", getQualifierString($1.qualifier));
context->recover(); context->recover();
} }
// make sure a sampler is not involved as well... // make sure a sampler is not involved as well...
...@@ -1095,7 +1102,7 @@ parameter_declarator ...@@ -1095,7 +1102,7 @@ parameter_declarator
// Type + name // Type + name
: type_specifier IDENTIFIER { : type_specifier IDENTIFIER {
if ($1.type == EbtVoid) { if ($1.type == EbtVoid) {
context->error($2.line, "illegal use of type 'void'", $2.string->c_str(), ""); context->error($2.line, "illegal use of type 'void'", $2.string->c_str());
context->recover(); context->recover();
} }
if (context->reservedErrorCheck($2.line, *$2.string)) if (context->reservedErrorCheck($2.line, *$2.string))
...@@ -1191,7 +1198,7 @@ init_declarator_list ...@@ -1191,7 +1198,7 @@ init_declarator_list
| init_declarator_list COMMA IDENTIFIER { | init_declarator_list COMMA IDENTIFIER {
if ($1.type.type == EbtInvariant && !$3.symbol) if ($1.type.type == EbtInvariant && !$3.symbol)
{ {
context->error($3.line, "undeclared identifier declared as invariant", $3.string->c_str(), ""); context->error($3.line, "undeclared identifier declared as invariant", $3.string->c_str());
context->recover(); context->recover();
} }
...@@ -1298,7 +1305,7 @@ single_declaration ...@@ -1298,7 +1305,7 @@ single_declaration
symbol->setId(variable->getUniqueId()); symbol->setId(variable->getUniqueId());
} }
| fully_specified_type IDENTIFIER LEFT_BRACKET RIGHT_BRACKET { | fully_specified_type IDENTIFIER LEFT_BRACKET RIGHT_BRACKET {
context->error($2.line, "unsized array declarations not supported", $2.string->c_str(), ""); context->error($2.line, "unsized array declarations not supported", $2.string->c_str());
context->recover(); context->recover();
TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$2.string, TType($1), $2.line); TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$2.string, TType($1), $2.line);
...@@ -1364,7 +1371,7 @@ single_declaration ...@@ -1364,7 +1371,7 @@ single_declaration
$$.type.setBasic(EbtInvariant, EvqInvariantVaryingOut, $2.line); $$.type.setBasic(EbtInvariant, EvqInvariantVaryingOut, $2.line);
if (!$2.symbol) if (!$2.symbol)
{ {
context->error($2.line, "undeclared identifier declared as invariant", $2.string->c_str(), ""); context->error($2.line, "undeclared identifier declared as invariant", $2.string->c_str());
context->recover(); context->recover();
$$.intermAggregate = 0; $$.intermAggregate = 0;
...@@ -1438,7 +1445,7 @@ single_declaration ...@@ -1438,7 +1445,7 @@ single_declaration
// context->recover(); // context->recover();
// $$.variable = new TVariable($2.string, $1); // $$.variable = new TVariable($2.string, $1);
// if (! context->symbolTable.insert(*$$.variable)) { // if (! context->symbolTable.insert(*$$.variable)) {
// context->error($2.line, "redefinition", $$.variable->getName().c_str(), ""); // context->error($2.line, "redefinition", $$.variable->getName().c_str());
// context->recover(); // context->recover();
// // don't have to delete $$.variable, the pool pop will take care of it // // don't have to delete $$.variable, the pool pop will take care of it
// } // }
...@@ -1450,26 +1457,26 @@ fully_specified_type ...@@ -1450,26 +1457,26 @@ fully_specified_type
$$ = $1; $$ = $1;
if ($1.array) { if ($1.array) {
context->error($1.line, "not supported", "first-class array", ""); context->error($1.line, "not supported", "first-class array");
context->recover(); context->recover();
$1.setArray(false); $1.setArray(false);
} }
} }
| type_qualifier type_specifier { | type_qualifier type_specifier {
if ($2.array) { if ($2.array) {
context->error($2.line, "not supported", "first-class array", ""); context->error($2.line, "not supported", "first-class array");
context->recover(); context->recover();
$2.setArray(false); $2.setArray(false);
} }
if ($1.qualifier == EvqAttribute && if ($1.qualifier == EvqAttribute &&
($2.type == EbtBool || $2.type == EbtInt)) { ($2.type == EbtBool || $2.type == EbtInt)) {
context->error($2.line, "cannot be bool or int", getQualifierString($1.qualifier), ""); context->error($2.line, "cannot be bool or int", getQualifierString($1.qualifier));
context->recover(); context->recover();
} }
if (($1.qualifier == EvqVaryingIn || $1.qualifier == EvqVaryingOut) && if (($1.qualifier == EvqVaryingIn || $1.qualifier == EvqVaryingOut) &&
($2.type == EbtBool || $2.type == EbtInt)) { ($2.type == EbtBool || $2.type == EbtInt)) {
context->error($2.line, "cannot be bool or int", getQualifierString($1.qualifier), ""); context->error($2.line, "cannot be bool or int", getQualifierString($1.qualifier));
context->recover(); context->recover();
} }
$$ = $2; $$ = $2;
...@@ -1654,7 +1661,7 @@ type_specifier_nonarray ...@@ -1654,7 +1661,7 @@ type_specifier_nonarray
} }
| SAMPLER_EXTERNAL_OES { | SAMPLER_EXTERNAL_OES {
if (!context->supportsExtension("GL_OES_EGL_image_external")) { if (!context->supportsExtension("GL_OES_EGL_image_external")) {
context->error($1.line, "unsupported type", "samplerExternalOES", ""); context->error($1.line, "unsupported type", "samplerExternalOES");
context->recover(); context->recover();
} }
FRAG_VERT_ONLY("samplerExternalOES", $1.line); FRAG_VERT_ONLY("samplerExternalOES", $1.line);
...@@ -1663,7 +1670,7 @@ type_specifier_nonarray ...@@ -1663,7 +1670,7 @@ type_specifier_nonarray
} }
| SAMPLER2DRECT { | SAMPLER2DRECT {
if (!context->supportsExtension("GL_ARB_texture_rectangle")) { if (!context->supportsExtension("GL_ARB_texture_rectangle")) {
context->error($1.line, "unsupported type", "sampler2DRect", ""); context->error($1.line, "unsupported type", "sampler2DRect");
context->recover(); context->recover();
} }
FRAG_VERT_ONLY("sampler2DRect", $1.line); FRAG_VERT_ONLY("sampler2DRect", $1.line);
...@@ -1966,14 +1973,14 @@ for_rest_statement ...@@ -1966,14 +1973,14 @@ for_rest_statement
jump_statement jump_statement
: CONTINUE SEMICOLON { : CONTINUE SEMICOLON {
if (context->loopNestingLevel <= 0) { if (context->loopNestingLevel <= 0) {
context->error($1.line, "continue statement only allowed in loops", "", ""); context->error($1.line, "continue statement only allowed in loops", "");
context->recover(); context->recover();
} }
$$ = context->intermediate.addBranch(EOpContinue, $1.line); $$ = context->intermediate.addBranch(EOpContinue, $1.line);
} }
| BREAK SEMICOLON { | BREAK SEMICOLON {
if (context->loopNestingLevel <= 0) { if (context->loopNestingLevel <= 0) {
context->error($1.line, "break statement only allowed in loops", "", ""); context->error($1.line, "break statement only allowed in loops", "");
context->recover(); context->recover();
} }
$$ = context->intermediate.addBranch(EOpBreak, $1.line); $$ = context->intermediate.addBranch(EOpBreak, $1.line);
...@@ -1981,7 +1988,7 @@ jump_statement ...@@ -1981,7 +1988,7 @@ jump_statement
| RETURN SEMICOLON { | RETURN SEMICOLON {
$$ = context->intermediate.addBranch(EOpReturn, $1.line); $$ = context->intermediate.addBranch(EOpReturn, $1.line);
if (context->currentFunctionType->getBasicType() != EbtVoid) { if (context->currentFunctionType->getBasicType() != EbtVoid) {
context->error($1.line, "non-void function must return a value", "return", ""); context->error($1.line, "non-void function must return a value", "return");
context->recover(); context->recover();
} }
} }
...@@ -1989,10 +1996,10 @@ jump_statement ...@@ -1989,10 +1996,10 @@ jump_statement
$$ = context->intermediate.addBranch(EOpReturn, $2, $1.line); $$ = context->intermediate.addBranch(EOpReturn, $2, $1.line);
context->functionReturnsValue = true; context->functionReturnsValue = true;
if (context->currentFunctionType->getBasicType() == EbtVoid) { if (context->currentFunctionType->getBasicType() == EbtVoid) {
context->error($1.line, "void function cannot return a value", "return", ""); context->error($1.line, "void function cannot return a value", "return");
context->recover(); context->recover();
} else if (*(context->currentFunctionType) != $2->getType()) { } else if (*(context->currentFunctionType) != $2->getType()) {
context->error($1.line, "function return is not matching type:", "return", ""); context->error($1.line, "function return is not matching type:", "return");
context->recover(); context->recover();
} }
} }
...@@ -2037,7 +2044,7 @@ function_definition ...@@ -2037,7 +2044,7 @@ function_definition
// //
// Then this function already has a body. // Then this function already has a body.
// //
context->error($1.line, "function already has a body", function->getName().c_str(), ""); context->error($1.line, "function already has a body", function->getName().c_str());
context->recover(); context->recover();
} }
prevDec->setDefined(); prevDec->setDefined();
...@@ -2047,7 +2054,7 @@ function_definition ...@@ -2047,7 +2054,7 @@ function_definition
// //
if (function->getName() == "main") { if (function->getName() == "main") {
if (function->getParamCount() > 0) { if (function->getParamCount() > 0) {
context->error($1.line, "function cannot take any parameter(s)", function->getName().c_str(), ""); context->error($1.line, "function cannot take any parameter(s)", function->getName().c_str());
context->recover(); context->recover();
} }
if (function->getReturnType().getBasicType() != EbtVoid) { if (function->getReturnType().getBasicType() != EbtVoid) {
...@@ -2079,7 +2086,7 @@ function_definition ...@@ -2079,7 +2086,7 @@ function_definition
// Insert the parameters with name in the symbol table. // Insert the parameters with name in the symbol table.
// //
if (! context->symbolTable.insert(*variable)) { if (! context->symbolTable.insert(*variable)) {
context->error($1.line, "redefinition", variable->getName().c_str(), ""); context->error($1.line, "redefinition", variable->getName().c_str());
context->recover(); context->recover();
delete variable; delete variable;
} }
......
...@@ -1550,7 +1550,7 @@ YY_RULE_SETUP ...@@ -1550,7 +1550,7 @@ YY_RULE_SETUP
YY_BREAK YY_BREAK
case 101: case 101:
YY_RULE_SETUP YY_RULE_SETUP
{ context->error(yylineno, "Invalid Octal number.", yytext, "", ""); context->recover(); return 0;} { context->error(yylineno, "Invalid Octal number.", yytext); context->recover(); return 0;}
YY_BREAK YY_BREAK
case 102: case 102:
YY_RULE_SETUP YY_RULE_SETUP
...@@ -2971,20 +2971,20 @@ void CPPDebugLogMsg(const char *msg) ...@@ -2971,20 +2971,20 @@ void CPPDebugLogMsg(const char *msg)
void CPPWarningToInfoLog(const char *msg) void CPPWarningToInfoLog(const char *msg)
{ {
SETUP_CONTEXT(cpp); SETUP_CONTEXT(cpp);
context->warning(yylineno, msg, "", ""); context->warning(yylineno, msg, "");
} }
void CPPShInfoLogMsg(const char *msg) void CPPShInfoLogMsg(const char *msg)
{ {
SETUP_CONTEXT(cpp); SETUP_CONTEXT(cpp);
context->error(yylineno, msg, "", ""); context->error(yylineno, msg, "");
context->recover(); context->recover();
} }
void CPPErrorToInfoLog(const char *msg) void CPPErrorToInfoLog(const char *msg)
{ {
SETUP_CONTEXT(cpp); SETUP_CONTEXT(cpp);
context->error(yylineno, msg, "", ""); context->error(yylineno, msg, "");
context->recover(); context->recover();
} }
...@@ -3047,7 +3047,7 @@ void HandlePragma(const char **tokens, int numTokens) ...@@ -3047,7 +3047,7 @@ void HandlePragma(const char **tokens, int numTokens)
context->handlePragmaDirective(yylineno, tokens[0], tokens[2]); context->handlePragmaDirective(yylineno, tokens[0], tokens[2]);
} }
void StoreStr(char *string) void StoreStr(const char *string)
{ {
SETUP_CONTEXT(cpp); SETUP_CONTEXT(cpp);
TString strSrc; TString strSrc;
...@@ -3126,9 +3126,9 @@ void yyerror(TParseContext* context, const char* reason) { ...@@ -3126,9 +3126,9 @@ void yyerror(TParseContext* context, const char* reason) {
struct yyguts_t* yyg = (struct yyguts_t*) context->scanner; struct yyguts_t* yyg = (struct yyguts_t*) context->scanner;
if (context->AfterEOF) { if (context->AfterEOF) {
context->error(yylineno, reason, "unexpected EOF", ""); context->error(yylineno, reason, "unexpected EOF");
} else { } else {
context->error(yylineno, reason, yytext, ""); context->error(yylineno, reason, yytext);
} }
context->recover(); context->recover();
} }
......
...@@ -271,21 +271,21 @@ extern void yyerror(TParseContext* context, const char* reason); ...@@ -271,21 +271,21 @@ extern void yyerror(TParseContext* context, const char* reason);
#define FRAG_VERT_ONLY(S, L) { \ #define FRAG_VERT_ONLY(S, L) { \
if (context->shaderType != SH_FRAGMENT_SHADER && \ if (context->shaderType != SH_FRAGMENT_SHADER && \
context->shaderType != SH_VERTEX_SHADER) { \ context->shaderType != SH_VERTEX_SHADER) { \
context->error(L, " supported in vertex/fragment shaders only ", S, "", ""); \ context->error(L, " supported in vertex/fragment shaders only ", S); \
context->recover(); \ context->recover(); \
} \ } \
} }
#define VERTEX_ONLY(S, L) { \ #define VERTEX_ONLY(S, L) { \
if (context->shaderType != SH_VERTEX_SHADER) { \ if (context->shaderType != SH_VERTEX_SHADER) { \
context->error(L, " supported in vertex shaders only ", S, "", ""); \ context->error(L, " supported in vertex shaders only ", S); \
context->recover(); \ context->recover(); \
} \ } \
} }
#define FRAG_ONLY(S, L) { \ #define FRAG_ONLY(S, L) { \
if (context->shaderType != SH_FRAGMENT_SHADER) { \ if (context->shaderType != SH_FRAGMENT_SHADER) { \
context->error(L, " supported in fragment shaders only ", S, "", ""); \ context->error(L, " supported in fragment shaders only ", S); \
context->recover(); \ context->recover(); \
} \ } \
} }
...@@ -658,26 +658,26 @@ static const yytype_int16 yyrhs[] = ...@@ -658,26 +658,26 @@ static const yytype_int16 yyrhs[] =
static const yytype_uint16 yyrline[] = static const yytype_uint16 yyrline[] =
{ {
0, 165, 165, 200, 203, 216, 221, 226, 232, 235, 0, 165, 165, 200, 203, 216, 221, 226, 232, 235,
308, 311, 420, 430, 443, 451, 550, 553, 561, 565, 314, 317, 426, 436, 449, 457, 557, 560, 568, 572,
572, 576, 583, 589, 598, 606, 661, 668, 678, 681, 579, 583, 590, 596, 605, 613, 668, 675, 685, 688,
691, 701, 722, 723, 724, 729, 730, 739, 751, 752, 698, 708, 729, 730, 731, 736, 737, 746, 758, 759,
760, 771, 775, 776, 786, 796, 806, 819, 820, 830, 767, 778, 782, 783, 793, 803, 813, 826, 827, 837,
843, 847, 851, 855, 856, 869, 870, 883, 884, 897, 850, 854, 858, 862, 863, 876, 877, 890, 891, 904,
898, 915, 916, 929, 930, 931, 932, 933, 937, 940, 905, 922, 923, 936, 937, 938, 939, 940, 944, 947,
951, 959, 986, 991, 998, 1036, 1039, 1046, 1054, 1075, 958, 966, 993, 998, 1005, 1043, 1046, 1053, 1061, 1082,
1096, 1107, 1136, 1141, 1151, 1156, 1166, 1169, 1172, 1175, 1103, 1114, 1143, 1148, 1158, 1163, 1173, 1176, 1179, 1182,
1181, 1188, 1191, 1213, 1231, 1255, 1278, 1282, 1300, 1308, 1188, 1195, 1198, 1220, 1238, 1262, 1285, 1289, 1307, 1315,
1340, 1360, 1449, 1458, 1481, 1484, 1490, 1498, 1506, 1514, 1347, 1367, 1456, 1465, 1488, 1491, 1497, 1505, 1513, 1521,
1524, 1531, 1534, 1537, 1543, 1546, 1561, 1565, 1569, 1573, 1531, 1538, 1541, 1544, 1550, 1553, 1568, 1572, 1576, 1580,
1582, 1587, 1592, 1597, 1602, 1607, 1612, 1617, 1622, 1627, 1589, 1594, 1599, 1604, 1609, 1614, 1619, 1624, 1629, 1634,
1633, 1639, 1645, 1650, 1655, 1664, 1673, 1678, 1691, 1691, 1640, 1646, 1652, 1657, 1662, 1671, 1680, 1685, 1698, 1698,
1705, 1705, 1714, 1717, 1732, 1768, 1772, 1778, 1786, 1802, 1712, 1712, 1721, 1724, 1739, 1775, 1779, 1785, 1793, 1809,
1806, 1810, 1811, 1817, 1818, 1819, 1820, 1821, 1825, 1826, 1813, 1817, 1818, 1824, 1825, 1826, 1827, 1828, 1832, 1833,
1826, 1826, 1836, 1837, 1841, 1841, 1842, 1842, 1847, 1850, 1833, 1833, 1843, 1844, 1848, 1848, 1849, 1849, 1854, 1857,
1860, 1863, 1869, 1870, 1874, 1882, 1886, 1896, 1901, 1918, 1867, 1870, 1876, 1877, 1881, 1889, 1893, 1903, 1908, 1925,
1918, 1923, 1923, 1930, 1930, 1938, 1941, 1947, 1950, 1956, 1925, 1930, 1930, 1937, 1937, 1945, 1948, 1954, 1957, 1963,
1960, 1967, 1974, 1981, 1988, 1999, 2008, 2012, 2019, 2022, 1967, 1974, 1981, 1988, 1995, 2006, 2015, 2019, 2026, 2029,
2028, 2028 2035, 2035
}; };
#endif #endif
...@@ -2071,7 +2071,7 @@ yyreduce: ...@@ -2071,7 +2071,7 @@ yyreduce:
const TSymbol* symbol = (yyvsp[(1) - (1)].lex).symbol; const TSymbol* symbol = (yyvsp[(1) - (1)].lex).symbol;
const TVariable* variable; const TVariable* variable;
if (symbol == 0) { if (symbol == 0) {
context->error((yyvsp[(1) - (1)].lex).line, "undeclared identifier", (yyvsp[(1) - (1)].lex).string->c_str(), ""); context->error((yyvsp[(1) - (1)].lex).line, "undeclared identifier", (yyvsp[(1) - (1)].lex).string->c_str());
context->recover(); context->recover();
TType type(EbtFloat, EbpUndefined); TType type(EbtFloat, EbpUndefined);
TVariable* fakeVariable = new TVariable((yyvsp[(1) - (1)].lex).string, type); TVariable* fakeVariable = new TVariable((yyvsp[(1) - (1)].lex).string, type);
...@@ -2080,7 +2080,7 @@ yyreduce: ...@@ -2080,7 +2080,7 @@ yyreduce:
} else { } else {
// This identifier can only be a variable type symbol // This identifier can only be a variable type symbol
if (! symbol->isVariable()) { if (! symbol->isVariable()) {
context->error((yyvsp[(1) - (1)].lex).line, "variable expected", (yyvsp[(1) - (1)].lex).string->c_str(), ""); context->error((yyvsp[(1) - (1)].lex).line, "variable expected", (yyvsp[(1) - (1)].lex).string->c_str());
context->recover(); context->recover();
} }
variable = static_cast<const TVariable*>(symbol); variable = static_cast<const TVariable*>(symbol);
...@@ -2115,7 +2115,7 @@ yyreduce: ...@@ -2115,7 +2115,7 @@ yyreduce:
// check for overflow for constants // check for overflow for constants
// //
if (abs((yyvsp[(1) - (1)].lex).i) >= (1 << 16)) { if (abs((yyvsp[(1) - (1)].lex).i) >= (1 << 16)) {
context->error((yyvsp[(1) - (1)].lex).line, " integer constant overflow", "", ""); context->error((yyvsp[(1) - (1)].lex).line, " integer constant overflow", "");
context->recover(); context->recover();
} }
ConstantUnion *unionArray = new ConstantUnion[1]; ConstantUnion *unionArray = new ConstantUnion[1];
...@@ -2161,9 +2161,9 @@ yyreduce: ...@@ -2161,9 +2161,9 @@ yyreduce:
{ {
if (!(yyvsp[(1) - (4)].interm.intermTypedNode)->isArray() && !(yyvsp[(1) - (4)].interm.intermTypedNode)->isMatrix() && !(yyvsp[(1) - (4)].interm.intermTypedNode)->isVector()) { if (!(yyvsp[(1) - (4)].interm.intermTypedNode)->isArray() && !(yyvsp[(1) - (4)].interm.intermTypedNode)->isMatrix() && !(yyvsp[(1) - (4)].interm.intermTypedNode)->isVector()) {
if ((yyvsp[(1) - (4)].interm.intermTypedNode)->getAsSymbolNode()) if ((yyvsp[(1) - (4)].interm.intermTypedNode)->getAsSymbolNode())
context->error((yyvsp[(2) - (4)].lex).line, " left of '[' is not of type array, matrix, or vector ", (yyvsp[(1) - (4)].interm.intermTypedNode)->getAsSymbolNode()->getSymbol().c_str(), ""); context->error((yyvsp[(2) - (4)].lex).line, " left of '[' is not of type array, matrix, or vector ", (yyvsp[(1) - (4)].interm.intermTypedNode)->getAsSymbolNode()->getSymbol().c_str());
else else
context->error((yyvsp[(2) - (4)].lex).line, " left of '[' is not of type array, matrix, or vector ", "expression", ""); context->error((yyvsp[(2) - (4)].lex).line, " left of '[' is not of type array, matrix, or vector ", "expression");
context->recover(); context->recover();
} }
if ((yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getQualifier() == EvqConst && (yyvsp[(3) - (4)].interm.intermTypedNode)->getQualifier() == EvqConst) { if ((yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getQualifier() == EvqConst && (yyvsp[(3) - (4)].interm.intermTypedNode)->getQualifier() == EvqConst) {
...@@ -2180,7 +2180,10 @@ yyreduce: ...@@ -2180,7 +2180,10 @@ yyreduce:
} else { } else {
if ((yyvsp[(3) - (4)].interm.intermTypedNode)->getQualifier() == EvqConst) { if ((yyvsp[(3) - (4)].interm.intermTypedNode)->getQualifier() == EvqConst) {
if (((yyvsp[(1) - (4)].interm.intermTypedNode)->isVector() || (yyvsp[(1) - (4)].interm.intermTypedNode)->isMatrix()) && (yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getNominalSize() <= (yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getUnionArrayPointer()->getIConst() && !(yyvsp[(1) - (4)].interm.intermTypedNode)->isArray() ) { if (((yyvsp[(1) - (4)].interm.intermTypedNode)->isVector() || (yyvsp[(1) - (4)].interm.intermTypedNode)->isMatrix()) && (yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getNominalSize() <= (yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getUnionArrayPointer()->getIConst() && !(yyvsp[(1) - (4)].interm.intermTypedNode)->isArray() ) {
context->error((yyvsp[(2) - (4)].lex).line, "", "[", "field selection out of range '%d'", (yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getUnionArrayPointer()->getIConst()); std::stringstream extraInfoStream;
extraInfoStream << "field selection out of range '" << (yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getUnionArrayPointer()->getIConst() << "'";
std::string extraInfo = extraInfoStream.str();
context->error((yyvsp[(2) - (4)].lex).line, "", "[", extraInfo.c_str());
context->recover(); context->recover();
} else { } else {
if ((yyvsp[(1) - (4)].interm.intermTypedNode)->isArray()) { if ((yyvsp[(1) - (4)].interm.intermTypedNode)->isArray()) {
...@@ -2193,7 +2196,10 @@ yyreduce: ...@@ -2193,7 +2196,10 @@ yyreduce:
context->recover(); context->recover();
} }
} else if ( (yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getUnionArrayPointer()->getIConst() >= (yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getArraySize()) { } else if ( (yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getUnionArrayPointer()->getIConst() >= (yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getArraySize()) {
context->error((yyvsp[(2) - (4)].lex).line, "", "[", "array index out of range '%d'", (yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getUnionArrayPointer()->getIConst()); std::stringstream extraInfoStream;
extraInfoStream << "array index out of range '" << (yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getUnionArrayPointer()->getIConst() << "'";
std::string extraInfo = extraInfoStream.str();
context->error((yyvsp[(2) - (4)].lex).line, "", "[", extraInfo.c_str());
context->recover(); context->recover();
} }
} }
...@@ -2244,7 +2250,7 @@ yyreduce: ...@@ -2244,7 +2250,7 @@ yyreduce:
{ {
if ((yyvsp[(1) - (3)].interm.intermTypedNode)->isArray()) { if ((yyvsp[(1) - (3)].interm.intermTypedNode)->isArray()) {
context->error((yyvsp[(3) - (3)].lex).line, "cannot apply dot operator to an array", ".", ""); context->error((yyvsp[(3) - (3)].lex).line, "cannot apply dot operator to an array", ".");
context->recover(); context->recover();
} }
...@@ -2289,7 +2295,7 @@ yyreduce: ...@@ -2289,7 +2295,7 @@ yyreduce:
} }
if (fields.wholeRow || fields.wholeCol) { if (fields.wholeRow || fields.wholeCol) {
context->error((yyvsp[(2) - (3)].lex).line, " non-scalar fields not implemented yet", ".", ""); context->error((yyvsp[(2) - (3)].lex).line, " non-scalar fields not implemented yet", ".");
context->recover(); context->recover();
ConstantUnion *unionArray = new ConstantUnion[1]; ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setIConst(0); unionArray->setIConst(0);
...@@ -2307,7 +2313,7 @@ yyreduce: ...@@ -2307,7 +2313,7 @@ yyreduce:
bool fieldFound = false; bool fieldFound = false;
const TTypeList* fields = (yyvsp[(1) - (3)].interm.intermTypedNode)->getType().getStruct(); const TTypeList* fields = (yyvsp[(1) - (3)].interm.intermTypedNode)->getType().getStruct();
if (fields == 0) { if (fields == 0) {
context->error((yyvsp[(2) - (3)].lex).line, "structure has no fields", "Internal Error", ""); context->error((yyvsp[(2) - (3)].lex).line, "structure has no fields", "Internal Error");
context->recover(); context->recover();
(yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode); (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
} else { } else {
...@@ -2339,13 +2345,13 @@ yyreduce: ...@@ -2339,13 +2345,13 @@ yyreduce:
(yyval.interm.intermTypedNode)->setType(*(*fields)[i].type); (yyval.interm.intermTypedNode)->setType(*(*fields)[i].type);
} }
} else { } else {
context->error((yyvsp[(2) - (3)].lex).line, " no such field in structure", (yyvsp[(3) - (3)].lex).string->c_str(), ""); context->error((yyvsp[(2) - (3)].lex).line, " no such field in structure", (yyvsp[(3) - (3)].lex).string->c_str());
context->recover(); context->recover();
(yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode); (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
} }
} }
} else { } else {
context->error((yyvsp[(2) - (3)].lex).line, " field selection requires structure, vector, or matrix on left hand side", (yyvsp[(3) - (3)].lex).string->c_str(), ""); context->error((yyvsp[(2) - (3)].lex).line, " field selection requires structure, vector, or matrix on left hand side", (yyvsp[(3) - (3)].lex).string->c_str());
context->recover(); context->recover();
(yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode); (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
} }
...@@ -2444,9 +2450,10 @@ yyreduce: ...@@ -2444,9 +2450,10 @@ yyreduce:
// //
(yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath(op, (yyvsp[(1) - (1)].interm).intermNode, 0, context->symbolTable); (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath(op, (yyvsp[(1) - (1)].interm).intermNode, 0, context->symbolTable);
if ((yyval.interm.intermTypedNode) == 0) { if ((yyval.interm.intermTypedNode) == 0) {
context->error((yyvsp[(1) - (1)].interm).intermNode->getLine(), " wrong operand type", "Internal Error", std::stringstream extraInfoStream;
"built in unary operator function. Type: %s", extraInfoStream << "built in unary operator function. Type: " << static_cast<TIntermTyped*>((yyvsp[(1) - (1)].interm).intermNode)->getCompleteString();
static_cast<TIntermTyped*>((yyvsp[(1) - (1)].interm).intermNode)->getCompleteString().c_str()); std::string extraInfo = extraInfoStream.str();
context->error((yyvsp[(1) - (1)].interm).intermNode->getLine(), " wrong operand type", "Internal Error", extraInfo.c_str());
YYERROR; YYERROR;
} }
} else { } else {
...@@ -2470,7 +2477,7 @@ yyreduce: ...@@ -2470,7 +2477,7 @@ yyreduce:
qual = fnCandidate->getParam(i).type->getQualifier(); qual = fnCandidate->getParam(i).type->getQualifier();
if (qual == EvqOut || qual == EvqInOut) { if (qual == EvqOut || qual == EvqInOut) {
if (context->lValueErrorCheck((yyval.interm.intermTypedNode)->getLine(), "assign", (yyval.interm.intermTypedNode)->getAsAggregate()->getSequence()[i]->getAsTyped())) { if (context->lValueErrorCheck((yyval.interm.intermTypedNode)->getLine(), "assign", (yyval.interm.intermTypedNode)->getAsAggregate()->getSequence()[i]->getAsTyped())) {
context->error((yyvsp[(1) - (1)].interm).intermNode->getLine(), "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error", ""); context->error((yyvsp[(1) - (1)].interm).intermNode->getLine(), "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error");
context->recover(); context->recover();
} }
} }
...@@ -2500,7 +2507,7 @@ yyreduce: ...@@ -2500,7 +2507,7 @@ yyreduce:
case 17: case 17:
{ {
context->error((yyvsp[(3) - (3)].interm).line, "methods are not supported", "", ""); context->error((yyvsp[(3) - (3)].interm).line, "methods are not supported", "");
context->recover(); context->recover();
(yyval.interm) = (yyvsp[(3) - (3)].interm); (yyval.interm) = (yyvsp[(3) - (3)].interm);
} }
...@@ -2611,7 +2618,7 @@ yyreduce: ...@@ -2611,7 +2618,7 @@ yyreduce:
default: break; default: break;
} }
if (op == EOpNull) { if (op == EOpNull) {
context->error((yyvsp[(1) - (1)].interm.type).line, "cannot construct this type", getBasicString((yyvsp[(1) - (1)].interm.type).type), ""); context->error((yyvsp[(1) - (1)].interm.type).line, "cannot construct this type", getBasicString((yyvsp[(1) - (1)].interm.type).type));
context->recover(); context->recover();
(yyvsp[(1) - (1)].interm.type).type = EbtFloat; (yyvsp[(1) - (1)].interm.type).type = EbtFloat;
op = EOpConstructFloat; op = EOpConstructFloat;
...@@ -3105,12 +3112,12 @@ yyreduce: ...@@ -3105,12 +3112,12 @@ yyreduce:
TFunction* prevDec = static_cast<TFunction*>(context->symbolTable.find((yyvsp[(1) - (2)].interm.function)->getMangledName())); TFunction* prevDec = static_cast<TFunction*>(context->symbolTable.find((yyvsp[(1) - (2)].interm.function)->getMangledName()));
if (prevDec) { if (prevDec) {
if (prevDec->getReturnType() != (yyvsp[(1) - (2)].interm.function)->getReturnType()) { if (prevDec->getReturnType() != (yyvsp[(1) - (2)].interm.function)->getReturnType()) {
context->error((yyvsp[(2) - (2)].lex).line, "overloaded functions must have the same return type", (yyvsp[(1) - (2)].interm.function)->getReturnType().getBasicString(), ""); context->error((yyvsp[(2) - (2)].lex).line, "overloaded functions must have the same return type", (yyvsp[(1) - (2)].interm.function)->getReturnType().getBasicString());
context->recover(); context->recover();
} }
for (int i = 0; i < prevDec->getParamCount(); ++i) { for (int i = 0; i < prevDec->getParamCount(); ++i) {
if (prevDec->getParam(i).type->getQualifier() != (yyvsp[(1) - (2)].interm.function)->getParam(i).type->getQualifier()) { if (prevDec->getParam(i).type->getQualifier() != (yyvsp[(1) - (2)].interm.function)->getParam(i).type->getQualifier()) {
context->error((yyvsp[(2) - (2)].lex).line, "overloaded functions must have the same parameter qualifiers", (yyvsp[(1) - (2)].interm.function)->getParam(i).type->getQualifierString(), ""); context->error((yyvsp[(2) - (2)].lex).line, "overloaded functions must have the same parameter qualifiers", (yyvsp[(1) - (2)].interm.function)->getParam(i).type->getQualifierString());
context->recover(); context->recover();
} }
} }
...@@ -3167,7 +3174,7 @@ yyreduce: ...@@ -3167,7 +3174,7 @@ yyreduce:
// //
// This parameter > first is void // This parameter > first is void
// //
context->error((yyvsp[(2) - (3)].lex).line, "cannot be an argument type except for '(void)'", "void", ""); context->error((yyvsp[(2) - (3)].lex).line, "cannot be an argument type except for '(void)'", "void");
context->recover(); context->recover();
delete (yyvsp[(3) - (3)].interm).param.type; delete (yyvsp[(3) - (3)].interm).param.type;
} else { } else {
...@@ -3182,7 +3189,7 @@ yyreduce: ...@@ -3182,7 +3189,7 @@ yyreduce:
{ {
if ((yyvsp[(1) - (3)].interm.type).qualifier != EvqGlobal && (yyvsp[(1) - (3)].interm.type).qualifier != EvqTemporary) { if ((yyvsp[(1) - (3)].interm.type).qualifier != EvqGlobal && (yyvsp[(1) - (3)].interm.type).qualifier != EvqTemporary) {
context->error((yyvsp[(2) - (3)].lex).line, "no qualifiers allowed for function return", getQualifierString((yyvsp[(1) - (3)].interm.type).qualifier), ""); context->error((yyvsp[(2) - (3)].lex).line, "no qualifiers allowed for function return", getQualifierString((yyvsp[(1) - (3)].interm.type).qualifier));
context->recover(); context->recover();
} }
// make sure a sampler is not involved as well... // make sure a sampler is not involved as well...
...@@ -3203,7 +3210,7 @@ yyreduce: ...@@ -3203,7 +3210,7 @@ yyreduce:
{ {
if ((yyvsp[(1) - (2)].interm.type).type == EbtVoid) { if ((yyvsp[(1) - (2)].interm.type).type == EbtVoid) {
context->error((yyvsp[(2) - (2)].lex).line, "illegal use of type 'void'", (yyvsp[(2) - (2)].lex).string->c_str(), ""); context->error((yyvsp[(2) - (2)].lex).line, "illegal use of type 'void'", (yyvsp[(2) - (2)].lex).string->c_str());
context->recover(); context->recover();
} }
if (context->reservedErrorCheck((yyvsp[(2) - (2)].lex).line, *(yyvsp[(2) - (2)].lex).string)) if (context->reservedErrorCheck((yyvsp[(2) - (2)].lex).line, *(yyvsp[(2) - (2)].lex).string))
...@@ -3324,7 +3331,7 @@ yyreduce: ...@@ -3324,7 +3331,7 @@ yyreduce:
{ {
if ((yyvsp[(1) - (3)].interm).type.type == EbtInvariant && !(yyvsp[(3) - (3)].lex).symbol) if ((yyvsp[(1) - (3)].interm).type.type == EbtInvariant && !(yyvsp[(3) - (3)].lex).symbol)
{ {
context->error((yyvsp[(3) - (3)].lex).line, "undeclared identifier declared as invariant", (yyvsp[(3) - (3)].lex).string->c_str(), ""); context->error((yyvsp[(3) - (3)].lex).line, "undeclared identifier declared as invariant", (yyvsp[(3) - (3)].lex).string->c_str());
context->recover(); context->recover();
} }
...@@ -3452,7 +3459,7 @@ yyreduce: ...@@ -3452,7 +3459,7 @@ yyreduce:
case 98: case 98:
{ {
context->error((yyvsp[(2) - (4)].lex).line, "unsized array declarations not supported", (yyvsp[(2) - (4)].lex).string->c_str(), ""); context->error((yyvsp[(2) - (4)].lex).line, "unsized array declarations not supported", (yyvsp[(2) - (4)].lex).string->c_str());
context->recover(); context->recover();
TIntermSymbol* symbol = context->intermediate.addSymbol(0, *(yyvsp[(2) - (4)].lex).string, TType((yyvsp[(1) - (4)].interm.type)), (yyvsp[(2) - (4)].lex).line); TIntermSymbol* symbol = context->intermediate.addSymbol(0, *(yyvsp[(2) - (4)].lex).string, TType((yyvsp[(1) - (4)].interm.type)), (yyvsp[(2) - (4)].lex).line);
...@@ -3530,7 +3537,7 @@ yyreduce: ...@@ -3530,7 +3537,7 @@ yyreduce:
(yyval.interm).type.setBasic(EbtInvariant, EvqInvariantVaryingOut, (yyvsp[(2) - (2)].lex).line); (yyval.interm).type.setBasic(EbtInvariant, EvqInvariantVaryingOut, (yyvsp[(2) - (2)].lex).line);
if (!(yyvsp[(2) - (2)].lex).symbol) if (!(yyvsp[(2) - (2)].lex).symbol)
{ {
context->error((yyvsp[(2) - (2)].lex).line, "undeclared identifier declared as invariant", (yyvsp[(2) - (2)].lex).string->c_str(), ""); context->error((yyvsp[(2) - (2)].lex).line, "undeclared identifier declared as invariant", (yyvsp[(2) - (2)].lex).string->c_str());
context->recover(); context->recover();
(yyval.interm).intermAggregate = 0; (yyval.interm).intermAggregate = 0;
...@@ -3549,7 +3556,7 @@ yyreduce: ...@@ -3549,7 +3556,7 @@ yyreduce:
(yyval.interm.type) = (yyvsp[(1) - (1)].interm.type); (yyval.interm.type) = (yyvsp[(1) - (1)].interm.type);
if ((yyvsp[(1) - (1)].interm.type).array) { if ((yyvsp[(1) - (1)].interm.type).array) {
context->error((yyvsp[(1) - (1)].interm.type).line, "not supported", "first-class array", ""); context->error((yyvsp[(1) - (1)].interm.type).line, "not supported", "first-class array");
context->recover(); context->recover();
(yyvsp[(1) - (1)].interm.type).setArray(false); (yyvsp[(1) - (1)].interm.type).setArray(false);
} }
...@@ -3560,19 +3567,19 @@ yyreduce: ...@@ -3560,19 +3567,19 @@ yyreduce:
{ {
if ((yyvsp[(2) - (2)].interm.type).array) { if ((yyvsp[(2) - (2)].interm.type).array) {
context->error((yyvsp[(2) - (2)].interm.type).line, "not supported", "first-class array", ""); context->error((yyvsp[(2) - (2)].interm.type).line, "not supported", "first-class array");
context->recover(); context->recover();
(yyvsp[(2) - (2)].interm.type).setArray(false); (yyvsp[(2) - (2)].interm.type).setArray(false);
} }
if ((yyvsp[(1) - (2)].interm.type).qualifier == EvqAttribute && if ((yyvsp[(1) - (2)].interm.type).qualifier == EvqAttribute &&
((yyvsp[(2) - (2)].interm.type).type == EbtBool || (yyvsp[(2) - (2)].interm.type).type == EbtInt)) { ((yyvsp[(2) - (2)].interm.type).type == EbtBool || (yyvsp[(2) - (2)].interm.type).type == EbtInt)) {
context->error((yyvsp[(2) - (2)].interm.type).line, "cannot be bool or int", getQualifierString((yyvsp[(1) - (2)].interm.type).qualifier), ""); context->error((yyvsp[(2) - (2)].interm.type).line, "cannot be bool or int", getQualifierString((yyvsp[(1) - (2)].interm.type).qualifier));
context->recover(); context->recover();
} }
if (((yyvsp[(1) - (2)].interm.type).qualifier == EvqVaryingIn || (yyvsp[(1) - (2)].interm.type).qualifier == EvqVaryingOut) && if (((yyvsp[(1) - (2)].interm.type).qualifier == EvqVaryingIn || (yyvsp[(1) - (2)].interm.type).qualifier == EvqVaryingOut) &&
((yyvsp[(2) - (2)].interm.type).type == EbtBool || (yyvsp[(2) - (2)].interm.type).type == EbtInt)) { ((yyvsp[(2) - (2)].interm.type).type == EbtBool || (yyvsp[(2) - (2)].interm.type).type == EbtInt)) {
context->error((yyvsp[(2) - (2)].interm.type).line, "cannot be bool or int", getQualifierString((yyvsp[(1) - (2)].interm.type).qualifier), ""); context->error((yyvsp[(2) - (2)].interm.type).line, "cannot be bool or int", getQualifierString((yyvsp[(1) - (2)].interm.type).qualifier));
context->recover(); context->recover();
} }
(yyval.interm.type) = (yyvsp[(2) - (2)].interm.type); (yyval.interm.type) = (yyvsp[(2) - (2)].interm.type);
...@@ -3861,7 +3868,7 @@ yyreduce: ...@@ -3861,7 +3868,7 @@ yyreduce:
{ {
if (!context->supportsExtension("GL_OES_EGL_image_external")) { if (!context->supportsExtension("GL_OES_EGL_image_external")) {
context->error((yyvsp[(1) - (1)].lex).line, "unsupported type", "samplerExternalOES", ""); context->error((yyvsp[(1) - (1)].lex).line, "unsupported type", "samplerExternalOES");
context->recover(); context->recover();
} }
FRAG_VERT_ONLY("samplerExternalOES", (yyvsp[(1) - (1)].lex).line); FRAG_VERT_ONLY("samplerExternalOES", (yyvsp[(1) - (1)].lex).line);
...@@ -3874,7 +3881,7 @@ yyreduce: ...@@ -3874,7 +3881,7 @@ yyreduce:
{ {
if (!context->supportsExtension("GL_ARB_texture_rectangle")) { if (!context->supportsExtension("GL_ARB_texture_rectangle")) {
context->error((yyvsp[(1) - (1)].lex).line, "unsupported type", "sampler2DRect", ""); context->error((yyvsp[(1) - (1)].lex).line, "unsupported type", "sampler2DRect");
context->recover(); context->recover();
} }
FRAG_VERT_ONLY("sampler2DRect", (yyvsp[(1) - (1)].lex).line); FRAG_VERT_ONLY("sampler2DRect", (yyvsp[(1) - (1)].lex).line);
...@@ -4335,7 +4342,7 @@ yyreduce: ...@@ -4335,7 +4342,7 @@ yyreduce:
{ {
if (context->loopNestingLevel <= 0) { if (context->loopNestingLevel <= 0) {
context->error((yyvsp[(1) - (2)].lex).line, "continue statement only allowed in loops", "", ""); context->error((yyvsp[(1) - (2)].lex).line, "continue statement only allowed in loops", "");
context->recover(); context->recover();
} }
(yyval.interm.intermNode) = context->intermediate.addBranch(EOpContinue, (yyvsp[(1) - (2)].lex).line); (yyval.interm.intermNode) = context->intermediate.addBranch(EOpContinue, (yyvsp[(1) - (2)].lex).line);
...@@ -4346,7 +4353,7 @@ yyreduce: ...@@ -4346,7 +4353,7 @@ yyreduce:
{ {
if (context->loopNestingLevel <= 0) { if (context->loopNestingLevel <= 0) {
context->error((yyvsp[(1) - (2)].lex).line, "break statement only allowed in loops", "", ""); context->error((yyvsp[(1) - (2)].lex).line, "break statement only allowed in loops", "");
context->recover(); context->recover();
} }
(yyval.interm.intermNode) = context->intermediate.addBranch(EOpBreak, (yyvsp[(1) - (2)].lex).line); (yyval.interm.intermNode) = context->intermediate.addBranch(EOpBreak, (yyvsp[(1) - (2)].lex).line);
...@@ -4358,7 +4365,7 @@ yyreduce: ...@@ -4358,7 +4365,7 @@ yyreduce:
{ {
(yyval.interm.intermNode) = context->intermediate.addBranch(EOpReturn, (yyvsp[(1) - (2)].lex).line); (yyval.interm.intermNode) = context->intermediate.addBranch(EOpReturn, (yyvsp[(1) - (2)].lex).line);
if (context->currentFunctionType->getBasicType() != EbtVoid) { if (context->currentFunctionType->getBasicType() != EbtVoid) {
context->error((yyvsp[(1) - (2)].lex).line, "non-void function must return a value", "return", ""); context->error((yyvsp[(1) - (2)].lex).line, "non-void function must return a value", "return");
context->recover(); context->recover();
} }
} }
...@@ -4370,10 +4377,10 @@ yyreduce: ...@@ -4370,10 +4377,10 @@ yyreduce:
(yyval.interm.intermNode) = context->intermediate.addBranch(EOpReturn, (yyvsp[(2) - (3)].interm.intermTypedNode), (yyvsp[(1) - (3)].lex).line); (yyval.interm.intermNode) = context->intermediate.addBranch(EOpReturn, (yyvsp[(2) - (3)].interm.intermTypedNode), (yyvsp[(1) - (3)].lex).line);
context->functionReturnsValue = true; context->functionReturnsValue = true;
if (context->currentFunctionType->getBasicType() == EbtVoid) { if (context->currentFunctionType->getBasicType() == EbtVoid) {
context->error((yyvsp[(1) - (3)].lex).line, "void function cannot return a value", "return", ""); context->error((yyvsp[(1) - (3)].lex).line, "void function cannot return a value", "return");
context->recover(); context->recover();
} else if (*(context->currentFunctionType) != (yyvsp[(2) - (3)].interm.intermTypedNode)->getType()) { } else if (*(context->currentFunctionType) != (yyvsp[(2) - (3)].interm.intermTypedNode)->getType()) {
context->error((yyvsp[(1) - (3)].lex).line, "function return is not matching type:", "return", ""); context->error((yyvsp[(1) - (3)].lex).line, "function return is not matching type:", "return");
context->recover(); context->recover();
} }
} }
...@@ -4431,7 +4438,7 @@ yyreduce: ...@@ -4431,7 +4438,7 @@ yyreduce:
// //
// Then this function already has a body. // Then this function already has a body.
// //
context->error((yyvsp[(1) - (1)].interm).line, "function already has a body", function->getName().c_str(), ""); context->error((yyvsp[(1) - (1)].interm).line, "function already has a body", function->getName().c_str());
context->recover(); context->recover();
} }
prevDec->setDefined(); prevDec->setDefined();
...@@ -4441,7 +4448,7 @@ yyreduce: ...@@ -4441,7 +4448,7 @@ yyreduce:
// //
if (function->getName() == "main") { if (function->getName() == "main") {
if (function->getParamCount() > 0) { if (function->getParamCount() > 0) {
context->error((yyvsp[(1) - (1)].interm).line, "function cannot take any parameter(s)", function->getName().c_str(), ""); context->error((yyvsp[(1) - (1)].interm).line, "function cannot take any parameter(s)", function->getName().c_str());
context->recover(); context->recover();
} }
if (function->getReturnType().getBasicType() != EbtVoid) { if (function->getReturnType().getBasicType() != EbtVoid) {
...@@ -4473,7 +4480,7 @@ yyreduce: ...@@ -4473,7 +4480,7 @@ yyreduce:
// Insert the parameters with name in the symbol table. // Insert the parameters with name in the symbol table.
// //
if (! context->symbolTable.insert(*variable)) { if (! context->symbolTable.insert(*variable)) {
context->error((yyvsp[(1) - (1)].interm).line, "redefinition", variable->getName().c_str(), ""); context->error((yyvsp[(1) - (1)].interm).line, "redefinition", variable->getName().c_str());
context->recover(); context->recover();
delete variable; delete variable;
} }
......
...@@ -531,6 +531,7 @@ public: ...@@ -531,6 +531,7 @@ public:
postVisit(postVisit), postVisit(postVisit),
rightToLeft(rightToLeft), rightToLeft(rightToLeft),
depth(0) {} depth(0) {}
virtual ~TIntermTraverser() {};
virtual void visitSymbol(TIntermSymbol*) {} virtual void visitSymbol(TIntermSymbol*) {}
virtual void visitConstantUnion(TIntermConstantUnion*) {} virtual void visitConstantUnion(TIntermConstantUnion*) {}
......
...@@ -308,7 +308,7 @@ struct AtomTable_Rec { ...@@ -308,7 +308,7 @@ struct AtomTable_Rec {
int size; int size;
}; };
static AtomTable latable = { { 0 } }; static AtomTable latable = { { NULL, 0, 0 }, { NULL, 0, 0, {0} }, NULL, NULL, 0, 0 };
AtomTable *atable = &latable; AtomTable *atable = &latable;
static int AddAtomFixed(AtomTable *atable, const char *s, int atom); static int AddAtomFixed(AtomTable *atable, const char *s, int atom);
......
...@@ -884,10 +884,10 @@ void FreeMacro(MacroSymbol *s) { ...@@ -884,10 +884,10 @@ void FreeMacro(MacroSymbol *s) {
} }
void PredefineIntMacro(const char *name, int value) { void PredefineIntMacro(const char *name, int value) {
SourceLoc location = {0}; SourceLoc location = {0, 0};
Symbol *symbol = NULL; Symbol *symbol = NULL;
MacroSymbol macro = {0}; MacroSymbol macro = {0, NULL, NULL, 0, 0};
yystypepp val = {0}; yystypepp val = {0, 0.0, 0, {0}};
int atom = 0; int atom = 0;
macro.body = NewTokenStream(name, macros->pool); macro.body = NewTokenStream(name, macros->pool);
......
...@@ -73,8 +73,8 @@ void CPPShInfoLogMsg(const char*); // Store cpp Err Msg into Sh.Info.Lo ...@@ -73,8 +73,8 @@ void CPPShInfoLogMsg(const char*); // Store cpp Err Msg into Sh.Info.Lo
void CPPWarningToInfoLog(const char *msg); // Prints warning messages into info log void CPPWarningToInfoLog(const char *msg); // Prints warning messages into info log
void HandlePragma(const char**, int numTokens); // #pragma directive container. void HandlePragma(const char**, int numTokens); // #pragma directive container.
void ResetTString(void); // #error Message as TString. void ResetTString(void); // #error Message as TString.
void CPPErrorToInfoLog(const char*); // Stick all cpp errors into Sh.Info.log . void CPPErrorToInfoLog(const char*); // Stick all cpp errors into Sh.Info.log.
void StoreStr(char*); // Store the TString in Parse Context. void StoreStr(const char*); // Store the TString in Parse Context.
void SetLineNumber(int); // Set line number. void SetLineNumber(int); // Set line number.
void SetStringNumber(int); // Set string number. void SetStringNumber(int); // Set string number.
int GetLineNumber(void); // Get the current String Number. int GetLineNumber(void); // Get the current String Number.
......
...@@ -84,6 +84,8 @@ ...@@ -84,6 +84,8 @@
// This file is auto-generated by generate_parser.sh. DO NOT EDIT! // This file is auto-generated by generate_parser.sh. DO NOT EDIT!
#if defined(__GNUC__) #if defined(__GNUC__)
// Triggered by the auto-generated pplval variable.
#pragma GCC diagnostic ignored "-Wuninitialized"
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
#pragma warning(disable: 4065 4701) #pragma warning(disable: 4065 4701)
#endif #endif
...@@ -467,9 +469,9 @@ static const yytype_int8 yyrhs[] = ...@@ -467,9 +469,9 @@ static const yytype_int8 yyrhs[] =
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ /* YYRLINE[YYN] -- source line where rule number YYN was defined. */
static const yytype_uint8 yyrline[] = static const yytype_uint8 yyrline[] =
{ {
0, 85, 85, 92, 93, 96, 99, 102, 105, 108, 0, 87, 87, 94, 95, 98, 101, 104, 107, 110,
111, 114, 117, 120, 123, 126, 129, 132, 135, 138, 113, 116, 119, 122, 125, 128, 131, 134, 137, 140,
151, 164, 167, 170, 173, 176, 179 153, 166, 169, 172, 175, 178, 181
}; };
#endif #endif
......
...@@ -21,6 +21,8 @@ WHICH GENERATES THE GLSL ES preprocessor expression parser. ...@@ -21,6 +21,8 @@ WHICH GENERATES THE GLSL ES preprocessor expression parser.
// This file is auto-generated by generate_parser.sh. DO NOT EDIT! // This file is auto-generated by generate_parser.sh. DO NOT EDIT!
#if defined(__GNUC__) #if defined(__GNUC__)
// Triggered by the auto-generated pplval variable.
#pragma GCC diagnostic ignored "-Wuninitialized"
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
#pragma warning(disable: 4065 4701) #pragma warning(disable: 4065 4701)
#endif #endif
......
...@@ -519,6 +519,11 @@ IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh. ...@@ -519,6 +519,11 @@ IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh.
#include "Diagnostics.h" #include "Diagnostics.h"
#include "Token.h" #include "Token.h"
#if defined(__GNUC__)
// Triggered by the auto-generated yy_fatal_error function.
#pragma GCC diagnostic ignored "-Wmissing-noreturn"
#endif
typedef std::string YYSTYPE; typedef std::string YYSTYPE;
typedef pp::SourceLocation YYLTYPE; typedef pp::SourceLocation YYLTYPE;
......
...@@ -28,6 +28,11 @@ IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh. ...@@ -28,6 +28,11 @@ IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh.
#include "Diagnostics.h" #include "Diagnostics.h"
#include "Token.h" #include "Token.h"
#if defined(__GNUC__)
// Triggered by the auto-generated yy_fatal_error function.
#pragma GCC diagnostic ignored "-Wmissing-noreturn"
#endif
typedef std::string YYSTYPE; typedef std::string YYSTYPE;
typedef pp::SourceLocation YYLTYPE; typedef pp::SourceLocation YYLTYPE;
......
...@@ -75,7 +75,7 @@ static int eof_scan(InputSrc *is, yystypepp * yylvalpp) ...@@ -75,7 +75,7 @@ static int eof_scan(InputSrc *is, yystypepp * yylvalpp)
static void noop(InputSrc *in, int ch, yystypepp * yylvalpp) {} static void noop(InputSrc *in, int ch, yystypepp * yylvalpp) {}
static InputSrc eof_inputsrc = { 0, &eof_scan, &eof_scan, &noop }; static InputSrc eof_inputsrc = { 0, &eof_scan, &eof_scan, &noop, 0, 0 };
static int byte_scan(InputSrc *, yystypepp * yylvalpp); static int byte_scan(InputSrc *, yystypepp * yylvalpp);
......
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