Index: src/Common/Eval.cc
===================================================================
--- src/Common/Eval.cc	(revision 790d83558fed5c46c4c9acfac1cbfe1d8cccbd1a)
+++ src/Common/Eval.cc	(revision 2da12ae2df22a8ab193e99e082199971510f6663)
@@ -19,80 +19,8 @@
 
 #include "AST/Inspect.hpp"
-#include "Common/PassVisitor.h"
 #include "CodeGen/OperatorTable.h"						// access: OperatorInfo
 #include "AST/Pass.hpp"
 #include "InitTweak/InitTweak.h"
-#include "SynTree/Expression.h"
-
-//-------------------------------------------------------------
-// Old AST
-struct EvalOld : public WithShortCircuiting {
-	long long int value = 0;							// compose the result of the constant expression
-	bool valid = true;									// true => constant expression and value is the result
-														// false => not constant expression, e.g., ++i
-	bool cfavalid = true;								// true => constant expression and value computable
-														// false => constant expression but value not computable, e.g., sizeof(int)
-
-	void previsit( const BaseSyntaxNode * ) { visit_children = false; }
-	void postvisit( const BaseSyntaxNode * ) { valid = false; }
-
-	void postvisit( const SizeofExpr * ) {
-	}
-
-	void postvisit( const ConstantExpr * expr ) {
-		value = expr->intValue();
-	}
-
-	void postvisit( const CastExpr * expr ) {
-		auto arg = eval(expr->arg);
-		valid = arg.second;
-		value = arg.first;
-		// TODO: perform type conversion on value if valid
-	}
-
-	void postvisit( const VariableExpr * const expr ) {
-		if ( EnumInstType * inst = dynamic_cast<EnumInstType *>(expr->result) ) {
-			if ( EnumDecl * decl = inst->baseEnum ) {
-				if ( decl->valueOf( expr->var, value ) ) { // value filled by valueOf
-					return;
-				}
-			}
-		}
-		valid = false;
-	}
-
-	void postvisit( const ApplicationExpr * expr ) {
-		DeclarationWithType * function = InitTweak::getFunction(const_cast<ApplicationExpr *>(expr));
-		if ( ! function || function->linkage != LinkageSpec::Intrinsic ) { valid = false; return; }
-		const std::string & fname = function->name;
-		assertf( expr->args.size() == 1 || expr->args.size() == 2, "Intrinsic function with %zd arguments: %s", expr->args.size(), fname.c_str() );
-		std::pair<long long int, bool> arg1, arg2;
-		arg1 = eval(expr->args.front());
-		valid = valid && arg1.second;
-		if ( ! valid ) return;
-		if ( expr->args.size() == 2 ) {
-			arg2 = eval(expr->args.back());
-			valid = valid && arg2.second;
-			if ( ! valid ) return;
-		}
-		if (fname == "?+?") {
-			value = arg1.first + arg2.first;
-		} else if (fname == "?-?") {
-			value = arg1.first - arg2.first;
-		} else if (fname == "?*?") {
-			value = arg1.first * arg2.first;
-		} else if (fname == "?/?") {
-			value = arg1.first / arg2.first;
-		} else if (fname == "?%?") {
-			value = arg1.first % arg2.first;
-		} else {
-			valid = false;
-		}
-		// TODO: implement other intrinsic functions
-	}
-};
-
-//-------------------------------------------------------------
-// New AST
+
 struct EvalNew : public ast::WithShortCircuiting {
 	Evaluation result = { 0, true, true };
@@ -270,14 +198,4 @@
 };
 
-std::pair<long long int, bool> eval( const Expression * expr ) {
-	PassVisitor<EvalOld> ev;
-	if ( expr ) {
-		expr->accept( ev );
-		return std::make_pair( ev.pass.value, ev.pass.valid );
-	} else {
-		return std::make_pair( 0, false );
-	}
-}
-
 Evaluation eval( const ast::Expr * expr ) {
 	if ( expr ) {
Index: src/Common/Eval.h
===================================================================
--- src/Common/Eval.h	(revision 790d83558fed5c46c4c9acfac1cbfe1d8cccbd1a)
+++ src/Common/Eval.h	(revision 2da12ae2df22a8ab193e99e082199971510f6663)
@@ -30,6 +30,4 @@
 
 /// Evaluates expr as a long long int.
-/// If second is false, expr could not be evaluated.
-std::pair<long long int, bool> eval(const Expression * expr);
 Evaluation eval(const ast::Expr * expr);
 
Index: src/Common/Examine.cc
===================================================================
--- src/Common/Examine.cc	(revision 790d83558fed5c46c4c9acfac1cbfe1d8cccbd1a)
+++ src/Common/Examine.cc	(revision 2da12ae2df22a8ab193e99e082199971510f6663)
@@ -19,21 +19,4 @@
 #include "CodeGen/OperatorTable.h"
 #include "InitTweak/InitTweak.h"
-
-DeclarationWithType * isMainFor( FunctionDecl * func, AggregateDecl::Aggregate kind ) {
-	if (func->name != "main") return nullptr;
-	if (func->type->parameters.size() != 1) return nullptr;
-
-	auto param = func->type->parameters.front();
-
-	auto type = dynamic_cast<ReferenceType * >(param->get_type());
-	if (!type) return nullptr;
-
-	auto obj = dynamic_cast<StructInstType *>(type->base);
-	if (!obj) return nullptr;
-
-	if (kind != obj->baseStruct->kind) return nullptr;
-
-	return param;
-}
 
 namespace {
@@ -69,16 +52,4 @@
 
 namespace {
-	Type * getDestructorParam( FunctionDecl * func ) {
-		if ( !CodeGen::isDestructor( func->name ) ) return nullptr;
-
-		auto params = func->type->parameters;
-		if ( 1 != params.size() ) return nullptr;
-
-		auto ref = dynamic_cast<ReferenceType *>( params.front()->get_type() );
-		if ( ref ) {
-			return ref->base;
-		}
-		return nullptr;
-	}
 
 const ast::Type * getDestructorParam( const ast::FunctionDecl * func ) {
@@ -88,12 +59,4 @@
 }
 
-}
-
-bool isDestructorFor( FunctionDecl * func, StructDecl * type_decl ) {
-	if ( Type * type = getDestructorParam( func ) ) {
-		auto stype = dynamic_cast<StructInstType *>( type );
-		return stype && stype->baseStruct == type_decl;
-	}
-	return false;
 }
 
Index: src/Common/Examine.h
===================================================================
--- src/Common/Examine.h	(revision 790d83558fed5c46c4c9acfac1cbfe1d8cccbd1a)
+++ src/Common/Examine.h	(revision 2da12ae2df22a8ab193e99e082199971510f6663)
@@ -15,8 +15,6 @@
 
 #include "AST/Decl.hpp"
-#include "SynTree/Declaration.h"
 
 /// Check if this is a main function for a type of an aggregate kind.
-DeclarationWithType * isMainFor( FunctionDecl * func, AggregateDecl::Aggregate kind );
 const ast::DeclWithType * isMainFor(
 	const ast::FunctionDecl * func, ast::AggregateDecl::Aggregate kind );
@@ -24,5 +22,4 @@
 
 /// Check if this function is a destructor for the given structure.
-bool isDestructorFor( FunctionDecl * func, StructDecl * type_decl );
 bool isDestructorFor(
 	const ast::FunctionDecl * func, const ast::StructDecl * type );
Index: src/Common/PassVisitor.cc
===================================================================
--- src/Common/PassVisitor.cc	(revision 790d83558fed5c46c4c9acfac1cbfe1d8cccbd1a)
+++ 	(revision )
@@ -1,19 +1,0 @@
-//
-// Cforall Version 1.0.0 Copyright (C) 2019 University of Waterloo
-//
-// The contents of this file are covered under the licence agreement in the
-// file "LICENCE" distributed with Cforall.
-//
-// PassVisitor.cc --
-//
-// Author           : Thierry Delisle
-// Created On       : Fri Mar 03 14:53:53 2019
-// Last Modified By :
-// Last Modified On :
-// Update Count     :
-//
-
-#include "Common/PassVisitor.h"
-
-PassVisitorStats pass_visitor_stats;
-Stats::Counters::SimpleCounter* BaseSyntaxNode::new_nodes = nullptr;
Index: src/Common/PassVisitor.h
===================================================================
--- src/Common/PassVisitor.h	(revision 790d83558fed5c46c4c9acfac1cbfe1d8cccbd1a)
+++ 	(revision )
@@ -1,575 +1,0 @@
-#pragma once
-
-// IWYU pragma: private, include "Common/PassVisitor.h"
-
-#include <stack>
-#include <type_traits>
-
-#include "Common/Stats.h"
-#include "Common/utility.h"
-
-#include "SynTree/Mutator.h"
-#include "SynTree/Visitor.h"
-
-#include "SymTab/Indexer.h"
-
-#include "SynTree/Attribute.h"
-#include "SynTree/Initializer.h"
-#include "SynTree/Statement.h"
-#include "SynTree/Type.h"
-#include "SynTree/Declaration.h"
-#include "SynTree/Expression.h"
-#include "SynTree/Constant.h"
-
-class TypeSubstitution;
-
-#include "PassVisitor.proto.h"
-
-//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-// Templated visitor type
-// To use declare a PassVisitor< YOUR VISITOR TYPE >
-// The visitor type should specify the previsit/postvisit/premutate/postmutate for types that are desired.
-// Note: previsit/postvisit/premutate/postmutate must be **public** members
-//
-// Several additional features are available through inheritance
-// | WithTypeSubstitution - provides polymorphic TypeSubstitution * env for the current expression
-// | WithStmtsToAdd       - provides the ability to insert statements before or after the current statement by adding new statements into
-//                          stmtsToAddBefore or stmtsToAddAfter respectively.
-// | WithShortCircuiting  - provides the ability to skip visiting child nodes; set visit_children to false in pre{visit,mutate} to skip visiting children
-// | WithGuards           - provides the ability to save/restore data like a LIFO stack; to save, call GuardValue with the variable to save, the variable
-//                          will automatically be restored to its previous value after the corresponding postvisit/postmutate teminates.
-//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-template< typename pass_type >
-class PassVisitor final : public Visitor, public Mutator {
-public:
-
-	template< typename... Args >
-	PassVisitor(Args &&... args)
-		: pass( std::forward<Args>( args )... )
-	{
-		typedef PassVisitor<pass_type> this_t;
-		this_t * const * visitor = visitor_impl(pass, 0);
-		if(visitor) {
-			*const_cast<this_t **>( visitor ) = this;
-		}
-	}
-
-	virtual ~PassVisitor() = default;
-
-	pass_type pass;
-
-	virtual void visit( ObjectDecl * objectDecl ) override final;
-	virtual void visit( const ObjectDecl * objectDecl ) override final;
-	virtual void visit( FunctionDecl * functionDecl ) override final;
-	virtual void visit( const FunctionDecl * functionDecl ) override final;
-	virtual void visit( StructDecl * aggregateDecl ) override final;
-	virtual void visit( const StructDecl * aggregateDecl ) override final;
-	virtual void visit( UnionDecl * aggregateDecl ) override final;
-	virtual void visit( const UnionDecl * aggregateDecl ) override final;
-	virtual void visit( EnumDecl * aggregateDecl ) override final;
-	virtual void visit( const EnumDecl * aggregateDecl ) override final;
-	virtual void visit( TraitDecl * aggregateDecl ) override final;
-	virtual void visit( const TraitDecl * aggregateDecl ) override final;
-	virtual void visit( TypeDecl * typeDecl ) override final;
-	virtual void visit( const TypeDecl * typeDecl ) override final;
-	virtual void visit( TypedefDecl * typeDecl ) override final;
-	virtual void visit( const TypedefDecl * typeDecl ) override final;
-	virtual void visit( AsmDecl * asmDecl ) override final;
-	virtual void visit( const AsmDecl * asmDecl ) override final;
-	virtual void visit( DirectiveDecl * directiveDecl ) override final;
-	virtual void visit( const DirectiveDecl * directiveDecl ) override final;
-	virtual void visit( StaticAssertDecl * assertDecl ) override final;
-	virtual void visit( const StaticAssertDecl * assertDecl ) override final;
-	virtual void visit( InlineMemberDecl * valueDecl ) override final;
-	virtual void visit( const InlineMemberDecl * valueDecl ) override final;
-
-	virtual void visit( CompoundStmt * compoundStmt ) override final;
-	virtual void visit( const CompoundStmt * compoundStmt ) override final;
-	virtual void visit( ExprStmt * exprStmt ) override final;
-	virtual void visit( const ExprStmt * exprStmt ) override final;
-	virtual void visit( AsmStmt * asmStmt ) override final;
-	virtual void visit( const AsmStmt * asmStmt ) override final;
-	virtual void visit( DirectiveStmt * dirStmt ) override final;
-	virtual void visit( const DirectiveStmt * dirStmt ) override final;
-	virtual void visit( IfStmt * ifStmt ) override final;
-	virtual void visit( const IfStmt * ifStmt ) override final;
-	virtual void visit( WhileDoStmt * whileDoStmt ) override final;
-	virtual void visit( const WhileDoStmt * whileDoStmt ) override final;
-	virtual void visit( ForStmt * forStmt ) override final;
-	virtual void visit( const ForStmt * forStmt ) override final;
-	virtual void visit( SwitchStmt * switchStmt ) override final;
-	virtual void visit( const SwitchStmt * switchStmt ) override final;
-	virtual void visit( CaseStmt * caseStmt ) override final;
-	virtual void visit( const CaseStmt * caseStmt ) override final;
-	virtual void visit( BranchStmt * branchStmt ) override final;
-	virtual void visit( const BranchStmt * branchStmt ) override final;
-	virtual void visit( ReturnStmt * returnStmt ) override final;
-	virtual void visit( const ReturnStmt * returnStmt ) override final;
-	virtual void visit( ThrowStmt * throwStmt ) override final;
-	virtual void visit( const ThrowStmt * throwStmt ) override final;
-	virtual void visit( TryStmt * tryStmt ) override final;
-	virtual void visit( const TryStmt * tryStmt ) override final;
-	virtual void visit( CatchStmt * catchStmt ) override final;
-	virtual void visit( const CatchStmt * catchStmt ) override final;
-	virtual void visit( FinallyStmt * finallyStmt ) override final;
-	virtual void visit( const FinallyStmt * finallyStmt ) override final;
-	virtual void visit( SuspendStmt * suspendStmt ) override final;
-	virtual void visit( const SuspendStmt * suspendStmt ) override final;
-	virtual void visit( WaitForStmt * waitforStmt ) override final;
-	virtual void visit( const WaitForStmt * waitforStmt ) override final;
-	virtual void visit( WithStmt * withStmt ) override final;
-	virtual void visit( const WithStmt * withStmt ) override final;
-	virtual void visit( NullStmt * nullStmt ) override final;
-	virtual void visit( const NullStmt * nullStmt ) override final;
-	virtual void visit( DeclStmt * declStmt ) override final;
-	virtual void visit( const DeclStmt * declStmt ) override final;
-	virtual void visit( ImplicitCtorDtorStmt * impCtorDtorStmt ) override final;
-	virtual void visit( const ImplicitCtorDtorStmt * impCtorDtorStmt ) override final;
-	virtual void visit( MutexStmt * mutexStmt ) override final;
-	virtual void visit( const MutexStmt * mutexStmt ) override final;
-
-	virtual void visit( ApplicationExpr * applicationExpr ) override final;
-	virtual void visit( const ApplicationExpr * applicationExpr ) override final;
-	virtual void visit( UntypedExpr * untypedExpr ) override final;
-	virtual void visit( const UntypedExpr * untypedExpr ) override final;
-	virtual void visit( NameExpr * nameExpr ) override final;
-	virtual void visit( const NameExpr * nameExpr ) override final;
-	virtual void visit ( QualifiedNameExpr * qualifiedNameExpr ) override final;
-	virtual void visit ( const QualifiedNameExpr * qualifiedNameExpr ) override final;
-	virtual void visit( CastExpr * castExpr ) override final;
-	virtual void visit( const CastExpr * castExpr ) override final;
-	virtual void visit( KeywordCastExpr * castExpr ) override final;
-	virtual void visit( const KeywordCastExpr * castExpr ) override final;
-	virtual void visit( VirtualCastExpr * castExpr ) override final;
-	virtual void visit( const VirtualCastExpr * castExpr ) override final;
-	virtual void visit( AddressExpr * addressExpr ) override final;
-	virtual void visit( const AddressExpr * addressExpr ) override final;
-	virtual void visit( LabelAddressExpr * labAddressExpr ) override final;
-	virtual void visit( const LabelAddressExpr * labAddressExpr ) override final;
-	virtual void visit( UntypedMemberExpr * memberExpr ) override final;
-	virtual void visit( const UntypedMemberExpr * memberExpr ) override final;
-	virtual void visit( MemberExpr * memberExpr ) override final;
-	virtual void visit( const MemberExpr * memberExpr ) override final;
-	virtual void visit( VariableExpr * variableExpr ) override final;
-	virtual void visit( const VariableExpr * variableExpr ) override final;
-	virtual void visit( ConstantExpr * constantExpr ) override final;
-	virtual void visit( const ConstantExpr * constantExpr ) override final;
-	virtual void visit( SizeofExpr * sizeofExpr ) override final;
-	virtual void visit( const SizeofExpr * sizeofExpr ) override final;
-	virtual void visit( AlignofExpr * alignofExpr ) override final;
-	virtual void visit( const AlignofExpr * alignofExpr ) override final;
-	virtual void visit( UntypedOffsetofExpr * offsetofExpr ) override final;
-	virtual void visit( const UntypedOffsetofExpr * offsetofExpr ) override final;
-	virtual void visit( OffsetofExpr * offsetofExpr ) override final;
-	virtual void visit( const OffsetofExpr * offsetofExpr ) override final;
-	virtual void visit( OffsetPackExpr * offsetPackExpr ) override final;
-	virtual void visit( const OffsetPackExpr * offsetPackExpr ) override final;
-	virtual void visit( LogicalExpr * logicalExpr ) override final;
-	virtual void visit( const LogicalExpr * logicalExpr ) override final;
-	virtual void visit( ConditionalExpr * conditionalExpr ) override final;
-	virtual void visit( const ConditionalExpr * conditionalExpr ) override final;
-	virtual void visit( CommaExpr * commaExpr ) override final;
-	virtual void visit( const CommaExpr * commaExpr ) override final;
-	virtual void visit( TypeExpr * typeExpr ) override final;
-	virtual void visit( const TypeExpr * typeExpr ) override final;
-	virtual void visit( DimensionExpr * dimensionExpr ) override final;
-	virtual void visit( const DimensionExpr * dimensionExpr ) override final;
-	virtual void visit( AsmExpr * asmExpr ) override final;
-	virtual void visit( const AsmExpr * asmExpr ) override final;
-	virtual void visit( ImplicitCopyCtorExpr * impCpCtorExpr ) override final;
-	virtual void visit( const ImplicitCopyCtorExpr * impCpCtorExpr ) override final;
-	virtual void visit( ConstructorExpr *  ctorExpr ) override final;
-	virtual void visit( const ConstructorExpr *  ctorExpr ) override final;
-	virtual void visit( CompoundLiteralExpr * compLitExpr ) override final;
-	virtual void visit( const CompoundLiteralExpr * compLitExpr ) override final;
-	virtual void visit( RangeExpr * rangeExpr ) override final;
-	virtual void visit( const RangeExpr * rangeExpr ) override final;
-	virtual void visit( UntypedTupleExpr * tupleExpr ) override final;
-	virtual void visit( const UntypedTupleExpr * tupleExpr ) override final;
-	virtual void visit( TupleExpr * tupleExpr ) override final;
-	virtual void visit( const TupleExpr * tupleExpr ) override final;
-	virtual void visit( TupleIndexExpr * tupleExpr ) override final;
-	virtual void visit( const TupleIndexExpr * tupleExpr ) override final;
-	virtual void visit( TupleAssignExpr * assignExpr ) override final;
-	virtual void visit( const TupleAssignExpr * assignExpr ) override final;
-	virtual void visit( StmtExpr *  stmtExpr ) override final;
-	virtual void visit( const StmtExpr *  stmtExpr ) override final;
-	virtual void visit( UniqueExpr *  uniqueExpr ) override final;
-	virtual void visit( const UniqueExpr *  uniqueExpr ) override final;
-	virtual void visit( UntypedInitExpr *  initExpr ) override final;
-	virtual void visit( const UntypedInitExpr *  initExpr ) override final;
-	virtual void visit( InitExpr *  initExpr ) override final;
-	virtual void visit( const InitExpr *  initExpr ) override final;
-	virtual void visit( DeletedExpr *  delExpr ) override final;
-	virtual void visit( const DeletedExpr *  delExpr ) override final;
-	virtual void visit( DefaultArgExpr * argExpr ) override final;
-	virtual void visit( const DefaultArgExpr * argExpr ) override final;
-	virtual void visit( GenericExpr * genExpr ) override final;
-	virtual void visit( const GenericExpr * genExpr ) override final;
-
-	virtual void visit( VoidType * basicType ) override final;
-	virtual void visit( const VoidType * basicType ) override final;
-	virtual void visit( BasicType * basicType ) override final;
-	virtual void visit( const BasicType * basicType ) override final;
-	virtual void visit( PointerType * pointerType ) override final;
-	virtual void visit( const PointerType * pointerType ) override final;
-	virtual void visit( ArrayType * arrayType ) override final;
-	virtual void visit( const ArrayType * arrayType ) override final;
-	virtual void visit( ReferenceType * referenceType ) override final;
-	virtual void visit( const ReferenceType * referenceType ) override final;
-	virtual void visit( QualifiedType * qualType ) override final;
-	virtual void visit( const QualifiedType * qualType ) override final;
-	virtual void visit( FunctionType * functionType ) override final;
-	virtual void visit( const FunctionType * functionType ) override final;
-	virtual void visit( StructInstType * aggregateUseType ) override final;
-	virtual void visit( const StructInstType * aggregateUseType ) override final;
-	virtual void visit( UnionInstType * aggregateUseType ) override final;
-	virtual void visit( const UnionInstType * aggregateUseType ) override final;
-	virtual void visit( EnumInstType * aggregateUseType ) override final;
-	virtual void visit( const EnumInstType * aggregateUseType ) override final;
-	virtual void visit( TraitInstType * aggregateUseType ) override final;
-	virtual void visit( const TraitInstType * aggregateUseType ) override final;
-	virtual void visit( TypeInstType * aggregateUseType ) override final;
-	virtual void visit( const TypeInstType * aggregateUseType ) override final;
-	virtual void visit( TupleType * tupleType ) override final;
-	virtual void visit( const TupleType * tupleType ) override final;
-	virtual void visit( TypeofType * typeofType ) override final;
-	virtual void visit( const TypeofType * typeofType ) override final;
-	virtual void visit( VTableType * vtableType ) override final;
-	virtual void visit( const VTableType * vtableType ) override final;
-	virtual void visit( AttrType * attrType ) override final;
-	virtual void visit( const AttrType * attrType ) override final;
-	virtual void visit( VarArgsType * varArgsType ) override final;
-	virtual void visit( const VarArgsType * varArgsType ) override final;
-	virtual void visit( ZeroType * zeroType ) override final;
-	virtual void visit( const ZeroType * zeroType ) override final;
-	virtual void visit( OneType * oneType ) override final;
-	virtual void visit( const OneType * oneType ) override final;
-	virtual void visit( GlobalScopeType * globalType ) override final;
-	virtual void visit( const GlobalScopeType * globalType ) override final;
-
-	virtual void visit( Designation * designation ) override final;
-	virtual void visit( const Designation * designation ) override final;
-	virtual void visit( SingleInit * singleInit ) override final;
-	virtual void visit( const SingleInit * singleInit ) override final;
-	virtual void visit( ListInit * listInit ) override final;
-	virtual void visit( const ListInit * listInit ) override final;
-	virtual void visit( ConstructorInit * ctorInit ) override final;
-	virtual void visit( const ConstructorInit * ctorInit ) override final;
-
-	virtual void visit( Constant * constant ) override final;
-	virtual void visit( const Constant * constant ) override final;
-
-	virtual void visit( Attribute * attribute ) override final;
-	virtual void visit( const Attribute * attribute ) override final;
-
-	virtual DeclarationWithType * mutate( ObjectDecl * objectDecl ) override final;
-	virtual DeclarationWithType * mutate( FunctionDecl * functionDecl ) override final;
-	virtual Declaration * mutate( StructDecl * aggregateDecl ) override final;
-	virtual Declaration * mutate( UnionDecl * aggregateDecl ) override final;
-	virtual Declaration * mutate( EnumDecl * aggregateDecl ) override final;
-	virtual Declaration * mutate( TraitDecl * aggregateDecl ) override final;
-	virtual Declaration * mutate( TypeDecl * typeDecl ) override final;
-	virtual Declaration * mutate( TypedefDecl * typeDecl ) override final;
-	virtual AsmDecl * mutate( AsmDecl * asmDecl ) override final;
-	virtual DirectiveDecl * mutate( DirectiveDecl * directiveDecl ) override final;
-	virtual StaticAssertDecl * mutate( StaticAssertDecl * assertDecl ) override final;
-	virtual DeclarationWithType * mutate( InlineMemberDecl * valueDecl ) override final;
-
-	virtual CompoundStmt * mutate( CompoundStmt * compoundStmt ) override final;
-	virtual Statement * mutate( ExprStmt * exprStmt ) override final;
-	virtual Statement * mutate( AsmStmt * asmStmt ) override final;
-	virtual Statement * mutate( DirectiveStmt * dirStmt ) override final;
-	virtual Statement * mutate( IfStmt * ifStmt ) override final;
-	virtual Statement * mutate( WhileDoStmt * whileDoStmt ) override final;
-	virtual Statement * mutate( ForStmt * forStmt ) override final;
-	virtual Statement * mutate( SwitchStmt * switchStmt ) override final;
-	virtual Statement * mutate( CaseStmt * caseStmt ) override final;
-	virtual Statement * mutate( BranchStmt * branchStmt ) override final;
-	virtual Statement * mutate( ReturnStmt * returnStmt ) override final;
-	virtual Statement * mutate( ThrowStmt * throwStmt ) override final;
-	virtual Statement * mutate( TryStmt * tryStmt ) override final;
-	virtual Statement * mutate( CatchStmt * catchStmt ) override final;
-	virtual Statement * mutate( FinallyStmt * finallyStmt ) override final;
-	virtual Statement * mutate( SuspendStmt * suspendStmt ) override final;
-	virtual Statement * mutate( WaitForStmt * waitforStmt ) override final;
-	virtual Declaration * mutate( WithStmt * withStmt ) override final;
-	virtual NullStmt * mutate( NullStmt * nullStmt ) override final;
-	virtual Statement * mutate( DeclStmt * declStmt ) override final;
-	virtual Statement * mutate( ImplicitCtorDtorStmt * impCtorDtorStmt ) override final;
-	virtual Statement * mutate( MutexStmt * mutexStmt ) override final;
-
-	virtual Expression * mutate( ApplicationExpr * applicationExpr ) override final;
-	virtual Expression * mutate( UntypedExpr * untypedExpr ) override final;
-	virtual Expression * mutate( NameExpr * nameExpr ) override final;
-	virtual Expression * mutate( AddressExpr * addrExpr ) override final;
-	virtual Expression * mutate( LabelAddressExpr * labAddressExpr ) override final;
-	virtual Expression * mutate( CastExpr * castExpr ) override final;
-	virtual Expression * mutate( KeywordCastExpr * castExpr ) override final;
-	virtual Expression * mutate( VirtualCastExpr * castExpr ) override final;
-	virtual Expression * mutate( UntypedMemberExpr * memberExpr ) override final;
-	virtual Expression * mutate( MemberExpr * memberExpr ) override final;
-	virtual Expression * mutate( VariableExpr * variableExpr ) override final;
-	virtual Expression * mutate( ConstantExpr * constantExpr ) override final;
-	virtual Expression * mutate( SizeofExpr * sizeofExpr ) override final;
-	virtual Expression * mutate( AlignofExpr * alignofExpr ) override final;
-	virtual Expression * mutate( UntypedOffsetofExpr * offsetofExpr ) override final;
-	virtual Expression * mutate( OffsetofExpr * offsetofExpr ) override final;
-	virtual Expression * mutate( OffsetPackExpr * offsetPackExpr ) override final;
-	virtual Expression * mutate( LogicalExpr * logicalExpr ) override final;
-	virtual Expression * mutate( ConditionalExpr * conditionalExpr ) override final;
-	virtual Expression * mutate( CommaExpr * commaExpr ) override final;
-	virtual Expression * mutate( TypeExpr * typeExpr ) override final;
-	virtual Expression * mutate( DimensionExpr * dimensionExpr ) override final;
-	virtual Expression * mutate( AsmExpr * asmExpr ) override final;
-	virtual Expression * mutate( ImplicitCopyCtorExpr * impCpCtorExpr ) override final;
-	virtual Expression * mutate( ConstructorExpr * ctorExpr ) override final;
-	virtual Expression * mutate( CompoundLiteralExpr * compLitExpr ) override final;
-	virtual Expression * mutate( RangeExpr * rangeExpr ) override final;
-	virtual Expression * mutate( UntypedTupleExpr * tupleExpr ) override final;
-	virtual Expression * mutate( TupleExpr * tupleExpr ) override final;
-	virtual Expression * mutate( TupleIndexExpr * tupleExpr ) override final;
-	virtual Expression * mutate( TupleAssignExpr * assignExpr ) override final; 
-	virtual Expression * mutate( StmtExpr *  stmtExpr ) override final;
-	virtual Expression * mutate( UniqueExpr *  uniqueExpr ) override final;
-	virtual Expression * mutate( UntypedInitExpr *  initExpr ) override final;
-	virtual Expression * mutate( InitExpr *  initExpr ) override final;
-	virtual Expression * mutate( DeletedExpr *  delExpr ) override final;
-	virtual Expression * mutate( DefaultArgExpr * argExpr ) override final;
-	virtual Expression * mutate( GenericExpr * genExpr ) override final;
-	virtual Expression * mutate( QualifiedNameExpr * qualifiedNameExpr ) override final;
-
-	virtual Type * mutate( VoidType * basicType ) override final;
-	virtual Type * mutate( BasicType * basicType ) override final;
-	virtual Type * mutate( PointerType * pointerType ) override final;
-	virtual Type * mutate( ArrayType * arrayType ) override final;
-	virtual Type * mutate( ReferenceType * referenceType ) override final;
-	virtual Type * mutate( QualifiedType * qualType ) override final;
-	virtual Type * mutate( FunctionType * functionType ) override final;
-	virtual Type * mutate( StructInstType * aggregateUseType ) override final;
-	virtual Type * mutate( UnionInstType * aggregateUseType ) override final;
-	virtual Type * mutate( EnumInstType * aggregateUseType ) override final;
-	virtual Type * mutate( TraitInstType * aggregateUseType ) override final;
-	virtual Type * mutate( TypeInstType * aggregateUseType ) override final;
-	virtual Type * mutate( TupleType * tupleType ) override final;
-	virtual Type * mutate( TypeofType * typeofType ) override final;
-	virtual Type * mutate( VTableType * vtableType ) override final;
-	virtual Type * mutate( AttrType * attrType ) override final;
-	virtual Type * mutate( VarArgsType * varArgsType ) override final;
-	virtual Type * mutate( ZeroType * zeroType ) override final;
-	virtual Type * mutate( OneType * oneType ) override final;
-	virtual Type * mutate( GlobalScopeType * globalType ) override final;
-
-	virtual Designation * mutate( Designation * designation ) override final;
-	virtual Initializer * mutate( SingleInit * singleInit ) override final;
-	virtual Initializer * mutate( ListInit * listInit ) override final;
-	virtual Initializer * mutate( ConstructorInit * ctorInit ) override final;
-
-	virtual Constant * mutate( Constant * constant ) override final;
-
-	virtual Attribute * mutate( Attribute * attribute ) override final;
-
-	virtual TypeSubstitution * mutate( TypeSubstitution * sub ) final;
-
-	bool isInFunction() const {
-		return inFunction;
-	}
-
-private:
-	bool inFunction = false;
-	bool atFunctionTop = false;
-
-	template<typename pass_t> friend void acceptAll( std::list< Declaration* > &decls, PassVisitor< pass_t >& visitor );
-	template<typename pass_t> friend void acceptAll( const std::list< const Declaration * > &decls, PassVisitor< pass_t >& visitor );
-	template<typename pass_t> friend void mutateAll( std::list< Declaration* > &decls, PassVisitor< pass_t >& visitor );
-	template< typename TreeType, typename pass_t > friend void maybeAccept_impl( TreeType * tree, PassVisitor< pass_t > & visitor );
-	template< typename TreeType, typename pass_t > friend void maybeAccept_impl( const TreeType * tree, PassVisitor< pass_t > & visitor );
-	template< typename TreeType, typename pass_t > friend void maybeMutate_impl( TreeType *& tree, PassVisitor< pass_t > & mutator );
-	template< typename Container, typename pass_t > friend void maybeAccept_impl( Container & container, PassVisitor< pass_t > & visitor );
-	template< typename Container, typename pass_t > friend void maybeAccept_impl( const Container & container, PassVisitor< pass_t > & visitor );
-	template< typename Container, typename pass_t > friend void maybeMutate_impl( Container & container, PassVisitor< pass_t > & mutator );
-
-	template<typename node_type> void call_previsit ( node_type * node ) { previsit_impl ( pass, node, 0 ); }
-	template<typename node_type> void call_previsit ( const node_type * node ) { previsit_impl ( pass, node, 0 ); }
-	template<typename node_type> void call_postvisit( node_type * node ) { postvisit_impl( pass, node, 0 ); }
-	template<typename node_type> void call_postvisit( const node_type * node ) { postvisit_impl( pass, node, 0 ); }
-
-	template<typename node_type> void call_premutate ( node_type * node ) { premutate_impl( pass, node, 0 ); }
-	template<typename return_type, typename node_type> return_type call_postmutate ( node_type * node ) { return postmutate_impl<return_type>( pass, node, 0 ); }
-
-	void call_beginScope() { begin_scope_impl( pass, 0 ); }
-	void call_endScope  () { end_scope_impl  ( pass, 0 ); }
-
-	void set_env( TypeSubstitution * env ) { set_env_impl( pass, env, 0); }
-
-	template< typename func_t >
-	void handleStatementList( std::list< Statement * > & statements, func_t func );
-	void visitStatementList ( std::list< Statement* > &statements );
-	void mutateStatementList( std::list< Statement* > &statements );
-	void visitStatementList ( const std::list< Statement * > & statements );
-
-	template< typename func_t >
-	Statement * handleStatement( Statement * stmt, func_t func );
-	Statement * visitStatement ( Statement * stmt );
-	Statement * mutateStatement( Statement * stmt );
-	void visitStatement ( const Statement * stmt );
-
-	template< typename func_t >
-	Expression * handleExpression( Expression * expr, func_t func );
-	Expression * visitExpression ( Expression * expr );
-	Expression * mutateExpression( Expression * expr );
-	void visitExpression ( const Expression * expr );
-
-
-	auto			 		get_env_ptr    () -> decltype(env_impl( pass, 0)) { return env_impl( pass, 0); }
-	std::list< Statement* > * 	get_beforeStmts() { return stmtsToAddBefore_impl( pass, 0); }
-	std::list< Statement* > * 	get_afterStmts () { return stmtsToAddAfter_impl ( pass, 0); }
-	std::list< Declaration* > * 	get_beforeDecls() { return declsToAddBefore_impl( pass, 0); }
-	std::list< Declaration* > * 	get_afterDecls () { return declsToAddAfter_impl ( pass, 0); }
-
-	bool       get_visit_children    () { bool_ref * ptr = visit_children_impl(pass, 0); return ptr ? *ptr : true; }
-	bool_ref * get_visit_children_ptr() { return visit_children_impl(pass, 0); }
-
-	void indexerScopeEnter  ()                                    { indexer_impl_enterScope  ( pass, 0       ); }
-	void indexerScopeLeave  ()                                    { indexer_impl_leaveScope  ( pass, 0       ); }
-	void indexerAddId       ( const DeclarationWithType * node  ) { indexer_impl_addId       ( pass, 0, node ); }
-	void indexerAddType     ( const NamedTypeDecl       * node  ) { indexer_impl_addType     ( pass, 0, node ); }
-	void indexerAddStruct   ( const std::string         & id    ) { indexer_impl_addStruct   ( pass, 0, id   ); }
-	void indexerAddStruct   ( const StructDecl          * node  ) { indexer_impl_addStruct   ( pass, 0, node ); }
-	void indexerAddStructFwd( const StructDecl          * node  ) { indexer_impl_addStructFwd( pass, 0, node ); }
-	void indexerAddEnum     ( const EnumDecl            * node  ) { indexer_impl_addEnum     ( pass, 0, node ); }
-	void indexerAddUnion    ( const std::string         & id    ) { indexer_impl_addUnion    ( pass, 0, id   ); }
-	void indexerAddUnion    ( const UnionDecl           * node  ) { indexer_impl_addUnion    ( pass, 0, node ); }
-	void indexerAddUnionFwd ( const UnionDecl           * node  ) { indexer_impl_addUnionFwd ( pass, 0, node ); }
-	void indexerAddTrait    ( const TraitDecl           * node  ) { indexer_impl_addTrait    ( pass, 0, node ); }
-	void indexerAddWith     ( const std::list< Expression * > & exprs, const Declaration * withStmt ) { indexer_impl_addWith( pass, 0, exprs, withStmt ); }
-
-
-	template< typename TreeType, typename VisitorType >
-	friend inline void indexerScopedAccept( TreeType * tree, VisitorType & visitor );
-
-	template< typename TreeType, typename VisitorType >
-	friend inline void indexerScopedAccept( const TreeType * tree, VisitorType & visitor );
-
-	template< typename TreeType, typename VisitorType >
-	friend inline void indexerScopedMutate( TreeType *& tree, VisitorType & visitor );
-};
-
-template<typename pass_type, typename T>
-void GuardValue( pass_type * pass, T& val ) {
-	pass->at_cleanup( [ val ]( void * newVal ) {
-		* static_cast< T * >( newVal ) = val;
-	}, static_cast< void * >( & val ) );
-}
-
-class WithTypeSubstitution {
-protected:
-	WithTypeSubstitution() = default;
-	~WithTypeSubstitution() = default;
-
-public:
-	TypeSubstitution * env = nullptr;
-};
-
-class WithConstTypeSubstitution {
-protected:
-	WithConstTypeSubstitution() = default;
-	~WithConstTypeSubstitution() = default;
-
-public:
-	const TypeSubstitution * env = nullptr;
-};
-
-class WithStmtsToAdd {
-protected:
-	WithStmtsToAdd() = default;
-	~WithStmtsToAdd() = default;
-
-public:
-	std::list< Statement* > stmtsToAddBefore;
-	std::list< Statement* > stmtsToAddAfter;
-};
-
-class WithDeclsToAdd {
-protected:
-	WithDeclsToAdd() = default;
-	~WithDeclsToAdd() {
-		assert( declsToAddBefore.empty() );
-	}
-
-public:
-	std::list< Declaration* > declsToAddBefore;
-	std::list< Declaration* > declsToAddAfter;
-};
-
-class WithShortCircuiting {
-protected:
-	WithShortCircuiting() = default;
-	~WithShortCircuiting() = default;
-
-public:
-	bool_ref visit_children;
-};
-
-class WithGuards {
-protected:
-	WithGuards() = default;
-	~WithGuards() = default;
-
-public:
-	at_cleanup_t at_cleanup;
-
-	template< typename T >
-	void GuardValue( T& val ) {
-		at_cleanup( [ val ]( void * newVal ) {
-			* static_cast< T * >( newVal ) = val;
-		}, static_cast< void * >( & val ) );
-	}
-
-	template< typename T >
-	void GuardScope( T& val ) {
-		val.beginScope();
-		at_cleanup( []( void * val ) {
-			static_cast< T * >( val )->endScope();
-		}, static_cast< void * >( & val ) );
-	}
-
-	template< typename Func >
-	void GuardAction( Func func ) {
-		at_cleanup( [func](__attribute__((unused)) void *) { func(); }, nullptr );
-	}
-};
-
-template<typename pass_type>
-class WithVisitorRef {
-protected:
-	WithVisitorRef() {}
-	~WithVisitorRef() {}
-
-public:
-	PassVisitor<pass_type> * const visitor = nullptr;
-
-	bool isInFunction() const {
-		return visitor->isInFunction();
-	}
-};
-
-class WithIndexer {
-protected:
-	WithIndexer( bool trackIdentifiers = true ) : indexer(trackIdentifiers) {}
-	~WithIndexer() {}
-
-public:
-	SymTab::Indexer indexer;
-};
-
-#include "Common/Stats.h"
-
-extern struct PassVisitorStats {
-	size_t depth = 0;
-	Stats::Counters::MaxCounter<double> * max = nullptr;
-	Stats::Counters::AverageCounter<double> * avg = nullptr;
-} pass_visitor_stats;
-
-#include "SynTree/TypeSubstitution.h"
-#include "PassVisitor.impl.h"
Index: src/Common/PassVisitor.impl.h
===================================================================
--- src/Common/PassVisitor.impl.h	(revision 790d83558fed5c46c4c9acfac1cbfe1d8cccbd1a)
+++ 	(revision )
@@ -1,4105 +1,0 @@
-#pragma once
-// IWYU pragma: private, include "PassVisitor.h"
-
-#define VISIT_START( node )                                     \
-	__attribute__((unused))                                   \
-	ChildrenGuard children_guard( get_visit_children_ptr() ); \
-	__attribute__((unused))                                   \
-	guard_value_impl guard( at_cleanup_impl(pass, 0) );       \
-	call_previsit( node );                                    \
-
-#define VISIT_END( node )                       \
-	call_postvisit( node );                   \
-
-#define MUTATE_START( node )                                    \
-	__attribute__((unused))                                   \
-	ChildrenGuard children_guard( get_visit_children_ptr() ); \
-	__attribute__((unused))                                   \
-	guard_value_impl guard( at_cleanup_impl(pass, 0) );       \
-	call_premutate( node );                                   \
-
-#define MUTATE_END( type, node )                \
-	auto __return = call_postmutate< type * >( node ); \
-	assert( __return ); \
-	return __return;
-
-
-template<typename T>
-static inline bool empty( T * ptr ) {
-	return !ptr || ptr->empty();
-}
-
-typedef std::list< Statement   * > StmtList_t;
-typedef std::list< Declaration * > DeclList_t;
-
-template<typename iterator_t>
-static inline void splice( iterator_t it, DeclList_t * decls ) {
-	std::transform(
-		decls->begin(),
-		decls->end(),
-		it,
-		[](Declaration * decl) -> auto {
-			return new DeclStmt( decl );
-		}
-	);
-	decls->clear();
-}
-
-template< typename pass_type >
-inline void acceptAll( std::list< Declaration* > &decls, PassVisitor< pass_type >& visitor ) {
-	DeclList_t* beforeDecls = visitor.get_beforeDecls();
-	DeclList_t* afterDecls  = visitor.get_afterDecls();
-	SemanticErrorException errors;
-
-	pass_visitor_stats.depth++;
-	pass_visitor_stats.max->push(pass_visitor_stats.depth);
-	pass_visitor_stats.avg->push(pass_visitor_stats.depth);
-	for ( std::list< Declaration* >::iterator i = decls.begin(); ; ++i ) {
-
-
-		// splice in new declarations after previous decl
-		if ( !empty( afterDecls ) ) { decls.splice( i, *afterDecls ); }
-
-		if ( i == decls.end() ) break;
-
-		try {
-			// run visitor on declaration
-			maybeAccept_impl( *i, visitor );
-		} catch( SemanticErrorException &e ) {
-			errors.append( e );
-		}
-
-		// splice in new declarations before current decl
-		if ( !empty( beforeDecls ) ) { decls.splice( i, *beforeDecls ); }
-	}
-	pass_visitor_stats.depth--;
-	if ( ! errors.isEmpty() ) {
-		throw errors;
-	}
-}
-
-template< typename pass_type >
-inline void acceptAll( const std::list< const Declaration * > & decls, PassVisitor< pass_type >& visitor ) {
-	SemanticErrorException errors;
-
-	pass_visitor_stats.depth++;
-	pass_visitor_stats.max->push(pass_visitor_stats.depth);
-	pass_visitor_stats.avg->push(pass_visitor_stats.depth);
-	for ( const Declaration * decl : decls ) {
-		try {
-			// run visitor on declaration
-			maybeAccept_impl( decl, visitor );
-		}
-		catch( SemanticErrorException &e ) {
-			errors.append( e );
-		}
-	}
-	pass_visitor_stats.depth--;
-	if ( ! errors.isEmpty() ) {
-		throw errors;
-	}
-}
-
-template< typename pass_type >
-inline void mutateAll( std::list< Declaration* > &decls, PassVisitor< pass_type >& mutator ) {
-	DeclList_t* beforeDecls = mutator.get_beforeDecls();
-	DeclList_t* afterDecls  = mutator.get_afterDecls();
-	SemanticErrorException errors;
-
-	pass_visitor_stats.depth++;
-	pass_visitor_stats.max->push(pass_visitor_stats.depth);
-	pass_visitor_stats.avg->push(pass_visitor_stats.depth);
-	for ( std::list< Declaration* >::iterator i = decls.begin(); ; ++i ) {
-		// splice in new declarations after previous decl
-		if ( !empty( afterDecls ) ) { decls.splice( i, *afterDecls ); }
-
-		if ( i == decls.end() ) break;
-		try {
-			// run mutator on declaration
-			maybeMutate_impl( *i, mutator );
-		} catch( SemanticErrorException &e ) {
-			errors.append( e );
-		}
-
-		// splice in new declarations before current decl
-		if ( !empty( beforeDecls ) ) { decls.splice( i, *beforeDecls ); }
-	}
-	pass_visitor_stats.depth--;
-	if ( ! errors.isEmpty() ) {
-		throw errors;
-	}
-}
-
-template< typename TreeType, typename pass_type >
-inline void maybeAccept_impl( TreeType * tree, PassVisitor< pass_type > & visitor ) {
-	if ( ! visitor.get_visit_children() ) return;
-	if ( tree ) {
-		tree->accept( visitor );
-	}
-}
-
-template< typename TreeType, typename pass_type >
-inline void maybeAccept_impl( const TreeType * tree, PassVisitor< pass_type > & visitor ) {
-	if ( ! visitor.get_visit_children() ) return;
-	if ( tree ) {
-		tree->accept( visitor );
-	}
-}
-
-template< typename Container, typename pass_type >
-inline void maybeAccept_impl( Container & container, PassVisitor< pass_type > & visitor ) {
-	if ( ! visitor.get_visit_children() ) return;
-	SemanticErrorException errors;
-
-	pass_visitor_stats.depth++;
-	pass_visitor_stats.max->push(pass_visitor_stats.depth);
-	pass_visitor_stats.avg->push(pass_visitor_stats.depth);
-	for ( typename Container::iterator i = container.begin(); i != container.end(); ++i ) {
-		try {
-			if ( *i ) {
-				(*i)->accept( visitor );
-			}
-		} catch( SemanticErrorException &e ) {
-			errors.append( e );
-		}
-	}
-	pass_visitor_stats.depth--;
-	if ( ! errors.isEmpty() ) {
-		throw errors;
-	}
-}
-
-template< typename Container, typename pass_type >
-inline void maybeAccept_impl( const Container & container, PassVisitor< pass_type > & visitor ) {
-	if ( ! visitor.get_visit_children() ) return;
-	SemanticErrorException errors;
-
-	pass_visitor_stats.depth++;
-	pass_visitor_stats.max->push(pass_visitor_stats.depth);
-	pass_visitor_stats.avg->push(pass_visitor_stats.depth);
-	for ( const auto & i : container ) {
-		try {
-			if ( i ) {
-				i->accept( visitor );
-			}
-		} catch( SemanticErrorException &e ) {
-			errors.append( e );
-		}
-	}
-	pass_visitor_stats.depth--;
-	if ( ! errors.isEmpty() ) {
-		throw errors;
-	}
-}
-
-template< typename TreeType, typename pass_type >
-inline void maybeMutate_impl( TreeType *& tree, PassVisitor< pass_type > & mutator ) {
-	if ( ! mutator.get_visit_children() ) return;
-
-	if ( tree ) {
-		tree = strict_dynamic_cast< TreeType * >( tree->acceptMutator( mutator ) );
-	}
-}
-
-template< typename Container, typename pass_type >
-inline void maybeMutate_impl( Container & container, PassVisitor< pass_type > & mutator ) {
-
-	if ( ! mutator.get_visit_children() ) return;
-	SemanticErrorException errors;
-
-	pass_visitor_stats.depth++;
-	pass_visitor_stats.max->push(pass_visitor_stats.depth);
-	pass_visitor_stats.avg->push(pass_visitor_stats.depth);
-	for ( typename Container::iterator i = container.begin(); i != container.end(); ++i ) {
-		try {
-			if ( *i ) {
-				*i = dynamic_cast< typename Container::value_type >( (*i)->acceptMutator( mutator ) );
-				assert( *i );
-			} // if
-		} catch( SemanticErrorException &e ) {
-			errors.append( e );
-		} // try
-	} // for
-	pass_visitor_stats.depth--;
-	if ( ! errors.isEmpty() ) {
-		throw errors;
-	} // if
-}
-
-template< typename pass_type >
-template< typename func_t >
-void PassVisitor< pass_type >::handleStatementList( std::list< Statement * > & statements, func_t func ) {
-	if ( ! get_visit_children() ) return;
-	SemanticErrorException errors;
-
-	// don't want statements from outer CompoundStmts to be added to this CompoundStmt
-	ValueGuardPtr< StmtList_t > oldBeforeStmts( get_beforeStmts() );
-	ValueGuardPtr< StmtList_t > oldAfterStmts ( get_afterStmts () );
-	ValueGuardPtr< DeclList_t > oldBeforeDecls( get_beforeDecls() );
-	ValueGuardPtr< DeclList_t > oldAfterDecls ( get_afterDecls () );
-
-	StmtList_t* beforeStmts = get_beforeStmts();
-	StmtList_t* afterStmts  = get_afterStmts();
-	DeclList_t* beforeDecls = get_beforeDecls();
-	DeclList_t* afterDecls  = get_afterDecls();
-
-	pass_visitor_stats.depth++;
-	pass_visitor_stats.max->push(pass_visitor_stats.depth);
-	pass_visitor_stats.avg->push(pass_visitor_stats.depth);
-	for ( std::list< Statement* >::iterator i = statements.begin(); i != statements.end(); ++i ) {
-
-		if ( !empty( afterDecls ) ) { splice( std::inserter( statements, i ), afterDecls ); }
-		if ( !empty( afterStmts ) ) { statements.splice( i, *afterStmts ); }
-
-		try {
-			func( *i );
-			assert( *i );
-			assert(( empty( beforeStmts ) && empty( afterStmts ))
-			    || ( empty( beforeDecls ) && empty( afterDecls )) );
-
-		} catch ( SemanticErrorException &e ) {
-			errors.append( e );
-		}
-
-		if ( !empty( beforeDecls ) ) { splice( std::inserter( statements, i ), beforeDecls ); }
-		if ( !empty( beforeStmts ) ) { statements.splice( i, *beforeStmts ); }
-	}
-	pass_visitor_stats.depth--;
-
-	if ( !empty( afterDecls ) ) { splice( std::back_inserter( statements ), afterDecls); }
-	if ( !empty( afterStmts ) ) { statements.splice( statements.end(), *afterStmts ); }
-	if ( !errors.isEmpty() ) { throw errors; }
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visitStatementList( std::list< Statement * > & statements ) {
-	handleStatementList( statements, [this]( Statement * stmt) {
-		maybeAccept_impl( stmt, *this );
-	});
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visitStatementList( const std::list< Statement * > & statements ) {
-	if ( ! get_visit_children() ) return;
-	SemanticErrorException errors;
-
-	pass_visitor_stats.depth++;
-	pass_visitor_stats.max->push(pass_visitor_stats.depth);
-	pass_visitor_stats.avg->push(pass_visitor_stats.depth);
-	for ( const Statement * i : statements ) {
-		try {
-			maybeAccept_impl( i, *this );
-		} catch ( SemanticErrorException &e ) {
-			errors.append( e );
-		}
-	}
-	pass_visitor_stats.depth--;
-	if ( !errors.isEmpty() ) { throw errors; }
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::mutateStatementList( std::list< Statement * > & statements ) {
-	handleStatementList( statements, [this]( Statement *& stmt) {
-		maybeMutate_impl( stmt, *this );
-	});
-}
-
-
-template< typename pass_type >
-template< typename func_t >
-Statement * PassVisitor< pass_type >::handleStatement( Statement * stmt, func_t func ) {
-	if ( ! get_visit_children() ) return stmt;
-
-	// don't want statements from outer CompoundStmts to be added to this CompoundStmt
-	ValueGuardPtr< typename std::remove_pointer<decltype(get_env_ptr())>::type >  oldEnv( get_env_ptr() );
-	ValueGuardPtr< DeclList_t >          oldBeforeDecls( get_beforeDecls() );
-	ValueGuardPtr< DeclList_t >          oldAfterDecls ( get_afterDecls () );
-	ValueGuardPtr< StmtList_t >          oldBeforeStmts( get_beforeStmts() );
-	ValueGuardPtr< StmtList_t >          oldAfterStmts ( get_afterStmts () );
-
-	Statement *newStmt = func( stmt );
-
-	StmtList_t* beforeStmts = get_beforeStmts();
-	StmtList_t* afterStmts  = get_afterStmts();
-	DeclList_t* beforeDecls = get_beforeDecls();
-	DeclList_t* afterDecls  = get_afterDecls();
-
-	if( empty(beforeStmts) && empty(afterStmts) && empty(beforeDecls) && empty(afterDecls) ) { return newStmt; }
-	assert(( empty( beforeStmts ) && empty( afterStmts ))
-	    || ( empty( beforeDecls ) && empty( afterDecls )) );
-
-	CompoundStmt *compound = new CompoundStmt();
-	if( !empty(beforeDecls) ) { splice( std::back_inserter( compound->get_kids() ), beforeDecls ); }
-	if( !empty(beforeStmts) ) { compound->get_kids().splice( compound->get_kids().end(), *beforeStmts ); }
-	compound->get_kids().push_back( newStmt );
-	if( !empty(afterDecls) ) { splice( std::back_inserter( compound->get_kids() ), afterDecls ); }
-	if( !empty(afterStmts) ) { compound->get_kids().splice( compound->get_kids().end(), *afterStmts ); }
-	return compound;
-}
-
-template< typename pass_type >
-Statement * PassVisitor< pass_type >::visitStatement( Statement * stmt ) {
-	return handleStatement( stmt, [this]( Statement * stmt ) {
-		maybeAccept_impl( stmt, *this );
-		return stmt;
-	});
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visitStatement( const Statement * stmt ) {
-	if ( ! get_visit_children() ) return;
-
-	// don't want statements from outer CompoundStmts to be added to this CompoundStmt
-	ValueGuardPtr< typename std::remove_pointer<decltype(get_env_ptr())>::type >  oldEnv( get_env_ptr() );
-
-	maybeAccept_impl( stmt, *this );
-}
-
-template< typename pass_type >
-Statement * PassVisitor< pass_type >::mutateStatement( Statement * stmt ) {
-	return handleStatement( stmt, [this]( Statement * stmt ) {
-		maybeMutate_impl( stmt, *this );
-		return stmt;
-	});
-}
-
-template< typename pass_type >
-template< typename func_t >
-Expression * PassVisitor< pass_type >::handleExpression( Expression * expr, func_t func ) {
-	if ( ! get_visit_children() ) return expr;
-	if( !expr ) return nullptr;
-
-	auto env_ptr = get_env_ptr();
-	if ( env_ptr && expr->get_env() ) {
-		*env_ptr = expr->get_env();
-	}
-
-	// should env be moved onto the result of the mutate?
-	return func( expr );
-}
-
-template< typename pass_type >
-Expression * PassVisitor< pass_type >::visitExpression( Expression * expr ) {
-	return handleExpression(expr, [this]( Expression * expr ) {
-		maybeAccept_impl( expr, *this );
-		return expr;
-	});
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visitExpression( const Expression * expr ) {
-	if ( ! get_visit_children() ) return;
-	if( !expr ) return;
-
-	auto env_ptr = get_env_ptr();
-	if ( env_ptr && expr->get_env() ) {
-		*env_ptr = expr->get_env();
-	}
-
-	maybeAccept_impl( expr, *this );
-}
-
-template< typename pass_type >
-Expression * PassVisitor< pass_type >::mutateExpression( Expression * expr ) {
-	return handleExpression(expr, [this]( Expression * expr ) {
-		maybeMutate_impl( expr, *this );
-		return expr;
-	});
-}
-
-template< typename TreeType, typename VisitorType >
-inline void indexerScopedAccept( TreeType * tree, VisitorType & visitor ) {
-	if ( ! visitor.get_visit_children() ) return;
-	auto guard = makeFuncGuard(
-		[&visitor]() { visitor.indexerScopeEnter(); },
-		[&visitor]() { visitor.indexerScopeLeave(); }
-	);
-	maybeAccept_impl( tree, visitor );
-}
-
-template< typename TreeType, typename VisitorType >
-inline void indexerScopedAccept( const TreeType * tree, VisitorType & visitor ) {
-	if ( ! visitor.get_visit_children() ) return;
-	auto guard = makeFuncGuard(
-		[&visitor]() { visitor.indexerScopeEnter(); },
-		[&visitor]() { visitor.indexerScopeLeave(); }
-	);
-	maybeAccept_impl( tree, visitor );
-}
-
-template< typename TreeType, typename MutatorType >
-inline void indexerScopedMutate( TreeType *& tree, MutatorType & mutator ) {
-	if ( ! mutator.get_visit_children() ) return;
-	auto guard = makeFuncGuard(
-		[&mutator]() { mutator.indexerScopeEnter(); },
-		[&mutator]() { mutator.indexerScopeLeave(); }
-	);
-	maybeMutate_impl( tree, mutator );
-}
-
-//------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-//========================================================================================================================================================================
-//========================================================================================================================================================================
-//========================================================================================================================================================================
-//========================================================================================================================================================================
-//========================================================================================================================================================================
-//------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-
-// A NOTE ON THE ORDER OF TRAVERSAL
-//
-// Types and typedefs have their base types visited before they are added to the type table.  This is ok, since there is
-// no such thing as a recursive type or typedef.
-//
-//             typedef struct { T *x; } T; // never allowed
-//
-// for structs/unions, it is possible to have recursion, so the decl should be added as if it's incomplete to begin, the
-// members are traversed, and then the complete type should be added (assuming the type is completed by this particular
-// declaration).
-//
-//             struct T { struct T *x; }; // allowed
-//
-// It is important to add the complete type to the symbol table *after* the members/base has been traversed, since that
-// traversal may modify the definition of the type and these modifications should be visible when the symbol table is
-// queried later in this pass.
-//
-// TODO: figure out whether recursive contexts are sensible/possible/reasonable.
-
-//--------------------------------------------------------------------------
-// ObjectDecl
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( ObjectDecl * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->type         , *this );
-	maybeAccept_impl   ( node->init         , *this );
-	maybeAccept_impl   ( node->bitfieldWidth, *this );
-	maybeAccept_impl   ( node->attributes   , *this );
-
-	indexerAddId( node );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const ObjectDecl * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->type         , *this );
-	maybeAccept_impl( node->init         , *this );
-	maybeAccept_impl( node->bitfieldWidth, *this );
-	maybeAccept_impl( node->attributes   , *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-DeclarationWithType * PassVisitor< pass_type >::mutate( ObjectDecl * node ) {
-	MUTATE_START( node );
-
-	indexerScopedMutate( node->type         , *this );
-	maybeMutate_impl   ( node->init         , *this );
-	maybeMutate_impl   ( node->bitfieldWidth, *this );
-	maybeMutate_impl   ( node->attributes   , *this );
-
-	indexerAddId( node );
-
-	MUTATE_END( DeclarationWithType, node );
-}
-
-//--------------------------------------------------------------------------
-// FunctionDecl
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( FunctionDecl * node ) {
-	VISIT_START( node );
-
-	indexerAddId( node );
-
-	maybeAccept_impl( node->withExprs, *this );
-	{
-		// with clause introduces a level of scope (for the with expression members).
-		// with clause exprs are added to the indexer before parameters so that parameters
-		// shadow with exprs and not the other way around.
-		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		indexerAddWith( node->withExprs, node );
-		{
-			auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-			// implicit add __func__ identifier as specified in the C manual 6.4.2.2
-			static ObjectDecl func(
-				"__func__", noStorageClasses, LinkageSpec::C, nullptr,
-				new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers( Type::Const ), BasicType::Char ), nullptr, true, false ),
-				nullptr
-			);
-			indexerAddId( &func );
-			maybeAccept_impl( node->type, *this );
-			// First remember that we are now within a function.
-			ValueGuard< bool > oldInFunction( inFunction );
-			inFunction = true;
-			// The function body needs to have the same scope as parameters.
-			// A CompoundStmt will not enter a new scope if atFunctionTop is true.
-			ValueGuard< bool > oldAtFunctionTop( atFunctionTop );
-			atFunctionTop = true;
-			maybeAccept_impl( node->statements, *this );
-			maybeAccept_impl( node->attributes, *this );
-		}
-	}
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const FunctionDecl * node ) {
-	VISIT_START( node );
-
-	indexerAddId( node );
-
-	maybeAccept_impl( node->withExprs, *this );
-	{
-		// with clause introduces a level of scope (for the with expression members).
-		// with clause exprs are added to the indexer before parameters so that parameters
-		// shadow with exprs and not the other way around.
-		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		indexerAddWith( node->withExprs, node );
-		{
-			auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-			// implicit add __func__ identifier as specified in the C manual 6.4.2.2
-			static ObjectDecl func(
-				"__func__", noStorageClasses, LinkageSpec::C, nullptr,
-				new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers( Type::Const ), BasicType::Char ), nullptr, true, false ),
-				nullptr
-			);
-			indexerAddId( &func );
-			maybeAccept_impl( node->type, *this );
-			// First remember that we are now within a function.
-			ValueGuard< bool > oldInFunction( inFunction );
-			inFunction = true;
-			// The function body needs to have the same scope as parameters.
-			// A CompoundStmt will not enter a new scope if atFunctionTop is true.
-			ValueGuard< bool > oldAtFunctionTop( atFunctionTop );
-			atFunctionTop = true;
-			maybeAccept_impl( node->statements, *this );
-			maybeAccept_impl( node->attributes, *this );
-		}
-	}
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-DeclarationWithType * PassVisitor< pass_type >::mutate( FunctionDecl * node ) {
-	MUTATE_START( node );
-
-	indexerAddId( node );
-
-	{
-		// with clause introduces a level of scope (for the with expression members).
-		// with clause exprs are added to the indexer before parameters so that parameters
-		// shadow with exprs and not the other way around.
-		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		indexerAddWith( node->withExprs, node );
-		{
-			auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-			// implicit add __func__ identifier as specified in the C manual 6.4.2.2
-			static ObjectDecl func(
-				"__func__", noStorageClasses, LinkageSpec::C, nullptr,
-				new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers( Type::Const ), BasicType::Char ), nullptr, true, false ),
-				nullptr
-			);
-			indexerAddId( &func );
-			maybeMutate_impl( node->type, *this );
-			maybeMutate_impl( node->attributes, *this );
-			// First remember that we are now within a function.
-			ValueGuard< bool > oldInFunction( inFunction );
-			inFunction = true;
-			// The function body needs to have the same scope as parameters.
-			// A CompoundStmt will not enter a new scope if atFunctionTop is true.
-			ValueGuard< bool > oldAtFunctionTop( atFunctionTop );
-			atFunctionTop = true;
-			maybeMutate_impl( node->statements, *this );
-		}
-	}
-
-	MUTATE_END( DeclarationWithType, node );
-}
-
-//--------------------------------------------------------------------------
-// StructDecl
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( StructDecl * node ) {
-	VISIT_START( node );
-
-	// make up a forward declaration and add it before processing the members
-	// needs to be on the heap because addStruct saves the pointer
-	indexerAddStructFwd( node );
-
-	{
-		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeAccept_impl( node->parameters, *this );
-		maybeAccept_impl( node->members   , *this );
-		maybeAccept_impl( node->attributes, *this );
-	}
-
-	// this addition replaces the forward declaration
-	indexerAddStruct( node );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const StructDecl * node ) {
-	VISIT_START( node );
-
-	// make up a forward declaration and add it before processing the members
-	// needs to be on the heap because addStruct saves the pointer
-	indexerAddStructFwd( node );
-
-	{
-		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeAccept_impl( node->parameters, *this );
-		maybeAccept_impl( node->members   , *this );
-		maybeAccept_impl( node->attributes, *this );
-	}
-
-	// this addition replaces the forward declaration
-	indexerAddStruct( node );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Declaration * PassVisitor< pass_type >::mutate( StructDecl * node ) {
-	MUTATE_START( node );
-
-	// make up a forward declaration and add it before processing the members
-	// needs to be on the heap because addStruct saves the pointer
-	indexerAddStructFwd( node );
-
-	{
-		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeMutate_impl( node->parameters, *this );
-		maybeMutate_impl( node->members   , *this );
-		maybeMutate_impl( node->attributes, *this );
-	}
-
-	// this addition replaces the forward declaration
-	indexerAddStruct( node );
-
-	MUTATE_END( Declaration, node );
-}
-
-//--------------------------------------------------------------------------
-// UnionDecl
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( UnionDecl * node ) {
-	VISIT_START( node );
-
-	// make up a forward declaration and add it before processing the members
-	indexerAddUnionFwd( node );
-
-	{
-		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeAccept_impl( node->parameters, *this );
-		maybeAccept_impl( node->members   , *this );
-		maybeAccept_impl( node->attributes, *this );
-	}
-
-	indexerAddUnion( node );
-
-	VISIT_END( node );
-}
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const UnionDecl * node ) {
-	VISIT_START( node );
-
-	// make up a forward declaration and add it before processing the members
-	indexerAddUnionFwd( node );
-
-	{
-		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeAccept_impl( node->parameters, *this );
-		maybeAccept_impl( node->members   , *this );
-		maybeAccept_impl( node->attributes, *this );
-	}
-
-	indexerAddUnion( node );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Declaration * PassVisitor< pass_type >::mutate( UnionDecl * node ) {
-	MUTATE_START( node );
-
-	// make up a forward declaration and add it before processing the members
-	indexerAddUnionFwd( node );
-
-	{
-		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeMutate_impl( node->parameters, *this );
-		maybeMutate_impl( node->members   , *this );
-		maybeMutate_impl( node->attributes, *this );
-	}
-
-	indexerAddUnion( node );
-
-	MUTATE_END( Declaration, node );
-}
-
-//--------------------------------------------------------------------------
-// EnumDecl
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( EnumDecl * node ) {
-	VISIT_START( node );
-
-	indexerAddEnum( node );
-
-	// unlike structs, traits, and unions, enums inject their members into the global scope
-	// if ( node->base ) maybeAccept_impl( node->base, *this ); // Need this? Maybe not?
-	maybeAccept_impl( node->parameters, *this );
-	maybeAccept_impl( node->members   , *this );
-	maybeAccept_impl( node->attributes, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const EnumDecl * node ) {
-	VISIT_START( node );
-
-	indexerAddEnum( node );
-
-	// unlike structs, traits, and unions, enums inject their members into the global scope
-	maybeAccept_impl( node->parameters, *this );
-	maybeAccept_impl( node->members   , *this );
-	maybeAccept_impl( node->attributes, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Declaration * PassVisitor< pass_type >::mutate( EnumDecl * node ) {
-	MUTATE_START( node );
-
-	indexerAddEnum( node );
-
-	// unlike structs, traits, and unions, enums inject their members into the global scope
-	maybeMutate_impl( node->parameters, *this );
-	maybeMutate_impl( node->members   , *this );
-	maybeMutate_impl( node->attributes, *this );
-
-	MUTATE_END( Declaration, node );
-}
-
-//--------------------------------------------------------------------------
-// TraitDecl
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( TraitDecl * node ) {
-	VISIT_START( node );
-
-	{
-		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeAccept_impl( node->parameters, *this );
-		maybeAccept_impl( node->members   , *this );
-		maybeAccept_impl( node->attributes, *this );
-	}
-
-	indexerAddTrait( node );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const TraitDecl * node ) {
-	VISIT_START( node );
-
-	{
-		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeAccept_impl( node->parameters, *this );
-		maybeAccept_impl( node->members   , *this );
-		maybeAccept_impl( node->attributes, *this );
-	}
-
-	indexerAddTrait( node );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Declaration * PassVisitor< pass_type >::mutate( TraitDecl * node ) {
-	MUTATE_START( node );
-
-	{
-		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeMutate_impl( node->parameters, *this );
-		maybeMutate_impl( node->members   , *this );
-		maybeMutate_impl( node->attributes, *this );
-	}
-
-	indexerAddTrait( node );
-
-	MUTATE_END( Declaration, node );
-}
-
-//--------------------------------------------------------------------------
-// TypeDecl
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( TypeDecl * node ) {
-	VISIT_START( node );
-
-	{
-		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeAccept_impl( node->base      , *this );
-	}
-
-	// see A NOTE ON THE ORDER OF TRAVERSAL, above
-	// note that assertions come after the type is added to the symtab, since they are not part of the type proper
-	// and may depend on the type itself
-	indexerAddType( node );
-
-	maybeAccept_impl( node->assertions, *this );
-
-	indexerScopedAccept( node->init, *this );
-
-	VISIT_END( node );
-}
-
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const TypeDecl * node ) {
-	VISIT_START( node );
-
-	{
-		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeAccept_impl( node->base      , *this );
-	}
-
-	// see A NOTE ON THE ORDER OF TRAVERSAL, above
-	// note that assertions come after the type is added to the symtab, since they are not part of the type proper
-	// and may depend on the type itself
-	indexerAddType( node );
-
-	maybeAccept_impl( node->assertions, *this );
-
-	indexerScopedAccept( node->init, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Declaration * PassVisitor< pass_type >::mutate( TypeDecl * node ) {
-	MUTATE_START( node );
-
-	{
-		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeMutate_impl( node->base      , *this );
-	}
-
-	// see A NOTE ON THE ORDER OF TRAVERSAL, above
-	// note that assertions come after the type is added to the symtab, since they are not part of the type proper
-	// and may depend on the type itself
-	indexerAddType( node );
-
-	maybeMutate_impl( node->assertions, *this );
-
-	indexerScopedMutate( node->init, *this );
-
-	MUTATE_END( Declaration, node );
-}
-
-//--------------------------------------------------------------------------
-// TypedefDecl
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( TypedefDecl * node ) {
-	VISIT_START( node );
-
-	{
-		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeAccept_impl( node->base      , *this );
-	}
-
-	indexerAddType( node );
-
-	maybeAccept_impl( node->assertions, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const TypedefDecl * node ) {
-	VISIT_START( node );
-
-	{
-		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeAccept_impl( node->base      , *this );
-	}
-
-	indexerAddType( node );
-
-	maybeAccept_impl( node->assertions, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Declaration * PassVisitor< pass_type >::mutate( TypedefDecl * node ) {
-	MUTATE_START( node );
-
-	{
-		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeMutate_impl( node->base      , *this );
-	}
-
-	indexerAddType( node );
-
-	maybeMutate_impl( node->assertions, *this );
-
-	MUTATE_END( Declaration, node );
-}
-
-//--------------------------------------------------------------------------
-// AsmDecl
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( AsmDecl * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->stmt, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const AsmDecl * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->stmt, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-AsmDecl * PassVisitor< pass_type >::mutate( AsmDecl * node ) {
-	MUTATE_START( node );
-
-	maybeMutate_impl( node->stmt, *this );
-
-	MUTATE_END( AsmDecl, node );
-}
-
-//--------------------------------------------------------------------------
-// DirectiveDecl
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( DirectiveDecl * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->stmt, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const DirectiveDecl * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->stmt, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-DirectiveDecl * PassVisitor< pass_type >::mutate( DirectiveDecl * node ) {
-	MUTATE_START( node );
-
-	maybeMutate_impl( node->stmt, *this );
-
-	MUTATE_END( DirectiveDecl, node );
-}
-
-//--------------------------------------------------------------------------
-// StaticAssertDecl
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( StaticAssertDecl * node ) {
-	VISIT_START( node );
-
-	node->condition = visitExpression( node->condition );
-	maybeAccept_impl( node->message, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const StaticAssertDecl * node ) {
-	VISIT_START( node );
-
-	visitExpression( node->condition );
-	maybeAccept_impl( node->message, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-StaticAssertDecl * PassVisitor< pass_type >::mutate( StaticAssertDecl * node ) {
-	MUTATE_START( node );
-
-	node->condition = mutateExpression( node->condition );
-	maybeMutate_impl( node->message, *this );
-
-	MUTATE_END( StaticAssertDecl, node );
-}
-
-//--------------------------------------------------------------------------
-// InlineMemberDecl
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( InlineMemberDecl * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->type, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const InlineMemberDecl * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->type, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-DeclarationWithType * PassVisitor< pass_type >::mutate( InlineMemberDecl * node ) {
-	MUTATE_START( node );
-
-	maybeMutate_impl( node->type, *this );
-
-	MUTATE_END( DeclarationWithType, node );
-}
-
-//--------------------------------------------------------------------------
-// CompoundStmt
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( CompoundStmt * node ) {
-	VISIT_START( node );
-	{
-		// Do not enter a new scope if atFunctionTop is true, don't leave one either.
-		ValueGuard< bool > oldAtFunctionTop( atFunctionTop );
-		auto guard1 = makeFuncGuard( [this, go = !atFunctionTop]() { if ( go ) indexerScopeEnter(); }, [this, go = !atFunctionTop]() { if ( go ) indexerScopeLeave(); } );
-		auto guard2 = makeFuncGuard( [this]() { call_beginScope();   }, [this]() { call_endScope();     } );
-		atFunctionTop = false;
-		visitStatementList( node->kids );
-	}
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const CompoundStmt * node ) {
-	VISIT_START( node );
-	{
-		// Do not enter a new scope if atFunctionTop is true, don't leave one either.
-		ValueGuard< bool > oldAtFunctionTop( atFunctionTop );
-		auto guard1 = makeFuncGuard( [this, go = !atFunctionTop]() { if ( go ) indexerScopeEnter(); }, [this, go = !atFunctionTop]() { if ( go ) indexerScopeLeave(); } );
-		auto guard2 = makeFuncGuard( [this]() { call_beginScope();   }, [this]() { call_endScope();     } );
-		atFunctionTop = false;
-		visitStatementList( node->kids );
-	}
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-CompoundStmt * PassVisitor< pass_type >::mutate( CompoundStmt * node ) {
-	MUTATE_START( node );
-	{
-		// Do not enter a new scope if atFunctionTop is true, don't leave one either.
-		ValueGuard< bool > oldAtFunctionTop( atFunctionTop );
-		auto guard1 = makeFuncGuard( [this, go = !atFunctionTop]() { if ( go ) indexerScopeEnter(); }, [this, go = !atFunctionTop]() { if ( go ) indexerScopeLeave(); } );
-		auto guard2 = makeFuncGuard( [this]() { call_beginScope();   }, [this]() { call_endScope();     } );
-		atFunctionTop = false;
-		mutateStatementList( node->kids );
-	}
-	MUTATE_END( CompoundStmt, node );
-}
-
-//--------------------------------------------------------------------------
-// ExprStmt
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( ExprStmt * node ) {
-	VISIT_START( node );
-
-	visitExpression( node->expr );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const ExprStmt * node ) {
-	VISIT_START( node );
-
-	visitExpression( node->expr );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Statement * PassVisitor< pass_type >::mutate( ExprStmt * node ) {
-	MUTATE_START( node );
-
-	node->expr = mutateExpression( node->expr );
-
-	MUTATE_END( Statement, node );
-}
-
-//--------------------------------------------------------------------------
-// AsmStmt
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( AsmStmt * node ) {
-	VISIT_START( node )
-
-	maybeAccept_impl( node->instruction, *this );
-	maybeAccept_impl( node->output, *this );
-	maybeAccept_impl( node->input, *this );
-	maybeAccept_impl( node->clobber, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const AsmStmt * node ) {
-	VISIT_START( node )
-
-	maybeAccept_impl( node->instruction, *this );
-	maybeAccept_impl( node->output, *this );
-	maybeAccept_impl( node->input, *this );
-	maybeAccept_impl( node->clobber, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Statement * PassVisitor< pass_type >::mutate( AsmStmt * node ) {
-	MUTATE_START( node );
-
-	maybeMutate_impl( node->instruction, *this );
-	maybeMutate_impl( node->output, *this );
-	maybeMutate_impl( node->input, *this );
-	maybeMutate_impl( node->clobber, *this );
-
-	MUTATE_END( Statement, node );
-}
-
-//--------------------------------------------------------------------------
-// AsmStmt
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( DirectiveStmt * node ) {
-	VISIT_START( node )
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const DirectiveStmt * node ) {
-	VISIT_START( node )
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Statement * PassVisitor< pass_type >::mutate( DirectiveStmt * node ) {
-	MUTATE_START( node );
-
-	MUTATE_END( Statement, node );
-}
-
-//--------------------------------------------------------------------------
-// IfStmt
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( IfStmt * node ) {
-	VISIT_START( node );
-	{
-		// if statements introduce a level of scope (for the initialization)
-		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeAccept_impl( node->initialization, *this );
-		visitExpression ( node->condition );
-		node->then = visitStatement( node->then );
-		node->else_ = visitStatement( node->else_ );
-	}
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const IfStmt * node ) {
-	VISIT_START( node );
-	{
-		// if statements introduce a level of scope (for the initialization)
-		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeAccept_impl( node->initialization, *this );
-		visitExpression ( node->condition );
-		visitStatement  ( node->then );
-		visitStatement  ( node->else_ );
-	}
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Statement * PassVisitor< pass_type >::mutate( IfStmt * node ) {
-	MUTATE_START( node );
-	{
-		// if statements introduce a level of scope (for the initialization)
-		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeMutate_impl( node->initialization, *this );
-		node->condition = mutateExpression( node->condition );
-		node->then  = mutateStatement ( node->then  );
-		node->else_  = mutateStatement ( node->else_  );
-	}
-	MUTATE_END( Statement, node );
-}
-
-//--------------------------------------------------------------------------
-// WhileDoStmt
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( WhileDoStmt * node ) {
-	VISIT_START( node );
-
-	{
-		// while statements introduce a level of scope (for the initialization)
-		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeAccept_impl( node->initialization, *this );
-		visitExpression ( node->condition );
-		node->body = visitStatement( node->body );
-	}
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const WhileDoStmt * node ) {
-	VISIT_START( node );
-
-	{
-		// while statements introduce a level of scope (for the initialization)
-		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeAccept_impl( node->initialization, *this );
-		visitExpression ( node->condition );
-		visitStatement  ( node->body );
-	}
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Statement * PassVisitor< pass_type >::mutate( WhileDoStmt * node ) {
-	MUTATE_START( node );
-
-	{
-		// while statements introduce a level of scope (for the initialization)
-		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeMutate_impl( node->initialization, *this );
-		node->condition = mutateExpression( node->condition );
-		node->body      = mutateStatement ( node->body      );
-	}
-
-
-	MUTATE_END( Statement, node );
-}
-
-//--------------------------------------------------------------------------
-// ForStmt
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( ForStmt * node ) {
-	VISIT_START( node );
-	{
-		// for statements introduce a level of scope (for the initialization)
-		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeAccept_impl( node->initialization, *this );
-		visitExpression( node->condition );
-		visitExpression( node->increment );
-		node->body = visitStatement( node->body );
-	}
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const ForStmt * node ) {
-	VISIT_START( node );
-	{
-		// for statements introduce a level of scope (for the initialization)
-		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeAccept_impl( node->initialization, *this );
-		visitExpression( node->condition );
-		visitExpression( node->increment );
-		visitStatement ( node->body );
-	}
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Statement * PassVisitor< pass_type >::mutate( ForStmt * node ) {
-	MUTATE_START( node );
-	{
-		// for statements introduce a level of scope (for the initialization)
-		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeMutate_impl( node->initialization, *this );
-		node->condition = mutateExpression( node->condition );
-		node->increment = mutateExpression( node->increment );
-		node->body      = mutateStatement ( node->body      );
-	}
-	MUTATE_END( Statement, node );
-}
-
-//--------------------------------------------------------------------------
-// SwitchStmt
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( SwitchStmt * node ) {
-	VISIT_START( node );
-
-	visitExpression   ( node->condition  );
-	visitStatementList( node->statements );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const SwitchStmt * node ) {
-	VISIT_START( node );
-
-	visitExpression   ( node->condition  );
-	visitStatementList( node->statements );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Statement * PassVisitor< pass_type >::mutate( SwitchStmt * node ) {
-	MUTATE_START( node );
-
-	node->condition = mutateExpression( node->condition );
-	mutateStatementList( node->statements );
-
-	MUTATE_END( Statement, node );
-}
-
-//--------------------------------------------------------------------------
-// CaseStmt
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( CaseStmt * node ) {
-	VISIT_START( node );
-
-	visitExpression   ( node->condition );
-	visitStatementList( node->stmts     );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const CaseStmt * node ) {
-	VISIT_START( node );
-
-	visitExpression   ( node->condition );
-	visitStatementList( node->stmts     );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Statement * PassVisitor< pass_type >::mutate( CaseStmt * node ) {
-	MUTATE_START( node );
-
-	node->condition = mutateExpression( node->condition );
-	mutateStatementList( node->stmts );
-
-	MUTATE_END( Statement, node );
-}
-
-//--------------------------------------------------------------------------
-// BranchStmt
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( BranchStmt * node ) {
-	VISIT_START( node );
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const BranchStmt * node ) {
-	VISIT_START( node );
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Statement * PassVisitor< pass_type >::mutate( BranchStmt * node ) {
-	MUTATE_START( node );
-	MUTATE_END( Statement, node );
-}
-
-//--------------------------------------------------------------------------
-// ReturnStmt
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( ReturnStmt * node ) {
-	VISIT_START( node );
-
-	visitExpression( node->expr );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const ReturnStmt * node ) {
-	VISIT_START( node );
-
-	visitExpression( node->expr );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Statement * PassVisitor< pass_type >::mutate( ReturnStmt * node ) {
-	MUTATE_START( node );
-
-	node->expr = mutateExpression( node->expr );
-
-	MUTATE_END( Statement, node );
-}
-
-//--------------------------------------------------------------------------
-// ThrowStmt
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( ThrowStmt * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->expr, *this );
-	maybeAccept_impl( node->target, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const ThrowStmt * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->expr, *this );
-	maybeAccept_impl( node->target, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Statement * PassVisitor< pass_type >::mutate( ThrowStmt * node ) {
-	MUTATE_START( node );
-
-	maybeMutate_impl( node->expr, *this );
-	maybeMutate_impl( node->target, *this );
-
-	MUTATE_END( Statement, node );
-}
-
-//--------------------------------------------------------------------------
-// TryStmt
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( TryStmt * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->block       , *this );
-	maybeAccept_impl( node->handlers    , *this );
-	maybeAccept_impl( node->finallyBlock, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const TryStmt * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->block       , *this );
-	maybeAccept_impl( node->handlers    , *this );
-	maybeAccept_impl( node->finallyBlock, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Statement * PassVisitor< pass_type >::mutate( TryStmt * node ) {
-	MUTATE_START( node );
-
-	maybeMutate_impl( node->block       , *this );
-	maybeMutate_impl( node->handlers    , *this );
-	maybeMutate_impl( node->finallyBlock, *this );
-
-	MUTATE_END( Statement, node );
-}
-
-//--------------------------------------------------------------------------
-// CatchStmt
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( CatchStmt * node ) {
-	VISIT_START( node );
-	{
-		// catch statements introduce a level of scope (for the caught exception)
-		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeAccept_impl( node->decl, *this );
-		node->cond = visitExpression( node->cond );
-		node->body = visitStatement ( node->body );
-	}
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const CatchStmt * node ) {
-	VISIT_START( node );
-	{
-		// catch statements introduce a level of scope (for the caught exception)
-		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeAccept_impl( node->decl, *this );
-		visitExpression ( node->cond );
-		visitStatement  ( node->body );
-	}
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Statement * PassVisitor< pass_type >::mutate( CatchStmt * node ) {
-	MUTATE_START( node );
-	{
-		// catch statements introduce a level of scope (for the caught exception)
-		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeMutate_impl( node->decl, *this );
-		node->cond = mutateExpression( node->cond );
-		node->body = mutateStatement ( node->body );
-	}
-	MUTATE_END( Statement, node );
-}
-
-//--------------------------------------------------------------------------
-// FinallyStmt
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( FinallyStmt * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->block, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const FinallyStmt * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->block, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Statement * PassVisitor< pass_type >::mutate( FinallyStmt * node ) {
-	MUTATE_START( node );
-
-	maybeMutate_impl( node->block, *this );
-
-	MUTATE_END( Statement, node );
-}
-
-//--------------------------------------------------------------------------
-// SuspendStmt
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( SuspendStmt * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->then  , *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const SuspendStmt * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->then  , *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Statement * PassVisitor< pass_type >::mutate( SuspendStmt * node ) {
-	MUTATE_START( node );
-
-	maybeMutate_impl( node->then  , *this );
-
-	MUTATE_END( Statement, node );
-}
-
-//--------------------------------------------------------------------------
-// WaitForStmt
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( WaitForStmt * node ) {
-	VISIT_START( node );
-
-	for( auto & clause : node->clauses ) {
-		maybeAccept_impl( clause.target.function, *this );
-		maybeAccept_impl( clause.target.arguments, *this );
-
-		maybeAccept_impl( clause.statement, *this );
-		maybeAccept_impl( clause.condition, *this );
-	}
-
-	maybeAccept_impl( node->timeout.time, *this );
-	maybeAccept_impl( node->timeout.statement, *this );
-	maybeAccept_impl( node->timeout.condition, *this );
-	maybeAccept_impl( node->orelse.statement, *this );
-	maybeAccept_impl( node->orelse.condition, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const WaitForStmt * node ) {
-	VISIT_START( node );
-
-	for( auto & clause : node->clauses ) {
-		maybeAccept_impl( clause.target.function, *this );
-		maybeAccept_impl( clause.target.arguments, *this );
-
-		maybeAccept_impl( clause.statement, *this );
-		maybeAccept_impl( clause.condition, *this );
-	}
-
-	maybeAccept_impl( node->timeout.time, *this );
-	maybeAccept_impl( node->timeout.statement, *this );
-	maybeAccept_impl( node->timeout.condition, *this );
-	maybeAccept_impl( node->orelse.statement, *this );
-	maybeAccept_impl( node->orelse.condition, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Statement * PassVisitor< pass_type >::mutate( WaitForStmt * node ) {
-	MUTATE_START( node );
-
-	for( auto & clause : node->clauses ) {
-		maybeMutate_impl( clause.target.function, *this );
-		maybeMutate_impl( clause.target.arguments, *this );
-
-		maybeMutate_impl( clause.statement, *this );
-		maybeMutate_impl( clause.condition, *this );
-	}
-
-	maybeMutate_impl( node->timeout.time, *this );
-	maybeMutate_impl( node->timeout.statement, *this );
-	maybeMutate_impl( node->timeout.condition, *this );
-	maybeMutate_impl( node->orelse.statement, *this );
-	maybeMutate_impl( node->orelse.condition, *this );
-
-	MUTATE_END( Statement, node );
-}
-
-
-
-//--------------------------------------------------------------------------
-// WithStmt
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( WithStmt * node ) {
-	VISIT_START( node );
-	maybeAccept_impl( node->exprs, *this );
-	{
-		// catch statements introduce a level of scope (for the caught exception)
-		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		indexerAddWith( node->exprs, node );
-		maybeAccept_impl( node->stmt, *this );
-	}
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const WithStmt * node ) {
-	VISIT_START( node );
-	maybeAccept_impl( node->exprs, *this );
-	{
-		// catch statements introduce a level of scope (for the caught exception)
-		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		indexerAddWith( node->exprs, node );
-		maybeAccept_impl( node->stmt, *this );
-	}
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Declaration * PassVisitor< pass_type >::mutate( WithStmt * node ) {
-	MUTATE_START( node );
-	maybeMutate_impl( node->exprs, *this );
-	{
-		// catch statements introduce a level of scope (for the caught exception)
-		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		indexerAddWith( node->exprs, node );
-		maybeMutate_impl( node->stmt, *this );
-	}
-	MUTATE_END( Declaration, node );
-}
-
-//--------------------------------------------------------------------------
-// NullStmt
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( NullStmt * node ) {
-	VISIT_START( node );
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const NullStmt * node ) {
-	VISIT_START( node );
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-NullStmt * PassVisitor< pass_type >::mutate( NullStmt * node ) {
-	MUTATE_START( node );
-	MUTATE_END( NullStmt, node );
-}
-
-//--------------------------------------------------------------------------
-// DeclStmt
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( DeclStmt * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->decl, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const DeclStmt * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->decl, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Statement * PassVisitor< pass_type >::mutate( DeclStmt * node ) {
-	MUTATE_START( node );
-
-	maybeMutate_impl( node->decl, *this );
-
-	MUTATE_END( Statement, node );
-}
-
-//--------------------------------------------------------------------------
-// ImplicitCtorDtorStmt
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( ImplicitCtorDtorStmt * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->callStmt, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const ImplicitCtorDtorStmt * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->callStmt, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Statement * PassVisitor< pass_type >::mutate( ImplicitCtorDtorStmt * node ) {
-	MUTATE_START( node );
-
-	maybeMutate_impl( node->callStmt, *this );
-
-	MUTATE_END( Statement, node );
-}
-
-//--------------------------------------------------------------------------
-// MutexStmt
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( MutexStmt * node ) {
-	VISIT_START( node );
-	// mutex statements introduce a level of scope (for the initialization)
-	maybeAccept_impl( node->mutexObjs, *this );
-	{
-		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		node->stmt = visitStatement( node->stmt );
-	}
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const MutexStmt * node ) {
-	VISIT_START( node );
-	maybeAccept_impl( node->mutexObjs, *this );
-	{
-		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		visitStatement( node->stmt );
-	}
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Statement * PassVisitor< pass_type >::mutate( MutexStmt * node ) {
-	MUTATE_START( node );
-	maybeMutate_impl( node->mutexObjs, *this );
-	{
-		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		node->stmt = mutateStatement( node->stmt );
-	}
-	MUTATE_END( Statement, node );
-}
-
-//--------------------------------------------------------------------------
-// ApplicationExpr
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( ApplicationExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result  , *this );
-	maybeAccept_impl   ( node->function, *this );
-	maybeAccept_impl   ( node->args    , *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const ApplicationExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result  , *this );
-	maybeAccept_impl   ( node->function, *this );
-	maybeAccept_impl   ( node->args    , *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Expression * PassVisitor< pass_type >::mutate( ApplicationExpr * node ) {
-	MUTATE_START( node );
-
-	indexerScopedMutate( node->env     , *this );
-	indexerScopedMutate( node->result  , *this );
-	maybeMutate_impl   ( node->function, *this );
-	maybeMutate_impl   ( node->args    , *this );
-
-	MUTATE_END( Expression, node );
-}
-
-//--------------------------------------------------------------------------
-// UntypedExpr
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( UntypedExpr * node ) {
-	VISIT_START( node );
-
-	// maybeAccept_impl( node->get_env(), *this );
-	indexerScopedAccept( node->result, *this );
-
-	for ( auto expr : node->args ) {
-		visitExpression( expr );
-	}
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const UntypedExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-
-	for ( auto expr : node->args ) {
-		visitExpression( expr );
-	}
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Expression * PassVisitor< pass_type >::mutate( UntypedExpr * node ) {
-	MUTATE_START( node );
-
-	indexerScopedMutate( node->env   , *this );
-	indexerScopedMutate( node->result, *this );
-
-	for ( auto& expr : node->args ) {
-		expr = mutateExpression( expr );
-	}
-
-	MUTATE_END( Expression, node );
-}
-
-//--------------------------------------------------------------------------
-// NameExpr
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( NameExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const NameExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Expression * PassVisitor< pass_type >::mutate( NameExpr * node ) {
-	MUTATE_START( node );
-
-	indexerScopedMutate( node->env   , *this );
-	indexerScopedMutate( node->result, *this );
-
-	MUTATE_END( Expression, node );
-}
-
-//--------------------------------------------------------------------------
-// QualifiedNameExpr
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( QualifiedNameExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl( node->type_decl, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const QualifiedNameExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl( node->type_decl, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Expression * PassVisitor< pass_type >::mutate( QualifiedNameExpr * node ) {
-	MUTATE_START( node );
-
-    indexerScopedMutate( node->env   , *this );
-    indexerScopedMutate( node->result, *this );
-	maybeMutate_impl( node->type_decl, *this );
-
-	MUTATE_END( Expression, node );
-}
-
-//--------------------------------------------------------------------------
-// CastExpr
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( CastExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl   ( node->arg   , *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const CastExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl   ( node->arg   , *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Expression * PassVisitor< pass_type >::mutate( CastExpr * node ) {
-	MUTATE_START( node );
-
-	indexerScopedMutate( node->env   , *this );
-	indexerScopedMutate( node->result, *this );
-	maybeMutate_impl   ( node->arg   , *this );
-
-	MUTATE_END( Expression, node );
-}
-
-//--------------------------------------------------------------------------
-// KeywordCastExpr
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( KeywordCastExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl        ( node->arg   , *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const KeywordCastExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl   ( node->arg   , *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Expression * PassVisitor< pass_type >::mutate( KeywordCastExpr * node ) {
-	MUTATE_START( node );
-
-	indexerScopedMutate( node->env   , *this );
-	indexerScopedMutate( node->result, *this );
-	maybeMutate_impl   ( node->arg   , *this );
-
-	MUTATE_END( Expression, node );
-}
-
-//--------------------------------------------------------------------------
-// VirtualCastExpr
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( VirtualCastExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl   ( node->arg, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const VirtualCastExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl   ( node->arg, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Expression * PassVisitor< pass_type >::mutate( VirtualCastExpr * node ) {
-	MUTATE_START( node );
-
-	indexerScopedMutate( node->env   , *this );
-	indexerScopedMutate( node->result, *this );
-	maybeMutate_impl   ( node->arg   , *this );
-
-	MUTATE_END( Expression, node );
-}
-
-//--------------------------------------------------------------------------
-// AddressExpr
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( AddressExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl   ( node->arg   , *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const AddressExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl   ( node->arg   , *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Expression * PassVisitor< pass_type >::mutate( AddressExpr * node ) {
-	MUTATE_START( node );
-
-	indexerScopedMutate( node->env   , *this );
-	indexerScopedMutate( node->result, *this );
-	maybeMutate_impl   ( node->arg   , *this );
-
-	MUTATE_END( Expression, node );
-}
-
-//--------------------------------------------------------------------------
-// LabelAddressExpr
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( LabelAddressExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const LabelAddressExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Expression * PassVisitor< pass_type >::mutate( LabelAddressExpr * node ) {
-	MUTATE_START( node );
-
-	indexerScopedMutate( node->env   , *this );
-	indexerScopedMutate( node->result, *this );
-
-	MUTATE_END( Expression, node );
-}
-
-//--------------------------------------------------------------------------
-// UntypedMemberExpr
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( UntypedMemberExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result   , *this );
-	maybeAccept_impl   ( node->aggregate, *this );
-	maybeAccept_impl   ( node->member   , *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const UntypedMemberExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result   , *this );
-	maybeAccept_impl   ( node->aggregate, *this );
-	maybeAccept_impl   ( node->member   , *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Expression * PassVisitor< pass_type >::mutate( UntypedMemberExpr * node ) {
-	MUTATE_START( node );
-
-	indexerScopedMutate( node->env      , *this );
-	indexerScopedMutate( node->result   , *this );
-	maybeMutate_impl   ( node->aggregate, *this );
-	maybeMutate_impl   ( node->member   , *this );
-
-	MUTATE_END( Expression, node );
-}
-
-//--------------------------------------------------------------------------
-// MemberExpr
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( MemberExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result   , *this );
-	maybeAccept_impl   ( node->aggregate, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const MemberExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result   , *this );
-	maybeAccept_impl   ( node->aggregate, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Expression * PassVisitor< pass_type >::mutate( MemberExpr * node ) {
-	MUTATE_START( node );
-
-	indexerScopedMutate( node->env      , *this );
-	indexerScopedMutate( node->result   , *this );
-	maybeMutate_impl   ( node->aggregate, *this );
-
-	MUTATE_END( Expression, node );
-}
-
-//--------------------------------------------------------------------------
-// VariableExpr
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( VariableExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const VariableExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Expression * PassVisitor< pass_type >::mutate( VariableExpr * node ) {
-	MUTATE_START( node );
-
-	indexerScopedMutate( node->env   , *this );
-	indexerScopedMutate( node->result, *this );
-
-	MUTATE_END( Expression, node );
-}
-
-//--------------------------------------------------------------------------
-// ConstantExpr
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( ConstantExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result   , *this );
-	maybeAccept_impl   ( &node->constant, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const ConstantExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result   , *this );
-	maybeAccept_impl   ( &node->constant, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Expression * PassVisitor< pass_type >::mutate( ConstantExpr * node ) {
-	MUTATE_START( node );
-
-	indexerScopedMutate( node->env   , *this );
-	indexerScopedMutate( node->result, *this );
-	Constant * ptr = &node->constant;
-	maybeMutate_impl( ptr, *this );
-	node->constant = *ptr;
-
-	MUTATE_END( Expression, node );
-}
-
-//--------------------------------------------------------------------------
-// SizeofExpr
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( SizeofExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-	if ( node->get_isType() ) {
-		maybeAccept_impl( node->type, *this );
-	} else {
-		maybeAccept_impl( node->expr, *this );
-	}
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const SizeofExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-	if ( node->get_isType() ) {
-		maybeAccept_impl( node->type, *this );
-	} else {
-		maybeAccept_impl( node->expr, *this );
-	}
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Expression * PassVisitor< pass_type >::mutate( SizeofExpr * node ) {
-	MUTATE_START( node );
-
-	indexerScopedMutate( node->env   , *this );
-	indexerScopedMutate( node->result, *this );
-	if ( node->get_isType() ) {
-		maybeMutate_impl( node->type, *this );
-	} else {
-		maybeMutate_impl( node->expr, *this );
-	}
-
-	MUTATE_END( Expression, node );
-}
-
-//--------------------------------------------------------------------------
-// AlignofExpr
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( AlignofExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-	if ( node->get_isType() ) {
-		maybeAccept_impl( node->type, *this );
-	} else {
-		maybeAccept_impl( node->expr, *this );
-	}
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const AlignofExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-	if ( node->get_isType() ) {
-		maybeAccept_impl( node->type, *this );
-	} else {
-		maybeAccept_impl( node->expr, *this );
-	}
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Expression * PassVisitor< pass_type >::mutate( AlignofExpr * node ) {
-	MUTATE_START( node );
-
-	indexerScopedMutate( node->env   , *this );
-	indexerScopedMutate( node->result, *this );
-	if ( node->get_isType() ) {
-		maybeMutate_impl( node->type, *this );
-	} else {
-		maybeMutate_impl( node->expr, *this );
-	}
-
-	MUTATE_END( Expression, node );
-}
-
-//--------------------------------------------------------------------------
-// UntypedOffsetofExpr
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( UntypedOffsetofExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl   ( node->type  , *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const UntypedOffsetofExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl   ( node->type  , *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Expression * PassVisitor< pass_type >::mutate( UntypedOffsetofExpr * node ) {
-	MUTATE_START( node );
-
-	indexerScopedMutate( node->env   , *this );
-	indexerScopedMutate( node->result, *this );
-	maybeMutate_impl   ( node->type  , *this );
-
-	MUTATE_END( Expression, node );
-}
-
-//--------------------------------------------------------------------------
-// OffsetofExpr
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( OffsetofExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl   ( node->type  , *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const OffsetofExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl   ( node->type  , *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Expression * PassVisitor< pass_type >::mutate( OffsetofExpr * node ) {
-	MUTATE_START( node );
-
-	indexerScopedMutate( node->env   , *this );
-	indexerScopedMutate( node->result, *this );
-	maybeMutate_impl   ( node->type  , *this );
-
-	MUTATE_END( Expression, node );
-}
-
-//--------------------------------------------------------------------------
-// OffsetPackExpr
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( OffsetPackExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl   ( node->type  , *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const OffsetPackExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl   ( node->type  , *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Expression * PassVisitor< pass_type >::mutate( OffsetPackExpr * node ) {
-	MUTATE_START( node );
-
-	indexerScopedMutate( node->env   , *this );
-	indexerScopedMutate( node->result, *this );
-	maybeMutate_impl   ( node->type  , *this );
-
-	MUTATE_END( Expression, node );
-}
-
-//--------------------------------------------------------------------------
-// LogicalExpr
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( LogicalExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl   ( node->arg1  , *this );
-	maybeAccept_impl   ( node->arg2  , *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const LogicalExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl   ( node->arg1  , *this );
-	maybeAccept_impl   ( node->arg2  , *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Expression * PassVisitor< pass_type >::mutate( LogicalExpr * node ) {
-	MUTATE_START( node );
-
-	indexerScopedMutate( node->env   , *this );
-	indexerScopedMutate( node->result, *this );
-	maybeMutate_impl   ( node->arg1  , *this );
-	maybeMutate_impl   ( node->arg2  , *this );
-
-	MUTATE_END( Expression, node );
-}
-
-//--------------------------------------------------------------------------
-// ConditionalExpr
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( ConditionalExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl        ( node->arg1  , *this );
-	maybeAccept_impl        ( node->arg2  , *this );
-	maybeAccept_impl        ( node->arg3  , *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const ConditionalExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl   ( node->arg1  , *this );
-	maybeAccept_impl   ( node->arg2  , *this );
-	maybeAccept_impl   ( node->arg3  , *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Expression * PassVisitor< pass_type >::mutate( ConditionalExpr * node ) {
-	MUTATE_START( node );
-
-	indexerScopedMutate( node->env   , *this );
-	indexerScopedMutate( node->result, *this );
-	maybeMutate_impl   ( node->arg1  , *this );
-	maybeMutate_impl   ( node->arg2  , *this );
-	maybeMutate_impl   ( node->arg3  , *this );
-
-	MUTATE_END( Expression, node );
-}
-
-//--------------------------------------------------------------------------
-// CommaExpr
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( CommaExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl   ( node->arg1  , *this );
-	maybeAccept_impl   ( node->arg2  , *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const CommaExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl   ( node->arg1  , *this );
-	maybeAccept_impl   ( node->arg2  , *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Expression * PassVisitor< pass_type >::mutate( CommaExpr * node ) {
-	MUTATE_START( node );
-
-	indexerScopedMutate( node->env   , *this );
-	indexerScopedMutate( node->result, *this );
-	maybeMutate_impl   ( node->arg1  , *this );
-	maybeMutate_impl   ( node->arg2  , *this );
-
-	MUTATE_END( Expression, node );
-}
-
-//--------------------------------------------------------------------------
-// TypeExpr
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( TypeExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl   ( node->type, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const TypeExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl   ( node->type, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Expression * PassVisitor< pass_type >::mutate( TypeExpr * node ) {
-	MUTATE_START( node );
-
-	indexerScopedMutate( node->env   , *this );
-	indexerScopedMutate( node->result, *this );
-	maybeMutate_impl   ( node->type  , *this );
-
-	MUTATE_END( Expression, node );
-}
-
-//--------------------------------------------------------------------------
-// DimensionExpr
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( DimensionExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const DimensionExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Expression * PassVisitor< pass_type >::mutate( DimensionExpr * node ) {
-	MUTATE_START( node );
-
-	indexerScopedMutate( node->env   , *this );
-	indexerScopedMutate( node->result, *this );
-
-	MUTATE_END( Expression, node );
-}
-
-//--------------------------------------------------------------------------
-// AsmExpr
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( AsmExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result    , *this );
-	maybeAccept_impl   ( node->constraint, *this );
-	maybeAccept_impl   ( node->operand   , *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const AsmExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result    , *this );
-	maybeAccept_impl   ( node->constraint, *this );
-	maybeAccept_impl   ( node->operand   , *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Expression * PassVisitor< pass_type >::mutate( AsmExpr * node ) {
-	MUTATE_START( node );
-
-	indexerScopedMutate( node->env       , *this );
-	indexerScopedMutate( node->result    , *this );
-	maybeMutate_impl   ( node->constraint, *this );
-	maybeMutate_impl   ( node->operand   , *this );
-
-	MUTATE_END( Expression, node );
-}
-
-//--------------------------------------------------------------------------
-// ImplicitCopyCtorExpr
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( ImplicitCopyCtorExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result    , *this );
-	maybeAccept_impl   ( node->callExpr  , *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const ImplicitCopyCtorExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result    , *this );
-	maybeAccept_impl   ( node->callExpr  , *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Expression * PassVisitor< pass_type >::mutate( ImplicitCopyCtorExpr * node ) {
-	MUTATE_START( node );
-
-	indexerScopedMutate( node->env       , *this );
-	indexerScopedMutate( node->result    , *this );
-	maybeMutate_impl   ( node->callExpr  , *this );
-
-	MUTATE_END( Expression, node );
-}
-
-//--------------------------------------------------------------------------
-// ConstructorExpr
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( ConstructorExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result  , *this );
-	maybeAccept_impl   ( node->callExpr, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const ConstructorExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result  , *this );
-	maybeAccept_impl   ( node->callExpr, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Expression * PassVisitor< pass_type >::mutate( ConstructorExpr * node ) {
-	MUTATE_START( node );
-
-	indexerScopedMutate( node->env     , *this );
-	indexerScopedMutate( node->result  , *this );
-	maybeMutate_impl   ( node->callExpr, *this );
-
-	MUTATE_END( Expression, node );
-}
-
-//--------------------------------------------------------------------------
-// CompoundLiteralExpr
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( CompoundLiteralExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result     , *this );
-	maybeAccept_impl   ( node->initializer, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const CompoundLiteralExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result     , *this );
-	maybeAccept_impl   ( node->initializer, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Expression * PassVisitor< pass_type >::mutate( CompoundLiteralExpr * node ) {
-	MUTATE_START( node );
-
-	indexerScopedMutate( node->env        , *this );
-	indexerScopedMutate( node->result     , *this );
-	maybeMutate_impl     ( node->initializer, *this );
-
-	MUTATE_END( Expression, node );
-}
-
-//--------------------------------------------------------------------------
-// RangeExpr
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( RangeExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl   ( node->low   , *this );
-	maybeAccept_impl   ( node->high  , *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const RangeExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl   ( node->low   , *this );
-	maybeAccept_impl   ( node->high  , *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Expression * PassVisitor< pass_type >::mutate( RangeExpr * node ) {
-	MUTATE_START( node );
-
-	indexerScopedMutate( node->env   , *this );
-	indexerScopedMutate( node->result, *this );
-	maybeMutate_impl   ( node->low   , *this );
-	maybeMutate_impl   ( node->high  , *this );
-
-	MUTATE_END( Expression, node );
-}
-
-//--------------------------------------------------------------------------
-// UntypedTupleExpr
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( UntypedTupleExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl   ( node->exprs , *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const UntypedTupleExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl   ( node->exprs , *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Expression * PassVisitor< pass_type >::mutate( UntypedTupleExpr * node ) {
-	MUTATE_START( node );
-
-	indexerScopedMutate( node->env   , *this );
-	indexerScopedMutate( node->result, *this );
-	maybeMutate_impl   ( node->exprs , *this );
-
-	MUTATE_END( Expression, node );
-}
-
-//--------------------------------------------------------------------------
-// TupleExpr
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( TupleExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl   ( node->exprs , *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const TupleExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl   ( node->exprs , *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Expression * PassVisitor< pass_type >::mutate( TupleExpr * node ) {
-	MUTATE_START( node );
-
-	indexerScopedMutate( node->env   , *this );
-	indexerScopedMutate( node->result, *this );
-	maybeMutate_impl   ( node->exprs , *this );
-
-	MUTATE_END( Expression, node );
-}
-
-//--------------------------------------------------------------------------
-// TupleIndexExpr
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( TupleIndexExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl   ( node->tuple , *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const TupleIndexExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl   ( node->tuple , *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Expression * PassVisitor< pass_type >::mutate( TupleIndexExpr * node ) {
-	MUTATE_START( node );
-
-	indexerScopedMutate( node->env   , *this );
-	indexerScopedMutate( node->result, *this );
-	maybeMutate_impl   ( node->tuple , *this );
-
-	MUTATE_END( Expression, node );
-}
-
-//--------------------------------------------------------------------------
-// TupleAssignExpr
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( TupleAssignExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result  , *this );
-	maybeAccept_impl   ( node->stmtExpr, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const TupleAssignExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result  , *this );
-	maybeAccept_impl( node->stmtExpr, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Expression * PassVisitor< pass_type >::mutate( TupleAssignExpr * node ) {
-	MUTATE_START( node );
-
-	indexerScopedMutate( node->env     , *this );
-	indexerScopedMutate( node->result  , *this );
-	maybeMutate_impl   ( node->stmtExpr, *this );
-
-	MUTATE_END( Expression, node );
-}
-
-//--------------------------------------------------------------------------
-// StmtExpr
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( StmtExpr * node ) {
-	VISIT_START( node );
-
-	// don't want statements from outer CompoundStmts to be added to this StmtExpr
-	ValueGuardPtr< typename std::remove_pointer<decltype(get_env_ptr())>::type >  oldEnv( get_env_ptr() );
-	ValueGuardPtr< std::list< Statement* > > oldBeforeStmts( get_beforeStmts() );
-	ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () );
-
-	indexerScopedAccept( node->result     , *this );
-	maybeAccept_impl   ( node->statements , *this );
-	maybeAccept_impl   ( node->returnDecls, *this );
-	maybeAccept_impl   ( node->dtors      , *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const StmtExpr * node ) {
-	VISIT_START( node );
-
-	// don't want statements from outer CompoundStmts to be added to this StmtExpr
-	ValueGuardPtr< typename std::remove_pointer<decltype(get_env_ptr())>::type >  oldEnv( get_env_ptr() );
-	ValueGuardPtr< std::list< Statement* > > oldBeforeStmts( get_beforeStmts() );
-	ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () );
-
-	indexerScopedAccept( node->result     , *this );
-	maybeAccept_impl   ( node->statements , *this );
-	maybeAccept_impl   ( node->returnDecls, *this );
-	maybeAccept_impl   ( node->dtors      , *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Expression * PassVisitor< pass_type >::mutate( StmtExpr * node ) {
-	MUTATE_START( node );
-
-	// don't want statements from outer CompoundStmts to be added to this StmtExpr
-	ValueGuardPtr< typename std::remove_pointer<decltype(get_env_ptr())>::type >  oldEnv( get_env_ptr() );
-	ValueGuardPtr< std::list< Statement* > > oldBeforeStmts( get_beforeStmts() );
-	ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () );
-
-	indexerScopedMutate( node->result     , *this );
-	maybeMutate_impl   ( node->statements , *this );
-	maybeMutate_impl   ( node->returnDecls, *this );
-	maybeMutate_impl   ( node->dtors      , *this );
-
-	MUTATE_END( Expression, node );
-}
-
-//--------------------------------------------------------------------------
-// UniqueExpr
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( UniqueExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl   ( node->expr  , *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const UniqueExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl   ( node->expr  , *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Expression * PassVisitor< pass_type >::mutate( UniqueExpr * node ) {
-	MUTATE_START( node );
-
-	indexerScopedMutate( node->env   , *this );
-	indexerScopedMutate( node->result, *this );
-	maybeMutate_impl   ( node->expr  , *this );
-
-	MUTATE_END( Expression, node );
-}
-
-//--------------------------------------------------------------------------
-// UntypedInitExpr
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( UntypedInitExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl   ( node->expr  , *this );
-	// not currently visiting initAlts, but this doesn't matter since this node is only used in the resolver.
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const UntypedInitExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl   ( node->expr  , *this );
-	// not currently visiting initAlts, but this doesn't matter since this node is only used in the resolver.
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Expression * PassVisitor< pass_type >::mutate( UntypedInitExpr * node ) {
-	MUTATE_START( node );
-
-	indexerScopedMutate( node->env   , *this );
-	indexerScopedMutate( node->result, *this );
-	maybeMutate_impl   ( node->expr  , *this );
-	// not currently visiting initAlts, but this doesn't matter since this node is only used in the resolver.
-
-	MUTATE_END( Expression, node );
-}
-
-//--------------------------------------------------------------------------
-// InitExpr
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( InitExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl   ( node->expr  , *this );
-	maybeAccept_impl   ( node->designation, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const InitExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl   ( node->expr  , *this );
-	maybeAccept_impl   ( node->designation, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Expression * PassVisitor< pass_type >::mutate( InitExpr * node ) {
-	MUTATE_START( node );
-
-	indexerScopedMutate( node->env   , *this );
-	indexerScopedMutate( node->result, *this );
-	maybeMutate_impl   ( node->expr  , *this );
-	maybeMutate_impl   ( node->designation, *this );
-
-	MUTATE_END( Expression, node );
-}
-
-//--------------------------------------------------------------------------
-// DeletedExpr
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( DeletedExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl   ( node->expr, *this );
-	// don't visit deleteStmt, because it is a pointer to somewhere else in the tree.
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const DeletedExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl   ( node->expr, *this );
-	// don't visit deleteStmt, because it is a pointer to somewhere else in the tree.
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Expression * PassVisitor< pass_type >::mutate( DeletedExpr * node ) {
-	MUTATE_START( node );
-
-	indexerScopedMutate( node->env, *this );
-	indexerScopedMutate( node->result, *this );
-	maybeMutate_impl( node->expr, *this );
-
-	MUTATE_END( Expression, node );
-}
-
-//--------------------------------------------------------------------------
-// DefaultArgExpr
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( DefaultArgExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl   ( node->expr, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const DefaultArgExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl   ( node->expr, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Expression * PassVisitor< pass_type >::mutate( DefaultArgExpr * node ) {
-	MUTATE_START( node );
-
-	indexerScopedMutate( node->env, *this );
-	indexerScopedMutate( node->result, *this );
-	maybeMutate_impl( node->expr, *this );
-
-	MUTATE_END( Expression, node );
-}
-
-//--------------------------------------------------------------------------
-// GenericExpr
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( GenericExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl( node->control, *this );
-	for ( GenericExpr::Association & assoc : node->associations ) {
-		indexerScopedAccept( assoc.type, *this );
-		maybeAccept_impl( assoc.expr, *this );
-	}
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const GenericExpr * node ) {
-	VISIT_START( node );
-
-	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl( node->control, *this );
-	for ( const GenericExpr::Association & assoc : node->associations ) {
-		indexerScopedAccept( assoc.type, *this );
-		maybeAccept_impl( assoc.expr, *this );
-	}
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Expression * PassVisitor< pass_type >::mutate( GenericExpr * node ) {
-	MUTATE_START( node );
-
-	indexerScopedMutate( node->env, *this );
-	indexerScopedMutate( node->result, *this );
-	maybeMutate_impl( node->control, *this );
-	for ( GenericExpr::Association & assoc : node->associations ) {
-		indexerScopedMutate( assoc.type, *this );
-		maybeMutate_impl( assoc.expr, *this );
-	}
-
-	MUTATE_END( Expression, node );
-}
-
-//--------------------------------------------------------------------------
-// VoidType
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( VoidType * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->forall, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const VoidType * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->forall, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Type * PassVisitor< pass_type >::mutate( VoidType * node ) {
-	MUTATE_START( node );
-
-	maybeMutate_impl( node->forall, *this );
-
-	MUTATE_END( Type, node );
-}
-
-//--------------------------------------------------------------------------
-// BasicType
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( BasicType * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->forall, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const BasicType * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->forall, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Type * PassVisitor< pass_type >::mutate( BasicType * node ) {
-	MUTATE_START( node );
-
-	maybeMutate_impl( node->forall, *this );
-
-	MUTATE_END( Type, node );
-}
-
-//--------------------------------------------------------------------------
-// PointerType
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( PointerType * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->forall, *this );
-	maybeAccept_impl( node->dimension, *this );
-	maybeAccept_impl( node->base, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const PointerType * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->forall, *this );
-	maybeAccept_impl( node->dimension, *this );
-	maybeAccept_impl( node->base, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Type * PassVisitor< pass_type >::mutate( PointerType * node ) {
-	MUTATE_START( node );
-
-	maybeMutate_impl( node->forall, *this );
-	maybeMutate_impl( node->dimension, *this );
-	maybeMutate_impl( node->base, *this );
-
-	MUTATE_END( Type, node );
-}
-
-//--------------------------------------------------------------------------
-// ArrayType
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( ArrayType * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->forall, *this );
-	maybeAccept_impl( node->dimension, *this );
-	maybeAccept_impl( node->base, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const ArrayType * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->forall, *this );
-	maybeAccept_impl( node->dimension, *this );
-	maybeAccept_impl( node->base, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Type * PassVisitor< pass_type >::mutate( ArrayType * node ) {
-	MUTATE_START( node );
-
-	maybeMutate_impl( node->forall, *this );
-	maybeMutate_impl( node->dimension, *this );
-	maybeMutate_impl( node->base, *this );
-
-	MUTATE_END( Type, node );
-}
-
-//--------------------------------------------------------------------------
-// ReferenceType
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( ReferenceType * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->forall, *this );
-	maybeAccept_impl( node->base, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const ReferenceType * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->forall, *this );
-	maybeAccept_impl( node->base, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Type * PassVisitor< pass_type >::mutate( ReferenceType * node ) {
-	MUTATE_START( node );
-
-	maybeMutate_impl( node->forall, *this );
-	maybeMutate_impl( node->base, *this );
-
-	MUTATE_END( Type, node );
-}
-
-//--------------------------------------------------------------------------
-// QualifiedType
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( QualifiedType * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->forall, *this );
-	maybeAccept_impl( node->parent, *this );
-	maybeAccept_impl( node->child, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const QualifiedType * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->forall, *this );
-	maybeAccept_impl( node->parent, *this );
-	maybeAccept_impl( node->child, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Type * PassVisitor< pass_type >::mutate( QualifiedType * node ) {
-	MUTATE_START( node );
-
-	maybeMutate_impl( node->forall, *this );
-	maybeMutate_impl( node->parent, *this );
-	maybeMutate_impl( node->child, *this );
-
-	MUTATE_END( Type, node );
-}
-
-//--------------------------------------------------------------------------
-// FunctionType
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( FunctionType * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->forall, *this );
-	maybeAccept_impl( node->returnVals, *this );
-	maybeAccept_impl( node->parameters, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const FunctionType * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->forall, *this );
-	maybeAccept_impl( node->returnVals, *this );
-	maybeAccept_impl( node->parameters, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Type * PassVisitor< pass_type >::mutate( FunctionType * node ) {
-	MUTATE_START( node );
-
-	maybeMutate_impl( node->forall, *this );
-	maybeMutate_impl( node->returnVals, *this );
-	maybeMutate_impl( node->parameters, *this );
-
-	MUTATE_END( Type, node );
-}
-
-//--------------------------------------------------------------------------
-// StructInstType
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( StructInstType * node ) {
-	VISIT_START( node );
-
-	indexerAddStruct( node->name );
-
-	{
-		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeAccept_impl( node->forall    , *this );
-		maybeAccept_impl( node->parameters, *this );
-	}
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const StructInstType * node ) {
-	VISIT_START( node );
-
-	indexerAddStruct( node->name );
-
-	{
-		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeAccept_impl( node->forall    , *this );
-		maybeAccept_impl( node->parameters, *this );
-	}
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Type * PassVisitor< pass_type >::mutate( StructInstType * node ) {
-	MUTATE_START( node );
-
-	indexerAddStruct( node->name );
-
-	{
-		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeMutate_impl( node->forall    , *this );
-		maybeMutate_impl( node->parameters, *this );
-	}
-
-	MUTATE_END( Type, node );
-}
-
-//--------------------------------------------------------------------------
-// UnionInstType
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( UnionInstType * node ) {
-	VISIT_START( node );
-
-	indexerAddUnion( node->name );
-
-	{
-		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeAccept_impl( node->forall    , *this );
-		maybeAccept_impl( node->parameters, *this );
-	}
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const UnionInstType * node ) {
-	VISIT_START( node );
-
-	indexerAddUnion( node->name );
-
-	{
-		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeAccept_impl( node->forall    , *this );
-		maybeAccept_impl( node->parameters, *this );
-	}
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Type * PassVisitor< pass_type >::mutate( UnionInstType * node ) {
-	MUTATE_START( node );
-
-	indexerAddUnion( node->name );
-
-	{
-		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeMutate_impl( node->forall    , *this );
-		maybeMutate_impl( node->parameters, *this );
-	}
-
-	MUTATE_END( Type, node );
-}
-
-//--------------------------------------------------------------------------
-// EnumInstType
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( EnumInstType * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->forall, *this );
-	maybeAccept_impl( node->parameters, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const EnumInstType * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->forall, *this );
-	maybeAccept_impl( node->parameters, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Type * PassVisitor< pass_type >::mutate( EnumInstType * node ) {
-	MUTATE_START( node );
-
-	maybeMutate_impl( node->forall, *this );
-	maybeMutate_impl( node->parameters, *this );
-
-	MUTATE_END( Type, node );
-}
-
-//--------------------------------------------------------------------------
-// TraitInstType
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( TraitInstType * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->forall    , *this );
-	maybeAccept_impl( node->parameters, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const TraitInstType * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->forall    , *this );
-	maybeAccept_impl( node->parameters, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Type * PassVisitor< pass_type >::mutate( TraitInstType * node ) {
-	MUTATE_START( node );
-
-	maybeMutate_impl( node->forall    , *this );
-	maybeMutate_impl( node->parameters, *this );
-
-	MUTATE_END( Type, node );
-}
-
-//--------------------------------------------------------------------------
-// TypeInstType
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( TypeInstType * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->forall    , *this );
-	maybeAccept_impl( node->parameters, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const TypeInstType * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->forall    , *this );
-	maybeAccept_impl( node->parameters, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Type * PassVisitor< pass_type >::mutate( TypeInstType * node ) {
-	MUTATE_START( node );
-
-	maybeMutate_impl( node->forall    , *this );
-	maybeMutate_impl( node->parameters, *this );
-
-	MUTATE_END( Type, node );
-}
-
-//--------------------------------------------------------------------------
-// TupleType
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( TupleType * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->forall, *this );
-	maybeAccept_impl( node->types, *this );
-	maybeAccept_impl( node->members, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const TupleType * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->forall, *this );
-	maybeAccept_impl( node->types, *this );
-	maybeAccept_impl( node->members, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Type * PassVisitor< pass_type >::mutate( TupleType * node ) {
-	MUTATE_START( node );
-
-	maybeMutate_impl( node->forall, *this );
-	maybeMutate_impl( node->types, *this );
-	maybeMutate_impl( node->members, *this );
-
-	MUTATE_END( Type, node );
-}
-
-//--------------------------------------------------------------------------
-// TypeofType
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( TypeofType * node ) {
-	VISIT_START( node );
-
-	assert( node->expr );
-	maybeAccept_impl( node->expr, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const TypeofType * node ) {
-	VISIT_START( node );
-
-	assert( node->expr );
-	maybeAccept_impl( node->expr, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Type * PassVisitor< pass_type >::mutate( TypeofType * node ) {
-	MUTATE_START( node );
-
-	assert( node->expr );
-	maybeMutate_impl( node->expr, *this );
-
-	MUTATE_END( Type, node );
-}
-
-//--------------------------------------------------------------------------
-// VTableType
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( VTableType * node ) {
-	VISIT_START( node );
-
-	// Forall qualifiers should be on base type, not here
-	// maybeAccept_impl( node->forall, *this );
-	maybeAccept_impl( node->base, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const VTableType * node ) {
-	VISIT_START( node );
-
-	// Forall qualifiers should be on base type, not here
-	// maybeAccept_impl( node->forall, *this );
-	maybeAccept_impl( node->base, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Type * PassVisitor< pass_type >::mutate( VTableType * node ) {
-	MUTATE_START( node );
-
-	// Forall qualifiers should be on base type, not here
-	// maybeMutate_impl( node->forall, *this );
-	maybeMutate_impl( node->base, *this );
-
-	MUTATE_END( Type, node );
-}
-
-//--------------------------------------------------------------------------
-// AttrType
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( AttrType * node ) {
-	VISIT_START( node );
-
-	if ( node->isType ) {
-		assert( node->type );
-		maybeAccept_impl( node->type, *this );
-	} else {
-		assert( node->expr );
-		maybeAccept_impl( node->expr, *this );
-	} // if
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const AttrType * node ) {
-	VISIT_START( node );
-
-	if ( node->isType ) {
-		assert( node->type );
-		maybeAccept_impl( node->type, *this );
-	} else {
-		assert( node->expr );
-		maybeAccept_impl( node->expr, *this );
-	} // if
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Type * PassVisitor< pass_type >::mutate( AttrType * node ) {
-	MUTATE_START( node );
-
-	if ( node->isType ) {
-		assert( node->type );
-		maybeMutate_impl( node->type, *this );
-	} else {
-		assert( node->expr );
-		maybeMutate_impl( node->expr, *this );
-	} // if
-
-	MUTATE_END( Type, node );
-}
-
-//--------------------------------------------------------------------------
-// VarArgsType
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( VarArgsType * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->forall, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const VarArgsType * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->forall, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Type * PassVisitor< pass_type >::mutate( VarArgsType * node ) {
-	MUTATE_START( node );
-
-	maybeMutate_impl( node->forall, *this );
-
-	MUTATE_END( Type, node );
-}
-
-//--------------------------------------------------------------------------
-// ZeroType
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( ZeroType * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->forall, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const ZeroType * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->forall, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Type * PassVisitor< pass_type >::mutate( ZeroType * node ) {
-	MUTATE_START( node );
-
-	maybeMutate_impl( node->forall, *this );
-
-	MUTATE_END( Type, node );
-}
-
-//--------------------------------------------------------------------------
-// OneType
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( OneType * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->forall, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const OneType * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->forall, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Type * PassVisitor< pass_type >::mutate( OneType * node ) {
-	MUTATE_START( node );
-
-	maybeMutate_impl( node->forall, *this );
-
-	MUTATE_END( Type, node );
-}
-
-//--------------------------------------------------------------------------
-// GlobalScopeType
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( GlobalScopeType * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->forall, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const GlobalScopeType * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->forall, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Type * PassVisitor< pass_type >::mutate( GlobalScopeType * node ) {
-	MUTATE_START( node );
-
-	maybeMutate_impl( node->forall, *this );
-
-	MUTATE_END( Type, node );
-}
-
-//--------------------------------------------------------------------------
-// Designation
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( Designation * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->designators, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const Designation * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->designators, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Designation * PassVisitor< pass_type >::mutate( Designation * node ) {
-	MUTATE_START( node );
-
-	maybeMutate_impl( node->designators, *this );
-
-	MUTATE_END( Designation, node );
-}
-
-//--------------------------------------------------------------------------
-// SingleInit
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( SingleInit * node ) {
-	VISIT_START( node );
-
-	visitExpression( node->value );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const SingleInit * node ) {
-	VISIT_START( node );
-
-	visitExpression( node->value );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Initializer * PassVisitor< pass_type >::mutate( SingleInit * node ) {
-	MUTATE_START( node );
-
-	node->value = mutateExpression( node->value );
-
-	MUTATE_END( Initializer, node );
-}
-
-//--------------------------------------------------------------------------
-// ListInit
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( ListInit * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->designations, *this );
-	maybeAccept_impl( node->initializers, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const ListInit * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->designations, *this );
-	maybeAccept_impl( node->initializers, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Initializer * PassVisitor< pass_type >::mutate( ListInit * node ) {
-	MUTATE_START( node );
-
-	maybeMutate_impl( node->designations, *this );
-	maybeMutate_impl( node->initializers, *this );
-
-	MUTATE_END( Initializer, node );
-}
-
-//--------------------------------------------------------------------------
-// ConstructorInit
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( ConstructorInit * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->ctor, *this );
-	maybeAccept_impl( node->dtor, *this );
-	maybeAccept_impl( node->init, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const ConstructorInit * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->ctor, *this );
-	maybeAccept_impl( node->dtor, *this );
-	maybeAccept_impl( node->init, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Initializer * PassVisitor< pass_type >::mutate( ConstructorInit * node ) {
-	MUTATE_START( node );
-
-	maybeMutate_impl( node->ctor, *this );
-	maybeMutate_impl( node->dtor, *this );
-	maybeMutate_impl( node->init, *this );
-
-	MUTATE_END( Initializer, node );
-}
-
-//--------------------------------------------------------------------------
-// Constant
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( Constant * node ) {
-	VISIT_START( node );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const Constant * node ) {
-	VISIT_START( node );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Constant * PassVisitor< pass_type >::mutate( Constant * node  )  {
-	MUTATE_START( node );
-
-	MUTATE_END( Constant, node );
-}
-
-//--------------------------------------------------------------------------
-// Attribute
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( Attribute * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->parameters, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const Attribute * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->parameters, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Attribute * PassVisitor< pass_type >::mutate( Attribute * node  )  {
-	MUTATE_START( node );
-
-	maybeMutate_impl( node->parameters, *this );
-
-	MUTATE_END( Attribute, node );
-}
-
-//--------------------------------------------------------------------------
-// TypeSubstitution
-template< typename pass_type >
-TypeSubstitution * PassVisitor< pass_type >::mutate( TypeSubstitution * node ) {
-	MUTATE_START( node );
-
-	for ( auto & p : node->typeEnv ) {
-		indexerScopedMutate( p.second, *this );
-	}
-	for ( auto & p : node->varEnv ) {
-		indexerScopedMutate( p.second, *this );
-	}
-
-	MUTATE_END( TypeSubstitution, node );
-}
-
-#undef VISIT_START
-#undef VISIT_END
-
-#undef MUTATE_START
-#undef MUTATE_END
Index: src/Common/PassVisitor.proto.h
===================================================================
--- src/Common/PassVisitor.proto.h	(revision 790d83558fed5c46c4c9acfac1cbfe1d8cccbd1a)
+++ 	(revision )
@@ -1,280 +1,0 @@
-#pragma once
-// IWYU pragma: private, include "PassVisitor.h"
-
-template<typename pass_type>
-class PassVisitor;
-
-typedef std::function<void( void * )> cleanup_func_t;
-typedef std::function< void( cleanup_func_t, void * ) > at_cleanup_t;
-
-class guard_value_impl {
-public:
-	guard_value_impl( at_cleanup_t * at_cleanup ) {
-		if( at_cleanup ) {
-			*at_cleanup = [this]( cleanup_func_t && func, void* val ) {
-				push( std::move( func ), val );
-			};
-		}
-	}
-
-	~guard_value_impl() {
-		while( !cleanups.empty() ) {
-			auto& cleanup = cleanups.top();
-			cleanup.func( cleanup.val );
-			cleanups.pop();
-		}
-	}
-
-	void push( cleanup_func_t && func, void* val ) {
-		cleanups.emplace( std::move(func), val );
-	}
-
-private:
-	struct cleanup_t {
-		cleanup_func_t func;
-		void * val;
-
-		cleanup_t( cleanup_func_t&& func, void * val ) : func(func), val(val) {}
-	};
-
-	std::stack< cleanup_t, std::vector< cleanup_t > > cleanups;
-};
-
-class bool_ref {
-public:
-	bool_ref() = default;
-	~bool_ref() = default;
-
-	operator bool() { return m_ref ? *m_ref : true; }
-	bool operator=( bool val ) { assert(m_ref); return *m_ref = val; }
-
-private:
-
-	friend class ChildrenGuard;
-
-	bool * set( bool * val ) {
-		bool * prev = m_ref;
-		m_ref = val;
-		return prev;
-	}
-
-	bool * m_ref = nullptr;
-};
-
-class ChildrenGuard {
-public:
-
-	ChildrenGuard( bool_ref * ref )
-		: m_val ( true )
-		, m_prev( ref ? ref->set( &m_val ) : nullptr )
-		, m_ref ( ref )
-	{}
-
-	~ChildrenGuard() {
-		if( m_ref ) {
-			m_ref->set( m_prev );
-		}
-	}
-
-	operator bool() { return m_val; }
-
-private:
-	bool       m_val;
-	bool     * m_prev;
-	bool_ref * m_ref;
-};
-
-//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-// Deep magic (a.k.a template meta programming) to make the templated visitor work
-// Basically the goal is to make 2 previsit_impl
-// 1 - Use when a pass implements a valid previsit. This uses overloading which means the any overload of
-//     'pass.previsit( node )' that compiles will be used for that node for that type
-//     This requires that this option only compile for passes that actually define an appropriate visit.
-//     SFINAE will make sure the compilation errors in this function don't halt the build.
-//     See http://en.cppreference.com/w/cpp/language/sfinae for details on SFINAE
-// 2 - Since the first implementation might not be specilizable, the second implementation exists and does nothing.
-//     This is needed only to eliminate the need for passes to specify any kind of handlers.
-//     The second implementation only works because it has a lower priority. This is due to the bogus last parameter.
-//     The second implementation takes a long while the first takes an int. Since the caller always passes an literal 0
-//     the first implementation takes priority in regards to overloading.
-// Mutator functions work along the same principal
-//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-// Visit
-template<typename pass_type, typename node_type>
-static inline auto previsit_impl( pass_type& pass, node_type * node, __attribute__((unused)) int unused ) -> decltype( pass.previsit( node ), void() ) {
-	pass.previsit( node );
-}
-
-template<typename pass_type, typename node_type>
-static inline void previsit_impl( __attribute__((unused)) pass_type& pass, __attribute__((unused)) node_type * node, __attribute__((unused)) long unused ) {}
-
-
-template<typename pass_type, typename node_type>
-static inline auto postvisit_impl( pass_type& pass, node_type * node, __attribute__((unused)) int unused ) -> decltype( pass.postvisit( node ), void() ) {
-	pass.postvisit( node );
-}
-
-template<typename pass_type, typename node_type>
-static inline void postvisit_impl( __attribute__((unused)) pass_type& pass, __attribute__((unused)) node_type * node, __attribute__((unused)) long unused ) {}
-
-template<typename pass_type, typename node_type>
-static inline auto previsit_impl( pass_type& pass, const node_type * node, __attribute__((unused)) int unused ) -> decltype( pass.previsit( node ), void() ) {
-	pass.previsit( node );
-}
-
-template<typename pass_type, typename node_type>
-static inline void previsit_impl( __attribute__((unused)) pass_type& pass, __attribute__((unused)) const node_type * node, __attribute__((unused)) long unused ) {}
-
-
-template<typename pass_type, typename node_type>
-static inline auto postvisit_impl( pass_type& pass, const node_type * node, __attribute__((unused)) int unused ) -> decltype( pass.postvisit( node ), void() ) {
-	pass.postvisit( node );
-}
-
-template<typename pass_type, typename node_type>
-static inline void postvisit_impl( __attribute__((unused)) pass_type& pass, __attribute__((unused)) const node_type * node, __attribute__((unused)) long unused ) {}
-
-//---------------------------------------------------------
-// Mutate
-template<typename pass_type, typename node_type>
-static inline auto premutate_impl( pass_type& pass, node_type * node, __attribute__((unused)) int unused ) -> decltype( pass.premutate( node ), void() ) {
-	return pass.premutate( node );
-}
-
-template<typename pass_type, typename node_type>
-static inline void premutate_impl( __attribute__((unused)) pass_type& pass, __attribute__((unused)) node_type * node, __attribute__((unused)) long unused ) {}
-
-
-template<typename return_type, typename pass_type, typename node_type>
-static inline auto postmutate_impl( pass_type& pass, node_type * node, __attribute__((unused)) int unused ) -> decltype( pass.postmutate( node ) ) {
-	return pass.postmutate( node );
-}
-
-template<typename return_type, typename pass_type, typename node_type>
-static inline return_type postmutate_impl( __attribute__((unused)) pass_type& pass, node_type * node, __attribute__((unused)) long unused ) { return node; }
-
-//---------------------------------------------------------
-// Begin/End scope
-template<typename pass_type>
-static inline auto begin_scope_impl( pass_type& pass, __attribute__((unused)) int unused ) -> decltype( pass.beginScope(), void() ) {
-	pass.beginScope();
-}
-
-template<typename pass_type>
-static inline void begin_scope_impl( __attribute__((unused)) pass_type& pass, __attribute__((unused)) long unused ) {}
-
-
-template<typename pass_type>
-static inline auto end_scope_impl( pass_type& pass, __attribute__((unused)) int unused ) -> decltype( pass.endScope(), void() ) {
-	pass.endScope();
-}
-
-template<typename pass_type>
-static inline void end_scope_impl( __attribute__((unused)) pass_type& pass, __attribute__((unused)) long unused ) {}
-
-//---------------------------------------------------------
-// Fields
-#define FIELD_PTR( type, name )                                                                                                        \
-template<typename pass_type>                                                                                                           \
-static inline auto name##_impl( pass_type& pass, __attribute__((unused)) int unused ) -> decltype( &pass.name ) { return &pass.name; } \
-                                                                                                                                       \
-template<typename pass_type>                                                                                                           \
-static inline type * name##_impl( __attribute__((unused)) pass_type& pass, __attribute__((unused)) long unused ) { return nullptr;}    \
-
-FIELD_PTR( const TypeSubstitution *, env )
-FIELD_PTR( std::list< Statement* >, stmtsToAddBefore )
-FIELD_PTR( std::list< Statement* >, stmtsToAddAfter  )
-FIELD_PTR( std::list< Declaration* >, declsToAddBefore )
-FIELD_PTR( std::list< Declaration* >, declsToAddAfter  )
-FIELD_PTR( bool_ref, visit_children )
-FIELD_PTR( at_cleanup_t, at_cleanup )
-FIELD_PTR( PassVisitor<pass_type> * const, visitor )
-
-#undef FIELD_PTR
-
-//---------------------------------------------------------
-// Indexer
-template<typename pass_type>
-static inline auto indexer_impl_enterScope( pass_type & pass, int ) -> decltype( pass.indexer.enterScope(), void() ) {
-	pass.indexer.enterScope();
-}
-
-template<typename pass_type>
-static inline auto indexer_impl_enterScope( pass_type &, long ) {}
-
-template<typename pass_type>
-static inline auto indexer_impl_leaveScope( pass_type & pass, int ) -> decltype( pass.indexer.leaveScope(), void() ) {
-	pass.indexer.leaveScope();
-}
-
-template<typename pass_type>
-static inline auto indexer_impl_leaveScope( pass_type &, long ) {}
-
-
-#define INDEXER_FUNC1( func, type )                                                                                             \
-template<typename pass_type>                                                                                                   \
-static inline auto indexer_impl_##func ( pass_type & pass, int, type arg ) -> decltype( pass.indexer.func( arg ), void() ) {   \
-	pass.indexer.func( arg );                                                                                                \
-}                                                                                                                              \
-template<typename pass_type>                                                                                                   \
-static inline void indexer_impl_##func ( pass_type &, long, type ) { }
-
-#define INDEXER_FUNC2( func, type1, type2 )                                                                                             \
-template<typename pass_type>                                                                                                   \
-static inline auto indexer_impl_##func ( pass_type & pass, int, type1 arg1, type2 arg2 ) -> decltype( pass.indexer.func( arg1, arg2 ), void() ) {   \
-	pass.indexer.func( arg1, arg2 );                                                                                                \
-}                                                                                                                              \
-template<typename pass_type>                                                                                                   \
-static inline void indexer_impl_##func ( pass_type &, long, type1, type2 ) { }
-
-
-INDEXER_FUNC1( addId     , const DeclarationWithType *       );
-INDEXER_FUNC1( addType   , const NamedTypeDecl *             );
-INDEXER_FUNC1( addStruct , const StructDecl *                );
-INDEXER_FUNC1( addEnum   , const EnumDecl *                  );
-INDEXER_FUNC1( addUnion  , const UnionDecl *                 );
-INDEXER_FUNC1( addTrait  , const TraitDecl *                 );
-INDEXER_FUNC2( addWith   , const std::list< Expression * > &, const Declaration * );
-
-#undef INDEXER_FUNC1
-#undef INDEXER_FUNC2
-
-template<typename pass_type>
-static inline auto indexer_impl_addStructFwd( pass_type & pass, int, const StructDecl * decl ) -> decltype( pass.indexer.addStruct( decl ), void() ) {
-	StructDecl * fwd = new StructDecl( decl->name );
-	cloneAll( decl->parameters, fwd->parameters );
-	pass.indexer.addStruct( fwd );
-}
-
-template<typename pass_type>
-static inline auto indexer_impl_addStructFwd( pass_type &, long, const StructDecl * ) {}
-
-template<typename pass_type>
-static inline auto indexer_impl_addUnionFwd( pass_type & pass, int, const UnionDecl * decl ) -> decltype( pass.indexer.addUnion( decl ), void() ) {
-	UnionDecl * fwd = new UnionDecl( decl->name );
-	cloneAll( decl->parameters, fwd->parameters );
-	pass.indexer.addUnion( fwd );
-}
-
-template<typename pass_type>
-static inline auto indexer_impl_addUnionFwd( pass_type &, long, const UnionDecl * ) {}
-
-template<typename pass_type>
-static inline auto indexer_impl_addStruct( pass_type & pass, int, const std::string & str ) -> decltype( pass.indexer.addStruct( str ), void() ) {
-	if ( ! pass.indexer.lookupStruct( str ) ) {
-		pass.indexer.addStruct( str );
-	}
-}
-
-template<typename pass_type>
-static inline auto indexer_impl_addStruct( pass_type &, long, const std::string & ) {}
-
-template<typename pass_type>
-static inline auto indexer_impl_addUnion( pass_type & pass, int, const std::string & str ) -> decltype( pass.indexer.addUnion( str ), void() ) {
-	if ( ! pass.indexer.lookupUnion( str ) ) {
-		pass.indexer.addUnion( str );
-	}
-}
-
-template<typename pass_type>
-static inline auto indexer_impl_addUnion( pass_type &, long, const std::string & ) {}
Index: src/Common/module.mk
===================================================================
--- src/Common/module.mk	(revision 790d83558fed5c46c4c9acfac1cbfe1d8cccbd1a)
+++ src/Common/module.mk	(revision 2da12ae2df22a8ab193e99e082199971510f6663)
@@ -31,8 +31,4 @@
 	Common/Indenter.cc \
 	Common/Iterate.hpp \
-	Common/PassVisitor.cc \
-	Common/PassVisitor.h \
-	Common/PassVisitor.impl.h \
-	Common/PassVisitor.proto.h \
 	Common/PersistentMap.h \
 	Common/ResolvProtoDump.hpp \
