Index: src/CodeGen/CodeGenerator.cc
===================================================================
--- src/CodeGen/CodeGenerator.cc	(revision 4e8949f3e86a781045a82d44c0fd4e0469048937)
+++ src/CodeGen/CodeGenerator.cc	(revision d48e529cc868a651ee3760fbd3cf7b1570a205b4)
@@ -89,10 +89,10 @@
 		} else if ( currentLocation.followedBy( to, 1 ) ) {
 			output << "\n" << indent;
-			currentLocation.linenumber += 1;
+			currentLocation.first_line += 1;
 		} else if ( currentLocation.followedBy( to, 2 ) ) {
 			output << "\n\n" << indent;
-			currentLocation.linenumber += 2;
-		} else {
-			output << "\n# " << to.linenumber << " \"" << to.filename
+			currentLocation.first_line += 2;
+		} else {
+			output << "\n# " << to.first_line << " \"" << to.filename
 			       << "\"\n" << indent;
 			currentLocation = to;
Index: src/Common/CodeLocation.h
===================================================================
--- src/Common/CodeLocation.h	(revision 4e8949f3e86a781045a82d44c0fd4e0469048937)
+++ src/Common/CodeLocation.h	(revision d48e529cc868a651ee3760fbd3cf7b1570a205b4)
@@ -20,16 +20,13 @@
 
 struct CodeLocation {
-	int linenumber;
-	std::string filename;
+	int first_line = -1, first_column = -1, last_line = -1, last_column = -1;
+	std::string filename = "";
 
 	/// Create a new unset CodeLocation.
-		CodeLocation()
-		: linenumber( -1 )
-		, filename("")
-	{}
+	CodeLocation() = default;
 
 	/// Create a new CodeLocation with the given values.
 	CodeLocation( const char* filename, int lineno )
-		: linenumber( lineno )
+		: first_line( lineno )
 		, filename(filename ? filename : "")
 	{}
@@ -38,5 +35,5 @@
 
 	bool isSet () const {
-		return -1 != linenumber;
+		return -1 != first_line;
 	}
 
@@ -46,5 +43,5 @@
 
 	bool followedBy( CodeLocation const & other, int seperation ) {
-		return (linenumber + seperation == other.linenumber &&
+		return (first_line + seperation == other.first_line &&
 		        filename == other.filename);
 	}
@@ -61,4 +58,4 @@
 inline std::ostream & operator<<( std::ostream & out, const CodeLocation & location ) {
 	// Column number ":1" allows IDEs to parse the error message and position the cursor in the source text.
-	return location.isSet() ? out << location.filename << ":" << location.linenumber << ":1 " : out;
+	return location.isSet() ? out << location.filename << ":" << location.first_line << ":1 " : out;
 }
Index: src/Common/SemanticError.h
===================================================================
--- src/Common/SemanticError.h	(revision 4e8949f3e86a781045a82d44c0fd4e0469048937)
+++ src/Common/SemanticError.h	(revision d48e529cc868a651ee3760fbd3cf7b1570a205b4)
@@ -32,5 +32,5 @@
 
 	void maybeSet( const CodeLocation & location ) {
-		if( this->location.linenumber < 0 ) {
+		if( this->location.isUnset() ) {
 			this->location = location;
 		}
Index: src/ControlStruct/ExceptTranslate.cc
===================================================================
--- src/ControlStruct/ExceptTranslate.cc	(revision 4e8949f3e86a781045a82d44c0fd4e0469048937)
+++ src/ControlStruct/ExceptTranslate.cc	(revision d48e529cc868a651ee3760fbd3cf7b1570a205b4)
@@ -622,5 +622,5 @@
 				assertf(false, "Invalid throw in %s at %i\n",
 					throwStmt->location.filename.c_str(),
-					throwStmt->location.linenumber);
+					throwStmt->location.first_line);
 				return nullptr;
 			}
@@ -633,5 +633,5 @@
 				assertf(false, "Invalid throwResume in %s at %i\n",
 					throwStmt->location.filename.c_str(),
-					throwStmt->location.linenumber);
+					throwStmt->location.first_line);
 				return nullptr;
 			}
Index: src/Parser/ParseNode.h
===================================================================
--- src/Parser/ParseNode.h	(revision 4e8949f3e86a781045a82d44c0fd4e0469048937)
+++ src/Parser/ParseNode.h	(revision d48e529cc868a651ee3760fbd3cf7b1570a205b4)
@@ -44,6 +44,10 @@
 //##############################################################################
 
+typedef CodeLocation YYLTYPE;
+#define YYLTYPE_IS_DECLARED 1 /* alert the parser that we have our own definition */
+
 extern char * yyfilename;
 extern int yylineno;
+extern YYLTYPE yylloc;
 
 class ParseNode {
@@ -73,5 +77,5 @@
 	ParseNode * next = nullptr;
 	std::string * name = nullptr;
-	CodeLocation location = { yyfilename, yylineno };
+	CodeLocation location = yylloc;
 }; // ParseNode
 
Index: src/Parser/lex.ll
===================================================================
--- src/Parser/lex.ll	(revision 4e8949f3e86a781045a82d44c0fd4e0469048937)
+++ src/Parser/lex.ll	(revision d48e529cc868a651ee3760fbd3cf7b1570a205b4)
@@ -26,5 +26,5 @@
 
 unsigned int column = 0;								// position of the end of the last token parsed
-#define YY_USER_ACTION column += yyleng;				// trigger before each matching rule's action
+#define YY_USER_ACTION yylloc.first_line = yylineno; yylloc.first_column = column; column += yyleng; yylloc.last_column = column; yylloc.last_line = yylineno; yylloc.filename = yyfilename ? yyfilename : "";				// trigger before each matching rule's action
 
 #include <string>
Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision 4e8949f3e86a781045a82d44c0fd4e0469048937)
+++ src/Parser/parser.yy	(revision d48e529cc868a651ee3760fbd3cf7b1570a205b4)
@@ -116,4 +116,21 @@
 
 bool forall = false;									// aggregate have one or more forall qualifiers ?
+
+# define YYLLOC_DEFAULT(Cur, Rhs, N)                            \
+do                                                              \
+	if (N) {                                                      \
+		(Cur).first_line   = YYRHSLOC(Rhs, 1).first_line;           \
+		(Cur).first_column = YYRHSLOC(Rhs, 1).first_column;         \
+		(Cur).last_line    = YYRHSLOC(Rhs, N).last_line;            \
+		(Cur).last_column  = YYRHSLOC(Rhs, N).last_column;          \
+		(Cur).filename     = YYRHSLOC(Rhs, 1).filename;             \
+	} else {                                                      \
+		(Cur).first_line   = (Cur).last_line   =                    \
+			YYRHSLOC(Rhs, 0).last_line;                               \
+		(Cur).first_column = (Cur).last_column =                    \
+			YYRHSLOC(Rhs, 0).last_column;                             \
+		(Cur).filename     = YYRHSLOC(Rhs, 0).filename;             \
+	}                                                             \
+while (0)
 %}
 
@@ -346,4 +363,5 @@
 %precedence ELSE	// token precedence for start of else clause in IF/WAITFOR statement
 
+%locations
 
 %start translation_unit									// parse-tree root
