Index: doc/theses/thierry_delisle_PhD/thesis/text/existing.tex
===================================================================
--- doc/theses/thierry_delisle_PhD/thesis/text/existing.tex	(revision d67735510bcb770552b5898e5b45fc6bc07534aa)
+++ doc/theses/thierry_delisle_PhD/thesis/text/existing.tex	(revision 6726a3a9cf8ffacc8cccb80819bb2c1d2687cfed)
@@ -14,5 +14,7 @@
 
 \section{Naming Convention}
-Scheduling has been studied by various communities concentrating on different incarnation of the same problems. As a result, there are no standard naming conventions for scheduling that is respected across these communities. This document uses the term \newterm{\Gls{at}} to refer to the abstract objects being scheduled and the term \newterm{\Gls{proc}} to refer to the concrete objects executing these \ats.
+Scheduling has been studied by various communities concentrating on different incarnation of the same problems. 
+As a result, there are no standard naming conventions for scheduling that is respected across these communities. 
+This document uses the term \newterm{\Gls{at}} to refer to the abstract objects being scheduled and the term \newterm{\Gls{proc}} to refer to the concrete objects executing these \ats.
 
 \section{Static Scheduling}
@@ -26,5 +28,6 @@
 \section{Dynamic Scheduling}
 \newterm{Dynamic schedulers} determine \ats dependencies and costs during scheduling, if at all.
-Hence, unlike static scheduling, \ats dependencies are conditional and detected at runtime. This detection takes the form of observing new \ats(s) in the system and determining dependencies from their behaviour, including suspending or halting a \ats that dynamically detects unfulfilled dependencies.
+Hence, unlike static scheduling, \ats dependencies are conditional and detected at runtime. 
+This detection takes the form of observing new \ats(s) in the system and determining dependencies from their behaviour, including suspending or halting a \ats that dynamically detects unfulfilled dependencies.
 Furthermore, each \ats has the responsibility of adding dependent \ats back into the system once dependencies are fulfilled.
 As a consequence, the scheduler often has an incomplete view of the system, seeing only \ats with no pending dependencies.
Index: doc/theses/thierry_delisle_PhD/thesis/text/io.tex
===================================================================
--- doc/theses/thierry_delisle_PhD/thesis/text/io.tex	(revision d67735510bcb770552b5898e5b45fc6bc07534aa)
+++ doc/theses/thierry_delisle_PhD/thesis/text/io.tex	(revision 6726a3a9cf8ffacc8cccb80819bb2c1d2687cfed)
@@ -1,4 +1,4 @@
 \chapter{User Level \io}
-As mentioned in Section~\ref{prev:io}, user-Level \io requires multiplexing the \io operations of many \glspl{thrd} onto fewer \glspl{proc} using asynchronous \io operations.
+As mentioned in Section~\ref{prev:io}, user-level \io requires multiplexing the \io operations of many \glspl{thrd} onto fewer \glspl{proc} using asynchronous \io operations.
 Different operating systems offer various forms of asynchronous operations and, as mentioned in Chapter~\ref{intro}, this work is exclusively focused on the Linux operating-system.
 
@@ -72,5 +72,5 @@
 
 \paragraph{\lstinline{poll}} is the next oldest option, and takes as input an array of structures containing the FD numbers rather than their position in an array of bits, allowing a more compact input for interest sets that contain widely spaced FDs.
-(For small interest sets with densely packed FDs, the @select@ bit mask can take less storage, and hence, copy less information into the kernel.)
+For small interest sets with densely packed FDs, the @select@ bit mask can take less storage, and hence, copy less information into the kernel.
 Furthermore, @poll@ is non-destructive, so the array of structures does not have to be re-initialize on every call.
 Like @select@, @poll@ suffers from the limitation that the interest set cannot be changed by other \gls{kthrd}, while a manager thread is blocked in @poll@.
@@ -277,8 +277,6 @@
 While this example is artificial, in the presence of many \glspl{thrd}, it is possible for this problem to arise ``in the wild''.
 Furthermore, this pattern is difficult to reliably detect and avoid.
-Once in this situation, the only escape is to interrupted the spinning \gls{thrd}, either directly or via some regular preemption (\eg time slicing).
+Once in this situation, the only escape is to interrupted the spinning \gls{thrd}, either directly or via some regular preemption, \eg time slicing.
 Having to interrupt \glspl{thrd} for this purpose is costly, the latency can be large between interrupts, and the situation may be hard to detect.
-% However, a more important reason why interrupting the \gls{thrd} is not a satisfying solution is that the \gls{proc} is using the instance it is tied to.
-% If it were to use it, then helping could be done as part of the usage.
 Interrupts are needed here entirely because the \gls{proc} is tied to an instance it is not using.
 Therefore, a more satisfying solution is for the \gls{thrd} submitting the operation to notice that the instance is unused and simply go ahead and use it.
@@ -301,5 +299,4 @@
 Free SQEs, \ie, SQEs that are not currently being used to represent a request, can be written to safely and have a field called @user_data@ that the kernel only reads to copy to @cqe@s.
 Allocation also requires no ordering guarantee as all free SQEs are interchangeable.
-% This requires a simple concurrent bag.
 The only added complexity is that the number of SQEs is fixed, which means allocation can fail.
 
@@ -310,5 +307,5 @@
 
 Once an SQE is filled in, it is added to the submission ring buffer, an operation that is not thread-safe, and then the kernel must be notified using the @io_uring_enter@ system call.
-The submission ring buffer is the same size as the pre-allocated SQE buffer, therefore pushing to the ring buffer cannot fail because it is invalid to have the same \lstinline{sqe} multiple times in a ring buffer.
+The submission ring buffer is the same size as the pre-allocated SQE buffer, therefore pushing to the ring buffer cannot fail because it would mean a \lstinline{sqe} multiple times in the ring buffer, which is undefined behaviour.
 However, as mentioned, the system call itself can fail with the expectation that it can be retried once some submitted operations complete.
 
@@ -346,10 +343,10 @@
 While instance borrowing looks similar to work sharing and stealing, I think it is different enough to warrant a different verb to avoid confusion.}
 
-In this approach, each cluster (see Figure~\ref{fig:system}) owns a pool of @io_uring@ instances managed by an \newterm{arbiter}.
+In this approach, each cluster, see Figure~\ref{fig:system}, owns a pool of @io_uring@ instances managed by an \newterm{arbiter}.
 When a \gls{thrd} attempts to issue an \io operation, it ask for an instance from the arbiter and issues requests to that instance.
 This instance is now bound to the \gls{proc} the \gls{thrd} is running on.
 This binding is kept until the arbiter decides to revoke it, taking back the instance and reverting the \gls{proc} to its initial state with respect to \io.
 This tight coupling means that synchronization can be minimal since only one \gls{proc} can use the instance at a time, akin to the private instances approach.
-However, it differs in that revocation by the arbiter (an interrupt) means this approach does not suffer from the deadlock scenario described above.
+However, it differs in that revocation by the arbiter means this approach does not suffer from the deadlock scenario described above.
 
 Arbitration is needed in the following cases:
@@ -377,5 +374,5 @@
 
 \paragraph{External Submissions} are handled by the arbiter by revoking the appropriate instance and adding the submission to the submission ring.
-However,  there is no need to immediately revoke the instance.
+However, there is no need to immediately revoke the instance.
 External submissions must simply be added to the ring before the next system call, \ie, when the submission ring is flushed.
 This means whoever is responsible for the system call, first checks if the instance has any external submissions.
@@ -453,5 +450,4 @@
 
 \section{Interface}
-
 The last important part of the \io subsystem is its interface.
 There are multiple approaches that can be offered to programmers, each with advantages and disadvantages.
Index: src/AST/Expr.cpp
===================================================================
--- src/AST/Expr.cpp	(revision d67735510bcb770552b5898e5b45fc6bc07534aa)
+++ src/AST/Expr.cpp	(revision 6726a3a9cf8ffacc8cccb80819bb2c1d2687cfed)
@@ -272,5 +272,5 @@
 	// Adjust the length of the string for the terminator.
 	const Expr * strSize = from_ulong( loc, str.size() + 1 );
-	const Type * strType = new ArrayType( charType, strSize, FixedLen, StaticDim );
+	const Type * strType = new ArrayType( charType, strSize, FixedLen, DynamicDim );
 	const std::string strValue = "\"" + str + "\"";
 	return new ConstantExpr( loc, strType, strValue, std::nullopt );
Index: src/CodeGen/FixNames.cc
===================================================================
--- src/CodeGen/FixNames.cc	(revision d67735510bcb770552b5898e5b45fc6bc07534aa)
+++ src/CodeGen/FixNames.cc	(revision 6726a3a9cf8ffacc8cccb80819bb2c1d2687cfed)
@@ -5,11 +5,11 @@
 // file "LICENCE" distributed with Cforall.
 //
-// FixNames.cc --
+// FixNames.cc -- Adjustments to typed declarations.
 //
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Andrew Beach
-// Last Modified On : Fri Oct 29 15:49:00 2021
-// Update Count     : 23
+// Last Modified On : Wed Jul 20 11:49:00 2022
+// Update Count     : 24
 //
 
@@ -87,5 +87,5 @@
 
 /// Does work with the main function and scopeLevels.
-class FixNames_new : public ast::WithGuards {
+class FixNames_new final {
 	int scopeLevel = 1;
 
@@ -103,14 +103,10 @@
 
 	const ast::FunctionDecl *postvisit( const ast::FunctionDecl *functionDecl ) {
-		// This store is used to ensure a maximum of one call to mutate.
-		ast::FunctionDecl * mutDecl = nullptr;
+		if ( FixMain::isMain( functionDecl ) ) {
+			auto mutDecl = ast::mutate( functionDecl );
 
-		if ( shouldSetScopeLevel( functionDecl ) ) {
-			mutDecl = ast::mutate( functionDecl );
-			mutDecl->scopeLevel = scopeLevel;
-		}
-
-		if ( FixMain::isMain( functionDecl ) ) {
-			if ( !mutDecl ) { mutDecl = ast::mutate( functionDecl ); }
+			if ( shouldSetScopeLevel( mutDecl ) ) {
+				mutDecl->scopeLevel = scopeLevel;
+			}
 
 			int nargs = mutDecl->params.size();
@@ -124,10 +120,19 @@
 				)
 			);
+
+			return mutDecl;
+		} else if ( shouldSetScopeLevel( functionDecl ) ) {
+			return ast::mutate_field( functionDecl, &ast::FunctionDecl::scopeLevel, scopeLevel );
+		} else {
+			return functionDecl;
 		}
-		return mutDecl ? mutDecl : functionDecl;
 	}
 
 	void previsit( const ast::CompoundStmt * ) {
-		GuardValue( scopeLevel ) += 1;
+		scopeLevel += 1;
+	}
+
+	void postvisit( const ast::CompoundStmt * ) {
+		scopeLevel -= 1;
 	}
 };
Index: src/CodeGen/FixNames.h
===================================================================
--- src/CodeGen/FixNames.h	(revision d67735510bcb770552b5898e5b45fc6bc07534aa)
+++ src/CodeGen/FixNames.h	(revision 6726a3a9cf8ffacc8cccb80819bb2c1d2687cfed)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// FixNames.h --
+// FixNames.h -- Adjustments to typed declarations.
 //
 // Author           : Richard C. Bilson
@@ -26,5 +26,6 @@
 	/// mangles object and function names
 	void fixNames( std::list< Declaration* > & translationUnit );
-	void fixNames( ast::TranslationUnit & translationUnit );
+/// Sets scope levels and fills in main's default return.
+void fixNames( ast::TranslationUnit & translationUnit );
 } // namespace CodeGen
 
Index: src/Concurrency/Keywords.h
===================================================================
--- src/Concurrency/Keywords.h	(revision d67735510bcb770552b5898e5b45fc6bc07534aa)
+++ src/Concurrency/Keywords.h	(revision 6726a3a9cf8ffacc8cccb80819bb2c1d2687cfed)
@@ -28,9 +28,9 @@
 	void implementThreadStarter( std::list< Declaration * > & translationUnit );
 
-/// Implement the sue-like keywords and the suspend keyword.
+/// Implement the sue-like keywords and the suspend keyword. Pre-Autogen
 void implementKeywords( ast::TranslationUnit & translationUnit );
-/// Implement the mutex parameters and mutex statement.
+/// Implement the mutex parameters and mutex statement. Post-Autogen
 void implementMutex( ast::TranslationUnit & translationUnit );
-/// Add the thread starter code to constructors.
+/// Add the thread starter code to constructors. Post-Autogen
 void implementThreadStarter( ast::TranslationUnit & translationUnit );
 };
Index: src/ControlStruct/ExceptDecl.cc
===================================================================
--- src/ControlStruct/ExceptDecl.cc	(revision d67735510bcb770552b5898e5b45fc6bc07534aa)
+++ src/ControlStruct/ExceptDecl.cc	(revision 6726a3a9cf8ffacc8cccb80819bb2c1d2687cfed)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// ExceptDecl.cc --
+// ExceptDecl.cc -- Handles declarations of exception types.
 //
 // Author           : Henry Xue
Index: src/ControlStruct/ExceptDecl.h
===================================================================
--- src/ControlStruct/ExceptDecl.h	(revision d67735510bcb770552b5898e5b45fc6bc07534aa)
+++ src/ControlStruct/ExceptDecl.h	(revision 6726a3a9cf8ffacc8cccb80819bb2c1d2687cfed)
@@ -5,11 +5,11 @@
 // file "LICENCE" distributed with Cforall.
 //
-// ExceptDecl.h --
+// ExceptDecl.h -- Handles declarations of exception types.
 //
 // 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
+// Last Modified By : Andrew Beach
+// Last Modified On : Tue Jul 12 15:49:00 2022
+// Update Count     : 2
 //
 
@@ -20,5 +20,12 @@
 class Declaration;
 
+namespace ast {
+	class TranslationUnit;
+}
+
 namespace ControlStruct {
-	void translateExcept( std::list< Declaration *> & translationUnit );
+/// Unfold exception declarations into raw structure declarations.
+/// Also builds vtable declarations and converts vtable types.
+void translateExcept( std::list< Declaration *> & translationUnit );
+void translateExcept( ast::TranslationUnit & translationUnit );
 }
Index: src/ControlStruct/ExceptDeclNew.cpp
===================================================================
--- src/ControlStruct/ExceptDeclNew.cpp	(revision 6726a3a9cf8ffacc8cccb80819bb2c1d2687cfed)
+++ src/ControlStruct/ExceptDeclNew.cpp	(revision 6726a3a9cf8ffacc8cccb80819bb2c1d2687cfed)
@@ -0,0 +1,544 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2018 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// ExceptDeclNew.cpp --
+//
+// Author           : Andrew Beach
+// Created On       : Tue Jul 12 15:50:00 2022
+// Last Modified By : Andrew Beach
+// Last Modified On : Mon Jul 18 11:01:00 2022
+// Update Count     : 0
+//
+
+#include "ExceptDecl.h"
+
+#include "AST/Decl.hpp"
+#include "AST/Pass.hpp"
+#include "AST/Print.hpp"
+#include "AST/Type.hpp"
+#include "Virtual/Tables.h"
+
+namespace ControlStruct {
+
+namespace {
+
+std::vector<ast::ptr<ast::Expr>> forallToParams(
+		std::vector<ast::ptr<ast::TypeDecl>> const & forall ) {
+	return map_range<std::vector<ast::ptr<ast::Expr>>>( forall,
+		[]( ast::ptr<ast::TypeDecl> const & decl ) {
+			return new ast::TypeExpr( decl->location,
+				new ast::TypeInstType( decl->name, decl->kind ) );
+		}
+	);
+}
+
+// A slightly argumented extra constructor, adds a deepCopy.
+ast::StructInstType * namedStructInstType(
+		std::string const & name, ast::CV::Qualifiers qualifiers,
+		std::vector<ast::ptr<ast::Expr>> const & params ) {
+	ast::StructInstType * type = new ast::StructInstType( name, qualifiers );
+	for ( ast::ptr<ast::Expr> const & param : params ) {
+		type->params.push_back( ast::deepCopy( param ) );
+	}
+	return type;
+}
+
+ast::StructInstType * createExceptionInstType(
+		std::string const & exceptionName,
+		std::vector<ast::ptr<ast::Expr>> const & params ) {
+	return namedStructInstType( exceptionName, ast::CV::Qualifiers(), params );
+}
+
+ast::StructInstType * createVTableInstType(
+		std::string const & exceptionName,
+		std::vector<ast::ptr<ast::Expr>> const & params ) {
+	std::string name = Virtual::vtableTypeName( exceptionName );
+	return namedStructInstType( name, ast::CV::Const, params );
+}
+
+ast::StructInstType * createTypeIdInstType(
+		std::string const & exceptionName,
+		std::vector<ast::ptr<ast::Expr>> const & params ) {
+	std::string name = Virtual::typeIdType( exceptionName );
+	return namedStructInstType( name, ast::CV::Const, params );
+}
+
+ast::FunctionType const * createCopyFuncType(
+		std::string const & exceptionName,
+		std::vector<ast::ptr<ast::Expr>> const & params ) {
+	ast::FunctionType * type = new ast::FunctionType( ast::FixedArgs );
+	type->params.push_back( new ast::PointerType(
+		createExceptionInstType( exceptionName, params ) ) );
+	type->params.push_back( new ast::PointerType(
+		createExceptionInstType( exceptionName, params ) ) );
+	type->returns.push_back( new ast::VoidType() );
+	return type;
+}
+
+ast::FunctionType const * createDtorFuncType(
+		std::string const & exceptionName,
+		std::vector<ast::ptr<ast::Expr>> const & params ) {
+	ast::FunctionType * type = new ast::FunctionType( ast::FixedArgs );
+	type->params.push_back( new ast::ReferenceType(
+		createExceptionInstType( exceptionName, params ) ) );
+	type->returns.push_back( new ast::VoidType() );
+	return type;
+}
+
+ast::FunctionType const * createMsgFuncType(
+		std::string const & exceptionName,
+		std::vector<ast::ptr<ast::Expr>> const & params ) {
+	ast::FunctionType * type = new ast::FunctionType( ast::FixedArgs );
+	type->params.push_back( new ast::PointerType(
+		createExceptionInstType( exceptionName, params ) ) );
+	type->returns.push_back( new ast::PointerType(
+		new ast::BasicType( ast::BasicType::Char, ast::CV::Const ) ) );
+	return type;
+}
+
+ast::StructDecl const * createTypeIdStruct(
+		CodeLocation const & location,
+		std::string const & exceptionName,
+		std::vector<ast::ptr<ast::TypeDecl>> const & forallClause ) {
+	ast::StructDecl * decl = new ast::StructDecl( location,
+			Virtual::typeIdType( exceptionName ) );
+	decl->members.push_back( new ast::ObjectDecl(
+		location,
+		"parent",
+		new ast::PointerType(
+			new ast::StructInstType( "__cfavir_type_info", ast::CV::Const ) ),
+		nullptr,
+		ast::Storage::Classes(),
+		ast::Linkage::Cforall
+	) );
+	decl->body = true;
+	for ( ast::ptr<ast::TypeDecl> const & param : forallClause ) {
+		decl->params.push_back( ast::deepCopy( param ) );
+	}
+	return decl;
+}
+
+ast::ObjectDecl const * createTypeIdValue(
+		CodeLocation const & location,
+		std::string const & exceptionName,
+		std::vector<ast::ptr<ast::Expr>> const & params ) {
+	ast::StructInstType * typeIdType =
+		createTypeIdInstType( exceptionName, params );
+	return new ast::ObjectDecl(
+		location,
+		Virtual::typeIdName( exceptionName ),
+		typeIdType,
+		new ast::ListInit( location, {
+			new ast::SingleInit( location,
+				new ast::AddressExpr( location,
+					new ast::NameExpr( location, "__cfatid_exception_t" ) ),
+				ast::MaybeConstruct ),
+		}, {}, ast::MaybeConstruct ),
+		ast::Storage::Classes(),
+		ast::Linkage::Cforall,
+		nullptr,
+		{ new ast::Attribute( "cfa_linkonce" ) }
+	);
+}
+
+ast::StructDecl const * createExceptionStructForward(
+		CodeLocation const & location,
+		std::string const & exceptionName,
+		std::vector<ast::ptr<ast::TypeDecl>> const & forall ) {
+	ast::StructDecl * decl = new ast::StructDecl( location, exceptionName );
+	for ( ast::ptr<ast::TypeDecl> const & param : forall ) {
+		decl->params.push_back( ast::deepCopy( param ) );
+	}
+	return decl;
+}
+
+ast::StructDecl const * createVirtualTableStruct(
+		CodeLocation const & location,
+		std::string const & exceptionName,
+		std::vector<ast::ptr<ast::TypeDecl>> const & forall,
+		std::vector<ast::ptr<ast::Expr>> const & params ) {
+	ast::StructInstType * typeIdType =
+		createTypeIdInstType( exceptionName, params );
+	ast::ObjectDecl * typeId = new ast::ObjectDecl(
+		location,
+		"__cfavir_typeid",
+		new ast::PointerType( typeIdType ),
+		nullptr,
+		ast::Storage::Classes(),
+		ast::Linkage::Cforall
+	);
+	ast::ObjectDecl * size = new ast::ObjectDecl(
+		location,
+		"size",
+		new ast::TypeInstType( "size_t", ast::TypeDecl::Dtype ),
+		nullptr,
+		ast::Storage::Classes(),
+		ast::Linkage::Cforall
+	);
+	ast::ObjectDecl * copy = new ast::ObjectDecl(
+		location,
+		"copy",
+		new ast::PointerType( createCopyFuncType( exceptionName, params ) ),
+		nullptr,
+		ast::Storage::Classes(),
+		ast::Linkage::Cforall
+	);
+	ast::ObjectDecl * dtor = new ast::ObjectDecl(
+		location,
+		"^?{}",
+		new ast::PointerType( createDtorFuncType( exceptionName, params ) ),
+		nullptr,
+		ast::Storage::Classes(),
+		ast::Linkage::Cforall
+	);
+	ast::ObjectDecl * msg = new ast::ObjectDecl(
+		location,
+		"msg",
+		new ast::PointerType( createMsgFuncType( exceptionName, params ) ),
+		nullptr,
+		ast::Storage::Classes(),
+		ast::Linkage::Cforall
+	);
+	ast::StructDecl * decl = new ast::StructDecl(
+		location,
+		Virtual::vtableTypeName( exceptionName ) );
+	decl->members.push_back( typeId );
+	decl->members.push_back( size );
+	decl->members.push_back( copy );
+	decl->members.push_back( dtor );
+	decl->members.push_back( msg );
+	decl->body = true;
+	for ( ast::ptr<ast::TypeDecl> const & param : forall ) {
+		decl->params.push_back( param );
+	}
+	return decl;
+}
+
+ast::StructDecl const * createExceptionStruct(
+		CodeLocation const & location,
+		std::string const & exceptionName,
+		std::vector<ast::ptr<ast::TypeDecl>> const & forallClause,
+		std::vector<ast::ptr<ast::Expr>> const & params,
+		std::vector<ast::ptr<ast::Decl>> const & members ) {
+	ast::StructDecl * decl = new ast::StructDecl( location, exceptionName );
+	decl->members.push_back( new ast::ObjectDecl(
+		location,
+		"virtual_table",
+		new ast::PointerType(
+			createVTableInstType( exceptionName, params ) ),
+		nullptr,
+		ast::Storage::Classes(),
+		ast::Linkage::Cforall
+	) );
+	for ( ast::ptr<ast::Decl> const & member : members ) {
+		decl->members.push_back( ast::deepCopy( member ) );
+	}
+	decl->body = true;
+	for ( ast::ptr<ast::TypeDecl> const & param : forallClause ) {
+		decl->params.push_back( ast::deepCopy( param ) );
+	}
+	return decl;
+}
+
+ast::ObjectDecl const * createExternTypeId(
+		CodeLocation const & location,
+		std::string const & exceptionName,
+		std::vector<ast::ptr<ast::Expr>> const & params ) {
+	return new ast::ObjectDecl(
+		location,
+		Virtual::typeIdName( exceptionName ),
+		createVTableInstType( exceptionName, params ),
+		nullptr,
+		ast::Storage::Extern,
+		ast::Linkage::Cforall,
+		nullptr,
+		{ new ast::Attribute( "cfa_linkonce" ) }
+	);
+}
+
+ast::ObjectDecl const * createExternVTable(
+		CodeLocation const & location,
+		std::string const & exceptionName,
+		std::vector<ast::ptr<ast::Expr>> const & params,
+		std::string const & tableName ) {
+	return new ast::ObjectDecl(
+		location,
+		tableName,
+		createVTableInstType( exceptionName, params ),
+		nullptr,
+		ast::Storage::Extern,
+		ast::Linkage::Cforall
+	);
+}
+
+ast::FunctionDecl const * createCopy(
+		CodeLocation const & location,
+		std::string const & exceptionName,
+		std::vector<ast::ptr<ast::Expr>> const & params ) {
+	return new ast::FunctionDecl(
+		location,
+		"copy",
+		{/* forall */},
+		{/* assertions */},
+		{
+			new ast::ObjectDecl(
+				location,
+				"this",
+				new ast::PointerType(
+					createExceptionInstType( exceptionName, params ) ),
+				nullptr,
+				ast::Storage::Classes(),
+				ast::Linkage::Cforall
+			),
+			new ast::ObjectDecl(
+				location,
+				"that",
+				new ast::PointerType(
+					createExceptionInstType( exceptionName, params ) ),
+				nullptr,
+				ast::Storage::Classes(),
+				ast::Linkage::Cforall
+			),
+		},
+		{
+			new ast::ObjectDecl(
+				location,
+				"",
+				new ast::VoidType(),
+				nullptr,
+				ast::Storage::Classes(),
+				ast::Linkage::Cforall
+			),
+		},
+		new ast::CompoundStmt( location, {
+			new ast::ExprStmt( location,
+				new ast::UntypedExpr( location,
+					new ast::NameExpr( location, "?=?" ),
+					{
+						new ast::UntypedExpr( location,
+							new ast::NameExpr( location, "*?" ),
+							{ new ast::NameExpr( location, "this" ) } ),
+						new ast::UntypedExpr( location,
+							new ast::NameExpr( location, "*?" ),
+							{ new ast::NameExpr( location, "that" ) } ),
+					}
+				)
+			),
+		} ),
+		ast::Storage::Classes(),
+		ast::Linkage::Cforall
+	);
+}
+
+ast::FunctionDecl const * createMsg(
+		CodeLocation const & location,
+		std::string const & exceptionName,
+		std::vector<ast::ptr<ast::Expr>> const & params ) {
+	std::stringstream msg;
+	msg << exceptionName;
+	// The forall variant, add parameters to the string.
+	if ( !params.empty() ) {
+		msg << "(";
+		bool first = true;
+		for ( auto & param : params ) {
+			// Seperator Logic: A comma proceeds all but the first object.
+			if ( first ) {
+				first = false;
+			} else {
+				msg << ", ";
+			}
+
+			ast::print( msg, param.get() );
+		}
+		msg << ")";
+	}
+	return new ast::FunctionDecl(
+		location,
+		"msg",
+		{/* forall */},
+		{/* assertions */},
+		{
+			new ast::ObjectDecl(
+				location,
+				"this",
+				new ast::PointerType(
+					createExceptionInstType( exceptionName, params ) ),
+				nullptr,
+				ast::Storage::Classes(),
+				ast::Linkage::Cforall
+			),
+		},
+		{
+			new ast::ObjectDecl(
+				location,
+				"",
+				new ast::PointerType(
+					new ast::BasicType( ast::BasicType::Char, ast::CV::Const ) ),
+				nullptr,
+				ast::Storage::Classes(),
+				ast::Linkage::Cforall
+			),
+		},
+		new ast::CompoundStmt( location, {
+			new ast::ReturnStmt( location,
+				ast::ConstantExpr::from_string( location, msg.str() )
+			),
+		} ),
+		ast::Storage::Classes(),
+		ast::Linkage::Cforall
+	);
+}
+
+ast::ObjectDecl const * createVirtualTable(
+		CodeLocation const & location,
+		std::string const & exceptionName,
+		std::vector<ast::ptr<ast::Expr>> const & params,
+		std::string const & tableName ) {
+	ast::StructInstType * sizeType = new ast::StructInstType( exceptionName );
+	for ( ast::ptr<ast::Expr> const & param : params ) {
+		sizeType->params.push_back( ast::deepCopy( param ) );
+	}
+	std::vector<ast::ptr<ast::Init>> inits {
+		new ast::SingleInit( location,
+			new ast::AddressExpr( location,
+				new ast::NameExpr( location,
+					Virtual::typeIdName( exceptionName ) ) ) ),
+		new ast::SingleInit( location,
+			new ast::SizeofExpr( location, sizeType )  ),
+		new ast::SingleInit( location,
+			new ast::NameExpr( location, "copy" ) ),
+		new ast::SingleInit( location,
+			new ast::NameExpr( location, "^?{}" ) ),
+		new ast::SingleInit( location,
+			new ast::NameExpr( location, "msg" ) ),
+	};
+	std::vector<ast::ptr<ast::Designation>> dsigs {
+		new ast::Designation( location, {
+			new ast::NameExpr( location, "__cfavir_typeid" ) } ),
+		new ast::Designation( location, {
+			new ast::NameExpr( location, "size" ) } ),
+		new ast::Designation( location, {
+			new ast::NameExpr( location, "copy" ) } ),
+		new ast::Designation( location, {
+			new ast::NameExpr( location, "^?{}" ) } ),
+		new ast::Designation( location, {
+			new ast::NameExpr( location, "msg" ) } ),
+	};
+	return new ast::ObjectDecl(
+		location,
+		tableName,
+		createVTableInstType( exceptionName, params ),
+		new ast::ListInit( location, std::move( inits ), std::move( dsigs ) ),
+		ast::Storage::Classes(),
+		ast::Linkage::Cforall
+	);
+}
+
+struct ExceptDeclCore : public ast::WithDeclsToAdd<> {
+	ast::StructDecl const * transformExcept( ast::StructDecl const * decl );
+	ast::ObjectDecl const * transformVTable(
+		ast::ObjectDecl const * decl, ast::VTableType const * type );
+
+	ast::StructDecl const * postvisit( ast::StructDecl const * decl ) {
+		// Exceptions don't get their own node type, so filter that.
+		if ( ast::AggregateDecl::Exception == decl->kind ) {
+			return transformExcept( decl );
+		}
+		return decl;
+	}
+
+	ast::ObjectDecl const * postvisit( ast::ObjectDecl const * decl ) {
+		// Modify remaining objects that have a vtable type.
+		if ( auto * type = decl->type.as<ast::VTableType>() ) {
+			return transformVTable( decl, type );
+		}
+		return decl;
+	}
+};
+
+ast::StructDecl const * ExceptDeclCore::transformExcept(
+		ast::StructDecl const * decl ) {
+	CodeLocation const & location = decl->location;
+	std::string const & exceptionName = decl->name;
+	std::vector<ast::ptr<ast::TypeDecl>> const & forall = decl->params;
+	std::vector<ast::ptr<ast::Expr>> params = forallToParams( forall );
+	std::vector<ast::ptr<ast::Decl>> const & members = decl->members;
+
+	declsToAddBefore.push_back(
+		createTypeIdStruct( location, exceptionName, forall ) );
+	if ( forall.empty() ) {
+		// Non-forall variant.
+		declsToAddBefore.push_back(
+			createTypeIdValue( location, exceptionName, params ) );
+	}
+	declsToAddBefore.push_back(
+		createExceptionStructForward( location, exceptionName, forall ) );
+	declsToAddBefore.push_back(
+		createVirtualTableStruct( location, exceptionName, forall, params ) );
+	return createExceptionStruct( location, exceptionName, forall, params, members );
+}
+
+ast::ObjectDecl const * ExceptDeclCore::transformVTable(
+		ast::ObjectDecl const * decl, ast::VTableType const * type ) {
+	CodeLocation const & location = decl->location;
+	auto base = type->base.strict_as<ast::TypeInstType>();
+	std::string const & exceptionName = base->name;
+	std::vector<ast::ptr<ast::Expr>> const & params = base->params;
+	std::string const & tableName = decl->name;
+
+	if ( decl->storage.is_extern ) {
+		// Unique type-ids are only needed for polymorphic instances.
+		if ( !params.empty() ) {
+			declsToAddBefore.push_back(
+				createExternTypeId( location, exceptionName, params ) );
+		}
+		return createExternVTable( location, exceptionName, params, tableName );
+	} else {
+		// Unique type-ids are only needed for polymorphic instances.
+		if ( !params.empty() ) {
+			declsToAddBefore.push_back(
+				createTypeIdValue( location, exceptionName, params ) );
+		}
+		declsToAddBefore.push_back(
+			createCopy( location, exceptionName, params ) );
+		declsToAddBefore.push_back(
+			createMsg( location, exceptionName, params ) );
+		return createVirtualTable(
+			location, exceptionName, params, tableName );
+	}
+}
+
+struct VTableCore {
+	ast::StructInstType const * postvisit( ast::VTableType const * type ) {
+		auto inst = type->base.as<ast::BaseInstType>();
+
+		std::string vtableName = Virtual::vtableTypeName( inst->name );
+		auto newType = new ast::StructInstType( vtableName );
+		for ( ast::ptr<ast::Expr> const & param : inst->params ) {
+			newType->params.push_back( param );
+		}
+
+		return newType;
+	}
+};
+
+} // namespace
+
+void translateExcept( ast::TranslationUnit & translationUnit ) {
+	// Can I combine these?
+	// Second pass really only covers what the first has missed.
+	// Maybe if the first one is all previsits and the second all postvisit.
+	ast::Pass<ExceptDeclCore>::run( translationUnit );
+	ast::Pass<VTableCore>::run( translationUnit );
+}
+
+} // namespace ControlStruct
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/ControlStruct/HoistControlDecls.hpp
===================================================================
--- src/ControlStruct/HoistControlDecls.hpp	(revision d67735510bcb770552b5898e5b45fc6bc07534aa)
+++ src/ControlStruct/HoistControlDecls.hpp	(revision 6726a3a9cf8ffacc8cccb80819bb2c1d2687cfed)
@@ -21,5 +21,6 @@
 
 namespace ControlStruct {
-// Hoist declarations out of control flow statements into compound statement.
+/// Hoist declarations out of control flow statements into compound statement.
+/// Must happen before auto-gen routines are added.
 void hoistControlDecls( ast::TranslationUnit & translationUnit );
 } // namespace ControlStruct
Index: src/ControlStruct/MultiLevelExit.cpp
===================================================================
--- src/ControlStruct/MultiLevelExit.cpp	(revision d67735510bcb770552b5898e5b45fc6bc07534aa)
+++ src/ControlStruct/MultiLevelExit.cpp	(revision 6726a3a9cf8ffacc8cccb80819bb2c1d2687cfed)
@@ -149,6 +149,5 @@
 };
 
-NullStmt * labelledNullStmt(
-	const CodeLocation & cl, const Label & label ) {
+NullStmt * labelledNullStmt( const CodeLocation & cl, const Label & label ) {
 	return new NullStmt( cl, vector<Label>{ label } );
 }
@@ -164,5 +163,5 @@
 
 const CompoundStmt * MultiLevelExitCore::previsit(
-	const CompoundStmt * stmt ) {
+		const CompoundStmt * stmt ) {
 	visit_children = false;
 
@@ -189,6 +188,5 @@
 }
 
-size_t getUnusedIndex(
-	const Stmt * stmt, const Label & originalTarget ) {
+size_t getUnusedIndex( const Stmt * stmt, const Label & originalTarget ) {
 	const size_t size = stmt->labels.size();
 
@@ -210,6 +208,5 @@
 }
 
-const Stmt * addUnused(
-	const Stmt * stmt, const Label & originalTarget ) {
+const Stmt * addUnused( const Stmt * stmt, const Label & originalTarget ) {
 	size_t i = getUnusedIndex( stmt, originalTarget );
 	if ( i == stmt->labels.size() ) {
@@ -356,6 +353,5 @@
 
 // Mimic what the built-in push_front would do anyways. It is O(n).
-void push_front(
-	vector<ptr<Stmt>> & vec, const Stmt * element ) {
+void push_front( vector<ptr<Stmt>> & vec, const Stmt * element ) {
 	vec.emplace_back( nullptr );
 	for ( size_t i = vec.size() - 1 ; 0 < i ; --i ) {
@@ -590,19 +586,15 @@
 
 		ptr<Stmt> else_stmt = nullptr;
-		Stmt * loop_kid = nullptr;
+		const Stmt * loop_kid = nullptr;
 		// check if loop node and if so add else clause if it exists
-		const WhileDoStmt * whilePtr = dynamic_cast<const WhileDoStmt *>(kid.get());
-		if ( whilePtr && whilePtr->else_) {
+		const WhileDoStmt * whilePtr = kid.as<WhileDoStmt>();
+		if ( whilePtr && whilePtr->else_ ) {
 			else_stmt = whilePtr->else_;
-			WhileDoStmt * mutate_ptr = mutate(whilePtr);
-			mutate_ptr->else_ = nullptr;
-			loop_kid = mutate_ptr;
-		}
-		const ForStmt * forPtr = dynamic_cast<const ForStmt *>(kid.get());
-		if ( forPtr && forPtr->else_) {
+			loop_kid = mutate_field( whilePtr, &WhileDoStmt::else_, nullptr );
+		}
+		const ForStmt * forPtr = kid.as<ForStmt>();
+		if ( forPtr && forPtr->else_ ) {
 			else_stmt = forPtr->else_;
-			ForStmt * mutate_ptr = mutate(forPtr);
-			mutate_ptr->else_ = nullptr;
-			loop_kid = mutate_ptr;
+			loop_kid = mutate_field( forPtr, &ForStmt::else_, nullptr );
 		}
 
Index: src/ControlStruct/module.mk
===================================================================
--- src/ControlStruct/module.mk	(revision d67735510bcb770552b5898e5b45fc6bc07534aa)
+++ src/ControlStruct/module.mk	(revision 6726a3a9cf8ffacc8cccb80819bb2c1d2687cfed)
@@ -17,4 +17,5 @@
 SRC += \
 	ControlStruct/ExceptDecl.cc \
+	ControlStruct/ExceptDeclNew.cpp \
 	ControlStruct/ExceptDecl.h \
 	ControlStruct/ExceptTranslateNew.cpp \
Index: src/InitTweak/GenInit.cc
===================================================================
--- src/InitTweak/GenInit.cc	(revision d67735510bcb770552b5898e5b45fc6bc07534aa)
+++ src/InitTweak/GenInit.cc	(revision 6726a3a9cf8ffacc8cccb80819bb2c1d2687cfed)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// GenInit.cc --
+// GenInit.cc -- Generate initializers, and other stuff.
 //
 // Author           : Rob Schluntz
Index: src/InitTweak/GenInit.h
===================================================================
--- src/InitTweak/GenInit.h	(revision d67735510bcb770552b5898e5b45fc6bc07534aa)
+++ src/InitTweak/GenInit.h	(revision 6726a3a9cf8ffacc8cccb80819bb2c1d2687cfed)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// GenInit.h --
+// GenInit.h -- Generate initializers, and other stuff.
 //
 // Author           : Rodolfo G. Esteves
@@ -29,5 +29,6 @@
 	void genInit( ast::TranslationUnit & translationUnit );
 
-	/// Converts return statements into copy constructor calls on the hidden return variable
+	/// Converts return statements into copy constructor calls on the hidden return variable.
+	/// This pass must happen before auto-gen.
 	void fixReturnStatements( std::list< Declaration * > & translationUnit );
 	void fixReturnStatements( ast::TranslationUnit & translationUnit );
Index: src/Tuples/Tuples.cc
===================================================================
--- src/Tuples/Tuples.cc	(revision d67735510bcb770552b5898e5b45fc6bc07534aa)
+++ src/Tuples/Tuples.cc	(revision 6726a3a9cf8ffacc8cccb80819bb2c1d2687cfed)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// Tuples.h --
+// Tuples.cc -- A collection of tuple operations.
 //
 // Author           : Andrew Beach
Index: src/Tuples/Tuples.h
===================================================================
--- src/Tuples/Tuples.h	(revision d67735510bcb770552b5898e5b45fc6bc07534aa)
+++ src/Tuples/Tuples.h	(revision 6726a3a9cf8ffacc8cccb80819bb2c1d2687cfed)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// Tuples.h --
+// Tuples.h -- A collection of tuple operations.
 //
 // Author           : Rodolfo G. Esteves
Index: src/Validate/Autogen.hpp
===================================================================
--- src/Validate/Autogen.hpp	(revision d67735510bcb770552b5898e5b45fc6bc07534aa)
+++ src/Validate/Autogen.hpp	(revision 6726a3a9cf8ffacc8cccb80819bb2c1d2687cfed)
@@ -22,4 +22,6 @@
 namespace Validate {
 
+/// Generate routines for all data types in the translation unit.
+/// A lot of passes have to happen either before or after this pass.
 void autogenerateRoutines( ast::TranslationUnit & translationUnit );
 
Index: src/Validate/CompoundLiteral.hpp
===================================================================
--- src/Validate/CompoundLiteral.hpp	(revision d67735510bcb770552b5898e5b45fc6bc07534aa)
+++ src/Validate/CompoundLiteral.hpp	(revision 6726a3a9cf8ffacc8cccb80819bb2c1d2687cfed)
@@ -23,4 +23,5 @@
 
 /// Use variables to implement compound literals.
+/// Must happen after auto-gen routines are added.
 void handleCompoundLiterals( ast::TranslationUnit & translationUnit );
 
Index: src/Validate/EnumAndPointerDecay.cpp
===================================================================
--- src/Validate/EnumAndPointerDecay.cpp	(revision d67735510bcb770552b5898e5b45fc6bc07534aa)
+++ src/Validate/EnumAndPointerDecay.cpp	(revision 6726a3a9cf8ffacc8cccb80819bb2c1d2687cfed)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// EnumAndPointerDecay.cpp --
+// EnumAndPointerDecay.cpp -- Normalizes enumerations and types in functions.
 //
 // Author           : Andrew Beach
Index: src/Validate/EnumAndPointerDecay.hpp
===================================================================
--- src/Validate/EnumAndPointerDecay.hpp	(revision d67735510bcb770552b5898e5b45fc6bc07534aa)
+++ src/Validate/EnumAndPointerDecay.hpp	(revision 6726a3a9cf8ffacc8cccb80819bb2c1d2687cfed)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// EnumAndPointerDecay.hpp --
+// EnumAndPointerDecay.hpp -- Normalizes enumerations and types in functions.
 //
 // Author           : Andrew Beach
@@ -22,4 +22,7 @@
 namespace Validate {
 
+/// Fix the parameter and return types of functions. Also assigns types to
+/// enumeration values. This must happen before Link Reference to Types,
+/// it needs correct types for mangling, and before auto-gen.
 void decayEnumsAndPointers( ast::TranslationUnit & translationUnit );
 
Index: src/Validate/FindSpecialDecls.h
===================================================================
--- src/Validate/FindSpecialDecls.h	(revision d67735510bcb770552b5898e5b45fc6bc07534aa)
+++ src/Validate/FindSpecialDecls.h	(revision 6726a3a9cf8ffacc8cccb80819bb2c1d2687cfed)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// FindSpecialDeclarations.h --
+// FindSpecialDeclarations.h -- Find special declarations used in the compiler.
 //
 // Author           : Rob Schluntz
@@ -43,5 +43,5 @@
 	void findSpecialDecls( std::list< Declaration * > & translationUnit );
 
-/// find and remember some of the special declarations that are useful for
+/// Find and remember some of the special declarations that are useful for
 /// generating code, so that they do not have to be discovered multiple times.
 void findGlobalDecls( ast::TranslationUnit & translationUnit );
Index: src/Validate/FixQualifiedTypes.cpp
===================================================================
--- src/Validate/FixQualifiedTypes.cpp	(revision d67735510bcb770552b5898e5b45fc6bc07534aa)
+++ src/Validate/FixQualifiedTypes.cpp	(revision 6726a3a9cf8ffacc8cccb80819bb2c1d2687cfed)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// FixQualifiedTypes.cpp --
+// FixQualifiedTypes.cpp -- Replace the qualified type with a direct type.
 //
 // Author           : Andrew Beach
@@ -76,5 +76,4 @@
 							ret->qualifiers = type->qualifiers;
 							ast::TypeSubstitution sub( aggr->params, instp->params );
-							// = parent->genericSubstitution();
 							auto result = sub.apply(ret);
 							return result.node.release();
Index: src/Validate/FixQualifiedTypes.hpp
===================================================================
--- src/Validate/FixQualifiedTypes.hpp	(revision d67735510bcb770552b5898e5b45fc6bc07534aa)
+++ src/Validate/FixQualifiedTypes.hpp	(revision 6726a3a9cf8ffacc8cccb80819bb2c1d2687cfed)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// FixQualifiedTypes.hpp --
+// FixQualifiedTypes.hpp -- Replace the qualified type with a direct type.
 //
 // Author           : Andrew Beach
@@ -22,4 +22,7 @@
 namespace Validate {
 
+/// Replaces qualified types with an unqualified NamedTypeDecl.
+/// Must happen after Link References To Types,
+/// because aggregate members are accessed.
 void fixQualifiedTypes( ast::TranslationUnit & translationUnit );
 
Index: src/Validate/FixReturnTypes.cpp
===================================================================
--- src/Validate/FixReturnTypes.cpp	(revision d67735510bcb770552b5898e5b45fc6bc07534aa)
+++ src/Validate/FixReturnTypes.cpp	(revision 6726a3a9cf8ffacc8cccb80819bb2c1d2687cfed)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// FixReturnTypes.cpp --
+// FixReturnTypes.cpp -- Unifies the representation of return types.
 //
 // Author           : Andrew Beach
Index: src/Validate/FixReturnTypes.hpp
===================================================================
--- src/Validate/FixReturnTypes.hpp	(revision d67735510bcb770552b5898e5b45fc6bc07534aa)
+++ src/Validate/FixReturnTypes.hpp	(revision 6726a3a9cf8ffacc8cccb80819bb2c1d2687cfed)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// FixReturnTypes.hpp --
+// FixReturnTypes.hpp -- Unifies the representation of return types.
 //
 // Author           : Andrew Beach
@@ -22,6 +22,7 @@
 namespace Validate {
 
-// This pass needs to happen early so that other passes can find tuple types
-// in the right places, especially for function return types.
+/// This pass needs to happen early so that other passes can find tuple types
+/// in the right places, especially for function return types.
+/// Must happen before auto-gen.
 void fixReturnTypes( ast::TranslationUnit & translationUnit );
 
Index: src/Validate/ForallPointerDecay.hpp
===================================================================
--- src/Validate/ForallPointerDecay.hpp	(revision d67735510bcb770552b5898e5b45fc6bc07534aa)
+++ src/Validate/ForallPointerDecay.hpp	(revision 6726a3a9cf8ffacc8cccb80819bb2c1d2687cfed)
@@ -29,4 +29,7 @@
 /// Also checks that operator names are used properly on functions and
 /// assigns unique IDs. This is a "legacy" pass.
+/// Must be after implement concurrent keywords; because uniqueIds must be
+/// set on declaration before resolution.
+/// Must happen before auto-gen routines are added.
 void decayForallPointers( ast::TranslationUnit & transUnit );
 
Index: src/Validate/GenericParameter.cpp
===================================================================
--- src/Validate/GenericParameter.cpp	(revision d67735510bcb770552b5898e5b45fc6bc07534aa)
+++ src/Validate/GenericParameter.cpp	(revision 6726a3a9cf8ffacc8cccb80819bb2c1d2687cfed)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// GenericParameter.hpp --
+// GenericParameter.hpp -- Generic parameter related passes.
 //
 // Author           : Andrew Beach
Index: src/Validate/GenericParameter.hpp
===================================================================
--- src/Validate/GenericParameter.hpp	(revision d67735510bcb770552b5898e5b45fc6bc07534aa)
+++ src/Validate/GenericParameter.hpp	(revision 6726a3a9cf8ffacc8cccb80819bb2c1d2687cfed)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// GenericParameter.hpp --
+// GenericParameter.hpp -- Generic parameter related passes.
 //
 // Author           : Andrew Beach
@@ -23,4 +23,6 @@
 
 /// Perform substutions for generic parameters and fill in defaults.
+/// Check as early as possible, but it can't happen before Link References to
+/// Types and observed failing when attempted before eliminate typedef.
 void fillGenericParameters( ast::TranslationUnit & translationUnit );
 
Index: src/Validate/HoistStruct.hpp
===================================================================
--- src/Validate/HoistStruct.hpp	(revision d67735510bcb770552b5898e5b45fc6bc07534aa)
+++ src/Validate/HoistStruct.hpp	(revision 6726a3a9cf8ffacc8cccb80819bb2c1d2687cfed)
@@ -22,5 +22,5 @@
 namespace Validate {
 
-/// Flattens nested type declarations.
+/// Flattens nested type declarations. (Run right after Fix Qualified Types.)
 void hoistStruct( ast::TranslationUnit & translationUnit );
 
Index: src/Validate/HoistTypeDecls.cpp
===================================================================
--- src/Validate/HoistTypeDecls.cpp	(revision d67735510bcb770552b5898e5b45fc6bc07534aa)
+++ src/Validate/HoistTypeDecls.cpp	(revision 6726a3a9cf8ffacc8cccb80819bb2c1d2687cfed)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// HoistTypeDecls.cpp --
+// HoistTypeDecls.cpp -- Hoists declarations of implicitly declared types.
 //
 // Author           : Andrew Beach
Index: src/Validate/HoistTypeDecls.hpp
===================================================================
--- src/Validate/HoistTypeDecls.hpp	(revision d67735510bcb770552b5898e5b45fc6bc07534aa)
+++ src/Validate/HoistTypeDecls.hpp	(revision 6726a3a9cf8ffacc8cccb80819bb2c1d2687cfed)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// HoistTypeDecls.hpp --
+// HoistTypeDecls.hpp -- Hoists declarations of implicitly declared types.
 //
 // Author           : Andrew Beach
@@ -22,4 +22,7 @@
 namespace Validate {
 
+/// There are some places where a type can be declared but are usually only
+/// referenced (with an *InstType). This inserts the declarations before
+/// they are referenced.
 void hoistTypeDecls( ast::TranslationUnit & translationUnit );
 
Index: src/Validate/LabelAddressFixer.cpp
===================================================================
--- src/Validate/LabelAddressFixer.cpp	(revision d67735510bcb770552b5898e5b45fc6bc07534aa)
+++ src/Validate/LabelAddressFixer.cpp	(revision 6726a3a9cf8ffacc8cccb80819bb2c1d2687cfed)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// LabelAddressFixer.cpp --
+// LabelAddressFixer.cpp -- Create label address expressions.
 //
 // Author           : Andrew Beach
Index: src/Validate/LabelAddressFixer.hpp
===================================================================
--- src/Validate/LabelAddressFixer.hpp	(revision d67735510bcb770552b5898e5b45fc6bc07534aa)
+++ src/Validate/LabelAddressFixer.hpp	(revision 6726a3a9cf8ffacc8cccb80819bb2c1d2687cfed)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// LabelAddressFixer.hpp --
+// LabelAddressFixer.hpp -- Create label address expressions.
 //
 // Author           : Andrew Beach
@@ -20,4 +20,6 @@
 namespace Validate {
 
+/// Label addresses are not actually created in the parser, this pass finds
+/// the patterns that represent the label address expression.
 void fixLabelAddresses( ast::TranslationUnit & translationUnit );
 
Index: src/Validate/LinkReferenceToTypes.hpp
===================================================================
--- src/Validate/LinkReferenceToTypes.hpp	(revision d67735510bcb770552b5898e5b45fc6bc07534aa)
+++ src/Validate/LinkReferenceToTypes.hpp	(revision 6726a3a9cf8ffacc8cccb80819bb2c1d2687cfed)
@@ -22,4 +22,7 @@
 namespace Validate {
 
+/// Fills in the base value of various instance types, and some related
+/// adjustments, such as setting the sized flag.
+/// Because of the sized flag, it must happen before auto-gen.
 void linkReferenceToTypes( ast::TranslationUnit & translationUnit );
 
Index: src/Validate/ReplaceTypedef.cpp
===================================================================
--- src/Validate/ReplaceTypedef.cpp	(revision d67735510bcb770552b5898e5b45fc6bc07534aa)
+++ src/Validate/ReplaceTypedef.cpp	(revision 6726a3a9cf8ffacc8cccb80819bb2c1d2687cfed)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// ReplaceTypedef.cpp --
+// ReplaceTypedef.cpp -- Fill in all typedefs with the underlying type.
 //
 // Author           : Andrew Beach
Index: src/Validate/ReplaceTypedef.hpp
===================================================================
--- src/Validate/ReplaceTypedef.hpp	(revision d67735510bcb770552b5898e5b45fc6bc07534aa)
+++ src/Validate/ReplaceTypedef.hpp	(revision 6726a3a9cf8ffacc8cccb80819bb2c1d2687cfed)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// ReplaceTypedef.hpp --
+// ReplaceTypedef.hpp -- Fill in all typedefs with the underlying type.
 //
 // Author           : Andrew Beach
@@ -22,4 +22,5 @@
 namespace Validate {
 
+/// Uses of typedef are replaced with the type in the typedef.
 void replaceTypedef( ast::TranslationUnit & translationUnit );
 
Index: src/Validate/VerifyCtorDtorAssign.cpp
===================================================================
--- src/Validate/VerifyCtorDtorAssign.cpp	(revision d67735510bcb770552b5898e5b45fc6bc07534aa)
+++ src/Validate/VerifyCtorDtorAssign.cpp	(revision 6726a3a9cf8ffacc8cccb80819bb2c1d2687cfed)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// VerifyCtorDtorAssign.cpp --
+// VerifyCtorDtorAssign.cpp -- Check the form of operators.
 //
 // Author           : Andrew Beach
Index: src/Validate/VerifyCtorDtorAssign.hpp
===================================================================
--- src/Validate/VerifyCtorDtorAssign.hpp	(revision d67735510bcb770552b5898e5b45fc6bc07534aa)
+++ src/Validate/VerifyCtorDtorAssign.hpp	(revision 6726a3a9cf8ffacc8cccb80819bb2c1d2687cfed)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// VerifyCtorDtorAssign.hpp --
+// VerifyCtorDtorAssign.hpp -- Check the form of operators.
 //
 // Author           : Andrew Beach
@@ -22,4 +22,6 @@
 namespace Validate {
 
+/// Check that constructors, destructors and assignments all have the correct
+/// form. Must happen before auto-gen or anything that examines operators.
 void verifyCtorDtorAssign( ast::TranslationUnit & translationUnit );
 
Index: src/Virtual/Tables.h
===================================================================
--- src/Virtual/Tables.h	(revision d67735510bcb770552b5898e5b45fc6bc07534aa)
+++ src/Virtual/Tables.h	(revision 6726a3a9cf8ffacc8cccb80819bb2c1d2687cfed)
@@ -19,6 +19,11 @@
 #include "AST/Fwd.hpp"
 class Declaration;
+class Expression;
+class FunctionDecl;
+class Initializer;
+class ObjectDecl;
 class StructDecl;
-class Expression;
+class StructInstType;
+class Type;
 
 namespace Virtual {
Index: src/main.cc
===================================================================
--- src/main.cc	(revision d67735510bcb770552b5898e5b45fc6bc07534aa)
+++ src/main.cc	(revision 6726a3a9cf8ffacc8cccb80819bb2c1d2687cfed)
@@ -10,6 +10,6 @@
 // Created On       : Fri May 15 23:12:02 2015
 // Last Modified By : Andrew Beach
-// Last Modified On : Tue Jul 12 12:02:00 2022
-// Update Count     : 675
+// Last Modified On : Mon Jul 18 11:08:00 2022
+// Update Count     : 676
 //
 
@@ -330,15 +330,5 @@
 		Stats::Time::StopBlock();
 
-		PASS( "Translate Exception Declarations", ControlStruct::translateExcept( translationUnit ) );
-		if ( exdeclp ) {
-			dump( translationUnit );
-			return EXIT_SUCCESS;
-		} // if
-
-		CodeTools::fillLocations( translationUnit );
-
 		if( useNewAST ) {
-			CodeTools::fillLocations( translationUnit );
-
 			if (Stats::Counters::enabled) {
 				ast::pass_visitor_stats.avg = Stats::Counters::build<Stats::Counters::AverageCounter<double>>("Average Depth - New");
@@ -349,7 +339,11 @@
 			forceFillCodeLocations( transUnit );
 
-			// Must happen before auto-gen, or anything that examines ops.
+			PASS( "Translate Exception Declarations", ControlStruct::translateExcept( transUnit ) );
+			if ( exdeclp ) {
+				dump( move( transUnit ) );
+				return EXIT_SUCCESS;
+			}
+
 			PASS( "Verify Ctor, Dtor & Assign", Validate::verifyCtorDtorAssign( transUnit ) );
-
 			PASS( "Hoist Type Decls", Validate::hoistTypeDecls( transUnit ) );
 			// Hoist Type Decls pulls some declarations out of contexts where
@@ -359,45 +353,20 @@
 
 			PASS( "Replace Typedefs", Validate::replaceTypedef( transUnit ) );
-
-			// Must happen before auto-gen.
 			PASS( "Fix Return Types", Validate::fixReturnTypes( transUnit ) );
-
-			// Must happen before Link Reference to Types, it needs correct
-			// types for mangling.
 			PASS( "Enum and Pointer Decay", Validate::decayEnumsAndPointers( transUnit ) );
 
-			// Must happen before auto-gen, because it uses the sized flag.
 			PASS( "Link Reference To Types", Validate::linkReferenceToTypes( transUnit ) );
 
-			// Must happen after Link References To Types,
-			// because aggregate members are accessed.
 			PASS( "Fix Qualified Types", Validate::fixQualifiedTypes( transUnit ) );
-
 			PASS( "Hoist Struct", Validate::hoistStruct( transUnit ) );
 			PASS( "Eliminate Typedef", Validate::eliminateTypedef( transUnit ) );
-
-			// Check as early as possible. Can't happen before
-			// LinkReferenceToType, observed failing when attempted
-			// before eliminateTypedef
 			PASS( "Validate Generic Parameters", Validate::fillGenericParameters( transUnit ) );
-
 			PASS( "Translate Dimensions", Validate::translateDimensionParameters( transUnit ) );
 			PASS( "Check Function Returns", Validate::checkReturnStatements( transUnit ) );
-
-			// Must happen before Autogen.
 			PASS( "Fix Return Statements", InitTweak::fixReturnStatements( transUnit ) );
-
 			PASS( "Implement Concurrent Keywords", Concurrency::implementKeywords( transUnit ) );
-
-			// Must be after implement concurrent keywords; because uniqueIds
-			//   must be set on declaration before resolution.
-			// Must happen before autogen routines are added.
 			PASS( "Forall Pointer Decay", Validate::decayForallPointers( transUnit ) );
-
-			// Must happen before autogen routines are added.
 			PASS( "Hoist Control Declarations", ControlStruct::hoistControlDecls( transUnit ) );
 
-			// Must be after enum and pointer decay.
-			// Must be before compound literals.
 			PASS( "Generate Autogen Routines", Validate::autogenerateRoutines( transUnit ) );
 
@@ -473,4 +442,10 @@
 			translationUnit = convert( move( transUnit ) );
 		} else {
+			PASS( "Translate Exception Declarations", ControlStruct::translateExcept( translationUnit ) );
+			if ( exdeclp ) {
+				dump( translationUnit );
+				return EXIT_SUCCESS;
+			} // if
+
 			// add the assignment statement after the initialization of a type parameter
 			PASS( "Validate", SymTab::validate( translationUnit ) );
