Index: src/ControlStruct/ExceptDecl.cc
===================================================================
--- src/ControlStruct/ExceptDecl.cc	(revision 0c730d99f3adb5e9d0dd1dea118413d63b716406)
+++ src/ControlStruct/ExceptDecl.cc	(revision 0c730d99f3adb5e9d0dd1dea118413d63b716406)
@@ -0,0 +1,238 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// ExceptDecl.cc --
+//
+// Author           : Henry Xue
+// Created On       : Tue Jul 20 04:10:50 2021
+// Last Modified By : Henry Xue
+// Last Modified On : Tue Jul 20 04:10:50 2021
+// Update Count     : 1
+//
+
+#include "ExceptDecl.h"
+
+#include "Common/PassVisitor.h"  // for PassVisitor
+#include "SynTree/Mutator.h"     // for mutateAll
+#include "Virtual/Tables.h"      // for helpers
+
+namespace ControlStruct {
+
+StructDecl * ehmTypeIdStruct( const std::string & exceptionName, std::list< TypeDecl *> * parameters ) {
+	StructDecl * structDecl = new StructDecl( Virtual::typeIdType( exceptionName ) );
+	structDecl->members.push_back( new ObjectDecl(
+		"parent",
+		noStorageClasses,
+		LinkageSpec::Cforall,
+		nullptr,
+		new PointerType( noQualifiers,
+			new TypeInstType( Type::Const, "__cfavir_type_info", false ) ),
+		nullptr
+	) );
+	structDecl->set_body( true );
+	if ( parameters ) {
+		structDecl->parameters = *parameters;
+	}
+	return structDecl;
+}
+
+ObjectDecl * ehmTypeIdValue( const std::string & exceptionName, std::list< Expression *> * parameters ) {
+	StructInstType * structInstType = new StructInstType( Type::Const, Virtual::typeIdType( exceptionName ) );
+	if ( parameters ) {
+		structInstType->parameters = *parameters;
+	}
+	return new ObjectDecl(
+		Virtual::typeIdName( exceptionName ),
+		noStorageClasses,
+		LinkageSpec::Cforall,
+		nullptr,
+		structInstType,
+		new ListInit( { new SingleInit(
+			new AddressExpr( new NameExpr( "__cfatid_exception_t" ) )
+			) }, {}, true ),
+		{ new Attribute( "cfa_linkonce" ) }
+	);
+}
+
+StructDecl * ehmExceptionStructDecl( const std::string & exceptionName, std::list< TypeDecl *> * parameters ) {
+	StructDecl * structDecl = new StructDecl( exceptionName );
+	if ( parameters ) {
+		structDecl->parameters = *parameters;
+	}
+	return structDecl;
+}
+
+StructDecl * ehmVirtualTableStruct( const std::string & exceptionName, std::list< TypeDecl *> * parameters ) {
+	// _EHM_TYPE_ID_TYPE(exception_name) parameters const * __cfavir_typeid;
+	ObjectDecl * typeId = new ObjectDecl(
+		"__cfavir_typeid",
+		noStorageClasses,
+		LinkageSpec::Cforall,
+		nullptr,
+		new PointerType( noQualifiers,
+			new StructInstType( Type::Const, Virtual::typeIdType( exceptionName ) ) ),
+		nullptr
+	);
+
+	// size_t size;
+	ObjectDecl * size = new ObjectDecl(
+		"size",
+		noStorageClasses,
+		LinkageSpec::Cforall,
+		nullptr,
+		new TypeInstType( noQualifiers, "size_t", false ),
+		nullptr
+	);
+	
+	// void (*copy)(exception_name parameters * this, exception_name parameters * other);
+	FunctionType * copyFnType = new FunctionType( noQualifiers, false );
+	copyFnType->get_parameters().push_back( new ObjectDecl(
+		"this",
+		noStorageClasses,
+		LinkageSpec::Cforall,
+		nullptr,
+		new PointerType( noQualifiers,
+			new TypeInstType( noQualifiers, exceptionName, false ) ),
+		nullptr
+	) );
+	copyFnType->get_parameters().push_back( new ObjectDecl(
+		"other",
+		noStorageClasses,
+		LinkageSpec::Cforall,
+		nullptr,
+		new PointerType( noQualifiers,
+			new TypeInstType( noQualifiers, exceptionName, false ) ),
+		nullptr
+	) );
+	copyFnType->get_returnVals().push_back( new ObjectDecl(
+		"",
+		noStorageClasses,
+		LinkageSpec::Cforall,
+		nullptr,
+		new VoidType( noQualifiers ),
+		nullptr
+	) );
+	ObjectDecl * copy = new ObjectDecl(
+		"copy",
+		noStorageClasses,
+		LinkageSpec::Cforall,
+		nullptr,
+		new PointerType( noQualifiers, copyFnType ),
+		nullptr
+	);
+
+	// void (*^?{})(exception_name parameters & this);
+	FunctionType * dtorFnType = new FunctionType( noQualifiers, false );
+	dtorFnType->get_parameters().push_back( new ObjectDecl(
+		"this",
+		noStorageClasses,
+		LinkageSpec::Cforall,
+		nullptr,
+		new ReferenceType( noQualifiers,
+			new TypeInstType( noQualifiers, exceptionName, false ) ),
+		nullptr
+	) );
+	dtorFnType->get_returnVals().push_back( new ObjectDecl(
+		"",
+		noStorageClasses,
+		LinkageSpec::Cforall,
+		nullptr,
+		new VoidType( noQualifiers ),
+		nullptr
+	) );
+	ObjectDecl * dtor = new ObjectDecl(
+		"^?{}",
+		noStorageClasses,
+		LinkageSpec::Cforall,
+		nullptr,
+		new PointerType( noQualifiers, dtorFnType ),
+		nullptr
+	);
+
+	// const char * (*msg)(exception_name parameters * this);
+	FunctionType * msgFnType = new FunctionType( noQualifiers, false );
+	msgFnType->get_parameters().push_back( new ObjectDecl(
+		"this",
+		noStorageClasses,
+		LinkageSpec::Cforall,
+		nullptr,
+		new PointerType( noQualifiers,
+			new TypeInstType( noQualifiers, exceptionName, false ) ),
+		nullptr
+	) );
+	msgFnType->get_returnVals().push_back( new ObjectDecl(
+		"",
+		noStorageClasses,
+		LinkageSpec::Cforall,
+		nullptr,
+		new PointerType( noQualifiers, new BasicType( Type::Const, BasicType::Char ) ),
+		nullptr
+	) );
+	ObjectDecl * msg = new ObjectDecl(
+		"msg",
+		noStorageClasses,
+		LinkageSpec::Cforall,
+		nullptr,
+		new PointerType( noQualifiers, msgFnType ),
+		nullptr
+	);
+
+	StructDecl * structDecl = new StructDecl( Virtual::vtableTypeName( exceptionName ) );
+	structDecl->members.push_back( typeId );
+	structDecl->members.push_back( size );
+	structDecl->members.push_back( copy );
+	structDecl->members.push_back( dtor );
+	structDecl->members.push_back( msg );
+	structDecl->set_body( true );
+	if ( parameters ) {
+		structDecl->parameters = *parameters;
+	}
+	return structDecl;
+}
+
+StructDecl * ehmExceptionStruct( const std::string & exceptionName, const std::list<Declaration*> & members,
+								 std::list<TypeDecl *> * parameters ) {
+	StructDecl * structDecl = new StructDecl( exceptionName );
+	structDecl->members = members;
+	structDecl->members.push_front( new ObjectDecl(
+		"virtual_table",
+		noStorageClasses,
+		LinkageSpec::Cforall,
+		nullptr,
+		new PointerType( noQualifiers,
+			new StructInstType( Type::Const, Virtual::vtableTypeName( exceptionName ) ) ),
+		nullptr
+	) );
+	structDecl->set_body( true );
+	if ( parameters ) {
+		structDecl->parameters = *parameters;
+	}
+	return structDecl;
+}
+
+class ExceptDeclCore : public WithDeclsToAdd {
+public:
+	Declaration * postmutate( StructDecl * structDecl );
+};
+
+Declaration * ExceptDeclCore::postmutate( StructDecl * structDecl ) {
+	if ( structDecl->is_exception() ) {
+		const std::string & exceptionName = structDecl->name;
+		declsToAddBefore.push_back( ehmTypeIdStruct( exceptionName, nullptr ) );
+		declsToAddBefore.push_back( ehmTypeIdValue( exceptionName, nullptr ) );
+		declsToAddBefore.push_back( ehmExceptionStructDecl( exceptionName, nullptr ) );
+		declsToAddBefore.push_back( ehmVirtualTableStruct( exceptionName, nullptr ) );
+		return ehmExceptionStruct( exceptionName, structDecl->get_members(), nullptr );
+	}
+	return structDecl;
+}
+
+void translateExcept( std::list< Declaration *> & translationUnit ) {
+	PassVisitor<ExceptDeclCore> translator;
+	mutateAll( translationUnit, translator );
+}
+
+}
Index: src/ControlStruct/ExceptDecl.h
===================================================================
--- src/ControlStruct/ExceptDecl.h	(revision 0c730d99f3adb5e9d0dd1dea118413d63b716406)
+++ src/ControlStruct/ExceptDecl.h	(revision 0c730d99f3adb5e9d0dd1dea118413d63b716406)
@@ -0,0 +1,24 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// ExceptDecl.h --
+//
+// Author           : Henry Xue
+// Created On       : Tue Jul 20 04:10:50 2021
+// Last Modified By : Henry Xue
+// Last Modified On : Tue Jul 20 04:10:50 2021
+// Update Count     : 1
+//
+
+#pragma once
+
+#include <list>  // for list
+
+class Declaration;
+
+namespace ControlStruct {
+	void translateExcept( std::list< Declaration *> & translationUnit );
+}
Index: src/ControlStruct/module.mk
===================================================================
--- src/ControlStruct/module.mk	(revision f9b68d6fb9c867b6b46f5ddf1f0999759d9d443b)
+++ src/ControlStruct/module.mk	(revision 0c730d99f3adb5e9d0dd1dea118413d63b716406)
@@ -10,10 +10,12 @@
 ## Author           : Richard C. Bilson
 ## Created On       : Mon Jun  1 17:49:17 2015
-## Last Modified By : Andrew Beach
-## Last Modified On : Wed Jun 28 16:15:00 2017
-## Update Count     : 4
+## Last Modified By : Henry Xue
+## Last Modified On : Tue Jul 20 04:10:50 2021
+## Update Count     : 5
 ###############################################################################
 
 SRC_CONTROLSTRUCT = \
+	ControlStruct/ExceptDecl.cc \
+	ControlStruct/ExceptDecl.h \
 	ControlStruct/ForExprMutator.cc \
 	ControlStruct/ForExprMutator.h \
Index: src/Parser/TypeData.cc
===================================================================
--- src/Parser/TypeData.cc	(revision f9b68d6fb9c867b6b46f5ddf1f0999759d9d443b)
+++ src/Parser/TypeData.cc	(revision 0c730d99f3adb5e9d0dd1dea118413d63b716406)
@@ -9,7 +9,7 @@
 // Author           : Rodolfo G. Esteves
 // Created On       : Sat May 16 15:12:51 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Jul 14 18:57:31 2021
-// Update Count     : 672
+// Last Modified By : Henry Xue
+// Last Modified On : Tue Jul 20 04:10:50 2021
+// Update Count     : 673
 //
 
@@ -778,4 +778,5 @@
 	  case AggregateDecl::Struct:
 	  case AggregateDecl::Coroutine:
+	  case AggregateDecl::Exception:
 	  case AggregateDecl::Generator:
 	  case AggregateDecl::Monitor:
Index: src/SynTree/Declaration.h
===================================================================
--- src/SynTree/Declaration.h	(revision f9b68d6fb9c867b6b46f5ddf1f0999759d9d443b)
+++ src/SynTree/Declaration.h	(revision 0c730d99f3adb5e9d0dd1dea118413d63b716406)
@@ -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 Mar 12 18:35:36 2021
-// Update Count     : 159
+// Last Modified By : Henry Xue
+// Last Modified On : Tue Jul 20 04:10:50 2021
+// Update Count     : 160
 //
 
@@ -300,4 +300,5 @@
 
 	bool is_coroutine() { return kind == Coroutine; }
+	bool is_exception() { return kind == Exception; }
 	bool is_generator() { return kind == Generator; }
 	bool is_monitor  () { return kind == Monitor  ; }
Index: src/main.cc
===================================================================
--- src/main.cc	(revision f9b68d6fb9c867b6b46f5ddf1f0999759d9d443b)
+++ src/main.cc	(revision 0c730d99f3adb5e9d0dd1dea118413d63b716406)
@@ -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 Mar  6 15:49:00 2021
-// Update Count     : 656
+// Last Modified By : Henry Xue
+// Last Modified On : Tue Jul 20 04:10:50 2021
+// Update Count     : 657
 //
 
@@ -49,4 +49,5 @@
 #include "Common/utility.h"                 // for deleteAll, filter, printAll
 #include "Concurrency/Waitfor.h"            // for generateWaitfor
+#include "ControlStruct/ExceptDecl.h"       // for translateExcept
 #include "ControlStruct/ExceptTranslate.h"  // for translateEHM
 #include "ControlStruct/Mutate.h"           // for mutate
@@ -305,4 +306,6 @@
 		CodeTools::fillLocations( translationUnit );
 		Stats::Time::StopBlock();
+
+		PASS( "Translate Exception Declarations", ControlStruct::translateExcept( translationUnit ) );
 
 		// add the assignment statement after the initialization of a type parameter
