Index: src/Common/SemanticError.cc
===================================================================
--- src/Common/SemanticError.cc	(revision eafb0940a4d0710ce0168718144c5d75bd21e5fa)
+++ src/Common/SemanticError.cc	(revision 294647bb36b8887ef83cb50ce4390321fab6d613)
@@ -34,5 +34,7 @@
 
 void SemanticError::append( const std::string & msg ) {
-  errors.push_back( std::string( "Error: ") + msg );
+  using std::to_string;
+  const std::string loc = location.linenumber >= 0 ? "At \"" + to_string(location) + "\" " : "";
+  errors.push_back( loc + "Error: " + msg );
 }
 
@@ -45,4 +47,12 @@
 }
 
+void SemanticError::set_location( const CodeLocation& location ) {
+  this->location = location;
+  using std::to_string;
+  const std::string loc = location.linenumber >= 0 ? "At \"" + to_string(location) + "\" " : "";
+  auto& error = *errors.begin();
+  error.insert( 0, loc.c_str());
+}
+
 // Local Variables: //
 // tab-width: 4 //
Index: src/Common/SemanticError.h
===================================================================
--- src/Common/SemanticError.h	(revision eafb0940a4d0710ce0168718144c5d75bd21e5fa)
+++ src/Common/SemanticError.h	(revision 294647bb36b8887ef83cb50ce4390321fab6d613)
@@ -23,4 +23,6 @@
 #include <iostream>
 
+#include "utility.h"
+
 class SemanticError : public std::exception {
   public:
@@ -35,8 +37,10 @@
 	void print( std::ostream &os );
 
+	void set_location( const CodeLocation& location );
 	// constructs an exception using the given message and the printed
 	// representation of the obj (T must have a print method)
   private:
 	std::list< std::string > errors;
+	CodeLocation location;
 };
 
Index: src/Common/utility.h
===================================================================
--- src/Common/utility.h	(revision eafb0940a4d0710ce0168718144c5d75bd21e5fa)
+++ src/Common/utility.h	(revision 294647bb36b8887ef83cb50ce4390321fab6d613)
@@ -25,6 +25,6 @@
 #include <sstream>
 #include <string>
+
 #include <cassert>
-
 template< typename T >
 static inline T * maybeClone( const T *orig ) {
@@ -303,4 +303,23 @@
 	return group_iterate_t<Args...>(args...);
 }
+
+struct CodeLocation {
+	int linenumber;
+	std::string filename;
+
+	CodeLocation() 
+		: linenumber( -1 )
+		, filename("")
+	{}
+
+	CodeLocation( const char* filename, int lineno )
+		: linenumber( lineno )
+		, filename(filename ? filename : "")
+	{}
+};
+
+inline std::string to_string( const CodeLocation& location ) {
+	return location.filename + ":" + std::to_string(location.linenumber);
+}
 #endif // _UTILITY_H
 
Index: src/Parser/DeclarationNode.cc
===================================================================
--- src/Parser/DeclarationNode.cc	(revision eafb0940a4d0710ce0168718144c5d75bd21e5fa)
+++ src/Parser/DeclarationNode.cc	(revision 294647bb36b8887ef83cb50ce4390321fab6d613)
@@ -921,4 +921,5 @@
 				Declaration * decl = extr->build();
 				if ( decl ) {
+					decl->location = cur->location;
 					* out++ = decl;
 				} // if
@@ -928,7 +929,9 @@
 			Declaration * decl = cur->build();
 			if ( decl ) {
+				decl->location = cur->location;
 				* out++ = decl;
 			} // if
 		} catch( SemanticError &e ) {
+			e.set_location( cur->location );
 			errors.append( e );
 		} // try
@@ -950,15 +953,21 @@
 			if ( decl ) {
 				if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) {
+					dwt->location = cur->location;
 					* out++ = dwt;
 				} else if ( StructDecl * agg = dynamic_cast< StructDecl * >( decl ) ) {
 					StructInstType * inst = new StructInstType( Type::Qualifiers(), agg->get_name() );
-					* out++ = new ObjectDecl( "", DeclarationNode::NoStorageClass, linkage, nullptr, inst, nullptr );
+					auto obj = new ObjectDecl( "", DeclarationNode::NoStorageClass, linkage, nullptr, inst, nullptr );
+					obj->location = cur->location;
+					* out++ = obj; 
 					delete agg;
 				} else if ( UnionDecl * agg = dynamic_cast< UnionDecl * >( decl ) ) {
 					UnionInstType * inst = new UnionInstType( Type::Qualifiers(), agg->get_name() );
-					* out++ = new ObjectDecl( "", DeclarationNode::NoStorageClass, linkage, nullptr, inst, nullptr );
+					auto obj = new ObjectDecl( "", DeclarationNode::NoStorageClass, linkage, nullptr, inst, nullptr );
+					obj->location = cur->location;
+					* out++ = obj;
 				} // if
 			} // if
 		} catch( SemanticError &e ) {
+			e.set_location( cur->location );
 			errors.append( e );
 		} // try
Index: src/Parser/ParseNode.h
===================================================================
--- src/Parser/ParseNode.h	(revision eafb0940a4d0710ce0168718144c5d75bd21e5fa)
+++ src/Parser/ParseNode.h	(revision 294647bb36b8887ef83cb50ce4390321fab6d613)
@@ -39,4 +39,7 @@
 //##############################################################################
 
+extern char* yyfilename;
+extern int yylineno;
+
 class ParseNode {
   public:
@@ -65,4 +68,5 @@
 	ParseNode * next = nullptr;
 	std::string * name = nullptr;
+	CodeLocation location = { yyfilename, yylineno };
 }; // ParseNode
 
@@ -410,10 +414,11 @@
 	while ( cur ) {
 		try {
-//			SynTreeType * result = dynamic_cast< SynTreeType * >( maybeBuild< typename std::result_of< decltype(&NodeType::build)(NodeType)>::type >( cur ) );
 			SynTreeType * result = dynamic_cast< SynTreeType * >( maybeBuild< typename std::pointer_traits< decltype(cur->build())>::element_type >( cur ) );
 			if ( result ) {
+				result->location = cur->location;
 				* out++ = result;
 			} // if
 		} catch( SemanticError &e ) {
+			e.set_location( cur->location );
 			errors.append( e );
 		} // try
Index: src/SynTree/BaseSyntaxNode.h
===================================================================
--- src/SynTree/BaseSyntaxNode.h	(revision 294647bb36b8887ef83cb50ce4390321fab6d613)
+++ src/SynTree/BaseSyntaxNode.h	(revision 294647bb36b8887ef83cb50ce4390321fab6d613)
@@ -0,0 +1,32 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// BaseSyntaxNode.h --
+//
+// Author           : Thierry Delisle
+// Created On       : Tue Feb 14 07:44:20 2017
+// Last Modified By :
+// Last Modified On :
+// Update Count     :
+//
+
+#ifndef BASE_SYNTAX_NODE_H
+#define BASE_SYNTAX_NODE_H
+
+#include "Common/utility.h"
+
+class BaseSyntaxNode {
+  public:
+	CodeLocation location;
+};
+
+#endif // BASE_SYNTAX_NODE_H
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/SynTree/Declaration.h
===================================================================
--- src/SynTree/Declaration.h	(revision eafb0940a4d0710ce0168718144c5d75bd21e5fa)
+++ src/SynTree/Declaration.h	(revision 294647bb36b8887ef83cb50ce4390321fab6d613)
@@ -17,12 +17,14 @@
 #define DECLARATION_H
 
+#include <string>
+
+#include "BaseSyntaxNode.h"
+#include "Mutator.h"
+#include "Visitor.h"
 #include "SynTree.h"
-#include "Visitor.h"
-#include "Mutator.h"
 #include "Parser/LinkageSpec.h"
 #include "Parser/ParseNode.h"
-#include <string>
-
-class Declaration {
+
+class Declaration : public BaseSyntaxNode {
   public:
 	Declaration( const std::string &name, DeclarationNode::StorageClass sc, LinkageSpec::Spec linkage );
Index: src/SynTree/Expression.h
===================================================================
--- src/SynTree/Expression.h	(revision eafb0940a4d0710ce0168718144c5d75bd21e5fa)
+++ src/SynTree/Expression.h	(revision 294647bb36b8887ef83cb50ce4390321fab6d613)
@@ -19,12 +19,14 @@
 #include <map>
 #include <memory>
+
+#include "BaseSyntaxNode.h"
+#include "Constant.h"
+#include "Mutator.h"
 #include "SynTree.h"
 #include "Visitor.h"
-#include "Mutator.h"
-#include "Constant.h"
 #include "Common/UniqueName.h"
 
 /// Expression is the root type for all expressions
-class Expression {
+class Expression : public BaseSyntaxNode{
   public:
 	Expression( Expression * _aname = nullptr );
Index: src/SynTree/Initializer.h
===================================================================
--- src/SynTree/Initializer.h	(revision eafb0940a4d0710ce0168718144c5d75bd21e5fa)
+++ src/SynTree/Initializer.h	(revision 294647bb36b8887ef83cb50ce4390321fab6d613)
@@ -17,15 +17,16 @@
 #define INITIALIZER_H
 
+#include <cassert>
+
+#include "BaseSyntaxNode.h"
+#include "Mutator.h"
 #include "SynTree.h"
+#include "Type.h"
 #include "Visitor.h"
-#include "Mutator.h"
-#include "Type.h"
-
-#include <cassert>
 
 const std::list<Expression*> noDesignators;
 
 // Initializer: base class for object initializers (provide default values)
-class Initializer {
+class Initializer : public BaseSyntaxNode {
   public:
 	//	Initializer( std::string _name = std::string(""), int _pos = 0 );
Index: src/SynTree/Statement.h
===================================================================
--- src/SynTree/Statement.h	(revision eafb0940a4d0710ce0168718144c5d75bd21e5fa)
+++ src/SynTree/Statement.h	(revision 294647bb36b8887ef83cb50ce4390321fab6d613)
@@ -17,12 +17,13 @@
 #define STATEMENT_H
 
+#include "BaseSyntaxNode.h"
+#include "Label.h"
+#include "Mutator.h"
 #include "SynTree.h"
+#include "Type.h"
 #include "Visitor.h"
-#include "Mutator.h"
 #include "Common/SemanticError.h"
-#include "Type.h"
-#include "Label.h"
-
-class Statement {
+
+class Statement : public BaseSyntaxNode {
   public:
 	Statement( std::list<Label> labels );
