Index: src/ControlStruct/MultiLevelExit.cpp
===================================================================
--- src/ControlStruct/MultiLevelExit.cpp	(revision 891f7074e4bf1a3467ca38add7c71ff492fc38a0)
+++ src/ControlStruct/MultiLevelExit.cpp	(revision 3b80db89ad8057ef837786b049cd89765ab7a20d)
@@ -9,7 +9,7 @@
 // Author           : Andrew Beach
 // Created On       : Mon Nov  1 13:48:00 2021
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Feb  2 23:07:54 2022
-// Update Count     : 33
+// Last Modified By : Andrew Beach
+// Last Modified On : Mon Mar 28  9:42:00 2022
+// Update Count     : 34
 //
 
@@ -40,5 +40,5 @@
 
 	enum Kind {
-		ForStmtK, WhileDoStmtK, CompoundStmtK, IfStmtK, CaseStmtK, SwitchStmtK, TryStmtK
+		ForStmtK, WhileDoStmtK, CompoundStmtK, IfStmtK, CaseClauseK, SwitchStmtK, TryStmtK
 	} kind;
 
@@ -58,6 +58,6 @@
 	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 CaseClause *, const CompoundStmt *stmt, Label fallExit ) :
+		stmt( stmt ), firstTarget( fallExit ), secondTarget(), kind( CaseClauseK ) {}
 	Entry( const SwitchStmt *stmt, Label breakExit, Label fallDefaultExit ) :
 		stmt( stmt ), firstTarget( breakExit ), secondTarget( fallDefaultExit ), kind( SwitchStmtK ) {}
@@ -66,18 +66,18 @@
 
 	bool isContTarget() const { return kind <= WhileDoStmtK; }
-	bool isBreakTarget() const { return kind != CaseStmtK; }
-	bool isFallTarget() const { return kind == CaseStmtK; }
+	bool isBreakTarget() const { return kind != CaseClauseK; }
+	bool isFallTarget() const { return kind == CaseClauseK; }
 	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 useBreakExit() { assert( kind != CaseClauseK ); return useTarget(firstTarget); }
+	Label useFallExit() { assert( kind == CaseClauseK );  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 isBreakUsed() const { assert( kind != CaseClauseK ); return firstTarget.used; }
+	bool isFallUsed() const { assert( kind == CaseClauseK ); return firstTarget.used; }
 	bool isFallDefaultUsed() const { assert( kind == SwitchStmtK ); return secondTarget.used; }
 	void seenDefault() { fallDefaultValid = false; }
@@ -115,5 +115,5 @@
 	void previsit( const ForStmt * );
 	const ForStmt * postvisit( const ForStmt * );
-	const CaseStmt * previsit( const CaseStmt * );
+	const CaseClause * previsit( const CaseClause * );
 	void previsit( const IfStmt * );
 	const IfStmt * postvisit( const IfStmt * );
@@ -123,5 +123,5 @@
 	void previsit( const TryStmt * );
 	void postvisit( const TryStmt * );
-	void previsit( const FinallyStmt * );
+	void previsit( const FinallyClause * );
 
 	const Stmt * mutateLoop( const Stmt * body, Entry& );
@@ -288,6 +288,5 @@
 		  auto switchStmt = strict_dynamic_cast< const SwitchStmt * >( targetEntry->stmt );
 		  bool foundDefault = false;
-		  for ( auto subStmt : switchStmt->stmts ) {
-			  const CaseStmt * caseStmt = subStmt.strict_as<CaseStmt>();
+		  for ( auto caseStmt : switchStmt->cases ) {
 			  if ( caseStmt->isDefault() ) {
 				  foundDefault = true;
@@ -365,5 +364,5 @@
 }
 
-const CaseStmt * MultiLevelExitCore::previsit( const CaseStmt * stmt ) {
+const CaseClause * MultiLevelExitCore::previsit( const CaseClause * stmt ) {
 	visit_children = false;
 
@@ -375,19 +374,21 @@
 
 	// The cond may not exist, but if it does update it now.
-	visitor->maybe_accept( stmt, &CaseStmt::cond );
+	visitor->maybe_accept( stmt, &CaseClause::cond );
 
 	// Just save the mutated node for simplicity.
-	CaseStmt * mutStmt = mutate( stmt );
-
-	Label fallLabel = newLabel( "fallThrough", stmt );
+	CaseClause * mutStmt = mutate( stmt );
+
+	Label fallLabel = newLabel( "fallThrough", stmt->location );
 	if ( ! mutStmt->stmts.empty() ) {
+		// These should already be in a block.
+		auto first = mutStmt->stmts.front().get_and_mutate();
+		auto block = strict_dynamic_cast<CompoundStmt *>( first );
+
 		// Ensure that the stack isn't corrupted by exceptions in fixBlock.
 		auto guard = makeFuncGuard(
-			[&](){ enclosing_control_structures.emplace_back( mutStmt, fallLabel ); },
+			[&](){ enclosing_control_structures.emplace_back( mutStmt, block, fallLabel ); },
 			[this](){ enclosing_control_structures.pop_back(); }
 			);
 
-		// These should already be in a block.
-		auto block = mutate( mutStmt->stmts.front().strict_as<CompoundStmt>() );
 		block->kids = fixBlock( block->kids, true );
 
@@ -396,5 +397,5 @@
 		Entry & entry = enclosing_control_structures.back();
 		if ( entry.isFallUsed() ) {
-			mutStmt->stmts.push_back( labelledNullStmt( mutStmt->location, entry.useFallExit() ) );
+			mutStmt->stmts.push_back( labelledNullStmt( block->location, entry.useFallExit() ) );
 		}
 	}
@@ -433,15 +434,14 @@
 }
 
-bool isDefaultCase( const ptr<Stmt> & stmt ) {
-	const CaseStmt * caseStmt = stmt.strict_as<CaseStmt>();
-	return caseStmt->isDefault();
+static bool isDefaultCase( const ptr<CaseClause> & caseClause ) {
+	return caseClause->isDefault();
 }
 
 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, "" );
+	auto it = find_if( stmt->cases.rbegin(), stmt->cases.rend(), isDefaultCase );
+
+	const CaseClause * defaultCase = it != stmt->cases.rend() ? (*it) : nullptr;
+	Label defaultLabel = defaultCase ? newLabel( "fallThroughDefault", defaultCase->location ) : Label( stmt->location, "" );
 	enclosing_control_structures.emplace_back( stmt, label, defaultLabel );
 	GuardAction( [this]() { enclosing_control_structures.pop_back(); } );
@@ -449,6 +449,5 @@
 	// 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 );
+	for ( const CaseClause * caseStmt : stmt->cases ) {
 		if ( caseStmt->stmts.empty() ) continue;
 		auto block = caseStmt->stmts.front().strict_as<CompoundStmt>();
@@ -471,11 +470,11 @@
 		// 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 CaseStmt( mutStmt->location, nullptr, {} ) );
-		}
-
-		auto caseStmt = mutStmt->stmts.back().strict_as<CaseStmt>();
+		if ( mutStmt->cases.empty() ) {
+			mutStmt->cases.push_back( new CaseClause( mutStmt->location, nullptr, {} ) );
+		}
+
+		auto caseStmt = mutStmt->cases.back().get();
 		auto mutCase = mutate( caseStmt );
-		mutStmt->stmts.back() = mutCase;
+		mutStmt->cases.back() = mutCase;
 
 		Label label( mutCase->location, "breakLabel" );
@@ -514,5 +513,5 @@
 }
 
-void MultiLevelExitCore::previsit( const FinallyStmt * ) {
+void MultiLevelExitCore::previsit( const FinallyClause * ) {
 	GuardAction([this, old = move( enclosing_control_structures)](){ enclosing_control_structures = move(old); });
 	enclosing_control_structures = vector<Entry>();
