From 59b23de5eda005c990b26a43b3a0c5ab8dc78bfd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emmanuel=20Beno=C3=AEt?= <tseeker@nocternity.net>
Date: Thu, 30 Nov 2017 17:56:37 +0100
Subject: [PATCH] Parser - Fixed problem with unused functions

---
 TODO          |  2 --
 c-opast.hh    |  3 +++
 c-opparser.cc | 10 ++++++++--
 3 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/TODO b/TODO
index 2867e3d..c7e75df 100644
--- a/TODO
+++ b/TODO
@@ -7,8 +7,6 @@ Post-processing:
 * Lens dirt
 
 Scripting:
-* Eliminate functions that are not called / prevent them from causing
-	type errors
 * Spill values in the FPU stack runs out
 * More checks in the execution engine
 * Overrides
diff --git a/c-opast.hh b/c-opast.hh
index 1cb9417..0099494 100644
--- a/c-opast.hh
+++ b/c-opast.hh
@@ -363,6 +363,9 @@ class T_RootNode : public A_Node
 		{ return functions_.indexOf( name ); }
 	A_FuncNode& function( const uint32_t index ) const noexcept
 		{ return *functions_.values( )[ index ]; }
+
+	void removeFunction( T_String const& name ) noexcept
+		{ functions_.remove( name ); }
 };
 
 /*----------------------------------------------------------------------------*/
diff --git a/c-opparser.cc b/c-opparser.cc
index 989cfed..c5444ff 100644
--- a/c-opparser.cc
+++ b/c-opparser.cc
@@ -392,7 +392,7 @@ bool T_ParserImpl_::checkCalls( ) noexcept
 
 /* Go through the call graph, determine whether functions are called from the
  * initialisation block, the frame rendering block, or both, and then enforce
- * restrictions on instructions.
+ * restrictions on instructions. Also, remove functions that are never called.
  */
 bool T_ParserImpl_::checkInstructionRestrictions( ) noexcept
 {
@@ -415,7 +415,12 @@ bool T_ParserImpl_::checkInstructionRestrictions( ) noexcept
 			callInfo[ id ] |= E_InstrRestriction::FRAME;
 			return true;
 		} );
-	for ( auto i = 0u ; i < output->root.nFunctions( ) ; i ++ ) {
+	for ( auto i = 0u ; i < output->root.nFunctions( ) ; ) {
+		if ( !callInfo[ i ] ) {
+			output->root.removeFunction( output->root.function( i ).name( ) );
+			callInfo.removeSwap( i );
+			continue;
+		}
 		visitor.visit( output->root.function( i ) , [&]( A_Node& node , bool exit ) {
 			if ( exit ) {
 				return false;
@@ -430,6 +435,7 @@ bool T_ParserImpl_::checkInstructionRestrictions( ) noexcept
 			}
 			return true;
 		} );
+		i ++;
 	}
 	return errors.empty( );
 }