Index: src/Virtual/ExpandCasts.cc
===================================================================
--- src/Virtual/ExpandCasts.cc	(revision bccd70a18277379d29bc911ade6a08acf9c36dbd)
+++ src/Virtual/ExpandCasts.cc	(revision 27316b4ae738446efa6bb22e754956242e3d79b4)
@@ -24,13 +24,7 @@
 #include "AST/Expr.hpp"
 #include "AST/Pass.hpp"
-#include "Common/PassVisitor.h"    // for PassVisitor
 #include "Common/ScopedMap.h"      // for ScopedMap
 #include "Common/SemanticError.h"  // for SemanticError
 #include "SymTab/Mangler.h"        // for mangleType
-#include "SynTree/Declaration.h"   // for ObjectDecl, StructDecl, FunctionDecl
-#include "SynTree/Expression.h"    // for VirtualCastExpr, CastExpr, Address...
-#include "SynTree/Mutator.h"       // for mutateAll
-#include "SynTree/Type.h"          // for Type, PointerType, StructInstType
-#include "SynTree/Visitor.h"       // for acceptAll
 
 namespace Virtual {
@@ -43,9 +37,4 @@
 }
 
-bool is_type_id_object( const ObjectDecl * objectDecl ) {
-	const std::string & objectName = objectDecl->name;
-	return is_prefix( "__cfatid_", objectName );
-}
-
 bool is_type_id_object( const ast::ObjectDecl * decl ) {
 	return is_prefix( "__cfatid_", decl->name );
@@ -55,219 +44,4 @@
 
 	/// Maps virtual table types the instance for that type.
-	class VirtualTableMap final {
-		ScopedMap<std::string, ObjectDecl *> vtable_instances;
-	public:
-		void enterScope() {
-			vtable_instances.beginScope();
-		}
-		void leaveScope() {
-			vtable_instances.endScope();
-		}
-
-		ObjectDecl * insert( ObjectDecl * vtableDecl ) {
-			std::string const & mangledName = SymTab::Mangler::mangleType( vtableDecl->type );
-			ObjectDecl *& value = vtable_instances[ mangledName ];
-			if ( value ) {
-				if ( vtableDecl->storageClasses.is_extern ) {
-					return nullptr;
-				} else if ( ! value->storageClasses.is_extern ) {
-					return value;
-				}
-			}
-			value = vtableDecl;
-			return nullptr;
-		}
-
-		ObjectDecl * lookup( const Type * vtableType ) {
-			std::string const & mangledName = SymTab::Mangler::mangleType( vtableType );
-			const auto it = vtable_instances.find( mangledName );
-			return ( vtable_instances.end() == it ) ? nullptr : it->second;
-		}
-	};
-
-	class VirtualCastCore {
-		CastExpr * cast_to_type_id( Expression * expr, int level_of_indirection ) {
-			Type * type = new StructInstType(
-				Type::Qualifiers( Type::Const ), pvt_decl );
-			for (int i = 0 ; i < level_of_indirection ; ++i) {
-				type = new PointerType( noQualifiers, type );
-			}
-			return new CastExpr( expr, type );
-		}
-
-	public:
-		VirtualCastCore() :
-			indexer(), vcast_decl( nullptr ), pvt_decl( nullptr )
-		{}
-
-		void premutate( FunctionDecl * functionDecl );
-		void premutate( StructDecl * structDecl );
-		void premutate( ObjectDecl * objectDecl );
-
-		Expression * postmutate( VirtualCastExpr * castExpr );
-
-		VirtualTableMap indexer;
-	private:
-		FunctionDecl *vcast_decl;
-		StructDecl *pvt_decl;
-	};
-
-	void VirtualCastCore::premutate( FunctionDecl * functionDecl ) {
-		if ( (! vcast_decl) &&
-		     functionDecl->get_name() == "__cfavir_virtual_cast" ) {
-			vcast_decl = functionDecl;
-		}
-	}
-
-	void VirtualCastCore::premutate( StructDecl * structDecl ) {
-		if ( pvt_decl || ! structDecl->has_body() ) {
-			return;
-		} else if ( structDecl->get_name() == "__cfavir_type_info" ) {
-			pvt_decl = structDecl;
-		}
-	}
-
-	void VirtualCastCore::premutate( ObjectDecl * objectDecl ) {
-		if ( is_type_id_object( objectDecl ) ) {
-			// Multiple definitions should be fine because of linkonce.
-			indexer.insert( objectDecl );
-		}
-	}
-
-	/// Better error locations for generated casts.
-	CodeLocation castLocation( const VirtualCastExpr * castExpr ) {
-		if ( castExpr->location.isSet() ) {
-			return castExpr->location;
-		} else if ( castExpr->arg->location.isSet() ) {
-			return castExpr->arg->location;
-		} else if ( castExpr->result->location.isSet() ) {
-			return castExpr->result->location;
-		} else {
-			return CodeLocation();
-		}
-	}
-
-	[[noreturn]] void castError( const VirtualCastExpr * castExpr, std::string const & message ) {
-		SemanticError( castLocation( castExpr ), message );
-	}
-
-	/// Get the base type from a pointer or reference.
-	const Type * getBaseType( const Type * type ) {
-		if ( auto target = dynamic_cast<const PointerType *>( type ) ) {
-			return target->base;
-		} else if ( auto target = dynamic_cast<const ReferenceType *>( type ) ) {
-			return target->base;
-		} else {
-			return nullptr;
-		}
-	}
-
-	/* Attempt to follow the "head" field of the structure to get the...
-	 * Returns nullptr on error, otherwise owner must free returned node.
-	 */
-	StructInstType * followHeadPointerType(
-			const StructInstType * oldType,
-			const std::string& fieldName,
-			const CodeLocation& errorLocation ) {
-
-		// First section of the function is all about trying to fill this variable in.
-		StructInstType * newType = nullptr;
-		{
-			const StructDecl * oldDecl = oldType->baseStruct;
-			assert( oldDecl );
-
-			// Helper function for throwing semantic errors.
-			auto throwError = [&fieldName, &errorLocation, &oldDecl](const std::string& message) {
-				const std::string& context = "While following head pointer of " +
-					oldDecl->name + " named '" + fieldName + "': ";
-				SemanticError( errorLocation, context + message );
-			};
-
-			if ( oldDecl->members.empty() ) {
-				throwError( "Type has no fields." );
-			}
-			const Declaration * memberDecl = oldDecl->members.front();
-			assert( memberDecl );
-			const ObjectDecl * fieldDecl = dynamic_cast<const ObjectDecl *>( memberDecl );
-			assert( fieldDecl );
-			if ( fieldName != fieldDecl->name ) {
-				throwError( "Head field did not have expected name." );
-			}
-
-			const Type * fieldType = fieldDecl->type;
-			if ( nullptr == fieldType ) {
-				throwError( "Could not get head field." );
-			}
-			const PointerType * ptrType = dynamic_cast<const PointerType *>( fieldType );
-			if ( nullptr == ptrType ) {
-				throwError( "First field is not a pointer type." );
-			}
-			assert( ptrType->base );
-			newType = dynamic_cast<StructInstType *>( ptrType->base );
-			if ( nullptr == newType ) {
-				throwError( "First field does not point to a structure type." );
-			}
-		}
-
-		// Now we can look into copying it.
-		newType = newType->clone();
-		if ( ! oldType->parameters.empty() ) {
-			deleteAll( newType->parameters );
-			newType->parameters.clear();
-			cloneAll( oldType->parameters, newType->parameters );
-		}
-		return newType;
-	}
-
-	/// Get the type-id type from a virtual type.
-	StructInstType * getTypeIdType( const Type * type, const CodeLocation& errorLocation ) {
-		const StructInstType * typeInst = dynamic_cast<const StructInstType *>( type );
-		if ( nullptr == typeInst ) {
-			return nullptr;
-		}
-		StructInstType * tableInst =
-			followHeadPointerType( typeInst, "virtual_table", errorLocation );
-		if ( nullptr == tableInst ) {
-			return nullptr;
-		}
-		StructInstType * typeIdInst =
-			followHeadPointerType( tableInst, "__cfavir_typeid", errorLocation );
-		delete tableInst;
-		return typeIdInst;
-	}
-
-	Expression * VirtualCastCore::postmutate( VirtualCastExpr * castExpr ) {
-		assertf( castExpr->result, "Virtual Cast target not found before expansion." );
-
-		assert( vcast_decl );
-		assert( pvt_decl );
-
-		const Type * base_type = getBaseType( castExpr->result );
-		if ( nullptr == base_type ) {
-			castError( castExpr, "Virtual cast target must be a pointer or reference type." );
-		}
-		const Type * type_id_type = getTypeIdType( base_type, castLocation( castExpr ) );
-		if ( nullptr == type_id_type ) {
-			castError( castExpr, "Ill formed virtual cast target type." );
-		}
-		ObjectDecl * type_id = indexer.lookup( type_id_type );
-		delete type_id_type;
-		if ( nullptr == type_id ) {
-			castError( castExpr, "Virtual cast does not target a virtual type." );
-		}
-
-		Expression * result = new CastExpr(
-			new ApplicationExpr( VariableExpr::functionPointer( vcast_decl ), {
-				cast_to_type_id( new AddressExpr( new VariableExpr( type_id ) ), 1 ),
-				cast_to_type_id( castExpr->get_arg(), 2 ),
-			} ),
-			castExpr->get_result()->clone()
-		);
-
-		castExpr->set_arg( nullptr );
-		castExpr->set_result( nullptr );
-		delete castExpr;
-		return result;
-	}
 
 /// Better error locations for generated casts.
@@ -494,9 +268,4 @@
 } // namespace
 
-void expandCasts( std::list< Declaration * > & translationUnit ) {
-	PassVisitor<VirtualCastCore> translator;
-	mutateAll( translationUnit, translator );
-}
-
 void expandCasts( ast::TranslationUnit & translationUnit ) {
 	ast::Pass<ExpandCastsCore>::run( translationUnit );
