Index: src/ControlStruct/ExceptTranslateNew.cpp
===================================================================
--- src/ControlStruct/ExceptTranslateNew.cpp	(revision 5f3ba117d89cd71b0b82121f2363d27a6752b378)
+++ src/ControlStruct/ExceptTranslateNew.cpp	(revision 12b5e94a9df5bfc0037b0fe7eb823f658a9b0d9d)
@@ -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
 //
 
Index: src/ControlStruct/FixLabels.cpp
===================================================================
--- src/ControlStruct/FixLabels.cpp	(revision 5f3ba117d89cd71b0b82121f2363d27a6752b378)
+++ src/ControlStruct/FixLabels.cpp	(revision 12b5e94a9df5bfc0037b0fe7eb823f658a9b0d9d)
@@ -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 5f3ba117d89cd71b0b82121f2363d27a6752b378)
+++ src/ControlStruct/FixLabels.hpp	(revision 12b5e94a9df5bfc0037b0fe7eb823f658a9b0d9d)
@@ -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.cc
===================================================================
--- src/ControlStruct/ForExprMutator.cc	(revision 5f3ba117d89cd71b0b82121f2363d27a6752b378)
+++ src/ControlStruct/ForExprMutator.cc	(revision 12b5e94a9df5bfc0037b0fe7eb823f658a9b0d9d)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Mon Mar 11 22:26:52 2019
-// Update Count     : 14
+// Last Modified On : Tue Feb  1 09:26:12 2022
+// Update Count     : 16
 //
 
@@ -45,6 +45,6 @@
 		return hoist( forStmt, forStmt->initialization );
 	}
-	Statement * ForExprMutator::postmutate( WhileStmt * whileStmt ) {
-		return hoist( whileStmt, whileStmt->initialization );
+	Statement * ForExprMutator::postmutate( WhileDoStmt * whileDoStmt ) {
+		return hoist( whileDoStmt, whileDoStmt->initialization );
 	}
 } // namespace ControlStruct
Index: src/ControlStruct/ForExprMutator.h
===================================================================
--- src/ControlStruct/ForExprMutator.h	(revision 5f3ba117d89cd71b0b82121f2363d27a6752b378)
+++ src/ControlStruct/ForExprMutator.h	(revision 12b5e94a9df5bfc0037b0fe7eb823f658a9b0d9d)
@@ -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 : Tue Feb  1 09:18:50 2022
+// Update Count     : 7
 //
 
@@ -18,5 +18,5 @@
 class IfStmt;
 class ForStmt;
-class WhileStmt;
+class WhileDoStmt;
 class Statement;
 
@@ -24,7 +24,7 @@
 	class ForExprMutator {
 	  public:
-		Statement *postmutate( IfStmt * );
-		Statement *postmutate( ForStmt * );
-		Statement *postmutate( WhileStmt * );
+		Statement * postmutate( IfStmt * );
+		Statement * postmutate( ForStmt * );
+		Statement * postmutate( WhileDoStmt * );
 	};
 } // namespace ControlStruct
Index: src/ControlStruct/HoistControlDecls.cpp
===================================================================
--- src/ControlStruct/HoistControlDecls.cpp	(revision 12b5e94a9df5bfc0037b0fe7eb823f658a9b0d9d)
+++ src/ControlStruct/HoistControlDecls.cpp	(revision 12b5e94a9df5bfc0037b0fe7eb823f658a9b0d9d)
@@ -0,0 +1,86 @@
+//
+// 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.
+//
+// HoistControlDecls.cpp -- Desugar Cforall control structures.
+//
+// Author           : Andrew Beach
+// Created On       : Fri Dec  3 15:34:00 2021
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Tue Feb  1 18:59:47 2022
+// Update Count     : 25
+//
+
+#include "HoistControlDecls.hpp"
+
+#include "AST/Decl.hpp"
+#include "AST/Pass.hpp"
+#include "AST/TranslationUnit.hpp"
+using namespace ast;
+
+namespace ControlStruct {
+
+template<typename StmtT>
+const Stmt * hoist( const StmtT * stmt ) {
+	// If no hoisting is needed, then make no changes.
+
+	if ( stmt->inits.size() == 0 ) {					// no declarations ?
+		// if ( /* no conditional declarations */ ...  ) ...
+		return stmt;
+	} // if
+
+	// 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 );
+	}
+	//    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 hoistControlDeclsCore {
+	// Statements with declarations in conditional.
+	const Stmt * postvisit( const IfStmt * stmt ) {
+		return hoist<IfStmt>( stmt );
+	}
+	const Stmt * postvisit( const ForStmt * stmt ) {
+		return hoist<ForStmt>( stmt );
+	}
+	const Stmt * postvisit( const WhileDoStmt * stmt ) {
+		return hoist<WhileDoStmt>( stmt );
+	}
+};
+
+// Hoist initialization out of for statements.
+void hoistControlDecls( TranslationUnit & translationUnit ) {
+	Pass<hoistControlDeclsCore>::run( translationUnit );
+}
+
+} // namespace ControlStruct
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/ControlStruct/HoistControlDecls.hpp
===================================================================
--- src/ControlStruct/HoistControlDecls.hpp	(revision 12b5e94a9df5bfc0037b0fe7eb823f658a9b0d9d)
+++ src/ControlStruct/HoistControlDecls.hpp	(revision 12b5e94a9df5bfc0037b0fe7eb823f658a9b0d9d)
@@ -0,0 +1,31 @@
+//
+// 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.
+//
+// HoistControlDecls.hpp -- Desugar Cforall control structures.
+//
+// Author           : Andrew Beach
+// Created On       : Fri Dec  3 15:31:00 2021
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Mon Jan 31 22:25:07 2022
+// Update Count     : 3
+//
+
+#pragma once
+
+namespace ast {
+class TranslationUnit;
+}
+
+namespace ControlStruct {
+// Hoist declarations out of control flow statements into compound statement.
+void hoistControlDecls( ast::TranslationUnit & translationUnit );
+} // namespace ControlStruct
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/ControlStruct/LabelFixer.cc
===================================================================
--- src/ControlStruct/LabelFixer.cc	(revision 5f3ba117d89cd71b0b82121f2363d27a6752b378)
+++ src/ControlStruct/LabelFixer.cc	(revision 12b5e94a9df5bfc0037b0fe7eb823f658a9b0d9d)
@@ -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 : Tue Feb  1 09:12:09 2022
+// Update Count     : 162
 //
 
@@ -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< WhileDoStmt * > ( 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 5f3ba117d89cd71b0b82121f2363d27a6752b378)
+++ src/ControlStruct/LabelFixer.h	(revision 12b5e94a9df5bfc0037b0fe7eb823f658a9b0d9d)
@@ -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 5f3ba117d89cd71b0b82121f2363d27a6752b378)
+++ src/ControlStruct/LabelGenerator.cc	(revision 12b5e94a9df5bfc0037b0fe7eb823f658a9b0d9d)
@@ -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 5f3ba117d89cd71b0b82121f2363d27a6752b378)
+++ src/ControlStruct/LabelGenerator.h	(revision 12b5e94a9df5bfc0037b0fe7eb823f658a9b0d9d)
@@ -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 12b5e94a9df5bfc0037b0fe7eb823f658a9b0d9d)
+++ src/ControlStruct/LabelGeneratorNew.cpp	(revision 12b5e94a9df5bfc0037b0fe7eb823f658a9b0d9d)
@@ -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 : Wed Feb  2 09:11:17 2022
+// Update Count     : 72
+//
+
+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;
+
+	assertf( stmt, "CFA internal error: parameter statement cannot be null pointer" );
+
+	enum { size = 128 };
+	char buf[size];										// space to build label
+	int len = snprintf( buf, size, "__L%d__%s", current++, suffix.c_str() );
+	assertf( len < size, "CFA Internal error: buffer overflow creating label" );
+
+	// What does this do?
+	if ( ! stmt->labels.empty() ) {
+		len = snprintf( buf + len, size - len, "_%s__", stmt->labels.front().name.c_str() );
+		assertf( len < size - len, "CFA Internal error: buffer overflow creating label" );
+	} // 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 12b5e94a9df5bfc0037b0fe7eb823f658a9b0d9d)
+++ src/ControlStruct/LabelGeneratorNew.hpp	(revision 12b5e94a9df5bfc0037b0fe7eb823f658a9b0d9d)
@@ -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/MLEMutator.cc
===================================================================
--- src/ControlStruct/MLEMutator.cc	(revision 5f3ba117d89cd71b0b82121f2363d27a6752b378)
+++ src/ControlStruct/MLEMutator.cc	(revision 12b5e94a9df5bfc0037b0fe7eb823f658a9b0d9d)
@@ -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 : Wed Jan 22 11:50:00 2020
-// Update Count     : 223
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Wed Feb  2 20:18:57 2022
+// Update Count     : 227
 //
 
@@ -39,5 +39,5 @@
 	namespace {
 		bool isLoop( const MultiLevelExitMutator::Entry & e ) {
-			return dynamic_cast< WhileStmt * >( e.get_controlStructure() )
+			return dynamic_cast< WhileDoStmt * >( e.get_controlStructure() )
 				|| dynamic_cast< ForStmt * >( e.get_controlStructure() );
 		}
@@ -136,5 +136,5 @@
 			}
 		}
-		assertf( false, "Could not find label '%s' on statement %s",
+		assertf( false, "CFA internal error: could not find label '%s' on statement %s",
 			originalTarget.get_name().c_str(), toString( stmt ).c_str() );
 	}
@@ -295,6 +295,6 @@
 	}
 
-	void MultiLevelExitMutator::premutate( WhileStmt * whileStmt ) {
-		return prehandleLoopStmt( whileStmt );
+	void MultiLevelExitMutator::premutate( WhileDoStmt * whileDoStmt ) {
+		return prehandleLoopStmt( whileDoStmt );
 	}
 
@@ -303,6 +303,6 @@
 	}
 
-	Statement * MultiLevelExitMutator::postmutate( WhileStmt * whileStmt ) {
-		return posthandleLoopStmt( whileStmt );
+	Statement * MultiLevelExitMutator::postmutate( WhileDoStmt * whileDoStmt ) {
+		return posthandleLoopStmt( whileDoStmt );
 	}
 
@@ -395,5 +395,7 @@
 		}
 		assert( ! enclosingControlStructures.empty() );
-		assertf( dynamic_cast<SwitchStmt *>( enclosingControlStructures.back().get_controlStructure() ), "Control structure enclosing a case clause must be a switch, but is: %s", toCString( enclosingControlStructures.back().get_controlStructure() ) );
+		assertf( dynamic_cast<SwitchStmt *>( enclosingControlStructures.back().get_controlStructure() ),
+				 "CFA internal error: control structure enclosing a case clause must be a switch, but is: %s",
+				 toCString( enclosingControlStructures.back().get_controlStructure() ) );
 		if ( caseStmt->isDefault() ) {
 			if ( enclosingControlStructures.back().isFallDefaultUsed() ) {
Index: src/ControlStruct/MLEMutator.h
===================================================================
--- src/ControlStruct/MLEMutator.h	(revision 5f3ba117d89cd71b0b82121f2363d27a6752b378)
+++ src/ControlStruct/MLEMutator.h	(revision 12b5e94a9df5bfc0037b0fe7eb823f658a9b0d9d)
@@ -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 : Wed Jan 22 11:50:00 2020
-// Update Count     : 48
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Tue Feb  1 09:27:24 2022
+// Update Count     : 50
 //
 
@@ -42,6 +42,6 @@
 		void premutate( CompoundStmt *cmpndStmt );
 		Statement * postmutate( BranchStmt *branchStmt ) throw ( SemanticErrorException );
-		void premutate( WhileStmt *whileStmt );
-		Statement * postmutate( WhileStmt *whileStmt );
+		void premutate( WhileDoStmt *whileDoStmt );
+		Statement * postmutate( WhileDoStmt *whileDoStmt );
 		void premutate( ForStmt *forStmt );
 		Statement * postmutate( ForStmt *forStmt );
@@ -67,5 +67,5 @@
 				stmt( stmt ), breakExit( breakExit ), contExit( contExit ) {}
 
-			explicit Entry( WhileStmt *stmt, Label breakExit, Label contExit ) :
+			explicit Entry( WhileDoStmt *stmt, Label breakExit, Label contExit ) :
 				stmt( stmt ), breakExit( breakExit ), contExit( contExit ) {}
 
Index: src/ControlStruct/MultiLevelExit.cpp
===================================================================
--- src/ControlStruct/MultiLevelExit.cpp	(revision 5f3ba117d89cd71b0b82121f2363d27a6752b378)
+++ src/ControlStruct/MultiLevelExit.cpp	(revision 12b5e94a9df5bfc0037b0fe7eb823f658a9b0d9d)
@@ -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 : Wed Feb  2 23:07:54 2022
+// Update Count     : 33
 //
 
@@ -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,49 +40,50 @@
 
 	enum Kind {
-		ForStmt, WhileStmt, CompoundStmt, IfStmt, CaseStmt, SwitchStmt, TryStmt
+		ForStmtK, WhileDoStmtK, 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; }
-
-	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); }
-
-	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; }
+  public:
+	Entry( const ForStmt * stmt, Label breakExit, Label contExit ) :
+		stmt( stmt ), firstTarget( breakExit ), secondTarget( contExit ), kind( ForStmtK ) {}
+	Entry( const WhileDoStmt * stmt, Label breakExit, Label contExit ) :
+		stmt( stmt ), firstTarget( breakExit ), secondTarget( contExit ), kind( WhileDoStmtK ) {}
+	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 <= WhileDoStmtK; }
+	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
+	Label useContExit() { assert( kind <= WhileDoStmtK ); 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 <= WhileDoStmtK ); 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();
@@ -103,32 +103,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 WhileDoStmt * );
+	const WhileDoStmt * postvisit( const WhileDoStmt * );
+	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;
 
@@ -138,17 +138,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 } );
 }
 
@@ -158,26 +158,28 @@
 {}
 
-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;
-	bool isLabeled = !stmt->labels.empty();
+
+	// if the stmt is labelled then generate a label to check in postvisit if the label is used
+	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 ) {
-		assert( !enclosing_control_structures.empty() );
+		assert( ! enclosing_control_structures.empty() );
 		Entry & entry = enclosing_control_structures.back();
-		if ( !entry.useBreakExit().empty() ) {
+		if ( ! entry.useBreakExit().empty() ) {
 			break_label = entry.useBreakExit();
 		}
@@ -187,15 +189,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;
 			}
@@ -203,128 +205,128 @@
 		}
 	}
-	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 ) {
+	assertf( false, "CFA internal error: could not find label '%s' on statement %s",
+			 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;
 }
 
-const ast::BranchStmt * MultiLevelExitCore::postvisit( const ast::BranchStmt * stmt ) {
-	std::vector<Entry>::reverse_iterator targetEntry =
+// This routine updates targets on enclosing control structures to indicate which
+//     label is used by the BranchStmt that is passed
+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;
-	}
-	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(), "" );
+	// Branch error checks: get the appropriate label name, which is always replaced.
+	Label exitLabel( CodeLocation(), "" );
 	switch ( stmt->kind ) {
-	case ast::BranchStmt::Break:
-		assert( !targetEntry->useBreakExit().empty() );
+	  case BranchStmt::Break:
+		assert( ! targetEntry->useBreakExit().empty() );
 		exitLabel = targetEntry->useBreakExit();
 		break;
-	case ast::BranchStmt::Continue:
-		assert( !targetEntry->useContExit().empty() );
+	  case BranchStmt::Continue:
+		assert( ! targetEntry->useContExit().empty() );
 		exitLabel = targetEntry->useContExit();
 		break;
-	case ast::BranchStmt::FallThrough:
-		assert( !targetEntry->useFallExit().empty() );
+	  case BranchStmt::FallThrough:
+		assert( ! targetEntry->useFallExit().empty() );
 		exitLabel = targetEntry->useFallExit();
 		break;
-	case ast::BranchStmt::FallThroughDefault:
-		assert( !targetEntry->useFallDefaultExit().empty() );
+	  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" );
+		if ( ! targetEntry->isFallDefaultValid() ) {
+			SemanticError( stmt->location, "'fallthrough default' must precede the 'default' clause" );
 		}
 		break;
-	default:
+	  default:
 		assert(0);
 	}
@@ -333,21 +335,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 WhileDoStmt * stmt ) {
 	return prehandleLoopStmt( stmt );
 }
 
-const ast::WhileStmt * MultiLevelExitCore::postvisit( const ast::WhileStmt * stmt ) {
+const WhileDoStmt * MultiLevelExitCore::postvisit( const WhileDoStmt * 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 );
 }
@@ -355,58 +357,55 @@
 // 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() );
+		assert( ! enclosing_control_structures.empty() );
 		enclosing_control_structures.back().seenDefault();
 	}
 
 	// 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() ) {
-			mutStmt->stmts.push_back(
-				labelledNullStmt( mutStmt->location, entry.useFallExit() ) );
-		}
-	}
-	assert( !enclosing_control_structures.empty() );
+			mutStmt->stmts.push_back( labelledNullStmt( mutStmt->location, entry.useFallExit() ) );
+		}
+	}
+	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 ),
+			 "CFA internal error: 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()
-			) );
+			push_front( mutStmt->stmts, labelledNullStmt( stmt->location, entry.useFallDefaultExit() ) );
 		}
 	}
@@ -414,8 +413,8 @@
 }
 
-void MultiLevelExitCore::previsit( const ast::IfStmt * stmt ) {
-	bool labeledBlock = !stmt->labels.empty();
+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(); } );
@@ -423,9 +422,9 @@
 }
 
-const ast::IfStmt * MultiLevelExitCore::postvisit( const ast::IfStmt * stmt ) {
-	bool labeledBlock = !stmt->labels.empty();
+const IfStmt * MultiLevelExitCore::postvisit( const IfStmt * stmt ) {
+	bool labeledBlock = ! stmt->labels.empty();
 	if ( labeledBlock ) {
 		auto this_label = enclosing_control_structures.back().useBreakExit();
-		if ( !this_label.empty() ) {
+		if ( ! this_label.empty() ) {
 			break_label = this_label;
 		}
@@ -434,29 +433,26 @@
 }
 
-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 );
+	// Collect valid labels for fallthrough. It starts with all labels at 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 );
 			}
@@ -465,26 +461,24 @@
 }
 
-const ast::SwitchStmt * MultiLevelExitCore::postvisit( const ast::SwitchStmt * stmt ) {
-	assert( !enclosing_control_structures.empty() );
+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 );
+		// 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 if no cases.
+		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 );
@@ -495,5 +489,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" );
@@ -501,8 +495,8 @@
 }
 
-void MultiLevelExitCore::previsit( const ast::TryStmt * stmt ) {
-	bool isLabeled = !stmt->labels.empty();
+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(); } );
@@ -510,9 +504,9 @@
 }
 
-void MultiLevelExitCore::postvisit( const ast::TryStmt * stmt ) {
-	bool isLabeled = !stmt->labels.empty();
+void MultiLevelExitCore::postvisit( const TryStmt * stmt ) {
+	bool isLabeled = ! stmt->labels.empty();
 	if ( isLabeled ) {
 		auto this_label = enclosing_control_structures.back().useBreakExit();
-		if ( !this_label.empty() ) {
+		if ( ! this_label.empty() ) {
 			break_label = this_label;
 		}
@@ -520,23 +514,30 @@
 }
 
-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();
 	}
 
+	// 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 );
+		// {
+		//  body
+		// }
 		new_body->kids.push_back(
 			labelledNullStmt( body->location, entry.useContExit() ) );
+		// {
+		//  body
+		//  ContinueLabel: {}
+		// }
 		return new_body;
 	}
@@ -549,7 +550,11 @@
 	// 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
+	// children will tag labels as being used during their traversal which occurs before postvisit
+
+	// GuardAction calls the lambda after the node is done being visited
 	GuardAction( [this](){ enclosing_control_structures.pop_back(); } );
 }
@@ -557,25 +562,27 @@
 template<typename LoopNode>
 const LoopNode * MultiLevelExitCore::posthandleLoopStmt( const LoopNode * loopStmt ) {
-	assert( !enclosing_control_structures.empty() );
+	assert( ! enclosing_control_structures.empty() );
 	Entry & entry = enclosing_control_structures.back();
 	assert( entry.stmt == loopStmt );
 
-	// Now we check if the labels are used and add them if so.
-	return ast::mutate_field(
-		loopStmt, &LoopNode::body, mutateLoop( loopStmt->body, entry ) );
-}
-
-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.
+	// 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
+	// 		if they are the same the node isn't mutated, if they differ then the new mutated node is returned
+	// 		the stmts will only differ if a label is used
+}
+
+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 );
 			}
@@ -588,12 +595,11 @@
 		}
 
-		if ( !break_label.empty() ) {
-			ret.push_back(
-				labelledNullStmt( ret.back()->location, break_label ) );
-			break_label = ast::Label( CodeLocation(), "" );
-		}
-	}
-
-	if ( !errors.isEmpty() ) {
+		if ( ! break_label.empty() ) {
+			ret.push_back( labelledNullStmt( ret.back()->location, break_label ) );
+			break_label = Label( CodeLocation(), "" );
+		}
+	}
+
+	if ( ! errors.isEmpty() ) {
 		throw errors;
 	}
@@ -601,15 +607,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 5f3ba117d89cd71b0b82121f2363d27a6752b378)
+++ src/ControlStruct/MultiLevelExit.hpp	(revision 12b5e94a9df5bfc0037b0fe7eb823f658a9b0d9d)
@@ -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 5f3ba117d89cd71b0b82121f2363d27a6752b378)
+++ src/ControlStruct/module.mk	(revision 12b5e94a9df5bfc0037b0fe7eb823f658a9b0d9d)
@@ -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
 ###############################################################################
 
@@ -22,8 +22,12 @@
 	ControlStruct/ForExprMutator.cc \
 	ControlStruct/ForExprMutator.h \
+	ControlStruct/HoistControlDecls.cpp \
+	ControlStruct/HoistControlDecls.hpp \
 	ControlStruct/LabelFixer.cc \
 	ControlStruct/LabelFixer.h \
 	ControlStruct/LabelGenerator.cc \
 	ControlStruct/LabelGenerator.h \
+	ControlStruct/LabelGeneratorNew.cpp \
+	ControlStruct/LabelGeneratorNew.hpp \
 	ControlStruct/MLEMutator.cc \
 	ControlStruct/MLEMutator.h \
