Index: src/Virtual/ExpandCasts.cc
===================================================================
--- src/Virtual/ExpandCasts.cc	(revision fc1a3e283512526d1ddc12898c7c5fa33f0ddeaf)
+++ 	(revision )
@@ -1,272 +1,0 @@
-//
-// 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.
-//
-// ExpandCasts.cc --
-//
-// Author           : Andrew Beach
-// Created On       : Mon Jul 24 13:59:00 2017
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Mon Nov 27 09:28:20 2023
-// Update Count     : 10
-//
-
-#include "ExpandCasts.h"
-
-#include <cassert>                 // for assert, assertf
-#include <iterator>                // for back_inserter, inserter
-#include <string>                  // for string, allocator, operator==, ope...
-
-#include "AST/Copy.hpp"
-#include "AST/Decl.hpp"
-#include "AST/Expr.hpp"
-#include "AST/Pass.hpp"
-#include "Common/ScopedMap.h"      // for ScopedMap
-#include "Common/SemanticError.h"  // for SemanticError
-#include "SymTab/Mangler.h"        // for mangleType
-
-namespace Virtual {
-
-namespace {
-
-bool is_prefix( const std::string & prefix, const std::string& entire ) {
-	size_t const p_size = prefix.size();
-	return (p_size < entire.size() && prefix == entire.substr(0, p_size));
-}
-
-bool is_type_id_object( const ast::ObjectDecl * decl ) {
-	return is_prefix( "__cfatid_", decl->name );
-}
-
-	// Indented until the new ast code gets added.
-
-	/// Maps virtual table types the instance for that type.
-
-/// Better error locations for generated casts.
-// TODO: Does the improved distribution of code locations make this unneeded?
-CodeLocation castLocation( const ast::VirtualCastExpr * castExpr ) {
-	if ( castExpr->location.isSet() ) {
-		return castExpr->location;
-	} else if ( castExpr->arg->location.isSet() ) {
-		return castExpr->arg->location;
-	} else {
-		return CodeLocation();
-	}
-}
-
-[[noreturn]] void castError( ast::VirtualCastExpr const * castExpr, std::string const & message ) {
-	SemanticError( castLocation( castExpr ), message );
-}
-
-class TypeIdTable final {
-	ScopedMap<std::string, ast::ObjectDecl const *> instances;
-public:
-	void enterScope() { instances.beginScope(); }
-	void leaveScope() { instances.endScope(); }
-
-	// Attempt to insert an instance into the map. If there is a conflict,
-	// returns the previous declaration for error messages.
-	ast::ObjectDecl const * insert( ast::ObjectDecl const * typeIdDecl ) {
-		std::string mangledName = Mangle::mangleType( typeIdDecl->type );
-		ast::ObjectDecl const *& value = instances[ mangledName ];
-		if ( value ) {
-			if ( typeIdDecl->storage.is_extern ) {
-				return nullptr;
-			} else if ( !value->storage.is_extern ) {
-				return value;
-			}
-		}
-		value = typeIdDecl;
-		return nullptr;
-	}
-
-	ast::ObjectDecl const * lookup( ast::Type const * typeIdType ) {
-		std::string mangledName = Mangle::mangleType( typeIdType );
-		auto const it = instances.find( mangledName );
-		return ( instances.end() == it ) ? nullptr : it->second;
-	}
-};
-
-struct ExpandCastsCore final {
-	void previsit( ast::FunctionDecl const * decl );
-	void previsit( ast::StructDecl const * decl );
-	void previsit( ast::ObjectDecl const * decl );
-	ast::Expr const * postvisit( ast::VirtualCastExpr const * expr );
-
-	ast::CastExpr const * cast_to_type_id(
-		ast::Expr const * expr, unsigned int level_of_indirection );
-
-	ast::FunctionDecl const * vcast_decl = nullptr;
-	ast::StructDecl const * info_decl = nullptr;
-
-	TypeIdTable symtab;
-};
-
-void ExpandCastsCore::previsit( ast::FunctionDecl const * decl ) {
-	if ( !vcast_decl && "__cfavir_virtual_cast" == decl->name ) {
-		vcast_decl = decl;
-	}
-}
-
-void ExpandCastsCore::previsit( ast::StructDecl const * decl ) {
-	if ( !info_decl && decl->body && "__cfavir_type_info" == decl->name ) {
-		info_decl = decl;
-	}
-}
-
-void ExpandCastsCore::previsit( ast::ObjectDecl const * decl ) {
-	if ( is_type_id_object( decl ) ) {
-		// Multiple definitions should be fine because of linkonce.
-		symtab.insert( decl );
-	}
-}
-
-/// Get the base type from a pointer or reference.
-ast::Type const * getBaseType( ast::ptr<ast::Type> const & type ) {
-	if ( auto target = type.as<ast::PointerType>() ) {
-		return target->base.get();
-	} else if ( auto target = type.as<ast::ReferenceType>() ) {
-		return target->base.get();
-	} else {
-		return nullptr;
-	}
-}
-
-/// Copy newType, but give the copy the params of the oldType.
-ast::StructInstType * polyCopy(
-		ast::StructInstType const * oldType,
-		ast::StructInstType const * newType ) {
-	assert( oldType->params.size() == newType->params.size() );
-	ast::StructInstType * retType = ast::deepCopy( newType );
-	if ( ! oldType->params.empty() ) {
-		retType->params.clear();
-		for ( auto oldParams : oldType->params ) {
-			retType->params.push_back( ast::deepCopy( oldParams ) );
-		}
-	}
-	return retType;
-}
-
-/// Follow the "head" field of the structure to get the type that is pointed
-/// to by that field.
-ast::StructInstType const * followHeadPointerType(
-		CodeLocation const & errorLocation,
-		ast::StructInstType const * oldType,
-		std::string const & fieldName ) {
-	ast::StructDecl const * oldDecl = oldType->base;
-	assert( oldDecl );
-
-	// Helper function for throwing semantic errors.
-	auto throwError = [&fieldName, &errorLocation, &oldDecl]( std::string const & message ) {
-		SemanticError( errorLocation, "While following head pointer of %s named \"%s\": %s",
-					   oldDecl->name.c_str(), fieldName.c_str(), message.c_str() );
-	};
-
-	if ( oldDecl->members.empty() ) {
-		throwError( "Type has no fields." );
-	}
-	ast::ptr<ast::Decl> const & memberDecl = oldDecl->members.front();
-	assert( memberDecl );
-	ast::ObjectDecl const * fieldDecl = memberDecl.as<ast::ObjectDecl>();
-	assert( fieldDecl );
-	if ( fieldName != fieldDecl->name ) {
-		throwError( "Head field did not have expected name." );
-	}
-
-	ast::ptr<ast::Type> const & fieldType = fieldDecl->type;
-	if ( nullptr == fieldType ) {
-		throwError( "Could not get head field." );
-	}
-	auto ptrType = fieldType.as<ast::PointerType>();
-	if ( nullptr == ptrType ) {
-		throwError( "First field is not a pointer type." );
-	}
-	assert( ptrType->base );
-	auto newType = ptrType->base.as<ast::StructInstType>();
-	if ( nullptr == newType ) {
-		throwError( "First field does not point to a structure type." );
-	}
-
-	return polyCopy( oldType, newType );
-}
-
-/// Get the type-id type from a virtual type.
-ast::StructInstType const * getTypeIdType(
-		CodeLocation const & errorLocation,
-		ast::Type const * type ) {
-	auto typeInst = dynamic_cast<ast::StructInstType const *>( type );
-	if ( nullptr == typeInst ) {
-		return nullptr;
-	}
-	ast::ptr<ast::StructInstType> tableInst =
-		followHeadPointerType( errorLocation, typeInst, "virtual_table" );
-	if ( nullptr == tableInst ) {
-		return nullptr;
-	}
-	ast::StructInstType const * typeIdInst =
-		followHeadPointerType( errorLocation, tableInst, "__cfavir_typeid" );
-	return typeIdInst;
-}
-
-ast::Expr const * ExpandCastsCore::postvisit(
-		ast::VirtualCastExpr const * expr ) {
-	assertf( expr->result, "Virtual cast target not found before expansion." );
-
-	assert( vcast_decl );
-	assert( info_decl );
-
-	ast::Type const * base_type = getBaseType( expr->result );
-	if ( nullptr == base_type ) {
-		castError( expr, "Virtual cast target must be a pointer or reference type." );
-	}
-	ast::StructInstType const * type_id_type =
-			getTypeIdType( castLocation( expr ), base_type );
-	if ( nullptr == type_id_type ) {
-		castError( expr, "Ill formed virtual cast target type." );
-	}
-	ast::ObjectDecl const * type_id = symtab.lookup( type_id_type );
-	if ( nullptr == type_id ) {
-		// I'm trying to give a different error for polymorpic types as
-		// different things can go wrong there.
-		if ( type_id_type->params.empty() ) {
-			castError( expr, "Virtual cast does not target a virtual type." );
-		} else {
-			castError( expr, "Virtual cast does not target a type with a "
-				"type id (possible missing virtual table)." );
-		}
-	}
-
-	return new ast::CastExpr( expr->location,
-		new ast::ApplicationExpr( expr->location,
-			ast::VariableExpr::functionPointer( expr->location, vcast_decl ),
-			{
-				cast_to_type_id(
-					new ast::AddressExpr( expr->location,
-						new ast::VariableExpr( expr->location, type_id ) ),
-					1 ),
-				cast_to_type_id( expr->arg, 2 ),
-			}
-		),
-		ast::deepCopy( expr->result )
-	);
-}
-
-ast::CastExpr const * ExpandCastsCore::cast_to_type_id(
-		ast::Expr const * expr, unsigned int level_of_indirection ) {
-	assert( info_decl );
-	ast::Type * type = new ast::StructInstType( info_decl, ast::CV::Const );
-	for ( unsigned int i = 0 ; i < level_of_indirection ; ++i ) {
-		type = new ast::PointerType( type );
-	}
-	return new ast::CastExpr( expr->location, expr, type );
-}
-
-} // namespace
-
-void expandCasts( ast::TranslationUnit & translationUnit ) {
-	ast::Pass<ExpandCastsCore>::run( translationUnit );
-}
-
-} // namespace Virtual
Index: src/Virtual/ExpandCasts.cpp
===================================================================
--- src/Virtual/ExpandCasts.cpp	(revision c778ef1fa5b161d07ea4e5f42e20a63d926fc1ca)
+++ src/Virtual/ExpandCasts.cpp	(revision c778ef1fa5b161d07ea4e5f42e20a63d926fc1ca)
@@ -0,0 +1,272 @@
+//
+// 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.
+//
+// ExpandCasts.cpp --
+//
+// Author           : Andrew Beach
+// Created On       : Mon Jul 24 13:59:00 2017
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Mon Nov 27 09:28:20 2023
+// Update Count     : 10
+//
+
+#include "ExpandCasts.hpp"
+
+#include <cassert>                   // for assert, assertf
+#include <iterator>                  // for back_inserter, inserter
+#include <string>                    // for string, allocator, operator==, o...
+
+#include "AST/Copy.hpp"
+#include "AST/Decl.hpp"
+#include "AST/Expr.hpp"
+#include "AST/Pass.hpp"
+#include "Common/ScopedMap.hpp"      // for ScopedMap
+#include "Common/SemanticError.hpp"  // for SemanticError
+#include "SymTab/Mangler.hpp"        // for mangleType
+
+namespace Virtual {
+
+namespace {
+
+bool is_prefix( const std::string & prefix, const std::string& entire ) {
+	size_t const p_size = prefix.size();
+	return (p_size < entire.size() && prefix == entire.substr(0, p_size));
+}
+
+bool is_type_id_object( const ast::ObjectDecl * decl ) {
+	return is_prefix( "__cfatid_", decl->name );
+}
+
+	// Indented until the new ast code gets added.
+
+	/// Maps virtual table types the instance for that type.
+
+/// Better error locations for generated casts.
+// TODO: Does the improved distribution of code locations make this unneeded?
+CodeLocation castLocation( const ast::VirtualCastExpr * castExpr ) {
+	if ( castExpr->location.isSet() ) {
+		return castExpr->location;
+	} else if ( castExpr->arg->location.isSet() ) {
+		return castExpr->arg->location;
+	} else {
+		return CodeLocation();
+	}
+}
+
+[[noreturn]] void castError( ast::VirtualCastExpr const * castExpr, std::string const & message ) {
+	SemanticError( castLocation( castExpr ), message );
+}
+
+class TypeIdTable final {
+	ScopedMap<std::string, ast::ObjectDecl const *> instances;
+public:
+	void enterScope() { instances.beginScope(); }
+	void leaveScope() { instances.endScope(); }
+
+	// Attempt to insert an instance into the map. If there is a conflict,
+	// returns the previous declaration for error messages.
+	ast::ObjectDecl const * insert( ast::ObjectDecl const * typeIdDecl ) {
+		std::string mangledName = Mangle::mangleType( typeIdDecl->type );
+		ast::ObjectDecl const *& value = instances[ mangledName ];
+		if ( value ) {
+			if ( typeIdDecl->storage.is_extern ) {
+				return nullptr;
+			} else if ( !value->storage.is_extern ) {
+				return value;
+			}
+		}
+		value = typeIdDecl;
+		return nullptr;
+	}
+
+	ast::ObjectDecl const * lookup( ast::Type const * typeIdType ) {
+		std::string mangledName = Mangle::mangleType( typeIdType );
+		auto const it = instances.find( mangledName );
+		return ( instances.end() == it ) ? nullptr : it->second;
+	}
+};
+
+struct ExpandCastsCore final {
+	void previsit( ast::FunctionDecl const * decl );
+	void previsit( ast::StructDecl const * decl );
+	void previsit( ast::ObjectDecl const * decl );
+	ast::Expr const * postvisit( ast::VirtualCastExpr const * expr );
+
+	ast::CastExpr const * cast_to_type_id(
+		ast::Expr const * expr, unsigned int level_of_indirection );
+
+	ast::FunctionDecl const * vcast_decl = nullptr;
+	ast::StructDecl const * info_decl = nullptr;
+
+	TypeIdTable symtab;
+};
+
+void ExpandCastsCore::previsit( ast::FunctionDecl const * decl ) {
+	if ( !vcast_decl && "__cfavir_virtual_cast" == decl->name ) {
+		vcast_decl = decl;
+	}
+}
+
+void ExpandCastsCore::previsit( ast::StructDecl const * decl ) {
+	if ( !info_decl && decl->body && "__cfavir_type_info" == decl->name ) {
+		info_decl = decl;
+	}
+}
+
+void ExpandCastsCore::previsit( ast::ObjectDecl const * decl ) {
+	if ( is_type_id_object( decl ) ) {
+		// Multiple definitions should be fine because of linkonce.
+		symtab.insert( decl );
+	}
+}
+
+/// Get the base type from a pointer or reference.
+ast::Type const * getBaseType( ast::ptr<ast::Type> const & type ) {
+	if ( auto target = type.as<ast::PointerType>() ) {
+		return target->base.get();
+	} else if ( auto target = type.as<ast::ReferenceType>() ) {
+		return target->base.get();
+	} else {
+		return nullptr;
+	}
+}
+
+/// Copy newType, but give the copy the params of the oldType.
+ast::StructInstType * polyCopy(
+		ast::StructInstType const * oldType,
+		ast::StructInstType const * newType ) {
+	assert( oldType->params.size() == newType->params.size() );
+	ast::StructInstType * retType = ast::deepCopy( newType );
+	if ( ! oldType->params.empty() ) {
+		retType->params.clear();
+		for ( auto oldParams : oldType->params ) {
+			retType->params.push_back( ast::deepCopy( oldParams ) );
+		}
+	}
+	return retType;
+}
+
+/// Follow the "head" field of the structure to get the type that is pointed
+/// to by that field.
+ast::StructInstType const * followHeadPointerType(
+		CodeLocation const & errorLocation,
+		ast::StructInstType const * oldType,
+		std::string const & fieldName ) {
+	ast::StructDecl const * oldDecl = oldType->base;
+	assert( oldDecl );
+
+	// Helper function for throwing semantic errors.
+	auto throwError = [&fieldName, &errorLocation, &oldDecl]( std::string const & message ) {
+		SemanticError( errorLocation, "While following head pointer of %s named \"%s\": %s",
+					   oldDecl->name.c_str(), fieldName.c_str(), message.c_str() );
+	};
+
+	if ( oldDecl->members.empty() ) {
+		throwError( "Type has no fields." );
+	}
+	ast::ptr<ast::Decl> const & memberDecl = oldDecl->members.front();
+	assert( memberDecl );
+	ast::ObjectDecl const * fieldDecl = memberDecl.as<ast::ObjectDecl>();
+	assert( fieldDecl );
+	if ( fieldName != fieldDecl->name ) {
+		throwError( "Head field did not have expected name." );
+	}
+
+	ast::ptr<ast::Type> const & fieldType = fieldDecl->type;
+	if ( nullptr == fieldType ) {
+		throwError( "Could not get head field." );
+	}
+	auto ptrType = fieldType.as<ast::PointerType>();
+	if ( nullptr == ptrType ) {
+		throwError( "First field is not a pointer type." );
+	}
+	assert( ptrType->base );
+	auto newType = ptrType->base.as<ast::StructInstType>();
+	if ( nullptr == newType ) {
+		throwError( "First field does not point to a structure type." );
+	}
+
+	return polyCopy( oldType, newType );
+}
+
+/// Get the type-id type from a virtual type.
+ast::StructInstType const * getTypeIdType(
+		CodeLocation const & errorLocation,
+		ast::Type const * type ) {
+	auto typeInst = dynamic_cast<ast::StructInstType const *>( type );
+	if ( nullptr == typeInst ) {
+		return nullptr;
+	}
+	ast::ptr<ast::StructInstType> tableInst =
+		followHeadPointerType( errorLocation, typeInst, "virtual_table" );
+	if ( nullptr == tableInst ) {
+		return nullptr;
+	}
+	ast::StructInstType const * typeIdInst =
+		followHeadPointerType( errorLocation, tableInst, "__cfavir_typeid" );
+	return typeIdInst;
+}
+
+ast::Expr const * ExpandCastsCore::postvisit(
+		ast::VirtualCastExpr const * expr ) {
+	assertf( expr->result, "Virtual cast target not found before expansion." );
+
+	assert( vcast_decl );
+	assert( info_decl );
+
+	ast::Type const * base_type = getBaseType( expr->result );
+	if ( nullptr == base_type ) {
+		castError( expr, "Virtual cast target must be a pointer or reference type." );
+	}
+	ast::StructInstType const * type_id_type =
+			getTypeIdType( castLocation( expr ), base_type );
+	if ( nullptr == type_id_type ) {
+		castError( expr, "Ill formed virtual cast target type." );
+	}
+	ast::ObjectDecl const * type_id = symtab.lookup( type_id_type );
+	if ( nullptr == type_id ) {
+		// I'm trying to give a different error for polymorpic types as
+		// different things can go wrong there.
+		if ( type_id_type->params.empty() ) {
+			castError( expr, "Virtual cast does not target a virtual type." );
+		} else {
+			castError( expr, "Virtual cast does not target a type with a "
+				"type id (possible missing virtual table)." );
+		}
+	}
+
+	return new ast::CastExpr( expr->location,
+		new ast::ApplicationExpr( expr->location,
+			ast::VariableExpr::functionPointer( expr->location, vcast_decl ),
+			{
+				cast_to_type_id(
+					new ast::AddressExpr( expr->location,
+						new ast::VariableExpr( expr->location, type_id ) ),
+					1 ),
+				cast_to_type_id( expr->arg, 2 ),
+			}
+		),
+		ast::deepCopy( expr->result )
+	);
+}
+
+ast::CastExpr const * ExpandCastsCore::cast_to_type_id(
+		ast::Expr const * expr, unsigned int level_of_indirection ) {
+	assert( info_decl );
+	ast::Type * type = new ast::StructInstType( info_decl, ast::CV::Const );
+	for ( unsigned int i = 0 ; i < level_of_indirection ; ++i ) {
+		type = new ast::PointerType( type );
+	}
+	return new ast::CastExpr( expr->location, expr, type );
+}
+
+} // namespace
+
+void expandCasts( ast::TranslationUnit & translationUnit ) {
+	ast::Pass<ExpandCastsCore>::run( translationUnit );
+}
+
+} // namespace Virtual
Index: src/Virtual/ExpandCasts.h
===================================================================
--- src/Virtual/ExpandCasts.h	(revision fc1a3e283512526d1ddc12898c7c5fa33f0ddeaf)
+++ 	(revision )
@@ -1,32 +1,0 @@
-//
-// 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.
-//
-// ExpandCasts.h --
-//
-// Author           : Andrew Beach
-// Created On       : Mon Jul 24 13:54:00 2017
-// Last Modified By : Andrew Beach
-// Last Modified On : Fri Jul 29 14:40:00 2022
-// Update Count     : 1
-//
-
-#pragma once
-
-#include <list>  // for list
-
-class Declaration;
-namespace ast {
-	class TranslationUnit;
-}
-
-namespace Virtual {
-void expandCasts( std::list< Declaration * > & translationUnit );
-void expandCasts( ast::TranslationUnit & translationUnit );
-// Breaks all virtual cast nodes up into translatable nodes.
-
-// Later this might just set some information so it can happen at CodeGen.
-
-}
Index: src/Virtual/ExpandCasts.hpp
===================================================================
--- src/Virtual/ExpandCasts.hpp	(revision c778ef1fa5b161d07ea4e5f42e20a63d926fc1ca)
+++ src/Virtual/ExpandCasts.hpp	(revision c778ef1fa5b161d07ea4e5f42e20a63d926fc1ca)
@@ -0,0 +1,32 @@
+//
+// 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.
+//
+// ExpandCasts.hpp --
+//
+// Author           : Andrew Beach
+// Created On       : Mon Jul 24 13:54:00 2017
+// Last Modified By : Andrew Beach
+// Last Modified On : Fri Jul 29 14:40:00 2022
+// Update Count     : 1
+//
+
+#pragma once
+
+#include <list>  // for list
+
+class Declaration;
+namespace ast {
+	class TranslationUnit;
+}
+
+namespace Virtual {
+void expandCasts( std::list< Declaration * > & translationUnit );
+void expandCasts( ast::TranslationUnit & translationUnit );
+// Breaks all virtual cast nodes up into translatable nodes.
+
+// Later this might just set some information so it can happen at CodeGen.
+
+}
Index: src/Virtual/Tables.cc
===================================================================
--- src/Virtual/Tables.cc	(revision fc1a3e283512526d1ddc12898c7c5fa33f0ddeaf)
+++ 	(revision )
@@ -1,220 +1,0 @@
-//
-// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
-//
-// The contents of this file are covered under the licence agreement in the
-// file "LICENCE" distributed with Cforall.
-//
-// Tables.cc --
-//
-// Author           : Andrew Beach
-// Created On       : Mon Aug 31 11:11:00 2020
-// Last Modified By : Andrew Beach
-// Last Modified On : Fri Mar 11 10:40:00 2022
-// Update Count     : 3
-//
-
-#include "AST/Attribute.hpp"
-#include "AST/Copy.hpp"
-#include "AST/Decl.hpp"
-#include "AST/Expr.hpp"
-#include "AST/Init.hpp"
-#include "AST/Stmt.hpp"
-#include "AST/Type.hpp"
-
-namespace Virtual {
-
-std::string typeIdType( std::string const & type_name ) {
-	return "__cfatid_struct_" + type_name;
-}
-
-std::string typeIdName( std::string const & type_name ) {
-	return "__cfatid_" + type_name;
-}
-
-static std::string typeIdTypeToInstance( std::string const & type_name ) {
-	return typeIdName(type_name.substr(16));
-}
-
-std::string vtableTypeName( std::string const & name ) {
-	return name + "_vtable";
-}
-
-std::string baseTypeName( std::string const & vtable_type_name ) {
-	return vtable_type_name.substr(0, vtable_type_name.size() - 7);
-}
-
-std::string instanceName( std::string const & name ) {
-	return std::string("_") + name + "_instance";
-}
-
-std::string vtableInstanceName( std::string const & name ) {
-	return instanceName( vtableTypeName( name ) );
-}
-
-std::string concurrentDefaultVTableName() {
-	return "_default_vtable";
-}
-
-bool isVTableInstanceName( std::string const & name ) {
-	// There are some delicate length calculations here.
-	return 17 < name.size() && '_' == name[0] &&
-		std::string("_vtable_instance") == name.substr(1, name.size() - 17);
-}
-
-static ast::ObjectDecl * makeVtableDeclaration(
-		CodeLocation const & location, std::string const & name,
-		ast::StructInstType const * type, ast::Init const * init ) {
-	ast::Storage::Classes storage;
-	if ( nullptr == init ) {
-		storage.is_extern = true;
-	}
-	return new ast::ObjectDecl(
-		location,
-		name,
-		type,
-		init,
-		storage,
-		ast::Linkage::Cforall
-	);
-}
-
-ast::ObjectDecl * makeVtableForward(
-		CodeLocation const & location, std::string const & name,
-		ast::StructInstType const * vtableType ) {
-	assert( vtableType );
-	return makeVtableDeclaration( location, name, vtableType, nullptr );
-}
-
-static std::vector<ast::ptr<ast::Init>> buildInits(
-		CodeLocation const & location,
-		//std::string const & name,
-		ast::StructInstType const * vtableType,
-		ast::Type const * objectType ) {
-	ast::StructDecl const * vtableStruct = vtableType->base;
-
-	std::vector<ast::ptr<ast::Init>> inits;
-	inits.reserve( vtableStruct->members.size() );
-
-	// This is designed to run before the resolver.
-	for ( auto field : vtableStruct->members ) {
-		if ( std::string( "parent" ) == field->name ) {
-			// This will not work with polymorphic state.
-			auto oField = field.strict_as<ast::ObjectDecl>();
-			auto fieldType = oField->type.strict_as<ast::PointerType>();
-			auto parentType = fieldType->base.strict_as<ast::StructInstType>();
-			std::string const & parentInstance = instanceName( parentType->name );
-			inits.push_back(
-					new ast::SingleInit( location, new ast::AddressExpr( new ast::NameExpr( location, parentInstance ) ) ) );
-		} else if ( std::string( "__cfavir_typeid" ) == field->name ) {
-			std::string const & baseType = baseTypeName( vtableType->name );
-			std::string const & typeId = typeIdName( baseType );
-			inits.push_back( new ast::SingleInit( location, new ast::AddressExpr( new ast::NameExpr( location, typeId ) ) ) );
-		} else if ( std::string( "size" ) == field->name ) {
-			inits.push_back( new ast::SingleInit( location, new ast::SizeofExpr( location, objectType )
-			) );
-		} else if ( std::string( "align" ) == field->name ) {
-			inits.push_back( new ast::SingleInit( location,
-				new ast::AlignofExpr( location, objectType )
-			) );
-		} else {
-			inits.push_back( new ast::SingleInit( location,
-				new ast::NameExpr( location, field->name )
-			) );
-		}
-		//ast::Expr * expr = buildInitExpr(...);
-		//inits.push_back( new ast::SingleInit( location, expr ) )
-	}
-
-	return inits;
-}
-
-ast::ObjectDecl * makeVtableInstance(
-		CodeLocation const & location,
-		std::string const & name,
-		ast::StructInstType const * vtableType,
-		ast::Type const * objectType,
-		ast::Init const * init ) {
-	assert( vtableType );
-	assert( objectType );
-
-	// Build the initialization.
-	if ( nullptr == init ) {
-		init = new ast::ListInit( location,
-			buildInits( location, vtableType, objectType ) );
-
-	// The provided init should initialize everything except the parent
-	// pointer, the size-of and align-of fields. These should be inserted.
-	} else {
-		// Except this is not yet supported.
-		assert(false);
-	}
-	return makeVtableDeclaration( location, name, vtableType, init );
-}
-
-namespace {
-	std::string const functionName = "get_exception_vtable";
-}
-
-ast::FunctionDecl * makeGetExceptionForward(
-		CodeLocation const & location,
-		ast::Type const * vtableType,
-		ast::Type const * exceptType ) {
-	assert( vtableType );
-	assert( exceptType );
-	return new ast::FunctionDecl(
-		location,
-		functionName,
-		{ new ast::ObjectDecl(
-			location,
-			"__unused",
-			new ast::PointerType( exceptType )
-		) },
-		{ new ast::ObjectDecl(
-			location,
-			"_retvalue",
-			new ast::ReferenceType( vtableType )
-		) },
-		nullptr,
-		ast::Storage::Classes(),
-		ast::Linkage::Cforall,
-		{ new ast::Attribute( "unused" ) }
-	);
-}
-
-ast::FunctionDecl * makeGetExceptionFunction(
-		CodeLocation const & location,
-		ast::ObjectDecl const * vtableInstance, ast::Type const * exceptType ) {
-	assert( vtableInstance );
-	assert( exceptType );
-	ast::FunctionDecl * func = makeGetExceptionForward(
-			location, ast::deepCopy( vtableInstance->type ), exceptType );
-	func->stmts = new ast::CompoundStmt( location, {
-		new ast::ReturnStmt( location, new ast::VariableExpr( location, vtableInstance ) )
-	} );
-	return func;
-}
-
-ast::ObjectDecl * makeTypeIdInstance(
-		CodeLocation const & location,
-		ast::StructInstType const * typeIdType ) {
-	assert( typeIdType );
-	ast::StructInstType * type = ast::mutate( typeIdType );
-	type->set_const( true );
-	std::string const & typeid_name = typeIdTypeToInstance( typeIdType->name );
-	return new ast::ObjectDecl(
-		location,
-		typeid_name,
-		type,
-		new ast::ListInit( location, {
-			new ast::SingleInit( location,
-				new ast::AddressExpr( location,
-					new ast::NameExpr( location, "__cfatid_exception_t" ) ) )
-		} ),
-		ast::Storage::Classes(),
-		ast::Linkage::Cforall,
-		nullptr,
-		{ new ast::Attribute( "cfa_linkonce" ) }
-	);
-}
-
-}
Index: src/Virtual/Tables.cpp
===================================================================
--- src/Virtual/Tables.cpp	(revision c778ef1fa5b161d07ea4e5f42e20a63d926fc1ca)
+++ src/Virtual/Tables.cpp	(revision c778ef1fa5b161d07ea4e5f42e20a63d926fc1ca)
@@ -0,0 +1,220 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// Tables.cc --
+//
+// Author           : Andrew Beach
+// Created On       : Mon Aug 31 11:11:00 2020
+// Last Modified By : Andrew Beach
+// Last Modified On : Fri Mar 11 10:40:00 2022
+// Update Count     : 3
+//
+
+#include "AST/Attribute.hpp"
+#include "AST/Copy.hpp"
+#include "AST/Decl.hpp"
+#include "AST/Expr.hpp"
+#include "AST/Init.hpp"
+#include "AST/Stmt.hpp"
+#include "AST/Type.hpp"
+
+namespace Virtual {
+
+std::string typeIdType( std::string const & type_name ) {
+	return "__cfatid_struct_" + type_name;
+}
+
+std::string typeIdName( std::string const & type_name ) {
+	return "__cfatid_" + type_name;
+}
+
+static std::string typeIdTypeToInstance( std::string const & type_name ) {
+	return typeIdName(type_name.substr(16));
+}
+
+std::string vtableTypeName( std::string const & name ) {
+	return name + "_vtable";
+}
+
+std::string baseTypeName( std::string const & vtable_type_name ) {
+	return vtable_type_name.substr(0, vtable_type_name.size() - 7);
+}
+
+std::string instanceName( std::string const & name ) {
+	return std::string("_") + name + "_instance";
+}
+
+std::string vtableInstanceName( std::string const & name ) {
+	return instanceName( vtableTypeName( name ) );
+}
+
+std::string concurrentDefaultVTableName() {
+	return "_default_vtable";
+}
+
+bool isVTableInstanceName( std::string const & name ) {
+	// There are some delicate length calculations here.
+	return 17 < name.size() && '_' == name[0] &&
+		std::string("_vtable_instance") == name.substr(1, name.size() - 17);
+}
+
+static ast::ObjectDecl * makeVtableDeclaration(
+		CodeLocation const & location, std::string const & name,
+		ast::StructInstType const * type, ast::Init const * init ) {
+	ast::Storage::Classes storage;
+	if ( nullptr == init ) {
+		storage.is_extern = true;
+	}
+	return new ast::ObjectDecl(
+		location,
+		name,
+		type,
+		init,
+		storage,
+		ast::Linkage::Cforall
+	);
+}
+
+ast::ObjectDecl * makeVtableForward(
+		CodeLocation const & location, std::string const & name,
+		ast::StructInstType const * vtableType ) {
+	assert( vtableType );
+	return makeVtableDeclaration( location, name, vtableType, nullptr );
+}
+
+static std::vector<ast::ptr<ast::Init>> buildInits(
+		CodeLocation const & location,
+		//std::string const & name,
+		ast::StructInstType const * vtableType,
+		ast::Type const * objectType ) {
+	ast::StructDecl const * vtableStruct = vtableType->base;
+
+	std::vector<ast::ptr<ast::Init>> inits;
+	inits.reserve( vtableStruct->members.size() );
+
+	// This is designed to run before the resolver.
+	for ( auto field : vtableStruct->members ) {
+		if ( std::string( "parent" ) == field->name ) {
+			// This will not work with polymorphic state.
+			auto oField = field.strict_as<ast::ObjectDecl>();
+			auto fieldType = oField->type.strict_as<ast::PointerType>();
+			auto parentType = fieldType->base.strict_as<ast::StructInstType>();
+			std::string const & parentInstance = instanceName( parentType->name );
+			inits.push_back(
+					new ast::SingleInit( location, new ast::AddressExpr( new ast::NameExpr( location, parentInstance ) ) ) );
+		} else if ( std::string( "__cfavir_typeid" ) == field->name ) {
+			std::string const & baseType = baseTypeName( vtableType->name );
+			std::string const & typeId = typeIdName( baseType );
+			inits.push_back( new ast::SingleInit( location, new ast::AddressExpr( new ast::NameExpr( location, typeId ) ) ) );
+		} else if ( std::string( "size" ) == field->name ) {
+			inits.push_back( new ast::SingleInit( location, new ast::SizeofExpr( location, objectType )
+			) );
+		} else if ( std::string( "align" ) == field->name ) {
+			inits.push_back( new ast::SingleInit( location,
+				new ast::AlignofExpr( location, objectType )
+			) );
+		} else {
+			inits.push_back( new ast::SingleInit( location,
+				new ast::NameExpr( location, field->name )
+			) );
+		}
+		//ast::Expr * expr = buildInitExpr(...);
+		//inits.push_back( new ast::SingleInit( location, expr ) )
+	}
+
+	return inits;
+}
+
+ast::ObjectDecl * makeVtableInstance(
+		CodeLocation const & location,
+		std::string const & name,
+		ast::StructInstType const * vtableType,
+		ast::Type const * objectType,
+		ast::Init const * init ) {
+	assert( vtableType );
+	assert( objectType );
+
+	// Build the initialization.
+	if ( nullptr == init ) {
+		init = new ast::ListInit( location,
+			buildInits( location, vtableType, objectType ) );
+
+	// The provided init should initialize everything except the parent
+	// pointer, the size-of and align-of fields. These should be inserted.
+	} else {
+		// Except this is not yet supported.
+		assert(false);
+	}
+	return makeVtableDeclaration( location, name, vtableType, init );
+}
+
+namespace {
+	std::string const functionName = "get_exception_vtable";
+}
+
+ast::FunctionDecl * makeGetExceptionForward(
+		CodeLocation const & location,
+		ast::Type const * vtableType,
+		ast::Type const * exceptType ) {
+	assert( vtableType );
+	assert( exceptType );
+	return new ast::FunctionDecl(
+		location,
+		functionName,
+		{ new ast::ObjectDecl(
+			location,
+			"__unused",
+			new ast::PointerType( exceptType )
+		) },
+		{ new ast::ObjectDecl(
+			location,
+			"_retvalue",
+			new ast::ReferenceType( vtableType )
+		) },
+		nullptr,
+		ast::Storage::Classes(),
+		ast::Linkage::Cforall,
+		{ new ast::Attribute( "unused" ) }
+	);
+}
+
+ast::FunctionDecl * makeGetExceptionFunction(
+		CodeLocation const & location,
+		ast::ObjectDecl const * vtableInstance, ast::Type const * exceptType ) {
+	assert( vtableInstance );
+	assert( exceptType );
+	ast::FunctionDecl * func = makeGetExceptionForward(
+			location, ast::deepCopy( vtableInstance->type ), exceptType );
+	func->stmts = new ast::CompoundStmt( location, {
+		new ast::ReturnStmt( location, new ast::VariableExpr( location, vtableInstance ) )
+	} );
+	return func;
+}
+
+ast::ObjectDecl * makeTypeIdInstance(
+		CodeLocation const & location,
+		ast::StructInstType const * typeIdType ) {
+	assert( typeIdType );
+	ast::StructInstType * type = ast::mutate( typeIdType );
+	type->set_const( true );
+	std::string const & typeid_name = typeIdTypeToInstance( typeIdType->name );
+	return new ast::ObjectDecl(
+		location,
+		typeid_name,
+		type,
+		new ast::ListInit( location, {
+			new ast::SingleInit( location,
+				new ast::AddressExpr( location,
+					new ast::NameExpr( location, "__cfatid_exception_t" ) ) )
+		} ),
+		ast::Storage::Classes(),
+		ast::Linkage::Cforall,
+		nullptr,
+		{ new ast::Attribute( "cfa_linkonce" ) }
+	);
+}
+
+}
Index: src/Virtual/Tables.h
===================================================================
--- src/Virtual/Tables.h	(revision fc1a3e283512526d1ddc12898c7c5fa33f0ddeaf)
+++ 	(revision )
@@ -1,71 +1,0 @@
-//
-// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
-//
-// The contents of this file are covered under the licence agreement in the
-// file "LICENCE" distributed with Cforall.
-//
-// Tables.h --
-//
-// Author           : Andrew Beach
-// Created On       : Mon Aug 31 11:07:00 2020
-// Last Modified By : Andrew Beach
-// Last Modified On : Wec Dec  8 16:58:00 2021
-// Update Count     : 3
-//
-
-#include <list>  // for list
-
-#include <string>
-#include "AST/Fwd.hpp"
-
-namespace Virtual {
-
-std::string typeIdType( std::string const & type_name );
-std::string typeIdName( std::string const & type_name );
-std::string vtableTypeName( std::string const & type_name );
-std::string instanceName( std::string const & vtable_name );
-std::string vtableInstanceName( std::string const & type_name );
-std::string concurrentDefaultVTableName();
-bool isVTableInstanceName( std::string const & name );
-
-/* Create a forward declaration of a vtable of the given type.
- * vtableType node is consumed.
- */
-ast::ObjectDecl * makeVtableForward(
-	CodeLocation const & location, std::string const & name,
-	ast::StructInstType const * vtableType );
-
-/* Create an initialized definition of a vtable.
- * vtableType and init (if provided) nodes are consumed.
- */
-ast::ObjectDecl * makeVtableInstance(
-	CodeLocation const & location,
-	std::string const & name,
-	ast::StructInstType const * vtableType,
-	ast::Type const * objectType,
-	ast::Init const * init = nullptr );
-
-// Some special code for how exceptions interact with virtual tables.
-
-/* Create a forward declaration of the exception virtual function
- * linking the vtableType to the exceptType. Both nodes are consumed.
- */
-ast::FunctionDecl * makeGetExceptionForward(
-	CodeLocation const & location,
-	ast::Type const * vtableType,
-	ast::Type const * exceptType );
-
-/* Create the definition of the exception virtual function.
- * exceptType node is consumed.
- */
-ast::FunctionDecl * makeGetExceptionFunction(
-	CodeLocation const & location,
-	ast::ObjectDecl const * vtableInstance, ast::Type const * exceptType );
-
-/* Build an instance of the type-id from the type of the type-id.
- * TODO: Should take the parent type. Currently locked to the exception_t.
- */
-ast::ObjectDecl * makeTypeIdInstance(
-	const CodeLocation & location, ast::StructInstType const * typeIdType );
-
-}
Index: src/Virtual/Tables.hpp
===================================================================
--- src/Virtual/Tables.hpp	(revision c778ef1fa5b161d07ea4e5f42e20a63d926fc1ca)
+++ src/Virtual/Tables.hpp	(revision c778ef1fa5b161d07ea4e5f42e20a63d926fc1ca)
@@ -0,0 +1,71 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// Tables.hpp --
+//
+// Author           : Andrew Beach
+// Created On       : Mon Aug 31 11:07:00 2020
+// Last Modified By : Andrew Beach
+// Last Modified On : Wec Dec  8 16:58:00 2021
+// Update Count     : 3
+//
+
+#include <list>  // for list
+
+#include <string>
+#include "AST/Fwd.hpp"
+
+namespace Virtual {
+
+std::string typeIdType( std::string const & type_name );
+std::string typeIdName( std::string const & type_name );
+std::string vtableTypeName( std::string const & type_name );
+std::string instanceName( std::string const & vtable_name );
+std::string vtableInstanceName( std::string const & type_name );
+std::string concurrentDefaultVTableName();
+bool isVTableInstanceName( std::string const & name );
+
+/* Create a forward declaration of a vtable of the given type.
+ * vtableType node is consumed.
+ */
+ast::ObjectDecl * makeVtableForward(
+	CodeLocation const & location, std::string const & name,
+	ast::StructInstType const * vtableType );
+
+/* Create an initialized definition of a vtable.
+ * vtableType and init (if provided) nodes are consumed.
+ */
+ast::ObjectDecl * makeVtableInstance(
+	CodeLocation const & location,
+	std::string const & name,
+	ast::StructInstType const * vtableType,
+	ast::Type const * objectType,
+	ast::Init const * init = nullptr );
+
+// Some special code for how exceptions interact with virtual tables.
+
+/* Create a forward declaration of the exception virtual function
+ * linking the vtableType to the exceptType. Both nodes are consumed.
+ */
+ast::FunctionDecl * makeGetExceptionForward(
+	CodeLocation const & location,
+	ast::Type const * vtableType,
+	ast::Type const * exceptType );
+
+/* Create the definition of the exception virtual function.
+ * exceptType node is consumed.
+ */
+ast::FunctionDecl * makeGetExceptionFunction(
+	CodeLocation const & location,
+	ast::ObjectDecl const * vtableInstance, ast::Type const * exceptType );
+
+/* Build an instance of the type-id from the type of the type-id.
+ * TODO: Should take the parent type. Currently locked to the exception_t.
+ */
+ast::ObjectDecl * makeTypeIdInstance(
+	const CodeLocation & location, ast::StructInstType const * typeIdType );
+
+}
Index: src/Virtual/module.mk
===================================================================
--- src/Virtual/module.mk	(revision fc1a3e283512526d1ddc12898c7c5fa33f0ddeaf)
+++ src/Virtual/module.mk	(revision c778ef1fa5b161d07ea4e5f42e20a63d926fc1ca)
@@ -16,8 +16,8 @@
 
 SRC += \
-	Virtual/ExpandCasts.cc \
-	Virtual/ExpandCasts.h \
-	Virtual/Tables.cc \
-	Virtual/Tables.h \
+	Virtual/ExpandCasts.cpp \
+	Virtual/ExpandCasts.hpp \
+	Virtual/Tables.cpp \
+	Virtual/Tables.hpp \
 	Virtual/VirtualDtor.cpp \
 	Virtual/VirtualDtor.hpp
