Index: src/SymTab/Validate.cc
===================================================================
--- src/SymTab/Validate.cc	(revision 982832e24b58f99cf8d892fbb03bfd2c5cd57b15)
+++ src/SymTab/Validate.cc	(revision 8d722ccd70892f5a8493fa5275330663ce8fb632)
@@ -123,23 +123,20 @@
 
 	/// Associates forward declarations of aggregates with their definitions
-	class LinkReferenceToTypes final : public Indexer {
-		typedef Indexer Parent;
-	  public:
-		LinkReferenceToTypes( bool doDebug, const Indexer *indexer );
-		using Parent::visit;
-		void visit( TypeInstType *typeInst ) final;
-
-		void visit( EnumInstType *enumInst ) final;
-		void visit( StructInstType *structInst ) final;
-		void visit( UnionInstType *unionInst ) final;
-		void visit( TraitInstType *traitInst ) final;
-
-		void visit( EnumDecl *enumDecl ) final;
-		void visit( StructDecl *structDecl ) final;
-		void visit( UnionDecl *unionDecl ) final;
-		void visit( TraitDecl * traitDecl ) final;
+	struct LinkReferenceToTypes final : public WithIndexer {
+		LinkReferenceToTypes( const Indexer *indexer );
+		void postvisit( TypeInstType *typeInst );
+
+		void postvisit( EnumInstType *enumInst );
+		void postvisit( StructInstType *structInst );
+		void postvisit( UnionInstType *unionInst );
+		void postvisit( TraitInstType *traitInst );
+
+		void postvisit( EnumDecl *enumDecl );
+		void postvisit( StructDecl *structDecl );
+		void postvisit( UnionDecl *unionDecl );
+		void postvisit( TraitDecl * traitDecl );
 
 	  private:
-		const Indexer *indexer;
+		const Indexer *local_indexer;
 
 		typedef std::map< std::string, std::list< EnumInstType * > > ForwardEnumsType;
@@ -152,14 +149,7 @@
 
 	/// Replaces array and function types in forall lists by appropriate pointer type and assigns each Object and Function declaration a unique ID.
-	class ForallPointerDecay final : public Indexer {
-		typedef Indexer Parent;
-	  public:
-	  	using Parent::visit;
-		ForallPointerDecay( const Indexer *indexer );
-
-		virtual void visit( ObjectDecl *object ) override;
-		virtual void visit( FunctionDecl *func ) override;
-
-		const Indexer *indexer;
+	struct ForallPointerDecay final {
+		void previsit( ObjectDecl *object );
+		void previsit( FunctionDecl *func );
 	};
 
@@ -263,8 +253,8 @@
 	};
 
-	void validate( std::list< Declaration * > &translationUnit, bool doDebug ) {
+	void validate( std::list< Declaration * > &translationUnit, __attribute__((unused)) bool doDebug ) {
 		PassVisitor<EnumAndPointerDecay> epc;
-		LinkReferenceToTypes lrt( doDebug, 0 );
-		ForallPointerDecay fpd( 0 );
+		PassVisitor<LinkReferenceToTypes> lrt( nullptr );
+		PassVisitor<ForallPointerDecay> fpd;
 		PassVisitor<CompoundLiteral> compoundliteral;
 		PassVisitor<ValidateGenericParameters> genericParams;
@@ -293,6 +283,6 @@
 	void validateType( Type *type, const Indexer *indexer ) {
 		PassVisitor<EnumAndPointerDecay> epc;
-		LinkReferenceToTypes lrt( false, indexer );
-		ForallPointerDecay fpd( indexer );
+		PassVisitor<LinkReferenceToTypes> lrt( indexer );
+		PassVisitor<ForallPointerDecay> fpd;
 		type->accept( epc );
 		type->accept( lrt );
@@ -408,15 +398,14 @@
 	}
 
-	LinkReferenceToTypes::LinkReferenceToTypes( bool doDebug, const Indexer *other_indexer ) : Indexer( doDebug ) {
+	LinkReferenceToTypes::LinkReferenceToTypes( const Indexer *other_indexer ) {
 		if ( other_indexer ) {
-			indexer = other_indexer;
+			local_indexer = other_indexer;
 		} else {
-			indexer = this;
-		} // if
-	}
-
-	void LinkReferenceToTypes::visit( EnumInstType *enumInst ) {
-		Parent::visit( enumInst );
-		EnumDecl *st = indexer->lookupEnum( enumInst->get_name() );
+			local_indexer = &indexer;
+		} // if
+	}
+
+	void LinkReferenceToTypes::postvisit( EnumInstType *enumInst ) {
+		EnumDecl *st = local_indexer->lookupEnum( enumInst->get_name() );
 		// it's not a semantic error if the enum is not found, just an implicit forward declaration
 		if ( st ) {
@@ -430,7 +419,6 @@
 	}
 
-	void LinkReferenceToTypes::visit( StructInstType *structInst ) {
-		Parent::visit( structInst );
-		StructDecl *st = indexer->lookupStruct( structInst->get_name() );
+	void LinkReferenceToTypes::postvisit( StructInstType *structInst ) {
+		StructDecl *st = local_indexer->lookupStruct( structInst->get_name() );
 		// it's not a semantic error if the struct is not found, just an implicit forward declaration
 		if ( st ) {
@@ -444,7 +432,6 @@
 	}
 
-	void LinkReferenceToTypes::visit( UnionInstType *unionInst ) {
-		Parent::visit( unionInst );
-		UnionDecl *un = indexer->lookupUnion( unionInst->get_name() );
+	void LinkReferenceToTypes::postvisit( UnionInstType *unionInst ) {
+		UnionDecl *un = local_indexer->lookupUnion( unionInst->get_name() );
 		// it's not a semantic error if the union is not found, just an implicit forward declaration
 		if ( un ) {
@@ -499,7 +486,5 @@
 	}
 
-	void LinkReferenceToTypes::visit( TraitDecl * traitDecl ) {
-		Parent::visit( traitDecl );
-
+	void LinkReferenceToTypes::postvisit( TraitDecl * traitDecl ) {
 		if ( traitDecl->name == "sized" ) {
 			// "sized" is a special trait - flick the sized status on for the type variable
@@ -523,8 +508,7 @@
 	}
 
-	void LinkReferenceToTypes::visit( TraitInstType * traitInst ) {
-		Parent::visit( traitInst );
+	void LinkReferenceToTypes::postvisit( TraitInstType * traitInst ) {
 		// handle other traits
-		TraitDecl *traitDecl = indexer->lookupTrait( traitInst->name );
+		TraitDecl *traitDecl = local_indexer->lookupTrait( traitInst->name );
 		if ( ! traitDecl ) {
 			throw SemanticError( "use of undeclared trait " + traitInst->name );
@@ -547,7 +531,6 @@
 	}
 
-	void LinkReferenceToTypes::visit( EnumDecl *enumDecl ) {
+	void LinkReferenceToTypes::postvisit( EnumDecl *enumDecl ) {
 		// visit enum members first so that the types of self-referencing members are updated properly
-		Parent::visit( enumDecl );
 		if ( ! enumDecl->get_members().empty() ) {
 			ForwardEnumsType::iterator fwds = forwardEnums.find( enumDecl->get_name() );
@@ -561,8 +544,7 @@
 	}
 
-	void LinkReferenceToTypes::visit( StructDecl *structDecl ) {
+	void LinkReferenceToTypes::postvisit( StructDecl *structDecl ) {
 		// visit struct members first so that the types of self-referencing members are updated properly
-		// xxx - need to ensure that type parameters match up between forward declarations and definition (most importantly, number of type parameters and and their defaults)
-		Parent::visit( structDecl );
+		// xxx - need to ensure that type parameters match up between forward declarations and definition (most importantly, number of type parameters and their defaults)
 		if ( ! structDecl->get_members().empty() ) {
 			ForwardStructsType::iterator fwds = forwardStructs.find( structDecl->get_name() );
@@ -576,6 +558,5 @@
 	}
 
-	void LinkReferenceToTypes::visit( UnionDecl *unionDecl ) {
-		Parent::visit( unionDecl );
+	void LinkReferenceToTypes::postvisit( UnionDecl *unionDecl ) {
 		if ( ! unionDecl->get_members().empty() ) {
 			ForwardUnionsType::iterator fwds = forwardUnions.find( unionDecl->get_name() );
@@ -589,17 +570,9 @@
 	}
 
-	void LinkReferenceToTypes::visit( TypeInstType *typeInst ) {
-		if ( NamedTypeDecl *namedTypeDecl = lookupType( typeInst->get_name() ) ) {
+	void LinkReferenceToTypes::postvisit( TypeInstType *typeInst ) {
+		if ( NamedTypeDecl *namedTypeDecl = local_indexer->lookupType( typeInst->get_name() ) ) {
 			if ( TypeDecl *typeDecl = dynamic_cast< TypeDecl * >( namedTypeDecl ) ) {
 				typeInst->set_isFtype( typeDecl->get_kind() == TypeDecl::Ftype );
 			} // if
-		} // if
-	}
-
-	ForallPointerDecay::ForallPointerDecay( const Indexer *other_indexer ) :  Indexer( false ) {
-		if ( other_indexer ) {
-			indexer = other_indexer;
-		} else {
-			indexer = this;
 		} // if
 	}
@@ -633,16 +606,14 @@
 	}
 
-	void ForallPointerDecay::visit( ObjectDecl *object ) {
+	void ForallPointerDecay::previsit( ObjectDecl *object ) {
 		forallFixer( object->get_type() );
 		if ( PointerType *pointer = dynamic_cast< PointerType * >( object->get_type() ) ) {
 			forallFixer( pointer->get_base() );
 		} // if
-		Parent::visit( object );
 		object->fixUniqueId();
 	}
 
-	void ForallPointerDecay::visit( FunctionDecl *func ) {
+	void ForallPointerDecay::previsit( FunctionDecl *func ) {
 		forallFixer( func->get_type() );
-		Parent::visit( func );
 		func->fixUniqueId();
 	}
