Index: libcfa/src/concurrency/kernel.cfa
===================================================================
--- libcfa/src/concurrency/kernel.cfa	(revision 3e5db5b4130e8f655563072771bcc8b389ad7681)
+++ libcfa/src/concurrency/kernel.cfa	(revision 34c32f098e353062f8da7759b872f43ad7bc5a74)
@@ -42,7 +42,7 @@
 
 #if !defined(__CFA_NO_STATISTICS__)
-	#define __STATS( ...) __VA_ARGS__
+	#define __STATS_DEF( ...) __VA_ARGS__
 #else
-	#define __STATS( ...)
+	#define __STATS_DEF( ...)
 #endif
 
@@ -122,4 +122,5 @@
 static thread$ * __next_thread(cluster * this);
 static thread$ * __next_thread_slow(cluster * this);
+static thread$ * __next_thread_search(cluster * this);
 static inline bool __must_unpark( thread$ * thrd ) __attribute((nonnull(1)));
 static void __run_thread(processor * this, thread$ * dst);
@@ -187,6 +188,4 @@
 		MAIN_LOOP:
 		for() {
-			#define OLD_MAIN 1
-			#if OLD_MAIN
 			// Check if there is pending io
 			__maybe_io_drain( this );
@@ -196,8 +195,18 @@
 
 			if( !readyThread ) {
-				__tls_stats()->io.flush.idle++;
+				__IO_STATS__(true, io.flush.idle++; )
 				__cfa_io_flush( this, 0 );
 
+				readyThread = __next_thread( this->cltr );
+			}
+
+			if( !readyThread ) for(5) {
+				__IO_STATS__(true, io.flush.idle++; )
+
 				readyThread = __next_thread_slow( this->cltr );
+
+				if( readyThread ) break;
+
+				__cfa_io_flush( this, 0 );
 			}
 
@@ -211,12 +220,10 @@
 
 				// Confirm the ready-queue is empty
-				readyThread = __next_thread_slow( this->cltr );
+				readyThread = __next_thread_search( this->cltr );
 				if( readyThread ) {
 					// A thread was found, cancel the halt
 					mark_awake(this->cltr->procs, * this);
 
-					#if !defined(__CFA_NO_STATISTICS__)
-						__tls_stats()->ready.sleep.cancels++;
-					#endif
+					__STATS__(true, ready.sleep.cancels++; )
 
 					// continue the mai loop
@@ -245,123 +252,7 @@
 
 			if(this->io.pending && !this->io.dirty) {
-				__tls_stats()->io.flush.dirty++;
+				__IO_STATS__(true, io.flush.dirty++; )
 				__cfa_io_flush( this, 0 );
 			}
-
-			#else
-				#warning new kernel loop
-			SEARCH: {
-				/* paranoid */ verify( ! __preemption_enabled() );
-
-				// First, lock the scheduler since we are searching for a thread
-				ready_schedule_lock();
-
-				// Try to get the next thread
-				readyThread = pop_fast( this->cltr );
-				if(readyThread) { ready_schedule_unlock(); break SEARCH; }
-
-				// If we can't find a thread, might as well flush any outstanding I/O
-				if(this->io.pending) { __cfa_io_flush( this, 0 ); }
-
-				// Spin a little on I/O, just in case
-				for(5) {
-					__maybe_io_drain( this );
-					readyThread = pop_fast( this->cltr );
-					if(readyThread) { ready_schedule_unlock(); break SEARCH; }
-				}
-
-				// no luck, try stealing a few times
-				for(5) {
-					if( __maybe_io_drain( this ) ) {
-						readyThread = pop_fast( this->cltr );
-					} else {
-						readyThread = pop_slow( this->cltr );
-					}
-					if(readyThread) { ready_schedule_unlock(); break SEARCH; }
-				}
-
-				// still no luck, search for a thread
-				readyThread = pop_search( this->cltr );
-				if(readyThread) { ready_schedule_unlock(); break SEARCH; }
-
-				// Don't block if we are done
-				if( __atomic_load_n(&this->do_terminate, __ATOMIC_SEQ_CST) ) {
-					ready_schedule_unlock();
-					break MAIN_LOOP;
-				}
-
-				__STATS( __tls_stats()->ready.sleep.halts++; )
-
-				// Push self to idle stack
-				ready_schedule_unlock();
-				if(!mark_idle(this->cltr->procs, * this)) goto SEARCH;
-				ready_schedule_lock();
-
-				// Confirm the ready-queue is empty
-				__maybe_io_drain( this );
-				readyThread = pop_search( this->cltr );
-				ready_schedule_unlock();
-
-				if( readyThread ) {
-					// A thread was found, cancel the halt
-					mark_awake(this->cltr->procs, * this);
-
-					__STATS( __tls_stats()->ready.sleep.cancels++; )
-
-					// continue the main loop
-					break SEARCH;
-				}
-
-				__STATS( if(this->print_halts) __cfaabi_bits_print_safe( STDOUT_FILENO, "PH:%d - %lld 0\n", this->unique_id, rdtscl()); )
-				__cfadbg_print_safe(runtime_core, "Kernel : core %p waiting on eventfd %d\n", this, this->idle_fd);
-
-				{
-					eventfd_t val;
-					ssize_t ret = read( this->idle_fd, &val, sizeof(val) );
-					if(ret < 0) {
-						switch((int)errno) {
-						case EAGAIN:
-						#if EAGAIN != EWOULDBLOCK
-							case EWOULDBLOCK:
-						#endif
-						case EINTR:
-							// No need to do anything special here, just assume it's a legitimate wake-up
-							break;
-						default:
-							abort( "KERNEL : internal error, read failure on idle eventfd, error(%d) %s.", (int)errno, strerror( (int)errno ) );
-						}
-					}
-				}
-
-					__STATS( if(this->print_halts) __cfaabi_bits_print_safe( STDOUT_FILENO, "PH:%d - %lld 1\n", this->unique_id, rdtscl()); )
-
-				// We were woken up, remove self from idle
-				mark_awake(this->cltr->procs, * this);
-
-				// DON'T just proceed, start looking again
-				continue MAIN_LOOP;
-			}
-
-		RUN_THREAD:
-			/* paranoid */ verify( ! __preemption_enabled() );
-			/* paranoid */ verify( readyThread );
-
-			// Reset io dirty bit
-			this->io.dirty = false;
-
-			// We found a thread run it
-			__run_thread(this, readyThread);
-
-			// Are we done?
-			if( __atomic_load_n(&this->do_terminate, __ATOMIC_SEQ_CST) ) break MAIN_LOOP;
-
-			if(this->io.pending && !this->io.dirty) {
-				__cfa_io_flush( this, 0 );
-			}
-
-			ready_schedule_lock();
-			__maybe_io_drain( this );
-			ready_schedule_unlock();
-			#endif
 		}
 
@@ -474,7 +365,5 @@
 				break RUNNING;
 			case TICKET_UNBLOCK:
-				#if !defined(__CFA_NO_STATISTICS__)
-					__tls_stats()->ready.threads.threads++;
-				#endif
+				__STATS__(true, ready.threads.threads++; )
 				// This is case 2, the racy case, someone tried to run this thread before it finished blocking
 				// In this case, just run it again.
@@ -491,7 +380,5 @@
 	__cfadbg_print_safe(runtime_core, "Kernel : core %p finished running thread %p\n", this, thrd_dst);
 
-	#if !defined(__CFA_NO_STATISTICS__)
-		__tls_stats()->ready.threads.threads--;
-	#endif
+	__STATS__(true, ready.threads.threads--; )
 
 	/* paranoid */ verify( ! __preemption_enabled() );
@@ -504,5 +391,5 @@
 	thread$ * thrd_src = kernelTLS().this_thread;
 
-	__STATS( thrd_src->last_proc = kernelTLS().this_processor; )
+	__STATS_DEF( thrd_src->last_proc = kernelTLS().this_processor; )
 
 	// Run the thread on this processor
@@ -556,5 +443,5 @@
 	// Dereference the thread now because once we push it, there is not guaranteed it's still valid.
 	struct cluster * cl = thrd->curr_cluster;
-	__STATS(bool outside = hint == UNPARK_LOCAL && thrd->last_proc && thrd->last_proc != kernelTLS().this_processor; )
+	__STATS_DEF(bool outside = hint == UNPARK_LOCAL && thrd->last_proc && thrd->last_proc != kernelTLS().this_processor; )
 
 	// push the thread to the cluster ready-queue
@@ -607,12 +494,17 @@
 
 	ready_schedule_lock();
-		thread$ * thrd;
-		for(25) {
-			thrd = pop_slow( this );
-			if(thrd) goto RET;
-		}
-		thrd = pop_search( this );
-
-		RET:
+		thread$ * thrd = pop_slow( this );
+	ready_schedule_unlock();
+
+	/* paranoid */ verify( ! __preemption_enabled() );
+	return thrd;
+}
+
+// KERNEL ONLY
+static inline thread$ * __next_thread_search(cluster * this) with( *this ) {
+	/* paranoid */ verify( ! __preemption_enabled() );
+
+	ready_schedule_lock();
+		thread$ * thrd = pop_search( this );
 	ready_schedule_unlock();
 
@@ -856,7 +748,5 @@
 
 static bool mark_idle(__cluster_proc_list & this, processor & proc) {
-	#if !defined(__CFA_NO_STATISTICS__)
-		__tls_stats()->ready.sleep.halts++;
-	#endif
+	__STATS__(true, ready.sleep.halts++; )
 
 	proc.idle_wctx.fd = 0;
@@ -951,11 +841,7 @@
 		unsigned tail = *ctx->cq.tail;
 		if(head == tail) return false;
-		#if OLD_MAIN
-			ready_schedule_lock();
-			ret = __cfa_io_drain( proc );
-			ready_schedule_unlock();
-		#else
-			ret = __cfa_io_drain( proc );
-		#endif
+		ready_schedule_lock();
+		ret = __cfa_io_drain( proc );
+		ready_schedule_unlock();
 	#endif
 	return ret;
Index: libcfa/src/concurrency/kernel/fwd.hfa
===================================================================
--- libcfa/src/concurrency/kernel/fwd.hfa	(revision 3e5db5b4130e8f655563072771bcc8b389ad7681)
+++ libcfa/src/concurrency/kernel/fwd.hfa	(revision 34c32f098e353062f8da7759b872f43ad7bc5a74)
@@ -396,6 +396,18 @@
 				if( !(in_kernel) ) enable_interrupts(); \
 			}
+			#if defined(CFA_HAVE_LINUX_IO_URING_H)
+				#define __IO_STATS__(in_kernel, ...) { \
+					if( !(in_kernel) ) disable_interrupts(); \
+					with( *__tls_stats() ) { \
+						__VA_ARGS__ \
+					} \
+					if( !(in_kernel) ) enable_interrupts(); \
+				}
+			#else
+				#define __IO_STATS__(in_kernel, ...)
+			#endif
 		#else
 			#define __STATS__(in_kernel, ...)
+			#define __IO_STATS__(in_kernel, ...)
 		#endif
 	}
Index: src/AST/Stmt.hpp
===================================================================
--- src/AST/Stmt.hpp	(revision 3e5db5b4130e8f655563072771bcc8b389ad7681)
+++ src/AST/Stmt.hpp	(revision 34c32f098e353062f8da7759b872f43ad7bc5a74)
@@ -9,7 +9,7 @@
 // Author           : Aaron B. Moss
 // Created On       : Wed May  8 13:00:00 2019
-// Last Modified By : Andrew Beach
-// Last Modified On : Fri May 17 12:45:00 2019
-// Update Count     : 5
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Mon Jan 31 22:38:53 2022
+// Update Count     : 12
 //
 
@@ -17,9 +17,9 @@
 
 #include <list>
-#include <utility>                // for move
+#include <utility>										// for move
 #include <vector>
 
 #include "Label.hpp"
-#include "Node.hpp"               // for node, ptr
+#include "Node.hpp"										// for node, ptr
 #include "ParseNode.hpp"
 #include "Visitor.hpp"
@@ -27,36 +27,35 @@
 
 // Must be included in *all* AST classes; should be #undef'd at the end of the file
-#define MUTATE_FRIEND \
+#define MUTATE_FRIEND													\
     template<typename node_t> friend node_t * mutate(const node_t * node); \
 	template<typename node_t> friend node_t * shallowCopy(const node_t * node);
 
 namespace ast {
-
 class Expr;
 
-/// Base statement node
+// Base statement node
 class Stmt : public ParseNode {
-public:
+  public:
 	std::vector<Label> labels;
 
 	Stmt( const CodeLocation & loc, std::vector<Label> && labels = {} )
-	: ParseNode(loc), labels(std::move(labels)) {}
+		: ParseNode(loc), labels(std::move(labels)) {}
 
 	Stmt(const Stmt& o) : ParseNode(o), labels(o.labels) {}
 
 	const Stmt * accept( Visitor & v ) const override = 0;
-private:
+  private:
 	Stmt * clone() const override = 0;
 	MUTATE_FRIEND
 };
 
-/// Compound statement `{ ... }`
+// Compound statement: { ... }
 class CompoundStmt final : public Stmt {
-public:
+  public:
 	std::list<ptr<Stmt>> kids;
 
 	CompoundStmt(const CodeLocation & loc, std::list<ptr<Stmt>> && ks = {},
-		std::vector<Label>&& labels = {} )
-	: Stmt(loc, std::move(labels)), kids(std::move(ks)) {}
+				 std::vector<Label>&& labels = {} )
+		: Stmt(loc, std::move(labels)), kids(std::move(ks)) {}
 
 	CompoundStmt( const CompoundStmt& o );
@@ -67,38 +66,38 @@
 
 	const CompoundStmt * accept( Visitor & v ) const override { return v.visit( this ); }
-private:
+  private:
 	CompoundStmt * clone() const override { return new CompoundStmt{ *this }; }
 	MUTATE_FRIEND
 };
 
-/// Empty statment `;`
+// Empty statment: ;
 class NullStmt final : public Stmt {
-public:
+  public:
 	NullStmt( const CodeLocation & loc, std::vector<Label> && labels = {} )
-	: Stmt(loc, std::move(labels)) {}
+		: Stmt(loc, std::move(labels)) {}
 
 	const NullStmt * accept( Visitor & v ) const override { return v.visit( this ); }
-private:
+  private:
 	NullStmt * clone() const override { return new NullStmt{ *this }; }
 	MUTATE_FRIEND
 };
 
-/// Expression wrapped by statement
+// Expression wrapped by statement
 class ExprStmt final : public Stmt {
-public:
+  public:
 	ptr<Expr> expr;
 
 	ExprStmt( const CodeLocation& loc, const Expr* e, std::vector<Label>&& labels = {} )
-	: Stmt(loc, std::move(labels)), expr(e) {}
-
-	const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
-private:
+		: Stmt(loc, std::move(labels)), expr(e) {}
+
+	const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
+  private:
 	ExprStmt * clone() const override { return new ExprStmt{ *this }; }
 	MUTATE_FRIEND
 };
 
-/// Assembly statement `asm ... ( "..." : ... )`
+// Assembly statement: asm ... ( "..." : ... )
 class AsmStmt final : public Stmt {
-public:
+  public:
 	bool isVolatile;
 	ptr<Expr> instruction;
@@ -108,35 +107,35 @@
 
 	AsmStmt( const CodeLocation & loc, bool isVolatile, const Expr * instruction,
-		std::vector<ptr<Expr>> && output, std::vector<ptr<Expr>> && input,
-		std::vector<ptr<ConstantExpr>> && clobber, std::vector<Label> && gotoLabels,
-		std::vector<Label> && labels = {})
-	: Stmt(loc, std::move(labels)), isVolatile(isVolatile), instruction(instruction),
-	  output(std::move(output)), input(std::move(input)), clobber(std::move(clobber)),
-	  gotoLabels(std::move(gotoLabels)) {}
-
-	const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
-private:
+			 std::vector<ptr<Expr>> && output, std::vector<ptr<Expr>> && input,
+			 std::vector<ptr<ConstantExpr>> && clobber, std::vector<Label> && gotoLabels,
+			 std::vector<Label> && labels = {})
+		: Stmt(loc, std::move(labels)), isVolatile(isVolatile), instruction(instruction),
+		  output(std::move(output)), input(std::move(input)), clobber(std::move(clobber)),
+		  gotoLabels(std::move(gotoLabels)) {}
+
+	const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
+  private:
 	AsmStmt * clone() const override { return new AsmStmt{ *this }; }
 	MUTATE_FRIEND
 };
 
-/// C-preprocessor directive `#...`
+// C-preprocessor directive: #...
 class DirectiveStmt final : public Stmt {
-public:
+  public:
 	std::string directive;
 
 	DirectiveStmt( const CodeLocation & loc, const std::string & directive,
-		std::vector<Label> && labels = {} )
-	: Stmt(loc, std::move(labels)), directive(directive) {}
-
-	const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
-private:
+				   std::vector<Label> && labels = {} )
+		: Stmt(loc, std::move(labels)), directive(directive) {}
+
+	const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
+  private:
 	DirectiveStmt * clone() const override { return new DirectiveStmt{ *this }; }
 	MUTATE_FRIEND
 };
 
-/// If conditional statement `if (...) ... else ...`
+// If statement: if (...) ... else ...
 class IfStmt final : public Stmt {
-public:
+  public:
 	ptr<Expr> cond;
 	ptr<Stmt> thenPart;
@@ -145,91 +144,91 @@
 
 	IfStmt( const CodeLocation & loc, const Expr * cond, const Stmt * thenPart,
-		const Stmt * elsePart = nullptr, std::vector<ptr<Stmt>> && inits = {},
-		std::vector<Label> && labels = {} )
-	: Stmt(loc, std::move(labels)), cond(cond), thenPart(thenPart), elsePart(elsePart),
-	  inits(std::move(inits)) {}
-
-	const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
-private:
+			const Stmt * elsePart = nullptr, std::vector<ptr<Stmt>> && inits = {},
+			std::vector<Label> && labels = {} )
+		: Stmt(loc, std::move(labels)), cond(cond), thenPart(thenPart), elsePart(elsePart),
+		  inits(std::move(inits)) {}
+
+	const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
+  private:
 	IfStmt * clone() const override { return new IfStmt{ *this }; }
 	MUTATE_FRIEND
 };
 
-/// Switch or choose conditional statement `switch (...) { ... }`
+// Switch or choose statement: switch (...) { ... }
 class SwitchStmt final : public Stmt {
-public:
+  public:
 	ptr<Expr> cond;
 	std::vector<ptr<Stmt>> stmts;
 
 	SwitchStmt( const CodeLocation & loc, const Expr * cond, std::vector<ptr<Stmt>> && stmts,
-		std::vector<Label> && labels = {} )
-	: Stmt(loc, std::move(labels)), cond(cond), stmts(std::move(stmts)) {}
-
-	const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
-private:
+				std::vector<Label> && labels = {} )
+		: Stmt(loc, std::move(labels)), cond(cond), stmts(std::move(stmts)) {}
+
+	const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
+  private:
 	SwitchStmt * clone() const override { return new SwitchStmt{ *this }; }
 	MUTATE_FRIEND
 };
 
-/// Case label `case ...:` `default:`
+// Case label: case ...: or default:
 class CaseStmt final : public Stmt {
-public:
-	/// Null for the default label.
+  public:
+	// Null for the default label.
 	ptr<Expr> cond;
 	std::vector<ptr<Stmt>> stmts;
 
 	CaseStmt( const CodeLocation & loc, const Expr * cond, std::vector<ptr<Stmt>> && stmts,
-		std::vector<Label> && labels = {} )
-	: Stmt(loc, std::move(labels)), cond(cond), stmts(std::move(stmts)) {}
+			  std::vector<Label> && labels = {} )
+		: Stmt(loc, std::move(labels)), cond(cond), stmts(std::move(stmts)) {}
 
 	bool isDefault() const { return !cond; }
 
 	const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
-private:
+  private:
 	CaseStmt * clone() const override { return new CaseStmt{ *this }; }
 	MUTATE_FRIEND
 };
 
-/// While loop `while (...) ...` `do ... while (...);
+// While loop: while (...) ... else ... or do ... while (...) else ...;
 class WhileStmt final : public Stmt {
-public:
+  public:
 	ptr<Expr> cond;
 	ptr<Stmt> body;
+	ptr<Stmt> elsePart;
 	std::vector<ptr<Stmt>> inits;
 	bool isDoWhile;
 
 	WhileStmt( const CodeLocation & loc, const Expr * cond, const Stmt * body,
-		std::vector<ptr<Stmt>> && inits, bool isDoWhile = false, std::vector<Label> && labels = {} )
-	: Stmt(loc, std::move(labels)), cond(cond), body(body), inits(std::move(inits)),
-	  isDoWhile(isDoWhile) {}
-
-	const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
-private:
+			   std::vector<ptr<Stmt>> && inits, bool isDoWhile = false, std::vector<Label> && labels = {} )
+		: Stmt(loc, std::move(labels)), cond(cond), body(body), inits(std::move(inits)), isDoWhile(isDoWhile) {}
+
+	const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
+  private:
 	WhileStmt * clone() const override { return new WhileStmt{ *this }; }
 	MUTATE_FRIEND
 };
 
-/// For loop `for (... ; ... ; ...) ...`
+// For loop: for (... ; ... ; ...) ... else ...
 class ForStmt final : public Stmt {
-public:
+  public:
 	std::vector<ptr<Stmt>> inits;
 	ptr<Expr> cond;
 	ptr<Expr> inc;
 	ptr<Stmt> body;
+	ptr<Stmt> elsePart;
 
 	ForStmt( const CodeLocation & loc, std::vector<ptr<Stmt>> && inits, const Expr * cond,
-		const Expr * inc, const Stmt * body, std::vector<Label> && labels = {} )
-	: Stmt(loc, std::move(labels)), inits(std::move(inits)), cond(cond), inc(inc),
-	  body(body) {}
-
-	const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
-private:
+			 const Expr * inc, const Stmt * body, std::vector<Label> && labels = {} )
+		: Stmt(loc, std::move(labels)), inits(std::move(inits)), cond(cond), inc(inc), body(body) {}
+
+	const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
+  private:
 	ForStmt * clone() const override { return new ForStmt{ *this }; }
 	MUTATE_FRIEND
 };
 
-/// Branch control flow statement `goto ...` `break` `continue` `fallthru`
+// Branch control flow statement: goto ... or break or continue or fallthru
 class BranchStmt final : public Stmt {
-public:
+  public:
 	enum Kind { Goto, Break, Continue, FallThrough, FallThroughDefault };
 	static constexpr size_t kindEnd = 1 + (size_t)FallThroughDefault;
@@ -241,14 +240,14 @@
 
 	BranchStmt( const CodeLocation & loc, Kind kind, Label target,
-		std::vector<Label> && labels = {} );
+				std::vector<Label> && labels = {} );
 	BranchStmt( const CodeLocation & loc, const Expr * computedTarget,
-		std::vector<Label> && labels = {} )
-	: Stmt(loc, std::move(labels)), originalTarget(loc), target(loc),
-	  computedTarget(computedTarget), kind(Goto) {}
+				std::vector<Label> && labels = {} )
+		: Stmt(loc, std::move(labels)), originalTarget(loc), target(loc),
+		  computedTarget(computedTarget), kind(Goto) {}
 
 	const char * kindName() const { return kindNames[kind]; }
 
 	const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
-private:
+  private:
 	BranchStmt * clone() const override { return new BranchStmt{ *this }; }
 	MUTATE_FRIEND
@@ -257,24 +256,24 @@
 };
 
-/// Return statement `return ...`
+// Return statement: return ...
 class ReturnStmt final : public Stmt {
-public:
+  public:
 	ptr<Expr> expr;
 
 	ReturnStmt( const CodeLocation & loc, const Expr * expr, std::vector<Label> && labels = {} )
-	: Stmt(loc, std::move(labels)), expr(expr) {}
-
-	const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
-private:
+		: Stmt(loc, std::move(labels)), expr(expr) {}
+
+	const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
+  private:
 	ReturnStmt * clone() const override { return new ReturnStmt{ *this }; }
 	MUTATE_FRIEND
 };
 
-/// Kind of exception
+// Kind of exception
 enum ExceptionKind { Terminate, Resume };
 
-/// Throw statement `throw ...`
+// Throw statement: throw ...
 class ThrowStmt final : public Stmt {
-public:
+  public:
 	ptr<Expr> expr;
 	ptr<Expr> target;
@@ -284,15 +283,15 @@
 		const CodeLocation & loc, ExceptionKind kind, const Expr * expr, const Expr * target,
 		std::vector<Label> && labels = {} )
-	: Stmt(loc, std::move(labels)), expr(expr), target(target), kind(kind) {}
-
-	const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
-private:
+		: Stmt(loc, std::move(labels)), expr(expr), target(target), kind(kind) {}
+
+	const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
+  private:
 	ThrowStmt * clone() const override { return new ThrowStmt{ *this }; }
 	MUTATE_FRIEND
 };
 
-/// Try statement `try { ... } ...`
+// Try statement: try { ... } ...
 class TryStmt final : public Stmt {
-public:
+  public:
 	ptr<CompoundStmt> body;
 	std::vector<ptr<CatchStmt>> handlers;
@@ -303,15 +302,15 @@
 		std::vector<ptr<CatchStmt>> && handlers, const FinallyStmt * finally,
 		std::vector<Label> && labels = {} )
-	: Stmt(loc, std::move(labels)), body(body), handlers(std::move(handlers)), finally(finally) {}
-
-	const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
-private:
+		: Stmt(loc, std::move(labels)), body(body), handlers(std::move(handlers)), finally(finally) {}
+
+	const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
+  private:
 	TryStmt * clone() const override { return new TryStmt{ *this }; }
 	MUTATE_FRIEND
 };
 
-/// Catch clause of try statement
+// Catch clause of try statement
 class CatchStmt final : public Stmt {
-public:
+  public:
 	ptr<Decl> decl;
 	ptr<Expr> cond;
@@ -322,45 +321,45 @@
 		const CodeLocation & loc, ExceptionKind kind, const Decl * decl, const Expr * cond,
 		const Stmt * body, std::vector<Label> && labels = {} )
-	: Stmt(loc, std::move(labels)), decl(decl), cond(cond), body(body), kind(kind) {}
-
-	const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
-private:
+		: Stmt(loc, std::move(labels)), decl(decl), cond(cond), body(body), kind(kind) {}
+
+	const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
+  private:
 	CatchStmt * clone() const override { return new CatchStmt{ *this }; }
 	MUTATE_FRIEND
 };
 
-/// Finally clause of try statement
+// Finally clause of try statement
 class FinallyStmt final : public Stmt {
-public:
+  public:
 	ptr<CompoundStmt> body;
 
 	FinallyStmt( const CodeLocation & loc, const CompoundStmt * body,
-		std::vector<Label> && labels = {} )
-	: Stmt(loc, std::move(labels)), body(body) {}
-
-	const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
-private:
+				 std::vector<Label> && labels = {} )
+		: Stmt(loc, std::move(labels)), body(body) {}
+
+	const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
+  private:
 	FinallyStmt * clone() const override { return new FinallyStmt{ *this }; }
 	MUTATE_FRIEND
 };
 
-/// Suspend statement
+// Suspend statement
 class SuspendStmt final : public Stmt {
-public:
+  public:
 	ptr<CompoundStmt> then;
 	enum Type { None, Coroutine, Generator } type = None;
 
 	SuspendStmt( const CodeLocation & loc, const CompoundStmt * then, Type type, std::vector<Label> && labels = {} )
-	: Stmt(loc, std::move(labels)), then(then), type(type) {}
-
-	const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
-private:
+		: Stmt(loc, std::move(labels)), then(then), type(type) {}
+
+	const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
+  private:
 	SuspendStmt * clone() const override { return new SuspendStmt{ *this }; }
 	MUTATE_FRIEND
 };
 
-/// Wait for concurrency statement `when (...) waitfor (... , ...) ... timeout(...) ... else ...`
+// Waitfor statement: when (...) waitfor (... , ...) ... timeout(...) ... else ...
 class WaitForStmt final : public Stmt {
-public:
+  public:
 	struct Target {
 		ptr<Expr> func;
@@ -390,64 +389,61 @@
 
 	WaitForStmt( const CodeLocation & loc, std::vector<Label> && labels = {} )
-	: Stmt(loc, std::move(labels)) {}
-
-	const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
-private:
+		: Stmt(loc, std::move(labels)) {}
+
+	const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
+  private:
 	WaitForStmt * clone() const override { return new WaitForStmt{ *this }; }
 	MUTATE_FRIEND
 };
 
-/// Any declaration in a (compound) statement.
+// Any declaration in a (compound) statement.
 class DeclStmt final : public Stmt {
-public:
+  public:
 	ptr<Decl> decl;
 
 	DeclStmt( const CodeLocation & loc, const Decl * decl, std::vector<Label> && labels = {} )
-	: Stmt(loc, std::move(labels)), decl(decl) {}
-
-	const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
-private:
+		: Stmt(loc, std::move(labels)), decl(decl) {}
+
+	const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
+  private:
 	DeclStmt * clone() const override { return new DeclStmt{ *this }; }
 	MUTATE_FRIEND
 };
 
-/// Represents an implicit application of a constructor or destructor.
+// Represents an implicit application of a constructor or destructor.
 class ImplicitCtorDtorStmt final : public Stmt {
-public:
+  public:
 	ptr<Stmt> callStmt;
 
 	ImplicitCtorDtorStmt( const CodeLocation & loc, const Stmt * callStmt,
-		std::vector<Label> && labels = {} )
-	: Stmt(loc, std::move(labels)), callStmt(callStmt) {}
-
-	const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
-private:
+						  std::vector<Label> && labels = {} )
+		: Stmt(loc, std::move(labels)), callStmt(callStmt) {}
+
+	const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
+  private:
 	ImplicitCtorDtorStmt * clone() const override { return new ImplicitCtorDtorStmt{ *this }; }
 	MUTATE_FRIEND
 };
 
-/// Mutex Statement
+// Mutex Statement
 class MutexStmt final : public Stmt {
-public:
+  public:
 	ptr<Stmt> stmt;
 	std::vector<ptr<Expr>> mutexObjs;
 
 	MutexStmt( const CodeLocation & loc, const Stmt * stmt, 
-		std::vector<ptr<Expr>> && mutexes, std::vector<Label> && labels = {} )
-	: Stmt(loc, std::move(labels)), stmt(stmt), mutexObjs(std::move(mutexes)) {}
-
-	const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
-private:
+			   std::vector<ptr<Expr>> && mutexes, std::vector<Label> && labels = {} )
+		: Stmt(loc, std::move(labels)), stmt(stmt), mutexObjs(std::move(mutexes)) {}
+
+	const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
+  private:
 	MutexStmt * clone() const override { return new MutexStmt{ *this }; }
 	MUTATE_FRIEND
 };
-
-}
+} // namespace ast
 
 #undef MUTATE_FRIEND
 
 // Local Variables: //
-// tab-width: 4 //
 // mode: c++ //
-// compile-command: "make install" //
 // End: //
Index: src/ControlStruct/ExceptTranslateNew.cpp
===================================================================
--- src/ControlStruct/ExceptTranslateNew.cpp	(revision 3e5db5b4130e8f655563072771bcc8b389ad7681)
+++ src/ControlStruct/ExceptTranslateNew.cpp	(revision 34c32f098e353062f8da7759b872f43ad7bc5a74)
@@ -9,7 +9,7 @@
 // Author           : Andrew Beach
 // Created On       : Mon Nov  8 11:53:00 2021
-// Last Modified By : Andrew Beach
-// Last Modified On : Mon Nov  8 16:50:00 2021
-// Update Count     : 0
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Mon Jan 31 18:49:58 2022
+// Update Count     : 1
 //
 
@@ -22,6 +22,4 @@
 
 namespace ControlStruct {
-
-namespace {
 
 class TranslateThrowsCore : public ast::WithGuards {
@@ -128,6 +126,4 @@
 }
 
-} // namespace
-
 void translateThrows( ast::TranslationUnit & transUnit ) {
 	ast::Pass<TranslateThrowsCore>::run( transUnit );
Index: src/ControlStruct/FixLabels.cpp
===================================================================
--- src/ControlStruct/FixLabels.cpp	(revision 3e5db5b4130e8f655563072771bcc8b389ad7681)
+++ src/ControlStruct/FixLabels.cpp	(revision 34c32f098e353062f8da7759b872f43ad7bc5a74)
@@ -9,7 +9,7 @@
 // Author           : Andrew Beach
 // Created On       : Mon Nov  1 09:39:00 2021
-// Last Modified By : Andrew Beach
-// Last Modified On : Mon Nov  8 10:53:00 2021
-// Update Count     : 3
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Mon Jan 31 22:19:17 2022
+// Update Count     : 9
 //
 
@@ -20,42 +20,40 @@
 #include "AST/Stmt.hpp"
 #include "ControlStruct/MultiLevelExit.hpp"
+using namespace ast;
 
 namespace ControlStruct {
-
-namespace {
-
-class FixLabelsCore final : public ast::WithGuards {
+class FixLabelsCore final : public WithGuards {
 	LabelToStmt labelTable;
-public:
+  public:
 	FixLabelsCore() : labelTable() {}
 
-	void previsit( const ast::FunctionDecl * );
-	const ast::FunctionDecl * postvisit( const ast::FunctionDecl * );
-	void previsit( const ast::Stmt * );
-	void previsit( const ast::BranchStmt * );
-	void previsit( const ast::LabelAddressExpr * );
+	void previsit( const FunctionDecl * );
+	const FunctionDecl * postvisit( const FunctionDecl * );
+	void previsit( const Stmt * );
+	void previsit( const BranchStmt * );
+	void previsit( const LabelAddressExpr * );
 
-	void setLabelsDef( const std::vector<ast::Label> &, const ast::Stmt * );
-	void setLabelsUsage( const ast::Label & );
+	void setLabelsDef( const std::vector<Label> &, const Stmt * );
+	void setLabelsUsage( const Label & );
 };
 
-void FixLabelsCore::previsit( const ast::FunctionDecl * ) {
+void FixLabelsCore::previsit( const FunctionDecl * ) {
 	GuardValue( labelTable ).clear();
 }
 
-const ast::FunctionDecl * FixLabelsCore::postvisit(
-		const ast::FunctionDecl * decl ) {
+const FunctionDecl * FixLabelsCore::postvisit(
+	const FunctionDecl * decl ) {
 	if ( nullptr == decl->stmts ) return decl;
 	for ( auto kvp : labelTable ) {
 		if ( nullptr == kvp.second ) {
 			SemanticError( kvp.first.location,
-				"Use of undefined label: " + kvp.first.name );
+						   "Use of undefined label: " + kvp.first.name );
 		}
 	}
-	return ast::mutate_field( decl, &ast::FunctionDecl::stmts,
-		multiLevelExitUpdate( decl->stmts.get(), labelTable ) );
+	return mutate_field( decl, &FunctionDecl::stmts,
+						 multiLevelExitUpdate( decl->stmts.get(), labelTable ) );
 }
 
-void FixLabelsCore::previsit( const ast::Stmt * stmt ) {
+void FixLabelsCore::previsit( const Stmt * stmt ) {
 	if ( !stmt->labels.empty() ) {
 		setLabelsDef( stmt->labels, stmt );
@@ -63,5 +61,5 @@
 }
 
-void FixLabelsCore::previsit( const ast::BranchStmt * stmt ) {
+void FixLabelsCore::previsit( const BranchStmt * stmt ) {
 	if ( !stmt->labels.empty() ) {
 		setLabelsDef( stmt->labels, stmt );
@@ -72,5 +70,5 @@
 }
 
-void FixLabelsCore::previsit( const ast::LabelAddressExpr * expr ) {
+void FixLabelsCore::previsit( const LabelAddressExpr * expr ) {
 	assert( !expr->arg.empty() );
 	setLabelsUsage( expr->arg );
@@ -78,5 +76,5 @@
 
 void FixLabelsCore::setLabelsDef(
-		const std::vector<ast::Label> & labels, const ast::Stmt * stmt ) {
+	const std::vector<Label> & labels, const Stmt * stmt ) {
 	assert( !labels.empty() );
 	assert( stmt );
@@ -89,5 +87,5 @@
 			// Duplicate definition, this is an error.
 			SemanticError( label.location,
-				"Duplicate definition of label: " + label.name );
+						   "Duplicate definition of label: " + label.name );
 		} else {
 			// Perviously used, but not defined until now.
@@ -98,5 +96,5 @@
 
 // Label was used, if it is new add it to the table.
-void FixLabelsCore::setLabelsUsage( const ast::Label & label ) {
+void FixLabelsCore::setLabelsUsage( const Label & label ) {
 	if ( labelTable.find( label ) == labelTable.end() ) {
 		labelTable[ label ] = nullptr;
@@ -104,10 +102,7 @@
 }
 
-} // namespace
-
-void fixLabels( ast::TranslationUnit & translationUnit ) {
-	ast::Pass<FixLabelsCore>::run( translationUnit );
+void fixLabels( TranslationUnit & translationUnit ) {
+	Pass<FixLabelsCore>::run( translationUnit );
 }
-
 } // namespace ControlStruct
 
Index: src/ControlStruct/FixLabels.hpp
===================================================================
--- src/ControlStruct/FixLabels.hpp	(revision 3e5db5b4130e8f655563072771bcc8b389ad7681)
+++ src/ControlStruct/FixLabels.hpp	(revision 34c32f098e353062f8da7759b872f43ad7bc5a74)
@@ -9,7 +9,7 @@
 // Author           : Andrew Beach
 // Created On       : Mon Nov  1 09:36:00 2021
-// Last Modified By : Andrew Beach
-// Last Modified On : Mon Nov  1 09:40:00 2021
-// Update Count     : 0
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Mon Jan 31 22:18:43 2022
+// Update Count     : 2
 //
 
@@ -17,12 +17,10 @@
 
 namespace ast {
-	class TranslationUnit;
+class TranslationUnit;
 }
 
 namespace ControlStruct {
-
-/// normalizes label definitions and generates multi-level exit labels
+// normalizes label definitions and generates multi-level exit labels
 void fixLabels( ast::TranslationUnit & translationUnit );
-
 }
 
Index: src/ControlStruct/ForExprMutator.h
===================================================================
--- src/ControlStruct/ForExprMutator.h	(revision 3e5db5b4130e8f655563072771bcc8b389ad7681)
+++ src/ControlStruct/ForExprMutator.h	(revision 34c32f098e353062f8da7759b872f43ad7bc5a74)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Aug 17 15:32:48 2017
-// Update Count     : 5
+// Last Modified On : Sun Jan 30 09:14:46 2022
+// Update Count     : 6
 //
 
@@ -24,7 +24,7 @@
 	class ForExprMutator {
 	  public:
-		Statement *postmutate( IfStmt * );
-		Statement *postmutate( ForStmt * );
-		Statement *postmutate( WhileStmt * );
+		Statement * postmutate( IfStmt * );
+		Statement * postmutate( ForStmt * );
+		Statement * postmutate( WhileStmt * );
 	};
 } // namespace ControlStruct
Index: src/ControlStruct/HoistControlDecls.cpp
===================================================================
--- src/ControlStruct/HoistControlDecls.cpp	(revision 3e5db5b4130e8f655563072771bcc8b389ad7681)
+++ src/ControlStruct/HoistControlDecls.cpp	(revision 34c32f098e353062f8da7759b872f43ad7bc5a74)
@@ -9,7 +9,7 @@
 // Author           : Andrew Beach
 // Created On       : Fri Dec  3 15:34:00 2021
-// Last Modified By : Andrew Beach
-// Last Modified On : Fri Dec  3 15:34:00 2021
-// Update Count     : 0
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Mon Jan 31 18:52:35 2022
+// Update Count     : 23
 //
 
@@ -19,44 +19,62 @@
 #include "AST/Pass.hpp"
 #include "AST/TranslationUnit.hpp"
+using namespace ast;
 
 namespace ControlStruct {
 
-namespace {
+template<typename StmtT>
+const Stmt * hoist( const StmtT * stmt ) {
+	// If no hoisting is needed, then make no changes.
 
-template<typename StmtT>
-const ast::Stmt * hoist( const StmtT * stmt ) {
-	// If no hoisting is needed, then make no changes.
-	if ( 0 == stmt->inits.size() ) {
+	if ( stmt->inits.size() == 0 ) {					// no declarations ?
+		// if ( /* no conditional declarations */ ...  ) ...
 		return stmt;
-	}
+	} // if
 
-	// Put initializers and the old statement in the compound statement.
-	ast::CompoundStmt * block = new ast::CompoundStmt( stmt->location );
-	StmtT * mutStmt = ast::mutate( stmt );
-	for ( const ast::Stmt * next : mutStmt->inits ) {
+	// Put hoist declarations and modified statement in a compound statement.
+
+	CompoundStmt * block = new CompoundStmt( stmt->location ); // create empty compound statement
+	//    {
+	//    }
+
+	for ( const Stmt * next : stmt->inits ) {			// link conditional declarations into compound
 		block->kids.push_back( next );
 	}
-	mutStmt->inits.clear();
-	block->kids.push_back( mutStmt );
+	//    if ( int x = f(), y = g(); ... ) ...
+	// link declarations into compound statement
+	//    {
+	//         int x = f();
+	//         int y = g();
+	//    }
+
+	StmtT * mutStmt = mutate( stmt );					// create mutate handle to change statement
+	mutStmt->inits.clear();								// remove declarations
+	//    if ( ... ) ...
+
+	block->kids.push_back( mutStmt );					// link modified statement into compound
+	//    {
+	//        int x = f();
+	//        int y = g();
+	//        if ( ... ) ...
+	//    }
 	return block;
 }
 
-struct HoistControlCore {
-	const ast::Stmt * postvisit( const ast::IfStmt * stmt ) {
-		return hoist<ast::IfStmt>( stmt );
+struct hoistControlDeclsCore {
+	// Statements with declarations in conditional.
+	const Stmt * postvisit( const IfStmt * stmt ) {
+		return hoist<IfStmt>( stmt );
 	}
-	const ast::Stmt * postvisit( const ast::ForStmt * stmt ) {
-		return hoist<ast::ForStmt>( stmt );
+	const Stmt * postvisit( const ForStmt * stmt ) {
+		return hoist<ForStmt>( stmt );
 	}
-	const ast::Stmt * postvisit( const ast::WhileStmt * stmt ) {
-		return hoist<ast::WhileStmt>( stmt );
+	const Stmt * postvisit( const WhileStmt * stmt ) {
+		return hoist<WhileStmt>( stmt );
 	}
 };
 
-} // namespace
-
-/// Hoist initialization out of for statements.
-void hoistControlDecls( ast::TranslationUnit & translationUnit ) {
-	ast::Pass<HoistControlCore>::run( translationUnit );
+// Hoist initialization out of for statements.
+void hoistControlDecls( TranslationUnit & translationUnit ) {
+	Pass<hoistControlDeclsCore>::run( translationUnit );
 }
 
Index: src/ControlStruct/HoistControlDecls.hpp
===================================================================
--- src/ControlStruct/HoistControlDecls.hpp	(revision 3e5db5b4130e8f655563072771bcc8b389ad7681)
+++ src/ControlStruct/HoistControlDecls.hpp	(revision 34c32f098e353062f8da7759b872f43ad7bc5a74)
@@ -9,7 +9,7 @@
 // Author           : Andrew Beach
 // Created On       : Fri Dec  3 15:31:00 2021
-// Last Modified By : Andrew Beach
-// Last Modified On : Fri Dec  3 15:31:00 2021
-// Update Count     : 0
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Mon Jan 31 22:25:07 2022
+// Update Count     : 3
 //
 
@@ -17,12 +17,10 @@
 
 namespace ast {
-	class TranslationUnit;
+class TranslationUnit;
 }
 
 namespace ControlStruct {
-
-/// Hoist initialization out of control flow statements.
+// Hoist declarations out of control flow statements into compound statement.
 void hoistControlDecls( ast::TranslationUnit & translationUnit );
-
 } // namespace ControlStruct
 
Index: src/ControlStruct/LabelFixer.cc
===================================================================
--- src/ControlStruct/LabelFixer.cc	(revision 3e5db5b4130e8f655563072771bcc8b389ad7681)
+++ src/ControlStruct/LabelFixer.cc	(revision 34c32f098e353062f8da7759b872f43ad7bc5a74)
@@ -9,7 +9,7 @@
 // Author           : Rodolfo G. Esteves
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Andrew Beach
-// Last Modified On : Tue Jan 21 10:32:00 2020
-// Update Count     : 160
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Mon Jan 31 22:28:31 2022
+// Update Count     : 161
 //
 
@@ -27,107 +27,107 @@
 
 namespace ControlStruct {
-	bool LabelFixer::Entry::insideLoop() {
-		return ( dynamic_cast< ForStmt * > ( definition ) ||
-			dynamic_cast< WhileStmt * > ( definition )  );
+bool LabelFixer::Entry::insideLoop() {
+	return ( dynamic_cast< ForStmt * > ( definition ) ||
+		dynamic_cast< WhileStmt * > ( definition )  );
+}
+
+LabelFixer::LabelFixer( LabelGenerator * gen ) : generator ( gen ) {
+	if ( generator == 0 )
+		generator = LabelGenerator::getGenerator();
+}
+
+void LabelFixer::previsit( FunctionDecl * ) {
+	// need to go into a nested function in a fresh state
+	GuardValue( labelTable );
+	labelTable.clear();
+}
+
+void LabelFixer::postvisit( FunctionDecl * functionDecl ) {
+	PassVisitor<MultiLevelExitMutator> mlem( resolveJumps(), generator );
+	// We start in the body so we can stop when we hit another FunctionDecl.
+	maybeMutate( functionDecl->statements, mlem );
+}
+
+// prune to at most one label definition for each statement
+void LabelFixer::previsit( Statement * stmt ) {
+	std::list< Label > &labels = stmt->get_labels();
+
+	if ( ! labels.empty() ) {
+		// only remember one label for each statement
+		Label current = setLabelsDef( labels, stmt );
+	} // if
+}
+
+void LabelFixer::previsit( BranchStmt * branchStmt ) {
+	previsit( ( Statement *)branchStmt );
+
+	// for labeled branches, add an entry to the label table
+	Label target = branchStmt->get_target();
+	if ( target != "" ) {
+		setLabelsUsg( target, branchStmt );
+	}
+}
+
+void LabelFixer::previsit( LabelAddressExpr * addrExpr ) {
+	Label & target = addrExpr->arg;
+	assert( target != "" );
+	setLabelsUsg( target, addrExpr );
+}
+
+
+// Sets the definition of the labelTable entry to be the provided statement for every label in
+// the list parameter. Happens for every kind of statement.
+Label LabelFixer::setLabelsDef( std::list< Label > & llabel, Statement * definition ) {
+	assert( definition != 0 );
+	assert( llabel.size() > 0 );
+
+	for ( std::list< Label >::iterator i = llabel.begin(); i != llabel.end(); i++ ) {
+		Label & l = *i;
+		l.set_statement( definition ); // attach statement to the label to be used later
+		if ( labelTable.find( l ) == labelTable.end() ) {
+			// All labels on this statement need to use the same entry,
+			// so this should only be created once.
+			// undefined and unused until now, add an entry
+			labelTable[ l ] = new Entry( definition );
+		} else if ( labelTable[ l ]->defined() ) {
+			// defined twice, error
+			SemanticError( l.get_statement()->location,
+				"Duplicate definition of label: " + l.get_name() );
+		} else {
+			// used previously, but undefined until now -> link with this entry
+			// Question: Is changing objects important?
+			delete labelTable[ l ];
+			labelTable[ l ] = new Entry( definition );
+		} // if
+	} // for
+
+	// Produce one of the labels attached to this statement to be temporarily used as the
+	// canonical label.
+	return labelTable[ llabel.front() ]->get_label();
+}
+
+// A label was used, add it to the table if it isn't already there
+template< typename UsageNode >
+void LabelFixer::setLabelsUsg( Label orgValue, UsageNode *use ) {
+	assert( use != 0 );
+
+	// add label with an unknown origin
+	if ( labelTable.find( orgValue ) == labelTable.end() ) {
+		labelTable[ orgValue ] = new Entry( 0 );
+	}
+}
+
+// Builds a table that maps a label to its defining statement.
+std::map<Label, Statement * > * LabelFixer::resolveJumps() throw ( SemanticErrorException ) {
+	std::map< Label, Statement * > *ret = new std::map< Label, Statement * >();
+	for ( std::map< Label, Entry * >::iterator i = labelTable.begin(); i != labelTable.end(); ++i ) {
+		if ( ! i->second->defined() ) {
+			SemanticError( i->first.get_statement()->location, "Use of undefined label: " + i->first.get_name() );
+		}
+		(*ret)[ i->first ] = i->second->get_definition();
 	}
 
-	LabelFixer::LabelFixer( LabelGenerator * gen ) : generator ( gen ) {
-		if ( generator == 0 )
-			generator = LabelGenerator::getGenerator();
-	}
-
-	void LabelFixer::previsit( FunctionDecl * ) {
-		// need to go into a nested function in a fresh state
-		GuardValue( labelTable );
-		labelTable.clear();
-	}
-
-	void LabelFixer::postvisit( FunctionDecl * functionDecl ) {
-		PassVisitor<MultiLevelExitMutator> mlem( resolveJumps(), generator );
-		// We start in the body so we can stop when we hit another FunctionDecl.
-		maybeMutate( functionDecl->statements, mlem );
-	}
-
-	// prune to at most one label definition for each statement
-	void LabelFixer::previsit( Statement * stmt ) {
-		std::list< Label > &labels = stmt->get_labels();
-
-		if ( ! labels.empty() ) {
-			// only remember one label for each statement
-			Label current = setLabelsDef( labels, stmt );
-		} // if
-	}
-
-	void LabelFixer::previsit( BranchStmt * branchStmt ) {
-		previsit( ( Statement *)branchStmt );
-
-		// for labeled branches, add an entry to the label table
-		Label target = branchStmt->get_target();
-		if ( target != "" ) {
-			setLabelsUsg( target, branchStmt );
-		}
-	}
-
-	void LabelFixer::previsit( LabelAddressExpr * addrExpr ) {
-		Label & target = addrExpr->arg;
-		assert( target != "" );
-		setLabelsUsg( target, addrExpr );
-	}
-
-
-	// Sets the definition of the labelTable entry to be the provided statement for every label in
-	// the list parameter. Happens for every kind of statement.
-	Label LabelFixer::setLabelsDef( std::list< Label > & llabel, Statement * definition ) {
-		assert( definition != 0 );
-		assert( llabel.size() > 0 );
-
-		for ( std::list< Label >::iterator i = llabel.begin(); i != llabel.end(); i++ ) {
-			Label & l = *i;
-			l.set_statement( definition ); // attach statement to the label to be used later
-			if ( labelTable.find( l ) == labelTable.end() ) {
-				// All labels on this statement need to use the same entry,
-				// so this should only be created once.
-				// undefined and unused until now, add an entry
-				labelTable[ l ] = new Entry( definition );
-			} else if ( labelTable[ l ]->defined() ) {
-				// defined twice, error
-				SemanticError( l.get_statement()->location,
-					"Duplicate definition of label: " + l.get_name() );
-			} else {
-				// used previously, but undefined until now -> link with this entry
-				// Question: Is changing objects important?
-				delete labelTable[ l ];
-				labelTable[ l ] = new Entry( definition );
-			} // if
-		} // for
-
-		// Produce one of the labels attached to this statement to be temporarily used as the
-		// canonical label.
-		return labelTable[ llabel.front() ]->get_label();
-	}
-
-	// A label was used, add it to the table if it isn't already there
-	template< typename UsageNode >
-	void LabelFixer::setLabelsUsg( Label orgValue, UsageNode *use ) {
-		assert( use != 0 );
-
-		// add label with an unknown origin
-		if ( labelTable.find( orgValue ) == labelTable.end() ) {
-			labelTable[ orgValue ] = new Entry( 0 );
-		}
-	}
-
-	// Builds a table that maps a label to its defining statement.
-	std::map<Label, Statement * > * LabelFixer::resolveJumps() throw ( SemanticErrorException ) {
-		std::map< Label, Statement * > *ret = new std::map< Label, Statement * >();
-		for ( std::map< Label, Entry * >::iterator i = labelTable.begin(); i != labelTable.end(); ++i ) {
-			if ( ! i->second->defined() ) {
-				SemanticError( i->first.get_statement()->location, "Use of undefined label: " + i->first.get_name() );
-			}
-			(*ret)[ i->first ] = i->second->get_definition();
-		}
-
-		return ret;
-	}
+	return ret;
+}
 }  // namespace ControlStruct
 
Index: src/ControlStruct/LabelFixer.h
===================================================================
--- src/ControlStruct/LabelFixer.h	(revision 3e5db5b4130e8f655563072771bcc8b389ad7681)
+++ src/ControlStruct/LabelFixer.h	(revision 34c32f098e353062f8da7759b872f43ad7bc5a74)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Sat Jul 22 09:17:24 2017
-// Update Count     : 34
+// Last Modified On : Mon Jan 31 22:28:04 2022
+// Update Count     : 35
 //
 
@@ -26,49 +26,49 @@
 
 namespace ControlStruct {
-	/// normalizes label definitions and generates multi-level exit labels
-	class LabelGenerator;
+// normalizes label definitions and generates multi-level exit labels
+class LabelGenerator;
 
-	class LabelFixer final : public WithGuards {
-	  public:
-		LabelFixer( LabelGenerator *gen = 0 );
+class LabelFixer final : public WithGuards {
+  public:
+	LabelFixer( LabelGenerator *gen = 0 );
 
-		std::map < Label, Statement * > *resolveJumps() throw ( SemanticErrorException );
+	std::map < Label, Statement * > *resolveJumps() throw ( SemanticErrorException );
 
-		// Declarations
-		void previsit( FunctionDecl *functionDecl );
-		void postvisit( FunctionDecl *functionDecl );
+	// Declarations
+	void previsit( FunctionDecl *functionDecl );
+	void postvisit( FunctionDecl *functionDecl );
 
-		// Statements
-		void previsit( Statement *stmt );
-		void previsit( BranchStmt *branchStmt );
+	// Statements
+	void previsit( Statement *stmt );
+	void previsit( BranchStmt *branchStmt );
 
-		// Expressions
-		void previsit( LabelAddressExpr *addrExpr );
+	// Expressions
+	void previsit( LabelAddressExpr *addrExpr );
 
-		Label setLabelsDef( std::list< Label > &, Statement *definition );
-		template< typename UsageNode >
-		void setLabelsUsg( Label, UsageNode *usage = 0 );
+	Label setLabelsDef( std::list< Label > &, Statement *definition );
+	template< typename UsageNode >
+	void setLabelsUsg( Label, UsageNode *usage = 0 );
+
+  private:
+	class Entry {
+		public:
+		Entry( Statement *to ) : definition( to ) {}
+		bool defined() { return ( definition != 0 ); }
+		bool insideLoop();
+
+		Label get_label() const { return label; }
+		void set_label( Label lab ) { label = lab; }
+
+		Statement *get_definition() const { return definition; }
+		void set_definition( Statement *def ) { definition = def; }
 
 	  private:
-		class Entry {
-			public:
-			Entry( Statement *to ) : definition( to ) {}
-			bool defined() { return ( definition != 0 ); }
-			bool insideLoop();
+		Label label;
+		Statement *definition;
+	};
 
-			Label get_label() const { return label; }
-			void set_label( Label lab ) { label = lab; }
-
-			Statement *get_definition() const { return definition; }
-			void set_definition( Statement *def ) { definition = def; }
-
-		  private:
-			Label label;
-			Statement *definition;
-		};
-
-		std::map < Label, Entry *> labelTable;
-		LabelGenerator *generator;
-	};
+	std::map < Label, Entry *> labelTable;
+	LabelGenerator *generator;
+};
 } // namespace ControlStruct
 
Index: src/ControlStruct/LabelGenerator.cc
===================================================================
--- src/ControlStruct/LabelGenerator.cc	(revision 3e5db5b4130e8f655563072771bcc8b389ad7681)
+++ src/ControlStruct/LabelGenerator.cc	(revision 34c32f098e353062f8da7759b872f43ad7bc5a74)
@@ -9,7 +9,7 @@
 // Author           : Rodolfo G. Esteves
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Andrew Beach
-// Last Modified On : Mon Nov  8 10:18:00 2021
-// Update Count     : 17
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Mon Jan 31 22:30:26 2022
+// Update Count     : 28
 //
 
@@ -17,10 +17,8 @@
 #include <sstream>              // for ostringstream
 #include <list>                 // for list
+using namespace std;
 
 #include "LabelGenerator.h"
 
-#include "AST/Attribute.hpp"
-#include "AST/Label.hpp"
-#include "AST/Stmt.hpp"
 #include "SynTree/Attribute.h"  // for Attribute
 #include "SynTree/Label.h"      // for Label, operator<<
@@ -28,45 +26,27 @@
 
 namespace ControlStruct {
-
 int LabelGenerator::current = 0;
 LabelGenerator * LabelGenerator::labelGenerator = nullptr;
 
-	LabelGenerator * LabelGenerator::getGenerator() {
-		if ( LabelGenerator::labelGenerator == 0 )
-			LabelGenerator::labelGenerator = new LabelGenerator();
-		return labelGenerator;
-	}
-
-	Label LabelGenerator::newLabel( std::string suffix, Statement * stmt ) {
-		std::ostringstream os;
-		os << "__L" << current++ << "__" << suffix;
-		if ( stmt && ! stmt->get_labels().empty() ) {
-			os << "_" << stmt->get_labels().front() << "__";
-		} // if
-		std::string ret = os.str();
-		Label l( ret );
-		l.get_attributes().push_back( new Attribute("unused") );
-		return l;
-	}
-
-ast::Label LabelGenerator::newLabel(
-		const std::string & suffix, const ast::Stmt * stmt ) {
-	assert( stmt );
-
-	std::ostringstream os;
-	os << "__L" << current++ << "__" << suffix;
-	if ( stmt && !stmt->labels.empty() ) {
-		os << "_" << stmt->labels.front() << "__";
-	}
-	ast::Label ret_label( stmt->location, os.str() );
-	ret_label.attributes.push_back( new ast::Attribute( "unused" ) );
-	return ret_label;
+LabelGenerator * LabelGenerator::getGenerator() {
+	if ( LabelGenerator::labelGenerator == 0 )
+		LabelGenerator::labelGenerator = new LabelGenerator();
+	return labelGenerator;
 }
 
+Label LabelGenerator::newLabel( string suffix, Statement * stmt ) {
+	ostringstream os;
+	os << "__L_OLD" << current++ << "__" << suffix;
+	if ( stmt && ! stmt->get_labels().empty() ) {
+		os << "_" << stmt->get_labels().front() << "__";
+	} // if
+	string ret = os.str();
+	Label l( ret );
+	l.get_attributes().push_back( new Attribute( "unused" ) );
+	return l;
+}
 } // namespace ControlStruct
 
 // Local Variables: //
-// tab-width: 4 //
 // mode: c++ //
-// compile-command: "make install" //
 // End: //
Index: src/ControlStruct/LabelGenerator.h
===================================================================
--- src/ControlStruct/LabelGenerator.h	(revision 3e5db5b4130e8f655563072771bcc8b389ad7681)
+++ src/ControlStruct/LabelGenerator.h	(revision 34c32f098e353062f8da7759b872f43ad7bc5a74)
@@ -9,7 +9,7 @@
 // Author           : Rodolfo G. Esteves
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Andrew Beach
-// Last Modified On : Mon Nov  8 10:16:00 2021
-// Update Count     : 8
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Mon Jan 31 22:30:10 2022
+// Update Count     : 16
 //
 
@@ -21,24 +21,20 @@
 
 class Statement;
+
 namespace ast {
-	class Stmt;
-	class Label;
+class Stmt;
+class Label;
 }
 
 namespace ControlStruct {
-
 class LabelGenerator {
 	static int current;
 	static LabelGenerator *labelGenerator;
-protected:
+  protected:
 	LabelGenerator() {}
-public:
+  public:
 	static LabelGenerator *getGenerator();
 	static Label newLabel(std::string suffix, Statement * stmt = nullptr);
-	static ast::Label newLabel( const std::string&, const ast::Stmt * );
-	static void reset() { current = 0; }
-	static void rewind() { current--; }
 };
-
 } // namespace ControlStruct
 
Index: src/ControlStruct/LabelGeneratorNew.cpp
===================================================================
--- src/ControlStruct/LabelGeneratorNew.cpp	(revision 34c32f098e353062f8da7759b872f43ad7bc5a74)
+++ src/ControlStruct/LabelGeneratorNew.cpp	(revision 34c32f098e353062f8da7759b872f43ad7bc5a74)
@@ -0,0 +1,52 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// LabelGenerator.cc --
+//
+// Author           : Peter A. Buhr
+// Created On       : Mon May 18 07:44:20 2015
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Mon Jan 31 18:51:10 2022
+// Update Count     : 71
+//
+
+using namespace std;
+
+#include "LabelGeneratorNew.hpp"
+
+#include "AST/Attribute.hpp"
+#include "AST/Label.hpp"
+#include "AST/Stmt.hpp"
+using namespace ast;
+
+namespace ControlStruct {
+
+Label newLabel( const string & suffix, const Stmt * stmt ) {
+	static int current = 0;
+
+	assert( ( (void)"CFA internal error: parameter statement cannot be null pointer", stmt ) );
+
+	enum { size = 128 };
+	char buf[size];										// space to build label
+	int len = snprintf( buf, size, "__L%d__%s", current++, suffix.c_str() );
+	assert( ( (void)"CFA Internal error: buffer overflow creating label", len < size ) );
+
+	// What does this do?
+	if ( ! stmt->labels.empty() ) {
+		len = snprintf( buf + len, size - len, "_%s__", stmt->labels.front().name.c_str() );
+		assert( ( (void)"CFA Internal error: buffer overflow creating label", len < size - len ) );
+	} // if
+
+	Label ret_label( stmt->location, buf );
+	ret_label.attributes.push_back( new Attribute( "unused" ) );
+	return ret_label;
+}
+
+} // namespace ControlStruct
+
+// Local Variables: //
+// mode: c++ //
+// End: //
Index: src/ControlStruct/LabelGeneratorNew.hpp
===================================================================
--- src/ControlStruct/LabelGeneratorNew.hpp	(revision 34c32f098e353062f8da7759b872f43ad7bc5a74)
+++ src/ControlStruct/LabelGeneratorNew.hpp	(revision 34c32f098e353062f8da7759b872f43ad7bc5a74)
@@ -0,0 +1,35 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// LabelGenerator.h --
+//
+// Author           : Rodolfo G. Esteves
+// Created On       : Mon May 18 07:44:20 2015
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Mon Jan 31 18:03:09 2022
+// Update Count     : 27
+//
+
+#pragma once
+
+#include <string>										// for string
+
+class Statement;
+
+namespace ast {
+	class Stmt;
+	class Label;
+} // namespace ast
+
+namespace ControlStruct {
+	ast::Label newLabel( const std::string &, const ast::Stmt * );
+} // namespace ControlStruct
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/ControlStruct/MultiLevelExit.cpp
===================================================================
--- src/ControlStruct/MultiLevelExit.cpp	(revision 3e5db5b4130e8f655563072771bcc8b389ad7681)
+++ src/ControlStruct/MultiLevelExit.cpp	(revision 34c32f098e353062f8da7759b872f43ad7bc5a74)
@@ -9,7 +9,7 @@
 // Author           : Andrew Beach
 // Created On       : Mon Nov  1 13:48:00 2021
-// Last Modified By : Andrew Beach
-// Last Modified On : Mon Nov  8 10:56:00 2021
-// Update Count     : 2
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Mon Jan 31 22:35:08 2022
+// Update Count     : 28
 //
 
@@ -18,21 +18,20 @@
 #include "AST/Pass.hpp"
 #include "AST/Stmt.hpp"
-#include "ControlStruct/LabelGenerator.h"
+#include "LabelGeneratorNew.hpp"
 
 #include <set>
+using namespace std;
+using namespace ast;
 
 namespace ControlStruct {
-
-namespace {
-
 class Entry {
-public:
-	const ast::Stmt * stmt;
-private:
+  public:
+	const Stmt * stmt;
+  private:
 	// Organized like a manual ADT. Avoids creating a bunch of dead data.
 	struct Target {
-		ast::Label label;
+		Label label;
 		bool used = false;
-		Target( const ast::Label & label ) : label( label ) {}
+		Target( const Label & label ) : label( label ) {}
 		Target() : label( CodeLocation() ) {}
 	};
@@ -41,51 +40,51 @@
 
 	enum Kind {
-		ForStmt, WhileStmt, CompoundStmt, IfStmt, CaseStmt, SwitchStmt, TryStmt
+		ForStmtK, WhileStmtK, CompoundStmtK, IfStmtK, CaseStmtK, SwitchStmtK, TryStmtK
 	} kind;
 
 	bool fallDefaultValid = true;
 
-	static ast::Label & useTarget( Target & target ) {
+	static Label & useTarget( Target & target ) {
 		target.used = true;
 		return target.label;
 	}
 
-public:
-	Entry( const ast::ForStmt * stmt, ast::Label breakExit, ast::Label contExit ) :
-		stmt( stmt ), firstTarget( breakExit ), secondTarget( contExit ), kind( ForStmt ) {}
-	Entry( const ast::WhileStmt * stmt, ast::Label breakExit, ast::Label contExit ) :
-		stmt( stmt ), firstTarget( breakExit ), secondTarget( contExit ), kind( WhileStmt ) {}
-	Entry( const ast::CompoundStmt *stmt, ast::Label breakExit ) :
-		stmt( stmt ), firstTarget( breakExit ), secondTarget(), kind( CompoundStmt ) {}
-	Entry( const ast::IfStmt *stmt, ast::Label breakExit ) :
-		stmt( stmt ), firstTarget( breakExit ), secondTarget(), kind( IfStmt ) {}
-	Entry( const ast::CaseStmt *stmt, ast::Label fallExit ) :
-		stmt( stmt ), firstTarget( fallExit ), secondTarget(), kind( CaseStmt ) {}
-	Entry( const ast::SwitchStmt *stmt, ast::Label breakExit, ast::Label fallDefaultExit ) :
-		stmt( stmt ), firstTarget( breakExit ), secondTarget( fallDefaultExit ), kind( SwitchStmt ) {}
-	Entry( const ast::TryStmt *stmt, ast::Label breakExit ) :
-		stmt( stmt ), firstTarget( breakExit ), secondTarget(), kind( TryStmt ) {}
-
-	bool isContTarget() const { return kind <= WhileStmt; }
-	bool isBreakTarget() const { return CaseStmt != kind; }
-	bool isFallTarget() const { return CaseStmt == kind; }
-	bool isFallDefaultTarget() const { return SwitchStmt == kind; }
+  public:
+	Entry( const ForStmt * stmt, Label breakExit, Label contExit ) :
+		stmt( stmt ), firstTarget( breakExit ), secondTarget( contExit ), kind( ForStmtK ) {}
+	Entry( const WhileStmt * stmt, Label breakExit, Label contExit ) :
+		stmt( stmt ), firstTarget( breakExit ), secondTarget( contExit ), kind( WhileStmtK ) {}
+	Entry( const CompoundStmt *stmt, Label breakExit ) :
+		stmt( stmt ), firstTarget( breakExit ), secondTarget(), kind( CompoundStmtK ) {}
+	Entry( const IfStmt *stmt, Label breakExit ) :
+		stmt( stmt ), firstTarget( breakExit ), secondTarget(), kind( IfStmtK ) {}
+	Entry( const CaseStmt *stmt, Label fallExit ) :
+		stmt( stmt ), firstTarget( fallExit ), secondTarget(), kind( CaseStmtK ) {}
+	Entry( const SwitchStmt *stmt, Label breakExit, Label fallDefaultExit ) :
+		stmt( stmt ), firstTarget( breakExit ), secondTarget( fallDefaultExit ), kind( SwitchStmtK ) {}
+	Entry( const TryStmt *stmt, Label breakExit ) :
+		stmt( stmt ), firstTarget( breakExit ), secondTarget(), kind( TryStmtK ) {}
+
+	bool isContTarget() const { return kind <= WhileStmtK; }
+	bool isBreakTarget() const { return kind != CaseStmtK; }
+	bool isFallTarget() const { return kind == CaseStmtK; }
+	bool isFallDefaultTarget() const { return kind == SwitchStmtK; }
 
 	// These routines set a target as being "used" by a BranchStmt
-	ast::Label useContExit() { assert( kind <= WhileStmt ); return useTarget(secondTarget); }
-	ast::Label useBreakExit() { assert( CaseStmt != kind ); return useTarget(firstTarget); }
-	ast::Label useFallExit() { assert( CaseStmt == kind );  return useTarget(firstTarget); }
-	ast::Label useFallDefaultExit() { assert( SwitchStmt == kind ); return useTarget(secondTarget); }
+	Label useContExit() { assert( kind <= WhileStmtK ); return useTarget(secondTarget); }
+	Label useBreakExit() { assert( kind != CaseStmtK ); return useTarget(firstTarget); }
+	Label useFallExit() { assert( kind == CaseStmtK );  return useTarget(firstTarget); }
+	Label useFallDefaultExit() { assert( kind == SwitchStmtK ); return useTarget(secondTarget); }
 
 	// These routines check if a specific label for a statement is used by a BranchStmt
-	bool isContUsed() const { assert( kind <= WhileStmt ); return secondTarget.used; }
-	bool isBreakUsed() const { assert( CaseStmt != kind ); return firstTarget.used; }
-	bool isFallUsed() const { assert( CaseStmt == kind ); return firstTarget.used; }
-	bool isFallDefaultUsed() const { assert( SwitchStmt == kind ); return secondTarget.used; }
+	bool isContUsed() const { assert( kind <= WhileStmtK ); return secondTarget.used; }
+	bool isBreakUsed() const { assert( kind != CaseStmtK ); return firstTarget.used; }
+	bool isFallUsed() const { assert( kind == CaseStmtK ); return firstTarget.used; }
+	bool isFallDefaultUsed() const { assert( kind == SwitchStmtK ); return secondTarget.used; }
 	void seenDefault() { fallDefaultValid = false; }
 	bool isFallDefaultValid() const { return fallDefaultValid; }
 };
 
-// Helper predicates used in std::find_if calls (it doesn't take methods):
+// Helper predicates used in find_if calls (it doesn't take methods):
 bool isBreakTarget( const Entry & entry ) {
 	return entry.isBreakTarget();
@@ -105,32 +104,32 @@
 
 struct MultiLevelExitCore final :
-		public ast::WithVisitorRef<MultiLevelExitCore>,
-		public ast::WithShortCircuiting, public ast::WithGuards {
+	public WithVisitorRef<MultiLevelExitCore>,
+	public WithShortCircuiting, public WithGuards {
 	MultiLevelExitCore( const LabelToStmt & lt );
 
-	void previsit( const ast::FunctionDecl * );
-
-	const ast::CompoundStmt * previsit( const ast::CompoundStmt * );
-	const ast::BranchStmt * postvisit( const ast::BranchStmt * );
-	void previsit( const ast::WhileStmt * );
-	const ast::WhileStmt * postvisit( const ast::WhileStmt * );
-	void previsit( const ast::ForStmt * );
-	const ast::ForStmt * postvisit( const ast::ForStmt * );
-	const ast::CaseStmt * previsit( const ast::CaseStmt * );
-	void previsit( const ast::IfStmt * );
-	const ast::IfStmt * postvisit( const ast::IfStmt * );
-	void previsit( const ast::SwitchStmt * );
-	const ast::SwitchStmt * postvisit( const ast::SwitchStmt * );
-	void previsit( const ast::ReturnStmt * );
-	void previsit( const ast::TryStmt * );
-	void postvisit( const ast::TryStmt * );
-	void previsit( const ast::FinallyStmt * );
-
-	const ast::Stmt * mutateLoop( const ast::Stmt * body, Entry& );
+	void previsit( const FunctionDecl * );
+
+	const CompoundStmt * previsit( const CompoundStmt * );
+	const BranchStmt * postvisit( const BranchStmt * );
+	void previsit( const WhileStmt * );
+	const WhileStmt * postvisit( const WhileStmt * );
+	void previsit( const ForStmt * );
+	const ForStmt * postvisit( const ForStmt * );
+	const CaseStmt * previsit( const CaseStmt * );
+	void previsit( const IfStmt * );
+	const IfStmt * postvisit( const IfStmt * );
+	void previsit( const SwitchStmt * );
+	const SwitchStmt * postvisit( const SwitchStmt * );
+	void previsit( const ReturnStmt * );
+	void previsit( const TryStmt * );
+	void postvisit( const TryStmt * );
+	void previsit( const FinallyStmt * );
+
+	const Stmt * mutateLoop( const Stmt * body, Entry& );
 
 	const LabelToStmt & target_table;
-	std::set<ast::Label> fallthrough_labels;
-	std::vector<Entry> enclosing_control_structures;
-	ast::Label break_label;
+	set<Label> fallthrough_labels;
+	vector<Entry> enclosing_control_structures;
+	Label break_label;
 	bool inFinally;
 
@@ -140,17 +139,17 @@
 	const LoopNode * posthandleLoopStmt( const LoopNode * loopStmt );
 
-	std::list<ast::ptr<ast::Stmt>> fixBlock(
-		const std::list<ast::ptr<ast::Stmt>> & kids, bool caseClause );
+	list<ptr<Stmt>> fixBlock(
+		const list<ptr<Stmt>> & kids, bool caseClause );
 
 	template<typename UnaryPredicate>
 	auto findEnclosingControlStructure( UnaryPredicate pred ) {
-		return std::find_if( enclosing_control_structures.rbegin(),
-			enclosing_control_structures.rend(), pred );
+		return find_if( enclosing_control_structures.rbegin(),
+						enclosing_control_structures.rend(), pred );
 	}
 };
 
-ast::NullStmt * labelledNullStmt(
-		const CodeLocation & cl, const ast::Label & label ) {
-	return new ast::NullStmt( cl, std::vector<ast::Label>{ label } );
+NullStmt * labelledNullStmt(
+	const CodeLocation & cl, const Label & label ) {
+	return new NullStmt( cl, vector<Label>{ label } );
 }
 
@@ -160,10 +159,10 @@
 {}
 
-void MultiLevelExitCore::previsit( const ast::FunctionDecl * ) {
+void MultiLevelExitCore::previsit( const FunctionDecl * ) {
 	visit_children = false;
 }
 
-const ast::CompoundStmt * MultiLevelExitCore::previsit(
-		const ast::CompoundStmt * stmt ) {
+const CompoundStmt * MultiLevelExitCore::previsit(
+	const CompoundStmt * stmt ) {
 	visit_children = false;
 
@@ -171,12 +170,12 @@
 	bool isLabeled = !stmt->labels.empty();
 	if ( isLabeled ) {
-		ast::Label breakLabel = LabelGenerator::newLabel( "blockBreak", stmt );
+		Label breakLabel = newLabel( "blockBreak", stmt );
 		enclosing_control_structures.emplace_back( stmt, breakLabel );
 		GuardAction( [this]() { enclosing_control_structures.pop_back(); } );
 	}
 
-	auto mutStmt = ast::mutate( stmt );
+	auto mutStmt = mutate( stmt );
 	// A child statement may set the break label.
-	mutStmt->kids = std::move( fixBlock( stmt->kids, false ) );
+	mutStmt->kids = move( fixBlock( stmt->kids, false ) );
 
 	if ( isLabeled ) {
@@ -191,15 +190,15 @@
 
 size_t getUnusedIndex(
-		const ast::Stmt * stmt, const ast::Label & originalTarget ) {
+	const Stmt * stmt, const Label & originalTarget ) {
 	const size_t size = stmt->labels.size();
 
-	// If the label is empty, we can skip adding the unused attribute:
-	if ( originalTarget.empty() ) return size;
+	// If the label is empty, do not add unused attribute.
+  if ( originalTarget.empty() ) return size;
 
 	// Search for a label that matches the originalTarget.
 	for ( size_t i = 0 ; i < size ; ++i ) {
-		const ast::Label & label = stmt->labels[i];
+		const Label & label = stmt->labels[i];
 		if ( label == originalTarget ) {
-			for ( const ast::Attribute * attr : label.attributes ) {
+			for ( const Attribute * attr : label.attributes ) {
 				if ( attr->name == "unused" ) return size;
 			}
@@ -208,15 +207,15 @@
 	}
 	assertf( false, "Could not find label '%s' on statement %s",
-		originalTarget.name.c_str(), toString( stmt ).c_str() );
-}
-
-const ast::Stmt * addUnused(
-		const ast::Stmt * stmt, const ast::Label & originalTarget ) {
+			 originalTarget.name.c_str(), toString( stmt ).c_str() );
+}
+
+const Stmt * addUnused(
+	const Stmt * stmt, const Label & originalTarget ) {
 	size_t i = getUnusedIndex( stmt, originalTarget );
 	if ( i == stmt->labels.size() ) {
 		return stmt;
 	}
-	ast::Stmt * mutStmt = ast::mutate( stmt );
-	mutStmt->labels[i].attributes.push_back( new ast::Attribute( "unused" ) );
+	Stmt * mutStmt = mutate( stmt );
+	mutStmt->labels[i].attributes.push_back( new Attribute( "unused" ) );
 	return mutStmt;
 }
@@ -224,116 +223,113 @@
 // This routine updates targets on enclosing control structures to indicate which
 //     label is used by the BranchStmt that is passed
-const ast::BranchStmt * MultiLevelExitCore::postvisit( const ast::BranchStmt * stmt ) {
-	std::vector<Entry>::reverse_iterator targetEntry =
+const BranchStmt * MultiLevelExitCore::postvisit( const BranchStmt * stmt ) {
+	vector<Entry>::reverse_iterator targetEntry =
 		enclosing_control_structures.rend();
 
 	// Labels on different stmts require different approaches to access
 	switch ( stmt->kind ) {
-	case ast::BranchStmt::Goto:
+	  case BranchStmt::Goto:
 		return stmt;
-	case ast::BranchStmt::Continue:
-	case ast::BranchStmt::Break: {
-		bool isContinue = stmt->kind == ast::BranchStmt::Continue;
-		// Handle unlabeled break and continue.
-		if ( stmt->target.empty() ) {
-			if ( isContinue ) {
-				targetEntry = findEnclosingControlStructure( isContinueTarget );
-			} else {
-				if ( enclosing_control_structures.empty() ) {
-					SemanticError( stmt->location,
-						"'break' outside a loop, 'switch', or labelled block" );
-				}
-				targetEntry = findEnclosingControlStructure( isBreakTarget );
-			}
-		// Handle labeled break and continue.
-		} else {
-			// Lookup label in table to find attached control structure.
-			targetEntry = findEnclosingControlStructure(
-				[ targetStmt = target_table.at(stmt->target) ](auto entry){
-					return entry.stmt == targetStmt;
-				} );
-		}
-		// Ensure that selected target is valid.
-		if ( targetEntry == enclosing_control_structures.rend() || ( isContinue && !isContinueTarget( *targetEntry ) ) ) {
-			SemanticError(
-				stmt->location,
-				toString( (isContinue ? "'continue'" : "'break'"),
-					" target must be an enclosing ",
-					(isContinue ? "loop: " : "control structure: "),
-					stmt->originalTarget ) );
-		}
-		break;
-	}
-	// handle fallthrough in case/switch stmts
-	case ast::BranchStmt::FallThrough: {
-		targetEntry = findEnclosingControlStructure( isFallthroughTarget );
-		// Check that target is valid.
-		if ( targetEntry == enclosing_control_structures.rend() ) {
-			SemanticError( stmt->location, "'fallthrough' must be enclosed in a 'switch' or 'choose'" );
-		}
-		if ( !stmt->target.empty() ) {
-			// Labelled fallthrough: target must be a valid fallthough label.
-			if ( !fallthrough_labels.count( stmt->target ) ) {
-				SemanticError( stmt->location, toString( "'fallthrough' target must be a later case statement: ", stmt->originalTarget ) );
-			}
-			return new ast::BranchStmt(
-				stmt->location, ast::BranchStmt::Goto, stmt->originalTarget );
-		}
-		break;
-	}
-	case ast::BranchStmt::FallThroughDefault: {
-		targetEntry = findEnclosingControlStructure( isFallthroughDefaultTarget );
-
-		// Check that this is in a switch or choose statement.
-		if ( targetEntry == enclosing_control_structures.rend() ) {
-			SemanticError( stmt->location, "'fallthrough' must be enclosed in a 'switch' or 'choose'" );
-		}
-
-		// Check that the switch or choose has a default clause.
-		auto switchStmt = strict_dynamic_cast< const ast::SwitchStmt * >(
-			targetEntry->stmt );
-		bool foundDefault = false;
-		for ( auto subStmt : switchStmt->stmts ) {
-			const ast::CaseStmt * caseStmt = subStmt.strict_as<ast::CaseStmt>();
-			if ( caseStmt->isDefault() ) {
-				foundDefault = true;
-				break;
-			}
-		}
-		if ( !foundDefault ) {
-			SemanticError( stmt->location, "'fallthrough default' must be enclosed in a 'switch' or 'choose' control structure with a 'default' clause" );
-		}
-		break;
-	}
-	default:
+	  case BranchStmt::Continue:
+	  case BranchStmt::Break: {
+		  bool isContinue = stmt->kind == BranchStmt::Continue;
+		  // Handle unlabeled break and continue.
+		  if ( stmt->target.empty() ) {
+			  if ( isContinue ) {
+				  targetEntry = findEnclosingControlStructure( isContinueTarget );
+			  } else {
+				  if ( enclosing_control_structures.empty() ) {
+					  SemanticError( stmt->location,
+									 "'break' outside a loop, 'switch', or labelled block" );
+				  }
+				  targetEntry = findEnclosingControlStructure( isBreakTarget );
+			  }
+			  // Handle labeled break and continue.
+		  } else {
+			  // Lookup label in table to find attached control structure.
+			  targetEntry = findEnclosingControlStructure(
+				  [ targetStmt = target_table.at(stmt->target) ](auto entry){
+					  return entry.stmt == targetStmt;
+				  } );
+		  }
+		  // Ensure that selected target is valid.
+		  if ( targetEntry == enclosing_control_structures.rend() || ( isContinue && !isContinueTarget( *targetEntry ) ) ) {
+			  SemanticError( stmt->location, toString( (isContinue ? "'continue'" : "'break'"),
+							" target must be an enclosing ", (isContinue ? "loop: " : "control structure: "),
+							stmt->originalTarget ) );
+		  }
+		  break;
+	  }
+	  // handle fallthrough in case/switch stmts
+	  case BranchStmt::FallThrough: {
+		  targetEntry = findEnclosingControlStructure( isFallthroughTarget );
+		  // Check that target is valid.
+		  if ( targetEntry == enclosing_control_structures.rend() ) {
+			  SemanticError( stmt->location, "'fallthrough' must be enclosed in a 'switch' or 'choose'" );
+		  }
+		  if ( !stmt->target.empty() ) {
+			  // Labelled fallthrough: target must be a valid fallthough label.
+			  if ( !fallthrough_labels.count( stmt->target ) ) {
+				  SemanticError( stmt->location, toString( "'fallthrough' target must be a later case statement: ",
+														   stmt->originalTarget ) );
+			  }
+			  return new BranchStmt(
+				  stmt->location, BranchStmt::Goto, stmt->originalTarget );
+		  }
+		  break;
+	  }
+	  case BranchStmt::FallThroughDefault: {
+		  targetEntry = findEnclosingControlStructure( isFallthroughDefaultTarget );
+
+		  // Check if in switch or choose statement.
+		  if ( targetEntry == enclosing_control_structures.rend() ) {
+			  SemanticError( stmt->location, "'fallthrough' must be enclosed in a 'switch' or 'choose'" );
+		  }
+
+		  // Check if switch or choose has default clause.
+		  auto switchStmt = strict_dynamic_cast< const SwitchStmt * >( targetEntry->stmt );
+		  bool foundDefault = false;
+		  for ( auto subStmt : switchStmt->stmts ) {
+			  const CaseStmt * caseStmt = subStmt.strict_as<CaseStmt>();
+			  if ( caseStmt->isDefault() ) {
+				  foundDefault = true;
+				  break;
+			  }
+		  }
+		  if ( ! foundDefault ) {
+			  SemanticError( stmt->location, "'fallthrough default' must be enclosed in a 'switch' or 'choose'"
+							 "control structure with a 'default' clause" );
+		  }
+		  break;
+	  }
+	  default:
 		assert( false );
 	}
 
 	// Branch error checks: get the appropriate label name:
-	// (This label will always be replaced.)
-	ast::Label exitLabel( CodeLocation(), "" );
+	// (This label is always replaced.)
+	Label exitLabel( CodeLocation(), "" );
 	switch ( stmt->kind ) {
-	case ast::BranchStmt::Break:
+	  case BranchStmt::Break:
 		assert( !targetEntry->useBreakExit().empty() );
 		exitLabel = targetEntry->useBreakExit();
 		break;
-	case ast::BranchStmt::Continue:
+	  case BranchStmt::Continue:
 		assert( !targetEntry->useContExit().empty() );
 		exitLabel = targetEntry->useContExit();
 		break;
-	case ast::BranchStmt::FallThrough:
+	  case BranchStmt::FallThrough:
 		assert( !targetEntry->useFallExit().empty() );
 		exitLabel = targetEntry->useFallExit();
 		break;
-	case ast::BranchStmt::FallThroughDefault:
+	  case BranchStmt::FallThroughDefault:
 		assert( !targetEntry->useFallDefaultExit().empty() );
 		exitLabel = targetEntry->useFallDefaultExit();
 		// Check that fallthrough default comes before the default clause.
 		if ( !targetEntry->isFallDefaultValid() ) {
-			SemanticError( stmt->location,
-				"'fallthrough default' must precede the 'default' clause" );
+			SemanticError( stmt->location, "'fallthrough default' must precede the 'default' clause" );
 		}
 		break;
-	default:
+	  default:
 		assert(0);
 	}
@@ -342,21 +338,21 @@
 	targetEntry->stmt = addUnused( targetEntry->stmt, stmt->originalTarget );
 
-	// Replace this with a goto to make later passes more uniform.
-	return new ast::BranchStmt( stmt->location, ast::BranchStmt::Goto, exitLabel );
-}
-
-void MultiLevelExitCore::previsit( const ast::WhileStmt * stmt ) {
+	// Replace with goto to make later passes more uniform.
+	return new BranchStmt( stmt->location, BranchStmt::Goto, exitLabel );
+}
+
+void MultiLevelExitCore::previsit( const WhileStmt * stmt ) {
 	return prehandleLoopStmt( stmt );
 }
 
-const ast::WhileStmt * MultiLevelExitCore::postvisit( const ast::WhileStmt * stmt ) {
+const WhileStmt * MultiLevelExitCore::postvisit( const WhileStmt * stmt ) {
 	return posthandleLoopStmt( stmt );
 }
 
-void MultiLevelExitCore::previsit( const ast::ForStmt * stmt ) {
+void MultiLevelExitCore::previsit( const ForStmt * stmt ) {
 	return prehandleLoopStmt( stmt );
 }
 
-const ast::ForStmt * MultiLevelExitCore::postvisit( const ast::ForStmt * stmt ) {
+const ForStmt * MultiLevelExitCore::postvisit( const ForStmt * stmt ) {
 	return posthandleLoopStmt( stmt );
 }
@@ -364,16 +360,16 @@
 // Mimic what the built-in push_front would do anyways. It is O(n).
 void push_front(
-		std::vector<ast::ptr<ast::Stmt>> & vec, const ast::Stmt * element ) {
+	vector<ptr<Stmt>> & vec, const Stmt * element ) {
 	vec.emplace_back( nullptr );
 	for ( size_t i = vec.size() - 1 ; 0 < i ; --i ) {
-		vec[ i ] = std::move( vec[ i - 1 ] );
+		vec[ i ] = move( vec[ i - 1 ] );
 	}
 	vec[ 0 ] = element;
 }
 
-const ast::CaseStmt * MultiLevelExitCore::previsit( const ast::CaseStmt * stmt ) {
+const CaseStmt * MultiLevelExitCore::previsit( const CaseStmt * stmt ) {
 	visit_children = false;
 
-	// If it is the default, mark the default as seen.
+	// If default, mark seen.
 	if ( stmt->isDefault() ) {
 		assert( !enclosing_control_structures.empty() );
@@ -382,23 +378,23 @@
 
 	// The cond may not exist, but if it does update it now.
-	visitor->maybe_accept( stmt, &ast::CaseStmt::cond );
+	visitor->maybe_accept( stmt, &CaseStmt::cond );
 
 	// Just save the mutated node for simplicity.
-	ast::CaseStmt * mutStmt = ast::mutate( stmt );
-
-	ast::Label fallLabel = LabelGenerator::newLabel( "fallThrough", stmt );
-	if ( !mutStmt->stmts.empty() ) {
+	CaseStmt * mutStmt = mutate( stmt );
+
+	Label fallLabel = newLabel( "fallThrough", stmt );
+	if ( ! mutStmt->stmts.empty() ) {
 		// Ensure that the stack isn't corrupted by exceptions in fixBlock.
 		auto guard = makeFuncGuard(
 			[&](){ enclosing_control_structures.emplace_back( mutStmt, fallLabel ); },
 			[this](){ enclosing_control_structures.pop_back(); }
-		);
+			);
 
 		// These should already be in a block.
-		auto block = ast::mutate( mutStmt->stmts.front().strict_as<ast::CompoundStmt>() );
+		auto block = mutate( mutStmt->stmts.front().strict_as<CompoundStmt>() );
 		block->kids = fixBlock( block->kids, true );
 
 		// Add fallthrough label if necessary.
-		assert( !enclosing_control_structures.empty() );
+		assert( ! enclosing_control_structures.empty() );
 		Entry & entry = enclosing_control_structures.back();
 		if ( entry.isFallUsed() ) {
@@ -407,15 +403,15 @@
 		}
 	}
-	assert( !enclosing_control_structures.empty() );
+	assert( ! enclosing_control_structures.empty() );
 	Entry & entry = enclosing_control_structures.back();
-	assertf( dynamic_cast< const ast::SwitchStmt * >( entry.stmt ),
-		"Control structure enclosing a case clause must be a switch, but is: %s",
-		toString( entry.stmt ).c_str() );
+	assertf( dynamic_cast< const SwitchStmt * >( entry.stmt ),
+			 "Control structure enclosing a case clause must be a switch, but is: %s",
+			 toString( entry.stmt ).c_str() );
 	if ( mutStmt->isDefault() ) {
 		if ( entry.isFallDefaultUsed() ) {
 			// Add fallthrough default label if necessary.
 			push_front( mutStmt->stmts, labelledNullStmt(
-				stmt->location, entry.useFallDefaultExit()
-			) );
+							stmt->location, entry.useFallDefaultExit()
+							) );
 		}
 	}
@@ -423,8 +419,8 @@
 }
 
-void MultiLevelExitCore::previsit( const ast::IfStmt * stmt ) {
+void MultiLevelExitCore::previsit( const IfStmt * stmt ) {
 	bool labeledBlock = !stmt->labels.empty();
 	if ( labeledBlock ) {
-		ast::Label breakLabel = LabelGenerator::newLabel( "blockBreak", stmt );
+		Label breakLabel = newLabel( "blockBreak", stmt );
 		enclosing_control_structures.emplace_back( stmt, breakLabel );
 		GuardAction( [this](){ enclosing_control_structures.pop_back(); } );
@@ -432,5 +428,5 @@
 }
 
-const ast::IfStmt * MultiLevelExitCore::postvisit( const ast::IfStmt * stmt ) {
+const IfStmt * MultiLevelExitCore::postvisit( const IfStmt * stmt ) {
 	bool labeledBlock = !stmt->labels.empty();
 	if ( labeledBlock ) {
@@ -443,29 +439,29 @@
 }
 
-bool isDefaultCase( const ast::ptr<ast::Stmt> & stmt ) {
-	const ast::CaseStmt * caseStmt = stmt.strict_as<ast::CaseStmt>();
+bool isDefaultCase( const ptr<Stmt> & stmt ) {
+	const CaseStmt * caseStmt = stmt.strict_as<CaseStmt>();
 	return caseStmt->isDefault();
 }
 
-void MultiLevelExitCore::previsit( const ast::SwitchStmt * stmt ) {
-	ast::Label label = LabelGenerator::newLabel( "switchBreak", stmt );
-	auto it = std::find_if( stmt->stmts.rbegin(), stmt->stmts.rend(), isDefaultCase );
-
-	const ast::CaseStmt * defaultCase = it != stmt->stmts.rend()
-		? (it)->strict_as<ast::CaseStmt>() : nullptr;
-	ast::Label defaultLabel = defaultCase
-		? LabelGenerator::newLabel( "fallThroughDefault", defaultCase )
-		: ast::Label( stmt->location, "" );
+void MultiLevelExitCore::previsit( const SwitchStmt * stmt ) {
+	Label label = newLabel( "switchBreak", stmt );
+	auto it = find_if( stmt->stmts.rbegin(), stmt->stmts.rend(), isDefaultCase );
+
+	const CaseStmt * defaultCase = it != stmt->stmts.rend()
+		? (it)->strict_as<CaseStmt>() : nullptr;
+	Label defaultLabel = defaultCase
+		? newLabel( "fallThroughDefault", defaultCase )
+		: Label( stmt->location, "" );
 	enclosing_control_structures.emplace_back( stmt, label, defaultLabel );
 	GuardAction( [this]() { enclosing_control_structures.pop_back(); } );
 
 	// Collect valid labels for fallthrough. It starts with all labels at
-	// this level, then removed as we see them in traversal.
-	for ( const ast::Stmt * stmt : stmt->stmts ) {
-		auto * caseStmt = strict_dynamic_cast< const ast::CaseStmt * >( stmt );
+	// this level, then remove as each is seen during traversal.
+	for ( const Stmt * stmt : stmt->stmts ) {
+		auto * caseStmt = strict_dynamic_cast< const CaseStmt * >( stmt );
 		if ( caseStmt->stmts.empty() ) continue;
-		auto block = caseStmt->stmts.front().strict_as<ast::CompoundStmt>();
-		for ( const ast::Stmt * stmt : block->kids ) {
-			for ( const ast::Label & l : stmt->labels ) {
+		auto block = caseStmt->stmts.front().strict_as<CompoundStmt>();
+		for ( const Stmt * stmt : block->kids ) {
+			for ( const Label & l : stmt->labels ) {
 				fallthrough_labels.insert( l );
 			}
@@ -474,26 +470,26 @@
 }
 
-const ast::SwitchStmt * MultiLevelExitCore::postvisit( const ast::SwitchStmt * stmt ) {
+const SwitchStmt * MultiLevelExitCore::postvisit( const SwitchStmt * stmt ) {
 	assert( !enclosing_control_structures.empty() );
 	Entry & entry = enclosing_control_structures.back();
 	assert( entry.stmt == stmt );
 
-	// Only run if we need to generate the break label.
+	// Only run to generate the break label.
 	if ( entry.isBreakUsed() ) {
 		// To keep the switch statements uniform (all direct children of a
 		// SwitchStmt should be CastStmts), append the exit label and break
 		// to the last case, create a default case is there are no cases.
-		ast::SwitchStmt * mutStmt = ast::mutate( stmt );
+		SwitchStmt * mutStmt = mutate( stmt );
 		if ( mutStmt->stmts.empty() ) {
-			mutStmt->stmts.push_back( new ast::CaseStmt(
-				mutStmt->location, nullptr, {} ));
-		}
-
-		auto caseStmt = mutStmt->stmts.back().strict_as<ast::CaseStmt>();
-		auto mutCase = ast::mutate( caseStmt );
+			mutStmt->stmts.push_back( new CaseStmt(
+										  mutStmt->location, nullptr, {} ));
+		}
+
+		auto caseStmt = mutStmt->stmts.back().strict_as<CaseStmt>();
+		auto mutCase = mutate( caseStmt );
 		mutStmt->stmts.back() = mutCase;
 
-		ast::Label label( mutCase->location, "breakLabel" );
-		auto branch = new ast::BranchStmt( mutCase->location, ast::BranchStmt::Break, label );
+		Label label( mutCase->location, "breakLabel" );
+		auto branch = new BranchStmt( mutCase->location, BranchStmt::Break, label );
 		branch->labels.push_back( entry.useBreakExit() );
 		mutCase->stmts.push_back( branch );
@@ -504,5 +500,5 @@
 }
 
-void MultiLevelExitCore::previsit( const ast::ReturnStmt * stmt ) {
+void MultiLevelExitCore::previsit( const ReturnStmt * stmt ) {
 	if ( inFinally ) {
 		SemanticError( stmt->location, "'return' may not appear in a finally clause" );
@@ -510,8 +506,8 @@
 }
 
-void MultiLevelExitCore::previsit( const ast::TryStmt * stmt ) {
+void MultiLevelExitCore::previsit( const TryStmt * stmt ) {
 	bool isLabeled = !stmt->labels.empty();
 	if ( isLabeled ) {
-		ast::Label breakLabel = LabelGenerator::newLabel( "blockBreak", stmt );
+		Label breakLabel = newLabel( "blockBreak", stmt );
 		enclosing_control_structures.emplace_back( stmt, breakLabel );
 		GuardAction([this](){ enclosing_control_structures.pop_back(); } );
@@ -519,5 +515,5 @@
 }
 
-void MultiLevelExitCore::postvisit( const ast::TryStmt * stmt ) {
+void MultiLevelExitCore::postvisit( const TryStmt * stmt ) {
 	bool isLabeled = !stmt->labels.empty();
 	if ( isLabeled ) {
@@ -529,14 +525,14 @@
 }
 
-void MultiLevelExitCore::previsit( const ast::FinallyStmt * ) {
-	GuardAction([this, old = std::move(enclosing_control_structures)](){
-		enclosing_control_structures = std::move(old);
-	});
-	enclosing_control_structures = std::vector<Entry>();
+void MultiLevelExitCore::previsit( const FinallyStmt * ) {
+	GuardAction([this, old = move(enclosing_control_structures)](){
+					enclosing_control_structures = move(old);
+				});
+	enclosing_control_structures = vector<Entry>();
 	GuardValue( inFinally ) = true;
 }
 
-const ast::Stmt * MultiLevelExitCore::mutateLoop(
-		const ast::Stmt * body, Entry & entry ) {
+const Stmt * MultiLevelExitCore::mutateLoop(
+	const Stmt * body, Entry & entry ) {
 	if ( entry.isBreakUsed() ) {
 		break_label = entry.useBreakExit();
@@ -545,5 +541,5 @@
 	// if continue is used insert a continue label into the back of the body of the loop
 	if ( entry.isContUsed() ) {
-		ast::CompoundStmt * new_body = new ast::CompoundStmt( body->location );
+		CompoundStmt * new_body = new CompoundStmt( body->location );
 		// {}
 		new_body->kids.push_back( body );
@@ -567,6 +563,6 @@
 	// Remember is loop before going onto mutate the body.
 	// The labels will be folded in if they are used.
-	ast::Label breakLabel = LabelGenerator::newLabel( "loopBreak", loopStmt );
-	ast::Label contLabel = LabelGenerator::newLabel( "loopContinue", loopStmt );
+	Label breakLabel = newLabel( "loopBreak", loopStmt );
+	Label contLabel = newLabel( "loopContinue", loopStmt );
 	enclosing_control_structures.emplace_back( loopStmt, breakLabel, contLabel );
 	// labels are added temporarily to see if they are used and then added permanently in postvisit if ther are used
@@ -583,6 +579,6 @@
 	assert( entry.stmt == loopStmt );
 
-	// Now we check if the labels are used and add them if so.
-	return ast::mutate_field(
+	// Now check if the labels are used and add them if so.
+	return mutate_field(
 		loopStmt, &LoopNode::body, mutateLoop( loopStmt->body, entry ) );
 	// this call to mutate_field compares loopStmt->body and the result of mutateLoop
@@ -591,16 +587,16 @@
 }
 
-std::list<ast::ptr<ast::Stmt>> MultiLevelExitCore::fixBlock(
-		const std::list<ast::ptr<ast::Stmt>> & kids, bool is_case_clause ) {
-	// Unfortunately we can't use the automatic error collection.
+list<ptr<Stmt>> MultiLevelExitCore::fixBlock(
+	const list<ptr<Stmt>> & kids, bool is_case_clause ) {
+	// Unfortunately cannot use automatic error collection.
 	SemanticErrorException errors;
 
-	std::list<ast::ptr<ast::Stmt>> ret;
+	list<ptr<Stmt>> ret;
 
 	// Manually visit each child.
-	for ( const ast::ptr<ast::Stmt> & kid : kids ) {
+	for ( const ptr<Stmt> & kid : kids ) {
 		if ( is_case_clause ) {
 			// Once a label is seen, it's no longer a valid for fallthrough.
-			for ( const ast::Label & l : kid->labels ) {
+			for ( const Label & l : kid->labels ) {
 				fallthrough_labels.erase( l );
 			}
@@ -616,5 +612,5 @@
 			ret.push_back(
 				labelledNullStmt( ret.back()->location, break_label ) );
-			break_label = ast::Label( CodeLocation(), "" );
+			break_label = Label( CodeLocation(), "" );
 		}
 	}
@@ -626,15 +622,12 @@
 }
 
-} // namespace
-
-const ast::CompoundStmt * multiLevelExitUpdate(
-    	const ast::CompoundStmt * stmt,
-		const LabelToStmt & labelTable ) {
+const CompoundStmt * multiLevelExitUpdate(
+	const CompoundStmt * stmt,
+	const LabelToStmt & labelTable ) {
 	// Must start in the body, so FunctionDecls can be a stopping point.
-	ast::Pass<MultiLevelExitCore> visitor( labelTable );
-	const ast::CompoundStmt * ret = stmt->accept( visitor );
+	Pass<MultiLevelExitCore> visitor( labelTable );
+	const CompoundStmt * ret = stmt->accept( visitor );
 	return ret;
 }
-
 } // namespace ControlStruct
 
Index: src/ControlStruct/MultiLevelExit.hpp
===================================================================
--- src/ControlStruct/MultiLevelExit.hpp	(revision 3e5db5b4130e8f655563072771bcc8b389ad7681)
+++ src/ControlStruct/MultiLevelExit.hpp	(revision 34c32f098e353062f8da7759b872f43ad7bc5a74)
@@ -9,7 +9,7 @@
 // Author           : Andrew Beach
 // Created On       : Mon Nov  1 13:49:00 2021
-// Last Modified By : Andrew Beach
-// Last Modified On : Mon Nov  8 10:53:00 2021
-// Update Count     : 3
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Mon Jan 31 22:34:06 2022
+// Update Count     : 6
 //
 
@@ -19,17 +19,14 @@
 
 namespace ast {
-	class CompoundStmt;
-	class Label;
-	class Stmt;
+class CompoundStmt;
+class Label;
+class Stmt;
 }
 
 namespace ControlStruct {
-
 using LabelToStmt = std::map<ast::Label, const ast::Stmt *>;
 
-/// Mutate a function body to handle multi-level exits.
-const ast::CompoundStmt * multiLevelExitUpdate(
-	const ast::CompoundStmt *, const LabelToStmt & );
-
+// Mutate a function body to handle multi-level exits.
+const ast::CompoundStmt * multiLevelExitUpdate(	const ast::CompoundStmt *, const LabelToStmt & );
 }
 
Index: src/ControlStruct/module.mk
===================================================================
--- src/ControlStruct/module.mk	(revision 3e5db5b4130e8f655563072771bcc8b389ad7681)
+++ src/ControlStruct/module.mk	(revision 34c32f098e353062f8da7759b872f43ad7bc5a74)
@@ -10,7 +10,7 @@
 ## Author           : Richard C. Bilson
 ## Created On       : Mon Jun  1 17:49:17 2015
-## Last Modified By : Henry Xue
-## Last Modified On : Tue Jul 20 04:10:50 2021
-## Update Count     : 5
+## Last Modified By : Peter A. Buhr
+## Last Modified On : Sat Jan 29 12:04:19 2022
+## Update Count     : 7
 ###############################################################################
 
@@ -28,4 +28,6 @@
 	ControlStruct/LabelGenerator.cc \
 	ControlStruct/LabelGenerator.h \
+	ControlStruct/LabelGeneratorNew.cpp \
+	ControlStruct/LabelGeneratorNew.hpp \
 	ControlStruct/MLEMutator.cc \
 	ControlStruct/MLEMutator.h \
Index: src/Parser/ParseNode.h
===================================================================
--- src/Parser/ParseNode.h	(revision 3e5db5b4130e8f655563072771bcc8b389ad7681)
+++ src/Parser/ParseNode.h	(revision 34c32f098e353062f8da7759b872f43ad7bc5a74)
@@ -10,6 +10,6 @@
 // Created On       : Sat May 16 13:28:16 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Jul 14 17:28:53 2021
-// Update Count     : 900
+// Last Modified On : Sat Jan 29 09:45:56 2022
+// Update Count     : 901
 //
 
@@ -390,6 +390,6 @@
 Statement * build_expr( ExpressionNode * ctl );
 
-struct IfCtrl {
-	IfCtrl( DeclarationNode * decl, ExpressionNode * condition ) :
+struct CondCtl {
+	CondCtl( DeclarationNode * decl, ExpressionNode * condition ) :
 		init( decl ? new StatementNode( decl ) : nullptr ), condition( condition ) {}
 
@@ -409,10 +409,10 @@
 };
 
-Expression * build_if_control( IfCtrl * ctl, std::list< Statement * > & init );
-Statement * build_if( IfCtrl * ctl, StatementNode * then_stmt, StatementNode * else_stmt );
+Expression * build_if_control( CondCtl * ctl, std::list< Statement * > & init );
+Statement * build_if( CondCtl * ctl, StatementNode * then_stmt, StatementNode * else_stmt );
 Statement * build_switch( bool isSwitch, ExpressionNode * ctl, StatementNode * stmt );
 Statement * build_case( ExpressionNode * ctl );
 Statement * build_default();
-Statement * build_while( IfCtrl * ctl, StatementNode * stmt );
+Statement * build_while( CondCtl * ctl, StatementNode * stmt );
 Statement * build_do_while( ExpressionNode * ctl, StatementNode * stmt );
 Statement * build_for( ForCtrl * forctl, StatementNode * stmt );
Index: src/Parser/StatementNode.cc
===================================================================
--- src/Parser/StatementNode.cc	(revision 3e5db5b4130e8f655563072771bcc8b389ad7681)
+++ src/Parser/StatementNode.cc	(revision 34c32f098e353062f8da7759b872f43ad7bc5a74)
@@ -10,6 +10,6 @@
 // Created On       : Sat May 16 14:59:41 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Sat Oct 24 04:20:55 2020
-// Update Count     : 383
+// Last Modified On : Sat Jan 29 09:45:51 2022
+// Update Count     : 384
 //
 
@@ -78,5 +78,5 @@
 } // build_expr
 
-Expression * build_if_control( IfCtrl * ctl, std::list< Statement * > & init ) {
+Expression * build_if_control( CondCtl * ctl, std::list< Statement * > & init ) {
 	if ( ctl->init != 0 ) {
 		buildMoveList( ctl->init, init );
@@ -100,5 +100,5 @@
 } // build_if_control
 
-Statement * build_if( IfCtrl * ctl, StatementNode * then_stmt, StatementNode * else_stmt ) {
+Statement * build_if( CondCtl * ctl, StatementNode * then_stmt, StatementNode * else_stmt ) {
 	Statement * thenb, * elseb = nullptr;
 	std::list< Statement * > branches;
@@ -145,5 +145,5 @@
 } // build_default
 
-Statement * build_while( IfCtrl * ctl, StatementNode * stmt ) {
+Statement * build_while( CondCtl * ctl, StatementNode * stmt ) {
 	std::list< Statement * > branches;
 	buildMoveList< Statement, StatementNode >( stmt, branches );
Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision 3e5db5b4130e8f655563072771bcc8b389ad7681)
+++ src/Parser/parser.yy	(revision 34c32f098e353062f8da7759b872f43ad7bc5a74)
@@ -10,6 +10,6 @@
 // Created On       : Sat Sep  1 20:22:55 2001
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Oct 15 09:20:17 2021
-// Update Count     : 5163
+// Last Modified On : Sun Jan 30 09:41:13 2022
+// Update Count     : 5165
 //
 
@@ -238,5 +238,5 @@
 	WaitForStmt * wfs;
 	Expression * constant;
-	IfCtrl * ifctl;
+	CondCtl * ifctl;
 	ForCtrl * fctl;
 	enum OperKinds compop;
@@ -327,5 +327,5 @@
 %type<en> comma_expression				comma_expression_opt
 %type<en> argument_expression_list_opt	argument_expression_list	argument_expression			default_initializer_opt
-%type<ifctl> if_control_expression
+%type<ifctl> conditional_declaration
 %type<fctl> for_control_expression		for_control_expression_list
 %type<compop> inclexcl
@@ -1123,20 +1123,20 @@
 
 if_statement:
-	IF '(' if_control_expression ')' statement			%prec THEN
+	IF '(' conditional_declaration ')' statement		%prec THEN
 		// explicitly deal with the shift/reduce conflict on if/else
 		{ $$ = new StatementNode( build_if( $3, maybe_build_compound( $5 ), nullptr ) ); }
-	| IF '(' if_control_expression ')' statement ELSE statement
+	| IF '(' conditional_declaration ')' statement ELSE statement
 		{ $$ = new StatementNode( build_if( $3, maybe_build_compound( $5 ), maybe_build_compound( $7 ) ) ); }
 	;
 
-if_control_expression:
+conditional_declaration:
 	comma_expression
-		{ $$ = new IfCtrl( nullptr, $1 ); }
+		{ $$ = new CondCtl( nullptr, $1 ); }
 	| c_declaration										// no semi-colon
-		{ $$ = new IfCtrl( $1, nullptr ); }
+		{ $$ = new CondCtl( $1, nullptr ); }
 	| cfa_declaration									// no semi-colon
-		{ $$ = new IfCtrl( $1, nullptr ); }
+		{ $$ = new CondCtl( $1, nullptr ); }
 	| declaration comma_expression						// semi-colon separated
-		{ $$ = new IfCtrl( $1, $2 ); }
+		{ $$ = new CondCtl( $1, $2 ); }
  	;
 
@@ -1193,8 +1193,8 @@
 iteration_statement:
 	WHILE '(' ')' statement								// CFA => while ( 1 )
-		{ $$ = new StatementNode( build_while( new IfCtrl( nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ), maybe_build_compound( $4 ) ) ); }
-	| WHILE '(' if_control_expression ')' statement		%prec THEN
+		{ $$ = new StatementNode( build_while( new CondCtl( nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ), maybe_build_compound( $4 ) ) ); }
+	| WHILE '(' conditional_declaration ')' statement	%prec THEN
 		{ $$ = new StatementNode( build_while( $3, maybe_build_compound( $5 ) ) ); }
-	| WHILE '(' if_control_expression ')' statement ELSE statement // CFA
+	| WHILE '(' conditional_declaration ')' statement ELSE statement // CFA
 		{ SemanticError( yylloc, "Loop default block is currently unimplemented." ); $$ = nullptr; }
 	| DO statement WHILE '(' ')' ';'					// CFA => do while( 1 )
Index: tests/concurrent/preempt.cfa
===================================================================
--- tests/concurrent/preempt.cfa	(revision 3e5db5b4130e8f655563072771bcc8b389ad7681)
+++ tests/concurrent/preempt.cfa	(revision 34c32f098e353062f8da7759b872f43ad7bc5a74)
@@ -1,2 +1,3 @@
+#include <clock.hfa>
 #include <fstream.hfa>
 #include <kernel.hfa>
@@ -22,9 +23,13 @@
 extern void __cfaabi_check_preemption();
 
-static volatile int counter = 0;
+static struct {
+	volatile int counter;
+	volatile Time prev;
+	Duration durations[6];
+} globals;
 
 thread worker_t {
 	int value;
-	unsigned spin;
+	unsigned long long spin;
 };
 
@@ -35,12 +40,26 @@
 
 void main(worker_t & this) {
-	while(TEST(counter < N)) {
-		if(this.spin > 100_000_000) abort | "Worker" | this.value | "has been spinning too long! (" | this.spin | ")";
+	while(TEST(globals.counter < N)) {
+		if(this.spin > 50_000_000_000) abort | "Worker" | this.value | "has been spinning too long! (" | this.spin | ")";
 		__cfaabi_check_preemption();
-		if( (counter % 7) == this.value ) {
+		if( (globals.counter % 7) == this.value ) {
 			__cfaabi_check_preemption();
-			int next = __atomic_add_fetch( &counter, 1, __ATOMIC_SEQ_CST );
+			#if !defined(TEST_LONG)
+				Time now = timeHiRes();
+				Duration diff = now - globals.prev;
+				globals.prev = now;
+			#endif
+			int next = __atomic_add_fetch( &globals.counter, 1, __ATOMIC_SEQ_CST );
 			__cfaabi_check_preemption();
-			if( (next % 100) == 0 ) printf("%d\n", (int)next);
+			if( (next % 100) == 0 ) {
+				#if !defined(TEST_LONG)
+					unsigned idx = next / 100;
+					if (idx >= 6) abort | "Idx from next is invalid: " | idx | "vs" | next;
+					globals.durations[idx] = diff;
+					if(diff > 12`s) serr | "Duration suspiciously large:" | diff;
+				#endif
+				printf("%d\n", (int)next);
+
+			}
 			__cfaabi_check_preemption();
 			this.spin = 0;
@@ -54,5 +73,13 @@
 int main(int argc, char* argv[]) {
 	processor p;
+	globals.counter = 0;
+	globals.durations[0] = 0;
+	globals.durations[1] = 0;
+	globals.durations[2] = 0;
+	globals.durations[3] = 0;
+	globals.durations[4] = 0;
+	globals.durations[5] = 0;
 	{
+		globals.prev = timeHiRes();
 		worker_t w0 = 0;
 		worker_t w1 = 1;
Index: tools/auto-complete.md
===================================================================
--- tools/auto-complete.md	(revision 3e5db5b4130e8f655563072771bcc8b389ad7681)
+++ tools/auto-complete.md	(revision 34c32f098e353062f8da7759b872f43ad7bc5a74)
@@ -32,2 +32,23 @@
 
 ### Zsh
+
+1 - Add the following somewhere:
+    #compdef test.py
+
+    _test_py() {
+        local -a options
+        options=$($words[1] --list-comp)
+        _alternative "files:filenames:($options)"
+    }
+
+    _test_py "$@"
+
+2 - Add the path to that file to the "fpath" environment variable.
+
+3 - In ~/.zshrc add
+    autoload -U compinit
+    compinit
+
+*How it works:* I don't know ;P
+
+
