Index: src/ControlStruct/ExceptTranslate.cc
===================================================================
--- src/ControlStruct/ExceptTranslate.cc	(revision ba9127067dc626fc81dbe378f35ac7259432e40d)
+++ src/ControlStruct/ExceptTranslate.cc	(revision ba9127067dc626fc81dbe378f35ac7259432e40d)
@@ -0,0 +1,485 @@
+//
+// 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.
+//
+// ExceptVisitor.cc --
+//
+// Author           : Andrew Beach
+// Created On       : Wed Jun 14 16:49:00 2017
+// Last Modified By : Andrew Beach
+// Last Modified On : Thr Jun 22 15:57:00 2017
+// Update Count     : 0
+//
+
+#include "ExceptTranslate.h"
+#include "Common/PassVisitor.h"
+
+namespace ControlFlow {
+
+	// This (large) section could probably be moved out of the class
+	// and be static helpers instead.
+
+	// Type(Qualifiers &, false, std::list<Attribute *> &)
+
+	// void (*function)()
+	static FunctionType void_func_t(Type::Qualifiers(), false);
+	// void (*function)(int, exception);
+	static FunctionType catch_func_t(Type::Qualifiers(), false);
+	// int (*function)(exception);
+	static FunctionType match_func_t(Type::Qualifiers(), false);
+	// bool (*function)(exception);
+	static FunctionType handle_func_t(Type::Qualifiers(), false);
+
+	static void init_func_types() {
+		static init_complete = false;
+		if (init_complete) {
+			return;
+		}
+		ObjectDecl index_obj(
+			"index_t",
+			Type::StorageClasses(),
+			LinkageSpec::Cforall,
+			/*bitfieldWidth*/ NULL,
+			new BasicType(emptyQualifiers, BasicType::UnsignedInt),
+			/*init*/ NULL
+		);
+		ObjectDecl exception_obj(
+			"exception_t",
+			Type::StorageClasses(),
+			LinkageSpec::Cforall,
+			/*bitfieldWidth*/ NULL,
+			new BasicType(emptyQualifiers, BasicType::UnsignedInt),
+			/*init*/ NULL
+		);
+		ObjectDecl bool_obj(
+			"bool_t",
+			Type::StorageClasses(),
+			LinkageSpec::Cforall,
+			/*bitfieldWidth*/ NULL,
+			new BasicType(emptyQualifiers, BasicType::Bool),
+			/*init*/ NULL
+		);
+
+		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_parameters().push_back(exception_obj.clone());
+		handle_func_t.get_returnVals().push_back(bool_obj.clone());
+		handle_func_t.get_parameters().push_back(exception_obj.clone());
+
+		init_complete = true;
+	}
+
+	// Buricratic Helpers (Not having to do with the paritular operation.)
+
+	typedef std::list<CatchStmt*> CatchList;
+
+	void split( CatchList& allHandlers, CatchList& terHandlers,
+	            CatchList& resHandlers ) {
+		while ( !allHandlers.empty() ) {
+			Statement * stmt = allHandlers.front();
+			allHandlers.pop_front();
+			if (CaseStmt::Terminate == stmt->get_kind()) {
+				terHandlers.push_back(stmt);
+			} else {
+				resHandlers.push_back(stmt);
+			}
+		}
+	}
+
+	template<typename T>
+	void free_all( std::list<T *> &list ) {
+		std::list<T *>::iterator it;
+		for ( it = list.begin() ; it != list.end() ; ++it ) {
+			delete *it;
+		}
+		list.clear();
+	}
+
+	void appendDeclStmt( CompoundStmt * block, Declaration * item ) {
+		block->push_back(new DeclStmt(no_labels, item));
+	}
+
+	Expression * nameOf( FunctionDecl * function ) {
+		return new VariableExpr( function );
+	}
+
+	// ThrowStmt Mutation Helpers
+
+	Statement * create_terminate_throw( ThrowStmt *throwStmt ) {
+		// __throw_terminate( EXPR );
+		ApplicationExpr * call = new ApplicationExpr( /* ... */ );
+		call->get_args.push_back( throwStmt->get_expr() );
+		Statement * result = new ExprStmt( throwStmt->get_labels(), call );
+		throwStmt->set_expr( nullptr );
+		delete throwStmt;
+		return result;
+	}
+	Statement * create_terminate_rethrow( ThrowStmt *throwStmt ) {
+		// __rethrow_terminate();
+		Statement * result = new ExprStmt(
+			throwStmt->get_labels(),
+			new ApplicationExpr( /* ... */ );
+			);
+		delete throwStmt;
+		return result;
+	}
+	Statement * create_resume_throw( ThrowStmt *throwStmt ) {
+		// __throw_resume( EXPR );
+		ApplicationExpr * call = new ApplicationExpr( /* ... */ );
+		call->get_args.push_back( throwStmt->get_expr() );
+		Statement * result = new ExprStmt( throwStmt->get_labels(), call );
+		throwStmt->set_expr( nullptr );
+		delete throwStmt;
+		return result;
+	}
+	Statement * create_resume_rethrow( ThrowStmt *throwStmt ) {
+		// return false;
+		Statement * result = new ReturnStmt(
+			throwStmt->get_labels(),
+			new ConstantExpr(
+				Constant(
+					new BasicType(
+						Type::Qualifiers(),
+						BasicType::Bool
+						),
+					"0")
+				)
+			);
+		delete throwStmt;
+		return result;
+	}
+
+	// TryStmt Mutation Helpers
+
+	CompoundStmt * take_try_block( TryStmt *tryStmt ) {
+		CompoundStmt * block = tryStmt->get_block();
+		tryStmt->set_block( nullptr );
+		return block;
+	}
+	FunctionDecl * create_try_wrapper( TryStmt *tryStmt ) {
+		CompoundStmt * body = base_try->get_block();
+		base_try->set_block(nullptr);
+
+		return new FunctionDecl("try", Type::StorageClasses(),
+			LinkageSpec::Cforall, void_func_t, body);
+	}
+
+	FunctionDecl * create_terminate_catch( CatchList &handlers ) {
+		std::list<CaseStmt *> handler_wrappers;
+
+		// Index 1..{number of handlers}
+		int index = 0;
+		CatchList::iterator it = handlers.begin();
+		for ( ; it != handlers.end() ; ++it ) {
+			++index;
+			CatchStmt * handler = *it;
+
+			std::list<Statement *> core;
+			if ( /*the exception is named*/ ) {
+				ObjectDecl * local_except = /* Dynamic case, same */;
+				core->push_back( new DeclStmt( noLabel, local_except ) );
+			}
+			// Append the provided statement to the handler.
+			core->push_back( cur_handler->get_body() );
+			// Append return onto the inner block? case stmt list?
+			CaseStmt * wrapper = new CaseStmt(
+				noLabels,
+				new ConstantExpr( Constant::from_int( index ) ),
+				core
+				);
+			handler_wrappers.push_back(wrapper);
+		}
+		// TODO: Some sort of meaningful error on default perhaps?
+
+		SwitchStmt * handler_lookup = new SwitchStmt(
+			noLabels,
+			/*parameter 0: index*/,
+			handler_wrappers,
+			false
+			);
+		CompoundStmt * body = new CompoundStmt( noLabels );
+		body->push_back( handler_lookup );
+
+		return new FunctionDecl("catch", Type::StorageClasses(),
+			LinkageSpec::Cforall, catch_func_t, body);
+	}
+
+	// Create a single check from a moddified handler.
+	CompoundStmt *create_single_matcher( CatchStmt * modded_handler ) {
+		CompoundStmt * block = new CompoundStmt( noLables );
+
+		appendDeclStmt( block, modded_handler->get_decl() );
+
+		// TODO: This is not the actual check.
+		LogicalExpr * cond = new ConstantExpr( Constant::from_bool( false ) );
+
+		if ( modded_handler->get_cond() ) {
+			cond = new LogicalExpr( cond, modded_handler->get_cond() )q
+		}
+		block->push_back( new IfStmt( noLabels,
+			cond, modded_handler->get_body() );
+
+		modded_handler->set_decl( nullptr );
+		modded_handler->set_cond( nullptr );
+		modded_handler->set_body( nullptr );
+		delete modded_handler;
+		return block;
+	}
+
+	FunctionDecl * create_terminate_match( CatchList &handlers ) {
+		CompoundStmt * body = new CompoundStmt( noLabels );
+
+		// Index 1..{number of handlers}
+		int index = 0;
+		CatchList::iterator it;
+		for ( it = handlers.begin() ; it != handlers.end() ; ++it ) {
+			++index;
+			CatchStmt * handler = *it;
+
+			// body should have been taken by create_terminate_catch.
+			// assert( nullptr == handler->get_body() );
+			handler->set_body( new ReturnStmt( noLabels,
+				new ConstantExpr( Constant::from_int( index ) ) ) );
+
+			body->push_back( create_single_matcher( handler ) );
+		}
+
+		return new FunctionDecl("match", Type::StorageClasses(),
+			LinkageSpec::Cforall, match_func_t, body);
+	}
+
+	Statement * create_terminate_caller(
+			FunctionDecl * try_wrapper,
+			FunctionDecl * terminate_catch,
+			FunctionDecl * terminate_match) {
+
+		ApplicationExpr * caller = new ApplicationExpr( /* ... */ );
+		std::list<Expression *>& args = caller.get_args();
+		args.push_back( nameOf( try_wrapper ) );
+		args.push_back( nameOf( terminate_catch ) );
+		args.push_back( nameOf( terminate_match ) );
+
+		return new ExprStmt( noLabels, caller );
+	}
+
+	FunctionDecl * create_resume_handler( CatchList &handlers ) {
+		CompoundStmt * body = new CompountStmt( noLabels );
+
+		CatchList::iterator it;
+		for ( it = handlers.begin() ; it != handlers.end() ; ++it ) {
+			CatchStmt * handler = *it;
+
+			// Modifiy body.
+			CompoundStmt * handling_code =
+				dynamic_cast<CompoundStmt*>( handler->get_body() );
+			if ( ! handling_code ) {
+				handling_code = new CompoundStmt( noLabels );
+				handling_code->push_back( handler->get_body() );
+			}
+			handling_code->push_back( new ReturnStmt( noLabel,
+				new ConstantExpr( Constant::from_bool( false ) ) ) );
+			handler->set_body( handling_code );
+
+			// Create the handler.
+			body->push_back( create_single_matcher( handler ) );
+		}
+
+		return new FunctionDecl("handle", Type::StorageClasses(),
+			LinkageSpec::Cforall, handle_func_t, body);
+	}
+
+	Statement * create_resume_wrapper(
+			Statement * wraps,
+			FunctionDecl * resume_handler ) {
+		CompoundStmt * body = new CompoundStmt( noLabels );
+
+		// struct node = {current top resume handler, call to resume_handler};
+		// __attribute__((cleanup( ... )));
+		// set top resume handler to node.
+		// The wrapped statement.
+
+		ListInit * node_init;
+		{
+			std::list<Initializer*> field_inits;
+			field_inits.push_back( new SingleInit( /* ... */ ) );
+			field_inits.push_back( new SingleInit( nameOf( resume_handler ) ) );
+			node_init = new ListInit( field_inits );
+		}
+
+		std::list< Attribute * > attributes;
+		{
+			std::list< Expression * > attr_params;
+			attr_params.push_back( nameOf( /* ... deconstructor ... */ ) );
+			attrributes.push_back( new Attribute( "cleanup", attr_params ) );
+		}
+
+		appendDeclStmt( body,
+		/**/ ObjectDecl(
+			"resume_node",
+			Type::StorageClasses(),
+			LinkageSpec::Cforall,
+			nullptr,
+			/* Type* = resume_node */,
+			node_init,
+			attributes
+			)
+		);
+		body->push_back( wraps );
+		return body;
+	}
+
+	FunctionDecl * create_finally_wrapper( TryStmt * tryStmt ) {
+		CompoundStmt * body = tryStmt->get_finally();
+		tryStmt->set_finally( nullptr );
+
+		return new FunctionDecl("finally", Type::StorageClasses(),
+			LinkageSpec::Cforall, void_func_t, body);
+	}
+
+	ObjectDecl * create_finally_hook( FunctionDecl * finally_wrapper ) {
+		// struct _cleanup_hook NAME __attribute__((cleanup( ... )));
+
+		// Make Cleanup Attribute.
+		std::list< Attribute * > attributes;
+		{
+			std::list< Expression * > attr_params;
+			attr_params.push_back( nameOf( finally_wrapper ) );
+			attrributes.push_back( new Attribute( "cleanup", attr_params ) );
+		}
+
+		return ObjectDecl( /* ... */
+			const std::string &name "finally_hook",
+			Type::StorageClasses(),
+			LinkageSpec::Cforall,
+			nullptr,
+			/* ... Type * ... */,
+			nullptr,
+			attributes
+			);
+	}
+
+
+	class ExceptionMutatorCore : public WithScoping {
+		enum Context { NoHandler, TerHandler, ResHandler };
+
+		// Also need to handle goto, break & continue.
+		// They need to be cut off in a ResHandler, until we enter another
+		// loop, switch or the goto stays within the function.
+
+		Context curContext;
+
+		// We might not need this, but a unique base for each try block's
+		// generated functions might be nice.
+		//std::string curFunctionName;
+		//unsigned int try_count = 0;
+
+
+	public:
+		ExceptionMutatorCore() :
+			curContext(NoHandler)
+		{}
+
+		void premutate( CatchStmt *tryStmt );
+		Statement * postmutate( ThrowStmt *throwStmt );
+		Statement * postmutate( TryStmt *tryStmt );
+	};
+
+	Statement * ExceptionMutatorCore::postmutate( ThrowStmt *throwStmt ) {
+		// Ignoring throwStmt->get_target() for now.
+		if ( ThrowStmt::Terminate == throwStmt->get_kind() ) {
+			if ( throwStmt->get_expr() ) {
+				return create_terminate_throw( throwStmt );
+			} else if ( TerHandler == curContext ) {
+				return create_terminate_rethrow( throwStmt );
+			} else {
+				assertf(false, "Invalid throw in %s at %i\n",
+					throwStmt->location.filename,
+					throwStmt->location.linenumber);
+				return nullptr;
+			}
+		} else {
+			if ( throwStmt->get_expr() ) {
+				return create_resume_throw( throwStmt );
+			} else if ( ResHandler == curContext ) {
+				return create_resume_rethrow( throwStmt );
+			} else {
+				assertf(false, "Invalid throwResume in %s at %i\n",
+					throwStmt->location.filename,
+					throwStmt->location.linenumber);
+				return nullptr;
+			}
+		}
+	}
+
+	Statement * ExceptionMutatorCore::postmutate( TryStmt *tryStmt ) {
+		// Generate a prefix for the function names?
+
+		CompoundStmt * block = new CompoundStmt();
+		Statement * inner = take_try_block( tryStmt );
+
+		if ( tryStmt->get_finally() ) {
+			// Define the helper function.
+			FunctionDecl * finally_block =
+				create_finally_wrapper( tryStmt );
+			appendDeclStmt( block, finally_block );
+			// Create and add the finally cleanup hook.
+			appendDeclStmt( block, create_finally_hook( finally_block ) );
+		}
+
+		StatementList termination_handlers;
+		StatementList resumption_handlers;
+		split( tryStmt->get_handlers(),
+		       termination_handlers, resumption_handlers );
+
+		if ( resumeption_handlers.size() ) {
+			// Define the helper function.
+			FunctionDecl * resume_handler =
+				create_resume_handler( resumption_handlers );
+			appendDeclStmt( block, resume_handler );
+			// Prepare hooks
+			inner = create_resume_wrapper( inner, resume_handler );
+		}
+
+		if ( termination_handlers.size() ) {
+			// Define the three helper functions.
+			FunctionDecl * try_wrapper = create_try_wrapper( inner );
+			appendDeclStmt( block, try_wrapper );
+			FunctionDecl * terminate_catch =
+				create_terminate_catch( termination_handlers );
+			appendDeclStmt( block, terminate_catch );
+			FunctionDecl * terminate_match =
+				create_terminate_match( termination_handlers );
+			appendDeclStmt( block, terminate_match );
+			// Build the call to the try wrapper.
+			inner = create_terminate_caller(
+				try_wrapper, terminate_catch, terminate_match );
+		}
+
+		// Embed the try block.
+		block->push_back( inner );
+
+		free_all( termination_handlers );
+		free_all( resumption_handlers );
+
+		return block;
+	}
+
+	void ExceptionMutatorCore::premutate( CatchStmt *catchStmt ) {
+		GuardValue( curContext );
+		if ( CatchStmt::Termination == catchStmt->get_kind() ) {
+			curContext = TerHandler;
+		} else {
+			curContext = ResHandler;
+		}
+	}
+
+    void translateEHM( std::list< Declaration *> & translationUnit ) {
+		PassVisitor<ExceptionMutatorCore> translator;
+		for ( Declaration * decl : translationUnit ) {
+			decl->mutate( translator );
+		}
+	}
+}
