Index: src/ControlStruct/ExceptTranslate.cc
===================================================================
--- src/ControlStruct/ExceptTranslate.cc	(revision 0a6d8204aa07464088764b1d42a540ea42e521ad)
+++ src/ControlStruct/ExceptTranslate.cc	(revision 8ad57526fac65680cee486a070c56fdcbee2a28e)
@@ -10,6 +10,6 @@
 // Created On       : Wed Jun 14 16:49:00 2017
 // Last Modified By : Andrew Beach
-// Last Modified On : Fri Mar 27 11:58:00 2020
-// Update Count     : 13
+// Last Modified On : Tue May 19 16:46:00 2020
+// Update Count     : 14
 //
 
@@ -64,5 +64,123 @@
 	}
 
-	class ExceptionMutatorCore : public WithGuards {
+	class ThrowMutatorCore : public WithGuards {
+		ObjectDecl * terminate_handler_except;
+		enum Context { NoHandler, TerHandler, ResHandler } cur_context;
+
+		// The helper functions for code/syntree generation.
+		Statement * create_either_throw(
+			ThrowStmt * throwStmt, const char * throwFunc );
+		Statement * create_terminate_rethrow( ThrowStmt * throwStmt );
+		Statement * create_resume_rethrow( ThrowStmt * throwStmt );
+
+	public:
+		ThrowMutatorCore() :
+			terminate_handler_except( nullptr ),
+			cur_context( NoHandler )
+		{}
+
+		void premutate( CatchStmt *catchStmt );
+		Statement * postmutate( ThrowStmt *throwStmt );
+	};
+
+	// ThrowStmt Mutation Helpers
+
+	Statement * ThrowMutatorCore::create_either_throw(
+			ThrowStmt * throwStmt, const char * throwFunc ) {
+		// `throwFunc`( `throwStmt->get_name()` );
+		UntypedExpr * call = new UntypedExpr( new NameExpr( throwFunc ) );
+		call->get_args().push_back( throwStmt->get_expr() );
+		throwStmt->set_expr( nullptr );
+		delete throwStmt;
+		return new ExprStmt( call );
+	}
+
+	Statement * ThrowMutatorCore::create_terminate_rethrow(
+			ThrowStmt *throwStmt ) {
+		// { `terminate_handler_except` = 0p; __rethrow_terminate(); }
+		assert( nullptr == throwStmt->get_expr() );
+		assert( terminate_handler_except );
+
+		CompoundStmt * result = new CompoundStmt();
+		result->labels =  throwStmt->labels;
+		result->push_back( new ExprStmt( UntypedExpr::createAssign(
+			nameOf( terminate_handler_except ),
+			new ConstantExpr( Constant::null(
+				//new PointerType(
+				//	noQualifiers,
+					terminate_handler_except->get_type()->clone()
+				//	)
+				) )
+			) ) );
+		result->push_back( new ExprStmt(
+			new UntypedExpr( new NameExpr( "__cfaehm_rethrow_terminate" ) )
+			) );
+		delete throwStmt;
+		return result;
+	}
+
+	Statement * ThrowMutatorCore::create_resume_rethrow(
+			ThrowStmt *throwStmt ) {
+		// return false;
+		Statement * result = new ReturnStmt(
+			new ConstantExpr( Constant::from_bool( false ) )
+			);
+		result->labels = throwStmt->labels;
+		delete throwStmt;
+		return result;
+	}
+
+	// Visiting/Mutating Functions
+
+	void ThrowMutatorCore::premutate( CatchStmt *catchStmt ) {
+		// Validate the statement's form.
+		ObjectDecl * decl = dynamic_cast<ObjectDecl *>( catchStmt->get_decl() );
+		// Also checking the type would be nice.
+		if ( decl ) {
+			// Pass.
+		} else if ( CatchStmt::Terminate == catchStmt->get_kind() ) {
+			SemanticError(catchStmt->location, "catch must have exception type");
+		} else {
+			SemanticError(catchStmt->location, "catchResume must have exception type");
+		}
+
+		// Track the handler context.
+		GuardValue( cur_context );
+		if ( CatchStmt::Terminate == catchStmt->get_kind() ) {
+			cur_context = TerHandler;
+
+			GuardValue( terminate_handler_except );
+			terminate_handler_except = decl;
+		} else {
+			cur_context = ResHandler;
+		}
+	}
+
+	Statement * ThrowMutatorCore::postmutate( ThrowStmt *throwStmt ) {
+		// Ignoring throwStmt->get_target() for now.
+		if ( ThrowStmt::Terminate == throwStmt->get_kind() ) {
+			if ( throwStmt->get_expr() ) {
+				return create_either_throw( throwStmt, "$throw" );
+			} else if ( TerHandler == cur_context ) {
+				return create_terminate_rethrow( throwStmt );
+			} else {
+				abort("Invalid throw in %s at %i\n",
+					throwStmt->location.filename.c_str(),
+					throwStmt->location.first_line);
+			}
+		} else {
+			if ( throwStmt->get_expr() ) {
+				return create_either_throw( throwStmt, "$throwResume" );
+			} else if ( ResHandler == cur_context ) {
+				return create_resume_rethrow( throwStmt );
+			} else {
+				abort("Invalid throwResume in %s at %i\n",
+					throwStmt->location.filename.c_str(),
+					throwStmt->location.first_line);
+			}
+		}
+	}
+
+	class TryMutatorCore : public WithGuards {
 		enum Context { NoHandler, TerHandler, ResHandler };
 
@@ -82,10 +200,4 @@
 
 		// The many helper functions for code/syntree generation.
-		Statement * create_given_throw(
-			const char * throwFunc, ThrowStmt * throwStmt );
-		Statement * create_terminate_throw( ThrowStmt * throwStmt );
-		Statement * create_terminate_rethrow( ThrowStmt * throwStmt );
-		Statement * create_resume_throw( ThrowStmt * throwStmt );
-		Statement * create_resume_rethrow( ThrowStmt * throwStmt );
 		CompoundStmt * take_try_block( TryStmt * tryStmt );
 		FunctionDecl * create_try_wrapper( CompoundStmt * body );
@@ -121,5 +233,5 @@
 
 	public:
-		ExceptionMutatorCore() :
+		TryMutatorCore() :
 			cur_context( NoHandler ),
 			handler_except_decl( nullptr ),
@@ -138,5 +250,5 @@
 	};
 
-	void ExceptionMutatorCore::init_func_types() {
+	void TryMutatorCore::init_func_types() {
 		assert( except_decl );
 
@@ -196,66 +308,7 @@
 	}
 
-	// ThrowStmt Mutation Helpers
-
-	Statement * ExceptionMutatorCore::create_given_throw(
-			const char * throwFunc, ThrowStmt * throwStmt ) {
-		// `throwFunc`( `throwStmt->get_name` );
-		UntypedExpr * call = new UntypedExpr( new NameExpr( throwFunc ) );
-		call->get_args().push_back( throwStmt->get_expr() );
-		throwStmt->set_expr( nullptr );
-		delete throwStmt;
-		return new ExprStmt( call );
-	}
-
-	Statement * ExceptionMutatorCore::create_terminate_throw(
-			ThrowStmt *throwStmt ) {
-		// __throw_terminate( `throwStmt->get_name()` ); }
-		return create_given_throw( "__cfaehm_throw_terminate", throwStmt );
-	}
-
-	Statement * ExceptionMutatorCore::create_terminate_rethrow(
-			ThrowStmt *throwStmt ) {
-		// { `handler_except_decl` = NULL; __rethrow_terminate(); }
-		assert( nullptr == throwStmt->get_expr() );
-		assert( handler_except_decl );
-
-		CompoundStmt * result = new CompoundStmt();
-		result->labels =  throwStmt->labels;
-		result->push_back( new ExprStmt( UntypedExpr::createAssign(
-			nameOf( handler_except_decl ),
-			new ConstantExpr( Constant::null(
-				new PointerType(
-					noQualifiers,
-					handler_except_decl->get_type()->clone()
-					)
-				) )
-			) ) );
-		result->push_back( new ExprStmt(
-			new UntypedExpr( new NameExpr( "__cfaehm_rethrow_terminate" ) )
-			) );
-		delete throwStmt;
-		return result;
-	}
-
-	Statement * ExceptionMutatorCore::create_resume_throw(
-			ThrowStmt *throwStmt ) {
-		// __throw_resume( `throwStmt->get_name` );
-		return create_given_throw( "__cfaehm_throw_resume", throwStmt );
-	}
-
-	Statement * ExceptionMutatorCore::create_resume_rethrow(
-			ThrowStmt *throwStmt ) {
-		// return false;
-		Statement * result = new ReturnStmt(
-			new ConstantExpr( Constant::from_bool( false ) )
-			);
-		result->labels = throwStmt->labels;
-		delete throwStmt;
-		return result;
-	}
-
 	// TryStmt Mutation Helpers
 
-	CompoundStmt * ExceptionMutatorCore::take_try_block( TryStmt *tryStmt ) {
+	CompoundStmt * TryMutatorCore::take_try_block( TryStmt *tryStmt ) {
 		CompoundStmt * block = tryStmt->get_block();
 		tryStmt->set_block( nullptr );
@@ -263,5 +316,5 @@
 	}
 
-	FunctionDecl * ExceptionMutatorCore::create_try_wrapper(
+	FunctionDecl * TryMutatorCore::create_try_wrapper(
 			CompoundStmt *body ) {
 
@@ -270,5 +323,5 @@
 	}
 
-	FunctionDecl * ExceptionMutatorCore::create_terminate_catch(
+	FunctionDecl * TryMutatorCore::create_terminate_catch(
 			CatchList &handlers ) {
 		std::list<CaseStmt *> handler_wrappers;
@@ -350,5 +403,5 @@
 	// Create a single check from a moddified handler.
 	// except_obj is referenced, modded_handler will be freed.
-	CompoundStmt * ExceptionMutatorCore::create_single_matcher(
+	CompoundStmt * TryMutatorCore::create_single_matcher(
 			DeclarationWithType * except_obj, CatchStmt * modded_handler ) {
 		// {
@@ -388,5 +441,5 @@
 	}
 
-	FunctionDecl * ExceptionMutatorCore::create_terminate_match(
+	FunctionDecl * TryMutatorCore::create_terminate_match(
 			CatchList &handlers ) {
 		// int match(exception * except) {
@@ -425,5 +478,5 @@
 	}
 
-	CompoundStmt * ExceptionMutatorCore::create_terminate_caller(
+	CompoundStmt * TryMutatorCore::create_terminate_caller(
 			FunctionDecl * try_wrapper,
 			FunctionDecl * terminate_catch,
@@ -443,5 +496,5 @@
 	}
 
-	FunctionDecl * ExceptionMutatorCore::create_resume_handler(
+	FunctionDecl * TryMutatorCore::create_resume_handler(
 			CatchList &handlers ) {
 		// bool handle(exception * except) {
@@ -480,5 +533,5 @@
 	}
 
-	CompoundStmt * ExceptionMutatorCore::create_resume_wrapper(
+	CompoundStmt * TryMutatorCore::create_resume_wrapper(
 			Statement * wraps,
 			FunctionDecl * resume_handler ) {
@@ -524,5 +577,5 @@
 	}
 
-	FunctionDecl * ExceptionMutatorCore::create_finally_wrapper(
+	FunctionDecl * TryMutatorCore::create_finally_wrapper(
 			TryStmt * tryStmt ) {
 		// void finally() { <finally code> }
@@ -537,8 +590,8 @@
 	}
 
-	ObjectDecl * ExceptionMutatorCore::create_finally_hook(
+	ObjectDecl * TryMutatorCore::create_finally_hook(
 			FunctionDecl * finally_wrapper ) {
 		// struct __cfaehm_cleanup_hook __finally_hook
-		//   	__attribute__((cleanup( finally_wrapper )));
+		//   	__attribute__((cleanup( `finally_wrapper` )));
 
 		// Make Cleanup Attribute.
@@ -565,8 +618,7 @@
 
 	// Visiting/Mutating Functions
-	void ExceptionMutatorCore::premutate( CatchStmt *catchStmt ) {
+	void TryMutatorCore::premutate( CatchStmt *catchStmt ) {
 		// Validate the Statement's form.
-		ObjectDecl * decl =
-			dynamic_cast<ObjectDecl *>( catchStmt->get_decl() );
+		ObjectDecl * decl = dynamic_cast<ObjectDecl *>( catchStmt->get_decl() );
 		if ( decl && true /* check decl->get_type() */ ) {
 			// Pass.
@@ -589,5 +641,5 @@
 	}
 
-	void ExceptionMutatorCore::premutate( StructDecl *structDecl ) {
+	void TryMutatorCore::premutate( StructDecl *structDecl ) {
 		if ( !structDecl->has_body() ) {
 			// Skip children?
@@ -604,35 +656,12 @@
 			hook_decl = structDecl;
 		}
-		// Later we might get the exception type as well.
-	}
-
-	Statement * ExceptionMutatorCore::postmutate( ThrowStmt *throwStmt ) {
-		assert( except_decl );
-
-		// Ignoring throwStmt->get_target() for now.
-		if ( ThrowStmt::Terminate == throwStmt->get_kind() ) {
-			if ( throwStmt->get_expr() ) {
-				return create_terminate_throw( throwStmt );
-			} else if ( TerHandler == cur_context ) {
-				return create_terminate_rethrow( throwStmt );
-			} else {
-				abort("Invalid throw in %s at %i\n",
-					throwStmt->location.filename.c_str(),
-					throwStmt->location.first_line);
-			}
-		} else {
-			if ( throwStmt->get_expr() ) {
-				return create_resume_throw( throwStmt );
-			} else if ( ResHandler == cur_context ) {
-				return create_resume_rethrow( throwStmt );
-			} else {
-				abort("Invalid throwResume in %s at %i\n",
-					throwStmt->location.filename.c_str(),
-					throwStmt->location.first_line);
-			}
-		}
-	}
-
-	Statement * ExceptionMutatorCore::postmutate( TryStmt *tryStmt ) {
+	}
+
+	Statement * TryMutatorCore::postmutate( ThrowStmt * ) {
+		// All throws should be removed by this point.
+		assert( false );
+	}
+
+	Statement * TryMutatorCore::postmutate( TryStmt *tryStmt ) {
 		assert( except_decl );
 		assert( node_decl );
@@ -688,7 +717,12 @@
 	}
 
-	void translateEHM( std::list< Declaration *> & translationUnit ) {
-		PassVisitor<ExceptionMutatorCore> translator;
+	void translateThrows( std::list< Declaration *> & translationUnit ) {
+		PassVisitor<ThrowMutatorCore> translator;
 		mutateAll( translationUnit, translator );
 	}
+
+	void translateTries( std::list< Declaration *> & translationUnit ) {
+		PassVisitor<TryMutatorCore> translator;
+		mutateAll( translationUnit, translator );
+	}
 }
Index: src/ControlStruct/ExceptTranslate.h
===================================================================
--- src/ControlStruct/ExceptTranslate.h	(revision 0a6d8204aa07464088764b1d42a540ea42e521ad)
+++ src/ControlStruct/ExceptTranslate.h	(revision 8ad57526fac65680cee486a070c56fdcbee2a28e)
@@ -9,7 +9,7 @@
 // Author           : Andrew Beach
 // Created On       : Tus Jun 06 10:13:00 2017
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Sat Jul 22 09:19:23 2017
-// Update Count     : 4
+// Last Modified By : Andrew Beach
+// Last Modified On : Tus May 19 11:47:00 2020
+// Update Count     : 5
 //
 
@@ -21,7 +21,14 @@
 
 namespace ControlStruct {
-	void translateEHM( std::list< Declaration *> & translationUnit );
-	// Converts exception handling structures into their underlying C code.  Translation does use the exception
-	// handling header, make sure it is visible wherever translation occurs.
+	void translateThrows( std::list< Declaration *> & translationUnit );
+	/* Replaces all throw & throwResume statements with function calls.
+	 * These still need to be resolved, so call this before the reslover.
+	 */
+
+	void translateTries( std::list< Declaration *> & translationUnit );
+	/* Replaces all try blocks (and their many clauses) with function definitions and calls.
+	 * This uses the exception built-ins to produce typed output and should take place after
+	 * the resolver.
+	 */
 }
 
Index: src/main.cc
===================================================================
--- src/main.cc	(revision 0a6d8204aa07464088764b1d42a540ea42e521ad)
+++ src/main.cc	(revision 8ad57526fac65680cee486a070c56fdcbee2a28e)
@@ -9,7 +9,7 @@
 // Author           : Peter Buhr and Rob Schluntz
 // Created On       : Fri May 15 23:12:02 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Sat Feb  8 08:33:50 2020
-// Update Count     : 633
+// Last Modified By : Andrew Beach
+// Last Modified On : Tue May 19 12:03:00 2020
+// Update Count     : 634
 //
 
@@ -312,4 +312,5 @@
 		} // if
 
+		PASS( "Translate Throws", ControlStruct::translateThrows( translationUnit ) );
 		PASS( "Fix Labels", ControlStruct::fixLabels( translationUnit ) );
 		PASS( "Fix Names", CodeGen::fixNames( translationUnit ) );
@@ -354,5 +355,5 @@
 		PASS( "Expand Unique Expr", Tuples::expandUniqueExpr( translationUnit ) ); // xxx - is this the right place for this? want to expand ASAP so tha, sequent passes don't need to worry about double-visiting a unique expr - needs to go after InitTweak::fix so that copy constructed return declarations are reused
 
-		PASS( "Translate EHM" , ControlStruct::translateEHM( translationUnit ) );
+		PASS( "Translate Tries" , ControlStruct::translateTries( translationUnit ) );
 
 		PASS( "Gen Waitfor" , Concurrency::generateWaitFor( translationUnit ) );
