Index: src/Common/CodeLocation.h
===================================================================
--- src/Common/CodeLocation.h	(revision 274ce8c98a0dc1608308c1bd35c41bcd52a1c812)
+++ src/Common/CodeLocation.h	(revision 274ce8c98a0dc1608308c1bd35c41bcd52a1c812)
@@ -0,0 +1,70 @@
+//
+// 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.
+//
+// CodeLocation.h --
+//
+// 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
+//
+
+#pragma once
+
+#include <string>
+
+struct CodeLocation {
+	int linenumber;
+	std::string filename;
+
+	/// Create a new unset CodeLocation.
+		CodeLocation()
+		: linenumber( -1 )
+		, filename("")
+	{}
+
+	/// Create a new CodeLocation with the given values.
+	CodeLocation( const char* filename, int lineno )
+		: linenumber( lineno )
+		, filename(filename ? filename : "")
+	{}
+
+	CodeLocation( const CodeLocation& rhs ) = default;
+
+	bool isSet () const {
+		return -1 != linenumber;
+	}
+
+	bool isUnset () const {
+		return !isSet();
+	}
+
+	void unset () {
+		linenumber = -1;
+		filename = "";
+	}
+
+	// Use field access for set.
+
+	bool followedBy( CodeLocation const & other, int seperation ) {
+		return (linenumber + seperation == other.linenumber &&
+		        filename == other.filename);
+	}
+
+	bool operator==( CodeLocation const & other ) {
+		return followedBy( other, 0 );
+	}
+
+	bool operator!=( CodeLocation const & other ) {
+		return !(*this == other);
+	}
+};
+
+inline std::string to_string( const CodeLocation& location ) {
+    return location.isSet() ? location.filename + ":" + std::to_string(location.linenumber) + " " : "";
+}
+
Index: src/Common/SemanticError.h
===================================================================
--- src/Common/SemanticError.h	(revision 6d49ea3165b7fb8906721da9a6f6949632d35140)
+++ src/Common/SemanticError.h	(revision 274ce8c98a0dc1608308c1bd35c41bcd52a1c812)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Jul 21 22:18:59 2017
-// Update Count     : 6
+// Last Modified By : Andrew Beach
+// Last Modified On : Thr Aug 17 14:01:00 2017
+// Update Count     : 7
 //
 
@@ -21,5 +21,5 @@
 #include <string>     // for string
 
-#include "utility.h"  // for CodeLocation, toString
+#include "CodeLocation.h"  // for CodeLocation, toString
 
 struct error {
Index: src/Common/utility.h
===================================================================
--- src/Common/utility.h	(revision 6d49ea3165b7fb8906721da9a6f6949632d35140)
+++ src/Common/utility.h	(revision 274ce8c98a0dc1608308c1bd35c41bcd52a1c812)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Jul 21 22:19:13 2017
-// Update Count     : 33
+// Last Modified By : Andrew Beach
+// Last Modified On : Thr Aug 17 11:38:00 2017
+// Update Count     : 34
 //
 
@@ -341,42 +341,4 @@
 }
 
-struct CodeLocation {
-	int linenumber;
-	std::string filename;
-
-	/// Create a new unset CodeLocation.
-	CodeLocation()
-		: linenumber( -1 )
-		, filename("")
-	{}
-
-	/// Create a new CodeLocation with the given values.
-	CodeLocation( const char* filename, int lineno )
-		: linenumber( lineno )
-		, filename(filename ? filename : "")
-	{}
-
-	CodeLocation( const CodeLocation& rhs ) = default;
-
-	bool isSet () const {
-		return -1 != linenumber;
-	}
-
-	bool isUnset () const {
-		return !isSet();
-	}
-
-	void unset () {
-		linenumber = -1;
-		filename = "";
-	}
-
-	// Use field access for set.
-};
-
-inline std::string to_string( const CodeLocation& location ) {
-	return location.isSet() ? location.filename + ":" + std::to_string(location.linenumber) + " " : "";
-}
-
 // Local Variables: //
 // tab-width: 4 //
Index: src/ControlStruct/ExceptTranslate.cc
===================================================================
--- src/ControlStruct/ExceptTranslate.cc	(revision 6d49ea3165b7fb8906721da9a6f6949632d35140)
+++ src/ControlStruct/ExceptTranslate.cc	(revision 274ce8c98a0dc1608308c1bd35c41bcd52a1c812)
@@ -10,6 +10,6 @@
 // Created On       : Wed Jun 14 16:49:00 2017
 // Last Modified By : Andrew Beach
-// Last Modified On : Tus Aug  8 16:54:00 2017
-// Update Count     : 7
+// Last Modified On : Thr Aug 17 17:19:00 2017
+// Update Count     : 9
 //
 
@@ -166,5 +166,6 @@
 			/*bitfieldWidth*/ NULL,
 			new BasicType( noQualifiers, BasicType::Bool ),
-			/*init*/ NULL
+			/*init*/ NULL,
+			std::list<Attribute *>{ new Attribute( "unused" ) }
 			);
 		ObjectDecl voidptr_obj(
@@ -183,7 +184,10 @@
 			);
 
+		ObjectDecl * unused_index_obj = index_obj.clone();
+		unused_index_obj->attributes.push_back( new Attribute( "unused" ) );
+
 		catch_func_t.get_parameters().push_back( index_obj.clone() );
 		catch_func_t.get_parameters().push_back( exception_obj.clone() );
-		match_func_t.get_returnVals().push_back( index_obj.clone() );
+		match_func_t.get_returnVals().push_back( unused_index_obj );
 		match_func_t.get_parameters().push_back( exception_obj.clone() );
 		handle_func_t.get_returnVals().push_back( bool_obj.clone() );
@@ -417,6 +421,6 @@
 		}
 
-		body->push_back( new ReturnStmt( noLabels, new ConstantExpr(
-			Constant::from_int( 0 ) ) ) );
+		body->push_back( new ReturnStmt( noLabels,
+			new ConstantExpr( Constant::from_int( 0 ) ) ) );
 
 		return new FunctionDecl("match", Type::StorageClasses(),
@@ -449,5 +453,5 @@
 		CompoundStmt * body = new CompoundStmt( noLabels );
 
-		FunctionType * func_type = match_func_t.clone();
+		FunctionType * func_type = handle_func_t.clone();
 		DeclarationWithType * except_obj = func_type->get_parameters().back();
 
@@ -472,6 +476,6 @@
 		}
 
-		body->push_back( new ReturnStmt( noLabels, new ConstantExpr(
-			Constant::from_bool( false ) ) ) );
+		body->push_back( new ReturnStmt( noLabels,
+			new ConstantExpr( Constant::from_bool( false ) ) ) );
 
 		return new FunctionDecl("handle", Type::StorageClasses(),
Index: src/ControlStruct/LabelGenerator.cc
===================================================================
--- src/ControlStruct/LabelGenerator.cc	(revision 6d49ea3165b7fb8906721da9a6f6949632d35140)
+++ src/ControlStruct/LabelGenerator.cc	(revision 274ce8c98a0dc1608308c1bd35c41bcd52a1c812)
@@ -9,10 +9,11 @@
 // Author           : Rodolfo G. Esteves
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Jun 23 12:18:34 2015
-// Update Count     : 13
+// Last Modified By : Andrew Beach
+// Last Modified On : Thr Aug 14 14:14:00 2015
+// Update Count     : 14
 //
 
-#include <iostream>             // for operator<<, basic_ostream, ostringstream
+#include <iostream>             // for operator<<, basic_ostream
+#include <sstream>              // for ostringstream
 #include <list>                 // for list
 
Index: src/Parser/ParseNode.h
===================================================================
--- src/Parser/ParseNode.h	(revision 6d49ea3165b7fb8906721da9a6f6949632d35140)
+++ src/Parser/ParseNode.h	(revision 274ce8c98a0dc1608308c1bd35c41bcd52a1c812)
@@ -9,7 +9,7 @@
 // Author           : Rodolfo G. Esteves
 // Created On       : Sat May 16 13:28:16 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Aug 16 16:46:48 2017
-// Update Count     : 794
+// Last Modified By : Andrew Beach
+// Last Modified On : Thr Aug 17 13:46:00 2017
+// Update Count     : 795
 //
 
@@ -24,7 +24,8 @@
 #include <string>                  // for string
 
+#include "Common/CodeLocation.h"   // for CodeLocation
 #include "Common/SemanticError.h"  // for SemanticError
 #include "Common/UniqueName.h"     // for UniqueName
-#include "Common/utility.h"        // for maybeClone, CodeLocation, maybeBuild
+#include "Common/utility.h"        // for maybeClone, maybeBuild
 #include "Parser/LinkageSpec.h"    // for Spec
 #include "SynTree/Expression.h"    // for Expression, ConstantExpr (ptr only)
Index: src/SynTree/BaseSyntaxNode.h
===================================================================
--- src/SynTree/BaseSyntaxNode.h	(revision 6d49ea3165b7fb8906721da9a6f6949632d35140)
+++ src/SynTree/BaseSyntaxNode.h	(revision 274ce8c98a0dc1608308c1bd35c41bcd52a1c812)
@@ -9,13 +9,13 @@
 // Author           : Thierry Delisle
 // Created On       : Tue Feb 14 07:44:20 2017
-// Last Modified By :
-// Last Modified On :
-// Update Count     :
+// Last Modified By : Andrew Beach
+// Last Modified On : Thr Aug 17 13:44:00
+// Update Count     : 1
 //
 
 #pragma once
 
-#include "Common/utility.h"
-#include "Visitor.h"
+#include "Common/CodeLocation.h"
+class Visitor;
 
 class BaseSyntaxNode {
Index: src/driver/cfa.cc
===================================================================
--- src/driver/cfa.cc	(revision 6d49ea3165b7fb8906721da9a6f6949632d35140)
+++ src/driver/cfa.cc	(revision 274ce8c98a0dc1608308c1bd35c41bcd52a1c812)
@@ -9,7 +9,7 @@
 // Author           : Peter A. Buhr
 // Created On       : Tue Aug 20 13:44:49 2002
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Jan 20 14:38:45 2017
-// Update Count     : 155
+// Last Modified By : Andrew Beach
+// Last Modified On : Thr Aug 17 15:24:00 2017
+// Update Count     : 156
 //
 
@@ -281,4 +281,8 @@
 #endif //HAVE_LIBCFA
 
+	// Add exception flags (unconditionally)
+	args[nargs] = "-fexceptions";
+	nargs += 1;
+
 	// add the correct set of flags based on the type of compile this is
 
Index: src/libcfa/exception.c
===================================================================
--- src/libcfa/exception.c	(revision 6d49ea3165b7fb8906721da9a6f6949632d35140)
+++ src/libcfa/exception.c	(revision 274ce8c98a0dc1608308c1bd35c41bcd52a1c812)
@@ -10,6 +10,6 @@
 // Created On       : Mon Jun 26 15:13:00 2017
 // Last Modified By : Andrew Beach
-// Last Modified On : Fri Aug  4 15:20:00 2017
-// Update Count     : 6
+// Last Modified On : Thr Aug 17 15:45:00 2017
+// Update Count     : 7
 //
 
@@ -23,4 +23,5 @@
 #include <stdio.h>
 #include <unwind.h>
+#include <libhdr/libdebug.h>
 
 // FIX ME: temporary hack to keep ARM build working
@@ -79,6 +80,5 @@
 void __cfaehm__throw_resume(exception * except) {
 
-	// DEBUG
-	printf("Throwing resumption exception\n");
+	LIB_DEBUG_PRINT_SAFE("Throwing resumption exception\n");
 
 	struct __cfaehm__try_resume_node * original_head = shared_stack.current_resume;
@@ -94,5 +94,5 @@
 	}
 
-	printf("Unhandled exception\n");
+	LIB_DEBUG_PRINT_SAFE("Unhandled exception\n");
 	shared_stack.current_resume = original_head;
 
@@ -106,5 +106,5 @@
 
 void __cfaehm__try_resume_setup(struct __cfaehm__try_resume_node * node,
-                        int (*handler)(exception * except)) {
+                        _Bool (*handler)(exception * except)) {
 	node->next = shared_stack.top_resume;
 	node->handler = handler;
@@ -154,6 +154,5 @@
 	struct exception_context_t * context = this_exception_context();
 
-	// DEBUG
-	printf( "Deleting Exception\n");
+	LIB_DEBUG_PRINT_SAFE("Deleting Exception\n");
 
 	// Remove the exception from the list.
@@ -235,6 +234,5 @@
 
 void __cfaehm__throw_terminate( exception * val ) {
-	// DEBUG
-	printf("Throwing termination exception\n");
+	LIB_DEBUG_PRINT_SAFE("Throwing termination exception\n");
 
 	__cfaehm__allocate_exception( val );
@@ -243,6 +241,5 @@
 
 void __cfaehm__rethrow_terminate(void) {
-	// DEBUG
-	printf("Rethrowing termination exception\n");
+	LIB_DEBUG_PRINT_SAFE("Rethrowing termination exception\n");
 
 	__cfaehm__begin_unwind();
@@ -257,18 +254,15 @@
 {
 
-	// DEBUG
-	//printf("CFA: 0x%lx\n", _Unwind_GetCFA(context));
-	printf("Personality function (%d, %x, %llu, %p, %p):", version, actions, exceptionClass, unwind_exception, context);
+	//LIB_DEBUG_PRINT_SAFE("CFA: 0x%lx\n", _Unwind_GetCFA(context));
+	LIB_DEBUG_PRINT_SAFE("Personality function (%d, %x, %llu, %p, %p):", version, actions, exceptionClass, unwind_exception, context);
 
 	// If we've reached the end of the stack then there is nothing much we can do...
 	if( actions & _UA_END_OF_STACK ) return _URC_END_OF_STACK;
 
-	// DEBUG
 	if (actions & _UA_SEARCH_PHASE) {
-		printf(" lookup phase");
-	}
-	// DEBUG
+		LIB_DEBUG_PRINT_SAFE(" lookup phase");
+	}
 	else if (actions & _UA_CLEANUP_PHASE) {
-		printf(" cleanup phase");
+		LIB_DEBUG_PRINT_SAFE(" cleanup phase");
 	}
 	// Just in case, probably can't actually happen
@@ -306,5 +300,5 @@
 		// Have we reach the correct frame info yet?
 		if( lsd_info.Start + callsite_start + callsite_len < instruction_ptr ) {
-			//DEBUG BEGIN
+#ifdef __CFA_DEBUG_PRINT__
 			void * ls = (void*)lsd_info.Start;
 			void * cs = (void*)callsite_start;
@@ -313,6 +307,6 @@
 			void * ep = (void*)lsd_info.Start + callsite_start + callsite_len;
 			void * ip = (void*)instruction_ptr;
-			printf("\nfound %p - %p (%p, %p, %p), looking for %p\n", bp, ep, ls, cs, cl, ip);
-			//DEBUG END
+			LIB_DEBUG_PRINT_SAFE("\nfound %p - %p (%p, %p, %p), looking for %p\n", bp, ep, ls, cs, cl, ip);
+#endif // __CFA_DEBUG_PRINT__
 			continue;
 		}
@@ -362,11 +356,14 @@
 
 					// Based on the return value, check if we matched the exception
-					if( ret == _URC_HANDLER_FOUND) printf(" handler found\n");
-					else printf(" no handler\n");
+					if( ret == _URC_HANDLER_FOUND) {
+						LIB_DEBUG_PRINT_SAFE(" handler found\n");
+					} else {
+						LIB_DEBUG_PRINT_SAFE(" no handler\n");
+					}
 					return ret;
 				}
 
 				// This is only a cleanup handler, ignore it
-				printf(" no action");
+				LIB_DEBUG_PRINT_SAFE(" no action");
 			}
 			else if (actions & _UA_CLEANUP_PHASE) {
@@ -388,6 +385,5 @@
 				_Unwind_SetIP( context, ((lsd_info.LPStart) + (callsite_landing_pad)) );
 
-				// DEBUG
-				printf(" action\n");
+				LIB_DEBUG_PRINT_SAFE(" action\n");
 
 				// Return have some action to run
@@ -397,12 +393,11 @@
 
 		// Nothing to do, move along
-		printf(" no landing pad");
+		LIB_DEBUG_PRINT_SAFE(" no landing pad");
 	}
 	// No handling found
-	printf(" table end reached\n");
-
-	// DEBUG
+	LIB_DEBUG_PRINT_SAFE(" table end reached\n");
+
 	UNWIND:
-	printf(" unwind\n");
+	LIB_DEBUG_PRINT_SAFE(" unwind\n");
 
 	// Keep unwinding the stack
Index: src/libcfa/exception.h
===================================================================
--- src/libcfa/exception.h	(revision 6d49ea3165b7fb8906721da9a6f6949632d35140)
+++ src/libcfa/exception.h	(revision 274ce8c98a0dc1608308c1bd35c41bcd52a1c812)
@@ -10,6 +10,6 @@
 // Created On       : Mon Jun 26 15:11:00 2017
 // Last Modified By : Andrew Beach
-// Last Modified On : Fri Aug  4 15:20:00 2017
-// Update Count     : 5
+// Last Modified On : Thr Aug 17 15:44:00 2017
+// Update Count     : 6
 //
 
@@ -55,5 +55,5 @@
 struct __cfaehm__try_resume_node {
     struct __cfaehm__try_resume_node * next;
-    int (*handler)(exception * except);
+    _Bool (*handler)(exception * except);
 };
 
@@ -61,5 +61,5 @@
 void __cfaehm__try_resume_setup(
     struct __cfaehm__try_resume_node * node,
-    int (*handler)(exception * except));
+    _Bool (*handler)(exception * except));
 void __cfaehm__try_resume_cleanup(
     struct __cfaehm__try_resume_node * node);
Index: src/tests/except-0.c
===================================================================
--- src/tests/except-0.c	(revision 6d49ea3165b7fb8906721da9a6f6949632d35140)
+++ src/tests/except-0.c	(revision 274ce8c98a0dc1608308c1bd35c41bcd52a1c812)
@@ -7,4 +7,10 @@
 #include <stdio.h>
 #include <stdbool.h>
+
+#include "except-mac.h"
+TRIVIAL_EXCEPTION(yin)
+TRIVIAL_EXCEPTION(yang)
+TRIVIAL_EXCEPTION(zen)
+
 
 // Local type to mark exits from scopes. (see ERROR)
@@ -23,34 +29,16 @@
 
 
-// Local Exception Types and manual vtable types.
-//#define TRIVIAL_EXCEPTION(name) //TRIVAL_EXCEPTION(yin)
-struct yin;
-struct yin_vtable {
-	struct exception_t_vtable const * parent;
-	size_t size;
-    void (*copy)(yin *this, yin * other);
-    void (*free)(yin *this);
-    const char (*msg)(yin *this);
-};
-struct yin {
-	struct yin_vtable const * parent;
-};
-void yin_msg(yin) {
-	return "in";
-}
-yin_vtable _yin_vtable_instance = {
-	&_exception_t_vtable_instance, sizeof(yin), ?{}, ^?{}, yin_msg
-}
-
-
-void terminate(exception * except_value) {
+// Mark throws: make sure to only pass in exception types.
+forall(dtype T)
+void terminate(T * except_value) {
 	signal_exit a = {"terminate function"};
-	throw except_value;
+	THROW(except_value);
 	printf("terminate returned\n");
 }
 
-void resume(exception * except_value) {
+forall(dtype T)
+void resume(T * except_value) {
 	signal_exit a = {"resume function"};
-	throwResume except_value;
+	THROW_RESUME(except_value);
 	printf("resume returned\n");
 }
@@ -60,7 +48,7 @@
 	signal_exit a = {"bar function"};
 	try {
-		terminate(4);
-	} catch (3) {
-		printf("bar caught exception 3.\n");
+		terminate(&(zen){});
+	} catch (yin * error) {
+		printf("bar caught exception yin.\n");
 	}
 }
@@ -70,8 +58,8 @@
 	try {
 		bar();
-	} catch (4) {
-		printf("foo caught exception 4.\n");
-	} catch (2) {
-		printf("foo caught exception 2.\n");
+	} catch (yang * error) {
+		printf("foo caught exception yang.\n");
+	} catch (zen * error) {
+		printf("foo caught exception zen.\n");
 	}
 }
@@ -81,7 +69,8 @@
 	signal_exit a = {"beta function"};
 	try {
-		resume(4);
-	} catchResume (3) {
-		printf("beta caught exception 3\n");
+		zen x;
+		resume(&x);
+	} catchResume (yin * error) {
+		printf("beta caught exception yin\n");
 	}
 }
@@ -91,8 +80,8 @@
 	try {
 		beta();
-	} catchResume (2) {
-		printf("alpha caught exception 2\n");
-	} catchResume (4) {
-		printf("alpha caught exception 4\n");
+	} catchResume (yang * error) {
+		printf("alpha caught exception yang\n");
+	} catchResume (zen * error) {
+		printf("alpha caught exception zen\n");
 	}
 }
@@ -117,7 +106,8 @@
 void fallback() {
 	try {
-		resume(2);
-	} catch (2) {
-		printf("fallback caught termination 2\n");
+		zen x;
+		resume(&x);
+	} catch (zen * error) {
+		printf("fallback caught termination zen\n");
 	}
 }
@@ -127,7 +117,9 @@
 	signal_exit a = {"terminate_swap"};
 	try {
-		terminate(2);
-	} catch (2) {
-		terminate(3);
+		yin x;
+		terminate(&x);
+	} catch (yin * error) {
+		yang y;
+		terminate(&y);
 	}
 }
@@ -137,6 +129,6 @@
 	try {
 		terminate_swap();
-	} catch (3) {
-		printf("terminate_swapped caught exception 3\n");
+	} catch (yang * error) {
+		printf("terminate_swapped caught exception yang\n");
 	}
 }
@@ -146,7 +138,9 @@
 	signal_exit a = {"resume_swap"};
 	try {
-		resume(2);
-	} catchResume (2) {
-		resume(3);
+		yin x;
+		resume(&x);
+	} catchResume (yin * error) {
+		yang y;
+		resume(&y);
 	}
 }
@@ -155,6 +149,6 @@
 	try {
 		resume_swap();
-	} catchResume (3) {
-		printf("resume_swapped caught exception 3\n");
+	} catchResume (yang * error) {
+		printf("resume_swapped caught exception yang\n");
 	}
 }
@@ -164,12 +158,13 @@
 	try {
 		try {
-			terminate(2);
-		} catch (2) {
-			printf("reterminate 2 caught and "
-			       "will rethrow exception 2\n");
+			zen x;
+			terminate(&x);
+		} catch (zen * error) {
+			printf("reterminate zen caught and "
+			       "will rethrow exception zen\n");
 			throw;
 		}
-	} catch (2) {
-		printf("reterminate 1 caught exception 2\n");
+	} catch (zen * error) {
+		printf("reterminate 1 caught exception zen\n");
 	}
 }
@@ -179,11 +174,12 @@
 	try {
 		try {
-			resume(2);
-		} catchResume (2) {
-			printf("reresume 2 caught and rethrows exception 2\n");
+			zen x;
+			resume(&x);
+		} catchResume (zen * error) {
+			printf("reresume zen caught and rethrows exception zen\n");
 			throwResume;
 		}
-	} catchResume (2) {
-		printf("reresume 1 caught exception 2\n");
+	} catchResume (zen * error) {
+		printf("reresume 1 caught exception zen\n");
 	}
 }
@@ -193,7 +189,8 @@
 	// terminate block, call resume
 	try {
-		resume(3);
-	} catch (3) {
-		printf("fum caught exception 3\n");
+		zen x;
+		resume(&x);
+	} catch (zen * error) {
+		printf("fum caught exception zen\n");
 	}
 }
@@ -202,7 +199,8 @@
 	// resume block, call terminate
 	try {
-		terminate(3);
-	} catchResume (3) {
-		printf("foe caught exception 3\n");
+		zen y;
+		terminate(&y);
+	} catchResume (zen * error) {
+		printf("foe caught exception zen\n");
 	}
 }
@@ -212,6 +210,6 @@
 	try {
 		foe();
-	} catch (3) {
-		printf("fy caught exception 3\n");
+	} catch (zen * error) {
+		printf("fy caught exception zen\n");
 		fum();
 	}
@@ -222,6 +220,6 @@
 	try {
 		fy();
-	} catchResume (3) {
-		printf("fee caught exception 3\n");
+	} catchResume (zen * error) {
+		printf("fee caught exception zen\n");
 	}
 }
@@ -242,5 +240,8 @@
 	reresume(); printf("\n");
 	fee(); printf("\n");
+
 	// Uncaught termination test.
-	terminate(7);
-}
+	printf("Throw uncaught.\n");
+	yang z;
+	terminate(&z);
+}
Index: src/tests/except-1.c
===================================================================
--- src/tests/except-1.c	(revision 6d49ea3165b7fb8906721da9a6f6949632d35140)
+++ src/tests/except-1.c	(revision 274ce8c98a0dc1608308c1bd35c41bcd52a1c812)
@@ -5,15 +5,21 @@
 #include <stdio.h>
 
+#include "except-mac.h"
+TRIVIAL_EXCEPTION(yin)
+TRIVIAL_EXCEPTION(yang)
+
 int main()
 {
 	try {
-		throw 3;
+		yin a;
+		THROW(&a);
 	}
-	catch( 3 ) {
+	catch( yin * err ) {
 		printf("First Caught\n");
 		try {
-			throw 4;
+			yang b;
+			THROW(&b);
 		}
-		catch( 4 ) {
+		catch( yang * err ) {
 			printf("Both Caught\n");
 		}
@@ -23,12 +29,13 @@
 	try {
 		try {
-			throw 2;
+			yang c;
+			THROW(&c);
 		}
-		catch( 2 ) {
+		catch( yang * err ) {
 			printf("First Catch and rethrow\n");
 			throw;
 		}
 	}
-	catch( 2 ) {
+	catch( yang * err ) {
 		printf("Second Catch\n");
 	}
@@ -37,12 +44,14 @@
 	try {
 		try {
-			throw 5;
+			yin d;
+			THROW(&d);
 		}
-		catch( 5 ) {
+		catch( yin * err ) {
 			printf("Throw before cleanup\n");
-			throw 6;
+			yang e;
+			THROW(&e);
 		}
 	}
-	catch( 6 ) {
+	catch( yang * err ) {
 		printf("Catch after cleanup\n");
 	}
@@ -51,12 +60,14 @@
 	try {
 		try {
-			throw 7;
+			yin f;
+			THROW(&f);
 		}
-		catch( 7 ) {
+		catch( yin * err ) {
 			printf("Caught initial throw.\n");
 			try {
-				throw 8;
+				yang g;
+				THROW(&g);
 			}
-			catch( 8 ) {
+			catch( yang * err ) {
 				printf("Caught intermediate throw.\n");
 			}
@@ -64,5 +75,5 @@
 		}
 	}
-	catch( 7 ) {
+	catch( yin * err ) {
 		printf("Caught final throw.\n");
 	}
Index: src/tests/except-2.c
===================================================================
--- src/tests/except-2.c	(revision 6d49ea3165b7fb8906721da9a6f6949632d35140)
+++ src/tests/except-2.c	(revision 274ce8c98a0dc1608308c1bd35c41bcd52a1c812)
@@ -2,39 +2,7 @@
 
 
-#include <string.h>
+#include <stdlib>
+#include "except-mac.h"
 
-// Local Exception Types and manual vtable types.
-#define GLUE2(left, right) left##right
-#define GLUE3(left, middle, right) left##middle##right
-#define BASE_EXCEPT __cfaehm__base_exception_t
-#define TABLE(name) GLUE2(name,_vtable)
-#define INSTANCE(name) GLUE3(_,name,_vtable_instance)
-#define TRIVIAL_EXCEPTION(name) \
-struct name; \
-struct TABLE(name) { \
-	struct TABLE(BASE_EXCEPT) const * parent; \
-	size_t size; \
-	void (*copy)(name *this, name * other); \
-	void (*free)(name *this); \
-	const char * (*msg)(name *this); \
-}; \
-extern TABLE(name) INSTANCE(name); \
-struct name { \
-	struct TABLE(name) const * virtual_table; \
-}; \
-const char * name##_msg(name * this) { \
-	return #name; \
-} \
-void name##_copy(name * this, name * other) { \
-	this->virtual_table = other->virtual_table; \
-} \
-TABLE(name) INSTANCE(name) @= { \
-	.parent : &INSTANCE(BASE_EXCEPT), \
-	.size : sizeof(name), .copy : name##_copy, \
-	.free : ^?{}, .msg : name##_msg \
-}; \
-void ?{}(name * this) { \
-	this->virtual_table = &INSTANCE(name); \
-}
 TRIVIAL_EXCEPTION(yin)
 TRIVIAL_EXCEPTION(yang)
@@ -50,4 +18,5 @@
 };
 extern num_error_vtable INSTANCE(num_error);
+
 struct num_error {
 	struct num_error_vtable const * virtual_table;
@@ -55,8 +24,10 @@
 	int num;
 };
+
 void num_error_msg(num_error * this) {
 	if ( ! this->msg ) {
-		const char * base = "Num Error with code: X";
-		this->msg = strdup( base );
+		static const char * base = "Num Error with code: X";
+		this->msg = malloc(22);
+		for (int i = 0 ; (this->msg[i] = base[i]) ; ++i);
 	}
 	this->msg[21] = '0' + this->num;
@@ -90,5 +61,5 @@
 	try {
 		yin black;
-		throw (BASE_EXCEPT *)&black;
+		THROW(&black);
 	} catch ( yin * error ) {
 		printf("throw yin caught.\n");
@@ -97,5 +68,5 @@
 	try {
 		yang white;
-		throwResume (BASE_EXCEPT *)&white;
+		THROW_RESUME(&white);
 		printf("> throwResume returned.\n");
 	} catchResume ( yang * error ) {
@@ -105,5 +76,5 @@
 	try {
 		num_error x = { 2 };
-		throw (BASE_EXCEPT *)&x;
+		THROW(&x);
 	}
 	catch (num_error * error ; 3 == error->virtual_table->code( error ) ) {
Index: src/tests/except-3.c
===================================================================
--- src/tests/except-3.c	(revision 274ce8c98a0dc1608308c1bd35c41bcd52a1c812)
+++ src/tests/except-3.c	(revision 274ce8c98a0dc1608308c1bd35c41bcd52a1c812)
@@ -0,0 +1,18 @@
+// Test that __attribute__((cleanup(...))) is working.
+
+#include <stdio.h>
+#include "except-mac.h"
+TRIVIAL_EXCEPTION(myth)
+
+int main (int argc, char * argv[]) {
+	try {
+		try {
+			printf("throw [");
+			THROW(&(myth){});
+		} finally {
+			printf("] unwind <");
+		}
+	} catch (myth * error) {
+		printf("> catch\n");
+	}
+}
Index: src/tests/except-mac.h
===================================================================
--- src/tests/except-mac.h	(revision 274ce8c98a0dc1608308c1bd35c41bcd52a1c812)
+++ src/tests/except-mac.h	(revision 274ce8c98a0dc1608308c1bd35c41bcd52a1c812)
@@ -0,0 +1,78 @@
+// Macros to try and make declaring and using exceptions easier
+// No, these are not part of the language, they replace the virtual system.
+
+// Internal use:
+#define GLUE2(left, right) left##right
+#define GLUE3(left, middle, right) left##middle##right
+
+// The fully (perhaps overly) qualified name of the base exception type:
+#define BASE_EXCEPT __cfaehm__base_exception_t
+
+// Get the name of the vtable type and vtable instance for an exception type:
+#define TABLE(name) GLUE2(name,_vtable)
+#define INSTANCE(name) GLUE3(_,name,_vtable_instance)
+
+// Throws and the bit of overhead:
+#define THROW(expr) throw ((BASE_EXCEPT *)(expr))
+#define THROW_RESUME(expr) throwResume ((BASE_EXCEPT *)(expr))
+
+
+
+// The following macros are for defining your own new exception types.
+
+// Declare vtable and forward declare the exception type and vtable instance.
+// This should start a new exception declaration.
+// ... argument is the additional vtable fields.
+#define DECLARE_EXCEPT(except_name,parent_name,...) \
+struct except_name; \
+struct TABLE(except_name) { \
+	struct TABLE(parent_name) const * parent; \
+	size_t size; \
+	void (*copy)(except_name *this, except_name * other); \
+	void (*free)(except_name *this); \
+	const char * (*msg)(except_name *this); \
+	__VA_ARGS__ \
+}; \
+extern TABLE(except_name) INSTANCE(except_name);
+
+// The first field of the exception structure should be created with this.
+#define VTABLE_FIELD(except_name) \
+struct TABLE(except_name) const * virtual_table
+
+// In each constructor the vtable must be initialized.
+#define VTABLE_INIT(this_name,except_name) \
+this_name->virtual_table = &INSTANCE(except_name)
+
+// Declare the vtable instance. This should end an exception declaration.
+// ... argument is the remaining vtable field values.
+#define VTABLE_INSTANCE(except_name,parent_name,copy,free,msg,...) \
+TABLE(except_name) INSTANCE(except_name) @= { \
+	&INSTANCE(parent_name), sizeof(except_name), \
+	copy, free, msg, ## __VA_ARGS__ \
+};
+
+// Same, but used declarators for arguments.
+#define VTABLE_INSTANCE_KEY(except_name,parent_name,copy,free,msg,...) \
+TABLE(except_name) INSTANCE(except_name) @= { \
+	.parent : &INSTANCE(parent_name), .size : sizeof(except_name), \
+	.copy : copy, .free : free, .msg : msg, ## __VA_ARGS__ \
+};
+
+
+
+// Declare a trivial exception, one that adds no features:
+#define TRIVIAL_EXCEPTION(name) \
+DECLARE_EXCEPT(name,BASE_EXCEPT,) \
+struct name { \
+	VTABLE_FIELD(name); \
+}; \
+const char * GLUE2(name,_msg)(name * this) { \
+    return #name; \
+} \
+void GLUE2(name,_copy)(name * this, name * other) { \
+    this->virtual_table = other->virtual_table; \
+} \
+void ?{}(name * this) { \
+	VTABLE_INIT(this,name); \
+} \
+VTABLE_INSTANCE(name,BASE_EXCEPT,GLUE2(name,_copy),^?{},GLUE2(name,_msg),)
