Index: src/Common/CodeLocation.h
===================================================================
--- src/Common/CodeLocation.h	(revision 234223fb13167c125e360f00a079c2de9c607865)
+++ src/Common/CodeLocation.h	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -9,7 +9,7 @@
 // Author           : Andrew Beach
 // Created On       : Thr Aug 17 11:23:00 2017
-// Last Modified By : Andrew Beach
-// Last Modified On : Thr Aug 17 14:07:00 2017
-// Update Count     : 0
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Mon Aug 28 12:46:01 2017
+// Update Count     : 2
 //
 
@@ -66,5 +66,6 @@
 
 inline std::string to_string( const CodeLocation& location ) {
-    return location.isSet() ? location.filename + ":" + std::to_string(location.linenumber) + " " : "";
+    // Column number ":1" allows IDEs to parse the error message and position the cursor in the source text.
+    return location.isSet() ? location.filename + ":" + std::to_string(location.linenumber) + ":1 " : "";
 }
 
Index: src/Common/Debug.h
===================================================================
--- src/Common/Debug.h	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
+++ src/Common/Debug.h	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -0,0 +1,42 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2017 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// Debug.h --
+//
+// Author           : Rob Schluntz
+// Created On       : Fri Sep 1 11:09:14 2017
+// Last Modified By : Rob Schluntz
+// Last Modified On : Fri Sep 1 11:09:36 2017
+// Update Count     : 2
+//
+
+#pragma once
+
+#include <string>
+#include <list>
+#include <iostream>
+
+#include "CodeGen/Generate.h"
+#include "Parser/LinkageSpec.h"
+#include "SynTree/Declaration.h"
+
+/// debug codegen a translation unit
+static inline void debugCodeGen( const std::list< Declaration * > & translationUnit, const std::string & label ) {
+	std::list< Declaration * > decls;
+
+	filter( translationUnit.begin(), translationUnit.end(), back_inserter( decls ), []( Declaration * decl ) {
+		return ! LinkageSpec::isBuiltin( decl->get_linkage() );
+	});
+
+	std::cerr << "======" << label << "======" << std::endl;
+	CodeGen::generate( decls, std::cerr, false, true );
+} // dump
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/Common/SemanticError.cc
===================================================================
--- src/Common/SemanticError.cc	(revision 234223fb13167c125e360f00a079c2de9c607865)
+++ src/Common/SemanticError.cc	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -10,21 +10,16 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue May 19 07:21:25 2015
-// Update Count     : 1
+// Last Modified On : Tue Aug 29 18:17:35 2017
+// Update Count     : 3
 //
 
-#include <cstdio>            // for fileno, stderr
-#include <unistd.h>          // for isatty
-#include <iostream>          // for basic_ostream, operator<<, ostream
-#include <list>              // for list, _List_iterator
-#include <string>            // for string, operator<<, operator+, to_string
+#include <cstdio>										// for fileno, stderr
+#include <unistd.h>										// for isatty
+#include <iostream>										// for basic_ostream, operator<<, ostream
+#include <list>											// for list, _List_iterator
+#include <string>										// for string, operator<<, operator+, to_string
 
-#include "Common/utility.h"  // for to_string, CodeLocation (ptr only)
+#include "Common/utility.h"								// for to_string, CodeLocation (ptr only)
 #include "SemanticError.h"
-
-inline const std::string& error_str() {
-	static std::string str = isatty( fileno(stderr) ) ? "\e[31merror:\e[39m " : "error: ";
-	return str;
-}
 
 SemanticError::SemanticError() {
@@ -49,6 +44,6 @@
 void SemanticError::print( std::ostream &os ) {
 	using std::to_string;
-	for(auto err : errors) {
-		os << to_string( err.location ) << err.description << '\n';
+	for( auto err : errors ) {
+		os << to_string( err.location ) << err.description << std::endl;
 	}
 }
Index: src/Common/SemanticError.h
===================================================================
--- src/Common/SemanticError.h	(revision 234223fb13167c125e360f00a079c2de9c607865)
+++ src/Common/SemanticError.h	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -9,17 +9,18 @@
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Andrew Beach
-// Last Modified On : Thr Aug 17 14:01:00 2017
-// Update Count     : 7
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Tue Aug 29 22:03:36 2017
+// Update Count     : 17
 //
 
 #pragma once
 
-#include <exception>  // for exception
-#include <iostream>   // for ostream
-#include <list>       // for list
-#include <string>     // for string
+#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 "CodeLocation.h"								// for CodeLocation, toString
 
 struct error {
@@ -28,7 +29,7 @@
 
 	error() = default;
-	error( const std::string& str ) : description( str ) {}
+	error( const std::string & str ) : description( str ) {}
 
-	void maybeSet( const CodeLocation& location ) {
+	void maybeSet( const CodeLocation & location ) {
 		if( this->location.linenumber < 0 ) {
 			this->location = location;
@@ -41,15 +42,20 @@
 	SemanticError();
 	SemanticError( std::string error );
-	template< typename T > SemanticError( const std::string &error, const T *obj );
+	template< typename T > SemanticError( const std::string & error, const T * obj );
 	~SemanticError() throw() {}
 
-	void append( SemanticError &other );
+	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( const std::string & );
 	bool isEmpty() const;
-	void print( std::ostream &os );
+	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 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< error > errors;
@@ -57,5 +63,5 @@
 
 template< typename T >
-SemanticError::SemanticError( const std::string &error, const T *obj ) {
+SemanticError::SemanticError( const std::string & error, const T * obj ) {
 	append( toString( error, obj ) );
 }
Index: src/Common/utility.h
===================================================================
--- src/Common/utility.h	(revision 234223fb13167c125e360f00a079c2de9c607865)
+++ src/Common/utility.h	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -174,4 +174,19 @@
 }
 
+template <typename E, typename UnaryPredicate, template< typename, typename...> class Container, typename... Args >
+void filter( Container< E *, Args... > & container, UnaryPredicate pred, bool doDelete ) {
+	auto i = begin( container );
+	while ( i != end( container ) ) {
+		auto it = next( i );
+		if ( pred( *i ) ) {
+			if ( doDelete ) {
+				delete *i;
+			} // if
+			container.erase( i );
+		} // if
+		i = it;
+	} // while
+}
+
 template< typename... Args >
 auto zip(Args&&... args) -> decltype(zipWith(std::forward<Args>(args)..., std::make_pair)) {
@@ -207,4 +222,11 @@
 	std::cerr << "Warning: ";
 	warn_single( params... );
+}
+
+/// determines if `pref` is a prefix of `str`
+static inline bool isPrefix( const std::string & str, const std::string & pref ) {
+	if ( pref.size() > str.size() ) return false;
+	auto its = std::mismatch( pref.begin(), pref.end(), str.begin() );
+	return its.first == pref.end();
 }
 
