Index: src/ControlStruct/FixLabels.cpp
===================================================================
--- src/ControlStruct/FixLabels.cpp	(revision b8ab91afb998c4dde77866f9cb4d46188ec52752)
+++ src/ControlStruct/FixLabels.cpp	(revision 21fe17fb9204b02e5ee7ce500f9d93f6889e2447)
@@ -10,6 +10,6 @@
 // Created On       : Mon Nov  1 09:39:00 2021
 // Last Modified By : Andrew Beach
-// Last Modified On : Mon Nov  2 10:32:00 2021
-// Update Count     : 0
+// Last Modified On : Mon Nov  5 16:05:00 2021
+// Update Count     : 1
 //
 
@@ -26,29 +26,6 @@
 namespace {
 
-struct MultiLevelExitCore :
-		public ast::WithVisitorRef<MultiLevelExitCore>,
-		public ast::WithShortCircuiting, public ast::WithGuards {
-	class Entry;
-};
-
-struct Entry {
-	ast::Label label;
-	const ast::Stmt * def;
-
-	Entry() : label( CodeLocation() ), def( nullptr ) {}
-	Entry( const ast::Stmt * def ) : label( def->location ), def( def ) {}
-
-	bool isDefined() const {
-		return nullptr != def;
-	}
-
-	bool isInsideLoop() {
-		return ( dynamic_cast< const ast::ForStmt *>( def ) ||
-			dynamic_cast< const ast::WhileStmt *>( def ) );
-	}
-};
-
 class FixLabelsCore final : public ast::WithGuards {
-	std::map<ast::Label, Entry *> labelTable;
+	LabelToStmt labelTable;
 	LabelGenerator_new * label_gen;
 public:
@@ -58,6 +35,4 @@
 	{}
 
-	std::map<ast::Label, const ast::Stmt *> * resolveJumps();
-
 	void previsit( const ast::FunctionDecl * );
 	const ast::FunctionDecl * postvisit( const ast::FunctionDecl * );
@@ -66,20 +41,7 @@
 	void previsit( const ast::LabelAddressExpr * );
 
-	ast::Label setLabelsDef( const std::vector<ast::Label> &, const ast::Stmt * );
-	template<typename UsageNode>
-	void setLabelsUsage(ast::Label, const UsageNode * usage );
+	void setLabelsDef( const std::vector<ast::Label> &, const ast::Stmt * );
+	void setLabelsUsage( const ast::Label & );
 };
-
-std::map<ast::Label, const ast::Stmt *> * FixLabelsCore::resolveJumps() {
-	auto ret = new std::map<ast::Label, const ast::Stmt *>();
-	for ( auto kvp : labelTable ) {
-		if ( !kvp.second->isDefined() ) {
-			SemanticError( kvp.first.location,
-				"Use of undefined label: " + kvp.first.name );
-		}
-		(*ret)[ kvp.first ] = kvp.second->def;
-	}
-	return ret;
-}
 
 void FixLabelsCore::previsit( const ast::FunctionDecl * ) {
@@ -90,23 +52,27 @@
 		const ast::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 );
+		}
+	}
+	LabelToStmt * copy = new LabelToStmt( labelTable );
 	return ast::mutate_field( decl, &ast::FunctionDecl::stmts,
-		multiLevelExitUpdate( decl->stmts.get(), resolveJumps(), label_gen ) );
+		multiLevelExitUpdate( decl->stmts.get(), copy, label_gen ) );
 }
 
 void FixLabelsCore::previsit( const ast::Stmt * stmt ) {
-	if ( stmt->labels.empty() ) {
-		return;
+	if ( !stmt->labels.empty() ) {
+		setLabelsDef( stmt->labels, stmt );
 	}
-	// Only remember one label for each statement.
-	// (But we don't do anything with one label. What does it do?)
-	ast::Label current = setLabelsDef( stmt->labels, stmt );
 }
 
 void FixLabelsCore::previsit( const ast::BranchStmt * stmt ) {
 	if ( !stmt->labels.empty() ) {
-		ast::Label current = setLabelsDef( stmt->labels, stmt );
+		setLabelsDef( stmt->labels, stmt );
 	}
 	if ( !stmt->target.empty() ) {
-		setLabelsUsage( stmt->target, stmt );
+		setLabelsUsage( stmt->target );
 	}
 }
@@ -114,8 +80,8 @@
 void FixLabelsCore::previsit( const ast::LabelAddressExpr * expr ) {
 	assert( !expr->arg.empty() );
-	setLabelsUsage( expr->arg, expr );
+	setLabelsUsage( expr->arg );
 }
 
-ast::Label FixLabelsCore::setLabelsDef(
+void FixLabelsCore::setLabelsDef(
 		const std::vector<ast::Label> & labels, const ast::Stmt * stmt ) {
 	assert( !labels.empty() );
@@ -125,6 +91,6 @@
 		if ( labelTable.find( label ) == labelTable.end() ) {
 			// Make sure to only create the entry once.
-			labelTable[ label ] = new Entry( stmt );
-		} else if ( labelTable[ label ]->isDefined() ) {
+			labelTable[ label ] = stmt;
+		} else if ( nullptr != labelTable[ label ] ) {
 			// Duplicate definition, this is an error.
 			SemanticError( label.location,
@@ -132,22 +98,13 @@
 		} else {
 			// Perviously used, but not defined until now.
-			// (There was a question about changing objects, is that the Entry?)
-			delete labelTable[ label ];
-			labelTable[ label ] = new Entry( stmt );
+			labelTable[ label ] = stmt;
 		}
 	}
-
-	// Return the labels on this statement to be the tmp. canonical label.
-	return labelTable[ labels.front() ]->label;
 }
 
 // Label was used, if it is new add it to the table.
-// (Why do we pass in usage? It's only use is in the assertion.)
-template<typename UsageNode>
-void FixLabelsCore::setLabelsUsage(ast::Label label, const UsageNode * usage ) {
-	assert( usage );
-
+void FixLabelsCore::setLabelsUsage( const ast::Label & label ) {
 	if ( labelTable.find( label ) == labelTable.end() ) {
-		labelTable[ label ] = new Entry();
+		labelTable[ label ] = nullptr;
 	}
 }
