Index: src/AST/Node.hpp
===================================================================
--- src/AST/Node.hpp	(revision 9519aba7964e345345fd95d48fcca0103be2c788)
+++ src/AST/Node.hpp	(revision 1346914ea47e0410d38c770b01303dae319282ea)
@@ -18,4 +18,6 @@
 #include <cassert>
 #include <iosfwd>
+
+#include "Common/ErrorObjects.h"  // for SemanticErrorException
 
 namespace ast {
@@ -100,4 +102,22 @@
 }
 
+/// Call a visitor on a collection of nodes, throwing any exceptions when completed
+template< typename Container >
+void accept_each( const Container & c, Visitor & v ) {
+	SemanticErrorException errors;
+	for ( const auto & i : c ) {
+		try {
+			if ( i ) {
+				i->accept( v );
+			}
+		} catch ( SemanticErrorException & e ) {
+			errors.append( e );
+		}
+	}
+	if ( ! errors.isEmpty() ) {
+		throw errors;
+	}
+}
+
 /// Base class for the smart pointer types
 /// should never really be used.
Index: src/SymTab/Mangler.cc
===================================================================
--- src/SymTab/Mangler.cc	(revision 9519aba7964e345345fd95d48fcca0103be2c788)
+++ src/SymTab/Mangler.cc	(revision 1346914ea47e0410d38c770b01303dae319282ea)
@@ -399,26 +399,26 @@
 			Mangler_new( const Mangler_new & ) = delete;
 
-			void previsit( ast::Node * ) { visit_children = false; }
-
-			void postvisit( ast::ObjectDecl * declaration );
-			void postvisit( ast::FunctionDecl * declaration );
-			void postvisit( ast::TypeDecl * declaration );
-
-			void postvisit( ast::VoidType * voidType );
-			void postvisit( ast::BasicType * basicType );
-			void postvisit( ast::PointerType * pointerType );
-			void postvisit( ast::ArrayType * arrayType );
-			void postvisit( ast::ReferenceType * refType );
-			void postvisit( ast::FunctionType * functionType );
-			void postvisit( ast::StructInstType * aggregateUseType );
-			void postvisit( ast::UnionInstType * aggregateUseType );
-			void postvisit( ast::EnumInstType * aggregateUseType );
-			void postvisit( ast::TypeInstType * aggregateUseType );
-			void postvisit( ast::TraitInstType * inst );
-			void postvisit( ast::TupleType * tupleType );
-			void postvisit( ast::VarArgsType * varArgsType );
-			void postvisit( ast::ZeroType * zeroType );
-			void postvisit( ast::OneType * oneType );
-			void postvisit( ast::QualifiedType * qualType );
+			void previsit( const ast::Node * ) { visit_children = false; }
+
+			void postvisit( const ast::ObjectDecl * declaration );
+			void postvisit( const ast::FunctionDecl * declaration );
+			void postvisit( const ast::TypeDecl * declaration );
+
+			void postvisit( const ast::VoidType * voidType );
+			void postvisit( const ast::BasicType * basicType );
+			void postvisit( const ast::PointerType * pointerType );
+			void postvisit( const ast::ArrayType * arrayType );
+			void postvisit( const ast::ReferenceType * refType );
+			void postvisit( const ast::FunctionType * functionType );
+			void postvisit( const ast::StructInstType * aggregateUseType );
+			void postvisit( const ast::UnionInstType * aggregateUseType );
+			void postvisit( const ast::EnumInstType * aggregateUseType );
+			void postvisit( const ast::TypeInstType * aggregateUseType );
+			void postvisit( const ast::TraitInstType * inst );
+			void postvisit( const ast::TupleType * tupleType );
+			void postvisit( const ast::VarArgsType * varArgsType );
+			void postvisit( const ast::ZeroType * zeroType );
+			void postvisit( const ast::OneType * oneType );
+			void postvisit( const ast::QualifiedType * qualType );
 
 			std::string get_mangleName() { return mangleName.str(); }
@@ -441,8 +441,8 @@
 
 		  private:
-			void mangleDecl( ast::DeclWithType *declaration );
-			void mangleRef( ast::ReferenceToType *refType, std::string prefix );
-
-			void printQualifiers( ast::Type *type );
+			void mangleDecl( const ast::DeclWithType *declaration );
+			void mangleRef( const ast::ReferenceToType *refType, std::string prefix );
+
+			void printQualifiers( const ast::Type *type );
 		}; // Mangler_new
 	} // namespace
@@ -468,5 +468,5 @@
 			mangleGenericParams( mangleGenericParams ) {}
 
-		void Mangler_new::mangleDecl( ast::DeclWithType * decl ) {
+		void Mangler_new::mangleDecl( const ast::DeclWithType * decl ) {
 			bool wasTopLevel = isTopLevel;
 			if ( isTopLevel ) {
@@ -498,18 +498,18 @@
 		}
 
-		void Mangler_new::postvisit( ast::ObjectDecl * decl ) {
+		void Mangler_new::postvisit( const ast::ObjectDecl * decl ) {
 			mangleDecl( decl );
 		}
 
-		void Mangler_new::postvisit( ast::FunctionDecl * decl ) {
+		void Mangler_new::postvisit( const ast::FunctionDecl * decl ) {
 			mangleDecl( decl );
 		}
 
-		void Mangler_new::postvisit( ast::VoidType * voidType ) {
+		void Mangler_new::postvisit( const ast::VoidType * voidType ) {
 			printQualifiers( voidType );
 			mangleName << Encoding::void_t;
 		}
 
-		void Mangler_new::postvisit( ast::BasicType * basicType ) {
+		void Mangler_new::postvisit( const ast::BasicType * basicType ) {
 			printQualifiers( basicType );
 			assertf( basicType->kind < ast::BasicType::NUMBER_OF_BASIC_TYPES, "Unhandled basic type: %d", basicType->kind );
@@ -517,5 +517,5 @@
 		}
 
-		void Mangler_new::postvisit( ast::PointerType * pointerType ) {
+		void Mangler_new::postvisit( const ast::PointerType * pointerType ) {
 			printQualifiers( pointerType );
 			// mangle void (*f)() and void f() to the same name to prevent overloading on functions and function pointers
@@ -524,5 +524,5 @@
 		}
 
-		void Mangler_new::postvisit( ast::ArrayType * arrayType ) {
+		void Mangler_new::postvisit( const ast::ArrayType * arrayType ) {
 			// TODO: encode dimension
 			printQualifiers( arrayType );
@@ -531,5 +531,5 @@
 		}
 
-		void Mangler_new::postvisit( ast::ReferenceType * refType ) {
+		void Mangler_new::postvisit( const ast::ReferenceType * refType ) {
 			// don't print prefix (e.g. 'R') for reference types so that references and non-references do not overload.
 			// Further, do not print the qualifiers for a reference type (but do run printQualifers because of TypeDecls, etc.),
@@ -541,14 +541,12 @@
 		}
 
-		namespace {
-			inline std::vector< ast::ptr< ast::Type > > getTypes( const std::vector< ast::ptr< ast::DeclWithType > > & decls ) {
-				std::vector< ast::ptr< ast::Type > > ret;
-				std::transform( decls.begin(), decls.end(), std::back_inserter( ret ),
-								std::mem_fun( &ast::DeclWithType::get_type ) );
-				return ret;
-			}
-		}
-
-		void Mangler_new::postvisit( ast::FunctionType * functionType ) {
+		inline std::vector< ast::ptr< ast::Type > > getTypes( const std::vector< ast::ptr< ast::DeclWithType > > & decls ) {
+			std::vector< ast::ptr< ast::Type > > ret;
+			std::transform( decls.begin(), decls.end(), std::back_inserter( ret ),
+							std::mem_fun( &ast::DeclWithType::get_type ) );
+			return ret;
+		}
+
+		void Mangler_new::postvisit( const ast::FunctionType * functionType ) {
 			printQualifiers( functionType );
 			mangleName << Encoding::function;
@@ -560,12 +558,12 @@
 			std::vector< ast::ptr< ast::Type > > returnTypes = getTypes( functionType->returns );
 			if (returnTypes.empty()) mangleName << Encoding::void_t;
-			else acceptAll( returnTypes, *visitor );
+			else accept_each( returnTypes, *visitor );
 			mangleName << "_";
 			std::vector< ast::ptr< ast::Type > > paramTypes = getTypes( functionType->params );
-			acceptAll( paramTypes, *visitor );
+			accept_each( paramTypes, *visitor );
 			mangleName << "_";
 		}
 
-		void Mangler_new::mangleRef( ast::ReferenceToType * refType, std::string prefix ) {
+		void Mangler_new::mangleRef( const ast::ReferenceToType * refType, std::string prefix ) {
 			printQualifiers( refType );
 
@@ -573,10 +571,9 @@
 
 			if ( mangleGenericParams ) {
-				std::vector< ast::ptr< ast::Expr > >& params = refType->params;
-				if ( ! params.empty() ) {
+				if ( ! refType->params.empty() ) {
 					mangleName << "_";
-					for ( std::vector< ast::ptr< ast::Expr > >::const_iterator param = params.begin(); param != params.end(); ++param ) {
-						const ast::TypeExpr *paramType = param->as< ast::TypeExpr >();
-						assertf(paramType, "Aggregate parameters should be type expressions: %s", toCString(*param));
+					for ( const ast::Expr * param : refType->params ) {
+						auto paramType = dynamic_cast< const ast::TypeExpr * >( param );
+						assertf(paramType, "Aggregate parameters should be type expressions: %s", toCString(param));
 						maybeAccept( paramType->type.get(), *visitor );
 					}
@@ -586,17 +583,17 @@
 		}
 
-		void Mangler_new::postvisit( ast::StructInstType * aggregateUseType ) {
+		void Mangler_new::postvisit( const ast::StructInstType * aggregateUseType ) {
 			mangleRef( aggregateUseType, Encoding::struct_t );
 		}
 
-		void Mangler_new::postvisit( ast::UnionInstType * aggregateUseType ) {
+		void Mangler_new::postvisit( const ast::UnionInstType * aggregateUseType ) {
 			mangleRef( aggregateUseType, Encoding::union_t );
 		}
 
-		void Mangler_new::postvisit( ast::EnumInstType * aggregateUseType ) {
+		void Mangler_new::postvisit( const ast::EnumInstType * aggregateUseType ) {
 			mangleRef( aggregateUseType, Encoding::enum_t );
 		}
 
-		void Mangler_new::postvisit( ast::TypeInstType * typeInst ) {
+		void Mangler_new::postvisit( const ast::TypeInstType * typeInst ) {
 			VarMapType::iterator varNum = varNums.find( typeInst->name );
 			if ( varNum == varNums.end() ) {
@@ -614,16 +611,16 @@
 		}
 
-		void Mangler_new::postvisit( ast::TraitInstType * inst ) {
+		void Mangler_new::postvisit( const ast::TraitInstType * inst ) {
 			printQualifiers( inst );
 			mangleName << inst->name.size() << inst->name;
 		}
 
-		void Mangler_new::postvisit( ast::TupleType * tupleType ) {
+		void Mangler_new::postvisit( const ast::TupleType * tupleType ) {
 			printQualifiers( tupleType );
 			mangleName << Encoding::tuple << tupleType->types.size();
-			acceptAll( tupleType->types, *visitor );
-		}
-
-		void Mangler_new::postvisit( ast::VarArgsType * varArgsType ) {
+			accept_each( tupleType->types, *visitor );
+		}
+
+		void Mangler_new::postvisit( const ast::VarArgsType * varArgsType ) {
 			printQualifiers( varArgsType );
 			static const std::string vargs = "__builtin_va_list";
@@ -631,13 +628,13 @@
 		}
 
-		void Mangler_new::postvisit( ast::ZeroType * ) {
+		void Mangler_new::postvisit( const ast::ZeroType * ) {
 			mangleName << Encoding::zero;
 		}
 
-		void Mangler_new::postvisit( ast::OneType * ) {
+		void Mangler_new::postvisit( const ast::OneType * ) {
 			mangleName << Encoding::one;
 		}
 
-		void Mangler_new::postvisit( ast::QualifiedType * qualType ) {
+		void Mangler_new::postvisit( const ast::QualifiedType * qualType ) {
 			bool inqual = inQualifiedType;
 			if (! inqual ) {
@@ -655,5 +652,5 @@
 		}
 
-		void Mangler_new::postvisit( ast::TypeDecl * decl ) {
+		void Mangler_new::postvisit( const ast::TypeDecl * decl ) {
 			// TODO: is there any case where mangling a TypeDecl makes sense? If so, this code needs to be
 			// fixed to ensure that two TypeDecls mangle to the same name when they are the same type and vice versa.
@@ -672,31 +669,31 @@
 		}
 
-		void Mangler_new::printQualifiers( ast::Type * type ) {
+		void Mangler_new::printQualifiers( const ast::Type * type ) {
 			// skip if not including qualifiers
 			if ( typeMode ) return;
-			if ( ast::ParameterizedType * ptype = dynamic_cast< ast::ParameterizedType * >(type) ) {
+			if ( auto ptype = dynamic_cast< const ast::ParameterizedType * >(type) ) {
 				if ( ! ptype->forall.empty() ) {
 					std::list< std::string > assertionNames;
 					int dcount = 0, fcount = 0, vcount = 0, acount = 0;
 					mangleName << Encoding::forall;
-					for ( ast::ParameterizedType::ForallList::iterator i = ptype->forall.begin(); i != ptype->forall.end(); ++i ) {
-						switch ( (*i)->kind ) {
-							case ast::TypeVar::Kind::Dtype:
+					for ( const ast::TypeDecl * decl : ptype->forall ) {
+						switch ( decl->kind ) {
+						case ast::TypeVar::Kind::Dtype:
 							dcount++;
 							break;
-							case ast::TypeVar::Kind::Ftype:
+						case ast::TypeVar::Kind::Ftype:
 							fcount++;
 							break;
-							case ast::TypeVar::Kind::Ttype:
+						case ast::TypeVar::Kind::Ttype:
 							vcount++;
 							break;
-							default:
+						default:
 							assert( false );
 						} // switch
-						varNums[ (*i)->name ] = std::make_pair( nextVarNum, (int)(*i)->kind );
-						for ( std::vector< ast::ptr< ast::DeclWithType > >::const_iterator assert = (*i)->assertions.begin(); assert != (*i)->assertions.end(); ++assert ) {
+						varNums[ decl->name ] = std::make_pair( nextVarNum, (int)decl->kind );
+						for ( const ast::DeclWithType * assert : decl->assertions ) {
 							ast::Pass<Mangler_new> sub_mangler( 
 								mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums );
-							(*assert)->accept( sub_mangler );
+							assert->accept( sub_mangler );
 							assertionNames.push_back( sub_mangler.pass.get_mangleName() );
 							acount++;
