Index: src/ResolvExpr/CandidateFinder.cpp
===================================================================
--- src/ResolvExpr/CandidateFinder.cpp	(revision 4559b34425030aa5ff5e6be7a0d6e46d70ae6fec)
+++ src/ResolvExpr/CandidateFinder.cpp	(revision 92538ab6b62a97cccbb9045dcd6004887dec9529)
@@ -10,6 +10,6 @@
 // Created On       : Wed Jun 5 14:30:00 2019
 // Last Modified By : Andrew Beach
-// Last Modified On : Tue Oct  1 14:55:00 2019
-// Update Count     : 2
+// Last Modified On : Wed Mar 16 11:58:00 2022
+// Update Count     : 3
 //
 
@@ -595,4 +595,5 @@
 	/// Actually visits expressions to find their candidate interpretations
 	class Finder final : public ast::WithShortCircuiting {
+		const ResolveContext & context;
 		const ast::SymbolTable & symtab;
 	public:
@@ -618,6 +619,6 @@
 
 		Finder( CandidateFinder & f )
-		: symtab( f.localSyms ), selfFinder( f ), candidates( f.candidates ), tenv( f.env ),
-		  targetType( f.targetType ) {}
+		: context( f.context ), symtab( context.symtab ), selfFinder( f ),
+		  candidates( f.candidates ), tenv( f.env ), targetType( f.targetType ) {}
 
 		void previsit( const ast::Node * ) { visit_children = false; }
@@ -872,5 +873,5 @@
 			Tuples::handleTupleAssignment( selfFinder, untypedExpr, argCandidates );
 
-			CandidateFinder funcFinder{ symtab, tenv };
+			CandidateFinder funcFinder( context, tenv );
 			if (auto nameExpr = untypedExpr->func.as<ast::NameExpr>()) {
 				auto kind = ast::SymbolTable::getSpecialFunctionKind(nameExpr->name);
@@ -918,5 +919,5 @@
 			// find function operators
 			ast::ptr< ast::Expr > opExpr = new ast::NameExpr{ untypedExpr->location, "?()" };
-			CandidateFinder opFinder{ symtab, tenv };
+			CandidateFinder opFinder( context, tenv );
 			// okay if there aren't any function operations
 			opFinder.find( opExpr, ResolvMode::withoutFailFast() );
@@ -1059,5 +1060,5 @@
 
 		void postvisit( const ast::AddressExpr * addressExpr ) {
-			CandidateFinder finder{ symtab, tenv };
+			CandidateFinder finder( context, tenv );
 			finder.find( addressExpr->arg );
 
@@ -1079,9 +1080,9 @@
 			ast::ptr< ast::Type > toType = castExpr->result;
 			assert( toType );
-			toType = resolveTypeof( toType, symtab );
+			toType = resolveTypeof( toType, context );
 			// toType = SymTab::validateType( castExpr->location, toType, symtab );
 			toType = adjustExprType( toType, tenv, symtab );
 
-			CandidateFinder finder{ symtab, tenv, toType };
+			CandidateFinder finder( context, tenv, toType );
 			finder.find( castExpr->arg, ResolvMode::withAdjustment() );
 
@@ -1136,5 +1137,5 @@
 		void postvisit( const ast::VirtualCastExpr * castExpr ) {
 			assertf( castExpr->result, "Implicit virtual cast targets not yet supported." );
-			CandidateFinder finder{ symtab, tenv };
+			CandidateFinder finder( context, tenv );
 			// don't prune here, all alternatives guaranteed to have same type
 			finder.find( castExpr->arg, ResolvMode::withoutPrune() );
@@ -1153,5 +1154,5 @@
 			auto target = inst->base.get();
 
-			CandidateFinder finder{ symtab, tenv };
+			CandidateFinder finder( context, tenv );
 
 			auto pick_alternatives = [target, this](CandidateList & found, bool expect_ref) {
@@ -1202,5 +1203,5 @@
 
 		void postvisit( const ast::UntypedMemberExpr * memberExpr ) {
-			CandidateFinder aggFinder{ symtab, tenv };
+			CandidateFinder aggFinder( context, tenv );
 			aggFinder.find( memberExpr->aggregate, ResolvMode::withAdjustment() );
 			for ( CandidateRef & agg : aggFinder.candidates ) {
@@ -1287,9 +1288,9 @@
 				addCandidate(
 					new ast::SizeofExpr{
-						sizeofExpr->location, resolveTypeof( sizeofExpr->type, symtab ) },
+						sizeofExpr->location, resolveTypeof( sizeofExpr->type, context ) },
 					tenv );
 			} else {
 				// find all candidates for the argument to sizeof
-				CandidateFinder finder{ symtab, tenv };
+				CandidateFinder finder( context, tenv );
 				finder.find( sizeofExpr->expr );
 				// find the lowest-cost candidate, otherwise ambiguous
@@ -1311,9 +1312,9 @@
 				addCandidate(
 					new ast::AlignofExpr{
-						alignofExpr->location, resolveTypeof( alignofExpr->type, symtab ) },
+						alignofExpr->location, resolveTypeof( alignofExpr->type, context ) },
 					tenv );
 			} else {
 				// find all candidates for the argument to alignof
-				CandidateFinder finder{ symtab, tenv };
+				CandidateFinder finder( context, tenv );
 				finder.find( alignofExpr->expr );
 				// find the lowest-cost candidate, otherwise ambiguous
@@ -1354,9 +1355,9 @@
 
 		void postvisit( const ast::LogicalExpr * logicalExpr ) {
-			CandidateFinder finder1{ symtab, tenv };
+			CandidateFinder finder1( context, tenv );
 			finder1.find( logicalExpr->arg1, ResolvMode::withAdjustment() );
 			if ( finder1.candidates.empty() ) return;
 
-			CandidateFinder finder2{ symtab, tenv };
+			CandidateFinder finder2( context, tenv );
 			finder2.find( logicalExpr->arg2, ResolvMode::withAdjustment() );
 			if ( finder2.candidates.empty() ) return;
@@ -1384,15 +1385,15 @@
 		void postvisit( const ast::ConditionalExpr * conditionalExpr ) {
 			// candidates for condition
-			CandidateFinder finder1{ symtab, tenv };
+			CandidateFinder finder1( context, tenv );
 			finder1.find( conditionalExpr->arg1, ResolvMode::withAdjustment() );
 			if ( finder1.candidates.empty() ) return;
 
 			// candidates for true result
-			CandidateFinder finder2{ symtab, tenv };
+			CandidateFinder finder2( context, tenv );
 			finder2.find( conditionalExpr->arg2, ResolvMode::withAdjustment() );
 			if ( finder2.candidates.empty() ) return;
 
 			// candidates for false result
-			CandidateFinder finder3{ symtab, tenv };
+			CandidateFinder finder3( context, tenv );
 			finder3.find( conditionalExpr->arg3, ResolvMode::withAdjustment() );
 			if ( finder3.candidates.empty() ) return;
@@ -1445,7 +1446,7 @@
 		void postvisit( const ast::CommaExpr * commaExpr ) {
 			ast::TypeEnvironment env{ tenv };
-			ast::ptr< ast::Expr > arg1 = resolveInVoidContext( commaExpr->arg1, symtab, env );
-
-			CandidateFinder finder2{ symtab, env };
+			ast::ptr< ast::Expr > arg1 = resolveInVoidContext( commaExpr->arg1, context, env );
+
+			CandidateFinder finder2( context, env );
 			finder2.find( commaExpr->arg2, ResolvMode::withAdjustment() );
 
@@ -1460,5 +1461,5 @@
 
 		void postvisit( const ast::ConstructorExpr * ctorExpr ) {
-			CandidateFinder finder{ symtab, tenv };
+			CandidateFinder finder( context, tenv );
 			finder.find( ctorExpr->callExpr, ResolvMode::withoutPrune() );
 			for ( CandidateRef & r : finder.candidates ) {
@@ -1469,9 +1470,9 @@
 		void postvisit( const ast::RangeExpr * rangeExpr ) {
 			// resolve low and high, accept candidates where low and high types unify
-			CandidateFinder finder1{ symtab, tenv };
+			CandidateFinder finder1( context, tenv );
 			finder1.find( rangeExpr->low, ResolvMode::withAdjustment() );
 			if ( finder1.candidates.empty() ) return;
 
-			CandidateFinder finder2{ symtab, tenv };
+			CandidateFinder finder2( context, tenv );
 			finder2.find( rangeExpr->high, ResolvMode::withAdjustment() );
 			if ( finder2.candidates.empty() ) return;
@@ -1549,5 +1550,5 @@
 
 		void postvisit( const ast::UniqueExpr * unqExpr ) {
-			CandidateFinder finder{ symtab, tenv };
+			CandidateFinder finder( context, tenv );
 			finder.find( unqExpr->expr, ResolvMode::withAdjustment() );
 			for ( CandidateRef & r : finder.candidates ) {
@@ -1558,5 +1559,5 @@
 
 		void postvisit( const ast::StmtExpr * stmtExpr ) {
-			addCandidate( resolveStmtExpr( stmtExpr, symtab ), tenv );
+			addCandidate( resolveStmtExpr( stmtExpr, context ), tenv );
 		}
 
@@ -1570,5 +1571,5 @@
 			for ( const ast::InitAlternative & initAlt : initExpr->initAlts ) {
 				// calculate target type
-				const ast::Type * toType = resolveTypeof( initAlt.type, symtab );
+				const ast::Type * toType = resolveTypeof( initAlt.type, context );
 				// toType = SymTab::validateType( initExpr->location, toType, symtab );
 				toType = adjustExprType( toType, tenv, symtab );
@@ -1576,5 +1577,5 @@
 				// types are not bound to the initialization type, since return type variables are
 				// only open for the duration of resolving the UntypedExpr.
-				CandidateFinder finder{ symtab, tenv, toType };
+				CandidateFinder finder( context, tenv, toType );
 				finder.find( initExpr->expr, ResolvMode::withAdjustment() );
 				for ( CandidateRef & cand : finder.candidates ) {
@@ -1693,5 +1694,5 @@
 		}
 		else {
-			satisfyAssertions(candidate, localSyms, satisfied, errors);
+			satisfyAssertions(candidate, context.symtab, satisfied, errors);
 			needRecomputeKey = true;
 		}
@@ -1855,5 +1856,5 @@
 			r->expr = ast::mutate_field(
 				r->expr.get(), &ast::Expr::result,
-				adjustExprType( r->expr->result, r->env, localSyms ) );
+				adjustExprType( r->expr->result, r->env, context.symtab ) );
 		}
 	}
@@ -1873,5 +1874,5 @@
 
 	for ( const auto & x : xs ) {
-		out.emplace_back( localSyms, env );
+		out.emplace_back( context, env );
 		out.back().find( x, ResolvMode::withAdjustment() );
 
Index: src/ResolvExpr/CandidateFinder.hpp
===================================================================
--- src/ResolvExpr/CandidateFinder.hpp	(revision 4559b34425030aa5ff5e6be7a0d6e46d70ae6fec)
+++ src/ResolvExpr/CandidateFinder.hpp	(revision 92538ab6b62a97cccbb9045dcd6004887dec9529)
@@ -10,6 +10,6 @@
 // Created On       : Wed Jun 5 14:30:00 2019
 // Last Modified By : Andrew Beach
-// Last Modified On : Tue Oct  1  9:51:00 2019
-// Update Count     : 2
+// Last Modified On : Wed Mar 16 15:22:00 2022
+// Update Count     : 3
 //
 
@@ -25,8 +25,10 @@
 namespace ResolvExpr {
 
+struct ResolveContext;
+
 /// Data to perform expression resolution
 struct CandidateFinder {
 	CandidateList candidates;          ///< List of candidate resolutions
-	const ast::SymbolTable & localSyms;   ///< Symbol table to lookup candidates
+	const ResolveContext & context;  ///< Information about where the canditates are being found.
 	const ast::TypeEnvironment & env;  ///< Substitutions performed in this resolution
 	ast::ptr< ast::Type > targetType;  ///< Target type for resolution
@@ -34,7 +36,7 @@
 
 	CandidateFinder(
-		const ast::SymbolTable & syms, const ast::TypeEnvironment & env,
+		const ResolveContext & context, const ast::TypeEnvironment & env,
 		const ast::Type * tt = nullptr )
-	: candidates(), localSyms( syms ), env( env ), targetType( tt ) {}
+	: candidates(), context( context ), env( env ), targetType( tt ) {}
 
 	/// Fill candidates with feasible resolutions for `expr`
Index: src/ResolvExpr/CandidatePrinter.cpp
===================================================================
--- src/ResolvExpr/CandidatePrinter.cpp	(revision 4559b34425030aa5ff5e6be7a0d6e46d70ae6fec)
+++ src/ResolvExpr/CandidatePrinter.cpp	(revision 92538ab6b62a97cccbb9045dcd6004887dec9529)
@@ -10,6 +10,6 @@
 // Created On       : Tue Nov  9  9:54:00 2021
 // Last Modified By : Andrew Beach
-// Last Modified On : Tue Nov  9 15:47:00 2021
-// Update Count     : 0
+// Last Modified On : Wed Mar 16 13:56:00 2022
+// Update Count     : 1
 //
 
@@ -22,4 +22,5 @@
 #include "AST/TranslationUnit.hpp"
 #include "ResolvExpr/CandidateFinder.hpp"
+#include "ResolvExpr/Resolver.h"
 
 #include <iostream>
@@ -29,5 +30,6 @@
 namespace {
 
-class CandidatePrintCore : public ast::WithSymbolTable {
+class CandidatePrintCore : public ast::WithSymbolTable,
+		public ast::WithConstTranslationUnit {
 	std::ostream & os;
 public:
@@ -36,5 +38,5 @@
 	void postvisit( const ast::ExprStmt * stmt ) {
 		ast::TypeEnvironment env;
-		CandidateFinder finder( symtab, env );
+		CandidateFinder finder( { symtab, transUnit().global }, env );
 		finder.find( stmt->expr, ResolvMode::withAdjustment() );
 		int count = 1;
Index: src/ResolvExpr/RenameVars.h
===================================================================
--- src/ResolvExpr/RenameVars.h	(revision 4559b34425030aa5ff5e6be7a0d6e46d70ae6fec)
+++ src/ResolvExpr/RenameVars.h	(revision 92538ab6b62a97cccbb9045dcd6004887dec9529)
@@ -36,10 +36,7 @@
 	};
 	const ast::Type * renameTyVars( const ast::Type *, RenameMode mode = GEN_USAGE, bool reset = true );
-	
 
 	/// resets internal state of renamer to avoid overflow
 	void resetTyVarRenaming();
-
-	
 } // namespace ResolvExpr
 
Index: src/ResolvExpr/ResolveTypeof.cc
===================================================================
--- src/ResolvExpr/ResolveTypeof.cc	(revision 4559b34425030aa5ff5e6be7a0d6e46d70ae6fec)
+++ src/ResolvExpr/ResolveTypeof.cc	(revision 92538ab6b62a97cccbb9045dcd6004887dec9529)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Sun May 17 12:12:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Tue May 19 16:49:04 2015
-// Update Count     : 3
+// Last Modified By : Andrew Beach
+// Last Modified On : Wed Mar 16 16:09:00 2022
+// Update Count     : 4
 //
 
@@ -22,4 +22,5 @@
 #include "AST/Node.hpp"
 #include "AST/Pass.hpp"
+#include "AST/TranslationUnit.hpp"
 #include "AST/Type.hpp"
 #include "AST/TypeEnvironment.hpp"
@@ -119,7 +120,8 @@
 namespace {
 	struct ResolveTypeof_new : public ast::WithShortCircuiting {
-		const ast::SymbolTable & localSymtab;
-
-		ResolveTypeof_new( const ast::SymbolTable & syms ) : localSymtab( syms ) {}
+		const ResolveContext & context;
+
+		ResolveTypeof_new( const ResolveContext & context ) :
+			context( context ) {}
 
 		void previsit( const ast::TypeofType * ) { visit_children = false; }
@@ -137,5 +139,5 @@
 				ast::TypeEnvironment dummy;
 				ast::ptr< ast::Expr > newExpr =
-					resolveInVoidContext( typeofType->expr, localSymtab, dummy );
+					resolveInVoidContext( typeofType->expr, context, dummy );
 				assert( newExpr->result && ! newExpr->result->isVoid() );
 				newType = newExpr->result;
@@ -161,19 +163,19 @@
 } // anonymous namespace
 
-const ast::Type * resolveTypeof( const ast::Type * type , const ast::SymbolTable & symtab ) {
-	ast::Pass< ResolveTypeof_new > mutator{ symtab };
+const ast::Type * resolveTypeof( const ast::Type * type , const ResolveContext & context ) {
+	ast::Pass< ResolveTypeof_new > mutator( context );
 	return type->accept( mutator );
 }
 
 struct FixArrayDimension {
-	// should not require a mutable symbol table - prevent pass template instantiation
-	const ast::SymbolTable & _symtab; 
-	FixArrayDimension(const ast::SymbolTable & symtab): _symtab(symtab) {}
+	const ResolveContext & context;
+	FixArrayDimension(const ResolveContext & context) : context( context ) {}
 
 	const ast::ArrayType * previsit (const ast::ArrayType * arrayType) {
 		if (!arrayType->dimension) return arrayType;
 		auto mutType = mutate(arrayType);
-		ast::ptr<ast::Type> sizetype = ast::sizeType ? ast::sizeType : new ast::BasicType(ast::BasicType::LongUnsignedInt); 
-		mutType->dimension = findSingleExpression(arrayType->dimension, sizetype, _symtab);
+		auto globalSizeType = context.global.sizeType;
+		ast::ptr<ast::Type> sizetype = globalSizeType ? globalSizeType : new ast::BasicType(ast::BasicType::LongUnsignedInt);
+		mutType->dimension = findSingleExpression(arrayType->dimension, sizetype, context );
 
 		if (InitTweak::isConstExpr(mutType->dimension)) {
@@ -187,41 +189,29 @@
 };
 
-const ast::Type * fixArrayType( const ast::Type * type, const ast::SymbolTable & symtab) {
-	ast::Pass<FixArrayDimension> visitor {symtab};
+const ast::Type * fixArrayType( const ast::Type * type, const ResolveContext & context ) {
+	ast::Pass<FixArrayDimension> visitor(context);
 	return type->accept(visitor);
 }
 
-const ast::ObjectDecl * fixObjectType( const ast::ObjectDecl * decl , const ast::SymbolTable & symtab ) {
-	if (!decl->isTypeFixed) { 
-		auto mutDecl = mutate(decl);
-		auto resolvedType = resolveTypeof(decl->type, symtab);
-		resolvedType = fixArrayType(resolvedType, symtab);
+const ast::ObjectDecl * fixObjectType( const ast::ObjectDecl * decl , const ResolveContext & context ) {
+	if (decl->isTypeFixed) {
+		return decl;
+	}
+
+	auto mutDecl = mutate(decl);
+	{
+		auto resolvedType = resolveTypeof(decl->type, context);
+		resolvedType = fixArrayType(resolvedType, context);
 		mutDecl->type = resolvedType;
-
-		// check variable length if object is an array.
-		// xxx - should this be part of fixObjectType?
-
-		/*
-		if (auto arrayType = dynamic_cast<const ast::ArrayType *>(resolvedType)) {
-			auto dimExpr = findSingleExpression(arrayType->dimension, ast::sizeType, symtab);
-			if (auto varexpr = arrayType->dimension.as<ast::VariableExpr>()) {// hoisted previously
-				if (InitTweak::isConstExpr(varexpr->var.strict_as<ast::ObjectDecl>()->init)) {
-					auto mutType = mutate(arrayType);
-					mutType->isVarLen = ast::LengthFlag::VariableLen;
-					mutDecl->type = mutType;
-				}
-			}
-		}
-		*/
-
-
-		if (!mutDecl->name.empty()) 
-			mutDecl->mangleName = Mangle::mangle(mutDecl); // do not mangle unnamed variables
-		
-		mutDecl->type = renameTyVars(mutDecl->type, RenameMode::GEN_EXPR_ID);
-		mutDecl->isTypeFixed = true;
-		return mutDecl;
-	}
-	return decl;
+	}
+
+	// Do not mangle unnamed variables.
+	if (!mutDecl->name.empty()) {
+		mutDecl->mangleName = Mangle::mangle(mutDecl);
+	}
+
+	mutDecl->type = renameTyVars(mutDecl->type, RenameMode::GEN_EXPR_ID);
+	mutDecl->isTypeFixed = true;
+	return mutDecl;
 }
 
Index: src/ResolvExpr/ResolveTypeof.h
===================================================================
--- src/ResolvExpr/ResolveTypeof.h	(revision 4559b34425030aa5ff5e6be7a0d6e46d70ae6fec)
+++ src/ResolvExpr/ResolveTypeof.h	(revision 92538ab6b62a97cccbb9045dcd6004887dec9529)
@@ -5,11 +5,11 @@
 // file "LICENCE" distributed with Cforall.
 //
-// ResolveTypeof.h -- 
+// ResolveTypeof.h --
 //
 // Author           : Richard C. Bilson
 // Created On       : Sun May 17 12:14:53 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Sat Jul 22 09:38:35 2017
-// Update Count     : 3
+// Last Modified By : Andrew Beach
+// Last Modified On : Wed Mar 16 11:33:00 2022
+// Update Count     : 4
 //
 
@@ -22,12 +22,13 @@
 namespace ast {
 	class Type;
-	class SymbolTable;
 	class ObjectDecl;
 }
 
 namespace ResolvExpr {
+	struct ResolveContext;
+
 	Type *resolveTypeof( Type*, const SymTab::Indexer &indexer );
-	const ast::Type * resolveTypeof( const ast::Type *, const ast::SymbolTable & );
-	const ast::ObjectDecl * fixObjectType( const ast::ObjectDecl * decl , const ast::SymbolTable & symtab );
+	const ast::Type * resolveTypeof( const ast::Type *, const ResolveContext & );
+	const ast::ObjectDecl * fixObjectType( const ast::ObjectDecl * decl , const ResolveContext & );
 } // namespace ResolvExpr
 
Index: src/ResolvExpr/Resolver.cc
===================================================================
--- src/ResolvExpr/Resolver.cc	(revision 4559b34425030aa5ff5e6be7a0d6e46d70ae6fec)
+++ src/ResolvExpr/Resolver.cc	(revision 92538ab6b62a97cccbb9045dcd6004887dec9529)
@@ -9,7 +9,7 @@
 // Author           : Aaron B. Moss
 // Created On       : Sun May 17 12:17:01 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Feb  1 16:27:14 2022
-// Update Count     : 245
+// Last Modified By : Andrew Beach
+// Last Modified On : Fri Mar 18 10:41:00 2022
+// Update Count     : 247
 //
 
@@ -997,5 +997,5 @@
 		/// Calls the CandidateFinder and finds the single best candidate
 		CandidateRef findUnfinishedKindExpression(
-			const ast::Expr * untyped, const ast::SymbolTable & symtab, const std::string & kind,
+			const ast::Expr * untyped, const ResolveContext & context, const std::string & kind,
 			std::function<bool(const Candidate &)> pred = anyCandidate, ResolvMode mode = {}
 		) {
@@ -1007,5 +1007,5 @@
 			++recursion_level;
 			ast::TypeEnvironment env;
-			CandidateFinder finder{ symtab, env };
+			CandidateFinder finder( context, env );
 			finder.find( untyped, recursion_level == 1 ? mode.atTopLevel() : mode );
 			--recursion_level;
@@ -1129,5 +1129,6 @@
 
 	ast::ptr< ast::Expr > resolveInVoidContext(
-		const ast::Expr * expr, const ast::SymbolTable & symtab, ast::TypeEnvironment & env
+		const ast::Expr * expr, const ResolveContext & context,
+		ast::TypeEnvironment & env
 	) {
 		assertf( expr, "expected a non-null expression" );
@@ -1136,5 +1137,5 @@
 		ast::ptr< ast::CastExpr > untyped = new ast::CastExpr{ expr };
 		CandidateRef choice = findUnfinishedKindExpression(
-			untyped, symtab, "", anyCandidate, ResolvMode::withAdjustment() );
+			untyped, context, "", anyCandidate, ResolvMode::withAdjustment() );
 
 		// a cast expression has either 0 or 1 interpretations (by language rules);
@@ -1149,8 +1150,8 @@
 		/// context.
 		ast::ptr< ast::Expr > findVoidExpression(
-			const ast::Expr * untyped, const ast::SymbolTable & symtab
+			const ast::Expr * untyped, const ResolveContext & context
 		) {
 			ast::TypeEnvironment env;
-			ast::ptr< ast::Expr > newExpr = resolveInVoidContext( untyped, symtab, env );
+			ast::ptr< ast::Expr > newExpr = resolveInVoidContext( untyped, context, env );
 			finishExpr( newExpr, env, untyped->env );
 			return newExpr;
@@ -1163,5 +1164,5 @@
 		/// lowest cost, returning the resolved version
 		ast::ptr< ast::Expr > findKindExpression(
-			const ast::Expr * untyped, const ast::SymbolTable & symtab,
+			const ast::Expr * untyped, const ResolveContext & context,
 			std::function<bool(const Candidate &)> pred = anyCandidate,
 			const std::string & kind = "", ResolvMode mode = {}
@@ -1169,5 +1170,5 @@
 			if ( ! untyped ) return {};
 			CandidateRef choice =
-				findUnfinishedKindExpression( untyped, symtab, kind, pred, mode );
+				findUnfinishedKindExpression( untyped, context, kind, pred, mode );
 			ResolvExpr::finishExpr( choice->expr, choice->env, untyped->env );
 			return std::move( choice->expr );
@@ -1176,8 +1177,8 @@
 		/// Resolve `untyped` to the single expression whose candidate is the best match
 		ast::ptr< ast::Expr > findSingleExpression(
-			const ast::Expr * untyped, const ast::SymbolTable & symtab
+			const ast::Expr * untyped, const ResolveContext & context
 		) {
 			Stats::ResolveTime::start( untyped );
-			auto res = findKindExpression( untyped, symtab );
+			auto res = findKindExpression( untyped, context );
 			Stats::ResolveTime::stop();
 			return res;
@@ -1186,10 +1187,11 @@
 
 	ast::ptr< ast::Expr > findSingleExpression(
-		const ast::Expr * untyped, const ast::Type * type, const ast::SymbolTable & symtab
+		const ast::Expr * untyped, const ast::Type * type,
+		const ResolveContext & context
 	) {
 		assert( untyped && type );
 		ast::ptr< ast::Expr > castExpr = new ast::CastExpr{ untyped, type };
-		ast::ptr< ast::Expr > newExpr = findSingleExpression( castExpr, symtab );
-		removeExtraneousCast( newExpr, symtab );
+		ast::ptr< ast::Expr > newExpr = findSingleExpression( castExpr, context );
+		removeExtraneousCast( newExpr, context.symtab );
 		return newExpr;
 	}
@@ -1217,7 +1219,7 @@
 		/// Resolve `untyped` as an integral expression, returning the resolved version
 		ast::ptr< ast::Expr > findIntegralExpression(
-			const ast::Expr * untyped, const ast::SymbolTable & symtab
+			const ast::Expr * untyped, const ResolveContext & context
 		) {
-			return findKindExpression( untyped, symtab, hasIntegralType, "condition" );
+			return findKindExpression( untyped, context, hasIntegralType, "condition" );
 		}
 
@@ -1249,4 +1251,5 @@
 		// for work previously in GenInit
 		static InitTweak::ManagedTypes_new managedTypes;
+		ResolveContext context;
 
 		bool inEnumDecl = false;
@@ -1254,6 +1257,9 @@
 	public:
 		static size_t traceId;
-		Resolver_new() = default;
-		Resolver_new( const ast::SymbolTable & syms ) { symtab = syms; }
+		Resolver_new( const ast::TranslationGlobal & global ) :
+			context{ symtab, global } {}
+		Resolver_new( const ResolveContext & context ) :
+			ast::WithSymbolTable{ context.symtab },
+			context{ symtab, context.global } {}
 
 		const ast::FunctionDecl * previsit( const ast::FunctionDecl * );
@@ -1272,13 +1278,13 @@
 		const ast::AsmStmt *         previsit( const ast::AsmStmt * );
 		const ast::IfStmt *          previsit( const ast::IfStmt * );
-		const ast::WhileDoStmt *       previsit( const ast::WhileDoStmt * );
+		const ast::WhileDoStmt *     previsit( const ast::WhileDoStmt * );
 		const ast::ForStmt *         previsit( const ast::ForStmt * );
 		const ast::SwitchStmt *      previsit( const ast::SwitchStmt * );
-		const ast::CaseStmt *        previsit( const ast::CaseStmt * );
+		const ast::CaseClause *      previsit( const ast::CaseClause * );
 		const ast::BranchStmt *      previsit( const ast::BranchStmt * );
 		const ast::ReturnStmt *      previsit( const ast::ReturnStmt * );
 		const ast::ThrowStmt *       previsit( const ast::ThrowStmt * );
-		const ast::CatchStmt *       previsit( const ast::CatchStmt * );
-		const ast::CatchStmt *       postvisit( const ast::CatchStmt * );
+		const ast::CatchClause *     previsit( const ast::CatchClause * );
+		const ast::CatchClause *     postvisit( const ast::CatchClause * );
 		const ast::WaitForStmt *     previsit( const ast::WaitForStmt * );
 		const ast::WithStmt *        previsit( const ast::WithStmt * );
@@ -1299,20 +1305,20 @@
 
 	void resolve( ast::TranslationUnit& translationUnit ) {
-		ast::Pass< Resolver_new >::run( translationUnit );
+		ast::Pass< Resolver_new >::run( translationUnit, translationUnit.global );
 	}
 
 	ast::ptr< ast::Init > resolveCtorInit(
-		const ast::ConstructorInit * ctorInit, const ast::SymbolTable & symtab
+		const ast::ConstructorInit * ctorInit, const ResolveContext & context
 	) {
 		assert( ctorInit );
-		ast::Pass< Resolver_new > resolver{ symtab };
+		ast::Pass< Resolver_new > resolver( context );
 		return ctorInit->accept( resolver );
 	}
 
 	const ast::Expr * resolveStmtExpr(
-		const ast::StmtExpr * stmtExpr, const ast::SymbolTable & symtab
+		const ast::StmtExpr * stmtExpr, const ResolveContext & context
 	) {
 		assert( stmtExpr );
-		ast::Pass< Resolver_new > resolver{ symtab };
+		ast::Pass< Resolver_new > resolver( context );
 		auto ret = mutate(stmtExpr->accept(resolver));
 		strict_dynamic_cast< ast::StmtExpr * >( ret )->computeResult();
@@ -1321,10 +1327,10 @@
 
 	namespace {
-		const ast::Attribute * handleAttribute(const CodeLocation & loc, const ast::Attribute * attr, const ast::SymbolTable & symtab) {
+		const ast::Attribute * handleAttribute(const CodeLocation & loc, const ast::Attribute * attr, const ResolveContext & context) {
 			std::string name = attr->normalizedName();
 			if (name == "constructor" || name == "destructor") {
 				if (attr->params.size() == 1) {
 					auto arg = attr->params.front();
-					auto resolved = ResolvExpr::findSingleExpression( arg, new ast::BasicType( ast::BasicType::LongLongSignedInt ), symtab );
+					auto resolved = ResolvExpr::findSingleExpression( arg, new ast::BasicType( ast::BasicType::LongLongSignedInt ), context );
 					auto result = eval(arg);
 
@@ -1369,5 +1375,5 @@
 
 			for (auto & attr: mutDecl->attributes) {
-				attr = handleAttribute(mutDecl->location, attr, symtab);
+				attr = handleAttribute(mutDecl->location, attr, context );
 			}
 
@@ -1379,8 +1385,8 @@
 			for (auto & typeParam : mutDecl->type_params) {
 				symtab.addType(typeParam);
-				mutType->forall.emplace_back(new ast::TypeInstType(typeParam->name, typeParam));
+				mutType->forall.emplace_back(new ast::TypeInstType(typeParam));
 			}
 			for (auto & asst : mutDecl->assertions) {
-				asst = fixObjectType(asst.strict_as<ast::ObjectDecl>(), symtab);
+				asst = fixObjectType(asst.strict_as<ast::ObjectDecl>(), context);
 				symtab.addId(asst);
 				mutType->assertions.emplace_back(new ast::VariableExpr(functionDecl->location, asst));
@@ -1394,10 +1400,10 @@
 
 			for (auto & param : mutDecl->params) {
-				param = fixObjectType(param.strict_as<ast::ObjectDecl>(), symtab);
+				param = fixObjectType(param.strict_as<ast::ObjectDecl>(), context);
 				symtab.addId(param);
 				paramTypes.emplace_back(param->get_type());
 			}
 			for (auto & ret : mutDecl->returns) {
-				ret = fixObjectType(ret.strict_as<ast::ObjectDecl>(), symtab);
+				ret = fixObjectType(ret.strict_as<ast::ObjectDecl>(), context);
 				returnTypes.emplace_back(ret->get_type());
 			}
@@ -1498,5 +1504,5 @@
 		else {
 			if (!objectDecl->isTypeFixed) {
-				auto newDecl = fixObjectType(objectDecl, symtab);
+				auto newDecl = fixObjectType(objectDecl, context);
 				auto mutDecl = mutate(newDecl);
 
@@ -1529,5 +1535,5 @@
 			// nested type decls are hoisted already. no need to do anything
 			if (auto obj = member.as<ast::ObjectDecl>()) {
-				member = fixObjectType(obj, symtab);
+				member = fixObjectType(obj, context);
 			}
 		}
@@ -1552,14 +1558,14 @@
 		return ast::mutate_field(
 			assertDecl, &ast::StaticAssertDecl::cond,
-			findIntegralExpression( assertDecl->cond, symtab ) );
+			findIntegralExpression( assertDecl->cond, context ) );
 	}
 
 	template< typename PtrType >
-	const PtrType * handlePtrType( const PtrType * type, const ast::SymbolTable & symtab ) {
+	const PtrType * handlePtrType( const PtrType * type, const ResolveContext & context ) {
 		if ( type->dimension ) {
-			ast::ptr< ast::Type > sizeType = ast::sizeType;
+			ast::ptr< ast::Type > sizeType = context.global.sizeType;
 			ast::mutate_field(
 				type, &PtrType::dimension,
-				findSingleExpression( type->dimension, sizeType, symtab ) );
+				findSingleExpression( type->dimension, sizeType, context ) );
 		}
 		return type;
@@ -1567,9 +1573,9 @@
 
 	const ast::ArrayType * Resolver_new::previsit( const ast::ArrayType * at ) {
-		return handlePtrType( at, symtab );
+		return handlePtrType( at, context );
 	}
 
 	const ast::PointerType * Resolver_new::previsit( const ast::PointerType * pt ) {
-		return handlePtrType( pt, symtab );
+		return handlePtrType( pt, context );
 	}
 
@@ -1579,5 +1585,5 @@
 
 		return ast::mutate_field(
-			exprStmt, &ast::ExprStmt::expr, findVoidExpression( exprStmt->expr, symtab ) );
+			exprStmt, &ast::ExprStmt::expr, findVoidExpression( exprStmt->expr, context ) );
 	}
 
@@ -1586,5 +1592,5 @@
 
 		asmExpr = ast::mutate_field(
-			asmExpr, &ast::AsmExpr::operand, findVoidExpression( asmExpr->operand, symtab ) );
+			asmExpr, &ast::AsmExpr::operand, findVoidExpression( asmExpr->operand, context ) );
 
 		return asmExpr;
@@ -1600,10 +1606,10 @@
 	const ast::IfStmt * Resolver_new::previsit( const ast::IfStmt * ifStmt ) {
 		return ast::mutate_field(
-			ifStmt, &ast::IfStmt::cond, findIntegralExpression( ifStmt->cond, symtab ) );
+			ifStmt, &ast::IfStmt::cond, findIntegralExpression( ifStmt->cond, context ) );
 	}
 
 	const ast::WhileDoStmt * Resolver_new::previsit( const ast::WhileDoStmt * whileDoStmt ) {
 		return ast::mutate_field(
-			whileDoStmt, &ast::WhileDoStmt::cond, findIntegralExpression( whileDoStmt->cond, symtab ) );
+			whileDoStmt, &ast::WhileDoStmt::cond, findIntegralExpression( whileDoStmt->cond, context ) );
 	}
 
@@ -1611,10 +1617,10 @@
 		if ( forStmt->cond ) {
 			forStmt = ast::mutate_field(
-				forStmt, &ast::ForStmt::cond, findIntegralExpression( forStmt->cond, symtab ) );
+				forStmt, &ast::ForStmt::cond, findIntegralExpression( forStmt->cond, context ) );
 		}
 
 		if ( forStmt->inc ) {
 			forStmt = ast::mutate_field(
-				forStmt, &ast::ForStmt::inc, findVoidExpression( forStmt->inc, symtab ) );
+				forStmt, &ast::ForStmt::inc, findVoidExpression( forStmt->inc, context ) );
 		}
 
@@ -1626,10 +1632,10 @@
 		switchStmt = ast::mutate_field(
 			switchStmt, &ast::SwitchStmt::cond,
-			findIntegralExpression( switchStmt->cond, symtab ) );
+			findIntegralExpression( switchStmt->cond, context ) );
 		currentObject = ast::CurrentObject{ switchStmt->location, switchStmt->cond->result };
 		return switchStmt;
 	}
 
-	const ast::CaseStmt * Resolver_new::previsit( const ast::CaseStmt * caseStmt ) {
+	const ast::CaseClause * Resolver_new::previsit( const ast::CaseClause * caseStmt ) {
 		if ( caseStmt->cond ) {
 			std::deque< ast::InitAlternative > initAlts = currentObject.getOptions();
@@ -1639,5 +1645,5 @@
 			ast::ptr< ast::Expr > untyped =
 				new ast::CastExpr{ caseStmt->location, caseStmt->cond, initAlts.front().type };
-			ast::ptr< ast::Expr > newExpr = findSingleExpression( untyped, symtab );
+			ast::ptr< ast::Expr > newExpr = findSingleExpression( untyped, context );
 
 			// case condition cannot have a cast in C, so it must be removed here, regardless of
@@ -1647,5 +1653,5 @@
 			}
 
-			caseStmt = ast::mutate_field( caseStmt, &ast::CaseStmt::cond, newExpr );
+			caseStmt = ast::mutate_field( caseStmt, &ast::CaseClause::cond, newExpr );
 		}
 		return caseStmt;
@@ -1660,5 +1666,5 @@
 			branchStmt = ast::mutate_field(
 				branchStmt, &ast::BranchStmt::computedTarget,
-				findSingleExpression( branchStmt->computedTarget, target, symtab ) );
+				findSingleExpression( branchStmt->computedTarget, target, context ) );
 		}
 		return branchStmt;
@@ -1670,5 +1676,5 @@
 			returnStmt = ast::mutate_field(
 				returnStmt, &ast::ReturnStmt::expr,
-				findSingleExpression( returnStmt->expr, functionReturn, symtab ) );
+				findSingleExpression( returnStmt->expr, functionReturn, context ) );
 		}
 		return returnStmt;
@@ -1685,38 +1691,38 @@
 			throwStmt = ast::mutate_field(
 				throwStmt, &ast::ThrowStmt::expr,
-				findSingleExpression( throwStmt->expr, exceptType, symtab ) );
+				findSingleExpression( throwStmt->expr, exceptType, context ) );
 		}
 		return throwStmt;
 	}
 
-	const ast::CatchStmt * Resolver_new::previsit( const ast::CatchStmt * catchStmt ) {
+	const ast::CatchClause * Resolver_new::previsit( const ast::CatchClause * catchClause ) {
 		// Until we are very sure this invarent (ifs that move between passes have then)
 		// holds, check it. This allows a check for when to decode the mangling.
-		if ( auto ifStmt = catchStmt->body.as<ast::IfStmt>() ) {
+		if ( auto ifStmt = catchClause->body.as<ast::IfStmt>() ) {
 			assert( ifStmt->then );
 		}
 		// Encode the catchStmt so the condition can see the declaration.
-		if ( catchStmt->cond ) {
-			ast::CatchStmt * stmt = mutate( catchStmt );
-			stmt->body = new ast::IfStmt( stmt->location, stmt->cond, nullptr, stmt->body );
-			stmt->cond = nullptr;
-			return stmt;
-		}
-		return catchStmt;
-	}
-
-	const ast::CatchStmt * Resolver_new::postvisit( const ast::CatchStmt * catchStmt ) {
+		if ( catchClause->cond ) {
+			ast::CatchClause * clause = mutate( catchClause );
+			clause->body = new ast::IfStmt( clause->location, clause->cond, nullptr, clause->body );
+			clause->cond = nullptr;
+			return clause;
+		}
+		return catchClause;
+	}
+
+	const ast::CatchClause * Resolver_new::postvisit( const ast::CatchClause * catchClause ) {
 		// Decode the catchStmt so everything is stored properly.
-		const ast::IfStmt * ifStmt = catchStmt->body.as<ast::IfStmt>();
+		const ast::IfStmt * ifStmt = catchClause->body.as<ast::IfStmt>();
 		if ( nullptr != ifStmt && nullptr == ifStmt->then ) {
 			assert( ifStmt->cond );
 			assert( ifStmt->else_ );
-			ast::CatchStmt * stmt = ast::mutate( catchStmt );
-			stmt->cond = ifStmt->cond;
-			stmt->body = ifStmt->else_;
+			ast::CatchClause * clause = ast::mutate( catchClause );
+			clause->cond = ifStmt->cond;
+			clause->body = ifStmt->else_;
 			// ifStmt should be implicately deleted here.
-			return stmt;
-		}
-		return catchStmt;
+			return clause;
+		}
+		return catchClause;
 	}
 
@@ -1729,5 +1735,5 @@
 
 			ast::TypeEnvironment env;
-			CandidateFinder funcFinder{ symtab, env };
+			CandidateFinder funcFinder( context, env );
 
 			// Find all candidates for a function in canonical form
@@ -1943,9 +1949,9 @@
 				);
 
-				clause2.target.args.emplace_back( findSingleExpression( init, symtab ) );
+				clause2.target.args.emplace_back( findSingleExpression( init, context ) );
 			}
 
 			// Resolve the conditions as if it were an IfStmt, statements normally
-			clause2.cond = findSingleExpression( clause.cond, symtab );
+			clause2.cond = findSingleExpression( clause.cond, context );
 			clause2.stmt = clause.stmt->accept( *visitor );
 
@@ -1962,6 +1968,6 @@
 			ast::ptr< ast::Type > target =
 				new ast::BasicType{ ast::BasicType::LongLongUnsignedInt };
-			timeout2.time = findSingleExpression( stmt->timeout.time, target, symtab );
-			timeout2.cond = findSingleExpression( stmt->timeout.cond, symtab );
+			timeout2.time = findSingleExpression( stmt->timeout.time, target, context );
+			timeout2.cond = findSingleExpression( stmt->timeout.cond, context );
 			timeout2.stmt = stmt->timeout.stmt->accept( *visitor );
 
@@ -1976,5 +1982,5 @@
 			ast::WaitForStmt::OrElse orElse2;
 
-			orElse2.cond = findSingleExpression( stmt->orElse.cond, symtab );
+			orElse2.cond = findSingleExpression( stmt->orElse.cond, context );
 			orElse2.stmt = stmt->orElse.stmt->accept( *visitor );
 
@@ -1997,5 +2003,5 @@
 		for (auto & expr : exprs) {
 			// only struct- and union-typed expressions are viable candidates
-			expr = findKindExpression( expr, symtab, structOrUnion, "with expression" );
+			expr = findKindExpression( expr, context, structOrUnion, "with expression" );
 
 			// if with expression might be impure, create a temporary so that it is evaluated once
@@ -2023,5 +2029,5 @@
 		ast::ptr< ast::Expr > untyped = new ast::UntypedInitExpr{
 			singleInit->location, singleInit->value, currentObject.getOptions() };
-		ast::ptr<ast::Expr> newExpr = findSingleExpression( untyped, symtab );
+		ast::ptr<ast::Expr> newExpr = findSingleExpression( untyped, context );
 		const ast::InitExpr * initExpr = newExpr.strict_as< ast::InitExpr >();
 
Index: src/ResolvExpr/Resolver.h
===================================================================
--- src/ResolvExpr/Resolver.h	(revision 4559b34425030aa5ff5e6be7a0d6e46d70ae6fec)
+++ src/ResolvExpr/Resolver.h	(revision 92538ab6b62a97cccbb9045dcd6004887dec9529)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Sun May 17 12:18:34 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Mon Feb 18 20:40:38 2019
-// Update Count     : 4
+// Last Modified By : Andrew Beach
+// Last Modified On : Wed Mar 16 11:32:00 2022
+// Update Count     : 5
 //
 
@@ -23,5 +23,7 @@
 class Declaration;
 class Expression;
+class DeletedExpr;
 class StmtExpr;
+class Type;
 namespace SymTab {
 	class Indexer;
@@ -35,4 +37,5 @@
 	class StmtExpr;
 	class SymbolTable;
+	class TranslationGlobal;
 	class TranslationUnit;
 	class Type;
@@ -55,4 +58,10 @@
 	void resolveWithExprs( std::list< Declaration * > & translationUnit );
 
+	/// Helper Type: Passes around information between various sub-calls.
+	struct ResolveContext {
+		const ast::SymbolTable & symtab;
+		const ast::TranslationGlobal & global;
+	};
+
 	/// Checks types and binds syntactic constructs to typed representations
 	void resolve( ast::TranslationUnit& translationUnit );
@@ -62,17 +71,17 @@
 	/// context.
 	ast::ptr< ast::Expr > resolveInVoidContext(
-		const ast::Expr * expr, const ast::SymbolTable & symtab, ast::TypeEnvironment & env );
+		const ast::Expr * expr, const ResolveContext &, ast::TypeEnvironment & env );
 	/// Resolve `untyped` to the single expression whose candidate is the best match for the
 	/// given type.
 	ast::ptr< ast::Expr > findSingleExpression(
-		const ast::Expr * untyped, const ast::Type * type, const ast::SymbolTable & symtab );
+		const ast::Expr * untyped, const ast::Type * type, const ResolveContext & );
 	ast::ptr< ast::Expr > findVoidExpression(
-		const ast::Expr * untyped, const ast::SymbolTable & symtab);
+		const ast::Expr * untyped, const ResolveContext & );
 	/// Resolves a constructor init expression
 	ast::ptr< ast::Init > resolveCtorInit(
-		const ast::ConstructorInit * ctorInit, const ast::SymbolTable & symtab );
+		const ast::ConstructorInit * ctorInit, const ResolveContext & context );
 	/// Resolves a statement expression
 	const ast::Expr * resolveStmtExpr(
-		const ast::StmtExpr * stmtExpr, const ast::SymbolTable & symtab );
+		const ast::StmtExpr * stmtExpr, const ResolveContext & context );
 } // namespace ResolvExpr
 
Index: src/ResolvExpr/Unify.cc
===================================================================
--- src/ResolvExpr/Unify.cc	(revision 4559b34425030aa5ff5e6be7a0d6e46d70ae6fec)
+++ src/ResolvExpr/Unify.cc	(revision 92538ab6b62a97cccbb9045dcd6004887dec9529)
@@ -943,5 +943,5 @@
 			// check that the other type is compatible and named the same
 			auto otherInst = dynamic_cast< const XInstType * >( other );
-			this->result = otherInst && inst->name == otherInst->name;
+			if (otherInst && inst->name == otherInst->name) this->result = otherInst;
 			return otherInst;
 		}
