Commit 1397dd35 by alokp@chromium.org

Refactor location tracking.

R=kbr@chromium.org Review URL: https://codereview.appspot.com/9078046 git-svn-id: https://angleproject.googlecode.com/svn/trunk@2202 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent ebc93e08
...@@ -14,24 +14,12 @@ ...@@ -14,24 +14,12 @@
#include "compiler/PoolAlloc.h" #include "compiler/PoolAlloc.h"
// We need two pieces of information to report errors/warnings - string and struct TSourceLoc {
// line number. We encode these into a single int so that it can be easily int first_file;
// incremented/decremented by lexer. The right SOURCE_LOC_LINE_SIZE bits store int first_line;
// line number while the rest store the string number. Since the shaders are int last_file;
// usually small, we should not run out of memory. SOURCE_LOC_LINE_SIZE int last_line;
// can be increased to alleviate this issue. };
typedef int TSourceLoc;
const unsigned int SOURCE_LOC_LINE_SIZE = 16; // in bits.
const unsigned int SOURCE_LOC_LINE_MASK = (1 << SOURCE_LOC_LINE_SIZE) - 1;
inline TSourceLoc EncodeSourceLoc(int string, int line) {
return (string << SOURCE_LOC_LINE_SIZE) | (line & SOURCE_LOC_LINE_MASK);
}
inline void DecodeSourceLoc(TSourceLoc loc, int* string, int* line) {
if (string) *string = loc >> SOURCE_LOC_LINE_SIZE;
if (line) *line = loc & SOURCE_LOC_LINE_MASK;
}
// //
// Put POOL_ALLOCATOR_NEW_DELETE in base classes to make them use this scheme. // Put POOL_ALLOCATOR_NEW_DELETE in base classes to make them use this scheme.
......
...@@ -62,7 +62,8 @@ bool InitializeSymbolTable( ...@@ -62,7 +62,8 @@ bool InitializeSymbolTable(
if (PaParseStrings(1, &builtInShaders, &builtInLengths, &parseContext) != 0) if (PaParseStrings(1, &builtInShaders, &builtInLengths, &parseContext) != 0)
{ {
infoSink.info.message(EPrefixInternalError, "Unable to parse built-ins"); infoSink.info.prefix(EPrefixInternalError);
infoSink.info << "Unable to parse built-ins";
return false; return false;
} }
} }
...@@ -170,8 +171,10 @@ bool TCompiler::compile(const char* const shaderStrings[], ...@@ -170,8 +171,10 @@ bool TCompiler::compile(const char* const shaderStrings[],
// We preserve symbols at the built-in level from compile-to-compile. // We preserve symbols at the built-in level from compile-to-compile.
// Start pushing the user-defined symbols at global level. // Start pushing the user-defined symbols at global level.
symbolTable.push(); symbolTable.push();
if (!symbolTable.atGlobalLevel()) if (!symbolTable.atGlobalLevel()) {
infoSink.info.message(EPrefixInternalError, "Wrong symbol table level"); infoSink.info.prefix(EPrefixInternalError);
infoSink.info << "Wrong symbol table level";
}
// Parse shader. // Parse shader.
bool success = bool success =
...@@ -217,7 +220,8 @@ bool TCompiler::compile(const char* const shaderStrings[], ...@@ -217,7 +220,8 @@ bool TCompiler::compile(const char* const shaderStrings[],
if (compileOptions & SH_ENFORCE_PACKING_RESTRICTIONS) { if (compileOptions & SH_ENFORCE_PACKING_RESTRICTIONS) {
success = enforcePackingRestrictions(); success = enforcePackingRestrictions();
if (!success) { if (!success) {
infoSink.info.message(EPrefixError, "too many uniforms"); infoSink.info.prefix(EPrefixError);
infoSink.info << "too many uniforms";
} }
} }
} }
...@@ -271,10 +275,12 @@ bool TCompiler::detectRecursion(TIntermNode* root) ...@@ -271,10 +275,12 @@ bool TCompiler::detectRecursion(TIntermNode* root)
case DetectRecursion::kErrorNone: case DetectRecursion::kErrorNone:
return true; return true;
case DetectRecursion::kErrorMissingMain: case DetectRecursion::kErrorMissingMain:
infoSink.info.message(EPrefixError, "Missing main()"); infoSink.info.prefix(EPrefixError);
infoSink.info << "Missing main()";
return false; return false;
case DetectRecursion::kErrorRecursion: case DetectRecursion::kErrorRecursion:
infoSink.info.message(EPrefixError, "Function recursion detected"); infoSink.info.prefix(EPrefixError);
infoSink.info << "Function recursion detected";
return false; return false;
default: default:
UNREACHABLE(); UNREACHABLE();
......
...@@ -46,7 +46,7 @@ void TDiagnostics::writeInfo(Severity severity, ...@@ -46,7 +46,7 @@ void TDiagnostics::writeInfo(Severity severity,
TInfoSinkBase& sink = mInfoSink.info; TInfoSinkBase& sink = mInfoSink.info;
/* VC++ format: file(linenum) : error #: 'token' : extrainfo */ /* VC++ format: file(linenum) : error #: 'token' : extrainfo */
sink.prefix(prefix); sink.prefix(prefix);
sink.location(EncodeSourceLoc(loc.file, loc.line)); sink.location(loc.file, loc.line);
sink << "'" << token << "' : " << reason << " " << extra << "\n"; sink << "'" << token << "' : " << reason << " " << extra << "\n";
} }
......
...@@ -6,8 +6,8 @@ ...@@ -6,8 +6,8 @@
#include "compiler/InfoSink.h" #include "compiler/InfoSink.h"
void TInfoSinkBase::prefix(TPrefixType message) { void TInfoSinkBase::prefix(TPrefixType p) {
switch(message) { switch(p) {
case EPrefixNone: case EPrefixNone:
break; break;
case EPrefixWarning: case EPrefixWarning:
...@@ -31,29 +31,24 @@ void TInfoSinkBase::prefix(TPrefixType message) { ...@@ -31,29 +31,24 @@ void TInfoSinkBase::prefix(TPrefixType message) {
} }
} }
void TInfoSinkBase::location(TSourceLoc loc) { void TInfoSinkBase::location(int file, int line) {
int string = 0, line = 0;
DecodeSourceLoc(loc, &string, &line);
TPersistStringStream stream; TPersistStringStream stream;
if (line) if (line)
stream << string << ":" << line; stream << file << ":" << line;
else else
stream << string << ":? "; stream << file << ":? ";
stream << ": "; stream << ": ";
sink.append(stream.str()); sink.append(stream.str());
} }
void TInfoSinkBase::message(TPrefixType message, const char* s) { void TInfoSinkBase::location(const TSourceLoc& loc) {
prefix(message); location(loc.first_file, loc.first_line);
sink.append(s);
sink.append("\n");
} }
void TInfoSinkBase::message(TPrefixType message, const char* s, TSourceLoc loc) { void TInfoSinkBase::message(TPrefixType p, const TSourceLoc& loc, const char* m) {
prefix(message); prefix(p);
location(loc); location(loc);
sink.append(s); sink.append(m);
sink.append("\n"); sink.append("\n");
} }
...@@ -96,10 +96,10 @@ public: ...@@ -96,10 +96,10 @@ public:
const TPersistString& str() const { return sink; } const TPersistString& str() const { return sink; }
const char* c_str() const { return sink.c_str(); } const char* c_str() const { return sink.c_str(); }
void prefix(TPrefixType message); void prefix(TPrefixType p);
void location(TSourceLoc loc); void location(int file, int line);
void message(TPrefixType message, const char* s); void location(const TSourceLoc& loc);
void message(TPrefixType message, const char* s, TSourceLoc loc); void message(TPrefixType p, const TSourceLoc& loc, const char* m);
private: private:
TPersistString sink; TPersistString sink;
......
...@@ -131,7 +131,7 @@ const char* getOperatorString(TOperator op) { ...@@ -131,7 +131,7 @@ const char* getOperatorString(TOperator op) {
// //
// Returns the added node. // Returns the added node.
// //
TIntermSymbol* TIntermediate::addSymbol(int id, const TString& name, const TType& type, TSourceLoc line) TIntermSymbol* TIntermediate::addSymbol(int id, const TString& name, const TType& type, const TSourceLoc& line)
{ {
TIntermSymbol* node = new TIntermSymbol(id, name, type); TIntermSymbol* node = new TIntermSymbol(id, name, type);
node->setLine(line); node->setLine(line);
...@@ -144,7 +144,7 @@ TIntermSymbol* TIntermediate::addSymbol(int id, const TString& name, const TType ...@@ -144,7 +144,7 @@ TIntermSymbol* TIntermediate::addSymbol(int id, const TString& name, const TType
// //
// Returns the added node. // Returns the added node.
// //
TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc line, TSymbolTable& symbolTable) TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc& line, TSymbolTable& symbolTable)
{ {
switch (op) { switch (op) {
case EOpEqual: case EOpEqual:
...@@ -200,8 +200,6 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn ...@@ -200,8 +200,6 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
// one and promote it to the right type. // one and promote it to the right type.
// //
TIntermBinary* node = new TIntermBinary(op); TIntermBinary* node = new TIntermBinary(op);
if (line == 0)
line = right->getLine();
node->setLine(line); node->setLine(line);
node->setLeft(left); node->setLeft(left);
...@@ -230,15 +228,13 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn ...@@ -230,15 +228,13 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
// //
// Returns the added node. // Returns the added node.
// //
TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc line) TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc& line)
{ {
// //
// Like adding binary math, except the conversion can only go // Like adding binary math, except the conversion can only go
// from right to left. // from right to left.
// //
TIntermBinary* node = new TIntermBinary(op); TIntermBinary* node = new TIntermBinary(op);
if (line == 0)
line = left->getLine();
node->setLine(line); node->setLine(line);
TIntermTyped* child = addConversion(op, left->getType(), right); TIntermTyped* child = addConversion(op, left->getType(), right);
...@@ -260,11 +256,9 @@ TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TInterm ...@@ -260,11 +256,9 @@ TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TInterm
// Returns the added node. // Returns the added node.
// The caller should set the type of the returned node. // The caller should set the type of the returned node.
// //
TIntermTyped* TIntermediate::addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc line) TIntermTyped* TIntermediate::addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, const TSourceLoc& line)
{ {
TIntermBinary* node = new TIntermBinary(op); TIntermBinary* node = new TIntermBinary(op);
if (line == 0)
line = index->getLine();
node->setLine(line); node->setLine(line);
node->setLeft(base); node->setLeft(base);
node->setRight(index); node->setRight(index);
...@@ -279,13 +273,13 @@ TIntermTyped* TIntermediate::addIndex(TOperator op, TIntermTyped* base, TIntermT ...@@ -279,13 +273,13 @@ TIntermTyped* TIntermediate::addIndex(TOperator op, TIntermTyped* base, TIntermT
// //
// Returns the added node. // Returns the added node.
// //
TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode, TSourceLoc line, TSymbolTable& symbolTable) TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode, const TSourceLoc& line, TSymbolTable& symbolTable)
{ {
TIntermUnary* node; TIntermUnary* node;
TIntermTyped* child = childNode->getAsTyped(); TIntermTyped* child = childNode->getAsTyped();
if (child == 0) { if (child == 0) {
infoSink.info.message(EPrefixInternalError, "Bad type in AddUnaryMath", line); infoSink.info.message(EPrefixInternalError, line, "Bad type in AddUnaryMath");
return 0; return 0;
} }
...@@ -348,8 +342,6 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode, ...@@ -348,8 +342,6 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode,
// Make a new node for the operator. // Make a new node for the operator.
// //
node = new TIntermUnary(op); node = new TIntermUnary(op);
if (line == 0)
line = child->getLine();
node->setLine(line); node->setLine(line);
node->setOperand(child); node->setOperand(child);
...@@ -376,7 +368,7 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode, ...@@ -376,7 +368,7 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode,
// Returns an aggregate node, which could be the one passed in if // Returns an aggregate node, which could be the one passed in if
// it was already an aggregate but no operator was set. // it was already an aggregate but no operator was set.
// //
TIntermAggregate* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator op, TSourceLoc line) TIntermAggregate* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator op, const TSourceLoc& line)
{ {
TIntermAggregate* aggNode; TIntermAggregate* aggNode;
...@@ -391,8 +383,6 @@ TIntermAggregate* TIntermediate::setAggregateOperator(TIntermNode* node, TOperat ...@@ -391,8 +383,6 @@ TIntermAggregate* TIntermediate::setAggregateOperator(TIntermNode* node, TOperat
// //
aggNode = new TIntermAggregate(); aggNode = new TIntermAggregate();
aggNode->getSequence().push_back(node); aggNode->getSequence().push_back(node);
if (line == 0)
line = node->getLine();
} }
} else } else
aggNode = new TIntermAggregate(); aggNode = new TIntermAggregate();
...@@ -401,7 +391,6 @@ TIntermAggregate* TIntermediate::setAggregateOperator(TIntermNode* node, TOperat ...@@ -401,7 +391,6 @@ TIntermAggregate* TIntermediate::setAggregateOperator(TIntermNode* node, TOperat
// Set the operator. // Set the operator.
// //
aggNode->setOp(op); aggNode->setOp(op);
if (line != 0)
aggNode->setLine(line); aggNode->setLine(line);
return aggNode; return aggNode;
...@@ -491,7 +480,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt ...@@ -491,7 +480,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
case EbtInt: newOp = EOpConvIntToFloat; break; case EbtInt: newOp = EOpConvIntToFloat; break;
case EbtBool: newOp = EOpConvBoolToFloat; break; case EbtBool: newOp = EOpConvBoolToFloat; break;
default: default:
infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine()); infoSink.info.message(EPrefixInternalError, node->getLine(), "Bad promotion node");
return 0; return 0;
} }
break; break;
...@@ -500,7 +489,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt ...@@ -500,7 +489,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
case EbtInt: newOp = EOpConvIntToBool; break; case EbtInt: newOp = EOpConvIntToBool; break;
case EbtFloat: newOp = EOpConvFloatToBool; break; case EbtFloat: newOp = EOpConvFloatToBool; break;
default: default:
infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine()); infoSink.info.message(EPrefixInternalError, node->getLine(), "Bad promotion node");
return 0; return 0;
} }
break; break;
...@@ -509,12 +498,12 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt ...@@ -509,12 +498,12 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
case EbtBool: newOp = EOpConvBoolToInt; break; case EbtBool: newOp = EOpConvBoolToInt; break;
case EbtFloat: newOp = EOpConvFloatToInt; break; case EbtFloat: newOp = EOpConvFloatToInt; break;
default: default:
infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine()); infoSink.info.message(EPrefixInternalError, node->getLine(), "Bad promotion node");
return 0; return 0;
} }
break; break;
default: default:
infoSink.info.message(EPrefixInternalError, "Bad promotion type", node->getLine()); infoSink.info.message(EPrefixInternalError, node->getLine(), "Bad promotion type");
return 0; return 0;
} }
...@@ -534,7 +523,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt ...@@ -534,7 +523,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
// Returns the resulting aggregate, unless 0 was passed in for // Returns the resulting aggregate, unless 0 was passed in for
// both existing nodes. // both existing nodes.
// //
TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* right, TSourceLoc line) TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* right, const TSourceLoc& line)
{ {
if (left == 0 && right == 0) if (left == 0 && right == 0)
return 0; return 0;
...@@ -551,7 +540,6 @@ TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* r ...@@ -551,7 +540,6 @@ TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* r
if (right) if (right)
aggNode->getSequence().push_back(right); aggNode->getSequence().push_back(right);
if (line != 0)
aggNode->setLine(line); aggNode->setLine(line);
return aggNode; return aggNode;
...@@ -562,18 +550,14 @@ TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* r ...@@ -562,18 +550,14 @@ TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* r
// //
// Returns an aggregate, unless 0 was passed in for the existing node. // Returns an aggregate, unless 0 was passed in for the existing node.
// //
TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node, TSourceLoc line) TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node, const TSourceLoc& line)
{ {
if (node == 0) if (node == 0)
return 0; return 0;
TIntermAggregate* aggNode = new TIntermAggregate; TIntermAggregate* aggNode = new TIntermAggregate;
aggNode->getSequence().push_back(node); aggNode->getSequence().push_back(node);
if (line != 0)
aggNode->setLine(line); aggNode->setLine(line);
else
aggNode->setLine(node->getLine());
return aggNode; return aggNode;
} }
...@@ -585,7 +569,7 @@ TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node, TSourceLoc lin ...@@ -585,7 +569,7 @@ TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node, TSourceLoc lin
// //
// Returns the selection node created. // Returns the selection node created.
// //
TIntermNode* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nodePair, TSourceLoc line) TIntermNode* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nodePair, const TSourceLoc& line)
{ {
// //
// For compile time constant selections, prune the code and // For compile time constant selections, prune the code and
...@@ -606,7 +590,7 @@ TIntermNode* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nod ...@@ -606,7 +590,7 @@ TIntermNode* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nod
} }
TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, TSourceLoc line) TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, const TSourceLoc& line)
{ {
if (left->getType().getQualifier() == EvqConst && right->getType().getQualifier() == EvqConst) { if (left->getType().getQualifier() == EvqConst && right->getType().getQualifier() == EvqConst) {
return right; return right;
...@@ -626,7 +610,7 @@ TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, T ...@@ -626,7 +610,7 @@ TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, T
// //
// Returns the selection node created, or 0 if one could not be. // Returns the selection node created, or 0 if one could not be.
// //
TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, TSourceLoc line) TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc& line)
{ {
// //
// Get compatible types. // Get compatible types.
...@@ -669,7 +653,7 @@ TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* true ...@@ -669,7 +653,7 @@ TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* true
// Returns the constant union node created. // Returns the constant union node created.
// //
TIntermConstantUnion* TIntermediate::addConstantUnion(ConstantUnion* unionArrayPointer, const TType& t, TSourceLoc line) TIntermConstantUnion* TIntermediate::addConstantUnion(ConstantUnion* unionArrayPointer, const TType& t, const TSourceLoc& line)
{ {
TIntermConstantUnion* node = new TIntermConstantUnion(unionArrayPointer, t); TIntermConstantUnion* node = new TIntermConstantUnion(unionArrayPointer, t);
node->setLine(line); node->setLine(line);
...@@ -677,7 +661,7 @@ TIntermConstantUnion* TIntermediate::addConstantUnion(ConstantUnion* unionArrayP ...@@ -677,7 +661,7 @@ TIntermConstantUnion* TIntermediate::addConstantUnion(ConstantUnion* unionArrayP
return node; return node;
} }
TIntermTyped* TIntermediate::addSwizzle(TVectorFields& fields, TSourceLoc line) TIntermTyped* TIntermediate::addSwizzle(TVectorFields& fields, const TSourceLoc& line)
{ {
TIntermAggregate* node = new TIntermAggregate(EOpSequence); TIntermAggregate* node = new TIntermAggregate(EOpSequence);
...@@ -700,7 +684,7 @@ TIntermTyped* TIntermediate::addSwizzle(TVectorFields& fields, TSourceLoc line) ...@@ -700,7 +684,7 @@ TIntermTyped* TIntermediate::addSwizzle(TVectorFields& fields, TSourceLoc line)
// //
// Create loop nodes. // Create loop nodes.
// //
TIntermNode* TIntermediate::addLoop(TLoopType type, TIntermNode* init, TIntermTyped* cond, TIntermTyped* expr, TIntermNode* body, TSourceLoc line) TIntermNode* TIntermediate::addLoop(TLoopType type, TIntermNode* init, TIntermTyped* cond, TIntermTyped* expr, TIntermNode* body, const TSourceLoc& line)
{ {
TIntermNode* node = new TIntermLoop(type, init, cond, expr, body); TIntermNode* node = new TIntermLoop(type, init, cond, expr, body);
node->setLine(line); node->setLine(line);
...@@ -711,12 +695,12 @@ TIntermNode* TIntermediate::addLoop(TLoopType type, TIntermNode* init, TIntermTy ...@@ -711,12 +695,12 @@ TIntermNode* TIntermediate::addLoop(TLoopType type, TIntermNode* init, TIntermTy
// //
// Add branches. // Add branches.
// //
TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TSourceLoc line) TIntermBranch* TIntermediate::addBranch(TOperator branchOp, const TSourceLoc& line)
{ {
return addBranch(branchOp, 0, line); return addBranch(branchOp, 0, line);
} }
TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TIntermTyped* expression, TSourceLoc line) TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TIntermTyped* expression, const TSourceLoc& line)
{ {
TIntermBranch* node = new TIntermBranch(branchOp, expression); TIntermBranch* node = new TIntermBranch(branchOp, expression);
node->setLine(line); node->setLine(line);
...@@ -861,7 +845,7 @@ bool TIntermBinary::promote(TInfoSink& infoSink) ...@@ -861,7 +845,7 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
{ {
// This function only handles scalars, vectors, and matrices. // This function only handles scalars, vectors, and matrices.
if (left->isArray() || right->isArray()) { if (left->isArray() || right->isArray()) {
infoSink.info.message(EPrefixInternalError, "Invalid operation for arrays", getLine()); infoSink.info.message(EPrefixInternalError, getLine(), "Invalid operation for arrays");
return false; return false;
} }
...@@ -966,7 +950,7 @@ bool TIntermBinary::promote(TInfoSink& infoSink) ...@@ -966,7 +950,7 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
setType(TType(basicType, higherPrecision, EvqTemporary, size, false)); setType(TType(basicType, higherPrecision, EvqTemporary, size, false));
} }
} else { } else {
infoSink.info.message(EPrefixInternalError, "Missing elses", getLine()); infoSink.info.message(EPrefixInternalError, getLine(), "Missing elses");
return false; return false;
} }
break; break;
...@@ -995,7 +979,7 @@ bool TIntermBinary::promote(TInfoSink& infoSink) ...@@ -995,7 +979,7 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
setType(TType(basicType, higherPrecision, EvqTemporary, size, false)); setType(TType(basicType, higherPrecision, EvqTemporary, size, false));
} }
} else { } else {
infoSink.info.message(EPrefixInternalError, "Missing elses", getLine()); infoSink.info.message(EPrefixInternalError, getLine(), "Missing elses");
return false; return false;
} }
break; break;
...@@ -1139,7 +1123,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod ...@@ -1139,7 +1123,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
break; break;
case EOpMatrixTimesMatrix: case EOpMatrixTimesMatrix:
if (getType().getBasicType() != EbtFloat || node->getBasicType() != EbtFloat) { if (getType().getBasicType() != EbtFloat || node->getBasicType() != EbtFloat) {
infoSink.info.message(EPrefixInternalError, "Constant Folding cannot be done for matrix multiply", getLine()); infoSink.info.message(EPrefixInternalError, getLine(), "Constant Folding cannot be done for matrix multiply");
return 0; return 0;
} }
{// support MSVC++6.0 {// support MSVC++6.0
...@@ -1162,7 +1146,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod ...@@ -1162,7 +1146,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
switch (getType().getBasicType()) { switch (getType().getBasicType()) {
case EbtFloat: case EbtFloat:
if (rightUnionArray[i] == 0.0f) { if (rightUnionArray[i] == 0.0f) {
infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", getLine()); infoSink.info.message(EPrefixWarning, getLine(), "Divide by zero error during constant folding");
tempConstArray[i].setFConst(unionArray[i].getFConst() < 0 ? -FLT_MAX : FLT_MAX); tempConstArray[i].setFConst(unionArray[i].getFConst() < 0 ? -FLT_MAX : FLT_MAX);
} else } else
tempConstArray[i].setFConst(unionArray[i].getFConst() / rightUnionArray[i].getFConst()); tempConstArray[i].setFConst(unionArray[i].getFConst() / rightUnionArray[i].getFConst());
...@@ -1170,13 +1154,13 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod ...@@ -1170,13 +1154,13 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
case EbtInt: case EbtInt:
if (rightUnionArray[i] == 0) { if (rightUnionArray[i] == 0) {
infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", getLine()); infoSink.info.message(EPrefixWarning, getLine(), "Divide by zero error during constant folding");
tempConstArray[i].setIConst(INT_MAX); tempConstArray[i].setIConst(INT_MAX);
} else } else
tempConstArray[i].setIConst(unionArray[i].getIConst() / rightUnionArray[i].getIConst()); tempConstArray[i].setIConst(unionArray[i].getIConst() / rightUnionArray[i].getIConst());
break; break;
default: default:
infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"/\"", getLine()); infoSink.info.message(EPrefixInternalError, getLine(), "Constant folding cannot be done for \"/\"");
return 0; return 0;
} }
} }
...@@ -1185,7 +1169,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod ...@@ -1185,7 +1169,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
case EOpMatrixTimesVector: case EOpMatrixTimesVector:
if (node->getBasicType() != EbtFloat) { if (node->getBasicType() != EbtFloat) {
infoSink.info.message(EPrefixInternalError, "Constant Folding cannot be done for matrix times vector", getLine()); infoSink.info.message(EPrefixInternalError, getLine(), "Constant Folding cannot be done for matrix times vector");
return 0; return 0;
} }
tempConstArray = new ConstantUnion[getNominalSize()]; tempConstArray = new ConstantUnion[getNominalSize()];
...@@ -1206,7 +1190,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod ...@@ -1206,7 +1190,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
case EOpVectorTimesMatrix: case EOpVectorTimesMatrix:
if (getType().getBasicType() != EbtFloat) { if (getType().getBasicType() != EbtFloat) {
infoSink.info.message(EPrefixInternalError, "Constant Folding cannot be done for vector times matrix", getLine()); infoSink.info.message(EPrefixInternalError, getLine(), "Constant Folding cannot be done for vector times matrix");
return 0; return 0;
} }
...@@ -1334,7 +1318,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod ...@@ -1334,7 +1318,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
return tempNode; return tempNode;
default: default:
infoSink.info.message(EPrefixInternalError, "Invalid operator for constant folding", getLine()); infoSink.info.message(EPrefixInternalError, getLine(), "Invalid operator for constant folding");
return 0; return 0;
} }
tempNode = new TIntermConstantUnion(tempConstArray, returnType); tempNode = new TIntermConstantUnion(tempConstArray, returnType);
...@@ -1354,7 +1338,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod ...@@ -1354,7 +1338,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
case EbtFloat: tempConstArray[i].setFConst(-unionArray[i].getFConst()); break; case EbtFloat: tempConstArray[i].setFConst(-unionArray[i].getFConst()); break;
case EbtInt: tempConstArray[i].setIConst(-unionArray[i].getIConst()); break; case EbtInt: tempConstArray[i].setIConst(-unionArray[i].getIConst()); break;
default: default:
infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine()); infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant");
return 0; return 0;
} }
break; break;
...@@ -1362,7 +1346,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod ...@@ -1362,7 +1346,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
switch (getType().getBasicType()) { switch (getType().getBasicType()) {
case EbtBool: tempConstArray[i].setBConst(!unionArray[i].getBConst()); break; case EbtBool: tempConstArray[i].setBConst(!unionArray[i].getBConst()); break;
default: default:
infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine()); infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant");
return 0; return 0;
} }
break; break;
...@@ -1397,7 +1381,7 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC ...@@ -1397,7 +1381,7 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
leftUnionArray[i].setFConst(static_cast<float>(node->getFConst(i))); leftUnionArray[i].setFConst(static_cast<float>(node->getFConst(i)));
break; break;
default: default:
infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine()); infoSink.info.message(EPrefixInternalError, node->getLine(), "Cannot promote");
return 0; return 0;
} }
break; break;
...@@ -1413,7 +1397,7 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC ...@@ -1413,7 +1397,7 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
leftUnionArray[i].setIConst(static_cast<int>(node->getFConst(i))); leftUnionArray[i].setIConst(static_cast<int>(node->getFConst(i)));
break; break;
default: default:
infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine()); infoSink.info.message(EPrefixInternalError, node->getLine(), "Cannot promote");
return 0; return 0;
} }
break; break;
...@@ -1429,13 +1413,13 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC ...@@ -1429,13 +1413,13 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
leftUnionArray[i].setBConst(node->getFConst(i) != 0.0f); leftUnionArray[i].setBConst(node->getFConst(i) != 0.0f);
break; break;
default: default:
infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine()); infoSink.info.message(EPrefixInternalError, node->getLine(), "Cannot promote");
return 0; return 0;
} }
break; break;
default: default:
infoSink.info.message(EPrefixInternalError, "Incorrect data type found", node->getLine()); infoSink.info.message(EPrefixInternalError, node->getLine(), "Incorrect data type found");
return 0; return 0;
} }
......
...@@ -1238,7 +1238,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) ...@@ -1238,7 +1238,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
{ {
if (mInsideFunction) if (mInsideFunction)
{ {
outputLineDirective(node->getLine()); outputLineDirective(node->getLine().first_line);
out << "{\n"; out << "{\n";
mScopeDepth++; mScopeDepth++;
...@@ -1255,7 +1255,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) ...@@ -1255,7 +1255,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
for (TIntermSequence::iterator sit = node->getSequence().begin(); sit != node->getSequence().end(); sit++) for (TIntermSequence::iterator sit = node->getSequence().begin(); sit != node->getSequence().end(); sit++)
{ {
outputLineDirective((*sit)->getLine()); outputLineDirective((*sit)->getLine().first_line);
traverseStatements(*sit); traverseStatements(*sit);
...@@ -1264,7 +1264,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) ...@@ -1264,7 +1264,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
if (mInsideFunction) if (mInsideFunction)
{ {
outputLineDirective(node->getEndLine()); outputLineDirective(node->getLine().last_line);
out << "}\n"; out << "}\n";
mScopeDepth--; mScopeDepth--;
...@@ -1741,7 +1741,7 @@ bool OutputHLSL::visitSelection(Visit visit, TIntermSelection *node) ...@@ -1741,7 +1741,7 @@ bool OutputHLSL::visitSelection(Visit visit, TIntermSelection *node)
out << ")\n"; out << ")\n";
outputLineDirective(node->getLine()); outputLineDirective(node->getLine().first_line);
out << "{\n"; out << "{\n";
if (node->getTrueBlock()) if (node->getTrueBlock())
...@@ -1749,20 +1749,20 @@ bool OutputHLSL::visitSelection(Visit visit, TIntermSelection *node) ...@@ -1749,20 +1749,20 @@ bool OutputHLSL::visitSelection(Visit visit, TIntermSelection *node)
traverseStatements(node->getTrueBlock()); traverseStatements(node->getTrueBlock());
} }
outputLineDirective(node->getLine()); outputLineDirective(node->getLine().first_line);
out << ";\n}\n"; out << ";\n}\n";
if (node->getFalseBlock()) if (node->getFalseBlock())
{ {
out << "else\n"; out << "else\n";
outputLineDirective(node->getFalseBlock()->getLine()); outputLineDirective(node->getFalseBlock()->getLine().first_line);
out << "{\n"; out << "{\n";
outputLineDirective(node->getFalseBlock()->getLine()); outputLineDirective(node->getFalseBlock()->getLine().first_line);
traverseStatements(node->getFalseBlock()); traverseStatements(node->getFalseBlock());
outputLineDirective(node->getFalseBlock()->getLine()); outputLineDirective(node->getFalseBlock()->getLine().first_line);
out << ";\n}\n"; out << ";\n}\n";
} }
} }
...@@ -1795,7 +1795,7 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node) ...@@ -1795,7 +1795,7 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node)
{ {
out << "{do\n"; out << "{do\n";
outputLineDirective(node->getLine()); outputLineDirective(node->getLine().first_line);
out << "{\n"; out << "{\n";
} }
else else
...@@ -1823,7 +1823,7 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node) ...@@ -1823,7 +1823,7 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node)
out << ")\n"; out << ")\n";
outputLineDirective(node->getLine()); outputLineDirective(node->getLine().first_line);
out << "{\n"; out << "{\n";
} }
...@@ -1832,12 +1832,12 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node) ...@@ -1832,12 +1832,12 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node)
traverseStatements(node->getBody()); traverseStatements(node->getBody());
} }
outputLineDirective(node->getLine()); outputLineDirective(node->getLine().first_line);
out << ";}\n"; out << ";}\n";
if (node->getType() == ELoopDoWhile) if (node->getType() == ELoopDoWhile)
{ {
outputLineDirective(node->getCondition()->getLine()); outputLineDirective(node->getCondition()->getLine().first_line);
out << "while(\n"; out << "while(\n";
node->getCondition()->traverse(this); node->getCondition()->traverse(this);
...@@ -2109,7 +2109,7 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node) ...@@ -2109,7 +2109,7 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node)
out << increment; out << increment;
out << ")\n"; out << ")\n";
outputLineDirective(node->getLine()); outputLineDirective(node->getLine().first_line);
out << "{\n"; out << "{\n";
if (node->getBody()) if (node->getBody())
...@@ -2117,7 +2117,7 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node) ...@@ -2117,7 +2117,7 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node)
node->getBody()->traverse(this); node->getBody()->traverse(this);
} }
outputLineDirective(node->getLine()); outputLineDirective(node->getLine().first_line);
out << ";}\n"; out << ";}\n";
if (!firstLoopFragment) if (!firstLoopFragment)
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
// Look at a '.' field selector string and change it into offsets // Look at a '.' field selector string and change it into offsets
// for a vector. // for a vector.
// //
bool TParseContext::parseVectorFields(const TString& compString, int vecSize, TVectorFields& fields, int line) bool TParseContext::parseVectorFields(const TString& compString, int vecSize, TVectorFields& fields, const TSourceLoc& line)
{ {
fields.num = (int) compString.size(); fields.num = (int) compString.size();
if (fields.num > 4) { if (fields.num > 4) {
...@@ -115,7 +115,7 @@ bool TParseContext::parseVectorFields(const TString& compString, int vecSize, TV ...@@ -115,7 +115,7 @@ bool TParseContext::parseVectorFields(const TString& compString, int vecSize, TV
// Look at a '.' field selector string and change it into offsets // Look at a '.' field selector string and change it into offsets
// for a matrix. // for a matrix.
// //
bool TParseContext::parseMatrixFields(const TString& compString, int matSize, TMatrixFields& fields, int line) bool TParseContext::parseMatrixFields(const TString& compString, int matSize, TMatrixFields& fields, const TSourceLoc& line)
{ {
fields.wholeRow = false; fields.wholeRow = false;
fields.wholeCol = false; fields.wholeCol = false;
...@@ -175,22 +175,24 @@ void TParseContext::recover() ...@@ -175,22 +175,24 @@ void TParseContext::recover()
// //
// Used by flex/bison to output all syntax and parsing errors. // Used by flex/bison to output all syntax and parsing errors.
// //
void TParseContext::error(TSourceLoc loc, void TParseContext::error(const TSourceLoc& loc,
const char* reason, const char* token, const char* reason, const char* token,
const char* extraInfo) const char* extraInfo)
{ {
pp::SourceLocation srcLoc; pp::SourceLocation srcLoc;
DecodeSourceLoc(loc, &srcLoc.file, &srcLoc.line); srcLoc.file = loc.first_file;
srcLoc.line = loc.first_line;
diagnostics.writeInfo(pp::Diagnostics::ERROR, diagnostics.writeInfo(pp::Diagnostics::ERROR,
srcLoc, reason, token, extraInfo); srcLoc, reason, token, extraInfo);
} }
void TParseContext::warning(TSourceLoc loc, void TParseContext::warning(const TSourceLoc& loc,
const char* reason, const char* token, const char* reason, const char* token,
const char* extraInfo) { const char* extraInfo) {
pp::SourceLocation srcLoc; pp::SourceLocation srcLoc;
DecodeSourceLoc(loc, &srcLoc.file, &srcLoc.line); srcLoc.file = loc.first_file;
srcLoc.line = loc.first_line;
diagnostics.writeInfo(pp::Diagnostics::WARNING, diagnostics.writeInfo(pp::Diagnostics::WARNING,
srcLoc, reason, token, extraInfo); srcLoc, reason, token, extraInfo);
} }
...@@ -203,7 +205,7 @@ void TParseContext::trace(const char* str) ...@@ -203,7 +205,7 @@ void TParseContext::trace(const char* str)
// //
// Same error message for all places assignments don't work. // Same error message for all places assignments don't work.
// //
void TParseContext::assignError(int 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 extraInfoStream;
extraInfoStream << "cannot convert from '" << right << "' to '" << left << "'"; extraInfoStream << "cannot convert from '" << right << "' to '" << left << "'";
...@@ -214,7 +216,7 @@ void TParseContext::assignError(int line, const char* op, TString left, TString ...@@ -214,7 +216,7 @@ void TParseContext::assignError(int line, const char* op, TString left, TString
// //
// Same error message for all places unary operations don't work. // Same error message for all places unary operations don't work.
// //
void TParseContext::unaryOpError(int line, const char* op, TString operand) void TParseContext::unaryOpError(const TSourceLoc& line, const char* op, TString operand)
{ {
std::stringstream extraInfoStream; std::stringstream extraInfoStream;
extraInfoStream << "no operation '" << op << "' exists that takes an operand of type " << operand extraInfoStream << "no operation '" << op << "' exists that takes an operand of type " << operand
...@@ -226,7 +228,7 @@ void TParseContext::unaryOpError(int line, const char* op, TString operand) ...@@ -226,7 +228,7 @@ void TParseContext::unaryOpError(int line, const char* op, TString operand)
// //
// Same error message for all binary operations don't work. // Same error message for all binary operations don't work.
// //
void TParseContext::binaryOpError(int line, const char* op, TString left, TString right) void TParseContext::binaryOpError(const TSourceLoc& line, const char* op, TString left, TString right)
{ {
std::stringstream extraInfoStream; std::stringstream extraInfoStream;
extraInfoStream << "no operation '" << op << "' exists that takes a left-hand operand of type '" << left extraInfoStream << "no operation '" << op << "' exists that takes a left-hand operand of type '" << left
...@@ -235,7 +237,7 @@ void TParseContext::binaryOpError(int line, const char* op, TString left, TStrin ...@@ -235,7 +237,7 @@ void TParseContext::binaryOpError(int line, const char* op, TString left, TStrin
error(line, " wrong operand types ", op, extraInfo.c_str()); error(line, " wrong operand types ", op, extraInfo.c_str());
} }
bool TParseContext::precisionErrorCheck(int line, TPrecision precision, TBasicType type){ bool TParseContext::precisionErrorCheck(const TSourceLoc& line, TPrecision precision, TBasicType type){
if (!checksPrecisionErrors) if (!checksPrecisionErrors)
return false; return false;
switch( type ){ switch( type ){
...@@ -263,7 +265,7 @@ bool TParseContext::precisionErrorCheck(int line, TPrecision precision, TBasicTy ...@@ -263,7 +265,7 @@ bool TParseContext::precisionErrorCheck(int line, TPrecision precision, TBasicTy
// //
// Returns true if the was an error. // Returns true if the was an error.
// //
bool TParseContext::lValueErrorCheck(int line, const char* op, TIntermTyped* node) bool TParseContext::lValueErrorCheck(const TSourceLoc& line, const char* op, TIntermTyped* node)
{ {
TIntermSymbol* symNode = node->getAsSymbolNode(); TIntermSymbol* symNode = node->getAsSymbolNode();
TIntermBinary* binaryNode = node->getAsBinaryNode(); TIntermBinary* binaryNode = node->getAsBinaryNode();
...@@ -409,7 +411,7 @@ bool TParseContext::integerErrorCheck(TIntermTyped* node, const char* token) ...@@ -409,7 +411,7 @@ bool TParseContext::integerErrorCheck(TIntermTyped* node, const char* token)
// //
// Returns true if the was an error. // Returns true if the was an error.
// //
bool TParseContext::globalErrorCheck(int line, bool global, const char* token) bool TParseContext::globalErrorCheck(const TSourceLoc& line, bool global, const char* token)
{ {
if (global) if (global)
return false; return false;
...@@ -428,7 +430,7 @@ bool TParseContext::globalErrorCheck(int line, bool global, const char* token) ...@@ -428,7 +430,7 @@ bool TParseContext::globalErrorCheck(int line, bool global, const char* token)
// //
// Returns true if there was an error. // Returns true if there was an error.
// //
bool TParseContext::reservedErrorCheck(int line, const TString& identifier) bool TParseContext::reservedErrorCheck(const TSourceLoc& 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()) {
...@@ -466,7 +468,7 @@ bool TParseContext::reservedErrorCheck(int line, const TString& identifier) ...@@ -466,7 +468,7 @@ bool TParseContext::reservedErrorCheck(int line, const TString& identifier)
// //
// Returns true if there was an error in construction. // Returns true if there was an error in construction.
// //
bool TParseContext::constructorErrorCheck(int line, TIntermNode* node, TFunction& function, TOperator op, TType* type) bool TParseContext::constructorErrorCheck(const TSourceLoc& line, TIntermNode* node, TFunction& function, TOperator op, TType* type)
{ {
*type = function.getReturnType(); *type = function.getReturnType();
...@@ -568,7 +570,7 @@ bool TParseContext::constructorErrorCheck(int line, TIntermNode* node, TFunction ...@@ -568,7 +570,7 @@ bool TParseContext::constructorErrorCheck(int line, TIntermNode* node, TFunction
// //
// returns true in case of an error // returns true in case of an error
// //
bool TParseContext::voidErrorCheck(int line, const TString& identifier, const TPublicType& pubType) bool TParseContext::voidErrorCheck(const TSourceLoc& 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());
...@@ -582,7 +584,7 @@ bool TParseContext::voidErrorCheck(int line, const TString& identifier, const TP ...@@ -582,7 +584,7 @@ bool TParseContext::voidErrorCheck(int line, const TString& identifier, const TP
// //
// returns true in case of an error // returns true in case of an error
// //
bool TParseContext::boolErrorCheck(int line, const TIntermTyped* type) bool TParseContext::boolErrorCheck(const TSourceLoc& line, const TIntermTyped* type)
{ {
if (type->getBasicType() != EbtBool || type->isArray() || type->isMatrix() || type->isVector()) { if (type->getBasicType() != EbtBool || type->isArray() || type->isMatrix() || type->isVector()) {
error(line, "boolean expression expected", ""); error(line, "boolean expression expected", "");
...@@ -596,7 +598,7 @@ bool TParseContext::boolErrorCheck(int line, const TIntermTyped* type) ...@@ -596,7 +598,7 @@ bool TParseContext::boolErrorCheck(int line, const TIntermTyped* type)
// //
// returns true in case of an error // returns true in case of an error
// //
bool TParseContext::boolErrorCheck(int line, const TPublicType& pType) bool TParseContext::boolErrorCheck(const TSourceLoc& 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", "");
...@@ -606,7 +608,7 @@ bool TParseContext::boolErrorCheck(int line, const TPublicType& pType) ...@@ -606,7 +608,7 @@ bool TParseContext::boolErrorCheck(int line, const TPublicType& pType)
return false; return false;
} }
bool TParseContext::samplerErrorCheck(int line, const TPublicType& pType, const char* reason) bool TParseContext::samplerErrorCheck(const TSourceLoc& line, const TPublicType& pType, const char* reason)
{ {
if (pType.type == EbtStruct) { if (pType.type == EbtStruct) {
if (containsSampler(*pType.userDef)) { if (containsSampler(*pType.userDef)) {
...@@ -625,7 +627,7 @@ bool TParseContext::samplerErrorCheck(int line, const TPublicType& pType, const ...@@ -625,7 +627,7 @@ bool TParseContext::samplerErrorCheck(int line, const TPublicType& pType, const
return false; return false;
} }
bool TParseContext::structQualifierErrorCheck(int line, const TPublicType& pType) bool TParseContext::structQualifierErrorCheck(const TSourceLoc& 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) {
...@@ -640,7 +642,7 @@ bool TParseContext::structQualifierErrorCheck(int line, const TPublicType& pType ...@@ -640,7 +642,7 @@ bool TParseContext::structQualifierErrorCheck(int line, const TPublicType& pType
return false; return false;
} }
bool TParseContext::parameterSamplerErrorCheck(int line, TQualifier qualifier, const TType& type) bool TParseContext::parameterSamplerErrorCheck(const TSourceLoc& line, TQualifier qualifier, const TType& type)
{ {
if ((qualifier == EvqOut || qualifier == EvqInOut) && if ((qualifier == EvqOut || qualifier == EvqInOut) &&
type.getBasicType() != EbtStruct && IsSampler(type.getBasicType())) { type.getBasicType() != EbtStruct && IsSampler(type.getBasicType())) {
...@@ -672,7 +674,7 @@ bool TParseContext::containsSampler(TType& type) ...@@ -672,7 +674,7 @@ bool TParseContext::containsSampler(TType& type)
// //
// Returns true if there was an error. // Returns true if there was an error.
// //
bool TParseContext::arraySizeErrorCheck(int line, TIntermTyped* expr, int& size) bool TParseContext::arraySizeErrorCheck(const TSourceLoc& 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) {
...@@ -696,7 +698,7 @@ bool TParseContext::arraySizeErrorCheck(int line, TIntermTyped* expr, int& size) ...@@ -696,7 +698,7 @@ bool TParseContext::arraySizeErrorCheck(int line, TIntermTyped* expr, int& size)
// //
// Returns true if there is an error. // Returns true if there is an error.
// //
bool TParseContext::arrayQualifierErrorCheck(int line, TPublicType type) bool TParseContext::arrayQualifierErrorCheck(const TSourceLoc& 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());
...@@ -711,7 +713,7 @@ bool TParseContext::arrayQualifierErrorCheck(int line, TPublicType type) ...@@ -711,7 +713,7 @@ bool TParseContext::arrayQualifierErrorCheck(int line, TPublicType type)
// //
// Returns true if there is an error. // Returns true if there is an error.
// //
bool TParseContext::arrayTypeErrorCheck(int line, TPublicType type) bool TParseContext::arrayTypeErrorCheck(const TSourceLoc& line, TPublicType type)
{ {
// //
// Can the type be an array? // Can the type be an array?
...@@ -732,7 +734,7 @@ bool TParseContext::arrayTypeErrorCheck(int line, TPublicType type) ...@@ -732,7 +734,7 @@ bool TParseContext::arrayTypeErrorCheck(int line, TPublicType type)
// //
// Returns true if there was an error. // Returns true if there was an error.
// //
bool TParseContext::arrayErrorCheck(int line, TString& identifier, TPublicType type, TVariable*& variable) bool TParseContext::arrayErrorCheck(const TSourceLoc& line, TString& identifier, TPublicType type, TVariable*& variable)
{ {
// //
// Don't check for reserved word use until after we know it's not in the symbol table, // Don't check for reserved word use until after we know it's not in the symbol table,
...@@ -797,7 +799,7 @@ bool TParseContext::arrayErrorCheck(int line, TString& identifier, TPublicType t ...@@ -797,7 +799,7 @@ bool TParseContext::arrayErrorCheck(int line, TString& identifier, TPublicType t
return false; return false;
} }
bool TParseContext::arraySetMaxSize(TIntermSymbol *node, TType* type, int size, bool updateFlag, TSourceLoc line) bool TParseContext::arraySetMaxSize(TIntermSymbol *node, TType* type, int size, bool updateFlag, const TSourceLoc& line)
{ {
bool builtIn = false; bool builtIn = false;
TSymbol* symbol = symbolTable.find(node->getSymbol(), &builtIn); TSymbol* symbol = symbolTable.find(node->getSymbol(), &builtIn);
...@@ -846,7 +848,7 @@ bool TParseContext::arraySetMaxSize(TIntermSymbol *node, TType* type, int size, ...@@ -846,7 +848,7 @@ bool TParseContext::arraySetMaxSize(TIntermSymbol *node, TType* type, int size,
// //
// Returns true if there was an error. // Returns true if there was an error.
// //
bool TParseContext::nonInitConstErrorCheck(int line, TString& identifier, TPublicType& type, bool array) bool TParseContext::nonInitConstErrorCheck(const TSourceLoc& line, TString& identifier, TPublicType& type, bool array)
{ {
if (type.qualifier == EvqConst) if (type.qualifier == EvqConst)
{ {
...@@ -878,7 +880,7 @@ bool TParseContext::nonInitConstErrorCheck(int line, TString& identifier, TPubli ...@@ -878,7 +880,7 @@ bool TParseContext::nonInitConstErrorCheck(int line, TString& identifier, TPubli
// //
// Returns true if there was an error. // Returns true if there was an error.
// //
bool TParseContext::nonInitErrorCheck(int line, TString& identifier, TPublicType& type, TVariable*& variable) bool TParseContext::nonInitErrorCheck(const TSourceLoc& line, TString& identifier, TPublicType& type, TVariable*& variable)
{ {
if (reservedErrorCheck(line, identifier)) if (reservedErrorCheck(line, identifier))
recover(); recover();
...@@ -898,7 +900,7 @@ bool TParseContext::nonInitErrorCheck(int line, TString& identifier, TPublicType ...@@ -898,7 +900,7 @@ bool TParseContext::nonInitErrorCheck(int line, TString& identifier, TPublicType
return false; return false;
} }
bool TParseContext::paramErrorCheck(int line, TQualifier qualifier, TQualifier paramQualifier, TType* type) bool TParseContext::paramErrorCheck(const TSourceLoc& 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));
...@@ -917,7 +919,7 @@ bool TParseContext::paramErrorCheck(int line, TQualifier qualifier, TQualifier p ...@@ -917,7 +919,7 @@ bool TParseContext::paramErrorCheck(int line, TQualifier qualifier, TQualifier p
return false; return false;
} }
bool TParseContext::extensionErrorCheck(int line, const TString& extension) bool TParseContext::extensionErrorCheck(const TSourceLoc& line, const TString& extension)
{ {
const TExtensionBehavior& extBehavior = extensionBehavior(); const TExtensionBehavior& extBehavior = extensionBehavior();
TExtensionBehavior::const_iterator iter = extBehavior.find(extension.c_str()); TExtensionBehavior::const_iterator iter = extBehavior.find(extension.c_str());
...@@ -956,7 +958,7 @@ bool TParseContext::supportsExtension(const char* extension) ...@@ -956,7 +958,7 @@ bool TParseContext::supportsExtension(const char* extension)
// //
// Return the function symbol if found, otherwise 0. // Return the function symbol if found, otherwise 0.
// //
const TFunction* TParseContext::findFunction(int line, TFunction* call, bool *builtIn) const TFunction* TParseContext::findFunction(const TSourceLoc& line, TFunction* call, bool *builtIn)
{ {
// First find by unmangled name to check whether the function name has been // First find by unmangled name to check whether the function name has been
// hidden by a variable name or struct typename. // hidden by a variable name or struct typename.
...@@ -982,7 +984,7 @@ const TFunction* TParseContext::findFunction(int line, TFunction* call, bool *bu ...@@ -982,7 +984,7 @@ const TFunction* TParseContext::findFunction(int line, TFunction* call, bool *bu
// Initializers show up in several places in the grammar. Have one set of // Initializers show up in several places in the grammar. Have one set of
// code to handle them here. // code to handle them here.
// //
bool TParseContext::executeInitializer(TSourceLoc line, TString& identifier, TPublicType& pType, bool TParseContext::executeInitializer(const TSourceLoc& line, TString& identifier, TPublicType& pType,
TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable) TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable)
{ {
TType type = TType(pType); TType type = TType(pType);
...@@ -1094,7 +1096,7 @@ bool TParseContext::areAllChildConst(TIntermAggregate* aggrNode) ...@@ -1094,7 +1096,7 @@ bool TParseContext::areAllChildConst(TIntermAggregate* aggrNode)
// //
// Returns 0 for an error or the constructed node (aggregate or typed) for no error. // Returns 0 for an error or the constructed node (aggregate or typed) for no error.
// //
TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType* type, TOperator op, TFunction* fnCall, TSourceLoc line) TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType* type, TOperator op, TFunction* fnCall, const TSourceLoc& line)
{ {
if (node == 0) if (node == 0)
return 0; return 0;
...@@ -1202,7 +1204,7 @@ TIntermTyped* TParseContext::foldConstConstructor(TIntermAggregate* aggrNode, co ...@@ -1202,7 +1204,7 @@ TIntermTyped* TParseContext::foldConstConstructor(TIntermAggregate* aggrNode, co
// //
// Returns 0 for an error or the constructed node. // Returns 0 for an error or the constructed node.
// //
TIntermTyped* TParseContext::constructBuiltIn(const TType* type, TOperator op, TIntermNode* node, TSourceLoc line, bool subset) TIntermTyped* TParseContext::constructBuiltIn(const TType* type, TOperator op, TIntermNode* node, const TSourceLoc& line, bool subset)
{ {
TIntermTyped* newNode; TIntermTyped* newNode;
TOperator basicOp; TOperator basicOp;
...@@ -1264,7 +1266,7 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType* type, TOperator op, T ...@@ -1264,7 +1266,7 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType* type, TOperator op, T
// //
// Returns 0 for an error or the input node itself if the expected and the given parameter types match. // Returns 0 for an error or the input node itself if the expected and the given parameter types match.
// //
TIntermTyped* TParseContext::constructStruct(TIntermNode* node, TType* type, int paramCount, TSourceLoc line, bool subset) TIntermTyped* TParseContext::constructStruct(TIntermNode* node, TType* type, int paramCount, const TSourceLoc& line, bool subset)
{ {
if (*type == node->getAsTyped()->getType()) { if (*type == node->getAsTyped()->getType()) {
if (subset) if (subset)
...@@ -1291,7 +1293,7 @@ TIntermTyped* TParseContext::constructStruct(TIntermNode* node, TType* type, int ...@@ -1291,7 +1293,7 @@ TIntermTyped* TParseContext::constructStruct(TIntermNode* node, TType* type, int
// node or it could be the intermediate tree representation of accessing fields in a constant structure or column of // node or it could be the intermediate tree representation of accessing fields in a constant structure or column of
// a constant matrix. // a constant matrix.
// //
TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTyped* node, TSourceLoc line) TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTyped* node, const TSourceLoc& line)
{ {
TIntermTyped* typedNode; TIntermTyped* typedNode;
TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion(); TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
...@@ -1335,7 +1337,7 @@ TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTy ...@@ -1335,7 +1337,7 @@ TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTy
// to the function could either be a symbol node (m[0] where m is a constant matrix)that represents a // to the function could either be a symbol node (m[0] where m is a constant matrix)that represents a
// constant matrix or it could be the tree representation of the constant matrix (s.m1[0] where s is a constant structure) // constant matrix or it could be the tree representation of the constant matrix (s.m1[0] where s is a constant structure)
// //
TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, TSourceLoc line) TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, const TSourceLoc& line)
{ {
TIntermTyped* typedNode; TIntermTyped* typedNode;
TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion(); TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
...@@ -1370,7 +1372,7 @@ TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, T ...@@ -1370,7 +1372,7 @@ TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, T
// to the function could either be a symbol node (a[0] where a is a constant array)that represents a // to the function could either be a symbol node (a[0] where a is a constant array)that represents a
// constant array or it could be the tree representation of the constant array (s.a1[0] where s is a constant structure) // constant array or it could be the tree representation of the constant array (s.a1[0] where s is a constant structure)
// //
TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TSourceLoc line) TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, const TSourceLoc& line)
{ {
TIntermTyped* typedNode; TIntermTyped* typedNode;
TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion(); TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
...@@ -1407,7 +1409,7 @@ TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TS ...@@ -1407,7 +1409,7 @@ TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TS
// If there is an embedded/nested struct, it appropriately calls addConstStructNested or addConstStructFromAggr // If there is an embedded/nested struct, it appropriately calls addConstStructNested or addConstStructFromAggr
// function and returns the parse-tree with the values of the embedded/nested struct. // function and returns the parse-tree with the values of the embedded/nested struct.
// //
TIntermTyped* TParseContext::addConstStruct(TString& identifier, TIntermTyped* node, TSourceLoc line) TIntermTyped* TParseContext::addConstStruct(TString& identifier, TIntermTyped* node, const TSourceLoc& line)
{ {
const TTypeList* fields = node->getType().getStruct(); const TTypeList* fields = node->getType().getStruct();
TIntermTyped *typedNode; TIntermTyped *typedNode;
...@@ -1437,7 +1439,7 @@ TIntermTyped* TParseContext::addConstStruct(TString& identifier, TIntermTyped* n ...@@ -1437,7 +1439,7 @@ TIntermTyped* TParseContext::addConstStruct(TString& identifier, TIntermTyped* n
return typedNode; return typedNode;
} }
bool TParseContext::enterStructDeclaration(int line, const TString& identifier) bool TParseContext::enterStructDeclaration(const TSourceLoc& line, const TString& identifier)
{ {
++structNestingLevel; ++structNestingLevel;
...@@ -1463,7 +1465,7 @@ const int kWebGLMaxStructNesting = 4; ...@@ -1463,7 +1465,7 @@ const int kWebGLMaxStructNesting = 4;
} // namespace } // namespace
bool TParseContext::structNestingErrorCheck(TSourceLoc line, const TType& fieldType) bool TParseContext::structNestingErrorCheck(const TSourceLoc& line, const TType& fieldType)
{ {
if (!isWebGLBasedSpec(shaderSpec)) { if (!isWebGLBasedSpec(shaderSpec)) {
return false; return false;
......
...@@ -63,40 +63,40 @@ struct TParseContext { ...@@ -63,40 +63,40 @@ struct TParseContext {
int numErrors() const { return diagnostics.numErrors(); } int numErrors() const { return diagnostics.numErrors(); }
TInfoSink& infoSink() { return diagnostics.infoSink(); } TInfoSink& infoSink() { return diagnostics.infoSink(); }
void error(TSourceLoc loc, const char *reason, const char* token, void error(const TSourceLoc& loc, const char *reason, const char* token,
const char* extraInfo=""); const char* extraInfo="");
void warning(TSourceLoc loc, const char* reason, const char* token, void warning(const TSourceLoc& loc, const char* reason, const char* token,
const char* extraInfo=""); const char* extraInfo="");
void trace(const char* str); void trace(const char* str);
void recover(); void recover();
bool parseVectorFields(const TString&, int vecSize, TVectorFields&, int line); bool parseVectorFields(const TString&, int vecSize, TVectorFields&, const TSourceLoc& line);
bool parseMatrixFields(const TString&, int matSize, TMatrixFields&, int line); bool parseMatrixFields(const TString&, int matSize, TMatrixFields&, const TSourceLoc& line);
bool reservedErrorCheck(int line, const TString& identifier); bool reservedErrorCheck(const TSourceLoc& line, const TString& identifier);
void assignError(int line, const char* op, TString left, TString right); void assignError(const TSourceLoc& line, const char* op, TString left, TString right);
void unaryOpError(int line, const char* op, TString operand); void unaryOpError(const TSourceLoc& line, const char* op, TString operand);
void binaryOpError(int line, const char* op, TString left, TString right); void binaryOpError(const TSourceLoc& line, const char* op, TString left, TString right);
bool precisionErrorCheck(int line, TPrecision precision, TBasicType type); bool precisionErrorCheck(const TSourceLoc& line, TPrecision precision, TBasicType type);
bool lValueErrorCheck(int line, const char* op, TIntermTyped*); bool lValueErrorCheck(const TSourceLoc& line, const char* op, TIntermTyped*);
bool constErrorCheck(TIntermTyped* node); bool constErrorCheck(TIntermTyped* node);
bool integerErrorCheck(TIntermTyped* node, const char* token); bool integerErrorCheck(TIntermTyped* node, const char* token);
bool globalErrorCheck(int line, bool global, const char* token); bool globalErrorCheck(const TSourceLoc& line, bool global, const char* token);
bool constructorErrorCheck(int line, TIntermNode*, TFunction&, TOperator, TType*); bool constructorErrorCheck(const TSourceLoc& line, TIntermNode*, TFunction&, TOperator, TType*);
bool arraySizeErrorCheck(int line, TIntermTyped* expr, int& size); bool arraySizeErrorCheck(const TSourceLoc& line, TIntermTyped* expr, int& size);
bool arrayQualifierErrorCheck(int line, TPublicType type); bool arrayQualifierErrorCheck(const TSourceLoc& line, TPublicType type);
bool arrayTypeErrorCheck(int line, TPublicType type); bool arrayTypeErrorCheck(const TSourceLoc& line, TPublicType type);
bool arrayErrorCheck(int line, TString& identifier, TPublicType type, TVariable*& variable); bool arrayErrorCheck(const TSourceLoc& line, TString& identifier, TPublicType type, TVariable*& variable);
bool voidErrorCheck(int, const TString&, const TPublicType&); bool voidErrorCheck(const TSourceLoc&, const TString&, const TPublicType&);
bool boolErrorCheck(int, const TIntermTyped*); bool boolErrorCheck(const TSourceLoc&, const TIntermTyped*);
bool boolErrorCheck(int, const TPublicType&); bool boolErrorCheck(const TSourceLoc&, const TPublicType&);
bool samplerErrorCheck(int line, const TPublicType& pType, const char* reason); bool samplerErrorCheck(const TSourceLoc& line, const TPublicType& pType, const char* reason);
bool structQualifierErrorCheck(int line, const TPublicType& pType); bool structQualifierErrorCheck(const TSourceLoc& line, const TPublicType& pType);
bool parameterSamplerErrorCheck(int line, TQualifier qualifier, const TType& type); bool parameterSamplerErrorCheck(const TSourceLoc& line, TQualifier qualifier, const TType& type);
bool nonInitConstErrorCheck(int line, TString& identifier, TPublicType& type, bool array); bool nonInitConstErrorCheck(const TSourceLoc& line, TString& identifier, TPublicType& type, bool array);
bool nonInitErrorCheck(int line, TString& identifier, TPublicType& type, TVariable*& variable); bool nonInitErrorCheck(const TSourceLoc& line, TString& identifier, TPublicType& type, TVariable*& variable);
bool paramErrorCheck(int line, TQualifier qualifier, TQualifier paramQualifier, TType* type); bool paramErrorCheck(const TSourceLoc& line, TQualifier qualifier, TQualifier paramQualifier, TType* type);
bool extensionErrorCheck(int line, const TString&); bool extensionErrorCheck(const TSourceLoc& line, const TString&);
const TPragma& pragma() const { return directiveHandler.pragma(); } const TPragma& pragma() const { return directiveHandler.pragma(); }
const TExtensionBehavior& extensionBehavior() const { return directiveHandler.extensionBehavior(); } const TExtensionBehavior& extensionBehavior() const { return directiveHandler.extensionBehavior(); }
...@@ -104,27 +104,27 @@ struct TParseContext { ...@@ -104,27 +104,27 @@ struct TParseContext {
bool containsSampler(TType& type); bool containsSampler(TType& type);
bool areAllChildConst(TIntermAggregate* aggrNode); bool areAllChildConst(TIntermAggregate* aggrNode);
const TFunction* findFunction(int line, TFunction* pfnCall, bool *builtIn = 0); const TFunction* findFunction(const TSourceLoc& line, TFunction* pfnCall, bool *builtIn = 0);
bool executeInitializer(TSourceLoc line, TString& identifier, TPublicType& pType, bool executeInitializer(const TSourceLoc& line, TString& identifier, TPublicType& pType,
TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable = 0); TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable = 0);
bool arraySetMaxSize(TIntermSymbol*, TType*, int, bool, TSourceLoc); bool arraySetMaxSize(TIntermSymbol*, TType*, int, bool, const TSourceLoc&);
TIntermTyped* addConstructor(TIntermNode*, const TType*, TOperator, TFunction*, TSourceLoc); TIntermTyped* addConstructor(TIntermNode*, const TType*, TOperator, TFunction*, const TSourceLoc&);
TIntermTyped* foldConstConstructor(TIntermAggregate* aggrNode, const TType& type); TIntermTyped* foldConstConstructor(TIntermAggregate* aggrNode, const TType& type);
TIntermTyped* constructStruct(TIntermNode*, TType*, int, TSourceLoc, bool subset); TIntermTyped* constructStruct(TIntermNode*, TType*, int, const TSourceLoc&, bool subset);
TIntermTyped* constructBuiltIn(const TType*, TOperator, TIntermNode*, TSourceLoc, bool subset); TIntermTyped* constructBuiltIn(const TType*, TOperator, TIntermNode*, const TSourceLoc&, bool subset);
TIntermTyped* addConstVectorNode(TVectorFields&, TIntermTyped*, TSourceLoc); TIntermTyped* addConstVectorNode(TVectorFields&, TIntermTyped*, const TSourceLoc&);
TIntermTyped* addConstMatrixNode(int , TIntermTyped*, TSourceLoc); TIntermTyped* addConstMatrixNode(int , TIntermTyped*, const TSourceLoc&);
TIntermTyped* addConstArrayNode(int index, TIntermTyped* node, TSourceLoc line); TIntermTyped* addConstArrayNode(int index, TIntermTyped* node, const TSourceLoc& line);
TIntermTyped* addConstStruct(TString& , TIntermTyped*, TSourceLoc); TIntermTyped* addConstStruct(TString& , TIntermTyped*, const TSourceLoc&);
// Performs an error check for embedded struct declarations. // Performs an error check for embedded struct declarations.
// Returns true if an error was raised due to the declaration of // Returns true if an error was raised due to the declaration of
// this struct. // this struct.
bool enterStructDeclaration(TSourceLoc line, const TString& identifier); bool enterStructDeclaration(const TSourceLoc& line, const TString& identifier);
void exitStructDeclaration(); void exitStructDeclaration();
bool structNestingErrorCheck(TSourceLoc line, const TType& fieldType); bool structNestingErrorCheck(const TSourceLoc& line, const TType& fieldType);
}; };
int PaParseStrings(size_t count, const char* const string[], const int length[], int PaParseStrings(size_t count, const char* const string[], const int length[],
......
...@@ -214,9 +214,9 @@ struct TPublicType ...@@ -214,9 +214,9 @@ struct TPublicType
bool array; bool array;
int arraySize; int arraySize;
TType* userDef; TType* userDef;
int line; TSourceLoc line;
void setBasic(TBasicType bt, TQualifier q, int ln = 0) void setBasic(TBasicType bt, TQualifier q, const TSourceLoc& ln)
{ {
type = bt; type = bt;
qualifier = q; qualifier = q;
......
...@@ -47,7 +47,10 @@ WHICH GENERATES THE GLSL ES LEXER (glslang_lex.cpp). ...@@ -47,7 +47,10 @@ WHICH GENERATES THE GLSL ES LEXER (glslang_lex.cpp).
#pragma warning(disable : 4102) #pragma warning(disable : 4102)
#endif #endif
#define YY_USER_ACTION yylval->lex.line = yylineno; #define YY_USER_ACTION \
yylloc->first_file = yylloc->last_file = yycolumn; \
yylloc->first_line = yylloc->last_line = yylineno;
#define YY_INPUT(buf, result, max_size) \ #define YY_INPUT(buf, result, max_size) \
result = string_input(buf, max_size, yyscanner); result = string_input(buf, max_size, yyscanner);
...@@ -57,7 +60,7 @@ static int reserved_word(yyscan_t yyscanner); ...@@ -57,7 +60,7 @@ static int reserved_word(yyscan_t yyscanner);
%} %}
%option noyywrap nounput never-interactive %option noyywrap nounput never-interactive
%option yylineno reentrant bison-bridge %option yylineno reentrant bison-bridge bison-locations
%option extra-type="TParseContext*" %option extra-type="TParseContext*"
D [0-9] D [0-9]
...@@ -253,7 +256,8 @@ yy_size_t string_input(char* buf, yy_size_t max_size, yyscan_t yyscanner) { ...@@ -253,7 +256,8 @@ yy_size_t string_input(char* buf, yy_size_t max_size, yyscan_t yyscanner) {
yy_size_t len = token.type == pp::Token::LAST ? 0 : token.text.size(); yy_size_t len = token.type == pp::Token::LAST ? 0 : token.text.size();
if (len < max_size) if (len < max_size)
memcpy(buf, token.text.c_str(), len); memcpy(buf, token.text.c_str(), len);
yyset_lineno(EncodeSourceLoc(token.location.file, token.location.line), yyscanner); yyset_column(token.location.file, yyscanner);
yyset_lineno(token.location.line, yyscanner);
if (len >= max_size) if (len >= max_size)
YY_FATAL_ERROR("Input buffer overflow"); YY_FATAL_ERROR("Input buffer overflow");
...@@ -279,18 +283,11 @@ int check_type(yyscan_t yyscanner) { ...@@ -279,18 +283,11 @@ 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(yylineno, "Illegal use of reserved word", yytext, ""); yyextra->error(*yylloc, "Illegal use of reserved word", yytext, "");
yyextra->recover(); yyextra->recover();
return 0; return 0;
} }
void yyerror(TParseContext* context, const char* reason) {
struct yyguts_t* yyg = (struct yyguts_t*) context->scanner;
context->error(yylineno, reason, yytext);
context->recover();
}
int glslang_initialize(TParseContext* context) { int glslang_initialize(TParseContext* context) {
yyscan_t scanner = NULL; yyscan_t scanner = NULL;
if (yylex_init_extra(context, &scanner)) if (yylex_init_extra(context, &scanner))
...@@ -313,7 +310,8 @@ int glslang_finalize(TParseContext* context) { ...@@ -313,7 +310,8 @@ int glslang_finalize(TParseContext* context) {
int glslang_scan(size_t count, const char* const string[], const int length[], int glslang_scan(size_t count, const char* const string[], const int length[],
TParseContext* context) { TParseContext* context) {
yyrestart(NULL, context->scanner); yyrestart(NULL, context->scanner);
yyset_lineno(EncodeSourceLoc(0, 1), context->scanner); yyset_column(0, context->scanner);
yyset_lineno(1, context->scanner);
// Initialize preprocessor. // Initialize preprocessor.
if (!context->preprocessor.init(count, string, length)) if (!context->preprocessor.init(count, string, length))
......
...@@ -39,7 +39,6 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h). ...@@ -39,7 +39,6 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h).
#include "GLSLANG/ShaderLang.h" #include "GLSLANG/ShaderLang.h"
#define YYENABLE_NLS 0 #define YYENABLE_NLS 0
#define YYLTYPE_IS_TRIVIAL 1
#define YYLEX_PARAM context->scanner #define YYLEX_PARAM context->scanner
%} %}
...@@ -47,10 +46,15 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h). ...@@ -47,10 +46,15 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h).
%expect 1 /* One shift reduce conflict because of if | else */ %expect 1 /* One shift reduce conflict because of if | else */
%pure-parser %pure-parser
%parse-param {TParseContext* context} %parse-param {TParseContext* context}
%locations
%code requires {
#define YYLTYPE TSourceLoc
#define YYLTYPE_IS_DECLARED 1
}
%union { %union {
struct { struct {
TSourceLoc line;
union { union {
TString *string; TString *string;
float f; float f;
...@@ -60,7 +64,6 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h). ...@@ -60,7 +64,6 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h).
TSymbol* symbol; TSymbol* symbol;
} lex; } lex;
struct { struct {
TSourceLoc line;
TOperator op; TOperator op;
union { union {
TIntermNode* intermNode; TIntermNode* intermNode;
...@@ -81,8 +84,24 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h). ...@@ -81,8 +84,24 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h).
} }
%{ %{
extern int yylex(YYSTYPE* yylval_param, void* yyscanner); extern int yylex(YYSTYPE* yylval, YYLTYPE* yylloc, void* yyscanner);
extern void yyerror(TParseContext* context, const char* reason); static void yyerror(YYLTYPE* yylloc, TParseContext* context, const char* reason);
#define YYLLOC_DEFAULT(Current, Rhs, N) \
do { \
if (YYID(N)) { \
(Current).first_file = YYRHSLOC(Rhs, 1).first_file; \
(Current).first_line = YYRHSLOC(Rhs, 1).first_line; \
(Current).last_file = YYRHSLOC(Rhs, N).last_file; \
(Current).last_line = YYRHSLOC(Rhs, N).last_line; \
} \
else { \
(Current).first_file = YYRHSLOC(Rhs, 0).last_file; \
(Current).first_line = YYRHSLOC(Rhs, 0).last_line; \
(Current).last_file = YYRHSLOC(Rhs, 0).last_file; \
(Current).last_line = YYRHSLOC(Rhs, 0).last_line; \
} \
} while (0)
#define FRAG_VERT_ONLY(S, L) { \ #define FRAG_VERT_ONLY(S, L) { \
if (context->shaderType != SH_FRAGMENT_SHADER && \ if (context->shaderType != SH_FRAGMENT_SHADER && \
...@@ -174,7 +193,7 @@ variable_identifier ...@@ -174,7 +193,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, "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);
...@@ -183,7 +202,7 @@ variable_identifier ...@@ -183,7 +202,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, "variable expected", $1.string->c_str());
context->recover(); context->recover();
} }
variable = static_cast<const TVariable*>(symbol); variable = static_cast<const TVariable*>(symbol);
...@@ -195,11 +214,12 @@ variable_identifier ...@@ -195,11 +214,12 @@ variable_identifier
if (variable->getType().getQualifier() == EvqConst ) { if (variable->getType().getQualifier() == EvqConst ) {
ConstantUnion* constArray = variable->getConstPointer(); ConstantUnion* constArray = variable->getConstPointer();
TType t(variable->getType()); TType t(variable->getType());
$$ = context->intermediate.addConstantUnion(constArray, t, $1.line); $$ = context->intermediate.addConstantUnion(constArray, t, @1);
} else } else
$$ = context->intermediate.addSymbol(variable->getUniqueId(), $$ = context->intermediate.addSymbol(variable->getUniqueId(),
variable->getName(), variable->getName(),
variable->getType(), $1.line); variable->getType(),
@1);
} }
; ;
...@@ -213,22 +233,22 @@ primary_expression ...@@ -213,22 +233,22 @@ 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, " integer constant overflow", "");
context->recover(); context->recover();
} }
ConstantUnion *unionArray = new ConstantUnion[1]; ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setIConst($1.i); unionArray->setIConst($1.i);
$$ = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), $1.line); $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), @1);
} }
| FLOATCONSTANT { | FLOATCONSTANT {
ConstantUnion *unionArray = new ConstantUnion[1]; ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setFConst($1.f); unionArray->setFConst($1.f);
$$ = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConst), $1.line); $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConst), @1);
} }
| BOOLCONSTANT { | BOOLCONSTANT {
ConstantUnion *unionArray = new ConstantUnion[1]; ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setBConst($1.b); unionArray->setBConst($1.b);
$$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $1.line); $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @1);
} }
| LEFT_PAREN expression RIGHT_PAREN { | LEFT_PAREN expression RIGHT_PAREN {
$$ = $2; $$ = $2;
...@@ -242,21 +262,21 @@ postfix_expression ...@@ -242,21 +262,21 @@ 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, " 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, " 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) {
if ($1->isArray()) { // constant folding for arrays if ($1->isArray()) { // constant folding for arrays
$$ = context->addConstArrayNode($3->getAsConstantUnion()->getIConst(0), $1, $2.line); $$ = context->addConstArrayNode($3->getAsConstantUnion()->getIConst(0), $1, @2);
} else if ($1->isVector()) { // constant folding for vectors } else if ($1->isVector()) { // constant folding for vectors
TVectorFields fields; TVectorFields fields;
fields.num = 1; fields.num = 1;
fields.offsets[0] = $3->getAsConstantUnion()->getIConst(0); // need to do it this way because v.xy sends fields integer array fields.offsets[0] = $3->getAsConstantUnion()->getIConst(0); // need to do it this way because v.xy sends fields integer array
$$ = context->addConstVectorNode(fields, $1, $2.line); $$ = context->addConstVectorNode(fields, $1, @2);
} else if ($1->isMatrix()) { // constant folding for matrices } else if ($1->isMatrix()) { // constant folding for matrices
$$ = context->addConstMatrixNode($3->getAsConstantUnion()->getIConst(0), $1, $2.line); $$ = context->addConstMatrixNode($3->getAsConstantUnion()->getIConst(0), $1, @2);
} }
} else { } else {
if ($3->getQualifier() == EvqConst) { if ($3->getQualifier() == EvqConst) {
...@@ -264,41 +284,41 @@ postfix_expression ...@@ -264,41 +284,41 @@ postfix_expression
std::stringstream extraInfoStream; std::stringstream extraInfoStream;
extraInfoStream << "field selection out of range '" << $3->getAsConstantUnion()->getIConst(0) << "'"; extraInfoStream << "field selection out of range '" << $3->getAsConstantUnion()->getIConst(0) << "'";
std::string extraInfo = extraInfoStream.str(); std::string extraInfo = extraInfoStream.str();
context->error($2.line, "", "[", extraInfo.c_str()); context->error(@2, "", "[", extraInfo.c_str());
context->recover(); context->recover();
} else { } else {
if ($1->isArray()) { if ($1->isArray()) {
if ($1->getType().getArraySize() == 0) { if ($1->getType().getArraySize() == 0) {
if ($1->getType().getMaxArraySize() <= $3->getAsConstantUnion()->getIConst(0)) { if ($1->getType().getMaxArraySize() <= $3->getAsConstantUnion()->getIConst(0)) {
if (context->arraySetMaxSize($1->getAsSymbolNode(), $1->getTypePointer(), $3->getAsConstantUnion()->getIConst(0), true, $2.line)) if (context->arraySetMaxSize($1->getAsSymbolNode(), $1->getTypePointer(), $3->getAsConstantUnion()->getIConst(0), true, @2))
context->recover(); context->recover();
} else { } else {
if (context->arraySetMaxSize($1->getAsSymbolNode(), $1->getTypePointer(), 0, false, $2.line)) if (context->arraySetMaxSize($1->getAsSymbolNode(), $1->getTypePointer(), 0, false, @2))
context->recover(); context->recover();
} }
} else if ( $3->getAsConstantUnion()->getIConst(0) >= $1->getType().getArraySize()) { } else if ( $3->getAsConstantUnion()->getIConst(0) >= $1->getType().getArraySize()) {
std::stringstream extraInfoStream; std::stringstream extraInfoStream;
extraInfoStream << "array index out of range '" << $3->getAsConstantUnion()->getIConst(0) << "'"; extraInfoStream << "array index out of range '" << $3->getAsConstantUnion()->getIConst(0) << "'";
std::string extraInfo = extraInfoStream.str(); std::string extraInfo = extraInfoStream.str();
context->error($2.line, "", "[", extraInfo.c_str()); context->error(@2, "", "[", extraInfo.c_str());
context->recover(); context->recover();
} }
} }
$$ = context->intermediate.addIndex(EOpIndexDirect, $1, $3, $2.line); $$ = context->intermediate.addIndex(EOpIndexDirect, $1, $3, @2);
} }
} else { } else {
if ($1->isArray() && $1->getType().getArraySize() == 0) { if ($1->isArray() && $1->getType().getArraySize() == 0) {
context->error($2.line, "", "[", "array must be redeclared with a size before being indexed with a variable"); context->error(@2, "", "[", "array must be redeclared with a size before being indexed with a variable");
context->recover(); context->recover();
} }
$$ = context->intermediate.addIndex(EOpIndexIndirect, $1, $3, $2.line); $$ = context->intermediate.addIndex(EOpIndexIndirect, $1, $3, @2);
} }
} }
if ($$ == 0) { if ($$ == 0) {
ConstantUnion *unionArray = new ConstantUnion[1]; ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setFConst(0.0f); unionArray->setFConst(0.0f);
$$ = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpHigh, EvqConst), $2.line); $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpHigh, EvqConst), @2);
} else if ($1->isArray()) { } else if ($1->isArray()) {
if ($1->getType().getStruct()) if ($1->getType().getStruct())
$$->setType(TType($1->getType().getStruct(), $1->getType().getTypeName())); $$->setType(TType($1->getType().getStruct(), $1->getType().getTypeName()));
...@@ -323,20 +343,20 @@ postfix_expression ...@@ -323,20 +343,20 @@ postfix_expression
} }
| postfix_expression DOT identifier { | postfix_expression DOT identifier {
if ($1->isArray()) { if ($1->isArray()) {
context->error($3.line, "cannot apply dot operator to an array", "."); context->error(@3, "cannot apply dot operator to an array", ".");
context->recover(); context->recover();
} }
if ($1->isVector()) { if ($1->isVector()) {
TVectorFields fields; TVectorFields fields;
if (! context->parseVectorFields(*$3.string, $1->getNominalSize(), fields, $3.line)) { if (! context->parseVectorFields(*$3.string, $1->getNominalSize(), fields, @3)) {
fields.num = 1; fields.num = 1;
fields.offsets[0] = 0; fields.offsets[0] = 0;
context->recover(); context->recover();
} }
if ($1->getType().getQualifier() == EvqConst) { // constant folding for vector fields if ($1->getType().getQualifier() == EvqConst) { // constant folding for vector fields
$$ = context->addConstVectorNode(fields, $1, $3.line); $$ = context->addConstVectorNode(fields, $1, @3);
if ($$ == 0) { if ($$ == 0) {
context->recover(); context->recover();
$$ = $1; $$ = $1;
...@@ -345,13 +365,13 @@ postfix_expression ...@@ -345,13 +365,13 @@ postfix_expression
$$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqConst, (int) (*$3.string).size())); $$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqConst, (int) (*$3.string).size()));
} else { } else {
TString vectorString = *$3.string; TString vectorString = *$3.string;
TIntermTyped* index = context->intermediate.addSwizzle(fields, $3.line); TIntermTyped* index = context->intermediate.addSwizzle(fields, @3);
$$ = context->intermediate.addIndex(EOpVectorSwizzle, $1, index, $2.line); $$ = context->intermediate.addIndex(EOpVectorSwizzle, $1, index, @2);
$$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqTemporary, (int) vectorString.size())); $$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqTemporary, (int) vectorString.size()));
} }
} else if ($1->isMatrix()) { } else if ($1->isMatrix()) {
TMatrixFields fields; TMatrixFields fields;
if (! context->parseMatrixFields(*$3.string, $1->getNominalSize(), fields, $3.line)) { if (! context->parseMatrixFields(*$3.string, $1->getNominalSize(), fields, @3)) {
fields.wholeRow = false; fields.wholeRow = false;
fields.wholeCol = false; fields.wholeCol = false;
fields.row = 0; fields.row = 0;
...@@ -360,25 +380,25 @@ postfix_expression ...@@ -360,25 +380,25 @@ 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, " 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);
TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), $3.line); TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), @3);
$$ = context->intermediate.addIndex(EOpIndexDirect, $1, index, $2.line); $$ = context->intermediate.addIndex(EOpIndexDirect, $1, index, @2);
$$->setType(TType($1->getBasicType(), $1->getPrecision(),EvqTemporary, $1->getNominalSize())); $$->setType(TType($1->getBasicType(), $1->getPrecision(),EvqTemporary, $1->getNominalSize()));
} else { } else {
ConstantUnion *unionArray = new ConstantUnion[1]; ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setIConst(fields.col * $1->getNominalSize() + fields.row); unionArray->setIConst(fields.col * $1->getNominalSize() + fields.row);
TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), $3.line); TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), @3);
$$ = context->intermediate.addIndex(EOpIndexDirect, $1, index, $2.line); $$ = context->intermediate.addIndex(EOpIndexDirect, $1, index, @2);
$$->setType(TType($1->getBasicType(), $1->getPrecision())); $$->setType(TType($1->getBasicType(), $1->getPrecision()));
} }
} else if ($1->getBasicType() == EbtStruct) { } else if ($1->getBasicType() == EbtStruct) {
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, "structure has no fields", "Internal Error");
context->recover(); context->recover();
$$ = $1; $$ = $1;
} else { } else {
...@@ -391,7 +411,7 @@ postfix_expression ...@@ -391,7 +411,7 @@ postfix_expression
} }
if (fieldFound) { if (fieldFound) {
if ($1->getType().getQualifier() == EvqConst) { if ($1->getType().getQualifier() == EvqConst) {
$$ = context->addConstStruct(*$3.string, $1, $2.line); $$ = context->addConstStruct(*$3.string, $1, @2);
if ($$ == 0) { if ($$ == 0) {
context->recover(); context->recover();
$$ = $1; $$ = $1;
...@@ -405,39 +425,39 @@ postfix_expression ...@@ -405,39 +425,39 @@ postfix_expression
} else { } else {
ConstantUnion *unionArray = new ConstantUnion[1]; ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setIConst(i); unionArray->setIConst(i);
TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, *(*fields)[i], $3.line); TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, *(*fields)[i], @3);
$$ = context->intermediate.addIndex(EOpIndexDirectStruct, $1, index, $2.line); $$ = context->intermediate.addIndex(EOpIndexDirectStruct, $1, index, @2);
$$->setType(*(*fields)[i]); $$->setType(*(*fields)[i]);
} }
} else { } else {
context->error($2.line, " no such field in structure", $3.string->c_str()); context->error(@2, " 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, " field selection requires structure, vector, or matrix on left hand side", $3.string->c_str());
context->recover(); context->recover();
$$ = $1; $$ = $1;
} }
// don't delete $3.string, it's from the pool // don't delete $3.string, it's from the pool
} }
| postfix_expression INC_OP { | postfix_expression INC_OP {
if (context->lValueErrorCheck($2.line, "++", $1)) if (context->lValueErrorCheck(@2, "++", $1))
context->recover(); context->recover();
$$ = context->intermediate.addUnaryMath(EOpPostIncrement, $1, $2.line, context->symbolTable); $$ = context->intermediate.addUnaryMath(EOpPostIncrement, $1, @2, context->symbolTable);
if ($$ == 0) { if ($$ == 0) {
context->unaryOpError($2.line, "++", $1->getCompleteString()); context->unaryOpError(@2, "++", $1->getCompleteString());
context->recover(); context->recover();
$$ = $1; $$ = $1;
} }
} }
| postfix_expression DEC_OP { | postfix_expression DEC_OP {
if (context->lValueErrorCheck($2.line, "--", $1)) if (context->lValueErrorCheck(@2, "--", $1))
context->recover(); context->recover();
$$ = context->intermediate.addUnaryMath(EOpPostDecrement, $1, $2.line, context->symbolTable); $$ = context->intermediate.addUnaryMath(EOpPostDecrement, $1, @2, context->symbolTable);
if ($$ == 0) { if ($$ == 0) {
context->unaryOpError($2.line, "--", $1->getCompleteString()); context->unaryOpError(@2, "--", $1->getCompleteString());
context->recover(); context->recover();
$$ = $1; $$ = $1;
} }
...@@ -465,18 +485,18 @@ function_call ...@@ -465,18 +485,18 @@ function_call
// Their parameters will be verified algorithmically. // Their parameters will be verified algorithmically.
// //
TType type(EbtVoid, EbpUndefined); // use this to get the type back TType type(EbtVoid, EbpUndefined); // use this to get the type back
if (context->constructorErrorCheck($1.line, $1.intermNode, *fnCall, op, &type)) { if (context->constructorErrorCheck(@1, $1.intermNode, *fnCall, op, &type)) {
$$ = 0; $$ = 0;
} else { } else {
// //
// It's a constructor, of type 'type'. // It's a constructor, of type 'type'.
// //
$$ = context->addConstructor($1.intermNode, &type, op, fnCall, $1.line); $$ = context->addConstructor($1.intermNode, &type, op, fnCall, @1);
} }
if ($$ == 0) { if ($$ == 0) {
context->recover(); context->recover();
$$ = context->intermediate.setAggregateOperator(0, op, $1.line); $$ = context->intermediate.setAggregateOperator(0, op, @1);
} }
$$->setType(type); $$->setType(type);
} else { } else {
...@@ -485,13 +505,13 @@ function_call ...@@ -485,13 +505,13 @@ function_call
// //
const TFunction* fnCandidate; const TFunction* fnCandidate;
bool builtIn; bool builtIn;
fnCandidate = context->findFunction($1.line, fnCall, &builtIn); fnCandidate = context->findFunction(@1, fnCall, &builtIn);
if (fnCandidate) { if (fnCandidate) {
// //
// A declared function. // A declared function.
// //
if (builtIn && !fnCandidate->getExtension().empty() && if (builtIn && !fnCandidate->getExtension().empty() &&
context->extensionErrorCheck($1.line, fnCandidate->getExtension())) { context->extensionErrorCheck(@1, fnCandidate->getExtension())) {
context->recover(); context->recover();
} }
op = fnCandidate->getBuiltInOp(); op = fnCandidate->getBuiltInOp();
...@@ -503,7 +523,7 @@ function_call ...@@ -503,7 +523,7 @@ function_call
// //
// Treat it like a built-in unary operator. // Treat it like a built-in unary operator.
// //
$$ = context->intermediate.addUnaryMath(op, $1.intermNode, 0, context->symbolTable); $$ = context->intermediate.addUnaryMath(op, $1.intermNode, @1, context->symbolTable);
if ($$ == 0) { if ($$ == 0) {
std::stringstream extraInfoStream; std::stringstream extraInfoStream;
extraInfoStream << "built in unary operator function. Type: " << static_cast<TIntermTyped*>($1.intermNode)->getCompleteString(); extraInfoStream << "built in unary operator function. Type: " << static_cast<TIntermTyped*>($1.intermNode)->getCompleteString();
...@@ -512,12 +532,12 @@ function_call ...@@ -512,12 +532,12 @@ function_call
YYERROR; YYERROR;
} }
} else { } else {
$$ = context->intermediate.setAggregateOperator($1.intermAggregate, op, $1.line); $$ = context->intermediate.setAggregateOperator($1.intermAggregate, op, @1);
} }
} else { } else {
// This is a real function call // This is a real function call
$$ = context->intermediate.setAggregateOperator($1.intermAggregate, EOpFunctionCall, $1.line); $$ = context->intermediate.setAggregateOperator($1.intermAggregate, EOpFunctionCall, @1);
$$->setType(fnCandidate->getReturnType()); $$->setType(fnCandidate->getReturnType());
// this is how we know whether the given function is a builtIn function or a user defined function // this is how we know whether the given function is a builtIn function or a user defined function
...@@ -544,7 +564,7 @@ function_call ...@@ -544,7 +564,7 @@ function_call
// Put on a dummy node for error recovery // Put on a dummy node for error recovery
ConstantUnion *unionArray = new ConstantUnion[1]; ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setFConst(0.0f); unionArray->setFConst(0.0f);
$$ = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConst), $1.line); $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConst), @1);
context->recover(); context->recover();
} }
} }
...@@ -557,7 +577,7 @@ function_call_or_method ...@@ -557,7 +577,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, "methods are not supported", "");
context->recover(); context->recover();
$$ = $3; $$ = $3;
} }
...@@ -566,11 +586,9 @@ function_call_or_method ...@@ -566,11 +586,9 @@ function_call_or_method
function_call_generic function_call_generic
: function_call_header_with_parameters RIGHT_PAREN { : function_call_header_with_parameters RIGHT_PAREN {
$$ = $1; $$ = $1;
$$.line = $2.line;
} }
| function_call_header_no_parameters RIGHT_PAREN { | function_call_header_no_parameters RIGHT_PAREN {
$$ = $1; $$ = $1;
$$.line = $2.line;
} }
; ;
...@@ -596,7 +614,7 @@ function_call_header_with_parameters ...@@ -596,7 +614,7 @@ function_call_header_with_parameters
TParameter param = { 0, new TType($3->getType()) }; TParameter param = { 0, new TType($3->getType()) };
$1.function->addParameter(param); $1.function->addParameter(param);
$$.function = $1.function; $$.function = $1.function;
$$.intermNode = context->intermediate.growAggregate($1.intermNode, $3, $2.line); $$.intermNode = context->intermediate.growAggregate($1.intermNode, $3, @2);
} }
; ;
...@@ -637,23 +655,23 @@ function_identifier ...@@ -637,23 +655,23 @@ function_identifier
case EbtInt: case EbtInt:
switch($1.size) { switch($1.size) {
case 1: op = EOpConstructInt; break; case 1: op = EOpConstructInt; break;
case 2: FRAG_VERT_ONLY("ivec2", $1.line); op = EOpConstructIVec2; break; case 2: FRAG_VERT_ONLY("ivec2", @1); op = EOpConstructIVec2; break;
case 3: FRAG_VERT_ONLY("ivec3", $1.line); op = EOpConstructIVec3; break; case 3: FRAG_VERT_ONLY("ivec3", @1); op = EOpConstructIVec3; break;
case 4: FRAG_VERT_ONLY("ivec4", $1.line); op = EOpConstructIVec4; break; case 4: FRAG_VERT_ONLY("ivec4", @1); op = EOpConstructIVec4; break;
} }
break; break;
case EbtBool: case EbtBool:
switch($1.size) { switch($1.size) {
case 1: op = EOpConstructBool; break; case 1: op = EOpConstructBool; break;
case 2: FRAG_VERT_ONLY("bvec2", $1.line); op = EOpConstructBVec2; break; case 2: FRAG_VERT_ONLY("bvec2", @1); op = EOpConstructBVec2; break;
case 3: FRAG_VERT_ONLY("bvec3", $1.line); op = EOpConstructBVec3; break; case 3: FRAG_VERT_ONLY("bvec3", @1); op = EOpConstructBVec3; break;
case 4: FRAG_VERT_ONLY("bvec4", $1.line); op = EOpConstructBVec4; break; case 4: FRAG_VERT_ONLY("bvec4", @1); op = EOpConstructBVec4; break;
} }
break; break;
default: break; default: break;
} }
if (op == EOpNull) { if (op == EOpNull) {
context->error($1.line, "cannot construct this type", getBasicString($1.type)); context->error(@1, "cannot construct this type", getBasicString($1.type));
context->recover(); context->recover();
$1.type = EbtFloat; $1.type = EbtFloat;
op = EOpConstructFloat; op = EOpConstructFloat;
...@@ -665,7 +683,7 @@ function_identifier ...@@ -665,7 +683,7 @@ function_identifier
$$ = function; $$ = function;
} }
| IDENTIFIER { | IDENTIFIER {
if (context->reservedErrorCheck($1.line, *$1.string)) if (context->reservedErrorCheck(@1, *$1.string))
context->recover(); context->recover();
TType type(EbtVoid, EbpUndefined); TType type(EbtVoid, EbpUndefined);
TFunction *function = new TFunction($1.string, type); TFunction *function = new TFunction($1.string, type);
...@@ -678,28 +696,28 @@ unary_expression ...@@ -678,28 +696,28 @@ unary_expression
$$ = $1; $$ = $1;
} }
| INC_OP unary_expression { | INC_OP unary_expression {
if (context->lValueErrorCheck($1.line, "++", $2)) if (context->lValueErrorCheck(@1, "++", $2))
context->recover(); context->recover();
$$ = context->intermediate.addUnaryMath(EOpPreIncrement, $2, $1.line, context->symbolTable); $$ = context->intermediate.addUnaryMath(EOpPreIncrement, $2, @1, context->symbolTable);
if ($$ == 0) { if ($$ == 0) {
context->unaryOpError($1.line, "++", $2->getCompleteString()); context->unaryOpError(@1, "++", $2->getCompleteString());
context->recover(); context->recover();
$$ = $2; $$ = $2;
} }
} }
| DEC_OP unary_expression { | DEC_OP unary_expression {
if (context->lValueErrorCheck($1.line, "--", $2)) if (context->lValueErrorCheck(@1, "--", $2))
context->recover(); context->recover();
$$ = context->intermediate.addUnaryMath(EOpPreDecrement, $2, $1.line, context->symbolTable); $$ = context->intermediate.addUnaryMath(EOpPreDecrement, $2, @1, context->symbolTable);
if ($$ == 0) { if ($$ == 0) {
context->unaryOpError($1.line, "--", $2->getCompleteString()); context->unaryOpError(@1, "--", $2->getCompleteString());
context->recover(); context->recover();
$$ = $2; $$ = $2;
} }
} }
| unary_operator unary_expression { | unary_operator unary_expression {
if ($1.op != EOpNull) { if ($1.op != EOpNull) {
$$ = context->intermediate.addUnaryMath($1.op, $2, $1.line, context->symbolTable); $$ = context->intermediate.addUnaryMath($1.op, $2, @1, context->symbolTable);
if ($$ == 0) { if ($$ == 0) {
const char* errorOp = ""; const char* errorOp = "";
switch($1.op) { switch($1.op) {
...@@ -707,7 +725,7 @@ unary_expression ...@@ -707,7 +725,7 @@ unary_expression
case EOpLogicalNot: errorOp = "!"; break; case EOpLogicalNot: errorOp = "!"; break;
default: break; default: break;
} }
context->unaryOpError($1.line, errorOp, $2->getCompleteString()); context->unaryOpError(@1, errorOp, $2->getCompleteString());
context->recover(); context->recover();
$$ = $2; $$ = $2;
} }
...@@ -718,28 +736,28 @@ unary_expression ...@@ -718,28 +736,28 @@ unary_expression
// Grammar Note: No traditional style type casts. // Grammar Note: No traditional style type casts.
unary_operator unary_operator
: PLUS { $$.line = $1.line; $$.op = EOpNull; } : PLUS { $$.op = EOpNull; }
| DASH { $$.line = $1.line; $$.op = EOpNegative; } | DASH { $$.op = EOpNegative; }
| BANG { $$.line = $1.line; $$.op = EOpLogicalNot; } | BANG { $$.op = EOpLogicalNot; }
; ;
// Grammar Note: No '*' or '&' unary ops. Pointers are not supported. // Grammar Note: No '*' or '&' unary ops. Pointers are not supported.
multiplicative_expression multiplicative_expression
: unary_expression { $$ = $1; } : unary_expression { $$ = $1; }
| multiplicative_expression STAR unary_expression { | multiplicative_expression STAR unary_expression {
FRAG_VERT_ONLY("*", $2.line); FRAG_VERT_ONLY("*", @2);
$$ = context->intermediate.addBinaryMath(EOpMul, $1, $3, $2.line, context->symbolTable); $$ = context->intermediate.addBinaryMath(EOpMul, $1, $3, @2, context->symbolTable);
if ($$ == 0) { if ($$ == 0) {
context->binaryOpError($2.line, "*", $1->getCompleteString(), $3->getCompleteString()); context->binaryOpError(@2, "*", $1->getCompleteString(), $3->getCompleteString());
context->recover(); context->recover();
$$ = $1; $$ = $1;
} }
} }
| multiplicative_expression SLASH unary_expression { | multiplicative_expression SLASH unary_expression {
FRAG_VERT_ONLY("/", $2.line); FRAG_VERT_ONLY("/", @2);
$$ = context->intermediate.addBinaryMath(EOpDiv, $1, $3, $2.line, context->symbolTable); $$ = context->intermediate.addBinaryMath(EOpDiv, $1, $3, @2, context->symbolTable);
if ($$ == 0) { if ($$ == 0) {
context->binaryOpError($2.line, "/", $1->getCompleteString(), $3->getCompleteString()); context->binaryOpError(@2, "/", $1->getCompleteString(), $3->getCompleteString());
context->recover(); context->recover();
$$ = $1; $$ = $1;
} }
...@@ -749,17 +767,17 @@ multiplicative_expression ...@@ -749,17 +767,17 @@ multiplicative_expression
additive_expression additive_expression
: multiplicative_expression { $$ = $1; } : multiplicative_expression { $$ = $1; }
| additive_expression PLUS multiplicative_expression { | additive_expression PLUS multiplicative_expression {
$$ = context->intermediate.addBinaryMath(EOpAdd, $1, $3, $2.line, context->symbolTable); $$ = context->intermediate.addBinaryMath(EOpAdd, $1, $3, @2, context->symbolTable);
if ($$ == 0) { if ($$ == 0) {
context->binaryOpError($2.line, "+", $1->getCompleteString(), $3->getCompleteString()); context->binaryOpError(@2, "+", $1->getCompleteString(), $3->getCompleteString());
context->recover(); context->recover();
$$ = $1; $$ = $1;
} }
} }
| additive_expression DASH multiplicative_expression { | additive_expression DASH multiplicative_expression {
$$ = context->intermediate.addBinaryMath(EOpSub, $1, $3, $2.line, context->symbolTable); $$ = context->intermediate.addBinaryMath(EOpSub, $1, $3, @2, context->symbolTable);
if ($$ == 0) { if ($$ == 0) {
context->binaryOpError($2.line, "-", $1->getCompleteString(), $3->getCompleteString()); context->binaryOpError(@2, "-", $1->getCompleteString(), $3->getCompleteString());
context->recover(); context->recover();
$$ = $1; $$ = $1;
} }
...@@ -773,43 +791,43 @@ shift_expression ...@@ -773,43 +791,43 @@ shift_expression
relational_expression relational_expression
: shift_expression { $$ = $1; } : shift_expression { $$ = $1; }
| relational_expression LEFT_ANGLE shift_expression { | relational_expression LEFT_ANGLE shift_expression {
$$ = context->intermediate.addBinaryMath(EOpLessThan, $1, $3, $2.line, context->symbolTable); $$ = context->intermediate.addBinaryMath(EOpLessThan, $1, $3, @2, context->symbolTable);
if ($$ == 0) { if ($$ == 0) {
context->binaryOpError($2.line, "<", $1->getCompleteString(), $3->getCompleteString()); context->binaryOpError(@2, "<", $1->getCompleteString(), $3->getCompleteString());
context->recover(); context->recover();
ConstantUnion *unionArray = new ConstantUnion[1]; ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setBConst(false); unionArray->setBConst(false);
$$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line); $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
} }
} }
| relational_expression RIGHT_ANGLE shift_expression { | relational_expression RIGHT_ANGLE shift_expression {
$$ = context->intermediate.addBinaryMath(EOpGreaterThan, $1, $3, $2.line, context->symbolTable); $$ = context->intermediate.addBinaryMath(EOpGreaterThan, $1, $3, @2, context->symbolTable);
if ($$ == 0) { if ($$ == 0) {
context->binaryOpError($2.line, ">", $1->getCompleteString(), $3->getCompleteString()); context->binaryOpError(@2, ">", $1->getCompleteString(), $3->getCompleteString());
context->recover(); context->recover();
ConstantUnion *unionArray = new ConstantUnion[1]; ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setBConst(false); unionArray->setBConst(false);
$$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line); $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
} }
} }
| relational_expression LE_OP shift_expression { | relational_expression LE_OP shift_expression {
$$ = context->intermediate.addBinaryMath(EOpLessThanEqual, $1, $3, $2.line, context->symbolTable); $$ = context->intermediate.addBinaryMath(EOpLessThanEqual, $1, $3, @2, context->symbolTable);
if ($$ == 0) { if ($$ == 0) {
context->binaryOpError($2.line, "<=", $1->getCompleteString(), $3->getCompleteString()); context->binaryOpError(@2, "<=", $1->getCompleteString(), $3->getCompleteString());
context->recover(); context->recover();
ConstantUnion *unionArray = new ConstantUnion[1]; ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setBConst(false); unionArray->setBConst(false);
$$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line); $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
} }
} }
| relational_expression GE_OP shift_expression { | relational_expression GE_OP shift_expression {
$$ = context->intermediate.addBinaryMath(EOpGreaterThanEqual, $1, $3, $2.line, context->symbolTable); $$ = context->intermediate.addBinaryMath(EOpGreaterThanEqual, $1, $3, @2, context->symbolTable);
if ($$ == 0) { if ($$ == 0) {
context->binaryOpError($2.line, ">=", $1->getCompleteString(), $3->getCompleteString()); context->binaryOpError(@2, ">=", $1->getCompleteString(), $3->getCompleteString());
context->recover(); context->recover();
ConstantUnion *unionArray = new ConstantUnion[1]; ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setBConst(false); unionArray->setBConst(false);
$$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line); $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
} }
} }
; ;
...@@ -817,23 +835,23 @@ relational_expression ...@@ -817,23 +835,23 @@ relational_expression
equality_expression equality_expression
: relational_expression { $$ = $1; } : relational_expression { $$ = $1; }
| equality_expression EQ_OP relational_expression { | equality_expression EQ_OP relational_expression {
$$ = context->intermediate.addBinaryMath(EOpEqual, $1, $3, $2.line, context->symbolTable); $$ = context->intermediate.addBinaryMath(EOpEqual, $1, $3, @2, context->symbolTable);
if ($$ == 0) { if ($$ == 0) {
context->binaryOpError($2.line, "==", $1->getCompleteString(), $3->getCompleteString()); context->binaryOpError(@2, "==", $1->getCompleteString(), $3->getCompleteString());
context->recover(); context->recover();
ConstantUnion *unionArray = new ConstantUnion[1]; ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setBConst(false); unionArray->setBConst(false);
$$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line); $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
} }
} }
| equality_expression NE_OP relational_expression { | equality_expression NE_OP relational_expression {
$$ = context->intermediate.addBinaryMath(EOpNotEqual, $1, $3, $2.line, context->symbolTable); $$ = context->intermediate.addBinaryMath(EOpNotEqual, $1, $3, @2, context->symbolTable);
if ($$ == 0) { if ($$ == 0) {
context->binaryOpError($2.line, "!=", $1->getCompleteString(), $3->getCompleteString()); context->binaryOpError(@2, "!=", $1->getCompleteString(), $3->getCompleteString());
context->recover(); context->recover();
ConstantUnion *unionArray = new ConstantUnion[1]; ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setBConst(false); unionArray->setBConst(false);
$$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line); $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
} }
} }
; ;
...@@ -853,13 +871,13 @@ inclusive_or_expression ...@@ -853,13 +871,13 @@ inclusive_or_expression
logical_and_expression logical_and_expression
: inclusive_or_expression { $$ = $1; } : inclusive_or_expression { $$ = $1; }
| logical_and_expression AND_OP inclusive_or_expression { | logical_and_expression AND_OP inclusive_or_expression {
$$ = context->intermediate.addBinaryMath(EOpLogicalAnd, $1, $3, $2.line, context->symbolTable); $$ = context->intermediate.addBinaryMath(EOpLogicalAnd, $1, $3, @2, context->symbolTable);
if ($$ == 0) { if ($$ == 0) {
context->binaryOpError($2.line, "&&", $1->getCompleteString(), $3->getCompleteString()); context->binaryOpError(@2, "&&", $1->getCompleteString(), $3->getCompleteString());
context->recover(); context->recover();
ConstantUnion *unionArray = new ConstantUnion[1]; ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setBConst(false); unionArray->setBConst(false);
$$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line); $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
} }
} }
; ;
...@@ -867,13 +885,13 @@ logical_and_expression ...@@ -867,13 +885,13 @@ logical_and_expression
logical_xor_expression logical_xor_expression
: logical_and_expression { $$ = $1; } : logical_and_expression { $$ = $1; }
| logical_xor_expression XOR_OP logical_and_expression { | logical_xor_expression XOR_OP logical_and_expression {
$$ = context->intermediate.addBinaryMath(EOpLogicalXor, $1, $3, $2.line, context->symbolTable); $$ = context->intermediate.addBinaryMath(EOpLogicalXor, $1, $3, @2, context->symbolTable);
if ($$ == 0) { if ($$ == 0) {
context->binaryOpError($2.line, "^^", $1->getCompleteString(), $3->getCompleteString()); context->binaryOpError(@2, "^^", $1->getCompleteString(), $3->getCompleteString());
context->recover(); context->recover();
ConstantUnion *unionArray = new ConstantUnion[1]; ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setBConst(false); unionArray->setBConst(false);
$$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line); $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
} }
} }
; ;
...@@ -881,13 +899,13 @@ logical_xor_expression ...@@ -881,13 +899,13 @@ logical_xor_expression
logical_or_expression logical_or_expression
: logical_xor_expression { $$ = $1; } : logical_xor_expression { $$ = $1; }
| logical_or_expression OR_OP logical_xor_expression { | logical_or_expression OR_OP logical_xor_expression {
$$ = context->intermediate.addBinaryMath(EOpLogicalOr, $1, $3, $2.line, context->symbolTable); $$ = context->intermediate.addBinaryMath(EOpLogicalOr, $1, $3, @2, context->symbolTable);
if ($$ == 0) { if ($$ == 0) {
context->binaryOpError($2.line, "||", $1->getCompleteString(), $3->getCompleteString()); context->binaryOpError(@2, "||", $1->getCompleteString(), $3->getCompleteString());
context->recover(); context->recover();
ConstantUnion *unionArray = new ConstantUnion[1]; ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setBConst(false); unionArray->setBConst(false);
$$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line); $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
} }
} }
; ;
...@@ -895,15 +913,15 @@ logical_or_expression ...@@ -895,15 +913,15 @@ logical_or_expression
conditional_expression conditional_expression
: logical_or_expression { $$ = $1; } : logical_or_expression { $$ = $1; }
| logical_or_expression QUESTION expression COLON assignment_expression { | logical_or_expression QUESTION expression COLON assignment_expression {
if (context->boolErrorCheck($2.line, $1)) if (context->boolErrorCheck(@2, $1))
context->recover(); context->recover();
$$ = context->intermediate.addSelection($1, $3, $5, $2.line); $$ = context->intermediate.addSelection($1, $3, $5, @2);
if ($3->getType() != $5->getType()) if ($3->getType() != $5->getType())
$$ = 0; $$ = 0;
if ($$ == 0) { if ($$ == 0) {
context->binaryOpError($2.line, ":", $3->getCompleteString(), $5->getCompleteString()); context->binaryOpError(@2, ":", $3->getCompleteString(), $5->getCompleteString());
context->recover(); context->recover();
$$ = $5; $$ = $5;
} }
...@@ -913,11 +931,11 @@ conditional_expression ...@@ -913,11 +931,11 @@ conditional_expression
assignment_expression assignment_expression
: conditional_expression { $$ = $1; } : conditional_expression { $$ = $1; }
| unary_expression assignment_operator assignment_expression { | unary_expression assignment_operator assignment_expression {
if (context->lValueErrorCheck($2.line, "assign", $1)) if (context->lValueErrorCheck(@2, "assign", $1))
context->recover(); context->recover();
$$ = context->intermediate.addAssign($2.op, $1, $3, $2.line); $$ = context->intermediate.addAssign($2.op, $1, $3, @2);
if ($$ == 0) { if ($$ == 0) {
context->assignError($2.line, "assign", $1->getCompleteString(), $3->getCompleteString()); context->assignError(@2, "assign", $1->getCompleteString(), $3->getCompleteString());
context->recover(); context->recover();
$$ = $1; $$ = $1;
} }
...@@ -925,11 +943,11 @@ assignment_expression ...@@ -925,11 +943,11 @@ assignment_expression
; ;
assignment_operator assignment_operator
: EQUAL { $$.line = $1.line; $$.op = EOpAssign; } : EQUAL { $$.op = EOpAssign; }
| MUL_ASSIGN { FRAG_VERT_ONLY("*=", $1.line); $$.line = $1.line; $$.op = EOpMulAssign; } | MUL_ASSIGN { FRAG_VERT_ONLY("*=", @1); $$.op = EOpMulAssign; }
| DIV_ASSIGN { FRAG_VERT_ONLY("/=", $1.line); $$.line = $1.line; $$.op = EOpDivAssign; } | DIV_ASSIGN { FRAG_VERT_ONLY("/=", @1); $$.op = EOpDivAssign; }
| ADD_ASSIGN { $$.line = $1.line; $$.op = EOpAddAssign; } | ADD_ASSIGN { $$.op = EOpAddAssign; }
| SUB_ASSIGN { $$.line = $1.line; $$.op = EOpSubAssign; } | SUB_ASSIGN { $$.op = EOpSubAssign; }
; ;
expression expression
...@@ -937,9 +955,9 @@ expression ...@@ -937,9 +955,9 @@ expression
$$ = $1; $$ = $1;
} }
| expression COMMA assignment_expression { | expression COMMA assignment_expression {
$$ = context->intermediate.addComma($1, $3, $2.line); $$ = context->intermediate.addComma($1, $3, @2);
if ($$ == 0) { if ($$ == 0) {
context->binaryOpError($2.line, ",", $1->getCompleteString(), $3->getCompleteString()); context->binaryOpError(@2, ",", $1->getCompleteString(), $3->getCompleteString());
context->recover(); context->recover();
$$ = $3; $$ = $3;
} }
...@@ -969,11 +987,11 @@ declaration ...@@ -969,11 +987,11 @@ declaration
{ {
TVariable variable(param.name, *param.type); TVariable variable(param.name, *param.type);
prototype = context->intermediate.growAggregate(prototype, context->intermediate.addSymbol(variable.getUniqueId(), variable.getName(), variable.getType(), $1.line), $1.line); prototype = context->intermediate.growAggregate(prototype, context->intermediate.addSymbol(variable.getUniqueId(), variable.getName(), variable.getType(), @1), @1);
} }
else else
{ {
prototype = context->intermediate.growAggregate(prototype, context->intermediate.addSymbol(0, "", *param.type, $1.line), $1.line); prototype = context->intermediate.growAggregate(prototype, context->intermediate.addSymbol(0, "", *param.type, @1), @1);
} }
} }
...@@ -989,11 +1007,11 @@ declaration ...@@ -989,11 +1007,11 @@ declaration
} }
| PRECISION precision_qualifier type_specifier_no_prec SEMICOLON { | PRECISION precision_qualifier type_specifier_no_prec SEMICOLON {
if (($2 == EbpHigh) && (context->shaderType == SH_FRAGMENT_SHADER) && !context->fragmentPrecisionHigh) { if (($2 == EbpHigh) && (context->shaderType == SH_FRAGMENT_SHADER) && !context->fragmentPrecisionHigh) {
context->error($1.line, "precision is not supported in fragment shader", "highp"); context->error(@1, "precision is not supported in fragment shader", "highp");
context->recover(); context->recover();
} }
if (!context->symbolTable.setDefaultPrecision( $3, $2 )) { if (!context->symbolTable.setDefaultPrecision( $3, $2 )) {
context->error($1.line, "illegal type argument for default precision qualifier", getBasicString($3.type)); context->error(@1, "illegal type argument for default precision qualifier", getBasicString($3.type));
context->recover(); context->recover();
} }
$$ = 0; $$ = 0;
...@@ -1013,12 +1031,12 @@ function_prototype ...@@ -1013,12 +1031,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, "overloaded functions must have the same return type", $1->getReturnType().getBasicString());
context->recover(); context->recover();
} }
for (size_t i = 0; i < prevDec->getParamCount(); ++i) { for (size_t 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, "overloaded functions must have the same parameter qualifiers", $1->getParam(i).type->getQualifierString());
context->recover(); context->recover();
} }
} }
...@@ -1030,7 +1048,6 @@ function_prototype ...@@ -1030,7 +1048,6 @@ function_prototype
// being redeclared. So, pass back up this declaration, not the one in the symbol table. // being redeclared. So, pass back up this declaration, not the one in the symbol table.
// //
$$.function = $1; $$.function = $1;
$$.line = $2.line;
// We're at the inner scope level of the function's arguments and body statement. // We're at the inner scope level of the function's arguments and body statement.
// Add the function prototype to the surrounding scope instead. // Add the function prototype to the surrounding scope instead.
...@@ -1066,7 +1083,7 @@ function_header_with_parameters ...@@ -1066,7 +1083,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, "cannot be an argument type except for '(void)'", "void");
context->recover(); context->recover();
delete $3.param.type; delete $3.param.type;
} else { } else {
...@@ -1080,11 +1097,11 @@ function_header_with_parameters ...@@ -1080,11 +1097,11 @@ 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, "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...
if (context->structQualifierErrorCheck($2.line, $1)) if (context->structQualifierErrorCheck(@2, $1))
context->recover(); context->recover();
// Add the function as a prototype after parsing it (we do not support recursion) // Add the function as a prototype after parsing it (we do not support recursion)
...@@ -1101,31 +1118,29 @@ parameter_declarator ...@@ -1101,31 +1118,29 @@ 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, "illegal use of type 'void'", $2.string->c_str());
context->recover(); context->recover();
} }
if (context->reservedErrorCheck($2.line, *$2.string)) if (context->reservedErrorCheck(@2, *$2.string))
context->recover(); context->recover();
TParameter param = {$2.string, new TType($1)}; TParameter param = {$2.string, new TType($1)};
$$.line = $2.line;
$$.param = param; $$.param = param;
} }
| type_specifier identifier LEFT_BRACKET constant_expression RIGHT_BRACKET { | type_specifier identifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
// Check that we can make an array out of this type // Check that we can make an array out of this type
if (context->arrayTypeErrorCheck($3.line, $1)) if (context->arrayTypeErrorCheck(@3, $1))
context->recover(); context->recover();
if (context->reservedErrorCheck($2.line, *$2.string)) if (context->reservedErrorCheck(@2, *$2.string))
context->recover(); context->recover();
int size; int size;
if (context->arraySizeErrorCheck($3.line, $4, size)) if (context->arraySizeErrorCheck(@3, $4, size))
context->recover(); context->recover();
$1.setArray(true, size); $1.setArray(true, size);
TType* type = new TType($1); TType* type = new TType($1);
TParameter param = { $2.string, type }; TParameter param = { $2.string, type };
$$.line = $2.line;
$$.param = param; $$.param = param;
} }
; ;
...@@ -1141,14 +1156,14 @@ parameter_declaration ...@@ -1141,14 +1156,14 @@ parameter_declaration
// //
: type_qualifier parameter_qualifier parameter_declarator { : type_qualifier parameter_qualifier parameter_declarator {
$$ = $3; $$ = $3;
if (context->paramErrorCheck($3.line, $1.qualifier, $2, $$.param.type)) if (context->paramErrorCheck(@3, $1.qualifier, $2, $$.param.type))
context->recover(); context->recover();
} }
| parameter_qualifier parameter_declarator { | parameter_qualifier parameter_declarator {
$$ = $2; $$ = $2;
if (context->parameterSamplerErrorCheck($2.line, $1, *$2.param.type)) if (context->parameterSamplerErrorCheck(@2, $1, *$2.param.type))
context->recover(); context->recover();
if (context->paramErrorCheck($2.line, EvqTemporary, $1, $$.param.type)) if (context->paramErrorCheck(@2, EvqTemporary, $1, $$.param.type))
context->recover(); context->recover();
} }
// //
...@@ -1156,14 +1171,14 @@ parameter_declaration ...@@ -1156,14 +1171,14 @@ parameter_declaration
// //
| type_qualifier parameter_qualifier parameter_type_specifier { | type_qualifier parameter_qualifier parameter_type_specifier {
$$ = $3; $$ = $3;
if (context->paramErrorCheck($3.line, $1.qualifier, $2, $$.param.type)) if (context->paramErrorCheck(@3, $1.qualifier, $2, $$.param.type))
context->recover(); context->recover();
} }
| parameter_qualifier parameter_type_specifier { | parameter_qualifier parameter_type_specifier {
$$ = $2; $$ = $2;
if (context->parameterSamplerErrorCheck($2.line, $1, *$2.param.type)) if (context->parameterSamplerErrorCheck(@2, $1, *$2.param.type))
context->recover(); context->recover();
if (context->paramErrorCheck($2.line, EvqTemporary, $1, $$.param.type)) if (context->paramErrorCheck(@2, EvqTemporary, $1, $$.param.type))
context->recover(); context->recover();
} }
; ;
...@@ -1197,80 +1212,80 @@ init_declarator_list ...@@ -1197,80 +1212,80 @@ 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, "undeclared identifier declared as invariant", $3.string->c_str());
context->recover(); context->recover();
} }
TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$3.string, TType($1.type), $3.line); TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$3.string, TType($1.type), @3);
$$.intermAggregate = context->intermediate.growAggregate($1.intermNode, symbol, $3.line); $$.intermAggregate = context->intermediate.growAggregate($1.intermNode, symbol, @3);
if (context->structQualifierErrorCheck($3.line, $$.type)) if (context->structQualifierErrorCheck(@3, $$.type))
context->recover(); context->recover();
if (context->nonInitConstErrorCheck($3.line, *$3.string, $$.type, false)) if (context->nonInitConstErrorCheck(@3, *$3.string, $$.type, false))
context->recover(); context->recover();
TVariable* variable = 0; TVariable* variable = 0;
if (context->nonInitErrorCheck($3.line, *$3.string, $$.type, variable)) if (context->nonInitErrorCheck(@3, *$3.string, $$.type, variable))
context->recover(); context->recover();
if (symbol && variable) if (symbol && variable)
symbol->setId(variable->getUniqueId()); symbol->setId(variable->getUniqueId());
} }
| init_declarator_list COMMA identifier LEFT_BRACKET RIGHT_BRACKET { | init_declarator_list COMMA identifier LEFT_BRACKET RIGHT_BRACKET {
if (context->structQualifierErrorCheck($3.line, $1.type)) if (context->structQualifierErrorCheck(@3, $1.type))
context->recover(); context->recover();
if (context->nonInitConstErrorCheck($3.line, *$3.string, $1.type, true)) if (context->nonInitConstErrorCheck(@3, *$3.string, $1.type, true))
context->recover(); context->recover();
$$ = $1; $$ = $1;
if (context->arrayTypeErrorCheck($4.line, $1.type) || context->arrayQualifierErrorCheck($4.line, $1.type)) if (context->arrayTypeErrorCheck(@4, $1.type) || context->arrayQualifierErrorCheck(@4, $1.type))
context->recover(); context->recover();
else { else {
$1.type.setArray(true); $1.type.setArray(true);
TVariable* variable; TVariable* variable;
if (context->arrayErrorCheck($4.line, *$3.string, $1.type, variable)) if (context->arrayErrorCheck(@4, *$3.string, $1.type, variable))
context->recover(); context->recover();
} }
} }
| init_declarator_list COMMA identifier LEFT_BRACKET constant_expression RIGHT_BRACKET { | init_declarator_list COMMA identifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
if (context->structQualifierErrorCheck($3.line, $1.type)) if (context->structQualifierErrorCheck(@3, $1.type))
context->recover(); context->recover();
if (context->nonInitConstErrorCheck($3.line, *$3.string, $1.type, true)) if (context->nonInitConstErrorCheck(@3, *$3.string, $1.type, true))
context->recover(); context->recover();
$$ = $1; $$ = $1;
if (context->arrayTypeErrorCheck($4.line, $1.type) || context->arrayQualifierErrorCheck($4.line, $1.type)) if (context->arrayTypeErrorCheck(@4, $1.type) || context->arrayQualifierErrorCheck(@4, $1.type))
context->recover(); context->recover();
else { else {
int size; int size;
if (context->arraySizeErrorCheck($4.line, $5, size)) if (context->arraySizeErrorCheck(@4, $5, size))
context->recover(); context->recover();
$1.type.setArray(true, size); $1.type.setArray(true, size);
TVariable* variable = 0; TVariable* variable = 0;
if (context->arrayErrorCheck($4.line, *$3.string, $1.type, variable)) if (context->arrayErrorCheck(@4, *$3.string, $1.type, variable))
context->recover(); context->recover();
TType type = TType($1.type); TType type = TType($1.type);
type.setArraySize(size); type.setArraySize(size);
$$.intermAggregate = context->intermediate.growAggregate($1.intermNode, context->intermediate.addSymbol(variable ? variable->getUniqueId() : 0, *$3.string, type, $3.line), $3.line); $$.intermAggregate = context->intermediate.growAggregate($1.intermNode, context->intermediate.addSymbol(variable ? variable->getUniqueId() : 0, *$3.string, type, @3), @3);
} }
} }
| init_declarator_list COMMA identifier EQUAL initializer { | init_declarator_list COMMA identifier EQUAL initializer {
if (context->structQualifierErrorCheck($3.line, $1.type)) if (context->structQualifierErrorCheck(@3, $1.type))
context->recover(); context->recover();
$$ = $1; $$ = $1;
TIntermNode* intermNode; TIntermNode* intermNode;
if (!context->executeInitializer($3.line, *$3.string, $1.type, $5, intermNode)) { if (!context->executeInitializer(@3, *$3.string, $1.type, $5, intermNode)) {
// //
// build the intermediate representation // build the intermediate representation
// //
if (intermNode) if (intermNode)
$$.intermAggregate = context->intermediate.growAggregate($1.intermNode, intermNode, $4.line); $$.intermAggregate = context->intermediate.growAggregate($1.intermNode, intermNode, @4);
else else
$$.intermAggregate = $1.intermAggregate; $$.intermAggregate = $1.intermAggregate;
} else { } else {
...@@ -1283,79 +1298,79 @@ init_declarator_list ...@@ -1283,79 +1298,79 @@ init_declarator_list
single_declaration single_declaration
: fully_specified_type { : fully_specified_type {
$$.type = $1; $$.type = $1;
$$.intermAggregate = context->intermediate.makeAggregate(context->intermediate.addSymbol(0, "", TType($1), $1.line), $1.line); $$.intermAggregate = context->intermediate.makeAggregate(context->intermediate.addSymbol(0, "", TType($1), @1), @1);
} }
| fully_specified_type identifier { | fully_specified_type identifier {
TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$2.string, TType($1), $2.line); TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$2.string, TType($1), @2);
$$.intermAggregate = context->intermediate.makeAggregate(symbol, $2.line); $$.intermAggregate = context->intermediate.makeAggregate(symbol, @2);
if (context->structQualifierErrorCheck($2.line, $$.type)) if (context->structQualifierErrorCheck(@2, $$.type))
context->recover(); context->recover();
if (context->nonInitConstErrorCheck($2.line, *$2.string, $$.type, false)) if (context->nonInitConstErrorCheck(@2, *$2.string, $$.type, false))
context->recover(); context->recover();
$$.type = $1; $$.type = $1;
TVariable* variable = 0; TVariable* variable = 0;
if (context->nonInitErrorCheck($2.line, *$2.string, $$.type, variable)) if (context->nonInitErrorCheck(@2, *$2.string, $$.type, variable))
context->recover(); context->recover();
if (variable && symbol) if (variable && symbol)
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, "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);
$$.intermAggregate = context->intermediate.makeAggregate(symbol, $2.line); $$.intermAggregate = context->intermediate.makeAggregate(symbol, @2);
$$.type = $1; $$.type = $1;
} }
| fully_specified_type identifier LEFT_BRACKET constant_expression RIGHT_BRACKET { | fully_specified_type identifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
TType type = TType($1); TType type = TType($1);
int size; int size;
if (context->arraySizeErrorCheck($2.line, $4, size)) if (context->arraySizeErrorCheck(@2, $4, size))
context->recover(); context->recover();
type.setArraySize(size); type.setArraySize(size);
TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$2.string, type, $2.line); TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$2.string, type, @2);
$$.intermAggregate = context->intermediate.makeAggregate(symbol, $2.line); $$.intermAggregate = context->intermediate.makeAggregate(symbol, @2);
if (context->structQualifierErrorCheck($2.line, $1)) if (context->structQualifierErrorCheck(@2, $1))
context->recover(); context->recover();
if (context->nonInitConstErrorCheck($2.line, *$2.string, $1, true)) if (context->nonInitConstErrorCheck(@2, *$2.string, $1, true))
context->recover(); context->recover();
$$.type = $1; $$.type = $1;
if (context->arrayTypeErrorCheck($3.line, $1) || context->arrayQualifierErrorCheck($3.line, $1)) if (context->arrayTypeErrorCheck(@3, $1) || context->arrayQualifierErrorCheck(@3, $1))
context->recover(); context->recover();
else { else {
int size; int size;
if (context->arraySizeErrorCheck($3.line, $4, size)) if (context->arraySizeErrorCheck(@3, $4, size))
context->recover(); context->recover();
$1.setArray(true, size); $1.setArray(true, size);
TVariable* variable = 0; TVariable* variable = 0;
if (context->arrayErrorCheck($3.line, *$2.string, $1, variable)) if (context->arrayErrorCheck(@3, *$2.string, $1, variable))
context->recover(); context->recover();
if (variable && symbol) if (variable && symbol)
symbol->setId(variable->getUniqueId()); symbol->setId(variable->getUniqueId());
} }
} }
| fully_specified_type identifier EQUAL initializer { | fully_specified_type identifier EQUAL initializer {
if (context->structQualifierErrorCheck($2.line, $1)) if (context->structQualifierErrorCheck(@2, $1))
context->recover(); context->recover();
$$.type = $1; $$.type = $1;
TIntermNode* intermNode; TIntermNode* intermNode;
if (!context->executeInitializer($2.line, *$2.string, $1, $4, intermNode)) { if (!context->executeInitializer(@2, *$2.string, $1, $4, intermNode)) {
// //
// Build intermediate representation // Build intermediate representation
// //
if(intermNode) if(intermNode)
$$.intermAggregate = context->intermediate.makeAggregate(intermNode, $3.line); $$.intermAggregate = context->intermediate.makeAggregate(intermNode, @3);
else else
$$.intermAggregate = 0; $$.intermAggregate = 0;
} else { } else {
...@@ -1364,21 +1379,21 @@ single_declaration ...@@ -1364,21 +1379,21 @@ single_declaration
} }
} }
| INVARIANT IDENTIFIER { | INVARIANT IDENTIFIER {
VERTEX_ONLY("invariant declaration", $1.line); VERTEX_ONLY("invariant declaration", @1);
if (context->globalErrorCheck($1.line, context->symbolTable.atGlobalLevel(), "invariant varying")) if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "invariant varying"))
context->recover(); context->recover();
$$.type.setBasic(EbtInvariant, EvqInvariantVaryingOut, $2.line); $$.type.setBasic(EbtInvariant, EvqInvariantVaryingOut, @2);
if (!$2.symbol) if (!$2.symbol)
{ {
context->error($2.line, "undeclared identifier declared as invariant", $2.string->c_str()); context->error(@2, "undeclared identifier declared as invariant", $2.string->c_str());
context->recover(); context->recover();
$$.intermAggregate = 0; $$.intermAggregate = 0;
} }
else else
{ {
TIntermSymbol *symbol = context->intermediate.addSymbol(0, *$2.string, TType($$.type), $2.line); TIntermSymbol *symbol = context->intermediate.addSymbol(0, *$2.string, TType($$.type), @2);
$$.intermAggregate = context->intermediate.makeAggregate(symbol, $2.line); $$.intermAggregate = context->intermediate.makeAggregate(symbol, @2);
} }
} }
...@@ -1404,15 +1419,15 @@ single_declaration ...@@ -1404,15 +1419,15 @@ single_declaration
// //
//input_or_output //input_or_output
// : INPUT { // : INPUT {
// if (context->globalErrorCheck($1.line, context->symbolTable.atGlobalLevel(), "input")) // if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "input"))
// context->recover(); // context->recover();
// UNPACK_ONLY("input", $1.line); // UNPACK_ONLY("input", @1);
// $$.qualifier = EvqInput; // $$.qualifier = EvqInput;
// } // }
// | OUTPUT { // | OUTPUT {
// if (context->globalErrorCheck($1.line, context->symbolTable.atGlobalLevel(), "output")) // if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "output"))
// context->recover(); // context->recover();
// PACK_ONLY("output", $1.line); // PACK_ONLY("output", @1);
// $$.qualifier = EvqOutput; // $$.qualifier = EvqOutput;
// } // }
// ; // ;
...@@ -1440,11 +1455,11 @@ single_declaration ...@@ -1440,11 +1455,11 @@ single_declaration
// //
//buffer_declaration //buffer_declaration
// : type_specifier IDENTIFIER COLON constant_expression SEMICOLON { // : type_specifier IDENTIFIER COLON constant_expression SEMICOLON {
// if (context->reservedErrorCheck($2.line, *$2.string, context)) // if (context->reservedErrorCheck(@2, *$2.string, context))
// 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, "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
// } // }
...@@ -1456,26 +1471,26 @@ fully_specified_type ...@@ -1456,26 +1471,26 @@ fully_specified_type
$$ = $1; $$ = $1;
if ($1.array) { if ($1.array) {
context->error($1.line, "not supported", "first-class array"); context->error(@1, "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, "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, "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, "cannot be bool or int", getQualifierString($1.qualifier));
context->recover(); context->recover();
} }
$$ = $2; $$ = $2;
...@@ -1485,34 +1500,34 @@ fully_specified_type ...@@ -1485,34 +1500,34 @@ fully_specified_type
type_qualifier type_qualifier
: CONST_QUAL { : CONST_QUAL {
$$.setBasic(EbtVoid, EvqConst, $1.line); $$.setBasic(EbtVoid, EvqConst, @1);
} }
| ATTRIBUTE { | ATTRIBUTE {
VERTEX_ONLY("attribute", $1.line); VERTEX_ONLY("attribute", @1);
if (context->globalErrorCheck($1.line, context->symbolTable.atGlobalLevel(), "attribute")) if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "attribute"))
context->recover(); context->recover();
$$.setBasic(EbtVoid, EvqAttribute, $1.line); $$.setBasic(EbtVoid, EvqAttribute, @1);
} }
| VARYING { | VARYING {
if (context->globalErrorCheck($1.line, context->symbolTable.atGlobalLevel(), "varying")) if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "varying"))
context->recover(); context->recover();
if (context->shaderType == SH_VERTEX_SHADER) if (context->shaderType == SH_VERTEX_SHADER)
$$.setBasic(EbtVoid, EvqVaryingOut, $1.line); $$.setBasic(EbtVoid, EvqVaryingOut, @1);
else else
$$.setBasic(EbtVoid, EvqVaryingIn, $1.line); $$.setBasic(EbtVoid, EvqVaryingIn, @1);
} }
| INVARIANT VARYING { | INVARIANT VARYING {
if (context->globalErrorCheck($1.line, context->symbolTable.atGlobalLevel(), "invariant varying")) if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "invariant varying"))
context->recover(); context->recover();
if (context->shaderType == SH_VERTEX_SHADER) if (context->shaderType == SH_VERTEX_SHADER)
$$.setBasic(EbtVoid, EvqInvariantVaryingOut, $1.line); $$.setBasic(EbtVoid, EvqInvariantVaryingOut, @1);
else else
$$.setBasic(EbtVoid, EvqInvariantVaryingIn, $1.line); $$.setBasic(EbtVoid, EvqInvariantVaryingIn, @1);
} }
| UNIFORM { | UNIFORM {
if (context->globalErrorCheck($1.line, context->symbolTable.atGlobalLevel(), "uniform")) if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "uniform"))
context->recover(); context->recover();
$$.setBasic(EbtVoid, EvqUniform, $1.line); $$.setBasic(EbtVoid, EvqUniform, @1);
} }
; ;
...@@ -1522,7 +1537,7 @@ type_specifier ...@@ -1522,7 +1537,7 @@ type_specifier
if ($$.precision == EbpUndefined) { if ($$.precision == EbpUndefined) {
$$.precision = context->symbolTable.getDefaultPrecision($1.type); $$.precision = context->symbolTable.getDefaultPrecision($1.type);
if (context->precisionErrorCheck($1.line, $$.precision, $1.type)) { if (context->precisionErrorCheck(@1, $$.precision, $1.type)) {
context->recover(); context->recover();
} }
} }
...@@ -1552,11 +1567,11 @@ type_specifier_no_prec ...@@ -1552,11 +1567,11 @@ type_specifier_no_prec
| type_specifier_nonarray LEFT_BRACKET constant_expression RIGHT_BRACKET { | type_specifier_nonarray LEFT_BRACKET constant_expression RIGHT_BRACKET {
$$ = $1; $$ = $1;
if (context->arrayTypeErrorCheck($2.line, $1)) if (context->arrayTypeErrorCheck(@2, $1))
context->recover(); context->recover();
else { else {
int size; int size;
if (context->arraySizeErrorCheck($2.line, $3, size)) if (context->arraySizeErrorCheck(@2, $3, size))
context->recover(); context->recover();
$$.setArray(true, size); $$.setArray(true, size);
} }
...@@ -1566,118 +1581,118 @@ type_specifier_no_prec ...@@ -1566,118 +1581,118 @@ type_specifier_no_prec
type_specifier_nonarray type_specifier_nonarray
: VOID_TYPE { : VOID_TYPE {
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtVoid, qual, $1.line); $$.setBasic(EbtVoid, qual, @1);
} }
| FLOAT_TYPE { | FLOAT_TYPE {
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line); $$.setBasic(EbtFloat, qual, @1);
} }
| INT_TYPE { | INT_TYPE {
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtInt, qual, $1.line); $$.setBasic(EbtInt, qual, @1);
} }
| BOOL_TYPE { | BOOL_TYPE {
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtBool, qual, $1.line); $$.setBasic(EbtBool, qual, @1);
} }
// | UNSIGNED INT_TYPE { // | UNSIGNED INT_TYPE {
// PACK_UNPACK_ONLY("unsigned", $1.line); // PACK_UNPACK_ONLY("unsigned", @1);
// TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; // TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
// $$.setBasic(EbtInt, qual, $1.line); // $$.setBasic(EbtInt, qual, @1);
// } // }
| VEC2 { | VEC2 {
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line); $$.setBasic(EbtFloat, qual, @1);
$$.setAggregate(2); $$.setAggregate(2);
} }
| VEC3 { | VEC3 {
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line); $$.setBasic(EbtFloat, qual, @1);
$$.setAggregate(3); $$.setAggregate(3);
} }
| VEC4 { | VEC4 {
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line); $$.setBasic(EbtFloat, qual, @1);
$$.setAggregate(4); $$.setAggregate(4);
} }
| BVEC2 { | BVEC2 {
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtBool, qual, $1.line); $$.setBasic(EbtBool, qual, @1);
$$.setAggregate(2); $$.setAggregate(2);
} }
| BVEC3 { | BVEC3 {
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtBool, qual, $1.line); $$.setBasic(EbtBool, qual, @1);
$$.setAggregate(3); $$.setAggregate(3);
} }
| BVEC4 { | BVEC4 {
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtBool, qual, $1.line); $$.setBasic(EbtBool, qual, @1);
$$.setAggregate(4); $$.setAggregate(4);
} }
| IVEC2 { | IVEC2 {
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtInt, qual, $1.line); $$.setBasic(EbtInt, qual, @1);
$$.setAggregate(2); $$.setAggregate(2);
} }
| IVEC3 { | IVEC3 {
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtInt, qual, $1.line); $$.setBasic(EbtInt, qual, @1);
$$.setAggregate(3); $$.setAggregate(3);
} }
| IVEC4 { | IVEC4 {
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtInt, qual, $1.line); $$.setBasic(EbtInt, qual, @1);
$$.setAggregate(4); $$.setAggregate(4);
} }
| MATRIX2 { | MATRIX2 {
FRAG_VERT_ONLY("mat2", $1.line); FRAG_VERT_ONLY("mat2", @1);
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line); $$.setBasic(EbtFloat, qual, @1);
$$.setAggregate(2, true); $$.setAggregate(2, true);
} }
| MATRIX3 { | MATRIX3 {
FRAG_VERT_ONLY("mat3", $1.line); FRAG_VERT_ONLY("mat3", @1);
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line); $$.setBasic(EbtFloat, qual, @1);
$$.setAggregate(3, true); $$.setAggregate(3, true);
} }
| MATRIX4 { | MATRIX4 {
FRAG_VERT_ONLY("mat4", $1.line); FRAG_VERT_ONLY("mat4", @1);
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line); $$.setBasic(EbtFloat, qual, @1);
$$.setAggregate(4, true); $$.setAggregate(4, true);
} }
| SAMPLER2D { | SAMPLER2D {
FRAG_VERT_ONLY("sampler2D", $1.line); FRAG_VERT_ONLY("sampler2D", @1);
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line); $$.setBasic(EbtSampler2D, qual, @1);
} }
| SAMPLERCUBE { | SAMPLERCUBE {
FRAG_VERT_ONLY("samplerCube", $1.line); FRAG_VERT_ONLY("samplerCube", @1);
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSamplerCube, qual, $1.line); $$.setBasic(EbtSamplerCube, qual, @1);
} }
| 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, "unsupported type", "samplerExternalOES");
context->recover(); context->recover();
} }
FRAG_VERT_ONLY("samplerExternalOES", $1.line); FRAG_VERT_ONLY("samplerExternalOES", @1);
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSamplerExternalOES, qual, $1.line); $$.setBasic(EbtSamplerExternalOES, qual, @1);
} }
| 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, "unsupported type", "sampler2DRect");
context->recover(); context->recover();
} }
FRAG_VERT_ONLY("sampler2DRect", $1.line); FRAG_VERT_ONLY("sampler2DRect", @1);
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2DRect, qual, $1.line); $$.setBasic(EbtSampler2DRect, qual, @1);
} }
| struct_specifier { | struct_specifier {
FRAG_VERT_ONLY("struct", $1.line); FRAG_VERT_ONLY("struct", @1);
$$ = $1; $$ = $1;
$$.qualifier = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.qualifier = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
} }
...@@ -1688,29 +1703,29 @@ type_specifier_nonarray ...@@ -1688,29 +1703,29 @@ type_specifier_nonarray
// //
TType& structure = static_cast<TVariable*>($1.symbol)->getType(); TType& structure = static_cast<TVariable*>($1.symbol)->getType();
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtStruct, qual, $1.line); $$.setBasic(EbtStruct, qual, @1);
$$.userDef = &structure; $$.userDef = &structure;
} }
; ;
struct_specifier struct_specifier
: STRUCT identifier LEFT_BRACE { if (context->enterStructDeclaration($2.line, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE { : STRUCT identifier LEFT_BRACE { if (context->enterStructDeclaration(@2, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE {
if (context->reservedErrorCheck($2.line, *$2.string)) if (context->reservedErrorCheck(@2, *$2.string))
context->recover(); context->recover();
TType* structure = new TType($5.structure, *$2.string); TType* structure = new TType($5.structure, *$2.string);
TVariable* userTypeDef = new TVariable($2.string, *structure, true); TVariable* userTypeDef = new TVariable($2.string, *structure, true);
if (! context->symbolTable.insert(*userTypeDef)) { if (! context->symbolTable.insert(*userTypeDef)) {
context->error($2.line, "redefinition", $2.string->c_str(), "struct"); context->error(@2, "redefinition", $2.string->c_str(), "struct");
context->recover(); context->recover();
} }
$$.setBasic(EbtStruct, EvqTemporary, $1.line); $$.setBasic(EbtStruct, EvqTemporary, @1);
$$.userDef = structure; $$.userDef = structure;
context->exitStructDeclaration(); context->exitStructDeclaration();
} }
| STRUCT LEFT_BRACE { if (context->enterStructDeclaration($2.line, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE { | STRUCT LEFT_BRACE { if (context->enterStructDeclaration(@2, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE {
TType* structure = new TType($4.structure, TString("")); TType* structure = new TType($4.structure, TString(""));
$$.setBasic(EbtStruct, EvqTemporary, $1.line); $$.setBasic(EbtStruct, EvqTemporary, @1);
$$.userDef = structure; $$.userDef = structure;
context->exitStructDeclaration(); context->exitStructDeclaration();
} }
...@@ -1726,7 +1741,7 @@ struct_declaration_list ...@@ -1726,7 +1741,7 @@ struct_declaration_list
TType* field = (*$2.structure)[i]; TType* field = (*$2.structure)[i];
for (size_t j = 0; j < $$.structure->size(); ++j) { for (size_t j = 0; j < $$.structure->size(); ++j) {
if ((*$$.structure)[j]->getFieldName() == field->getFieldName()) { if ((*$$.structure)[j]->getFieldName() == field->getFieldName()) {
context->error($2.line, "duplicate field name in structure:", "struct", field->getFieldName().c_str()); context->error(@2, "duplicate field name in structure:", "struct", field->getFieldName().c_str());
context->recover(); context->recover();
} }
} }
...@@ -1739,7 +1754,7 @@ struct_declaration ...@@ -1739,7 +1754,7 @@ struct_declaration
: type_specifier struct_declarator_list SEMICOLON { : type_specifier struct_declarator_list SEMICOLON {
$$ = $2; $$ = $2;
if (context->voidErrorCheck($1.line, (*$2.structure)[0]->getFieldName(), $1)) { if (context->voidErrorCheck(@1, (*$2.structure)[0]->getFieldName(), $1)) {
context->recover(); context->recover();
} }
for (unsigned int i = 0; i < $$.structure->size(); ++i) { for (unsigned int i = 0; i < $$.structure->size(); ++i) {
...@@ -1754,7 +1769,7 @@ struct_declaration ...@@ -1754,7 +1769,7 @@ struct_declaration
// don't allow arrays of arrays // don't allow arrays of arrays
if (type->isArray()) { if (type->isArray()) {
if (context->arrayTypeErrorCheck($1.line, $1)) if (context->arrayTypeErrorCheck(@1, $1))
context->recover(); context->recover();
} }
if ($1.array) if ($1.array)
...@@ -1764,7 +1779,7 @@ struct_declaration ...@@ -1764,7 +1779,7 @@ struct_declaration
type->setTypeName($1.userDef->getTypeName()); type->setTypeName($1.userDef->getTypeName());
} }
if (context->structNestingErrorCheck($1.line, *type)) { if (context->structNestingErrorCheck(@1, *type)) {
context->recover(); context->recover();
} }
} }
...@@ -1783,21 +1798,21 @@ struct_declarator_list ...@@ -1783,21 +1798,21 @@ struct_declarator_list
struct_declarator struct_declarator
: identifier { : identifier {
if (context->reservedErrorCheck($1.line, *$1.string)) if (context->reservedErrorCheck(@1, *$1.string))
context->recover(); context->recover();
$$ = new TType(EbtVoid, EbpUndefined); $$ = new TType(EbtVoid, EbpUndefined);
$$->setFieldName(*$1.string); $$->setFieldName(*$1.string);
} }
| identifier LEFT_BRACKET constant_expression RIGHT_BRACKET { | identifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
if (context->reservedErrorCheck($1.line, *$1.string)) if (context->reservedErrorCheck(@1, *$1.string))
context->recover(); context->recover();
$$ = new TType(EbtVoid, EbpUndefined); $$ = new TType(EbtVoid, EbpUndefined);
$$->setFieldName(*$1.string); $$->setFieldName(*$1.string);
int size; int size;
if (context->arraySizeErrorCheck($2.line, $3, size)) if (context->arraySizeErrorCheck(@2, $3, size))
context->recover(); context->recover();
$$->setArraySize(size); $$->setArraySize(size);
} }
...@@ -1831,7 +1846,7 @@ compound_statement ...@@ -1831,7 +1846,7 @@ compound_statement
| LEFT_BRACE { context->symbolTable.push(); } statement_list { context->symbolTable.pop(); } RIGHT_BRACE { | LEFT_BRACE { context->symbolTable.push(); } statement_list { context->symbolTable.pop(); } RIGHT_BRACE {
if ($3 != 0) { if ($3 != 0) {
$3->setOp(EOpSequence); $3->setOp(EOpSequence);
$3->setEndLine($5.line); $3->setLine(@$);
} }
$$ = $3; $$ = $3;
} }
...@@ -1855,7 +1870,7 @@ compound_statement_no_new_scope ...@@ -1855,7 +1870,7 @@ compound_statement_no_new_scope
| LEFT_BRACE statement_list RIGHT_BRACE { | LEFT_BRACE statement_list RIGHT_BRACE {
if ($2) { if ($2) {
$2->setOp(EOpSequence); $2->setOp(EOpSequence);
$2->setEndLine($3.line); $2->setLine(@$);
} }
$$ = $2; $$ = $2;
} }
...@@ -1863,10 +1878,10 @@ compound_statement_no_new_scope ...@@ -1863,10 +1878,10 @@ compound_statement_no_new_scope
statement_list statement_list
: statement { : statement {
$$ = context->intermediate.makeAggregate($1, 0); $$ = context->intermediate.makeAggregate($1, @$);
} }
| statement_list statement { | statement_list statement {
$$ = context->intermediate.growAggregate($1, $2, 0); $$ = context->intermediate.growAggregate($1, $2, @$);
} }
; ;
...@@ -1877,9 +1892,9 @@ expression_statement ...@@ -1877,9 +1892,9 @@ expression_statement
selection_statement selection_statement
: IF LEFT_PAREN expression RIGHT_PAREN selection_rest_statement { : IF LEFT_PAREN expression RIGHT_PAREN selection_rest_statement {
if (context->boolErrorCheck($1.line, $3)) if (context->boolErrorCheck(@1, $3))
context->recover(); context->recover();
$$ = context->intermediate.addSelection($3, $5, $1.line); $$ = context->intermediate.addSelection($3, $5, @1);
} }
; ;
...@@ -1905,12 +1920,12 @@ condition ...@@ -1905,12 +1920,12 @@ condition
} }
| fully_specified_type identifier EQUAL initializer { | fully_specified_type identifier EQUAL initializer {
TIntermNode* intermNode; TIntermNode* intermNode;
if (context->structQualifierErrorCheck($2.line, $1)) if (context->structQualifierErrorCheck(@2, $1))
context->recover(); context->recover();
if (context->boolErrorCheck($2.line, $1)) if (context->boolErrorCheck(@2, $1))
context->recover(); context->recover();
if (!context->executeInitializer($2.line, *$2.string, $1, $4, intermNode)) if (!context->executeInitializer(@2, *$2.string, $1, $4, intermNode))
$$ = $4; $$ = $4;
else { else {
context->recover(); context->recover();
...@@ -1922,19 +1937,19 @@ condition ...@@ -1922,19 +1937,19 @@ condition
iteration_statement iteration_statement
: WHILE LEFT_PAREN { context->symbolTable.push(); ++context->loopNestingLevel; } condition RIGHT_PAREN statement_no_new_scope { : WHILE LEFT_PAREN { context->symbolTable.push(); ++context->loopNestingLevel; } condition RIGHT_PAREN statement_no_new_scope {
context->symbolTable.pop(); context->symbolTable.pop();
$$ = context->intermediate.addLoop(ELoopWhile, 0, $4, 0, $6, $1.line); $$ = context->intermediate.addLoop(ELoopWhile, 0, $4, 0, $6, @1);
--context->loopNestingLevel; --context->loopNestingLevel;
} }
| DO { ++context->loopNestingLevel; } statement_with_scope WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON { | DO { ++context->loopNestingLevel; } statement_with_scope WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON {
if (context->boolErrorCheck($8.line, $6)) if (context->boolErrorCheck(@8, $6))
context->recover(); context->recover();
$$ = context->intermediate.addLoop(ELoopDoWhile, 0, $6, 0, $3, $4.line); $$ = context->intermediate.addLoop(ELoopDoWhile, 0, $6, 0, $3, @4);
--context->loopNestingLevel; --context->loopNestingLevel;
} }
| FOR LEFT_PAREN { context->symbolTable.push(); ++context->loopNestingLevel; } for_init_statement for_rest_statement RIGHT_PAREN statement_no_new_scope { | FOR LEFT_PAREN { context->symbolTable.push(); ++context->loopNestingLevel; } for_init_statement for_rest_statement RIGHT_PAREN statement_no_new_scope {
context->symbolTable.pop(); context->symbolTable.pop();
$$ = context->intermediate.addLoop(ELoopFor, $4, reinterpret_cast<TIntermTyped*>($5.node1), reinterpret_cast<TIntermTyped*>($5.node2), $7, $1.line); $$ = context->intermediate.addLoop(ELoopFor, $4, reinterpret_cast<TIntermTyped*>($5.node1), reinterpret_cast<TIntermTyped*>($5.node2), $7, @1);
--context->loopNestingLevel; --context->loopNestingLevel;
} }
; ;
...@@ -1971,39 +1986,39 @@ for_rest_statement ...@@ -1971,39 +1986,39 @@ 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, "continue statement only allowed in loops", "");
context->recover(); context->recover();
} }
$$ = context->intermediate.addBranch(EOpContinue, $1.line); $$ = context->intermediate.addBranch(EOpContinue, @1);
} }
| 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, "break statement only allowed in loops", "");
context->recover(); context->recover();
} }
$$ = context->intermediate.addBranch(EOpBreak, $1.line); $$ = context->intermediate.addBranch(EOpBreak, @1);
} }
| RETURN SEMICOLON { | RETURN SEMICOLON {
$$ = context->intermediate.addBranch(EOpReturn, $1.line); $$ = context->intermediate.addBranch(EOpReturn, @1);
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, "non-void function must return a value", "return");
context->recover(); context->recover();
} }
} }
| RETURN expression SEMICOLON { | RETURN expression SEMICOLON {
$$ = context->intermediate.addBranch(EOpReturn, $2, $1.line); $$ = context->intermediate.addBranch(EOpReturn, $2, @1);
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, "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, "function return is not matching type:", "return");
context->recover(); context->recover();
} }
} }
| DISCARD SEMICOLON { | DISCARD SEMICOLON {
FRAG_ONLY("discard", $1.line); FRAG_ONLY("discard", @1);
$$ = context->intermediate.addBranch(EOpKill, $1.line); $$ = context->intermediate.addBranch(EOpKill, @1);
} }
; ;
...@@ -2015,7 +2030,7 @@ translation_unit ...@@ -2015,7 +2030,7 @@ translation_unit
context->treeRoot = $$; context->treeRoot = $$;
} }
| translation_unit external_declaration { | translation_unit external_declaration {
$$ = context->intermediate.growAggregate($1, $2, 0); $$ = context->intermediate.growAggregate($1, $2, @$);
context->treeRoot = $$; context->treeRoot = $$;
} }
; ;
...@@ -2037,7 +2052,7 @@ function_definition ...@@ -2037,7 +2052,7 @@ function_definition
if (builtIn) if (builtIn)
{ {
context->error($1.line, "built-in functions cannot be redefined", function->getName().c_str()); context->error(@1, "built-in functions cannot be redefined", function->getName().c_str());
context->recover(); context->recover();
} }
...@@ -2051,7 +2066,7 @@ function_definition ...@@ -2051,7 +2066,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, "function already has a body", function->getName().c_str());
context->recover(); context->recover();
} }
prevDec->setDefined(); prevDec->setDefined();
...@@ -2061,11 +2076,11 @@ function_definition ...@@ -2061,11 +2076,11 @@ 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, "function cannot take any parameter(s)", function->getName().c_str());
context->recover(); context->recover();
} }
if (function->getReturnType().getBasicType() != EbtVoid) { if (function->getReturnType().getBasicType() != EbtVoid) {
context->error($1.line, "", function->getReturnType().getBasicString(), "main function cannot return a value"); context->error(@1, "", function->getReturnType().getBasicString(), "main function cannot return a value");
context->recover(); context->recover();
} }
} }
...@@ -2093,7 +2108,7 @@ function_definition ...@@ -2093,7 +2108,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, "redefinition", variable->getName().c_str());
context->recover(); context->recover();
delete variable; delete variable;
} }
...@@ -2105,13 +2120,14 @@ function_definition ...@@ -2105,13 +2120,14 @@ function_definition
paramNodes, paramNodes,
context->intermediate.addSymbol(variable->getUniqueId(), context->intermediate.addSymbol(variable->getUniqueId(),
variable->getName(), variable->getName(),
variable->getType(), $1.line), variable->getType(),
$1.line); @1),
@1);
} else { } else {
paramNodes = context->intermediate.growAggregate(paramNodes, context->intermediate.addSymbol(0, "", *param.type, $1.line), $1.line); paramNodes = context->intermediate.growAggregate(paramNodes, context->intermediate.addSymbol(0, "", *param.type, @1), @1);
} }
} }
context->intermediate.setAggregateOperator(paramNodes, EOpParameters, $1.line); context->intermediate.setAggregateOperator(paramNodes, EOpParameters, @1);
$1.intermAggregate = paramNodes; $1.intermAggregate = paramNodes;
context->loopNestingLevel = 0; context->loopNestingLevel = 0;
} }
...@@ -2119,12 +2135,12 @@ function_definition ...@@ -2119,12 +2135,12 @@ function_definition
//?? Check that all paths return a value if return type != void ? //?? Check that all paths return a value if return type != void ?
// May be best done as post process phase on intermediate code // May be best done as post process phase on intermediate code
if (context->currentFunctionType->getBasicType() != EbtVoid && ! context->functionReturnsValue) { if (context->currentFunctionType->getBasicType() != EbtVoid && ! context->functionReturnsValue) {
context->error($1.line, "function does not return a value:", "", $1.function->getName().c_str()); context->error(@1, "function does not return a value:", "", $1.function->getName().c_str());
context->recover(); context->recover();
} }
$$ = context->intermediate.growAggregate($1.intermAggregate, $3, 0); $$ = context->intermediate.growAggregate($1.intermAggregate, $3, @$);
context->intermediate.setAggregateOperator($$, EOpFunction, $1.line); context->intermediate.setAggregateOperator($$, EOpFunction, @1);
$$->getAsAggregate()->setName($1.function->getMangledName().c_str()); $$->getAsAggregate()->setName($1.function->getMangledName().c_str());
$$->getAsAggregate()->setType($1.function->getReturnType()); $$->getAsAggregate()->setType($1.function->getReturnType());
...@@ -2133,15 +2149,17 @@ function_definition ...@@ -2133,15 +2149,17 @@ function_definition
$$->getAsAggregate()->setOptimize(context->pragma().optimize); $$->getAsAggregate()->setOptimize(context->pragma().optimize);
$$->getAsAggregate()->setDebug(context->pragma().debug); $$->getAsAggregate()->setDebug(context->pragma().debug);
if ($3 && $3->getAsAggregate())
$$->getAsAggregate()->setEndLine($3->getAsAggregate()->getEndLine());
context->symbolTable.pop(); context->symbolTable.pop();
} }
; ;
%% %%
void yyerror(YYLTYPE* yylloc, TParseContext* context, const char* reason) {
context->error(*yylloc, reason, "");
context->recover();
}
int glslang_parse(TParseContext* context) { int glslang_parse(TParseContext* context) {
return yyparse(context); return yyparse(context);
} }
...@@ -792,7 +792,10 @@ WHICH GENERATES THE GLSL ES LEXER (glslang_lex.cpp). ...@@ -792,7 +792,10 @@ WHICH GENERATES THE GLSL ES LEXER (glslang_lex.cpp).
#pragma warning(disable : 4102) #pragma warning(disable : 4102)
#endif #endif
#define YY_USER_ACTION yylval->lex.line = yylineno; #define YY_USER_ACTION \
yylloc->first_file = yylloc->last_file = yycolumn; \
yylloc->first_line = yylloc->last_line = yylineno;
#define YY_INPUT(buf, result, max_size) \ #define YY_INPUT(buf, result, max_size) \
result = string_input(buf, max_size, yyscanner); result = string_input(buf, max_size, yyscanner);
...@@ -838,6 +841,8 @@ struct yyguts_t ...@@ -838,6 +841,8 @@ struct yyguts_t
YYSTYPE * yylval_r; YYSTYPE * yylval_r;
YYLTYPE * yylloc_r;
}; /* end struct yyguts_t */ }; /* end struct yyguts_t */
static int yy_init_globals (yyscan_t yyscanner ); static int yy_init_globals (yyscan_t yyscanner );
...@@ -846,6 +851,8 @@ static int yy_init_globals (yyscan_t yyscanner ); ...@@ -846,6 +851,8 @@ static int yy_init_globals (yyscan_t yyscanner );
* from bison output in section 1.*/ * from bison output in section 1.*/
# define yylval yyg->yylval_r # define yylval yyg->yylval_r
# define yylloc yyg->yylloc_r
int yylex_init (yyscan_t* scanner); int yylex_init (yyscan_t* scanner);
int yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner); int yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
...@@ -883,6 +890,10 @@ YYSTYPE * yyget_lval (yyscan_t yyscanner ); ...@@ -883,6 +890,10 @@ YYSTYPE * yyget_lval (yyscan_t yyscanner );
void yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner ); void yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner );
YYLTYPE *yyget_lloc (yyscan_t yyscanner );
void yyset_lloc (YYLTYPE * yylloc_param ,yyscan_t yyscanner );
/* Macros after this point can all be overridden by user definitions in /* Macros after this point can all be overridden by user definitions in
* section 1. * section 1.
*/ */
...@@ -989,10 +1000,10 @@ static int input (yyscan_t yyscanner ); ...@@ -989,10 +1000,10 @@ static int input (yyscan_t yyscanner );
#define YY_DECL_IS_OURS 1 #define YY_DECL_IS_OURS 1
extern int yylex \ extern int yylex \
(YYSTYPE * yylval_param ,yyscan_t yyscanner); (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner);
#define YY_DECL int yylex \ #define YY_DECL int yylex \
(YYSTYPE * yylval_param , yyscan_t yyscanner) (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner)
#endif /* !YY_DECL */ #endif /* !YY_DECL */
/* Code executed at the beginning of each rule, after yytext and yyleng /* Code executed at the beginning of each rule, after yytext and yyleng
...@@ -1021,6 +1032,8 @@ YY_DECL ...@@ -1021,6 +1032,8 @@ YY_DECL
yylval = yylval_param; yylval = yylval_param;
yylloc = yylloc_param;
if ( !yyg->yy_init ) if ( !yyg->yy_init )
{ {
yyg->yy_init = 1; yyg->yy_init = 1;
...@@ -2659,6 +2672,18 @@ void yyset_lval (YYSTYPE * yylval_param , yyscan_t yyscanner) ...@@ -2659,6 +2672,18 @@ void yyset_lval (YYSTYPE * yylval_param , yyscan_t yyscanner)
yylval = yylval_param; yylval = yylval_param;
} }
YYLTYPE *yyget_lloc (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
return yylloc;
}
void yyset_lloc (YYLTYPE * yylloc_param , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
yylloc = yylloc_param;
}
/* User-visible API */ /* User-visible API */
/* yylex_init is special because it creates the scanner itself, so it is /* yylex_init is special because it creates the scanner itself, so it is
...@@ -2840,7 +2865,8 @@ yy_size_t string_input(char* buf, yy_size_t max_size, yyscan_t yyscanner) { ...@@ -2840,7 +2865,8 @@ yy_size_t string_input(char* buf, yy_size_t max_size, yyscan_t yyscanner) {
yy_size_t len = token.type == pp::Token::LAST ? 0 : token.text.size(); yy_size_t len = token.type == pp::Token::LAST ? 0 : token.text.size();
if (len < max_size) if (len < max_size)
memcpy(buf, token.text.c_str(), len); memcpy(buf, token.text.c_str(), len);
yyset_lineno(EncodeSourceLoc(token.location.file, token.location.line),yyscanner); yyset_column(token.location.file,yyscanner);
yyset_lineno(token.location.line,yyscanner);
if (len >= max_size) if (len >= max_size)
YY_FATAL_ERROR("Input buffer overflow"); YY_FATAL_ERROR("Input buffer overflow");
...@@ -2866,18 +2892,11 @@ int check_type(yyscan_t yyscanner) { ...@@ -2866,18 +2892,11 @@ 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(yylineno, "Illegal use of reserved word", yytext, ""); yyextra->error(*yylloc, "Illegal use of reserved word", yytext, "");
yyextra->recover(); yyextra->recover();
return 0; return 0;
} }
void yyerror(TParseContext* context, const char* reason) {
struct yyguts_t* yyg = (struct yyguts_t*) context->scanner;
context->error(yylineno, reason, yytext);
context->recover();
}
int glslang_initialize(TParseContext* context) { int glslang_initialize(TParseContext* context) {
yyscan_t scanner = NULL; yyscan_t scanner = NULL;
if (yylex_init_extra(context,&scanner)) if (yylex_init_extra(context,&scanner))
...@@ -2900,7 +2919,8 @@ int glslang_finalize(TParseContext* context) { ...@@ -2900,7 +2919,8 @@ int glslang_finalize(TParseContext* context) {
int glslang_scan(size_t count, const char* const string[], const int length[], int glslang_scan(size_t count, const char* const string[], const int length[],
TParseContext* context) { TParseContext* context) {
yyrestart(NULL,context->scanner); yyrestart(NULL,context->scanner);
yyset_lineno(EncodeSourceLoc(0, 1),context->scanner); yyset_column(0,context->scanner);
yyset_lineno(1,context->scanner);
// Initialize preprocessor. // Initialize preprocessor.
if (!context->preprocessor.init(count, string, length)) if (!context->preprocessor.init(count, string, length))
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -31,6 +31,14 @@ ...@@ -31,6 +31,14 @@
This special exception was added by the Free Software Foundation in This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */ version 2.2 of Bison. */
/* "%code requires" blocks. */
#define YYLTYPE TSourceLoc
#define YYLTYPE_IS_DECLARED 1
/* Tokens. */ /* Tokens. */
#ifndef YYTOKENTYPE #ifndef YYTOKENTYPE
...@@ -141,7 +149,6 @@ typedef union YYSTYPE ...@@ -141,7 +149,6 @@ typedef union YYSTYPE
struct { struct {
TSourceLoc line;
union { union {
TString *string; TString *string;
float f; float f;
...@@ -151,7 +158,6 @@ typedef union YYSTYPE ...@@ -151,7 +158,6 @@ typedef union YYSTYPE
TSymbol* symbol; TSymbol* symbol;
} lex; } lex;
struct { struct {
TSourceLoc line;
TOperator op; TOperator op;
union { union {
TIntermNode* intermNode; TIntermNode* intermNode;
...@@ -180,4 +186,18 @@ typedef union YYSTYPE ...@@ -180,4 +186,18 @@ typedef union YYSTYPE
#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
typedef struct YYLTYPE
{
int first_line;
int first_column;
int last_line;
int last_column;
} YYLTYPE;
# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
# define YYLTYPE_IS_DECLARED 1
# define YYLTYPE_IS_TRIVIAL 1
#endif
...@@ -189,7 +189,9 @@ bool TOutputTraverser::visitUnary(Visit visit, TIntermUnary* node) ...@@ -189,7 +189,9 @@ bool TOutputTraverser::visitUnary(Visit visit, TIntermUnary* node)
case EOpAny: out << "any"; break; case EOpAny: out << "any"; break;
case EOpAll: out << "all"; break; case EOpAll: out << "all"; break;
default: out.message(EPrefixError, "Bad unary op"); default:
out.prefix(EPrefixError);
out << "Bad unary op";
} }
out << " (" << node->getCompleteString() << ")"; out << " (" << node->getCompleteString() << ")";
...@@ -204,7 +206,8 @@ bool TOutputTraverser::visitAggregate(Visit visit, TIntermAggregate* node) ...@@ -204,7 +206,8 @@ bool TOutputTraverser::visitAggregate(Visit visit, TIntermAggregate* node)
TInfoSinkBase& out = sink; TInfoSinkBase& out = sink;
if (node->getOp() == EOpNull) { if (node->getOp() == EOpNull) {
out.message(EPrefixError, "node is still EOpNull!"); out.prefix(EPrefixError);
out << "node is still EOpNull!";
return true; return true;
} }
...@@ -263,7 +266,9 @@ bool TOutputTraverser::visitAggregate(Visit visit, TIntermAggregate* node) ...@@ -263,7 +266,9 @@ bool TOutputTraverser::visitAggregate(Visit visit, TIntermAggregate* node)
case EOpDeclaration: out << "Declaration: "; break; case EOpDeclaration: out << "Declaration: "; break;
default: out.message(EPrefixError, "Bad aggregation op"); default:
out.prefix(EPrefixError);
out << "Bad aggregation op";
} }
if (node->getOp() != EOpSequence && node->getOp() != EOpParameters) if (node->getOp() != EOpSequence && node->getOp() != EOpParameters)
...@@ -334,7 +339,7 @@ void TOutputTraverser::visitConstantUnion(TIntermConstantUnion* node) ...@@ -334,7 +339,7 @@ void TOutputTraverser::visitConstantUnion(TIntermConstantUnion* node)
out << " (const int)\n"; out << " (const int)\n";
break; break;
default: default:
out.message(EPrefixInternalError, "Unknown constant", node->getLine()); out.message(EPrefixInternalError, node->getLine(), "Unknown constant");
break; break;
} }
} }
......
...@@ -206,10 +206,16 @@ class TIntermNode { ...@@ -206,10 +206,16 @@ class TIntermNode {
public: public:
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator) POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
TIntermNode() : line(0) {} TIntermNode() {
// TODO: Move this to TSourceLoc constructor
// after getting rid of TPublicType.
line.first_file = line.last_file = 0;
line.first_line = line.last_line = 0;
}
virtual ~TIntermNode() { }
TSourceLoc getLine() const { return line; } const TSourceLoc& getLine() const { return line; }
void setLine(TSourceLoc l) { line = l; } void setLine(const TSourceLoc& l) { line = l; }
virtual void traverse(TIntermTraverser*) = 0; virtual void traverse(TIntermTraverser*) = 0;
virtual TIntermTyped* getAsTyped() { return 0; } virtual TIntermTyped* getAsTyped() { return 0; }
...@@ -220,7 +226,6 @@ public: ...@@ -220,7 +226,6 @@ public:
virtual TIntermSelection* getAsSelectionNode() { return 0; } virtual TIntermSelection* getAsSelectionNode() { return 0; }
virtual TIntermSymbol* getAsSymbolNode() { return 0; } virtual TIntermSymbol* getAsSymbolNode() { return 0; }
virtual TIntermLoop* getAsLoopNode() { return 0; } virtual TIntermLoop* getAsLoopNode() { return 0; }
virtual ~TIntermNode() { }
protected: protected:
TSourceLoc line; TSourceLoc line;
...@@ -450,7 +455,7 @@ typedef TVector<int> TQualifierList; ...@@ -450,7 +455,7 @@ typedef TVector<int> TQualifierList;
// //
class TIntermAggregate : public TIntermOperator { class TIntermAggregate : public TIntermOperator {
public: public:
TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), endLine(0), useEmulatedFunction(false) { } TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), useEmulatedFunction(false) { }
TIntermAggregate(TOperator o) : TIntermOperator(o), useEmulatedFunction(false) { } TIntermAggregate(TOperator o) : TIntermOperator(o), useEmulatedFunction(false) { }
~TIntermAggregate() { } ~TIntermAggregate() { }
...@@ -470,9 +475,6 @@ public: ...@@ -470,9 +475,6 @@ public:
void setDebug(bool d) { debug = d; } void setDebug(bool d) { debug = d; }
bool getDebug() { return debug; } bool getDebug() { return debug; }
void setEndLine(TSourceLoc line) { endLine = line; }
TSourceLoc getEndLine() const { return endLine; }
void setUseEmulatedFunction() { useEmulatedFunction = true; } void setUseEmulatedFunction() { useEmulatedFunction = true; }
bool getUseEmulatedFunction() { return useEmulatedFunction; } bool getUseEmulatedFunction() { return useEmulatedFunction; }
...@@ -485,7 +487,6 @@ protected: ...@@ -485,7 +487,6 @@ protected:
bool optimize; bool optimize;
bool debug; bool debug;
TSourceLoc endLine;
// If set to true, replace the built-in function call with an emulated one // If set to true, replace the built-in function call with an emulated one
// to work around driver bugs. // to work around driver bugs.
......
...@@ -25,34 +25,33 @@ public: ...@@ -25,34 +25,33 @@ public:
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator) POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
TIntermediate(TInfoSink& i) : infoSink(i) { } TIntermediate(TInfoSink& i) : infoSink(i) { }
TIntermSymbol* addSymbol(int Id, const TString&, const TType&, TSourceLoc); TIntermSymbol* addSymbol(int Id, const TString&, const TType&, const TSourceLoc&);
TIntermTyped* addConversion(TOperator, const TType&, TIntermTyped*); TIntermTyped* addConversion(TOperator, const TType&, TIntermTyped*);
TIntermTyped* addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc, TSymbolTable&); TIntermTyped* addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc&, TSymbolTable&);
TIntermTyped* addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc); TIntermTyped* addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc&);
TIntermTyped* addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc); TIntermTyped* addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, const TSourceLoc&);
TIntermTyped* addUnaryMath(TOperator op, TIntermNode* child, TSourceLoc, TSymbolTable&); TIntermTyped* addUnaryMath(TOperator op, TIntermNode* child, const TSourceLoc&, TSymbolTable&);
TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right, TSourceLoc); TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right, const TSourceLoc&);
TIntermAggregate* makeAggregate(TIntermNode* node, TSourceLoc); TIntermAggregate* makeAggregate(TIntermNode* node, const TSourceLoc&);
TIntermAggregate* setAggregateOperator(TIntermNode*, TOperator, TSourceLoc); TIntermAggregate* setAggregateOperator(TIntermNode*, TOperator, const TSourceLoc&);
TIntermNode* addSelection(TIntermTyped* cond, TIntermNodePair code, TSourceLoc); TIntermNode* addSelection(TIntermTyped* cond, TIntermNodePair code, const TSourceLoc&);
TIntermTyped* addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, TSourceLoc); TIntermTyped* addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc&);
TIntermTyped* addComma(TIntermTyped* left, TIntermTyped* right, TSourceLoc); TIntermTyped* addComma(TIntermTyped* left, TIntermTyped* right, const TSourceLoc&);
TIntermConstantUnion* addConstantUnion(ConstantUnion*, const TType&, TSourceLoc); TIntermConstantUnion* addConstantUnion(ConstantUnion*, const TType&, const TSourceLoc&);
TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*) ; TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*) ;
bool parseConstTree(TSourceLoc, TIntermNode*, ConstantUnion*, TOperator, TSymbolTable&, TType, bool singleConstantParam = false); bool parseConstTree(const TSourceLoc&, TIntermNode*, ConstantUnion*, TOperator, TSymbolTable&, TType, bool singleConstantParam = false);
TIntermNode* addLoop(TLoopType, TIntermNode*, TIntermTyped*, TIntermTyped*, TIntermNode*, TSourceLoc); TIntermNode* addLoop(TLoopType, TIntermNode*, TIntermTyped*, TIntermTyped*, TIntermNode*, const TSourceLoc&);
TIntermBranch* addBranch(TOperator, TSourceLoc); TIntermBranch* addBranch(TOperator, const TSourceLoc&);
TIntermBranch* addBranch(TOperator, TIntermTyped*, TSourceLoc); TIntermBranch* addBranch(TOperator, TIntermTyped*, const TSourceLoc&);
TIntermTyped* addSwizzle(TVectorFields&, TSourceLoc); TIntermTyped* addSwizzle(TVectorFields&, const TSourceLoc&);
bool postProcess(TIntermNode*); bool postProcess(TIntermNode*);
void remove(TIntermNode*); void remove(TIntermNode*);
void outputTree(TIntermNode*); void outputTree(TIntermNode*);
protected:
TInfoSink& infoSink;
private: private:
void operator=(TIntermediate&); // prevent assignments void operator=(TIntermediate&); // prevent assignments
TInfoSink& infoSink;
}; };
#endif // _LOCAL_INTERMEDIATE_INCLUDED_ #endif // _LOCAL_INTERMEDIATE_INCLUDED_
...@@ -61,7 +61,7 @@ protected: ...@@ -61,7 +61,7 @@ protected:
void TConstTraverser::visitSymbol(TIntermSymbol* node) void TConstTraverser::visitSymbol(TIntermSymbol* node)
{ {
infoSink.info.message(EPrefixInternalError, "Symbol Node found in constant constructor", node->getLine()); infoSink.info.message(EPrefixInternalError, node->getLine(), "Symbol Node found in constant constructor");
return; return;
} }
...@@ -74,12 +74,12 @@ bool TConstTraverser::visitBinary(Visit visit, TIntermBinary* node) ...@@ -74,12 +74,12 @@ bool TConstTraverser::visitBinary(Visit visit, TIntermBinary* node)
TString buf; TString buf;
buf.append("'constructor' : assigning non-constant to "); buf.append("'constructor' : assigning non-constant to ");
buf.append(type.getCompleteString()); buf.append(type.getCompleteString());
infoSink.info.message(EPrefixError, buf.c_str(), node->getLine()); infoSink.info.message(EPrefixError, node->getLine(), buf.c_str());
error = true; error = true;
return false; return false;
} }
infoSink.info.message(EPrefixInternalError, "Binary Node found in constant constructor", node->getLine()); infoSink.info.message(EPrefixInternalError, node->getLine(), "Binary Node found in constant constructor");
return false; return false;
} }
...@@ -89,7 +89,7 @@ bool TConstTraverser::visitUnary(Visit visit, TIntermUnary* node) ...@@ -89,7 +89,7 @@ bool TConstTraverser::visitUnary(Visit visit, TIntermUnary* node)
TString buf; TString buf;
buf.append("'constructor' : assigning non-constant to "); buf.append("'constructor' : assigning non-constant to ");
buf.append(type.getCompleteString()); buf.append(type.getCompleteString());
infoSink.info.message(EPrefixError, buf.c_str(), node->getLine()); infoSink.info.message(EPrefixError, node->getLine(), buf.c_str());
error = true; error = true;
return false; return false;
} }
...@@ -100,7 +100,7 @@ bool TConstTraverser::visitAggregate(Visit visit, TIntermAggregate* node) ...@@ -100,7 +100,7 @@ bool TConstTraverser::visitAggregate(Visit visit, TIntermAggregate* node)
TString buf; TString buf;
buf.append("'constructor' : assigning non-constant to "); buf.append("'constructor' : assigning non-constant to ");
buf.append(type.getCompleteString()); buf.append(type.getCompleteString());
infoSink.info.message(EPrefixError, buf.c_str(), node->getLine()); infoSink.info.message(EPrefixError, node->getLine(), buf.c_str());
error = true; error = true;
return false; return false;
} }
...@@ -144,7 +144,7 @@ bool TConstTraverser::visitAggregate(Visit visit, TIntermAggregate* node) ...@@ -144,7 +144,7 @@ bool TConstTraverser::visitAggregate(Visit visit, TIntermAggregate* node)
bool TConstTraverser::visitSelection(Visit visit, TIntermSelection* node) bool TConstTraverser::visitSelection(Visit visit, TIntermSelection* node)
{ {
infoSink.info.message(EPrefixInternalError, "Selection Node found in constant constructor", node->getLine()); infoSink.info.message(EPrefixInternalError, node->getLine(), "Selection Node found in constant constructor");
error = true; error = true;
return false; return false;
} }
...@@ -213,14 +213,14 @@ void TConstTraverser::visitConstantUnion(TIntermConstantUnion* node) ...@@ -213,14 +213,14 @@ void TConstTraverser::visitConstantUnion(TIntermConstantUnion* node)
bool TConstTraverser::visitLoop(Visit visit, TIntermLoop* node) bool TConstTraverser::visitLoop(Visit visit, TIntermLoop* node)
{ {
infoSink.info.message(EPrefixInternalError, "Loop Node found in constant constructor", node->getLine()); infoSink.info.message(EPrefixInternalError, node->getLine(), "Loop Node found in constant constructor");
error = true; error = true;
return false; return false;
} }
bool TConstTraverser::visitBranch(Visit visit, TIntermBranch* node) bool TConstTraverser::visitBranch(Visit visit, TIntermBranch* node)
{ {
infoSink.info.message(EPrefixInternalError, "Branch Node found in constant constructor", node->getLine()); infoSink.info.message(EPrefixInternalError, node->getLine(), "Branch Node found in constant constructor");
error = true; error = true;
return false; return false;
} }
...@@ -230,7 +230,7 @@ bool TConstTraverser::visitBranch(Visit visit, TIntermBranch* node) ...@@ -230,7 +230,7 @@ bool TConstTraverser::visitBranch(Visit visit, TIntermBranch* node)
// Individual functions can be initialized to 0 to skip processing of that // Individual functions can be initialized to 0 to skip processing of that
// type of node. It's children will still be processed. // type of node. It's children will still be processed.
// //
bool TIntermediate::parseConstTree(TSourceLoc line, TIntermNode* root, ConstantUnion* unionArray, TOperator constructorType, TSymbolTable& symbolTable, TType t, bool singleConstantParam) bool TIntermediate::parseConstTree(const TSourceLoc& line, TIntermNode* root, ConstantUnion* unionArray, TOperator constructorType, TSymbolTable& symbolTable, TType t, bool singleConstantParam)
{ {
if (root == 0) if (root == 0)
return false; return false;
......
...@@ -10,8 +10,8 @@ void RestrictVertexShaderTiming::visitSymbol(TIntermSymbol* node) ...@@ -10,8 +10,8 @@ void RestrictVertexShaderTiming::visitSymbol(TIntermSymbol* node)
{ {
if (IsSampler(node->getBasicType())) { if (IsSampler(node->getBasicType())) {
++mNumErrors; ++mNumErrors;
mSink.prefix(EPrefixError); mSink.message(EPrefixError,
mSink.location(node->getLine()); node->getLine(),
mSink << "Samplers are not permitted in vertex shaders.\n"; "Samplers are not permitted in vertex shaders");
} }
} }
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