Index: src/ResolvExpr/CommonType.cc
===================================================================
--- src/ResolvExpr/CommonType.cc	(revision ecd4923b6c6691baf4df6c29ef6d99081a28b0d1)
+++ src/ResolvExpr/CommonType.cc	(revision 2a84d06d1deb50fd2637ab8e384392089bda2faa)
@@ -18,4 +18,5 @@
 #include <utility>                       // for pair
 
+#include "Common/PassVisitor.h"
 #include "ResolvExpr/TypeEnvironment.h"  // for OpenVarSet, AssertionSet
 #include "SymTab/Indexer.h"              // for Indexer
@@ -29,25 +30,27 @@
 
 namespace ResolvExpr {
-	class CommonType : public Visitor {
-	  public:
+	struct CommonType : public WithShortCircuiting {
 		CommonType( Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars );
 		Type *get_result() const { return result; }
+
+		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 );
+
 	  private:
-		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 );
-
 		template< typename Pointer > void getCommonWithVoidPointer( Pointer* voidPointer, Pointer* otherPointer );
 		template< typename RefType > void handleRefType( RefType *inst, Type *other );
@@ -80,5 +83,5 @@
 
 	Type *commonType( Type *type1, Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars ) {
-		CommonType visitor( type2, widenFirst, widenSecond, indexer, env, openVars );
+		PassVisitor<CommonType> visitor( type2, widenFirst, widenSecond, indexer, env, openVars );
 
 		int depth1 = type1->referenceDepth();
@@ -116,5 +119,5 @@
 
 		type1->accept( visitor );
-		Type *result = visitor.get_result();
+		Type *result = visitor.pass.get_result();
 		if ( ! result ) {
 			// this appears to be handling for opaque type declarations
@@ -188,7 +191,7 @@
 	}
 
-	void CommonType::visit( VoidType * ) {}
-
-	void CommonType::visit( BasicType *basicType ) {
+	void CommonType::postvisit( VoidType * ) {}
+
+	void CommonType::postvisit( BasicType *basicType ) {
 		if ( BasicType *otherBasic = dynamic_cast< BasicType* >( type2 ) ) {
 			BasicType::Kind newType = combinedType[ basicType->get_kind() ][ otherBasic->get_kind() ];
@@ -219,5 +222,5 @@
 	}
 
-	void CommonType::visit( PointerType *pointerType ) {
+	void CommonType::postvisit( PointerType *pointerType ) {
 		if ( PointerType *otherPointer = dynamic_cast< PointerType* >( type2 ) ) {
 			// std::cerr << "commonType: two pointers: " << pointerType << " / " << otherPointer << std::endl;
@@ -254,7 +257,7 @@
 	}
 
-	void CommonType::visit( ArrayType * ) {}
-
-	void CommonType::visit( ReferenceType *refType ) {
+	void CommonType::postvisit( ArrayType * ) {}
+
+	void CommonType::postvisit( ReferenceType *refType ) {
 		if ( ReferenceType *otherRef = dynamic_cast< ReferenceType* >( type2 ) ) {
 			// std::cerr << "commonType: both references: " << refType << " / " << otherRef << std::endl;
@@ -291,21 +294,19 @@
 	}
 
-	void CommonType::visit( FunctionType * ) {}
-	void CommonType::visit( StructInstType * ) {}
-	void CommonType::visit( UnionInstType * ) {}
-
-	void CommonType::visit( EnumInstType *enumInstType ) {
+	void CommonType::postvisit( FunctionType * ) {}
+	void CommonType::postvisit( StructInstType * ) {}
+	void CommonType::postvisit( UnionInstType * ) {}
+
+	void CommonType::postvisit( EnumInstType *enumInstType ) {
 		if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< ZeroType* >( type2 ) || dynamic_cast< OneType* >( type2 ) ) {
 			// reuse BasicType, EnumInstType code by swapping type2 with enumInstType
-			ValueGuard< Type * > temp( type2 );
-			type2 = enumInstType;
-			temp.old->accept( *this );
-		} // if
-	}
-
-	void CommonType::visit( TraitInstType * ) {
-	}
-
-	void CommonType::visit( TypeInstType *inst ) {
+			result = commonType( type2, enumInstType, widenSecond, widenFirst, indexer, env, openVars );
+		} // if
+	}
+
+	void CommonType::postvisit( TraitInstType * ) {
+	}
+
+	void CommonType::postvisit( TypeInstType *inst ) {
 		if ( widenFirst ) {
 			NamedTypeDecl *nt = indexer.lookupType( inst->get_name() );
@@ -329,8 +330,8 @@
 	}
 
-	void CommonType::visit( TupleType * ) {}
-	void CommonType::visit( VarArgsType * ) {}
-
-	void CommonType::visit( ZeroType *zeroType ) {
+	void CommonType::postvisit( TupleType * ) {}
+	void CommonType::postvisit( VarArgsType * ) {}
+
+	void CommonType::postvisit( ZeroType *zeroType ) {
 		if ( widenFirst ) {
 			if ( dynamic_cast< BasicType* >( type2 ) || dynamic_cast< PointerType* >( type2 ) || dynamic_cast< EnumInstType* >( type2 ) ) {
@@ -346,5 +347,5 @@
 	}
 
-	void CommonType::visit( OneType *oneType ) {
+	void CommonType::postvisit( OneType *oneType ) {
 		if ( widenFirst ) {
 			if ( dynamic_cast< BasicType* >( type2 ) || dynamic_cast< EnumInstType* >( type2 ) ) {
