Index: src/Common/ErrorObjects.h
===================================================================
--- src/Common/ErrorObjects.h	(revision 1f37ed02cc74c64f4e7f522e805e7b6fba4e51ee)
+++ src/Common/ErrorObjects.h	(revision 1f37ed02cc74c64f4e7f522e805e7b6fba4e51ee)
@@ -0,0 +1,59 @@
+//
+// 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.
+//
+// ErrorObjects.h --
+//
+// Author           : Thierry Delisle
+// Created On       : Wed Feb 28 15:16:47 2018
+// Last Modified By :
+// Last Modified On :
+// Update Count     :
+//
+
+#pragma once
+
+
+#include <exception>	// for exception
+#include <iostream>	// for ostream
+#include <list>		// for list
+#include <string>		// for string
+#include <unistd.h>	// for isatty
+
+#include "CodeLocation.h"								// for CodeLocation, toString
+
+struct error {
+	CodeLocation location;
+	std::string description;
+
+	error() = default;
+	error( CodeLocation loc, const std::string & str ) : location( loc ), description( str ) {}
+};
+
+class SemanticErrorException : public std::exception {
+  public:
+  	SemanticErrorException() = default;
+	SemanticErrorException( CodeLocation location, std::string error );
+	~SemanticErrorException() throw() {}
+
+	void append( SemanticErrorException & other );
+	void append( CodeLocation location, const std::string & );
+	bool isEmpty() const;
+	void print();
+  private:
+	std::list< error > errors;
+};
+
+void SemanticWarningImpl( CodeLocation location, std::string error );
+
+template< typename T >
+static inline void SemanticWarningImpl( const T * obj, const std::string & error ) {
+	SemanticWarning( obj->location, toString( error, obj ) );
+}
+
+template< typename T >
+static inline void SemanticWarningImpl( CodeLocation location, const T * obj, const std::string & error ) {
+	SemanticWarningImpl( location, toString( error, obj ) );
+}
Index: src/Common/PassVisitor.impl.h
===================================================================
--- src/Common/PassVisitor.impl.h	(revision cfaf9beb67593b36a3927861cb7bb364983f7938)
+++ src/Common/PassVisitor.impl.h	(revision 1f37ed02cc74c64f4e7f522e805e7b6fba4e51ee)
@@ -65,5 +65,5 @@
 	DeclList_t* beforeDecls = visitor.get_beforeDecls();
 	DeclList_t* afterDecls  = visitor.get_afterDecls();
-	SemanticError errors;
+	SemanticErrorException errors;
 
 	for ( std::list< Declaration* >::iterator i = decls.begin(); ; ++i ) {
@@ -76,5 +76,5 @@
 			// run visitor on declaration
 			maybeAccept_impl( *i, visitor );
-		} catch( SemanticError &e ) {
+		} catch( SemanticErrorException &e ) {
 			errors.append( e );
 		}
@@ -92,5 +92,5 @@
 	DeclList_t* beforeDecls = mutator.get_beforeDecls();
 	DeclList_t* afterDecls  = mutator.get_afterDecls();
-	SemanticError errors;
+	SemanticErrorException errors;
 
 	for ( std::list< Declaration* >::iterator i = decls.begin(); ; ++i ) {
@@ -102,5 +102,5 @@
 			// run mutator on declaration
 			maybeMutate_impl( *i, mutator );
-		} catch( SemanticError &e ) {
+		} catch( SemanticErrorException &e ) {
 			errors.append( e );
 		}
@@ -125,5 +125,5 @@
 inline void maybeAccept_impl( Container & container, PassVisitor< pass_type > & visitor ) {
 	if ( ! visitor.get_visit_children() ) return;
-	SemanticError errors;
+	SemanticErrorException errors;
 	for ( typename Container::iterator i = container.begin(); i != container.end(); ++i ) {
 		try {
@@ -131,5 +131,5 @@
 				(*i)->accept( visitor );
 			}
-		} catch( SemanticError &e ) {
+		} catch( SemanticErrorException &e ) {
 			errors.append( e );
 		}
@@ -152,5 +152,5 @@
 inline void maybeMutate_impl( Container & container, PassVisitor< pass_type > & mutator ) {
 	if ( ! mutator.get_visit_children() ) return;
-	SemanticError errors;
+	SemanticErrorException errors;
 	for ( typename Container::iterator i = container.begin(); i != container.end(); ++i ) {
 		try {
@@ -159,5 +159,5 @@
 				assert( *i );
 			} // if
-		} catch( SemanticError &e ) {
+		} catch( SemanticErrorException &e ) {
 			errors.append( e );
 		} // try
@@ -172,5 +172,5 @@
 void PassVisitor< pass_type >::handleStatementList( std::list< Statement * > & statements, func_t func ) {
 	if ( ! get_visit_children() ) return;
-	SemanticError errors;
+	SemanticErrorException errors;
 
 	// don't want statements from outer CompoundStmts to be added to this CompoundStmt
@@ -195,5 +195,5 @@
 			    || ( empty( beforeDecls ) && empty( afterDecls )) );
 
-		} catch ( SemanticError &e ) {
+		} catch ( SemanticErrorException &e ) {
 			errors.append( e );
 		}
Index: src/Common/SemanticError.cc
===================================================================
--- src/Common/SemanticError.cc	(revision cfaf9beb67593b36a3927861cb7bb364983f7938)
+++ src/Common/SemanticError.cc	(revision 1f37ed02cc74c64f4e7f522e805e7b6fba4e51ee)
@@ -23,29 +23,71 @@
 #include "SemanticError.h"
 
-SemanticError::SemanticError( CodeLocation location, std::string error ) {
+SemanticErrorException::SemanticErrorException( CodeLocation location, std::string error ) {
 	append( location, error );
 }
 
-void SemanticError::append( SemanticError &other ) {
+void SemanticErrorException::append( SemanticErrorException &other ) {
 	errors.splice( errors.end(), other.errors );
 }
 
-void SemanticError::append( CodeLocation location, const std::string & msg ) {
+void SemanticErrorException::append( CodeLocation location, const std::string & msg ) {
 	errors.emplace_back( location, msg );
 }
 
-bool SemanticError::isEmpty() const {
+bool SemanticErrorException::isEmpty() const {
 	return errors.empty();
 }
 
-void SemanticError::print() {
+void SemanticErrorException::print() {
 	using std::to_string;
 	for( auto err : errors ) {
-		std::cerr << bold() << err.location << error_str() << reset_font() << err.description << std::endl;
+		std::cerr << ErrorHelpers::bold() << err.location << ErrorHelpers::error_str() << ErrorHelpers::reset_font() << err.description << std::endl;
 	}
 }
 
-SemanticWarning::SemanticWarning( CodeLocation location, std::string msg ) {
-	std::cerr << bold() << location << warning_str() << reset_font() << msg << std::endl;
+void SemanticError( CodeLocation location, std::string error ) {
+	throw SemanticErrorException(location, error);
+}
+
+void SemanticWarningImpl( CodeLocation location, std::string msg ) {
+	std::cerr << ErrorHelpers::bold() << location << ErrorHelpers::warning_str() << ErrorHelpers::reset_font() << msg << std::endl;
+}
+
+//-----------------------------------------------------------------------------
+// Helpers
+namespace ErrorHelpers {
+	const std::string & error_str() {
+		static std::string str = isatty( STDERR_FILENO ) ? "\e[31merror:\e[39m " : "error: ";
+		return str;
+	}
+
+	const std::string & warning_str() {
+		static std::string str = isatty( STDERR_FILENO ) ? "\e[95mwarning:\e[39m " : "warning: ";
+		return str;
+	}
+
+	const std::string & bold_ttycode() {
+		static std::string str = isatty( STDERR_FILENO ) ? "\e[1m" : "";
+		return str;
+	}
+
+	const std::string & reset_font_ttycode() {
+		static std::string str = isatty( STDERR_FILENO ) ? "\e[0m" : "";
+		return str;
+	}
+
+	std::string make_bold( const std::string & str ) {
+		return bold_ttycode() + str + reset_font_ttycode();
+	}
+
+	std::ostream & operator<<(std::ostream & os, bold) {
+		os << bold_ttycode();
+		return os;
+	}
+
+	std::ostream & operator<<(std::ostream & os, reset_font) {
+		os << reset_font_ttycode();
+		return os;
+	}
 }
 
Index: src/Common/SemanticError.h
===================================================================
--- src/Common/SemanticError.h	(revision cfaf9beb67593b36a3927861cb7bb364983f7938)
+++ src/Common/SemanticError.h	(revision 1f37ed02cc74c64f4e7f522e805e7b6fba4e51ee)
@@ -16,111 +16,61 @@
 #pragma once
 
-#include <exception>									// for exception
-#include <iostream>										// for ostream
-#include <list>											// for list
-#include <string>										// for string
-#include <unistd.h>										// for isatty
-
-#include "CodeLocation.h"								// for CodeLocation, toString
+#include "ErrorObjects.h"
 
 //-----------------------------------------------------------------------------
 // Errors
-struct error {
-	CodeLocation location;
-	std::string description;
 
-	error() = default;
-	error( CodeLocation loc, const std::string & str ) : location( loc ), description( str ) {}
-};
-
-class SemanticError : public std::exception {
-  public:
-  	SemanticError() = default;
-	SemanticError( CodeLocation location, std::string error );
-	~SemanticError() throw() {}
-
-	// constructs an exception using the given message and the printed representation of the obj (T must have a print method)
-	template< typename T > SemanticError(const T * obj, const std::string & error);
-	template< typename T > SemanticError( CodeLocation location, const T * obj, const std::string & error);
-
-	static inline const std::string & error_str() {
-		static std::string str = isatty( STDERR_FILENO ) ? "\e[31merror:\e[39m " : "error: ";
-		return str;
-	}
-
-	void append( SemanticError & other );
-	void append( CodeLocation location, const std::string & );
-	bool isEmpty() const;
-	void print();
-  private:
-	std::list< error > errors;
-};
+__attribute__((noreturn)) void SemanticError( CodeLocation location, std::string error );
 
 template< typename T >
-SemanticError::SemanticError( const T * obj, const std::string & error )
-	: SemanticError( obj->location, toString( error, obj ) )
-{}
+__attribute__((noreturn)) static inline void SemanticError( const T * obj, const std::string & error ) {
+	SemanticError( obj->location, toString( error, obj ) );
+}
 
 template< typename T >
-SemanticError::SemanticError( CodeLocation location, const T * obj, const std::string & error )
-	: SemanticError( location, toString( error, obj ) )
-{}
+__attribute__((noreturn)) static inline void SemanticError( CodeLocation location, const T * obj, const std::string & error ) {
+	SemanticError( location, toString( error, obj ) );
+}
 
 //-----------------------------------------------------------------------------
 // Warnings
-class SemanticWarning {
-  public:
-  	SemanticWarning( CodeLocation location, std::string error );
-	~SemanticWarning() throw() {}
 
-	// constructs an exception using the given message and the printed representation of the obj (T must have a print method)
-	template< typename T > SemanticWarning(const T * obj, const std::string & error);
-	template< typename T > SemanticWarning( CodeLocation location, const T * obj, const std::string & error);
+constexpr const char * const WarningFormats[] = {
 
-	static inline const std::string & warning_str() {
-		static std::string str = isatty( STDERR_FILENO ) ? "\e[95mwarning:\e[39m " : "warning: ";
-		return str;
-	}
-
-  private:
 };
 
-template< typename T >
-SemanticWarning::SemanticWarning( const T * obj, const std::string & error )
-	: SemanticWarning( obj->location, toString( error, obj ) )
-{}
+enum class Warning {
+	NUMBER_OF_WARNINGS, //This MUST be the last warning
+};
 
-template< typename T >
-SemanticWarning::SemanticWarning( CodeLocation location, const T * obj, const std::string & error )
-	: SemanticWarning( location, toString( error, obj ) )
-{}
+static_assert(
+	(sizeof(WarningFormats) / sizeof(WarningFormats[0])) == ((unsigned long)Warning::NUMBER_OF_WARNINGS),
+	"Each warning format should have a corresponding warning enum value"
+);
+
+#define SemanticWarning(loc, id, ...) SemanticWarningImpl(loc, id, WarningFormats[id], __VA_ARGS__)
+
+void SemanticWarningImpl (CodeLocation loc, Warning warn, const char * const fmt, ...) __attribute__((format(printf, 3, 4)));
+
 
 //-----------------------------------------------------------------------------
 // Helpers
-static inline const std::string & bold_ttycode() {
-	static std::string str = isatty( STDERR_FILENO ) ? "\e[1m" : "";
-	return str;
+namespace ErrorHelpers {
+	const std::string & error_str();
+	const std::string & warning_str();
+	const std::string & bold_ttycode();
+	const std::string & reset_font_ttycode();
+
+	std::string make_bold( const std::string & str );
+
+	struct bold {};
+	std::ostream & operator<<(std::ostream & os, bold);
+
+	struct reset_font {};
+	std::ostream & operator<<(std::ostream & os, reset_font);
 }
 
-static inline const std::string & reset_font_ttycode() {
-	static std::string str = isatty( STDERR_FILENO ) ? "\e[0m" : "";
-	return str;
-}
 
-static inline std::string make_bold( const std::string & str ) {
-	return bold_ttycode() + str + reset_font_ttycode();
-}
 
-struct bold {};
-static inline std::ostream & operator<<(std::ostream & os, bold) {
-	os << bold_ttycode();
-	return os;
-}
-
-struct reset_font {};
-static inline std::ostream & operator<<(std::ostream & os, reset_font) {
-	os << reset_font_ttycode();
-	return os;
-}
 
 // Local Variables: //
