Completed conversion of TSourceLoc into a struct

TSourceLoc was defined as an int, but is meant to be
used as a struct to carry all the information provided
by the parser, so the conversion was made in this cl.

Change-Id: I6015d11aafda96914ec7b2c37883ffbc963a08fe
Reviewed-on: https://swiftshader-review.googlesource.com/3664
Reviewed-by: Nicolas Capens <capn@google.com>
Tested-by: Alexis Hétu <sugoi@google.com>
diff --git a/src/OpenGL/compiler/Common.h b/src/OpenGL/compiler/Common.h
index af29b2f..f3bf435 100644
--- a/src/OpenGL/compiler/Common.h
+++ b/src/OpenGL/compiler/Common.h
@@ -14,24 +14,12 @@
 
 #include "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/OpenGL/compiler/Diagnostics.cpp b/src/OpenGL/compiler/Diagnostics.cpp
index 32715ad..65aa6ed 100644
--- a/src/OpenGL/compiler/Diagnostics.cpp
+++ b/src/OpenGL/compiler/Diagnostics.cpp
@@ -52,7 +52,10 @@
     TInfoSinkBase& sink = mInfoSink.info;
     /* VC++ format: file(linenum) : error #: 'token' : extrainfo */
     sink.prefix(prefix);
-    sink.location(EncodeSourceLoc(loc.file, loc.line));
+    TSourceLoc sourceLoc;
+    sourceLoc.first_file = sourceLoc.last_file = loc.file;
+    sourceLoc.first_line = sourceLoc.last_line = loc.line;
+    sink.location(sourceLoc);
     sink << "'" << token <<  "' : " << reason << " " << extra << "\n";
 }
 
diff --git a/src/OpenGL/compiler/InfoSink.cpp b/src/OpenGL/compiler/InfoSink.cpp
index 15c8ac7..53efd17 100644
--- a/src/OpenGL/compiler/InfoSink.cpp
+++ b/src/OpenGL/compiler/InfoSink.cpp
@@ -31,9 +31,8 @@
     }
 }
 
-void TInfoSinkBase::location(TSourceLoc loc) {
-    int string = 0, line = 0;
-    DecodeSourceLoc(loc, &string, &line);
+void TInfoSinkBase::location(const TSourceLoc& loc) {
+    int string = loc.first_file, line = loc.first_line;
 
     TPersistStringStream stream;
     if (line)
diff --git a/src/OpenGL/compiler/InfoSink.h b/src/OpenGL/compiler/InfoSink.h
index d626e3f..160ba2e 100644
--- a/src/OpenGL/compiler/InfoSink.h
+++ b/src/OpenGL/compiler/InfoSink.h
@@ -97,7 +97,7 @@
     const char* c_str() const { return sink.c_str(); }
 
     void prefix(TPrefixType message);
-    void location(TSourceLoc loc);
+    void location(const TSourceLoc& loc);
     void message(TPrefixType message, const char* s);
     void message(TPrefixType message, const char* s, TSourceLoc loc);
 
diff --git a/src/OpenGL/compiler/Initialize.cpp b/src/OpenGL/compiler/Initialize.cpp
index 7bad154..cc71e0e 100644
--- a/src/OpenGL/compiler/Initialize.cpp
+++ b/src/OpenGL/compiler/Initialize.cpp
@@ -400,9 +400,10 @@
     // Depth range in window coordinates
     //
 	TFieldList *fields = NewPoolTFieldList();
-	TField *near = new TField(new TType(EbtFloat, EbpHigh, EvqGlobal, 1), NewPoolTString("near"), 0);
-	TField *far = new TField(new TType(EbtFloat, EbpHigh, EvqGlobal, 1), NewPoolTString("far"), 0);
-	TField *diff = new TField(new TType(EbtFloat, EbpHigh, EvqGlobal, 1), NewPoolTString("diff"), 0);
+	TSourceLoc zeroSourceLoc = { 0, 0, 0, 0 };
+	TField *near = new TField(new TType(EbtFloat, EbpHigh, EvqGlobal, 1), NewPoolTString("near"), zeroSourceLoc);
+	TField *far = new TField(new TType(EbtFloat, EbpHigh, EvqGlobal, 1), NewPoolTString("far"), zeroSourceLoc);
+	TField *diff = new TField(new TType(EbtFloat, EbpHigh, EvqGlobal, 1), NewPoolTString("diff"), zeroSourceLoc);
 	fields->push_back(near);
 	fields->push_back(far);
 	fields->push_back(diff);
diff --git a/src/OpenGL/compiler/Intermediate.cpp b/src/OpenGL/compiler/Intermediate.cpp
index 0579deb..ccb8d63 100644
--- a/src/OpenGL/compiler/Intermediate.cpp
+++ b/src/OpenGL/compiler/Intermediate.cpp
@@ -177,7 +177,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);
@@ -190,7 +190,7 @@
 //
 // Returns the added node.
 //
-TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc line)
+TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc &line)
 {
     switch (op) {
         case EOpEqual:
@@ -247,8 +247,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);
@@ -276,7 +274,7 @@
 //
 // 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)
 {
     if (left->getType().getStruct() || right->getType().getStruct())
     {
@@ -287,8 +285,6 @@
     }
 
     TIntermBinary* node = new TIntermBinary(op);
-    if(line == 0)
-        line = left->getLine();
     node->setLine(line);
 
     node->setLeft(left);
@@ -306,11 +302,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);
@@ -325,7 +319,7 @@
 //
 // Returns the added node.
 //
-TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode, TSourceLoc line)
+TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode, const TSourceLoc &line)
 {
     TIntermUnary* node;
     TIntermTyped* child = childNode->getAsTyped();
@@ -366,8 +360,6 @@
     // Make a new node for the operator.
     //
     node = new TIntermUnary(op);
-    if (line == 0)
-        line = child->getLine();
     node->setLine(line);
     node->setOperand(child);
 
@@ -394,7 +386,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;
 
@@ -409,8 +401,6 @@
             //
             aggNode = new TIntermAggregate();
             aggNode->getSequence().push_back(node);
-            if (line == 0)
-                line = node->getLine();
         }
     } else
         aggNode = new TIntermAggregate();
@@ -419,8 +409,6 @@
     // Set the operator.
     //
     aggNode->setOp(op);
-    if (line != 0)
-        aggNode->setLine(line);
 
     return aggNode;
 }
@@ -432,7 +420,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;
@@ -449,8 +437,7 @@
     if (right)
         aggNode->getSequence().push_back(right);
 
-    if (line != 0)
-        aggNode->setLine(line);
+    aggNode->setLine(line);
 
     return aggNode;
 }
@@ -460,7 +447,7 @@
 //
 // 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;
@@ -468,10 +455,7 @@
     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;
 }
@@ -483,7 +467,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
@@ -504,7 +488,7 @@
 }
 
 
-TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, TSourceLoc line)
+TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, const TSourceLoc &line)
 {
     if (left->getType().getQualifier() == EvqConstExpr && right->getType().getQualifier() == EvqConstExpr) {
         return right;
@@ -524,7 +508,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)
 {
     if (trueBlock->getType() != falseBlock->getType())
     {
@@ -574,7 +558,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);
@@ -582,7 +566,7 @@
     return node;
 }
 
-TIntermTyped* TIntermediate::addSwizzle(TVectorFields& fields, TSourceLoc line)
+TIntermTyped* TIntermediate::addSwizzle(TVectorFields& fields, const TSourceLoc &line)
 {
 
     TIntermAggregate* node = new TIntermAggregate(EOpSequence);
@@ -605,7 +589,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);
@@ -616,12 +600,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);
diff --git a/src/OpenGL/compiler/ParseHelper.cpp b/src/OpenGL/compiler/ParseHelper.cpp
index e75f0ba..f27486e 100644
--- a/src/OpenGL/compiler/ParseHelper.cpp
+++ b/src/OpenGL/compiler/ParseHelper.cpp
@@ -180,8 +180,7 @@
                           const char* reason, const char* token,
                           const char* extraInfo)
 {
-    pp::SourceLocation srcLoc;
-    DecodeSourceLoc(loc, &srcLoc.file, &srcLoc.line);
+    pp::SourceLocation srcLoc(loc.first_file, loc.first_line);
     mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR,
                            srcLoc, reason, token, extraInfo);
 
@@ -190,8 +189,7 @@
 void TParseContext::warning(const TSourceLoc& loc,
                             const char* reason, const char* token,
                             const char* extraInfo) {
-    pp::SourceLocation srcLoc;
-    DecodeSourceLoc(loc, &srcLoc.file, &srcLoc.line);
+    pp::SourceLocation srcLoc(loc.first_file, loc.first_line);
     mDiagnostics.writeInfo(pp::Diagnostics::PP_WARNING,
                            srcLoc, reason, token, extraInfo);
 }
@@ -1064,15 +1062,13 @@
 
 void TParseContext::handleExtensionDirective(const TSourceLoc &line, const char* extName, const char* behavior)
 {
-    pp::SourceLocation loc;
-    DecodeSourceLoc(line, &loc.file, &loc.line);
+    pp::SourceLocation loc(line.first_file, line.first_line);
     mDirectiveHandler.handleExtension(loc, extName, behavior);
 }
 
 void TParseContext::handlePragmaDirective(const TSourceLoc &line, const char* name, const char* value)
 {
-    pp::SourceLocation loc;
-    DecodeSourceLoc(line, &loc.file, &loc.line);
+    pp::SourceLocation loc(line.first_file, line.first_line);
     mDirectiveHandler.handlePragma(loc, name, value);
 }
 
diff --git a/src/OpenGL/compiler/glslang.l b/src/OpenGL/compiler/glslang.l
index a903f23..d33b0ed 100644
--- a/src/OpenGL/compiler/glslang.l
+++ b/src/OpenGL/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);
 
@@ -399,7 +402,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");
@@ -555,7 +559,8 @@
 int glslang_scan(size_t count, const char* const string[], const int length[],
                  TParseContext* context) {
     yyrestart(NULL, context->getScanner());
-    yyset_lineno(EncodeSourceLoc(0, 1), context->getScanner());
+    yyset_column(0, context->getScanner());
+    yyset_lineno(1, context->getScanner());
     context->AfterEOF = false;
 
     // Initialize preprocessor.
diff --git a/src/OpenGL/compiler/glslang.y b/src/OpenGL/compiler/glslang.y
index a10fc14..21793d8 100644
--- a/src/OpenGL/compiler/glslang.y
+++ b/src/OpenGL/compiler/glslang.y
@@ -53,7 +53,6 @@
 
 %union {
     struct {
-        TSourceLoc line;
         union {
             TString *string;
             float f;
@@ -64,7 +63,6 @@
         TSymbol* symbol;
     } lex;
     struct {
-        TSourceLoc line;
         TOperator op;
         union {
             TIntermNode* intermNode;
@@ -91,7 +89,21 @@
 extern int yylex(YYSTYPE* yylval, YYLTYPE* yylloc, void* yyscanner);
 extern void yyerror(YYLTYPE* lloc, TParseContext* context, const char* reason);
 
-#define YYLLOC_DEFAULT(Current, Rhs, N) do { (Current) = YYRHSLOC(Rhs, N ? 1 : 0); } while (0)
+#define YYLLOC_DEFAULT(Current, Rhs, N)                      \

+  do {                                                       \

+      if (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->getShaderType() != GL_FRAGMENT_SHADER &&  \
@@ -300,11 +312,9 @@
 function_call_generic
     : function_call_header_with_parameters RIGHT_PAREN {
         $$ = $1;
-        $$.line = @2;
     }
     | function_call_header_no_parameters RIGHT_PAREN {
         $$ = $1;
-        $$.line = @2;
     }
     ;
 
@@ -411,12 +421,12 @@
 // Grammar Note:  No traditional style type casts.
 
 unary_operator
-    : PLUS  { $$.line = @1; $$.op = EOpNull; }
-    | DASH  { $$.line = @1; $$.op = EOpNegative; }
-    | BANG  { $$.line = @1; $$.op = EOpLogicalNot; }
+    : PLUS  { $$.op = EOpNull; }

+    | DASH  { $$.op = EOpNegative; }

+    | BANG  { $$.op = EOpLogicalNot; }

     | TILDE {
         ES3_ONLY("~", @1, "bit-wise operator");
-        $$.line = @1; $$.op = EOpBitwiseNot;
+        $$.op = EOpBitwiseNot;

     }
     ;
 // Grammar Note:  No '*' or '&' unary ops.  Pointers are not supported.
@@ -548,23 +558,28 @@
     ;
 
 assignment_operator
-    : EQUAL        {                                    $$.line = @1; $$.op = EOpAssign; }
-    | MUL_ASSIGN   { FRAG_VERT_ONLY("*=", @1);     $$.line = @1; $$.op = EOpMulAssign; }
-    | DIV_ASSIGN   { FRAG_VERT_ONLY("/=", @1);     $$.line = @1; $$.op = EOpDivAssign; }
+    : EQUAL        {                           $$.op = EOpAssign; }

+    | MUL_ASSIGN   { FRAG_VERT_ONLY("*=", @1); $$.op = EOpMulAssign; }

+    | DIV_ASSIGN   { FRAG_VERT_ONLY("/=", @1); $$.op = EOpDivAssign; }

     | MOD_ASSIGN   { ES3_ONLY("%=", @1, "integer modulus operator");
-                     FRAG_VERT_ONLY("%=", @1);     $$.line = @1; $$.op = EOpIModAssign; }
-    | ADD_ASSIGN   {                                    $$.line = @1; $$.op = EOpAddAssign; }
-    | SUB_ASSIGN   {                                    $$.line = @1; $$.op = EOpSubAssign; }
+                     FRAG_VERT_ONLY("%=", @1); $$.op = EOpIModAssign; }

+    | ADD_ASSIGN   {                           $$.op = EOpAddAssign; }

+    | SUB_ASSIGN   {                           $$.op = EOpSubAssign; }

     | LEFT_ASSIGN  { ES3_ONLY("<<=", @1, "bit-wise operator");
-                     FRAG_VERT_ONLY("<<=", @1);    $$.line = @1; $$.op = EOpBitShiftLeftAssign; }
+                     FRAG_VERT_ONLY("<<=", @1);

+                     $$.op = EOpBitShiftLeftAssign; }

     | RIGHT_ASSIGN { ES3_ONLY(">>=", @1, "bit-wise operator");
-                     FRAG_VERT_ONLY(">>=", @1);    $$.line = @1; $$.op = EOpBitShiftRightAssign; }
+                     FRAG_VERT_ONLY(">>=", @1);

+                     $$.op = EOpBitShiftRightAssign; }

     | AND_ASSIGN   { ES3_ONLY("&=", @1, "bit-wise operator");
-                     FRAG_VERT_ONLY("&=", @1);     $$.line = @1; $$.op = EOpBitwiseAndAssign; }
+                     FRAG_VERT_ONLY("&=", @1);

+                     $$.op = EOpBitwiseAndAssign; }

     | XOR_ASSIGN   { ES3_ONLY("^=", @1, "bit-wise operator");
-                     FRAG_VERT_ONLY("^=", @1);     $$.line = @1; $$.op = EOpBitwiseXorAssign; }
+                     FRAG_VERT_ONLY("^=", @1);

+                     $$.op = EOpBitwiseXorAssign; }

     | OR_ASSIGN    { ES3_ONLY("|=", @1, "bit-wise operator");
-                     FRAG_VERT_ONLY("|=", @1);     $$.line = @1; $$.op = EOpBitwiseOrAssign; }
+                     FRAG_VERT_ONLY("|=", @1);

+                     $$.op = EOpBitwiseOrAssign; }

     ;
 
 expression
@@ -686,7 +701,6 @@
         // being redeclared.  So, pass back up this declaration, not the one in the symbol table.
         //
         $$.function = $1;
-        $$.line = @2;
 
         // We're at the inner scope level of the function's arguments and body statement.
         // Add the function prototype to the surrounding scope instead.
@@ -763,7 +777,6 @@
         if (context->reservedErrorCheck(@2, *$2.string))
             context->recover();
         TParameter param = {$2.string, new TType($1)};
-        $$.line = @2;
         $$.param = param;
     }
     | type_specifier IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET {
@@ -781,7 +794,6 @@
 
         TType* type = new TType($1);
         TParameter param = { $2.string, type };
-        $$.line = @2;
         $$.param = param;
     }
     ;
@@ -990,17 +1002,14 @@
 storage_qualifier
     : CONST_QUAL {
         $$.qualifier = EvqConstExpr;
-		$$.line = @1;
     }
     | IN_QUAL {
         ES3_ONLY("in", @1, "storage qualifier");
         $$.qualifier = (context->getShaderType() == GL_FRAGMENT_SHADER) ? EvqFragmentIn : EvqVertexIn;
-		$$.line = @1;
     }
     | OUT_QUAL {
         ES3_ONLY("out", @1, "storage qualifier");
         $$.qualifier = (context->getShaderType() == GL_FRAGMENT_SHADER) ? EvqFragmentOut : EvqVertexOut;
-		$$.line = @1;
     }
     | CENTROID IN_QUAL {
         ES3_ONLY("centroid in", @1, "storage qualifier");
@@ -1010,7 +1019,6 @@
             context->recover();
         }
         $$.qualifier = (context->getShaderType() == GL_FRAGMENT_SHADER) ? EvqCentroidIn : EvqVertexIn;
-		$$.line = @2;
     }
     | CENTROID OUT_QUAL {
         ES3_ONLY("centroid out", @1, "storage qualifier");
@@ -1020,13 +1028,11 @@
             context->recover();
         }
         $$.qualifier = (context->getShaderType() == GL_FRAGMENT_SHADER) ? EvqFragmentOut : EvqCentroidOut;
-		$$.line = @2;
     }
 	| UNIFORM {
         if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "uniform"))
             context->recover();
         $$.qualifier = EvqUniform;
-		$$.line = @1;
     }
     ;
 
@@ -1480,10 +1486,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, @$);

     }
     ;
 
@@ -1628,7 +1634,7 @@
         context->setTreeRoot($$);
     }
     | translation_unit external_declaration {
-        $$ = context->intermediate.growAggregate($1, $2, 0);
+        $$ = context->intermediate.growAggregate($1, $2, @$);

         context->setTreeRoot($$);
     }
     ;
@@ -1736,7 +1742,7 @@
             context->recover();
         }
         
-        $$ = context->intermediate.growAggregate($1.intermAggregate, $3, 0);
+        $$ = context->intermediate.growAggregate($1.intermAggregate, $3, @$);

         context->intermediate.setAggregateOperator($$, EOpFunction, @1);
         $$->getAsAggregate()->setName($1.function->getMangledName().c_str());
         $$->getAsAggregate()->setType($1.function->getReturnType());
diff --git a/src/OpenGL/compiler/glslang_lex.cpp b/src/OpenGL/compiler/glslang_lex.cpp
index 22d82fc..36b237a 100644
--- a/src/OpenGL/compiler/glslang_lex.cpp
+++ b/src/OpenGL/compiler/glslang_lex.cpp
@@ -1034,7 +1034,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);
 
@@ -3291,7 +3294,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");
@@ -3447,7 +3451,8 @@
 int glslang_scan(size_t count, const char* const string[], const int length[],
                  TParseContext* context) {
     yyrestart(NULL,context->getScanner());
-    yyset_lineno(EncodeSourceLoc(0, 1),context->getScanner());
+    yyset_column(0,context->getScanner());
+    yyset_lineno(1,context->getScanner());
     context->AfterEOF = false;
 
     // Initialize preprocessor.
diff --git a/src/OpenGL/compiler/glslang_tab.cpp b/src/OpenGL/compiler/glslang_tab.cpp
index 64d47f8..1853808 100644
--- a/src/OpenGL/compiler/glslang_tab.cpp
+++ b/src/OpenGL/compiler/glslang_tab.cpp
@@ -266,7 +266,6 @@
 
 
     struct {
-        TSourceLoc line;
         union {
             TString *string;
             float f;
@@ -277,7 +276,6 @@
         TSymbol* symbol;
     } lex;
     struct {
-        TSourceLoc line;
         TOperator op;
         union {
             TIntermNode* intermNode;
@@ -327,7 +325,21 @@
 extern int yylex(YYSTYPE* yylval, YYLTYPE* yylloc, void* yyscanner);
 extern void yyerror(YYLTYPE* lloc, TParseContext* context, const char* reason);
 
-#define YYLLOC_DEFAULT(Current, Rhs, N) do { (Current) = YYRHSLOC(Rhs, N ? 1 : 0); } while (0)
+#define YYLLOC_DEFAULT(Current, Rhs, N)                      \
+  do {                                                       \
+      if (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->getShaderType() != GL_FRAGMENT_SHADER &&  \
@@ -765,34 +777,34 @@
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
-       0,   202,   202,   221,   224,   229,   234,   239,   244,   250,
-     253,   256,   259,   262,   265,   271,   279,   290,   293,   301,
-     305,   312,   316,   323,   329,   338,   346,   352,   359,   369,
-     372,   382,   392,   414,   415,   416,   417,   425,   426,   430,
-     434,   442,   443,   446,   452,   453,   457,   464,   465,   468,
-     471,   474,   480,   481,   484,   490,   491,   498,   499,   506,
-     507,   514,   515,   521,   522,   528,   529,   535,   536,   542,
-     543,   551,   552,   553,   554,   556,   557,   558,   560,   562,
-     564,   566,   571,   574,   585,   593,   601,   628,   634,   641,
-     645,   649,   653,   660,   698,   701,   708,   716,   737,   758,
-     769,   798,   803,   813,   818,   828,   831,   834,   837,   843,
-     850,   853,   857,   861,   866,   871,   878,   882,   886,   890,
-     895,   900,   904,   911,   921,   927,   930,   936,   942,   949,
-     958,   967,   970,   973,   980,   984,   991,   995,  1000,  1005,
-    1015,  1025,  1034,  1044,  1051,  1054,  1057,  1063,  1070,  1073,
-    1079,  1082,  1085,  1091,  1094,  1099,  1114,  1118,  1122,  1126,
-    1130,  1134,  1139,  1144,  1149,  1154,  1159,  1164,  1169,  1174,
-    1179,  1184,  1189,  1194,  1200,  1206,  1212,  1218,  1224,  1230,
-    1236,  1242,  1248,  1253,  1258,  1267,  1272,  1277,  1282,  1287,
-    1292,  1297,  1302,  1307,  1312,  1317,  1322,  1327,  1332,  1337,
-    1350,  1350,  1353,  1353,  1359,  1362,  1378,  1381,  1390,  1394,
-    1400,  1407,  1422,  1426,  1430,  1431,  1437,  1438,  1439,  1440,
-    1441,  1442,  1443,  1447,  1448,  1448,  1448,  1458,  1459,  1463,
-    1463,  1464,  1464,  1469,  1472,  1482,  1485,  1491,  1492,  1496,
-    1504,  1508,  1515,  1515,  1522,  1525,  1534,  1539,  1556,  1556,
-    1561,  1561,  1568,  1568,  1576,  1579,  1585,  1588,  1594,  1598,
-    1605,  1608,  1611,  1614,  1617,  1626,  1630,  1637,  1640,  1646,
-    1646
+       0,   214,   214,   233,   236,   241,   246,   251,   256,   262,
+     265,   268,   271,   274,   277,   283,   291,   302,   305,   313,
+     316,   322,   326,   333,   339,   348,   356,   362,   369,   379,
+     382,   392,   402,   424,   425,   426,   427,   435,   436,   440,
+     444,   452,   453,   456,   462,   463,   467,   474,   475,   478,
+     481,   484,   490,   491,   494,   500,   501,   508,   509,   516,
+     517,   524,   525,   531,   532,   538,   539,   545,   546,   552,
+     553,   561,   562,   563,   564,   566,   567,   568,   571,   574,
+     577,   580,   586,   589,   600,   608,   616,   643,   649,   656,
+     660,   664,   668,   675,   712,   715,   722,   730,   751,   772,
+     782,   810,   815,   825,   830,   840,   843,   846,   849,   855,
+     862,   865,   869,   873,   878,   883,   890,   894,   898,   902,
+     907,   912,   916,   923,   933,   939,   942,   948,   954,   961,
+     970,   979,   982,   985,   992,   996,  1003,  1006,  1010,  1014,
+    1023,  1032,  1040,  1050,  1057,  1060,  1063,  1069,  1076,  1079,
+    1085,  1088,  1091,  1097,  1100,  1105,  1120,  1124,  1128,  1132,
+    1136,  1140,  1145,  1150,  1155,  1160,  1165,  1170,  1175,  1180,
+    1185,  1190,  1195,  1200,  1206,  1212,  1218,  1224,  1230,  1236,
+    1242,  1248,  1254,  1259,  1264,  1273,  1278,  1283,  1288,  1293,
+    1298,  1303,  1308,  1313,  1318,  1323,  1328,  1333,  1338,  1343,
+    1356,  1356,  1359,  1359,  1365,  1368,  1384,  1387,  1396,  1400,
+    1406,  1413,  1428,  1432,  1436,  1437,  1443,  1444,  1445,  1446,
+    1447,  1448,  1449,  1453,  1454,  1454,  1454,  1464,  1465,  1469,
+    1469,  1470,  1470,  1475,  1478,  1488,  1491,  1497,  1498,  1502,
+    1510,  1514,  1521,  1521,  1528,  1531,  1540,  1545,  1562,  1562,
+    1567,  1567,  1574,  1574,  1582,  1585,  1591,  1594,  1600,  1604,
+    1611,  1614,  1617,  1620,  1623,  1632,  1636,  1643,  1646,  1652,
+    1652
 };
 #endif
 
@@ -2638,7 +2650,6 @@
 
     {
         (yyval.interm) = (yyvsp[(1) - (2)].interm);
-        (yyval.interm).line = (yylsp[(2) - (2)]);
     }
     break;
 
@@ -2646,7 +2657,6 @@
 
     {
         (yyval.interm) = (yyvsp[(1) - (2)].interm);
-        (yyval.interm).line = (yylsp[(2) - (2)]);
     }
     break;
 
@@ -2784,24 +2794,24 @@
 
   case 33:
 
-    { (yyval.interm).line = (yylsp[(1) - (1)]); (yyval.interm).op = EOpNull; }
+    { (yyval.interm).op = EOpNull; }
     break;
 
   case 34:
 
-    { (yyval.interm).line = (yylsp[(1) - (1)]); (yyval.interm).op = EOpNegative; }
+    { (yyval.interm).op = EOpNegative; }
     break;
 
   case 35:
 
-    { (yyval.interm).line = (yylsp[(1) - (1)]); (yyval.interm).op = EOpLogicalNot; }
+    { (yyval.interm).op = EOpLogicalNot; }
     break;
 
   case 36:
 
     {
         ES3_ONLY("~", (yylsp[(1) - (1)]), "bit-wise operator");
-        (yyval.interm).line = (yylsp[(1) - (1)]); (yyval.interm).op = EOpBitwiseNot;
+        (yyval.interm).op = EOpBitwiseNot;
     }
     break;
 
@@ -3030,63 +3040,68 @@
 
   case 71:
 
-    {                                    (yyval.interm).line = (yylsp[(1) - (1)]); (yyval.interm).op = EOpAssign; }
+    {                           (yyval.interm).op = EOpAssign; }
     break;
 
   case 72:
 
-    { FRAG_VERT_ONLY("*=", (yylsp[(1) - (1)]));     (yyval.interm).line = (yylsp[(1) - (1)]); (yyval.interm).op = EOpMulAssign; }
+    { FRAG_VERT_ONLY("*=", (yylsp[(1) - (1)])); (yyval.interm).op = EOpMulAssign; }
     break;
 
   case 73:
 
-    { FRAG_VERT_ONLY("/=", (yylsp[(1) - (1)]));     (yyval.interm).line = (yylsp[(1) - (1)]); (yyval.interm).op = EOpDivAssign; }
+    { FRAG_VERT_ONLY("/=", (yylsp[(1) - (1)])); (yyval.interm).op = EOpDivAssign; }
     break;
 
   case 74:
 
     { ES3_ONLY("%=", (yylsp[(1) - (1)]), "integer modulus operator");
-                     FRAG_VERT_ONLY("%=", (yylsp[(1) - (1)]));     (yyval.interm).line = (yylsp[(1) - (1)]); (yyval.interm).op = EOpIModAssign; }
+                     FRAG_VERT_ONLY("%=", (yylsp[(1) - (1)])); (yyval.interm).op = EOpIModAssign; }
     break;
 
   case 75:
 
-    {                                    (yyval.interm).line = (yylsp[(1) - (1)]); (yyval.interm).op = EOpAddAssign; }
+    {                           (yyval.interm).op = EOpAddAssign; }
     break;
 
   case 76:
 
-    {                                    (yyval.interm).line = (yylsp[(1) - (1)]); (yyval.interm).op = EOpSubAssign; }
+    {                           (yyval.interm).op = EOpSubAssign; }
     break;
 
   case 77:
 
     { ES3_ONLY("<<=", (yylsp[(1) - (1)]), "bit-wise operator");
-                     FRAG_VERT_ONLY("<<=", (yylsp[(1) - (1)]));    (yyval.interm).line = (yylsp[(1) - (1)]); (yyval.interm).op = EOpBitShiftLeftAssign; }
+                     FRAG_VERT_ONLY("<<=", (yylsp[(1) - (1)]));
+                     (yyval.interm).op = EOpBitShiftLeftAssign; }
     break;
 
   case 78:
 
     { ES3_ONLY(">>=", (yylsp[(1) - (1)]), "bit-wise operator");
-                     FRAG_VERT_ONLY(">>=", (yylsp[(1) - (1)]));    (yyval.interm).line = (yylsp[(1) - (1)]); (yyval.interm).op = EOpBitShiftRightAssign; }
+                     FRAG_VERT_ONLY(">>=", (yylsp[(1) - (1)]));
+                     (yyval.interm).op = EOpBitShiftRightAssign; }
     break;
 
   case 79:
 
     { ES3_ONLY("&=", (yylsp[(1) - (1)]), "bit-wise operator");
-                     FRAG_VERT_ONLY("&=", (yylsp[(1) - (1)]));     (yyval.interm).line = (yylsp[(1) - (1)]); (yyval.interm).op = EOpBitwiseAndAssign; }
+                     FRAG_VERT_ONLY("&=", (yylsp[(1) - (1)]));
+                     (yyval.interm).op = EOpBitwiseAndAssign; }
     break;
 
   case 80:
 
     { ES3_ONLY("^=", (yylsp[(1) - (1)]), "bit-wise operator");
-                     FRAG_VERT_ONLY("^=", (yylsp[(1) - (1)]));     (yyval.interm).line = (yylsp[(1) - (1)]); (yyval.interm).op = EOpBitwiseXorAssign; }
+                     FRAG_VERT_ONLY("^=", (yylsp[(1) - (1)]));
+                     (yyval.interm).op = EOpBitwiseXorAssign; }
     break;
 
   case 81:
 
     { ES3_ONLY("|=", (yylsp[(1) - (1)]), "bit-wise operator");
-                     FRAG_VERT_ONLY("|=", (yylsp[(1) - (1)]));     (yyval.interm).line = (yylsp[(1) - (1)]); (yyval.interm).op = EOpBitwiseOrAssign; }
+                     FRAG_VERT_ONLY("|=", (yylsp[(1) - (1)]));
+                     (yyval.interm).op = EOpBitwiseOrAssign; }
     break;
 
   case 82:
@@ -3241,7 +3256,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 = (yylsp[(2) - (2)]);
 
         // We're at the inner scope level of the function's arguments and body statement.
         // Add the function prototype to the surrounding scope instead.
@@ -3328,7 +3342,6 @@
         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 = (yylsp[(2) - (2)]);
         (yyval.interm).param = param;
     }
     break;
@@ -3350,7 +3363,6 @@
 
         TType* type = new TType((yyvsp[(1) - (5)].interm.type));
         TParameter param = { (yyvsp[(2) - (5)].lex).string, type };
-        (yyval.interm).line = (yylsp[(2) - (5)]);
         (yyval.interm).param = param;
     }
     break;
@@ -3662,7 +3674,6 @@
 
     {
         (yyval.interm.type).qualifier = EvqConstExpr;
-		(yyval.interm.type).line = (yylsp[(1) - (1)]);
     }
     break;
 
@@ -3671,7 +3682,6 @@
     {
         ES3_ONLY("in", (yylsp[(1) - (1)]), "storage qualifier");
         (yyval.interm.type).qualifier = (context->getShaderType() == GL_FRAGMENT_SHADER) ? EvqFragmentIn : EvqVertexIn;
-		(yyval.interm.type).line = (yylsp[(1) - (1)]);
     }
     break;
 
@@ -3680,7 +3690,6 @@
     {
         ES3_ONLY("out", (yylsp[(1) - (1)]), "storage qualifier");
         (yyval.interm.type).qualifier = (context->getShaderType() == GL_FRAGMENT_SHADER) ? EvqFragmentOut : EvqVertexOut;
-		(yyval.interm.type).line = (yylsp[(1) - (1)]);
     }
     break;
 
@@ -3694,7 +3703,6 @@
             context->recover();
         }
         (yyval.interm.type).qualifier = (context->getShaderType() == GL_FRAGMENT_SHADER) ? EvqCentroidIn : EvqVertexIn;
-		(yyval.interm.type).line = (yylsp[(2) - (2)]);
     }
     break;
 
@@ -3708,7 +3716,6 @@
             context->recover();
         }
         (yyval.interm.type).qualifier = (context->getShaderType() == GL_FRAGMENT_SHADER) ? EvqFragmentOut : EvqCentroidOut;
-		(yyval.interm.type).line = (yylsp[(2) - (2)]);
     }
     break;
 
@@ -3718,7 +3725,6 @@
         if (context->globalErrorCheck((yylsp[(1) - (1)]), context->symbolTable.atGlobalLevel(), "uniform"))
             context->recover();
         (yyval.interm.type).qualifier = EvqUniform;
-		(yyval.interm.type).line = (yylsp[(1) - (1)]);
     }
     break;
 
@@ -4488,14 +4494,14 @@
   case 235:
 
     {
-        (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 236:
 
     {
-        (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;
 
@@ -4723,7 +4729,7 @@
   case 266:
 
     {
-        (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->setTreeRoot((yyval.interm.intermNode));
     }
     break;
@@ -4841,7 +4847,7 @@
             context->recover();
         }
         
-        (yyval.interm.intermNode) = context->intermediate.growAggregate((yyvsp[(1) - (3)].interm).intermAggregate, (yyvsp[(3) - (3)].interm.intermNode), 0);
+        (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());
diff --git a/src/OpenGL/compiler/glslang_tab.h b/src/OpenGL/compiler/glslang_tab.h
index 869a237..6ec4a67 100644
--- a/src/OpenGL/compiler/glslang_tab.h
+++ b/src/OpenGL/compiler/glslang_tab.h
@@ -183,7 +183,6 @@
 
 
     struct {
-        TSourceLoc line;
         union {
             TString *string;
             float f;
@@ -194,7 +193,6 @@
         TSymbol* symbol;
     } lex;
     struct {
-        TSourceLoc line;
         TOperator op;
         union {
             TIntermNode* intermNode;
diff --git a/src/OpenGL/compiler/intermediate.h b/src/OpenGL/compiler/intermediate.h
index 7a65056..99d126d 100644
--- a/src/OpenGL/compiler/intermediate.h
+++ b/src/OpenGL/compiler/intermediate.h
@@ -252,10 +252,16 @@
 public:
     POOL_ALLOCATOR_NEW_DELETE();
 
-    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;
+    }
 
-    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; }
@@ -496,7 +502,7 @@
 //
 class TIntermAggregate : public TIntermOperator {
 public:
-    TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), endLine(0) { }
+    TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false) { endLine = { 0, 0, 0, 0 }; }
     TIntermAggregate(TOperator o) : TIntermOperator(o) { }
     ~TIntermAggregate() { }
 
@@ -516,8 +522,8 @@
     void setDebug(bool d) { debug = d; }
     bool getDebug() { return debug; }
 
-    void setEndLine(TSourceLoc line) { endLine = line; }
-    TSourceLoc getEndLine() const { return endLine; }
+    void setEndLine(const TSourceLoc& line) { endLine = line; }
+    const TSourceLoc& getEndLine() const { return endLine; }
 
 protected:
     TIntermAggregate(const TIntermAggregate&); // disallow copy constructor
diff --git a/src/OpenGL/compiler/localintermediate.h b/src/OpenGL/compiler/localintermediate.h
index 9e7b48e..e9831a4 100644
--- a/src/OpenGL/compiler/localintermediate.h
+++ b/src/OpenGL/compiler/localintermediate.h
@@ -23,26 +23,26 @@
     POOL_ALLOCATOR_NEW_DELETE();
 
     TIntermediate(TInfoSink& i) : infoSink(i) { }
-    TIntermSymbol* addSymbol(int Id, const TString&, const TType&, TSourceLoc);
-    TIntermTyped* addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc);
-    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);
-    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);
+    TIntermSymbol* addSymbol(int Id, const TString&, const TType&, const TSourceLoc&);
+    TIntermTyped* addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc&);
+    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&);
+    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&);
     TIntermSwitch *addSwitch(TIntermTyped *init, TIntermAggregate *statementList, const TSourceLoc &line);
     TIntermCase *addCase(TIntermTyped *condition, const TSourceLoc &line);
-    TIntermTyped* addComma(TIntermTyped* left, TIntermTyped* right, TSourceLoc);
-    TIntermConstantUnion* addConstantUnion(ConstantUnion*, const TType&, 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, 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, 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 outputTree(TIntermNode*);
     
diff --git a/src/OpenGL/compiler/parseConst.cpp b/src/OpenGL/compiler/parseConst.cpp
index 43e5c21..f141f54 100644
--- a/src/OpenGL/compiler/parseConst.cpp
+++ b/src/OpenGL/compiler/parseConst.cpp
@@ -228,7 +228,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, TType t, bool singleConstantParam)
+bool TIntermediate::parseConstTree(const TSourceLoc& line, TIntermNode* root, ConstantUnion* unionArray, TOperator constructorType, TType t, bool singleConstantParam)
 {
     if (root == 0)
         return false;