Commit 4de340ac by Olli Etuaho Committed by Commit Bot

Remove extraInfo parameter from compiler diagnostic functions

This makes error messages more consistent. It was not clear what was supposed to go to the extraInfo parameter, and previously it was mostly being misused, resulting in poorly formatted error messages. Sometimes the order of parameters to the diagnostic functions like error() and warning() was wrong altogether. The diagnostics API is simpler when there's only the "reason" and "token" parameters that have clear meaning and that are separated by consistent punctuation in the output. Fixes error messages like "redifinition interface block member" to be grammatically reasonable like the rest of the error messages. For other error messages, punctuation is added to make them clearer. Example: "invalid layout qualifier location requires an argument" is changed to "invalid layout qualifier: location requires an argument". Extra spaces are also removed from the beginning of error messages. BUG=angleproject:1670 BUG=angleproject:911 TEST=angle_unittests Change-Id: Id5fb1a1f2892fad2b796aaef47ffb07e9d79759c Reviewed-on: https://chromium-review.googlesource.com/420789Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
parent 08a617ad
...@@ -21,11 +21,11 @@ float CheckedSum(float lhs, float rhs, TDiagnostics *diag, const TSourceLoc &lin ...@@ -21,11 +21,11 @@ float CheckedSum(float lhs, float rhs, TDiagnostics *diag, const TSourceLoc &lin
float result = lhs + rhs; float result = lhs + rhs;
if (gl::isNaN(result) && !gl::isNaN(lhs) && !gl::isNaN(rhs)) if (gl::isNaN(result) && !gl::isNaN(lhs) && !gl::isNaN(rhs))
{ {
diag->warning(line, "Constant folded undefined addition generated NaN", "+", ""); diag->warning(line, "Constant folded undefined addition generated NaN", "+");
} }
else if (gl::isInf(result) && !gl::isInf(lhs) && !gl::isInf(rhs)) else if (gl::isInf(result) && !gl::isInf(lhs) && !gl::isInf(rhs))
{ {
diag->warning(line, "Constant folded addition overflowed to infinity", "+", ""); diag->warning(line, "Constant folded addition overflowed to infinity", "+");
} }
return result; return result;
} }
...@@ -35,11 +35,11 @@ float CheckedDiff(float lhs, float rhs, TDiagnostics *diag, const TSourceLoc &li ...@@ -35,11 +35,11 @@ float CheckedDiff(float lhs, float rhs, TDiagnostics *diag, const TSourceLoc &li
float result = lhs - rhs; float result = lhs - rhs;
if (gl::isNaN(result) && !gl::isNaN(lhs) && !gl::isNaN(rhs)) if (gl::isNaN(result) && !gl::isNaN(lhs) && !gl::isNaN(rhs))
{ {
diag->warning(line, "Constant folded undefined subtraction generated NaN", "-", ""); diag->warning(line, "Constant folded undefined subtraction generated NaN", "-");
} }
else if (gl::isInf(result) && !gl::isInf(lhs) && !gl::isInf(rhs)) else if (gl::isInf(result) && !gl::isInf(lhs) && !gl::isInf(rhs))
{ {
diag->warning(line, "Constant folded subtraction overflowed to infinity", "-", ""); diag->warning(line, "Constant folded subtraction overflowed to infinity", "-");
} }
return result; return result;
} }
...@@ -49,11 +49,11 @@ float CheckedMul(float lhs, float rhs, TDiagnostics *diag, const TSourceLoc &lin ...@@ -49,11 +49,11 @@ float CheckedMul(float lhs, float rhs, TDiagnostics *diag, const TSourceLoc &lin
float result = lhs * rhs; float result = lhs * rhs;
if (gl::isNaN(result) && !gl::isNaN(lhs) && !gl::isNaN(rhs)) if (gl::isNaN(result) && !gl::isNaN(lhs) && !gl::isNaN(rhs))
{ {
diag->warning(line, "Constant folded undefined multiplication generated NaN", "*", ""); diag->warning(line, "Constant folded undefined multiplication generated NaN", "*");
} }
else if (gl::isInf(result) && !gl::isInf(lhs) && !gl::isInf(rhs)) else if (gl::isInf(result) && !gl::isInf(lhs) && !gl::isInf(rhs))
{ {
diag->warning(line, "Constant folded multiplication overflowed to infinity", "*", ""); diag->warning(line, "Constant folded multiplication overflowed to infinity", "*");
} }
return result; return result;
} }
...@@ -380,7 +380,7 @@ TConstantUnion TConstantUnion::rshift(const TConstantUnion &lhs, ...@@ -380,7 +380,7 @@ TConstantUnion TConstantUnion::rshift(const TConstantUnion &lhs,
if ((rhs.type == EbtInt && (rhs.iConst < 0 || rhs.iConst > 31)) || if ((rhs.type == EbtInt && (rhs.iConst < 0 || rhs.iConst > 31)) ||
(rhs.type == EbtUInt && rhs.uConst > 31u)) (rhs.type == EbtUInt && rhs.uConst > 31u))
{ {
diag->error(line, "Undefined shift (operand out of range)", ">>", ""); diag->error(line, "Undefined shift (operand out of range)", ">>");
switch (lhs.type) switch (lhs.type)
{ {
case EbtInt: case EbtInt:
...@@ -487,7 +487,7 @@ TConstantUnion TConstantUnion::lshift(const TConstantUnion &lhs, ...@@ -487,7 +487,7 @@ TConstantUnion TConstantUnion::lshift(const TConstantUnion &lhs,
if ((rhs.type == EbtInt && (rhs.iConst < 0 || rhs.iConst > 31)) || if ((rhs.type == EbtInt && (rhs.iConst < 0 || rhs.iConst > 31)) ||
(rhs.type == EbtUInt && rhs.uConst > 31u)) (rhs.type == EbtUInt && rhs.uConst > 31u))
{ {
diag->error(line, "Undefined shift (operand out of range)", "<<", ""); diag->error(line, "Undefined shift (operand out of range)", "<<");
switch (lhs.type) switch (lhs.type)
{ {
case EbtInt: case EbtInt:
......
...@@ -26,8 +26,7 @@ TDiagnostics::~TDiagnostics() ...@@ -26,8 +26,7 @@ TDiagnostics::~TDiagnostics()
void TDiagnostics::writeInfo(Severity severity, void TDiagnostics::writeInfo(Severity severity,
const pp::SourceLocation &loc, const pp::SourceLocation &loc,
const std::string &reason, const std::string &reason,
const std::string &token, const std::string &token)
const std::string &extra)
{ {
TPrefixType prefix = EPrefixNone; TPrefixType prefix = EPrefixNone;
switch (severity) switch (severity)
...@@ -49,39 +48,28 @@ void TDiagnostics::writeInfo(Severity severity, ...@@ -49,39 +48,28 @@ void TDiagnostics::writeInfo(Severity severity,
/* VC++ format: file(linenum) : error #: 'token' : extrainfo */ /* VC++ format: file(linenum) : error #: 'token' : extrainfo */
sink.prefix(prefix); sink.prefix(prefix);
sink.location(loc.file, loc.line); sink.location(loc.file, loc.line);
sink << "'" << token << "' : " << reason << " " << extra << "\n"; sink << "'" << token << "' : " << reason << "\n";
} }
void TDiagnostics::error(const TSourceLoc &loc, void TDiagnostics::error(const TSourceLoc &loc, const char *reason, const char *token)
const char *reason,
const char *token,
const char *extraInfo)
{ {
pp::SourceLocation srcLoc; pp::SourceLocation srcLoc;
srcLoc.file = loc.first_file; srcLoc.file = loc.first_file;
srcLoc.line = loc.first_line; srcLoc.line = loc.first_line;
writeInfo(pp::Diagnostics::PP_ERROR, srcLoc, reason, token, extraInfo); writeInfo(pp::Diagnostics::PP_ERROR, srcLoc, reason, token);
}
void TDiagnostics::error(const TSourceLoc &loc, const char *reason, const char *token)
{
error(loc, reason, token, "");
} }
void TDiagnostics::warning(const TSourceLoc &loc, void TDiagnostics::warning(const TSourceLoc &loc, const char *reason, const char *token)
const char *reason,
const char *token,
const char *extraInfo)
{ {
pp::SourceLocation srcLoc; pp::SourceLocation srcLoc;
srcLoc.file = loc.first_file; srcLoc.file = loc.first_file;
srcLoc.line = loc.first_line; srcLoc.line = loc.first_line;
writeInfo(pp::Diagnostics::PP_WARNING, srcLoc, reason, token, extraInfo); writeInfo(pp::Diagnostics::PP_WARNING, srcLoc, reason, token);
} }
void TDiagnostics::print(ID id, const pp::SourceLocation &loc, const std::string &text) void TDiagnostics::print(ID id, const pp::SourceLocation &loc, const std::string &text)
{ {
writeInfo(severity(id), loc, message(id), text, ""); writeInfo(severity(id), loc, message(id), text);
} }
} // namespace sh } // namespace sh
...@@ -30,15 +30,10 @@ class TDiagnostics : public pp::Diagnostics, angle::NonCopyable ...@@ -30,15 +30,10 @@ class TDiagnostics : public pp::Diagnostics, angle::NonCopyable
void writeInfo(Severity severity, void writeInfo(Severity severity,
const pp::SourceLocation &loc, const pp::SourceLocation &loc,
const std::string &reason, const std::string &reason,
const std::string &token, const std::string &token);
const std::string &extra);
void error(const TSourceLoc &loc, const char *reason, const char *token, const char *extraInfo);
void error(const TSourceLoc &loc, const char *reason, const char *token); void error(const TSourceLoc &loc, const char *reason, const char *token);
void warning(const TSourceLoc &loc, void warning(const TSourceLoc &loc, const char *reason, const char *token);
const char *reason,
const char *token,
const char *extraInfo);
protected: protected:
void print(ID id, const pp::SourceLocation &loc, const std::string &text) override; void print(ID id, const pp::SourceLocation &loc, const std::string &text) override;
......
...@@ -52,7 +52,7 @@ TDirectiveHandler::~TDirectiveHandler() ...@@ -52,7 +52,7 @@ TDirectiveHandler::~TDirectiveHandler()
void TDirectiveHandler::handleError(const pp::SourceLocation &loc, const std::string &msg) void TDirectiveHandler::handleError(const pp::SourceLocation &loc, const std::string &msg)
{ {
mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc, msg, "", ""); mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc, msg, "");
} }
void TDirectiveHandler::handlePragma(const pp::SourceLocation &loc, void TDirectiveHandler::handlePragma(const pp::SourceLocation &loc,
...@@ -72,7 +72,7 @@ void TDirectiveHandler::handlePragma(const pp::SourceLocation &loc, ...@@ -72,7 +72,7 @@ void TDirectiveHandler::handlePragma(const pp::SourceLocation &loc,
// ESSL 3.00.4 section 4.6.1 // ESSL 3.00.4 section 4.6.1
mDiagnostics.writeInfo( mDiagnostics.writeInfo(
pp::Diagnostics::PP_ERROR, loc, pp::Diagnostics::PP_ERROR, loc,
"#pragma STDGL invariant(all) can not be used in fragment shader", name, value); "#pragma STDGL invariant(all) can not be used in fragment shader", name);
} }
mPragma.stdgl.invariantAll = true; mPragma.stdgl.invariantAll = true;
} }
...@@ -125,8 +125,8 @@ void TDirectiveHandler::handlePragma(const pp::SourceLocation &loc, ...@@ -125,8 +125,8 @@ void TDirectiveHandler::handlePragma(const pp::SourceLocation &loc,
if (invalidValue) if (invalidValue)
{ {
mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc, "invalid pragma value", value, mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
"'on' or 'off' expected"); "invalid pragma value - 'on' or 'off' expected", value);
} }
} }
} }
...@@ -140,7 +140,7 @@ void TDirectiveHandler::handleExtension(const pp::SourceLocation &loc, ...@@ -140,7 +140,7 @@ void TDirectiveHandler::handleExtension(const pp::SourceLocation &loc,
TBehavior behaviorVal = getBehavior(behavior); TBehavior behaviorVal = getBehavior(behavior);
if (behaviorVal == EBhUndefined) if (behaviorVal == EBhUndefined)
{ {
mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc, "behavior", name, "invalid"); mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc, "behavior invalid", name);
return; return;
} }
...@@ -148,13 +148,13 @@ void TDirectiveHandler::handleExtension(const pp::SourceLocation &loc, ...@@ -148,13 +148,13 @@ void TDirectiveHandler::handleExtension(const pp::SourceLocation &loc,
{ {
if (behaviorVal == EBhRequire) if (behaviorVal == EBhRequire)
{ {
mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc, "extension", name, mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
"cannot have 'require' behavior"); "extension cannot have 'require' behavior", name);
} }
else if (behaviorVal == EBhEnable) else if (behaviorVal == EBhEnable)
{ {
mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc, "extension", name, mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
"cannot have 'enable' behavior"); "extension cannot have 'enable' behavior", name);
} }
else else
{ {
...@@ -187,7 +187,7 @@ void TDirectiveHandler::handleExtension(const pp::SourceLocation &loc, ...@@ -187,7 +187,7 @@ void TDirectiveHandler::handleExtension(const pp::SourceLocation &loc,
UNREACHABLE(); UNREACHABLE();
break; break;
} }
mDiagnostics.writeInfo(severity, loc, "extension", name, "is not supported"); mDiagnostics.writeInfo(severity, loc, "extension is not supported", name);
} }
void TDirectiveHandler::handleVersion(const pp::SourceLocation &loc, int version) void TDirectiveHandler::handleVersion(const pp::SourceLocation &loc, int version)
...@@ -201,8 +201,7 @@ void TDirectiveHandler::handleVersion(const pp::SourceLocation &loc, int version ...@@ -201,8 +201,7 @@ void TDirectiveHandler::handleVersion(const pp::SourceLocation &loc, int version
std::stringstream stream; std::stringstream stream;
stream << version; stream << version;
std::string str = stream.str(); std::string str = stream.str();
mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc, "version number", str, mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc, "version number not supported", str);
"not supported");
} }
} }
......
...@@ -54,7 +54,7 @@ void UndefinedConstantFoldingError(const TSourceLoc &loc, ...@@ -54,7 +54,7 @@ void UndefinedConstantFoldingError(const TSourceLoc &loc,
TConstantUnion *result) TConstantUnion *result)
{ {
diagnostics->warning(loc, "operation result is undefined for the values passed in", diagnostics->warning(loc, "operation result is undefined for the values passed in",
GetOperatorString(op), ""); GetOperatorString(op));
switch (basicType) switch (basicType)
{ {
...@@ -1342,13 +1342,13 @@ TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op, ...@@ -1342,13 +1342,13 @@ TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op,
diagnostics->warning( diagnostics->warning(
getLine(), getLine(),
"Zero divided by zero during constant folding generated NaN", "Zero divided by zero during constant folding generated NaN",
"/", ""); "/");
resultArray[i].setFConst(std::numeric_limits<float>::quiet_NaN()); resultArray[i].setFConst(std::numeric_limits<float>::quiet_NaN());
} }
else else
{ {
diagnostics->warning( diagnostics->warning(getLine(),
getLine(), "Divide by zero during constant folding", "/", ""); "Divide by zero during constant folding", "/");
bool negativeResult = bool negativeResult =
std::signbit(dividend) != std::signbit(divisor); std::signbit(dividend) != std::signbit(divisor);
resultArray[i].setFConst( resultArray[i].setFConst(
...@@ -1361,7 +1361,7 @@ TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op, ...@@ -1361,7 +1361,7 @@ TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op,
diagnostics->warning(getLine(), diagnostics->warning(getLine(),
"Infinity divided by infinity during constant " "Infinity divided by infinity during constant "
"folding generated NaN", "folding generated NaN",
"/", ""); "/");
resultArray[i].setFConst(std::numeric_limits<float>::quiet_NaN()); resultArray[i].setFConst(std::numeric_limits<float>::quiet_NaN());
} }
else else
...@@ -1371,7 +1371,7 @@ TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op, ...@@ -1371,7 +1371,7 @@ TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op,
{ {
diagnostics->warning( diagnostics->warning(
getLine(), "Constant folded division overflowed to infinity", getLine(), "Constant folded division overflowed to infinity",
"/", ""); "/");
} }
resultArray[i].setFConst(result); resultArray[i].setFConst(result);
} }
...@@ -1381,7 +1381,7 @@ TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op, ...@@ -1381,7 +1381,7 @@ TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op,
if (rightArray[i] == 0) if (rightArray[i] == 0)
{ {
diagnostics->warning( diagnostics->warning(
getLine(), "Divide by zero error during constant folding", "/", ""); getLine(), "Divide by zero error during constant folding", "/");
resultArray[i].setIConst(INT_MAX); resultArray[i].setIConst(INT_MAX);
} }
else else
...@@ -1418,7 +1418,7 @@ TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op, ...@@ -1418,7 +1418,7 @@ TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op,
diagnostics->warning(getLine(), diagnostics->warning(getLine(),
"Negative modulus operator operand " "Negative modulus operator operand "
"encountered during constant folding", "encountered during constant folding",
"%", ""); "%");
resultArray[i].setIConst(0); resultArray[i].setIConst(0);
} }
else else
...@@ -1433,7 +1433,7 @@ TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op, ...@@ -1433,7 +1433,7 @@ TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op,
if (rightArray[i] == 0) if (rightArray[i] == 0)
{ {
diagnostics->warning( diagnostics->warning(
getLine(), "Divide by zero error during constant folding", "/", ""); getLine(), "Divide by zero error during constant folding", "/");
resultArray[i].setUConst(UINT_MAX); resultArray[i].setUConst(UINT_MAX);
} }
else else
......
...@@ -225,35 +225,28 @@ bool TParseContext::parseVectorFields(const TString &compString, ...@@ -225,35 +225,28 @@ bool TParseContext::parseVectorFields(const TString &compString,
// //
// Used by flex/bison to output all syntax and parsing errors. // Used by flex/bison to output all syntax and parsing errors.
// //
void TParseContext::error(const TSourceLoc &loc, void TParseContext::error(const TSourceLoc &loc, const char *reason, const char *token)
const char *reason,
const char *token,
const char *extraInfo)
{ {
mDiagnostics.error(loc, reason, token, extraInfo); mDiagnostics.error(loc, reason, token);
} }
void TParseContext::warning(const TSourceLoc &loc, void TParseContext::warning(const TSourceLoc &loc, const char *reason, const char *token)
const char *reason,
const char *token,
const char *extraInfo)
{ {
mDiagnostics.warning(loc, reason, token, extraInfo); mDiagnostics.warning(loc, reason, token);
} }
void TParseContext::outOfRangeError(bool isError, void TParseContext::outOfRangeError(bool isError,
const TSourceLoc &loc, const TSourceLoc &loc,
const char *reason, const char *reason,
const char *token, const char *token)
const char *extraInfo)
{ {
if (isError) if (isError)
{ {
error(loc, reason, token, extraInfo); error(loc, reason, token);
} }
else else
{ {
warning(loc, reason, token, extraInfo); warning(loc, reason, token);
} }
} }
...@@ -262,10 +255,10 @@ void TParseContext::outOfRangeError(bool isError, ...@@ -262,10 +255,10 @@ void TParseContext::outOfRangeError(bool isError,
// //
void TParseContext::assignError(const TSourceLoc &line, const char *op, TString left, TString right) void TParseContext::assignError(const TSourceLoc &line, const char *op, TString left, TString right)
{ {
std::stringstream extraInfoStream; std::stringstream reasonStream;
extraInfoStream << "cannot convert from '" << right << "' to '" << left << "'"; reasonStream << "cannot convert from '" << right << "' to '" << left << "'";
std::string extraInfo = extraInfoStream.str(); std::string reason = reasonStream.str();
error(line, "", op, extraInfo.c_str()); error(line, reason.c_str(), op);
} }
// //
...@@ -273,11 +266,12 @@ void TParseContext::assignError(const TSourceLoc &line, const char *op, TString ...@@ -273,11 +266,12 @@ void TParseContext::assignError(const TSourceLoc &line, const char *op, TString
// //
void TParseContext::unaryOpError(const TSourceLoc &line, const char *op, TString operand) void TParseContext::unaryOpError(const TSourceLoc &line, const char *op, TString operand)
{ {
std::stringstream extraInfoStream; std::stringstream reasonStream;
extraInfoStream << "no operation '" << op << "' exists that takes an operand of type " reasonStream << "wrong operand type - no operation '" << op
<< operand << " (or there is no acceptable conversion)"; << "' exists that takes an operand of type " << operand
std::string extraInfo = extraInfoStream.str(); << " (or there is no acceptable conversion)";
error(line, " wrong operand type", op, extraInfo.c_str()); std::string reason = reasonStream.str();
error(line, reason.c_str(), op);
} }
// //
...@@ -288,12 +282,13 @@ void TParseContext::binaryOpError(const TSourceLoc &line, ...@@ -288,12 +282,13 @@ void TParseContext::binaryOpError(const TSourceLoc &line,
TString left, TString left,
TString right) TString right)
{ {
std::stringstream extraInfoStream; std::stringstream reasonStream;
extraInfoStream << "no operation '" << op << "' exists that takes a left-hand operand of type '" reasonStream << "wrong operand types - no operation '" << op
<< left << "' and a right operand of type '" << right << "' exists that takes a left-hand operand of type '" << left
<< "' (or there is no acceptable conversion)"; << "' and a right operand of type '" << right
std::string extraInfo = extraInfoStream.str(); << "' (or there is no acceptable conversion)";
error(line, " wrong operand types ", op, extraInfo.c_str()); std::string reason = reasonStream.str();
error(line, reason.c_str(), op);
} }
void TParseContext::checkPrecisionSpecified(const TSourceLoc &line, void TParseContext::checkPrecisionSpecified(const TSourceLoc &line,
...@@ -370,10 +365,6 @@ bool TParseContext::checkCanBeLValue(const TSourceLoc &line, const char *op, TIn ...@@ -370,10 +365,6 @@ bool TParseContext::checkCanBeLValue(const TSourceLoc &line, const char *op, TIn
return false; return false;
} }
const char *symbol = 0;
if (symNode != 0)
symbol = symNode->getSymbol().c_str();
const char *message = 0; const char *message = 0;
switch (node->getQualifier()) switch (node->getQualifier())
{ {
...@@ -448,7 +439,7 @@ bool TParseContext::checkCanBeLValue(const TSourceLoc &line, const char *op, TIn ...@@ -448,7 +439,7 @@ bool TParseContext::checkCanBeLValue(const TSourceLoc &line, const char *op, TIn
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 false; return false;
} }
...@@ -464,17 +455,18 @@ bool TParseContext::checkCanBeLValue(const TSourceLoc &line, const char *op, TIn ...@@ -464,17 +455,18 @@ bool TParseContext::checkCanBeLValue(const TSourceLoc &line, const char *op, TIn
// //
if (symNode) if (symNode)
{ {
std::stringstream extraInfoStream; const char *symbol = symNode->getSymbol().c_str();
extraInfoStream << "\"" << symbol << "\" (" << message << ")"; std::stringstream reasonStream;
std::string extraInfo = extraInfoStream.str(); reasonStream << "l-value required (" << message << " \"" << symbol << "\")";
error(line, " l-value required", op, extraInfo.c_str()); std::string reason = reasonStream.str();
error(line, reason.c_str(), op);
} }
else else
{ {
std::stringstream extraInfoStream; std::stringstream reasonStream;
extraInfoStream << "(" << message << ")"; reasonStream << "l-value required (" << message << ")";
std::string extraInfo = extraInfoStream.str(); std::string reason = reasonStream.str();
error(line, " l-value required", op, extraInfo.c_str()); error(line, reason.c_str(), op);
} }
return false; return false;
...@@ -697,7 +689,7 @@ bool TParseContext::checkConstructorArguments(const TSourceLoc &line, ...@@ -697,7 +689,7 @@ bool TParseContext::checkConstructorArguments(const TSourceLoc &line,
ASSERT(!argType.isArray()); ASSERT(!argType.isArray());
if (!argType.sameElementType(type)) if (!argType.sameElementType(type))
{ {
error(line, "Array constructor argument has an incorrect type", "Error"); error(line, "Array constructor argument has an incorrect type", "constructor");
return false; return false;
} }
} }
...@@ -712,7 +704,7 @@ bool TParseContext::checkConstructorArguments(const TSourceLoc &line, ...@@ -712,7 +704,7 @@ bool TParseContext::checkConstructorArguments(const TSourceLoc &line,
if (i >= args->size() || (*args)[i]->getAsTyped()->getType() != *fields[i]->type()) if (i >= args->size() || (*args)[i]->getAsTyped()->getType() != *fields[i]->type())
{ {
error(line, "Structure constructor arguments do not match structure fields", error(line, "Structure constructor arguments do not match structure fields",
"Error"); "constructor");
return false; return false;
} }
} }
...@@ -767,7 +759,10 @@ bool TParseContext::checkIsNotSampler(const TSourceLoc &line, ...@@ -767,7 +759,10 @@ bool TParseContext::checkIsNotSampler(const TSourceLoc &line,
{ {
if (ContainsSampler(*pType.userDef)) if (ContainsSampler(*pType.userDef))
{ {
error(line, reason, getBasicString(pType.type), "(structure contains a sampler)"); std::stringstream reasonStream;
reasonStream << reason << " (structure contains a sampler)";
std::string reasonStr = reasonStream.str();
error(line, reasonStr.c_str(), getBasicString(pType.type));
return false; return false;
} }
...@@ -790,7 +785,10 @@ bool TParseContext::checkIsNotImage(const TSourceLoc &line, ...@@ -790,7 +785,10 @@ bool TParseContext::checkIsNotImage(const TSourceLoc &line,
{ {
if (ContainsImage(*pType.userDef)) if (ContainsImage(*pType.userDef))
{ {
error(line, reason, getBasicString(pType.type), "(structure contains an image)"); std::stringstream reasonStream;
reasonStream << reason << " (structure contains an image)";
std::string reasonStr = reasonStream.str();
error(line, reasonStr.c_str(), getBasicString(pType.type));
return false; return false;
} }
...@@ -822,8 +820,8 @@ void TParseContext::checkLocationIsNotSpecified(const TSourceLoc &location, ...@@ -822,8 +820,8 @@ void TParseContext::checkLocationIsNotSpecified(const TSourceLoc &location,
{ {
if (layoutQualifier.location != -1) if (layoutQualifier.location != -1)
{ {
error(location, "invalid layout qualifier:", "location", error(location, "invalid layout qualifier: only valid on program inputs and outputs",
"only valid on program inputs and outputs"); "location");
} }
} }
...@@ -1081,18 +1079,18 @@ bool TParseContext::checkCanUseExtension(const TSourceLoc &line, const TString & ...@@ -1081,18 +1079,18 @@ bool TParseContext::checkCanUseExtension(const TSourceLoc &line, const TString &
TExtensionBehavior::const_iterator iter = extBehavior.find(extension.c_str()); TExtensionBehavior::const_iterator iter = extBehavior.find(extension.c_str());
if (iter == extBehavior.end()) if (iter == extBehavior.end())
{ {
error(line, "extension", extension.c_str(), "is not supported"); error(line, "extension is not supported", extension.c_str());
return false; return false;
} }
// In GLSL ES, an extension's default behavior is "disable". // In GLSL ES, an extension's default behavior is "disable".
if (iter->second == EBhDisable || iter->second == EBhUndefined) if (iter->second == EBhDisable || iter->second == EBhUndefined)
{ {
error(line, "extension", extension.c_str(), "is disabled"); error(line, "extension is disabled", extension.c_str());
return false; return false;
} }
if (iter->second == EBhWarn) if (iter->second == EBhWarn)
{ {
warning(line, "extension", extension.c_str(), "is being used"); warning(line, "extension is being used", extension.c_str());
return true; return true;
} }
...@@ -1156,17 +1154,15 @@ void TParseContext::singleDeclarationErrorCheck(const TPublicType &publicType, ...@@ -1156,17 +1154,15 @@ void TParseContext::singleDeclarationErrorCheck(const TPublicType &publicType,
if (layoutQualifier.matrixPacking != EmpUnspecified) if (layoutQualifier.matrixPacking != EmpUnspecified)
{ {
error(identifierLocation, "layout qualifier", error(identifierLocation, "layout qualifier only valid for interface blocks",
getMatrixPackingString(layoutQualifier.matrixPacking), getMatrixPackingString(layoutQualifier.matrixPacking));
"only valid for interface blocks");
return; return;
} }
if (layoutQualifier.blockStorage != EbsUnspecified) if (layoutQualifier.blockStorage != EbsUnspecified)
{ {
error(identifierLocation, "layout qualifier", error(identifierLocation, "layout qualifier only valid for interface blocks",
getBlockStorageString(layoutQualifier.blockStorage), getBlockStorageString(layoutQualifier.blockStorage));
"only valid for interface blocks");
return; return;
} }
...@@ -1266,7 +1262,7 @@ void TParseContext::checkLayoutQualifierSupported(const TSourceLoc &location, ...@@ -1266,7 +1262,7 @@ void TParseContext::checkLayoutQualifierSupported(const TSourceLoc &location,
if (mShaderVersion < versionRequired) if (mShaderVersion < versionRequired)
{ {
error(location, "invalid layout qualifier:", layoutQualifierName.c_str(), "not supported"); error(location, "invalid layout qualifier: not supported", layoutQualifierName.c_str());
} }
} }
...@@ -1278,8 +1274,10 @@ bool TParseContext::checkWorkGroupSizeIsNotSpecified(const TSourceLoc &location, ...@@ -1278,8 +1274,10 @@ bool TParseContext::checkWorkGroupSizeIsNotSpecified(const TSourceLoc &location,
{ {
if (localSize[i] != -1) if (localSize[i] != -1)
{ {
error(location, "invalid layout qualifier:", getWorkGroupSizeString(i), error(location,
"only valid when used with 'in' in a compute shader global layout declaration"); "invalid layout qualifier: only valid when used with 'in' in a compute shader "
"global layout declaration",
getWorkGroupSizeString(i));
return false; return false;
} }
} }
...@@ -1292,8 +1290,8 @@ bool TParseContext::checkInternalFormatIsNotSpecified(const TSourceLoc &location ...@@ -1292,8 +1290,8 @@ bool TParseContext::checkInternalFormatIsNotSpecified(const TSourceLoc &location
{ {
if (internalFormat != EiifUnspecified) if (internalFormat != EiifUnspecified)
{ {
error(location, "invalid layout qualifier:", getImageInternalFormatString(internalFormat), error(location, "invalid layout qualifier: only valid when used with images",
"only valid when used with images"); getImageInternalFormatString(internalFormat));
return false; return false;
} }
return true; return true;
...@@ -1310,8 +1308,11 @@ void TParseContext::functionCallLValueErrorCheck(const TFunction *fnCandidate, ...@@ -1310,8 +1308,11 @@ void TParseContext::functionCallLValueErrorCheck(const TFunction *fnCandidate,
TIntermTyped *argument = (*(fnCall->getSequence()))[i]->getAsTyped(); TIntermTyped *argument = (*(fnCall->getSequence()))[i]->getAsTyped();
if (!checkCanBeLValue(argument->getLine(), "assign", argument)) if (!checkCanBeLValue(argument->getLine(), "assign", argument))
{ {
TString unmangledName =
TFunction::unmangleName(fnCall->getFunctionSymbolInfo()->getName());
error(argument->getLine(), error(argument->getLine(),
"Constant value cannot be passed for 'out' or 'inout' parameters.", "Error"); "Constant value cannot be passed for 'out' or 'inout' parameters.",
unmangledName.c_str());
return; return;
} }
} }
...@@ -1617,10 +1618,11 @@ bool TParseContext::executeInitializer(const TSourceLoc &line, ...@@ -1617,10 +1618,11 @@ bool TParseContext::executeInitializer(const TSourceLoc &line,
{ {
if (qualifier != initializer->getType().getQualifier()) if (qualifier != initializer->getType().getQualifier())
{ {
std::stringstream extraInfoStream; std::stringstream reasonStream;
extraInfoStream << "'" << variable->getType().getCompleteString() << "'"; reasonStream << "assigning non-constant to '" << variable->getType().getCompleteString()
std::string extraInfo = extraInfoStream.str(); << "'";
error(line, " assigning non-constant to", "=", extraInfo.c_str()); std::string reason = reasonStream.str();
error(line, reason.c_str(), "=");
variable->getType().setQualifier(EvqTemporary); variable->getType().setQualifier(EvqTemporary);
return true; return true;
} }
...@@ -2300,13 +2302,12 @@ void TParseContext::parseGlobalLayoutQualifier(const TTypeQualifierBuilder &type ...@@ -2300,13 +2302,12 @@ void TParseContext::parseGlobalLayoutQualifier(const TTypeQualifierBuilder &type
if (mComputeShaderLocalSize[i] < 1 || if (mComputeShaderLocalSize[i] < 1 ||
mComputeShaderLocalSize[i] > maxComputeWorkGroupSizeValue) mComputeShaderLocalSize[i] > maxComputeWorkGroupSizeValue)
{ {
std::stringstream errorMessageStream; std::stringstream reasonStream;
errorMessageStream << "Value must be at least 1 and no greater than " reasonStream << "invalid value: Value must be at least 1 and no greater than "
<< maxComputeWorkGroupSizeValue; << maxComputeWorkGroupSizeValue;
const std::string &errorMessage = errorMessageStream.str(); const std::string &reason = reasonStream.str();
error(typeQualifier.line, "invalid value:", getWorkGroupSizeString(i), error(typeQualifier.line, reason.c_str(), getWorkGroupSizeString(i));
errorMessage.c_str());
return; return;
} }
} }
...@@ -2324,8 +2325,8 @@ void TParseContext::parseGlobalLayoutQualifier(const TTypeQualifierBuilder &type ...@@ -2324,8 +2325,8 @@ void TParseContext::parseGlobalLayoutQualifier(const TTypeQualifierBuilder &type
if (typeQualifier.qualifier != EvqUniform) if (typeQualifier.qualifier != EvqUniform)
{ {
error(typeQualifier.line, "invalid qualifier:", error(typeQualifier.line, "invalid qualifier: global layout must be uniform",
getQualifierString(typeQualifier.qualifier), "global layout must be uniform"); getQualifierString(typeQualifier.qualifier));
return; return;
} }
...@@ -2412,7 +2413,7 @@ TIntermFunctionDefinition *TParseContext::addFunctionDefinition( ...@@ -2412,7 +2413,7 @@ TIntermFunctionDefinition *TParseContext::addFunctionDefinition(
// Check that non-void functions have at least one return statement. // Check that non-void functions have at least one return statement.
if (mCurrentFunctionType->getBasicType() != EbtVoid && !mFunctionReturnsValue) if (mCurrentFunctionType->getBasicType() != EbtVoid && !mFunctionReturnsValue)
{ {
error(location, "function does not return a value:", "", function.getName().c_str()); error(location, "function does not return a value:", function.getName().c_str());
} }
if (functionBody == nullptr) if (functionBody == nullptr)
...@@ -2479,8 +2480,8 @@ void TParseContext::parseFunctionDefinitionHeader(const TSourceLoc &location, ...@@ -2479,8 +2480,8 @@ void TParseContext::parseFunctionDefinitionHeader(const TSourceLoc &location,
} }
if ((*function)->getReturnType().getBasicType() != EbtVoid) if ((*function)->getReturnType().getBasicType() != EbtVoid)
{ {
error(location, "", (*function)->getReturnType().getBasicString(), error(location, "main function cannot return a value",
"main function cannot return a value"); (*function)->getReturnType().getBasicString());
} }
} }
...@@ -2584,7 +2585,7 @@ TFunction *TParseContext::parseFunctionDeclarator(const TSourceLoc &location, TF ...@@ -2584,7 +2585,7 @@ TFunction *TParseContext::parseFunctionDeclarator(const TSourceLoc &location, TF
{ {
if (!prevSym->isFunction()) if (!prevSym->isFunction())
{ {
error(location, "redefinition", function->getName().c_str(), "function"); error(location, "redefinition of a function", function->getName().c_str());
} }
} }
else else
...@@ -2757,8 +2758,8 @@ TIntermDeclaration *TParseContext::addInterfaceBlock( ...@@ -2757,8 +2758,8 @@ TIntermDeclaration *TParseContext::addInterfaceBlock(
if (typeQualifier.qualifier != EvqUniform) if (typeQualifier.qualifier != EvqUniform)
{ {
error(typeQualifier.line, "invalid qualifier:", getQualifierString(typeQualifier.qualifier), error(typeQualifier.line, "invalid qualifier: interface blocks must be uniform",
"interface blocks must be uniform"); getQualifierString(typeQualifier.qualifier));
} }
if (typeQualifier.invariant) if (typeQualifier.invariant)
...@@ -2788,7 +2789,7 @@ TIntermDeclaration *TParseContext::addInterfaceBlock( ...@@ -2788,7 +2789,7 @@ TIntermDeclaration *TParseContext::addInterfaceBlock(
TSymbol *blockNameSymbol = new TInterfaceBlockName(&blockName); TSymbol *blockNameSymbol = new TInterfaceBlockName(&blockName);
if (!symbolTable.declare(blockNameSymbol)) if (!symbolTable.declare(blockNameSymbol))
{ {
error(nameLine, "redefinition", blockName.c_str(), "interface block name"); error(nameLine, "redefinition of an interface block name", blockName.c_str());
} }
// check for sampler types and apply layout qualifiers // check for sampler types and apply layout qualifiers
...@@ -2798,14 +2799,16 @@ TIntermDeclaration *TParseContext::addInterfaceBlock( ...@@ -2798,14 +2799,16 @@ TIntermDeclaration *TParseContext::addInterfaceBlock(
TType *fieldType = field->type(); TType *fieldType = field->type();
if (IsSampler(fieldType->getBasicType())) if (IsSampler(fieldType->getBasicType()))
{ {
error(field->line(), "unsupported type", fieldType->getBasicString(), error(field->line(),
"sampler types are not allowed in interface blocks"); "unsupported type - sampler types are not allowed in interface blocks",
fieldType->getBasicString());
} }
if (IsImage(fieldType->getBasicType())) if (IsImage(fieldType->getBasicType()))
{ {
error(field->line(), "unsupported type", fieldType->getBasicString(), error(field->line(),
"image types are not allowed in interface blocks"); "unsupported type - image types are not allowed in interface blocks",
fieldType->getBasicString());
} }
const TQualifier qualifier = fieldType->getQualifier(); const TQualifier qualifier = fieldType->getQualifier();
...@@ -2831,8 +2834,8 @@ TIntermDeclaration *TParseContext::addInterfaceBlock( ...@@ -2831,8 +2834,8 @@ TIntermDeclaration *TParseContext::addInterfaceBlock(
if (fieldLayoutQualifier.blockStorage != EbsUnspecified) if (fieldLayoutQualifier.blockStorage != EbsUnspecified)
{ {
error(field->line(), "invalid layout qualifier:", error(field->line(), "invalid layout qualifier: cannot be used here",
getBlockStorageString(fieldLayoutQualifier.blockStorage), "cannot be used here"); getBlockStorageString(fieldLayoutQualifier.blockStorage));
} }
if (fieldLayoutQualifier.matrixPacking == EmpUnspecified) if (fieldLayoutQualifier.matrixPacking == EmpUnspecified)
...@@ -2841,9 +2844,9 @@ TIntermDeclaration *TParseContext::addInterfaceBlock( ...@@ -2841,9 +2844,9 @@ TIntermDeclaration *TParseContext::addInterfaceBlock(
} }
else if (!fieldType->isMatrix() && fieldType->getBasicType() != EbtStruct) else if (!fieldType->isMatrix() && fieldType->getBasicType() != EbtStruct)
{ {
warning(field->line(), "extraneous layout qualifier:", warning(field->line(),
getMatrixPackingString(fieldLayoutQualifier.matrixPacking), "extraneous layout qualifier: only has an effect on matrix types",
"only has an effect on matrix types"); getMatrixPackingString(fieldLayoutQualifier.matrixPacking));
} }
fieldType->setLayoutQualifier(fieldLayoutQualifier); fieldType->setLayoutQualifier(fieldLayoutQualifier);
...@@ -2880,8 +2883,8 @@ TIntermDeclaration *TParseContext::addInterfaceBlock( ...@@ -2880,8 +2883,8 @@ TIntermDeclaration *TParseContext::addInterfaceBlock(
if (!symbolTable.declare(fieldVariable)) if (!symbolTable.declare(fieldVariable))
{ {
error(field->line(), "redefinition", field->name().c_str(), error(field->line(), "redefinition of an interface block member name",
"interface block member name"); field->name().c_str());
} }
} }
} }
...@@ -2895,8 +2898,8 @@ TIntermDeclaration *TParseContext::addInterfaceBlock( ...@@ -2895,8 +2898,8 @@ TIntermDeclaration *TParseContext::addInterfaceBlock(
if (!symbolTable.declare(instanceTypeDef)) if (!symbolTable.declare(instanceTypeDef))
{ {
error(instanceLine, "redefinition", instanceName->c_str(), error(instanceLine, "redefinition of an interface block instance name",
"interface block instance name"); instanceName->c_str());
} }
symbolId = instanceTypeDef->getUniqueId(); symbolId = instanceTypeDef->getUniqueId();
...@@ -2918,11 +2921,10 @@ void TParseContext::enterStructDeclaration(const TSourceLoc &line, const TString ...@@ -2918,11 +2921,10 @@ void TParseContext::enterStructDeclaration(const TSourceLoc &line, const TString
++mStructNestingLevel; ++mStructNestingLevel;
// Embedded structure definitions are not supported per GLSL ES spec. // Embedded structure definitions are not supported per GLSL ES spec.
// They aren't allowed in GLSL either, but we need to detect this here // ESSL 1.00.17 section 10.9. ESSL 3.00.6 section 12.11.
// so we don't rely on the GLSL compiler to catch it.
if (mStructNestingLevel > 1) if (mStructNestingLevel > 1)
{ {
error(line, "", "Embedded struct definitions are not allowed"); error(line, "Embedded struct definitions are not allowed", "struct");
} }
} }
...@@ -2951,7 +2953,7 @@ void TParseContext::checkIsBelowStructNestingLimit(const TSourceLoc &line, const ...@@ -2951,7 +2953,7 @@ void TParseContext::checkIsBelowStructNestingLimit(const TSourceLoc &line, const
reasonStream << "Reference of struct type " << field.type()->getStruct()->name().c_str() reasonStream << "Reference of struct type " << field.type()->getStruct()->name().c_str()
<< " exceeds maximum allowed nesting level of " << kWebGLMaxStructNesting; << " exceeds maximum allowed nesting level of " << kWebGLMaxStructNesting;
std::string reason = reasonStream.str(); std::string reason = reasonStream.str();
error(line, reason.c_str(), field.name().c_str(), ""); error(line, reason.c_str(), field.name().c_str());
return; return;
} }
} }
...@@ -2991,18 +2993,18 @@ TIntermTyped *TParseContext::addIndexExpression(TIntermTyped *baseExpression, ...@@ -2991,18 +2993,18 @@ TIntermTyped *TParseContext::addIndexExpression(TIntermTyped *baseExpression,
{ {
if (baseExpression->isInterfaceBlock()) if (baseExpression->isInterfaceBlock())
{ {
error( error(location,
location, "", "[", "array indexes for interface blocks arrays must be constant integral expressions",
"array indexes for interface blocks arrays must be constant integral expressions"); "[");
} }
else if (baseExpression->getQualifier() == EvqFragmentOut) else if (baseExpression->getQualifier() == EvqFragmentOut)
{ {
error(location, "", "[", error(location,
"array indexes for fragment outputs must be constant integral expressions"); "array indexes for fragment outputs must be constant integral expressions", "[");
} }
else if (mShaderSpec == SH_WEBGL2_SPEC && baseExpression->getQualifier() == EvqFragData) else if (mShaderSpec == SH_WEBGL2_SPEC && baseExpression->getQualifier() == EvqFragData)
{ {
error(location, "", "[", "array index for gl_FragData must be constant zero"); error(location, "array index for gl_FragData must be constant zero", "[");
} }
} }
...@@ -3027,16 +3029,16 @@ TIntermTyped *TParseContext::addIndexExpression(TIntermTyped *baseExpression, ...@@ -3027,16 +3029,16 @@ TIntermTyped *TParseContext::addIndexExpression(TIntermTyped *baseExpression,
// Error has been already generated if index is not const. // Error has been already generated if index is not const.
if (indexExpression->getQualifier() == EvqConst) if (indexExpression->getQualifier() == EvqConst)
{ {
error(location, "", "[", error(location, "array index for gl_FragData must be constant zero", "[");
"array index for gl_FragData must be constant zero");
} }
safeIndex = 0; safeIndex = 0;
} }
else if (!isExtensionEnabled("GL_EXT_draw_buffers")) else if (!isExtensionEnabled("GL_EXT_draw_buffers"))
{ {
outOfRangeError(outOfRangeIndexIsError, location, "", "[", outOfRangeError(outOfRangeIndexIsError, location,
"array index for gl_FragData must be zero when " "array index for gl_FragData must be zero when "
"GL_EXT_draw_buffers is disabled"); "GL_EXT_draw_buffers is disabled",
"[");
safeIndex = 0; safeIndex = 0;
} }
} }
...@@ -3045,20 +3047,20 @@ TIntermTyped *TParseContext::addIndexExpression(TIntermTyped *baseExpression, ...@@ -3045,20 +3047,20 @@ TIntermTyped *TParseContext::addIndexExpression(TIntermTyped *baseExpression,
{ {
safeIndex = checkIndexOutOfRange(outOfRangeIndexIsError, location, index, safeIndex = checkIndexOutOfRange(outOfRangeIndexIsError, location, index,
baseExpression->getArraySize(), baseExpression->getArraySize(),
"array index out of range", "[]"); "array index out of range");
} }
} }
else if (baseExpression->isMatrix()) else if (baseExpression->isMatrix())
{ {
safeIndex = checkIndexOutOfRange(outOfRangeIndexIsError, location, index, safeIndex = checkIndexOutOfRange(outOfRangeIndexIsError, location, index,
baseExpression->getType().getCols(), baseExpression->getType().getCols(),
"matrix field selection out of range", "[]"); "matrix field selection out of range");
} }
else if (baseExpression->isVector()) else if (baseExpression->isVector())
{ {
safeIndex = checkIndexOutOfRange(outOfRangeIndexIsError, location, index, safeIndex = checkIndexOutOfRange(outOfRangeIndexIsError, location, index,
baseExpression->getType().getNominalSize(), baseExpression->getType().getNominalSize(),
"vector field selection out of range", "[]"); "vector field selection out of range");
} }
ASSERT(safeIndex >= 0); ASSERT(safeIndex >= 0);
...@@ -3086,15 +3088,14 @@ int TParseContext::checkIndexOutOfRange(bool outOfRangeIndexIsError, ...@@ -3086,15 +3088,14 @@ int TParseContext::checkIndexOutOfRange(bool outOfRangeIndexIsError,
const TSourceLoc &location, const TSourceLoc &location,
int index, int index,
int arraySize, int arraySize,
const char *reason, const char *reason)
const char *token)
{ {
if (index >= arraySize || index < 0) if (index >= arraySize || index < 0)
{ {
std::stringstream extraInfoStream; std::stringstream reasonStream;
extraInfoStream << "'" << index << "'"; reasonStream << reason << " '" << index << "'";
std::string extraInfo = extraInfoStream.str(); std::string token = reasonStream.str();
outOfRangeError(outOfRangeIndexIsError, location, reason, token, extraInfo.c_str()); outOfRangeError(outOfRangeIndexIsError, location, reason, "[]");
if (index < 0) if (index < 0)
{ {
return 0; return 0;
...@@ -3251,8 +3252,8 @@ TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierTyp ...@@ -3251,8 +3252,8 @@ TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierTyp
} }
else if (qualifierType == "location") else if (qualifierType == "location")
{ {
error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str(), error(qualifierTypeLine, "invalid layout qualifier: location requires an argument",
"location requires an argument"); qualifierType.c_str());
} }
else if (qualifierType == "rgba32f") else if (qualifierType == "rgba32f")
{ {
...@@ -3339,8 +3340,10 @@ void TParseContext::parseLocalSize(const TString &qualifierType, ...@@ -3339,8 +3340,10 @@ void TParseContext::parseLocalSize(const TString &qualifierType,
checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310); checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
if (intValue < 1) if (intValue < 1)
{ {
std::string errorMessage = std::string(getWorkGroupSizeString(index)) + " must be positive"; std::stringstream reasonStream;
error(intValueLine, "out of range:", intValueString.c_str(), errorMessage.c_str()); reasonStream << "out of range: " << getWorkGroupSizeString(index) << " must be positive";
std::string reason = reasonStream.str();
error(intValueLine, reason.c_str(), intValueString.c_str());
} }
(*localSize)[index] = intValue; (*localSize)[index] = intValue;
} }
...@@ -3359,8 +3362,8 @@ TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierTyp ...@@ -3359,8 +3362,8 @@ TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierTyp
// must check that location is non-negative // must check that location is non-negative
if (intValue < 0) if (intValue < 0)
{ {
error(intValueLine, "out of range:", intValueString.c_str(), error(intValueLine, "out of range: location must be non-negative",
"location must be non-negative"); intValueString.c_str());
} }
else else
{ {
...@@ -3406,6 +3409,24 @@ TLayoutQualifier TParseContext::joinLayoutQualifiers(TLayoutQualifier leftQualif ...@@ -3406,6 +3409,24 @@ TLayoutQualifier TParseContext::joinLayoutQualifiers(TLayoutQualifier leftQualif
&mDiagnostics); &mDiagnostics);
} }
TFieldList *TParseContext::combineStructFieldLists(TFieldList *processedFields,
const TFieldList *newlyAddedFields,
const TSourceLoc &location)
{
for (TField *field : *newlyAddedFields)
{
for (TField *oldField : *processedFields)
{
if (oldField->name() == field->name())
{
error(location, "duplicate field name in structure", field->name().c_str());
}
}
processedFields->push_back(field);
}
return processedFields;
}
TFieldList *TParseContext::addStructDeclaratorListWithQualifiers( TFieldList *TParseContext::addStructDeclaratorListWithQualifiers(
const TTypeQualifierBuilder &typeQualifierBuilder, const TTypeQualifierBuilder &typeQualifierBuilder,
TPublicType *typeSpecifier, TPublicType *typeSpecifier,
...@@ -3485,7 +3506,7 @@ TTypeSpecifierNonArray TParseContext::addStructure(const TSourceLoc &structLine, ...@@ -3485,7 +3506,7 @@ TTypeSpecifierNonArray TParseContext::addStructure(const TSourceLoc &structLine,
TVariable *userTypeDef = new TVariable(structName, *structureType, true); TVariable *userTypeDef = new TVariable(structName, *structureType, true);
if (!symbolTable.declare(userTypeDef)) if (!symbolTable.declare(userTypeDef))
{ {
error(nameLine, "redefinition", structName->c_str(), "struct"); error(nameLine, "redefinition of a struct", structName->c_str());
} }
} }
...@@ -4361,13 +4382,11 @@ TIntermTyped *TParseContext::addFunctionCallOrMethod(TFunction *fnCall, ...@@ -4361,13 +4382,11 @@ TIntermTyped *TParseContext::addFunctionCallOrMethod(TFunction *fnCall,
&fnCandidate->getReturnType()); &fnCandidate->getReturnType());
if (callNode == nullptr) if (callNode == nullptr)
{ {
std::stringstream extraInfoStream; std::stringstream reasonStream;
extraInfoStream reasonStream << "wrong operand type for built in unary function: "
<< "built in unary operator function. Type: " << static_cast<TIntermTyped *>(paramNode)->getCompleteString();
<< static_cast<TIntermTyped *>(paramNode)->getCompleteString(); std::string reason = reasonStream.str();
std::string extraInfo = extraInfoStream.str(); error(paramNode->getLine(), reason.c_str(), "Internal Error");
error(paramNode->getLine(), " wrong operand type", "Internal Error",
extraInfo.c_str());
*fatalError = true; *fatalError = true;
return nullptr; return nullptr;
} }
......
...@@ -50,21 +50,14 @@ class TParseContext : angle::NonCopyable ...@@ -50,21 +50,14 @@ class TParseContext : angle::NonCopyable
ShShaderSpec getShaderSpec() const { return mShaderSpec; } ShShaderSpec getShaderSpec() const { return mShaderSpec; }
int numErrors() const { return mDiagnostics.numErrors(); } int numErrors() const { return mDiagnostics.numErrors(); }
TInfoSink &infoSink() { return mDiagnostics.infoSink(); } TInfoSink &infoSink() { return mDiagnostics.infoSink(); }
void error(const TSourceLoc &loc, void error(const TSourceLoc &loc, const char *reason, const char *token);
const char *reason, void warning(const TSourceLoc &loc, const char *reason, const char *token);
const char *token,
const char *extraInfo = "");
void warning(const TSourceLoc &loc,
const char *reason,
const char *token,
const char *extraInfo = "");
// If isError is false, a warning will be reported instead. // If isError is false, a warning will be reported instead.
void outOfRangeError(bool isError, void outOfRangeError(bool isError,
const TSourceLoc &loc, const TSourceLoc &loc,
const char *reason, const char *reason,
const char *token, const char *token);
const char *extraInfo = "");
TIntermBlock *getTreeRoot() const { return mTreeRoot; } TIntermBlock *getTreeRoot() const { return mTreeRoot; }
void setTreeRoot(TIntermBlock *treeRoot) { mTreeRoot = treeRoot; } void setTreeRoot(TIntermBlock *treeRoot) { mTreeRoot = treeRoot; }
...@@ -273,6 +266,9 @@ class TParseContext : angle::NonCopyable ...@@ -273,6 +266,9 @@ class TParseContext : angle::NonCopyable
const TString &fieldString, const TString &fieldString,
const TSourceLoc &fieldLocation); const TSourceLoc &fieldLocation);
TFieldList *combineStructFieldLists(TFieldList *processedFields,
const TFieldList *newlyAddedFields,
const TSourceLoc &location);
TFieldList *addStructDeclaratorListWithQualifiers( TFieldList *addStructDeclaratorListWithQualifiers(
const TTypeQualifierBuilder &typeQualifierBuilder, const TTypeQualifierBuilder &typeQualifierBuilder,
TPublicType *typeSpecifier, TPublicType *typeSpecifier,
...@@ -362,13 +358,12 @@ class TParseContext : angle::NonCopyable ...@@ -362,13 +358,12 @@ class TParseContext : angle::NonCopyable
TSymbolTable &symbolTable; // symbol table that goes with the language currently being parsed TSymbolTable &symbolTable; // symbol table that goes with the language currently being parsed
private: private:
// Returns a clamped index. // Returns a clamped index. If it prints out an error message, the token is "[]".
int checkIndexOutOfRange(bool outOfRangeIndexIsError, int checkIndexOutOfRange(bool outOfRangeIndexIsError,
const TSourceLoc &location, const TSourceLoc &location,
int index, int index,
int arraySize, int arraySize,
const char *reason, const char *reason);
const char *token);
bool declareVariable(const TSourceLoc &line, bool declareVariable(const TSourceLoc &line,
const TString &identifier, const TString &identifier,
......
...@@ -476,7 +476,7 @@ TTypeQualifier GetVariableTypeQualifierFromSortedSequence( ...@@ -476,7 +476,7 @@ TTypeQualifier GetVariableTypeQualifierFromSortedSequence(
{ {
const TString &qualifierString = qualifier->getQualifierString(); const TString &qualifierString = qualifier->getQualifierString();
diagnostics->error(qualifier->getLine(), "invalid qualifier combination", diagnostics->error(qualifier->getLine(), "invalid qualifier combination",
qualifierString.c_str(), ""); qualifierString.c_str());
break; break;
} }
} }
...@@ -521,7 +521,7 @@ TTypeQualifier GetParameterTypeQualifierFromSortedSequence( ...@@ -521,7 +521,7 @@ TTypeQualifier GetParameterTypeQualifierFromSortedSequence(
{ {
const TString &qualifierString = qualifier->getQualifierString(); const TString &qualifierString = qualifier->getQualifierString();
diagnostics->error(qualifier->getLine(), "invalid parameter qualifier", diagnostics->error(qualifier->getLine(), "invalid parameter qualifier",
qualifierString.c_str(), ""); qualifierString.c_str());
break; break;
} }
} }
...@@ -542,7 +542,7 @@ TTypeQualifier GetParameterTypeQualifierFromSortedSequence( ...@@ -542,7 +542,7 @@ TTypeQualifier GetParameterTypeQualifierFromSortedSequence(
break; break;
default: default:
diagnostics->error(sortedSequence[0]->getLine(), "Invalid parameter qualifier ", diagnostics->error(sortedSequence[0]->getLine(), "Invalid parameter qualifier ",
getQualifierString(typeQualifier.qualifier), ""); getQualifierString(typeQualifier.qualifier));
} }
return typeQualifier; return typeQualifier;
} }
...@@ -578,7 +578,7 @@ TLayoutQualifier JoinLayoutQualifiers(TLayoutQualifier leftQualifier, ...@@ -578,7 +578,7 @@ TLayoutQualifier JoinLayoutQualifiers(TLayoutQualifier leftQualifier,
{ {
diagnostics->error(rightQualifierLocation, diagnostics->error(rightQualifierLocation,
"Cannot have multiple different work group size specifiers", "Cannot have multiple different work group size specifiers",
getWorkGroupSizeString(i), ""); getWorkGroupSizeString(i));
} }
joinedQualifier.localSize[i] = rightQualifier.localSize[i]; joinedQualifier.localSize[i] = rightQualifier.localSize[i];
} }
...@@ -661,15 +661,13 @@ bool TTypeQualifierBuilder::checkSequenceIsValid(TDiagnostics *diagnostics) cons ...@@ -661,15 +661,13 @@ bool TTypeQualifierBuilder::checkSequenceIsValid(TDiagnostics *diagnostics) cons
std::string errorMessage; std::string errorMessage;
if (HasRepeatingQualifiers(mQualifiers, areQualifierChecksRelaxed, &errorMessage)) if (HasRepeatingQualifiers(mQualifiers, areQualifierChecksRelaxed, &errorMessage))
{ {
diagnostics->error(mQualifiers[0]->getLine(), "qualifier sequence", errorMessage.c_str(), diagnostics->error(mQualifiers[0]->getLine(), errorMessage.c_str(), "qualifier sequence");
"");
return false; return false;
} }
if (!areQualifierChecksRelaxed && !AreQualifiersInOrder(mQualifiers, &errorMessage)) if (!areQualifierChecksRelaxed && !AreQualifiersInOrder(mQualifiers, &errorMessage))
{ {
diagnostics->error(mQualifiers[0]->getLine(), "qualifier sequence", errorMessage.c_str(), diagnostics->error(mQualifiers[0]->getLine(), errorMessage.c_str(), "qualifier sequence");
"");
return false; return false;
} }
......
...@@ -401,7 +401,7 @@ O [0-7] ...@@ -401,7 +401,7 @@ O [0-7]
} }
<FIELDS>[ \t\v\f\r] {} <FIELDS>[ \t\v\f\r] {}
<FIELDS>. { <FIELDS>. {
yyextra->error(*yylloc, "Illegal character at fieldname start", yytext, ""); yyextra->error(*yylloc, "Illegal character at fieldname start", yytext);
return 0; return 0;
} }
...@@ -445,7 +445,7 @@ int check_type(yyscan_t yyscanner) { ...@@ -445,7 +445,7 @@ int check_type(yyscan_t yyscanner) {
int reserved_word(yyscan_t yyscanner) { int reserved_word(yyscan_t yyscanner) {
struct yyguts_t* yyg = (struct yyguts_t*) yyscanner; struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
yyextra->error(*yylloc, "Illegal use of reserved word", yytext, ""); yyextra->error(*yylloc, "Illegal use of reserved word", yytext);
return 0; return 0;
} }
...@@ -539,12 +539,12 @@ int uint_constant(TParseContext *context) ...@@ -539,12 +539,12 @@ int uint_constant(TParseContext *context)
if (context->getShaderVersion() < 300) if (context->getShaderVersion() < 300)
{ {
context->error(*yylloc, "Unsigned integers are unsupported prior to GLSL ES 3.00", yytext, ""); context->error(*yylloc, "Unsigned integers are unsupported prior to GLSL ES 3.00", yytext);
return 0; return 0;
} }
if (!atoi_clamp(yytext, &(yylval->lex.u))) if (!atoi_clamp(yytext, &(yylval->lex.u)))
yyextra->error(*yylloc, "Integer overflow", yytext, ""); yyextra->error(*yylloc, "Integer overflow", yytext);
return UINTCONSTANT; return UINTCONSTANT;
} }
...@@ -562,7 +562,7 @@ int floatsuffix_check(TParseContext* context) ...@@ -562,7 +562,7 @@ int floatsuffix_check(TParseContext* context)
std::string text = yytext; std::string text = yytext;
text.resize(text.size() - 1); text.resize(text.size() - 1);
if (!strtof_clamp(text, &(yylval->lex.f))) if (!strtof_clamp(text, &(yylval->lex.f)))
yyextra->warning(*yylloc, "Float overflow", yytext, ""); yyextra->warning(*yylloc, "Float overflow", yytext);
return(FLOATCONSTANT); return(FLOATCONSTANT);
} }
...@@ -578,9 +578,9 @@ int int_constant(TParseContext *context) { ...@@ -578,9 +578,9 @@ int int_constant(TParseContext *context) {
if (!atoi_clamp(yytext, &u)) if (!atoi_clamp(yytext, &u))
{ {
if (context->getShaderVersion() >= 300) if (context->getShaderVersion() >= 300)
yyextra->error(*yylloc, "Integer overflow", yytext, ""); yyextra->error(*yylloc, "Integer overflow", yytext);
else else
yyextra->warning(*yylloc, "Integer overflow", yytext, ""); yyextra->warning(*yylloc, "Integer overflow", yytext);
} }
yylval->lex.i = static_cast<int>(u); yylval->lex.i = static_cast<int>(u);
return INTCONSTANT; return INTCONSTANT;
...@@ -590,7 +590,7 @@ int float_constant(yyscan_t yyscanner) { ...@@ -590,7 +590,7 @@ int float_constant(yyscan_t yyscanner) {
struct yyguts_t* yyg = (struct yyguts_t*) yyscanner; struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
if (!strtof_clamp(yytext, &(yylval->lex.f))) if (!strtof_clamp(yytext, &(yylval->lex.f)))
yyextra->warning(*yylloc, "Float overflow", yytext, ""); yyextra->warning(*yylloc, "Float overflow", yytext);
return FLOATCONSTANT; return FLOATCONSTANT;
} }
......
...@@ -932,7 +932,7 @@ storage_qualifier ...@@ -932,7 +932,7 @@ storage_qualifier
| INOUT_QUAL { | INOUT_QUAL {
if (!context->declaringFunction()) if (!context->declaringFunction())
{ {
context->error(@1, "invalid inout qualifier", "'inout' can be only used with function parameters"); context->error(@1, "invalid qualifier: can be only used with function parameters", "inout");
} }
$$ = new TStorageQualifierWrapper(EvqInOut, @1); $$ = new TStorageQualifierWrapper(EvqInOut, @1);
} }
...@@ -1257,16 +1257,7 @@ struct_declaration_list ...@@ -1257,16 +1257,7 @@ struct_declaration_list
$$ = $1; $$ = $1;
} }
| struct_declaration_list struct_declaration { | struct_declaration_list struct_declaration {
$$ = $1; $$ = context->combineStructFieldLists($1, $2, @2);
for (size_t i = 0; i < $2->size(); ++i) {
TField* field = (*$2)[i];
for (size_t j = 0; j < $$->size(); ++j) {
if ((*$$)[j]->name() == field->name()) {
context->error(@2, "duplicate field name in structure:", "struct", field->name().c_str());
}
}
$$->push_back(field);
}
} }
; ;
......
#line 17 "./glslang.l"
// //
// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved. // Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
...@@ -221,7 +222,7 @@ typedef size_t yy_size_t; ...@@ -221,7 +222,7 @@ typedef size_t yy_size_t;
#define YY_LESS_LINENO(n) \ #define YY_LESS_LINENO(n) \
do { \ do { \
yy_size_t yyl;\ yy_size_t yyl;\
for ( yyl = n; yyl < static_cast<yy_site_t>(yyleng); ++yyl )\ for ( yyl = n; yyl < yyleng; ++yyl )\
if ( yytext[yyl] == '\n' )\ if ( yytext[yyl] == '\n' )\
--yylineno;\ --yylineno;\
}while(0) }while(0)
...@@ -396,7 +397,7 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); ...@@ -396,7 +397,7 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
*/ */
#define YY_DO_BEFORE_ACTION \ #define YY_DO_BEFORE_ACTION \
yyg->yytext_ptr = yy_bp; \ yyg->yytext_ptr = yy_bp; \
yyleng = (size_t) (yy_cp - yy_bp); \ yyleng = (yy_size_t) (yy_cp - yy_bp); \
yyg->yy_hold_char = *yy_cp; \ yyg->yy_hold_char = *yy_cp; \
*yy_cp = '\0'; \ *yy_cp = '\0'; \
yyg->yy_c_buf_p = yy_cp; yyg->yy_c_buf_p = yy_cp;
...@@ -1380,7 +1381,7 @@ yy_find_action: ...@@ -1380,7 +1381,7 @@ yy_find_action:
if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] ) if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] )
{ {
yy_size_t yyl; yy_size_t yyl;
for ( yyl = 0; yyl < static_cast<yy_size_t>(yyleng); ++yyl ) for ( yyl = 0; yyl < yyleng; ++yyl )
if ( yytext[yyl] == '\n' ) if ( yytext[yyl] == '\n' )
do{ yylineno++; do{ yylineno++;
...@@ -2141,7 +2142,7 @@ YY_RULE_SETUP ...@@ -2141,7 +2142,7 @@ YY_RULE_SETUP
case 238: case 238:
YY_RULE_SETUP YY_RULE_SETUP
{ {
yyextra->error(*yylloc, "Illegal character at fieldname start", yytext, ""); yyextra->error(*yylloc, "Illegal character at fieldname start", yytext);
return 0; return 0;
} }
YY_BREAK YY_BREAK
...@@ -2384,7 +2385,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) ...@@ -2384,7 +2385,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
static_cast<int>(number_to_move) - 1; number_to_move - 1;
} }
...@@ -2392,10 +2393,8 @@ static int yy_get_next_buffer (yyscan_t yyscanner) ...@@ -2392,10 +2393,8 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
num_to_read = YY_READ_BUF_SIZE; num_to_read = YY_READ_BUF_SIZE;
/* Read in more data. */ /* Read in more data. */
size_t result = 0;
YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
result, num_to_read ); yyg->yy_n_chars, num_to_read );
yyg->yy_n_chars = static_cast<int>(result);
YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
} }
...@@ -2836,7 +2835,7 @@ static void yyensure_buffer_stack (yyscan_t yyscanner) ...@@ -2836,7 +2835,7 @@ static void yyensure_buffer_stack (yyscan_t yyscanner)
/* Increase the buffer to prepare for a possible push. */ /* Increase the buffer to prepare for a possible push. */
int grow_size = 8 /* arbitrary grow size */; int grow_size = 8 /* arbitrary grow size */;
num_to_alloc = static_cast<int>(yyg->yy_buffer_stack_max + grow_size); num_to_alloc = yyg->yy_buffer_stack_max + grow_size;
yyg->yy_buffer_stack = (struct yy_buffer_state**)yyrealloc yyg->yy_buffer_stack = (struct yy_buffer_state**)yyrealloc
(yyg->yy_buffer_stack, (yyg->yy_buffer_stack,
num_to_alloc * sizeof(struct yy_buffer_state*) num_to_alloc * sizeof(struct yy_buffer_state*)
...@@ -2870,7 +2869,7 @@ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscann ...@@ -2870,7 +2869,7 @@ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscann
if ( ! b ) if ( ! b )
YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
b->yy_buf_size = static_cast<int>(size) - 2; /* "- 2" to take care of EOB's */ b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
b->yy_buf_pos = b->yy_ch_buf = base; b->yy_buf_pos = b->yy_ch_buf = base;
b->yy_is_our_buffer = 0; b->yy_is_our_buffer = 0;
b->yy_input_file = 0; b->yy_input_file = 0;
...@@ -2919,7 +2918,7 @@ YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len ...@@ -2919,7 +2918,7 @@ YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len
if ( ! buf ) if ( ! buf )
YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
for ( i = 0; i < static_cast<yy_size_t>(_yybytes_len); ++i ) for ( i = 0; i < _yybytes_len; ++i )
buf[i] = yybytes[i]; buf[i] = yybytes[i];
buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
...@@ -3342,7 +3341,7 @@ int check_type(yyscan_t yyscanner) { ...@@ -3342,7 +3341,7 @@ int check_type(yyscan_t yyscanner) {
int reserved_word(yyscan_t yyscanner) { int reserved_word(yyscan_t yyscanner) {
struct yyguts_t* yyg = (struct yyguts_t*) yyscanner; struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
yyextra->error(*yylloc, "Illegal use of reserved word", yytext, ""); yyextra->error(*yylloc, "Illegal use of reserved word", yytext);
return 0; return 0;
} }
...@@ -3436,12 +3435,12 @@ int uint_constant(TParseContext *context) ...@@ -3436,12 +3435,12 @@ int uint_constant(TParseContext *context)
if (context->getShaderVersion() < 300) if (context->getShaderVersion() < 300)
{ {
context->error(*yylloc, "Unsigned integers are unsupported prior to GLSL ES 3.00", yytext, ""); context->error(*yylloc, "Unsigned integers are unsupported prior to GLSL ES 3.00", yytext);
return 0; return 0;
} }
if (!atoi_clamp(yytext, &(yylval->lex.u))) if (!atoi_clamp(yytext, &(yylval->lex.u)))
yyextra->error(*yylloc, "Integer overflow", yytext, ""); yyextra->error(*yylloc, "Integer overflow", yytext);
return UINTCONSTANT; return UINTCONSTANT;
} }
...@@ -3459,7 +3458,7 @@ int floatsuffix_check(TParseContext* context) ...@@ -3459,7 +3458,7 @@ int floatsuffix_check(TParseContext* context)
std::string text = yytext; std::string text = yytext;
text.resize(text.size() - 1); text.resize(text.size() - 1);
if (!strtof_clamp(text, &(yylval->lex.f))) if (!strtof_clamp(text, &(yylval->lex.f)))
yyextra->warning(*yylloc, "Float overflow", yytext, ""); yyextra->warning(*yylloc, "Float overflow", yytext);
return(FLOATCONSTANT); return(FLOATCONSTANT);
} }
...@@ -3475,9 +3474,9 @@ int int_constant(TParseContext *context) { ...@@ -3475,9 +3474,9 @@ int int_constant(TParseContext *context) {
if (!atoi_clamp(yytext, &u)) if (!atoi_clamp(yytext, &u))
{ {
if (context->getShaderVersion() >= 300) if (context->getShaderVersion() >= 300)
yyextra->error(*yylloc, "Integer overflow", yytext, ""); yyextra->error(*yylloc, "Integer overflow", yytext);
else else
yyextra->warning(*yylloc, "Integer overflow", yytext, ""); yyextra->warning(*yylloc, "Integer overflow", yytext);
} }
yylval->lex.i = static_cast<int>(u); yylval->lex.i = static_cast<int>(u);
return INTCONSTANT; return INTCONSTANT;
...@@ -3487,7 +3486,7 @@ int float_constant(yyscan_t yyscanner) { ...@@ -3487,7 +3486,7 @@ int float_constant(yyscan_t yyscanner) {
struct yyguts_t* yyg = (struct yyguts_t*) yyscanner; struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
if (!strtof_clamp(yytext, &(yylval->lex.f))) if (!strtof_clamp(yytext, &(yylval->lex.f)))
yyextra->warning(*yylloc, "Float overflow", yytext, ""); yyextra->warning(*yylloc, "Float overflow", yytext);
return FLOATCONSTANT; return FLOATCONSTANT;
} }
......
...@@ -755,13 +755,13 @@ static const yytype_uint16 yyrline[] = ...@@ -755,13 +755,13 @@ static const yytype_uint16 yyrline[] =
1147, 1150, 1153, 1156, 1159, 1162, 1165, 1168, 1171, 1174, 1147, 1150, 1153, 1156, 1159, 1162, 1165, 1168, 1171, 1174,
1177, 1180, 1183, 1190, 1196, 1199, 1202, 1205, 1208, 1211, 1177, 1180, 1183, 1190, 1196, 1199, 1202, 1205, 1208, 1211,
1214, 1217, 1220, 1223, 1226, 1229, 1232, 1235, 1247, 1247, 1214, 1217, 1220, 1223, 1226, 1229, 1232, 1235, 1247, 1247,
1250, 1250, 1256, 1259, 1274, 1277, 1284, 1288, 1294, 1300, 1250, 1250, 1256, 1259, 1265, 1268, 1275, 1279, 1285, 1291,
1312, 1316, 1320, 1321, 1327, 1328, 1329, 1330, 1331, 1332, 1303, 1307, 1311, 1312, 1318, 1319, 1320, 1321, 1322, 1323,
1333, 1337, 1338, 1338, 1338, 1347, 1348, 1352, 1352, 1353, 1324, 1328, 1329, 1329, 1329, 1338, 1339, 1343, 1343, 1344,
1353, 1358, 1361, 1370, 1375, 1382, 1383, 1387, 1394, 1398, 1344, 1349, 1352, 1361, 1366, 1373, 1374, 1378, 1385, 1389,
1405, 1405, 1412, 1415, 1422, 1426, 1439, 1439, 1444, 1444, 1396, 1396, 1403, 1406, 1413, 1417, 1430, 1430, 1435, 1435,
1450, 1450, 1458, 1461, 1467, 1470, 1476, 1480, 1487, 1490, 1441, 1441, 1449, 1452, 1458, 1461, 1467, 1471, 1478, 1481,
1493, 1496, 1499, 1508, 1514, 1520, 1523, 1529, 1529 1484, 1487, 1490, 1499, 1505, 1511, 1514, 1520, 1520
}; };
#endif #endif
...@@ -3677,7 +3677,7 @@ yyreduce: ...@@ -3677,7 +3677,7 @@ yyreduce:
{ {
if (!context->declaringFunction()) if (!context->declaringFunction())
{ {
context->error((yylsp[0]), "invalid inout qualifier", "'inout' can be only used with function parameters"); context->error((yylsp[0]), "invalid qualifier: can be only used with function parameters", "inout");
} }
(yyval.interm.qualifierWrapper) = new TStorageQualifierWrapper(EvqInOut, (yylsp[0])); (yyval.interm.qualifierWrapper) = new TStorageQualifierWrapper(EvqInOut, (yylsp[0]));
} }
...@@ -4402,16 +4402,7 @@ yyreduce: ...@@ -4402,16 +4402,7 @@ yyreduce:
case 223: case 223:
{ {
(yyval.interm.fieldList) = (yyvsp[-1].interm.fieldList); (yyval.interm.fieldList) = context->combineStructFieldLists((yyvsp[-1].interm.fieldList), (yyvsp[0].interm.fieldList), (yylsp[0]));
for (size_t i = 0; i < (yyvsp[0].interm.fieldList)->size(); ++i) {
TField* field = (*(yyvsp[0].interm.fieldList))[i];
for (size_t j = 0; j < (yyval.interm.fieldList)->size(); ++j) {
if ((*(yyval.interm.fieldList))[j]->name() == field->name()) {
context->error((yylsp[0]), "duplicate field name in structure:", "struct", field->name().c_str());
}
}
(yyval.interm.fieldList)->push_back(field);
}
} }
break; break;
......
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