Refactor location tracking.

R=kbr@chromium.org

Review URL: https://codereview.appspot.com/9078046


Conflicts:

	src/compiler/glslang_tab.cpp
	src/compiler/glslang_tab.h

git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@2237 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/compiler/Common.h b/src/compiler/Common.h
index 27a5598..532486a 100644
--- a/src/compiler/Common.h
+++ b/src/compiler/Common.h
@@ -14,24 +14,12 @@
 
 #include "compiler/PoolAlloc.h"
 
-// We need two pieces of information to report errors/warnings - string and
-// line number. We encode these into a single int so that it can be easily
-// incremented/decremented by lexer. The right SOURCE_LOC_LINE_SIZE bits store
-// line number while the rest store the string number. Since the shaders are
-// usually small, we should not run out of memory. SOURCE_LOC_LINE_SIZE
-// 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;
-}
+struct TSourceLoc {
+    int first_file;
+    int first_line;
+    int last_file;
+    int last_line;
+};
 
 //
 // Put POOL_ALLOCATOR_NEW_DELETE in base classes to make them use this scheme.
diff --git a/src/compiler/Compiler.cpp b/src/compiler/Compiler.cpp
index 804d332..395fb2a 100644
--- a/src/compiler/Compiler.cpp
+++ b/src/compiler/Compiler.cpp
@@ -62,7 +62,8 @@
 
         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;
         }
     }
@@ -170,8 +171,10 @@
     // We preserve symbols at the built-in level from compile-to-compile.
     // Start pushing the user-defined symbols at global level.
     symbolTable.push();
-    if (!symbolTable.atGlobalLevel())
-        infoSink.info.message(EPrefixInternalError, "Wrong symbol table level");
+    if (!symbolTable.atGlobalLevel()) {
+        infoSink.info.prefix(EPrefixInternalError);
+        infoSink.info << "Wrong symbol table level";
+    }
 
     // Parse shader.
     bool success =
@@ -217,7 +220,8 @@
             if (compileOptions & SH_ENFORCE_PACKING_RESTRICTIONS) {
                 success = enforcePackingRestrictions();
                 if (!success) {
-                    infoSink.info.message(EPrefixError, "too many uniforms");
+                    infoSink.info.prefix(EPrefixError);
+                    infoSink.info << "too many uniforms";
                 }
             }
         }
@@ -272,10 +276,12 @@
         case DetectRecursion::kErrorNone:
             return true;
         case DetectRecursion::kErrorMissingMain:
-            infoSink.info.message(EPrefixError, "Missing main()");
+            infoSink.info.prefix(EPrefixError);
+            infoSink.info << "Missing main()";
             return false;
         case DetectRecursion::kErrorRecursion:
-            infoSink.info.message(EPrefixError, "Function recursion detected");
+            infoSink.info.prefix(EPrefixError);
+            infoSink.info << "Function recursion detected";
             return false;
         default:
             UNREACHABLE();
diff --git a/src/compiler/Diagnostics.cpp b/src/compiler/Diagnostics.cpp
index 06f370d..8a38c41 100644
--- a/src/compiler/Diagnostics.cpp
+++ b/src/compiler/Diagnostics.cpp
@@ -46,7 +46,7 @@
     TInfoSinkBase& sink = mInfoSink.info;
     /* VC++ format: file(linenum) : error #: 'token' : extrainfo */
     sink.prefix(prefix);
-    sink.location(EncodeSourceLoc(loc.file, loc.line));
+    sink.location(loc.file, loc.line);
     sink << "'" << token <<  "' : " << reason << " " << extra << "\n";
 }
 
diff --git a/src/compiler/InfoSink.cpp b/src/compiler/InfoSink.cpp
index ba32f78..d20a6c0 100644
--- a/src/compiler/InfoSink.cpp
+++ b/src/compiler/InfoSink.cpp
@@ -6,8 +6,8 @@
 
 #include "compiler/InfoSink.h"
 
-void TInfoSinkBase::prefix(TPrefixType message) {
-    switch(message) {
+void TInfoSinkBase::prefix(TPrefixType p) {
+    switch(p) {
         case EPrefixNone:
             break;
         case EPrefixWarning:
@@ -31,29 +31,24 @@
     }
 }
 
-void TInfoSinkBase::location(TSourceLoc loc) {
-    int string = 0, line = 0;
-    DecodeSourceLoc(loc, &string, &line);
-
+void TInfoSinkBase::location(int file, int line) {
     TPersistStringStream stream;
     if (line)
-        stream << string << ":" << line;
+        stream << file << ":" << line;
     else
-        stream << string << ":? ";
+        stream << file << ":? ";
     stream << ": ";
 
     sink.append(stream.str());
 }
 
-void TInfoSinkBase::message(TPrefixType message, const char* s) {
-    prefix(message);
-    sink.append(s);
-    sink.append("\n");
+void TInfoSinkBase::location(const TSourceLoc& loc) {
+    location(loc.first_file, loc.first_line);
 }
 
-void TInfoSinkBase::message(TPrefixType message, const char* s, TSourceLoc loc) {
-    prefix(message);
+void TInfoSinkBase::message(TPrefixType p, const TSourceLoc& loc, const char* m) {
+    prefix(p);
     location(loc);
-    sink.append(s);
+    sink.append(m);
     sink.append("\n");
 }
diff --git a/src/compiler/InfoSink.h b/src/compiler/InfoSink.h
index e2224e9..6888838 100644
--- a/src/compiler/InfoSink.h
+++ b/src/compiler/InfoSink.h
@@ -96,10 +96,10 @@
     const TPersistString& str() const { return sink; }
     const char* c_str() const { return sink.c_str(); }
 
-    void prefix(TPrefixType message);
-    void location(TSourceLoc loc);
-    void message(TPrefixType message, const char* s);
-    void message(TPrefixType message, const char* s, TSourceLoc loc);
+    void prefix(TPrefixType p);
+    void location(int file, int line);
+    void location(const TSourceLoc& loc);
+    void message(TPrefixType p, const TSourceLoc& loc, const char* m);
 
 private:
     TPersistString sink;
diff --git a/src/compiler/Intermediate.cpp b/src/compiler/Intermediate.cpp
index 11ca25e..53aaa0f 100644
--- a/src/compiler/Intermediate.cpp
+++ b/src/compiler/Intermediate.cpp
@@ -131,7 +131,7 @@
 //
 // 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);
     node->setLine(line);
@@ -144,7 +144,7 @@
 //
 // 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) {
         case EOpEqual:
@@ -200,8 +200,6 @@
     // one and promote it to the right type.
     //
     TIntermBinary* node = new TIntermBinary(op);
-    if (line == 0)
-        line = right->getLine();
     node->setLine(line);
 
     node->setLeft(left);
@@ -230,15 +228,13 @@
 //
 // 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
     // from right to left.
     //
     TIntermBinary* node = new TIntermBinary(op);
-    if (line == 0)
-        line = left->getLine();
     node->setLine(line);
 
     TIntermTyped* child = addConversion(op, left->getType(), right);
@@ -260,11 +256,9 @@
 // Returns the added 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);
-    if (line == 0)
-        line = index->getLine();
     node->setLine(line);
     node->setLeft(base);
     node->setRight(index);
@@ -279,13 +273,13 @@
 //
 // 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;
     TIntermTyped* child = childNode->getAsTyped();
 
     if (child == 0) {
-        infoSink.info.message(EPrefixInternalError, "Bad type in AddUnaryMath", line);
+        infoSink.info.message(EPrefixInternalError, line, "Bad type in AddUnaryMath");
         return 0;
     }
 
@@ -348,8 +342,6 @@
     // Make a new node for the operator.
     //
     node = new TIntermUnary(op);
-    if (line == 0)
-        line = child->getLine();
     node->setLine(line);
     node->setOperand(child);
 
@@ -376,7 +368,7 @@
 // Returns an aggregate node, which could be the one passed in if
 // 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;
 
@@ -391,8 +383,6 @@
             //
             aggNode = new TIntermAggregate();
             aggNode->getSequence().push_back(node);
-            if (line == 0)
-                line = node->getLine();
         }
     } else
         aggNode = new TIntermAggregate();
@@ -401,8 +391,7 @@
     // Set the operator.
     //
     aggNode->setOp(op);
-    if (line != 0)
-        aggNode->setLine(line);
+    aggNode->setLine(line);
 
     return aggNode;
 }
@@ -491,7 +480,7 @@
                     case EbtInt:   newOp = EOpConvIntToFloat;  break;
                     case EbtBool:  newOp = EOpConvBoolToFloat; break;
                     default:
-                        infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine());
+                        infoSink.info.message(EPrefixInternalError, node->getLine(), "Bad promotion node");
                         return 0;
                 }
                 break;
@@ -500,7 +489,7 @@
                     case EbtInt:   newOp = EOpConvIntToBool;   break;
                     case EbtFloat: newOp = EOpConvFloatToBool; break;
                     default:
-                        infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine());
+                        infoSink.info.message(EPrefixInternalError, node->getLine(), "Bad promotion node");
                         return 0;
                 }
                 break;
@@ -509,12 +498,12 @@
                     case EbtBool:   newOp = EOpConvBoolToInt;  break;
                     case EbtFloat:  newOp = EOpConvFloatToInt; break;
                     default:
-                        infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine());
+                        infoSink.info.message(EPrefixInternalError, node->getLine(), "Bad promotion node");
                         return 0;
                 }
                 break;
             default:
-                infoSink.info.message(EPrefixInternalError, "Bad promotion type", node->getLine());
+                infoSink.info.message(EPrefixInternalError, node->getLine(), "Bad promotion type");
                 return 0;
         }
 
@@ -534,7 +523,7 @@
 // Returns the resulting aggregate, unless 0 was passed in for
 // 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)
         return 0;
@@ -551,8 +540,7 @@
     if (right)
         aggNode->getSequence().push_back(right);
 
-    if (line != 0)
-        aggNode->setLine(line);
+    aggNode->setLine(line);
 
     return aggNode;
 }
@@ -562,18 +550,14 @@
 //
 // 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)
         return 0;
 
     TIntermAggregate* aggNode = new TIntermAggregate;
     aggNode->getSequence().push_back(node);
-
-    if (line != 0)
-        aggNode->setLine(line);
-    else
-        aggNode->setLine(node->getLine());
+    aggNode->setLine(line);
 
     return aggNode;
 }
@@ -585,7 +569,7 @@
 //
 // 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
@@ -606,7 +590,7 @@
 }
 
 
-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) {
         return right;
@@ -626,7 +610,7 @@
 //
 // 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.
@@ -669,7 +653,7 @@
 // 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);
     node->setLine(line);
@@ -677,7 +661,7 @@
     return node;
 }
 
-TIntermTyped* TIntermediate::addSwizzle(TVectorFields& fields, TSourceLoc line)
+TIntermTyped* TIntermediate::addSwizzle(TVectorFields& fields, const TSourceLoc& line)
 {
 
     TIntermAggregate* node = new TIntermAggregate(EOpSequence);
@@ -700,7 +684,7 @@
 //
 // 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);
     node->setLine(line);
@@ -711,12 +695,12 @@
 //
 // Add branches.
 //
-TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TSourceLoc line)
+TIntermBranch* TIntermediate::addBranch(TOperator branchOp, const TSourceLoc& 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);
     node->setLine(line);
@@ -861,7 +845,7 @@
 {
     // This function only handles scalars, vectors, and matrices.
     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;
     }
 
@@ -966,7 +950,7 @@
                     setType(TType(basicType, higherPrecision, EvqTemporary, size, false));
                 }
             } else {
-                infoSink.info.message(EPrefixInternalError, "Missing elses", getLine());
+                infoSink.info.message(EPrefixInternalError, getLine(), "Missing elses");
                 return false;
             }
             break;
@@ -995,7 +979,7 @@
                     setType(TType(basicType, higherPrecision, EvqTemporary, size, false));
                 }
             } else {
-                infoSink.info.message(EPrefixInternalError, "Missing elses", getLine());
+                infoSink.info.message(EPrefixInternalError, getLine(), "Missing elses");
                 return false;
             }
             break;
@@ -1139,7 +1123,7 @@
                 break;
             case EOpMatrixTimesMatrix:
                 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;
                 }
                 {// support MSVC++6.0
@@ -1162,7 +1146,7 @@
                         switch (getType().getBasicType()) {
             case EbtFloat:
                 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);
                 } else
                     tempConstArray[i].setFConst(unionArray[i].getFConst() / rightUnionArray[i].getFConst());
@@ -1170,13 +1154,13 @@
 
             case EbtInt:
                 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);
                 } else
                     tempConstArray[i].setIConst(unionArray[i].getIConst() / rightUnionArray[i].getIConst());
                 break;
             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;
                         }
                     }
@@ -1185,7 +1169,7 @@
 
             case EOpMatrixTimesVector:
                 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;
                 }
                 tempConstArray = new ConstantUnion[getNominalSize()];
@@ -1206,7 +1190,7 @@
 
             case EOpVectorTimesMatrix:
                 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;
                 }
 
@@ -1334,7 +1318,7 @@
                 return tempNode;
 
             default:
-                infoSink.info.message(EPrefixInternalError, "Invalid operator for constant folding", getLine());
+                infoSink.info.message(EPrefixInternalError, getLine(), "Invalid operator for constant folding");
                 return 0;
         }
         tempNode = new TIntermConstantUnion(tempConstArray, returnType);
@@ -1354,7 +1338,7 @@
                         case EbtFloat: tempConstArray[i].setFConst(-unionArray[i].getFConst()); break;
                         case EbtInt:   tempConstArray[i].setIConst(-unionArray[i].getIConst()); break;
                         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;
                     }
                     break;
@@ -1362,7 +1346,7 @@
                     switch (getType().getBasicType()) {
                         case EbtBool:  tempConstArray[i].setBConst(!unionArray[i].getBConst()); break;
                         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;
                     }
                     break;
@@ -1397,7 +1381,7 @@
                         leftUnionArray[i].setFConst(static_cast<float>(node->getFConst(i)));
                         break;
                     default:
-                        infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
+                        infoSink.info.message(EPrefixInternalError, node->getLine(), "Cannot promote");
                         return 0;
                 }
                 break;
@@ -1413,7 +1397,7 @@
                         leftUnionArray[i].setIConst(static_cast<int>(node->getFConst(i)));
                         break;
                     default:
-                        infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
+                        infoSink.info.message(EPrefixInternalError, node->getLine(), "Cannot promote");
                         return 0;
                 }
                 break;
@@ -1429,13 +1413,13 @@
                         leftUnionArray[i].setBConst(node->getFConst(i) != 0.0f);
                         break;
                     default:
-                        infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
+                        infoSink.info.message(EPrefixInternalError, node->getLine(), "Cannot promote");
                         return 0;
                 }
 
                 break;
             default:
-                infoSink.info.message(EPrefixInternalError, "Incorrect data type found", node->getLine());
+                infoSink.info.message(EPrefixInternalError, node->getLine(), "Incorrect data type found");
                 return 0;
         }
 
diff --git a/src/compiler/OutputHLSL.cpp b/src/compiler/OutputHLSL.cpp
index cb686fe..078cad6 100644
--- a/src/compiler/OutputHLSL.cpp
+++ b/src/compiler/OutputHLSL.cpp
@@ -1566,7 +1566,7 @@
         {
             if (mInsideFunction)
             {
-                outputLineDirective(node->getLine());
+                outputLineDirective(node->getLine().first_line);
                 out << "{\n";
 
                 mScopeDepth++;
@@ -1583,7 +1583,7 @@
 
             for (TIntermSequence::iterator sit = node->getSequence().begin(); sit != node->getSequence().end(); sit++)
             {
-                outputLineDirective((*sit)->getLine());
+                outputLineDirective((*sit)->getLine().first_line);
 
                 traverseStatements(*sit);
 
@@ -1592,7 +1592,7 @@
 
             if (mInsideFunction)
             {
-                outputLineDirective(node->getEndLine());
+                outputLineDirective(node->getLine().last_line);
                 out << "}\n";
 
                 mScopeDepth--;
@@ -2089,7 +2089,7 @@
 
         out << ")\n";
         
-        outputLineDirective(node->getLine());
+        outputLineDirective(node->getLine().first_line);
         out << "{\n";
 
         if (node->getTrueBlock())
@@ -2097,20 +2097,20 @@
             traverseStatements(node->getTrueBlock());
         }
 
-        outputLineDirective(node->getLine());
+        outputLineDirective(node->getLine().first_line);
         out << ";\n}\n";
 
         if (node->getFalseBlock())
         {
             out << "else\n";
 
-            outputLineDirective(node->getFalseBlock()->getLine());
+            outputLineDirective(node->getFalseBlock()->getLine().first_line);
             out << "{\n";
 
-            outputLineDirective(node->getFalseBlock()->getLine());
+            outputLineDirective(node->getFalseBlock()->getLine().first_line);
             traverseStatements(node->getFalseBlock());
 
-            outputLineDirective(node->getFalseBlock()->getLine());
+            outputLineDirective(node->getFalseBlock()->getLine().first_line);
             out << ";\n}\n";
         }
     }
@@ -2146,7 +2146,7 @@
     {
         out << "{do\n";
 
-        outputLineDirective(node->getLine());
+        outputLineDirective(node->getLine().first_line);
         out << "{\n";
     }
     else
@@ -2174,7 +2174,7 @@
 
         out << ")\n";
         
-        outputLineDirective(node->getLine());
+        outputLineDirective(node->getLine().first_line);
         out << "{\n";
     }
 
@@ -2183,12 +2183,12 @@
         traverseStatements(node->getBody());
     }
 
-    outputLineDirective(node->getLine());
+    outputLineDirective(node->getLine().first_line);
     out << ";}\n";
 
     if (node->getType() == ELoopDoWhile)
     {
-        outputLineDirective(node->getCondition()->getLine());
+        outputLineDirective(node->getCondition()->getLine().first_line);
         out << "while(\n";
 
         node->getCondition()->traverse(this);
@@ -2460,7 +2460,7 @@
                 out << increment;
                 out << ")\n";
                 
-                outputLineDirective(node->getLine());
+                outputLineDirective(node->getLine().first_line);
                 out << "{\n";
 
                 if (node->getBody())
@@ -2468,7 +2468,7 @@
                     node->getBody()->traverse(this);
                 }
 
-                outputLineDirective(node->getLine());
+                outputLineDirective(node->getLine().first_line);
                 out << ";}\n";
 
                 if (!firstLoopFragment)
diff --git a/src/compiler/ParseHelper.cpp b/src/compiler/ParseHelper.cpp
index be81ede..2dbda03 100644
--- a/src/compiler/ParseHelper.cpp
+++ b/src/compiler/ParseHelper.cpp
@@ -22,7 +22,7 @@
 // Look at a '.' field selector string and change it into offsets
 // 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();
     if (fields.num > 4) {
@@ -115,7 +115,7 @@
 // Look at a '.' field selector string and change it into offsets
 // 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.wholeCol = false;
@@ -175,22 +175,24 @@
 //
 // 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* extraInfo)
 {
     pp::SourceLocation srcLoc;
-    DecodeSourceLoc(loc, &srcLoc.file, &srcLoc.line);
+    srcLoc.file = loc.first_file;
+    srcLoc.line = loc.first_line;
     diagnostics.writeInfo(pp::Diagnostics::ERROR,
                           srcLoc, reason, token, extraInfo);
 
 }
 
-void TParseContext::warning(TSourceLoc loc,
+void TParseContext::warning(const TSourceLoc& loc,
                             const char* reason, const char* token,
                             const char* extraInfo) {
     pp::SourceLocation srcLoc;
-    DecodeSourceLoc(loc, &srcLoc.file, &srcLoc.line);
+    srcLoc.file = loc.first_file;
+    srcLoc.line = loc.first_line;
     diagnostics.writeInfo(pp::Diagnostics::WARNING,
                           srcLoc, reason, token, extraInfo);
 }
@@ -203,7 +205,7 @@
 //
 // 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;
     extraInfoStream << "cannot convert from '" << right << "' to '" << left << "'";
@@ -214,7 +216,7 @@
 //
 // 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;
     extraInfoStream << "no operation '" << op << "' exists that takes an operand of type " << operand 
@@ -226,7 +228,7 @@
 //
 // 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;
     extraInfoStream << "no operation '" << op << "' exists that takes a left-hand operand of type '" << left 
@@ -235,7 +237,7 @@
     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)
         return false;
     switch( type ){
@@ -263,7 +265,7 @@
 //
 // 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();
     TIntermBinary* binaryNode = node->getAsBinaryNode();
@@ -409,7 +411,7 @@
 //
 // 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)
         return false;
@@ -428,7 +430,7 @@
 //
 // 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";
     if (!symbolTable.atBuiltInLevel()) {
@@ -466,7 +468,7 @@
 //
 // 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();
 
@@ -568,7 +570,7 @@
 //
 // 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) {
         error(line, "illegal use of type 'void'", identifier.c_str());
@@ -582,7 +584,7 @@
 //
 // 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()) {
         error(line, "boolean expression expected", "");
@@ -596,7 +598,7 @@
 //
 // 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)) {
         error(line, "boolean expression expected", "");
@@ -606,7 +608,7 @@
     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 (containsSampler(*pType.userDef)) {
@@ -625,7 +627,7 @@
     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) &&
         pType.type == EbtStruct) {
@@ -640,7 +642,7 @@
     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) && 
              type.getBasicType() != EbtStruct && IsSampler(type.getBasicType())) {
@@ -672,7 +674,7 @@
 //
 // 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();
     if (constant == 0 || constant->getBasicType() != EbtInt) {
@@ -696,7 +698,7 @@
 //
 // 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)) {
         error(line, "cannot declare arrays of this qualifier", TType(type).getCompleteString().c_str());
@@ -711,7 +713,7 @@
 //
 // 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?
@@ -732,7 +734,7 @@
 //
 // 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,
@@ -797,7 +799,7 @@
     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;
     TSymbol* symbol = symbolTable.find(node->getSymbol(), &builtIn);
@@ -846,7 +848,7 @@
 //
 // 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)
     {
@@ -878,7 +880,7 @@
 //
 // 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))
         recover();
@@ -898,7 +900,7 @@
     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) {
         error(line, "qualifier not allowed on function parameter", getQualifierString(qualifier));
@@ -917,7 +919,7 @@
     return false;
 }
 
-bool TParseContext::extensionErrorCheck(int line, const TString& extension)
+bool TParseContext::extensionErrorCheck(const TSourceLoc& line, const TString& extension)
 {
     const TExtensionBehavior& extBehavior = extensionBehavior();
     TExtensionBehavior::const_iterator iter = extBehavior.find(extension.c_str());
@@ -956,7 +958,7 @@
 //
 // 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
     // hidden by a variable name or struct typename.
@@ -982,7 +984,7 @@
 // Initializers show up in several places in the grammar.  Have one set of
 // 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)
 {
     TType type = TType(pType);
@@ -1094,7 +1096,7 @@
 //
 // 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)
         return 0;
@@ -1202,7 +1204,7 @@
 //
 // 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;
     TOperator basicOp;
@@ -1264,7 +1266,7 @@
 //
 // 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 (subset)
@@ -1291,7 +1293,7 @@
 // node or it could be the intermediate tree representation of accessing fields in a constant structure or column of 
 // a constant matrix.
 //
-TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTyped* node, TSourceLoc line)
+TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTyped* node, const TSourceLoc& line)
 {
     TIntermTyped* typedNode;
     TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
@@ -1335,7 +1337,7 @@
 // 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)
 //
-TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, TSourceLoc line)
+TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, const TSourceLoc& line)
 {
     TIntermTyped* typedNode;
     TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
@@ -1370,7 +1372,7 @@
 // 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)
 //
-TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TSourceLoc line)
+TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, const TSourceLoc& line)
 {
     TIntermTyped* typedNode;
     TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
@@ -1407,7 +1409,7 @@
 // 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.
 //
-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();
     TIntermTyped *typedNode;
@@ -1437,7 +1439,7 @@
     return typedNode;
 }
 
-bool TParseContext::enterStructDeclaration(int line, const TString& identifier)
+bool TParseContext::enterStructDeclaration(const TSourceLoc& line, const TString& identifier)
 {
     ++structNestingLevel;
 
@@ -1463,7 +1465,7 @@
 
 }  // namespace
 
-bool TParseContext::structNestingErrorCheck(TSourceLoc line, const TType& fieldType)
+bool TParseContext::structNestingErrorCheck(const TSourceLoc& line, const TType& fieldType)
 {
     if (!isWebGLBasedSpec(shaderSpec)) {
         return false;
diff --git a/src/compiler/ParseHelper.h b/src/compiler/ParseHelper.h
index ce98fcc..c791e1b 100644
--- a/src/compiler/ParseHelper.h
+++ b/src/compiler/ParseHelper.h
@@ -63,40 +63,40 @@
 
     int numErrors() const { return diagnostics.numErrors(); }
     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="");
-    void warning(TSourceLoc loc, const char* reason, const char* token,
+    void warning(const TSourceLoc& loc, const char* reason, const char* token,
                  const char* extraInfo="");
     void trace(const char* str);
     void recover();
 
-    bool parseVectorFields(const TString&, int vecSize, TVectorFields&, int line);
-    bool parseMatrixFields(const TString&, int matSize, TMatrixFields&, int line);
+    bool parseVectorFields(const TString&, int vecSize, TVectorFields&, const TSourceLoc& line);
+    bool parseMatrixFields(const TString&, int matSize, TMatrixFields&, const TSourceLoc& line);
 
-    bool reservedErrorCheck(int line, const TString& identifier);
-    void assignError(int line, const char* op, TString left, TString right);
-    void unaryOpError(int line, const char* op, TString operand);
-    void binaryOpError(int line, const char* op, TString left, TString right);
-    bool precisionErrorCheck(int line, TPrecision precision, TBasicType type);
-    bool lValueErrorCheck(int line, const char* op, TIntermTyped*);
+    bool reservedErrorCheck(const TSourceLoc& line, const TString& identifier);
+    void assignError(const TSourceLoc& line, const char* op, TString left, TString right);
+    void unaryOpError(const TSourceLoc& line, const char* op, TString operand);
+    void binaryOpError(const TSourceLoc& line, const char* op, TString left, TString right);
+    bool precisionErrorCheck(const TSourceLoc& line, TPrecision precision, TBasicType type);
+    bool lValueErrorCheck(const TSourceLoc& line, const char* op, TIntermTyped*);
     bool constErrorCheck(TIntermTyped* node);
     bool integerErrorCheck(TIntermTyped* node, const char* token);
-    bool globalErrorCheck(int line, bool global, const char* token);
-    bool constructorErrorCheck(int line, TIntermNode*, TFunction&, TOperator, TType*);
-    bool arraySizeErrorCheck(int line, TIntermTyped* expr, int& size);
-    bool arrayQualifierErrorCheck(int line, TPublicType type);
-    bool arrayTypeErrorCheck(int line, TPublicType type);
-    bool arrayErrorCheck(int line, TString& identifier, TPublicType type, TVariable*& variable);
-    bool voidErrorCheck(int, const TString&, const TPublicType&);
-    bool boolErrorCheck(int, const TIntermTyped*);
-    bool boolErrorCheck(int, const TPublicType&);
-    bool samplerErrorCheck(int line, const TPublicType& pType, const char* reason);
-    bool structQualifierErrorCheck(int line, const TPublicType& pType);
-    bool parameterSamplerErrorCheck(int line, TQualifier qualifier, const TType& type);
-    bool nonInitConstErrorCheck(int line, TString& identifier, TPublicType& type, bool array);
-    bool nonInitErrorCheck(int line, TString& identifier, TPublicType& type, TVariable*& variable);
-    bool paramErrorCheck(int line, TQualifier qualifier, TQualifier paramQualifier, TType* type);
-    bool extensionErrorCheck(int line, const TString&);
+    bool globalErrorCheck(const TSourceLoc& line, bool global, const char* token);
+    bool constructorErrorCheck(const TSourceLoc& line, TIntermNode*, TFunction&, TOperator, TType*);
+    bool arraySizeErrorCheck(const TSourceLoc& line, TIntermTyped* expr, int& size);
+    bool arrayQualifierErrorCheck(const TSourceLoc& line, TPublicType type);
+    bool arrayTypeErrorCheck(const TSourceLoc& line, TPublicType type);
+    bool arrayErrorCheck(const TSourceLoc& line, TString& identifier, TPublicType type, TVariable*& variable);
+    bool voidErrorCheck(const TSourceLoc&, const TString&, const TPublicType&);
+    bool boolErrorCheck(const TSourceLoc&, const TIntermTyped*);
+    bool boolErrorCheck(const TSourceLoc&, const TPublicType&);
+    bool samplerErrorCheck(const TSourceLoc& line, const TPublicType& pType, const char* reason);
+    bool structQualifierErrorCheck(const TSourceLoc& line, const TPublicType& pType);
+    bool parameterSamplerErrorCheck(const TSourceLoc& line, TQualifier qualifier, const TType& type);
+    bool nonInitConstErrorCheck(const TSourceLoc& line, TString& identifier, TPublicType& type, bool array);
+    bool nonInitErrorCheck(const TSourceLoc& line, TString& identifier, TPublicType& type, TVariable*& variable);
+    bool paramErrorCheck(const TSourceLoc& line, TQualifier qualifier, TQualifier paramQualifier, TType* type);
+    bool extensionErrorCheck(const TSourceLoc& line, const TString&);
 
     const TPragma& pragma() const { return directiveHandler.pragma(); }
     const TExtensionBehavior& extensionBehavior() const { return directiveHandler.extensionBehavior(); }
@@ -104,27 +104,27 @@
 
     bool containsSampler(TType& type);
     bool areAllChildConst(TIntermAggregate* aggrNode);
-    const TFunction* findFunction(int line, TFunction* pfnCall, bool *builtIn = 0);
-    bool executeInitializer(TSourceLoc line, TString& identifier, TPublicType& pType,
+    const TFunction* findFunction(const TSourceLoc& line, TFunction* pfnCall, bool *builtIn = 0);
+    bool executeInitializer(const TSourceLoc& line, TString& identifier, TPublicType& pType,
                             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* constructStruct(TIntermNode*, TType*, int, TSourceLoc, bool subset);
-    TIntermTyped* constructBuiltIn(const TType*, TOperator, TIntermNode*, TSourceLoc, bool subset);
-    TIntermTyped* addConstVectorNode(TVectorFields&, TIntermTyped*, TSourceLoc);
-    TIntermTyped* addConstMatrixNode(int , TIntermTyped*, TSourceLoc);
-    TIntermTyped* addConstArrayNode(int index, TIntermTyped* node, TSourceLoc line);
-    TIntermTyped* addConstStruct(TString& , TIntermTyped*, TSourceLoc);
+    TIntermTyped* constructStruct(TIntermNode*, TType*, int, const TSourceLoc&, bool subset);
+    TIntermTyped* constructBuiltIn(const TType*, TOperator, TIntermNode*, const TSourceLoc&, bool subset);
+    TIntermTyped* addConstVectorNode(TVectorFields&, TIntermTyped*, const TSourceLoc&);
+    TIntermTyped* addConstMatrixNode(int , TIntermTyped*, const TSourceLoc&);
+    TIntermTyped* addConstArrayNode(int index, TIntermTyped* node, const TSourceLoc& line);
+    TIntermTyped* addConstStruct(TString& , TIntermTyped*, const TSourceLoc&);
 
     // Performs an error check for embedded struct declarations.
     // Returns true if an error was raised due to the declaration of
     // this struct.
-    bool enterStructDeclaration(TSourceLoc line, const TString& identifier);
+    bool enterStructDeclaration(const TSourceLoc& line, const TString& identifier);
     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[],
diff --git a/src/compiler/Types.h b/src/compiler/Types.h
index b6fd5e7..34f0b94 100644
--- a/src/compiler/Types.h
+++ b/src/compiler/Types.h
@@ -251,9 +251,9 @@
     bool array;
     int arraySize;
     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;
         qualifier = q;
diff --git a/src/compiler/glslang.l b/src/compiler/glslang.l
index 605eda8..4049875 100644
--- a/src/compiler/glslang.l
+++ b/src/compiler/glslang.l
@@ -47,7 +47,10 @@
 #pragma warning(disable : 4102)
 #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) \
     result = string_input(buf, max_size, yyscanner);
 
@@ -57,7 +60,7 @@
 %}
 
 %option noyywrap nounput never-interactive
-%option yylineno reentrant bison-bridge
+%option yylineno reentrant bison-bridge bison-locations
 %option extra-type="TParseContext*"
 
 D           [0-9]
@@ -253,7 +256,8 @@
     yy_size_t len = token.type == pp::Token::LAST ? 0 : token.text.size();
     if (len < max_size)
         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)
         YY_FATAL_ERROR("Input buffer overflow");
@@ -279,18 +283,11 @@
 int reserved_word(yyscan_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();
     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) {
     yyscan_t scanner = NULL;
     if (yylex_init_extra(context, &scanner))
@@ -313,7 +310,8 @@
 int glslang_scan(size_t count, const char* const string[], const int length[],
                  TParseContext* context) {
     yyrestart(NULL, context->scanner);
-    yyset_lineno(EncodeSourceLoc(0, 1), context->scanner);
+    yyset_column(0, context->scanner);
+    yyset_lineno(1, context->scanner);
 
     // Initialize preprocessor.
     if (!context->preprocessor.init(count, string, length))
diff --git a/src/compiler/glslang.y b/src/compiler/glslang.y
index eed9fa8..4a386ba 100644
--- a/src/compiler/glslang.y
+++ b/src/compiler/glslang.y
@@ -39,7 +39,6 @@
 #include "GLSLANG/ShaderLang.h"
 
 #define YYENABLE_NLS 0
-#define YYLTYPE_IS_TRIVIAL 1
 
 #define YYLEX_PARAM context->scanner
 %}
@@ -47,10 +46,15 @@
 %expect 1 /* One shift reduce conflict because of if | else */
 %pure-parser
 %parse-param {TParseContext* context}
+%locations
+
+%code requires {
+#define YYLTYPE TSourceLoc
+#define YYLTYPE_IS_DECLARED 1
+}
 
 %union {
     struct {
-        TSourceLoc line;
         union {
             TString *string;
             float f;
@@ -60,7 +64,6 @@
         TSymbol* symbol;
     } lex;
     struct {
-        TSourceLoc line;
         TOperator op;
         union {
             TIntermNode* intermNode;
@@ -81,8 +84,24 @@
 }
 
 %{
-extern int yylex(YYSTYPE* yylval_param, void* yyscanner);
-extern void yyerror(TParseContext* context, const char* reason);
+extern int yylex(YYSTYPE* yylval, YYLTYPE* yylloc, void* yyscanner);
+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) {  \
     if (context->shaderType != SH_FRAGMENT_SHADER &&  \
@@ -174,7 +193,7 @@
         const TSymbol* symbol = $1.symbol;
         const TVariable* variable;
         if (symbol == 0) {
-            context->error($1.line, "undeclared identifier", $1.string->c_str());
+            context->error(@1, "undeclared identifier", $1.string->c_str());
             context->recover();
             TType type(EbtFloat, EbpUndefined);
             TVariable* fakeVariable = new TVariable($1.string, type);
@@ -183,7 +202,7 @@
         } else {
             // This identifier can only be a variable type symbol
             if (! symbol->isVariable()) {
-                context->error($1.line, "variable expected", $1.string->c_str());
+                context->error(@1, "variable expected", $1.string->c_str());
                 context->recover();
             }
             variable = static_cast<const TVariable*>(symbol);
@@ -195,11 +214,12 @@
         if (variable->getType().getQualifier() == EvqConst ) {
             ConstantUnion* constArray = variable->getConstPointer();
             TType t(variable->getType());
-            $$ = context->intermediate.addConstantUnion(constArray, t, $1.line);
+            $$ = context->intermediate.addConstantUnion(constArray, t, @1);
         } else
             $$ = context->intermediate.addSymbol(variable->getUniqueId(),
-                                                     variable->getName(),
-                                                     variable->getType(), $1.line);
+                                                 variable->getName(),
+                                                 variable->getType(),
+                                                 @1);
     }
     ;
 
@@ -213,22 +233,22 @@
         // check for overflow for constants
         //
         if (abs($1.i) >= (1 << 16)) {
-            context->error($1.line, " integer constant overflow", "");
+            context->error(@1, " integer constant overflow", "");
             context->recover();
         }
         ConstantUnion *unionArray = new ConstantUnion[1];
         unionArray->setIConst($1.i);
-        $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), $1.line);
+        $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), @1);
     }
     | FLOATCONSTANT {
         ConstantUnion *unionArray = new ConstantUnion[1];
         unionArray->setFConst($1.f);
-        $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConst), $1.line);
+        $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConst), @1);
     }
     | BOOLCONSTANT {
         ConstantUnion *unionArray = new ConstantUnion[1];
         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 {
         $$ = $2;
@@ -242,21 +262,21 @@
     | postfix_expression LEFT_BRACKET integer_expression RIGHT_BRACKET {
         if (!$1->isArray() && !$1->isMatrix() && !$1->isVector()) {
             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
-                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();
         }
         if ($1->getType().getQualifier() == EvqConst && $3->getQualifier() == EvqConst) {
             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
                 TVectorFields fields;
                 fields.num = 1;
                 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
-                $$ = context->addConstMatrixNode($3->getAsConstantUnion()->getIConst(0), $1, $2.line);
+                $$ = context->addConstMatrixNode($3->getAsConstantUnion()->getIConst(0), $1, @2);
             }
         } else {
             if ($3->getQualifier() == EvqConst) {
@@ -264,41 +284,41 @@
                     std::stringstream extraInfoStream;
                     extraInfoStream << "field selection out of range '" << $3->getAsConstantUnion()->getIConst(0) << "'";
                     std::string extraInfo = extraInfoStream.str();
-                    context->error($2.line, "", "[", extraInfo.c_str());
+                    context->error(@2, "", "[", extraInfo.c_str());
                     context->recover();
                 } else {
                     if ($1->isArray()) {
                         if ($1->getType().getArraySize() == 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();
                             } else {
-                                if (context->arraySetMaxSize($1->getAsSymbolNode(), $1->getTypePointer(), 0, false, $2.line))
+                                if (context->arraySetMaxSize($1->getAsSymbolNode(), $1->getTypePointer(), 0, false, @2))
                                     context->recover();
                             }
                         } else if ( $3->getAsConstantUnion()->getIConst(0) >= $1->getType().getArraySize()) {
                             std::stringstream extraInfoStream;
                             extraInfoStream << "array index out of range '" << $3->getAsConstantUnion()->getIConst(0) << "'";
                             std::string extraInfo = extraInfoStream.str();
-                            context->error($2.line, "", "[", extraInfo.c_str());
+                            context->error(@2, "", "[", extraInfo.c_str());
                             context->recover();
                         }
                     }
-                    $$ = context->intermediate.addIndex(EOpIndexDirect, $1, $3, $2.line);
+                    $$ = context->intermediate.addIndex(EOpIndexDirect, $1, $3, @2);
                 }
             } else {
                 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->intermediate.addIndex(EOpIndexIndirect, $1, $3, $2.line);
+                $$ = context->intermediate.addIndex(EOpIndexIndirect, $1, $3, @2);
             }
         }
         if ($$ == 0) {
             ConstantUnion *unionArray = new ConstantUnion[1];
             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()) {
             if ($1->getType().getStruct())
                 $$->setType(TType($1->getType().getStruct(), $1->getType().getTypeName()));
@@ -323,20 +343,20 @@
     }
     | postfix_expression DOT identifier {
         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();
         }
 
         if ($1->isVector()) {
             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.offsets[0] = 0;
                 context->recover();
             }
 
             if ($1->getType().getQualifier() == EvqConst) { // constant folding for vector fields
-                $$ = context->addConstVectorNode(fields, $1, $3.line);
+                $$ = context->addConstVectorNode(fields, $1, @3);
                 if ($$ == 0) {
                     context->recover();
                     $$ = $1;
@@ -345,13 +365,13 @@
                     $$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqConst, (int) (*$3.string).size()));
             } else {
                 TString vectorString = *$3.string;
-                TIntermTyped* index = context->intermediate.addSwizzle(fields, $3.line);
-                $$ = context->intermediate.addIndex(EOpVectorSwizzle, $1, index, $2.line);
+                TIntermTyped* index = context->intermediate.addSwizzle(fields, @3);
+                $$ = context->intermediate.addIndex(EOpVectorSwizzle, $1, index, @2);
                 $$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqTemporary, (int) vectorString.size()));
             }
         } else if ($1->isMatrix()) {
             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.wholeCol = false;
                 fields.row = 0;
@@ -360,25 +380,25 @@
             }
 
             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();
                 ConstantUnion *unionArray = new ConstantUnion[1];
                 unionArray->setIConst(0);
-                TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), $3.line);
-                $$ = context->intermediate.addIndex(EOpIndexDirect, $1, index, $2.line);
+                TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), @3);
+                $$ = context->intermediate.addIndex(EOpIndexDirect, $1, index, @2);
                 $$->setType(TType($1->getBasicType(), $1->getPrecision(),EvqTemporary, $1->getNominalSize()));
             } else {
                 ConstantUnion *unionArray = new ConstantUnion[1];
                 unionArray->setIConst(fields.col * $1->getNominalSize() + fields.row);
-                TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), $3.line);
-                $$ = context->intermediate.addIndex(EOpIndexDirect, $1, index, $2.line);
+                TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), @3);
+                $$ = context->intermediate.addIndex(EOpIndexDirect, $1, index, @2);
                 $$->setType(TType($1->getBasicType(), $1->getPrecision()));
             }
         } else if ($1->getBasicType() == EbtStruct) {
             bool fieldFound = false;
             const TTypeList* fields = $1->getType().getStruct();
             if (fields == 0) {
-                context->error($2.line, "structure has no fields", "Internal Error");
+                context->error(@2, "structure has no fields", "Internal Error");
                 context->recover();
                 $$ = $1;
             } else {
@@ -391,7 +411,7 @@
                 }
                 if (fieldFound) {
                     if ($1->getType().getQualifier() == EvqConst) {
-                        $$ = context->addConstStruct(*$3.string, $1, $2.line);
+                        $$ = context->addConstStruct(*$3.string, $1, @2);
                         if ($$ == 0) {
                             context->recover();
                             $$ = $1;
@@ -405,39 +425,39 @@
                     } else {
                         ConstantUnion *unionArray = new ConstantUnion[1];
                         unionArray->setIConst(i);
-                        TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, *(*fields)[i], $3.line);
-                        $$ = context->intermediate.addIndex(EOpIndexDirectStruct, $1, index, $2.line);
+                        TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, *(*fields)[i], @3);
+                        $$ = context->intermediate.addIndex(EOpIndexDirectStruct, $1, index, @2);
                         $$->setType(*(*fields)[i]);
                     }
                 } 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();
                     $$ = $1;
                 }
             }
         } 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();
             $$ = $1;
         }
         // don't delete $3.string, it's from the pool
     }
     | postfix_expression INC_OP {
-        if (context->lValueErrorCheck($2.line, "++", $1))
+        if (context->lValueErrorCheck(@2, "++", $1))
             context->recover();
-        $$ = context->intermediate.addUnaryMath(EOpPostIncrement, $1, $2.line, context->symbolTable);
+        $$ = context->intermediate.addUnaryMath(EOpPostIncrement, $1, @2, context->symbolTable);
         if ($$ == 0) {
-            context->unaryOpError($2.line, "++", $1->getCompleteString());
+            context->unaryOpError(@2, "++", $1->getCompleteString());
             context->recover();
             $$ = $1;
         }
     }
     | postfix_expression DEC_OP {
-        if (context->lValueErrorCheck($2.line, "--", $1))
+        if (context->lValueErrorCheck(@2, "--", $1))
             context->recover();
-        $$ = context->intermediate.addUnaryMath(EOpPostDecrement, $1, $2.line, context->symbolTable);
+        $$ = context->intermediate.addUnaryMath(EOpPostDecrement, $1, @2, context->symbolTable);
         if ($$ == 0) {
-            context->unaryOpError($2.line, "--", $1->getCompleteString());
+            context->unaryOpError(@2, "--", $1->getCompleteString());
             context->recover();
             $$ = $1;
         }
@@ -465,18 +485,18 @@
             // Their parameters will be verified algorithmically.
             //
             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;
             } else {
                 //
                 // 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) {
                 context->recover();
-                $$ = context->intermediate.setAggregateOperator(0, op, $1.line);
+                $$ = context->intermediate.setAggregateOperator(0, op, @1);
             }
             $$->setType(type);
         } else {
@@ -485,13 +505,13 @@
             //
             const TFunction* fnCandidate;
             bool builtIn;
-            fnCandidate = context->findFunction($1.line, fnCall, &builtIn);
+            fnCandidate = context->findFunction(@1, fnCall, &builtIn);
             if (fnCandidate) {
                 //
                 // A declared function.
                 //
                 if (builtIn && !fnCandidate->getExtension().empty() &&
-                    context->extensionErrorCheck($1.line, fnCandidate->getExtension())) {
+                    context->extensionErrorCheck(@1, fnCandidate->getExtension())) {
                     context->recover();
                 }
                 op = fnCandidate->getBuiltInOp();
@@ -503,7 +523,7 @@
                         //
                         // 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)  {
                             std::stringstream extraInfoStream;
                             extraInfoStream << "built in unary operator function.  Type: " << static_cast<TIntermTyped*>($1.intermNode)->getCompleteString();
@@ -512,12 +532,12 @@
                             YYERROR;
                         }
                     } else {
-                        $$ = context->intermediate.setAggregateOperator($1.intermAggregate, op, $1.line);
+                        $$ = context->intermediate.setAggregateOperator($1.intermAggregate, op, @1);
                     }
                 } else {
                     // This is a real function call
 
-                    $$ = context->intermediate.setAggregateOperator($1.intermAggregate, EOpFunctionCall, $1.line);
+                    $$ = context->intermediate.setAggregateOperator($1.intermAggregate, EOpFunctionCall, @1);
                     $$->setType(fnCandidate->getReturnType());
 
                     // this is how we know whether the given function is a builtIn function or a user defined function
@@ -544,7 +564,7 @@
                 // Put on a dummy node for error recovery
                 ConstantUnion *unionArray = new ConstantUnion[1];
                 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();
             }
         }
@@ -557,7 +577,7 @@
         $$ = $1;
     }
     | postfix_expression DOT function_call_generic {
-        context->error($3.line, "methods are not supported", "");
+        context->error(@3, "methods are not supported", "");
         context->recover();
         $$ = $3;
     }
@@ -566,11 +586,9 @@
 function_call_generic
     : function_call_header_with_parameters RIGHT_PAREN {
         $$ = $1;
-        $$.line = $2.line;
     }
     | function_call_header_no_parameters RIGHT_PAREN {
         $$ = $1;
-        $$.line = $2.line;
     }
     ;
 
@@ -596,7 +614,7 @@
         TParameter param = { 0, new TType($3->getType()) };
         $1.function->addParameter(param);
         $$.function = $1.function;
-        $$.intermNode = context->intermediate.growAggregate($1.intermNode, $3, $2.line);
+        $$.intermNode = context->intermediate.growAggregate($1.intermNode, $3, @2);
     }
     ;
 
@@ -637,23 +655,23 @@
             case EbtInt:
                 switch($1.size) {
                 case 1:                                         op = EOpConstructInt;   break;
-                case 2:       FRAG_VERT_ONLY("ivec2", $1.line); op = EOpConstructIVec2; break;
-                case 3:       FRAG_VERT_ONLY("ivec3", $1.line); op = EOpConstructIVec3; break;
-                case 4:       FRAG_VERT_ONLY("ivec4", $1.line); op = EOpConstructIVec4; break;
+                case 2:       FRAG_VERT_ONLY("ivec2", @1); op = EOpConstructIVec2; break;
+                case 3:       FRAG_VERT_ONLY("ivec3", @1); op = EOpConstructIVec3; break;
+                case 4:       FRAG_VERT_ONLY("ivec4", @1); op = EOpConstructIVec4; break;
                 }
                 break;
             case EbtBool:
                 switch($1.size) {
                 case 1:                                         op = EOpConstructBool;  break;
-                case 2:       FRAG_VERT_ONLY("bvec2", $1.line); op = EOpConstructBVec2; break;
-                case 3:       FRAG_VERT_ONLY("bvec3", $1.line); op = EOpConstructBVec3; break;
-                case 4:       FRAG_VERT_ONLY("bvec4", $1.line); op = EOpConstructBVec4; break;
+                case 2:       FRAG_VERT_ONLY("bvec2", @1); op = EOpConstructBVec2; break;
+                case 3:       FRAG_VERT_ONLY("bvec3", @1); op = EOpConstructBVec3; break;
+                case 4:       FRAG_VERT_ONLY("bvec4", @1); op = EOpConstructBVec4; break;
                 }
                 break;
             default: break;
             }
             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();
                 $1.type = EbtFloat;
                 op = EOpConstructFloat;
@@ -665,7 +683,7 @@
         $$ = function;
     }
     | IDENTIFIER {
-        if (context->reservedErrorCheck($1.line, *$1.string))
+        if (context->reservedErrorCheck(@1, *$1.string))
             context->recover();
         TType type(EbtVoid, EbpUndefined);
         TFunction *function = new TFunction($1.string, type);
@@ -678,28 +696,28 @@
         $$ = $1;
     }
     | INC_OP unary_expression {
-        if (context->lValueErrorCheck($1.line, "++", $2))
+        if (context->lValueErrorCheck(@1, "++", $2))
             context->recover();
-        $$ = context->intermediate.addUnaryMath(EOpPreIncrement, $2, $1.line, context->symbolTable);
+        $$ = context->intermediate.addUnaryMath(EOpPreIncrement, $2, @1, context->symbolTable);
         if ($$ == 0) {
-            context->unaryOpError($1.line, "++", $2->getCompleteString());
+            context->unaryOpError(@1, "++", $2->getCompleteString());
             context->recover();
             $$ = $2;
         }
     }
     | DEC_OP unary_expression {
-        if (context->lValueErrorCheck($1.line, "--", $2))
+        if (context->lValueErrorCheck(@1, "--", $2))
             context->recover();
-        $$ = context->intermediate.addUnaryMath(EOpPreDecrement, $2, $1.line, context->symbolTable);
+        $$ = context->intermediate.addUnaryMath(EOpPreDecrement, $2, @1, context->symbolTable);
         if ($$ == 0) {
-            context->unaryOpError($1.line, "--", $2->getCompleteString());
+            context->unaryOpError(@1, "--", $2->getCompleteString());
             context->recover();
             $$ = $2;
         }
     }
     | unary_operator unary_expression {
         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) {
                 const char* errorOp = "";
                 switch($1.op) {
@@ -707,7 +725,7 @@
                 case EOpLogicalNot: errorOp = "!"; break;
                 default: break;
                 }
-                context->unaryOpError($1.line, errorOp, $2->getCompleteString());
+                context->unaryOpError(@1, errorOp, $2->getCompleteString());
                 context->recover();
                 $$ = $2;
             }
@@ -718,28 +736,28 @@
 // Grammar Note:  No traditional style type casts.
 
 unary_operator
-    : PLUS  { $$.line = $1.line; $$.op = EOpNull; }
-    | DASH  { $$.line = $1.line; $$.op = EOpNegative; }
-    | BANG  { $$.line = $1.line; $$.op = EOpLogicalNot; }
+    : PLUS  { $$.op = EOpNull; }
+    | DASH  { $$.op = EOpNegative; }
+    | BANG  { $$.op = EOpLogicalNot; }
     ;
 // Grammar Note:  No '*' or '&' unary ops.  Pointers are not supported.
 
 multiplicative_expression
     : unary_expression { $$ = $1; }
     | multiplicative_expression STAR unary_expression {
-        FRAG_VERT_ONLY("*", $2.line);
-        $$ = context->intermediate.addBinaryMath(EOpMul, $1, $3, $2.line, context->symbolTable);
+        FRAG_VERT_ONLY("*", @2);
+        $$ = context->intermediate.addBinaryMath(EOpMul, $1, $3, @2, context->symbolTable);
         if ($$ == 0) {
-            context->binaryOpError($2.line, "*", $1->getCompleteString(), $3->getCompleteString());
+            context->binaryOpError(@2, "*", $1->getCompleteString(), $3->getCompleteString());
             context->recover();
             $$ = $1;
         }
     }
     | multiplicative_expression SLASH unary_expression {
-        FRAG_VERT_ONLY("/", $2.line);
-        $$ = context->intermediate.addBinaryMath(EOpDiv, $1, $3, $2.line, context->symbolTable);
+        FRAG_VERT_ONLY("/", @2);
+        $$ = context->intermediate.addBinaryMath(EOpDiv, $1, $3, @2, context->symbolTable);
         if ($$ == 0) {
-            context->binaryOpError($2.line, "/", $1->getCompleteString(), $3->getCompleteString());
+            context->binaryOpError(@2, "/", $1->getCompleteString(), $3->getCompleteString());
             context->recover();
             $$ = $1;
         }
@@ -749,17 +767,17 @@
 additive_expression
     : multiplicative_expression { $$ = $1; }
     | 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) {
-            context->binaryOpError($2.line, "+", $1->getCompleteString(), $3->getCompleteString());
+            context->binaryOpError(@2, "+", $1->getCompleteString(), $3->getCompleteString());
             context->recover();
             $$ = $1;
         }
     }
     | 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) {
-            context->binaryOpError($2.line, "-", $1->getCompleteString(), $3->getCompleteString());
+            context->binaryOpError(@2, "-", $1->getCompleteString(), $3->getCompleteString());
             context->recover();
             $$ = $1;
         }
@@ -773,43 +791,43 @@
 relational_expression
     : shift_expression { $$ = $1; }
     | 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) {
-            context->binaryOpError($2.line, "<", $1->getCompleteString(), $3->getCompleteString());
+            context->binaryOpError(@2, "<", $1->getCompleteString(), $3->getCompleteString());
             context->recover();
             ConstantUnion *unionArray = new ConstantUnion[1];
             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  {
-        $$ = context->intermediate.addBinaryMath(EOpGreaterThan, $1, $3, $2.line, context->symbolTable);
+        $$ = context->intermediate.addBinaryMath(EOpGreaterThan, $1, $3, @2, context->symbolTable);
         if ($$ == 0) {
-            context->binaryOpError($2.line, ">", $1->getCompleteString(), $3->getCompleteString());
+            context->binaryOpError(@2, ">", $1->getCompleteString(), $3->getCompleteString());
             context->recover();
             ConstantUnion *unionArray = new ConstantUnion[1];
             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  {
-        $$ = context->intermediate.addBinaryMath(EOpLessThanEqual, $1, $3, $2.line, context->symbolTable);
+        $$ = context->intermediate.addBinaryMath(EOpLessThanEqual, $1, $3, @2, context->symbolTable);
         if ($$ == 0) {
-            context->binaryOpError($2.line, "<=", $1->getCompleteString(), $3->getCompleteString());
+            context->binaryOpError(@2, "<=", $1->getCompleteString(), $3->getCompleteString());
             context->recover();
             ConstantUnion *unionArray = new ConstantUnion[1];
             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  {
-        $$ = context->intermediate.addBinaryMath(EOpGreaterThanEqual, $1, $3, $2.line, context->symbolTable);
+        $$ = context->intermediate.addBinaryMath(EOpGreaterThanEqual, $1, $3, @2, context->symbolTable);
         if ($$ == 0) {
-            context->binaryOpError($2.line, ">=", $1->getCompleteString(), $3->getCompleteString());
+            context->binaryOpError(@2, ">=", $1->getCompleteString(), $3->getCompleteString());
             context->recover();
             ConstantUnion *unionArray = new ConstantUnion[1];
             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 @@
 equality_expression
     : relational_expression { $$ = $1; }
     | 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) {
-            context->binaryOpError($2.line, "==", $1->getCompleteString(), $3->getCompleteString());
+            context->binaryOpError(@2, "==", $1->getCompleteString(), $3->getCompleteString());
             context->recover();
             ConstantUnion *unionArray = new ConstantUnion[1];
             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 {
-        $$ = context->intermediate.addBinaryMath(EOpNotEqual, $1, $3, $2.line, context->symbolTable);
+        $$ = context->intermediate.addBinaryMath(EOpNotEqual, $1, $3, @2, context->symbolTable);
         if ($$ == 0) {
-            context->binaryOpError($2.line, "!=", $1->getCompleteString(), $3->getCompleteString());
+            context->binaryOpError(@2, "!=", $1->getCompleteString(), $3->getCompleteString());
             context->recover();
             ConstantUnion *unionArray = new ConstantUnion[1];
             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 @@
 logical_and_expression
     : inclusive_or_expression { $$ = $1; }
     | 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) {
-            context->binaryOpError($2.line, "&&", $1->getCompleteString(), $3->getCompleteString());
+            context->binaryOpError(@2, "&&", $1->getCompleteString(), $3->getCompleteString());
             context->recover();
             ConstantUnion *unionArray = new ConstantUnion[1];
             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_xor_expression
     : logical_and_expression { $$ = $1; }
     | 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) {
-            context->binaryOpError($2.line, "^^", $1->getCompleteString(), $3->getCompleteString());
+            context->binaryOpError(@2, "^^", $1->getCompleteString(), $3->getCompleteString());
             context->recover();
             ConstantUnion *unionArray = new ConstantUnion[1];
             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_or_expression
     : logical_xor_expression { $$ = $1; }
     | 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) {
-            context->binaryOpError($2.line, "||", $1->getCompleteString(), $3->getCompleteString());
+            context->binaryOpError(@2, "||", $1->getCompleteString(), $3->getCompleteString());
             context->recover();
             ConstantUnion *unionArray = new ConstantUnion[1];
             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 @@
 conditional_expression
     : logical_or_expression { $$ = $1; }
     | logical_or_expression QUESTION expression COLON assignment_expression {
-       if (context->boolErrorCheck($2.line, $1))
+       if (context->boolErrorCheck(@2, $1))
             context->recover();
 
-        $$ = context->intermediate.addSelection($1, $3, $5, $2.line);
+        $$ = context->intermediate.addSelection($1, $3, $5, @2);
         if ($3->getType() != $5->getType())
             $$ = 0;
 
         if ($$ == 0) {
-            context->binaryOpError($2.line, ":", $3->getCompleteString(), $5->getCompleteString());
+            context->binaryOpError(@2, ":", $3->getCompleteString(), $5->getCompleteString());
             context->recover();
             $$ = $5;
         }
@@ -913,11 +931,11 @@
 assignment_expression
     : conditional_expression { $$ = $1; }
     | unary_expression assignment_operator assignment_expression {
-        if (context->lValueErrorCheck($2.line, "assign", $1))
+        if (context->lValueErrorCheck(@2, "assign", $1))
             context->recover();
-        $$ = context->intermediate.addAssign($2.op, $1, $3, $2.line);
+        $$ = context->intermediate.addAssign($2.op, $1, $3, @2);
         if ($$ == 0) {
-            context->assignError($2.line, "assign", $1->getCompleteString(), $3->getCompleteString());
+            context->assignError(@2, "assign", $1->getCompleteString(), $3->getCompleteString());
             context->recover();
             $$ = $1;
         }
@@ -925,11 +943,11 @@
     ;
 
 assignment_operator
-    : EQUAL        {                                    $$.line = $1.line; $$.op = EOpAssign; }
-    | MUL_ASSIGN   { FRAG_VERT_ONLY("*=", $1.line);     $$.line = $1.line; $$.op = EOpMulAssign; }
-    | DIV_ASSIGN   { FRAG_VERT_ONLY("/=", $1.line);     $$.line = $1.line; $$.op = EOpDivAssign; }
-    | ADD_ASSIGN   {                                    $$.line = $1.line; $$.op = EOpAddAssign; }
-    | SUB_ASSIGN   {                                    $$.line = $1.line; $$.op = EOpSubAssign; }
+    : EQUAL        {                            $$.op = EOpAssign; }
+    | MUL_ASSIGN   { FRAG_VERT_ONLY("*=", @1);  $$.op = EOpMulAssign; }
+    | DIV_ASSIGN   { FRAG_VERT_ONLY("/=", @1);  $$.op = EOpDivAssign; }
+    | ADD_ASSIGN   {                            $$.op = EOpAddAssign; }
+    | SUB_ASSIGN   {                            $$.op = EOpSubAssign; }
     ;
 
 expression
@@ -937,9 +955,9 @@
         $$ = $1;
     }
     | expression COMMA assignment_expression {
-        $$ = context->intermediate.addComma($1, $3, $2.line);
+        $$ = context->intermediate.addComma($1, $3, @2);
         if ($$ == 0) {
-            context->binaryOpError($2.line, ",", $1->getCompleteString(), $3->getCompleteString());
+            context->binaryOpError(@2, ",", $1->getCompleteString(), $3->getCompleteString());
             context->recover();
             $$ = $3;
         }
@@ -969,11 +987,11 @@
             {
                 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
             {
-                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 @@
     }
     | PRECISION precision_qualifier type_specifier_no_prec SEMICOLON {
         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();
         }
         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();
         }
         $$ = 0;
@@ -1013,12 +1031,12 @@
         TFunction* prevDec = static_cast<TFunction*>(context->symbolTable.find($1->getMangledName()));
         if (prevDec) {
             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();
             }
             for (size_t i = 0; i < prevDec->getParamCount(); ++i) {
                 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();
                 }
             }
@@ -1030,7 +1048,6 @@
         // being redeclared.  So, pass back up this declaration, not the one in the symbol table.
         //
         $$.function = $1;
-        $$.line = $2.line;
 
         // We're at the inner scope level of the function's arguments and body statement.
         // Add the function prototype to the surrounding scope instead.
@@ -1066,7 +1083,7 @@
             //
             // 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();
             delete $3.param.type;
         } else {
@@ -1080,11 +1097,11 @@
 function_header
     : fully_specified_type IDENTIFIER LEFT_PAREN {
         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();
         }
         // make sure a sampler is not involved as well...
-        if (context->structQualifierErrorCheck($2.line, $1))
+        if (context->structQualifierErrorCheck(@2, $1))
             context->recover();
 
         // Add the function as a prototype after parsing it (we do not support recursion)
@@ -1101,31 +1118,29 @@
     // Type + name
     : type_specifier identifier {
         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();
         }
-        if (context->reservedErrorCheck($2.line, *$2.string))
+        if (context->reservedErrorCheck(@2, *$2.string))
             context->recover();
         TParameter param = {$2.string, new TType($1)};
-        $$.line = $2.line;
         $$.param = param;
     }
     | type_specifier identifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
         // Check that we can make an array out of this type
-        if (context->arrayTypeErrorCheck($3.line, $1))
+        if (context->arrayTypeErrorCheck(@3, $1))
             context->recover();
 
-        if (context->reservedErrorCheck($2.line, *$2.string))
+        if (context->reservedErrorCheck(@2, *$2.string))
             context->recover();
 
         int size;
-        if (context->arraySizeErrorCheck($3.line, $4, size))
+        if (context->arraySizeErrorCheck(@3, $4, size))
             context->recover();
         $1.setArray(true, size);
 
         TType* type = new TType($1);
         TParameter param = { $2.string, type };
-        $$.line = $2.line;
         $$.param = param;
     }
     ;
@@ -1141,14 +1156,14 @@
     //
     : type_qualifier parameter_qualifier parameter_declarator {
         $$ = $3;
-        if (context->paramErrorCheck($3.line, $1.qualifier, $2, $$.param.type))
+        if (context->paramErrorCheck(@3, $1.qualifier, $2, $$.param.type))
             context->recover();
     }
     | parameter_qualifier parameter_declarator {
         $$ = $2;
-        if (context->parameterSamplerErrorCheck($2.line, $1, *$2.param.type))
+        if (context->parameterSamplerErrorCheck(@2, $1, *$2.param.type))
             context->recover();
-        if (context->paramErrorCheck($2.line, EvqTemporary, $1, $$.param.type))
+        if (context->paramErrorCheck(@2, EvqTemporary, $1, $$.param.type))
             context->recover();
     }
     //
@@ -1156,14 +1171,14 @@
     //
     | type_qualifier parameter_qualifier parameter_type_specifier {
         $$ = $3;
-        if (context->paramErrorCheck($3.line, $1.qualifier, $2, $$.param.type))
+        if (context->paramErrorCheck(@3, $1.qualifier, $2, $$.param.type))
             context->recover();
     }
     | parameter_qualifier parameter_type_specifier {
         $$ = $2;
-        if (context->parameterSamplerErrorCheck($2.line, $1, *$2.param.type))
+        if (context->parameterSamplerErrorCheck(@2, $1, *$2.param.type))
             context->recover();
-        if (context->paramErrorCheck($2.line, EvqTemporary, $1, $$.param.type))
+        if (context->paramErrorCheck(@2, EvqTemporary, $1, $$.param.type))
             context->recover();
     }
     ;
@@ -1197,80 +1212,80 @@
     | init_declarator_list COMMA identifier {
         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();
         }
 
-        TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$3.string, TType($1.type), $3.line);
-        $$.intermAggregate = context->intermediate.growAggregate($1.intermNode, symbol, $3.line);
+        TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$3.string, TType($1.type), @3);
+        $$.intermAggregate = context->intermediate.growAggregate($1.intermNode, symbol, @3);
         
-        if (context->structQualifierErrorCheck($3.line, $$.type))
+        if (context->structQualifierErrorCheck(@3, $$.type))
             context->recover();
 
-        if (context->nonInitConstErrorCheck($3.line, *$3.string, $$.type, false))
+        if (context->nonInitConstErrorCheck(@3, *$3.string, $$.type, false))
             context->recover();
 
         TVariable* variable = 0;
-        if (context->nonInitErrorCheck($3.line, *$3.string, $$.type, variable))
+        if (context->nonInitErrorCheck(@3, *$3.string, $$.type, variable))
             context->recover();
         if (symbol && variable)
             symbol->setId(variable->getUniqueId());
     }
     | init_declarator_list COMMA identifier LEFT_BRACKET RIGHT_BRACKET {
-        if (context->structQualifierErrorCheck($3.line, $1.type))
+        if (context->structQualifierErrorCheck(@3, $1.type))
             context->recover();
 
-        if (context->nonInitConstErrorCheck($3.line, *$3.string, $1.type, true))
+        if (context->nonInitConstErrorCheck(@3, *$3.string, $1.type, true))
             context->recover();
 
         $$ = $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();
         else {
             $1.type.setArray(true);
             TVariable* variable;
-            if (context->arrayErrorCheck($4.line, *$3.string, $1.type, variable))
+            if (context->arrayErrorCheck(@4, *$3.string, $1.type, variable))
                 context->recover();
         }
     }
     | 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();
 
-        if (context->nonInitConstErrorCheck($3.line, *$3.string, $1.type, true))
+        if (context->nonInitConstErrorCheck(@3, *$3.string, $1.type, true))
             context->recover();
 
         $$ = $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();
         else {
             int size;
-            if (context->arraySizeErrorCheck($4.line, $5, size))
+            if (context->arraySizeErrorCheck(@4, $5, size))
                 context->recover();
             $1.type.setArray(true, size);
             TVariable* variable = 0;
-            if (context->arrayErrorCheck($4.line, *$3.string, $1.type, variable))
+            if (context->arrayErrorCheck(@4, *$3.string, $1.type, variable))
                 context->recover();
             TType type = TType($1.type);
             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 {
-        if (context->structQualifierErrorCheck($3.line, $1.type))
+        if (context->structQualifierErrorCheck(@3, $1.type))
             context->recover();
 
         $$ = $1;
 
         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
             //
             if (intermNode)
-        $$.intermAggregate = context->intermediate.growAggregate($1.intermNode, intermNode, $4.line);
+        $$.intermAggregate = context->intermediate.growAggregate($1.intermNode, intermNode, @4);
             else
                 $$.intermAggregate = $1.intermAggregate;
         } else {
@@ -1283,79 +1298,79 @@
 single_declaration
     : fully_specified_type {
         $$.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 {
-        TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$2.string, TType($1), $2.line);
-        $$.intermAggregate = context->intermediate.makeAggregate(symbol, $2.line);
+        TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$2.string, TType($1), @2);
+        $$.intermAggregate = context->intermediate.makeAggregate(symbol, @2);
         
-        if (context->structQualifierErrorCheck($2.line, $$.type))
+        if (context->structQualifierErrorCheck(@2, $$.type))
             context->recover();
 
-        if (context->nonInitConstErrorCheck($2.line, *$2.string, $$.type, false))
+        if (context->nonInitConstErrorCheck(@2, *$2.string, $$.type, false))
             context->recover();
             
             $$.type = $1;
 
         TVariable* variable = 0;
-        if (context->nonInitErrorCheck($2.line, *$2.string, $$.type, variable))
+        if (context->nonInitErrorCheck(@2, *$2.string, $$.type, variable))
             context->recover();
         if (variable && symbol)
             symbol->setId(variable->getUniqueId());
     }
     | 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();
 
-        TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$2.string, TType($1), $2.line);
-        $$.intermAggregate = context->intermediate.makeAggregate(symbol, $2.line);
+        TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$2.string, TType($1), @2);
+        $$.intermAggregate = context->intermediate.makeAggregate(symbol, @2);
         $$.type = $1;
     }
     | fully_specified_type identifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
         TType type = TType($1);
         int size;
-        if (context->arraySizeErrorCheck($2.line, $4, size))
+        if (context->arraySizeErrorCheck(@2, $4, size))
             context->recover();
         type.setArraySize(size);
-        TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$2.string, type, $2.line);
-        $$.intermAggregate = context->intermediate.makeAggregate(symbol, $2.line);
+        TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$2.string, type, @2);
+        $$.intermAggregate = context->intermediate.makeAggregate(symbol, @2);
         
-        if (context->structQualifierErrorCheck($2.line, $1))
+        if (context->structQualifierErrorCheck(@2, $1))
             context->recover();
 
-        if (context->nonInitConstErrorCheck($2.line, *$2.string, $1, true))
+        if (context->nonInitConstErrorCheck(@2, *$2.string, $1, true))
             context->recover();
 
         $$.type = $1;
 
-        if (context->arrayTypeErrorCheck($3.line, $1) || context->arrayQualifierErrorCheck($3.line, $1))
+        if (context->arrayTypeErrorCheck(@3, $1) || context->arrayQualifierErrorCheck(@3, $1))
             context->recover();
         else {
             int size;
-            if (context->arraySizeErrorCheck($3.line, $4, size))
+            if (context->arraySizeErrorCheck(@3, $4, size))
                 context->recover();
 
             $1.setArray(true, size);
             TVariable* variable = 0;
-            if (context->arrayErrorCheck($3.line, *$2.string, $1, variable))
+            if (context->arrayErrorCheck(@3, *$2.string, $1, variable))
                 context->recover();
             if (variable && symbol)
                 symbol->setId(variable->getUniqueId());
         }
     }
     | fully_specified_type identifier EQUAL initializer {
-        if (context->structQualifierErrorCheck($2.line, $1))
+        if (context->structQualifierErrorCheck(@2, $1))
             context->recover();
 
         $$.type = $1;
 
         TIntermNode* intermNode;
-        if (!context->executeInitializer($2.line, *$2.string, $1, $4, intermNode)) {
+        if (!context->executeInitializer(@2, *$2.string, $1, $4, intermNode)) {
         //
         // Build intermediate representation
         //
             if(intermNode)
-                $$.intermAggregate = context->intermediate.makeAggregate(intermNode, $3.line);
+                $$.intermAggregate = context->intermediate.makeAggregate(intermNode, @3);
             else
                 $$.intermAggregate = 0;
         } else {
@@ -1364,21 +1379,21 @@
         }
     }
     | INVARIANT IDENTIFIER {
-        VERTEX_ONLY("invariant declaration", $1.line);
-        if (context->globalErrorCheck($1.line, context->symbolTable.atGlobalLevel(), "invariant varying"))
+        VERTEX_ONLY("invariant declaration", @1);
+        if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "invariant varying"))
             context->recover();
-        $$.type.setBasic(EbtInvariant, EvqInvariantVaryingOut, $2.line);
+        $$.type.setBasic(EbtInvariant, EvqInvariantVaryingOut, @2);
         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();
             
             $$.intermAggregate = 0;
         }
         else
         {
-            TIntermSymbol *symbol = context->intermediate.addSymbol(0, *$2.string, TType($$.type), $2.line);
-            $$.intermAggregate = context->intermediate.makeAggregate(symbol, $2.line);
+            TIntermSymbol *symbol = context->intermediate.addSymbol(0, *$2.string, TType($$.type), @2);
+            $$.intermAggregate = context->intermediate.makeAggregate(symbol, @2);
         }
     }
 
@@ -1404,15 +1419,15 @@
 //
 //input_or_output
 //    : INPUT {
-//        if (context->globalErrorCheck($1.line, context->symbolTable.atGlobalLevel(), "input"))
+//        if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "input"))
 //            context->recover();
-//        UNPACK_ONLY("input", $1.line);
+//        UNPACK_ONLY("input", @1);
 //        $$.qualifier = EvqInput;
 //    }
 //    | OUTPUT {
-//        if (context->globalErrorCheck($1.line, context->symbolTable.atGlobalLevel(), "output"))
+//        if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "output"))
 //            context->recover();
-//        PACK_ONLY("output", $1.line);
+//        PACK_ONLY("output", @1);
 //        $$.qualifier = EvqOutput;
 //    }
 //    ;
@@ -1440,11 +1455,11 @@
 //
 //buffer_declaration
 //    : type_specifier IDENTIFIER COLON constant_expression SEMICOLON {
-//        if (context->reservedErrorCheck($2.line, *$2.string, context))
+//        if (context->reservedErrorCheck(@2, *$2.string, context))
 //            context->recover();
 //        $$.variable = new TVariable($2.string, $1);
 //        if (! context->symbolTable.insert(*$$.variable)) {
-//            context->error($2.line, "redefinition", $$.variable->getName().c_str());
+//            context->error(@2, "redefinition", $$.variable->getName().c_str());
 //            context->recover();
 //            // don't have to delete $$.variable, the pool pop will take care of it
 //        }
@@ -1456,26 +1471,26 @@
         $$ = $1;
 
         if ($1.array) {
-            context->error($1.line, "not supported", "first-class array");
+            context->error(@1, "not supported", "first-class array");
             context->recover();
             $1.setArray(false);
         }
     }
     | type_qualifier type_specifier  {
         if ($2.array) {
-            context->error($2.line, "not supported", "first-class array");
+            context->error(@2, "not supported", "first-class array");
             context->recover();
             $2.setArray(false);
         }
 
         if ($1.qualifier == EvqAttribute &&
             ($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();
         }
         if (($1.qualifier == EvqVaryingIn || $1.qualifier == EvqVaryingOut) &&
             ($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();
         }
         $$ = $2;
@@ -1485,34 +1500,34 @@
 
 type_qualifier
     : CONST_QUAL {
-        $$.setBasic(EbtVoid, EvqConst, $1.line);
+        $$.setBasic(EbtVoid, EvqConst, @1);
     }
     | ATTRIBUTE {
-        VERTEX_ONLY("attribute", $1.line);
-        if (context->globalErrorCheck($1.line, context->symbolTable.atGlobalLevel(), "attribute"))
+        VERTEX_ONLY("attribute", @1);
+        if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "attribute"))
             context->recover();
-        $$.setBasic(EbtVoid, EvqAttribute, $1.line);
+        $$.setBasic(EbtVoid, EvqAttribute, @1);
     }
     | VARYING {
-        if (context->globalErrorCheck($1.line, context->symbolTable.atGlobalLevel(), "varying"))
+        if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "varying"))
             context->recover();
         if (context->shaderType == SH_VERTEX_SHADER)
-            $$.setBasic(EbtVoid, EvqVaryingOut, $1.line);
+            $$.setBasic(EbtVoid, EvqVaryingOut, @1);
         else
-            $$.setBasic(EbtVoid, EvqVaryingIn, $1.line);
+            $$.setBasic(EbtVoid, EvqVaryingIn, @1);
     }
     | INVARIANT VARYING {
-        if (context->globalErrorCheck($1.line, context->symbolTable.atGlobalLevel(), "invariant varying"))
+        if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "invariant varying"))
             context->recover();
         if (context->shaderType == SH_VERTEX_SHADER)
-            $$.setBasic(EbtVoid, EvqInvariantVaryingOut, $1.line);
+            $$.setBasic(EbtVoid, EvqInvariantVaryingOut, @1);
         else
-            $$.setBasic(EbtVoid, EvqInvariantVaryingIn, $1.line);
+            $$.setBasic(EbtVoid, EvqInvariantVaryingIn, @1);
     }
     | UNIFORM {
-        if (context->globalErrorCheck($1.line, context->symbolTable.atGlobalLevel(), "uniform"))
+        if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "uniform"))
             context->recover();
-        $$.setBasic(EbtVoid, EvqUniform, $1.line);
+        $$.setBasic(EbtVoid, EvqUniform, @1);
     }
     ;
 
@@ -1522,7 +1537,7 @@
 
         if ($$.precision == EbpUndefined) {
             $$.precision = context->symbolTable.getDefaultPrecision($1.type);
-            if (context->precisionErrorCheck($1.line, $$.precision, $1.type)) {
+            if (context->precisionErrorCheck(@1, $$.precision, $1.type)) {
                 context->recover();
             }
         }
@@ -1552,11 +1567,11 @@
     | type_specifier_nonarray LEFT_BRACKET constant_expression RIGHT_BRACKET {
         $$ = $1;
 
-        if (context->arrayTypeErrorCheck($2.line, $1))
+        if (context->arrayTypeErrorCheck(@2, $1))
             context->recover();
         else {
             int size;
-            if (context->arraySizeErrorCheck($2.line, $3, size))
+            if (context->arraySizeErrorCheck(@2, $3, size))
                 context->recover();
             $$.setArray(true, size);
         }
@@ -1566,118 +1581,118 @@
 type_specifier_nonarray
     : VOID_TYPE {
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
-        $$.setBasic(EbtVoid, qual, $1.line);
+        $$.setBasic(EbtVoid, qual, @1);
     }
     | FLOAT_TYPE {
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
-        $$.setBasic(EbtFloat, qual, $1.line);
+        $$.setBasic(EbtFloat, qual, @1);
     }
     | INT_TYPE {
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
-        $$.setBasic(EbtInt, qual, $1.line);
+        $$.setBasic(EbtInt, qual, @1);
     }
     | BOOL_TYPE {
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
-        $$.setBasic(EbtBool, qual, $1.line);
+        $$.setBasic(EbtBool, qual, @1);
     }
 //    | UNSIGNED INT_TYPE {
-//        PACK_UNPACK_ONLY("unsigned", $1.line);
+//        PACK_UNPACK_ONLY("unsigned", @1);
 //        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
-//        $$.setBasic(EbtInt, qual, $1.line);
+//        $$.setBasic(EbtInt, qual, @1);
 //    }
     | VEC2 {
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
-        $$.setBasic(EbtFloat, qual, $1.line);
+        $$.setBasic(EbtFloat, qual, @1);
         $$.setAggregate(2);
     }
     | VEC3 {
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
-        $$.setBasic(EbtFloat, qual, $1.line);
+        $$.setBasic(EbtFloat, qual, @1);
         $$.setAggregate(3);
     }
     | VEC4 {
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
-        $$.setBasic(EbtFloat, qual, $1.line);
+        $$.setBasic(EbtFloat, qual, @1);
         $$.setAggregate(4);
     }
     | BVEC2 {
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
-        $$.setBasic(EbtBool, qual, $1.line);
+        $$.setBasic(EbtBool, qual, @1);
         $$.setAggregate(2);
     }
     | BVEC3 {
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
-        $$.setBasic(EbtBool, qual, $1.line);
+        $$.setBasic(EbtBool, qual, @1);
         $$.setAggregate(3);
     }
     | BVEC4 {
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
-        $$.setBasic(EbtBool, qual, $1.line);
+        $$.setBasic(EbtBool, qual, @1);
         $$.setAggregate(4);
     }
     | IVEC2 {
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
-        $$.setBasic(EbtInt, qual, $1.line);
+        $$.setBasic(EbtInt, qual, @1);
         $$.setAggregate(2);
     }
     | IVEC3 {
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
-        $$.setBasic(EbtInt, qual, $1.line);
+        $$.setBasic(EbtInt, qual, @1);
         $$.setAggregate(3);
     }
     | IVEC4 {
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
-        $$.setBasic(EbtInt, qual, $1.line);
+        $$.setBasic(EbtInt, qual, @1);
         $$.setAggregate(4);
     }
     | MATRIX2 {
-        FRAG_VERT_ONLY("mat2", $1.line);
+        FRAG_VERT_ONLY("mat2", @1);
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
-        $$.setBasic(EbtFloat, qual, $1.line);
+        $$.setBasic(EbtFloat, qual, @1);
         $$.setAggregate(2, true);
     }
     | MATRIX3 {
-        FRAG_VERT_ONLY("mat3", $1.line);
+        FRAG_VERT_ONLY("mat3", @1);
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
-        $$.setBasic(EbtFloat, qual, $1.line);
+        $$.setBasic(EbtFloat, qual, @1);
         $$.setAggregate(3, true);
     }
     | MATRIX4 {
-        FRAG_VERT_ONLY("mat4", $1.line);
+        FRAG_VERT_ONLY("mat4", @1);
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
-        $$.setBasic(EbtFloat, qual, $1.line);
+        $$.setBasic(EbtFloat, qual, @1);
         $$.setAggregate(4, true);
     }
     | SAMPLER2D {
-        FRAG_VERT_ONLY("sampler2D", $1.line);
+        FRAG_VERT_ONLY("sampler2D", @1);
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
-        $$.setBasic(EbtSampler2D, qual, $1.line);
+        $$.setBasic(EbtSampler2D, qual, @1);
     }
     | SAMPLERCUBE {
-        FRAG_VERT_ONLY("samplerCube", $1.line);
+        FRAG_VERT_ONLY("samplerCube", @1);
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
-        $$.setBasic(EbtSamplerCube, qual, $1.line);
+        $$.setBasic(EbtSamplerCube, qual, @1);
     }
     | SAMPLER_EXTERNAL_OES {
         if (!context->supportsExtension("GL_OES_EGL_image_external")) {
-            context->error($1.line, "unsupported type", "samplerExternalOES");
+            context->error(@1, "unsupported type", "samplerExternalOES");
             context->recover();
         }
-        FRAG_VERT_ONLY("samplerExternalOES", $1.line);
+        FRAG_VERT_ONLY("samplerExternalOES", @1);
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
-        $$.setBasic(EbtSamplerExternalOES, qual, $1.line);
+        $$.setBasic(EbtSamplerExternalOES, qual, @1);
     }
     | SAMPLER2DRECT {
         if (!context->supportsExtension("GL_ARB_texture_rectangle")) {
-            context->error($1.line, "unsupported type", "sampler2DRect");
+            context->error(@1, "unsupported type", "sampler2DRect");
             context->recover();
         }
-        FRAG_VERT_ONLY("sampler2DRect", $1.line);
+        FRAG_VERT_ONLY("sampler2DRect", @1);
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
-        $$.setBasic(EbtSampler2DRect, qual, $1.line);
+        $$.setBasic(EbtSampler2DRect, qual, @1);
     }
     | struct_specifier {
-        FRAG_VERT_ONLY("struct", $1.line);
+        FRAG_VERT_ONLY("struct", @1);
         $$ = $1;
         $$.qualifier = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
     }
@@ -1688,29 +1703,29 @@
         //
         TType& structure = static_cast<TVariable*>($1.symbol)->getType();
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
-        $$.setBasic(EbtStruct, qual, $1.line);
+        $$.setBasic(EbtStruct, qual, @1);
         $$.userDef = &structure;
     }
     ;
 
 struct_specifier
-    : STRUCT identifier LEFT_BRACE { if (context->enterStructDeclaration($2.line, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE {
-        if (context->reservedErrorCheck($2.line, *$2.string))
+    : STRUCT identifier LEFT_BRACE { if (context->enterStructDeclaration(@2, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE {
+        if (context->reservedErrorCheck(@2, *$2.string))
             context->recover();
 
         TType* structure = new TType($5.structure, *$2.string);
         TVariable* userTypeDef = new TVariable($2.string, *structure, true);
         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();
         }
-        $$.setBasic(EbtStruct, EvqTemporary, $1.line);
+        $$.setBasic(EbtStruct, EvqTemporary, @1);
         $$.userDef = structure;
         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(""));
-        $$.setBasic(EbtStruct, EvqTemporary, $1.line);
+        $$.setBasic(EbtStruct, EvqTemporary, @1);
         $$.userDef = structure;
         context->exitStructDeclaration();
     }
@@ -1726,7 +1741,7 @@
             TType* field = (*$2.structure)[i];
             for (size_t j = 0; j < $$.structure->size(); ++j) {
                 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();
                 }
             }
@@ -1739,7 +1754,7 @@
     : type_specifier struct_declarator_list SEMICOLON {
         $$ = $2;
 
-        if (context->voidErrorCheck($1.line, (*$2.structure)[0]->getFieldName(), $1)) {
+        if (context->voidErrorCheck(@1, (*$2.structure)[0]->getFieldName(), $1)) {
             context->recover();
         }
         for (unsigned int i = 0; i < $$.structure->size(); ++i) {
@@ -1754,7 +1769,7 @@
 
             // don't allow arrays of arrays
             if (type->isArray()) {
-                if (context->arrayTypeErrorCheck($1.line, $1))
+                if (context->arrayTypeErrorCheck(@1, $1))
                     context->recover();
             }
             if ($1.array)
@@ -1764,7 +1779,7 @@
                 type->setTypeName($1.userDef->getTypeName());
             }
 
-            if (context->structNestingErrorCheck($1.line, *type)) {
+            if (context->structNestingErrorCheck(@1, *type)) {
                 context->recover();
             }
         }
@@ -1783,21 +1798,21 @@
 
 struct_declarator
     : identifier {
-        if (context->reservedErrorCheck($1.line, *$1.string))
+        if (context->reservedErrorCheck(@1, *$1.string))
             context->recover();
 
         $$ = new TType(EbtVoid, EbpUndefined);
         $$->setFieldName(*$1.string);
     }
     | identifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
-        if (context->reservedErrorCheck($1.line, *$1.string))
+        if (context->reservedErrorCheck(@1, *$1.string))
             context->recover();
 
         $$ = new TType(EbtVoid, EbpUndefined);
         $$->setFieldName(*$1.string);
 
         int size;
-        if (context->arraySizeErrorCheck($2.line, $3, size))
+        if (context->arraySizeErrorCheck(@2, $3, size))
             context->recover();
         $$->setArraySize(size);
     }
@@ -1831,7 +1846,7 @@
     | LEFT_BRACE { context->symbolTable.push(); } statement_list { context->symbolTable.pop(); } RIGHT_BRACE {
         if ($3 != 0) {
             $3->setOp(EOpSequence);
-            $3->setEndLine($5.line);
+            $3->setLine(@$);
         }
         $$ = $3;
     }
@@ -1855,7 +1870,7 @@
     | LEFT_BRACE statement_list RIGHT_BRACE {
         if ($2) {
             $2->setOp(EOpSequence);
-            $2->setEndLine($3.line);
+            $2->setLine(@$);
         }
         $$ = $2;
     }
@@ -1863,10 +1878,10 @@
 
 statement_list
     : statement {
-        $$ = context->intermediate.makeAggregate($1, 0);
+        $$ = context->intermediate.makeAggregate($1, @$);
     }
     | statement_list statement {
-        $$ = context->intermediate.growAggregate($1, $2, 0);
+        $$ = context->intermediate.growAggregate($1, $2, @$);
     }
     ;
 
@@ -1877,9 +1892,9 @@
 
 selection_statement
     : IF LEFT_PAREN expression RIGHT_PAREN selection_rest_statement {
-        if (context->boolErrorCheck($1.line, $3))
+        if (context->boolErrorCheck(@1, $3))
             context->recover();
-        $$ = context->intermediate.addSelection($3, $5, $1.line);
+        $$ = context->intermediate.addSelection($3, $5, @1);
     }
     ;
 
@@ -1905,12 +1920,12 @@
     }
     | fully_specified_type identifier EQUAL initializer {
         TIntermNode* intermNode;
-        if (context->structQualifierErrorCheck($2.line, $1))
+        if (context->structQualifierErrorCheck(@2, $1))
             context->recover();
-        if (context->boolErrorCheck($2.line, $1))
+        if (context->boolErrorCheck(@2, $1))
             context->recover();
 
-        if (!context->executeInitializer($2.line, *$2.string, $1, $4, intermNode))
+        if (!context->executeInitializer(@2, *$2.string, $1, $4, intermNode))
             $$ = $4;
         else {
             context->recover();
@@ -1922,19 +1937,19 @@
 iteration_statement
     : WHILE LEFT_PAREN { context->symbolTable.push(); ++context->loopNestingLevel; } condition RIGHT_PAREN statement_no_new_scope {
         context->symbolTable.pop();
-        $$ = context->intermediate.addLoop(ELoopWhile, 0, $4, 0, $6, $1.line);
+        $$ = context->intermediate.addLoop(ELoopWhile, 0, $4, 0, $6, @1);
         --context->loopNestingLevel;
     }
     | 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->intermediate.addLoop(ELoopDoWhile, 0, $6, 0, $3, $4.line);
+        $$ = context->intermediate.addLoop(ELoopDoWhile, 0, $6, 0, $3, @4);
         --context->loopNestingLevel;
     }
     | FOR LEFT_PAREN { context->symbolTable.push(); ++context->loopNestingLevel; } for_init_statement for_rest_statement RIGHT_PAREN statement_no_new_scope {
         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;
     }
     ;
@@ -1971,39 +1986,39 @@
 jump_statement
     : CONTINUE SEMICOLON {
         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->intermediate.addBranch(EOpContinue, $1.line);
+        $$ = context->intermediate.addBranch(EOpContinue, @1);
     }
     | BREAK SEMICOLON {
         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->intermediate.addBranch(EOpBreak, $1.line);
+        $$ = context->intermediate.addBranch(EOpBreak, @1);
     }
     | RETURN SEMICOLON {
-        $$ = context->intermediate.addBranch(EOpReturn, $1.line);
+        $$ = context->intermediate.addBranch(EOpReturn, @1);
         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();
         }
     }
     | RETURN expression SEMICOLON {
-        $$ = context->intermediate.addBranch(EOpReturn, $2, $1.line);
+        $$ = context->intermediate.addBranch(EOpReturn, $2, @1);
         context->functionReturnsValue = true;
         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();
         } 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();
         }
     }
     | DISCARD SEMICOLON {
-        FRAG_ONLY("discard", $1.line);
-        $$ = context->intermediate.addBranch(EOpKill, $1.line);
+        FRAG_ONLY("discard", @1);
+        $$ = context->intermediate.addBranch(EOpKill, @1);
     }
     ;
 
@@ -2015,7 +2030,7 @@
         context->treeRoot = $$;
     }
     | translation_unit external_declaration {
-        $$ = context->intermediate.growAggregate($1, $2, 0);
+        $$ = context->intermediate.growAggregate($1, $2, @$);
         context->treeRoot = $$;
     }
     ;
@@ -2037,7 +2052,7 @@
         
         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();
         }
         
@@ -2051,7 +2066,7 @@
             //
             // 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();
         }
         prevDec->setDefined();
@@ -2061,11 +2076,11 @@
         //
         if (function->getName() == "main") {
             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();
             }
             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();
             }
         }
@@ -2093,7 +2108,7 @@
                 // Insert the parameters with name in the symbol table.
                 //
                 if (! context->symbolTable.insert(*variable)) {
-                    context->error($1.line, "redefinition", variable->getName().c_str());
+                    context->error(@1, "redefinition", variable->getName().c_str());
                     context->recover();
                     delete variable;
                 }
@@ -2104,14 +2119,15 @@
                 paramNodes = context->intermediate.growAggregate(
                                                paramNodes,
                                                context->intermediate.addSymbol(variable->getUniqueId(),
-                                                                       variable->getName(),
-                                                                       variable->getType(), $1.line),
-                                               $1.line);
+                                                                               variable->getName(),
+                                                                               variable->getType(),
+                                                                               @1),
+                                               @1);
             } 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;
         context->loopNestingLevel = 0;
     }
@@ -2119,12 +2135,12 @@
         //?? Check that all paths return a value if return type != void ?
         //   May be best done as post process phase on intermediate code
         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->intermediate.growAggregate($1.intermAggregate, $3, 0);
-        context->intermediate.setAggregateOperator($$, EOpFunction, $1.line);
+        $$ = context->intermediate.growAggregate($1.intermAggregate, $3, @$);
+        context->intermediate.setAggregateOperator($$, EOpFunction, @1);
         $$->getAsAggregate()->setName($1.function->getMangledName().c_str());
         $$->getAsAggregate()->setType($1.function->getReturnType());
 
@@ -2133,15 +2149,17 @@
         $$->getAsAggregate()->setOptimize(context->pragma().optimize);
         $$->getAsAggregate()->setDebug(context->pragma().debug);
 
-        if ($3 && $3->getAsAggregate())
-            $$->getAsAggregate()->setEndLine($3->getAsAggregate()->getEndLine());
-
         context->symbolTable.pop();
     }
     ;
 
 %%
 
+void yyerror(YYLTYPE* yylloc, TParseContext* context, const char* reason) {
+    context->error(*yylloc, reason, "");
+    context->recover();
+}
+
 int glslang_parse(TParseContext* context) {
     return yyparse(context);
 }
diff --git a/src/compiler/glslang_lex.cpp b/src/compiler/glslang_lex.cpp
index 508cdb4..5ec7791 100644
--- a/src/compiler/glslang_lex.cpp
+++ b/src/compiler/glslang_lex.cpp
@@ -791,7 +791,10 @@
 #pragma warning(disable : 4102)
 #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) \
     result = string_input(buf, max_size, yyscanner);
 
@@ -837,6 +840,8 @@
 
     YYSTYPE * yylval_r;
 
+    YYLTYPE * yylloc_r;
+
     }; /* end struct yyguts_t */
 
 static int yy_init_globals (yyscan_t yyscanner );
@@ -845,6 +850,8 @@
      * from bison output in section 1.*/
     #    define yylval yyg->yylval_r
     
+    #    define yylloc yyg->yylloc_r
+    
 int yylex_init (yyscan_t* scanner);
 
 int yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
@@ -882,6 +889,10 @@
 
 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
  * section 1.
  */
@@ -988,10 +999,10 @@
 #define YY_DECL_IS_OURS 1
 
 extern int yylex \
-               (YYSTYPE * yylval_param ,yyscan_t yyscanner);
+               (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner);
 
 #define YY_DECL int yylex \
-               (YYSTYPE * yylval_param , yyscan_t yyscanner)
+               (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner)
 #endif /* !YY_DECL */
 
 /* Code executed at the beginning of each rule, after yytext and yyleng
@@ -1020,6 +1031,8 @@
 
     yylval = yylval_param;
 
+    yylloc = yylloc_param;
+
 	if ( !yyg->yy_init )
 		{
 		yyg->yy_init = 1;
@@ -2659,6 +2672,18 @@
     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 */
 
 /* yylex_init is special because it creates the scanner itself, so it is
@@ -2840,7 +2865,8 @@
     yy_size_t len = token.type == pp::Token::LAST ? 0 : token.text.size();
     if (len < max_size)
         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)
         YY_FATAL_ERROR("Input buffer overflow");
@@ -2866,18 +2892,11 @@
 int reserved_word(yyscan_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();
     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) {
     yyscan_t scanner = NULL;
     if (yylex_init_extra(context,&scanner))
@@ -2900,7 +2919,8 @@
 int glslang_scan(size_t count, const char* const string[], const int length[],
                  TParseContext* context) {
     yyrestart(NULL,context->scanner);
-    yyset_lineno(EncodeSourceLoc(0, 1),context->scanner);
+    yyset_column(0,context->scanner);
+    yyset_lineno(1,context->scanner);
 
     // Initialize preprocessor.
     if (!context->preprocessor.init(count, string, length))
diff --git a/src/compiler/glslang_tab.cpp b/src/compiler/glslang_tab.cpp
index 74502fb..4d2c9d5 100644
--- a/src/compiler/glslang_tab.cpp
+++ b/src/compiler/glslang_tab.cpp
@@ -89,7 +89,6 @@
 #include "GLSLANG/ShaderLang.h"
 
 #define YYENABLE_NLS 0
-#define YYLTYPE_IS_TRIVIAL 1
 
 #define YYLEX_PARAM context->scanner
 
@@ -122,6 +121,14 @@
 #if YYDEBUG
 extern int yydebug;
 #endif
+/* "%code requires" blocks.  */
+
+
+#define YYLTYPE TSourceLoc
+#define YYLTYPE_IS_DECLARED 1
+
+
+
 
 /* Tokens.  */
 #ifndef YYTOKENTYPE
@@ -231,7 +238,6 @@
 
 
     struct {
-        TSourceLoc line;
         union {
             TString *string;
             float f;
@@ -241,7 +247,6 @@
         TSymbol* symbol;
     } lex;
     struct {
-        TSourceLoc line;
         TOperator op;
         union {
             TIntermNode* intermNode;
@@ -268,6 +273,19 @@
 # define YYSTYPE_IS_DECLARED 1
 #endif
 
+#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
+
 
 #ifdef YYPARSE_PARAM
 #if defined __STDC__ || defined __cplusplus
@@ -288,8 +306,24 @@
 /* Copy the second part of user declarations.  */
 
 
-extern int yylex(YYSTYPE* yylval_param, void* yyscanner);
-extern void yyerror(TParseContext* context, const char* reason);
+extern int yylex(YYSTYPE* yylval, YYLTYPE* yylloc, void* yyscanner);
+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) {  \
     if (context->shaderType != SH_FRAGMENT_SHADER &&  \
@@ -472,13 +506,15 @@
 
 #if (! defined yyoverflow \
      && (! defined __cplusplus \
-	 || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+	 || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \
+	     && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
 
 /* A type that is properly aligned for any stack member.  */
 union yyalloc
 {
   yytype_int16 yyss_alloc;
   YYSTYPE yyvs_alloc;
+  YYLTYPE yyls_alloc;
 };
 
 /* The size of the maximum gap between one aligned stack and the next.  */
@@ -487,8 +523,8 @@
 /* The size of an array large to enough to hold all stacks, each with
    N elements.  */
 # define YYSTACK_BYTES(N) \
-     ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
-      + YYSTACK_GAP_MAXIMUM)
+     ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
+      + 2 * YYSTACK_GAP_MAXIMUM)
 
 # define YYCOPY_NEEDED 1
 
@@ -685,27 +721,27 @@
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
-       0,   168,   168,   169,   172,   207,   210,   223,   228,   233,
-     239,   242,   321,   324,   425,   435,   448,   456,   556,   559,
-     567,   571,   578,   582,   589,   595,   604,   612,   667,   677,
-     680,   690,   700,   721,   722,   723,   728,   729,   738,   750,
-     751,   759,   770,   774,   775,   785,   795,   805,   818,   819,
-     829,   842,   846,   850,   854,   855,   868,   869,   882,   883,
-     896,   897,   914,   915,   928,   929,   930,   931,   932,   936,
-     939,   950,   958,   985,   990,  1004,  1042,  1045,  1052,  1060,
-    1081,  1102,  1113,  1142,  1147,  1157,  1162,  1172,  1175,  1178,
-    1181,  1187,  1194,  1197,  1219,  1237,  1261,  1284,  1288,  1306,
-    1314,  1346,  1366,  1455,  1464,  1487,  1490,  1496,  1504,  1512,
-    1520,  1530,  1537,  1540,  1543,  1549,  1552,  1567,  1571,  1575,
-    1579,  1588,  1593,  1598,  1603,  1608,  1613,  1618,  1623,  1628,
-    1633,  1639,  1645,  1651,  1656,  1661,  1670,  1679,  1684,  1697,
-    1697,  1711,  1711,  1720,  1723,  1739,  1775,  1779,  1785,  1792,
-    1807,  1811,  1815,  1816,  1822,  1823,  1824,  1825,  1826,  1830,
-    1831,  1831,  1831,  1841,  1842,  1846,  1846,  1847,  1847,  1852,
-    1855,  1865,  1868,  1874,  1875,  1879,  1887,  1891,  1901,  1906,
-    1923,  1923,  1928,  1928,  1935,  1935,  1943,  1946,  1952,  1955,
-    1961,  1965,  1972,  1979,  1986,  1993,  2004,  2013,  2017,  2024,
-    2027,  2033,  2033
+       0,   187,   187,   188,   191,   227,   230,   243,   248,   253,
+     259,   262,   341,   344,   445,   455,   468,   476,   576,   579,
+     587,   590,   596,   600,   607,   613,   622,   630,   685,   695,
+     698,   708,   718,   739,   740,   741,   746,   747,   756,   768,
+     769,   777,   788,   792,   793,   803,   813,   823,   836,   837,
+     847,   860,   864,   868,   872,   873,   886,   887,   900,   901,
+     914,   915,   932,   933,   946,   947,   948,   949,   950,   954,
+     957,   968,   976,  1003,  1008,  1022,  1059,  1062,  1069,  1077,
+    1098,  1119,  1129,  1157,  1162,  1172,  1177,  1187,  1190,  1193,
+    1196,  1202,  1209,  1212,  1234,  1252,  1276,  1299,  1303,  1321,
+    1329,  1361,  1381,  1470,  1479,  1502,  1505,  1511,  1519,  1527,
+    1535,  1545,  1552,  1555,  1558,  1564,  1567,  1582,  1586,  1590,
+    1594,  1603,  1608,  1613,  1618,  1623,  1628,  1633,  1638,  1643,
+    1648,  1654,  1660,  1666,  1671,  1676,  1685,  1694,  1699,  1712,
+    1712,  1726,  1726,  1735,  1738,  1754,  1790,  1794,  1800,  1807,
+    1822,  1826,  1830,  1831,  1837,  1838,  1839,  1840,  1841,  1845,
+    1846,  1846,  1846,  1856,  1857,  1861,  1861,  1862,  1862,  1867,
+    1870,  1880,  1883,  1889,  1890,  1894,  1902,  1906,  1916,  1921,
+    1938,  1938,  1943,  1943,  1950,  1950,  1958,  1961,  1967,  1970,
+    1976,  1980,  1987,  1994,  2001,  2008,  2019,  2028,  2032,  2039,
+    2042,  2048,  2048
 };
 #endif
 
@@ -1330,7 +1366,7 @@
     }                                                           \
   else                                                          \
     {                                                           \
-      yyerror (context, YY_("syntax error: cannot back up")); \
+      yyerror (&yylloc, context, YY_("syntax error: cannot back up")); \
       YYERROR;							\
     }								\
 while (YYID (0))
@@ -1340,17 +1376,90 @@
 #define YYERRCODE	256
 
 
-/* This macro is provided for backward compatibility. */
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+   If N is 0, then set CURRENT to the empty location which ends
+   the previous symbol: RHS[0] (always defined).  */
+
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N)                                \
+    do                                                                  \
+      if (YYID (N))                                                     \
+        {                                                               \
+          (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;        \
+          (Current).first_column = YYRHSLOC (Rhs, 1).first_column;      \
+          (Current).last_line    = YYRHSLOC (Rhs, N).last_line;         \
+          (Current).last_column  = YYRHSLOC (Rhs, N).last_column;       \
+        }                                                               \
+      else                                                              \
+        {                                                               \
+          (Current).first_line   = (Current).last_line   =              \
+            YYRHSLOC (Rhs, 0).last_line;                                \
+          (Current).first_column = (Current).last_column =              \
+            YYRHSLOC (Rhs, 0).last_column;                              \
+        }                                                               \
+    while (YYID (0))
+#endif
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+
+
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+   This macro was not mandated originally: define only if we know
+   we won't break user code: when these are the locations we know.  */
+
 #ifndef YY_LOCATION_PRINT
-# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
+
+/* Print *YYLOCP on YYO.  Private, do not rely on its existence. */
+
+__attribute__((__unused__))
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static unsigned
+yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp)
+#else
+static unsigned
+yy_location_print_ (yyo, yylocp)
+    FILE *yyo;
+    YYLTYPE const * const yylocp;
+#endif
+{
+  unsigned res = 0;
+  int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0;
+  if (0 <= yylocp->first_line)
+    {
+      res += fprintf (yyo, "%d", yylocp->first_line);
+      if (0 <= yylocp->first_column)
+        res += fprintf (yyo, ".%d", yylocp->first_column);
+    }
+  if (0 <= yylocp->last_line)
+    {
+      if (yylocp->first_line < yylocp->last_line)
+        {
+          res += fprintf (yyo, "-%d", yylocp->last_line);
+          if (0 <= end_col)
+            res += fprintf (yyo, ".%d", end_col);
+        }
+      else if (0 <= end_col && yylocp->first_column < end_col)
+        res += fprintf (yyo, "-%d", end_col);
+    }
+  return res;
+ }
+
+#  define YY_LOCATION_PRINT(File, Loc)          \
+  yy_location_print_ (File, &(Loc))
+
+# else
+#  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
 #endif
 
 
 /* YYLEX -- calling `yylex' with the right arguments.  */
 #ifdef YYLEX_PARAM
-# define YYLEX yylex (&yylval, YYLEX_PARAM)
+# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM)
 #else
-# define YYLEX yylex (&yylval)
+# define YYLEX yylex (&yylval, &yylloc)
 #endif
 
 /* Enable debugging if requested.  */
@@ -1373,7 +1482,7 @@
     {									  \
       YYFPRINTF (stderr, "%s ", Title);					  \
       yy_symbol_print (stderr,						  \
-		  Type, Value, context); \
+		  Type, Value, Location, context); \
       YYFPRINTF (stderr, "\n");						  \
     }									  \
 } while (YYID (0))
@@ -1387,13 +1496,14 @@
 #if (defined __STDC__ || defined __C99__FUNC__ \
      || defined __cplusplus || defined _MSC_VER)
 static void
-yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, TParseContext* context)
+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, TParseContext* context)
 #else
 static void
-yy_symbol_value_print (yyoutput, yytype, yyvaluep, context)
+yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, context)
     FILE *yyoutput;
     int yytype;
     YYSTYPE const * const yyvaluep;
+    YYLTYPE const * const yylocationp;
     TParseContext* context;
 #endif
 {
@@ -1401,6 +1511,7 @@
   YYUSE (yyo);
   if (!yyvaluep)
     return;
+  YYUSE (yylocationp);
   YYUSE (context);
 # ifdef YYPRINT
   if (yytype < YYNTOKENS)
@@ -1423,13 +1534,14 @@
 #if (defined __STDC__ || defined __C99__FUNC__ \
      || defined __cplusplus || defined _MSC_VER)
 static void
-yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, TParseContext* context)
+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, TParseContext* context)
 #else
 static void
-yy_symbol_print (yyoutput, yytype, yyvaluep, context)
+yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp, context)
     FILE *yyoutput;
     int yytype;
     YYSTYPE const * const yyvaluep;
+    YYLTYPE const * const yylocationp;
     TParseContext* context;
 #endif
 {
@@ -1438,7 +1550,9 @@
   else
     YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
 
-  yy_symbol_value_print (yyoutput, yytype, yyvaluep, context);
+  YY_LOCATION_PRINT (yyoutput, *yylocationp);
+  YYFPRINTF (yyoutput, ": ");
+  yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, context);
   YYFPRINTF (yyoutput, ")");
 }
 
@@ -1481,11 +1595,12 @@
 #if (defined __STDC__ || defined __C99__FUNC__ \
      || defined __cplusplus || defined _MSC_VER)
 static void
-yy_reduce_print (YYSTYPE *yyvsp, int yyrule, TParseContext* context)
+yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, TParseContext* context)
 #else
 static void
-yy_reduce_print (yyvsp, yyrule, context)
+yy_reduce_print (yyvsp, yylsp, yyrule, context)
     YYSTYPE *yyvsp;
+    YYLTYPE *yylsp;
     int yyrule;
     TParseContext* context;
 #endif
@@ -1501,7 +1616,7 @@
       YYFPRINTF (stderr, "   $%d = ", yyi + 1);
       yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
 		       &(yyvsp[(yyi + 1) - (yynrhs)])
-		       		       , context);
+		       , &(yylsp[(yyi + 1) - (yynrhs)])		       , context);
       YYFPRINTF (stderr, "\n");
     }
 }
@@ -1509,7 +1624,7 @@
 # define YY_REDUCE_PRINT(Rule)		\
 do {					\
   if (yydebug)				\
-    yy_reduce_print (yyvsp, Rule, context); \
+    yy_reduce_print (yyvsp, yylsp, Rule, context); \
 } while (YYID (0))
 
 /* Nonzero means print parse trace.  It is left uninitialized so that
@@ -1789,17 +1904,19 @@
 #if (defined __STDC__ || defined __C99__FUNC__ \
      || defined __cplusplus || defined _MSC_VER)
 static void
-yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, TParseContext* context)
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, TParseContext* context)
 #else
 static void
-yydestruct (yymsg, yytype, yyvaluep, context)
+yydestruct (yymsg, yytype, yyvaluep, yylocationp, context)
     const char *yymsg;
     int yytype;
     YYSTYPE *yyvaluep;
+    YYLTYPE *yylocationp;
     TParseContext* context;
 #endif
 {
   YYUSE (yyvaluep);
+  YYUSE (yylocationp);
   YYUSE (context);
 
   if (!yymsg)
@@ -1861,6 +1978,11 @@
 static YYSTYPE yyval_default;
 # define YY_INITIAL_VALUE(Value) = Value
 #endif
+static YYLTYPE yyloc_default
+# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
+  = { 1, 1, 1, 1 }
+# endif
+;
 #ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
 # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
 # define YY_IGNORE_MAYBE_UNINITIALIZED_END
@@ -1872,6 +1994,10 @@
 /* The semantic value of the lookahead symbol.  */
 YYSTYPE yylval YY_INITIAL_VALUE(yyval_default);
 
+/* Location data for the lookahead symbol.  */
+YYLTYPE yylloc = yyloc_default;
+
+
     /* Number of syntax errors so far.  */
     int yynerrs;
 
@@ -1882,6 +2008,7 @@
     /* The stacks and their tools:
        `yyss': related to states.
        `yyvs': related to semantic values.
+       `yyls': related to locations.
 
        Refer to the stacks through separate pointers, to allow yyoverflow
        to reallocate them elsewhere.  */
@@ -1896,6 +2023,14 @@
     YYSTYPE *yyvs;
     YYSTYPE *yyvsp;
 
+    /* The location stack.  */
+    YYLTYPE yylsa[YYINITDEPTH];
+    YYLTYPE *yyls;
+    YYLTYPE *yylsp;
+
+    /* The locations where the error started and ended.  */
+    YYLTYPE yyerror_range[3];
+
     YYSIZE_T yystacksize;
 
   int yyn;
@@ -1905,6 +2040,7 @@
   /* The variables used to return semantic value and location from the
      action routines.  */
   YYSTYPE yyval;
+  YYLTYPE yyloc;
 
 #if YYERROR_VERBOSE
   /* Buffer for error messages, and its allocated size.  */
@@ -1913,7 +2049,7 @@
   YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
 #endif
 
-#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N))
+#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N), yylsp -= (N))
 
   /* The number of symbols on the RHS of the reduced rule.
      Keep to zero when no symbol should be popped.  */
@@ -1921,6 +2057,7 @@
 
   yyssp = yyss = yyssa;
   yyvsp = yyvs = yyvsa;
+  yylsp = yyls = yylsa;
   yystacksize = YYINITDEPTH;
 
   YYDPRINTF ((stderr, "Starting parse\n"));
@@ -1929,6 +2066,7 @@
   yyerrstatus = 0;
   yynerrs = 0;
   yychar = YYEMPTY; /* Cause a token to be read.  */
+  yylsp[0] = yylloc;
   goto yysetstate;
 
 /*------------------------------------------------------------.
@@ -1954,6 +2092,7 @@
 	   memory.  */
 	YYSTYPE *yyvs1 = yyvs;
 	yytype_int16 *yyss1 = yyss;
+	YYLTYPE *yyls1 = yyls;
 
 	/* Each stack pointer address is followed by the size of the
 	   data in use in that stack, in bytes.  This used to be a
@@ -1962,8 +2101,10 @@
 	yyoverflow (YY_("memory exhausted"),
 		    &yyss1, yysize * sizeof (*yyssp),
 		    &yyvs1, yysize * sizeof (*yyvsp),
+		    &yyls1, yysize * sizeof (*yylsp),
 		    &yystacksize);
 
+	yyls = yyls1;
 	yyss = yyss1;
 	yyvs = yyvs1;
       }
@@ -1986,6 +2127,7 @@
 	  goto yyexhaustedlab;
 	YYSTACK_RELOCATE (yyss_alloc, yyss);
 	YYSTACK_RELOCATE (yyvs_alloc, yyvs);
+	YYSTACK_RELOCATE (yyls_alloc, yyls);
 #  undef YYSTACK_RELOCATE
 	if (yyss1 != yyssa)
 	  YYSTACK_FREE (yyss1);
@@ -1995,6 +2137,7 @@
 
       yyssp = yyss + yysize - 1;
       yyvsp = yyvs + yysize - 1;
+      yylsp = yyls + yysize - 1;
 
       YYDPRINTF ((stderr, "Stack size increased to %lu\n",
 		  (unsigned long int) yystacksize));
@@ -2072,7 +2215,7 @@
   YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
   *++yyvsp = yylval;
   YY_IGNORE_MAYBE_UNINITIALIZED_END
-
+  *++yylsp = yylloc;
   goto yynewstate;
 
 
@@ -2103,7 +2246,8 @@
      GCC warning that YYVAL may be used uninitialized.  */
   yyval = yyvsp[1-yylen];
 
-
+  /* Default location.  */
+  YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);
   YY_REDUCE_PRINT (yyn);
   switch (yyn)
     {
@@ -2114,7 +2258,7 @@
         const TSymbol* symbol = (yyvsp[(1) - (1)].lex).symbol;
         const TVariable* variable;
         if (symbol == 0) {
-            context->error((yyvsp[(1) - (1)].lex).line, "undeclared identifier", (yyvsp[(1) - (1)].lex).string->c_str());
+            context->error((yylsp[(1) - (1)]), "undeclared identifier", (yyvsp[(1) - (1)].lex).string->c_str());
             context->recover();
             TType type(EbtFloat, EbpUndefined);
             TVariable* fakeVariable = new TVariable((yyvsp[(1) - (1)].lex).string, type);
@@ -2123,7 +2267,7 @@
         } else {
             // This identifier can only be a variable type symbol
             if (! symbol->isVariable()) {
-                context->error((yyvsp[(1) - (1)].lex).line, "variable expected", (yyvsp[(1) - (1)].lex).string->c_str());
+                context->error((yylsp[(1) - (1)]), "variable expected", (yyvsp[(1) - (1)].lex).string->c_str());
                 context->recover();
             }
             variable = static_cast<const TVariable*>(symbol);
@@ -2135,11 +2279,12 @@
         if (variable->getType().getQualifier() == EvqConst ) {
             ConstantUnion* constArray = variable->getConstPointer();
             TType t(variable->getType());
-            (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(constArray, t, (yyvsp[(1) - (1)].lex).line);
+            (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(constArray, t, (yylsp[(1) - (1)]));
         } else
             (yyval.interm.intermTypedNode) = context->intermediate.addSymbol(variable->getUniqueId(),
-                                                     variable->getName(),
-                                                     variable->getType(), (yyvsp[(1) - (1)].lex).line);
+                                                 variable->getName(),
+                                                 variable->getType(),
+                                                 (yylsp[(1) - (1)]));
     }
     break;
 
@@ -2158,12 +2303,12 @@
         // check for overflow for constants
         //
         if (abs((yyvsp[(1) - (1)].lex).i) >= (1 << 16)) {
-            context->error((yyvsp[(1) - (1)].lex).line, " integer constant overflow", "");
+            context->error((yylsp[(1) - (1)]), " integer constant overflow", "");
             context->recover();
         }
         ConstantUnion *unionArray = new ConstantUnion[1];
         unionArray->setIConst((yyvsp[(1) - (1)].lex).i);
-        (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), (yyvsp[(1) - (1)].lex).line);
+        (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), (yylsp[(1) - (1)]));
     }
     break;
 
@@ -2172,7 +2317,7 @@
     {
         ConstantUnion *unionArray = new ConstantUnion[1];
         unionArray->setFConst((yyvsp[(1) - (1)].lex).f);
-        (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConst), (yyvsp[(1) - (1)].lex).line);
+        (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConst), (yylsp[(1) - (1)]));
     }
     break;
 
@@ -2181,7 +2326,7 @@
     {
         ConstantUnion *unionArray = new ConstantUnion[1];
         unionArray->setBConst((yyvsp[(1) - (1)].lex).b);
-        (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yyvsp[(1) - (1)].lex).line);
+        (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yylsp[(1) - (1)]));
     }
     break;
 
@@ -2204,21 +2349,21 @@
     {
         if (!(yyvsp[(1) - (4)].interm.intermTypedNode)->isArray() && !(yyvsp[(1) - (4)].interm.intermTypedNode)->isMatrix() && !(yyvsp[(1) - (4)].interm.intermTypedNode)->isVector()) {
             if ((yyvsp[(1) - (4)].interm.intermTypedNode)->getAsSymbolNode())
-                context->error((yyvsp[(2) - (4)].lex).line, " left of '[' is not of type array, matrix, or vector ", (yyvsp[(1) - (4)].interm.intermTypedNode)->getAsSymbolNode()->getSymbol().c_str());
+                context->error((yylsp[(2) - (4)]), " left of '[' is not of type array, matrix, or vector ", (yyvsp[(1) - (4)].interm.intermTypedNode)->getAsSymbolNode()->getSymbol().c_str());
             else
-                context->error((yyvsp[(2) - (4)].lex).line, " left of '[' is not of type array, matrix, or vector ", "expression");
+                context->error((yylsp[(2) - (4)]), " left of '[' is not of type array, matrix, or vector ", "expression");
             context->recover();
         }
         if ((yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getQualifier() == EvqConst && (yyvsp[(3) - (4)].interm.intermTypedNode)->getQualifier() == EvqConst) {
             if ((yyvsp[(1) - (4)].interm.intermTypedNode)->isArray()) { // constant folding for arrays
-                (yyval.interm.intermTypedNode) = context->addConstArrayNode((yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getIConst(0), (yyvsp[(1) - (4)].interm.intermTypedNode), (yyvsp[(2) - (4)].lex).line);
+                (yyval.interm.intermTypedNode) = context->addConstArrayNode((yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getIConst(0), (yyvsp[(1) - (4)].interm.intermTypedNode), (yylsp[(2) - (4)]));
             } else if ((yyvsp[(1) - (4)].interm.intermTypedNode)->isVector()) {  // constant folding for vectors
                 TVectorFields fields;
                 fields.num = 1;
                 fields.offsets[0] = (yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getIConst(0); // need to do it this way because v.xy sends fields integer array
-                (yyval.interm.intermTypedNode) = context->addConstVectorNode(fields, (yyvsp[(1) - (4)].interm.intermTypedNode), (yyvsp[(2) - (4)].lex).line);
+                (yyval.interm.intermTypedNode) = context->addConstVectorNode(fields, (yyvsp[(1) - (4)].interm.intermTypedNode), (yylsp[(2) - (4)]));
             } else if ((yyvsp[(1) - (4)].interm.intermTypedNode)->isMatrix()) { // constant folding for matrices
-                (yyval.interm.intermTypedNode) = context->addConstMatrixNode((yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getIConst(0), (yyvsp[(1) - (4)].interm.intermTypedNode), (yyvsp[(2) - (4)].lex).line);
+                (yyval.interm.intermTypedNode) = context->addConstMatrixNode((yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getIConst(0), (yyvsp[(1) - (4)].interm.intermTypedNode), (yylsp[(2) - (4)]));
             }
         } else {
             if ((yyvsp[(3) - (4)].interm.intermTypedNode)->getQualifier() == EvqConst) {
@@ -2226,41 +2371,41 @@
                     std::stringstream extraInfoStream;
                     extraInfoStream << "field selection out of range '" << (yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getIConst(0) << "'";
                     std::string extraInfo = extraInfoStream.str();
-                    context->error((yyvsp[(2) - (4)].lex).line, "", "[", extraInfo.c_str());
+                    context->error((yylsp[(2) - (4)]), "", "[", extraInfo.c_str());
                     context->recover();
                 } else {
                     if ((yyvsp[(1) - (4)].interm.intermTypedNode)->isArray()) {
                         if ((yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getArraySize() == 0) {
                             if ((yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getMaxArraySize() <= (yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getIConst(0)) {
-                                if (context->arraySetMaxSize((yyvsp[(1) - (4)].interm.intermTypedNode)->getAsSymbolNode(), (yyvsp[(1) - (4)].interm.intermTypedNode)->getTypePointer(), (yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getIConst(0), true, (yyvsp[(2) - (4)].lex).line))
+                                if (context->arraySetMaxSize((yyvsp[(1) - (4)].interm.intermTypedNode)->getAsSymbolNode(), (yyvsp[(1) - (4)].interm.intermTypedNode)->getTypePointer(), (yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getIConst(0), true, (yylsp[(2) - (4)])))
                                     context->recover();
                             } else {
-                                if (context->arraySetMaxSize((yyvsp[(1) - (4)].interm.intermTypedNode)->getAsSymbolNode(), (yyvsp[(1) - (4)].interm.intermTypedNode)->getTypePointer(), 0, false, (yyvsp[(2) - (4)].lex).line))
+                                if (context->arraySetMaxSize((yyvsp[(1) - (4)].interm.intermTypedNode)->getAsSymbolNode(), (yyvsp[(1) - (4)].interm.intermTypedNode)->getTypePointer(), 0, false, (yylsp[(2) - (4)])))
                                     context->recover();
                             }
                         } else if ( (yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getIConst(0) >= (yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getArraySize()) {
                             std::stringstream extraInfoStream;
                             extraInfoStream << "array index out of range '" << (yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getIConst(0) << "'";
                             std::string extraInfo = extraInfoStream.str();
-                            context->error((yyvsp[(2) - (4)].lex).line, "", "[", extraInfo.c_str());
+                            context->error((yylsp[(2) - (4)]), "", "[", extraInfo.c_str());
                             context->recover();
                         }
                     }
-                    (yyval.interm.intermTypedNode) = context->intermediate.addIndex(EOpIndexDirect, (yyvsp[(1) - (4)].interm.intermTypedNode), (yyvsp[(3) - (4)].interm.intermTypedNode), (yyvsp[(2) - (4)].lex).line);
+                    (yyval.interm.intermTypedNode) = context->intermediate.addIndex(EOpIndexDirect, (yyvsp[(1) - (4)].interm.intermTypedNode), (yyvsp[(3) - (4)].interm.intermTypedNode), (yylsp[(2) - (4)]));
                 }
             } else {
                 if ((yyvsp[(1) - (4)].interm.intermTypedNode)->isArray() && (yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getArraySize() == 0) {
-                    context->error((yyvsp[(2) - (4)].lex).line, "", "[", "array must be redeclared with a size before being indexed with a variable");
+                    context->error((yylsp[(2) - (4)]), "", "[", "array must be redeclared with a size before being indexed with a variable");
                     context->recover();
                 }
 
-                (yyval.interm.intermTypedNode) = context->intermediate.addIndex(EOpIndexIndirect, (yyvsp[(1) - (4)].interm.intermTypedNode), (yyvsp[(3) - (4)].interm.intermTypedNode), (yyvsp[(2) - (4)].lex).line);
+                (yyval.interm.intermTypedNode) = context->intermediate.addIndex(EOpIndexIndirect, (yyvsp[(1) - (4)].interm.intermTypedNode), (yyvsp[(3) - (4)].interm.intermTypedNode), (yylsp[(2) - (4)]));
             }
         }
         if ((yyval.interm.intermTypedNode) == 0) {
             ConstantUnion *unionArray = new ConstantUnion[1];
             unionArray->setFConst(0.0f);
-            (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpHigh, EvqConst), (yyvsp[(2) - (4)].lex).line);
+            (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpHigh, EvqConst), (yylsp[(2) - (4)]));
         } else if ((yyvsp[(1) - (4)].interm.intermTypedNode)->isArray()) {
             if ((yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getStruct())
                 (yyval.interm.intermTypedNode)->setType(TType((yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getStruct(), (yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getTypeName()));
@@ -2293,20 +2438,20 @@
 
     {
         if ((yyvsp[(1) - (3)].interm.intermTypedNode)->isArray()) {
-            context->error((yyvsp[(3) - (3)].lex).line, "cannot apply dot operator to an array", ".");
+            context->error((yylsp[(3) - (3)]), "cannot apply dot operator to an array", ".");
             context->recover();
         }
 
         if ((yyvsp[(1) - (3)].interm.intermTypedNode)->isVector()) {
             TVectorFields fields;
-            if (! context->parseVectorFields(*(yyvsp[(3) - (3)].lex).string, (yyvsp[(1) - (3)].interm.intermTypedNode)->getNominalSize(), fields, (yyvsp[(3) - (3)].lex).line)) {
+            if (! context->parseVectorFields(*(yyvsp[(3) - (3)].lex).string, (yyvsp[(1) - (3)].interm.intermTypedNode)->getNominalSize(), fields, (yylsp[(3) - (3)]))) {
                 fields.num = 1;
                 fields.offsets[0] = 0;
                 context->recover();
             }
 
             if ((yyvsp[(1) - (3)].interm.intermTypedNode)->getType().getQualifier() == EvqConst) { // constant folding for vector fields
-                (yyval.interm.intermTypedNode) = context->addConstVectorNode(fields, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].lex).line);
+                (yyval.interm.intermTypedNode) = context->addConstVectorNode(fields, (yyvsp[(1) - (3)].interm.intermTypedNode), (yylsp[(3) - (3)]));
                 if ((yyval.interm.intermTypedNode) == 0) {
                     context->recover();
                     (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
@@ -2315,13 +2460,13 @@
                     (yyval.interm.intermTypedNode)->setType(TType((yyvsp[(1) - (3)].interm.intermTypedNode)->getBasicType(), (yyvsp[(1) - (3)].interm.intermTypedNode)->getPrecision(), EvqConst, (int) (*(yyvsp[(3) - (3)].lex).string).size()));
             } else {
                 TString vectorString = *(yyvsp[(3) - (3)].lex).string;
-                TIntermTyped* index = context->intermediate.addSwizzle(fields, (yyvsp[(3) - (3)].lex).line);
-                (yyval.interm.intermTypedNode) = context->intermediate.addIndex(EOpVectorSwizzle, (yyvsp[(1) - (3)].interm.intermTypedNode), index, (yyvsp[(2) - (3)].lex).line);
+                TIntermTyped* index = context->intermediate.addSwizzle(fields, (yylsp[(3) - (3)]));
+                (yyval.interm.intermTypedNode) = context->intermediate.addIndex(EOpVectorSwizzle, (yyvsp[(1) - (3)].interm.intermTypedNode), index, (yylsp[(2) - (3)]));
                 (yyval.interm.intermTypedNode)->setType(TType((yyvsp[(1) - (3)].interm.intermTypedNode)->getBasicType(), (yyvsp[(1) - (3)].interm.intermTypedNode)->getPrecision(), EvqTemporary, (int) vectorString.size()));
             }
         } else if ((yyvsp[(1) - (3)].interm.intermTypedNode)->isMatrix()) {
             TMatrixFields fields;
-            if (! context->parseMatrixFields(*(yyvsp[(3) - (3)].lex).string, (yyvsp[(1) - (3)].interm.intermTypedNode)->getNominalSize(), fields, (yyvsp[(3) - (3)].lex).line)) {
+            if (! context->parseMatrixFields(*(yyvsp[(3) - (3)].lex).string, (yyvsp[(1) - (3)].interm.intermTypedNode)->getNominalSize(), fields, (yylsp[(3) - (3)]))) {
                 fields.wholeRow = false;
                 fields.wholeCol = false;
                 fields.row = 0;
@@ -2330,25 +2475,25 @@
             }
 
             if (fields.wholeRow || fields.wholeCol) {
-                context->error((yyvsp[(2) - (3)].lex).line, " non-scalar fields not implemented yet", ".");
+                context->error((yylsp[(2) - (3)]), " non-scalar fields not implemented yet", ".");
                 context->recover();
                 ConstantUnion *unionArray = new ConstantUnion[1];
                 unionArray->setIConst(0);
-                TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), (yyvsp[(3) - (3)].lex).line);
-                (yyval.interm.intermTypedNode) = context->intermediate.addIndex(EOpIndexDirect, (yyvsp[(1) - (3)].interm.intermTypedNode), index, (yyvsp[(2) - (3)].lex).line);
+                TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), (yylsp[(3) - (3)]));
+                (yyval.interm.intermTypedNode) = context->intermediate.addIndex(EOpIndexDirect, (yyvsp[(1) - (3)].interm.intermTypedNode), index, (yylsp[(2) - (3)]));
                 (yyval.interm.intermTypedNode)->setType(TType((yyvsp[(1) - (3)].interm.intermTypedNode)->getBasicType(), (yyvsp[(1) - (3)].interm.intermTypedNode)->getPrecision(),EvqTemporary, (yyvsp[(1) - (3)].interm.intermTypedNode)->getNominalSize()));
             } else {
                 ConstantUnion *unionArray = new ConstantUnion[1];
                 unionArray->setIConst(fields.col * (yyvsp[(1) - (3)].interm.intermTypedNode)->getNominalSize() + fields.row);
-                TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), (yyvsp[(3) - (3)].lex).line);
-                (yyval.interm.intermTypedNode) = context->intermediate.addIndex(EOpIndexDirect, (yyvsp[(1) - (3)].interm.intermTypedNode), index, (yyvsp[(2) - (3)].lex).line);
+                TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), (yylsp[(3) - (3)]));
+                (yyval.interm.intermTypedNode) = context->intermediate.addIndex(EOpIndexDirect, (yyvsp[(1) - (3)].interm.intermTypedNode), index, (yylsp[(2) - (3)]));
                 (yyval.interm.intermTypedNode)->setType(TType((yyvsp[(1) - (3)].interm.intermTypedNode)->getBasicType(), (yyvsp[(1) - (3)].interm.intermTypedNode)->getPrecision()));
             }
         } else if ((yyvsp[(1) - (3)].interm.intermTypedNode)->getBasicType() == EbtStruct) {
             bool fieldFound = false;
             const TTypeList* fields = (yyvsp[(1) - (3)].interm.intermTypedNode)->getType().getStruct();
             if (fields == 0) {
-                context->error((yyvsp[(2) - (3)].lex).line, "structure has no fields", "Internal Error");
+                context->error((yylsp[(2) - (3)]), "structure has no fields", "Internal Error");
                 context->recover();
                 (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
             } else {
@@ -2361,7 +2506,7 @@
                 }
                 if (fieldFound) {
                     if ((yyvsp[(1) - (3)].interm.intermTypedNode)->getType().getQualifier() == EvqConst) {
-                        (yyval.interm.intermTypedNode) = context->addConstStruct(*(yyvsp[(3) - (3)].lex).string, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line);
+                        (yyval.interm.intermTypedNode) = context->addConstStruct(*(yyvsp[(3) - (3)].lex).string, (yyvsp[(1) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]));
                         if ((yyval.interm.intermTypedNode) == 0) {
                             context->recover();
                             (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
@@ -2375,18 +2520,18 @@
                     } else {
                         ConstantUnion *unionArray = new ConstantUnion[1];
                         unionArray->setIConst(i);
-                        TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, *(*fields)[i], (yyvsp[(3) - (3)].lex).line);
-                        (yyval.interm.intermTypedNode) = context->intermediate.addIndex(EOpIndexDirectStruct, (yyvsp[(1) - (3)].interm.intermTypedNode), index, (yyvsp[(2) - (3)].lex).line);
+                        TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, *(*fields)[i], (yylsp[(3) - (3)]));
+                        (yyval.interm.intermTypedNode) = context->intermediate.addIndex(EOpIndexDirectStruct, (yyvsp[(1) - (3)].interm.intermTypedNode), index, (yylsp[(2) - (3)]));
                         (yyval.interm.intermTypedNode)->setType(*(*fields)[i]);
                     }
                 } else {
-                    context->error((yyvsp[(2) - (3)].lex).line, " no such field in structure", (yyvsp[(3) - (3)].lex).string->c_str());
+                    context->error((yylsp[(2) - (3)]), " no such field in structure", (yyvsp[(3) - (3)].lex).string->c_str());
                     context->recover();
                     (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
                 }
             }
         } else {
-            context->error((yyvsp[(2) - (3)].lex).line, " field selection requires structure, vector, or matrix on left hand side", (yyvsp[(3) - (3)].lex).string->c_str());
+            context->error((yylsp[(2) - (3)]), " field selection requires structure, vector, or matrix on left hand side", (yyvsp[(3) - (3)].lex).string->c_str());
             context->recover();
             (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
         }
@@ -2397,11 +2542,11 @@
   case 14:
 
     {
-        if (context->lValueErrorCheck((yyvsp[(2) - (2)].lex).line, "++", (yyvsp[(1) - (2)].interm.intermTypedNode)))
+        if (context->lValueErrorCheck((yylsp[(2) - (2)]), "++", (yyvsp[(1) - (2)].interm.intermTypedNode)))
             context->recover();
-        (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath(EOpPostIncrement, (yyvsp[(1) - (2)].interm.intermTypedNode), (yyvsp[(2) - (2)].lex).line, context->symbolTable);
+        (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath(EOpPostIncrement, (yyvsp[(1) - (2)].interm.intermTypedNode), (yylsp[(2) - (2)]), context->symbolTable);
         if ((yyval.interm.intermTypedNode) == 0) {
-            context->unaryOpError((yyvsp[(2) - (2)].lex).line, "++", (yyvsp[(1) - (2)].interm.intermTypedNode)->getCompleteString());
+            context->unaryOpError((yylsp[(2) - (2)]), "++", (yyvsp[(1) - (2)].interm.intermTypedNode)->getCompleteString());
             context->recover();
             (yyval.interm.intermTypedNode) = (yyvsp[(1) - (2)].interm.intermTypedNode);
         }
@@ -2411,11 +2556,11 @@
   case 15:
 
     {
-        if (context->lValueErrorCheck((yyvsp[(2) - (2)].lex).line, "--", (yyvsp[(1) - (2)].interm.intermTypedNode)))
+        if (context->lValueErrorCheck((yylsp[(2) - (2)]), "--", (yyvsp[(1) - (2)].interm.intermTypedNode)))
             context->recover();
-        (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath(EOpPostDecrement, (yyvsp[(1) - (2)].interm.intermTypedNode), (yyvsp[(2) - (2)].lex).line, context->symbolTable);
+        (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath(EOpPostDecrement, (yyvsp[(1) - (2)].interm.intermTypedNode), (yylsp[(2) - (2)]), context->symbolTable);
         if ((yyval.interm.intermTypedNode) == 0) {
-            context->unaryOpError((yyvsp[(2) - (2)].lex).line, "--", (yyvsp[(1) - (2)].interm.intermTypedNode)->getCompleteString());
+            context->unaryOpError((yylsp[(2) - (2)]), "--", (yyvsp[(1) - (2)].interm.intermTypedNode)->getCompleteString());
             context->recover();
             (yyval.interm.intermTypedNode) = (yyvsp[(1) - (2)].interm.intermTypedNode);
         }
@@ -2445,18 +2590,18 @@
             // Their parameters will be verified algorithmically.
             //
             TType type(EbtVoid, EbpUndefined);  // use this to get the type back
-            if (context->constructorErrorCheck((yyvsp[(1) - (1)].interm).line, (yyvsp[(1) - (1)].interm).intermNode, *fnCall, op, &type)) {
+            if (context->constructorErrorCheck((yylsp[(1) - (1)]), (yyvsp[(1) - (1)].interm).intermNode, *fnCall, op, &type)) {
                 (yyval.interm.intermTypedNode) = 0;
             } else {
                 //
                 // It's a constructor, of type 'type'.
                 //
-                (yyval.interm.intermTypedNode) = context->addConstructor((yyvsp[(1) - (1)].interm).intermNode, &type, op, fnCall, (yyvsp[(1) - (1)].interm).line);
+                (yyval.interm.intermTypedNode) = context->addConstructor((yyvsp[(1) - (1)].interm).intermNode, &type, op, fnCall, (yylsp[(1) - (1)]));
             }
 
             if ((yyval.interm.intermTypedNode) == 0) {
                 context->recover();
-                (yyval.interm.intermTypedNode) = context->intermediate.setAggregateOperator(0, op, (yyvsp[(1) - (1)].interm).line);
+                (yyval.interm.intermTypedNode) = context->intermediate.setAggregateOperator(0, op, (yylsp[(1) - (1)]));
             }
             (yyval.interm.intermTypedNode)->setType(type);
         } else {
@@ -2465,13 +2610,13 @@
             //
             const TFunction* fnCandidate;
             bool builtIn;
-            fnCandidate = context->findFunction((yyvsp[(1) - (1)].interm).line, fnCall, &builtIn);
+            fnCandidate = context->findFunction((yylsp[(1) - (1)]), fnCall, &builtIn);
             if (fnCandidate) {
                 //
                 // A declared function.
                 //
                 if (builtIn && !fnCandidate->getExtension().empty() &&
-                    context->extensionErrorCheck((yyvsp[(1) - (1)].interm).line, fnCandidate->getExtension())) {
+                    context->extensionErrorCheck((yylsp[(1) - (1)]), fnCandidate->getExtension())) {
                     context->recover();
                 }
                 op = fnCandidate->getBuiltInOp();
@@ -2483,7 +2628,7 @@
                         //
                         // Treat it like a built-in unary operator.
                         //
-                        (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath(op, (yyvsp[(1) - (1)].interm).intermNode, 0, context->symbolTable);
+                        (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath(op, (yyvsp[(1) - (1)].interm).intermNode, (yylsp[(1) - (1)]), context->symbolTable);
                         if ((yyval.interm.intermTypedNode) == 0)  {
                             std::stringstream extraInfoStream;
                             extraInfoStream << "built in unary operator function.  Type: " << static_cast<TIntermTyped*>((yyvsp[(1) - (1)].interm).intermNode)->getCompleteString();
@@ -2492,12 +2637,12 @@
                             YYERROR;
                         }
                     } else {
-                        (yyval.interm.intermTypedNode) = context->intermediate.setAggregateOperator((yyvsp[(1) - (1)].interm).intermAggregate, op, (yyvsp[(1) - (1)].interm).line);
+                        (yyval.interm.intermTypedNode) = context->intermediate.setAggregateOperator((yyvsp[(1) - (1)].interm).intermAggregate, op, (yylsp[(1) - (1)]));
                     }
                 } else {
                     // This is a real function call
 
-                    (yyval.interm.intermTypedNode) = context->intermediate.setAggregateOperator((yyvsp[(1) - (1)].interm).intermAggregate, EOpFunctionCall, (yyvsp[(1) - (1)].interm).line);
+                    (yyval.interm.intermTypedNode) = context->intermediate.setAggregateOperator((yyvsp[(1) - (1)].interm).intermAggregate, EOpFunctionCall, (yylsp[(1) - (1)]));
                     (yyval.interm.intermTypedNode)->setType(fnCandidate->getReturnType());
 
                     // this is how we know whether the given function is a builtIn function or a user defined function
@@ -2524,7 +2669,7 @@
                 // Put on a dummy node for error recovery
                 ConstantUnion *unionArray = new ConstantUnion[1];
                 unionArray->setFConst(0.0f);
-                (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConst), (yyvsp[(1) - (1)].interm).line);
+                (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConst), (yylsp[(1) - (1)]));
                 context->recover();
             }
         }
@@ -2542,7 +2687,7 @@
   case 19:
 
     {
-        context->error((yyvsp[(3) - (3)].interm).line, "methods are not supported", "");
+        context->error((yylsp[(3) - (3)]), "methods are not supported", "");
         context->recover();
         (yyval.interm) = (yyvsp[(3) - (3)].interm);
     }
@@ -2552,7 +2697,6 @@
 
     {
         (yyval.interm) = (yyvsp[(1) - (2)].interm);
-        (yyval.interm).line = (yyvsp[(2) - (2)].lex).line;
     }
     break;
 
@@ -2560,7 +2704,6 @@
 
     {
         (yyval.interm) = (yyvsp[(1) - (2)].interm);
-        (yyval.interm).line = (yyvsp[(2) - (2)].lex).line;
     }
     break;
 
@@ -2596,7 +2739,7 @@
         TParameter param = { 0, new TType((yyvsp[(3) - (3)].interm.intermTypedNode)->getType()) };
         (yyvsp[(1) - (3)].interm).function->addParameter(param);
         (yyval.interm).function = (yyvsp[(1) - (3)].interm).function;
-        (yyval.interm).intermNode = context->intermediate.growAggregate((yyvsp[(1) - (3)].interm).intermNode, (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line);
+        (yyval.interm).intermNode = context->intermediate.growAggregate((yyvsp[(1) - (3)].interm).intermNode, (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]));
     }
     break;
 
@@ -2637,23 +2780,23 @@
             case EbtInt:
                 switch((yyvsp[(1) - (1)].interm.type).size) {
                 case 1:                                         op = EOpConstructInt;   break;
-                case 2:       FRAG_VERT_ONLY("ivec2", (yyvsp[(1) - (1)].interm.type).line); op = EOpConstructIVec2; break;
-                case 3:       FRAG_VERT_ONLY("ivec3", (yyvsp[(1) - (1)].interm.type).line); op = EOpConstructIVec3; break;
-                case 4:       FRAG_VERT_ONLY("ivec4", (yyvsp[(1) - (1)].interm.type).line); op = EOpConstructIVec4; break;
+                case 2:       FRAG_VERT_ONLY("ivec2", (yylsp[(1) - (1)])); op = EOpConstructIVec2; break;
+                case 3:       FRAG_VERT_ONLY("ivec3", (yylsp[(1) - (1)])); op = EOpConstructIVec3; break;
+                case 4:       FRAG_VERT_ONLY("ivec4", (yylsp[(1) - (1)])); op = EOpConstructIVec4; break;
                 }
                 break;
             case EbtBool:
                 switch((yyvsp[(1) - (1)].interm.type).size) {
                 case 1:                                         op = EOpConstructBool;  break;
-                case 2:       FRAG_VERT_ONLY("bvec2", (yyvsp[(1) - (1)].interm.type).line); op = EOpConstructBVec2; break;
-                case 3:       FRAG_VERT_ONLY("bvec3", (yyvsp[(1) - (1)].interm.type).line); op = EOpConstructBVec3; break;
-                case 4:       FRAG_VERT_ONLY("bvec4", (yyvsp[(1) - (1)].interm.type).line); op = EOpConstructBVec4; break;
+                case 2:       FRAG_VERT_ONLY("bvec2", (yylsp[(1) - (1)])); op = EOpConstructBVec2; break;
+                case 3:       FRAG_VERT_ONLY("bvec3", (yylsp[(1) - (1)])); op = EOpConstructBVec3; break;
+                case 4:       FRAG_VERT_ONLY("bvec4", (yylsp[(1) - (1)])); op = EOpConstructBVec4; break;
                 }
                 break;
             default: break;
             }
             if (op == EOpNull) {
-                context->error((yyvsp[(1) - (1)].interm.type).line, "cannot construct this type", getBasicString((yyvsp[(1) - (1)].interm.type).type));
+                context->error((yylsp[(1) - (1)]), "cannot construct this type", getBasicString((yyvsp[(1) - (1)].interm.type).type));
                 context->recover();
                 (yyvsp[(1) - (1)].interm.type).type = EbtFloat;
                 op = EOpConstructFloat;
@@ -2669,7 +2812,7 @@
   case 28:
 
     {
-        if (context->reservedErrorCheck((yyvsp[(1) - (1)].lex).line, *(yyvsp[(1) - (1)].lex).string))
+        if (context->reservedErrorCheck((yylsp[(1) - (1)]), *(yyvsp[(1) - (1)].lex).string))
             context->recover();
         TType type(EbtVoid, EbpUndefined);
         TFunction *function = new TFunction((yyvsp[(1) - (1)].lex).string, type);
@@ -2687,11 +2830,11 @@
   case 30:
 
     {
-        if (context->lValueErrorCheck((yyvsp[(1) - (2)].lex).line, "++", (yyvsp[(2) - (2)].interm.intermTypedNode)))
+        if (context->lValueErrorCheck((yylsp[(1) - (2)]), "++", (yyvsp[(2) - (2)].interm.intermTypedNode)))
             context->recover();
-        (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath(EOpPreIncrement, (yyvsp[(2) - (2)].interm.intermTypedNode), (yyvsp[(1) - (2)].lex).line, context->symbolTable);
+        (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath(EOpPreIncrement, (yyvsp[(2) - (2)].interm.intermTypedNode), (yylsp[(1) - (2)]), context->symbolTable);
         if ((yyval.interm.intermTypedNode) == 0) {
-            context->unaryOpError((yyvsp[(1) - (2)].lex).line, "++", (yyvsp[(2) - (2)].interm.intermTypedNode)->getCompleteString());
+            context->unaryOpError((yylsp[(1) - (2)]), "++", (yyvsp[(2) - (2)].interm.intermTypedNode)->getCompleteString());
             context->recover();
             (yyval.interm.intermTypedNode) = (yyvsp[(2) - (2)].interm.intermTypedNode);
         }
@@ -2701,11 +2844,11 @@
   case 31:
 
     {
-        if (context->lValueErrorCheck((yyvsp[(1) - (2)].lex).line, "--", (yyvsp[(2) - (2)].interm.intermTypedNode)))
+        if (context->lValueErrorCheck((yylsp[(1) - (2)]), "--", (yyvsp[(2) - (2)].interm.intermTypedNode)))
             context->recover();
-        (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath(EOpPreDecrement, (yyvsp[(2) - (2)].interm.intermTypedNode), (yyvsp[(1) - (2)].lex).line, context->symbolTable);
+        (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath(EOpPreDecrement, (yyvsp[(2) - (2)].interm.intermTypedNode), (yylsp[(1) - (2)]), context->symbolTable);
         if ((yyval.interm.intermTypedNode) == 0) {
-            context->unaryOpError((yyvsp[(1) - (2)].lex).line, "--", (yyvsp[(2) - (2)].interm.intermTypedNode)->getCompleteString());
+            context->unaryOpError((yylsp[(1) - (2)]), "--", (yyvsp[(2) - (2)].interm.intermTypedNode)->getCompleteString());
             context->recover();
             (yyval.interm.intermTypedNode) = (yyvsp[(2) - (2)].interm.intermTypedNode);
         }
@@ -2716,7 +2859,7 @@
 
     {
         if ((yyvsp[(1) - (2)].interm).op != EOpNull) {
-            (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath((yyvsp[(1) - (2)].interm).op, (yyvsp[(2) - (2)].interm.intermTypedNode), (yyvsp[(1) - (2)].interm).line, context->symbolTable);
+            (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath((yyvsp[(1) - (2)].interm).op, (yyvsp[(2) - (2)].interm.intermTypedNode), (yylsp[(1) - (2)]), context->symbolTable);
             if ((yyval.interm.intermTypedNode) == 0) {
                 const char* errorOp = "";
                 switch((yyvsp[(1) - (2)].interm).op) {
@@ -2724,7 +2867,7 @@
                 case EOpLogicalNot: errorOp = "!"; break;
                 default: break;
                 }
-                context->unaryOpError((yyvsp[(1) - (2)].interm).line, errorOp, (yyvsp[(2) - (2)].interm.intermTypedNode)->getCompleteString());
+                context->unaryOpError((yylsp[(1) - (2)]), errorOp, (yyvsp[(2) - (2)].interm.intermTypedNode)->getCompleteString());
                 context->recover();
                 (yyval.interm.intermTypedNode) = (yyvsp[(2) - (2)].interm.intermTypedNode);
             }
@@ -2735,17 +2878,17 @@
 
   case 33:
 
-    { (yyval.interm).line = (yyvsp[(1) - (1)].lex).line; (yyval.interm).op = EOpNull; }
+    { (yyval.interm).op = EOpNull; }
     break;
 
   case 34:
 
-    { (yyval.interm).line = (yyvsp[(1) - (1)].lex).line; (yyval.interm).op = EOpNegative; }
+    { (yyval.interm).op = EOpNegative; }
     break;
 
   case 35:
 
-    { (yyval.interm).line = (yyvsp[(1) - (1)].lex).line; (yyval.interm).op = EOpLogicalNot; }
+    { (yyval.interm).op = EOpLogicalNot; }
     break;
 
   case 36:
@@ -2756,10 +2899,10 @@
   case 37:
 
     {
-        FRAG_VERT_ONLY("*", (yyvsp[(2) - (3)].lex).line);
-        (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpMul, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable);
+        FRAG_VERT_ONLY("*", (yylsp[(2) - (3)]));
+        (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpMul, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]), context->symbolTable);
         if ((yyval.interm.intermTypedNode) == 0) {
-            context->binaryOpError((yyvsp[(2) - (3)].lex).line, "*", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
+            context->binaryOpError((yylsp[(2) - (3)]), "*", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
             context->recover();
             (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
         }
@@ -2769,10 +2912,10 @@
   case 38:
 
     {
-        FRAG_VERT_ONLY("/", (yyvsp[(2) - (3)].lex).line);
-        (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpDiv, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable);
+        FRAG_VERT_ONLY("/", (yylsp[(2) - (3)]));
+        (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpDiv, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]), context->symbolTable);
         if ((yyval.interm.intermTypedNode) == 0) {
-            context->binaryOpError((yyvsp[(2) - (3)].lex).line, "/", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
+            context->binaryOpError((yylsp[(2) - (3)]), "/", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
             context->recover();
             (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
         }
@@ -2787,9 +2930,9 @@
   case 40:
 
     {
-        (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpAdd, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable);
+        (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpAdd, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]), context->symbolTable);
         if ((yyval.interm.intermTypedNode) == 0) {
-            context->binaryOpError((yyvsp[(2) - (3)].lex).line, "+", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
+            context->binaryOpError((yylsp[(2) - (3)]), "+", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
             context->recover();
             (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
         }
@@ -2799,9 +2942,9 @@
   case 41:
 
     {
-        (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpSub, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable);
+        (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpSub, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]), context->symbolTable);
         if ((yyval.interm.intermTypedNode) == 0) {
-            context->binaryOpError((yyvsp[(2) - (3)].lex).line, "-", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
+            context->binaryOpError((yylsp[(2) - (3)]), "-", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
             context->recover();
             (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
         }
@@ -2821,13 +2964,13 @@
   case 44:
 
     {
-        (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpLessThan, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable);
+        (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpLessThan, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]), context->symbolTable);
         if ((yyval.interm.intermTypedNode) == 0) {
-            context->binaryOpError((yyvsp[(2) - (3)].lex).line, "<", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
+            context->binaryOpError((yylsp[(2) - (3)]), "<", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
             context->recover();
             ConstantUnion *unionArray = new ConstantUnion[1];
             unionArray->setBConst(false);
-            (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yyvsp[(2) - (3)].lex).line);
+            (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yylsp[(2) - (3)]));
         }
     }
     break;
@@ -2835,13 +2978,13 @@
   case 45:
 
     {
-        (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpGreaterThan, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable);
+        (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpGreaterThan, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]), context->symbolTable);
         if ((yyval.interm.intermTypedNode) == 0) {
-            context->binaryOpError((yyvsp[(2) - (3)].lex).line, ">", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
+            context->binaryOpError((yylsp[(2) - (3)]), ">", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
             context->recover();
             ConstantUnion *unionArray = new ConstantUnion[1];
             unionArray->setBConst(false);
-            (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yyvsp[(2) - (3)].lex).line);
+            (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yylsp[(2) - (3)]));
         }
     }
     break;
@@ -2849,13 +2992,13 @@
   case 46:
 
     {
-        (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpLessThanEqual, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable);
+        (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpLessThanEqual, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]), context->symbolTable);
         if ((yyval.interm.intermTypedNode) == 0) {
-            context->binaryOpError((yyvsp[(2) - (3)].lex).line, "<=", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
+            context->binaryOpError((yylsp[(2) - (3)]), "<=", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
             context->recover();
             ConstantUnion *unionArray = new ConstantUnion[1];
             unionArray->setBConst(false);
-            (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yyvsp[(2) - (3)].lex).line);
+            (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yylsp[(2) - (3)]));
         }
     }
     break;
@@ -2863,13 +3006,13 @@
   case 47:
 
     {
-        (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpGreaterThanEqual, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable);
+        (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpGreaterThanEqual, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]), context->symbolTable);
         if ((yyval.interm.intermTypedNode) == 0) {
-            context->binaryOpError((yyvsp[(2) - (3)].lex).line, ">=", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
+            context->binaryOpError((yylsp[(2) - (3)]), ">=", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
             context->recover();
             ConstantUnion *unionArray = new ConstantUnion[1];
             unionArray->setBConst(false);
-            (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yyvsp[(2) - (3)].lex).line);
+            (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yylsp[(2) - (3)]));
         }
     }
     break;
@@ -2882,13 +3025,13 @@
   case 49:
 
     {
-        (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpEqual, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable);
+        (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpEqual, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]), context->symbolTable);
         if ((yyval.interm.intermTypedNode) == 0) {
-            context->binaryOpError((yyvsp[(2) - (3)].lex).line, "==", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
+            context->binaryOpError((yylsp[(2) - (3)]), "==", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
             context->recover();
             ConstantUnion *unionArray = new ConstantUnion[1];
             unionArray->setBConst(false);
-            (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yyvsp[(2) - (3)].lex).line);
+            (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yylsp[(2) - (3)]));
         }
     }
     break;
@@ -2896,13 +3039,13 @@
   case 50:
 
     {
-        (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpNotEqual, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable);
+        (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpNotEqual, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]), context->symbolTable);
         if ((yyval.interm.intermTypedNode) == 0) {
-            context->binaryOpError((yyvsp[(2) - (3)].lex).line, "!=", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
+            context->binaryOpError((yylsp[(2) - (3)]), "!=", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
             context->recover();
             ConstantUnion *unionArray = new ConstantUnion[1];
             unionArray->setBConst(false);
-            (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yyvsp[(2) - (3)].lex).line);
+            (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yylsp[(2) - (3)]));
         }
     }
     break;
@@ -2930,13 +3073,13 @@
   case 55:
 
     {
-        (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpLogicalAnd, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable);
+        (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpLogicalAnd, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]), context->symbolTable);
         if ((yyval.interm.intermTypedNode) == 0) {
-            context->binaryOpError((yyvsp[(2) - (3)].lex).line, "&&", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
+            context->binaryOpError((yylsp[(2) - (3)]), "&&", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
             context->recover();
             ConstantUnion *unionArray = new ConstantUnion[1];
             unionArray->setBConst(false);
-            (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yyvsp[(2) - (3)].lex).line);
+            (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yylsp[(2) - (3)]));
         }
     }
     break;
@@ -2949,13 +3092,13 @@
   case 57:
 
     {
-        (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpLogicalXor, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable);
+        (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpLogicalXor, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]), context->symbolTable);
         if ((yyval.interm.intermTypedNode) == 0) {
-            context->binaryOpError((yyvsp[(2) - (3)].lex).line, "^^", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
+            context->binaryOpError((yylsp[(2) - (3)]), "^^", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
             context->recover();
             ConstantUnion *unionArray = new ConstantUnion[1];
             unionArray->setBConst(false);
-            (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yyvsp[(2) - (3)].lex).line);
+            (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yylsp[(2) - (3)]));
         }
     }
     break;
@@ -2968,13 +3111,13 @@
   case 59:
 
     {
-        (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpLogicalOr, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable);
+        (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpLogicalOr, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]), context->symbolTable);
         if ((yyval.interm.intermTypedNode) == 0) {
-            context->binaryOpError((yyvsp[(2) - (3)].lex).line, "||", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
+            context->binaryOpError((yylsp[(2) - (3)]), "||", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
             context->recover();
             ConstantUnion *unionArray = new ConstantUnion[1];
             unionArray->setBConst(false);
-            (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yyvsp[(2) - (3)].lex).line);
+            (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yylsp[(2) - (3)]));
         }
     }
     break;
@@ -2987,15 +3130,15 @@
   case 61:
 
     {
-       if (context->boolErrorCheck((yyvsp[(2) - (5)].lex).line, (yyvsp[(1) - (5)].interm.intermTypedNode)))
+       if (context->boolErrorCheck((yylsp[(2) - (5)]), (yyvsp[(1) - (5)].interm.intermTypedNode)))
             context->recover();
 
-        (yyval.interm.intermTypedNode) = context->intermediate.addSelection((yyvsp[(1) - (5)].interm.intermTypedNode), (yyvsp[(3) - (5)].interm.intermTypedNode), (yyvsp[(5) - (5)].interm.intermTypedNode), (yyvsp[(2) - (5)].lex).line);
+        (yyval.interm.intermTypedNode) = context->intermediate.addSelection((yyvsp[(1) - (5)].interm.intermTypedNode), (yyvsp[(3) - (5)].interm.intermTypedNode), (yyvsp[(5) - (5)].interm.intermTypedNode), (yylsp[(2) - (5)]));
         if ((yyvsp[(3) - (5)].interm.intermTypedNode)->getType() != (yyvsp[(5) - (5)].interm.intermTypedNode)->getType())
             (yyval.interm.intermTypedNode) = 0;
 
         if ((yyval.interm.intermTypedNode) == 0) {
-            context->binaryOpError((yyvsp[(2) - (5)].lex).line, ":", (yyvsp[(3) - (5)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(5) - (5)].interm.intermTypedNode)->getCompleteString());
+            context->binaryOpError((yylsp[(2) - (5)]), ":", (yyvsp[(3) - (5)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(5) - (5)].interm.intermTypedNode)->getCompleteString());
             context->recover();
             (yyval.interm.intermTypedNode) = (yyvsp[(5) - (5)].interm.intermTypedNode);
         }
@@ -3010,11 +3153,11 @@
   case 63:
 
     {
-        if (context->lValueErrorCheck((yyvsp[(2) - (3)].interm).line, "assign", (yyvsp[(1) - (3)].interm.intermTypedNode)))
+        if (context->lValueErrorCheck((yylsp[(2) - (3)]), "assign", (yyvsp[(1) - (3)].interm.intermTypedNode)))
             context->recover();
-        (yyval.interm.intermTypedNode) = context->intermediate.addAssign((yyvsp[(2) - (3)].interm).op, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].interm).line);
+        (yyval.interm.intermTypedNode) = context->intermediate.addAssign((yyvsp[(2) - (3)].interm).op, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]));
         if ((yyval.interm.intermTypedNode) == 0) {
-            context->assignError((yyvsp[(2) - (3)].interm).line, "assign", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
+            context->assignError((yylsp[(2) - (3)]), "assign", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
             context->recover();
             (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
         }
@@ -3023,27 +3166,27 @@
 
   case 64:
 
-    {                                    (yyval.interm).line = (yyvsp[(1) - (1)].lex).line; (yyval.interm).op = EOpAssign; }
+    {                            (yyval.interm).op = EOpAssign; }
     break;
 
   case 65:
 
-    { FRAG_VERT_ONLY("*=", (yyvsp[(1) - (1)].lex).line);     (yyval.interm).line = (yyvsp[(1) - (1)].lex).line; (yyval.interm).op = EOpMulAssign; }
+    { FRAG_VERT_ONLY("*=", (yylsp[(1) - (1)]));  (yyval.interm).op = EOpMulAssign; }
     break;
 
   case 66:
 
-    { FRAG_VERT_ONLY("/=", (yyvsp[(1) - (1)].lex).line);     (yyval.interm).line = (yyvsp[(1) - (1)].lex).line; (yyval.interm).op = EOpDivAssign; }
+    { FRAG_VERT_ONLY("/=", (yylsp[(1) - (1)]));  (yyval.interm).op = EOpDivAssign; }
     break;
 
   case 67:
 
-    {                                    (yyval.interm).line = (yyvsp[(1) - (1)].lex).line; (yyval.interm).op = EOpAddAssign; }
+    {                            (yyval.interm).op = EOpAddAssign; }
     break;
 
   case 68:
 
-    {                                    (yyval.interm).line = (yyvsp[(1) - (1)].lex).line; (yyval.interm).op = EOpSubAssign; }
+    {                            (yyval.interm).op = EOpSubAssign; }
     break;
 
   case 69:
@@ -3056,9 +3199,9 @@
   case 70:
 
     {
-        (yyval.interm.intermTypedNode) = context->intermediate.addComma((yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line);
+        (yyval.interm.intermTypedNode) = context->intermediate.addComma((yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]));
         if ((yyval.interm.intermTypedNode) == 0) {
-            context->binaryOpError((yyvsp[(2) - (3)].lex).line, ",", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
+            context->binaryOpError((yylsp[(2) - (3)]), ",", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
             context->recover();
             (yyval.interm.intermTypedNode) = (yyvsp[(3) - (3)].interm.intermTypedNode);
         }
@@ -3090,11 +3233,11 @@
             {
                 TVariable variable(param.name, *param.type);
                 
-                prototype = context->intermediate.growAggregate(prototype, context->intermediate.addSymbol(variable.getUniqueId(), variable.getName(), variable.getType(), (yyvsp[(1) - (2)].interm).line), (yyvsp[(1) - (2)].interm).line);
+                prototype = context->intermediate.growAggregate(prototype, context->intermediate.addSymbol(variable.getUniqueId(), variable.getName(), variable.getType(), (yylsp[(1) - (2)])), (yylsp[(1) - (2)]));
             }
             else
             {
-                prototype = context->intermediate.growAggregate(prototype, context->intermediate.addSymbol(0, "", *param.type, (yyvsp[(1) - (2)].interm).line), (yyvsp[(1) - (2)].interm).line);
+                prototype = context->intermediate.growAggregate(prototype, context->intermediate.addSymbol(0, "", *param.type, (yylsp[(1) - (2)])), (yylsp[(1) - (2)]));
             }
         }
         
@@ -3118,11 +3261,11 @@
 
     {
         if (((yyvsp[(2) - (4)].interm.precision) == EbpHigh) && (context->shaderType == SH_FRAGMENT_SHADER) && !context->fragmentPrecisionHigh) {
-            context->error((yyvsp[(1) - (4)].lex).line, "precision is not supported in fragment shader", "highp");
+            context->error((yylsp[(1) - (4)]), "precision is not supported in fragment shader", "highp");
             context->recover();
         }
         if (!context->symbolTable.setDefaultPrecision( (yyvsp[(3) - (4)].interm.type), (yyvsp[(2) - (4)].interm.precision) )) {
-            context->error((yyvsp[(1) - (4)].lex).line, "illegal type argument for default precision qualifier", getBasicString((yyvsp[(3) - (4)].interm.type).type));
+            context->error((yylsp[(1) - (4)]), "illegal type argument for default precision qualifier", getBasicString((yyvsp[(3) - (4)].interm.type).type));
             context->recover();
         }
         (yyval.interm.intermNode) = 0;
@@ -3143,12 +3286,12 @@
         TFunction* prevDec = static_cast<TFunction*>(context->symbolTable.find((yyvsp[(1) - (2)].interm.function)->getMangledName()));
         if (prevDec) {
             if (prevDec->getReturnType() != (yyvsp[(1) - (2)].interm.function)->getReturnType()) {
-                context->error((yyvsp[(2) - (2)].lex).line, "overloaded functions must have the same return type", (yyvsp[(1) - (2)].interm.function)->getReturnType().getBasicString());
+                context->error((yylsp[(2) - (2)]), "overloaded functions must have the same return type", (yyvsp[(1) - (2)].interm.function)->getReturnType().getBasicString());
                 context->recover();
             }
             for (size_t i = 0; i < prevDec->getParamCount(); ++i) {
                 if (prevDec->getParam(i).type->getQualifier() != (yyvsp[(1) - (2)].interm.function)->getParam(i).type->getQualifier()) {
-                    context->error((yyvsp[(2) - (2)].lex).line, "overloaded functions must have the same parameter qualifiers", (yyvsp[(1) - (2)].interm.function)->getParam(i).type->getQualifierString());
+                    context->error((yylsp[(2) - (2)]), "overloaded functions must have the same parameter qualifiers", (yyvsp[(1) - (2)].interm.function)->getParam(i).type->getQualifierString());
                     context->recover();
                 }
             }
@@ -3160,7 +3303,6 @@
         // being redeclared.  So, pass back up this declaration, not the one in the symbol table.
         //
         (yyval.interm).function = (yyvsp[(1) - (2)].interm.function);
-        (yyval.interm).line = (yyvsp[(2) - (2)].lex).line;
 
         // We're at the inner scope level of the function's arguments and body statement.
         // Add the function prototype to the surrounding scope instead.
@@ -3205,7 +3347,7 @@
             //
             // This parameter > first is void
             //
-            context->error((yyvsp[(2) - (3)].lex).line, "cannot be an argument type except for '(void)'", "void");
+            context->error((yylsp[(2) - (3)]), "cannot be an argument type except for '(void)'", "void");
             context->recover();
             delete (yyvsp[(3) - (3)].interm).param.type;
         } else {
@@ -3220,11 +3362,11 @@
 
     {
         if ((yyvsp[(1) - (3)].interm.type).qualifier != EvqGlobal && (yyvsp[(1) - (3)].interm.type).qualifier != EvqTemporary) {
-            context->error((yyvsp[(2) - (3)].lex).line, "no qualifiers allowed for function return", getQualifierString((yyvsp[(1) - (3)].interm.type).qualifier));
+            context->error((yylsp[(2) - (3)]), "no qualifiers allowed for function return", getQualifierString((yyvsp[(1) - (3)].interm.type).qualifier));
             context->recover();
         }
         // make sure a sampler is not involved as well...
-        if (context->structQualifierErrorCheck((yyvsp[(2) - (3)].lex).line, (yyvsp[(1) - (3)].interm.type)))
+        if (context->structQualifierErrorCheck((yylsp[(2) - (3)]), (yyvsp[(1) - (3)].interm.type)))
             context->recover();
 
         // Add the function as a prototype after parsing it (we do not support recursion)
@@ -3241,13 +3383,12 @@
 
     {
         if ((yyvsp[(1) - (2)].interm.type).type == EbtVoid) {
-            context->error((yyvsp[(2) - (2)].lex).line, "illegal use of type 'void'", (yyvsp[(2) - (2)].lex).string->c_str());
+            context->error((yylsp[(2) - (2)]), "illegal use of type 'void'", (yyvsp[(2) - (2)].lex).string->c_str());
             context->recover();
         }
-        if (context->reservedErrorCheck((yyvsp[(2) - (2)].lex).line, *(yyvsp[(2) - (2)].lex).string))
+        if (context->reservedErrorCheck((yylsp[(2) - (2)]), *(yyvsp[(2) - (2)].lex).string))
             context->recover();
         TParameter param = {(yyvsp[(2) - (2)].lex).string, new TType((yyvsp[(1) - (2)].interm.type))};
-        (yyval.interm).line = (yyvsp[(2) - (2)].lex).line;
         (yyval.interm).param = param;
     }
     break;
@@ -3256,20 +3397,19 @@
 
     {
         // Check that we can make an array out of this type
-        if (context->arrayTypeErrorCheck((yyvsp[(3) - (5)].lex).line, (yyvsp[(1) - (5)].interm.type)))
+        if (context->arrayTypeErrorCheck((yylsp[(3) - (5)]), (yyvsp[(1) - (5)].interm.type)))
             context->recover();
 
-        if (context->reservedErrorCheck((yyvsp[(2) - (5)].lex).line, *(yyvsp[(2) - (5)].lex).string))
+        if (context->reservedErrorCheck((yylsp[(2) - (5)]), *(yyvsp[(2) - (5)].lex).string))
             context->recover();
 
         int size;
-        if (context->arraySizeErrorCheck((yyvsp[(3) - (5)].lex).line, (yyvsp[(4) - (5)].interm.intermTypedNode), size))
+        if (context->arraySizeErrorCheck((yylsp[(3) - (5)]), (yyvsp[(4) - (5)].interm.intermTypedNode), size))
             context->recover();
         (yyvsp[(1) - (5)].interm.type).setArray(true, size);
 
         TType* type = new TType((yyvsp[(1) - (5)].interm.type));
         TParameter param = { (yyvsp[(2) - (5)].lex).string, type };
-        (yyval.interm).line = (yyvsp[(2) - (5)].lex).line;
         (yyval.interm).param = param;
     }
     break;
@@ -3278,7 +3418,7 @@
 
     {
         (yyval.interm) = (yyvsp[(3) - (3)].interm);
-        if (context->paramErrorCheck((yyvsp[(3) - (3)].interm).line, (yyvsp[(1) - (3)].interm.type).qualifier, (yyvsp[(2) - (3)].interm.qualifier), (yyval.interm).param.type))
+        if (context->paramErrorCheck((yylsp[(3) - (3)]), (yyvsp[(1) - (3)].interm.type).qualifier, (yyvsp[(2) - (3)].interm.qualifier), (yyval.interm).param.type))
             context->recover();
     }
     break;
@@ -3287,9 +3427,9 @@
 
     {
         (yyval.interm) = (yyvsp[(2) - (2)].interm);
-        if (context->parameterSamplerErrorCheck((yyvsp[(2) - (2)].interm).line, (yyvsp[(1) - (2)].interm.qualifier), *(yyvsp[(2) - (2)].interm).param.type))
+        if (context->parameterSamplerErrorCheck((yylsp[(2) - (2)]), (yyvsp[(1) - (2)].interm.qualifier), *(yyvsp[(2) - (2)].interm).param.type))
             context->recover();
-        if (context->paramErrorCheck((yyvsp[(2) - (2)].interm).line, EvqTemporary, (yyvsp[(1) - (2)].interm.qualifier), (yyval.interm).param.type))
+        if (context->paramErrorCheck((yylsp[(2) - (2)]), EvqTemporary, (yyvsp[(1) - (2)].interm.qualifier), (yyval.interm).param.type))
             context->recover();
     }
     break;
@@ -3298,7 +3438,7 @@
 
     {
         (yyval.interm) = (yyvsp[(3) - (3)].interm);
-        if (context->paramErrorCheck((yyvsp[(3) - (3)].interm).line, (yyvsp[(1) - (3)].interm.type).qualifier, (yyvsp[(2) - (3)].interm.qualifier), (yyval.interm).param.type))
+        if (context->paramErrorCheck((yylsp[(3) - (3)]), (yyvsp[(1) - (3)].interm.type).qualifier, (yyvsp[(2) - (3)].interm.qualifier), (yyval.interm).param.type))
             context->recover();
     }
     break;
@@ -3307,9 +3447,9 @@
 
     {
         (yyval.interm) = (yyvsp[(2) - (2)].interm);
-        if (context->parameterSamplerErrorCheck((yyvsp[(2) - (2)].interm).line, (yyvsp[(1) - (2)].interm.qualifier), *(yyvsp[(2) - (2)].interm).param.type))
+        if (context->parameterSamplerErrorCheck((yylsp[(2) - (2)]), (yyvsp[(1) - (2)].interm.qualifier), *(yyvsp[(2) - (2)].interm).param.type))
             context->recover();
-        if (context->paramErrorCheck((yyvsp[(2) - (2)].interm).line, EvqTemporary, (yyvsp[(1) - (2)].interm.qualifier), (yyval.interm).param.type))
+        if (context->paramErrorCheck((yylsp[(2) - (2)]), EvqTemporary, (yyvsp[(1) - (2)].interm.qualifier), (yyval.interm).param.type))
             context->recover();
     }
     break;
@@ -3362,21 +3502,21 @@
     {
         if ((yyvsp[(1) - (3)].interm).type.type == EbtInvariant && !(yyvsp[(3) - (3)].lex).symbol)
         {
-            context->error((yyvsp[(3) - (3)].lex).line, "undeclared identifier declared as invariant", (yyvsp[(3) - (3)].lex).string->c_str());
+            context->error((yylsp[(3) - (3)]), "undeclared identifier declared as invariant", (yyvsp[(3) - (3)].lex).string->c_str());
             context->recover();
         }
 
-        TIntermSymbol* symbol = context->intermediate.addSymbol(0, *(yyvsp[(3) - (3)].lex).string, TType((yyvsp[(1) - (3)].interm).type), (yyvsp[(3) - (3)].lex).line);
-        (yyval.interm).intermAggregate = context->intermediate.growAggregate((yyvsp[(1) - (3)].interm).intermNode, symbol, (yyvsp[(3) - (3)].lex).line);
+        TIntermSymbol* symbol = context->intermediate.addSymbol(0, *(yyvsp[(3) - (3)].lex).string, TType((yyvsp[(1) - (3)].interm).type), (yylsp[(3) - (3)]));
+        (yyval.interm).intermAggregate = context->intermediate.growAggregate((yyvsp[(1) - (3)].interm).intermNode, symbol, (yylsp[(3) - (3)]));
         
-        if (context->structQualifierErrorCheck((yyvsp[(3) - (3)].lex).line, (yyval.interm).type))
+        if (context->structQualifierErrorCheck((yylsp[(3) - (3)]), (yyval.interm).type))
             context->recover();
 
-        if (context->nonInitConstErrorCheck((yyvsp[(3) - (3)].lex).line, *(yyvsp[(3) - (3)].lex).string, (yyval.interm).type, false))
+        if (context->nonInitConstErrorCheck((yylsp[(3) - (3)]), *(yyvsp[(3) - (3)].lex).string, (yyval.interm).type, false))
             context->recover();
 
         TVariable* variable = 0;
-        if (context->nonInitErrorCheck((yyvsp[(3) - (3)].lex).line, *(yyvsp[(3) - (3)].lex).string, (yyval.interm).type, variable))
+        if (context->nonInitErrorCheck((yylsp[(3) - (3)]), *(yyvsp[(3) - (3)].lex).string, (yyval.interm).type, variable))
             context->recover();
         if (symbol && variable)
             symbol->setId(variable->getUniqueId());
@@ -3386,20 +3526,20 @@
   case 94:
 
     {
-        if (context->structQualifierErrorCheck((yyvsp[(3) - (5)].lex).line, (yyvsp[(1) - (5)].interm).type))
+        if (context->structQualifierErrorCheck((yylsp[(3) - (5)]), (yyvsp[(1) - (5)].interm).type))
             context->recover();
 
-        if (context->nonInitConstErrorCheck((yyvsp[(3) - (5)].lex).line, *(yyvsp[(3) - (5)].lex).string, (yyvsp[(1) - (5)].interm).type, true))
+        if (context->nonInitConstErrorCheck((yylsp[(3) - (5)]), *(yyvsp[(3) - (5)].lex).string, (yyvsp[(1) - (5)].interm).type, true))
             context->recover();
 
         (yyval.interm) = (yyvsp[(1) - (5)].interm);
 
-        if (context->arrayTypeErrorCheck((yyvsp[(4) - (5)].lex).line, (yyvsp[(1) - (5)].interm).type) || context->arrayQualifierErrorCheck((yyvsp[(4) - (5)].lex).line, (yyvsp[(1) - (5)].interm).type))
+        if (context->arrayTypeErrorCheck((yylsp[(4) - (5)]), (yyvsp[(1) - (5)].interm).type) || context->arrayQualifierErrorCheck((yylsp[(4) - (5)]), (yyvsp[(1) - (5)].interm).type))
             context->recover();
         else {
             (yyvsp[(1) - (5)].interm).type.setArray(true);
             TVariable* variable;
-            if (context->arrayErrorCheck((yyvsp[(4) - (5)].lex).line, *(yyvsp[(3) - (5)].lex).string, (yyvsp[(1) - (5)].interm).type, variable))
+            if (context->arrayErrorCheck((yylsp[(4) - (5)]), *(yyvsp[(3) - (5)].lex).string, (yyvsp[(1) - (5)].interm).type, variable))
                 context->recover();
         }
     }
@@ -3408,27 +3548,27 @@
   case 95:
 
     {
-        if (context->structQualifierErrorCheck((yyvsp[(3) - (6)].lex).line, (yyvsp[(1) - (6)].interm).type))
+        if (context->structQualifierErrorCheck((yylsp[(3) - (6)]), (yyvsp[(1) - (6)].interm).type))
             context->recover();
 
-        if (context->nonInitConstErrorCheck((yyvsp[(3) - (6)].lex).line, *(yyvsp[(3) - (6)].lex).string, (yyvsp[(1) - (6)].interm).type, true))
+        if (context->nonInitConstErrorCheck((yylsp[(3) - (6)]), *(yyvsp[(3) - (6)].lex).string, (yyvsp[(1) - (6)].interm).type, true))
             context->recover();
 
         (yyval.interm) = (yyvsp[(1) - (6)].interm);
 
-        if (context->arrayTypeErrorCheck((yyvsp[(4) - (6)].lex).line, (yyvsp[(1) - (6)].interm).type) || context->arrayQualifierErrorCheck((yyvsp[(4) - (6)].lex).line, (yyvsp[(1) - (6)].interm).type))
+        if (context->arrayTypeErrorCheck((yylsp[(4) - (6)]), (yyvsp[(1) - (6)].interm).type) || context->arrayQualifierErrorCheck((yylsp[(4) - (6)]), (yyvsp[(1) - (6)].interm).type))
             context->recover();
         else {
             int size;
-            if (context->arraySizeErrorCheck((yyvsp[(4) - (6)].lex).line, (yyvsp[(5) - (6)].interm.intermTypedNode), size))
+            if (context->arraySizeErrorCheck((yylsp[(4) - (6)]), (yyvsp[(5) - (6)].interm.intermTypedNode), size))
                 context->recover();
             (yyvsp[(1) - (6)].interm).type.setArray(true, size);
             TVariable* variable = 0;
-            if (context->arrayErrorCheck((yyvsp[(4) - (6)].lex).line, *(yyvsp[(3) - (6)].lex).string, (yyvsp[(1) - (6)].interm).type, variable))
+            if (context->arrayErrorCheck((yylsp[(4) - (6)]), *(yyvsp[(3) - (6)].lex).string, (yyvsp[(1) - (6)].interm).type, variable))
                 context->recover();
             TType type = TType((yyvsp[(1) - (6)].interm).type);
             type.setArraySize(size);
-            (yyval.interm).intermAggregate = context->intermediate.growAggregate((yyvsp[(1) - (6)].interm).intermNode, context->intermediate.addSymbol(variable ? variable->getUniqueId() : 0, *(yyvsp[(3) - (6)].lex).string, type, (yyvsp[(3) - (6)].lex).line), (yyvsp[(3) - (6)].lex).line);
+            (yyval.interm).intermAggregate = context->intermediate.growAggregate((yyvsp[(1) - (6)].interm).intermNode, context->intermediate.addSymbol(variable ? variable->getUniqueId() : 0, *(yyvsp[(3) - (6)].lex).string, type, (yylsp[(3) - (6)])), (yylsp[(3) - (6)]));
         }
     }
     break;
@@ -3436,18 +3576,18 @@
   case 96:
 
     {
-        if (context->structQualifierErrorCheck((yyvsp[(3) - (5)].lex).line, (yyvsp[(1) - (5)].interm).type))
+        if (context->structQualifierErrorCheck((yylsp[(3) - (5)]), (yyvsp[(1) - (5)].interm).type))
             context->recover();
 
         (yyval.interm) = (yyvsp[(1) - (5)].interm);
 
         TIntermNode* intermNode;
-        if (!context->executeInitializer((yyvsp[(3) - (5)].lex).line, *(yyvsp[(3) - (5)].lex).string, (yyvsp[(1) - (5)].interm).type, (yyvsp[(5) - (5)].interm.intermTypedNode), intermNode)) {
+        if (!context->executeInitializer((yylsp[(3) - (5)]), *(yyvsp[(3) - (5)].lex).string, (yyvsp[(1) - (5)].interm).type, (yyvsp[(5) - (5)].interm.intermTypedNode), intermNode)) {
             //
             // build the intermediate representation
             //
             if (intermNode)
-        (yyval.interm).intermAggregate = context->intermediate.growAggregate((yyvsp[(1) - (5)].interm).intermNode, intermNode, (yyvsp[(4) - (5)].lex).line);
+        (yyval.interm).intermAggregate = context->intermediate.growAggregate((yyvsp[(1) - (5)].interm).intermNode, intermNode, (yylsp[(4) - (5)]));
             else
                 (yyval.interm).intermAggregate = (yyvsp[(1) - (5)].interm).intermAggregate;
         } else {
@@ -3461,26 +3601,26 @@
 
     {
         (yyval.interm).type = (yyvsp[(1) - (1)].interm.type);
-        (yyval.interm).intermAggregate = context->intermediate.makeAggregate(context->intermediate.addSymbol(0, "", TType((yyvsp[(1) - (1)].interm.type)), (yyvsp[(1) - (1)].interm.type).line), (yyvsp[(1) - (1)].interm.type).line);
+        (yyval.interm).intermAggregate = context->intermediate.makeAggregate(context->intermediate.addSymbol(0, "", TType((yyvsp[(1) - (1)].interm.type)), (yylsp[(1) - (1)])), (yylsp[(1) - (1)]));
     }
     break;
 
   case 98:
 
     {
-        TIntermSymbol* symbol = context->intermediate.addSymbol(0, *(yyvsp[(2) - (2)].lex).string, TType((yyvsp[(1) - (2)].interm.type)), (yyvsp[(2) - (2)].lex).line);
-        (yyval.interm).intermAggregate = context->intermediate.makeAggregate(symbol, (yyvsp[(2) - (2)].lex).line);
+        TIntermSymbol* symbol = context->intermediate.addSymbol(0, *(yyvsp[(2) - (2)].lex).string, TType((yyvsp[(1) - (2)].interm.type)), (yylsp[(2) - (2)]));
+        (yyval.interm).intermAggregate = context->intermediate.makeAggregate(symbol, (yylsp[(2) - (2)]));
         
-        if (context->structQualifierErrorCheck((yyvsp[(2) - (2)].lex).line, (yyval.interm).type))
+        if (context->structQualifierErrorCheck((yylsp[(2) - (2)]), (yyval.interm).type))
             context->recover();
 
-        if (context->nonInitConstErrorCheck((yyvsp[(2) - (2)].lex).line, *(yyvsp[(2) - (2)].lex).string, (yyval.interm).type, false))
+        if (context->nonInitConstErrorCheck((yylsp[(2) - (2)]), *(yyvsp[(2) - (2)].lex).string, (yyval.interm).type, false))
             context->recover();
             
             (yyval.interm).type = (yyvsp[(1) - (2)].interm.type);
 
         TVariable* variable = 0;
-        if (context->nonInitErrorCheck((yyvsp[(2) - (2)].lex).line, *(yyvsp[(2) - (2)].lex).string, (yyval.interm).type, variable))
+        if (context->nonInitErrorCheck((yylsp[(2) - (2)]), *(yyvsp[(2) - (2)].lex).string, (yyval.interm).type, variable))
             context->recover();
         if (variable && symbol)
             symbol->setId(variable->getUniqueId());
@@ -3490,11 +3630,11 @@
   case 99:
 
     {
-        context->error((yyvsp[(2) - (4)].lex).line, "unsized array declarations not supported", (yyvsp[(2) - (4)].lex).string->c_str());
+        context->error((yylsp[(2) - (4)]), "unsized array declarations not supported", (yyvsp[(2) - (4)].lex).string->c_str());
         context->recover();
 
-        TIntermSymbol* symbol = context->intermediate.addSymbol(0, *(yyvsp[(2) - (4)].lex).string, TType((yyvsp[(1) - (4)].interm.type)), (yyvsp[(2) - (4)].lex).line);
-        (yyval.interm).intermAggregate = context->intermediate.makeAggregate(symbol, (yyvsp[(2) - (4)].lex).line);
+        TIntermSymbol* symbol = context->intermediate.addSymbol(0, *(yyvsp[(2) - (4)].lex).string, TType((yyvsp[(1) - (4)].interm.type)), (yylsp[(2) - (4)]));
+        (yyval.interm).intermAggregate = context->intermediate.makeAggregate(symbol, (yylsp[(2) - (4)]));
         (yyval.interm).type = (yyvsp[(1) - (4)].interm.type);
     }
     break;
@@ -3504,30 +3644,30 @@
     {
         TType type = TType((yyvsp[(1) - (5)].interm.type));
         int size;
-        if (context->arraySizeErrorCheck((yyvsp[(2) - (5)].lex).line, (yyvsp[(4) - (5)].interm.intermTypedNode), size))
+        if (context->arraySizeErrorCheck((yylsp[(2) - (5)]), (yyvsp[(4) - (5)].interm.intermTypedNode), size))
             context->recover();
         type.setArraySize(size);
-        TIntermSymbol* symbol = context->intermediate.addSymbol(0, *(yyvsp[(2) - (5)].lex).string, type, (yyvsp[(2) - (5)].lex).line);
-        (yyval.interm).intermAggregate = context->intermediate.makeAggregate(symbol, (yyvsp[(2) - (5)].lex).line);
+        TIntermSymbol* symbol = context->intermediate.addSymbol(0, *(yyvsp[(2) - (5)].lex).string, type, (yylsp[(2) - (5)]));
+        (yyval.interm).intermAggregate = context->intermediate.makeAggregate(symbol, (yylsp[(2) - (5)]));
         
-        if (context->structQualifierErrorCheck((yyvsp[(2) - (5)].lex).line, (yyvsp[(1) - (5)].interm.type)))
+        if (context->structQualifierErrorCheck((yylsp[(2) - (5)]), (yyvsp[(1) - (5)].interm.type)))
             context->recover();
 
-        if (context->nonInitConstErrorCheck((yyvsp[(2) - (5)].lex).line, *(yyvsp[(2) - (5)].lex).string, (yyvsp[(1) - (5)].interm.type), true))
+        if (context->nonInitConstErrorCheck((yylsp[(2) - (5)]), *(yyvsp[(2) - (5)].lex).string, (yyvsp[(1) - (5)].interm.type), true))
             context->recover();
 
         (yyval.interm).type = (yyvsp[(1) - (5)].interm.type);
 
-        if (context->arrayTypeErrorCheck((yyvsp[(3) - (5)].lex).line, (yyvsp[(1) - (5)].interm.type)) || context->arrayQualifierErrorCheck((yyvsp[(3) - (5)].lex).line, (yyvsp[(1) - (5)].interm.type)))
+        if (context->arrayTypeErrorCheck((yylsp[(3) - (5)]), (yyvsp[(1) - (5)].interm.type)) || context->arrayQualifierErrorCheck((yylsp[(3) - (5)]), (yyvsp[(1) - (5)].interm.type)))
             context->recover();
         else {
             int size;
-            if (context->arraySizeErrorCheck((yyvsp[(3) - (5)].lex).line, (yyvsp[(4) - (5)].interm.intermTypedNode), size))
+            if (context->arraySizeErrorCheck((yylsp[(3) - (5)]), (yyvsp[(4) - (5)].interm.intermTypedNode), size))
                 context->recover();
 
             (yyvsp[(1) - (5)].interm.type).setArray(true, size);
             TVariable* variable = 0;
-            if (context->arrayErrorCheck((yyvsp[(3) - (5)].lex).line, *(yyvsp[(2) - (5)].lex).string, (yyvsp[(1) - (5)].interm.type), variable))
+            if (context->arrayErrorCheck((yylsp[(3) - (5)]), *(yyvsp[(2) - (5)].lex).string, (yyvsp[(1) - (5)].interm.type), variable))
                 context->recover();
             if (variable && symbol)
                 symbol->setId(variable->getUniqueId());
@@ -3538,18 +3678,18 @@
   case 101:
 
     {
-        if (context->structQualifierErrorCheck((yyvsp[(2) - (4)].lex).line, (yyvsp[(1) - (4)].interm.type)))
+        if (context->structQualifierErrorCheck((yylsp[(2) - (4)]), (yyvsp[(1) - (4)].interm.type)))
             context->recover();
 
         (yyval.interm).type = (yyvsp[(1) - (4)].interm.type);
 
         TIntermNode* intermNode;
-        if (!context->executeInitializer((yyvsp[(2) - (4)].lex).line, *(yyvsp[(2) - (4)].lex).string, (yyvsp[(1) - (4)].interm.type), (yyvsp[(4) - (4)].interm.intermTypedNode), intermNode)) {
+        if (!context->executeInitializer((yylsp[(2) - (4)]), *(yyvsp[(2) - (4)].lex).string, (yyvsp[(1) - (4)].interm.type), (yyvsp[(4) - (4)].interm.intermTypedNode), intermNode)) {
         //
         // Build intermediate representation
         //
             if(intermNode)
-                (yyval.interm).intermAggregate = context->intermediate.makeAggregate(intermNode, (yyvsp[(3) - (4)].lex).line);
+                (yyval.interm).intermAggregate = context->intermediate.makeAggregate(intermNode, (yylsp[(3) - (4)]));
             else
                 (yyval.interm).intermAggregate = 0;
         } else {
@@ -3562,21 +3702,21 @@
   case 102:
 
     {
-        VERTEX_ONLY("invariant declaration", (yyvsp[(1) - (2)].lex).line);
-        if (context->globalErrorCheck((yyvsp[(1) - (2)].lex).line, context->symbolTable.atGlobalLevel(), "invariant varying"))
+        VERTEX_ONLY("invariant declaration", (yylsp[(1) - (2)]));
+        if (context->globalErrorCheck((yylsp[(1) - (2)]), context->symbolTable.atGlobalLevel(), "invariant varying"))
             context->recover();
-        (yyval.interm).type.setBasic(EbtInvariant, EvqInvariantVaryingOut, (yyvsp[(2) - (2)].lex).line);
+        (yyval.interm).type.setBasic(EbtInvariant, EvqInvariantVaryingOut, (yylsp[(2) - (2)]));
         if (!(yyvsp[(2) - (2)].lex).symbol)
         {
-            context->error((yyvsp[(2) - (2)].lex).line, "undeclared identifier declared as invariant", (yyvsp[(2) - (2)].lex).string->c_str());
+            context->error((yylsp[(2) - (2)]), "undeclared identifier declared as invariant", (yyvsp[(2) - (2)].lex).string->c_str());
             context->recover();
             
             (yyval.interm).intermAggregate = 0;
         }
         else
         {
-            TIntermSymbol *symbol = context->intermediate.addSymbol(0, *(yyvsp[(2) - (2)].lex).string, TType((yyval.interm).type), (yyvsp[(2) - (2)].lex).line);
-            (yyval.interm).intermAggregate = context->intermediate.makeAggregate(symbol, (yyvsp[(2) - (2)].lex).line);
+            TIntermSymbol *symbol = context->intermediate.addSymbol(0, *(yyvsp[(2) - (2)].lex).string, TType((yyval.interm).type), (yylsp[(2) - (2)]));
+            (yyval.interm).intermAggregate = context->intermediate.makeAggregate(symbol, (yylsp[(2) - (2)]));
         }
     }
     break;
@@ -3587,7 +3727,7 @@
         (yyval.interm.type) = (yyvsp[(1) - (1)].interm.type);
 
         if ((yyvsp[(1) - (1)].interm.type).array) {
-            context->error((yyvsp[(1) - (1)].interm.type).line, "not supported", "first-class array");
+            context->error((yylsp[(1) - (1)]), "not supported", "first-class array");
             context->recover();
             (yyvsp[(1) - (1)].interm.type).setArray(false);
         }
@@ -3598,19 +3738,19 @@
 
     {
         if ((yyvsp[(2) - (2)].interm.type).array) {
-            context->error((yyvsp[(2) - (2)].interm.type).line, "not supported", "first-class array");
+            context->error((yylsp[(2) - (2)]), "not supported", "first-class array");
             context->recover();
             (yyvsp[(2) - (2)].interm.type).setArray(false);
         }
 
         if ((yyvsp[(1) - (2)].interm.type).qualifier == EvqAttribute &&
             ((yyvsp[(2) - (2)].interm.type).type == EbtBool || (yyvsp[(2) - (2)].interm.type).type == EbtInt)) {
-            context->error((yyvsp[(2) - (2)].interm.type).line, "cannot be bool or int", getQualifierString((yyvsp[(1) - (2)].interm.type).qualifier));
+            context->error((yylsp[(2) - (2)]), "cannot be bool or int", getQualifierString((yyvsp[(1) - (2)].interm.type).qualifier));
             context->recover();
         }
         if (((yyvsp[(1) - (2)].interm.type).qualifier == EvqVaryingIn || (yyvsp[(1) - (2)].interm.type).qualifier == EvqVaryingOut) &&
             ((yyvsp[(2) - (2)].interm.type).type == EbtBool || (yyvsp[(2) - (2)].interm.type).type == EbtInt)) {
-            context->error((yyvsp[(2) - (2)].interm.type).line, "cannot be bool or int", getQualifierString((yyvsp[(1) - (2)].interm.type).qualifier));
+            context->error((yylsp[(2) - (2)]), "cannot be bool or int", getQualifierString((yyvsp[(1) - (2)].interm.type).qualifier));
             context->recover();
         }
         (yyval.interm.type) = (yyvsp[(2) - (2)].interm.type);
@@ -3621,50 +3761,50 @@
   case 105:
 
     {
-        (yyval.interm.type).setBasic(EbtVoid, EvqConst, (yyvsp[(1) - (1)].lex).line);
+        (yyval.interm.type).setBasic(EbtVoid, EvqConst, (yylsp[(1) - (1)]));
     }
     break;
 
   case 106:
 
     {
-        VERTEX_ONLY("attribute", (yyvsp[(1) - (1)].lex).line);
-        if (context->globalErrorCheck((yyvsp[(1) - (1)].lex).line, context->symbolTable.atGlobalLevel(), "attribute"))
+        VERTEX_ONLY("attribute", (yylsp[(1) - (1)]));
+        if (context->globalErrorCheck((yylsp[(1) - (1)]), context->symbolTable.atGlobalLevel(), "attribute"))
             context->recover();
-        (yyval.interm.type).setBasic(EbtVoid, EvqAttribute, (yyvsp[(1) - (1)].lex).line);
+        (yyval.interm.type).setBasic(EbtVoid, EvqAttribute, (yylsp[(1) - (1)]));
     }
     break;
 
   case 107:
 
     {
-        if (context->globalErrorCheck((yyvsp[(1) - (1)].lex).line, context->symbolTable.atGlobalLevel(), "varying"))
+        if (context->globalErrorCheck((yylsp[(1) - (1)]), context->symbolTable.atGlobalLevel(), "varying"))
             context->recover();
         if (context->shaderType == SH_VERTEX_SHADER)
-            (yyval.interm.type).setBasic(EbtVoid, EvqVaryingOut, (yyvsp[(1) - (1)].lex).line);
+            (yyval.interm.type).setBasic(EbtVoid, EvqVaryingOut, (yylsp[(1) - (1)]));
         else
-            (yyval.interm.type).setBasic(EbtVoid, EvqVaryingIn, (yyvsp[(1) - (1)].lex).line);
+            (yyval.interm.type).setBasic(EbtVoid, EvqVaryingIn, (yylsp[(1) - (1)]));
     }
     break;
 
   case 108:
 
     {
-        if (context->globalErrorCheck((yyvsp[(1) - (2)].lex).line, context->symbolTable.atGlobalLevel(), "invariant varying"))
+        if (context->globalErrorCheck((yylsp[(1) - (2)]), context->symbolTable.atGlobalLevel(), "invariant varying"))
             context->recover();
         if (context->shaderType == SH_VERTEX_SHADER)
-            (yyval.interm.type).setBasic(EbtVoid, EvqInvariantVaryingOut, (yyvsp[(1) - (2)].lex).line);
+            (yyval.interm.type).setBasic(EbtVoid, EvqInvariantVaryingOut, (yylsp[(1) - (2)]));
         else
-            (yyval.interm.type).setBasic(EbtVoid, EvqInvariantVaryingIn, (yyvsp[(1) - (2)].lex).line);
+            (yyval.interm.type).setBasic(EbtVoid, EvqInvariantVaryingIn, (yylsp[(1) - (2)]));
     }
     break;
 
   case 109:
 
     {
-        if (context->globalErrorCheck((yyvsp[(1) - (1)].lex).line, context->symbolTable.atGlobalLevel(), "uniform"))
+        if (context->globalErrorCheck((yylsp[(1) - (1)]), context->symbolTable.atGlobalLevel(), "uniform"))
             context->recover();
-        (yyval.interm.type).setBasic(EbtVoid, EvqUniform, (yyvsp[(1) - (1)].lex).line);
+        (yyval.interm.type).setBasic(EbtVoid, EvqUniform, (yylsp[(1) - (1)]));
     }
     break;
 
@@ -3675,7 +3815,7 @@
 
         if ((yyval.interm.type).precision == EbpUndefined) {
             (yyval.interm.type).precision = context->symbolTable.getDefaultPrecision((yyvsp[(1) - (1)].interm.type).type);
-            if (context->precisionErrorCheck((yyvsp[(1) - (1)].interm.type).line, (yyval.interm.type).precision, (yyvsp[(1) - (1)].interm.type).type)) {
+            if (context->precisionErrorCheck((yylsp[(1) - (1)]), (yyval.interm.type).precision, (yyvsp[(1) - (1)].interm.type).type)) {
                 context->recover();
             }
         }
@@ -3723,11 +3863,11 @@
     {
         (yyval.interm.type) = (yyvsp[(1) - (4)].interm.type);
 
-        if (context->arrayTypeErrorCheck((yyvsp[(2) - (4)].lex).line, (yyvsp[(1) - (4)].interm.type)))
+        if (context->arrayTypeErrorCheck((yylsp[(2) - (4)]), (yyvsp[(1) - (4)].interm.type)))
             context->recover();
         else {
             int size;
-            if (context->arraySizeErrorCheck((yyvsp[(2) - (4)].lex).line, (yyvsp[(3) - (4)].interm.intermTypedNode), size))
+            if (context->arraySizeErrorCheck((yylsp[(2) - (4)]), (yyvsp[(3) - (4)].interm.intermTypedNode), size))
                 context->recover();
             (yyval.interm.type).setArray(true, size);
         }
@@ -3738,7 +3878,7 @@
 
     {
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
-        (yyval.interm.type).setBasic(EbtVoid, qual, (yyvsp[(1) - (1)].lex).line);
+        (yyval.interm.type).setBasic(EbtVoid, qual, (yylsp[(1) - (1)]));
     }
     break;
 
@@ -3746,7 +3886,7 @@
 
     {
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
-        (yyval.interm.type).setBasic(EbtFloat, qual, (yyvsp[(1) - (1)].lex).line);
+        (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[(1) - (1)]));
     }
     break;
 
@@ -3754,7 +3894,7 @@
 
     {
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
-        (yyval.interm.type).setBasic(EbtInt, qual, (yyvsp[(1) - (1)].lex).line);
+        (yyval.interm.type).setBasic(EbtInt, qual, (yylsp[(1) - (1)]));
     }
     break;
 
@@ -3762,7 +3902,7 @@
 
     {
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
-        (yyval.interm.type).setBasic(EbtBool, qual, (yyvsp[(1) - (1)].lex).line);
+        (yyval.interm.type).setBasic(EbtBool, qual, (yylsp[(1) - (1)]));
     }
     break;
 
@@ -3770,7 +3910,7 @@
 
     {
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
-        (yyval.interm.type).setBasic(EbtFloat, qual, (yyvsp[(1) - (1)].lex).line);
+        (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[(1) - (1)]));
         (yyval.interm.type).setAggregate(2);
     }
     break;
@@ -3779,7 +3919,7 @@
 
     {
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
-        (yyval.interm.type).setBasic(EbtFloat, qual, (yyvsp[(1) - (1)].lex).line);
+        (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[(1) - (1)]));
         (yyval.interm.type).setAggregate(3);
     }
     break;
@@ -3788,7 +3928,7 @@
 
     {
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
-        (yyval.interm.type).setBasic(EbtFloat, qual, (yyvsp[(1) - (1)].lex).line);
+        (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[(1) - (1)]));
         (yyval.interm.type).setAggregate(4);
     }
     break;
@@ -3797,7 +3937,7 @@
 
     {
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
-        (yyval.interm.type).setBasic(EbtBool, qual, (yyvsp[(1) - (1)].lex).line);
+        (yyval.interm.type).setBasic(EbtBool, qual, (yylsp[(1) - (1)]));
         (yyval.interm.type).setAggregate(2);
     }
     break;
@@ -3806,7 +3946,7 @@
 
     {
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
-        (yyval.interm.type).setBasic(EbtBool, qual, (yyvsp[(1) - (1)].lex).line);
+        (yyval.interm.type).setBasic(EbtBool, qual, (yylsp[(1) - (1)]));
         (yyval.interm.type).setAggregate(3);
     }
     break;
@@ -3815,7 +3955,7 @@
 
     {
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
-        (yyval.interm.type).setBasic(EbtBool, qual, (yyvsp[(1) - (1)].lex).line);
+        (yyval.interm.type).setBasic(EbtBool, qual, (yylsp[(1) - (1)]));
         (yyval.interm.type).setAggregate(4);
     }
     break;
@@ -3824,7 +3964,7 @@
 
     {
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
-        (yyval.interm.type).setBasic(EbtInt, qual, (yyvsp[(1) - (1)].lex).line);
+        (yyval.interm.type).setBasic(EbtInt, qual, (yylsp[(1) - (1)]));
         (yyval.interm.type).setAggregate(2);
     }
     break;
@@ -3833,7 +3973,7 @@
 
     {
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
-        (yyval.interm.type).setBasic(EbtInt, qual, (yyvsp[(1) - (1)].lex).line);
+        (yyval.interm.type).setBasic(EbtInt, qual, (yylsp[(1) - (1)]));
         (yyval.interm.type).setAggregate(3);
     }
     break;
@@ -3842,7 +3982,7 @@
 
     {
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
-        (yyval.interm.type).setBasic(EbtInt, qual, (yyvsp[(1) - (1)].lex).line);
+        (yyval.interm.type).setBasic(EbtInt, qual, (yylsp[(1) - (1)]));
         (yyval.interm.type).setAggregate(4);
     }
     break;
@@ -3850,9 +3990,9 @@
   case 130:
 
     {
-        FRAG_VERT_ONLY("mat2", (yyvsp[(1) - (1)].lex).line);
+        FRAG_VERT_ONLY("mat2", (yylsp[(1) - (1)]));
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
-        (yyval.interm.type).setBasic(EbtFloat, qual, (yyvsp[(1) - (1)].lex).line);
+        (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[(1) - (1)]));
         (yyval.interm.type).setAggregate(2, true);
     }
     break;
@@ -3860,9 +4000,9 @@
   case 131:
 
     {
-        FRAG_VERT_ONLY("mat3", (yyvsp[(1) - (1)].lex).line);
+        FRAG_VERT_ONLY("mat3", (yylsp[(1) - (1)]));
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
-        (yyval.interm.type).setBasic(EbtFloat, qual, (yyvsp[(1) - (1)].lex).line);
+        (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[(1) - (1)]));
         (yyval.interm.type).setAggregate(3, true);
     }
     break;
@@ -3870,9 +4010,9 @@
   case 132:
 
     {
-        FRAG_VERT_ONLY("mat4", (yyvsp[(1) - (1)].lex).line);
+        FRAG_VERT_ONLY("mat4", (yylsp[(1) - (1)]));
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
-        (yyval.interm.type).setBasic(EbtFloat, qual, (yyvsp[(1) - (1)].lex).line);
+        (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[(1) - (1)]));
         (yyval.interm.type).setAggregate(4, true);
     }
     break;
@@ -3880,18 +4020,18 @@
   case 133:
 
     {
-        FRAG_VERT_ONLY("sampler2D", (yyvsp[(1) - (1)].lex).line);
+        FRAG_VERT_ONLY("sampler2D", (yylsp[(1) - (1)]));
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
-        (yyval.interm.type).setBasic(EbtSampler2D, qual, (yyvsp[(1) - (1)].lex).line);
+        (yyval.interm.type).setBasic(EbtSampler2D, qual, (yylsp[(1) - (1)]));
     }
     break;
 
   case 134:
 
     {
-        FRAG_VERT_ONLY("samplerCube", (yyvsp[(1) - (1)].lex).line);
+        FRAG_VERT_ONLY("samplerCube", (yylsp[(1) - (1)]));
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
-        (yyval.interm.type).setBasic(EbtSamplerCube, qual, (yyvsp[(1) - (1)].lex).line);
+        (yyval.interm.type).setBasic(EbtSamplerCube, qual, (yylsp[(1) - (1)]));
     }
     break;
 
@@ -3899,12 +4039,12 @@
 
     {
         if (!context->supportsExtension("GL_OES_EGL_image_external")) {
-            context->error((yyvsp[(1) - (1)].lex).line, "unsupported type", "samplerExternalOES");
+            context->error((yylsp[(1) - (1)]), "unsupported type", "samplerExternalOES");
             context->recover();
         }
-        FRAG_VERT_ONLY("samplerExternalOES", (yyvsp[(1) - (1)].lex).line);
+        FRAG_VERT_ONLY("samplerExternalOES", (yylsp[(1) - (1)]));
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
-        (yyval.interm.type).setBasic(EbtSamplerExternalOES, qual, (yyvsp[(1) - (1)].lex).line);
+        (yyval.interm.type).setBasic(EbtSamplerExternalOES, qual, (yylsp[(1) - (1)]));
     }
     break;
 
@@ -3912,19 +4052,19 @@
 
     {
         if (!context->supportsExtension("GL_ARB_texture_rectangle")) {
-            context->error((yyvsp[(1) - (1)].lex).line, "unsupported type", "sampler2DRect");
+            context->error((yylsp[(1) - (1)]), "unsupported type", "sampler2DRect");
             context->recover();
         }
-        FRAG_VERT_ONLY("sampler2DRect", (yyvsp[(1) - (1)].lex).line);
+        FRAG_VERT_ONLY("sampler2DRect", (yylsp[(1) - (1)]));
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
-        (yyval.interm.type).setBasic(EbtSampler2DRect, qual, (yyvsp[(1) - (1)].lex).line);
+        (yyval.interm.type).setBasic(EbtSampler2DRect, qual, (yylsp[(1) - (1)]));
     }
     break;
 
   case 137:
 
     {
-        FRAG_VERT_ONLY("struct", (yyvsp[(1) - (1)].interm.type).line);
+        FRAG_VERT_ONLY("struct", (yylsp[(1) - (1)]));
         (yyval.interm.type) = (yyvsp[(1) - (1)].interm.type);
         (yyval.interm.type).qualifier = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
     }
@@ -3939,29 +4079,29 @@
         //
         TType& structure = static_cast<TVariable*>((yyvsp[(1) - (1)].lex).symbol)->getType();
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
-        (yyval.interm.type).setBasic(EbtStruct, qual, (yyvsp[(1) - (1)].lex).line);
+        (yyval.interm.type).setBasic(EbtStruct, qual, (yylsp[(1) - (1)]));
         (yyval.interm.type).userDef = &structure;
     }
     break;
 
   case 139:
 
-    { if (context->enterStructDeclaration((yyvsp[(2) - (3)].lex).line, *(yyvsp[(2) - (3)].lex).string)) context->recover(); }
+    { if (context->enterStructDeclaration((yylsp[(2) - (3)]), *(yyvsp[(2) - (3)].lex).string)) context->recover(); }
     break;
 
   case 140:
 
     {
-        if (context->reservedErrorCheck((yyvsp[(2) - (6)].lex).line, *(yyvsp[(2) - (6)].lex).string))
+        if (context->reservedErrorCheck((yylsp[(2) - (6)]), *(yyvsp[(2) - (6)].lex).string))
             context->recover();
 
         TType* structure = new TType((yyvsp[(5) - (6)].interm).structure, *(yyvsp[(2) - (6)].lex).string);
         TVariable* userTypeDef = new TVariable((yyvsp[(2) - (6)].lex).string, *structure, true);
         if (! context->symbolTable.insert(*userTypeDef)) {
-            context->error((yyvsp[(2) - (6)].lex).line, "redefinition", (yyvsp[(2) - (6)].lex).string->c_str(), "struct");
+            context->error((yylsp[(2) - (6)]), "redefinition", (yyvsp[(2) - (6)].lex).string->c_str(), "struct");
             context->recover();
         }
-        (yyval.interm.type).setBasic(EbtStruct, EvqTemporary, (yyvsp[(1) - (6)].lex).line);
+        (yyval.interm.type).setBasic(EbtStruct, EvqTemporary, (yylsp[(1) - (6)]));
         (yyval.interm.type).userDef = structure;
         context->exitStructDeclaration();
     }
@@ -3969,14 +4109,14 @@
 
   case 141:
 
-    { if (context->enterStructDeclaration((yyvsp[(2) - (2)].lex).line, *(yyvsp[(2) - (2)].lex).string)) context->recover(); }
+    { if (context->enterStructDeclaration((yylsp[(2) - (2)]), *(yyvsp[(2) - (2)].lex).string)) context->recover(); }
     break;
 
   case 142:
 
     {
         TType* structure = new TType((yyvsp[(4) - (5)].interm).structure, TString(""));
-        (yyval.interm.type).setBasic(EbtStruct, EvqTemporary, (yyvsp[(1) - (5)].lex).line);
+        (yyval.interm.type).setBasic(EbtStruct, EvqTemporary, (yylsp[(1) - (5)]));
         (yyval.interm.type).userDef = structure;
         context->exitStructDeclaration();
     }
@@ -3997,7 +4137,7 @@
             TType* field = (*(yyvsp[(2) - (2)].interm).structure)[i];
             for (size_t j = 0; j < (yyval.interm).structure->size(); ++j) {
                 if ((*(yyval.interm).structure)[j]->getFieldName() == field->getFieldName()) {
-                    context->error((yyvsp[(2) - (2)].interm).line, "duplicate field name in structure:", "struct", field->getFieldName().c_str());
+                    context->error((yylsp[(2) - (2)]), "duplicate field name in structure:", "struct", field->getFieldName().c_str());
                     context->recover();
                 }
             }
@@ -4011,7 +4151,7 @@
     {
         (yyval.interm) = (yyvsp[(2) - (3)].interm);
 
-        if (context->voidErrorCheck((yyvsp[(1) - (3)].interm.type).line, (*(yyvsp[(2) - (3)].interm).structure)[0]->getFieldName(), (yyvsp[(1) - (3)].interm.type))) {
+        if (context->voidErrorCheck((yylsp[(1) - (3)]), (*(yyvsp[(2) - (3)].interm).structure)[0]->getFieldName(), (yyvsp[(1) - (3)].interm.type))) {
             context->recover();
         }
         for (unsigned int i = 0; i < (yyval.interm).structure->size(); ++i) {
@@ -4026,7 +4166,7 @@
 
             // don't allow arrays of arrays
             if (type->isArray()) {
-                if (context->arrayTypeErrorCheck((yyvsp[(1) - (3)].interm.type).line, (yyvsp[(1) - (3)].interm.type)))
+                if (context->arrayTypeErrorCheck((yylsp[(1) - (3)]), (yyvsp[(1) - (3)].interm.type)))
                     context->recover();
             }
             if ((yyvsp[(1) - (3)].interm.type).array)
@@ -4036,7 +4176,7 @@
                 type->setTypeName((yyvsp[(1) - (3)].interm.type).userDef->getTypeName());
             }
 
-            if (context->structNestingErrorCheck((yyvsp[(1) - (3)].interm.type).line, *type)) {
+            if (context->structNestingErrorCheck((yylsp[(1) - (3)]), *type)) {
                 context->recover();
             }
         }
@@ -4061,7 +4201,7 @@
   case 148:
 
     {
-        if (context->reservedErrorCheck((yyvsp[(1) - (1)].lex).line, *(yyvsp[(1) - (1)].lex).string))
+        if (context->reservedErrorCheck((yylsp[(1) - (1)]), *(yyvsp[(1) - (1)].lex).string))
             context->recover();
 
         (yyval.interm.field) = new TType(EbtVoid, EbpUndefined);
@@ -4072,14 +4212,14 @@
   case 149:
 
     {
-        if (context->reservedErrorCheck((yyvsp[(1) - (4)].lex).line, *(yyvsp[(1) - (4)].lex).string))
+        if (context->reservedErrorCheck((yylsp[(1) - (4)]), *(yyvsp[(1) - (4)].lex).string))
             context->recover();
 
         (yyval.interm.field) = new TType(EbtVoid, EbpUndefined);
         (yyval.interm.field)->setFieldName(*(yyvsp[(1) - (4)].lex).string);
 
         int size;
-        if (context->arraySizeErrorCheck((yyvsp[(2) - (4)].lex).line, (yyvsp[(3) - (4)].interm.intermTypedNode), size))
+        if (context->arraySizeErrorCheck((yylsp[(2) - (4)]), (yyvsp[(3) - (4)].interm.intermTypedNode), size))
             context->recover();
         (yyval.interm.field)->setArraySize(size);
     }
@@ -4150,7 +4290,7 @@
     {
         if ((yyvsp[(3) - (5)].interm.intermAggregate) != 0) {
             (yyvsp[(3) - (5)].interm.intermAggregate)->setOp(EOpSequence);
-            (yyvsp[(3) - (5)].interm.intermAggregate)->setEndLine((yyvsp[(5) - (5)].lex).line);
+            (yyvsp[(3) - (5)].interm.intermAggregate)->setLine((yyloc));
         }
         (yyval.interm.intermAggregate) = (yyvsp[(3) - (5)].interm.intermAggregate);
     }
@@ -4198,7 +4338,7 @@
     {
         if ((yyvsp[(2) - (3)].interm.intermAggregate)) {
             (yyvsp[(2) - (3)].interm.intermAggregate)->setOp(EOpSequence);
-            (yyvsp[(2) - (3)].interm.intermAggregate)->setEndLine((yyvsp[(3) - (3)].lex).line);
+            (yyvsp[(2) - (3)].interm.intermAggregate)->setLine((yyloc));
         }
         (yyval.interm.intermNode) = (yyvsp[(2) - (3)].interm.intermAggregate);
     }
@@ -4207,14 +4347,14 @@
   case 171:
 
     {
-        (yyval.interm.intermAggregate) = context->intermediate.makeAggregate((yyvsp[(1) - (1)].interm.intermNode), 0);
+        (yyval.interm.intermAggregate) = context->intermediate.makeAggregate((yyvsp[(1) - (1)].interm.intermNode), (yyloc));
     }
     break;
 
   case 172:
 
     {
-        (yyval.interm.intermAggregate) = context->intermediate.growAggregate((yyvsp[(1) - (2)].interm.intermAggregate), (yyvsp[(2) - (2)].interm.intermNode), 0);
+        (yyval.interm.intermAggregate) = context->intermediate.growAggregate((yyvsp[(1) - (2)].interm.intermAggregate), (yyvsp[(2) - (2)].interm.intermNode), (yyloc));
     }
     break;
 
@@ -4231,9 +4371,9 @@
   case 175:
 
     {
-        if (context->boolErrorCheck((yyvsp[(1) - (5)].lex).line, (yyvsp[(3) - (5)].interm.intermTypedNode)))
+        if (context->boolErrorCheck((yylsp[(1) - (5)]), (yyvsp[(3) - (5)].interm.intermTypedNode)))
             context->recover();
-        (yyval.interm.intermNode) = context->intermediate.addSelection((yyvsp[(3) - (5)].interm.intermTypedNode), (yyvsp[(5) - (5)].interm.nodePair), (yyvsp[(1) - (5)].lex).line);
+        (yyval.interm.intermNode) = context->intermediate.addSelection((yyvsp[(3) - (5)].interm.intermTypedNode), (yyvsp[(5) - (5)].interm.nodePair), (yylsp[(1) - (5)]));
     }
     break;
 
@@ -4266,12 +4406,12 @@
 
     {
         TIntermNode* intermNode;
-        if (context->structQualifierErrorCheck((yyvsp[(2) - (4)].lex).line, (yyvsp[(1) - (4)].interm.type)))
+        if (context->structQualifierErrorCheck((yylsp[(2) - (4)]), (yyvsp[(1) - (4)].interm.type)))
             context->recover();
-        if (context->boolErrorCheck((yyvsp[(2) - (4)].lex).line, (yyvsp[(1) - (4)].interm.type)))
+        if (context->boolErrorCheck((yylsp[(2) - (4)]), (yyvsp[(1) - (4)].interm.type)))
             context->recover();
 
-        if (!context->executeInitializer((yyvsp[(2) - (4)].lex).line, *(yyvsp[(2) - (4)].lex).string, (yyvsp[(1) - (4)].interm.type), (yyvsp[(4) - (4)].interm.intermTypedNode), intermNode))
+        if (!context->executeInitializer((yylsp[(2) - (4)]), *(yyvsp[(2) - (4)].lex).string, (yyvsp[(1) - (4)].interm.type), (yyvsp[(4) - (4)].interm.intermTypedNode), intermNode))
             (yyval.interm.intermTypedNode) = (yyvsp[(4) - (4)].interm.intermTypedNode);
         else {
             context->recover();
@@ -4289,7 +4429,7 @@
 
     {
         context->symbolTable.pop();
-        (yyval.interm.intermNode) = context->intermediate.addLoop(ELoopWhile, 0, (yyvsp[(4) - (6)].interm.intermTypedNode), 0, (yyvsp[(6) - (6)].interm.intermNode), (yyvsp[(1) - (6)].lex).line);
+        (yyval.interm.intermNode) = context->intermediate.addLoop(ELoopWhile, 0, (yyvsp[(4) - (6)].interm.intermTypedNode), 0, (yyvsp[(6) - (6)].interm.intermNode), (yylsp[(1) - (6)]));
         --context->loopNestingLevel;
     }
     break;
@@ -4302,10 +4442,10 @@
   case 183:
 
     {
-        if (context->boolErrorCheck((yyvsp[(8) - (8)].lex).line, (yyvsp[(6) - (8)].interm.intermTypedNode)))
+        if (context->boolErrorCheck((yylsp[(8) - (8)]), (yyvsp[(6) - (8)].interm.intermTypedNode)))
             context->recover();
 
-        (yyval.interm.intermNode) = context->intermediate.addLoop(ELoopDoWhile, 0, (yyvsp[(6) - (8)].interm.intermTypedNode), 0, (yyvsp[(3) - (8)].interm.intermNode), (yyvsp[(4) - (8)].lex).line);
+        (yyval.interm.intermNode) = context->intermediate.addLoop(ELoopDoWhile, 0, (yyvsp[(6) - (8)].interm.intermTypedNode), 0, (yyvsp[(3) - (8)].interm.intermNode), (yylsp[(4) - (8)]));
         --context->loopNestingLevel;
     }
     break;
@@ -4319,7 +4459,7 @@
 
     {
         context->symbolTable.pop();
-        (yyval.interm.intermNode) = context->intermediate.addLoop(ELoopFor, (yyvsp[(4) - (7)].interm.intermNode), reinterpret_cast<TIntermTyped*>((yyvsp[(5) - (7)].interm.nodePair).node1), reinterpret_cast<TIntermTyped*>((yyvsp[(5) - (7)].interm.nodePair).node2), (yyvsp[(7) - (7)].interm.intermNode), (yyvsp[(1) - (7)].lex).line);
+        (yyval.interm.intermNode) = context->intermediate.addLoop(ELoopFor, (yyvsp[(4) - (7)].interm.intermNode), reinterpret_cast<TIntermTyped*>((yyvsp[(5) - (7)].interm.nodePair).node1), reinterpret_cast<TIntermTyped*>((yyvsp[(5) - (7)].interm.nodePair).node2), (yyvsp[(7) - (7)].interm.intermNode), (yylsp[(1) - (7)]));
         --context->loopNestingLevel;
     }
     break;
@@ -4372,10 +4512,10 @@
 
     {
         if (context->loopNestingLevel <= 0) {
-            context->error((yyvsp[(1) - (2)].lex).line, "continue statement only allowed in loops", "");
+            context->error((yylsp[(1) - (2)]), "continue statement only allowed in loops", "");
             context->recover();
         }
-        (yyval.interm.intermNode) = context->intermediate.addBranch(EOpContinue, (yyvsp[(1) - (2)].lex).line);
+        (yyval.interm.intermNode) = context->intermediate.addBranch(EOpContinue, (yylsp[(1) - (2)]));
     }
     break;
 
@@ -4383,19 +4523,19 @@
 
     {
         if (context->loopNestingLevel <= 0) {
-            context->error((yyvsp[(1) - (2)].lex).line, "break statement only allowed in loops", "");
+            context->error((yylsp[(1) - (2)]), "break statement only allowed in loops", "");
             context->recover();
         }
-        (yyval.interm.intermNode) = context->intermediate.addBranch(EOpBreak, (yyvsp[(1) - (2)].lex).line);
+        (yyval.interm.intermNode) = context->intermediate.addBranch(EOpBreak, (yylsp[(1) - (2)]));
     }
     break;
 
   case 194:
 
     {
-        (yyval.interm.intermNode) = context->intermediate.addBranch(EOpReturn, (yyvsp[(1) - (2)].lex).line);
+        (yyval.interm.intermNode) = context->intermediate.addBranch(EOpReturn, (yylsp[(1) - (2)]));
         if (context->currentFunctionType->getBasicType() != EbtVoid) {
-            context->error((yyvsp[(1) - (2)].lex).line, "non-void function must return a value", "return");
+            context->error((yylsp[(1) - (2)]), "non-void function must return a value", "return");
             context->recover();
         }
     }
@@ -4404,13 +4544,13 @@
   case 195:
 
     {
-        (yyval.interm.intermNode) = context->intermediate.addBranch(EOpReturn, (yyvsp[(2) - (3)].interm.intermTypedNode), (yyvsp[(1) - (3)].lex).line);
+        (yyval.interm.intermNode) = context->intermediate.addBranch(EOpReturn, (yyvsp[(2) - (3)].interm.intermTypedNode), (yylsp[(1) - (3)]));
         context->functionReturnsValue = true;
         if (context->currentFunctionType->getBasicType() == EbtVoid) {
-            context->error((yyvsp[(1) - (3)].lex).line, "void function cannot return a value", "return");
+            context->error((yylsp[(1) - (3)]), "void function cannot return a value", "return");
             context->recover();
         } else if (*(context->currentFunctionType) != (yyvsp[(2) - (3)].interm.intermTypedNode)->getType()) {
-            context->error((yyvsp[(1) - (3)].lex).line, "function return is not matching type:", "return");
+            context->error((yylsp[(1) - (3)]), "function return is not matching type:", "return");
             context->recover();
         }
     }
@@ -4419,8 +4559,8 @@
   case 196:
 
     {
-        FRAG_ONLY("discard", (yyvsp[(1) - (2)].lex).line);
-        (yyval.interm.intermNode) = context->intermediate.addBranch(EOpKill, (yyvsp[(1) - (2)].lex).line);
+        FRAG_ONLY("discard", (yylsp[(1) - (2)]));
+        (yyval.interm.intermNode) = context->intermediate.addBranch(EOpKill, (yylsp[(1) - (2)]));
     }
     break;
 
@@ -4435,7 +4575,7 @@
   case 198:
 
     {
-        (yyval.interm.intermNode) = context->intermediate.growAggregate((yyvsp[(1) - (2)].interm.intermNode), (yyvsp[(2) - (2)].interm.intermNode), 0);
+        (yyval.interm.intermNode) = context->intermediate.growAggregate((yyvsp[(1) - (2)].interm.intermNode), (yyvsp[(2) - (2)].interm.intermNode), (yyloc));
         context->treeRoot = (yyval.interm.intermNode);
     }
     break;
@@ -4463,7 +4603,7 @@
         
         if (builtIn)
         {
-            context->error((yyvsp[(1) - (1)].interm).line, "built-in functions cannot be redefined", function->getName().c_str());
+            context->error((yylsp[(1) - (1)]), "built-in functions cannot be redefined", function->getName().c_str());
             context->recover();
         }
         
@@ -4477,7 +4617,7 @@
             //
             // Then this function already has a body.
             //
-            context->error((yyvsp[(1) - (1)].interm).line, "function already has a body", function->getName().c_str());
+            context->error((yylsp[(1) - (1)]), "function already has a body", function->getName().c_str());
             context->recover();
         }
         prevDec->setDefined();
@@ -4487,11 +4627,11 @@
         //
         if (function->getName() == "main") {
             if (function->getParamCount() > 0) {
-                context->error((yyvsp[(1) - (1)].interm).line, "function cannot take any parameter(s)", function->getName().c_str());
+                context->error((yylsp[(1) - (1)]), "function cannot take any parameter(s)", function->getName().c_str());
                 context->recover();
             }
             if (function->getReturnType().getBasicType() != EbtVoid) {
-                context->error((yyvsp[(1) - (1)].interm).line, "", function->getReturnType().getBasicString(), "main function cannot return a value");
+                context->error((yylsp[(1) - (1)]), "", function->getReturnType().getBasicString(), "main function cannot return a value");
                 context->recover();
             }
         }
@@ -4519,7 +4659,7 @@
                 // Insert the parameters with name in the symbol table.
                 //
                 if (! context->symbolTable.insert(*variable)) {
-                    context->error((yyvsp[(1) - (1)].interm).line, "redefinition", variable->getName().c_str());
+                    context->error((yylsp[(1) - (1)]), "redefinition", variable->getName().c_str());
                     context->recover();
                     delete variable;
                 }
@@ -4530,14 +4670,15 @@
                 paramNodes = context->intermediate.growAggregate(
                                                paramNodes,
                                                context->intermediate.addSymbol(variable->getUniqueId(),
-                                                                       variable->getName(),
-                                                                       variable->getType(), (yyvsp[(1) - (1)].interm).line),
-                                               (yyvsp[(1) - (1)].interm).line);
+                                                                               variable->getName(),
+                                                                               variable->getType(),
+                                                                               (yylsp[(1) - (1)])),
+                                               (yylsp[(1) - (1)]));
             } else {
-                paramNodes = context->intermediate.growAggregate(paramNodes, context->intermediate.addSymbol(0, "", *param.type, (yyvsp[(1) - (1)].interm).line), (yyvsp[(1) - (1)].interm).line);
+                paramNodes = context->intermediate.growAggregate(paramNodes, context->intermediate.addSymbol(0, "", *param.type, (yylsp[(1) - (1)])), (yylsp[(1) - (1)]));
             }
         }
-        context->intermediate.setAggregateOperator(paramNodes, EOpParameters, (yyvsp[(1) - (1)].interm).line);
+        context->intermediate.setAggregateOperator(paramNodes, EOpParameters, (yylsp[(1) - (1)]));
         (yyvsp[(1) - (1)].interm).intermAggregate = paramNodes;
         context->loopNestingLevel = 0;
     }
@@ -4549,12 +4690,12 @@
         //?? Check that all paths return a value if return type != void ?
         //   May be best done as post process phase on intermediate code
         if (context->currentFunctionType->getBasicType() != EbtVoid && ! context->functionReturnsValue) {
-            context->error((yyvsp[(1) - (3)].interm).line, "function does not return a value:", "", (yyvsp[(1) - (3)].interm).function->getName().c_str());
+            context->error((yylsp[(1) - (3)]), "function does not return a value:", "", (yyvsp[(1) - (3)].interm).function->getName().c_str());
             context->recover();
         }
         
-        (yyval.interm.intermNode) = context->intermediate.growAggregate((yyvsp[(1) - (3)].interm).intermAggregate, (yyvsp[(3) - (3)].interm.intermNode), 0);
-        context->intermediate.setAggregateOperator((yyval.interm.intermNode), EOpFunction, (yyvsp[(1) - (3)].interm).line);
+        (yyval.interm.intermNode) = context->intermediate.growAggregate((yyvsp[(1) - (3)].interm).intermAggregate, (yyvsp[(3) - (3)].interm.intermNode), (yyloc));
+        context->intermediate.setAggregateOperator((yyval.interm.intermNode), EOpFunction, (yylsp[(1) - (3)]));
         (yyval.interm.intermNode)->getAsAggregate()->setName((yyvsp[(1) - (3)].interm).function->getMangledName().c_str());
         (yyval.interm.intermNode)->getAsAggregate()->setType((yyvsp[(1) - (3)].interm).function->getReturnType());
 
@@ -4563,9 +4704,6 @@
         (yyval.interm.intermNode)->getAsAggregate()->setOptimize(context->pragma().optimize);
         (yyval.interm.intermNode)->getAsAggregate()->setDebug(context->pragma().debug);
 
-        if ((yyvsp[(3) - (3)].interm.intermNode) && (yyvsp[(3) - (3)].interm.intermNode)->getAsAggregate())
-            (yyval.interm.intermNode)->getAsAggregate()->setEndLine((yyvsp[(3) - (3)].interm.intermNode)->getAsAggregate()->getEndLine());
-
         context->symbolTable.pop();
     }
     break;
@@ -4592,6 +4730,7 @@
   YY_STACK_PRINT (yyss, yyssp);
 
   *++yyvsp = yyval;
+  *++yylsp = yyloc;
 
   /* Now `shift' the result of the reduction.  Determine what state
      that goes to, based on the state we popped back to and the rule
@@ -4621,7 +4760,7 @@
     {
       ++yynerrs;
 #if ! YYERROR_VERBOSE
-      yyerror (context, YY_("syntax error"));
+      yyerror (&yylloc, context, YY_("syntax error"));
 #else
 # define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
                                         yyssp, yytoken)
@@ -4648,7 +4787,7 @@
                 yymsgp = yymsg;
               }
           }
-        yyerror (context, yymsgp);
+        yyerror (&yylloc, context, yymsgp);
         if (yysyntax_error_status == 2)
           goto yyexhaustedlab;
       }
@@ -4656,7 +4795,7 @@
 #endif
     }
 
-
+  yyerror_range[1] = yylloc;
 
   if (yyerrstatus == 3)
     {
@@ -4672,7 +4811,7 @@
       else
 	{
 	  yydestruct ("Error: discarding",
-		      yytoken, &yylval, context);
+		      yytoken, &yylval, &yylloc, context);
 	  yychar = YYEMPTY;
 	}
     }
@@ -4693,6 +4832,7 @@
   if (/*CONSTCOND*/ 0)
      goto yyerrorlab;
 
+  yyerror_range[1] = yylsp[1-yylen];
   /* Do not reclaim the symbols of the rule which action triggered
      this YYERROR.  */
   YYPOPSTACK (yylen);
@@ -4726,9 +4866,9 @@
       if (yyssp == yyss)
 	YYABORT;
 
-
+      yyerror_range[1] = *yylsp;
       yydestruct ("Error: popping",
-		  yystos[yystate], yyvsp, context);
+		  yystos[yystate], yyvsp, yylsp, context);
       YYPOPSTACK (1);
       yystate = *yyssp;
       YY_STACK_PRINT (yyss, yyssp);
@@ -4738,6 +4878,11 @@
   *++yyvsp = yylval;
   YY_IGNORE_MAYBE_UNINITIALIZED_END
 
+  yyerror_range[2] = yylloc;
+  /* Using YYLLOC is tempting, but would change the location of
+     the lookahead.  YYLOC is available though.  */
+  YYLLOC_DEFAULT (yyloc, yyerror_range, 2);
+  *++yylsp = yyloc;
 
   /* Shift the error token.  */
   YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
@@ -4765,7 +4910,7 @@
 | yyexhaustedlab -- memory exhaustion comes here.  |
 `-------------------------------------------------*/
 yyexhaustedlab:
-  yyerror (context, YY_("memory exhausted"));
+  yyerror (&yylloc, context, YY_("memory exhausted"));
   yyresult = 2;
   /* Fall through.  */
 #endif
@@ -4777,7 +4922,7 @@
          user semantic actions for why this is necessary.  */
       yytoken = YYTRANSLATE (yychar);
       yydestruct ("Cleanup: discarding lookahead",
-                  yytoken, &yylval, context);
+                  yytoken, &yylval, &yylloc, context);
     }
   /* Do not reclaim the symbols of the rule which action triggered
      this YYABORT or YYACCEPT.  */
@@ -4786,7 +4931,7 @@
   while (yyssp != yyss)
     {
       yydestruct ("Cleanup: popping",
-		  yystos[*yyssp], yyvsp, context);
+		  yystos[*yyssp], yyvsp, yylsp, context);
       YYPOPSTACK (1);
     }
 #ifndef yyoverflow
@@ -4805,6 +4950,11 @@
 
 
 
+void yyerror(YYLTYPE* yylloc, TParseContext* context, const char* reason) {
+    context->error(*yylloc, reason, "");
+    context->recover();
+}
+
 int glslang_parse(TParseContext* context) {
     return yyparse(context);
 }
diff --git a/src/compiler/glslang_tab.h b/src/compiler/glslang_tab.h
index 681b50a..4789f5c 100644
--- a/src/compiler/glslang_tab.h
+++ b/src/compiler/glslang_tab.h
@@ -39,6 +39,14 @@
 #if YYDEBUG
 extern int yydebug;
 #endif
+/* "%code requires" blocks.  */
+
+
+#define YYLTYPE TSourceLoc
+#define YYLTYPE_IS_DECLARED 1
+
+
+
 
 /* Tokens.  */
 #ifndef YYTOKENTYPE
@@ -148,7 +156,6 @@
 
 
     struct {
-        TSourceLoc line;
         union {
             TString *string;
             float f;
@@ -158,7 +165,6 @@
         TSymbol* symbol;
     } lex;
     struct {
-        TSourceLoc line;
         TOperator op;
         union {
             TIntermNode* intermNode;
@@ -185,6 +191,19 @@
 # define YYSTYPE_IS_DECLARED 1
 #endif
 
+#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
+
 
 #ifdef YYPARSE_PARAM
 #if defined __STDC__ || defined __cplusplus
diff --git a/src/compiler/intermOut.cpp b/src/compiler/intermOut.cpp
index f48a049..80f45fd 100644
--- a/src/compiler/intermOut.cpp
+++ b/src/compiler/intermOut.cpp
@@ -189,7 +189,9 @@
         case EOpAny:            out << "any";                  break;
         case EOpAll:            out << "all";                  break;
 
-        default: out.message(EPrefixError, "Bad unary op");
+        default:
+            out.prefix(EPrefixError);
+            out << "Bad unary op";
     }
 
     out << " (" << node->getCompleteString() << ")";
@@ -204,7 +206,8 @@
     TInfoSinkBase& out = sink;
 
     if (node->getOp() == EOpNull) {
-        out.message(EPrefixError, "node is still EOpNull!");
+        out.prefix(EPrefixError);
+        out << "node is still EOpNull!";
         return true;
     }
 
@@ -263,7 +266,9 @@
 
         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)
@@ -334,7 +339,7 @@
                 out << " (const int)\n";
                 break;
             default:
-                out.message(EPrefixInternalError, "Unknown constant", node->getLine());
+                out.message(EPrefixInternalError, node->getLine(), "Unknown constant");
                 break;
         }
     }
diff --git a/src/compiler/intermediate.h b/src/compiler/intermediate.h
index 8e76ef9..b5955bf 100644
--- a/src/compiler/intermediate.h
+++ b/src/compiler/intermediate.h
@@ -206,10 +206,16 @@
 public:
     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; }
-    void setLine(TSourceLoc l) { line = l; }
+    const TSourceLoc& getLine() const { return line; }
+    void setLine(const TSourceLoc& l) { line = l; }
 
     virtual void traverse(TIntermTraverser*) = 0;
     virtual TIntermTyped* getAsTyped() { return 0; }
@@ -220,7 +226,6 @@
     virtual TIntermSelection* getAsSelectionNode() { return 0; }
     virtual TIntermSymbol* getAsSymbolNode() { return 0; }
     virtual TIntermLoop* getAsLoopNode() { return 0; }
-    virtual ~TIntermNode() { }
 
 protected:
     TSourceLoc line;
@@ -454,7 +459,7 @@
 //
 class TIntermAggregate : public TIntermOperator {
 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() { }
 
@@ -474,9 +479,6 @@
     void setDebug(bool d) { debug = d; }
     bool getDebug() { return debug; }
 
-    void setEndLine(TSourceLoc line) { endLine = line; }
-    TSourceLoc getEndLine() const { return endLine; }
-
     void setUseEmulatedFunction() { useEmulatedFunction = true; }
     bool getUseEmulatedFunction() { return useEmulatedFunction; }
 
@@ -489,7 +491,6 @@
 
     bool optimize;
     bool debug;
-    TSourceLoc endLine;
 
     // If set to true, replace the built-in function call with an emulated one
     // to work around driver bugs.
diff --git a/src/compiler/localintermediate.h b/src/compiler/localintermediate.h
index 56890bd..b673407 100644
--- a/src/compiler/localintermediate.h
+++ b/src/compiler/localintermediate.h
@@ -25,34 +25,33 @@
     POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
 
     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* addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc, TSymbolTable&);
-    TIntermTyped* addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc);
-    TIntermTyped* addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc);
-    TIntermTyped* addUnaryMath(TOperator op, TIntermNode* child, TSourceLoc, TSymbolTable&);
-    TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right, TSourceLoc);
-    TIntermAggregate* makeAggregate(TIntermNode* node, TSourceLoc);
-    TIntermAggregate* setAggregateOperator(TIntermNode*, TOperator, TSourceLoc);
-    TIntermNode*  addSelection(TIntermTyped* cond, TIntermNodePair code, TSourceLoc);
-    TIntermTyped* addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, TSourceLoc);
-    TIntermTyped* addComma(TIntermTyped* left, TIntermTyped* right, TSourceLoc);
-    TIntermConstantUnion* addConstantUnion(ConstantUnion*, const TType&, TSourceLoc);
+    TIntermTyped* addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc&, TSymbolTable&);
+    TIntermTyped* addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc&);
+    TIntermTyped* addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, const TSourceLoc&);
+    TIntermTyped* addUnaryMath(TOperator op, TIntermNode* child, const TSourceLoc&, TSymbolTable&);
+    TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right, const TSourceLoc&);
+    TIntermAggregate* makeAggregate(TIntermNode* node, const TSourceLoc&);
+    TIntermAggregate* setAggregateOperator(TIntermNode*, TOperator, const TSourceLoc&);
+    TIntermNode*  addSelection(TIntermTyped* cond, TIntermNodePair code, const TSourceLoc&);
+    TIntermTyped* addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc&);
+    TIntermTyped* addComma(TIntermTyped* left, TIntermTyped* right, const TSourceLoc&);
+    TIntermConstantUnion* addConstantUnion(ConstantUnion*, const TType&, const TSourceLoc&);
     TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*) ;
-    bool parseConstTree(TSourceLoc, TIntermNode*, ConstantUnion*, TOperator, TSymbolTable&, TType, bool singleConstantParam = false);        
-    TIntermNode* addLoop(TLoopType, TIntermNode*, TIntermTyped*, TIntermTyped*, TIntermNode*, TSourceLoc);
-    TIntermBranch* addBranch(TOperator, TSourceLoc);
-    TIntermBranch* addBranch(TOperator, TIntermTyped*, TSourceLoc);
-    TIntermTyped* addSwizzle(TVectorFields&, TSourceLoc);
+    bool parseConstTree(const TSourceLoc&, TIntermNode*, ConstantUnion*, TOperator, TSymbolTable&, TType, bool singleConstantParam = false);        
+    TIntermNode* addLoop(TLoopType, TIntermNode*, TIntermTyped*, TIntermTyped*, TIntermNode*, const TSourceLoc&);
+    TIntermBranch* addBranch(TOperator, const TSourceLoc&);
+    TIntermBranch* addBranch(TOperator, TIntermTyped*, const TSourceLoc&);
+    TIntermTyped* addSwizzle(TVectorFields&, const TSourceLoc&);
     bool postProcess(TIntermNode*);
-	void remove(TIntermNode*);
+    void remove(TIntermNode*);
     void outputTree(TIntermNode*);
-    
-protected:
-    TInfoSink& infoSink;
 
 private:
     void operator=(TIntermediate&); // prevent assignments
+
+    TInfoSink& infoSink;
 };
 
 #endif // _LOCAL_INTERMEDIATE_INCLUDED_
diff --git a/src/compiler/parseConst.cpp b/src/compiler/parseConst.cpp
index 421d31f..4e78e21 100644
--- a/src/compiler/parseConst.cpp
+++ b/src/compiler/parseConst.cpp
@@ -61,7 +61,7 @@
 
 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;
 
 }
@@ -74,12 +74,12 @@
         TString buf;
         buf.append("'constructor' : assigning non-constant to ");
         buf.append(type.getCompleteString());
-        infoSink.info.message(EPrefixError, buf.c_str(), node->getLine());
+        infoSink.info.message(EPrefixError, node->getLine(), buf.c_str());
         error = true;
         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;
 }
@@ -89,7 +89,7 @@
     TString buf;
     buf.append("'constructor' : assigning non-constant to ");
     buf.append(type.getCompleteString());
-    infoSink.info.message(EPrefixError, buf.c_str(), node->getLine());
+    infoSink.info.message(EPrefixError, node->getLine(), buf.c_str());
     error = true;
     return false;  
 }
@@ -100,7 +100,7 @@
         TString buf;
         buf.append("'constructor' : assigning non-constant to ");
         buf.append(type.getCompleteString());
-        infoSink.info.message(EPrefixError, buf.c_str(), node->getLine());
+        infoSink.info.message(EPrefixError, node->getLine(), buf.c_str());
         error = true;
         return false;  
     }
@@ -144,7 +144,7 @@
 
 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;
     return false;
 }
@@ -213,14 +213,14 @@
 
 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;
     return false;
 }
 
 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;
     return false;
 }
@@ -230,7 +230,7 @@
 // Individual functions can be initialized to 0 to skip processing of that
 // 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)
         return false;
diff --git a/src/compiler/timing/RestrictVertexShaderTiming.cpp b/src/compiler/timing/RestrictVertexShaderTiming.cpp
index 524c6cf..355eb62 100644
--- a/src/compiler/timing/RestrictVertexShaderTiming.cpp
+++ b/src/compiler/timing/RestrictVertexShaderTiming.cpp
@@ -10,8 +10,8 @@
 {
     if (IsSampler(node->getBasicType())) {
         ++mNumErrors;
-        mSink.prefix(EPrefixError);
-        mSink.location(node->getLine());
-        mSink << "Samplers are not permitted in vertex shaders.\n";
+        mSink.message(EPrefixError,
+                      node->getLine(),
+                      "Samplers are not permitted in vertex shaders");
     }
 }