Index: src/ResolvExpr/CastCost.cc
===================================================================
--- src/ResolvExpr/CastCost.cc	(revision 721cd19ff0bf583b48c8ce89d21b2892d6bb485f)
+++ src/ResolvExpr/CastCost.cc	(revision bd0b6b626c4c287f1fed4a7fe7ee5b6de256a01a)
@@ -31,10 +31,12 @@
 
 namespace ResolvExpr {
-	class CastCost : public ConversionCost {
+	struct CastCost : public ConversionCost {
 	  public:
 		CastCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc );
 
-		virtual void visit( BasicType *basicType );
-		virtual void visit( PointerType *pointerType );
+		using ConversionCost::previsit;
+		using ConversionCost::postvisit;
+		void postvisit( BasicType * basicType );
+		void postvisit( PointerType * pointerType );
 	};
 
@@ -78,11 +80,11 @@
 			});
 		} else {
-			CastCost converter( dest, indexer, env, castCost );
+			PassVisitor<CastCost> converter( dest, indexer, env, castCost );
 			src->accept( converter );
-			if ( converter.get_cost() == Cost::infinity ) {
+			if ( converter.pass.get_cost() == Cost::infinity ) {
 				return Cost::infinity;
 			} else {
 				// xxx - why are we adding cost 0 here?
-				return converter.get_cost() + Cost::zero;
+				return converter.pass.get_cost() + Cost::zero;
 			} // if
 		} // if
@@ -93,5 +95,5 @@
 	}
 
-	void CastCost::visit( BasicType *basicType ) {
+	void CastCost::postvisit( BasicType *basicType ) {
 		PointerType *destAsPointer = dynamic_cast< PointerType* >( dest );
 		if ( destAsPointer && basicType->isInteger() ) {
@@ -103,5 +105,5 @@
 	}
 
-	void CastCost::visit( PointerType *pointerType ) {
+	void CastCost::postvisit( PointerType *pointerType ) {
 		if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) {
 			if ( pointerType->get_qualifiers() <= destAsPtr->get_qualifiers() && typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) {
Index: src/ResolvExpr/ConversionCost.cc
===================================================================
--- src/ResolvExpr/ConversionCost.cc	(revision 721cd19ff0bf583b48c8ce89d21b2892d6bb485f)
+++ src/ResolvExpr/ConversionCost.cc	(revision bd0b6b626c4c287f1fed4a7fe7ee5b6de256a01a)
@@ -81,10 +81,10 @@
 			});
 		} else {
-			ConversionCost converter( dest, indexer, env, conversionCost );
+			PassVisitor<ConversionCost> converter( dest, indexer, env, conversionCost );
 			src->accept( converter );
-			if ( converter.get_cost() == Cost::infinity ) {
+			if ( converter.pass.get_cost() == Cost::infinity ) {
 				return Cost::infinity;
 			} else {
-				return converter.get_cost() + Cost::zero;
+				return converter.pass.get_cost() + Cost::zero;
 			} // if
 		} // if
@@ -130,7 +130,7 @@
 			} else {
 				PRINT( std::cerr << "reference to rvalue conversion" << std::endl; )
-				ConversionCost converter( dest, indexer, env, conversionCost );
+				PassVisitor<ConversionCost> converter( dest, indexer, env, conversionCost );
 				src->accept( converter );
-				return converter.get_cost();
+				return converter.pass.get_cost();
 			} // if
 		} else {
@@ -257,9 +257,9 @@
 	};
 
-	void ConversionCost::visit( VoidType * ) {
+	void ConversionCost::postvisit( VoidType * ) {
 		cost = Cost::infinity;
 	}
 
-	void ConversionCost::visit(BasicType *basicType) {
+	void ConversionCost::postvisit(BasicType *basicType) {
 		if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
 			int tableResult = costMatrix[ basicType->get_kind() ][ destAsBasic->get_kind() ];
@@ -278,5 +278,5 @@
 	}
 
-	void ConversionCost::visit( PointerType * pointerType ) {
+	void ConversionCost::postvisit( PointerType * pointerType ) {
 		if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) {
 			PRINT( std::cerr << pointerType << " ===> " << destAsPtr << std::endl; )
@@ -312,7 +312,7 @@
 	}
 
-	void ConversionCost::visit( ArrayType * ) {}
-
-	void ConversionCost::visit( ReferenceType * refType ) {
+	void ConversionCost::postvisit( ArrayType * ) {}
+
+	void ConversionCost::postvisit( ReferenceType * refType ) {
 		// Note: dest can never be a reference, since it would have been caught in an earlier check
 		assert( ! dynamic_cast< ReferenceType * >( dest ) );
@@ -331,7 +331,7 @@
 	}
 
-	void ConversionCost::visit( FunctionType * ) {}
-
-	void ConversionCost::visit( StructInstType * inst ) {
+	void ConversionCost::postvisit( FunctionType * ) {}
+
+	void ConversionCost::postvisit( StructInstType * inst ) {
 		if ( StructInstType *destAsInst = dynamic_cast< StructInstType* >( dest ) ) {
 			if ( inst->name == destAsInst->name ) {
@@ -341,5 +341,5 @@
 	}
 
-	void ConversionCost::visit( UnionInstType * inst ) {
+	void ConversionCost::postvisit( UnionInstType * inst ) {
 		if ( UnionInstType *destAsInst = dynamic_cast< UnionInstType* >( dest ) ) {
 			if ( inst->name == destAsInst->name ) {
@@ -349,5 +349,5 @@
 	}
 
-	void ConversionCost::visit( EnumInstType * ) {
+	void ConversionCost::postvisit( EnumInstType * ) {
 		static Type::Qualifiers q;
 		static BasicType integer( q, BasicType::SignedInt );
@@ -358,7 +358,7 @@
 	}
 
-	void ConversionCost::visit( TraitInstType * ) {}
-
-	void ConversionCost::visit( TypeInstType *inst ) {
+	void ConversionCost::postvisit( TraitInstType * ) {}
+
+	void ConversionCost::postvisit( TypeInstType *inst ) {
 		EqvClass eqvClass;
 		NamedTypeDecl *namedType;
@@ -379,5 +379,5 @@
 	}
 
-	void ConversionCost::visit( TupleType * tupleType ) {
+	void ConversionCost::postvisit( TupleType * tupleType ) {
 		Cost c = Cost::zero;
 		if ( TupleType * destAsTuple = dynamic_cast< TupleType * >( dest ) ) {
@@ -399,5 +399,5 @@
 	}
 
-	void ConversionCost::visit( VarArgsType * ) {
+	void ConversionCost::postvisit( VarArgsType * ) {
 		if ( dynamic_cast< VarArgsType* >( dest ) ) {
 			cost = Cost::zero;
@@ -405,5 +405,5 @@
 	}
 
-	void ConversionCost::visit( ZeroType * ) {
+	void ConversionCost::postvisit( ZeroType * ) {
 		if ( dynamic_cast< ZeroType * >( dest ) ) {
 			cost = Cost::zero;
@@ -422,5 +422,5 @@
 	}
 
-	void ConversionCost::visit( OneType * ) {
+	void ConversionCost::postvisit( OneType * ) {
 		if ( dynamic_cast< OneType * >( dest ) ) {
 			cost = Cost::zero;
Index: src/ResolvExpr/ConversionCost.h
===================================================================
--- src/ResolvExpr/ConversionCost.h	(revision 721cd19ff0bf583b48c8ce89d21b2892d6bb485f)
+++ src/ResolvExpr/ConversionCost.h	(revision bd0b6b626c4c287f1fed4a7fe7ee5b6de256a01a)
@@ -19,4 +19,6 @@
 
 #include "Cost.h"             // for Cost
+
+#include "Common/PassVisitor.h"
 #include "SynTree/Visitor.h"  // for Visitor
 #include "SynTree/SynTree.h"  // for Visitor Nodes
@@ -30,5 +32,5 @@
 
 	typedef std::function<Cost(Type *, Type *, const SymTab::Indexer &, const TypeEnvironment &)> CostFunction;
-	class ConversionCost : public Visitor {
+	struct ConversionCost : public WithShortCircuiting {
 	  public:
 		ConversionCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction );
@@ -36,19 +38,21 @@
 		Cost get_cost() const { return cost; }
 
-		virtual void visit(VoidType *voidType);
-		virtual void visit(BasicType *basicType);
-		virtual void visit(PointerType *pointerType);
-		virtual void visit(ArrayType *arrayType);
-		virtual void visit(ReferenceType *refType);
-		virtual void visit(FunctionType *functionType);
-		virtual void visit(StructInstType *aggregateUseType);
-		virtual void visit(UnionInstType *aggregateUseType);
-		virtual void visit(EnumInstType *aggregateUseType);
-		virtual void visit(TraitInstType *aggregateUseType);
-		virtual void visit(TypeInstType *aggregateUseType);
-		virtual void visit(TupleType *tupleType);
-		virtual void visit(VarArgsType *varArgsType);
-		virtual void visit(ZeroType *zeroType);
-		virtual void visit(OneType *oneType);
+		void previsit( BaseSyntaxNode * ) { visit_children = false; }
+
+		void postvisit( VoidType * voidType );
+		void postvisit( BasicType * basicType );
+		void postvisit( PointerType * pointerType );
+		void postvisit( ArrayType * arrayType );
+		void postvisit( ReferenceType * refType );
+		void postvisit( FunctionType * functionType );
+		void postvisit( StructInstType * aggregateUseType );
+		void postvisit( UnionInstType * aggregateUseType );
+		void postvisit( EnumInstType * aggregateUseType );
+		void postvisit( TraitInstType * aggregateUseType );
+		void postvisit( TypeInstType * aggregateUseType );
+		void postvisit( TupleType * tupleType );
+		void postvisit( VarArgsType * varArgsType );
+		void postvisit( ZeroType * zeroType );
+		void postvisit( OneType * oneType );
 	  protected:
 		Type *dest;
