Index: src/Common/SemanticError.h
===================================================================
--- src/Common/SemanticError.h	(revision d48e529cc868a651ee3760fbd3cf7b1570a205b4)
+++ src/Common/SemanticError.h	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
@@ -24,24 +24,23 @@
 #include "CodeLocation.h"								// for CodeLocation, toString
 
+//-----------------------------------------------------------------------------
+// Errors
 struct error {
+	CodeLocation location;
 	std::string description;
-	CodeLocation location;
 
 	error() = default;
-	error( const std::string & str ) : description( str ) {}
-
-	void maybeSet( const CodeLocation & location ) {
-		if( this->location.isUnset() ) {
-			this->location = location;
-		}
-	}
+	error( CodeLocation loc, const std::string & str ) : location( loc ), description( str ) {}
 };
 
 class SemanticError : public std::exception {
   public:
-	SemanticError();
-	SemanticError( std::string error );
-	template< typename T > SemanticError( const std::string & error, const T * obj );
+  	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() {
@@ -51,11 +50,7 @@
 
 	void append( SemanticError & other );
-	void append( const std::string & );
+	void append( CodeLocation location, const std::string & );
 	bool isEmpty() const;
-	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)
+	void print();
   private:
 	std::list< error > errors;
@@ -63,6 +58,68 @@
 
 template< typename T >
-SemanticError::SemanticError( const std::string & error, const T * obj ) {
-	append( toString( error, obj ) );
+SemanticError::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 ) )
+{}
+
+//-----------------------------------------------------------------------------
+// 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);
+
+	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 ) )
+{}
+
+template< typename T >
+SemanticWarning::SemanticWarning( CodeLocation location, const T * obj, const std::string & error )
+	: SemanticWarning( location, toString( error, obj ) )
+{}
+
+//-----------------------------------------------------------------------------
+// Helpers
+static inline const std::string & bold_ttycode() {
+	static std::string str = isatty( STDERR_FILENO ) ? "\e[1m" : "";
+	return str;
+}
+
+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;
 }
 
