Index: src/SymTab/Mangler.cc
===================================================================
--- src/SymTab/Mangler.cc	(revision 4b97770cddc6c963b957ff9691018b2a164df9af)
+++ src/SymTab/Mangler.cc	(revision b0c32da8d2956a86a73c0000c8f8110a5c0a64ba)
@@ -23,4 +23,5 @@
 
 #include "CodeGen/OperatorTable.h"  // for OperatorInfo, operatorLookup
+#include "Common/PassVisitor.h"
 #include "Common/SemanticError.h"   // for SemanticError
 #include "Common/utility.h"         // for toString
@@ -31,285 +32,340 @@
 
 namespace SymTab {
-	std::string Mangler::mangleType( Type * ty ) {
-		Mangler mangler( false, true, true );
-		maybeAccept( ty, mangler );
-		return mangler.get_mangleName();
-	}
-
-	std::string Mangler::mangleConcrete( Type* ty ) {
-		Mangler mangler( false, false, false );
-		maybeAccept( ty, mangler );
-		return mangler.get_mangleName();
-	}
-
-	Mangler::Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams )
-		: nextVarNum( 0 ), isTopLevel( true ), mangleOverridable( mangleOverridable ), typeMode( typeMode ), mangleGenericParams( mangleGenericParams ) {}
-
-	Mangler::Mangler( const Mangler &rhs ) : mangleName() {
-		varNums = rhs.varNums;
-		nextVarNum = rhs.nextVarNum;
-		isTopLevel = rhs.isTopLevel;
-		mangleOverridable = rhs.mangleOverridable;
-		typeMode = rhs.typeMode;
-	}
-
-	void Mangler::mangleDecl( DeclarationWithType * declaration ) {
-		bool wasTopLevel = isTopLevel;
-		if ( isTopLevel ) {
-			varNums.clear();
-			nextVarNum = 0;
-			isTopLevel = false;
-		} // if
-		mangleName << "__";
-		CodeGen::OperatorInfo opInfo;
-		if ( operatorLookup( declaration->get_name(), opInfo ) ) {
-			mangleName << opInfo.outputName;
-		} else {
-			mangleName << declaration->get_name();
-		} // if
-		mangleName << "__";
-		maybeAccept( declaration->get_type(), *this );
-		if ( mangleOverridable && LinkageSpec::isOverridable( declaration->get_linkage() ) ) {
-			// want to be able to override autogenerated and intrinsic routines,
-			// so they need a different name mangling
-			if ( declaration->get_linkage() == LinkageSpec::AutoGen ) {
-				mangleName << "autogen__";
-			} else if ( declaration->get_linkage() == LinkageSpec::Intrinsic ) {
-				mangleName << "intrinsic__";
-			} else {
-				// if we add another kind of overridable function, this has to change
-				assert( false && "unknown overrideable linkage" );
-			} // if
+	namespace Mangler {
+		namespace {
+			/// Mangles names to a unique C identifier
+			struct Mangler : public WithShortCircuiting, public WithVisitorRef<Mangler> {
+				Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams );
+				Mangler( const Mangler & );
+
+				void previsit( BaseSyntaxNode * ) { visit_children = false; }
+
+				void postvisit( ObjectDecl * declaration );
+				void postvisit( FunctionDecl * declaration );
+				void postvisit( TypeDecl * declaration );
+
+				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( TypeInstType * aggregateUseType );
+				void postvisit( TupleType * tupleType );
+				void postvisit( VarArgsType * varArgsType );
+				void postvisit( ZeroType * zeroType );
+				void postvisit( OneType * oneType );
+
+				std::string get_mangleName() { return mangleName.str(); }
+			  private:
+				std::ostringstream mangleName;  ///< Mangled name being constructed
+				typedef std::map< std::string, std::pair< int, int > > VarMapType;
+				VarMapType varNums;             ///< Map of type variables to indices
+				int nextVarNum;                 ///< Next type variable index
+				bool isTopLevel;                ///< Is the Mangler at the top level
+				bool mangleOverridable;         ///< Specially mangle overridable built-in methods
+				bool typeMode;                  ///< Produce a unique mangled name for a type
+				bool mangleGenericParams;       ///< Include generic parameters in name mangling if true
+
+				void mangleDecl( DeclarationWithType *declaration );
+				void mangleRef( ReferenceToType *refType, std::string prefix );
+
+				void printQualifiers( Type *type );
+			}; // Mangler
+		} // namespace
+
+		std::string mangle( BaseSyntaxNode * decl, bool mangleOverridable, bool typeMode, bool mangleGenericParams ) {
+			PassVisitor<Mangler> mangler( mangleOverridable, typeMode, mangleGenericParams );
+			maybeAccept( decl, mangler );
+			return mangler.pass.get_mangleName();
 		}
-		isTopLevel = wasTopLevel;
-	}
-
-	void Mangler::visit( ObjectDecl * declaration ) {
-		mangleDecl( declaration );
-	}
-
-	void Mangler::visit( FunctionDecl * declaration ) {
-		mangleDecl( declaration );
-	}
-
-	void Mangler::visit( VoidType * voidType ) {
-		printQualifiers( voidType );
-		mangleName << "v";
-	}
-
-	void Mangler::visit( BasicType * basicType ) {
-		static const char *btLetter[] = {
-			"b",	// Bool
-			"c",	// Char
-			"Sc",	// SignedChar
-			"Uc",	// UnsignedChar
-			"s",	// ShortSignedInt
-			"Us",	// ShortUnsignedInt
-			"i",	// SignedInt
-			"Ui",	// UnsignedInt
-			"l",	// LongSignedInt
-			"Ul",	// LongUnsignedInt
-			"q",	// LongLongSignedInt
-			"Uq",	// LongLongUnsignedInt
-			"f",	// Float
-			"d",	// Double
-			"r",	// LongDouble
-			"Xf",	// FloatComplex
-			"Xd",	// DoubleComplex
-			"Xr",	// LongDoubleComplex
-			"If",	// FloatImaginary
-			"Id",	// DoubleImaginary
-			"Ir",	// LongDoubleImaginary
-			"w",	// SignedInt128
-			"Uw",	// UnsignedInt128
-		};
-
-		printQualifiers( basicType );
-		mangleName << btLetter[ basicType->get_kind() ];
-	}
-
-	void Mangler::visit( PointerType * pointerType ) {
-		printQualifiers( pointerType );
-		mangleName << "P";
-		maybeAccept( pointerType->get_base(), *this );
-	}
-
-	void Mangler::visit( ArrayType * arrayType ) {
-		// TODO: encode dimension
-		printQualifiers( arrayType );
-		mangleName << "A0";
-		maybeAccept( arrayType->get_base(), *this );
-	}
-
-	void Mangler::visit( ReferenceType * refType ) {
-		printQualifiers( refType );
-		mangleName << "R";
-		maybeAccept( refType->get_base(), *this );
-	}
-
-	namespace {
-		inline std::list< Type* > getTypes( const std::list< DeclarationWithType* > decls ) {
-			std::list< Type* > ret;
-			std::transform( decls.begin(), decls.end(), std::back_inserter( ret ),
-							std::mem_fun( &DeclarationWithType::get_type ) );
-			return ret;
+
+		std::string mangleType( Type * ty ) {
+			PassVisitor<Mangler> mangler( false, true, true );
+			maybeAccept( ty, mangler );
+			return mangler.pass.get_mangleName();
 		}
-	}
-
-	void Mangler::visit( FunctionType * functionType ) {
-		printQualifiers( functionType );
-		mangleName << "F";
-		std::list< Type* > returnTypes = getTypes( functionType->get_returnVals() );
-		acceptAll( returnTypes, *this );
-		mangleName << "_";
-		std::list< Type* > paramTypes = getTypes( functionType->get_parameters() );
-		acceptAll( paramTypes, *this );
-		mangleName << "_";
-	}
-
-	void Mangler::mangleRef( ReferenceToType * refType, std::string prefix ) {
-		printQualifiers( refType );
-
-		mangleName << ( refType->get_name().length() + prefix.length() ) << prefix << refType->get_name();
-
-		if ( mangleGenericParams ) {
-			std::list< Expression* >& params = refType->get_parameters();
-			if ( ! params.empty() ) {
+
+		std::string mangleConcrete( Type * ty ) {
+			PassVisitor<Mangler> mangler( false, false, false );
+			maybeAccept( ty, mangler );
+			return mangler.pass.get_mangleName();
+		}
+
+		namespace {
+			Mangler::Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams )
+				: nextVarNum( 0 ), isTopLevel( true ), mangleOverridable( mangleOverridable ), typeMode( typeMode ), mangleGenericParams( mangleGenericParams ) {}
+
+			Mangler::Mangler( const Mangler &rhs ) : mangleName() {
+				varNums = rhs.varNums;
+				nextVarNum = rhs.nextVarNum;
+				isTopLevel = rhs.isTopLevel;
+				mangleOverridable = rhs.mangleOverridable;
+				typeMode = rhs.typeMode;
+			}
+
+			void Mangler::mangleDecl( DeclarationWithType * declaration ) {
+				bool wasTopLevel = isTopLevel;
+				if ( isTopLevel ) {
+					varNums.clear();
+					nextVarNum = 0;
+					isTopLevel = false;
+				} // if
+				mangleName << "__";
+				CodeGen::OperatorInfo opInfo;
+				if ( operatorLookup( declaration->get_name(), opInfo ) ) {
+					mangleName << opInfo.outputName;
+				} else {
+					mangleName << declaration->get_name();
+				} // if
+				mangleName << "__";
+				maybeAccept( declaration->get_type(), *visitor );
+				if ( mangleOverridable && LinkageSpec::isOverridable( declaration->get_linkage() ) ) {
+					// want to be able to override autogenerated and intrinsic routines,
+					// so they need a different name mangling
+					if ( declaration->get_linkage() == LinkageSpec::AutoGen ) {
+						mangleName << "autogen__";
+					} else if ( declaration->get_linkage() == LinkageSpec::Intrinsic ) {
+						mangleName << "intrinsic__";
+					} else {
+						// if we add another kind of overridable function, this has to change
+						assert( false && "unknown overrideable linkage" );
+					} // if
+				}
+				isTopLevel = wasTopLevel;
+			}
+
+			void Mangler::postvisit( ObjectDecl * declaration ) {
+				mangleDecl( declaration );
+			}
+
+			void Mangler::postvisit( FunctionDecl * declaration ) {
+				mangleDecl( declaration );
+			}
+
+			void Mangler::postvisit( VoidType * voidType ) {
+				printQualifiers( voidType );
+				mangleName << "v";
+			}
+
+			void Mangler::postvisit( BasicType * basicType ) {
+				static const char *btLetter[] = {
+					"b",	// Bool
+					"c",	// Char
+					"Sc",	// SignedChar
+					"Uc",	// UnsignedChar
+					"s",	// ShortSignedInt
+					"Us",	// ShortUnsignedInt
+					"i",	// SignedInt
+					"Ui",	// UnsignedInt
+					"l",	// LongSignedInt
+					"Ul",	// LongUnsignedInt
+					"q",	// LongLongSignedInt
+					"Uq",	// LongLongUnsignedInt
+					"f",	// Float
+					"d",	// Double
+					"r",	// LongDouble
+					"Xf",	// FloatComplex
+					"Xd",	// DoubleComplex
+					"Xr",	// LongDoubleComplex
+					"If",	// FloatImaginary
+					"Id",	// DoubleImaginary
+					"Ir",	// LongDoubleImaginary
+					"w",	// SignedInt128
+					"Uw",	// UnsignedInt128
+				};
+
+				printQualifiers( basicType );
+				mangleName << btLetter[ basicType->get_kind() ];
+			}
+
+			void Mangler::postvisit( PointerType * pointerType ) {
+				printQualifiers( pointerType );
+				mangleName << "P";
+				maybeAccept( pointerType->get_base(), *visitor );
+			}
+
+			void Mangler::postvisit( ArrayType * arrayType ) {
+				// TODO: encode dimension
+				printQualifiers( arrayType );
+				mangleName << "A0";
+				maybeAccept( arrayType->get_base(), *visitor );
+			}
+
+			void Mangler::postvisit( ReferenceType * refType ) {
+				printQualifiers( refType );
+				mangleName << "R";
+				maybeAccept( refType->get_base(), *visitor );
+			}
+
+			namespace {
+				inline std::list< Type* > getTypes( const std::list< DeclarationWithType* > decls ) {
+					std::list< Type* > ret;
+					std::transform( decls.begin(), decls.end(), std::back_inserter( ret ),
+									std::mem_fun( &DeclarationWithType::get_type ) );
+					return ret;
+				}
+			}
+
+			void Mangler::postvisit( FunctionType * functionType ) {
+				printQualifiers( functionType );
+				mangleName << "F";
+				std::list< Type* > returnTypes = getTypes( functionType->get_returnVals() );
+				acceptAll( returnTypes, *visitor );
 				mangleName << "_";
-				for ( std::list< Expression* >::const_iterator param = params.begin(); param != params.end(); ++param ) {
-					TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
-					assertf(paramType, "Aggregate parameters should be type expressions: %s", toString(*param).c_str());
-					maybeAccept( paramType->get_type(), *this );
+				std::list< Type* > paramTypes = getTypes( functionType->get_parameters() );
+				acceptAll( paramTypes, *visitor );
+				mangleName << "_";
+			}
+
+			void Mangler::mangleRef( ReferenceToType * refType, std::string prefix ) {
+				printQualifiers( refType );
+
+				mangleName << ( refType->get_name().length() + prefix.length() ) << prefix << refType->get_name();
+
+				if ( mangleGenericParams ) {
+					std::list< Expression* >& params = refType->get_parameters();
+					if ( ! params.empty() ) {
+						mangleName << "_";
+						for ( std::list< Expression* >::const_iterator param = params.begin(); param != params.end(); ++param ) {
+							TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
+							assertf(paramType, "Aggregate parameters should be type expressions: %s", toString(*param).c_str());
+							maybeAccept( paramType->get_type(), *visitor );
+						}
+						mangleName << "_";
+					}
 				}
+			}
+
+			void Mangler::postvisit( StructInstType * aggregateUseType ) {
+				mangleRef( aggregateUseType, "s" );
+			}
+
+			void Mangler::postvisit( UnionInstType * aggregateUseType ) {
+				mangleRef( aggregateUseType, "u" );
+			}
+
+			void Mangler::postvisit( EnumInstType * aggregateUseType ) {
+				mangleRef( aggregateUseType, "e" );
+			}
+
+			void Mangler::postvisit( TypeInstType * typeInst ) {
+				VarMapType::iterator varNum = varNums.find( typeInst->get_name() );
+				if ( varNum == varNums.end() ) {
+					mangleRef( typeInst, "t" );
+				} else {
+					printQualifiers( typeInst );
+					std::ostringstream numStream;
+					numStream << varNum->second.first;
+					switch ( (TypeDecl::Kind )varNum->second.second ) {
+					  case TypeDecl::Dtype:
+						mangleName << "d";
+						break;
+					  case TypeDecl::Ftype:
+						mangleName << "f";
+						break;
+						case TypeDecl::Ttype:
+						mangleName << "tVARGS";
+						break;
+						default:
+						assert( false );
+					} // switch
+					mangleName << numStream.str();
+				} // if
+			}
+
+			void Mangler::postvisit( TupleType * tupleType ) {
+				printQualifiers( tupleType );
+				mangleName << "T";
+				acceptAll( tupleType->types, *visitor );
 				mangleName << "_";
 			}
-		}
-	}
-
-	void Mangler::visit( StructInstType * aggregateUseType ) {
-		mangleRef( aggregateUseType, "s" );
-	}
-
-	void Mangler::visit( UnionInstType * aggregateUseType ) {
-		mangleRef( aggregateUseType, "u" );
-	}
-
-	void Mangler::visit( EnumInstType * aggregateUseType ) {
-		mangleRef( aggregateUseType, "e" );
-	}
-
-	void Mangler::visit( TypeInstType * typeInst ) {
-		VarMapType::iterator varNum = varNums.find( typeInst->get_name() );
-		if ( varNum == varNums.end() ) {
-			mangleRef( typeInst, "t" );
-		} else {
-			printQualifiers( typeInst );
-			std::ostringstream numStream;
-			numStream << varNum->second.first;
-			switch ( (TypeDecl::Kind )varNum->second.second ) {
-			  case TypeDecl::Dtype:
-				mangleName << "d";
-				break;
-			  case TypeDecl::Ftype:
-				mangleName << "f";
-				break;
-				case TypeDecl::Ttype:
-				mangleName << "tVARGS";
-				break;
-				default:
-				assert( false );
-			} // switch
-			mangleName << numStream.str();
-		} // if
-	}
-
-	void Mangler::visit( TupleType * tupleType ) {
-		printQualifiers( tupleType );
-		mangleName << "T";
-		acceptAll( tupleType->types, *this );
-		mangleName << "_";
-	}
-
-	void Mangler::visit( VarArgsType * varArgsType ) {
-		printQualifiers( varArgsType );
-		mangleName << "VARGS";
-	}
-
-	void Mangler::visit( ZeroType * ) {
-		mangleName << "Z";
-	}
-
-	void Mangler::visit( OneType * ) {
-		mangleName << "O";
-	}
-
-	void Mangler::visit( TypeDecl * decl ) {
-		static const char *typePrefix[] = { "BT", "BD", "BF" };
-		mangleName << typePrefix[ decl->get_kind() ] << ( decl->name.length() + 1 ) << decl->name;
-	}
-
-	void printVarMap( const std::map< std::string, std::pair< int, int > > &varMap, std::ostream &os ) {
-		for ( std::map< std::string, std::pair< int, int > >::const_iterator i = varMap.begin(); i != varMap.end(); ++i ) {
-			os << i->first << "(" << i->second.first << "/" << i->second.second << ")" << std::endl;
-		} // for
-	}
-
-	void Mangler::printQualifiers( Type * type ) {
-		// skip if not including qualifiers
-		if ( typeMode ) return;
-
-		if ( ! type->get_forall().empty() ) {
-			std::list< std::string > assertionNames;
-			int tcount = 0, dcount = 0, fcount = 0, vcount = 0;
-			mangleName << "A";
-			for ( Type::ForallList::iterator i = type->forall.begin(); i != type->forall.end(); ++i ) {
-				switch ( (*i)->get_kind() ) {
-				  case TypeDecl::Dtype:
-					dcount++;
-					break;
-				  case TypeDecl::Ftype:
-					fcount++;
-					break;
-				  case TypeDecl::Ttype:
-					vcount++;
-					break;
-				  default:
-					assert( false );
-				} // switch
-				varNums[ (*i)->name ] = std::pair< int, int >( nextVarNum++, (int)(*i)->get_kind() );
-				for ( std::list< DeclarationWithType* >::iterator assert = (*i)->assertions.begin(); assert != (*i)->assertions.end(); ++assert ) {
-					Mangler sub_mangler( mangleOverridable, typeMode, mangleGenericParams );
-					sub_mangler.nextVarNum = nextVarNum;
-					sub_mangler.isTopLevel = false;
-					sub_mangler.varNums = varNums;
-					(*assert)->accept( sub_mangler );
-					assertionNames.push_back( sub_mangler.mangleName.str() );
+
+			void Mangler::postvisit( VarArgsType * varArgsType ) {
+				printQualifiers( varArgsType );
+				mangleName << "VARGS";
+			}
+
+			void Mangler::postvisit( ZeroType * ) {
+				mangleName << "Z";
+			}
+
+			void Mangler::postvisit( OneType * ) {
+				mangleName << "O";
+			}
+
+			void Mangler::postvisit( TypeDecl * decl ) {
+				static const char *typePrefix[] = { "BT", "BD", "BF" };
+				mangleName << typePrefix[ decl->get_kind() ] << ( decl->name.length() + 1 ) << decl->name;
+			}
+
+			__attribute__((unused)) void printVarMap( const std::map< std::string, std::pair< int, int > > &varMap, std::ostream &os ) {
+				for ( std::map< std::string, std::pair< int, int > >::const_iterator i = varMap.begin(); i != varMap.end(); ++i ) {
+					os << i->first << "(" << i->second.first << "/" << i->second.second << ")" << std::endl;
 				} // for
-			} // for
-			mangleName << tcount << "_" << dcount << "_" << fcount << "_" << vcount << "_";
-			std::copy( assertionNames.begin(), assertionNames.end(), std::ostream_iterator< std::string >( mangleName, "" ) );
-			mangleName << "_";
-		} // if
-		if ( type->get_const() ) {
-			mangleName << "C";
-		} // if
-		if ( type->get_volatile() ) {
-			mangleName << "V";
-		} // if
-		if ( type->get_mutex() ) {
-			mangleName << "M";
-		} // if
-		// Removed due to restrict not affecting function compatibility in GCC
-//		if ( type->get_isRestrict() ) {
-//			mangleName << "E";
-//		} // if
-		if ( type->get_lvalue() ) {
-			// mangle based on whether the type is lvalue, so that the resolver can differentiate lvalues and rvalues
-			mangleName << "L";
-		}
-		if ( type->get_atomic() ) {
-			mangleName << "A";
-		} // if
-	}
+			}
+
+			void Mangler::printQualifiers( Type * type ) {
+				// skip if not including qualifiers
+				if ( typeMode ) return;
+
+				if ( ! type->get_forall().empty() ) {
+					std::list< std::string > assertionNames;
+					int tcount = 0, dcount = 0, fcount = 0, vcount = 0;
+					mangleName << "A";
+					for ( Type::ForallList::iterator i = type->forall.begin(); i != type->forall.end(); ++i ) {
+						switch ( (*i)->get_kind() ) {
+						  case TypeDecl::Dtype:
+							dcount++;
+							break;
+						  case TypeDecl::Ftype:
+							fcount++;
+							break;
+						  case TypeDecl::Ttype:
+							vcount++;
+							break;
+						  default:
+							assert( false );
+						} // switch
+						varNums[ (*i)->name ] = std::pair< int, int >( nextVarNum++, (int)(*i)->get_kind() );
+						for ( std::list< DeclarationWithType* >::iterator assert = (*i)->assertions.begin(); assert != (*i)->assertions.end(); ++assert ) {
+							PassVisitor<Mangler> sub_mangler( mangleOverridable, typeMode, mangleGenericParams );
+							sub_mangler.pass.nextVarNum = nextVarNum;
+							sub_mangler.pass.isTopLevel = false;
+							sub_mangler.pass.varNums = varNums;
+							(*assert)->accept( sub_mangler );
+							assertionNames.push_back( sub_mangler.pass.mangleName.str() );
+						} // for
+					} // for
+					mangleName << tcount << "_" << dcount << "_" << fcount << "_" << vcount << "_";
+					std::copy( assertionNames.begin(), assertionNames.end(), std::ostream_iterator< std::string >( mangleName, "" ) );
+					mangleName << "_";
+				} // if
+				if ( type->get_const() ) {
+					mangleName << "C";
+				} // if
+				if ( type->get_volatile() ) {
+					mangleName << "V";
+				} // if
+				if ( type->get_mutex() ) {
+					mangleName << "M";
+				} // if
+				// Removed due to restrict not affecting function compatibility in GCC
+		//		if ( type->get_isRestrict() ) {
+		//			mangleName << "E";
+		//		} // if
+				if ( type->get_lvalue() ) {
+					// mangle based on whether the type is lvalue, so that the resolver can differentiate lvalues and rvalues
+					mangleName << "L";
+				}
+				if ( type->get_atomic() ) {
+					mangleName << "A";
+				} // if
+			}
+		}	// namespace
+	} // namespace Mangler
 } // namespace SymTab
 
Index: src/SymTab/Mangler.h
===================================================================
--- src/SymTab/Mangler.h	(revision 4b97770cddc6c963b957ff9691018b2a164df9af)
+++ src/SymTab/Mangler.h	(revision b0c32da8d2956a86a73c0000c8f8110a5c0a64ba)
@@ -25,61 +25,13 @@
 
 namespace SymTab {
-	/// Mangles names to a unique C identifier
-	class Mangler : public Visitor {
-	  public:
+	namespace Mangler {
 		/// Mangle syntax tree object; primary interface to clients
-		template< typename SynTreeClass >
-	    static std::string mangle( SynTreeClass *decl, bool mangleOverridable = true, bool typeMode = false, bool mangleGenericParams = true );
+		std::string mangle( BaseSyntaxNode * decl, bool mangleOverridable = true, bool typeMode = false, bool mangleGenericParams = true );
+
 		/// Mangle a type name; secondary interface
-		static std::string mangleType( Type* ty );
+		std::string mangleType( Type* ty );
 		/// Mangle ignoring generic type parameters
-		static std::string mangleConcrete( Type* ty );
-
-
-		virtual void visit( ObjectDecl *declaration );
-		virtual void visit( FunctionDecl *declaration );
-		virtual void visit( TypeDecl *declaration );
-
-		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( TypeInstType *aggregateUseType );
-		virtual void visit( TupleType *tupleType );
-		virtual void visit( VarArgsType *varArgsType );
-		virtual void visit( ZeroType *zeroType );
-		virtual void visit( OneType *oneType );
-
-		std::string get_mangleName() { return mangleName.str(); }
-	  private:
-		std::ostringstream mangleName;  ///< Mangled name being constructed
-		typedef std::map< std::string, std::pair< int, int > > VarMapType;
-		VarMapType varNums;             ///< Map of type variables to indices
-		int nextVarNum;                 ///< Next type variable index
-		bool isTopLevel;                ///< Is the Mangler at the top level
-		bool mangleOverridable;         ///< Specially mangle overridable built-in methods
-		bool typeMode;                  ///< Produce a unique mangled name for a type
-		bool mangleGenericParams;       ///< Include generic parameters in name mangling if true
-
-		Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams );
-		Mangler( const Mangler & );
-
-		void mangleDecl( DeclarationWithType *declaration );
-		void mangleRef( ReferenceToType *refType, std::string prefix );
-
-		void printQualifiers( Type *type );
-	}; // Mangler
-
-	template< typename SynTreeClass >
-	std::string Mangler::mangle( SynTreeClass *decl, bool mangleOverridable, bool typeMode, bool mangleGenericParams ) {
-		Mangler mangler( mangleOverridable, typeMode, mangleGenericParams );
-		maybeAccept( decl, mangler );
-		return mangler.get_mangleName();
-	}
+		std::string mangleConcrete( Type* ty );
+	} // Mangler
 } // SymTab
 
