Index: src/CodeGen/GenType.cc
===================================================================
--- src/CodeGen/GenType.cc	(revision 1619acd5ad23c53dd53ac9d62878d1d11644638c)
+++ src/CodeGen/GenType.cc	(revision 78754d782a2b5ad40158459a92881261efa9c6b2)
@@ -26,24 +26,26 @@
 
 namespace CodeGen {
-	class GenType : public Visitor {
-	  public:
+	struct GenType : public WithVisitorRef<GenType>, public WithShortCircuiting {
 		GenType( const std::string &typeString, bool pretty = false, bool genC = false, bool lineMarks = false );
 		std::string get_typeString() const { return typeString; }
 		void set_typeString( const std::string &newValue ) { typeString = newValue; }
 
-		virtual void visit( FunctionType *funcType );
-		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( StructInstType *structInst );
-		virtual void visit( UnionInstType *unionInst );
-		virtual void visit( EnumInstType *enumInst );
-		virtual void visit( TypeInstType *typeInst );
-		virtual void visit( TupleType * tupleType );
-		virtual void visit( VarArgsType *varArgsType );
-		virtual void visit( ZeroType *zeroType );
-		virtual void visit( OneType *oneType );
+		void previsit( BaseSyntaxNode * );
+		void postvisit( BaseSyntaxNode * );
+
+		void postvisit( FunctionType * funcType );
+		void postvisit( VoidType * voidType );
+		void postvisit( BasicType * basicType );
+		void postvisit( PointerType * pointerType );
+		void postvisit( ArrayType * arrayType );
+		void postvisit( ReferenceType * refType );
+		void postvisit( StructInstType * structInst );
+		void postvisit( UnionInstType * unionInst );
+		void postvisit( EnumInstType * enumInst );
+		void postvisit( TypeInstType * typeInst );
+		void postvisit( TupleType  * tupleType );
+		void postvisit( VarArgsType * varArgsType );
+		void postvisit( ZeroType * zeroType );
+		void postvisit( OneType * oneType );
 
 	  private:
@@ -59,5 +61,5 @@
 
 	std::string genType( Type *type, const std::string &baseString, bool pretty, bool genC , bool lineMarks ) {
-		GenType gt( baseString, pretty, genC, lineMarks );
+		PassVisitor<GenType> gt( baseString, pretty, genC, lineMarks );
 		std::ostringstream os;
 
@@ -68,5 +70,5 @@
 
 		type->accept( gt );
-		return os.str() + gt.get_typeString();
+		return os.str() + gt.pass.get_typeString();
 	}
 
@@ -77,11 +79,24 @@
 	GenType::GenType( const std::string &typeString, bool pretty, bool genC, bool lineMarks ) : typeString( typeString ), pretty( pretty ), genC( genC ), lineMarks( lineMarks ) {}
 
-	void GenType::visit( VoidType *voidType ) {
+	// *** BaseSyntaxNode
+	void GenType::previsit( BaseSyntaxNode * ) {
+		// turn off automatic recursion for all nodes, to allow each visitor to
+		// precisely control the order in which its children are visited.
+		visit_children = false;
+	}
+
+	void GenType::postvisit( BaseSyntaxNode * node ) {
+		std::stringstream ss;
+		node->print( ss );
+		assertf( false, "Unhandled node reached in GenType: %s", ss.str().c_str() );
+	}
+
+	void GenType::postvisit( VoidType * voidType ) {
 		typeString = "void " + typeString;
 		handleQualifiers( voidType );
 	}
 
-	void GenType::visit( BasicType *basicType ) {
-		BasicType::Kind kind = basicType->get_kind();
+	void GenType::postvisit( BasicType * basicType ) {
+		BasicType::Kind kind = basicType->kind;
 		assert( 0 <= kind && kind < BasicType::NUMBER_OF_BASIC_TYPES );
 		typeString = std::string( BasicType::typeNames[kind] ) + " " + typeString;
@@ -89,5 +104,5 @@
 	}
 
-	void GenType::genArray( const Type::Qualifiers &qualifiers, Type *base, Expression *dimension, bool isVarLen, bool isStatic ) {
+	void GenType::genArray( const Type::Qualifiers & qualifiers, Type * base, Expression *dimension, bool isVarLen, bool isStatic ) {
 		std::ostringstream os;
 		if ( typeString != "" ) {
@@ -126,11 +141,11 @@
 		typeString = os.str();
 
-		base->accept( *this );
-	}
-
-	void GenType::visit( PointerType *pointerType ) {
-		assert( pointerType->get_base() != 0);
-		if ( pointerType->get_isStatic() || pointerType->get_isVarLen() || pointerType->get_dimension() ) {
-			genArray( pointerType->get_qualifiers(), pointerType->get_base(), pointerType->get_dimension(), pointerType->get_isVarLen(), pointerType->get_isStatic() );
+		base->accept( *visitor );
+	}
+
+	void GenType::postvisit( PointerType * pointerType ) {
+		assert( pointerType->base != 0);
+		if ( pointerType->get_isStatic() || pointerType->get_isVarLen() || pointerType->dimension ) {
+			genArray( pointerType->get_qualifiers(), pointerType->base, pointerType->dimension, pointerType->get_isVarLen(), pointerType->get_isStatic() );
 		} else {
 			handleQualifiers( pointerType );
@@ -140,21 +155,21 @@
 				typeString = "*" + typeString;
 			} // if
-			pointerType->get_base()->accept( *this );
-		} // if
-	}
-
-	void GenType::visit( ArrayType *arrayType ) {
-		genArray( arrayType->get_qualifiers(), arrayType->get_base(), arrayType->get_dimension(), arrayType->get_isVarLen(), arrayType->get_isStatic() );
-	}
-
-	void GenType::visit( ReferenceType *refType ) {
-		assert( refType->get_base() != 0);
+			pointerType->base->accept( *visitor );
+		} // if
+	}
+
+	void GenType::postvisit( ArrayType * arrayType ) {
+		genArray( arrayType->get_qualifiers(), arrayType->base, arrayType->dimension, arrayType->get_isVarLen(), arrayType->get_isStatic() );
+	}
+
+	void GenType::postvisit( ReferenceType * refType ) {
+		assert( refType->base != 0);
 		assertf( ! genC, "Reference types should not reach code generation." );
 		handleQualifiers( refType );
 		typeString = "&" + typeString;
-		refType->get_base()->accept( *this );
-	}
-
-	void GenType::visit( FunctionType *funcType ) {
+		refType->base->accept( *visitor );
+	}
+
+	void GenType::postvisit( FunctionType * funcType ) {
 		std::ostringstream os;
 
@@ -169,5 +184,5 @@
 		/************* parameters ***************/
 
-		const std::list<DeclarationWithType *> &pars = funcType->get_parameters();
+		const std::list<DeclarationWithType *> &pars = funcType->parameters;
 
 		if ( pars.empty() ) {
@@ -191,17 +206,17 @@
 		typeString = os.str();
 
-		if ( funcType->get_returnVals().size() == 0 ) {
+		if ( funcType->returnVals.size() == 0 ) {
 			typeString = "void " + typeString;
 		} else {
-			funcType->get_returnVals().front()->get_type()->accept( *this );
+			funcType->returnVals.front()->get_type()->accept( *visitor );
 		} // if
 
 		// add forall
-		if( ! funcType->get_forall().empty() && ! genC ) {
+		if( ! funcType->forall.empty() && ! genC ) {
 			// assertf( ! genC, "Aggregate type parameters should not reach code generation." );
 			std::ostringstream os;
 			PassVisitor<CodeGenerator> cg( os, pretty, genC, lineMarks );
 			os << "forall(";
-			cg.pass.genCommaList( funcType->get_forall().begin(), funcType->get_forall().end() );
+			cg.pass.genCommaList( funcType->forall.begin(), funcType->forall.end() );
 			os << ")" << std::endl;
 			typeString = os.str() + typeString;
@@ -221,28 +236,28 @@
 	}
 
-	void GenType::visit( StructInstType *structInst )  {
-		typeString = structInst->get_name() + handleGeneric( structInst ) + " " + typeString;
+	void GenType::postvisit( StructInstType * structInst )  {
+		typeString = structInst->name + handleGeneric( structInst ) + " " + typeString;
 		if ( genC ) typeString = "struct " + typeString;
 		handleQualifiers( structInst );
 	}
 
-	void GenType::visit( UnionInstType *unionInst ) {
-		typeString = unionInst->get_name() + handleGeneric( unionInst ) + " " + typeString;
+	void GenType::postvisit( UnionInstType * unionInst ) {
+		typeString = unionInst->name + handleGeneric( unionInst ) + " " + typeString;
 		if ( genC ) typeString = "union " + typeString;
 		handleQualifiers( unionInst );
 	}
 
-	void GenType::visit( EnumInstType *enumInst ) {
-		typeString = enumInst->get_name() + " " + typeString;
+	void GenType::postvisit( EnumInstType * enumInst ) {
+		typeString = enumInst->name + " " + typeString;
 		if ( genC ) typeString = "enum " + typeString;
 		handleQualifiers( enumInst );
 	}
 
-	void GenType::visit( TypeInstType *typeInst ) {
-		typeString = typeInst->get_name() + " " + typeString;
+	void GenType::postvisit( TypeInstType * typeInst ) {
+		typeString = typeInst->name + " " + typeString;
 		handleQualifiers( typeInst );
 	}
 
-	void GenType::visit( TupleType * tupleType ) {
+	void GenType::postvisit( TupleType * tupleType ) {
 		assertf( ! genC, "Tuple types should not reach code generation." );
 		unsigned int i = 0;
@@ -257,10 +272,10 @@
 	}
 
-	void GenType::visit( VarArgsType *varArgsType ) {
+	void GenType::postvisit( VarArgsType * varArgsType ) {
 		typeString = "__builtin_va_list " + typeString;
 		handleQualifiers( varArgsType );
 	}
 
-	void GenType::visit( ZeroType *zeroType ) {
+	void GenType::postvisit( ZeroType * zeroType ) {
 		// ideally these wouldn't hit codegen at all, but should be safe to make them ints
 		typeString = (pretty ? "zero_t " : "long int ") + typeString;
@@ -268,5 +283,5 @@
 	}
 
-	void GenType::visit( OneType *oneType ) {
+	void GenType::postvisit( OneType * oneType ) {
 		// ideally these wouldn't hit codegen at all, but should be safe to make them ints
 		typeString = (pretty ? "one_t " : "long int ") + typeString;
@@ -274,5 +289,5 @@
 	}
 
-	void GenType::handleQualifiers( Type *type ) {
+	void GenType::handleQualifiers( Type * type ) {
 		if ( type->get_const() ) {
 			typeString = "const " + typeString;
