Index: src/AST/Convert.cpp
===================================================================
--- src/AST/Convert.cpp	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/AST/Convert.cpp	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -518,5 +518,5 @@
 	}
 
-	const ast::Stmt * visit( const ast::WithStmt * node ) override final {
+	const ast::Decl * visit( const ast::WithStmt * node ) override final {
 		if ( inCache( node ) ) return nullptr;
 		auto stmt = new WithStmt(
@@ -524,5 +524,6 @@
 			get<Statement>().accept1( node->stmt )
 		);
-		return stmtPostamble( stmt, node );
+		declPostamble( stmt, node );
+		return nullptr;
 	}
 
@@ -1050,6 +1051,6 @@
 				get<Expression>().accept1(node->expr),
 				inCache(node->deleteStmt) ?
-					this->node :
-					get<BaseSyntaxNode>().accept1(node->deleteStmt)
+					strict_dynamic_cast<Declaration*>(this->node) :
+					get<Declaration>().accept1(node->deleteStmt)
 			)
 		);
@@ -1366,5 +1367,5 @@
 	ast::Node * node = nullptr;
 	/// cache of nodes that might be referenced by readonly<> for de-duplication
-	std::unordered_map< BaseSyntaxNode *, ast::Node * > cache = {};
+	std::unordered_map< const BaseSyntaxNode *, ast::Node * > cache = {};
 
 	// Local Utilities:
@@ -1433,8 +1434,8 @@
 		to<std::vector>::from( make_labels( std::move( labels ) ) )
 
-	static ast::CV::Qualifiers cv( Type * ty ) { return { ty->get_qualifiers().val }; }
+	static ast::CV::Qualifiers cv( const Type * ty ) { return { ty->tq.val }; }
 
 	/// returns true and sets `node` if in cache
-	bool inCache( BaseSyntaxNode * old ) {
+	bool inCache( const BaseSyntaxNode * old ) {
 		auto it = cache.find( old );
 		if ( it == cache.end() ) return false;
@@ -1445,5 +1446,5 @@
 	// Now all the visit functions:
 
-	virtual void visit( ObjectDecl * old ) override final {
+	virtual void visit( const ObjectDecl * old ) override final {
 		auto&& type = GET_ACCEPT_1(type, Type);
 		auto&& init = GET_ACCEPT_1(init, Init);
@@ -1476,5 +1477,5 @@
 	}
 
-	virtual void visit( FunctionDecl * old ) override final {
+	virtual void visit( const FunctionDecl * old ) override final {
 		if ( inCache( old ) ) return;
 		auto decl = new ast::FunctionDecl{
@@ -1509,5 +1510,5 @@
 	}
 
-	virtual void visit( StructDecl * old ) override final {
+	virtual void visit( const StructDecl * old ) override final {
 		if ( inCache( old ) ) return;
 		auto decl = new ast::StructDecl(
@@ -1534,5 +1535,5 @@
 	}
 
-	virtual void visit( UnionDecl * old ) override final {
+	virtual void visit( const UnionDecl * old ) override final {
 		if ( inCache( old ) ) return;
 		auto decl = new ast::UnionDecl(
@@ -1554,5 +1555,5 @@
 	}
 
-	virtual void visit( EnumDecl * old ) override final {
+	virtual void visit( const EnumDecl * old ) override final {
 		if ( inCache( old ) ) return;
 		auto decl = new ast::EnumDecl(
@@ -1574,5 +1575,5 @@
 	}
 
-	virtual void visit( TraitDecl * old ) override final {
+	virtual void visit( const TraitDecl * old ) override final {
 		if ( inCache( old ) ) return;
 		auto decl = new ast::TraitDecl(
@@ -1594,5 +1595,5 @@
 	}
 
-	virtual void visit( TypeDecl * old ) override final {
+	virtual void visit( const TypeDecl * old ) override final {
 		if ( inCache( old ) ) return;
 		auto decl = new ast::TypeDecl{
@@ -1614,5 +1615,5 @@
 	}
 
-	virtual void visit( TypedefDecl * old ) override final {
+	virtual void visit( const TypedefDecl * old ) override final {
 		auto decl = new ast::TypedefDecl(
 			old->location,
@@ -1631,5 +1632,5 @@
 	}
 
-	virtual void visit( AsmDecl * old ) override final {
+	virtual void visit( const AsmDecl * old ) override final {
 		auto decl = new ast::AsmDecl{
 			old->location,
@@ -1643,5 +1644,5 @@
 	}
 
-	virtual void visit( StaticAssertDecl * old ) override final {
+	virtual void visit( const StaticAssertDecl * old ) override final {
 		auto decl = new ast::StaticAssertDecl{
 			old->location,
@@ -1656,5 +1657,5 @@
 	}
 
-	virtual void visit( CompoundStmt * old ) override final {
+	virtual void visit( const CompoundStmt * old ) override final {
 		if ( inCache( old ) ) return;
 		auto stmt = new ast::CompoundStmt(
@@ -1668,5 +1669,5 @@
 	}
 
-	virtual void visit( ExprStmt * old ) override final {
+	virtual void visit( const ExprStmt * old ) override final {
 		if ( inCache( old ) ) return;
 		this->node = new ast::ExprStmt(
@@ -1678,5 +1679,5 @@
 	}
 
-	virtual void visit( AsmStmt * old ) override final {
+	virtual void visit( const AsmStmt * old ) override final {
 		if ( inCache( old ) ) return;
 		this->node = new ast::AsmStmt(
@@ -1693,5 +1694,5 @@
 	}
 
-	virtual void visit( DirectiveStmt * old ) override final {
+	virtual void visit( const DirectiveStmt * old ) override final {
 		if ( inCache( old ) ) return;
 		this->node = new ast::DirectiveStmt(
@@ -1703,5 +1704,5 @@
 	}
 
-	virtual void visit( IfStmt * old ) override final {
+	virtual void visit( const IfStmt * old ) override final {
 		if ( inCache( old ) ) return;
 		this->node = new ast::IfStmt(
@@ -1716,5 +1717,5 @@
 	}
 
-	virtual void visit( SwitchStmt * old ) override final {
+	virtual void visit( const SwitchStmt * old ) override final {
 		if ( inCache( old ) ) return;
 		this->node = new ast::SwitchStmt(
@@ -1727,5 +1728,5 @@
 	}
 
-	virtual void visit( CaseStmt * old ) override final {
+	virtual void visit( const CaseStmt * old ) override final {
 		if ( inCache( old ) ) return;
 		this->node = new ast::CaseStmt(
@@ -1738,5 +1739,5 @@
 	}
 
-	virtual void visit( WhileStmt * old ) override final {
+	virtual void visit( const WhileStmt * old ) override final {
 		if ( inCache( old ) ) return;
 		this->node = new ast::WhileStmt(
@@ -1751,5 +1752,5 @@
 	}
 
-	virtual void visit( ForStmt * old ) override final {
+	virtual void visit( const ForStmt * old ) override final {
 		if ( inCache( old ) ) return;
 		this->node = new ast::ForStmt(
@@ -1764,5 +1765,5 @@
 	}
 
-	virtual void visit( BranchStmt * old ) override final {
+	virtual void visit( const BranchStmt * old ) override final {
 		if ( inCache( old ) ) return;
 		if (old->computedTarget) {
@@ -1801,5 +1802,5 @@
 	}
 
-	virtual void visit( ReturnStmt * old ) override final {
+	virtual void visit( const ReturnStmt * old ) override final {
 		if ( inCache( old ) ) return;
 		this->node = new ast::ReturnStmt(
@@ -1811,5 +1812,5 @@
 	}
 
-	virtual void visit( ThrowStmt * old ) override final {
+	virtual void visit( const ThrowStmt * old ) override final {
 		if ( inCache( old ) ) return;
 		ast::ExceptionKind kind;
@@ -1835,5 +1836,5 @@
 	}
 
-	virtual void visit( TryStmt * old ) override final {
+	virtual void visit( const TryStmt * old ) override final {
 		if ( inCache( old ) ) return;
 		this->node = new ast::TryStmt(
@@ -1847,5 +1848,5 @@
 	}
 
-	virtual void visit( CatchStmt * old ) override final {
+	virtual void visit( const CatchStmt * old ) override final {
 		if ( inCache( old ) ) return;
 		ast::ExceptionKind kind;
@@ -1872,5 +1873,5 @@
 	}
 
-	virtual void visit( FinallyStmt * old ) override final {
+	virtual void visit( const FinallyStmt * old ) override final {
 		if ( inCache( old ) ) return;
 		this->node = new ast::FinallyStmt(
@@ -1882,5 +1883,5 @@
 	}
 
-	virtual void visit( WaitForStmt * old ) override final {
+	virtual void visit( const WaitForStmt * old ) override final {
 		if ( inCache( old ) ) return;
 		ast::WaitForStmt * stmt = new ast::WaitForStmt(
@@ -1914,16 +1915,15 @@
 	}
 
-	virtual void visit( WithStmt * old ) override final {
+	virtual void visit( const WithStmt * old ) override final {
 		if ( inCache( old ) ) return;
 		this->node = new ast::WithStmt(
 			old->location,
 			GET_ACCEPT_V(exprs, Expr),
-			GET_ACCEPT_1(stmt, Stmt),
-			GET_LABELS_V(old->labels)
+			GET_ACCEPT_1(stmt, Stmt)
 		);
 		cache.emplace( old, this->node );
 	}
 
-	virtual void visit( NullStmt * old ) override final {
+	virtual void visit( const NullStmt * old ) override final {
 		if ( inCache( old ) ) return;
 		this->node = new ast::NullStmt(
@@ -1934,5 +1934,5 @@
 	}
 
-	virtual void visit( DeclStmt * old ) override final {
+	virtual void visit( const DeclStmt * old ) override final {
 		if ( inCache( old ) ) return;
 		this->node = new ast::DeclStmt(
@@ -1944,5 +1944,5 @@
 	}
 
-	virtual void visit( ImplicitCtorDtorStmt * old ) override final {
+	virtual void visit( const ImplicitCtorDtorStmt * old ) override final {
 		if ( inCache( old ) ) return;
 		auto stmt = new ast::ImplicitCtorDtorStmt(
@@ -2001,5 +2001,5 @@
 	}
 
-	ast::Expr * visitBaseExpr_SkipResultType(Expression * old, ast::Expr * nw) {
+	ast::Expr * visitBaseExpr_SkipResultType( const Expression * old, ast::Expr * nw) {
 
 		nw->env    = convertTypeSubstitution(old->env);
@@ -2011,5 +2011,5 @@
 	}
 
-	ast::Expr * visitBaseExpr(Expression * old, ast::Expr * nw) {
+	ast::Expr * visitBaseExpr( const Expression * old, ast::Expr * nw) {
 
 		nw->result = GET_ACCEPT_1(result, Type);
@@ -2017,5 +2017,5 @@
 	}
 
-	virtual void visit( ApplicationExpr * old ) override final {
+	virtual void visit( const ApplicationExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::ApplicationExpr(
@@ -2027,5 +2027,5 @@
 	}
 
-	virtual void visit( UntypedExpr * old ) override final {
+	virtual void visit( const UntypedExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::UntypedExpr(
@@ -2037,5 +2037,5 @@
 	}
 
-	virtual void visit( NameExpr * old ) override final {
+	virtual void visit( const NameExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::NameExpr(
@@ -2046,5 +2046,5 @@
 	}
 
-	virtual void visit( CastExpr * old ) override final {
+	virtual void visit( const CastExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::CastExpr(
@@ -2056,5 +2056,5 @@
 	}
 
-	virtual void visit( KeywordCastExpr * old) override final {
+	virtual void visit( const KeywordCastExpr * old) override final {
 		ast::KeywordCastExpr::Target castTarget = ast::KeywordCastExpr::NUMBER_OF_TARGETS;
 		switch (old->target) {
@@ -2081,5 +2081,5 @@
 	}
 
-	virtual void visit( VirtualCastExpr * old ) override final {
+	virtual void visit( const VirtualCastExpr * old ) override final {
 		this->node = visitBaseExpr_SkipResultType( old,
 			new ast::VirtualCastExpr(
@@ -2091,5 +2091,5 @@
 	}
 
-	virtual void visit( AddressExpr * old ) override final {
+	virtual void visit( const AddressExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::AddressExpr(
@@ -2100,5 +2100,5 @@
 	}
 
-	virtual void visit( LabelAddressExpr * old ) override final {
+	virtual void visit( const LabelAddressExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::LabelAddressExpr(
@@ -2109,5 +2109,5 @@
 	}
 
-	virtual void visit( UntypedMemberExpr * old ) override final {
+	virtual void visit( const UntypedMemberExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::UntypedMemberExpr(
@@ -2119,5 +2119,5 @@
 	}
 
-	virtual void visit( MemberExpr * old ) override final {
+	virtual void visit( const MemberExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::MemberExpr(
@@ -2129,5 +2129,5 @@
 	}
 
-	virtual void visit( VariableExpr * old ) override final {
+	virtual void visit( const VariableExpr * old ) override final {
 		auto expr = new ast::VariableExpr(
 			old->location
@@ -2140,16 +2140,16 @@
 	}
 
-	virtual void visit( ConstantExpr * old ) override final {
+	virtual void visit( const ConstantExpr * old ) override final {
 		ast::ConstantExpr *rslt = new ast::ConstantExpr(
 			old->location,
 			GET_ACCEPT_1(result, Type),
-			old->constant.get_value(),
+			old->constant.rep,
 			old->constant.ival
 		);
-		rslt->underlyer = getAccept1< ast::Type, Type* >( old->constant.get_type() );
+		rslt->underlyer = getAccept1< ast::Type, Type* >( old->constant.type );
 		this->node = visitBaseExpr( old, rslt );
 	}
 
-	virtual void visit( SizeofExpr * old ) override final {
+	virtual void visit( const SizeofExpr * old ) override final {
 		assert (old->expr || old->type);
 		assert (! (old->expr && old->type));
@@ -2172,5 +2172,5 @@
 	}
 
-	virtual void visit( AlignofExpr * old ) override final {
+	virtual void visit( const AlignofExpr * old ) override final {
 		assert (old->expr || old->type);
 		assert (! (old->expr && old->type));
@@ -2193,5 +2193,5 @@
 	}
 
-	virtual void visit( UntypedOffsetofExpr * old ) override final {
+	virtual void visit( const UntypedOffsetofExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::UntypedOffsetofExpr(
@@ -2203,5 +2203,5 @@
 	}
 
-	virtual void visit( OffsetofExpr * old ) override final {
+	virtual void visit( const OffsetofExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::OffsetofExpr(
@@ -2213,5 +2213,5 @@
 	}
 
-	virtual void visit( OffsetPackExpr * old ) override final {
+	virtual void visit( const OffsetPackExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::OffsetPackExpr(
@@ -2222,5 +2222,5 @@
 	}
 
-	virtual void visit( LogicalExpr * old ) override final {
+	virtual void visit( const LogicalExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::LogicalExpr(
@@ -2235,5 +2235,5 @@
 	}
 
-	virtual void visit( ConditionalExpr * old ) override final {
+	virtual void visit( const ConditionalExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::ConditionalExpr(
@@ -2246,5 +2246,5 @@
 	}
 
-	virtual void visit( CommaExpr * old ) override final {
+	virtual void visit( const CommaExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::CommaExpr(
@@ -2256,5 +2256,5 @@
 	}
 
-	virtual void visit( TypeExpr * old ) override final {
+	virtual void visit( const TypeExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::TypeExpr(
@@ -2265,5 +2265,5 @@
 	}
 
-	virtual void visit( AsmExpr * old ) override final {
+	virtual void visit( const AsmExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::AsmExpr(
@@ -2276,5 +2276,5 @@
 	}
 
-	virtual void visit( ImplicitCopyCtorExpr * old ) override final {
+	virtual void visit( const ImplicitCopyCtorExpr * old ) override final {
 		auto rslt = new ast::ImplicitCopyCtorExpr(
 			old->location,
@@ -2285,5 +2285,5 @@
 	}
 
-	virtual void visit( ConstructorExpr * old ) override final {
+	virtual void visit( const ConstructorExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::ConstructorExpr(
@@ -2294,5 +2294,5 @@
 	}
 
-	virtual void visit( CompoundLiteralExpr * old ) override final {
+	virtual void visit( const CompoundLiteralExpr * old ) override final {
 		this->node = visitBaseExpr_SkipResultType( old,
 			new ast::CompoundLiteralExpr(
@@ -2304,5 +2304,5 @@
 	}
 
-	virtual void visit( RangeExpr * old ) override final {
+	virtual void visit( const RangeExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::RangeExpr(
@@ -2314,5 +2314,5 @@
 	}
 
-	virtual void visit( UntypedTupleExpr * old ) override final {
+	virtual void visit( const UntypedTupleExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::UntypedTupleExpr(
@@ -2323,5 +2323,5 @@
 	}
 
-	virtual void visit( TupleExpr * old ) override final {
+	virtual void visit( const TupleExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::TupleExpr(
@@ -2332,5 +2332,5 @@
 	}
 
-	virtual void visit( TupleIndexExpr * old ) override final {
+	virtual void visit( const TupleIndexExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::TupleIndexExpr(
@@ -2342,5 +2342,5 @@
 	}
 
-	virtual void visit( TupleAssignExpr * old ) override final {
+	virtual void visit( const TupleAssignExpr * old ) override final {
 		this->node = visitBaseExpr_SkipResultType( old,
 			new ast::TupleAssignExpr(
@@ -2352,5 +2352,5 @@
 	}
 
-	virtual void visit( StmtExpr * old ) override final {
+	virtual void visit( const StmtExpr * old ) override final {
 		auto rslt = new ast::StmtExpr(
 			old->location,
@@ -2363,5 +2363,5 @@
 	}
 
-	virtual void visit( UniqueExpr * old ) override final {
+	virtual void visit( const UniqueExpr * old ) override final {
 		auto rslt = new ast::UniqueExpr(
 			old->location,
@@ -2375,5 +2375,5 @@
 	}
 
-	virtual void visit( UntypedInitExpr * old ) override final {
+	virtual void visit( const UntypedInitExpr * old ) override final {
 		std::deque<ast::InitAlternative> initAlts;
 		for (auto ia : old->initAlts) {
@@ -2392,5 +2392,5 @@
 	}
 
-	virtual void visit( InitExpr * old ) override final {
+	virtual void visit( const InitExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::InitExpr(
@@ -2402,5 +2402,5 @@
 	}
 
-	virtual void visit( DeletedExpr * old ) override final {
+	virtual void visit( const DeletedExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::DeletedExpr(
@@ -2408,11 +2408,11 @@
 				GET_ACCEPT_1(expr, Expr),
 				inCache(old->deleteStmt) ?
-					this->node :
-					GET_ACCEPT_1(deleteStmt, Node)
-			)
-		);
-	}
-
-	virtual void visit( DefaultArgExpr * old ) override final {
+					strict_dynamic_cast<ast::Decl*>(this->node) :
+					GET_ACCEPT_1(deleteStmt, Decl)
+			)
+		);
+	}
+
+	virtual void visit( const DefaultArgExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::DefaultArgExpr(
@@ -2423,5 +2423,5 @@
 	}
 
-	virtual void visit( GenericExpr * old ) override final {
+	virtual void visit( const GenericExpr * old ) override final {
 		std::vector<ast::GenericExpr::Association> associations;
 		for (auto association : old->associations) {
@@ -2440,5 +2440,5 @@
 	}
 
-	void visitType( Type * old, ast::Type * type ) {
+	void visitType( const Type * old, ast::Type * type ) {
 		// Some types do this in their constructor so add a check.
 		if ( !old->attributes.empty() && type->attributes.empty() ) {
@@ -2448,9 +2448,9 @@
 	}
 
-	virtual void visit( VoidType * old ) override final {
+	virtual void visit( const VoidType * old ) override final {
 		visitType( old, new ast::VoidType{ cv( old ) } );
 	}
 
-	virtual void visit( BasicType * old ) override final {
+	virtual void visit( const BasicType * old ) override final {
 		auto type = new ast::BasicType{ (ast::BasicType::Kind)(unsigned)old->kind, cv( old ) };
 		// I believe this should always be a BasicType.
@@ -2461,5 +2461,5 @@
 	}
 
-	virtual void visit( PointerType * old ) override final {
+	virtual void visit( const PointerType * old ) override final {
 		visitType( old, new ast::PointerType{
 			GET_ACCEPT_1( base, Type ),
@@ -2471,5 +2471,5 @@
 	}
 
-	virtual void visit( ArrayType * old ) override final {
+	virtual void visit( const ArrayType * old ) override final {
 		visitType( old, new ast::ArrayType{
 			GET_ACCEPT_1( base, Type ),
@@ -2481,5 +2481,5 @@
 	}
 
-	virtual void visit( ReferenceType * old ) override final {
+	virtual void visit( const ReferenceType * old ) override final {
 		visitType( old, new ast::ReferenceType{
 			GET_ACCEPT_1( base, Type ),
@@ -2488,5 +2488,5 @@
 	}
 
-	virtual void visit( QualifiedType * old ) override final {
+	virtual void visit( const QualifiedType * old ) override final {
 		visitType( old, new ast::QualifiedType{
 			GET_ACCEPT_1( parent, Type ),
@@ -2496,5 +2496,5 @@
 	}
 
-	virtual void visit( FunctionType * old ) override final {
+	virtual void visit( const FunctionType * old ) override final {
 		auto ty = new ast::FunctionType {
 			(ast::ArgumentFlag)old->isVarArgs,
@@ -2507,5 +2507,5 @@
 	}
 
-	void postvisit( ReferenceToType * old, ast::ReferenceToType * ty ) {
+	void postvisit( const ReferenceToType * old, ast::ReferenceToType * ty ) {
 		ty->forall = GET_ACCEPT_V( forall, TypeDecl );
 		ty->params = GET_ACCEPT_V( parameters, Expr );
@@ -2514,5 +2514,5 @@
 	}
 
-	virtual void visit( StructInstType * old ) override final {
+	virtual void visit( const StructInstType * old ) override final {
 		ast::StructInstType * ty;
 		if ( old->baseStruct ) {
@@ -2532,5 +2532,5 @@
 	}
 
-	virtual void visit( UnionInstType * old ) override final {
+	virtual void visit( const UnionInstType * old ) override final {
 		ast::UnionInstType * ty;
 		if ( old->baseUnion ) {
@@ -2550,5 +2550,5 @@
 	}
 
-	virtual void visit( EnumInstType * old ) override final {
+	virtual void visit( const EnumInstType * old ) override final {
 		ast::EnumInstType * ty;
 		if ( old->baseEnum ) {
@@ -2568,5 +2568,5 @@
 	}
 
-	virtual void visit( TraitInstType * old ) override final {
+	virtual void visit( const TraitInstType * old ) override final {
 		ast::TraitInstType * ty;
 		if ( old->baseTrait ) {
@@ -2586,5 +2586,5 @@
 	}
 
-	virtual void visit( TypeInstType * old ) override final {
+	virtual void visit( const TypeInstType * old ) override final {
 		ast::TypeInstType * ty;
 		if ( old->baseType ) {
@@ -2606,5 +2606,5 @@
 	}
 
-	virtual void visit( TupleType * old ) override final {
+	virtual void visit( const TupleType * old ) override final {
 		visitType( old, new ast::TupleType{
 			GET_ACCEPT_V( types, Type ),
@@ -2614,5 +2614,5 @@
 	}
 
-	virtual void visit( TypeofType * old ) override final {
+	virtual void visit( const TypeofType * old ) override final {
 		visitType( old, new ast::TypeofType{
 			GET_ACCEPT_1( expr, Expr ),
@@ -2622,25 +2622,25 @@
 	}
 
-	virtual void visit( AttrType * ) override final {
+	virtual void visit( const AttrType * ) override final {
 		assertf( false, "AttrType deprecated in new AST." );
 	}
 
-	virtual void visit( VarArgsType * old ) override final {
+	virtual void visit( const VarArgsType * old ) override final {
 		visitType( old, new ast::VarArgsType{ cv( old ) } );
 	}
 
-	virtual void visit( ZeroType * old ) override final {
+	virtual void visit( const ZeroType * old ) override final {
 		visitType( old, new ast::ZeroType{ cv( old ) } );
 	}
 
-	virtual void visit( OneType * old ) override final {
+	virtual void visit( const OneType * old ) override final {
 		visitType( old, new ast::OneType{ cv( old ) } );
 	}
 
-	virtual void visit( GlobalScopeType * old ) override final {
+	virtual void visit( const GlobalScopeType * old ) override final {
 		visitType( old, new ast::GlobalScopeType{} );
 	}
 
-	virtual void visit( Designation * old ) override final {
+	virtual void visit( const Designation * old ) override final {
 		this->node = new ast::Designation(
 			old->location,
@@ -2649,5 +2649,5 @@
 	}
 
-	virtual void visit( SingleInit * old ) override final {
+	virtual void visit( const SingleInit * old ) override final {
 		this->node = new ast::SingleInit(
 			old->location,
@@ -2657,5 +2657,5 @@
 	}
 
-	virtual void visit( ListInit * old ) override final {
+	virtual void visit( const ListInit * old ) override final {
 		this->node = new ast::ListInit(
 			old->location,
@@ -2666,5 +2666,5 @@
 	}
 
-	virtual void visit( ConstructorInit * old ) override final {
+	virtual void visit( const ConstructorInit * old ) override final {
 		this->node = new ast::ConstructorInit(
 			old->location,
@@ -2675,5 +2675,5 @@
 	}
 
-	virtual void visit( Constant * ) override final {
+	virtual void visit( const Constant * ) override final {
 		// Handled in visit( ConstantEpxr * ).
 		// In the new tree, Constant fields are inlined into containing ConstantExpression.
@@ -2681,5 +2681,5 @@
 	}
 
-	virtual void visit( Attribute * old ) override final {
+	virtual void visit( const Attribute * old ) override final {
 		this->node = new ast::Attribute(
 			old->name,
@@ -2688,5 +2688,5 @@
 	}
 
-	virtual void visit( AttrExpr * ) override final {
+	virtual void visit( const AttrExpr * ) override final {
 		assertf( false, "AttrExpr deprecated in new AST." );
 	}
Index: src/AST/Decl.hpp
===================================================================
--- src/AST/Decl.hpp	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/AST/Decl.hpp	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -104,7 +104,7 @@
 	ptr<Expr> bitfieldWidth;
 
-	ObjectDecl( const CodeLocation & loc, const std::string & name, const Type * type, 
-		const Init * init = nullptr, Storage::Classes storage = {}, 
-		Linkage::Spec linkage = Linkage::C, const Expr * bitWd = nullptr, 
+	ObjectDecl( const CodeLocation & loc, const std::string & name, const Type * type,
+		const Init * init = nullptr, Storage::Classes storage = {},
+		Linkage::Spec linkage = Linkage::C, const Expr * bitWd = nullptr,
 		std::vector< ptr<Attribute> > && attrs = {}, Function::Specs fs = {} )
 	: DeclWithType( loc, name, storage, linkage, std::move(attrs), fs ), type( type ),
@@ -325,4 +325,19 @@
 };
 
+/// With statement `with (...) ...`
+class WithStmt final : public Decl {
+public:
+	std::vector<ptr<Expr>> exprs;
+	ptr<Stmt> stmt;
+
+	WithStmt( const CodeLocation & loc, std::vector<ptr<Expr>> && exprs, const Stmt * stmt )
+	: Decl(loc, "", Storage::Auto, Linkage::Cforall), exprs(std::move(exprs)), stmt(stmt) {}
+
+	const Decl * accept( Visitor & v ) const override { return v.visit( this ); }
+private:
+	WithStmt * clone() const override { return new WithStmt{ *this }; }
+	MUTATE_FRIEND
+};
+
 class AsmDecl : public Decl {
 public:
Index: src/AST/Expr.hpp
===================================================================
--- src/AST/Expr.hpp	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/AST/Expr.hpp	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -50,6 +50,6 @@
 
 	ParamEntry() : decl( 0 ), declptr( nullptr ), actualType( nullptr ), formalType( nullptr ), expr( nullptr ) {}
-	ParamEntry( 
-		UniqueId id, const Decl * declptr, const Type * actual, const Type * formal, 
+	ParamEntry(
+		UniqueId id, const Decl * declptr, const Type * actual, const Type * formal,
 		const Expr * e )
 	: decl( id ), declptr( declptr ), actualType( actual ), formalType( formal ), expr( e ) {}
@@ -115,7 +115,7 @@
 			case Empty: new(&data.resnSlots) ResnSlots{}; mode = Slots; // fallthrough
 			case Slots: return data.resnSlots;
-			case Params: assert(!"Cannot return to resnSlots from Params");
+			case Params: assertf(false, "Cannot return to resnSlots from Params"); abort();
 			}
-			return *((ResnSlots*)nullptr);
+			assertf(false, "unreachable");
 		}
 
@@ -124,6 +124,6 @@
 				return data.resnSlots;
 			}
-			assert(!"Mode was not already resnSlots");
-			return *((ResnSlots*)nullptr);
+			assertf(false, "Mode was not already resnSlots");
+			abort();
 		}
 
@@ -134,6 +134,5 @@
 			case Params: return data.inferParams;
 			}
-			assert(!"unreachable");
-			return *((InferredParams*)nullptr);
+			assertf(false, "unreachable");
 		}
 
@@ -142,14 +141,14 @@
 				return data.inferParams;
 			}
-			assert(!"Mode was not already Params");
-			return *((InferredParams*)nullptr);
+			assertf(false, "Mode was not already Params");
+			abort();
 		}
 
 		void set_inferParams( InferredParams && ps ) {
 			switch(mode) {
-			case Slots: 
+			case Slots:
 				data.resnSlots.~ResnSlots();
 				// fallthrough
-			case Empty: 
+			case Empty:
 				new(&data.inferParams) InferredParams{ std::move( ps ) };
 				mode = Params;
@@ -175,5 +174,5 @@
 					data.inferParams[p.first] = std::move(p.second);
 				}
-			} else assert(!"invalid mode");
+			} else assertf(false, "invalid mode");
 		}
 	};
@@ -387,5 +386,5 @@
 
 	ConstantExpr(
-		const CodeLocation & loc, const Type * ty, const std::string & r, 
+		const CodeLocation & loc, const Type * ty, const std::string & r,
 			std::optional<unsigned long long> i )
 	: Expr( loc, ty ), rep( r ), ival( i ) {}
@@ -773,7 +772,7 @@
 public:
 	ptr<Expr> expr;
-	readonly<Node> deleteStmt;
-
-	DeletedExpr( const CodeLocation & loc, const Expr * e, const Node * del )
+	readonly<Decl> deleteStmt;
+
+	DeletedExpr( const CodeLocation & loc, const Expr * e, const Decl * del )
 	: Expr( loc, e->result ), expr( e ), deleteStmt( del ) { assert( expr->result ); }
 
Index: src/AST/Pass.hpp
===================================================================
--- src/AST/Pass.hpp	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/AST/Pass.hpp	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -115,5 +115,5 @@
 	const ast::Stmt *             visit( const ast::FinallyStmt          * ) override final;
 	const ast::Stmt *             visit( const ast::WaitForStmt          * ) override final;
-	const ast::Stmt *             visit( const ast::WithStmt             * ) override final;
+	const ast::Decl *             visit( const ast::WithStmt             * ) override final;
 	const ast::NullStmt *         visit( const ast::NullStmt             * ) override final;
 	const ast::Stmt *             visit( const ast::DeclStmt             * ) override final;
Index: src/AST/Pass.impl.hpp
===================================================================
--- src/AST/Pass.impl.hpp	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/AST/Pass.impl.hpp	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -909,5 +909,5 @@
 // WithStmt
 template< typename pass_t >
-const ast::Stmt * ast::Pass< pass_t >::visit( const ast::WithStmt * node ) {
+const ast::Decl * ast::Pass< pass_t >::visit( const ast::WithStmt * node ) {
 	VISIT_START( node );
 
Index: src/AST/Print.cpp
===================================================================
--- src/AST/Print.cpp	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/AST/Print.cpp	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -37,5 +37,5 @@
 }
 
-class Printer : public Visitor {
+class Printer final : public Visitor {
 public:
 	ostream & os;
@@ -272,5 +272,5 @@
 
 public:
-	virtual const ast::DeclWithType * visit( const ast::ObjectDecl * node ) {
+	virtual const ast::DeclWithType * visit( const ast::ObjectDecl * node ) override final {
 		if ( ! node->name.empty() ) os << node->name << ": ";
 
@@ -314,5 +314,5 @@
 	}
 
-	virtual const ast::DeclWithType * visit( const ast::FunctionDecl * node ) {
+	virtual const ast::DeclWithType * visit( const ast::FunctionDecl * node ) override final {
 		if ( !node->name.empty() ) os << node->name << ": ";
 
@@ -342,25 +342,25 @@
 	}
 
-	virtual const ast::Decl * visit( const ast::StructDecl * node ) {
+	virtual const ast::Decl * visit( const ast::StructDecl * node ) override final {
 		print(node);
 		return node;
 	}
 
-	virtual const ast::Decl * visit( const ast::UnionDecl * node ) {
+	virtual const ast::Decl * visit( const ast::UnionDecl * node ) override final {
 		print(node);
 		return node;
 	}
 
-	virtual const ast::Decl * visit( const ast::EnumDecl * node ) {
+	virtual const ast::Decl * visit( const ast::EnumDecl * node ) override final {
 		print(node);
 		return node;
 	}
 
-	virtual const ast::Decl * visit( const ast::TraitDecl * node ) {
+	virtual const ast::Decl * visit( const ast::TraitDecl * node ) override final {
 		print(node);
 		return node;
 	}
 
-	virtual const ast::Decl * visit( const ast::TypeDecl * node ) {
+	virtual const ast::Decl * visit( const ast::TypeDecl * node ) override final {
 		preprint( node );
 		if ( ! short_mode && node->init ) {
@@ -374,15 +374,15 @@
 	}
 
-	virtual const ast::Decl * visit( const ast::TypedefDecl * node ) {
-		preprint( node );
-		return node;
-	}
-
-	virtual const ast::AsmDecl * visit( const ast::AsmDecl * node ) {
+	virtual const ast::Decl * visit( const ast::TypedefDecl * node ) override final {
+		preprint( node );
+		return node;
+	}
+
+	virtual const ast::AsmDecl * visit( const ast::AsmDecl * node ) override final {
 		safe_print( node->stmt );
 		return node;
 	}
 
-	virtual const ast::StaticAssertDecl * visit( const ast::StaticAssertDecl * node ) {
+	virtual const ast::StaticAssertDecl * visit( const ast::StaticAssertDecl * node ) override final {
 		os << "Static Assert with condition: ";
 		++indent;
@@ -396,5 +396,5 @@
 	}
 
-	virtual const ast::CompoundStmt * visit( const ast::CompoundStmt * node ) {
+	virtual const ast::CompoundStmt * visit( const ast::CompoundStmt * node ) override final {
 		os << "Compound Statement:" << endl;
 		++indent;
@@ -404,5 +404,5 @@
 	}
 
-	virtual const ast::Stmt * visit( const ast::ExprStmt * node ) {
+	virtual const ast::Stmt * visit( const ast::ExprStmt * node ) override final {
 		++indent;
 		os << "Expression Statement:" << endl << indent;
@@ -412,5 +412,5 @@
 	}
 
-	virtual const ast::Stmt * visit( const ast::AsmStmt * node ) {
+	virtual const ast::Stmt * visit( const ast::AsmStmt * node ) override final {
 		os << "Assembler Statement:" << endl;
 		++indent;
@@ -433,10 +433,10 @@
 	}
 
-	virtual const ast::Stmt * visit( const ast::DirectiveStmt * node ) {
+	virtual const ast::Stmt * visit( const ast::DirectiveStmt * node ) override final {
 		os << "GCC Directive: " << node->directive << endl;
 		return node;
 	}
 
-	virtual const ast::Stmt * visit( const ast::IfStmt * node ) {
+	virtual const ast::Stmt * visit( const ast::IfStmt * node ) override final {
 		os << "If on condition:" << endl;
 		++indent;
@@ -473,5 +473,5 @@
 	}
 
-	virtual const ast::Stmt * visit( const ast::WhileStmt * node ) {
+	virtual const ast::Stmt * visit( const ast::WhileStmt * node ) override final {
 		if ( node->isDoWhile ) { os << "Do-"; }
 		os << "While on condition:" << endl;
@@ -490,5 +490,5 @@
 	}
 
-	virtual const ast::Stmt * visit( const ast::ForStmt * node ) {
+	virtual const ast::Stmt * visit( const ast::ForStmt * node ) override final {
 		os << "For Statement" << endl;
 
@@ -532,5 +532,5 @@
 	}
 
-	virtual const ast::Stmt * visit( const ast::SwitchStmt * node ) {
+	virtual const ast::Stmt * visit( const ast::SwitchStmt * node ) override final {
 		os << "Switch on condition: ";
 		safe_print( node->cond );
@@ -546,5 +546,5 @@
 	}
 
-	virtual const ast::Stmt * visit( const ast::CaseStmt * node ) {
+	virtual const ast::Stmt * visit( const ast::CaseStmt * node ) override final {
 		if ( node->isDefault() ) {
 			os << indent << "Default ";
@@ -565,5 +565,5 @@
 	}
 
-	virtual const ast::Stmt * visit( const ast::BranchStmt * node ) {
+	virtual const ast::Stmt * visit( const ast::BranchStmt * node ) override final {
 		os << "Branch (" << node->kindName() << ")" << endl;
 		++indent;
@@ -586,5 +586,5 @@
 	}
 
-	virtual const ast::Stmt * visit( const ast::ReturnStmt * node ) {
+	virtual const ast::Stmt * visit( const ast::ReturnStmt * node ) override final {
 		os << "Return Statement, returning";
 		if ( node->expr ) {
@@ -601,5 +601,5 @@
 	}
 
-	virtual const ast::Stmt * visit( const ast::ThrowStmt * node ) {
+	virtual const ast::Stmt * visit( const ast::ThrowStmt * node ) override final {
 		if ( node->target ) os << "Non-Local ";
 
@@ -621,5 +621,5 @@
 	}
 
-	virtual const ast::Stmt * visit( const ast::TryStmt * node ) {
+	virtual const ast::Stmt * visit( const ast::TryStmt * node ) override final {
 		++indent;
 		os << "Try Statement" << endl << indent-1
@@ -642,5 +642,5 @@
 	}
 
-	virtual const ast::Stmt * visit( const ast::CatchStmt * node ) {
+	virtual const ast::Stmt * visit( const ast::CatchStmt * node ) override final {
 		os << "Catch ";
 		switch ( node->kind ) {
@@ -667,5 +667,5 @@
 	}
 
-	virtual const ast::Stmt * visit( const ast::FinallyStmt * node ) {
+	virtual const ast::Stmt * visit( const ast::FinallyStmt * node ) override final {
 		os << "Finally Statement" << endl;
 		os << indent << "... with block:" << endl;
@@ -678,5 +678,5 @@
 	}
 
-	virtual const ast::Stmt * visit( const ast::WaitForStmt * node ) {
+	virtual const ast::Stmt * visit( const ast::WaitForStmt * node ) override final {
 		os << "Waitfor Statement" << endl;
 		indent += 2;
@@ -732,5 +732,5 @@
 	}
 
-	virtual const ast::Stmt * visit( const ast::WithStmt * node ) {
+	virtual const ast::Decl * visit( const ast::WithStmt * node ) override final {
 		os << "With statement" << endl;
 		os << indent << "... with expressions:" << endl;
@@ -744,5 +744,5 @@
 	}
 
-	virtual const ast::NullStmt * visit( const ast::NullStmt * node ) {
+	virtual const ast::NullStmt * visit( const ast::NullStmt * node ) override final {
 		os << "Null Statement" << endl;
 		print( node->labels );
@@ -751,5 +751,5 @@
 	}
 
-	virtual const ast::Stmt * visit( const ast::DeclStmt * node ) {
+	virtual const ast::Stmt * visit( const ast::DeclStmt * node ) override final {
 		os << "Declaration of ";
 		safe_print( node->decl );
@@ -758,5 +758,5 @@
 	}
 
-	virtual const ast::Stmt * visit( const ast::ImplicitCtorDtorStmt * node ) {
+	virtual const ast::Stmt * visit( const ast::ImplicitCtorDtorStmt * node ) override final {
 		os << "Implicit Ctor Dtor Statement" << endl;
 		os << indent << "... with Ctor/Dtor: ";
@@ -769,5 +769,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::ApplicationExpr * node ) {
+	virtual const ast::Expr * visit( const ast::ApplicationExpr * node ) override final {
 		++indent;
 		os << "Application of" << endl << indent;
@@ -784,5 +784,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::UntypedExpr * node ) {
+	virtual const ast::Expr * visit( const ast::UntypedExpr * node ) override final {
 		++indent;
 		os << "Applying untyped:" << endl;
@@ -797,5 +797,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::NameExpr * node ) {
+	virtual const ast::Expr * visit( const ast::NameExpr * node ) override final {
 		os << "Name: " << node->name;
 		postprint( node );
@@ -804,5 +804,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::AddressExpr * node ) {
+	virtual const ast::Expr * visit( const ast::AddressExpr * node ) override final {
 		os << "Address of:" << endl;
 		++indent;
@@ -815,5 +815,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::LabelAddressExpr * node ) {
+	virtual const ast::Expr * visit( const ast::LabelAddressExpr * node ) override final {
 		os << "Address of label:" << node->arg;
 
@@ -821,5 +821,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::CastExpr * node ) {
+	virtual const ast::Expr * visit( const ast::CastExpr * node ) override final {
 		++indent;
 		os << (node->isGenerated ? "Generated" : "Explicit") << " cast of:" << endl << indent;
@@ -841,5 +841,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::KeywordCastExpr * node ) {
+	virtual const ast::Expr * visit( const ast::KeywordCastExpr * node ) override final {
 		++indent;
 		os << "Keyword Cast of:" << endl << indent;
@@ -852,5 +852,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::VirtualCastExpr * node ) {
+	virtual const ast::Expr * visit( const ast::VirtualCastExpr * node ) override final {
 		++indent;
 		os << "Virtual Cast of:" << endl << indent;
@@ -869,5 +869,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::UntypedMemberExpr * node ) {
+	virtual const ast::Expr * visit( const ast::UntypedMemberExpr * node ) override final {
 		++indent;
 		os << "Untyped Member Expression, with field: " << endl << indent;
@@ -881,5 +881,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::MemberExpr * node ) {
+	virtual const ast::Expr * visit( const ast::MemberExpr * node ) override final {
 		++indent;
 		os << "Member Expression, with field:" << endl << indent;
@@ -893,5 +893,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::VariableExpr * node ) {
+	virtual const ast::Expr * visit( const ast::VariableExpr * node ) override final {
 		os << "Variable Expression: ";
 		short_print( node->var );
@@ -901,5 +901,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::ConstantExpr * node ) {
+	virtual const ast::Expr * visit( const ast::ConstantExpr * node ) override final {
 		os << "Constant Expression (" << node->rep;
 		if ( node->result ) {
@@ -913,5 +913,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::SizeofExpr * node ) {
+	virtual const ast::Expr * visit( const ast::SizeofExpr * node ) override final {
 		os << "Sizeof Expression on: ";
 		++indent;
@@ -924,5 +924,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::AlignofExpr * node ) {
+	virtual const ast::Expr * visit( const ast::AlignofExpr * node ) override final {
 		os << "Alignof Expression on: ";
 		++indent;
@@ -935,5 +935,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::UntypedOffsetofExpr * node ) {
+	virtual const ast::Expr * visit( const ast::UntypedOffsetofExpr * node ) override final {
 		os << "Untyped Offsetof Expression on member " << node->member << " of ";
 		++indent;
@@ -945,5 +945,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::OffsetofExpr * node ) {
+	virtual const ast::Expr * visit( const ast::OffsetofExpr * node ) override final {
 		os << "Offsetof Expression on member " << node->member->name << " of ";
 		++indent;
@@ -955,5 +955,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::OffsetPackExpr * node ) {
+	virtual const ast::Expr * visit( const ast::OffsetPackExpr * node ) override final {
 		os << "Offset Pack Expression on: ";
 		++indent;
@@ -965,5 +965,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::LogicalExpr * node ) {
+	virtual const ast::Expr * visit( const ast::LogicalExpr * node ) override final {
 		os << "Short-circuited operation (" << (node->isAnd ? "and" : "or") << ") on: ";
 		safe_print( node->arg1 );
@@ -975,5 +975,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::ConditionalExpr * node ) {
+	virtual const ast::Expr * visit( const ast::ConditionalExpr * node ) override final {
 		++indent;
 		os << "Conditional expression on:" << endl << indent;
@@ -989,5 +989,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::CommaExpr * node ) {
+	virtual const ast::Expr * visit( const ast::CommaExpr * node ) override final {
 		++indent;
 		os << "Comma Expression:" << endl << indent;
@@ -1001,5 +1001,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::TypeExpr * node ) {
+	virtual const ast::Expr * visit( const ast::TypeExpr * node ) override final {
 		safe_print( node->type );
 		postprint( node );
@@ -1008,5 +1008,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::AsmExpr * node ) {
+	virtual const ast::Expr * visit( const ast::AsmExpr * node ) override final {
 		os << "Asm Expression:" << endl;
 		++indent;
@@ -1019,5 +1019,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::ImplicitCopyCtorExpr * node ) {
+	virtual const ast::Expr * visit( const ast::ImplicitCopyCtorExpr * node ) override final {
 		++indent;
 		os << "Implicit Copy Constructor Expression:" << endl << indent;
@@ -1029,5 +1029,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::ConstructorExpr * node ) {
+	virtual const ast::Expr * visit( const ast::ConstructorExpr * node ) override final {
 		os <<  "Constructor Expression:" << endl << indent+1;
 		indent += 2;
@@ -1039,5 +1039,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::CompoundLiteralExpr * node ) {
+	virtual const ast::Expr * visit( const ast::CompoundLiteralExpr * node ) override final {
 		++indent;
 		os << "Compound Literal Expression: " << endl << indent;
@@ -1051,5 +1051,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::RangeExpr * node ) {
+	virtual const ast::Expr * visit( const ast::RangeExpr * node ) override final {
 		os << "Range Expression: ";
 		safe_print( node->low );
@@ -1061,5 +1061,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::UntypedTupleExpr * node ) {
+	virtual const ast::Expr * visit( const ast::UntypedTupleExpr * node ) override final {
 		os << "Untyped Tuple:" << endl;
 		++indent;
@@ -1071,5 +1071,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::TupleExpr * node ) {
+	virtual const ast::Expr * visit( const ast::TupleExpr * node ) override final {
 		os << "Tuple:" << endl;
 		++indent;
@@ -1081,5 +1081,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::TupleIndexExpr * node ) {
+	virtual const ast::Expr * visit( const ast::TupleIndexExpr * node ) override final {
 		os << "Tuple Index Expression, with tuple:" << endl;
 		++indent;
@@ -1093,5 +1093,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::TupleAssignExpr * node ) {
+	virtual const ast::Expr * visit( const ast::TupleAssignExpr * node ) override final {
 		os << "Tuple Assignment Expression, with stmt expr:" << endl;
 		++indent;
@@ -1104,5 +1104,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::StmtExpr * node ) {
+	virtual const ast::Expr * visit( const ast::StmtExpr * node ) override final {
 		++indent;
 		os << "Statement Expression:" << endl << indent;
@@ -1122,5 +1122,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::UniqueExpr * node ) {
+	virtual const ast::Expr * visit( const ast::UniqueExpr * node ) override final {
 		++indent;
 		os << "Unique Expression with id: " << node->id << endl << indent;
@@ -1136,5 +1136,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::UntypedInitExpr * node ) {
+	virtual const ast::Expr * visit( const ast::UntypedInitExpr * node ) override final {
 		++indent;
 		os << "Untyped Init Expression" << endl << indent;
@@ -1152,5 +1152,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::InitExpr * node ) {
+	virtual const ast::Expr * visit( const ast::InitExpr * node ) override final {
 		++indent;
 		os << "Init Expression" << endl << indent;
@@ -1163,5 +1163,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::DeletedExpr * node ) {
+	virtual const ast::Expr * visit( const ast::DeletedExpr * node ) override final {
 		++indent;
 		os << "Deleted Expression" << endl << indent;
@@ -1174,5 +1174,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::DefaultArgExpr * node ) {
+	virtual const ast::Expr * visit( const ast::DefaultArgExpr * node ) override final {
 		++indent;
 		os << "Default Argument Expression" << endl << indent;
@@ -1183,5 +1183,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::GenericExpr * node ) {
+	virtual const ast::Expr * visit( const ast::GenericExpr * node ) override final {
 		++indent;
 		os << "C11 _Generic Expression" << endl << indent;
@@ -1206,5 +1206,5 @@
 	}
 
-	virtual const ast::Type * visit( const ast::VoidType * node ) {
+	virtual const ast::Type * visit( const ast::VoidType * node ) override final {
 		preprint( node );
 		os << "void";
@@ -1212,5 +1212,5 @@
 	}
 
-	virtual const ast::Type * visit( const ast::BasicType * node ) {
+	virtual const ast::Type * visit( const ast::BasicType * node ) override final {
 		preprint( node );
 		os << ast::BasicType::typeNames[ node->kind ];
@@ -1218,5 +1218,5 @@
 	}
 
-	virtual const ast::Type * visit( const ast::PointerType * node ) {
+	virtual const ast::Type * visit( const ast::PointerType * node ) override final {
 		preprint( node );
 		if ( ! node->isArray() ) {
@@ -1241,5 +1241,5 @@
 	}
 
-	virtual const ast::Type * visit( const ast::ArrayType * node ) {
+	virtual const ast::Type * visit( const ast::ArrayType * node ) override final {
 		preprint( node );
 		if ( node->isStatic ) {
@@ -1265,5 +1265,5 @@
 	}
 
-	virtual const ast::Type * visit( const ast::ReferenceType * node ) {
+	virtual const ast::Type * visit( const ast::ReferenceType * node ) override final {
 		preprint( node );
 		os << "reference to ";
@@ -1273,5 +1273,5 @@
 	}
 
-	virtual const ast::Type * visit( const ast::QualifiedType * node ) {
+	virtual const ast::Type * visit( const ast::QualifiedType * node ) override final {
 		preprint( node );
 		++indent;
@@ -1286,5 +1286,5 @@
 	}
 
-	virtual const ast::Type * visit( const ast::FunctionType * node ) {
+	virtual const ast::Type * visit( const ast::FunctionType * node ) override final {
 		preprint( node );
 
@@ -1315,5 +1315,5 @@
 	}
 
-	virtual const ast::Type * visit( const ast::StructInstType * node ) {
+	virtual const ast::Type * visit( const ast::StructInstType * node ) override final {
 		preprint( node );
 		os << "instance of struct " << node->name;
@@ -1326,5 +1326,5 @@
 	}
 
-	virtual const ast::Type * visit( const ast::UnionInstType * node ) {
+	virtual const ast::Type * visit( const ast::UnionInstType * node ) override final {
 		preprint( node );
 		os << "instance of union " << node->name;
@@ -1337,5 +1337,5 @@
 	}
 
-	virtual const ast::Type * visit( const ast::EnumInstType * node ) {
+	virtual const ast::Type * visit( const ast::EnumInstType * node ) override final {
 		preprint( node );
 		os << "instance of enum " << node->name;
@@ -1348,5 +1348,5 @@
 	}
 
-	virtual const ast::Type * visit( const ast::TraitInstType * node ) {
+	virtual const ast::Type * visit( const ast::TraitInstType * node ) override final {
 		preprint( node );
 		os << "instance of trait " << node->name;
@@ -1356,5 +1356,5 @@
 	}
 
-	virtual const ast::Type * visit( const ast::TypeInstType * node ) {
+	virtual const ast::Type * visit( const ast::TypeInstType * node ) override final {
 		preprint( node );
 		os << "instance of type " << node->name
@@ -1365,5 +1365,5 @@
 	}
 
-	virtual const ast::Type * visit( const ast::TupleType * node ) {
+	virtual const ast::Type * visit( const ast::TupleType * node ) override final {
 		preprint( node );
 		os << "tuple of types" << endl;
@@ -1375,5 +1375,5 @@
 	}
 
-	virtual const ast::Type * visit( const ast::TypeofType * node ) {
+	virtual const ast::Type * visit( const ast::TypeofType * node ) override final {
 		preprint( node );
 		if ( node->kind == ast::TypeofType::Basetypeof ) { os << "base-"; }
@@ -1384,5 +1384,5 @@
 	}
 
-	virtual const ast::Type * visit( const ast::VarArgsType * node ) {
+	virtual const ast::Type * visit( const ast::VarArgsType * node ) override final {
 		preprint( node );
 		os << "builtin var args pack";
@@ -1390,5 +1390,5 @@
 	}
 
-	virtual const ast::Type * visit( const ast::ZeroType * node ) {
+	virtual const ast::Type * visit( const ast::ZeroType * node ) override final {
 		preprint( node );
 		os << "zero_t";
@@ -1396,5 +1396,5 @@
 	}
 
-	virtual const ast::Type * visit( const ast::OneType * node ) {
+	virtual const ast::Type * visit( const ast::OneType * node ) override final {
 		preprint( node );
 		os << "one_t";
@@ -1402,5 +1402,5 @@
 	}
 
-	virtual const ast::Type * visit( const ast::GlobalScopeType * node ) {
+	virtual const ast::Type * visit( const ast::GlobalScopeType * node ) override final {
 		preprint( node );
 		os << "Global Scope Type";
@@ -1408,5 +1408,5 @@
 	}
 
-	virtual const ast::Designation * visit( const ast::Designation * node ) {
+	virtual const ast::Designation * visit( const ast::Designation * node ) override final {
 		if ( node->designators.empty() ) return node;
 		os << "... designated by: " << endl;
@@ -1421,5 +1421,5 @@
 	}
 
-	virtual const ast::Init * visit( const ast::SingleInit * node ) {
+	virtual const ast::Init * visit( const ast::SingleInit * node ) override final {
 		os << "Simple Initializer: ";
 		safe_print( node->value );
@@ -1427,5 +1427,5 @@
 	}
 
-	virtual const ast::Init * visit( const ast::ListInit * node ) {
+	virtual const ast::Init * visit( const ast::ListInit * node ) override final {
 		os << "Compound initializer: " << endl;
 		++indent;
@@ -1445,5 +1445,5 @@
 	}
 
-	virtual const ast::Init * visit( const ast::ConstructorInit * node ) {
+	virtual const ast::Init * visit( const ast::ConstructorInit * node ) override final {
 		os << "Constructor initializer: " << endl;
 		if ( node->ctor ) {
@@ -1470,5 +1470,5 @@
 	}
 
-	virtual const ast::Attribute * visit( const ast::Attribute * node ) {
+	virtual const ast::Attribute * visit( const ast::Attribute * node ) override final {
 		if ( node->empty() ) return node;
 		os << "Attribute with name: " << node->name;
@@ -1481,5 +1481,5 @@
 	}
 
-	virtual const ast::TypeSubstitution * visit( const ast::TypeSubstitution * node ) {
+	virtual const ast::TypeSubstitution * visit( const ast::TypeSubstitution * node ) override final {
 		os << indent << "Types:" << endl;
 		for ( const auto& i : *node ) {
Index: src/AST/Stmt.hpp
===================================================================
--- src/AST/Stmt.hpp	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/AST/Stmt.hpp	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -382,20 +382,4 @@
 };
 
-/// With statement `with (...) ...`
-class WithStmt final : public Stmt {
-public:
-	std::vector<ptr<Expr>> exprs;
-	ptr<Stmt> stmt;
-
-	WithStmt( const CodeLocation & loc, std::vector<ptr<Expr>> && exprs, const Stmt * stmt,
-		std::vector<Label> && labels = {} )
-	: Stmt(loc, std::move(labels)), exprs(std::move(exprs)), stmt(stmt) {}
-
-	const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
-private:
-	WithStmt * clone() const override { return new WithStmt{ *this }; }
-	MUTATE_FRIEND
-};
-
 /// Any declaration in a (compound) statement.
 class DeclStmt final : public Stmt {
Index: src/AST/SymbolTable.cpp
===================================================================
--- src/AST/SymbolTable.cpp	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/AST/SymbolTable.cpp	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -73,5 +73,5 @@
 
 SymbolTable::SymbolTable()
-: idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable(), 
+: idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable(),
   prevScope(), scope( 0 ), repScope( 0 ) { ++*stats().count; }
 
@@ -171,5 +171,5 @@
 }
 
-void SymbolTable::addDeletedId( const DeclWithType * decl, const Node * deleter ) {
+void SymbolTable::addDeletedId( const DeclWithType * decl, const Decl * deleter ) {
 	// default handling of conflicts is to raise an error
 	addId( decl, OnConflict::error(), nullptr, deleter );
@@ -189,5 +189,5 @@
 			}
 		}
-		// does not need to be added to the table if both existing and added have a base that are 
+		// does not need to be added to the table if both existing and added have a base that are
 		// the same
 		return true;
@@ -209,14 +209,14 @@
 	const std::string &id = decl->name;
 
-	if ( ! typeTable ) { 
+	if ( ! typeTable ) {
 		typeTable = TypeTable::new_ptr();
 	} else {
 		++*stats().map_lookups;
 		auto existing = typeTable->find( id );
-		if ( existing != typeTable->end() 
-			&& existing->second.scope == scope 
+		if ( existing != typeTable->end()
+			&& existing->second.scope == scope
 			&& addedTypeConflicts( existing->second.decl, decl ) ) return;
 	}
-	
+
 	lazyInitScope();
 	++*stats().map_mutations;
@@ -237,6 +237,6 @@
 		++*stats().map_lookups;
 		auto existing = structTable->find( id );
-		if ( existing != structTable->end()  
-			&& existing->second.scope == scope 
+		if ( existing != structTable->end()
+			&& existing->second.scope == scope
 			&& addedDeclConflicts( existing->second.decl, decl ) ) return;
 	}
@@ -256,9 +256,9 @@
 		++*stats().map_lookups;
 		auto existing = enumTable->find( id );
-		if ( existing != enumTable->end()  
-			&& existing->second.scope == scope 
+		if ( existing != enumTable->end()
+			&& existing->second.scope == scope
 			&& addedDeclConflicts( existing->second.decl, decl ) ) return;
 	}
-	
+
 	lazyInitScope();
 	++*stats().map_mutations;
@@ -279,6 +279,6 @@
 		++*stats().map_lookups;
 		auto existing = unionTable->find( id );
-		if ( existing != unionTable->end() 
-			&& existing->second.scope == scope 
+		if ( existing != unionTable->end()
+			&& existing->second.scope == scope
 			&& addedDeclConflicts( existing->second.decl, decl ) ) return;
 	}
@@ -298,6 +298,6 @@
 		++*stats().map_lookups;
 		auto existing = traitTable->find( id );
-		if ( existing != traitTable->end() 
-			&& existing->second.scope == scope 
+		if ( existing != traitTable->end()
+			&& existing->second.scope == scope
 			&& addedDeclConflicts( existing->second.decl, decl ) ) return;
 	}
@@ -309,15 +309,15 @@
 
 
-void SymbolTable::addWith( const std::vector< ptr<Expr> > & withExprs, const Node * withStmt ) {
+void SymbolTable::addWith( const std::vector< ptr<Expr> > & withExprs, const Decl * withStmt ) {
 	for ( const Expr * expr : withExprs ) {
 		if ( ! expr->result ) continue;
 		const Type * resTy = expr->result->stripReferences();
 		auto aggrType = dynamic_cast< const ReferenceToType * >( resTy );
-		assertf( aggrType, "WithStmt expr has non-aggregate type: %s", 
+		assertf( aggrType, "WithStmt expr has non-aggregate type: %s",
 			toString( expr->result ).c_str() );
 		const AggregateDecl * aggr = aggrType->aggr();
-		assertf( aggr, "WithStmt has null aggregate from type: %s", 
+		assertf( aggr, "WithStmt has null aggregate from type: %s",
 			toString( expr->result ).c_str() );
-		
+
 		addMembers( aggr, expr, OnConflict::deleteWith( withStmt ) );
 	}
@@ -373,7 +373,7 @@
 	}
 
-	/// gets the declaration for the function acting on a type specified by otype key, 
+	/// gets the declaration for the function acting on a type specified by otype key,
 	/// nullptr if none such
-	const FunctionDecl * getFunctionForOtype( 
+	const FunctionDecl * getFunctionForOtype(
 			const DeclWithType * decl, const std::string & otypeKey ) {
 		auto func = dynamic_cast< const FunctionDecl * >( decl );
@@ -383,13 +383,13 @@
 }
 
-bool SymbolTable::removeSpecialOverrides( 
+bool SymbolTable::removeSpecialOverrides(
 		SymbolTable::IdData & data, SymbolTable::MangleTable::Ptr & mangleTable ) {
-	// if a type contains user defined ctor/dtor/assign, then special rules trigger, which 
-	// determine the set of ctor/dtor/assign that can be used  by the requester. In particular, 
-	// if the user defines a default ctor, then the generated default ctor is unavailable, 
-	// likewise for copy ctor and dtor. If the user defines any ctor/dtor, then no generated 
-	// field ctors are available. If the user defines any ctor then the generated default ctor 
-	// is unavailable (intrinsic default ctor must be overridden exactly). If the user defines 
-	// anything that looks like a copy constructor, then the generated copy constructor is 
+	// if a type contains user defined ctor/dtor/assign, then special rules trigger, which
+	// determine the set of ctor/dtor/assign that can be used  by the requester. In particular,
+	// if the user defines a default ctor, then the generated default ctor is unavailable,
+	// likewise for copy ctor and dtor. If the user defines any ctor/dtor, then no generated
+	// field ctors are available. If the user defines any ctor then the generated default ctor
+	// is unavailable (intrinsic default ctor must be overridden exactly). If the user defines
+	// anything that looks like a copy constructor, then the generated copy constructor is
 	// unavailable, and likewise for the assignment operator.
 
@@ -450,5 +450,5 @@
 		// if this is the first user-defined function, delete non-user-defined overloads
 		std::vector< MangleTable::value_type > deleted;
-		
+
 		for ( const auto& entry : *mangleTable ) {
 			// skip decls that aren't functions or are for the wrong type
@@ -489,5 +489,5 @@
 			if ( dataIsCopyFunc ) {
 				// remove current function if exists a user-defined copy function
-				// since the signatures for copy functions don't need to match exactly, using 
+				// since the signatures for copy functions don't need to match exactly, using
 				// a delete statement is the wrong approach
 				if ( InitTweak::isCopyFunction( decl ) ) return false;
@@ -499,5 +499,5 @@
 		}
 	}
-	
+
 	// nothing (more) to fix, return true
 	return true;
@@ -525,18 +525,18 @@
 
 bool SymbolTable::addedIdConflicts(
-		const SymbolTable::IdData & existing, const DeclWithType * added, 
-		SymbolTable::OnConflict handleConflicts, const Node * deleter ) {
-	// if we're giving the same name mangling to things of different types then there is something 
+		const SymbolTable::IdData & existing, const DeclWithType * added,
+		SymbolTable::OnConflict handleConflicts, const Decl * deleter ) {
+	// if we're giving the same name mangling to things of different types then there is something
 	// wrong
 	assert( (isObject( added ) && isObject( existing.id ) )
 		|| ( isFunction( added ) && isFunction( existing.id ) ) );
-	
+
 	if ( existing.id->linkage.is_overrideable ) {
 		// new definition shadows the autogenerated one, even at the same scope
 		return false;
-	} else if ( existing.id->linkage.is_mangled 
-			|| ResolvExpr::typesCompatible( 
+	} else if ( existing.id->linkage.is_mangled
+			|| ResolvExpr::typesCompatible(
 				added->get_type(), existing.id->get_type(), SymbolTable{} ) ) {
-		
+
 		// it is a conflict if one declaration is deleted and the other is not
 		if ( deleter && ! existing.deleter ) {
@@ -555,7 +555,7 @@
 		if ( isDefinition( added ) && isDefinition( existing.id ) ) {
 			if ( handleConflicts.mode == OnConflict::Error ) {
-				SemanticError( added, 
-					isFunction( added ) ? 
-						"duplicate function definition for " : 
+				SemanticError( added,
+					isFunction( added ) ?
+						"duplicate function definition for " :
 						"duplicate object definition for " );
 			}
@@ -572,7 +572,7 @@
 }
 
-void SymbolTable::addId( 
-		const DeclWithType * decl, SymbolTable::OnConflict handleConflicts, const Expr * baseExpr, 
-		const Node * deleter ) {
+void SymbolTable::addId(
+		const DeclWithType * decl, SymbolTable::OnConflict handleConflicts, const Expr * baseExpr,
+		const Decl * deleter ) {
 	++*stats().add_calls;
 	const std::string &name = decl->name;
@@ -581,5 +581,5 @@
 	std::string mangleName;
 	if ( decl->linkage.is_overrideable ) {
-		// mangle the name without including the appropriate suffix, so overridable routines 
+		// mangle the name without including the appropriate suffix, so overridable routines
 		// are placed into the same "bucket" as their user defined versions.
 		mangleName = Mangle::mangle( decl, Mangle::Mode{ Mangle::NoOverrideable } );
@@ -588,5 +588,5 @@
 	}
 
-	// this ensures that no two declarations with the same unmangled name at the same scope 
+	// this ensures that no two declarations with the same unmangled name at the same scope
 	// both have C linkage
 	if ( decl->linkage.is_mangled ) {
@@ -596,5 +596,5 @@
 		}
 	} else {
-		// NOTE: only correct if name mangling is completely isomorphic to C 
+		// NOTE: only correct if name mangling is completely isomorphic to C
 		// type-compatibility, which it may not be.
 		if ( hasIncompatibleCDecl( name, mangleName ) ) {
@@ -628,6 +628,6 @@
 						idTable = idTable->set(
 							name,
-							mangleTable->set( 
-								mangleName, 
+							mangleTable->set(
+								mangleName,
 								IdData{ existing->second, handleConflicts.deleter } ) );
 					}
@@ -647,5 +647,5 @@
 }
 
-void SymbolTable::addMembers( 
+void SymbolTable::addMembers(
 		const AggregateDecl * aggr, const Expr * expr, SymbolTable::OnConflict handleConflicts ) {
 	for ( const Decl * decl : aggr->members ) {
@@ -655,9 +655,9 @@
 				const Type * t = dwt->get_type()->stripReferences();
 				if ( auto rty = dynamic_cast<const ReferenceToType *>( t ) ) {
-					if ( ! dynamic_cast<const StructInstType *>(rty) 
+					if ( ! dynamic_cast<const StructInstType *>(rty)
 						&& ! dynamic_cast<const UnionInstType *>(rty) ) continue;
 					ResolvExpr::Cost cost = ResolvExpr::Cost::zero;
 					const Expr * base = ResolvExpr::referenceToRvalueConversion( expr, cost );
-					addMembers( 
+					addMembers(
 						rty->aggr(), new MemberExpr{ base->location, dwt, base }, handleConflicts );
 				}
@@ -680,5 +680,5 @@
 		if ( ! decl.second.id->linkage.is_mangled && decl.first == mangleName ) return true;
 	}
-	
+
 	return false;
 }
Index: src/AST/SymbolTable.hpp
===================================================================
--- src/AST/SymbolTable.hpp	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/AST/SymbolTable.hpp	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -37,13 +37,13 @@
 		readonly<DeclWithType> id = nullptr;  ///< Identifier of declaration
 		readonly<Expr> baseExpr = nullptr;    ///< Implied containing aggregate (from WithExpr)
-		readonly<Node> deleter = nullptr;     ///< Node deleting this declaration (if non-null)
+		readonly<Decl> deleter = nullptr;     ///< Node deleting this declaration (if non-null)
 		unsigned long scope = 0;              ///< Scope of identifier
 
 		IdData() = default;
-		IdData( const DeclWithType * i, const Expr * base, const Node * del, unsigned long s ) 
+		IdData( const DeclWithType * i, const Expr * base, const Decl * del, unsigned long s )
 		: id( i ), baseExpr( base ), deleter( del ), scope( s ) {}
-		
+
 		/// Modify an existing node with a new deleter
-		IdData( const IdData & o, const Node * del )
+		IdData( const IdData & o, const Decl * del )
 		: id( o.id ), baseExpr( o.baseExpr ), deleter( del ), scope( o.scope ) {}
 
@@ -58,5 +58,5 @@
 	struct scoped {
 		readonly<D> decl;     ///< wrapped declaration
-		unsigned long scope;  ///< scope of this declaration 
+		unsigned long scope;  ///< scope of this declaration
 
 		scoped(const D * d, unsigned long s) : decl(d), scope(s) {}
@@ -88,5 +88,5 @@
 	~SymbolTable();
 
-	// when using an indexer manually (e.g., within a mutator traversal), it is necessary to 
+	// when using an indexer manually (e.g., within a mutator traversal), it is necessary to
 	// tell the indexer explicitly when scopes begin and end
 	void enterScope();
@@ -118,5 +118,5 @@
 	void addId( const DeclWithType * decl, const Expr * baseExpr = nullptr );
 	/// Adds a deleted identifier declaration to the symbol table
-	void addDeletedId( const DeclWithType * decl, const Node * deleter );
+	void addDeletedId( const DeclWithType * decl, const Decl * deleter );
 
 	/// Adds a type to the symbol table
@@ -136,5 +136,5 @@
 
 	/// adds all of the IDs from WithStmt exprs
-	void addWith( const std::vector< ptr<Expr> > & withExprs, const Node * withStmt );
+	void addWith( const std::vector< ptr<Expr> > & withExprs, const Decl * withStmt );
 
 	/// convenience function for adding a list of Ids to the indexer
@@ -154,5 +154,5 @@
 	const SymbolTable * atScope( unsigned long i ) const;
 
-	/// Removes matching autogenerated constructors and destructors so that they will not be 
+	/// Removes matching autogenerated constructors and destructors so that they will not be
 	/// selected. If returns false, passed decl should not be added.
 	bool removeSpecialOverrides( IdData & decl, MangleTable::Ptr & mangleTable );
@@ -164,25 +164,25 @@
 			Delete  ///< Delete the earlier version with the delete statement
 		} mode;
-		const Node * deleter;  ///< Statement that deletes this expression
+		const Decl * deleter;  ///< Statement that deletes this expression
 
 	private:
 		OnConflict() : mode(Error), deleter(nullptr) {}
-		OnConflict( const Node * d ) : mode(Delete), deleter(d) {}
+		OnConflict( const Decl * d ) : mode(Delete), deleter(d) {}
 	public:
 		OnConflict( const OnConflict& ) = default;
 
 		static OnConflict error() { return {}; }
-		static OnConflict deleteWith( const Node * d ) { return { d }; }
+		static OnConflict deleteWith( const Decl * d ) { return { d }; }
 	};
 
 	/// true if the existing identifier conflicts with the added identifier
 	bool addedIdConflicts(
-		const IdData & existing, const DeclWithType * added, OnConflict handleConflicts, 
-		const Node * deleter );
+		const IdData & existing, const DeclWithType * added, OnConflict handleConflicts,
+		const Decl * deleter );
 
 	/// common code for addId, addDeletedId, etc.
-	void addId( 
-		const DeclWithType * decl, OnConflict handleConflicts, const Expr * baseExpr = nullptr, 
-		const Node * deleter = nullptr );
+	void addId(
+		const DeclWithType * decl, OnConflict handleConflicts, const Expr * baseExpr = nullptr,
+		const Decl * deleter = nullptr );
 
 	/// adds all of the members of the Aggregate (addWith helper)
Index: src/AST/Type.hpp
===================================================================
--- src/AST/Type.hpp	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/AST/Type.hpp	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -37,5 +37,6 @@
 
 template< typename T > class Pass;
-class ForallSubstitutor;
+
+struct ForallSubstitutor;
 
 class Type : public Node {
@@ -169,5 +170,5 @@
 	static const char *typeNames[];
 
-	BasicType( Kind k, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} ) 
+	BasicType( Kind k, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} )
 	: Type(q, std::move(as)), kind(k) {}
 
@@ -276,5 +277,5 @@
 public:
 	using ForallList = std::vector<ptr<TypeDecl>>;
-	
+
 	ForallList forall;
 
@@ -340,5 +341,5 @@
 	bool hoistType = false;
 
-	ReferenceToType( 
+	ReferenceToType(
 		const std::string& n, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} )
 	: ParameterizedType(q, std::move(as)), params(), name(n) {}
@@ -361,9 +362,9 @@
 	readonly<StructDecl> base;
 
-	StructInstType( 
+	StructInstType(
 		const std::string& n, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} )
 	: ReferenceToType( n, q, std::move(as) ), base() {}
 
-	StructInstType( 
+	StructInstType(
 		const StructDecl * b, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} );
 
@@ -383,9 +384,9 @@
 	readonly<UnionDecl> base;
 
-	UnionInstType( 
+	UnionInstType(
 		const std::string& n, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} )
 	: ReferenceToType( n, q, std::move(as) ), base() {}
 
-	UnionInstType( 
+	UnionInstType(
 		const UnionDecl * b, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} );
 
@@ -405,9 +406,9 @@
 	readonly<EnumDecl> base;
 
-	EnumInstType( 
+	EnumInstType(
 		const std::string& n, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} )
 	: ReferenceToType( n, q, std::move(as) ), base() {}
 
-	EnumInstType( 
+	EnumInstType(
 		const EnumDecl * b, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} );
 
@@ -427,9 +428,9 @@
 	readonly<TraitDecl> base;
 
-	TraitInstType( 
+	TraitInstType(
 		const std::string& n, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} )
 	: ReferenceToType( n, q, std::move(as) ), base() {}
-	
-	TraitInstType( 
+
+	TraitInstType(
 		const TraitDecl * b, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} );
 
@@ -451,10 +452,10 @@
 	TypeVar::Kind kind;
 
-	TypeInstType( 
+	TypeInstType(
 		const std::string& n, const TypeDecl * b, CV::Qualifiers q = {},
 		std::vector<ptr<Attribute>> && as = {} )
 	: ReferenceToType( n, q, std::move(as) ), base( b ), kind( b->kind ) {}
-	
-	TypeInstType( 
+
+	TypeInstType(
 		const std::string& n, TypeVar::Kind k, CV::Qualifiers q = {},
 		std::vector<ptr<Attribute>> && as = {} )
Index: src/AST/Visitor.hpp
===================================================================
--- src/AST/Visitor.hpp	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/AST/Visitor.hpp	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -48,5 +48,5 @@
     virtual const ast::Stmt *             visit( const ast::FinallyStmt          * ) = 0;
     virtual const ast::Stmt *             visit( const ast::WaitForStmt          * ) = 0;
-    virtual const ast::Stmt *             visit( const ast::WithStmt             * ) = 0;
+    virtual const ast::Decl *             visit( const ast::WithStmt             * ) = 0;
     virtual const ast::NullStmt *         visit( const ast::NullStmt             * ) = 0;
     virtual const ast::Stmt *             visit( const ast::DeclStmt             * ) = 0;
Index: src/Common/PassVisitor.h
===================================================================
--- src/Common/PassVisitor.h	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/Common/PassVisitor.h	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -60,102 +60,195 @@
 
 	virtual void visit( ObjectDecl * objectDecl ) override final;
+	virtual void visit( const ObjectDecl * objectDecl ) override final;
 	virtual void visit( FunctionDecl * functionDecl ) override final;
+	virtual void visit( const FunctionDecl * functionDecl ) override final;
 	virtual void visit( StructDecl * aggregateDecl ) override final;
+	virtual void visit( const StructDecl * aggregateDecl ) override final;
 	virtual void visit( UnionDecl * aggregateDecl ) override final;
+	virtual void visit( const UnionDecl * aggregateDecl ) override final;
 	virtual void visit( EnumDecl * aggregateDecl ) override final;
+	virtual void visit( const EnumDecl * aggregateDecl ) override final;
 	virtual void visit( TraitDecl * aggregateDecl ) override final;
+	virtual void visit( const TraitDecl * aggregateDecl ) override final;
 	virtual void visit( TypeDecl * typeDecl ) override final;
+	virtual void visit( const TypeDecl * typeDecl ) override final;
 	virtual void visit( TypedefDecl * typeDecl ) override final;
+	virtual void visit( const TypedefDecl * typeDecl ) override final;
 	virtual void visit( AsmDecl * asmDecl ) override final;
+	virtual void visit( const AsmDecl * asmDecl ) override final;
 	virtual void visit( StaticAssertDecl * assertDecl ) override final;
+	virtual void visit( const StaticAssertDecl * assertDecl ) override final;
 
 	virtual void visit( CompoundStmt * compoundStmt ) override final;
+	virtual void visit( const CompoundStmt * compoundStmt ) override final;
 	virtual void visit( ExprStmt * exprStmt ) override final;
+	virtual void visit( const ExprStmt * exprStmt ) override final;
 	virtual void visit( AsmStmt * asmStmt ) override final;
+	virtual void visit( const AsmStmt * asmStmt ) override final;
 	virtual void visit( DirectiveStmt * dirStmt ) override final;
+	virtual void visit( const DirectiveStmt * dirStmt ) override final;
 	virtual void visit( IfStmt * ifStmt ) override final;
+	virtual void visit( const IfStmt * ifStmt ) override final;
 	virtual void visit( WhileStmt * whileStmt ) override final;
+	virtual void visit( const WhileStmt * whileStmt ) override final;
 	virtual void visit( ForStmt * forStmt ) override final;
+	virtual void visit( const ForStmt * forStmt ) override final;
 	virtual void visit( SwitchStmt * switchStmt ) override final;
+	virtual void visit( const SwitchStmt * switchStmt ) override final;
 	virtual void visit( CaseStmt * caseStmt ) override final;
+	virtual void visit( const CaseStmt * caseStmt ) override final;
 	virtual void visit( BranchStmt * branchStmt ) override final;
+	virtual void visit( const BranchStmt * branchStmt ) override final;
 	virtual void visit( ReturnStmt * returnStmt ) override final;
+	virtual void visit( const ReturnStmt * returnStmt ) override final;
 	virtual void visit( ThrowStmt * throwStmt ) override final;
+	virtual void visit( const ThrowStmt * throwStmt ) override final;
 	virtual void visit( TryStmt * tryStmt ) override final;
+	virtual void visit( const TryStmt * tryStmt ) override final;
 	virtual void visit( CatchStmt * catchStmt ) override final;
+	virtual void visit( const CatchStmt * catchStmt ) override final;
 	virtual void visit( FinallyStmt * finallyStmt ) override final;
+	virtual void visit( const FinallyStmt * finallyStmt ) override final;
 	virtual void visit( WaitForStmt * waitforStmt ) override final;
+	virtual void visit( const WaitForStmt * waitforStmt ) override final;
 	virtual void visit( WithStmt * withStmt ) override final;
+	virtual void visit( const WithStmt * withStmt ) override final;
 	virtual void visit( NullStmt * nullStmt ) override final;
+	virtual void visit( const NullStmt * nullStmt ) override final;
 	virtual void visit( DeclStmt * declStmt ) override final;
+	virtual void visit( const DeclStmt * declStmt ) override final;
 	virtual void visit( ImplicitCtorDtorStmt * impCtorDtorStmt ) override final;
+	virtual void visit( const ImplicitCtorDtorStmt * impCtorDtorStmt ) override final;
 
 	virtual void visit( ApplicationExpr * applicationExpr ) override final;
+	virtual void visit( const ApplicationExpr * applicationExpr ) override final;
 	virtual void visit( UntypedExpr * untypedExpr ) override final;
+	virtual void visit( const UntypedExpr * untypedExpr ) override final;
 	virtual void visit( NameExpr * nameExpr ) override final;
+	virtual void visit( const NameExpr * nameExpr ) override final;
 	virtual void visit( CastExpr * castExpr ) override final;
+	virtual void visit( const CastExpr * castExpr ) override final;
 	virtual void visit( KeywordCastExpr * castExpr ) override final;
+	virtual void visit( const KeywordCastExpr * castExpr ) override final;
 	virtual void visit( VirtualCastExpr * castExpr ) override final;
+	virtual void visit( const VirtualCastExpr * castExpr ) override final;
 	virtual void visit( AddressExpr * addressExpr ) override final;
+	virtual void visit( const AddressExpr * addressExpr ) override final;
 	virtual void visit( LabelAddressExpr * labAddressExpr ) override final;
+	virtual void visit( const LabelAddressExpr * labAddressExpr ) override final;
 	virtual void visit( UntypedMemberExpr * memberExpr ) override final;
+	virtual void visit( const UntypedMemberExpr * memberExpr ) override final;
 	virtual void visit( MemberExpr * memberExpr ) override final;
+	virtual void visit( const MemberExpr * memberExpr ) override final;
 	virtual void visit( VariableExpr * variableExpr ) override final;
+	virtual void visit( const VariableExpr * variableExpr ) override final;
 	virtual void visit( ConstantExpr * constantExpr ) override final;
+	virtual void visit( const ConstantExpr * constantExpr ) override final;
 	virtual void visit( SizeofExpr * sizeofExpr ) override final;
+	virtual void visit( const SizeofExpr * sizeofExpr ) override final;
 	virtual void visit( AlignofExpr * alignofExpr ) override final;
+	virtual void visit( const AlignofExpr * alignofExpr ) override final;
 	virtual void visit( UntypedOffsetofExpr * offsetofExpr ) override final;
+	virtual void visit( const UntypedOffsetofExpr * offsetofExpr ) override final;
 	virtual void visit( OffsetofExpr * offsetofExpr ) override final;
+	virtual void visit( const OffsetofExpr * offsetofExpr ) override final;
 	virtual void visit( OffsetPackExpr * offsetPackExpr ) override final;
+	virtual void visit( const OffsetPackExpr * offsetPackExpr ) override final;
 	virtual void visit( AttrExpr * attrExpr ) override final;
+	virtual void visit( const AttrExpr * attrExpr ) override final;
 	virtual void visit( LogicalExpr * logicalExpr ) override final;
+	virtual void visit( const LogicalExpr * logicalExpr ) override final;
 	virtual void visit( ConditionalExpr * conditionalExpr ) override final;
+	virtual void visit( const ConditionalExpr * conditionalExpr ) override final;
 	virtual void visit( CommaExpr * commaExpr ) override final;
+	virtual void visit( const CommaExpr * commaExpr ) override final;
 	virtual void visit( TypeExpr * typeExpr ) override final;
+	virtual void visit( const TypeExpr * typeExpr ) override final;
 	virtual void visit( AsmExpr * asmExpr ) override final;
+	virtual void visit( const AsmExpr * asmExpr ) override final;
 	virtual void visit( ImplicitCopyCtorExpr * impCpCtorExpr ) override final;
+	virtual void visit( const ImplicitCopyCtorExpr * impCpCtorExpr ) override final;
 	virtual void visit( ConstructorExpr *  ctorExpr ) override final;
+	virtual void visit( const ConstructorExpr *  ctorExpr ) override final;
 	virtual void visit( CompoundLiteralExpr * compLitExpr ) override final;
+	virtual void visit( const CompoundLiteralExpr * compLitExpr ) override final;
 	virtual void visit( RangeExpr * rangeExpr ) override final;
+	virtual void visit( const RangeExpr * rangeExpr ) override final;
 	virtual void visit( UntypedTupleExpr * tupleExpr ) override final;
+	virtual void visit( const UntypedTupleExpr * tupleExpr ) override final;
 	virtual void visit( TupleExpr * tupleExpr ) override final;
+	virtual void visit( const TupleExpr * tupleExpr ) override final;
 	virtual void visit( TupleIndexExpr * tupleExpr ) override final;
+	virtual void visit( const TupleIndexExpr * tupleExpr ) override final;
 	virtual void visit( TupleAssignExpr * assignExpr ) override final;
+	virtual void visit( const TupleAssignExpr * assignExpr ) override final;
 	virtual void visit( StmtExpr *  stmtExpr ) override final;
+	virtual void visit( const StmtExpr *  stmtExpr ) override final;
 	virtual void visit( UniqueExpr *  uniqueExpr ) override final;
+	virtual void visit( const UniqueExpr *  uniqueExpr ) override final;
 	virtual void visit( UntypedInitExpr *  initExpr ) override final;
+	virtual void visit( const UntypedInitExpr *  initExpr ) override final;
 	virtual void visit( InitExpr *  initExpr ) override final;
+	virtual void visit( const InitExpr *  initExpr ) override final;
 	virtual void visit( DeletedExpr *  delExpr ) override final;
+	virtual void visit( const DeletedExpr *  delExpr ) override final;
 	virtual void visit( DefaultArgExpr * argExpr ) override final;
+	virtual void visit( const DefaultArgExpr * argExpr ) override final;
 	virtual void visit( GenericExpr * genExpr ) override final;
+	virtual void visit( const GenericExpr * genExpr ) override final;
 
 	virtual void visit( VoidType * basicType ) override final;
+	virtual void visit( const VoidType * basicType ) override final;
 	virtual void visit( BasicType * basicType ) override final;
+	virtual void visit( const BasicType * basicType ) override final;
 	virtual void visit( PointerType * pointerType ) override final;
+	virtual void visit( const PointerType * pointerType ) override final;
 	virtual void visit( ArrayType * arrayType ) override final;
+	virtual void visit( const ArrayType * arrayType ) override final;
 	virtual void visit( ReferenceType * referenceType ) override final;
+	virtual void visit( const ReferenceType * referenceType ) override final;
 	virtual void visit( QualifiedType * qualType ) override final;
+	virtual void visit( const QualifiedType * qualType ) override final;
 	virtual void visit( FunctionType * functionType ) override final;
+	virtual void visit( const FunctionType * functionType ) override final;
 	virtual void visit( StructInstType * aggregateUseType ) override final;
+	virtual void visit( const StructInstType * aggregateUseType ) override final;
 	virtual void visit( UnionInstType * aggregateUseType ) override final;
+	virtual void visit( const UnionInstType * aggregateUseType ) override final;
 	virtual void visit( EnumInstType * aggregateUseType ) override final;
+	virtual void visit( const EnumInstType * aggregateUseType ) override final;
 	virtual void visit( TraitInstType * aggregateUseType ) override final;
+	virtual void visit( const TraitInstType * aggregateUseType ) override final;
 	virtual void visit( TypeInstType * aggregateUseType ) override final;
+	virtual void visit( const TypeInstType * aggregateUseType ) override final;
 	virtual void visit( TupleType * tupleType ) override final;
+	virtual void visit( const TupleType * tupleType ) override final;
 	virtual void visit( TypeofType * typeofType ) override final;
+	virtual void visit( const TypeofType * typeofType ) override final;
 	virtual void visit( AttrType * attrType ) override final;
+	virtual void visit( const AttrType * attrType ) override final;
 	virtual void visit( VarArgsType * varArgsType ) override final;
+	virtual void visit( const VarArgsType * varArgsType ) override final;
 	virtual void visit( ZeroType * zeroType ) override final;
+	virtual void visit( const ZeroType * zeroType ) override final;
 	virtual void visit( OneType * oneType ) override final;
+	virtual void visit( const OneType * oneType ) override final;
 	virtual void visit( GlobalScopeType * globalType ) override final;
+	virtual void visit( const GlobalScopeType * globalType ) override final;
 
 	virtual void visit( Designation * designation ) override final;
+	virtual void visit( const Designation * designation ) override final;
 	virtual void visit( SingleInit * singleInit ) override final;
+	virtual void visit( const SingleInit * singleInit ) override final;
 	virtual void visit( ListInit * listInit ) override final;
+	virtual void visit( const ListInit * listInit ) override final;
 	virtual void visit( ConstructorInit * ctorInit ) override final;
+	virtual void visit( const ConstructorInit * ctorInit ) override final;
 
 	virtual void visit( Constant * constant ) override final;
+	virtual void visit( const Constant * constant ) override final;
 
 	virtual void visit( Attribute * attribute ) override final;
+	virtual void visit( const Attribute * attribute ) override final;
 
 	virtual DeclarationWithType * mutate( ObjectDecl * objectDecl ) override final;
@@ -186,5 +279,5 @@
 	virtual Statement * mutate( FinallyStmt * finallyStmt ) override final;
 	virtual Statement * mutate( WaitForStmt * waitforStmt ) override final;
-	virtual Statement * mutate( WithStmt * withStmt ) override final;
+	virtual Declaration * mutate( WithStmt * withStmt ) override final;
 	virtual NullStmt * mutate( NullStmt * nullStmt ) override final;
 	virtual Statement * mutate( DeclStmt * declStmt ) override final;
@@ -265,12 +358,17 @@
 
 	template<typename pass_t> friend void acceptAll( std::list< Declaration* > &decls, PassVisitor< pass_t >& visitor );
+	template<typename pass_t> friend void acceptAll( const std::list< const Declaration * > &decls, PassVisitor< pass_t >& visitor );
 	template<typename pass_t> friend void mutateAll( std::list< Declaration* > &decls, PassVisitor< pass_t >& visitor );
 	template< typename TreeType, typename pass_t > friend void maybeAccept_impl( TreeType * tree, PassVisitor< pass_t > & visitor );
+	template< typename TreeType, typename pass_t > friend void maybeAccept_impl( const TreeType * tree, PassVisitor< pass_t > & visitor );
 	template< typename TreeType, typename pass_t > friend void maybeMutate_impl( TreeType *& tree, PassVisitor< pass_t > & mutator );
 	template< typename Container, typename pass_t > friend void maybeAccept_impl( Container & container, PassVisitor< pass_t > & visitor );
+	template< typename Container, typename pass_t > friend void maybeAccept_impl( const Container & container, PassVisitor< pass_t > & visitor );
 	template< typename Container, typename pass_t > friend void maybeMutate_impl( Container & container, PassVisitor< pass_t > & mutator );
 
 	template<typename node_type> void call_previsit ( node_type * node ) { previsit_impl ( pass, node, 0 ); }
+	template<typename node_type> void call_previsit ( const node_type * node ) { previsit_impl ( pass, node, 0 ); }
 	template<typename node_type> void call_postvisit( node_type * node ) { postvisit_impl( pass, node, 0 ); }
+	template<typename node_type> void call_postvisit( const node_type * node ) { postvisit_impl( pass, node, 0 ); }
 
 	template<typename node_type> void call_premutate ( node_type * node ) { premutate_impl( pass, node, 0 ); }
@@ -286,4 +384,5 @@
 	void visitStatementList ( std::list< Statement* > &statements );
 	void mutateStatementList( std::list< Statement* > &statements );
+	void visitStatementList ( const std::list< Statement * > & statements );
 
 	template< typename func_t >
@@ -291,4 +390,5 @@
 	Statement * visitStatement ( Statement * stmt );
 	Statement * mutateStatement( Statement * stmt );
+	void visitStatement ( const Statement * stmt );
 
 	template< typename func_t >
@@ -296,4 +396,5 @@
 	Expression * visitExpression ( Expression * expr );
 	Expression * mutateExpression( Expression * expr );
+	void visitExpression ( const Expression * expr );
 
 
@@ -309,22 +410,25 @@
 	void indexerScopeEnter  ()                                    { indexer_impl_enterScope  ( pass, 0       ); }
 	void indexerScopeLeave  ()                                    { indexer_impl_leaveScope  ( pass, 0       ); }
-	void indexerAddId       ( DeclarationWithType       * node  ) { indexer_impl_addId       ( pass, 0, node ); }
-	void indexerAddType     ( NamedTypeDecl             * node  ) { indexer_impl_addType     ( pass, 0, node ); }
+	void indexerAddId       ( const DeclarationWithType * node  ) { indexer_impl_addId       ( pass, 0, node ); }
+	void indexerAddType     ( const NamedTypeDecl       * node  ) { indexer_impl_addType     ( pass, 0, node ); }
 	void indexerAddStruct   ( const std::string         & id    ) { indexer_impl_addStruct   ( pass, 0, id   ); }
-	void indexerAddStruct   ( StructDecl                * node  ) { indexer_impl_addStruct   ( pass, 0, node ); }
-	void indexerAddStructFwd( StructDecl                * node  ) { indexer_impl_addStructFwd( pass, 0, node ); }
-	void indexerAddEnum     ( EnumDecl                  * node  ) { indexer_impl_addEnum     ( pass, 0, node ); }
+	void indexerAddStruct   ( const StructDecl          * node  ) { indexer_impl_addStruct   ( pass, 0, node ); }
+	void indexerAddStructFwd( const StructDecl          * node  ) { indexer_impl_addStructFwd( pass, 0, node ); }
+	void indexerAddEnum     ( const EnumDecl            * node  ) { indexer_impl_addEnum     ( pass, 0, node ); }
 	void indexerAddUnion    ( const std::string         & id    ) { indexer_impl_addUnion    ( pass, 0, id   ); }
-	void indexerAddUnion    ( UnionDecl                 * node  ) { indexer_impl_addUnion    ( pass, 0, node ); }
-	void indexerAddUnionFwd ( UnionDecl                 * node  ) { indexer_impl_addUnionFwd ( pass, 0, node ); }
-	void indexerAddTrait    ( TraitDecl                 * node  ) { indexer_impl_addTrait    ( pass, 0, node ); }
-	void indexerAddWith     ( std::list< Expression * > & exprs, BaseSyntaxNode * withStmt ) { indexer_impl_addWith( pass, 0, exprs, withStmt ); }
+	void indexerAddUnion    ( const UnionDecl           * node  ) { indexer_impl_addUnion    ( pass, 0, node ); }
+	void indexerAddUnionFwd ( const UnionDecl           * node  ) { indexer_impl_addUnionFwd ( pass, 0, node ); }
+	void indexerAddTrait    ( const TraitDecl           * node  ) { indexer_impl_addTrait    ( pass, 0, node ); }
+	void indexerAddWith     ( const std::list< Expression * > & exprs, const Declaration * withStmt ) { indexer_impl_addWith( pass, 0, exprs, withStmt ); }
 
 
 	template< typename TreeType, typename VisitorType >
-	friend inline void indexerScopedAccept( TreeType * tree, VisitorType &visitor );
+	friend inline void indexerScopedAccept( TreeType * tree, VisitorType & visitor );
 
 	template< typename TreeType, typename VisitorType >
-	friend inline void indexerScopedMutate( TreeType *& tree, VisitorType &visitor );
+	friend inline void indexerScopedAccept( const TreeType * tree, VisitorType & visitor );
+
+	template< typename TreeType, typename VisitorType >
+	friend inline void indexerScopedMutate( TreeType *& tree, VisitorType & visitor );
 };
 
Index: src/Common/PassVisitor.impl.h
===================================================================
--- src/Common/PassVisitor.impl.h	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/Common/PassVisitor.impl.h	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -80,4 +80,26 @@
 
 template< typename pass_type >
+inline void acceptAll( const std::list< const Declaration * > & decls, PassVisitor< pass_type >& visitor ) {
+	SemanticErrorException errors;
+
+	pass_visitor_stats.depth++;
+	pass_visitor_stats.max->push(pass_visitor_stats.depth);
+	pass_visitor_stats.avg->push(pass_visitor_stats.depth);
+	for ( const Declaration * decl : decls ) {
+		try {
+			// run visitor on declaration
+			maybeAccept_impl( decl, visitor );
+		}
+		catch( SemanticErrorException &e ) {
+			errors.append( e );
+		}
+	}
+	pass_visitor_stats.depth--;
+	if ( ! errors.isEmpty() ) {
+		throw errors;
+	}
+}
+
+template< typename pass_type >
 inline void mutateAll( std::list< Declaration* > &decls, PassVisitor< pass_type >& mutator ) {
 	DeclList_t* beforeDecls = mutator.get_beforeDecls();
@@ -117,4 +139,12 @@
 }
 
+template< typename TreeType, typename pass_type >
+inline void maybeAccept_impl( const TreeType * tree, PassVisitor< pass_type > & visitor ) {
+	if ( ! visitor.get_visit_children() ) return;
+	if ( tree ) {
+		tree->accept( visitor );
+	}
+}
+
 template< typename Container, typename pass_type >
 inline void maybeAccept_impl( Container & container, PassVisitor< pass_type > & visitor ) {
@@ -129,4 +159,27 @@
 			if ( *i ) {
 				(*i)->accept( visitor );
+			}
+		} catch( SemanticErrorException &e ) {
+			errors.append( e );
+		}
+	}
+	pass_visitor_stats.depth--;
+	if ( ! errors.isEmpty() ) {
+		throw errors;
+	}
+}
+
+template< typename Container, typename pass_type >
+inline void maybeAccept_impl( const Container & container, PassVisitor< pass_type > & visitor ) {
+	if ( ! visitor.get_visit_children() ) return;
+	SemanticErrorException errors;
+
+	pass_visitor_stats.depth++;
+	pass_visitor_stats.max->push(pass_visitor_stats.depth);
+	pass_visitor_stats.avg->push(pass_visitor_stats.depth);
+	for ( const auto & i : container ) {
+		try {
+			if ( i ) {
+				i->accept( visitor );
 			}
 		} catch( SemanticErrorException &e ) {
@@ -227,4 +280,23 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visitStatementList( const std::list< Statement * > & statements ) {
+	if ( ! get_visit_children() ) return;
+	SemanticErrorException errors;
+
+	pass_visitor_stats.depth++;
+	pass_visitor_stats.max->push(pass_visitor_stats.depth);
+	pass_visitor_stats.avg->push(pass_visitor_stats.depth);
+	for ( const Statement * i : statements ) {
+		try {
+			maybeAccept_impl( i, *this );
+		} catch ( SemanticErrorException &e ) {
+			errors.append( e );
+		}
+	}
+	pass_visitor_stats.depth--;
+	if ( !errors.isEmpty() ) { throw errors; }
+}
+
+template< typename pass_type >
 void PassVisitor< pass_type >::mutateStatementList( std::list< Statement * > & statements ) {
 	handleStatementList( statements, [this]( Statement *& stmt) {
@@ -275,4 +347,14 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visitStatement( const Statement * stmt ) {
+	if ( ! get_visit_children() ) return;
+
+	// don't want statements from outer CompoundStmts to be added to this CompoundStmt
+	ValueGuardPtr< typename std::remove_pointer<decltype(get_env_ptr())>::type >  oldEnv( get_env_ptr() );
+
+	maybeAccept_impl( stmt, *this );
+}
+
+template< typename pass_type >
 Statement * PassVisitor< pass_type >::mutateStatement( Statement * stmt ) {
 	return handleStatement( stmt, [this]( Statement * stmt ) {
@@ -306,4 +388,17 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visitExpression( const Expression * expr ) {
+	if ( ! get_visit_children() ) return;
+	if( !expr ) return;
+
+	auto env_ptr = get_env_ptr();
+	if ( env_ptr && expr->get_env() ) {
+		*env_ptr = expr->get_env();
+	}
+
+	maybeAccept_impl( expr, *this );
+}
+
+template< typename pass_type >
 Expression * PassVisitor< pass_type >::mutateExpression( Expression * expr ) {
 	return handleExpression(expr, [this]( Expression * expr ) {
@@ -315,4 +410,14 @@
 template< typename TreeType, typename VisitorType >
 inline void indexerScopedAccept( TreeType * tree, VisitorType & visitor ) {
+	if ( ! visitor.get_visit_children() ) return;
+	auto guard = makeFuncGuard(
+		[&visitor]() { visitor.indexerScopeEnter(); },
+		[&visitor]() { visitor.indexerScopeLeave(); }
+	);
+	maybeAccept_impl( tree, visitor );
+}
+
+template< typename TreeType, typename VisitorType >
+inline void indexerScopedAccept( const TreeType * tree, VisitorType & visitor ) {
 	if ( ! visitor.get_visit_children() ) return;
 	auto guard = makeFuncGuard(
@@ -372,4 +477,16 @@
 
 	indexerAddId( node );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( const ObjectDecl * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( node->type         , *this );
+	maybeAccept_impl( node->init         , *this );
+	maybeAccept_impl( node->bitfieldWidth, *this );
+	maybeAccept_impl( node->attributes   , *this );
 
 	VISIT_END( node );
@@ -428,4 +545,39 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const FunctionDecl * node ) {
+	VISIT_START( node );
+
+	indexerAddId( node );
+
+	maybeAccept_impl( node->withExprs, *this );
+	{
+		// with clause introduces a level of scope (for the with expression members).
+		// with clause exprs are added to the indexer before parameters so that parameters
+		// shadow with exprs and not the other way around.
+		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
+		indexerAddWith( node->withExprs, node );
+		{
+			auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
+			// implicit add __func__ identifier as specified in the C manual 6.4.2.2
+			static ObjectDecl func(
+				"__func__", noStorageClasses, LinkageSpec::C, nullptr,
+				new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers( Type::Const ), BasicType::Char ), nullptr, true, false ),
+				nullptr
+			);
+			indexerAddId( &func );
+			maybeAccept_impl( node->type, *this );
+			// function body needs to have the same scope as parameters - CompoundStmt will not enter
+			// a new scope if inFunction is true
+			ValueGuard< bool > oldInFunction( inFunction );
+			inFunction = true;
+			maybeAccept_impl( node->statements, *this );
+			maybeAccept_impl( node->attributes, *this );
+		}
+	}
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 DeclarationWithType * PassVisitor< pass_type >::mutate( FunctionDecl * node ) {
 	MUTATE_START( node );
@@ -484,6 +636,6 @@
 
 template< typename pass_type >
-Declaration * PassVisitor< pass_type >::mutate( StructDecl * node ) {
-	MUTATE_START( node );
+void PassVisitor< pass_type >::visit( const StructDecl * node ) {
+	VISIT_START( node );
 
 	// make up a forward declaration and add it before processing the members
@@ -493,4 +645,24 @@
 	{
 		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
+		maybeAccept_impl( node->parameters, *this );
+		maybeAccept_impl( node->members   , *this );
+	}
+
+	// this addition replaces the forward declaration
+	indexerAddStruct( node );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+Declaration * PassVisitor< pass_type >::mutate( StructDecl * node ) {
+	MUTATE_START( node );
+
+	// make up a forward declaration and add it before processing the members
+	// needs to be on the heap because addStruct saves the pointer
+	indexerAddStructFwd( node );
+
+	{
+		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
 		maybeMutate_impl( node->parameters, *this );
 		maybeMutate_impl( node->members   , *this );
@@ -522,4 +694,21 @@
 	VISIT_END( node );
 }
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( const UnionDecl * node ) {
+	VISIT_START( node );
+
+	// make up a forward declaration and add it before processing the members
+	indexerAddUnionFwd( node );
+
+	{
+		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
+		maybeAccept_impl( node->parameters, *this );
+		maybeAccept_impl( node->members   , *this );
+	}
+
+	indexerAddUnion( node );
+
+	VISIT_END( node );
+}
 
 template< typename pass_type >
@@ -557,4 +746,17 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const EnumDecl * node ) {
+	VISIT_START( node );
+
+	indexerAddEnum( node );
+
+	// unlike structs, traits, and unions, enums inject their members into the global scope
+	maybeAccept_impl( node->parameters, *this );
+	maybeAccept_impl( node->members   , *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Declaration * PassVisitor< pass_type >::mutate( EnumDecl * node ) {
 	MUTATE_START( node );
@@ -573,4 +775,19 @@
 template< typename pass_type >
 void PassVisitor< pass_type >::visit( TraitDecl * node ) {
+	VISIT_START( node );
+
+	{
+		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
+		maybeAccept_impl( node->parameters, *this );
+		maybeAccept_impl( node->members   , *this );
+	}
+
+	indexerAddTrait( node );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( const TraitDecl * node ) {
 	VISIT_START( node );
 
@@ -625,12 +842,13 @@
 }
 
-template< typename pass_type >
-Declaration * PassVisitor< pass_type >::mutate( TypeDecl * node ) {
-	MUTATE_START( node );
+
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( const TypeDecl * node ) {
+	VISIT_START( node );
 
 	{
 		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeMutate_impl( node->parameters, *this );
-		maybeMutate_impl( node->base      , *this );
+		maybeAccept_impl( node->parameters, *this );
+		maybeAccept_impl( node->base      , *this );
 	}
 
@@ -640,4 +858,26 @@
 	indexerAddType( node );
 
+	maybeAccept_impl( node->assertions, *this );
+
+	indexerScopedAccept( node->init, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+Declaration * PassVisitor< pass_type >::mutate( TypeDecl * node ) {
+	MUTATE_START( node );
+
+	{
+		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
+		maybeMutate_impl( node->parameters, *this );
+		maybeMutate_impl( node->base      , *this );
+	}
+
+	// see A NOTE ON THE ORDER OF TRAVERSAL, above
+	// note that assertions come after the type is added to the symtab, since they are not part of the type proper
+	// and may depend on the type itself
+	indexerAddType( node );
+
 	maybeMutate_impl( node->assertions, *this );
 
@@ -667,4 +907,21 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const TypedefDecl * node ) {
+	VISIT_START( node );
+
+	{
+		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
+		maybeAccept_impl( node->parameters, *this );
+		maybeAccept_impl( node->base      , *this );
+	}
+
+	indexerAddType( node );
+
+	maybeAccept_impl( node->assertions, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Declaration * PassVisitor< pass_type >::mutate( TypedefDecl * node ) {
 	MUTATE_START( node );
@@ -695,4 +952,13 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const AsmDecl * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( node->stmt, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 AsmDecl * PassVisitor< pass_type >::mutate( AsmDecl * node ) {
 	MUTATE_START( node );
@@ -710,4 +976,14 @@
 
 	node->condition = visitExpression( node->condition );
+	maybeAccept_impl( node->message, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( const StaticAssertDecl * node ) {
+	VISIT_START( node );
+
+	visitExpression( node->condition );
 	maybeAccept_impl( node->message, *this );
 
@@ -742,4 +1018,18 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const CompoundStmt * node ) {
+	VISIT_START( node );
+	{
+		// do not enter a new scope if inFunction is true - needs to check old state before the assignment
+		ValueGuard< bool > oldInFunction( inFunction );
+		auto guard1 = makeFuncGuard( [this, &oldInFunction]() { if ( ! oldInFunction.old ) indexerScopeEnter(); }, [this, &oldInFunction]() { if ( ! oldInFunction.old ) indexerScopeLeave(); } );
+		auto guard2 = makeFuncGuard( [this]() { call_beginScope();   }, [this]() { call_endScope();     } );
+		inFunction = false;
+		visitStatementList( node->kids );
+	}
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 CompoundStmt * PassVisitor< pass_type >::mutate( CompoundStmt * node ) {
 	MUTATE_START( node );
@@ -767,4 +1057,13 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const ExprStmt * node ) {
+	VISIT_START( node );
+
+	visitExpression( node->expr );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Statement * PassVisitor< pass_type >::mutate( ExprStmt * node ) {
 	MUTATE_START( node );
@@ -790,4 +1089,16 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const AsmStmt * node ) {
+	VISIT_START( node )
+
+	maybeAccept_impl( node->instruction, *this );
+	maybeAccept_impl( node->output, *this );
+	maybeAccept_impl( node->input, *this );
+	maybeAccept_impl( node->clobber, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Statement * PassVisitor< pass_type >::mutate( AsmStmt * node ) {
 	MUTATE_START( node );
@@ -811,4 +1122,11 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const DirectiveStmt * node ) {
+	VISIT_START( node )
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Statement * PassVisitor< pass_type >::mutate( DirectiveStmt * node ) {
 	MUTATE_START( node );
@@ -825,5 +1143,5 @@
 		// if statements introduce a level of scope (for the initialization)
 		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeAccept_impl( node->get_initialization(), *this );
+		maybeAccept_impl( node->initialization, *this );
 		visitExpression ( node->condition );
 		node->thenPart = visitStatement( node->thenPart );
@@ -834,10 +1152,24 @@
 
 template< typename pass_type >
-Statement * PassVisitor< pass_type >::mutate( IfStmt * node ) {
-	MUTATE_START( node );
+void PassVisitor< pass_type >::visit( const IfStmt * node ) {
+	VISIT_START( node );
 	{
 		// if statements introduce a level of scope (for the initialization)
 		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeMutate_impl( node->get_initialization(), *this );
+		maybeAccept_impl( node->initialization, *this );
+		visitExpression ( node->condition );
+		visitStatement  ( node->thenPart );
+		visitStatement  ( node->elsePart );
+	}
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+Statement * PassVisitor< pass_type >::mutate( IfStmt * node ) {
+	MUTATE_START( node );
+	{
+		// if statements introduce a level of scope (for the initialization)
+		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
+		maybeMutate_impl( node->initialization, *this );
 		node->condition = mutateExpression( node->condition );
 		node->thenPart  = mutateStatement ( node->thenPart  );
@@ -859,4 +1191,19 @@
 		visitExpression ( node->condition );
 		node->body = visitStatement( node->body );
+	}
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( const WhileStmt * node ) {
+	VISIT_START( node );
+
+	{
+		// while statements introduce a level of scope (for the initialization)
+		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
+		maybeAccept_impl( node->initialization, *this );
+		visitExpression ( node->condition );
+		visitStatement  ( node->body );
 	}
 
@@ -897,4 +1244,18 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const ForStmt * node ) {
+	VISIT_START( node );
+	{
+		// for statements introduce a level of scope (for the initialization)
+		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
+		maybeAccept_impl( node->initialization, *this );
+		visitExpression( node->condition );
+		visitExpression( node->increment );
+		visitStatement ( node->body );
+	}
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Statement * PassVisitor< pass_type >::mutate( ForStmt * node ) {
 	MUTATE_START( node );
@@ -923,4 +1284,14 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const SwitchStmt * node ) {
+	VISIT_START( node );
+
+	visitExpression   ( node->condition  );
+	visitStatementList( node->statements );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Statement * PassVisitor< pass_type >::mutate( SwitchStmt * node ) {
 	MUTATE_START( node );
@@ -945,4 +1316,14 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const CaseStmt * node ) {
+	VISIT_START( node );
+
+	visitExpression   ( node->condition );
+	visitStatementList( node->stmts     );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Statement * PassVisitor< pass_type >::mutate( CaseStmt * node ) {
 	MUTATE_START( node );
@@ -963,4 +1344,10 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const BranchStmt * node ) {
+	VISIT_START( node );
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Statement * PassVisitor< pass_type >::mutate( BranchStmt * node ) {
 	MUTATE_START( node );
@@ -980,4 +1367,13 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const ReturnStmt * node ) {
+	VISIT_START( node );
+
+	visitExpression( node->expr );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Statement * PassVisitor< pass_type >::mutate( ReturnStmt * node ) {
 	MUTATE_START( node );
@@ -990,5 +1386,4 @@
 //--------------------------------------------------------------------------
 // ThrowStmt
-
 template< typename pass_type >
 void PassVisitor< pass_type >::visit( ThrowStmt * node ) {
@@ -1002,4 +1397,14 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const ThrowStmt * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( node->expr, *this );
+	maybeAccept_impl( node->target, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Statement * PassVisitor< pass_type >::mutate( ThrowStmt * node ) {
 	MUTATE_START( node );
@@ -1015,4 +1420,15 @@
 template< typename pass_type >
 void PassVisitor< pass_type >::visit( TryStmt * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( node->block       , *this );
+	maybeAccept_impl( node->handlers    , *this );
+	maybeAccept_impl( node->finallyBlock, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( const TryStmt * node ) {
 	VISIT_START( node );
 
@@ -1051,4 +1467,17 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const CatchStmt * node ) {
+	VISIT_START( node );
+	{
+		// catch statements introduce a level of scope (for the caught exception)
+		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
+		maybeAccept_impl( node->decl, *this );
+		visitExpression ( node->cond );
+		visitStatement  ( node->body );
+	}
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Statement * PassVisitor< pass_type >::mutate( CatchStmt * node ) {
 	MUTATE_START( node );
@@ -1075,4 +1504,13 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const FinallyStmt * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( node->block, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Statement * PassVisitor< pass_type >::mutate( FinallyStmt * node ) {
 	MUTATE_START( node );
@@ -1107,4 +1545,25 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const WaitForStmt * node ) {
+	VISIT_START( node );
+
+	for( auto & clause : node->clauses ) {
+		maybeAccept_impl( clause.target.function, *this );
+		maybeAccept_impl( clause.target.arguments, *this );
+
+		maybeAccept_impl( clause.statement, *this );
+		maybeAccept_impl( clause.condition, *this );
+	}
+
+	maybeAccept_impl( node->timeout.time, *this );
+	maybeAccept_impl( node->timeout.statement, *this );
+	maybeAccept_impl( node->timeout.condition, *this );
+	maybeAccept_impl( node->orelse.statement, *this );
+	maybeAccept_impl( node->orelse.condition, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Statement * PassVisitor< pass_type >::mutate( WaitForStmt * node ) {
 	MUTATE_START( node );
@@ -1130,5 +1589,5 @@
 
 //--------------------------------------------------------------------------
-// NullStmt
+// WithStmt
 template< typename pass_type >
 void PassVisitor< pass_type >::visit( WithStmt * node ) {
@@ -1145,5 +1604,18 @@
 
 template< typename pass_type >
-Statement * PassVisitor< pass_type >::mutate( WithStmt * node ) {
+void PassVisitor< pass_type >::visit( const WithStmt * node ) {
+	VISIT_START( node );
+	maybeAccept_impl( node->exprs, *this );
+	{
+		// catch statements introduce a level of scope (for the caught exception)
+		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
+		indexerAddWith( node->exprs, node );
+		maybeAccept_impl( node->stmt, *this );
+	}
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+Declaration * PassVisitor< pass_type >::mutate( WithStmt * node ) {
 	MUTATE_START( node );
 	maybeMutate_impl( node->exprs, *this );
@@ -1154,37 +1626,81 @@
 		maybeMutate_impl( node->stmt, *this );
 	}
+	MUTATE_END( Declaration, node );
+}
+
+//--------------------------------------------------------------------------
+// NullStmt
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( NullStmt * node ) {
+	VISIT_START( node );
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( const NullStmt * node ) {
+	VISIT_START( node );
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+NullStmt * PassVisitor< pass_type >::mutate( NullStmt * node ) {
+	MUTATE_START( node );
+	MUTATE_END( NullStmt, node );
+}
+
+//--------------------------------------------------------------------------
+// DeclStmt
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( DeclStmt * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( node->decl, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( const DeclStmt * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( node->decl, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+Statement * PassVisitor< pass_type >::mutate( DeclStmt * node ) {
+	MUTATE_START( node );
+
+	maybeMutate_impl( node->decl, *this );
+
 	MUTATE_END( Statement, node );
 }
 
 //--------------------------------------------------------------------------
-// NullStmt
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( NullStmt * node ) {
-	VISIT_START( node );
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-NullStmt * PassVisitor< pass_type >::mutate( NullStmt * node ) {
-	MUTATE_START( node );
-	MUTATE_END( NullStmt, node );
-}
-
-//--------------------------------------------------------------------------
-// DeclStmt
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( DeclStmt * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->decl, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Statement * PassVisitor< pass_type >::mutate( DeclStmt * node ) {
-	MUTATE_START( node );
-
-	maybeMutate_impl( node->decl, *this );
+// ImplicitCtorDtorStmt
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( ImplicitCtorDtorStmt * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( node->callStmt, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( const ImplicitCtorDtorStmt * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( node->callStmt, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+Statement * PassVisitor< pass_type >::mutate( ImplicitCtorDtorStmt * node ) {
+	MUTATE_START( node );
+
+	maybeMutate_impl( node->callStmt, *this );
 
 	MUTATE_END( Statement, node );
@@ -1192,24 +1708,4 @@
 
 //--------------------------------------------------------------------------
-// ImplicitCtorDtorStmt
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( ImplicitCtorDtorStmt * node ) {
-	VISIT_START( node );
-
-	maybeAccept_impl( node->callStmt, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Statement * PassVisitor< pass_type >::mutate( ImplicitCtorDtorStmt * node ) {
-	MUTATE_START( node );
-
-	maybeMutate_impl( node->callStmt, *this );
-
-	MUTATE_END( Statement, node );
-}
-
-//--------------------------------------------------------------------------
 // ApplicationExpr
 template< typename pass_type >
@@ -1218,6 +1714,17 @@
 
 	indexerScopedAccept( node->result  , *this );
-	maybeAccept_impl        ( node->function, *this );
-	maybeAccept_impl        ( node->args    , *this );
+	maybeAccept_impl   ( node->function, *this );
+	maybeAccept_impl   ( node->args    , *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( const ApplicationExpr * node ) {
+	VISIT_START( node );
+
+	indexerScopedAccept( node->result  , *this );
+	maybeAccept_impl   ( node->function, *this );
+	maybeAccept_impl   ( node->args    , *this );
 
 	VISIT_END( node );
@@ -1253,4 +1760,17 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const UntypedExpr * node ) {
+	VISIT_START( node );
+
+	indexerScopedAccept( node->result, *this );
+
+	for ( auto expr : node->args ) {
+		visitExpression( expr );
+	}
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Expression * PassVisitor< pass_type >::mutate( UntypedExpr * node ) {
 	MUTATE_START( node );
@@ -1278,4 +1798,13 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const NameExpr * node ) {
+	VISIT_START( node );
+
+	indexerScopedAccept( node->result, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Expression * PassVisitor< pass_type >::mutate( NameExpr * node ) {
 	MUTATE_START( node );
@@ -1294,5 +1823,15 @@
 
 	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl        ( node->arg   , *this );
+	maybeAccept_impl   ( node->arg   , *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( const CastExpr * node ) {
+	VISIT_START( node );
+
+	indexerScopedAccept( node->result, *this );
+	maybeAccept_impl   ( node->arg   , *this );
 
 	VISIT_END( node );
@@ -1323,4 +1862,14 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const KeywordCastExpr * node ) {
+	VISIT_START( node );
+
+	indexerScopedAccept( node->result, *this );
+	maybeAccept_impl   ( node->arg   , *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Expression * PassVisitor< pass_type >::mutate( KeywordCastExpr * node ) {
 	MUTATE_START( node );
@@ -1340,5 +1889,15 @@
 
 	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl( node->arg, *this );
+	maybeAccept_impl   ( node->arg, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( const VirtualCastExpr * node ) {
+	VISIT_START( node );
+
+	indexerScopedAccept( node->result, *this );
+	maybeAccept_impl   ( node->arg, *this );
 
 	VISIT_END( node );
@@ -1369,4 +1928,14 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const AddressExpr * node ) {
+	VISIT_START( node );
+
+	indexerScopedAccept( node->result, *this );
+	maybeAccept_impl   ( node->arg   , *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Expression * PassVisitor< pass_type >::mutate( AddressExpr * node ) {
 	MUTATE_START( node );
@@ -1391,4 +1960,13 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const LabelAddressExpr * node ) {
+	VISIT_START( node );
+
+	indexerScopedAccept( node->result, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Expression * PassVisitor< pass_type >::mutate( LabelAddressExpr * node ) {
 	MUTATE_START( node );
@@ -1404,4 +1982,15 @@
 template< typename pass_type >
 void PassVisitor< pass_type >::visit( UntypedMemberExpr * node ) {
+	VISIT_START( node );
+
+	indexerScopedAccept( node->result   , *this );
+	maybeAccept_impl   ( node->aggregate, *this );
+	maybeAccept_impl   ( node->member   , *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( const UntypedMemberExpr * node ) {
 	VISIT_START( node );
 
@@ -1438,4 +2027,14 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const MemberExpr * node ) {
+	VISIT_START( node );
+
+	indexerScopedAccept( node->result   , *this );
+	maybeAccept_impl   ( node->aggregate, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Expression * PassVisitor< pass_type >::mutate( MemberExpr * node ) {
 	MUTATE_START( node );
@@ -1460,4 +2059,13 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const VariableExpr * node ) {
+	VISIT_START( node );
+
+	indexerScopedAccept( node->result, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Expression * PassVisitor< pass_type >::mutate( VariableExpr * node ) {
 	MUTATE_START( node );
@@ -1473,4 +2081,14 @@
 template< typename pass_type >
 void PassVisitor< pass_type >::visit( ConstantExpr * node ) {
+	VISIT_START( node );
+
+	indexerScopedAccept( node->result   , *this );
+	maybeAccept_impl   ( &node->constant, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( const ConstantExpr * node ) {
 	VISIT_START( node );
 
@@ -1498,4 +2116,18 @@
 template< typename pass_type >
 void PassVisitor< pass_type >::visit( SizeofExpr * node ) {
+	VISIT_START( node );
+
+	indexerScopedAccept( node->result, *this );
+	if ( node->get_isType() ) {
+		maybeAccept_impl( node->type, *this );
+	} else {
+		maybeAccept_impl( node->expr, *this );
+	}
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( const SizeofExpr * node ) {
 	VISIT_START( node );
 
@@ -1542,4 +2174,18 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const AlignofExpr * node ) {
+	VISIT_START( node );
+
+	indexerScopedAccept( node->result, *this );
+	if ( node->get_isType() ) {
+		maybeAccept_impl( node->type, *this );
+	} else {
+		maybeAccept_impl( node->expr, *this );
+	}
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Expression * PassVisitor< pass_type >::mutate( AlignofExpr * node ) {
 	MUTATE_START( node );
@@ -1569,4 +2215,14 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const UntypedOffsetofExpr * node ) {
+	VISIT_START( node );
+
+	indexerScopedAccept( node->result, *this );
+	maybeAccept_impl   ( node->type  , *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Expression * PassVisitor< pass_type >::mutate( UntypedOffsetofExpr * node ) {
 	MUTATE_START( node );
@@ -1592,4 +2248,14 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const OffsetofExpr * node ) {
+	VISIT_START( node );
+
+	indexerScopedAccept( node->result, *this );
+	maybeAccept_impl   ( node->type  , *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Expression * PassVisitor< pass_type >::mutate( OffsetofExpr * node ) {
 	MUTATE_START( node );
@@ -1615,4 +2281,14 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const OffsetPackExpr * node ) {
+	VISIT_START( node );
+
+	indexerScopedAccept( node->result, *this );
+	maybeAccept_impl   ( node->type  , *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Expression * PassVisitor< pass_type >::mutate( OffsetPackExpr * node ) {
 	MUTATE_START( node );
@@ -1629,4 +2305,18 @@
 template< typename pass_type >
 void PassVisitor< pass_type >::visit( AttrExpr * node ) {
+	VISIT_START( node );
+
+	indexerScopedAccept( node->result, *this );
+	if ( node->get_isType() ) {
+		maybeAccept_impl( node->type, *this );
+	} else {
+		maybeAccept_impl( node->expr, *this );
+	}
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( const AttrExpr * node ) {
 	VISIT_START( node );
 
@@ -1670,4 +2360,15 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const LogicalExpr * node ) {
+	VISIT_START( node );
+
+	indexerScopedAccept( node->result, *this );
+	maybeAccept_impl   ( node->arg1  , *this );
+	maybeAccept_impl   ( node->arg2  , *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Expression * PassVisitor< pass_type >::mutate( LogicalExpr * node ) {
 	MUTATE_START( node );
@@ -1691,4 +2392,16 @@
 	maybeAccept_impl        ( node->arg2  , *this );
 	maybeAccept_impl        ( node->arg3  , *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( const ConditionalExpr * node ) {
+	VISIT_START( node );
+
+	indexerScopedAccept( node->result, *this );
+	maybeAccept_impl   ( node->arg1  , *this );
+	maybeAccept_impl   ( node->arg2  , *this );
+	maybeAccept_impl   ( node->arg3  , *this );
 
 	VISIT_END( node );
@@ -1722,4 +2435,15 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const CommaExpr * node ) {
+	VISIT_START( node );
+
+	indexerScopedAccept( node->result, *this );
+	maybeAccept_impl   ( node->arg1  , *this );
+	maybeAccept_impl   ( node->arg2  , *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Expression * PassVisitor< pass_type >::mutate( CommaExpr * node ) {
 	MUTATE_START( node );
@@ -1746,4 +2470,14 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const TypeExpr * node ) {
+	VISIT_START( node );
+
+	indexerScopedAccept( node->result, *this );
+	maybeAccept_impl   ( node->type, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Expression * PassVisitor< pass_type >::mutate( TypeExpr * node ) {
 	MUTATE_START( node );
@@ -1760,4 +2494,16 @@
 template< typename pass_type >
 void PassVisitor< pass_type >::visit( AsmExpr * node ) {
+	VISIT_START( node );
+
+	indexerScopedAccept( node->result    , *this );
+	maybeAccept_impl   ( node->inout     , *this );
+	maybeAccept_impl   ( node->constraint, *this );
+	maybeAccept_impl   ( node->operand   , *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( const AsmExpr * node ) {
 	VISIT_START( node );
 
@@ -1796,4 +2542,14 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const ImplicitCopyCtorExpr * node ) {
+	VISIT_START( node );
+
+	indexerScopedAccept( node->result    , *this );
+	maybeAccept_impl   ( node->callExpr  , *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Expression * PassVisitor< pass_type >::mutate( ImplicitCopyCtorExpr * node ) {
 	MUTATE_START( node );
@@ -1819,4 +2575,14 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const ConstructorExpr * node ) {
+	VISIT_START( node );
+
+	indexerScopedAccept( node->result  , *this );
+	maybeAccept_impl   ( node->callExpr, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Expression * PassVisitor< pass_type >::mutate( ConstructorExpr * node ) {
 	MUTATE_START( node );
@@ -1842,4 +2608,14 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const CompoundLiteralExpr * node ) {
+	VISIT_START( node );
+
+	indexerScopedAccept( node->result     , *this );
+	maybeAccept_impl   ( node->initializer, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Expression * PassVisitor< pass_type >::mutate( CompoundLiteralExpr * node ) {
 	MUTATE_START( node );
@@ -1856,4 +2632,15 @@
 template< typename pass_type >
 void PassVisitor< pass_type >::visit( RangeExpr * node ) {
+	VISIT_START( node );
+
+	indexerScopedAccept( node->result, *this );
+	maybeAccept_impl   ( node->low   , *this );
+	maybeAccept_impl   ( node->high  , *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( const RangeExpr * node ) {
 	VISIT_START( node );
 
@@ -1890,4 +2677,14 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const UntypedTupleExpr * node ) {
+	VISIT_START( node );
+
+	indexerScopedAccept( node->result, *this );
+	maybeAccept_impl   ( node->exprs , *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Expression * PassVisitor< pass_type >::mutate( UntypedTupleExpr * node ) {
 	MUTATE_START( node );
@@ -1913,4 +2710,14 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const TupleExpr * node ) {
+	VISIT_START( node );
+
+	indexerScopedAccept( node->result, *this );
+	maybeAccept_impl   ( node->exprs , *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Expression * PassVisitor< pass_type >::mutate( TupleExpr * node ) {
 	MUTATE_START( node );
@@ -1936,4 +2743,14 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const TupleIndexExpr * node ) {
+	VISIT_START( node );
+
+	indexerScopedAccept( node->result, *this );
+	maybeAccept_impl   ( node->tuple , *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Expression * PassVisitor< pass_type >::mutate( TupleIndexExpr * node ) {
 	MUTATE_START( node );
@@ -1954,4 +2771,14 @@
 	indexerScopedAccept( node->result  , *this );
 	maybeAccept_impl   ( node->stmtExpr, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( const TupleAssignExpr * node ) {
+	VISIT_START( node );
+
+	indexerScopedAccept( node->result  , *this );
+	maybeAccept_impl( node->stmtExpr, *this );
 
 	VISIT_END( node );
@@ -1989,6 +2816,6 @@
 
 template< typename pass_type >
-Expression * PassVisitor< pass_type >::mutate( StmtExpr * node ) {
-	MUTATE_START( node );
+void PassVisitor< pass_type >::visit( const StmtExpr * node ) {
+	VISIT_START( node );
 
 	// don't want statements from outer CompoundStmts to be added to this StmtExpr
@@ -1997,4 +2824,21 @@
 	ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () );
 
+	indexerScopedAccept( node->result     , *this );
+	maybeAccept_impl   ( node->statements , *this );
+	maybeAccept_impl   ( node->returnDecls, *this );
+	maybeAccept_impl   ( node->dtors      , *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+Expression * PassVisitor< pass_type >::mutate( StmtExpr * node ) {
+	MUTATE_START( node );
+
+	// don't want statements from outer CompoundStmts to be added to this StmtExpr
+	ValueGuardPtr< typename std::remove_pointer<decltype(get_env_ptr())>::type >  oldEnv( get_env_ptr() );
+	ValueGuardPtr< std::list< Statement* > > oldBeforeStmts( get_beforeStmts() );
+	ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () );
+
 	indexerScopedMutate( node->result     , *this );
 	maybeMutate_impl   ( node->statements , *this );
@@ -2018,4 +2862,14 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const UniqueExpr * node ) {
+	VISIT_START( node );
+
+	indexerScopedAccept( node->result, *this );
+	maybeAccept_impl   ( node->expr  , *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Expression * PassVisitor< pass_type >::mutate( UniqueExpr * node ) {
 	MUTATE_START( node );
@@ -2032,4 +2886,15 @@
 template< typename pass_type >
 void PassVisitor< pass_type >::visit( UntypedInitExpr * node ) {
+	VISIT_START( node );
+
+	indexerScopedAccept( node->result, *this );
+	maybeAccept_impl   ( node->expr  , *this );
+	// not currently visiting initAlts, but this doesn't matter since this node is only used in the resolver.
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( const UntypedInitExpr * node ) {
 	VISIT_START( node );
 
@@ -2067,4 +2932,15 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const InitExpr * node ) {
+	VISIT_START( node );
+
+	indexerScopedAccept( node->result, *this );
+	maybeAccept_impl   ( node->expr  , *this );
+	maybeAccept_impl   ( node->designation, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Expression * PassVisitor< pass_type >::mutate( InitExpr * node ) {
 	MUTATE_START( node );
@@ -2085,5 +2961,16 @@
 
 	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl( node->expr, *this );
+	maybeAccept_impl   ( node->expr, *this );
+	// don't visit deleteStmt, because it is a pointer to somewhere else in the tree.
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( const DeletedExpr * node ) {
+	VISIT_START( node );
+
+	indexerScopedAccept( node->result, *this );
+	maybeAccept_impl   ( node->expr, *this );
 	// don't visit deleteStmt, because it is a pointer to somewhere else in the tree.
 
@@ -2109,5 +2996,15 @@
 
 	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl( node->expr, *this );
+	maybeAccept_impl   ( node->expr, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( const DefaultArgExpr * node ) {
+	VISIT_START( node );
+
+	indexerScopedAccept( node->result, *this );
+	maybeAccept_impl   ( node->expr, *this );
 
 	VISIT_END( node );
@@ -2134,4 +3031,18 @@
 	maybeAccept_impl( node->control, *this );
 	for ( GenericExpr::Association & assoc : node->associations ) {
+		indexerScopedAccept( assoc.type, *this );
+		maybeAccept_impl( assoc.expr, *this );
+	}
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( const GenericExpr * node ) {
+	VISIT_START( node );
+
+	indexerScopedAccept( node->result, *this );
+	maybeAccept_impl( node->control, *this );
+	for ( const GenericExpr::Association & assoc : node->associations ) {
 		indexerScopedAccept( assoc.type, *this );
 		maybeAccept_impl( assoc.expr, *this );
@@ -2168,4 +3079,13 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const VoidType * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( node->forall, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Type * PassVisitor< pass_type >::mutate( VoidType * node ) {
 	MUTATE_START( node );
@@ -2180,4 +3100,13 @@
 template< typename pass_type >
 void PassVisitor< pass_type >::visit( BasicType * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( node->forall, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( const BasicType * node ) {
 	VISIT_START( node );
 
@@ -2210,4 +3139,15 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const PointerType * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( node->forall, *this );
+	// xxx - should PointerType visit/mutate dimension?
+	maybeAccept_impl( node->base, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Type * PassVisitor< pass_type >::mutate( PointerType * node ) {
 	MUTATE_START( node );
@@ -2234,4 +3174,15 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const ArrayType * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( node->forall, *this );
+	maybeAccept_impl( node->dimension, *this );
+	maybeAccept_impl( node->base, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Type * PassVisitor< pass_type >::mutate( ArrayType * node ) {
 	MUTATE_START( node );
@@ -2257,4 +3208,14 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const ReferenceType * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( node->forall, *this );
+	maybeAccept_impl( node->base, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Type * PassVisitor< pass_type >::mutate( ReferenceType * node ) {
 	MUTATE_START( node );
@@ -2280,4 +3241,15 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const QualifiedType * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( node->forall, *this );
+	maybeAccept_impl( node->parent, *this );
+	maybeAccept_impl( node->child, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Type * PassVisitor< pass_type >::mutate( QualifiedType * node ) {
 	MUTATE_START( node );
@@ -2304,4 +3276,15 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const FunctionType * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( node->forall, *this );
+	maybeAccept_impl( node->returnVals, *this );
+	maybeAccept_impl( node->parameters, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Type * PassVisitor< pass_type >::mutate( FunctionType * node ) {
 	MUTATE_START( node );
@@ -2332,4 +3315,19 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const StructInstType * node ) {
+	VISIT_START( node );
+
+	indexerAddStruct( node->name );
+
+	{
+		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
+		maybeAccept_impl( node->forall    , *this );
+		maybeAccept_impl( node->parameters, *this );
+	}
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Type * PassVisitor< pass_type >::mutate( StructInstType * node ) {
 	MUTATE_START( node );
@@ -2364,4 +3362,19 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const UnionInstType * node ) {
+	VISIT_START( node );
+
+	indexerAddStruct( node->name );
+
+	{
+		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
+		maybeAccept_impl( node->forall    , *this );
+		maybeAccept_impl( node->parameters, *this );
+	}
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Type * PassVisitor< pass_type >::mutate( UnionInstType * node ) {
 	MUTATE_START( node );
@@ -2391,4 +3404,14 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const EnumInstType * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( node->forall, *this );
+	maybeAccept_impl( node->parameters, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Type * PassVisitor< pass_type >::mutate( EnumInstType * node ) {
 	MUTATE_START( node );
@@ -2413,4 +3436,14 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const TraitInstType * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( node->forall    , *this );
+	maybeAccept_impl( node->parameters, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Type * PassVisitor< pass_type >::mutate( TraitInstType * node ) {
 	MUTATE_START( node );
@@ -2426,4 +3459,14 @@
 template< typename pass_type >
 void PassVisitor< pass_type >::visit( TypeInstType * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( node->forall    , *this );
+	maybeAccept_impl( node->parameters, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( const TypeInstType * node ) {
 	VISIT_START( node );
 
@@ -2458,4 +3501,15 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const TupleType * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( node->forall, *this );
+	maybeAccept_impl( node->types, *this );
+	maybeAccept_impl( node->members, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Type * PassVisitor< pass_type >::mutate( TupleType * node ) {
 	MUTATE_START( node );
@@ -2472,4 +3526,14 @@
 template< typename pass_type >
 void PassVisitor< pass_type >::visit( TypeofType * node ) {
+	VISIT_START( node );
+
+	assert( node->expr );
+	maybeAccept_impl( node->expr, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( const TypeofType * node ) {
 	VISIT_START( node );
 
@@ -2508,4 +3572,19 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const AttrType * node ) {
+	VISIT_START( node );
+
+	if ( node->isType ) {
+		assert( node->type );
+		maybeAccept_impl( node->type, *this );
+	} else {
+		assert( node->expr );
+		maybeAccept_impl( node->expr, *this );
+	} // if
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Type * PassVisitor< pass_type >::mutate( AttrType * node ) {
 	MUTATE_START( node );
@@ -2534,4 +3613,13 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const VarArgsType * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( node->forall, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Type * PassVisitor< pass_type >::mutate( VarArgsType * node ) {
 	MUTATE_START( node );
@@ -2554,4 +3642,13 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const ZeroType * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( node->forall, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Type * PassVisitor< pass_type >::mutate( ZeroType * node ) {
 	MUTATE_START( node );
@@ -2574,4 +3671,13 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const OneType * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( node->forall, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Type * PassVisitor< pass_type >::mutate( OneType * node ) {
 	MUTATE_START( node );
@@ -2594,4 +3700,13 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const GlobalScopeType * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( node->forall, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Type * PassVisitor< pass_type >::mutate( GlobalScopeType * node ) {
 	MUTATE_START( node );
@@ -2614,4 +3729,13 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const Designation * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( node->designators, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Designation * PassVisitor< pass_type >::mutate( Designation * node ) {
 	MUTATE_START( node );
@@ -2634,4 +3758,13 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const SingleInit * node ) {
+	VISIT_START( node );
+
+	visitExpression( node->value );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Initializer * PassVisitor< pass_type >::mutate( SingleInit * node ) {
 	MUTATE_START( node );
@@ -2646,4 +3779,14 @@
 template< typename pass_type >
 void PassVisitor< pass_type >::visit( ListInit * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( node->designations, *this );
+	maybeAccept_impl( node->initializers, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( const ListInit * node ) {
 	VISIT_START( node );
 
@@ -2678,4 +3821,15 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const ConstructorInit * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( node->ctor, *this );
+	maybeAccept_impl( node->dtor, *this );
+	maybeAccept_impl( node->init, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Initializer * PassVisitor< pass_type >::mutate( ConstructorInit * node ) {
 	MUTATE_START( node );
@@ -2698,4 +3852,11 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const Constant * node ) {
+	VISIT_START( node );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Constant * PassVisitor< pass_type >::mutate( Constant * node  )  {
 	MUTATE_START( node );
@@ -2708,4 +3869,13 @@
 template< typename pass_type >
 void PassVisitor< pass_type >::visit( Attribute * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( node->parameters, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( const Attribute * node ) {
 	VISIT_START( node );
 
Index: src/Common/PassVisitor.proto.h
===================================================================
--- src/Common/PassVisitor.proto.h	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/Common/PassVisitor.proto.h	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -118,4 +118,21 @@
 static inline void postvisit_impl( __attribute__((unused)) pass_type& pass, __attribute__((unused)) node_type * node, __attribute__((unused)) long unused ) {}
 
+template<typename pass_type, typename node_type>
+static inline auto previsit_impl( pass_type& pass, const node_type * node, __attribute__((unused)) int unused ) -> decltype( pass.previsit( node ), void() ) {
+	pass.previsit( node );
+}
+
+template<typename pass_type, typename node_type>
+static inline void previsit_impl( __attribute__((unused)) pass_type& pass, __attribute__((unused)) const node_type * node, __attribute__((unused)) long unused ) {}
+
+
+template<typename pass_type, typename node_type>
+static inline auto postvisit_impl( pass_type& pass, const node_type * node, __attribute__((unused)) int unused ) -> decltype( pass.postvisit( node ), void() ) {
+	pass.postvisit( node );
+}
+
+template<typename pass_type, typename node_type>
+static inline void postvisit_impl( __attribute__((unused)) pass_type& pass, __attribute__((unused)) const node_type * node, __attribute__((unused)) long unused ) {}
+
 //---------------------------------------------------------
 // Mutate
@@ -200,7 +217,6 @@
 	pass.indexer.func( arg );                                                                                                \
 }                                                                                                                              \
-                                                                                                                               \
-template<typename pass_type>                                                                                                   \
-static inline void indexer_impl_##func ( pass_type &, long, type ) { }                                                          \
+template<typename pass_type>                                                                                                   \
+static inline void indexer_impl_##func ( pass_type &, long, type ) { }
 
 #define INDEXER_FUNC2( func, type1, type2 )                                                                                             \
@@ -209,16 +225,15 @@
 	pass.indexer.func( arg1, arg2 );                                                                                                \
 }                                                                                                                              \
-                                                                                                                               \
 template<typename pass_type>                                                                                                   \
 static inline void indexer_impl_##func ( pass_type &, long, type1, type2 ) { }
 
 
-INDEXER_FUNC1( addId     , DeclarationWithType *       );
-INDEXER_FUNC1( addType   , NamedTypeDecl *             );
-INDEXER_FUNC1( addStruct , StructDecl *                );
-INDEXER_FUNC1( addEnum   , EnumDecl *                  );
-INDEXER_FUNC1( addUnion  , UnionDecl *                 );
-INDEXER_FUNC1( addTrait  , TraitDecl *                 );
-INDEXER_FUNC2( addWith   , std::list< Expression * > &, BaseSyntaxNode * );
+INDEXER_FUNC1( addId     , const DeclarationWithType *       );
+INDEXER_FUNC1( addType   , const NamedTypeDecl *             );
+INDEXER_FUNC1( addStruct , const StructDecl *                );
+INDEXER_FUNC1( addEnum   , const EnumDecl *                  );
+INDEXER_FUNC1( addUnion  , const UnionDecl *                 );
+INDEXER_FUNC1( addTrait  , const TraitDecl *                 );
+INDEXER_FUNC2( addWith   , const std::list< Expression * > &, const Declaration * );
 
 #undef INDEXER_FUNC1
@@ -226,5 +241,5 @@
 
 template<typename pass_type>
-static inline auto indexer_impl_addStructFwd( pass_type & pass, int, StructDecl * decl ) -> decltype( pass.indexer.addStruct( decl ), void() ) {
+static inline auto indexer_impl_addStructFwd( pass_type & pass, int, const StructDecl * decl ) -> decltype( pass.indexer.addStruct( decl ), void() ) {
 	StructDecl * fwd = new StructDecl( decl->name );
 	cloneAll( decl->parameters, fwd->parameters );
@@ -233,8 +248,8 @@
 
 template<typename pass_type>
-static inline auto indexer_impl_addStructFwd( pass_type &, long, StructDecl * ) {}
-
-template<typename pass_type>
-static inline auto indexer_impl_addUnionFwd( pass_type & pass, int, UnionDecl * decl ) -> decltype( pass.indexer.addUnion( decl ), void() ) {
+static inline auto indexer_impl_addStructFwd( pass_type &, long, const StructDecl * ) {}
+
+template<typename pass_type>
+static inline auto indexer_impl_addUnionFwd( pass_type & pass, int, const UnionDecl * decl ) -> decltype( pass.indexer.addUnion( decl ), void() ) {
 	UnionDecl * fwd = new UnionDecl( decl->name );
 	cloneAll( decl->parameters, fwd->parameters );
@@ -243,5 +258,5 @@
 
 template<typename pass_type>
-static inline auto indexer_impl_addUnionFwd( pass_type &, long, UnionDecl * ) {}
+static inline auto indexer_impl_addUnionFwd( pass_type &, long, const UnionDecl * ) {}
 
 template<typename pass_type>
Index: src/InitTweak/InitTweak.cc
===================================================================
--- src/InitTweak/InitTweak.cc	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/InitTweak/InitTweak.cc	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -318,5 +318,5 @@
 	virtual ~ExpanderImpl() = default;
 	virtual std::vector< ast::ptr< ast::Expr > > next( IndexList & indices ) = 0;
-	virtual ast::ptr< ast::Stmt > buildListInit( 
+	virtual ast::ptr< ast::Stmt > buildListInit(
 		ast::UntypedExpr * callExpr, IndexList & indices ) = 0;
 };
@@ -324,13 +324,13 @@
 namespace {
 	template< typename Out >
-	void buildCallExpr( 
-		ast::UntypedExpr * callExpr, const ast::Expr * index, const ast::Expr * dimension, 
+	void buildCallExpr(
+		ast::UntypedExpr * callExpr, const ast::Expr * index, const ast::Expr * dimension,
 		const ast::Init * init, Out & out
 	) {
 		const CodeLocation & loc = init->location;
 
-		auto cond = new ast::UntypedExpr{ 
+		auto cond = new ast::UntypedExpr{
 			loc, new ast::NameExpr{ loc, "?<?" }, { index, dimension } };
-		
+
 		std::vector< ast::ptr< ast::Expr > > args = makeInitList( init );
 		splice( callExpr->args, args );
@@ -338,5 +338,5 @@
 		out.emplace_back( new ast::IfStmt{ loc, cond, new ast::ExprStmt{ loc, callExpr } } );
 
-		out.emplace_back( new ast::ExprStmt{ 
+		out.emplace_back( new ast::ExprStmt{
 			loc, new ast::UntypedExpr{ loc, new ast::NameExpr{ loc, "++?" }, { index } } } );
 	}
@@ -344,5 +344,5 @@
 	template< typename Out >
 	void build(
-		ast::UntypedExpr * callExpr, const InitExpander_new::IndexList & indices, 
+		ast::UntypedExpr * callExpr, const InitExpander_new::IndexList & indices,
 		const ast::Init * init, Out & out
 	) {
@@ -371,7 +371,7 @@
 
 			static UniqueName targetLabel( "L__autogen__" );
-			ast::Label switchLabel{ 
+			ast::Label switchLabel{
 				loc, targetLabel.newName(), { new ast::Attribute{ "unused" } } };
-			
+
 			std::vector< ast::ptr< ast::Stmt > > branches;
 			for ( const ast::Init * init : *listInit ) {
@@ -381,5 +381,5 @@
 				std::vector< ast::ptr< ast::Stmt > > stmts;
 				build( callExpr, indices, init, stmts );
-				stmts.emplace_back( 
+				stmts.emplace_back(
 					new ast::BranchStmt{ loc, ast::BranchStmt::Break, switchLabel } );
 				branches.emplace_back( new ast::CaseStmt{ loc, condition, std::move( stmts ) } );
@@ -398,12 +398,12 @@
 			return makeInitList( init );
 		}
-		
-		ast::ptr< ast::Stmt > buildListInit( 
-			ast::UntypedExpr * callExpr, InitExpander_new::IndexList & indices 
+
+		ast::ptr< ast::Stmt > buildListInit(
+			ast::UntypedExpr * callExpr, InitExpander_new::IndexList & indices
 		) override {
-			// If array came with an initializer list, initialize each element. We may have more 
-			// initializers than elements of the array; need to check at each index that we have 
-			// not exceeded size. We may have fewer initializers than elements in the array; need 
-			// to default-construct remaining elements. To accomplish this, generate switch 
+			// If array came with an initializer list, initialize each element. We may have more
+			// initializers than elements of the array; need to check at each index that we have
+			// not exceeded size. We may have fewer initializers than elements in the array; need
+			// to default-construct remaining elements. To accomplish this, generate switch
 			// statement consuming all of expander's elements
 
@@ -427,6 +427,6 @@
 		ExprImpl_new( const ast::Expr * a ) : arg( a ) {}
 
-		std::vector< ast::ptr< ast::Expr > > next( 
-			InitExpander_new::IndexList & indices 
+		std::vector< ast::ptr< ast::Expr > > next(
+			InitExpander_new::IndexList & indices
 		) override {
 			if ( ! arg ) return {};
@@ -437,13 +437,13 @@
 				// go through indices and layer on subscript exprs ?[?]
 				++it;
-				expr = new ast::UntypedExpr{ 
+				expr = new ast::UntypedExpr{
 					loc, new ast::NameExpr{ loc, "?[?]" }, { expr, *it } };
 			}
 			return { expr };
 		}
-		
-		ast::ptr< ast::Stmt > buildListInit( 
-			ast::UntypedExpr *, InitExpander_new::IndexList & 
-		) override { 
+
+		ast::ptr< ast::Stmt > buildListInit(
+			ast::UntypedExpr *, InitExpander_new::IndexList &
+		) override {
 			return {};
 		}
@@ -464,5 +464,5 @@
 }
 
-/// builds statement which has the same semantics as a C-style list initializer (for array 
+/// builds statement which has the same semantics as a C-style list initializer (for array
 /// initializers) using callExpr as the base expression to perform initialization
 ast::ptr< ast::Stmt > InitExpander_new::buildListInit( ast::UntypedExpr * callExpr ) {
@@ -668,9 +668,9 @@
 
 		const ast::DeclWithType * func = getCalledFunction( appExpr->func );
-		assertf( func, 
+		assertf( func,
 			"getCalledFunction returned nullptr: %s", toString( appExpr->func ).c_str() );
-		
-		// check for Intrinsic only -- don't want to remove all overridable ctor/dtor because 
-		// autogenerated ctor/dtor will call all member dtors, and some members may have a 
+
+		// check for Intrinsic only -- don't want to remove all overridable ctor/dtor because
+		// autogenerated ctor/dtor will call all member dtors, and some members may have a
 		// user-defined dtor
 		return func->linkage == ast::Linkage::Intrinsic ? appExpr : nullptr;
@@ -707,5 +707,5 @@
 		return allofCtorDtor( stmt, []( const ast::Expr * callExpr ){
 			if ( const ast::ApplicationExpr * appExpr = isIntrinsicCallExpr( callExpr ) ) {
-				const ast::FunctionType * funcType = 
+				const ast::FunctionType * funcType =
 					GenPoly::getFunctionType( appExpr->func->result );
 				assert( funcType );
@@ -997,6 +997,6 @@
 	bool isCtorDtorAssign( const std::string & str ) { return isCtorDtor( str ) || isAssignment( str ); }
 
-	FunctionDecl * isCopyFunction( Declaration * decl, const std::string & fname ) {
-		FunctionDecl * function = dynamic_cast< FunctionDecl * >( decl );
+	const FunctionDecl * isCopyFunction( const Declaration * decl, const std::string & fname ) {
+		const FunctionDecl * function = dynamic_cast< const FunctionDecl * >( decl );
 		if ( ! function ) return nullptr;
 		if ( function->name != fname ) return nullptr;
@@ -1022,20 +1022,20 @@
 		if ( ! t1 ) return false;
 		const ast::Type * t2 = ftype->params.back()->get_type();
-		
+
 		return ResolvExpr::typesCompatibleIgnoreQualifiers( t1, t2, ast::SymbolTable{} );
 	}
 
-	FunctionDecl * isAssignment( Declaration * decl ) {
+	const FunctionDecl * isAssignment( const Declaration * decl ) {
 		return isCopyFunction( decl, "?=?" );
 	}
-	FunctionDecl * isDestructor( Declaration * decl ) {
-		if ( isDestructor( decl->get_name() ) ) {
-			return dynamic_cast< FunctionDecl * >( decl );
+	const FunctionDecl * isDestructor( const Declaration * decl ) {
+		if ( isDestructor( decl->name ) ) {
+			return dynamic_cast< const FunctionDecl * >( decl );
 		}
 		return nullptr;
 	}
-	FunctionDecl * isDefaultConstructor( Declaration * decl ) {
+	const FunctionDecl * isDefaultConstructor( const Declaration * decl ) {
 		if ( isConstructor( decl->name ) ) {
-			if ( FunctionDecl * func = dynamic_cast< FunctionDecl * >( decl ) ) {
+			if ( const FunctionDecl * func = dynamic_cast< const FunctionDecl * >( decl ) ) {
 				if ( func->type->parameters.size() == 1 ) {
 					return func;
@@ -1045,5 +1045,5 @@
 		return nullptr;
 	}
-	FunctionDecl * isCopyConstructor( Declaration * decl ) {
+	const FunctionDecl * isCopyConstructor( const Declaration * decl ) {
 		return isCopyFunction( decl, "?{}" );
 	}
Index: src/InitTweak/InitTweak.h
===================================================================
--- src/InitTweak/InitTweak.h	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/InitTweak/InitTweak.h	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -26,9 +26,9 @@
 // helper functions for initialization
 namespace InitTweak {
-	FunctionDecl * isAssignment( Declaration * decl );
-	FunctionDecl * isDestructor( Declaration * decl );
-	FunctionDecl * isDefaultConstructor( Declaration * decl );
-	FunctionDecl * isCopyConstructor( Declaration * decl );
-	FunctionDecl * isCopyFunction( Declaration * decl, const std::string & fname );
+	const FunctionDecl * isAssignment( const Declaration * decl );
+	const FunctionDecl * isDestructor( const Declaration * decl );
+	const FunctionDecl * isDefaultConstructor( const Declaration * decl );
+	const FunctionDecl * isCopyConstructor( const Declaration * decl );
+	const FunctionDecl * isCopyFunction( const Declaration * decl, const std::string & fname );
 	bool isCopyFunction( const ast::FunctionDecl * decl );
 
@@ -153,6 +153,6 @@
 		InitExpander_new & operator++ ();
 
-		/// builds statement which has the same semantics as a C-style list initializer (for array 
-		/// initializers) using callExpr as the base expression to perform initialization. 
+		/// builds statement which has the same semantics as a C-style list initializer (for array
+		/// initializers) using callExpr as the base expression to perform initialization.
 		/// Mutates callExpr
 		ast::ptr< ast::Stmt > buildListInit( ast::UntypedExpr * callExpr );
Index: src/Parser/LinkageSpec.h
===================================================================
--- src/Parser/LinkageSpec.h	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/Parser/LinkageSpec.h	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -9,7 +9,7 @@
 // Author           : Rodolfo G. Esteves
 // Created On       : Sat May 16 13:24:28 2015
-// Last Modified By : Andrew Beach
-// Last Modified On : Thr Spt 13 15:59:00 2018
-// Update Count     : 17
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Wed Jul 10 16:02:34 2019
+// Update Count     : 18
 //
 
@@ -35,4 +35,5 @@
 		constexpr Spec( unsigned int val ) : val( val ) {}
 		constexpr Spec( Spec const & other ) : val( other.val ) {}
+		constexpr Spec & operator=( const Spec & ) = default;
 		// Operators may go here.
 		// Supports == and !=
Index: src/Parser/ParseNode.h
===================================================================
--- src/Parser/ParseNode.h	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/Parser/ParseNode.h	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -437,5 +437,5 @@
 WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when );
 WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when, StatementNode * else_stmt, ExpressionNode * else_when );
-WithStmt * build_with( ExpressionNode * exprs, StatementNode * stmt );
+Statement * build_with( ExpressionNode * exprs, StatementNode * stmt );
 
 //##############################################################################
Index: src/Parser/StatementNode.cc
===================================================================
--- src/Parser/StatementNode.cc	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/Parser/StatementNode.cc	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -317,9 +317,9 @@
 } // build_waitfor_timeout
 
-WithStmt * build_with( ExpressionNode * exprs, StatementNode * stmt ) {
+Statement * build_with( ExpressionNode * exprs, StatementNode * stmt ) {
 	std::list< Expression * > e;
 	buildMoveList( exprs, e );
 	Statement * s = maybeMoveBuild<Statement>( stmt );
-	return new WithStmt( e, s );
+	return new DeclStmt( new WithStmt( e, s ) );
 } // build_with
 
Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/Parser/parser.yy	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -10,6 +10,6 @@
 // Created On       : Sat Sep  1 20:22:55 2001
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue May 28 17:06:37 2019
-// Update Count     : 4354
+// Last Modified On : Sun Jul 14 07:54:30 2019
+// Update Count     : 4355
 //
 
@@ -678,5 +678,7 @@
 
 argument_expression_list:
-	argument_expression
+	// empty
+		{ $$ = nullptr; }
+	| argument_expression
 	| argument_expression_list ',' argument_expression
 		{ $$ = (ExpressionNode *)( $1->set_last( $3 )); }
@@ -684,7 +686,5 @@
 
 argument_expression:
-	// empty
-		{ $$ = nullptr; }
-	| '@'												// CFA, default parameter
+	'@'													// CFA, default parameter
 		{ SemanticError( yylloc, "Default parameter for argument is currently unimplemented." ); $$ = nullptr; }
 	 	// { $$ = new ExpressionNode( build_constantInteger( *new string( "2" ) ) ); }
Index: src/ResolvExpr/AdjustExprType.cc
===================================================================
--- src/ResolvExpr/AdjustExprType.cc	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/ResolvExpr/AdjustExprType.cc	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -47,7 +47,7 @@
 		void premutate( OneType * ) { visit_children = false; }
 
-		Type * postmutate( ArrayType *arrayType );
-		Type * postmutate( FunctionType *functionType );
-		Type * postmutate( TypeInstType *aggregateUseType );
+		Type * postmutate( ArrayType * arrayType );
+		Type * postmutate( FunctionType * functionType );
+		Type * postmutate( TypeInstType * aggregateUseType );
 
 		private:
@@ -61,5 +61,5 @@
 
 	Type * AdjustExprType_old::postmutate( ArrayType * arrayType ) {
-		PointerType *pointerType = new PointerType{ arrayType->get_qualifiers(), arrayType->base };
+		PointerType * pointerType = new PointerType{ arrayType->get_qualifiers(), arrayType->base };
 		arrayType->base = nullptr;
 		delete arrayType;
@@ -72,10 +72,10 @@
 
 	Type * AdjustExprType_old::postmutate( TypeInstType * typeInst ) {
-		if ( const EqvClass* eqvClass = env.lookup( typeInst->get_name() ) ) {
+		if ( const EqvClass * eqvClass = env.lookup( typeInst->get_name() ) ) {
 			if ( eqvClass->data.kind == TypeDecl::Ftype ) {
 				return new PointerType{ Type::Qualifiers(), typeInst };
 			}
-		} else if ( NamedTypeDecl *ntDecl = indexer.lookupType( typeInst->get_name() ) ) {
-			if ( TypeDecl *tyDecl = dynamic_cast< TypeDecl* >( ntDecl ) ) {
+		} else if ( const NamedTypeDecl * ntDecl = indexer.lookupType( typeInst->get_name() ) ) {
+			if ( const TypeDecl * tyDecl = dynamic_cast< const TypeDecl * >( ntDecl ) ) {
 				if ( tyDecl->get_kind() == TypeDecl::Ftype ) {
 					return new PointerType{ Type::Qualifiers(), typeInst };
@@ -89,5 +89,5 @@
 void adjustExprType( Type *&type, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
 	PassVisitor<AdjustExprType_old> adjuster( env, indexer );
-	Type *newType = type->acceptMutator( adjuster );
+	Type * newType = type->acceptMutator( adjuster );
 	type = newType;
 }
@@ -149,6 +149,6 @@
 } // anonymous namespace
 
-const ast::Type * adjustExprType( 
-	const ast::Type * type, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab 
+const ast::Type * adjustExprType(
+	const ast::Type * type, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab
 ) {
 	ast::Pass<AdjustExprType_new> adjuster{ env, symtab };
Index: src/ResolvExpr/AlternativeFinder.cc
===================================================================
--- src/ResolvExpr/AlternativeFinder.cc	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/ResolvExpr/AlternativeFinder.cc	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -336,7 +336,7 @@
 		}
 
-		if ( StructInstType *structInst = dynamic_cast< StructInstType* >( aggrExpr->result ) ) {
+		if ( StructInstType * structInst = dynamic_cast< StructInstType* >( aggrExpr->result ) ) {
 			addAggMembers( structInst, aggrExpr.get(), alt, alt.cost+Cost::safe, "" );
-		} else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( aggrExpr->result ) ) {
+		} else if ( UnionInstType * unionInst = dynamic_cast< UnionInstType* >( aggrExpr->result ) ) {
 			addAggMembers( unionInst, aggrExpr.get(), alt, alt.cost+Cost::safe, "" );
 		} // if
@@ -344,10 +344,10 @@
 
 	template< typename StructOrUnionType >
-	void AlternativeFinder::Finder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Alternative& alt, const Cost &newCost, const std::string & name ) {
+	void AlternativeFinder::Finder::addAggMembers( StructOrUnionType * aggInst, Expression * expr, const Alternative& alt, const Cost &newCost, const std::string & name ) {
 		std::list< Declaration* > members;
 		aggInst->lookup( name, members );
 
 		for ( Declaration * decl : members ) {
-			if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( decl ) ) {
+			if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType* >( decl ) ) {
 				// addAnonAlternatives uses vector::push_back, which invalidates references to existing elements, so
 				// can't construct in place and use vector::back
@@ -362,5 +362,5 @@
 	}
 
-	void AlternativeFinder::Finder::addTupleMembers( TupleType *tupleType, Expression *expr, 			const Alternative &alt, const Cost &newCost, Expression *member ) {
+	void AlternativeFinder::Finder::addTupleMembers( TupleType * tupleType, Expression * expr, const Alternative &alt, const Cost &newCost, Expression * member ) {
 		if ( ConstantExpr * constantExpr = dynamic_cast< ConstantExpr * >( member ) ) {
 			// get the value of the constant expression as an int, must be between 0 and the length of the tuple type to have meaning
@@ -368,5 +368,5 @@
 			std::string tmp;
 			if ( val >= 0 && (unsigned long long)val < tupleType->size() ) {
-				alternatives.push_back( Alternative{ 
+				alternatives.push_back( Alternative{
 					alt, new TupleIndexExpr( expr->clone(), val ), newCost } );
 			} // if
@@ -374,5 +374,5 @@
 	}
 
-	void AlternativeFinder::Finder::postvisit( ApplicationExpr *applicationExpr ) {
+	void AlternativeFinder::Finder::postvisit( ApplicationExpr * applicationExpr ) {
 		alternatives.push_back( Alternative{ applicationExpr->clone(), env } );
 	}
@@ -475,5 +475,5 @@
 		}
 
-		// specialization cost of return types can't be accounted for directly, it disables 
+		// specialization cost of return types can't be accounted for directly, it disables
 		// otherwise-identical calls, like this example based on auto-newline in the I/O lib:
 		//
@@ -1226,6 +1226,6 @@
 				// count one safe conversion for each value that is thrown away
 				thisCost.incSafe( discardedValues );
-				Alternative newAlt{ 
-					restructureCast( alt.expr->clone(), toType, castExpr->isGenerated ), 
+				Alternative newAlt{
+					restructureCast( alt.expr->clone(), toType, castExpr->isGenerated ),
 					alt.env, openVars, needAssertions, alt.cost, alt.cost + thisCost };
 				inferParameters( newAlt, back_inserter( candidates ) );
@@ -1328,5 +1328,5 @@
 		if ( sizeofExpr->get_isType() ) {
 			Type * newType = sizeofExpr->get_type()->clone();
-			alternatives.push_back( Alternative{ 
+			alternatives.push_back( Alternative{
 				new SizeofExpr{ resolveTypeof( newType, indexer ) }, env } );
 		} else {
@@ -1343,5 +1343,5 @@
 			Alternative &choice = winners.front();
 			referenceToRvalueConversion( choice.expr, choice.cost );
-			alternatives.push_back( Alternative{ 
+			alternatives.push_back( Alternative{
 				choice, new SizeofExpr( choice.expr->clone() ), Cost::zero } );
 		} // if
@@ -1351,5 +1351,5 @@
 		if ( alignofExpr->get_isType() ) {
 			Type * newType = alignofExpr->get_type()->clone();
-			alternatives.push_back( Alternative{ 
+			alternatives.push_back( Alternative{
 				new AlignofExpr{ resolveTypeof( newType, indexer ) }, env } );
 		} else {
@@ -1366,5 +1366,5 @@
 			Alternative &choice = winners.front();
 			referenceToRvalueConversion( choice.expr, choice.cost );
-			alternatives.push_back( Alternative{ 
+			alternatives.push_back( Alternative{
 				choice, new AlignofExpr{ choice.expr->clone() }, Cost::zero } );
 		} // if
@@ -1377,5 +1377,5 @@
 		for ( std::list< Declaration* >::const_iterator i = members.begin(); i != members.end(); ++i ) {
 			if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i ) ) {
-				alternatives.push_back( Alternative{ 
+				alternatives.push_back( Alternative{
 					new OffsetofExpr{ aggInst->clone(), dwt }, env } );
 				renameTypes( alternatives.back().expr );
@@ -1405,8 +1405,8 @@
 
 	namespace {
-		void resolveAttr( SymTab::Indexer::IdData data, FunctionType *function, Type *argType, const TypeEnvironment &env, AlternativeFinder & finder ) {
+		void resolveAttr( SymTab::Indexer::IdData data, const FunctionType * function, Type * argType, const TypeEnvironment &env, AlternativeFinder & finder ) {
 			// assume no polymorphism
 			// assume no implicit conversions
-			assert( function->get_parameters().size() == 1 );
+			assert( function->parameters.size() == 1 );
 			PRINT(
 				std::cerr << "resolvAttr: funcDecl is ";
@@ -1418,9 +1418,9 @@
 			const SymTab::Indexer & indexer = finder.get_indexer();
 			AltList & alternatives = finder.get_alternatives();
-			if ( typesCompatibleIgnoreQualifiers( argType, function->get_parameters().front()->get_type(), indexer, env ) ) {
+			if ( typesCompatibleIgnoreQualifiers( argType, function->parameters.front()->get_type(), indexer, env ) ) {
 				Cost cost = Cost::zero;
 				Expression * newExpr = data.combine( cost );
-				alternatives.push_back( Alternative{ 
-					new AttrExpr{ newExpr, argType->clone() }, env, OpenVarSet{}, 
+				alternatives.push_back( Alternative{
+					new AttrExpr{ newExpr, argType->clone() }, env, OpenVarSet{},
 					AssertionList{}, Cost::zero, cost } );
 				for ( DeclarationWithType * retVal : function->returnVals ) {
@@ -1431,7 +1431,7 @@
 	}
 
-	void AlternativeFinder::Finder::postvisit( AttrExpr *attrExpr ) {
+	void AlternativeFinder::Finder::postvisit( AttrExpr * attrExpr ) {
 		// assume no 'pointer-to-attribute'
-		NameExpr *nameExpr = dynamic_cast< NameExpr* >( attrExpr->get_attr() );
+		NameExpr * nameExpr = dynamic_cast< NameExpr* >( attrExpr->get_attr() );
 		assert( nameExpr );
 		std::list< SymTab::Indexer::IdData > attrList;
@@ -1439,9 +1439,9 @@
 		if ( attrExpr->get_isType() || attrExpr->get_expr() ) {
 			for ( auto & data : attrList ) {
-				DeclarationWithType * id = data.id;
+				const DeclarationWithType * id = data.id;
 				// check if the type is function
-				if ( FunctionType *function = dynamic_cast< FunctionType* >( id->get_type() ) ) {
+				if ( const FunctionType * function = dynamic_cast< const FunctionType * >( id->get_type() ) ) {
 					// assume exactly one parameter
-					if ( function->get_parameters().size() == 1 ) {
+					if ( function->parameters.size() == 1 ) {
 						if ( attrExpr->get_isType() ) {
 							resolveAttr( data, function, attrExpr->get_type(), env, altFinder);
@@ -1462,5 +1462,5 @@
 				Cost cost = Cost::zero;
 				Expression * newExpr = data.combine( cost );
-				alternatives.push_back( Alternative{ 
+				alternatives.push_back( Alternative{
 					newExpr, env, OpenVarSet{}, AssertionList{}, Cost::zero, cost } );
 				renameTypes( alternatives.back().expr );
@@ -1469,5 +1469,5 @@
 	}
 
-	void AlternativeFinder::Finder::postvisit( LogicalExpr *logicalExpr ) {
+	void AlternativeFinder::Finder::postvisit( LogicalExpr * logicalExpr ) {
 		AlternativeFinder firstFinder( indexer, env );
 		firstFinder.findWithAdjustment( logicalExpr->get_arg1() );
@@ -1486,8 +1486,8 @@
 				cloneAll( second.need, need );
 
-				LogicalExpr *newExpr = new LogicalExpr{ 
+				LogicalExpr *newExpr = new LogicalExpr{
 					first.expr->clone(), second.expr->clone(), logicalExpr->get_isAnd() };
-				alternatives.push_back( Alternative{ 
-					newExpr, std::move(compositeEnv), std::move(openVars), 
+				alternatives.push_back( Alternative{
+					newExpr, std::move(compositeEnv), std::move(openVars),
 					AssertionList( need.begin(), need.end() ), first.cost + second.cost } );
 			}
@@ -1522,21 +1522,21 @@
 					cloneAll( third.need, need );
 					AssertionSet have;
-					
+
 					// unify true and false types, then infer parameters to produce new alternatives
 					Type* commonType = nullptr;
-					if ( unify( second.expr->result, third.expr->result, compositeEnv, 
+					if ( unify( second.expr->result, third.expr->result, compositeEnv,
 							need, have, openVars, indexer, commonType ) ) {
-						ConditionalExpr *newExpr = new ConditionalExpr{ 
+						ConditionalExpr *newExpr = new ConditionalExpr{
 							first.expr->clone(), second.expr->clone(), third.expr->clone() };
 						newExpr->result = commonType ? commonType : second.expr->result->clone();
 						// convert both options to the conditional result type
 						Cost cost = first.cost + second.cost + third.cost;
-						cost += computeExpressionConversionCost( 
+						cost += computeExpressionConversionCost(
 							newExpr->arg2, newExpr->result, indexer, compositeEnv );
-						cost += computeExpressionConversionCost( 
+						cost += computeExpressionConversionCost(
 							newExpr->arg3, newExpr->result, indexer, compositeEnv );
 						// output alternative
-						Alternative newAlt{ 
-							newExpr, std::move(compositeEnv), std::move(openVars), 
+						Alternative newAlt{
+							newExpr, std::move(compositeEnv), std::move(openVars),
 							AssertionList( need.begin(), need.end() ), cost };
 						inferParameters( newAlt, back_inserter( alternatives ) );
@@ -1553,5 +1553,5 @@
 		secondFinder.findWithAdjustment( commaExpr->get_arg2() );
 		for ( const Alternative & alt : secondFinder.alternatives ) {
-			alternatives.push_back( Alternative{ 
+			alternatives.push_back( Alternative{
 				alt, new CommaExpr{ newFirstArg->clone(), alt.expr->clone() }, alt.cost } );
 		} // for
@@ -1579,11 +1579,11 @@
 
 				Type* commonType = nullptr;
-				if ( unify( first.expr->result, second.expr->result, compositeEnv, need, have, 
+				if ( unify( first.expr->result, second.expr->result, compositeEnv, need, have,
 						openVars, indexer, commonType ) ) {
-					RangeExpr * newExpr = 
+					RangeExpr * newExpr =
 						new RangeExpr{ first.expr->clone(), second.expr->clone() };
 					newExpr->result = commonType ? commonType : first.expr->result->clone();
-					Alternative newAlt{ 
-						newExpr, std::move(compositeEnv), std::move(openVars), 
+					Alternative newAlt{
+						newExpr, std::move(compositeEnv), std::move(openVars),
 						AssertionList( need.begin(), need.end() ), first.cost + second.cost };
 					inferParameters( newAlt, back_inserter( alternatives ) );
@@ -1612,7 +1612,7 @@
 				cloneAll( alt.need, need );
 			}
-			
-			alternatives.push_back( Alternative{ 
-				new TupleExpr{ exprs }, std::move(compositeEnv), std::move(openVars), 
+
+			alternatives.push_back( Alternative{
+				new TupleExpr{ exprs }, std::move(compositeEnv), std::move(openVars),
 				AssertionList( need.begin(), need.end() ), sumCost( alts ) } );
 		} // for
@@ -1633,5 +1633,5 @@
 		finder.findWithoutPrune( ctorExpr->get_callExpr() );
 		for ( Alternative & alt : finder.alternatives ) {
-			alternatives.push_back( Alternative{ 
+			alternatives.push_back( Alternative{
 				alt, new ConstructorExpr( alt.expr->clone() ), alt.cost } );
 		}
@@ -1685,21 +1685,21 @@
 				cloneAll( alt.need, need );
 				AssertionSet have;
-				OpenVarSet openVars( alt.openVars );  
-				// xxx - find things in env that don't have a "representative type" and claim 
+				OpenVarSet openVars( alt.openVars );
+				// xxx - find things in env that don't have a "representative type" and claim
 				// those are open vars?
 				PRINT(
 					std::cerr << "  @ " << toType << " " << initAlt.designation << std::endl;
 				)
-				// It's possible that a cast can throw away some values in a multiply-valued 
-				// expression. (An example is a cast-to-void, which casts from one value to 
-				// zero.)  Figure out the prefix of the subexpression results that are cast 
-				// directly.  The candidate is invalid if it has fewer results than there are 
+				// It's possible that a cast can throw away some values in a multiply-valued
+				// expression. (An example is a cast-to-void, which casts from one value to
+				// zero.)  Figure out the prefix of the subexpression results that are cast
+				// directly.  The candidate is invalid if it has fewer results than there are
 				// types to cast to.
 				int discardedValues = alt.expr->result->size() - toType->size();
 				if ( discardedValues < 0 ) continue;
-				// xxx - may need to go into tuple types and extract relevant types and use 
-				// unifyList. Note that currently, this does not allow casting a tuple to an 
+				// xxx - may need to go into tuple types and extract relevant types and use
+				// unifyList. Note that currently, this does not allow casting a tuple to an
 				// atomic type (e.g. (int)([1, 2, 3]))
-				
+
 				// unification run for side-effects
 				unify( toType, alt.expr->result, newEnv, need, have, openVars, indexer );
@@ -1710,8 +1710,8 @@
 					// count one safe conversion for each value that is thrown away
 					thisCost.incSafe( discardedValues );
-					Alternative newAlt{ 
-						new InitExpr{ 
-							restructureCast( alt.expr->clone(), toType, true ), initAlt.designation->clone() }, 
-						std::move(newEnv), std::move(openVars), 
+					Alternative newAlt{
+						new InitExpr{
+							restructureCast( alt.expr->clone(), toType, true ), initAlt.designation->clone() },
+						std::move(newEnv), std::move(openVars),
 						AssertionList( need.begin(), need.end() ), alt.cost, thisCost };
 					inferParameters( newAlt, back_inserter( candidates ) );
Index: src/ResolvExpr/CastCost.cc
===================================================================
--- src/ResolvExpr/CastCost.cc	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/ResolvExpr/CastCost.cc	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -37,15 +37,15 @@
 	struct CastCost_old : public ConversionCost {
 	  public:
-		CastCost_old( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc );
+		CastCost_old( const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc );
 
 		using ConversionCost::previsit;
 		using ConversionCost::postvisit;
-		void postvisit( BasicType * basicType );
-		void postvisit( PointerType * pointerType );
+		void postvisit( const BasicType * basicType );
+		void postvisit( const PointerType * pointerType );
 	};
 
-	Cost castCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
-		if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
-			if ( const EqvClass* eqvClass = env.lookup( destAsTypeInst->get_name() ) ) {
+	Cost castCost( const Type * src, const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
+		if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType * >( dest ) ) {
+			if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->name ) ) {
 				if ( eqvClass->type ) {
 					return castCost( src, eqvClass->type, indexer, env );
@@ -53,7 +53,7 @@
 					return Cost::infinity;
 				}
-			} else if ( NamedTypeDecl *namedType = indexer.lookupType( destAsTypeInst->get_name() ) ) {
+			} else if ( const NamedTypeDecl * namedType = indexer.lookupType( destAsTypeInst->name ) ) {
 				// all typedefs should be gone by this point
-				TypeDecl *type = strict_dynamic_cast< TypeDecl* >( namedType );
+				const TypeDecl * type = strict_dynamic_cast< const TypeDecl * >( namedType );
 				if ( type->base ) {
 					return castCost( src, type->base, indexer, env ) + Cost::safe;
@@ -74,15 +74,15 @@
 			PRINT( std::cerr << "compatible!" << std::endl; )
 			return Cost::zero;
-		} else if ( dynamic_cast< VoidType* >( dest ) ) {
+		} else if ( dynamic_cast< const VoidType * >( dest ) ) {
 			return Cost::safe;
-		} else if ( ReferenceType * refType = dynamic_cast< ReferenceType * > ( dest ) ) {
+		} else if ( const ReferenceType * refType = dynamic_cast< const ReferenceType * > ( dest ) ) {
 			PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; )
-			return convertToReferenceCost( src, refType, indexer, env, [](Type * t1, Type * t2, const SymTab::Indexer & indexer, const TypeEnvironment & env ) {
+			return convertToReferenceCost( src, refType, indexer, env, [](const Type * t1, const Type * t2, const SymTab::Indexer & indexer, const TypeEnvironment & env ) {
 				return ptrsCastable( t1, t2, env, indexer );
 			});
 		} else {
-			PassVisitor<CastCost_old> converter( 
-				dest, indexer, env, 
-				(Cost (*)( Type *, Type *, const SymTab::Indexer &, const TypeEnvironment & ))
+			PassVisitor<CastCost_old> converter(
+				dest, indexer, env,
+				(Cost (*)( const Type *, const Type *, const SymTab::Indexer &, const TypeEnvironment & ))
 					castCost );
 			src->accept( converter );
@@ -96,12 +96,12 @@
 	}
 
-	CastCost_old::CastCost_old( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )
+	CastCost_old::CastCost_old( const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )
 		: ConversionCost( dest, indexer, env, costFunc ) {
 	}
 
-	void CastCost_old::postvisit( BasicType *basicType ) {
-		PointerType *destAsPointer = dynamic_cast< PointerType* >( dest );
+	void CastCost_old::postvisit( const BasicType * basicType ) {
+		const PointerType * destAsPointer = dynamic_cast< const PointerType * >( dest );
 		if ( destAsPointer && basicType->isInteger() ) {
-			// necessary for, e.g. unsigned long => void*
+			// necessary for, e.g. unsigned long => void *
 			cost = Cost::unsafe;
 		} else {
@@ -110,7 +110,7 @@
 	}
 
-	void CastCost_old::postvisit( PointerType *pointerType ) {
-		if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) {
-			if ( pointerType->get_qualifiers() <= destAsPtr->get_qualifiers() && typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) {
+	void CastCost_old::postvisit( const PointerType * pointerType ) {
+		if ( const PointerType * destAsPtr = dynamic_cast< const PointerType * >( dest ) ) {
+			if ( pointerType->tq <= destAsPtr->tq && typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) {
 				cost = Cost::safe;
 			} else {
@@ -125,7 +125,7 @@
 				} // if
 			} // if
-		} else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
+		} else if ( const BasicType * destAsBasic = dynamic_cast< const BasicType * >( dest ) ) {
 			if ( destAsBasic->isInteger() ) {
-				// necessary for, e.g. void* => unsigned long
+				// necessary for, e.g. void * => unsigned long
 				cost = Cost::unsafe;
 			} // if
@@ -138,6 +138,6 @@
 		using ConversionCost_new::postvisit;
 
-		CastCost_new( 
-			const ast::Type * dst, const ast::SymbolTable & symtab, 
+		CastCost_new(
+			const ast::Type * dst, const ast::SymbolTable & symtab,
 			const ast::TypeEnvironment & env, CostCalculation costFunc )
 		: ConversionCost_new( dst, symtab, env, costFunc ) {}
@@ -182,7 +182,7 @@
 } // anonymous namespace
 
-Cost castCost( 
-	const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 
-	const ast::TypeEnvironment & env 
+Cost castCost(
+	const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
+	const ast::TypeEnvironment & env
 ) {
 	if ( auto typeInst = dynamic_cast< const ast::TypeInstType * >( dst ) ) {
@@ -220,8 +220,8 @@
 		PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; )
 		#warning cast on ptrsCastable artifact of having two functions, remove when port done
-		return convertToReferenceCost( 
-			src, refType, symtab, env, 
-			( int (*)( 
-				const ast::Type *, const ast::Type *, const ast::SymbolTable &, 
+		return convertToReferenceCost(
+			src, refType, symtab, env,
+			( int (*)(
+				const ast::Type *, const ast::Type *, const ast::SymbolTable &,
 				const ast::TypeEnvironment & )
 			) ptrsCastable );
@@ -229,7 +229,7 @@
 		#warning cast on castCost artifact of having two functions, remove when port done
 		ast::Pass< CastCost_new > converter{
-			dst, symtab, env, 
-			( Cost (*)( 
-				const ast::Type *, const ast::Type *, const ast::SymbolTable &, 
+			dst, symtab, env,
+			( Cost (*)(
+				const ast::Type *, const ast::Type *, const ast::SymbolTable &,
 				const ast::TypeEnvironment & )
 			) castCost };
Index: src/ResolvExpr/CommonType.cc
===================================================================
--- src/ResolvExpr/CommonType.cc	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/ResolvExpr/CommonType.cc	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -38,6 +38,6 @@
 namespace ResolvExpr {
 	struct CommonType_old : public WithShortCircuiting {
-		CommonType_old( Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars );
-		Type *get_result() const { return result; }
+		CommonType_old( 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; }
@@ -60,9 +60,9 @@
 
 	  private:
-		template< typename Pointer > void getCommonWithVoidPointer( Pointer* voidPointer, Pointer* otherPointer );
-		template< typename RefType > void handleRefType( RefType *inst, Type *other );
-
-		Type *result;
-		Type *type2;				// inherited
+		template< typename Pointer > void getCommonWithVoidPointer( Pointer * voidPointer, Pointer * otherPointer );
+		template< typename RefType > void handleRefType( RefType * inst, Type * other );
+
+		Type * result;
+		Type * type2;				// inherited
 		bool widenFirst, widenSecond;
 		const SymTab::Indexer &indexer;
@@ -80,10 +80,10 @@
 				std::cerr << "unify success: " << widenFirst << " " << widenSecond << std::endl;
 			)
-			if ( (widenFirst || t2->get_qualifiers() <= t1->get_qualifiers()) && (widenSecond || t1->get_qualifiers() <= t2->get_qualifiers()) ) {
+			if ( (widenFirst || t2->tq <= t1->tq) && (widenSecond || t1->tq <= t2->tq) ) {
 				PRINT(
 					std::cerr << "widen okay" << std::endl;
 				)
-				common->get_qualifiers() |= t1->get_qualifiers();
-				common->get_qualifiers() |= t2->get_qualifiers();
+				common->tq |= t1->tq;
+				common->tq |= t2->tq;
 				return common;
 			}
@@ -95,5 +95,5 @@
 	}
 
-	Type *commonType( Type *type1, Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars ) {
+	Type * commonType( Type * type1, Type * type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars ) {
 		PassVisitor<CommonType_old> visitor( type2, widenFirst, widenSecond, indexer, env, openVars );
 
@@ -127,5 +127,5 @@
 						std::cerr << "formal is reference; result should be reference" << std::endl;
 					)
-					result = new ReferenceType( ref1->get_qualifiers(), result );
+					result = new ReferenceType( ref1->tq, result );
 				}
 				PRINT(
@@ -138,23 +138,23 @@
 
 		type1->accept( visitor );
-		Type *result = visitor.pass.get_result();
+		Type * result = visitor.pass.get_result();
 		if ( ! result ) {
 			// this appears to be handling for opaque type declarations
 			if ( widenSecond ) {
-				if ( TypeInstType *inst = dynamic_cast< TypeInstType* >( type2 ) ) {
-					if ( NamedTypeDecl *nt = indexer.lookupType( inst->get_name() ) ) {
-						TypeDecl *type = strict_dynamic_cast< TypeDecl* >( nt );
+				if ( const TypeInstType * inst = dynamic_cast< const TypeInstType * >( type2 ) ) {
+					if ( const NamedTypeDecl * nt = indexer.lookupType( inst->get_name() ) ) {
+						const TypeDecl * type = strict_dynamic_cast< const TypeDecl * >( nt );
 						if ( type->get_base() ) {
-							Type::Qualifiers tq1 = type1->get_qualifiers(), tq2 = type2->get_qualifiers();
+							Type::Qualifiers tq1 = type1->tq, tq2 = type2->tq;
 							AssertionSet have, need;
 							OpenVarSet newOpen( openVars );
-							type1->get_qualifiers() = Type::Qualifiers();
-							type->get_base()->get_qualifiers() = tq1;
+							type1->tq = Type::Qualifiers();
+							type->get_base()->tq = tq1;
 							if ( unifyExact( type1, type->get_base(), env, have, need, newOpen, indexer ) ) {
 								result = type1->clone();
-								result->get_qualifiers() = tq1 | tq2;
+								result->tq = tq1 | tq2;
 							} // if
-							type1->get_qualifiers() = tq1;
-							type->get_base()->get_qualifiers() = Type::Qualifiers();
+							type1->tq = tq1;
+							type->get_base()->tq = Type::Qualifiers();
 						} // if
 					} // if
@@ -190,5 +190,5 @@
 				 */
 				  {
-		/*     B*/                BT Bool,                BT Char,          BT SignedChar,        BT UnsignedChar,      BT ShortSignedInt,    BT ShortUnsignedInt,
+		/*     B */                BT Bool,                BT Char,          BT SignedChar,        BT UnsignedChar,      BT ShortSignedInt,    BT ShortUnsignedInt,
 				             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
 				          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
@@ -198,5 +198,5 @@
 				  },
 				  {
-		/*     C*/                BT Char,                BT Char,          BT SignedChar,        BT UnsignedChar,      BT ShortSignedInt,    BT ShortUnsignedInt,
+		/*     C */                BT Char,                BT Char,          BT SignedChar,        BT UnsignedChar,      BT ShortSignedInt,    BT ShortUnsignedInt,
 				             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
 				          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
@@ -206,5 +206,5 @@
 				  },
 				  {
-		/*    SC*/          BT SignedChar,          BT SignedChar,          BT SignedChar,        BT UnsignedChar,      BT ShortSignedInt,    BT ShortUnsignedInt,
+		/*    SC */          BT SignedChar,          BT SignedChar,          BT SignedChar,        BT UnsignedChar,      BT ShortSignedInt,    BT ShortUnsignedInt,
 				             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
 				          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
@@ -214,5 +214,5 @@
 				  },
 				  {
-		/*    UC*/        BT UnsignedChar,        BT UnsignedChar,        BT UnsignedChar,        BT UnsignedChar,      BT ShortSignedInt,    BT ShortUnsignedInt,
+		/*    UC */        BT UnsignedChar,        BT UnsignedChar,        BT UnsignedChar,        BT UnsignedChar,      BT ShortSignedInt,    BT ShortUnsignedInt,
 				             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
 				          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
@@ -222,5 +222,5 @@
 				  },
 				  {
-		/*    SI*/      BT ShortSignedInt,      BT ShortSignedInt,      BT ShortSignedInt,      BT ShortSignedInt,      BT ShortSignedInt,    BT ShortUnsignedInt,
+		/*    SI */      BT ShortSignedInt,      BT ShortSignedInt,      BT ShortSignedInt,      BT ShortSignedInt,      BT ShortSignedInt,    BT ShortUnsignedInt,
 				             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
 				          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
@@ -230,5 +230,5 @@
 				  },
 				  {
-		/*   SUI*/    BT ShortUnsignedInt,    BT ShortUnsignedInt,    BT ShortUnsignedInt,    BT ShortUnsignedInt,    BT ShortUnsignedInt,    BT ShortUnsignedInt,
+		/*   SUI */    BT ShortUnsignedInt,    BT ShortUnsignedInt,    BT ShortUnsignedInt,    BT ShortUnsignedInt,    BT ShortUnsignedInt,    BT ShortUnsignedInt,
 				             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
 				          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
@@ -238,5 +238,5 @@
 				  },
 				  {
-		/*     I*/           BT SignedInt,           BT SignedInt,           BT SignedInt,           BT SignedInt,           BT SignedInt,           BT SignedInt,
+		/*     I */           BT SignedInt,           BT SignedInt,           BT SignedInt,           BT SignedInt,           BT SignedInt,           BT SignedInt,
 				             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
 				          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
@@ -246,5 +246,5 @@
 				  },
 				  {
-		/*    UI*/         BT UnsignedInt,         BT UnsignedInt,         BT UnsignedInt,         BT UnsignedInt,         BT UnsignedInt,         BT UnsignedInt,
+		/*    UI */         BT UnsignedInt,         BT UnsignedInt,         BT UnsignedInt,         BT UnsignedInt,         BT UnsignedInt,         BT UnsignedInt,
 				           BT UnsignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
 				          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
@@ -254,5 +254,5 @@
 				  },
 				  {
-		/*    LI*/       BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,
+		/*    LI */       BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,
 				         BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
 				          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
@@ -262,5 +262,5 @@
 				  },
 				  {
-		/*   LUI*/     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,
+		/*   LUI */     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,
 				       BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
 				          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
@@ -270,5 +270,5 @@
 				  },
 				  {
-		/*   LLI*/   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,
+		/*   LLI */   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,
 				     BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
 				          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
@@ -278,5 +278,5 @@
 				  },
 				  {
-		/*  LLUI*/ BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt,
+		/*  LLUI */ BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt,
 				   BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt,
 				          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
@@ -286,5 +286,5 @@
 				  },
 				  {
-		/*    IB*/        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,
+		/*    IB */        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,
 				          BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,
 				          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
@@ -294,5 +294,5 @@
 				  },
 				  {
-		/*   UIB*/      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,
+		/*   UIB */      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,
 				        BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,
 				        BT UnsignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
@@ -302,5 +302,5 @@
 				  },
 				  {
-		/*   _FH*/            BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,
+		/*   _FH */            BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,
 				              BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,
 				              BT uFloat16,            BT uFloat16,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
@@ -310,5 +310,5 @@
 				  },
 				  {
-		/*   _FH*/     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,
+		/*   _FH */     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,
 				       BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,
 				       BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat32Complex,     BT uFloat32Complex,
@@ -318,5 +318,5 @@
 				  },
 				  {
-		/*    _F*/            BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,
+		/*    _F */            BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,
 				              BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,
 				              BT uFloat32,            BT uFloat32,            BT uFloat32,     BT uFloat32Complex,            BT uFloat32,     BT uFloat32Complex,
@@ -326,5 +326,5 @@
 				  },
 				  {
-		/*   _FC*/     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,
+		/*   _FC */     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,
 				       BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,
 				       BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,
@@ -334,5 +334,5 @@
 				  },
 				  {
-		/*     F*/               BT Float,               BT Float,               BT Float,               BT Float,               BT Float,               BT Float,
+		/*     F */               BT Float,               BT Float,               BT Float,               BT Float,               BT Float,               BT Float,
 				                 BT Float,               BT Float,               BT Float,               BT Float,               BT Float,               BT Float,
 				                 BT Float,               BT Float,               BT Float,        BT FloatComplex,               BT Float,        BT FloatComplex,
@@ -342,5 +342,5 @@
 				  },
 				  {
-		/*    FC*/        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,
+		/*    FC */        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,
 				          BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,
 				          BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,
@@ -350,5 +350,5 @@
 				  },
 				  {
-		/*   _FX*/           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,
+		/*   _FX */           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,
 				             BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,
 				             BT uFloat32x,           BT uFloat32x,           BT uFloat32x,    BT uFloat32xComplex,           BT uFloat32x,    BT uFloat32xComplex,
@@ -358,5 +358,5 @@
 				  },
 				  {
-		/*  _FXC*/    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,
+		/*  _FXC */    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,
 				      BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,
 				      BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,
@@ -366,5 +366,5 @@
 				  },
 				  {
-		/*    FD*/            BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,
+		/*    FD */            BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,
 				              BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,
 				              BT uFloat64,            BT uFloat64,            BT uFloat64,     BT uFloat64Complex,            BT uFloat64,     BT uFloat64Complex,
@@ -374,5 +374,5 @@
 				  },
 				  {
-		/*  _FDC*/     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,
+		/*  _FDC */     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,
 				       BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,
 				       BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,
@@ -382,5 +382,5 @@
 				  },
 				  {
-		/*     D*/              BT Double,              BT Double,              BT Double,              BT Double,              BT Double,              BT Double,
+		/*     D */              BT Double,              BT Double,              BT Double,              BT Double,              BT Double,              BT Double,
 				                BT Double,              BT Double,              BT Double,              BT Double,              BT Double,              BT Double,
 				                BT Double,              BT Double,              BT Double,       BT DoubleComplex,              BT Double,       BT DoubleComplex,
@@ -390,5 +390,5 @@
 				  },
 				  {
-		/*    DC*/       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,
+		/*    DC */       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,
 				         BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,
 				         BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,
@@ -398,5 +398,5 @@
 				  },
 				  {
-		/*  F80X*/           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,
+		/*  F80X */           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,
 				             BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,
 				             BT uFloat64x,           BT uFloat64x,           BT uFloat64x,    BT uFloat64xComplex,           BT uFloat64x,    BT uFloat64xComplex,
@@ -406,5 +406,5 @@
 				  },
 				  {
-		/* _FDXC*/    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,
+		/* _FDXC */    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,
 				      BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,
 				      BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,
@@ -422,5 +422,5 @@
 				  },
 				  {
-		/*   _FB*/           BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,
+		/*   _FB */           BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,
 				             BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,
 				             BT uFloat128,           BT uFloat128,           BT uFloat128,    BT uFloat128Complex,           BT uFloat128,    BT uFloat128Complex,
@@ -430,5 +430,5 @@
 				  },
 				  {
-		/* _FLDC*/    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,
+		/* _FLDC */    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,
 				      BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,
 				      BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,
@@ -438,5 +438,5 @@
 				  },
 				  {
-		/*    FB*/          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,
+		/*    FB */          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,
 				            BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,
 				            BT uuFloat128,          BT uuFloat128,          BT uuFloat128,    BT uFloat128Complex,          BT uuFloat128,    BT uFloat128Complex,
@@ -446,5 +446,5 @@
 				  },
 				  {
-		/*    LD*/          BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,
+		/*    LD */          BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,
 				            BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,
 				            BT LongDouble,          BT LongDouble,          BT LongDouble,   BT LongDoubleComplex,          BT LongDouble,   BT LongDoubleComplex,
@@ -454,5 +454,5 @@
 				  },
 				  {
-		/*   LDC*/   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,
+		/*   LDC */   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,
 				     BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,
 				     BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,
@@ -462,5 +462,5 @@
 				  },
 				  {
-		/*  _FBX*/          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,
+		/*  _FBX */          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,
 				            BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,
 				            BT uFloat128x,          BT uFloat128x,          BT uFloat128x,   BT uFloat128xComplex,          BT uFloat128x,   BT uFloat128xComplex,
@@ -470,5 +470,5 @@
 				  },
 				  {
-		/*_FLDXC*/   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
+		/* _FLDXC */   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
 				     BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
 				     BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
@@ -481,9 +481,9 @@
 	// GENERATED END
 	static_assert(
-		sizeof(commonTypes)/sizeof(commonTypes[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES*BasicType::NUMBER_OF_BASIC_TYPES,
+		sizeof(commonTypes)/sizeof(commonTypes[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES * BasicType::NUMBER_OF_BASIC_TYPES,
 		"Each basic type kind should have a corresponding row in the combined type matrix"
 	);
 
-	CommonType_old::CommonType_old( Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars )
+	CommonType_old::CommonType_old( Type * type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars )
 		: result( 0 ), type2( type2 ), widenFirst( widenFirst ), widenSecond( widenSecond ), indexer( indexer ), env( env ), openVars( openVars ) {
 	}
@@ -491,15 +491,15 @@
 	void CommonType_old::postvisit( VoidType * ) {}
 
-	void CommonType_old::postvisit( BasicType *basicType ) {
-		if ( BasicType *otherBasic = dynamic_cast< BasicType* >( type2 ) ) {
+	void CommonType_old::postvisit( BasicType * basicType ) {
+		if ( BasicType * otherBasic = dynamic_cast< BasicType * >( type2 ) ) {
 			BasicType::Kind newType = commonTypes[ basicType->get_kind() ][ otherBasic->get_kind() ];
-			if ( ( ( newType == basicType->get_kind() && basicType->get_qualifiers() >= otherBasic->get_qualifiers() ) || widenFirst ) && ( ( newType == otherBasic->get_kind() && basicType->get_qualifiers() <= otherBasic->get_qualifiers() ) || widenSecond ) ) {
-				result = new BasicType( basicType->get_qualifiers() | otherBasic->get_qualifiers(), newType );
+			if ( ( ( newType == basicType->get_kind() && basicType->tq >= otherBasic->tq ) || widenFirst ) && ( ( newType == otherBasic->get_kind() && basicType->tq <= otherBasic->tq ) || widenSecond ) ) {
+				result = new BasicType( basicType->tq | otherBasic->tq, newType );
 			} // if
-		} else if ( dynamic_cast< EnumInstType * > ( type2 ) || dynamic_cast< ZeroType* >( type2 ) || dynamic_cast< OneType* >( type2 ) ) {
+		} else if ( dynamic_cast< EnumInstType * > ( type2 ) || dynamic_cast< ZeroType * >( type2 ) || dynamic_cast< OneType * >( type2 ) ) {
 			// use signed int in lieu of the enum/zero/one type
 			BasicType::Kind newType = commonTypes[ basicType->get_kind() ][ BasicType::SignedInt ];
-			if ( ( ( newType == basicType->get_kind() && basicType->get_qualifiers() >= type2->get_qualifiers() ) || widenFirst ) && ( ( newType != basicType->get_kind() && basicType->get_qualifiers() <= type2->get_qualifiers() ) || widenSecond ) ) {
-				result = new BasicType( basicType->get_qualifiers() | type2->get_qualifiers(), newType );
+			if ( ( ( newType == basicType->get_kind() && basicType->tq >= type2->tq ) || widenFirst ) && ( ( newType != basicType->get_kind() && basicType->tq <= type2->tq ) || widenSecond ) ) {
+				result = new BasicType( basicType->tq | type2->tq, newType );
 			} // if
 		} // if
@@ -507,6 +507,6 @@
 
 	template< typename Pointer >
-	void CommonType_old::getCommonWithVoidPointer( Pointer* voidPointer, Pointer* otherPointer ) {
-		if ( TypeInstType* var = dynamic_cast< TypeInstType* >( otherPointer->get_base() ) ) {
+	void CommonType_old::getCommonWithVoidPointer( Pointer * voidPointer, Pointer * otherPointer ) {
+		if ( TypeInstType * var = dynamic_cast< TypeInstType * >( otherPointer->get_base() ) ) {
 			OpenVarSet::const_iterator entry = openVars.find( var->get_name() );
 			if ( entry != openVars.end() ) {
@@ -517,20 +517,20 @@
 		}
 		result = voidPointer->clone();
-		result->get_qualifiers() |= otherPointer->get_qualifiers();
-	}
-
-	void CommonType_old::postvisit( PointerType *pointerType ) {
-		if ( PointerType *otherPointer = dynamic_cast< PointerType* >( type2 ) ) {
+		result->tq |= otherPointer->tq;
+	}
+
+	void CommonType_old::postvisit( PointerType * pointerType ) {
+		if ( PointerType * otherPointer = dynamic_cast< PointerType * >( type2 ) ) {
 			// std::cerr << "commonType: two pointers: " << pointerType << " / " << otherPointer << std::endl;
-			if ( widenFirst && dynamic_cast< VoidType* >( otherPointer->get_base() ) && ! isFtype(pointerType->get_base()) ) {
+			if ( widenFirst && dynamic_cast< VoidType * >( otherPointer->get_base() ) && ! isFtype(pointerType->get_base()) ) {
 				getCommonWithVoidPointer( otherPointer, pointerType );
-			} else if ( widenSecond && dynamic_cast< VoidType* >( pointerType->get_base() ) && ! isFtype(otherPointer->get_base()) ) {
+			} else if ( widenSecond && dynamic_cast< VoidType * >( pointerType->get_base() ) && ! isFtype(otherPointer->get_base()) ) {
 				getCommonWithVoidPointer( pointerType, otherPointer );
-			} else if ( ( pointerType->get_base()->get_qualifiers() >= otherPointer->get_base()->get_qualifiers() || widenFirst )
-					   && ( pointerType->get_base()->get_qualifiers() <= otherPointer->get_base()->get_qualifiers() || widenSecond ) ) {
+			} else if ( ( pointerType->get_base()->tq >= otherPointer->get_base()->tq || widenFirst )
+					   && ( pointerType->get_base()->tq <= otherPointer->get_base()->tq || widenSecond ) ) {
 				// std::cerr << "middle case" << std::endl;
-				Type::Qualifiers tq1 = pointerType->get_base()->get_qualifiers(), tq2 = otherPointer->get_base()->get_qualifiers();
-				pointerType->get_base()->get_qualifiers() = Type::Qualifiers();
-				otherPointer->get_base()->get_qualifiers() = Type::Qualifiers();
+				Type::Qualifiers tq1 = pointerType->get_base()->tq, tq2 = otherPointer->get_base()->tq;
+				pointerType->get_base()->tq = Type::Qualifiers();
+				otherPointer->get_base()->tq = Type::Qualifiers();
 				AssertionSet have, need;
 				OpenVarSet newOpen( openVars );
@@ -542,14 +542,14 @@
 						result = otherPointer->clone();
 					} // if
-					strict_dynamic_cast<PointerType*>(result)->base->get_qualifiers() = tq1 | tq2;
+					strict_dynamic_cast<PointerType *>(result)->base->tq = tq1 | tq2;
 				} else {
 					/// std::cerr << "place for ptr-to-type" << std::endl;
 				} // if
-				pointerType->get_base()->get_qualifiers() = tq1;
-				otherPointer->get_base()->get_qualifiers() = tq2;
+				pointerType->get_base()->tq = tq1;
+				otherPointer->get_base()->tq = tq2;
 			} // if
-		} else if ( widenSecond && dynamic_cast< ZeroType* >( type2 ) ) {
+		} else if ( widenSecond && dynamic_cast< ZeroType * >( type2 ) ) {
 			result = pointerType->clone();
-			result->get_qualifiers() |= type2->get_qualifiers();
+			result->tq |= type2->tq;
 		} // if
 	}
@@ -557,18 +557,18 @@
 	void CommonType_old::postvisit( ArrayType * ) {}
 
-	void CommonType_old::postvisit( ReferenceType *refType ) {
-		if ( ReferenceType *otherRef = dynamic_cast< ReferenceType* >( type2 ) ) {
+	void CommonType_old::postvisit( ReferenceType * refType ) {
+		if ( ReferenceType * otherRef = dynamic_cast< ReferenceType * >( type2 ) ) {
 			// std::cerr << "commonType: both references: " << refType << " / " << otherRef << std::endl;
-			// std::cerr << ( refType->get_base()->get_qualifiers() >= otherRef->get_base()->get_qualifiers() || widenFirst ) << (refType->get_base()->get_qualifiers() <= otherRef->get_base()->get_qualifiers() || widenSecond) << std::endl;
-			if ( widenFirst && dynamic_cast< VoidType* >( otherRef->get_base() ) && ! isFtype(refType->get_base()) ) {
+			// std::cerr << ( refType->get_base()->tq >= otherRef->get_base()->tq || widenFirst ) << (refType->get_base()->tq <= otherRef->get_base()->tq || widenSecond) << std::endl;
+			if ( widenFirst && dynamic_cast< VoidType * >( otherRef->get_base() ) && ! isFtype(refType->get_base()) ) {
 				getCommonWithVoidPointer( otherRef, refType );
-			} else if ( widenSecond && dynamic_cast< VoidType* >( refType->get_base() ) && ! isFtype(otherRef->get_base()) ) {
+			} else if ( widenSecond && dynamic_cast< VoidType * >( refType->get_base() ) && ! isFtype(otherRef->get_base()) ) {
 				getCommonWithVoidPointer( refType, otherRef );
-			} else if ( ( refType->get_base()->get_qualifiers() >= otherRef->get_base()->get_qualifiers() || widenFirst )
-					   && ( refType->get_base()->get_qualifiers() <= otherRef->get_base()->get_qualifiers() || widenSecond ) ) {
+			} else if ( ( refType->get_base()->tq >= otherRef->get_base()->tq || widenFirst )
+					   && ( refType->get_base()->tq <= otherRef->get_base()->tq || widenSecond ) ) {
 				// std::cerr << "middle case" << std::endl;
-				Type::Qualifiers tq1 = refType->get_base()->get_qualifiers(), tq2 = otherRef->get_base()->get_qualifiers();
-				refType->get_base()->get_qualifiers() = Type::Qualifiers();
-				otherRef->get_base()->get_qualifiers() = Type::Qualifiers();
+				Type::Qualifiers tq1 = refType->get_base()->tq, tq2 = otherRef->get_base()->tq;
+				refType->get_base()->tq = Type::Qualifiers();
+				otherRef->get_base()->tq = Type::Qualifiers();
 				AssertionSet have, need;
 				OpenVarSet newOpen( openVars );
@@ -579,14 +579,14 @@
 						result = otherRef->clone();
 					} // if
-					strict_dynamic_cast<ReferenceType*>(result)->base->get_qualifiers() = tq1 | tq2;
+					strict_dynamic_cast<ReferenceType *>(result)->base->tq = tq1 | tq2;
 				} else {
 					/// std::cerr << "place for ptr-to-type" << std::endl;
 				} // if
-				refType->get_base()->get_qualifiers() = tq1;
-				otherRef->get_base()->get_qualifiers() = tq2;
+				refType->get_base()->tq = tq1;
+				otherRef->get_base()->tq = tq2;
 			} // if
-		} else if ( widenSecond && dynamic_cast< ZeroType* >( type2 ) ) {
+		} else if ( widenSecond && dynamic_cast< ZeroType * >( type2 ) ) {
 			result = refType->clone();
-			result->get_qualifiers() |= type2->get_qualifiers();
+			result->tq |= type2->tq;
 		} // if
 	}
@@ -596,6 +596,6 @@
 	void CommonType_old::postvisit( UnionInstType * ) {}
 
-	void CommonType_old::postvisit( EnumInstType *enumInstType ) {
-		if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< ZeroType* >( type2 ) || dynamic_cast< OneType* >( type2 ) ) {
+	void CommonType_old::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
 			result = commonType( type2, enumInstType, widenSecond, widenFirst, indexer, env, openVars );
@@ -606,21 +606,21 @@
 	}
 
-	void CommonType_old::postvisit( TypeInstType *inst ) {
+	void CommonType_old::postvisit( TypeInstType * inst ) {
 		if ( widenFirst ) {
-			NamedTypeDecl *nt = indexer.lookupType( inst->get_name() );
+			const NamedTypeDecl * nt = indexer.lookupType( inst->get_name() );
 			if ( nt ) {
-				TypeDecl *type = strict_dynamic_cast< TypeDecl* >( nt );
+				const TypeDecl * type = strict_dynamic_cast< const TypeDecl * >( nt );
 				if ( type->get_base() ) {
-					Type::Qualifiers tq1 = inst->get_qualifiers(), tq2 = type2->get_qualifiers();
+					Type::Qualifiers tq1 = inst->tq, tq2 = type2->tq;
 					AssertionSet have, need;
 					OpenVarSet newOpen( openVars );
-					type2->get_qualifiers() = Type::Qualifiers();
-					type->get_base()->get_qualifiers() = tq1;
+					type2->tq = Type::Qualifiers();
+					type->get_base()->tq = tq1;
 					if ( unifyExact( type->get_base(), type2, env, have, need, newOpen, indexer ) ) {
 						result = type2->clone();
-						result->get_qualifiers() = tq1 | tq2;
+						result->tq = tq1 | tq2;
 					} // if
-					type2->get_qualifiers() = tq2;
-					type->get_base()->get_qualifiers() = Type::Qualifiers();
+					type2->tq = tq2;
+					type->get_base()->tq = Type::Qualifiers();
 				} // if
 			} // if
@@ -631,28 +631,28 @@
 	void CommonType_old::postvisit( VarArgsType * ) {}
 
-	void CommonType_old::postvisit( ZeroType *zeroType ) {
+	void CommonType_old::postvisit( ZeroType * zeroType ) {
 		if ( widenFirst ) {
-			if ( dynamic_cast< BasicType* >( type2 ) || dynamic_cast< PointerType* >( type2 ) || dynamic_cast< EnumInstType* >( type2 ) ) {
-				if ( widenSecond || zeroType->get_qualifiers() <= type2->get_qualifiers() ) {
+			if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< PointerType * >( type2 ) || dynamic_cast< EnumInstType * >( type2 ) ) {
+				if ( widenSecond || zeroType->tq <= type2->tq ) {
 					result = type2->clone();
-					result->get_qualifiers() |= zeroType->get_qualifiers();
-				}
-			} else if ( widenSecond && dynamic_cast< OneType* >( type2 ) ) {
-				result = new BasicType( zeroType->get_qualifiers(), BasicType::SignedInt );
-				result->get_qualifiers() |= type2->get_qualifiers();
-			}
-		}
-	}
-
-	void CommonType_old::postvisit( OneType *oneType ) {
+					result->tq |= zeroType->tq;
+				}
+			} else if ( widenSecond && dynamic_cast< OneType * >( type2 ) ) {
+				result = new BasicType( zeroType->tq, BasicType::SignedInt );
+				result->tq |= type2->tq;
+			}
+		}
+	}
+
+	void CommonType_old::postvisit( OneType * oneType ) {
 		if ( widenFirst ) {
-			if ( dynamic_cast< BasicType* >( type2 ) || dynamic_cast< EnumInstType* >( type2 ) ) {
-				if ( widenSecond || oneType->get_qualifiers() <= type2->get_qualifiers() ) {
+			if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< EnumInstType * >( type2 ) ) {
+				if ( widenSecond || oneType->tq <= type2->tq ) {
 					result = type2->clone();
-					result->get_qualifiers() |= oneType->get_qualifiers();
-				}
-			} else if ( widenSecond && dynamic_cast< ZeroType* >( type2 ) ) {
-				result = new BasicType( oneType->get_qualifiers(), BasicType::SignedInt );
-				result->get_qualifiers() |= type2->get_qualifiers();
+					result->tq |= oneType->tq;
+				}
+			} else if ( widenSecond && dynamic_cast< ZeroType * >( type2 ) ) {
+				result = new BasicType( oneType->tq, BasicType::SignedInt );
+				result->tq |= type2->tq;
 			}
 		}
@@ -668,6 +668,6 @@
 		ast::ptr< ast::Type > result;
 
-		CommonType_new( 
-			const ast::Type * t2, WidenMode w, const ast::SymbolTable & st, 
+		CommonType_new(
+			const ast::Type * t2, WidenMode w, const ast::SymbolTable & st,
 			ast::TypeEnvironment & env, const ast::OpenVarSet & o )
 		: type2( t2 ), widen( w ), symtab( st ), tenv( env ), open( o ), result() {}
@@ -681,14 +681,14 @@
 				#warning remove casts when `commonTypes` moved to new AST
 				ast::BasicType::Kind kind = (ast::BasicType::Kind)(int)commonTypes[ (BasicType::Kind)(int)basic->kind ][ (BasicType::Kind)(int)basic2->kind ];
-				if ( 
-					( ( kind == basic->kind && basic->qualifiers >= basic2->qualifiers ) 
-						|| widen.first ) 
-					&& ( ( kind == basic2->kind && basic->qualifiers <= basic2->qualifiers ) 
-						|| widen.second ) 
+				if (
+					( ( kind == basic->kind && basic->qualifiers >= basic2->qualifiers )
+						|| widen.first )
+					&& ( ( kind == basic2->kind && basic->qualifiers <= basic2->qualifiers )
+						|| widen.second )
 				) {
 					result = new ast::BasicType{ kind, basic->qualifiers | basic2->qualifiers };
 				}
-			} else if ( 
-				dynamic_cast< const ast::EnumInstType * >( type2 ) 
+			} else if (
+				dynamic_cast< const ast::EnumInstType * >( type2 )
 				|| dynamic_cast< const ast::ZeroType * >( type2 )
 				|| dynamic_cast< const ast::OneType * >( type2 )
@@ -696,9 +696,9 @@
 				#warning remove casts when `commonTypes` moved to new AST
 				ast::BasicType::Kind kind = (ast::BasicType::Kind)(int)commonTypes[ (BasicType::Kind)(int)basic->kind ][ (BasicType::Kind)(int)ast::BasicType::SignedInt ];
-				if ( 
-					( ( kind == basic->kind && basic->qualifiers >= type2->qualifiers ) 
-						|| widen.first ) 
-					&& ( ( kind != basic->kind && basic->qualifiers <= type2->qualifiers ) 
-						|| widen.second ) 
+				if (
+					( ( kind == basic->kind && basic->qualifiers >= type2->qualifiers )
+						|| widen.first )
+					&& ( ( kind != basic->kind && basic->qualifiers <= type2->qualifiers )
+						|| widen.second )
 				) {
 					result = new ast::BasicType{ kind, basic->qualifiers | type2->qualifiers };
@@ -715,6 +715,6 @@
 				if ( entry != open.end() ) {
 					ast::AssertionSet need, have;
-					if ( ! tenv.bindVar( 
-						var, voidPtr->base, entry->second, need, have, open, widen, symtab ) 
+					if ( ! tenv.bindVar(
+						var, voidPtr->base, entry->second, need, have, open, widen, symtab )
 					) return;
 				}
@@ -727,14 +727,14 @@
 		void postvisit( const ast::PointerType * pointer ) {
 			if ( auto pointer2 = dynamic_cast< const ast::PointerType * >( type2 ) ) {
-				if ( 
-					widen.first 
-					&& pointer2->base.as< ast::VoidType >() 
-					&& ! ast::isFtype( pointer->base ) 
+				if (
+					widen.first
+					&& pointer2->base.as< ast::VoidType >()
+					&& ! ast::isFtype( pointer->base )
 				) {
 					getCommonWithVoidPointer( pointer2, pointer );
-				} else if ( 
-					widen.second 
-					&& pointer->base.as< ast::VoidType >() 
-					&& ! ast::isFtype( pointer2->base ) 
+				} else if (
+					widen.second
+					&& pointer->base.as< ast::VoidType >()
+					&& ! ast::isFtype( pointer2->base )
 				) {
 					getCommonWithVoidPointer( pointer, pointer2 );
@@ -746,10 +746,10 @@
 					ast::CV::Qualifiers q2 = pointer2->base->qualifiers;
 
-					// force t{1,2} to be cloned if their qualifiers must be stripped, so that 
+					// force t{1,2} to be cloned if their qualifiers must be stripped, so that
 					// pointer{,2}->base are unchanged
 					ast::ptr< ast::Type > t1{ pointer->base }, t2{ pointer2->base };
 					reset_qualifiers( t1 );
 					reset_qualifiers( t2 );
-					
+
 					ast::AssertionSet have, need;
 					ast::OpenVarSet newOpen{ open };
@@ -758,6 +758,6 @@
 						if ( q1.val != q2.val ) {
 							// reset result->base->qualifiers to be union of two base qualifiers
-							strict_dynamic_cast< ast::PointerType * >( 
-								result.get_and_mutate() 
+							strict_dynamic_cast< ast::PointerType * >(
+								result.get_and_mutate()
 							)->base.get_and_mutate()->qualifiers = q1 | q2;
 						}
@@ -775,9 +775,9 @@
 			if ( auto ref2 = dynamic_cast< const ast::ReferenceType * >( type2 ) ) {
 				if (
-					widen.first && ref2->base.as< ast::VoidType >() && ! ast::isFtype( ref->base ) 
+					widen.first && ref2->base.as< ast::VoidType >() && ! ast::isFtype( ref->base )
 				) {
 					getCommonWithVoidPointer( ref2, ref );
-				} else if ( 
-					widen.second && ref->base.as< ast::VoidType>() && ! ast::isFtype( ref2->base ) 
+				} else if (
+					widen.second && ref->base.as< ast::VoidType>() && ! ast::isFtype( ref2->base )
 				) {
 					getCommonWithVoidPointer( ref, ref2 );
@@ -788,5 +788,5 @@
 					ast::CV::Qualifiers q1 = ref->base->qualifiers, q2 = ref2->base->qualifiers;
 
-					// force t{1,2} to be cloned if their qualifiers must be stripped, so that 
+					// force t{1,2} to be cloned if their qualifiers must be stripped, so that
 					// ref{,2}->base are unchanged
 					ast::ptr< ast::Type > t1{ ref->base }, t2{ ref2->base };
@@ -800,6 +800,6 @@
 						if ( q1.val != q2.val ) {
 							// reset result->base->qualifiers to be union of two base qualifiers
-							strict_dynamic_cast< ast::ReferenceType * >( 
-								result.get_and_mutate() 
+							strict_dynamic_cast< ast::ReferenceType * >(
+								result.get_and_mutate()
 							)->base.get_and_mutate()->qualifiers = q1 | q2;
 						}
@@ -819,6 +819,6 @@
 
 		void postvisit( const ast::EnumInstType * enumInst ) {
-			if ( 
-				dynamic_cast< const ast::BasicType * >( type2 ) 
+			if (
+				dynamic_cast< const ast::BasicType * >( type2 )
 				|| dynamic_cast< const ast::ZeroType * >( type2 )
 				|| dynamic_cast< const ast::OneType * >( type2 )
@@ -834,6 +834,6 @@
 			if ( ! widen.first ) return;
 			if ( const ast::NamedTypeDecl * nt = symtab.lookupType( inst->name ) ) {
-				if ( const ast::Type * base = 
-						strict_dynamic_cast< const ast::TypeDecl * >( nt )->base 
+				if ( const ast::Type * base =
+						strict_dynamic_cast< const ast::TypeDecl * >( nt )->base
 				) {
 					ast::CV::Qualifiers q1 = inst->qualifiers, q2 = type2->qualifiers;
@@ -860,5 +860,5 @@
 		void postvisit( const ast::ZeroType * zero ) {
 			if ( ! widen.first ) return;
-			if ( 
+			if (
 				dynamic_cast< const ast::BasicType * >( type2 )
 				|| dynamic_cast< const ast::PointerType * >( type2 )
@@ -870,5 +870,5 @@
 				}
 			} else if ( widen.second && dynamic_cast< const ast::OneType * >( type2 ) ) {
-				result = new ast::BasicType{ 
+				result = new ast::BasicType{
 					ast::BasicType::SignedInt, zero->qualifiers | type2->qualifiers };
 			}
@@ -877,5 +877,5 @@
 		void postvisit( const ast::OneType * one ) {
 			if ( ! widen.first ) return;
-			if ( 
+			if (
 				dynamic_cast< const ast::BasicType * >( type2 )
 				|| dynamic_cast< const ast::EnumInstType * >( type2 )
@@ -886,5 +886,5 @@
 				}
 			} else if ( widen.second && dynamic_cast< const ast::ZeroType * >( type2 ) ) {
-				result = new ast::BasicType{ 
+				result = new ast::BasicType{
 					ast::BasicType::SignedInt, one->qualifiers | type2->qualifiers };
 			}
@@ -894,8 +894,8 @@
 
 	namespace {
-		ast::ptr< ast::Type > handleReference( 
-			const ast::ptr< ast::Type > & t1, const ast::ptr< ast::Type > & t2, WidenMode widen, 
-			const ast::SymbolTable & symtab, ast::TypeEnvironment & env, 
-			const ast::OpenVarSet & open 
+		ast::ptr< ast::Type > handleReference(
+			const ast::ptr< ast::Type > & t1, const ast::ptr< ast::Type > & t2, WidenMode widen,
+			const ast::SymbolTable & symtab, ast::TypeEnvironment & env,
+			const ast::OpenVarSet & open
 		) {
 			ast::ptr<ast::Type> common;
@@ -926,7 +926,7 @@
 
 	ast::ptr< ast::Type > commonType(
-			const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2, 
-			WidenMode widen, const ast::SymbolTable & symtab, ast::TypeEnvironment & env, 
-			const ast::OpenVarSet & open 
+			const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2,
+			WidenMode widen, const ast::SymbolTable & symtab, ast::TypeEnvironment & env,
+			const ast::OpenVarSet & open
 	) {
 		unsigned depth1 = type1->referenceDepth();
@@ -940,5 +940,5 @@
 			const ast::ReferenceType * ref1 = type1.as< ast::ReferenceType >();
 			const ast::ReferenceType * ref2 = type2.as< ast::ReferenceType >();
-			
+
 			if ( depth1 > depth2 ) {
 				assert( ref1 );
@@ -978,11 +978,11 @@
 						ast::OpenVarSet newOpen{ open };
 
-						// force t{1,2} to be cloned if its qualifiers must be stripped, so that 
-						// type1 and type->base are left unchanged; calling convention forces 
+						// force t{1,2} to be cloned if its qualifiers must be stripped, so that
+						// type1 and type->base are left unchanged; calling convention forces
 						// {type1,type->base}->strong_ref >= 1
 						ast::ptr<ast::Type> t1{ type1 }, t2{ type->base };
 						reset_qualifiers( t1 );
 						reset_qualifiers( t2, q1 );
-						
+
 						if ( unifyExact( t1, t2, env, have, need, newOpen, noWiden(), symtab ) ) {
 							result = t1;
Index: src/ResolvExpr/ConversionCost.cc
===================================================================
--- src/ResolvExpr/ConversionCost.cc	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/ResolvExpr/ConversionCost.cc	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -46,8 +46,8 @@
 #endif
 
-	Cost conversionCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
-		if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
+	Cost conversionCost( const Type * src, const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
+		if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType * >( dest ) ) {
 			PRINT( std::cerr << "type inst " << destAsTypeInst->name; )
-			if ( const EqvClass* eqvClass = env.lookup( destAsTypeInst->name ) ) {
+			if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->name ) ) {
 				if ( eqvClass->type ) {
 					return conversionCost( src, eqvClass->type, indexer, env );
@@ -55,7 +55,7 @@
 					return Cost::infinity;
 				}
-			} else if ( NamedTypeDecl *namedType = indexer.lookupType( destAsTypeInst->name ) ) {
+			} else if ( const NamedTypeDecl * namedType = indexer.lookupType( destAsTypeInst->name ) ) {
 				PRINT( std::cerr << " found" << std::endl; )
-				TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );
+				const TypeDecl * type = dynamic_cast< const TypeDecl * >( namedType );
 				// all typedefs should be gone by this point
 				assert( type );
@@ -77,15 +77,15 @@
 			PRINT( std::cerr << "compatible!" << std::endl; )
 			return Cost::zero;
-		} else if ( dynamic_cast< VoidType* >( dest ) ) {
+		} else if ( dynamic_cast< const VoidType * >( dest ) ) {
 			return Cost::safe;
-		} else if ( ReferenceType * refType = dynamic_cast< ReferenceType * > ( dest ) ) {
+		} else if ( const ReferenceType * refType = dynamic_cast< const ReferenceType * > ( dest ) ) {
 			PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; )
-			return convertToReferenceCost( src, refType, indexer, env, [](Type * t1, Type * t2, const SymTab::Indexer &, const TypeEnvironment & env ){
+			return convertToReferenceCost( src, refType, indexer, env, [](const Type * const t1, const Type * t2, const SymTab::Indexer &, const TypeEnvironment & env ){
 				return ptrsAssignable( t1, t2, env );
 			});
 		} else {
-			PassVisitor<ConversionCost> converter( 
-				dest, indexer, env, 
-				(Cost (*)(Type*, Type*, const SymTab::Indexer&, const TypeEnvironment&))
+			PassVisitor<ConversionCost> converter(
+				dest, indexer, env,
+				(Cost (*)(const Type *, const Type *, const SymTab::Indexer&, const TypeEnvironment&))
 					conversionCost );
 			src->accept( converter );
@@ -98,23 +98,23 @@
 	}
 
-	Cost convertToReferenceCost( Type * src, Type * dest, int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
+	Cost convertToReferenceCost( const Type * src, const Type * dest, int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
 		PRINT( std::cerr << "convert to reference cost... diff " << diff << " " << src << " / " << dest << std::endl; )
 		if ( diff > 0 ) {
 			// TODO: document this
-			Cost cost = convertToReferenceCost( strict_dynamic_cast< ReferenceType * >( src )->base, dest, diff-1, indexer, env, func );
+			Cost cost = convertToReferenceCost( strict_dynamic_cast< const ReferenceType * >( src )->base, dest, diff-1, indexer, env, func );
 			cost.incReference();
 			return cost;
 		} else if ( diff < -1 ) {
 			// TODO: document this
-			Cost cost = convertToReferenceCost( src, strict_dynamic_cast< ReferenceType * >( dest )->base, diff+1, indexer, env, func );
+			Cost cost = convertToReferenceCost( src, strict_dynamic_cast< const ReferenceType * >( dest )->base, diff+1, indexer, env, func );
 			cost.incReference();
 			return cost;
 		} else if ( diff == 0 ) {
-			ReferenceType * srcAsRef = dynamic_cast< ReferenceType * >( src );
-			ReferenceType * destAsRef = dynamic_cast< ReferenceType * >( dest );
+			const ReferenceType * srcAsRef = dynamic_cast< const ReferenceType * >( src );
+			const ReferenceType * destAsRef = dynamic_cast< const ReferenceType * >( dest );
 			if ( srcAsRef && destAsRef ) { // pointer-like conversions between references
 				PRINT( std::cerr << "converting between references" << std::endl; )
-				Type::Qualifiers tq1 = srcAsRef->base->get_qualifiers();
-				Type::Qualifiers tq2 = destAsRef->base->get_qualifiers();
+				Type::Qualifiers tq1 = srcAsRef->base->tq;
+				Type::Qualifiers tq2 = destAsRef->base->tq;
 				if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( srcAsRef->base, destAsRef->base, indexer, env ) ) {
 					PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; )
@@ -137,7 +137,7 @@
 			} else {
 				PRINT( std::cerr << "reference to rvalue conversion" << std::endl; )
-				PassVisitor<ConversionCost> converter( 
-					dest, indexer, env, 
-					(Cost (*)(Type*, Type*, const SymTab::Indexer&, const TypeEnvironment&))
+				PassVisitor<ConversionCost> converter(
+					dest, indexer, env,
+					(Cost (*)(const Type *, const Type *, const SymTab::Indexer&, const TypeEnvironment&))
 						conversionCost );
 				src->accept( converter );
@@ -145,5 +145,5 @@
 			} // if
 		} else {
-			ReferenceType * destAsRef = dynamic_cast< ReferenceType * >( dest );
+			const ReferenceType * destAsRef = dynamic_cast< const ReferenceType * >( dest );
 			assert( diff == -1 && destAsRef );
 			PRINT( std::cerr << "dest is: " << dest << " / src is: " << src << std::endl; )
@@ -156,7 +156,7 @@
 					)
 					// lvalue-to-reference conversion:  cv lvalue T => cv T &
-					if ( src->get_qualifiers() == destAsRef->base->get_qualifiers() ) {
+					if ( src->tq == destAsRef->base->tq ) {
 						return Cost::reference; // cost needs to be non-zero to add cast
-					} if ( src->get_qualifiers() < destAsRef->base->get_qualifiers() ) {
+					} if ( src->tq < destAsRef->base->tq ) {
 						return Cost::safe; // cost needs to be higher than previous cast to differentiate adding qualifiers vs. keeping same
 					} else {
@@ -178,5 +178,5 @@
 	}
 
-	Cost convertToReferenceCost( Type * src, ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
+	Cost convertToReferenceCost( const Type * src, const ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
 		int sdepth = src->referenceDepth(), ddepth = dest->referenceDepth();
 		Cost cost = convertToReferenceCost( src, dest, sdepth-ddepth, indexer, env, func );
@@ -185,5 +185,5 @@
 	}
 
-	ConversionCost::ConversionCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )
+	ConversionCost::ConversionCost( const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )
 		: dest( dest ), indexer( indexer ), cost( Cost::infinity ), env( env ), costFunc( costFunc ) {
 	}
@@ -193,22 +193,22 @@
 	/* EXTENDED INTEGRAL RANK HIERARCHY (root to leaves)
 	                         _Bool
-	char                signed char         unsigned char       
-	          signed short int         unsigned short int       
-	          signed int               unsigned int             
-	          signed long int          unsigned long int        
-	          signed long long int     unsigned long long int   
-	          __int128                 unsigned __int128        
-	          _Float16                 _Float16 _Complex        
-	          _Float32                 _Float32 _Complex        
-	          float                    float _Complex           
-	          _Float32x                _Float32x _Complex       
-	          _Float64                 _Float64 _Complex        
-	          double                   double _Complex          
-	          _Float64x                _Float64x _Complex       
+	char                signed char         unsigned char
+	          signed short int         unsigned short int
+	          signed int               unsigned int
+	          signed long int          unsigned long int
+	          signed long long int     unsigned long long int
+	          __int128                 unsigned __int128
+	          _Float16                 _Float16 _Complex
+	          _Float32                 _Float32 _Complex
+	          float                    float _Complex
+	          _Float32x                _Float32x _Complex
+	          _Float64                 _Float64 _Complex
+	          double                   double _Complex
+	          _Float64x                _Float64x _Complex
 	                     __float80
-	          _Float128                _Float128 _Complex       
+	          _Float128                _Float128 _Complex
 	                    __float128
-	          long double              long double _Complex     
-	          _Float128x               _Float128x _Complex      
+	          long double              long double _Complex
+	          _Float128x               _Float128x _Complex
 	*/
 	// GENERATED END
@@ -218,45 +218,45 @@
 	static const int costMatrix[BasicType::NUMBER_OF_BASIC_TYPES][BasicType::NUMBER_OF_BASIC_TYPES] = { // path length from root to node
 		/*             B    C   SC   UC   SI  SUI    I   UI   LI  LUI  LLI LLUI   IB  UIB  _FH  _FH   _F  _FC    F   FC  _FX _FXC   FD _FDC    D   DC F80X_FDXC  F80  _FB_FLDC   FB   LD  LDC _FBX_FLDXC */
-		/*     B*/ {   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  14,  15,  15,  16,  17,  16,  18,  17, },
-		/*     C*/ {  -1,   0,   1,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  14,  15,  16,  15,  17,  16, },
-		/*    SC*/ {  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  14,  15,  16,  15,  17,  16, },
-		/*    UC*/ {  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  14,  15,  16,  15,  17,  16, },
-		/*    SI*/ {  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  15,  14,  16,  15, },
-		/*   SUI*/ {  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  15,  14,  16,  15, },
-		/*     I*/ {  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  14,  13,  15,  14, },
-		/*    UI*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  14,  13,  15,  14, },
-		/*    LI*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  13,  12,  14,  13, },
-		/*   LUI*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  13,  12,  14,  13, },
-		/*   LLI*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  12,  11,  13,  12, },
-		/*  LLUI*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  12,  11,  13,  12, },
-		/*    IB*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  11,  10,  12,  11, },
-		/*   UIB*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  11,  10,  12,  11, },
-		/*   _FH*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,  10,   9,  11,  10, },
-		/*   _FH*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,   2,  -1,   3,  -1,   4,  -1,   5,  -1,   6,  -1,  -1,   7,  -1,  -1,   8,  -1,   9, },
-		/*    _F*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   9,   8,  10,   9, },
-		/*   _FC*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,   2,  -1,   3,  -1,   4,  -1,   5,  -1,  -1,   6,  -1,  -1,   7,  -1,   8, },
-		/*     F*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   8,   7,   9,   8, },
-		/*    FC*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,   2,  -1,   3,  -1,   4,  -1,  -1,   5,  -1,  -1,   6,  -1,   7, },
-		/*   _FX*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   7,   6,   8,   7, },
-		/*  _FXC*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,   2,  -1,   3,  -1,  -1,   4,  -1,  -1,   5,  -1,   6, },
-		/*    FD*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   6,   5,   7,   6, },
-		/*  _FDC*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,   2,  -1,  -1,   3,  -1,  -1,   4,  -1,   5, },
-		/*     D*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   5,   4,   6,   5, },
-		/*    DC*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,  -1,   2,  -1,  -1,   3,  -1,   4, },
-		/*  F80X*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   4,   3,   5,   4, },
-		/* _FDXC*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,  -1,   1,  -1,  -1,   2,  -1,   3, },
+		/*     B */ {   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  14,  15,  15,  16,  17,  16,  18,  17, },
+		/*     C */ {  -1,   0,   1,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  14,  15,  16,  15,  17,  16, },
+		/*    SC */ {  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  14,  15,  16,  15,  17,  16, },
+		/*    UC */ {  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  14,  15,  16,  15,  17,  16, },
+		/*    SI */ {  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  15,  14,  16,  15, },
+		/*   SUI */ {  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  15,  14,  16,  15, },
+		/*     I */ {  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  14,  13,  15,  14, },
+		/*    UI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  14,  13,  15,  14, },
+		/*    LI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  13,  12,  14,  13, },
+		/*   LUI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  13,  12,  14,  13, },
+		/*   LLI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  12,  11,  13,  12, },
+		/*  LLUI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  12,  11,  13,  12, },
+		/*    IB */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  11,  10,  12,  11, },
+		/*   UIB */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  11,  10,  12,  11, },
+		/*   _FH */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,  10,   9,  11,  10, },
+		/*   _FH */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,   2,  -1,   3,  -1,   4,  -1,   5,  -1,   6,  -1,  -1,   7,  -1,  -1,   8,  -1,   9, },
+		/*    _F */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   9,   8,  10,   9, },
+		/*   _FC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,   2,  -1,   3,  -1,   4,  -1,   5,  -1,  -1,   6,  -1,  -1,   7,  -1,   8, },
+		/*     F */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   8,   7,   9,   8, },
+		/*    FC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,   2,  -1,   3,  -1,   4,  -1,  -1,   5,  -1,  -1,   6,  -1,   7, },
+		/*   _FX */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   7,   6,   8,   7, },
+		/*  _FXC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,   2,  -1,   3,  -1,  -1,   4,  -1,  -1,   5,  -1,   6, },
+		/*    FD */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   6,   5,   7,   6, },
+		/*  _FDC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,   2,  -1,  -1,   3,  -1,  -1,   4,  -1,   5, },
+		/*     D */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   5,   4,   6,   5, },
+		/*    DC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,  -1,   2,  -1,  -1,   3,  -1,   4, },
+		/*  F80X */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   4,   3,   5,   4, },
+		/* _FDXC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,  -1,   1,  -1,  -1,   2,  -1,   3, },
 		/*   F80*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   1,   0,   1,   2,   2,   3,   3,   4,   4, },
-		/*   _FB*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3, },
-		/* _FLDC*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,  -1,   1,  -1,   2, },
-		/*    FB*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   1,   0,   1,   2,   2,   3, },
-		/*    LD*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2, },
-		/*   LDC*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1, },
-		/*  _FBX*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1, },
-		/*_FLDXC*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0, },
+		/*   _FB */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3, },
+		/* _FLDC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,  -1,   1,  -1,   2, },
+		/*    FB */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   1,   0,   1,   2,   2,   3, },
+		/*    LD */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2, },
+		/*   LDC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1, },
+		/*  _FBX */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1, },
+		/* _FLDXC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0, },
 	}; // costMatrix
 	static const int maxIntCost = 15;
 	// GENERATED END
 	static_assert(
-		sizeof(costMatrix)/sizeof(costMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES*BasicType::NUMBER_OF_BASIC_TYPES,
+		sizeof(costMatrix)/sizeof(costMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES * BasicType::NUMBER_OF_BASIC_TYPES,
 		"Missing row in the cost matrix"
 	);
@@ -266,54 +266,54 @@
 	static const int signMatrix[BasicType::NUMBER_OF_BASIC_TYPES][BasicType::NUMBER_OF_BASIC_TYPES] = { // number of sign changes in safe conversion
 		/*             B    C   SC   UC   SI  SUI    I   UI   LI  LUI  LLI LLUI   IB  UIB  _FH  _FH   _F  _FC    F   FC  _FX _FXC   FD _FDC    D   DC F80X_FDXC  F80  _FB_FLDC   FB   LD  LDC _FBX_FLDXC */
-		/*     B*/ {   0,   0,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
-		/*     C*/ {  -1,   0,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
-		/*    SC*/ {  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
-		/*    UC*/ {  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
-		/*    SI*/ {  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
-		/*   SUI*/ {  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
-		/*     I*/ {  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
-		/*    UI*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
-		/*    LI*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
-		/*   LUI*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
-		/*   LLI*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
-		/*  LLUI*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
-		/*    IB*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
-		/*   UIB*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
-		/*   _FH*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
-		/*   _FH*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
-		/*    _F*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
-		/*   _FC*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
-		/*     F*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
-		/*    FC*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
-		/*   _FX*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
-		/*  _FXC*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
-		/*    FD*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
-		/*  _FDC*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
-		/*     D*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
-		/*    DC*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
-		/*  F80X*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
-		/* _FDXC*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
+		/*     B */ {   0,   0,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
+		/*     C */ {  -1,   0,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
+		/*    SC */ {  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
+		/*    UC */ {  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
+		/*    SI */ {  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
+		/*   SUI */ {  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
+		/*     I */ {  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
+		/*    UI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
+		/*    LI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
+		/*   LUI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
+		/*   LLI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
+		/*  LLUI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
+		/*    IB */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
+		/*   UIB */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
+		/*   _FH */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
+		/*   _FH */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
+		/*    _F */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
+		/*   _FC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
+		/*     F */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
+		/*    FC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
+		/*   _FX */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
+		/*  _FXC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
+		/*    FD */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
+		/*  _FDC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
+		/*     D */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
+		/*    DC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
+		/*  F80X */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
+		/* _FDXC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
 		/*   F80*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
-		/*   _FB*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0, },
-		/* _FLDC*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
-		/*    FB*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0, },
-		/*    LD*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0, },
-		/*   LDC*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0, },
-		/*  _FBX*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0, },
-		/*_FLDXC*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0, },
+		/*   _FB */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0, },
+		/* _FLDC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
+		/*    FB */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0, },
+		/*    LD */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0, },
+		/*   LDC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0, },
+		/*  _FBX */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0, },
+		/* _FLDXC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0, },
 	}; // signMatrix
 	// GENERATED END
 	static_assert(
-		sizeof(signMatrix)/sizeof(signMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES*BasicType::NUMBER_OF_BASIC_TYPES,
+		sizeof(signMatrix)/sizeof(signMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES * BasicType::NUMBER_OF_BASIC_TYPES,
 		"Missing row in the sign matrix"
 	);
 
-	void ConversionCost::postvisit( VoidType * ) {
+	void ConversionCost::postvisit( const VoidType * ) {
 		cost = Cost::infinity;
 	}
 
-	void ConversionCost::postvisit(BasicType *basicType) {
-		if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
-			int tableResult = costMatrix[ basicType->get_kind() ][ destAsBasic->get_kind() ];
+	void ConversionCost::postvisit(const BasicType * basicType) {
+		if ( const BasicType * destAsBasic = dynamic_cast< const BasicType * >( dest ) ) {
+			int tableResult = costMatrix[ basicType->kind ][ destAsBasic->kind ];
 			if ( tableResult == -1 ) {
 				cost = Cost::unsafe;
@@ -321,7 +321,7 @@
 				cost = Cost::zero;
 				cost.incSafe( tableResult );
-				cost.incSign( signMatrix[ basicType->get_kind() ][ destAsBasic->get_kind() ] );
-			} // if
-		} else if ( dynamic_cast< EnumInstType *>( dest ) ) {
+				cost.incSign( signMatrix[ basicType->kind ][ destAsBasic->kind ] );
+			} // if
+		} else if ( dynamic_cast< const EnumInstType * >( dest ) ) {
 			// xxx - not positive this is correct, but appears to allow casting int => enum
 			cost = Cost::unsafe;
@@ -330,9 +330,9 @@
 	}
 
-	void ConversionCost::postvisit( PointerType * pointerType ) {
-		if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) {
+	void ConversionCost::postvisit( const PointerType * pointerType ) {
+		if ( const PointerType * destAsPtr = dynamic_cast< const PointerType * >( dest ) ) {
 			PRINT( std::cerr << pointerType << " ===> " << destAsPtr << std::endl; )
-			Type::Qualifiers tq1 = pointerType->base->get_qualifiers();
-			Type::Qualifiers tq2 = destAsPtr->base->get_qualifiers();
+			Type::Qualifiers tq1 = pointerType->base->tq;
+			Type::Qualifiers tq2 = destAsPtr->base->tq;
 			if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) {
 				PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; )
@@ -363,16 +363,16 @@
 	}
 
-	void ConversionCost::postvisit( ArrayType * ) {}
-
-	void ConversionCost::postvisit( ReferenceType * refType ) {
+	void ConversionCost::postvisit( const ArrayType * ) {}
+
+	void ConversionCost::postvisit( const ReferenceType * refType ) {
 		// Note: dest can never be a reference, since it would have been caught in an earlier check
-		assert( ! dynamic_cast< ReferenceType * >( dest ) );
+		assert( ! dynamic_cast< const ReferenceType * >( dest ) );
 		// convert reference to rvalue: cv T1 & => T2
 		// recursively compute conversion cost from T1 to T2.
 		// cv can be safely dropped because of 'implicit dereference' behavior.
 		cost = costFunc( refType->base, dest, indexer, env );
-		if ( refType->base->get_qualifiers() == dest->get_qualifiers() ) {
+		if ( refType->base->tq == dest->tq ) {
 			cost.incReference();  // prefer exact qualifiers
-		} else if ( refType->base->get_qualifiers() < dest->get_qualifiers() ) {
+		} else if ( refType->base->tq < dest->tq ) {
 			cost.incSafe(); // then gaining qualifiers
 		} else {
@@ -382,8 +382,8 @@
 	}
 
-	void ConversionCost::postvisit( FunctionType * ) {}
-
-	void ConversionCost::postvisit( StructInstType * inst ) {
-		if ( StructInstType *destAsInst = dynamic_cast< StructInstType* >( dest ) ) {
+	void ConversionCost::postvisit( const FunctionType * ) {}
+
+	void ConversionCost::postvisit( const StructInstType * inst ) {
+		if ( const StructInstType * destAsInst = dynamic_cast< const StructInstType * >( dest ) ) {
 			if ( inst->name == destAsInst->name ) {
 				cost = Cost::zero;
@@ -392,6 +392,6 @@
 	}
 
-	void ConversionCost::postvisit( UnionInstType * inst ) {
-		if ( UnionInstType *destAsInst = dynamic_cast< UnionInstType* >( dest ) ) {
+	void ConversionCost::postvisit( const UnionInstType * inst ) {
+		if ( const UnionInstType * destAsInst = dynamic_cast< const UnionInstType * >( dest ) ) {
 			if ( inst->name == destAsInst->name ) {
 				cost = Cost::zero;
@@ -400,5 +400,5 @@
 	}
 
-	void ConversionCost::postvisit( EnumInstType * ) {
+	void ConversionCost::postvisit( const EnumInstType * ) {
 		static Type::Qualifiers q;
 		static BasicType integer( q, BasicType::SignedInt );
@@ -409,15 +409,15 @@
 	}
 
-	void ConversionCost::postvisit( TraitInstType * ) {}
-
-	void ConversionCost::postvisit( TypeInstType *inst ) {
-		if ( const EqvClass *eqvClass = env.lookup( inst->name ) ) {
+	void ConversionCost::postvisit( const TraitInstType * ) {}
+
+	void ConversionCost::postvisit( const TypeInstType * inst ) {
+		if ( const EqvClass * eqvClass = env.lookup( inst->name ) ) {
 			cost = costFunc( eqvClass->type, dest, indexer, env );
-		} else if ( TypeInstType *destAsInst = dynamic_cast< TypeInstType* >( dest ) ) {
+		} else if ( const TypeInstType * destAsInst = dynamic_cast< const TypeInstType * >( dest ) ) {
 			if ( inst->name == destAsInst->name ) {
 				cost = Cost::zero;
 			}
-		} else if ( NamedTypeDecl *namedType = indexer.lookupType( inst->name ) ) {
-			TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );
+		} else if ( const NamedTypeDecl * namedType = indexer.lookupType( inst->name ) ) {
+			const TypeDecl * type = dynamic_cast< const TypeDecl * >( namedType );
 			// all typedefs should be gone by this point
 			assert( type );
@@ -428,11 +428,11 @@
 	}
 
-	void ConversionCost::postvisit( TupleType * tupleType ) {
+	void ConversionCost::postvisit( const TupleType * tupleType ) {
 		Cost c = Cost::zero;
-		if ( TupleType * destAsTuple = dynamic_cast< TupleType * >( dest ) ) {
+		if ( const TupleType * destAsTuple = dynamic_cast< const TupleType * >( dest ) ) {
 			std::list< Type * >::const_iterator srcIt = tupleType->types.begin();
 			std::list< Type * >::const_iterator destIt = destAsTuple->types.begin();
 			while ( srcIt != tupleType->types.end() && destIt != destAsTuple->types.end() ) {
-				Cost newCost = costFunc( *srcIt++, *destIt++, indexer, env );
+				Cost newCost = costFunc( * srcIt++, * destIt++, indexer, env );
 				if ( newCost == Cost::infinity ) {
 					return;
@@ -448,16 +448,16 @@
 	}
 
-	void ConversionCost::postvisit( VarArgsType * ) {
-		if ( dynamic_cast< VarArgsType* >( dest ) ) {
-			cost = Cost::zero;
-		}
-	}
-
-	void ConversionCost::postvisit( ZeroType * ) {
-		if ( dynamic_cast< ZeroType * >( dest ) ) {
-			cost = Cost::zero;
-		} else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
-			// copied from visit(BasicType*) for signed int, but +1 for safe conversions
-			int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ];
+	void ConversionCost::postvisit( const VarArgsType * ) {
+		if ( dynamic_cast< const VarArgsType * >( dest ) ) {
+			cost = Cost::zero;
+		}
+	}
+
+	void ConversionCost::postvisit( const ZeroType * ) {
+		if ( dynamic_cast< const ZeroType * >( dest ) ) {
+			cost = Cost::zero;
+		} else if ( const BasicType * destAsBasic = dynamic_cast< const BasicType * >( dest ) ) {
+			// copied from visit(BasicType *) for signed int, but +1 for safe conversions
+			int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->kind ];
 			if ( tableResult == -1 ) {
 				cost = Cost::unsafe;
@@ -465,7 +465,7 @@
 				cost = Cost::zero;
 				cost.incSafe( tableResult + 1 );
-				cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ] );
-			} // if
-		} else if ( dynamic_cast< PointerType* >( dest ) ) {
+				cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->kind ] );
+			} // if
+		} else if ( dynamic_cast< const PointerType * >( dest ) ) {
 			cost = Cost::zero;
 			cost.incSafe( maxIntCost + 2 ); // +1 for zero_t -> int, +1 for disambiguation
@@ -473,10 +473,10 @@
 	}
 
-	void ConversionCost::postvisit( OneType * ) {
-		if ( dynamic_cast< OneType * >( dest ) ) {
-			cost = Cost::zero;
-		} else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
-			// copied from visit(BasicType*) for signed int, but +1 for safe conversions
-			int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ];
+	void ConversionCost::postvisit( const OneType * ) {
+		if ( dynamic_cast< const OneType * >( dest ) ) {
+			cost = Cost::zero;
+		} else if ( const BasicType * destAsBasic = dynamic_cast< const BasicType * >( dest ) ) {
+			// copied from visit(BasicType *) for signed int, but +1 for safe conversions
+			int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->kind ];
 			if ( tableResult == -1 ) {
 				cost = Cost::unsafe;
@@ -484,5 +484,5 @@
 				cost = Cost::zero;
 				cost.incSafe( tableResult + 1 );
-				cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ] );
+				cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->kind ] );
 			} // if
 		} // if
@@ -729,5 +729,5 @@
 		auto dstEnd = dstAsTuple->types.end();
 		while ( srcIt != srcEnd && dstIt != dstEnd ) {
-			Cost newCost = costCalc( *srcIt++, *dstIt++, symtab, env );
+			Cost newCost = costCalc( * srcIt++, * dstIt++, symtab, env );
 			if ( newCost == Cost::infinity ) {
 				return;
Index: src/ResolvExpr/ConversionCost.h
===================================================================
--- src/ResolvExpr/ConversionCost.h	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/ResolvExpr/ConversionCost.h	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -33,30 +33,30 @@
 	class TypeEnvironment;
 
-	typedef std::function<Cost(Type *, Type *, const SymTab::Indexer &, const TypeEnvironment &)> CostFunction;
+	typedef std::function<Cost(const Type *, const Type *, const SymTab::Indexer &, const TypeEnvironment &)> CostFunction;
 	struct ConversionCost : public WithShortCircuiting {
 	  public:
-		ConversionCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction );
+		ConversionCost( const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction );
 
 		Cost get_cost() const { return cost; }
 
-		void previsit( BaseSyntaxNode * ) { visit_children = false; }
+		void previsit( const 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 );
+		void postvisit( const VoidType * voidType );
+		void postvisit( const BasicType * basicType );
+		void postvisit( const PointerType * pointerType );
+		void postvisit( const ArrayType * arrayType );
+		void postvisit( const ReferenceType * refType );
+		void postvisit( const FunctionType * functionType );
+		void postvisit( const StructInstType * aggregateUseType );
+		void postvisit( const UnionInstType * aggregateUseType );
+		void postvisit( const EnumInstType * aggregateUseType );
+		void postvisit( const TraitInstType * aggregateUseType );
+		void postvisit( const TypeInstType * aggregateUseType );
+		void postvisit( const TupleType * tupleType );
+		void postvisit( const VarArgsType * varArgsType );
+		void postvisit( const ZeroType * zeroType );
+		void postvisit( const OneType * oneType );
 	  protected:
-		Type *dest;
+		const Type * dest;
 		const SymTab::Indexer &indexer;
 		Cost cost;
@@ -65,6 +65,6 @@
 	};
 
-	typedef std::function<int(Type *, Type *, const SymTab::Indexer &, const TypeEnvironment &)> PtrsFunction;
-	Cost convertToReferenceCost( Type * src, ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func );
+	typedef std::function<int(const Type *, const Type *, const SymTab::Indexer &, const TypeEnvironment &)> PtrsFunction;
+	Cost convertToReferenceCost( const Type * src, const ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func );
 
 // Some function pointer types, differ in return type.
Index: src/ResolvExpr/PtrsAssignable.cc
===================================================================
--- src/ResolvExpr/PtrsAssignable.cc	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/ResolvExpr/PtrsAssignable.cc	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -27,38 +27,38 @@
 namespace ResolvExpr {
 	struct PtrsAssignable : public WithShortCircuiting {
-		PtrsAssignable( Type *dest, const TypeEnvironment &env );
+		PtrsAssignable( const Type * dest, const TypeEnvironment &env );
 
 		int get_result() const { return result; }
 
-		void previsit( Type * ) { visit_children = false; }
-
-		void postvisit( VoidType * voidType );
-		void postvisit( BasicType * basicType );
-		void postvisit( PointerType * pointerType );
-		void postvisit( ArrayType * arrayType );
-		void postvisit( FunctionType * functionType );
-		void postvisit( StructInstType * inst );
-		void postvisit( UnionInstType * inst );
-		void postvisit( EnumInstType * inst );
-		void postvisit( TraitInstType * inst );
-		void postvisit( TypeInstType * inst );
-		void postvisit( TupleType * tupleType );
-		void postvisit( VarArgsType * varArgsType );
-		void postvisit( ZeroType * zeroType );
-		void postvisit( OneType * oneType );
+		void previsit( const Type * ) { visit_children = false; }
+
+		void postvisit( const VoidType * voidType );
+		void postvisit( const BasicType * basicType );
+		void postvisit( const PointerType * pointerType );
+		void postvisit( const ArrayType * arrayType );
+		void postvisit( const FunctionType * functionType );
+		void postvisit( const StructInstType * inst );
+		void postvisit( const UnionInstType * inst );
+		void postvisit( const EnumInstType * inst );
+		void postvisit( const TraitInstType * inst );
+		void postvisit( const TypeInstType * inst );
+		void postvisit( const TupleType * tupleType );
+		void postvisit( const VarArgsType * varArgsType );
+		void postvisit( const ZeroType * zeroType );
+		void postvisit( const OneType * oneType );
 	  private:
-		Type *dest;
+		const Type * dest;
 		int result;
 		const TypeEnvironment &env;
 	};
 
-	int ptrsAssignable( Type *src, Type *dest, const TypeEnvironment &env ) {
+	int ptrsAssignable( const Type *src, const Type * dest, const TypeEnvironment &env ) {
 		// std::cerr << "assignable: " << src << " | " << dest << std::endl;
-		if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
-			if ( const EqvClass *eqvClass = env.lookup( destAsTypeInst->get_name() ) ) {
+		if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType* >( dest ) ) {
+			if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->get_name() ) ) {
 				return ptrsAssignable( src, eqvClass->type, env );
 			} // if
 		} // if
-		if ( dynamic_cast< VoidType* >( dest ) ) {
+		if ( dynamic_cast< const VoidType* >( dest ) ) {
 			// void * = T * for any T is unsafe
 			// xxx - this should be safe, but that currently breaks the build
@@ -71,21 +71,21 @@
 	}
 
-	PtrsAssignable::PtrsAssignable( Type *dest, const TypeEnvironment &env ) : dest( dest ), result( 0 ), env( env ) {}
-
-	void PtrsAssignable::postvisit( VoidType * ) {
+	PtrsAssignable::PtrsAssignable( const Type * dest, const TypeEnvironment &env ) : dest( dest ), result( 0 ), env( env ) {}
+
+	void PtrsAssignable::postvisit( const VoidType * ) {
 		// T * = void * is disallowed - this is a change from C, where any
 		// void * can be assigned or passed to a non-void pointer without a cast.
 	}
 
-	void PtrsAssignable::postvisit( __attribute__((unused)) BasicType *basicType ) {}
-	void PtrsAssignable::postvisit( __attribute__((unused)) PointerType *pointerType ) {}
-	void PtrsAssignable::postvisit( __attribute__((unused)) ArrayType *arrayType ) {}
-	void PtrsAssignable::postvisit( __attribute__((unused)) FunctionType *functionType ) {}
-
-	void PtrsAssignable::postvisit(  __attribute__((unused)) StructInstType *inst ) {}
-	void PtrsAssignable::postvisit(  __attribute__((unused)) UnionInstType *inst ) {}
-
-	void PtrsAssignable::postvisit( EnumInstType * ) {
-		if ( dynamic_cast< BasicType* >( dest ) ) {
+	void PtrsAssignable::postvisit( const BasicType * ) {}
+	void PtrsAssignable::postvisit( const PointerType * ) {}
+	void PtrsAssignable::postvisit( const ArrayType * ) {}
+	void PtrsAssignable::postvisit( const FunctionType * ) {}
+
+	void PtrsAssignable::postvisit( const StructInstType * ) {}
+	void PtrsAssignable::postvisit( const UnionInstType * ) {}
+
+	void PtrsAssignable::postvisit( const EnumInstType * ) {
+		if ( dynamic_cast< const BasicType* >( dest ) ) {
 			// int * = E *, etc. is safe. This isn't technically correct, as each
 			// enum has one basic type that it is compatible with, an that type can
@@ -97,7 +97,7 @@
 	}
 
-	void PtrsAssignable::postvisit(  __attribute__((unused)) TraitInstType *inst ) {}
-	void PtrsAssignable::postvisit( TypeInstType *inst ) {
-		if ( const EqvClass *eqvClass = env.lookup( inst->get_name() ) ) {
+	void PtrsAssignable::postvisit(  const TraitInstType * ) {}
+	void PtrsAssignable::postvisit( const TypeInstType * inst ) {
+		if ( const EqvClass * eqvClass = env.lookup( inst->name ) ) {
 			if ( eqvClass->type ) {
 				// T * = S * for any S depends on the type bound to T
@@ -107,8 +107,8 @@
 	}
 
-	void PtrsAssignable::postvisit(  __attribute__((unused)) TupleType *tupleType ) {}
-	void PtrsAssignable::postvisit(  __attribute__((unused)) VarArgsType *varArgsType ) {}
-	void PtrsAssignable::postvisit(  __attribute__((unused)) ZeroType *zeroType ) {}
-	void PtrsAssignable::postvisit(  __attribute__((unused)) OneType *oneType ) {}
+	void PtrsAssignable::postvisit( const TupleType * ) {}
+	void PtrsAssignable::postvisit( const VarArgsType * ) {}
+	void PtrsAssignable::postvisit( const ZeroType * ) {}
+	void PtrsAssignable::postvisit( const OneType * ) {}
 
 // TODO: Get rid of the `_new` suffix when the old version is removed.
Index: src/ResolvExpr/PtrsCastable.cc
===================================================================
--- src/ResolvExpr/PtrsCastable.cc	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/ResolvExpr/PtrsCastable.cc	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -29,26 +29,26 @@
 	struct PtrsCastable_old : public WithShortCircuiting  {
 	  public:
-		PtrsCastable_old( Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer );
+		PtrsCastable_old( const Type * dest, const TypeEnvironment &env, const SymTab::Indexer &indexer );
 
 		int get_result() const { return result; }
 
-		void previsit( Type * ) { visit_children = false; }
-
-		void postvisit( VoidType * voidType );
-		void postvisit( BasicType * basicType );
-		void postvisit( PointerType * pointerType );
-		void postvisit( ArrayType * arrayType );
-		void postvisit( FunctionType * functionType );
-		void postvisit( StructInstType * inst );
-		void postvisit( UnionInstType * inst );
-		void postvisit( EnumInstType * inst );
-		void postvisit( TraitInstType * inst );
-		void postvisit( TypeInstType * inst );
-		void postvisit( TupleType * tupleType );
-		void postvisit( VarArgsType * varArgsType );
-		void postvisit( ZeroType * zeroType );
-		void postvisit( OneType * oneType );
+		void previsit( const Type * ) { visit_children = false; }
+
+		void postvisit( const VoidType * voidType );
+		void postvisit( const BasicType * basicType );
+		void postvisit( const PointerType * pointerType );
+		void postvisit( const ArrayType * arrayType );
+		void postvisit( const FunctionType * functionType );
+		void postvisit( const StructInstType * inst );
+		void postvisit( const UnionInstType * inst );
+		void postvisit( const EnumInstType * inst );
+		void postvisit( const TraitInstType * inst );
+		void postvisit( const TypeInstType * inst );
+		void postvisit( const TupleType * tupleType );
+		void postvisit( const VarArgsType * varArgsType );
+		void postvisit( const ZeroType * zeroType );
+		void postvisit( const OneType * oneType );
 	  private:
-		Type *dest;
+		const Type * dest;
 		int result;
 		const TypeEnvironment &env;
@@ -57,15 +57,15 @@
 
 	namespace {
-		int objectCast( Type *src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
-			if ( dynamic_cast< FunctionType* >( src ) ) {
+		int objectCast( const Type * src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
+			if ( dynamic_cast< const FunctionType* >( src ) ) {
 				return -1;
-			} else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( src ) ) {
-				if ( NamedTypeDecl *ntDecl = indexer.lookupType( typeInst->get_name() ) ) {
-					if ( TypeDecl *tyDecl = dynamic_cast< TypeDecl* >( ntDecl ) ) {
-						if ( tyDecl->get_kind() == TypeDecl::Ftype ) {
+			} else if ( const TypeInstType * typeInst = dynamic_cast< const TypeInstType* >( src ) ) {
+				if ( const NamedTypeDecl * ntDecl = indexer.lookupType( typeInst->name ) ) {
+					if ( const TypeDecl * tyDecl = dynamic_cast< const TypeDecl* >( ntDecl ) ) {
+						if ( tyDecl->kind == TypeDecl::Ftype ) {
 							return -1;
 						} // if
 					} //if
-				} else if ( const EqvClass *eqvClass = env.lookup( typeInst->get_name() ) ) {
+				} else if ( const EqvClass * eqvClass = env.lookup( typeInst->get_name() ) ) {
 					if ( eqvClass->data.kind == TypeDecl::Ftype ) {
 						return -1;
@@ -75,17 +75,17 @@
 			return 1;
 		}
-		int functionCast( Type *src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
+		int functionCast( const Type * src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
 			return -1 * objectCast( src, env, indexer );  // reverse the sense of objectCast
 		}
 	}
 
-	int ptrsCastable( Type *src, Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
-		if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
-			if ( const EqvClass *eqvClass = env.lookup( destAsTypeInst->get_name() ) ) {
+	int ptrsCastable( const Type * src, const Type * dest, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
+		if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType* >( dest ) ) {
+			if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->get_name() ) ) {
 				// xxx - should this be ptrsCastable?
 				return ptrsAssignable( src, eqvClass->type, env );
 			} // if
 		} // if
-		if ( dynamic_cast< VoidType* >( dest ) ) {
+		if ( dynamic_cast< const VoidType* >( dest ) ) {
 			return objectCast( src, env, indexer );
 		} else {
@@ -96,42 +96,42 @@
 	}
 
-	PtrsCastable_old::PtrsCastable_old( Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer )
+	PtrsCastable_old::PtrsCastable_old( const Type * dest, const TypeEnvironment &env, const SymTab::Indexer &indexer )
 		: dest( dest ), result( 0 ), env( env ), indexer( indexer )	{
 	}
 
-	void PtrsCastable_old::postvisit( VoidType * ) {
-		result = objectCast( dest, env, indexer );
-	}
-
-	void PtrsCastable_old::postvisit( BasicType * ) {
-		result = objectCast( dest, env, indexer );
-	}
-
-	void PtrsCastable_old::postvisit( PointerType * ) {
-		result = objectCast( dest, env, indexer );
-	}
-
-	void PtrsCastable_old::postvisit( ArrayType * ) {
-		result = objectCast( dest, env, indexer );
-	}
-
-	void PtrsCastable_old::postvisit( FunctionType * ) {
+	void PtrsCastable_old::postvisit( const VoidType * ) {
+		result = objectCast( dest, env, indexer );
+	}
+
+	void PtrsCastable_old::postvisit( const BasicType * ) {
+		result = objectCast( dest, env, indexer );
+	}
+
+	void PtrsCastable_old::postvisit( const PointerType * ) {
+		result = objectCast( dest, env, indexer );
+	}
+
+	void PtrsCastable_old::postvisit( const ArrayType * ) {
+		result = objectCast( dest, env, indexer );
+	}
+
+	void PtrsCastable_old::postvisit( const FunctionType * ) {
 		// result = -1;
 		result = functionCast( dest, env, indexer );
 	}
 
-	void PtrsCastable_old::postvisit( StructInstType * ) {
-		result = objectCast( dest, env, indexer );
-	}
-
-	void PtrsCastable_old::postvisit( UnionInstType * ) {
-		result = objectCast( dest, env, indexer );
-	}
-
-	void PtrsCastable_old::postvisit( EnumInstType * ) {
-		if ( dynamic_cast< EnumInstType* >( dest ) ) {
+	void PtrsCastable_old::postvisit( const StructInstType * ) {
+		result = objectCast( dest, env, indexer );
+	}
+
+	void PtrsCastable_old::postvisit( const UnionInstType * ) {
+		result = objectCast( dest, env, indexer );
+	}
+
+	void PtrsCastable_old::postvisit( const EnumInstType * ) {
+		if ( dynamic_cast< const EnumInstType * >( dest ) ) {
 			result = 1;
-		} else if ( BasicType *bt = dynamic_cast< BasicType* >( dest ) ) {
-			if ( bt->get_kind() == BasicType::SignedInt ) {
+		} else if ( const BasicType * bt = dynamic_cast< const BasicType * >( dest ) ) {
+			if ( bt->kind == BasicType::SignedInt ) {
 				result = 0;
 			} else {
@@ -143,24 +143,24 @@
 	}
 
-	void PtrsCastable_old::postvisit( TraitInstType * ) {}
-
-	void PtrsCastable_old::postvisit(TypeInstType *inst ) {
+	void PtrsCastable_old::postvisit( const TraitInstType * ) {}
+
+	void PtrsCastable_old::postvisit( const TypeInstType *inst ) {
 		//result = objectCast( inst, env, indexer ) > 0 && objectCast( dest, env, indexer ) > 0 ? 1 : -1;
 		result = objectCast( inst, env, indexer ) == objectCast( dest, env, indexer ) ? 1 : -1;
 	}
 
-	void PtrsCastable_old::postvisit( TupleType * ) {
-		result = objectCast( dest, env, indexer );
-	}
-
-	void PtrsCastable_old::postvisit( VarArgsType * ) {
-		result = objectCast( dest, env, indexer );
-	}
-
-	void PtrsCastable_old::postvisit( ZeroType * ) {
-		result = objectCast( dest, env, indexer );
-	}
-
-	void PtrsCastable_old::postvisit( OneType * ) {
+	void PtrsCastable_old::postvisit( const TupleType * ) {
+		result = objectCast( dest, env, indexer );
+	}
+
+	void PtrsCastable_old::postvisit( const VarArgsType * ) {
+		result = objectCast( dest, env, indexer );
+	}
+
+	void PtrsCastable_old::postvisit( const ZeroType * ) {
+		result = objectCast( dest, env, indexer );
+	}
+
+	void PtrsCastable_old::postvisit( const OneType * ) {
 		result = objectCast( dest, env, indexer );
 	}
@@ -168,6 +168,6 @@
 namespace {
 	// can this type be cast to an object (1 for yes, -1 for no)
-	int objectCast( 
-		const ast::Type * src, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab 
+	int objectCast(
+		const ast::Type * src, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab
 	) {
 		if ( dynamic_cast< const ast::FunctionType * >( src ) ) {
@@ -191,6 +191,6 @@
 
 	// can this type be cast to a function (inverse of objectCast)
-	int functionCast( 
-		const ast::Type * src, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab 
+	int functionCast(
+		const ast::Type * src, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab
 	) {
 		return -1 * objectCast( src, env, symtab );
@@ -204,5 +204,5 @@
 		int result;
 
-		PtrsCastable_new( 
+		PtrsCastable_new(
 			const ast::Type * d, const ast::TypeEnvironment & e, const ast::SymbolTable & syms )
 		: dst( d ), env( e ), symtab( syms ), result( 0 ) {}
@@ -278,7 +278,7 @@
 } // anonymous namespace
 
-int ptrsCastable( 
-	const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 
-	const ast::TypeEnvironment & env 
+int ptrsCastable(
+	const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
+	const ast::TypeEnvironment & env
 ) {
 	if ( auto inst = dynamic_cast< const ast::TypeInstType * >( dst ) ) {
Index: src/ResolvExpr/ResolveAssertions.cc
===================================================================
--- src/ResolvExpr/ResolveAssertions.cc	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/ResolvExpr/ResolveAssertions.cc	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -9,7 +9,7 @@
 // Author           : Aaron B. Moss
 // Created On       : Fri Oct 05 13:46:00 2018
-// Last Modified By : Aaron B. Moss
-// Last Modified On : Fri Oct 05 13:46:00 2018
-// Update Count     : 1
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Wed Jul 10 16:10:37 2019
+// Update Count     : 2
 //
 
@@ -197,5 +197,5 @@
 			}
 			if ( i == b.size() /* && i < a.size() */ ) return 1;
-			
+
 			int c = a[i].compare( b[i] );
 			if ( c != 0 ) return c;
@@ -220,5 +220,5 @@
 
 		/// Initial resolution state for an alternative
-		ResnState( Alternative& a, SymTab::Indexer& indexer )
+		ResnState( Alternative & a, SymTab::Indexer & indexer )
 		: alt(a), need(), newNeed(), deferred(), inferred(), costs{ Cost::zero }, indexer(indexer) {
 			need.swap( a.need );
@@ -226,5 +226,5 @@
 
 		/// Updated resolution state with new need-list
-		ResnState( ResnState&& o, IterateFlag )
+		ResnState( ResnState && o, IterateFlag )
 		: alt(std::move(o.alt)), need(o.newNeed.begin(), o.newNeed.end()), newNeed(), deferred(),
 		  inferred(std::move(o.inferred)), costs(o.costs), indexer(o.indexer) {
@@ -234,11 +234,11 @@
 
 	/// Binds a single assertion, updating resolution state
-	void bindAssertion( const DeclarationWithType* decl, AssertionSetValue info, Alternative& alt,
-			AssnCandidate& match, InferCache& inferred ) {
-
-		DeclarationWithType* candidate = match.cdata.id;
-		assertf( candidate->get_uniqueId(), "Assertion candidate does not have a unique ID: %s", toString( candidate ).c_str() );
-
-		Expression* varExpr = match.cdata.combine( alt.cvtCost );
+	void bindAssertion( const DeclarationWithType * decl, AssertionSetValue info, Alternative & alt,
+			AssnCandidate & match, InferCache & inferred ) {
+
+		const DeclarationWithType * candidate = match.cdata.id;
+		assertf( candidate->uniqueId, "Assertion candidate does not have a unique ID: %s", toString( candidate ).c_str() );
+
+		Expression * varExpr = match.cdata.combine( alt.cvtCost );
 		delete varExpr->result;
 		varExpr->result = match.adjType->clone();
@@ -247,10 +247,10 @@
 		// place newly-inferred assertion in proper place in cache
 		inferred[ info.resnSlot ][ decl->get_uniqueId() ] = ParamEntry{
-				candidate->get_uniqueId(), candidate->clone(), match.adjType->clone(), decl->get_type()->clone(),
+				candidate->uniqueId, candidate->clone(), match.adjType->clone(), decl->get_type()->clone(),
 				varExpr };
 	}
 
 	/// Adds a captured assertion to the symbol table
-	void addToIndexer( AssertionSet &assertSet, SymTab::Indexer &indexer ) {
+	void addToIndexer( AssertionSet & assertSet, SymTab::Indexer & indexer ) {
 		for ( auto&  i : assertSet ) {
 			if ( i.second.isUsed ) {
@@ -264,5 +264,5 @@
 
 	/// Resolve a single assertion, in context
-	bool resolveAssertion( AssertionItem& assn, ResnState& resn ) {
+	bool resolveAssertion( AssertionItem & assn, ResnState & resn ) {
 		// skip unused assertions
 		if ( ! assn.info.isUsed ) return true;
@@ -274,6 +274,6 @@
 		// find the candidates that unify with the desired type
 		CandidateList matches;
-		for ( const auto& cdata : candidates ) {
-			DeclarationWithType* candidate = cdata.id;
+		for ( const auto & cdata : candidates ) {
+			const DeclarationWithType * candidate = cdata.id;
 
 			// build independent unification context for candidate
@@ -281,5 +281,5 @@
 			TypeEnvironment newEnv{ resn.alt.env };
 			OpenVarSet newOpenVars{ resn.alt.openVars };
-			Type* adjType = candidate->get_type()->clone();
+			Type * adjType = candidate->get_type()->clone();
 			adjustExprType( adjType, newEnv, resn.indexer );
 			renameTyVars( adjType );
@@ -368,8 +368,8 @@
 		std::string resKey = SymTab::Mangler::mangleType( resType );
 		delete resType;
-		return std::move( resKey );
-	}
-	
-	/// Replace resnSlots with inferParams and add alternative to output list, if meets pruning 
+		return resKey;
+	}
+
+	/// Replace resnSlots with inferParams and add alternative to output list, if meets pruning
 	/// threshold.
 	void finalizeAssertions( ResnState& resn, PruneMap & pruneThresholds, AltList& out ) {
@@ -406,5 +406,5 @@
 		ResnList resns{ ResnState{ alt, root_indexer } };
 		ResnList new_resns{};
-		
+
 		// Pruning thresholds by result type of the output alternatives.
 		// Alternatives *should* be generated in sorted order, so no need to retroactively prune
Index: src/ResolvExpr/Resolver.cc
===================================================================
--- src/ResolvExpr/Resolver.cc	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/ResolvExpr/Resolver.cc	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -562,8 +562,7 @@
 		// TODO: Replace *exception type with &exception type.
 		if ( throwStmt->get_expr() ) {
-			StructDecl * exception_decl =
-				indexer.lookupStruct( "__cfaabi_ehm__base_exception_t" );
+			const StructDecl * exception_decl = indexer.lookupStruct( "__cfaabi_ehm__base_exception_t" );
 			assert( exception_decl );
-			Type * exceptType = new PointerType( noQualifiers, new StructInstType( noQualifiers, exception_decl ) );
+			Type * exceptType = new PointerType( noQualifiers, new StructInstType( noQualifiers, const_cast<StructDecl *>(exception_decl) ) );
 			findSingleExpression( throwStmt->expr, exceptType, indexer );
 		}
@@ -972,5 +971,5 @@
 		/// Calls the CandidateFinder and finds the single best candidate
 		CandidateRef findUnfinishedKindExpression(
-			const ast::Expr * untyped, const ast::SymbolTable & symtab, const std::string & kind, 
+			const ast::Expr * untyped, const ast::SymbolTable & symtab, const std::string & kind,
 			std::function<bool(const Candidate &)> pred = anyCandidate, ResolvMode mode = {}
 		) {
@@ -994,6 +993,6 @@
 			// produce invalid error if no candidates
 			if ( candidates.empty() ) {
-				SemanticError( untyped, 
-					toString( "No reasonable alternatives for ", kind, (kind != "" ? " " : ""), 
+				SemanticError( untyped,
+					toString( "No reasonable alternatives for ", kind, (kind != "" ? " " : ""),
 					"expression: ") );
 			}
@@ -1031,5 +1030,5 @@
 			if ( winners.size() != 1 ) {
 				std::ostringstream stream;
-				stream << "Cannot choose between " << winners.size() << " alternatives for " 
+				stream << "Cannot choose between " << winners.size() << " alternatives for "
 					<< kind << (kind != "" ? " " : "") << "expression\n";
 				ast::print( stream, untyped );
@@ -1054,10 +1053,10 @@
 		struct StripCasts_new final {
 			const ast::Expr * postmutate( const ast::CastExpr * castExpr ) {
-				if ( 
-					castExpr->isGenerated 
-					&& typesCompatible( castExpr->arg->result, castExpr->result ) 
+				if (
+					castExpr->isGenerated
+					&& typesCompatible( castExpr->arg->result, castExpr->result )
 				) {
 					// generated cast is the same type as its argument, remove it after keeping env
-					return ast::mutate_field( 
+					return ast::mutate_field(
 						castExpr->arg.get(), &ast::Expr::env, castExpr->env );
 				}
@@ -1088,10 +1087,10 @@
 
 		/// Establish post-resolver invariants for expressions
-		void finishExpr( 
-			ast::ptr< ast::Expr > & expr, const ast::TypeEnvironment & env, 
+		void finishExpr(
+			ast::ptr< ast::Expr > & expr, const ast::TypeEnvironment & env,
 			const ast::TypeSubstitution * oldenv = nullptr
 		) {
 			// set up new type substitution for expression
-			ast::ptr< ast::TypeSubstitution > newenv = 
+			ast::ptr< ast::TypeSubstitution > newenv =
 				 oldenv ? oldenv : new ast::TypeSubstitution{};
 			env.writeToSubstitution( *newenv.get_and_mutate() );
@@ -1102,15 +1101,15 @@
 	} // anonymous namespace
 
-		
+
 	ast::ptr< ast::Expr > resolveInVoidContext(
 		const ast::Expr * expr, const ast::SymbolTable & symtab, ast::TypeEnvironment & env
 	) {
 		assertf( expr, "expected a non-null expression" );
-		
+
 		// set up and resolve expression cast to void
 		ast::ptr< ast::CastExpr > untyped = new ast::CastExpr{ expr };
-		CandidateRef choice = findUnfinishedKindExpression( 
+		CandidateRef choice = findUnfinishedKindExpression(
 			untyped, symtab, "", anyCandidate, ResolvMode::withAdjustment() );
-		
+
 		// a cast expression has either 0 or 1 interpretations (by language rules);
 		// if 0, an exception has already been thrown, and this code will not run
@@ -1122,7 +1121,7 @@
 
 	namespace {
-		/// Resolve `untyped` to the expression whose candidate is the best match for a `void` 
+		/// Resolve `untyped` to the expression whose candidate is the best match for a `void`
 		/// context.
-		ast::ptr< ast::Expr > findVoidExpression( 
+		ast::ptr< ast::Expr > findVoidExpression(
 			const ast::Expr * untyped, const ast::SymbolTable & symtab
 		) {
@@ -1134,13 +1133,13 @@
 		}
 
-		/// resolve `untyped` to the expression whose candidate satisfies `pred` with the 
+		/// resolve `untyped` to the expression whose candidate satisfies `pred` with the
 		/// lowest cost, returning the resolved version
 		ast::ptr< ast::Expr > findKindExpression(
-			const ast::Expr * untyped, const ast::SymbolTable & symtab, 
-			std::function<bool(const Candidate &)> pred = anyCandidate, 
+			const ast::Expr * untyped, const ast::SymbolTable & symtab,
+			std::function<bool(const Candidate &)> pred = anyCandidate,
 			const std::string & kind = "", ResolvMode mode = {}
 		) {
 			if ( ! untyped ) return {};
-			CandidateRef choice = 
+			CandidateRef choice =
 				findUnfinishedKindExpression( untyped, symtab, kind, pred, mode );
 			finishExpr( choice->expr, choice->env, untyped->env );
@@ -1149,6 +1148,6 @@
 
 		/// Resolve `untyped` to the single expression whose candidate is the best match
-		ast::ptr< ast::Expr > findSingleExpression( 
-			const ast::Expr * untyped, const ast::SymbolTable & symtab 
+		ast::ptr< ast::Expr > findSingleExpression(
+			const ast::Expr * untyped, const ast::SymbolTable & symtab
 		) {
 			return findKindExpression( untyped, symtab );
@@ -1170,9 +1169,9 @@
 		bool hasIntegralType( const Candidate & i ) {
 			const ast::Type * type = i.expr->result;
-			
+
 			if ( auto bt = dynamic_cast< const ast::BasicType * >( type ) ) {
 				return bt->isInteger();
-			} else if ( 
-				dynamic_cast< const ast::EnumInstType * >( type ) 
+			} else if (
+				dynamic_cast< const ast::EnumInstType * >( type )
 				|| dynamic_cast< const ast::ZeroType * >( type )
 				|| dynamic_cast< const ast::OneType * >( type )
@@ -1183,6 +1182,6 @@
 
 		/// Resolve `untyped` as an integral expression, returning the resolved version
-		ast::ptr< ast::Expr > findIntegralExpression( 
-			const ast::Expr * untyped, const ast::SymbolTable & symtab 
+		ast::ptr< ast::Expr > findIntegralExpression(
+			const ast::Expr * untyped, const ast::SymbolTable & symtab
 		) {
 			return findKindExpression( untyped, symtab, hasIntegralType, "condition" );
@@ -1192,6 +1191,6 @@
 		bool isCharType( const ast::Type * t ) {
 			if ( auto bt = dynamic_cast< const ast::BasicType * >( t ) ) {
-				return bt->kind == ast::BasicType::Char 
-					|| bt->kind == ast::BasicType::SignedChar 
+				return bt->kind == ast::BasicType::Char
+					|| bt->kind == ast::BasicType::SignedChar
 					|| bt->kind == ast::BasicType::UnsignedChar;
 			}
@@ -1253,6 +1252,6 @@
 	}
 
-	ast::ptr< ast::Init > resolveCtorInit( 
-		const ast::ConstructorInit * ctorInit, const ast::SymbolTable & symtab 
+	ast::ptr< ast::Init > resolveCtorInit(
+		const ast::ConstructorInit * ctorInit, const ast::SymbolTable & symtab
 	) {
 		assert( ctorInit );
@@ -1261,6 +1260,6 @@
 	}
 
-	ast::ptr< ast::Expr > resolveStmtExpr( 
-		const ast::StmtExpr * stmtExpr, const ast::SymbolTable & symtab 
+	ast::ptr< ast::Expr > resolveStmtExpr(
+		const ast::StmtExpr * stmtExpr, const ast::SymbolTable & symtab
 	) {
 		assert( stmtExpr );
@@ -1303,16 +1302,16 @@
 
 	void Resolver_new::previsit( const ast::ObjectDecl * objectDecl ) {
-		// To handle initialization of routine pointers [e.g. int (*fp)(int) = foo()], 
-		// class-variable `initContext` is changed multiple times because the LHS is analyzed 
-		// twice. The second analysis changes `initContext` because a function type can contain 
-		// object declarations in the return and parameter types. Therefore each value of 
-		// `initContext` is retained so the type on the first analysis is preserved and used for 
+		// To handle initialization of routine pointers [e.g. int (*fp)(int) = foo()],
+		// class-variable `initContext` is changed multiple times because the LHS is analyzed
+		// twice. The second analysis changes `initContext` because a function type can contain
+		// object declarations in the return and parameter types. Therefore each value of
+		// `initContext` is retained so the type on the first analysis is preserved and used for
 		// selecting the RHS.
 		GuardValue( currentObject );
 		currentObject = ast::CurrentObject{ objectDecl->location, objectDecl->get_type() };
 		if ( inEnumDecl && dynamic_cast< const ast::EnumInstType * >( objectDecl->get_type() ) ) {
-			// enumerator initializers should not use the enum type to initialize, since the 
+			// enumerator initializers should not use the enum type to initialize, since the
 			// enum type is still incomplete at this point. Use `int` instead.
-			currentObject = ast::CurrentObject{ 
+			currentObject = ast::CurrentObject{
 				objectDecl->location, new ast::BasicType{ ast::BasicType::SignedInt } };
 		}
@@ -1325,9 +1324,9 @@
 	}
 
-	const ast::StaticAssertDecl * Resolver_new::previsit( 
-		const ast::StaticAssertDecl * assertDecl 
+	const ast::StaticAssertDecl * Resolver_new::previsit(
+		const ast::StaticAssertDecl * assertDecl
 	) {
-		return ast::mutate_field( 
-			assertDecl, &ast::StaticAssertDecl::cond, 
+		return ast::mutate_field(
+			assertDecl, &ast::StaticAssertDecl::cond,
 			findIntegralExpression( assertDecl->cond, symtab ) );
 	}
@@ -1338,6 +1337,6 @@
 			#warning should use new equivalent to Validate::SizeType rather than sizeType here
 			ast::ptr< ast::Type > sizeType = new ast::BasicType{ ast::BasicType::LongUnsignedInt };
-			ast::mutate_field( 
-				type, &PtrType::dimension, 
+			ast::mutate_field(
+				type, &PtrType::dimension,
 				findSingleExpression( type->dimension, sizeType, symtab ) );
 		}
@@ -1356,6 +1355,6 @@
 		visit_children = false;
 		assertf( exprStmt->expr, "ExprStmt has null expression in resolver" );
-		
-		return ast::mutate_field( 
+
+		return ast::mutate_field(
 			exprStmt, &ast::ExprStmt::expr, findVoidExpression( exprStmt->expr, symtab ) );
 	}
@@ -1364,12 +1363,12 @@
 		visit_children = false;
 
-		asmExpr = ast::mutate_field( 
+		asmExpr = ast::mutate_field(
 			asmExpr, &ast::AsmExpr::operand, findVoidExpression( asmExpr->operand, symtab ) );
-		
+
 		if ( asmExpr->inout ) {
 			asmExpr = ast::mutate_field(
 				asmExpr, &ast::AsmExpr::inout, findVoidExpression( asmExpr->inout, symtab ) );
 		}
-		
+
 		return asmExpr;
 	}
@@ -1388,5 +1387,5 @@
 
 	const ast::WhileStmt * Resolver_new::previsit( const ast::WhileStmt * whileStmt ) {
-		return ast::mutate_field( 
+		return ast::mutate_field(
 			whileStmt, &ast::WhileStmt::cond, findIntegralExpression( whileStmt->cond, symtab ) );
 	}
@@ -1409,5 +1408,5 @@
 		GuardValue( currentObject );
 		switchStmt = ast::mutate_field(
-			switchStmt, &ast::SwitchStmt::cond, 
+			switchStmt, &ast::SwitchStmt::cond,
 			findIntegralExpression( switchStmt->cond, symtab ) );
 		currentObject = ast::CurrentObject{ switchStmt->location, switchStmt->cond->result };
@@ -1420,15 +1419,15 @@
 			assertf( initAlts.size() == 1, "SwitchStmt did not correctly resolve an integral "
 				"expression." );
-			
-			ast::ptr< ast::Expr > untyped = 
+
+			ast::ptr< ast::Expr > untyped =
 				new ast::CastExpr{ caseStmt->location, caseStmt->cond, initAlts.front().type };
 			ast::ptr< ast::Expr > newExpr = findSingleExpression( untyped, symtab );
-			
-			// case condition cannot have a cast in C, so it must be removed here, regardless of 
+
+			// case condition cannot have a cast in C, so it must be removed here, regardless of
 			// whether it would perform a conversion.
 			if ( const ast::CastExpr * castExpr = newExpr.as< ast::CastExpr >() ) {
 				swap_and_save_env( newExpr, castExpr->arg );
 			}
-			
+
 			caseStmt = ast::mutate_field( caseStmt, &ast::CaseStmt::cond, newExpr );
 		}
@@ -1443,5 +1442,5 @@
 			ast::ptr< ast::Type > target = new ast::PointerType{ new ast::VoidType{} };
 			branchStmt = ast::mutate_field(
-				branchStmt, &ast::BranchStmt::computedTarget, 
+				branchStmt, &ast::BranchStmt::computedTarget,
 				findSingleExpression( branchStmt->computedTarget, target, symtab ) );
 		}
@@ -1453,5 +1452,5 @@
 		if ( returnStmt->expr ) {
 			returnStmt = ast::mutate_field(
-				returnStmt, &ast::ReturnStmt::expr, 
+				returnStmt, &ast::ReturnStmt::expr,
 				findSingleExpression( returnStmt->expr, functionReturn, symtab ) );
 		}
@@ -1462,11 +1461,11 @@
 		visit_children = false;
 		if ( throwStmt->expr ) {
-			const ast::StructDecl * exceptionDecl = 
+			const ast::StructDecl * exceptionDecl =
 				symtab.lookupStruct( "__cfaabi_ehm__base_exception_t" );
 			assert( exceptionDecl );
-			ast::ptr< ast::Type > exceptType = 
+			ast::ptr< ast::Type > exceptType =
 				new ast::PointerType{ new ast::StructInstType{ exceptionDecl } };
 			throwStmt = ast::mutate_field(
-				throwStmt, &ast::ThrowStmt::expr, 
+				throwStmt, &ast::ThrowStmt::expr,
 				findSingleExpression( throwStmt->expr, exceptType, symtab ) );
 		}
@@ -1477,6 +1476,6 @@
 		if ( catchStmt->cond ) {
 			ast::ptr< ast::Type > boolType = new ast::BasicType{ ast::BasicType::Bool };
-			catchStmt = ast::mutate_field( 
-				catchStmt, &ast::CatchStmt::cond, 
+			catchStmt = ast::mutate_field(
+				catchStmt, &ast::CatchStmt::cond,
 				findSingleExpression( catchStmt->cond, boolType, symtab ) );
 		}
@@ -1506,12 +1505,12 @@
 
 			if ( clause.target.args.empty() ) {
-				SemanticError( stmt->location, 
+				SemanticError( stmt->location,
 					"Waitfor clause must have at least one mutex parameter");
 			}
 
 			// Find all alternatives for all arguments in canonical form
-			std::vector< CandidateFinder > argFinders = 
+			std::vector< CandidateFinder > argFinders =
 				funcFinder.findSubExprs( clause.target.args );
-			
+
 			// List all combinations of arguments
 			std::vector< CandidateList > possibilities;
@@ -1519,5 +1518,5 @@
 
 			// For every possible function:
-			// * try matching the arguments to the parameters, not the other way around because 
+			// * try matching the arguments to the parameters, not the other way around because
 			//   more arguments than parameters
 			CandidateList funcCandidates;
@@ -1526,8 +1525,8 @@
 			for ( CandidateRef & func : funcFinder.candidates ) {
 				try {
-					auto pointerType = dynamic_cast< const ast::PointerType * >( 
+					auto pointerType = dynamic_cast< const ast::PointerType * >(
 						func->expr->result->stripReferences() );
 					if ( ! pointerType ) {
-						SemanticError( stmt->location, func->expr->result.get(), 
+						SemanticError( stmt->location, func->expr->result.get(),
 							"candidate not viable: not a pointer type\n" );
 					}
@@ -1535,5 +1534,5 @@
 					auto funcType = pointerType->base.as< ast::FunctionType >();
 					if ( ! funcType ) {
-						SemanticError( stmt->location, func->expr->result.get(), 
+						SemanticError( stmt->location, func->expr->result.get(),
 							"candidate not viable: not a function type\n" );
 					}
@@ -1544,5 +1543,5 @@
 
 						if( ! nextMutex( param, paramEnd ) ) {
-							SemanticError( stmt->location, funcType, 
+							SemanticError( stmt->location, funcType,
 								"candidate function not viable: no mutex parameters\n");
 						}
@@ -1560,5 +1559,5 @@
 							ast::AssertionSet need, have;
 							ast::TypeEnvironment resultEnv{ func->env };
-							// Add all type variables as open so that those not used in the 
+							// Add all type variables as open so that those not used in the
 							// parameter list are still considered open
 							resultEnv.add( funcType->forall );
@@ -1580,5 +1579,5 @@
 							unsigned n_mutex_param = 0;
 
-							// For every argument of its set, check if it matches one of the 
+							// For every argument of its set, check if it matches one of the
 							// parameters. The order is important
 							for ( auto & arg : argsList ) {
@@ -1587,5 +1586,5 @@
 									// We ran out of parameters but still have arguments.
 									// This function doesn't match
-									SemanticError( stmt->location, funcType, 
+									SemanticError( stmt->location, funcType,
 										toString("candidate function not viable: too many mutex "
 										"arguments, expected ", n_mutex_param, "\n" ) );
@@ -1594,11 +1593,11 @@
 								++n_mutex_param;
 
-								// Check if the argument matches the parameter type in the current 
+								// Check if the argument matches the parameter type in the current
 								// scope
 								ast::ptr< ast::Type > paramType = (*param)->get_type();
-								if ( 
-									! unify( 
-										arg->expr->result, paramType, resultEnv, need, have, open, 
-										symtab ) 
+								if (
+									! unify(
+										arg->expr->result, paramType, resultEnv, need, have, open,
+										symtab )
 								) {
 									// Type doesn't match
@@ -1627,7 +1626,7 @@
 								} while ( nextMutex( param, paramEnd ) );
 
-								// We ran out of arguments but still have parameters left; this 
+								// We ran out of arguments but still have parameters left; this
 								// function doesn't match
-								SemanticError( stmt->location, funcType, 
+								SemanticError( stmt->location, funcType,
 									toString( "candidate function not viable: too few mutex "
 									"arguments, expected ", n_mutex_param, "\n" ) );
@@ -1657,5 +1656,5 @@
 			// Make sure correct number of arguments
 			if( funcCandidates.empty() ) {
-				SemanticErrorException top( stmt->location, 
+				SemanticErrorException top( stmt->location,
 					"No alternatives for function in call to waitfor" );
 				top.append( errors );
@@ -1664,6 +1663,6 @@
 
 			if( argsCandidates.empty() ) {
-				SemanticErrorException top( stmt->location, 
-					"No alternatives for arguments in call to waitfor" ); 
+				SemanticErrorException top( stmt->location,
+					"No alternatives for arguments in call to waitfor" );
 				top.append( errors );
 				throw top;
@@ -1671,5 +1670,5 @@
 
 			if( funcCandidates.size() > 1 ) {
-				SemanticErrorException top( stmt->location, 
+				SemanticErrorException top( stmt->location,
 					"Ambiguous function in call to waitfor" );
 				top.append( errors );
@@ -1686,7 +1685,7 @@
 			// build new clause
 			ast::WaitForStmt::Clause clause2;
-			
+
 			clause2.target.func = funcCandidates.front()->expr;
-			
+
 			clause2.target.args.reserve( clause.target.args.size() );
 			for ( auto arg : argsCandidates.front() ) {
@@ -1708,5 +1707,5 @@
 			ast::WaitForStmt::Timeout timeout2;
 
-			ast::ptr< ast::Type > target = 
+			ast::ptr< ast::Type > target =
 				new ast::BasicType{ ast::BasicType::LongLongUnsignedInt };
 			timeout2.time = findSingleExpression( stmt->timeout.time, target, symtab );
@@ -1740,7 +1739,7 @@
 	const ast::SingleInit * Resolver_new::previsit( const ast::SingleInit * singleInit ) {
 		visit_children = false;
-		// resolve initialization using the possibilities as determined by the `currentObject` 
+		// resolve initialization using the possibilities as determined by the `currentObject`
 		// cursor.
-		ast::ptr< ast::Expr > untyped = new ast::UntypedInitExpr{ 
+		ast::ptr< ast::Expr > untyped = new ast::UntypedInitExpr{
 			singleInit->location, singleInit->value, currentObject.getOptions() };
 		ast::ptr<ast::Expr> newExpr = findSingleExpression( untyped, symtab );
@@ -1751,6 +1750,6 @@
 
 		// discard InitExpr wrapper and retain relevant pieces.
-		// `initExpr` may have inferred params in the case where the expression specialized a 
-		// function pointer, and newExpr may already have inferParams of its own, so a simple 
+		// `initExpr` may have inferred params in the case where the expression specialized a
+		// function pointer, and newExpr may already have inferParams of its own, so a simple
 		// swap is not sufficient
 		ast::Expr::InferUnion inferred = initExpr->inferred;
@@ -1758,5 +1757,5 @@
 		newExpr.get_and_mutate()->inferred.splice( std::move(inferred) );
 
-		// get the actual object's type (may not exactly match what comes back from the resolver 
+		// get the actual object's type (may not exactly match what comes back from the resolver
 		// due to conversions)
 		const ast::Type * initContext = currentObject.getCurrentType();
@@ -1770,5 +1769,5 @@
 				if ( auto pt = newExpr->result.as< ast::PointerType >() ) {
 					if ( isCharType( pt->base ) ) {
-						// strip cast if we're initializing a char[] with a char* 
+						// strip cast if we're initializing a char[] with a char*
 						// e.g. char x[] = "hello"
 						if ( auto ce = newExpr.as< ast::CastExpr >() ) {
@@ -1793,8 +1792,8 @@
 		assert( listInit->designations.size() == listInit->initializers.size() );
 		for ( unsigned i = 0; i < listInit->designations.size(); ++i ) {
-			// iterate designations and initializers in pairs, moving the cursor to the current 
+			// iterate designations and initializers in pairs, moving the cursor to the current
 			// designated object and resolving the initializer against that object
 			listInit = ast::mutate_field_index(
-				listInit, &ast::ListInit::designations, i, 
+				listInit, &ast::ListInit::designations, i,
 				currentObject.findNext( listInit->designations[i] ) );
 			listInit = ast::mutate_field_index(
@@ -1818,6 +1817,6 @@
 		ctorInit = ast::mutate_field( ctorInit, &ast::ConstructorInit::init, nullptr );
 
-		// intrinsic single-parameter constructors and destructors do nothing. Since this was 
-		// implicitly generated, there's no way for it to have side effects, so get rid of it to 
+		// intrinsic single-parameter constructors and destructors do nothing. Since this was
+		// implicitly generated, there's no way for it to have side effects, so get rid of it to
 		// clean up generated code
 		if ( InitTweak::isIntrinsicSingleArgCallStmt( ctorInit->ctor ) ) {
Index: src/ResolvExpr/Unify.cc
===================================================================
--- src/ResolvExpr/Unify.cc	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/ResolvExpr/Unify.cc	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -97,14 +97,14 @@
 	bool unifyExact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widen, const SymTab::Indexer &indexer );
 
-	bool unifyExact( 
-		const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env, 
-		ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 
+	bool unifyExact(
+		const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env,
+		ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
 		WidenMode widen, const ast::SymbolTable & symtab );
 
-	bool typesCompatible( Type *first, Type *second, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
+	bool typesCompatible( const Type * first, const Type * second, const SymTab::Indexer & indexer, const TypeEnvironment & env ) {
 		TypeEnvironment newEnv;
 		OpenVarSet openVars, closedVars; // added closedVars
 		AssertionSet needAssertions, haveAssertions;
-		Type *newFirst = first->clone(), *newSecond = second->clone();
+		Type * newFirst = first->clone(), * newSecond = second->clone();
 		env.apply( newFirst );
 		env.apply( newSecond );
@@ -121,6 +121,6 @@
 	}
 
-	bool typesCompatible( 
-			const ast::Type * first, const ast::Type * second, const ast::SymbolTable & symtab, 
+	bool typesCompatible(
+			const ast::Type * first, const ast::Type * second, const ast::SymbolTable & symtab,
 			const ast::TypeEnvironment & env ) {
 		ast::TypeEnvironment newEnv;
@@ -135,9 +135,9 @@
 		findOpenVars( newSecond, open, closed, need, have, FirstOpen );
 
-		return unifyExact( 
+		return unifyExact(
 			newFirst, newSecond, newEnv, need, have, open, noWiden(), symtab );
 	}
 
-	bool typesCompatibleIgnoreQualifiers( Type *first, Type *second, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
+	bool typesCompatibleIgnoreQualifiers( const Type * first, const Type * second, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
 		TypeEnvironment newEnv;
 		OpenVarSet openVars;
@@ -163,11 +163,11 @@
 	}
 
-	bool typesCompatibleIgnoreQualifiers( 
-			const ast::Type * first, const ast::Type * second, const ast::SymbolTable & symtab, 
+	bool typesCompatibleIgnoreQualifiers(
+			const ast::Type * first, const ast::Type * second, const ast::SymbolTable & symtab,
 			const ast::TypeEnvironment & env ) {
 		ast::TypeEnvironment newEnv;
 		ast::OpenVarSet open;
 		ast::AssertionSet need, have;
-		
+
 		ast::ptr<ast::Type> newFirst{ first }, newSecond{ second };
 		env.apply( newFirst );
@@ -176,5 +176,5 @@
 		reset_qualifiers( newSecond );
 
-		return unifyExact( 
+		return unifyExact(
 			newFirst, newSecond, newEnv, need, have, open, noWiden(), symtab );
 	}
@@ -490,9 +490,9 @@
 
 			// sizes don't have to match if ttypes are involved; need to be more precise wrt where the ttype is to prevent errors
-			if ( 
-					(flatFunc->parameters.size() == flatOther->parameters.size() && 
-						flatFunc->returnVals.size() == flatOther->returnVals.size()) 
-					|| flatFunc->isTtype() 
-					|| flatOther->isTtype() 
+			if (
+					(flatFunc->parameters.size() == flatOther->parameters.size() &&
+						flatFunc->returnVals.size() == flatOther->returnVals.size())
+					|| flatFunc->isTtype()
+					|| flatOther->isTtype()
 			) {
 				if ( unifyDeclList( flatFunc->parameters.begin(), flatFunc->parameters.end(), flatOther->parameters.begin(), flatOther->parameters.end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
@@ -711,13 +711,13 @@
 		bool result;
 
-		Unify_new( 
-			const ast::Type * type2, ast::TypeEnvironment & env, ast::AssertionSet & need, 
-			ast::AssertionSet & have, const ast::OpenVarSet & open, WidenMode widen, 
+		Unify_new(
+			const ast::Type * type2, ast::TypeEnvironment & env, ast::AssertionSet & need,
+			ast::AssertionSet & have, const ast::OpenVarSet & open, WidenMode widen,
 			const ast::SymbolTable & symtab )
-		: type2(type2), tenv(env), need(need), have(have), open(open), widen(widen), 
+		: type2(type2), tenv(env), need(need), have(have), open(open), widen(widen),
 		  symtab(symtab), result(false) {}
 
 		void previsit( const ast::Node * ) { visit_children = false; }
-		
+
 		void postvisit( const ast::VoidType * ) {
 			result = dynamic_cast< const ast::VoidType * >( type2 );
@@ -732,6 +732,6 @@
 		void postvisit( const ast::PointerType * pointer ) {
 			if ( auto pointer2 = dynamic_cast< const ast::PointerType * >( type2 ) ) {
-				result = unifyExact( 
-					pointer->base, pointer2->base, tenv, need, have, open, 
+				result = unifyExact(
+					pointer->base, pointer2->base, tenv, need, have, open,
 					noWiden(), symtab );
 			}
@@ -742,8 +742,8 @@
 			if ( ! array2 ) return;
 
-			// to unify, array types must both be VLA or both not VLA and both must have a 
+			// to unify, array types must both be VLA or both not VLA and both must have a
 			// dimension expression or not have a dimension
 			if ( array->isVarLen != array2->isVarLen ) return;
-			if ( ! array->isVarLen && ! array2->isVarLen 
+			if ( ! array->isVarLen && ! array2->isVarLen
 					&& array->dimension && array2->dimension ) {
 				auto ce1 = array->dimension.as< ast::ConstantExpr >();
@@ -751,11 +751,11 @@
 
 				// see C11 Reference Manual 6.7.6.2.6
-				// two array types with size specifiers that are integer constant expressions are 
+				// two array types with size specifiers that are integer constant expressions are
 				// compatible if both size specifiers have the same constant value
 				if ( ce1 && ce2 && ce1->intValue() != ce2->intValue() ) return;
 			}
 
-			result = unifyExact( 
-				array->base, array2->base, tenv, need, have, open, noWiden(), 
+			result = unifyExact(
+				array->base, array2->base, tenv, need, have, open, noWiden(),
 				symtab );
 		}
@@ -763,6 +763,6 @@
 		void postvisit( const ast::ReferenceType * ref ) {
 			if ( auto ref2 = dynamic_cast< const ast::ReferenceType * >( type2 ) ) {
-				result = unifyExact( 
-					ref->base, ref2->base, tenv, need, have, open, noWiden(), 
+				result = unifyExact(
+					ref->base, ref2->base, tenv, need, have, open, noWiden(),
 					symtab );
 			}
@@ -771,5 +771,5 @@
 	private:
 		/// Replaces ttype variables with their bound types.
-		/// If this isn't done when satifying ttype assertions, then argument lists can have 
+		/// If this isn't done when satifying ttype assertions, then argument lists can have
 		/// different size and structure when they should be compatible.
 		struct TtypeExpander_new : public ast::WithShortCircuiting {
@@ -800,9 +800,9 @@
 				auto types = flatten( d->get_type() );
 				for ( ast::ptr< ast::Type > & t : types ) {
-					// outermost const, volatile, _Atomic qualifiers in parameters should not play 
-					// a role in the unification of function types, since they do not determine 
+					// outermost const, volatile, _Atomic qualifiers in parameters should not play
+					// a role in the unification of function types, since they do not determine
 					// whether a function is callable.
-					// NOTE: **must** consider at least mutex qualifier, since functions can be 
-					// overloaded on outermost mutex and a mutex function has different 
+					// NOTE: **must** consider at least mutex qualifier, since functions can be
+					// overloaded on outermost mutex and a mutex function has different
 					// requirements than a non-mutex function
 					remove_qualifiers( t, ast::CV::Const | ast::CV::Volatile | ast::CV::Atomic );
@@ -818,5 +818,5 @@
 			std::vector< ast::ptr< ast::Type > > types;
 			while ( crnt != end ) {
-				// it is guaranteed that a ttype variable will be bound to a flat tuple, so ensure 
+				// it is guaranteed that a ttype variable will be bound to a flat tuple, so ensure
 				// that this results in a flat tuple
 				flatten( (*crnt)->get_type(), types );
@@ -829,7 +829,7 @@
 
 		template< typename Iter >
-		static bool unifyDeclList( 
-			Iter crnt1, Iter end1, Iter crnt2, Iter end2, ast::TypeEnvironment & env, 
-			ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 
+		static bool unifyDeclList(
+			Iter crnt1, Iter end1, Iter crnt2, Iter end2, ast::TypeEnvironment & env,
+			ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
 			const ast::SymbolTable & symtab
 		) {
@@ -843,16 +843,16 @@
 				if ( isTuple1 && ! isTuple2 ) {
 					// combine remainder of list2, then unify
-					return unifyExact( 
-						t1, tupleFromDecls( crnt2, end2 ), env, need, have, open, 
+					return unifyExact(
+						t1, tupleFromDecls( crnt2, end2 ), env, need, have, open,
 						noWiden(), symtab );
 				} else if ( ! isTuple1 && isTuple2 ) {
 					// combine remainder of list1, then unify
-					return unifyExact( 
-						tupleFromDecls( crnt1, end1 ), t2, env, need, have, open, 
+					return unifyExact(
+						tupleFromDecls( crnt1, end1 ), t2, env, need, have, open,
 						noWiden(), symtab );
 				}
 
-				if ( ! unifyExact( 
-					t1, t2, env, need, have, open, noWiden(), symtab ) 
+				if ( ! unifyExact(
+					t1, t2, env, need, have, open, noWiden(), symtab )
 				) return false;
 
@@ -860,5 +860,5 @@
 			}
 
-			// May get to the end of one argument list before the other. This is only okay if the 
+			// May get to the end of one argument list before the other. This is only okay if the
 			// other is a ttype
 			if ( crnt1 != end1 ) {
@@ -866,6 +866,6 @@
 				const ast::Type * t1 = (*crnt1)->get_type();
 				if ( ! Tuples::isTtype( t1 ) ) return false;
-				return unifyExact( 
-					t1, tupleFromDecls( crnt2, end2 ), env, need, have, open, 
+				return unifyExact(
+					t1, tupleFromDecls( crnt2, end2 ), env, need, have, open,
 					noWiden(), symtab );
 			} else if ( crnt2 != end2 ) {
@@ -873,6 +873,6 @@
 				const ast::Type * t2 = (*crnt2)->get_type();
 				if ( ! Tuples::isTtype( t2 ) ) return false;
-				return unifyExact( 
-					tupleFromDecls( crnt1, end1 ), t2, env, need, have, open, 
+				return unifyExact(
+					tupleFromDecls( crnt1, end1 ), t2, env, need, have, open,
 					noWiden(), symtab );
 			}
@@ -881,12 +881,12 @@
 		}
 
-		static bool unifyDeclList( 
-			const std::vector< ast::ptr< ast::DeclWithType > > & list1, 
-			const std::vector< ast::ptr< ast::DeclWithType > > & list2, 
-			ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 
+		static bool unifyDeclList(
+			const std::vector< ast::ptr< ast::DeclWithType > > & list1,
+			const std::vector< ast::ptr< ast::DeclWithType > > & list2,
+			ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
 			const ast::OpenVarSet & open, const ast::SymbolTable & symtab
 		) {
-			return unifyDeclList( 
-				list1.begin(), list1.end(), list2.begin(), list2.end(), env, need, have, open, 
+			return unifyDeclList(
+				list1.begin(), list1.end(), list2.begin(), list2.end(), env, need, have, open,
 				symtab );
 		}
@@ -900,7 +900,7 @@
 
 		/// mark all assertions in `type` used in both `assn1` and `assn2`
-		static void markAssertions( 
-			ast::AssertionSet & assn1, ast::AssertionSet & assn2, 
-			const ast::ParameterizedType * type 
+		static void markAssertions(
+			ast::AssertionSet & assn1, ast::AssertionSet & assn2,
+			const ast::ParameterizedType * type
 		) {
 			for ( const auto & tyvar : type->forall ) {
@@ -918,13 +918,13 @@
 
 			if ( func->isVarArgs != func2->isVarArgs ) return;
-			
-			// Flatten the parameter lists for both functions so that tuple structure does not 
+
+			// Flatten the parameter lists for both functions so that tuple structure does not
 			// affect unification. Does not actually mutate function parameters.
 			auto params = flattenList( func->params, tenv );
 			auto params2 = flattenList( func2->params, tenv );
 
-			// sizes don't have to match if ttypes are involved; need to be more precise w.r.t. 
+			// sizes don't have to match if ttypes are involved; need to be more precise w.r.t.
 			// where the ttype is to prevent errors
-			if ( 
+			if (
 				( params.size() != params2.size() || func->returns.size() != func2->returns.size() )
 				&& ! func->isTtype()
@@ -933,7 +933,7 @@
 
 			if ( ! unifyDeclList( params, params2, tenv, need, have, open, symtab ) ) return;
-			if ( ! unifyDeclList( 
+			if ( ! unifyDeclList(
 				func->returns, func2->returns, tenv, need, have, open, symtab ) ) return;
-			
+
 			markAssertions( have, need, func );
 			markAssertions( have, need, func2 );
@@ -941,5 +941,5 @@
 			result = true;
 		}
-	
+
 	private:
 		template< typename RefType >
@@ -953,5 +953,5 @@
 		/// Creates a tuple type based on a list of TypeExpr
 		template< typename Iter >
-		static const ast::Type * tupleFromExprs( 
+		static const ast::Type * tupleFromExprs(
 			const ast::TypeExpr * param, Iter & crnt, Iter end, ast::CV::Qualifiers qs
 		) {
@@ -973,5 +973,5 @@
 			const RefType * inst2 = handleRefType( inst, other );
 			if ( ! inst2 ) return;
-			
+
 			// check that parameters of types unify, if any
 			const std::vector< ast::ptr< ast::Expr > > & params = inst->params;
@@ -1002,5 +1002,5 @@
 				}
 
-				if ( ! unifyExact( 
+				if ( ! unifyExact(
 						pty, pty2, tenv, need, have, open, noWiden(), symtab ) ) {
 					result = false;
@@ -1038,10 +1038,10 @@
 	private:
 		/// Creates a tuple type based on a list of Type
-		static ast::ptr< ast::Type > tupleFromTypes( 
+		static ast::ptr< ast::Type > tupleFromTypes(
 			const std::vector< ast::ptr< ast::Type > > & tys
 		) {
 			std::vector< ast::ptr< ast::Type > > out;
 			for ( const ast::Type * ty : tys ) {
-				// it is guaranteed that a ttype variable will be bound to a flat tuple, so ensure 
+				// it is guaranteed that a ttype variable will be bound to a flat tuple, so ensure
 				// that this results in a flat tuple
 				flatten( ty, out );
@@ -1051,8 +1051,8 @@
 		}
 
-		static bool unifyList( 
-			const std::vector< ast::ptr< ast::Type > > & list1, 
-			const std::vector< ast::ptr< ast::Type > > & list2, ast::TypeEnvironment & env, 
-			ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 
+		static bool unifyList(
+			const std::vector< ast::ptr< ast::Type > > & list1,
+			const std::vector< ast::ptr< ast::Type > > & list2, ast::TypeEnvironment & env,
+			ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
 			const ast::SymbolTable & symtab
 		) {
@@ -1068,16 +1068,16 @@
 				if ( isTuple1 && ! isTuple2 ) {
 					// combine entirety of list2, then unify
-					return unifyExact( 
-						t1, tupleFromTypes( list2 ), env, need, have, open, 
+					return unifyExact(
+						t1, tupleFromTypes( list2 ), env, need, have, open,
 						noWiden(), symtab );
 				} else if ( ! isTuple1 && isTuple2 ) {
 					// combine entirety of list1, then unify
 					return unifyExact(
-						tupleFromTypes( list1 ), t2, env, need, have, open, 
+						tupleFromTypes( list1 ), t2, env, need, have, open,
 						noWiden(), symtab );
 				}
 
-				if ( ! unifyExact( 
-					t1, t2, env, need, have, open, noWiden(), symtab ) 
+				if ( ! unifyExact(
+					t1, t2, env, need, have, open, noWiden(), symtab )
 				) return false;
 
@@ -1089,8 +1089,8 @@
 				const ast::Type * t1 = *crnt1;
 				if ( ! Tuples::isTtype( t1 ) ) return false;
-				// xxx - this doesn't generate an empty tuple, contrary to comment; both ported 
+				// xxx - this doesn't generate an empty tuple, contrary to comment; both ported
 				// from Rob's code
-				return unifyExact( 
-						t1, tupleFromTypes( list2 ), env, need, have, open, 
+				return unifyExact(
+						t1, tupleFromTypes( list2 ), env, need, have, open,
 						noWiden(), symtab );
 			} else if ( crnt2 != list2.end() ) {
@@ -1098,8 +1098,8 @@
 				const ast::Type * t2 = *crnt2;
 				if ( ! Tuples::isTtype( t2 ) ) return false;
-				// xxx - this doesn't generate an empty tuple, contrary to comment; both ported 
+				// xxx - this doesn't generate an empty tuple, contrary to comment; both ported
 				// from Rob's code
 				return unifyExact(
-						tupleFromTypes( list1 ), t2, env, need, have, open, 
+						tupleFromTypes( list1 ), t2, env, need, have, open,
 						noWiden(), symtab );
 			}
@@ -1133,5 +1133,5 @@
 		void postvisit( const ast::OneType * ) {
 			result = dynamic_cast< const ast::OneType * >( type2 );
-		}	
+		}
 
 	  private:
@@ -1140,7 +1140,7 @@
 	};
 
-	bool unify( 
-			const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 
-			ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 
+	bool unify(
+			const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
+			ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
 			ast::OpenVarSet & open, const ast::SymbolTable & symtab
 	) {
@@ -1149,19 +1149,19 @@
 	}
 
-	bool unify( 
-			const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 
-			ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 
-			ast::OpenVarSet & open, const ast::SymbolTable & symtab, ast::ptr<ast::Type> & common 
+	bool unify(
+			const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
+			ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
+			ast::OpenVarSet & open, const ast::SymbolTable & symtab, ast::ptr<ast::Type> & common
 	) {
 		ast::OpenVarSet closed;
 		findOpenVars( type1, open, closed, need, have, FirstClosed );
 		findOpenVars( type2, open, closed, need, have, FirstOpen );
-		return unifyInexact( 
+		return unifyInexact(
 			type1, type2, env, need, have, open, WidenMode{ true, true }, symtab, common );
 	}
 
-	bool unifyExact( 
-			const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env, 
-			ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 
+	bool unifyExact(
+			const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env,
+			ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
 			WidenMode widen, const ast::SymbolTable & symtab
 	) {
@@ -1170,6 +1170,6 @@
 		auto var1 = dynamic_cast< const ast::TypeInstType * >( type1 );
 		auto var2 = dynamic_cast< const ast::TypeInstType * >( type2 );
-		ast::OpenVarSet::const_iterator 
-			entry1 = var1 ? open.find( var1->name ) : open.end(), 
+		ast::OpenVarSet::const_iterator
+			entry1 = var1 ? open.find( var1->name ) : open.end(),
 			entry2 = var2 ? open.find( var2->name ) : open.end();
 		bool isopen1 = entry1 != open.end();
@@ -1178,6 +1178,6 @@
 		if ( isopen1 && isopen2 ) {
 			if ( entry1->second.kind != entry2->second.kind ) return false;
-			return env.bindVarToVar( 
-				var1, var2, ast::TypeDecl::Data{ entry1->second, entry2->second }, need, have, 
+			return env.bindVarToVar(
+				var1, var2, ast::TypeDecl::Data{ entry1->second, entry2->second }, need, have,
 				open, widen, symtab );
 		} else if ( isopen1 ) {
@@ -1192,18 +1192,18 @@
 	}
 
-	bool unifyInexact( 
-			const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 
-			ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 
-			const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab, 
-			ast::ptr<ast::Type> & common 
+	bool unifyInexact(
+			const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
+			ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
+			const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab,
+			ast::ptr<ast::Type> & common
 	) {
 		ast::CV::Qualifiers q1 = type1->qualifiers, q2 = type2->qualifiers;
-		
-		// force t1 and t2 to be cloned if their qualifiers must be stripped, so that type1 and 
+
+		// force t1 and t2 to be cloned if their qualifiers must be stripped, so that type1 and
 		// type2 are left unchanged; calling convention forces type{1,2}->strong_ref >= 1
 		ast::ptr<ast::Type> t1{ type1 }, t2{ type2 };
 		reset_qualifiers( t1 );
 		reset_qualifiers( t2 );
-		
+
 		if ( unifyExact( t1, t2, env, need, have, open, widen, symtab ) ) {
 			t1 = nullptr; t2 = nullptr; // release t1, t2 to avoid spurious clones
Index: src/ResolvExpr/typeops.h
===================================================================
--- src/ResolvExpr/typeops.h	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/ResolvExpr/typeops.h	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -28,5 +28,8 @@
 #include "SynTree/SynTree.h"
 #include "SynTree/Type.h"
-#include "SymTab/Indexer.h"
+
+namespace SymTab {
+	class Indexer;
+}
 
 namespace ResolvExpr {
@@ -60,5 +63,5 @@
 	// in AdjustExprType.cc
 	/// Replaces array types with the equivalent pointer, and function types with a pointer-to-function
-	void adjustExprType( Type *&type, const TypeEnvironment &env, const SymTab::Indexer &indexer );
+	void adjustExprType( Type *& type, const TypeEnvironment & env, const SymTab::Indexer & indexer );
 
 	/// Replaces array types with the equivalent pointer, and function types with a pointer-to-function using empty TypeEnvironment and Indexer
@@ -66,5 +69,5 @@
 
 	template< typename ForwardIterator >
-	void adjustExprTypeList( ForwardIterator begin, ForwardIterator end, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
+	void adjustExprTypeList( ForwardIterator begin, ForwardIterator end, const TypeEnvironment & env, const SymTab::Indexer & indexer ) {
 		while ( begin != end ) {
 			adjustExprType( *begin++, env, indexer );
@@ -73,54 +76,54 @@
 
 	/// Replaces array types with equivalent pointer, and function types with a pointer-to-function
-	const ast::Type * adjustExprType( 
+	const ast::Type * adjustExprType(
 		const ast::Type * type, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab );
 
 	// in CastCost.cc
-	Cost castCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env );
-	Cost castCost( 
-		const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 
+	Cost castCost( const Type * src, const Type * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env );
+	Cost castCost(
+		const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
 		const ast::TypeEnvironment & env );
 
 	// in ConversionCost.cc
-	Cost conversionCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env );
-	Cost conversionCost( 
-		const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 
+	Cost conversionCost( const Type * src, const Type * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env );
+	Cost conversionCost(
+		const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
 		const ast::TypeEnvironment & env );
 
 	// in AlternativeFinder.cc
-	Cost computeConversionCost( Type *actualType, Type *formalType, 
-		const SymTab::Indexer &indexer, const TypeEnvironment &env );
+	Cost computeConversionCost( Type * actualType, Type * formalType,
+		const SymTab::Indexer & indexer, const TypeEnvironment & env );
 
 	// in PtrsAssignable.cc
-	int ptrsAssignable( Type *src, Type *dest, const TypeEnvironment &env );
+	int ptrsAssignable( const Type * src, const Type * dest, const TypeEnvironment & env );
 	int ptrsAssignable( const ast::Type * src, const ast::Type * dst,
 		const ast::TypeEnvironment & env );
 
 	// in PtrsCastable.cc
-	int ptrsCastable( Type *src, Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer );
-	int ptrsCastable( 
-		const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 
+	int ptrsCastable( const Type * src, const Type * dest, const TypeEnvironment & env, const SymTab::Indexer & indexer );
+	int ptrsCastable(
+		const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
 		const ast::TypeEnvironment & env );
 
 	// in Unify.cc
-	bool typesCompatible( Type *, Type *, const SymTab::Indexer &indexer, const TypeEnvironment &env );
-	bool typesCompatibleIgnoreQualifiers( Type *, Type *, const SymTab::Indexer &indexer, const TypeEnvironment &env );
-
-	inline bool typesCompatible( Type *t1, Type *t2, const SymTab::Indexer &indexer ) {
+	bool typesCompatible( const Type *, const Type *, const SymTab::Indexer & indexer, const TypeEnvironment & env );
+	bool typesCompatibleIgnoreQualifiers( const Type *, const Type *, const SymTab::Indexer & indexer, const TypeEnvironment & env );
+
+	inline bool typesCompatible( const Type * t1, const Type * t2, const SymTab::Indexer & indexer ) {
 		TypeEnvironment env;
 		return typesCompatible( t1, t2, indexer, env );
 	}
 
-	inline bool typesCompatibleIgnoreQualifiers( Type *t1, Type *t2, const SymTab::Indexer &indexer ) {
+	inline bool typesCompatibleIgnoreQualifiers( const Type * t1, const Type * t2, const SymTab::Indexer & indexer ) {
 		TypeEnvironment env;
 		return typesCompatibleIgnoreQualifiers( t1, t2, indexer, env );
 	}
 
-	bool typesCompatible( 
-		const ast::Type *, const ast::Type *, const ast::SymbolTable & symtab = {}, 
+	bool typesCompatible(
+		const ast::Type *, const ast::Type *, const ast::SymbolTable & symtab = {},
 		const ast::TypeEnvironment & env = {} );
-	
+
 	bool typesCompatibleIgnoreQualifiers(
-		const ast::Type *, const ast::Type *, const ast::SymbolTable &, 
+		const ast::Type *, const ast::Type *, const ast::SymbolTable &,
 		const ast::TypeEnvironment & env = {} );
 
@@ -131,24 +134,24 @@
 
 	// in CommonType.cc
-	Type * commonType( Type *type1, Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars );
+	Type * commonType( Type * type1, Type * type2, bool widenFirst, bool widenSecond, const SymTab::Indexer & indexer, TypeEnvironment & env, const OpenVarSet & openVars );
 	ast::ptr< ast::Type > commonType(
-		const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2, WidenMode widen, 
+		const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2, WidenMode widen,
 		const ast::SymbolTable & symtab, ast::TypeEnvironment & env, const ast::OpenVarSet & open );
 
 	// in PolyCost.cc
-	int polyCost( Type *type, const TypeEnvironment &env, const SymTab::Indexer &indexer );
-	int polyCost( 
+	int polyCost( Type * type, const TypeEnvironment & env, const SymTab::Indexer & indexer );
+	int polyCost(
 		const ast::Type * type, const ast::SymbolTable & symtab, const ast::TypeEnvironment & env );
 
 	// in SpecCost.cc
-	int specCost( Type *type );
+	int specCost( Type * type );
 	int specCost( const ast::Type * type );
 
 	// in Occurs.cc
-	bool occurs( Type *type, std::string varName, const TypeEnvironment &env );
+	bool occurs( Type * type, std::string varName, const TypeEnvironment & env );
 	// new AST version in TypeEnvironment.cpp (only place it was used in old AST)
 
-	template<typename Iter> 
-	bool occursIn( Type* ty, Iter begin, Iter end, const TypeEnvironment &env ) {
+	template<typename Iter>
+	bool occursIn( Type* ty, Iter begin, Iter end, const TypeEnvironment & env ) {
 		while ( begin != end ) {
 			if ( occurs( ty, *begin, env ) ) return true;
@@ -176,8 +179,8 @@
 
 	/// flatten tuple type into existing list of types
-	static inline void flatten( 
-		const ast::Type * type, std::vector< ast::ptr< ast::Type > > & out 
+	static inline void flatten(
+		const ast::Type * type, std::vector< ast::ptr< ast::Type > > & out
 	) {
-		if ( auto tupleType = dynamic_cast< const ast::TupleType * >( type ) ) {	
+		if ( auto tupleType = dynamic_cast< const ast::TupleType * >( type ) ) {
 			for ( const ast::Type * t : tupleType->types ) {
 				flatten( t, out );
@@ -197,5 +200,5 @@
 
 	// in TypeEnvironment.cc
-	bool isFtype( Type *type );
+	bool isFtype( Type * type );
 } // namespace ResolvExpr
 
Index: src/SymTab/Indexer.cc
===================================================================
--- src/SymTab/Indexer.cc	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/SymTab/Indexer.cc	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -74,7 +74,7 @@
 	}
 
-	Indexer::Indexer() 
-	: idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable(), 
-	  prevScope(), scope( 0 ), repScope( 0 ) { ++*stats().count; }
+	Indexer::Indexer()
+	: idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable(),
+	  prevScope(), scope( 0 ), repScope( 0 ) { ++* stats().count; }
 
 	Indexer::~Indexer() {
@@ -84,7 +84,7 @@
 	void Indexer::lazyInitScope() {
 		if ( repScope < scope ) {
-			++*stats().lazy_scopes;
+			++* stats().lazy_scopes;
 			// create rollback
-			prevScope = std::make_shared<Indexer>( *this );
+			prevScope = std::make_shared<Indexer>( * this );
 			// update repScope
 			repScope = scope;
@@ -95,5 +95,5 @@
 		++scope;
 
-		++*stats().new_scopes;
+		++* stats().new_scopes;
 		stats().avg_scope_depth->push( scope );
 		stats().max_scope_depth->push( scope );
@@ -103,5 +103,5 @@
 		if ( repScope == scope ) {
 			Ptr prev = prevScope;           // make sure prevScope stays live
-			*this = std::move(*prevScope);  // replace with previous scope
+			* this = std::move(* prevScope);  // replace with previous scope
 		}
 
@@ -109,9 +109,9 @@
 	}
 
-	void Indexer::lookupId( const std::string &id, std::list< IdData > &out ) const {
-		++*stats().lookup_calls;
+	void Indexer::lookupId( const std::string & id, std::list< IdData > &out ) const {
+		++* stats().lookup_calls;
 		if ( ! idTable ) return;
 
-		++*stats().map_lookups;
+		++* stats().map_lookups;
 		auto decls = idTable->find( id );
 		if ( decls == idTable->end() ) return;
@@ -122,48 +122,48 @@
 	}
 
-	NamedTypeDecl *Indexer::lookupType( const std::string &id ) const {
-		++*stats().lookup_calls;
+	const NamedTypeDecl * Indexer::lookupType( const std::string & id ) const {
+		++* stats().lookup_calls;
 		if ( ! typeTable ) return nullptr;
-		++*stats().map_lookups;
+		++* stats().map_lookups;
 		auto it = typeTable->find( id );
 		return it == typeTable->end() ? nullptr : it->second.decl;
 	}
 
-	StructDecl *Indexer::lookupStruct( const std::string &id ) const {
-		++*stats().lookup_calls;
+	const StructDecl * Indexer::lookupStruct( const std::string & id ) const {
+		++* stats().lookup_calls;
 		if ( ! structTable ) return nullptr;
-		++*stats().map_lookups;
+		++* stats().map_lookups;
 		auto it = structTable->find( id );
 		return it == structTable->end() ? nullptr : it->second.decl;
 	}
 
-	EnumDecl *Indexer::lookupEnum( const std::string &id ) const {
-		++*stats().lookup_calls;
+	const EnumDecl * Indexer::lookupEnum( const std::string & id ) const {
+		++* stats().lookup_calls;
 		if ( ! enumTable ) return nullptr;
-		++*stats().map_lookups;
+		++* stats().map_lookups;
 		auto it = enumTable->find( id );
 		return it == enumTable->end() ? nullptr : it->second.decl;
 	}
 
-	UnionDecl *Indexer::lookupUnion( const std::string &id ) const {
-		++*stats().lookup_calls;
+	const UnionDecl * Indexer::lookupUnion( const std::string & id ) const {
+		++* stats().lookup_calls;
 		if ( ! unionTable ) return nullptr;
-		++*stats().map_lookups;
+		++* stats().map_lookups;
 		auto it = unionTable->find( id );
 		return it == unionTable->end() ? nullptr : it->second.decl;
 	}
 
-	TraitDecl *Indexer::lookupTrait( const std::string &id ) const {
-		++*stats().lookup_calls;
+	const TraitDecl * Indexer::lookupTrait( const std::string & id ) const {
+		++* stats().lookup_calls;
 		if ( ! traitTable ) return nullptr;
-		++*stats().map_lookups;
+		++* stats().map_lookups;
 		auto it = traitTable->find( id );
 		return it == traitTable->end() ? nullptr : it->second.decl;
 	}
 
-	const Indexer* Indexer::atScope( unsigned long target ) const {
+	const Indexer * Indexer::atScope( unsigned long target ) const {
 		// by lazy construction, final indexer in list has repScope 0, cannot be > target
 		// otherwise, will find first scope representing the target
-		const Indexer* indexer = this;
+		const Indexer * indexer = this;
 		while ( indexer->repScope > target ) {
 			indexer = indexer->prevScope.get();
@@ -172,30 +172,30 @@
 	}
 
-	NamedTypeDecl *Indexer::globalLookupType( const std::string &id ) const {
+	const NamedTypeDecl * Indexer::globalLookupType( const std::string & id ) const {
 		return atScope( 0 )->lookupType( id );
 	}
 
-	StructDecl *Indexer::globalLookupStruct( const std::string &id ) const {
+	const StructDecl * Indexer::globalLookupStruct( const std::string & id ) const {
 		return atScope( 0 )->lookupStruct( id );
 	}
 
-	UnionDecl *Indexer::globalLookupUnion( const std::string &id ) const {
+	const UnionDecl * Indexer::globalLookupUnion( const std::string & id ) const {
 		return atScope( 0 )->lookupUnion( id );
 	}
 
-	EnumDecl *Indexer::globalLookupEnum( const std::string &id ) const {
+	const EnumDecl * Indexer::globalLookupEnum( const std::string & id ) const {
 		return atScope( 0 )->lookupEnum( id );
 	}
 
-	bool isFunction( DeclarationWithType * decl ) {
+	bool isFunction( const DeclarationWithType * decl ) {
 		return GenPoly::getFunctionType( decl->get_type() );
 	}
 
-	bool isObject( DeclarationWithType * decl ) {
+	bool isObject( const DeclarationWithType * decl ) {
 		return ! isFunction( decl );
 	}
 
-	bool isDefinition( DeclarationWithType * decl ) {
-		if ( FunctionDecl * func = dynamic_cast< FunctionDecl * >( decl ) ) {
+	bool isDefinition( const DeclarationWithType * decl ) {
+		if ( const FunctionDecl * func = dynamic_cast< const FunctionDecl * >( decl ) ) {
 			// a function is a definition if it has a body
 			return func->statements;
@@ -207,9 +207,9 @@
 	}
 
-	
-	bool Indexer::addedIdConflicts( 
-			const Indexer::IdData & existing, DeclarationWithType *added, 
-			Indexer::OnConflict handleConflicts, BaseSyntaxNode * deleteStmt ) {
-		// if we're giving the same name mangling to things of different types then there is 
+
+	bool Indexer::addedIdConflicts(
+			const Indexer::IdData & existing, const DeclarationWithType * added,
+			Indexer::OnConflict handleConflicts, const Declaration * deleteStmt ) {
+		// if we're giving the same name mangling to things of different types then there is
 		// something wrong
 		assert( (isObject( added ) && isObject( existing.id ) )
@@ -219,6 +219,6 @@
 			// new definition shadows the autogenerated one, even at the same scope
 			return false;
-		} else if ( LinkageSpec::isMangled( added->linkage ) 
-				|| ResolvExpr::typesCompatible( 
+		} else if ( LinkageSpec::isMangled( added->linkage )
+				|| ResolvExpr::typesCompatible(
 					added->get_type(), existing.id->get_type(), Indexer() ) ) {
 
@@ -238,7 +238,7 @@
 			if ( isDefinition( added ) && isDefinition( existing.id ) ) {
 				if ( handleConflicts.mode == OnConflict::Error ) {
-					SemanticError( added, 
-						isFunction( added ) ? 
-							"duplicate function definition for " : 
+					SemanticError( added,
+						isFunction( added ) ?
+							"duplicate function definition for " :
 							"duplicate object definition for " );
 				}
@@ -255,8 +255,8 @@
 	}
 
-	bool Indexer::hasCompatibleCDecl( const std::string &id, const std::string &mangleName ) const {
+	bool Indexer::hasCompatibleCDecl( const std::string & id, const std::string &mangleName ) const {
 		if ( ! idTable ) return false;
 
-		++*stats().map_lookups;
+		++* stats().map_lookups;
 		auto decls = idTable->find( id );
 		if ( decls == idTable->end() ) return false;
@@ -270,13 +270,12 @@
 			}
 		}
-		
+
 		return false;
 	}
 
-	bool Indexer::hasIncompatibleCDecl( 
-			const std::string &id, const std::string &mangleName ) const {
+	bool Indexer::hasIncompatibleCDecl(const std::string & id, const std::string &mangleName ) const {
 		if ( ! idTable ) return false;
 
-		++*stats().map_lookups;
+		++* stats().map_lookups;
 		auto decls = idTable->find( id );
 		if ( decls == idTable->end() ) return false;
@@ -295,34 +294,33 @@
 
 	/// gets the base type of the first parameter; decl must be a ctor/dtor/assignment function
-	std::string getOtypeKey( FunctionDecl* function ) {
+	std::string getOtypeKey( const FunctionDecl * function ) {
 		auto& params = function->type->parameters;
 		assert( ! params.empty() );
 		// use base type of pointer, so that qualifiers on the pointer type aren't considered.
-		Type* base = InitTweak::getPointerBase( params.front()->get_type() );
+		Type * base = InitTweak::getPointerBase( params.front()->get_type() );
 		assert( base );
 		return Mangler::mangle( base );
 	}
 
-	/// gets the declaration for the function acting on a type specified by otype key, 
+	/// gets the declaration for the function acting on a type specified by otype key,
 	/// nullptr if none such
-	FunctionDecl * getFunctionForOtype( DeclarationWithType * decl, const std::string& otypeKey ) {
-		FunctionDecl * func = dynamic_cast< FunctionDecl * >( decl );
+	const FunctionDecl * getFunctionForOtype( const DeclarationWithType * decl, const std::string& otypeKey ) {
+		const FunctionDecl * func = dynamic_cast< const FunctionDecl * >( decl );
 		if ( ! func || otypeKey != getOtypeKey( func ) ) return nullptr;
 		return func;
 	}
 
-	bool Indexer::removeSpecialOverrides( 
-			Indexer::IdData& data, Indexer::MangleTable::Ptr& mangleTable ) {
-		// if a type contains user defined ctor/dtor/assign, then special rules trigger, which 
-		// determinethe set of ctor/dtor/assign that can be used  by the requester. In particular, 
-		// if the user defines a default ctor, then the generated default ctor is unavailable, 
-		// likewise for copy ctor and dtor. If the user defines any ctor/dtor, then no generated 
-		// field ctors are available. If the user defines any ctor then the generated default ctor 
-		// is unavailable (intrinsic default ctor must be overridden exactly). If the user defines 
-		// anything that looks like a copy constructor, then the generated copy constructor is 
+	bool Indexer::removeSpecialOverrides(Indexer::IdData& data, Indexer::MangleTable::Ptr& mangleTable ) {
+		// if a type contains user defined ctor/dtor/assign, then special rules trigger, which
+		// determinethe set of ctor/dtor/assign that can be used  by the requester. In particular,
+		// if the user defines a default ctor, then the generated default ctor is unavailable,
+		// likewise for copy ctor and dtor. If the user defines any ctor/dtor, then no generated
+		// field ctors are available. If the user defines any ctor then the generated default ctor
+		// is unavailable (intrinsic default ctor must be overridden exactly). If the user defines
+		// anything that looks like a copy constructor, then the generated copy constructor is
 		// unavailable, and likewise for the assignment operator.
 
 		// only relevant on function declarations
-		FunctionDecl * function = dynamic_cast< FunctionDecl * >( data.id );
+		const FunctionDecl * function = dynamic_cast< const FunctionDecl * >( data.id );
 		if ( ! function ) return true;
 		// only need to perform this check for constructors, destructors, and assignment functions
@@ -340,8 +338,8 @@
 			std::vector< MangleTable::value_type > deleted;
 			bool alreadyUserDefinedFunc = false;
-			
-			for ( const auto& entry : *mangleTable ) {
+
+			for ( const auto& entry : * mangleTable ) {
 				// skip decls that aren't functions or are for the wrong type
-				FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey );
+				const FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey );
 				if ( ! decl ) continue;
 
@@ -368,9 +366,9 @@
 			// perform removals from mangle table, and deletions if necessary
 			for ( const auto& key : removed ) {
-				++*stats().map_mutations;
+				++* stats().map_mutations;
 				mangleTable = mangleTable->erase( key );
 			}
 			if ( ! alreadyUserDefinedFunc ) for ( const auto& entry : deleted ) {
-				++*stats().map_mutations;
+				++* stats().map_mutations;
 				mangleTable = mangleTable->set( entry.first, IdData{ entry.second, function } );
 			}
@@ -379,8 +377,8 @@
 			// if this is the first user-defined function, delete non-user-defined overloads
 			std::vector< MangleTable::value_type > deleted;
-			
-			for ( const auto& entry : *mangleTable ) {
+
+			for ( const auto& entry : * mangleTable ) {
 				// skip decls that aren't functions or are for the wrong type
-				FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey );
+				const FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey );
 				if ( ! decl ) continue;
 
@@ -402,5 +400,5 @@
 			// this needs to be a separate loop because of iterator invalidation
 			for ( const auto& entry : deleted ) {
-				++*stats().map_mutations;
+				++* stats().map_mutations;
 				mangleTable = mangleTable->set( entry.first, IdData{ entry.second, function } );
 			}
@@ -408,7 +406,7 @@
 			// this is an overridable generated function
 			// if there already exists a matching user-defined function, delete this appropriately
-			for ( const auto& entry : *mangleTable ) {
+			for ( const auto& entry : * mangleTable ) {
 				// skip decls that aren't functions or are for the wrong type
-				FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey );
+				const FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey );
 				if ( ! decl ) continue;
 
@@ -418,5 +416,5 @@
 				if ( dataIsCopyFunc ) {
 					// remove current function if exists a user-defined copy function
-					// since the signatures for copy functions don't need to match exactly, using 
+					// since the signatures for copy functions don't need to match exactly, using
 					// a delete statement is the wrong approach
 					if ( InitTweak::isCopyFunction( decl, decl->name ) ) return false;
@@ -428,19 +426,18 @@
 			}
 		}
-		
+
 		// nothing (more) to fix, return true
 		return true;
 	}
 
-	void Indexer::addId( 
-			DeclarationWithType *decl, OnConflict handleConflicts, Expression * baseExpr, 
-			BaseSyntaxNode * deleteStmt ) {
-		++*stats().add_calls;
+	void Indexer::addId(const DeclarationWithType * decl, OnConflict handleConflicts, const Expression * baseExpr,
+			const Declaration * deleteStmt ) {
+		++* stats().add_calls;
 		const std::string &name = decl->name;
 		if ( name == "" ) return;
-		
+
 		std::string mangleName;
 		if ( LinkageSpec::isOverridable( decl->linkage ) ) {
-			// mangle the name without including the appropriate suffix, so overridable routines 
+			// mangle the name without including the appropriate suffix, so overridable routines
 			// are placed into the same "bucket" as their user defined versions.
 			mangleName = Mangler::mangle( decl, false );
@@ -449,5 +446,5 @@
 		} // if
 
-		// this ensures that no two declarations with the same unmangled name at the same scope 
+		// this ensures that no two declarations with the same unmangled name at the same scope
 		// both have C linkage
 		if ( LinkageSpec::isMangled( decl->linkage ) ) {
@@ -457,5 +454,5 @@
 			}
 		} else {
-			// NOTE: only correct if name mangling is completely isomorphic to C 
+			// NOTE: only correct if name mangling is completely isomorphic to C
 			// type-compatibility, which it may not be.
 			if ( hasIncompatibleCDecl( name, mangleName ) ) {
@@ -470,5 +467,5 @@
 			mangleTable = MangleTable::new_ptr();
 		} else {
-			++*stats().map_lookups;
+			++* stats().map_lookups;
 			auto decls = idTable->find( name );
 			if ( decls == idTable->end() ) {
@@ -477,5 +474,5 @@
 				mangleTable = decls->second;
 				// skip in-scope repeat declarations of same identifier
-				++*stats().map_lookups;
+				++* stats().map_lookups;
 				auto existing = mangleTable->find( mangleName );
 				if ( existing != mangleTable->end()
@@ -486,9 +483,9 @@
 							// set delete expression for conflicting identifier
 							lazyInitScope();
-							*stats().map_mutations += 2;
+							* stats().map_mutations += 2;
 							idTable = idTable->set(
 								name,
-								mangleTable->set( 
-									mangleName, 
+								mangleTable->set(
+									mangleName,
 									IdData{ existing->second, handleConflicts.deleteStmt } ) );
 						}
@@ -504,19 +501,19 @@
 		// Ensure that auto-generated ctor/dtor/assignment are deleted if necessary
 		if ( ! removeSpecialOverrides( data, mangleTable ) ) return;
-		*stats().map_mutations += 2;
+		* stats().map_mutations += 2;
 		idTable = idTable->set( name, mangleTable->set( mangleName, std::move(data) ) );
 	}
 
-	void Indexer::addId( DeclarationWithType * decl, Expression * baseExpr ) {
+	void Indexer::addId( const DeclarationWithType * decl, const Expression * baseExpr ) {
 		// default handling of conflicts is to raise an error
 		addId( decl, OnConflict::error(), baseExpr, decl->isDeleted ? decl : nullptr );
 	}
 
-	void Indexer::addDeletedId( DeclarationWithType * decl, BaseSyntaxNode * deleteStmt ) {
+	void Indexer::addDeletedId( const DeclarationWithType * decl, const Declaration * deleteStmt ) {
 		// default handling of conflicts is to raise an error
 		addId( decl, OnConflict::error(), nullptr, deleteStmt );
 	}
 
-	bool addedTypeConflicts( NamedTypeDecl *existing, NamedTypeDecl *added ) {
+	bool addedTypeConflicts( const NamedTypeDecl * existing, const NamedTypeDecl * added ) {
 		if ( existing->base == nullptr ) {
 			return false;
@@ -530,29 +527,29 @@
 			}
 		}
-		// does not need to be added to the table if both existing and added have a base that are 
+		// does not need to be added to the table if both existing and added have a base that are
 		// the same
 		return true;
 	}
 
-	void Indexer::addType( NamedTypeDecl *decl ) {
-		++*stats().add_calls;
-		const std::string &id = decl->name;
-
-		if ( ! typeTable ) { 
+	void Indexer::addType( const NamedTypeDecl * decl ) {
+		++* stats().add_calls;
+		const std::string & id = decl->name;
+
+		if ( ! typeTable ) {
 			typeTable = TypeTable::new_ptr();
 		} else {
-			++*stats().map_lookups;
+			++* stats().map_lookups;
 			auto existing = typeTable->find( id );
-			if ( existing != typeTable->end() 
-				&& existing->second.scope == scope 
+			if ( existing != typeTable->end()
+				&& existing->second.scope == scope
 				&& addedTypeConflicts( existing->second.decl, decl ) ) return;
 		}
-		
+
 		lazyInitScope();
-		++*stats().map_mutations;
+		++* stats().map_mutations;
 		typeTable = typeTable->set( id, Scoped<NamedTypeDecl>{ decl, scope } );
 	}
 
-	bool addedDeclConflicts( AggregateDecl *existing, AggregateDecl *added ) {
+	bool addedDeclConflicts( const AggregateDecl * existing, const AggregateDecl * added ) {
 		if ( ! existing->body ) {
 			return false;
@@ -563,96 +560,95 @@
 	}
 
-	void Indexer::addStruct( const std::string &id ) {
+	void Indexer::addStruct( const std::string & id ) {
 		addStruct( new StructDecl( id ) );
 	}
 
-	void Indexer::addStruct( StructDecl *decl ) {
-		++*stats().add_calls;
-		const std::string &id = decl->name;
+	void Indexer::addStruct( const StructDecl * decl ) {
+		++* stats().add_calls;
+		const std::string & id = decl->name;
 
 		if ( ! structTable ) {
 			structTable = StructTable::new_ptr();
 		} else {
-			++*stats().map_lookups;
+			++* stats().map_lookups;
 			auto existing = structTable->find( id );
-			if ( existing != structTable->end()  
-				&& existing->second.scope == scope 
+			if ( existing != structTable->end()
+				&& existing->second.scope == scope
 				&& addedDeclConflicts( existing->second.decl, decl ) ) return;
 		}
 
 		lazyInitScope();
-		++*stats().map_mutations;
+		++* stats().map_mutations;
 		structTable = structTable->set( id, Scoped<StructDecl>{ decl, scope } );
 	}
 
-	void Indexer::addEnum( EnumDecl *decl ) {
-		++*stats().add_calls;
-		const std::string &id = decl->name;
+	void Indexer::addEnum( const EnumDecl * decl ) {
+		++* stats().add_calls;
+		const std::string & id = decl->name;
 
 		if ( ! enumTable ) {
 			enumTable = EnumTable::new_ptr();
 		} else {
-			++*stats().map_lookups;
+			++* stats().map_lookups;
 			auto existing = enumTable->find( id );
-			if ( existing != enumTable->end()  
-				&& existing->second.scope == scope 
+			if ( existing != enumTable->end()
+				&& existing->second.scope == scope
 				&& addedDeclConflicts( existing->second.decl, decl ) ) return;
 		}
-		
+
 		lazyInitScope();
-		++*stats().map_mutations;
+		++* stats().map_mutations;
 		enumTable = enumTable->set( id, Scoped<EnumDecl>{ decl, scope } );
 	}
 
-	void Indexer::addUnion( const std::string &id ) {
+	void Indexer::addUnion( const std::string & id ) {
 		addUnion( new UnionDecl( id ) );
 	}
 
-	void Indexer::addUnion( UnionDecl *decl ) {
-		++*stats().add_calls;
-		const std::string &id = decl->name;
+	void Indexer::addUnion( const UnionDecl * decl ) {
+		++* stats().add_calls;
+		const std::string & id = decl->name;
 
 		if ( ! unionTable ) {
 			unionTable = UnionTable::new_ptr();
 		} else {
-			++*stats().map_lookups;
+			++* stats().map_lookups;
 			auto existing = unionTable->find( id );
-			if ( existing != unionTable->end() 
-				&& existing->second.scope == scope 
+			if ( existing != unionTable->end()
+				&& existing->second.scope == scope
 				&& addedDeclConflicts( existing->second.decl, decl ) ) return;
 		}
 
 		lazyInitScope();
-		++*stats().map_mutations;
+		++* stats().map_mutations;
 		unionTable = unionTable->set( id, Scoped<UnionDecl>{ decl, scope } );
 	}
 
-	void Indexer::addTrait( TraitDecl *decl ) {
-		++*stats().add_calls;
-		const std::string &id = decl->name;
+	void Indexer::addTrait( const TraitDecl * decl ) {
+		++* stats().add_calls;
+		const std::string & id = decl->name;
 
 		if ( ! traitTable ) {
 			traitTable = TraitTable::new_ptr();
 		} else {
-			++*stats().map_lookups;
+			++* stats().map_lookups;
 			auto existing = traitTable->find( id );
-			if ( existing != traitTable->end() 
-				&& existing->second.scope == scope 
+			if ( existing != traitTable->end()
+				&& existing->second.scope == scope
 				&& addedDeclConflicts( existing->second.decl, decl ) ) return;
 		}
 
 		lazyInitScope();
-		++*stats().map_mutations;
+		++* stats().map_mutations;
 		traitTable = traitTable->set( id, Scoped<TraitDecl>{ decl, scope } );
 	}
 
-	void Indexer::addMembers( AggregateDecl * aggr, Expression * expr, 
-			OnConflict handleConflicts ) {
+	void Indexer::addMembers( const AggregateDecl * aggr, const Expression * expr, OnConflict handleConflicts ) {
 		for ( Declaration * decl : aggr->members ) {
 			if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) {
 				addId( dwt, handleConflicts, expr );
 				if ( dwt->name == "" ) {
-					Type * t = dwt->get_type()->stripReferences();
-					if ( dynamic_cast<StructInstType*>( t ) || dynamic_cast<UnionInstType*>( t ) ) {
+					const Type * t = dwt->get_type()->stripReferences();
+					if ( dynamic_cast<const StructInstType *>( t ) || dynamic_cast<const UnionInstType *>( t ) ) {
 						Expression * base = expr->clone();
 						ResolvExpr::Cost cost = ResolvExpr::Cost::zero; // xxx - carry this cost into the indexer as a base cost?
@@ -665,6 +661,6 @@
 	}
 
-	void Indexer::addWith( std::list< Expression * > & withExprs, BaseSyntaxNode * withStmt ) {
-		for ( Expression * expr : withExprs ) {
+	void Indexer::addWith( const std::list< Expression * > & withExprs, const Declaration * withStmt ) {
+		for ( const Expression * expr : withExprs ) {
 			if ( expr->result ) {
 				AggregateDecl * aggr = expr->result->stripReferences()->getAggr();
@@ -689,5 +685,5 @@
 	}
 
-	void Indexer::addFunctionType( FunctionType * ftype ) {
+	void Indexer::addFunctionType( const FunctionType * ftype ) {
 		addTypes( ftype->forall );
 		addIds( ftype->returnVals );
@@ -700,5 +696,5 @@
 			Expression * base = baseExpr->clone();
 			ResolvExpr::referenceToRvalueConversion( base, cost );
-			ret = new MemberExpr( id, base );
+			ret = new MemberExpr( const_cast<DeclarationWithType *>(id), base );
 			// xxx - this introduces hidden environments, for now remove them.
 			// std::swap( base->env, ret->env );
@@ -706,7 +702,7 @@
 			base->env = nullptr;
 		} else {
-			ret = new VariableExpr( id );
-		}
-		if ( deleteStmt ) ret = new DeletedExpr( ret, deleteStmt );
+			ret = new VariableExpr( const_cast<DeclarationWithType *>(id) );
+		}
+		if ( deleteStmt ) ret = new DeletedExpr( ret, const_cast<Declaration *>(deleteStmt) );
 		return ret;
 	}
Index: src/SymTab/Indexer.h
===================================================================
--- src/SymTab/Indexer.h	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/SymTab/Indexer.h	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -34,5 +34,5 @@
 		virtual ~Indexer();
 
-		// when using an indexer manually (e.g., within a mutator traversal), it is necessary to 
+		// when using an indexer manually (e.g., within a mutator traversal), it is necessary to
 		// tell the indexer explicitly when scopes begin and end
 		void enterScope();
@@ -40,9 +40,9 @@
 
 		struct IdData {
-			DeclarationWithType * id = nullptr;
-			Expression * baseExpr = nullptr; // WithExpr
+			const DeclarationWithType * id = nullptr;
+			const Expression * baseExpr = nullptr; // WithExpr
 
 			/// non-null if this declaration is deleted
-			BaseSyntaxNode * deleteStmt = nullptr;
+			const Declaration * deleteStmt = nullptr;
 			/// scope of identifier
 			unsigned long scope = 0;
@@ -50,9 +50,9 @@
 			// NOTE: shouldn't need either of these constructors, but gcc-4 does not properly support initializer lists with default members.
 			IdData() = default;
-			IdData( 
-				DeclarationWithType * id, Expression * baseExpr, BaseSyntaxNode * deleteStmt,
-				unsigned long scope ) 
+			IdData(
+				const DeclarationWithType * id, const Expression * baseExpr, const Declaration * deleteStmt,
+				unsigned long scope )
 				: id( id ), baseExpr( baseExpr ), deleteStmt( deleteStmt ), scope( scope ) {}
-			IdData( const IdData& o, BaseSyntaxNode * deleteStmt )
+			IdData( const IdData& o, const Declaration * deleteStmt )
 				: id( o.id ), baseExpr( o.baseExpr ), deleteStmt( deleteStmt ), scope( o.scope ) {}
 
@@ -61,38 +61,38 @@
 
 		/// Gets all declarations with the given ID
-		void lookupId( const std::string &id, std::list< IdData > &out ) const;
+		void lookupId( const std::string & id, std::list< IdData > &out ) const;
 		/// Gets the top-most type declaration with the given ID
-		NamedTypeDecl *lookupType( const std::string &id ) const;
+		const NamedTypeDecl * lookupType( const std::string & id ) const;
 		/// Gets the top-most struct declaration with the given ID
-		StructDecl *lookupStruct( const std::string &id ) const;
+		const StructDecl * lookupStruct( const std::string & id ) const;
 		/// Gets the top-most enum declaration with the given ID
-		EnumDecl *lookupEnum( const std::string &id ) const;
+		const EnumDecl * lookupEnum( const std::string & id ) const;
 		/// Gets the top-most union declaration with the given ID
-		UnionDecl *lookupUnion( const std::string &id ) const;
+		const UnionDecl * lookupUnion( const std::string & id ) const;
 		/// Gets the top-most trait declaration with the given ID
-		TraitDecl *lookupTrait( const std::string &id ) const;
+		const TraitDecl * lookupTrait( const std::string & id ) const;
 
 		/// Gets the type declaration with the given ID at global scope
-		NamedTypeDecl *globalLookupType( const std::string &id ) const;
+		const NamedTypeDecl * globalLookupType( const std::string & id ) const;
 		/// Gets the struct declaration with the given ID at global scope
-		StructDecl *globalLookupStruct( const std::string &id ) const;
+		const StructDecl * globalLookupStruct( const std::string & id ) const;
 		/// Gets the union declaration with the given ID at global scope
-		UnionDecl *globalLookupUnion( const std::string &id ) const;
+		const UnionDecl * globalLookupUnion( const std::string & id ) const;
 		/// Gets the enum declaration with the given ID at global scope
-		EnumDecl *globalLookupEnum( const std::string &id ) const;
+		const EnumDecl * globalLookupEnum( const std::string & id ) const;
 
-		void addId( DeclarationWithType * decl, Expression * baseExpr = nullptr );
-		void addDeletedId( DeclarationWithType * decl, BaseSyntaxNode * deleteStmt );
+		void addId( const DeclarationWithType * decl, const Expression * baseExpr = nullptr );
+		void addDeletedId( const DeclarationWithType * decl, const Declaration * deleteStmt );
 
-		void addType( NamedTypeDecl *decl );
-		void addStruct( const std::string &id );
-		void addStruct( StructDecl *decl );
-		void addEnum( EnumDecl *decl );
-		void addUnion( const std::string &id );
-		void addUnion( UnionDecl *decl );
-		void addTrait( TraitDecl *decl );
+		void addType( const NamedTypeDecl * decl );
+		void addStruct( const std::string & id );
+		void addStruct( const StructDecl * decl );
+		void addEnum( const EnumDecl * decl );
+		void addUnion( const std::string & id );
+		void addUnion( const UnionDecl * decl );
+		void addTrait( const TraitDecl * decl );
 
 		/// adds all of the IDs from WithStmt exprs
-		void addWith( std::list< Expression * > & withExprs, BaseSyntaxNode * withStmt );
+		void addWith( const std::list< Expression * > & withExprs, const Declaration * withStmt );
 
 		/// convenience function for adding a list of Ids to the indexer
@@ -103,14 +103,14 @@
 
 		/// convenience function for adding all of the declarations in a function type to the indexer
-		void addFunctionType( FunctionType * ftype );
+		void addFunctionType( const FunctionType * ftype );
 
 	  private:
-	  	/// Wraps a Decl* with a scope
+	  	/// Wraps a Decl * with a scope
 	  	template<typename Decl>
 		struct Scoped {
-			Decl* decl;           ///< declaration
+			const Decl * decl;           ///< declaration
 			unsigned long scope;  ///< scope of this declaration
 
-			Scoped(Decl* d, unsigned long s) : decl(d), scope(s) {}
+			Scoped(const Decl * d, unsigned long s) : decl(d), scope(s) {}
 		};
 
@@ -140,9 +140,9 @@
 
 		/// Gets the indexer at the given scope
-		const Indexer* atScope( unsigned long scope ) const;
+		const Indexer * atScope( unsigned long scope ) const;
 
-		/// Removes matching autogenerated constructors and destructors so that they will not be 
+		/// Removes matching autogenerated constructors and destructors so that they will not be
 		/// selected. If returns false, passed decl should not be added.
-		bool removeSpecialOverrides( IdData& decl, MangleTable::Ptr& mangleTable );
+		bool removeSpecialOverrides( IdData & decl, MangleTable::Ptr & mangleTable );
 
 		/// Options for handling identifier conflicts
@@ -152,33 +152,32 @@
 				Delete  ///< Delete the earlier version with the delete statement
 			} mode;
-			BaseSyntaxNode * deleteStmt;  ///< Statement that deletes this expression
+			const Declaration * deleteStmt;  ///< Statement that deletes this expression
 
 		private:
 			OnConflict() : mode(Error), deleteStmt(nullptr) {}
-			OnConflict( BaseSyntaxNode * d ) : mode(Delete), deleteStmt(d) {}
+			OnConflict( const Declaration * d ) : mode(Delete), deleteStmt(d) {}
 		public:
 			OnConflict( const OnConflict& ) = default;
 
 			static OnConflict error() { return {}; }
-			static OnConflict deleteWith( BaseSyntaxNode * d ) { return { d }; }
+			static OnConflict deleteWith( const Declaration * d ) { return { d }; }
 		};
 
 		/// true if the existing identifier conflicts with the added identifier
 		bool addedIdConflicts(
-			const IdData& existing, DeclarationWithType * added, OnConflict handleConflicts, 
-			BaseSyntaxNode * deleteStmt );
+			const IdData & existing, const DeclarationWithType * added, OnConflict handleConflicts,
+			const Declaration * deleteStmt );
 
 		/// common code for addId, addDeletedId, etc.
-		void addId( 
-			DeclarationWithType * decl, OnConflict handleConflicts, 
-			Expression * baseExpr = nullptr, BaseSyntaxNode * deleteStmt = nullptr );
+		void addId(const DeclarationWithType * decl, OnConflict handleConflicts,
+			const Expression * baseExpr = nullptr, const Declaration * deleteStmt = nullptr );
 
 		/// adds all of the members of the Aggregate (addWith helper)
-		void addMembers( AggregateDecl * aggr, Expression * expr, OnConflict handleConflicts );
+		void addMembers( const AggregateDecl * aggr, const Expression * expr, OnConflict handleConflicts );
 
 		/// returns true if there exists a declaration with C linkage and the given name with the same mangled name
-		bool hasCompatibleCDecl( const std::string &id, const std::string &mangleName ) const;
+		bool hasCompatibleCDecl( const std::string & id, const std::string & mangleName ) const;
 		/// returns true if there exists a declaration with C linkage and the given name with a different mangled name
-		bool hasIncompatibleCDecl( const std::string &id, const std::string &mangleName ) const;
+		bool hasIncompatibleCDecl( const std::string & id, const std::string & mangleName ) const;
 	};
 } // namespace SymTab
Index: src/SymTab/Mangler.cc
===================================================================
--- src/SymTab/Mangler.cc	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/SymTab/Mangler.cc	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -42,26 +42,26 @@
 				Mangler_old( const Mangler_old & ) = delete;
 
-				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( TraitInstType * inst );
-				void postvisit( TupleType * tupleType );
-				void postvisit( VarArgsType * varArgsType );
-				void postvisit( ZeroType * zeroType );
-				void postvisit( OneType * oneType );
-				void postvisit( QualifiedType * qualType );
+				void previsit( const BaseSyntaxNode * ) { visit_children = false; }
+
+				void postvisit( const ObjectDecl * declaration );
+				void postvisit( const FunctionDecl * declaration );
+				void postvisit( const TypeDecl * declaration );
+
+				void postvisit( const VoidType * voidType );
+				void postvisit( const BasicType * basicType );
+				void postvisit( const PointerType * pointerType );
+				void postvisit( const ArrayType * arrayType );
+				void postvisit( const ReferenceType * refType );
+				void postvisit( const FunctionType * functionType );
+				void postvisit( const StructInstType * aggregateUseType );
+				void postvisit( const UnionInstType * aggregateUseType );
+				void postvisit( const EnumInstType * aggregateUseType );
+				void postvisit( const TypeInstType * aggregateUseType );
+				void postvisit( const TraitInstType * inst );
+				void postvisit( const TupleType * tupleType );
+				void postvisit( const VarArgsType * varArgsType );
+				void postvisit( const ZeroType * zeroType );
+				void postvisit( const OneType * oneType );
+				void postvisit( const QualifiedType * qualType );
 
 				std::string get_mangleName() { return mangleName.str(); }
@@ -79,16 +79,16 @@
 
 			  public:
-				Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams, 
+				Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams,
 					int nextVarNum, const VarMapType& varNums );
 
 			  private:
-				void mangleDecl( DeclarationWithType *declaration );
-				void mangleRef( ReferenceToType *refType, std::string prefix );
-
-				void printQualifiers( Type *type );
+				void mangleDecl( const DeclarationWithType * declaration );
+				void mangleRef( const ReferenceToType * refType, std::string prefix );
+
+				void printQualifiers( const Type *type );
 			}; // Mangler_old
 		} // namespace
 
-		std::string mangle( BaseSyntaxNode * decl, bool mangleOverridable, bool typeMode, bool mangleGenericParams ) {
+		std::string mangle( const BaseSyntaxNode * decl, bool mangleOverridable, bool typeMode, bool mangleGenericParams ) {
 			PassVisitor<Mangler_old> mangler( mangleOverridable, typeMode, mangleGenericParams );
 			maybeAccept( decl, mangler );
@@ -96,5 +96,5 @@
 		}
 
-		std::string mangleType( Type * ty ) {
+		std::string mangleType( const Type * ty ) {
 			PassVisitor<Mangler_old> mangler( false, true, true );
 			maybeAccept( ty, mangler );
@@ -102,5 +102,5 @@
 		}
 
-		std::string mangleConcrete( Type * ty ) {
+		std::string mangleConcrete( const Type * ty ) {
 			PassVisitor<Mangler_old> mangler( false, false, false );
 			maybeAccept( ty, mangler );
@@ -110,15 +110,15 @@
 		namespace {
 			Mangler_old::Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams )
-				: nextVarNum( 0 ), isTopLevel( true ), 
-				mangleOverridable( mangleOverridable ), typeMode( typeMode ), 
+				: nextVarNum( 0 ), isTopLevel( true ),
+				mangleOverridable( mangleOverridable ), typeMode( typeMode ),
 				mangleGenericParams( mangleGenericParams ) {}
-			
-			Mangler_old::Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams, 
+
+			Mangler_old::Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams,
 				int nextVarNum, const VarMapType& varNums )
-				: varNums( varNums ), nextVarNum( nextVarNum ), isTopLevel( false ), 
-				mangleOverridable( mangleOverridable ), typeMode( typeMode ), 
+				: varNums( varNums ), nextVarNum( nextVarNum ), isTopLevel( false ),
+				mangleOverridable( mangleOverridable ), typeMode( typeMode ),
 				mangleGenericParams( mangleGenericParams ) {}
 
-			void Mangler_old::mangleDecl( DeclarationWithType * declaration ) {
+			void Mangler_old::mangleDecl( const DeclarationWithType * declaration ) {
 				bool wasTopLevel = isTopLevel;
 				if ( isTopLevel ) {
@@ -150,24 +150,24 @@
 			}
 
-			void Mangler_old::postvisit( ObjectDecl * declaration ) {
+			void Mangler_old::postvisit( const ObjectDecl * declaration ) {
 				mangleDecl( declaration );
 			}
 
-			void Mangler_old::postvisit( FunctionDecl * declaration ) {
+			void Mangler_old::postvisit( const FunctionDecl * declaration ) {
 				mangleDecl( declaration );
 			}
 
-			void Mangler_old::postvisit( VoidType * voidType ) {
+			void Mangler_old::postvisit( const VoidType * voidType ) {
 				printQualifiers( voidType );
 				mangleName << Encoding::void_t;
 			}
 
-			void Mangler_old::postvisit( BasicType * basicType ) {
+			void Mangler_old::postvisit( const BasicType * basicType ) {
 				printQualifiers( basicType );
-				assertf( basicType->get_kind() < BasicType::NUMBER_OF_BASIC_TYPES, "Unhandled basic type: %d", basicType->get_kind() );
-				mangleName << Encoding::basicTypes[ basicType->get_kind() ];
-			}
-
-			void Mangler_old::postvisit( PointerType * pointerType ) {
+				assertf( basicType->kind < BasicType::NUMBER_OF_BASIC_TYPES, "Unhandled basic type: %d", basicType->kind );
+				mangleName << Encoding::basicTypes[ basicType->kind ];
+			}
+
+			void Mangler_old::postvisit( const PointerType * pointerType ) {
 				printQualifiers( pointerType );
 				// mangle void (*f)() and void f() to the same name to prevent overloading on functions and function pointers
@@ -176,5 +176,5 @@
 			}
 
-			void Mangler_old::postvisit( ArrayType * arrayType ) {
+			void Mangler_old::postvisit( const ArrayType * arrayType ) {
 				// TODO: encode dimension
 				printQualifiers( arrayType );
@@ -183,5 +183,5 @@
 			}
 
-			void Mangler_old::postvisit( ReferenceType * refType ) {
+			void Mangler_old::postvisit( const 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.),
@@ -202,5 +202,5 @@
 			}
 
-			void Mangler_old::postvisit( FunctionType * functionType ) {
+			void Mangler_old::postvisit( const FunctionType * functionType ) {
 				printQualifiers( functionType );
 				mangleName << Encoding::function;
@@ -219,5 +219,5 @@
 			}
 
-			void Mangler_old::mangleRef( ReferenceToType * refType, std::string prefix ) {
+			void Mangler_old::mangleRef( const ReferenceToType * refType, std::string prefix ) {
 				printQualifiers( refType );
 
@@ -225,10 +225,10 @@
 
 				if ( mangleGenericParams ) {
-					std::list< Expression* >& params = refType->parameters;
+					const std::list< Expression* > & params = refType->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", toCString(*param));
+						for ( const Expression * param : params ) {
+							const TypeExpr * paramType = dynamic_cast< const TypeExpr * >( param );
+							assertf(paramType, "Aggregate parameters should be type expressions: %s", toCString(param));
 							maybeAccept( paramType->type, *visitor );
 						}
@@ -238,17 +238,17 @@
 			}
 
-			void Mangler_old::postvisit( StructInstType * aggregateUseType ) {
+			void Mangler_old::postvisit( const StructInstType * aggregateUseType ) {
 				mangleRef( aggregateUseType, Encoding::struct_t );
 			}
 
-			void Mangler_old::postvisit( UnionInstType * aggregateUseType ) {
+			void Mangler_old::postvisit( const UnionInstType * aggregateUseType ) {
 				mangleRef( aggregateUseType, Encoding::union_t );
 			}
 
-			void Mangler_old::postvisit( EnumInstType * aggregateUseType ) {
+			void Mangler_old::postvisit( const EnumInstType * aggregateUseType ) {
 				mangleRef( aggregateUseType, Encoding::enum_t );
 			}
 
-			void Mangler_old::postvisit( TypeInstType * typeInst ) {
+			void Mangler_old::postvisit( const TypeInstType * typeInst ) {
 				VarMapType::iterator varNum = varNums.find( typeInst->get_name() );
 				if ( varNum == varNums.end() ) {
@@ -266,10 +266,10 @@
 			}
 
-			void Mangler_old::postvisit( TraitInstType * inst ) {
+			void Mangler_old::postvisit( const TraitInstType * inst ) {
 				printQualifiers( inst );
 				mangleName << inst->name.size() << inst->name;
 			}
 
-			void Mangler_old::postvisit( TupleType * tupleType ) {
+			void Mangler_old::postvisit( const TupleType * tupleType ) {
 				printQualifiers( tupleType );
 				mangleName << Encoding::tuple << tupleType->types.size();
@@ -277,5 +277,5 @@
 			}
 
-			void Mangler_old::postvisit( VarArgsType * varArgsType ) {
+			void Mangler_old::postvisit( const VarArgsType * varArgsType ) {
 				printQualifiers( varArgsType );
 				static const std::string vargs = "__builtin_va_list";
@@ -283,13 +283,13 @@
 			}
 
-			void Mangler_old::postvisit( ZeroType * ) {
+			void Mangler_old::postvisit( const ZeroType * ) {
 				mangleName << Encoding::zero;
 			}
 
-			void Mangler_old::postvisit( OneType * ) {
+			void Mangler_old::postvisit( const OneType * ) {
 				mangleName << Encoding::one;
 			}
 
-			void Mangler_old::postvisit( QualifiedType * qualType ) {
+			void Mangler_old::postvisit( const QualifiedType * qualType ) {
 				bool inqual = inQualifiedType;
 				if (! inqual ) {
@@ -307,5 +307,5 @@
 			}
 
-			void Mangler_old::postvisit( TypeDecl * decl ) {
+			void Mangler_old::postvisit( const 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.
@@ -314,6 +314,6 @@
 				// aside from the assert false.
 				assertf(false, "Mangler_old should not visit typedecl: %s", toCString(decl));
-				assertf( decl->get_kind() < TypeDecl::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", decl->get_kind() );
-				mangleName << Encoding::typeVariables[ decl->get_kind() ] << ( decl->name.length() ) << decl->name;
+				assertf( decl->kind < TypeDecl::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", decl->kind );
+				mangleName << Encoding::typeVariables[ decl->kind ] << ( decl->name.length() ) << decl->name;
 			}
 
@@ -324,13 +324,13 @@
 			}
 
-			void Mangler_old::printQualifiers( Type * type ) {
+			void Mangler_old::printQualifiers( const Type * type ) {
 				// skip if not including qualifiers
 				if ( typeMode ) return;
-				if ( ! type->get_forall().empty() ) {
+				if ( ! type->forall.empty() ) {
 					std::list< std::string > assertionNames;
 					int dcount = 0, fcount = 0, vcount = 0, acount = 0;
 					mangleName << Encoding::forall;
-					for ( Type::ForallList::iterator i = type->forall.begin(); i != type->forall.end(); ++i ) {
-						switch ( (*i)->get_kind() ) {
+					for ( const TypeDecl * i : type->forall ) {
+						switch ( i->kind ) {
 						  case TypeDecl::Dtype:
 							dcount++;
@@ -345,9 +345,9 @@
 							assert( false );
 						} // switch
-						varNums[ (*i)->name ] = std::make_pair( nextVarNum, (int)(*i)->get_kind() );
-						for ( std::list< DeclarationWithType* >::iterator assert = (*i)->assertions.begin(); assert != (*i)->assertions.end(); ++assert ) {
-							PassVisitor<Mangler_old> sub_mangler( 
+						varNums[ i->name ] = std::make_pair( nextVarNum, (int)i->kind );
+						for ( const DeclarationWithType * assert : i->assertions ) {
+							PassVisitor<Mangler_old> sub_mangler(
 								mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums );
-							(*assert)->accept( sub_mangler );
+							assert->accept( sub_mangler );
 							assertionNames.push_back( sub_mangler.pass.get_mangleName() );
 							acount++;
@@ -436,5 +436,5 @@
 
 		  private:
-			Mangler_new( bool mangleOverridable, bool typeMode, bool mangleGenericParams,  
+			Mangler_new( bool mangleOverridable, bool typeMode, bool mangleGenericParams,
 				int nextVarNum, const VarMapType& varNums );
 			friend class ast::Pass<Mangler_new>;
@@ -457,13 +457,13 @@
 	namespace {
 		Mangler_new::Mangler_new( Mangle::Mode mode )
-			: nextVarNum( 0 ), isTopLevel( true ), 
+			: nextVarNum( 0 ), isTopLevel( true ),
 			mangleOverridable  ( ! mode.no_overrideable   ),
-			typeMode           (   mode.type              ), 
+			typeMode           (   mode.type              ),
 			mangleGenericParams( ! mode.no_generic_params ) {}
-		
-		Mangler_new::Mangler_new( bool mangleOverridable, bool typeMode, bool mangleGenericParams, 
+
+		Mangler_new::Mangler_new( bool mangleOverridable, bool typeMode, bool mangleGenericParams,
 			int nextVarNum, const VarMapType& varNums )
-			: varNums( varNums ), nextVarNum( nextVarNum ), isTopLevel( false ), 
-			mangleOverridable( mangleOverridable ), typeMode( typeMode ), 
+			: varNums( varNums ), nextVarNum( nextVarNum ), isTopLevel( false ),
+			mangleOverridable( mangleOverridable ), typeMode( typeMode ),
 			mangleGenericParams( mangleGenericParams ) {}
 
@@ -693,5 +693,5 @@
 						varNums[ decl->name ] = std::make_pair( nextVarNum, (int)decl->kind );
 						for ( const ast::DeclWithType * assert : decl->assertions ) {
-							ast::Pass<Mangler_new> sub_mangler( 
+							ast::Pass<Mangler_new> sub_mangler(
 								mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums );
 							assert->accept( sub_mangler );
Index: src/SymTab/Mangler.h
===================================================================
--- src/SymTab/Mangler.h	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/SymTab/Mangler.h	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -40,10 +40,10 @@
 	namespace Mangler {
 		/// Mangle syntax tree object; primary interface to clients
-		std::string mangle( BaseSyntaxNode * decl, bool mangleOverridable = true, bool typeMode = false, bool mangleGenericParams = true );
+		std::string mangle( const BaseSyntaxNode * decl, bool mangleOverridable = true, bool typeMode = false, bool mangleGenericParams = true );
 
 		/// Mangle a type name; secondary interface
-		std::string mangleType( Type* ty );
+		std::string mangleType( const Type * ty );
 		/// Mangle ignoring generic type parameters
-		std::string mangleConcrete( Type* ty );
+		std::string mangleConcrete( const Type * ty );
 
 		namespace Encoding {
Index: src/SymTab/Validate.cc
===================================================================
--- src/SymTab/Validate.cc	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/SymTab/Validate.cc	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -119,5 +119,5 @@
 
 	  private:
-		template< typename AggDecl > void handleAggregate( AggDecl *aggregateDecl );
+		template< typename AggDecl > void handleAggregate( AggDecl * aggregateDecl );
 
 		AggregateDecl * parentAggr = nullptr;
@@ -134,32 +134,32 @@
 	/// Replaces enum types by int, and function or array types in function parameter and return lists by appropriate pointers.
 	struct EnumAndPointerDecay_old {
-		void previsit( EnumDecl *aggregateDecl );
-		void previsit( FunctionType *func );
+		void previsit( EnumDecl * aggregateDecl );
+		void previsit( FunctionType * func );
 	};
 
 	/// Associates forward declarations of aggregates with their definitions
 	struct LinkReferenceToTypes_old final : public WithIndexer, public WithGuards, public WithVisitorRef<LinkReferenceToTypes_old>, public WithShortCircuiting {
-		LinkReferenceToTypes_old( const Indexer *indexer );
-		void postvisit( TypeInstType *typeInst );
-
-		void postvisit( EnumInstType *enumInst );
-		void postvisit( StructInstType *structInst );
-		void postvisit( UnionInstType *unionInst );
-		void postvisit( TraitInstType *traitInst );
+		LinkReferenceToTypes_old( const Indexer * indexer );
+		void postvisit( TypeInstType * typeInst );
+
+		void postvisit( EnumInstType * enumInst );
+		void postvisit( StructInstType * structInst );
+		void postvisit( UnionInstType * unionInst );
+		void postvisit( TraitInstType * traitInst );
 		void previsit( QualifiedType * qualType );
 		void postvisit( QualifiedType * qualType );
 
-		void postvisit( EnumDecl *enumDecl );
-		void postvisit( StructDecl *structDecl );
-		void postvisit( UnionDecl *unionDecl );
+		void postvisit( EnumDecl * enumDecl );
+		void postvisit( StructDecl * structDecl );
+		void postvisit( UnionDecl * unionDecl );
 		void postvisit( TraitDecl * traitDecl );
 
-		void previsit( StructDecl *structDecl );
-		void previsit( UnionDecl *unionDecl );
+		void previsit( StructDecl * structDecl );
+		void previsit( UnionDecl * unionDecl );
 
 		void renameGenericParams( std::list< TypeDecl * > & params );
 
 	  private:
-		const Indexer *local_indexer;
+		const Indexer * local_indexer;
 
 		typedef std::map< std::string, std::list< EnumInstType * > > ForwardEnumsType;
@@ -239,5 +239,5 @@
 
 		template<typename AggDecl>
-		void handleAggregate( AggDecl *aggregateDecl );
+		void handleAggregate( AggDecl * aggregateDecl );
 
 		void previsit( StructDecl * aggregateDecl );
@@ -252,5 +252,5 @@
 		static void verify( std::list< Declaration * > &translationUnit );
 
-		void previsit( FunctionDecl *funcDecl );
+		void previsit( FunctionDecl * funcDecl );
 	};
 
@@ -287,6 +287,6 @@
 		Type::StorageClasses storageClasses;
 
-		void premutate( ObjectDecl *objectDecl );
-		Expression * postmutate( CompoundLiteralExpr *compLitExpr );
+		void premutate( ObjectDecl * objectDecl );
+		Expression * postmutate( CompoundLiteralExpr * compLitExpr );
 	};
 
@@ -393,5 +393,5 @@
 	}
 
-	void validateType( Type *type, const Indexer *indexer ) {
+	void validateType( Type * type, const Indexer * indexer ) {
 		PassVisitor<EnumAndPointerDecay_old> epc;
 		PassVisitor<LinkReferenceToTypes_old> lrt( indexer );
@@ -496,5 +496,5 @@
 	}
 
-	bool shouldHoist( Declaration *decl ) {
+	bool shouldHoist( Declaration * decl ) {
 		return dynamic_cast< StructDecl * >( decl ) || dynamic_cast< UnionDecl * >( decl ) || dynamic_cast< StaticAssertDecl * >( decl );
 	}
@@ -515,5 +515,5 @@
 
 	template< typename AggDecl >
-	void HoistStruct::handleAggregate( AggDecl *aggregateDecl ) {
+	void HoistStruct::handleAggregate( AggDecl * aggregateDecl ) {
 		if ( parentAggr ) {
 			aggregateDecl->parent = parentAggr;
@@ -560,5 +560,5 @@
 
 
-	bool isTypedef( Declaration *decl ) {
+	bool isTypedef( Declaration * decl ) {
 		return dynamic_cast< TypedefDecl * >( decl );
 	}
@@ -571,5 +571,5 @@
 
 	template< typename AggDecl >
-	void EliminateTypedef::handleAggregate( AggDecl *aggregateDecl ) {
+	void EliminateTypedef::handleAggregate( AggDecl * aggregateDecl ) {
 		filter( aggregateDecl->members, isTypedef, true );
 	}
@@ -586,5 +586,5 @@
 		// remove and delete decl stmts
 		filter( compoundStmt->kids, [](Statement * stmt) {
-			if ( DeclStmt *declStmt = dynamic_cast< DeclStmt * >( stmt ) ) {
+			if ( DeclStmt * declStmt = dynamic_cast< DeclStmt * >( stmt ) ) {
 				if ( dynamic_cast< TypedefDecl * >( declStmt->decl ) ) {
 					return true;
@@ -595,8 +595,8 @@
 	}
 
-	void EnumAndPointerDecay_old::previsit( EnumDecl *enumDecl ) {
+	void EnumAndPointerDecay_old::previsit( EnumDecl * enumDecl ) {
 		// Set the type of each member of the enumeration to be EnumConstant
 		for ( std::list< Declaration * >::iterator i = enumDecl->members.begin(); i != enumDecl->members.end(); ++i ) {
-			ObjectDecl * obj = dynamic_cast< ObjectDecl * >( *i );
+			ObjectDecl * obj = dynamic_cast< ObjectDecl * >( * i );
 			assert( obj );
 			obj->set_type( new EnumInstType( Type::Qualifiers( Type::Const ), enumDecl->name ) );
@@ -627,5 +627,5 @@
 	}
 
-	void EnumAndPointerDecay_old::previsit( FunctionType *func ) {
+	void EnumAndPointerDecay_old::previsit( FunctionType * func ) {
 		// Fix up parameters and return types
 		fixFunctionList( func->parameters, func->isVarArgs, func );
@@ -633,5 +633,5 @@
 	}
 
-	LinkReferenceToTypes_old::LinkReferenceToTypes_old( const Indexer *other_indexer ) {
+	LinkReferenceToTypes_old::LinkReferenceToTypes_old( const Indexer * other_indexer ) {
 		if ( other_indexer ) {
 			local_indexer = other_indexer;
@@ -641,9 +641,9 @@
 	}
 
-	void LinkReferenceToTypes_old::postvisit( EnumInstType *enumInst ) {
-		EnumDecl *st = local_indexer->lookupEnum( enumInst->name );
+	void LinkReferenceToTypes_old::postvisit( EnumInstType * enumInst ) {
+		const EnumDecl * st = local_indexer->lookupEnum( enumInst->name );
 		// it's not a semantic error if the enum is not found, just an implicit forward declaration
 		if ( st ) {
-			enumInst->baseEnum = st;
+			enumInst->baseEnum = const_cast<EnumDecl *>(st); // Just linking in the node
 		} // if
 		if ( ! st || ! st->body ) {
@@ -661,9 +661,9 @@
 	}
 
-	void LinkReferenceToTypes_old::postvisit( StructInstType *structInst ) {
-		StructDecl *st = local_indexer->lookupStruct( structInst->name );
+	void LinkReferenceToTypes_old::postvisit( StructInstType * structInst ) {
+		const StructDecl * st = local_indexer->lookupStruct( structInst->name );
 		// it's not a semantic error if the struct is not found, just an implicit forward declaration
 		if ( st ) {
-			structInst->baseStruct = st;
+			structInst->baseStruct = const_cast<StructDecl *>(st); // Just linking in the node
 		} // if
 		if ( ! st || ! st->body ) {
@@ -674,9 +674,9 @@
 	}
 
-	void LinkReferenceToTypes_old::postvisit( UnionInstType *unionInst ) {
-		UnionDecl *un = local_indexer->lookupUnion( unionInst->name );
+	void LinkReferenceToTypes_old::postvisit( UnionInstType * unionInst ) {
+		const UnionDecl * un = local_indexer->lookupUnion( unionInst->name );
 		// it's not a semantic error if the union is not found, just an implicit forward declaration
 		if ( un ) {
-			unionInst->baseUnion = un;
+			unionInst->baseUnion = const_cast<UnionDecl *>(un); // Just linking in the node
 		} // if
 		if ( ! un || ! un->body ) {
@@ -693,5 +693,5 @@
 	void LinkReferenceToTypes_old::postvisit( QualifiedType * qualType ) {
 		// linking only makes sense for the 'oldest ancestor' of the qualified type
-		qualType->parent->accept( *visitor );
+		qualType->parent->accept( * visitor );
 	}
 
@@ -762,5 +762,5 @@
 	void LinkReferenceToTypes_old::postvisit( TraitInstType * traitInst ) {
 		// handle other traits
-		TraitDecl *traitDecl = local_indexer->lookupTrait( traitInst->name );
+		const TraitDecl * traitDecl = local_indexer->lookupTrait( traitInst->name );
 		if ( ! traitDecl ) {
 			SemanticError( traitInst->location, "use of undeclared trait " + traitInst->name );
@@ -769,5 +769,5 @@
 			SemanticError( traitInst, "incorrect number of trait parameters: " );
 		} // if
-		traitInst->baseTrait = traitDecl;
+		traitInst->baseTrait = const_cast<TraitDecl *>(traitDecl); // Just linking in the node
 
 		// need to carry over the 'sized' status of each decl in the instance
@@ -786,5 +786,5 @@
 	}
 
-	void LinkReferenceToTypes_old::postvisit( EnumDecl *enumDecl ) {
+	void LinkReferenceToTypes_old::postvisit( EnumDecl * enumDecl ) {
 		// visit enum members first so that the types of self-referencing members are updated properly
 		if ( enumDecl->body ) {
@@ -792,5 +792,5 @@
 			if ( fwds != forwardEnums.end() ) {
 				for ( std::list< EnumInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) {
-					(*inst)->baseEnum = enumDecl;
+					(* inst)->baseEnum = enumDecl;
 				} // for
 				forwardEnums.erase( fwds );
@@ -834,5 +834,5 @@
 	}
 
-	void LinkReferenceToTypes_old::postvisit( StructDecl *structDecl ) {
+	void LinkReferenceToTypes_old::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 their defaults)
@@ -841,5 +841,5 @@
 			if ( fwds != forwardStructs.end() ) {
 				for ( std::list< StructInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) {
-					(*inst)->baseStruct = structDecl;
+					(* inst)->baseStruct = structDecl;
 				} // for
 				forwardStructs.erase( fwds );
@@ -848,10 +848,10 @@
 	}
 
-	void LinkReferenceToTypes_old::postvisit( UnionDecl *unionDecl ) {
+	void LinkReferenceToTypes_old::postvisit( UnionDecl * unionDecl ) {
 		if ( unionDecl->body ) {
 			ForwardUnionsType::iterator fwds = forwardUnions.find( unionDecl->name );
 			if ( fwds != forwardUnions.end() ) {
 				for ( std::list< UnionInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) {
-					(*inst)->baseUnion = unionDecl;
+					(* inst)->baseUnion = unionDecl;
 				} // for
 				forwardUnions.erase( fwds );
@@ -860,10 +860,10 @@
 	}
 
-	void LinkReferenceToTypes_old::postvisit( TypeInstType *typeInst ) {
+	void LinkReferenceToTypes_old::postvisit( TypeInstType * typeInst ) {
 		// ensure generic parameter instances are renamed like the base type
 		if ( inGeneric && typeInst->baseType ) typeInst->name = typeInst->baseType->name;
-		if ( NamedTypeDecl *namedTypeDecl = local_indexer->lookupType( typeInst->name ) ) {
-			if ( TypeDecl *typeDecl = dynamic_cast< TypeDecl * >( namedTypeDecl ) ) {
-				typeInst->set_isFtype( typeDecl->get_kind() == TypeDecl::Ftype );
+		if ( const NamedTypeDecl * namedTypeDecl = local_indexer->lookupType( typeInst->name ) ) {
+			if ( const TypeDecl * typeDecl = dynamic_cast< const TypeDecl * >( namedTypeDecl ) ) {
+				typeInst->set_isFtype( typeDecl->kind == TypeDecl::Ftype );
 			} // if
 		} // if
@@ -877,5 +877,5 @@
 			// expand trait instances into their members
 			for ( DeclarationWithType * assertion : asserts ) {
-				if ( TraitInstType *traitInst = dynamic_cast< TraitInstType * >( assertion->get_type() ) ) {
+				if ( TraitInstType * traitInst = dynamic_cast< TraitInstType * >( assertion->get_type() ) ) {
 					// expand trait instance into all of its members
 					expandAssertions( traitInst, back_inserter( type->assertions ) );
@@ -897,5 +897,5 @@
 	}
 
-	void ForallPointerDecay_old::previsit( ObjectDecl *object ) {
+	void ForallPointerDecay_old::previsit( ObjectDecl * object ) {
 		// ensure that operator names only apply to functions or function pointers
 		if ( CodeGen::isOperator( object->name ) && ! dynamic_cast< FunctionType * >( object->type->stripDeclarator() ) ) {
@@ -905,5 +905,5 @@
 	}
 
-	void ForallPointerDecay_old::previsit( FunctionDecl *func ) {
+	void ForallPointerDecay_old::previsit( FunctionDecl * func ) {
 		func->fixUniqueId();
 	}
@@ -961,5 +961,5 @@
 	Type * ReplaceTypedef::postmutate( QualifiedType * qualType ) {
 		// replacing typedefs only makes sense for the 'oldest ancestor' of the qualified type
-		qualType->parent = qualType->parent->acceptMutator( *visitor );
+		qualType->parent = qualType->parent->acceptMutator( * visitor );
 		return qualType;
 	}
@@ -970,5 +970,5 @@
 		TypedefMap::const_iterator def = typedefNames.find( typeInst->name );
 		if ( def != typedefNames.end() ) {
-			Type *ret = def->second.first->base->clone();
+			Type * ret = def->second.first->base->clone();
 			ret->location = typeInst->location;
 			ret->get_qualifiers() |= typeInst->get_qualifiers();
@@ -982,5 +982,5 @@
 			// place instance parameters on the typedef'd type
 			if ( ! typeInst->parameters.empty() ) {
-				ReferenceToType *rtt = dynamic_cast<ReferenceToType*>(ret);
+				ReferenceToType * rtt = dynamic_cast<ReferenceToType *>(ret);
 				if ( ! rtt ) {
 					SemanticError( typeInst->location, "Cannot apply type parameters to base type of " + typeInst->name );
@@ -988,5 +988,5 @@
 				rtt->parameters.clear();
 				cloneAll( typeInst->parameters, rtt->parameters );
-				mutateAll( rtt->parameters, *visitor );  // recursively fix typedefs on parameters
+				mutateAll( rtt->parameters, * visitor );  // recursively fix typedefs on parameters
 			} // if
 			delete typeInst;
@@ -1043,14 +1043,14 @@
 		//    struct screen;
 		// because the expansion of the typedef is:
-		//    void rtn( SCREEN *p ) => void rtn( struct screen *p )
+		//    void rtn( SCREEN * p ) => void rtn( struct screen * p )
 		// hence the type-name "screen" must be defined.
 		// Note, qualifiers on the typedef are superfluous for the forward declaration.
 
-		Type *designatorType = tyDecl->base->stripDeclarator();
-		if ( StructInstType *aggDecl = dynamic_cast< StructInstType * >( designatorType ) ) {
+		Type * designatorType = tyDecl->base->stripDeclarator();
+		if ( StructInstType * aggDecl = dynamic_cast< StructInstType * >( designatorType ) ) {
 			declsToAddBefore.push_back( new StructDecl( aggDecl->name, DeclarationNode::Struct, noAttributes, tyDecl->linkage ) );
-		} else if ( UnionInstType *aggDecl = dynamic_cast< UnionInstType * >( designatorType ) ) {
+		} else if ( UnionInstType * aggDecl = dynamic_cast< UnionInstType * >( designatorType ) ) {
 			declsToAddBefore.push_back( new UnionDecl( aggDecl->name, noAttributes, tyDecl->linkage ) );
-		} else if ( EnumInstType *enumDecl = dynamic_cast< EnumInstType * >( designatorType ) ) {
+		} else if ( EnumInstType * enumDecl = dynamic_cast< EnumInstType * >( designatorType ) ) {
 			declsToAddBefore.push_back( new EnumDecl( enumDecl->name, noAttributes, tyDecl->linkage ) );
 		} // if
@@ -1078,5 +1078,5 @@
 
 	DeclarationWithType * ReplaceTypedef::postmutate( ObjectDecl * objDecl ) {
-		if ( FunctionType *funtype = dynamic_cast<FunctionType *>( objDecl->type ) ) { // function type?
+		if ( FunctionType * funtype = dynamic_cast<FunctionType *>( objDecl->type ) ) { // function type?
 			// replace the current object declaration with a function declaration
 			FunctionDecl * newDecl = new FunctionDecl( objDecl->name, objDecl->get_storageClasses(), objDecl->linkage, funtype, 0, objDecl->attributes, objDecl->get_funcSpec() );
@@ -1104,5 +1104,5 @@
 	void ReplaceTypedef::addImplicitTypedef( AggDecl * aggDecl ) {
 		if ( typedefNames.count( aggDecl->get_name() ) == 0 ) {
-			Type *type = nullptr;
+			Type * type = nullptr;
 			if ( StructDecl * newDeclStructDecl = dynamic_cast< StructDecl * >( aggDecl ) ) {
 				type = new StructInstType( Type::Qualifiers(), newDeclStructDecl->get_name() );
@@ -1130,5 +1130,5 @@
 		GuardScope( typedefNames );
 		GuardScope( typedeclNames );
-		mutateAll( aggr->parameters, *visitor );
+		mutateAll( aggr->parameters, * visitor );
 
 		// unroll mutateAll for aggr->members so that implicit typedefs for nested types are added to the aggregate body.
@@ -1137,5 +1137,5 @@
 
 			try {
-				*i = maybeMutate( *i, *visitor );
+				* i = maybeMutate( * i, * visitor );
 			} catch ( SemanticErrorException &e ) {
 				errors.append( e );
@@ -1217,11 +1217,11 @@
 			for ( size_t i = 0; paramIter != params->end(); ++paramIter, ++i ) {
 				if ( i < args.size() ) {
-					TypeExpr * expr = strict_dynamic_cast< TypeExpr * >( *std::next( args.begin(), i ) );
-					sub.add( (*paramIter)->get_name(), expr->get_type()->clone() );
+					TypeExpr * expr = strict_dynamic_cast< TypeExpr * >( * std::next( args.begin(), i ) );
+					sub.add( (* paramIter)->get_name(), expr->get_type()->clone() );
 				} else if ( i == args.size() ) {
-					Type * defaultType = (*paramIter)->get_init();
+					Type * defaultType = (* paramIter)->get_init();
 					if ( defaultType ) {
 						args.push_back( new TypeExpr( defaultType->clone() ) );
-						sub.add( (*paramIter)->get_name(), defaultType->clone() );
+						sub.add( (* paramIter)->get_name(), defaultType->clone() );
 					}
 				}
@@ -1242,14 +1242,14 @@
 	}
 
-	void CompoundLiteral::premutate( ObjectDecl *objectDecl ) {
+	void CompoundLiteral::premutate( ObjectDecl * objectDecl ) {
 		storageClasses = objectDecl->get_storageClasses();
 	}
 
-	Expression *CompoundLiteral::postmutate( CompoundLiteralExpr *compLitExpr ) {
+	Expression * CompoundLiteral::postmutate( CompoundLiteralExpr * compLitExpr ) {
 		// transform [storage_class] ... (struct S){ 3, ... };
 		// into [storage_class] struct S temp =  { 3, ... };
 		static UniqueName indexName( "_compLit" );
 
-		ObjectDecl *tempvar = new ObjectDecl( indexName.newName(), storageClasses, LinkageSpec::C, nullptr, compLitExpr->get_result(), compLitExpr->get_initializer() );
+		ObjectDecl * tempvar = new ObjectDecl( indexName.newName(), storageClasses, LinkageSpec::C, nullptr, compLitExpr->get_result(), compLitExpr->get_initializer() );
 		compLitExpr->set_result( nullptr );
 		compLitExpr->set_initializer( nullptr );
@@ -1289,5 +1289,5 @@
 			TupleType * tupleType = strict_dynamic_cast< TupleType * >( ResolvExpr::extractResultType( ftype ) );
 			// ensure return value is not destructed by explicitly creating an empty ListInit node wherein maybeConstruct is false.
-			ObjectDecl * newRet = new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0, tupleType, new ListInit( std::list<Initializer*>(), noDesignators, false ) );
+			ObjectDecl * newRet = new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0, tupleType, new ListInit( std::list<Initializer *>(), noDesignators, false ) );
 			deleteAll( retVals );
 			retVals.clear();
@@ -1302,5 +1302,5 @@
 
 	void FixObjectType::previsit( ObjectDecl * objDecl ) {
-		Type *new_type = ResolvExpr::resolveTypeof( objDecl->get_type(), indexer );
+		Type * new_type = ResolvExpr::resolveTypeof( objDecl->get_type(), indexer );
 		new_type->get_qualifiers() -= Type::Lvalue; // even if typeof is lvalue, variable can never have lvalue-qualified type
 		objDecl->set_type( new_type );
@@ -1308,12 +1308,12 @@
 
 	void FixObjectType::previsit( FunctionDecl * funcDecl ) {
-		Type *new_type = ResolvExpr::resolveTypeof( funcDecl->type, indexer );
+		Type * new_type = ResolvExpr::resolveTypeof( funcDecl->type, indexer );
 		new_type->get_qualifiers() -= Type::Lvalue; // even if typeof is lvalue, variable can never have lvalue-qualified type
 		funcDecl->set_type( new_type );
 	}
 
-	void FixObjectType::previsit( TypeDecl *typeDecl ) {
+	void FixObjectType::previsit( TypeDecl * typeDecl ) {
 		if ( typeDecl->get_base() ) {
-			Type *new_type = ResolvExpr::resolveTypeof( typeDecl->get_base(), indexer );
+			Type * new_type = ResolvExpr::resolveTypeof( typeDecl->get_base(), indexer );
 			new_type->get_qualifiers() -= Type::Lvalue; // even if typeof is lvalue, variable can never have lvalue-qualified type
 			typeDecl->set_base( new_type );
@@ -1378,5 +1378,5 @@
 
 namespace {
-	/// Replaces enum types by int, and function/array types in function parameter and return 
+	/// Replaces enum types by int, and function/array types in function parameter and return
 	/// lists by appropriate pointers
 	struct EnumAndPointerDecay_new {
@@ -1385,9 +1385,9 @@
 			for ( unsigned i = 0; i < enumDecl->members.size(); ++i ) {
 				// build new version of object with EnumConstant
-				ast::ptr< ast::ObjectDecl > obj = 
+				ast::ptr< ast::ObjectDecl > obj =
 					enumDecl->members[i].strict_as< ast::ObjectDecl >();
-				obj.get_and_mutate()->type = 
+				obj.get_and_mutate()->type =
 					new ast::EnumInstType{ enumDecl->name, ast::CV::Const };
-				
+
 				// set into decl
 				ast::EnumDecl * mut = mutate( enumDecl );
@@ -1399,9 +1399,9 @@
 
 		static const ast::FunctionType * fixFunctionList(
-			const ast::FunctionType * func, 
+			const ast::FunctionType * func,
 			std::vector< ast::ptr< ast::DeclWithType > > ast::FunctionType::* field,
 			ast::ArgumentFlag isVarArgs = ast::FixedArgs
 		) {
-			const auto & dwts = func->*field;
+			const auto & dwts = func->* field;
 			unsigned nvals = dwts.size();
 			bool hasVoid = false;
@@ -1409,8 +1409,8 @@
 				func = ast::mutate_field_index( func, field, i, fixFunction( dwts[i], hasVoid ) );
 			}
-			
+
 			// the only case in which "void" is valid is where it is the only one in the list
 			if ( hasVoid && ( nvals > 1 || isVarArgs ) ) {
-				SemanticError( 
+				SemanticError(
 					dwts.front()->location, func, "invalid type void in function type" );
 			}
@@ -1418,5 +1418,5 @@
 			// one void is the only thing in the list, remove it
 			if ( hasVoid ) {
-				func = ast::mutate_field( 
+				func = ast::mutate_field(
 					func, field, std::vector< ast::ptr< ast::DeclWithType > >{} );
 			}
@@ -1432,11 +1432,11 @@
 
 	/// expand assertions from a trait instance, performing appropriate type variable substitutions
-	void expandAssertions( 
-		const ast::TraitInstType * inst, std::vector< ast::ptr< ast::DeclWithType > > & out 
+	void expandAssertions(
+		const ast::TraitInstType * inst, std::vector< ast::ptr< ast::DeclWithType > > & out
 	) {
 		assertf( inst->base, "Trait instance not linked to base trait: %s", toCString( inst ) );
 
 		// build list of trait members, substituting trait decl parameters for instance parameters
-		ast::TypeSubstitution sub{ 
+		ast::TypeSubstitution sub{
 			inst->base->params.begin(), inst->base->params.end(), inst->params.begin() };
 		// deliberately take ast::ptr by-value to ensure this does not mutate inst->base
@@ -1449,25 +1449,25 @@
 
 	/// Associates forward declarations of aggregates with their definitions
-	class LinkReferenceToTypes_new final 
-	: public ast::WithSymbolTable, public ast::WithGuards, public 
+	class LinkReferenceToTypes_new final
+	: public ast::WithSymbolTable, public ast::WithGuards, public
 	  ast::WithVisitorRef<LinkReferenceToTypes_new>, public ast::WithShortCircuiting {
-		
-		// these maps of uses of forward declarations of types need to have the actual type 
-		// declaration switched in *after* they have been traversed. To enable this in the 
-		// ast::Pass framework, any node that needs to be so mutated has mutate() called on it 
-		// before it is placed in the map, properly updating its parents in the usual traversal, 
+
+		// these maps of uses of forward declarations of types need to have the actual type
+		// declaration switched in * after * they have been traversed. To enable this in the
+		// ast::Pass framework, any node that needs to be so mutated has mutate() called on it
+		// before it is placed in the map, properly updating its parents in the usual traversal,
 		// then can have the actual mutation applied later
 		using ForwardEnumsType = std::unordered_multimap< std::string, ast::EnumInstType * >;
 		using ForwardStructsType = std::unordered_multimap< std::string, ast::StructInstType * >;
 		using ForwardUnionsType = std::unordered_multimap< std::string, ast::UnionInstType * >;
-		
+
 		const CodeLocation & location;
 		const ast::SymbolTable * localSymtab;
-		
+
 		ForwardEnumsType forwardEnums;
 		ForwardStructsType forwardStructs;
 		ForwardUnionsType forwardUnions;
 
-		/// true if currently in a generic type body, so that type parameter instances can be 
+		/// true if currently in a generic type body, so that type parameter instances can be
 		/// renamed appropriately
 		bool inGeneric = false;
@@ -1475,9 +1475,9 @@
 	public:
 		/// contstruct using running symbol table
-		LinkReferenceToTypes_new( const CodeLocation & loc ) 
+		LinkReferenceToTypes_new( const CodeLocation & loc )
 		: location( loc ), localSymtab( &symtab ) {}
-		
+
 		/// construct using provided symbol table
-		LinkReferenceToTypes_new( const CodeLocation & loc, const ast::SymbolTable & syms ) 
+		LinkReferenceToTypes_new( const CodeLocation & loc, const ast::SymbolTable & syms )
 		: location( loc ), localSymtab( &syms ) {}
 
@@ -1485,11 +1485,11 @@
 			// ensure generic parameter instances are renamed like the base type
 			if ( inGeneric && typeInst->base ) {
-				typeInst = ast::mutate_field( 
+				typeInst = ast::mutate_field(
 					typeInst, &ast::TypeInstType::name, typeInst->base->name );
 			}
 
-			if ( 
-				auto typeDecl = dynamic_cast< const ast::TypeDecl * >( 
-					localSymtab->lookupType( typeInst->name ) ) 
+			if (
+				auto typeDecl = dynamic_cast< const ast::TypeDecl * >(
+					localSymtab->lookupType( typeInst->name ) )
 			) {
 				typeInst = ast::mutate_field( typeInst, &ast::TypeInstType::kind, typeDecl->kind );
@@ -1517,5 +1517,5 @@
 			for ( const ast::Expr * param : inst->params ) {
 				if ( ! dynamic_cast< const ast::TypeExpr * >( param ) ) {
-					SemanticError( 
+					SemanticError(
 						location, inst, "Expression parameters for generic types are currently "
 						"unsupported: " );
@@ -1571,5 +1571,5 @@
 				auto expr = traitInst->params[i].as< ast::TypeExpr >();
 				if ( ! expr ) {
-					SemanticError( 
+					SemanticError(
 						traitInst->params[i].get(), "Expression parameters for trait instances "
 						"are currently unsupported: " );
@@ -1593,15 +1593,15 @@
 			return traitInst;
 		}
-		
+
 		void previsit( const ast::QualifiedType * ) { visit_children = false; }
-		
+
 		const ast::Type * postvisit( const ast::QualifiedType * qualType ) {
 			// linking only makes sense for the "oldest ancestor" of the qualified type
-			return ast::mutate_field( 
-				qualType, &ast::QualifiedType::parent, qualType->parent->accept( *visitor ) );
+			return ast::mutate_field(
+				qualType, &ast::QualifiedType::parent, qualType->parent->accept( * visitor ) );
 		}
 
 		const ast::Decl * postvisit( const ast::EnumDecl * enumDecl ) {
-			// visit enum members first so that the types of self-referencing members are updated 
+			// visit enum members first so that the types of self-referencing members are updated
 			// properly
 			if ( ! enumDecl->body ) return enumDecl;
@@ -1612,23 +1612,23 @@
 				auto inst = fwds.first;
 				do {
-					// forward decl is stored *mutably* in map, can thus be updated
+					// forward decl is stored * mutably * in map, can thus be updated
 					inst->second->base = enumDecl;
 				} while ( ++inst != fwds.second );
 				forwardEnums.erase( fwds.first, fwds.second );
 			}
-			
+
 			// ensure that enumerator initializers are properly set
 			for ( unsigned i = 0; i < enumDecl->members.size(); ++i ) {
 				auto field = enumDecl->members[i].strict_as< ast::ObjectDecl >();
 				if ( field->init ) {
-					// need to resolve enumerator initializers early so that other passes that 
+					// need to resolve enumerator initializers early so that other passes that
 					// determine if an expression is constexpr have appropriate information
 					auto init = field->init.strict_as< ast::SingleInit >();
-					
-					enumDecl = ast::mutate_field_index( 
-						enumDecl, &ast::EnumDecl::members, i, 
-						ast::mutate_field( field, &ast::ObjectDecl::init, 
+
+					enumDecl = ast::mutate_field_index(
+						enumDecl, &ast::EnumDecl::members, i,
+						ast::mutate_field( field, &ast::ObjectDecl::init,
 							ast::mutate_field( init, &ast::SingleInit::value,
-								ResolvExpr::findSingleExpression( 
+								ResolvExpr::findSingleExpression(
 									init->value, new ast::BasicType{ ast::BasicType::SignedInt },
 									symtab ) ) ) );
@@ -1639,5 +1639,5 @@
 		}
 
-		/// rename generic type parameters uniquely so that they do not conflict with user defined 
+		/// rename generic type parameters uniquely so that they do not conflict with user defined
 		/// function forall parameters, e.g. the T in Box and the T in f, below
 		///   forall(otype T)
@@ -1657,6 +1657,6 @@
 				const ast::TypeDecl * td = aggr->params[i];
 
-				aggr = ast::mutate_field_index( 
-					aggr, &AggrDecl::params, i, 
+				aggr = ast::mutate_field_index(
+					aggr, &AggrDecl::params, i,
 					ast::mutate_field( td, &ast::TypeDecl::name, "__" + td->name + "_generic_" ) );
 			}
@@ -1669,5 +1669,5 @@
 
 		void postvisit( const ast::StructDecl * structDecl ) {
-			// visit struct members first so that the types of self-referencing members are 
+			// visit struct members first so that the types of self-referencing members are
 			// updated properly
 			if ( ! structDecl->body ) return;
@@ -1678,5 +1678,5 @@
 				auto inst = fwds.first;
 				do {
-					// forward decl is stored *mutably* in map, can thus be updated
+					// forward decl is stored * mutably * in map, can thus be updated
 					inst->second->base = structDecl;
 				} while ( ++inst != fwds.second );
@@ -1690,5 +1690,5 @@
 
 		void postvisit( const ast::UnionDecl * unionDecl ) {
-			// visit union members first so that the types of self-referencing members are updated 
+			// visit union members first so that the types of self-referencing members are updated
 			// properly
 			if ( ! unionDecl->body ) return;
@@ -1699,5 +1699,5 @@
 				auto inst = fwds.first;
 				do {
-					// forward decl is stored *mutably* in map, can thus be updated
+					// forward decl is stored * mutably * in map, can thus be updated
 					inst->second->base = unionDecl;
 				} while ( ++inst != fwds.second );
@@ -1712,7 +1712,7 @@
 					"number of parameters: %zd", traitDecl->params.size() );
 
-				traitDecl = ast::mutate_field_index( 
-					traitDecl, &ast::TraitDecl::params, 0, 
-					ast::mutate_field( 
+				traitDecl = ast::mutate_field_index(
+					traitDecl, &ast::TraitDecl::params, 0,
+					ast::mutate_field(
 						traitDecl->params.front().get(), &ast::TypeDecl::sized, true ) );
 			}
@@ -1737,10 +1737,10 @@
 				traitDecl = mut;
 			}
-			
+
 			return traitDecl;
 		}
 	};
 
-	/// Replaces array and function types in forall lists by appropriate pointer type and assigns 
+	/// Replaces array and function types in forall lists by appropriate pointer type and assigns
 	/// each object and function declaration a unique ID
 	class ForallPointerDecay_new {
@@ -1751,6 +1751,6 @@
 		const ast::ObjectDecl * previsit( const ast::ObjectDecl * obj ) {
 			// ensure that operator names only apply to functions or function pointers
-			if ( 
-				CodeGen::isOperator( obj->name ) 
+			if (
+				CodeGen::isOperator( obj->name )
 				&& ! dynamic_cast< const ast::FunctionType * >( obj->type->stripDeclarator() )
 			) {
@@ -1776,10 +1776,10 @@
 		/// Fix up assertions -- flattens assertion lists, removing all trait instances
 		template< typename node_t, typename parent_t >
-		static const node_t * forallFixer( 
-			const CodeLocation & loc, const node_t * node, 
+		static const node_t * forallFixer(
+			const CodeLocation & loc, const node_t * node,
 			ast::ParameterizedType::ForallList parent_t::* forallField
 		) {
-			for ( unsigned i = 0; i < (node->*forallField).size(); ++i ) {
-				const ast::TypeDecl * type = (node->*forallField)[i];
+			for ( unsigned i = 0; i < (node->* forallField).size(); ++i ) {
+				const ast::TypeDecl * type = (node->* forallField)[i];
 				if ( type->assertions.empty() ) continue;
 
@@ -1789,6 +1789,6 @@
 				// expand trait instances into their members
 				for ( const ast::DeclWithType * assn : type->assertions ) {
-					auto traitInst = 
-						dynamic_cast< const ast::TraitInstType * >( assn->get_type() ); 
+					auto traitInst =
+						dynamic_cast< const ast::TraitInstType * >( assn->get_type() );
 					if ( traitInst ) {
 						// expand trait instance to all its members
@@ -1831,5 +1831,5 @@
 } // anonymous namespace
 
-const ast::Type * validateType( 
+const ast::Type * validateType(
 		const CodeLocation & loc, const ast::Type * type, const ast::SymbolTable & symtab ) {
 	ast::Pass< EnumAndPointerDecay_new > epc;
Index: src/SymTab/Validate.h
===================================================================
--- src/SymTab/Validate.h	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/SymTab/Validate.h	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -19,7 +19,7 @@
 #include <list>  // for list
 
-class CodeLocation;
-class Declaration;
-class Type;
+struct CodeLocation;
+class  Declaration;
+class  Type;
 
 namespace ast {
@@ -35,5 +35,5 @@
 	void validateType( Type *type, const Indexer *indexer );
 
-	const ast::Type * validateType( 
+	const ast::Type * validateType(
 		const CodeLocation & loc, const ast::Type * type, const ast::SymbolTable & symtab );
 } // namespace SymTab
Index: src/SynTree/Attribute.h
===================================================================
--- src/SynTree/Attribute.h	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/SynTree/Attribute.h	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -50,4 +50,5 @@
 	Attribute * clone() const override { return new Attribute( *this ); }
 	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual Attribute * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
 	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
Index: src/SynTree/BaseSyntaxNode.h
===================================================================
--- src/SynTree/BaseSyntaxNode.h	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/SynTree/BaseSyntaxNode.h	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -9,7 +9,7 @@
 // Author           : Thierry Delisle
 // Created On       : Tue Feb 14 07:44:20 2017
-// Last Modified By : Andrew Beach
-// Last Modified On : Thr Aug 17 13:44:00
-// Update Count     : 1
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Wed Jul 10 16:13:49 2019
+// Update Count     : 4
 //
 
@@ -25,10 +25,11 @@
 class BaseSyntaxNode {
   public:
-  static Stats::Counters::SimpleCounter* new_nodes;
+	static Stats::Counters::SimpleCounter* new_nodes;
 
 	CodeLocation location;
 
-  BaseSyntaxNode() { ++*new_nodes; }
-  BaseSyntaxNode( const BaseSyntaxNode& o ) : location(o.location) { ++*new_nodes; }
+	BaseSyntaxNode() { ++*new_nodes; }
+	BaseSyntaxNode( const BaseSyntaxNode & o ) : location(o.location) { ++*new_nodes; }
+	BaseSyntaxNode & operator=( const BaseSyntaxNode & ) = default;
 
 	virtual ~BaseSyntaxNode() {}
@@ -36,8 +37,9 @@
 	virtual BaseSyntaxNode * clone() const = 0;
 	virtual void accept( Visitor & v ) = 0;
+	virtual void accept( Visitor & v ) const = 0;
 	virtual BaseSyntaxNode * acceptMutator( Mutator & m ) = 0;
-  /// Notes:
-  /// * each node is responsible for indenting its children.
-  /// * Expressions should not finish with a newline, since the expression's parent has better information.
+	/// Notes:
+	/// * each node is responsible for indenting its children.
+	/// * Expressions should not finish with a newline, since the expression's parent has better information.
 	virtual void print( std::ostream & os, Indenter indent = {} ) const = 0;
 };
Index: src/SynTree/Constant.h
===================================================================
--- src/SynTree/Constant.h	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/SynTree/Constant.h	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Andrew Beach
-// Last Modified On : Fri Spt 28 14:48:00 2018
-// Update Count     : 18
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Wed Jul 10 15:57:38 2019
+// Update Count     : 19
 //
 
@@ -30,7 +30,8 @@
 	Constant( Type * type, std::string rep, std::optional<unsigned long long> i );
 	Constant( const Constant & other );
+	Constant & operator=( const Constant & ) = default;
 	virtual ~Constant();
 
-	virtual Constant * clone() const { return new Constant( *this ); }
+	virtual Constant * clone() const override { return new Constant( *this ); }
 
 	Type * get_type() { return type; }
@@ -50,13 +51,12 @@
 	static Constant null( Type * ptrtype = nullptr );
 
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Constant * acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, Indenter indent = 0 ) const;
-  private:
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
+	virtual Constant * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = 0 ) const override;
+
 	Type * type;
 	std::string rep;
 	std::optional<unsigned long long> ival;
-
-	friend class ConverterOldToNew;
 };
 
Index: src/SynTree/Declaration.h
===================================================================
--- src/SynTree/Declaration.h	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/SynTree/Declaration.h	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -63,5 +63,6 @@
 	void fixUniqueId( void );
 	virtual Declaration *clone() const override = 0;
-	virtual void accept( Visitor &v ) override = 0;
+	virtual void accept( Visitor & v ) override = 0;
+	virtual void accept( Visitor & v ) const override = 0;
 	virtual Declaration *acceptMutator( Mutator &m ) override = 0;
 	virtual void print( std::ostream &os, Indenter indent = {} ) const override = 0;
@@ -139,5 +140,6 @@
 
 	virtual ObjectDecl *clone() const override { return new ObjectDecl( *this ); }
-	virtual void accept( Visitor &v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual DeclarationWithType *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
 	virtual void print( std::ostream &os, Indenter indent = {} ) const override;
@@ -169,5 +171,6 @@
 
 	virtual FunctionDecl *clone() const override { return new FunctionDecl( *this ); }
-	virtual void accept( Visitor &v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual DeclarationWithType *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
 	virtual void print( std::ostream &os, Indenter indent = {} ) const override;
@@ -238,5 +241,6 @@
 
 	virtual TypeDecl *clone() const override { return new TypeDecl( *this ); }
-	virtual void accept( Visitor &v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
 	virtual void print( std::ostream &os, Indenter indent = {} ) const override;
@@ -256,5 +260,6 @@
 
 	virtual TypedefDecl *clone() const override { return new TypedefDecl( *this ); }
-	virtual void accept( Visitor &v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
   private:
@@ -300,5 +305,6 @@
 
 	virtual StructDecl *clone() const override { return new StructDecl( *this ); }
-	virtual void accept( Visitor &v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
 	DeclarationNode::Aggregate kind;
@@ -314,5 +320,6 @@
 
 	virtual UnionDecl *clone() const override { return new UnionDecl( *this ); }
-	virtual void accept( Visitor &v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
   private:
@@ -329,5 +336,6 @@
 
 	virtual EnumDecl *clone() const override { return new EnumDecl( *this ); }
-	virtual void accept( Visitor &v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
   private:
@@ -345,8 +353,26 @@
 
 	virtual TraitDecl *clone() const override { return new TraitDecl( *this ); }
-	virtual void accept( Visitor &v ) override { v.visit( this ); }
-	virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
-  private:
-	virtual std::string typeString() const override;
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
+	virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
+  private:
+	virtual std::string typeString() const override;
+};
+
+class WithStmt : public Declaration {
+public:
+	std::list< Expression * > exprs;
+	Statement * stmt;
+
+	WithStmt( const std::list< Expression * > & exprs, Statement * stmt );
+	WithStmt( const WithStmt & other );
+	virtual ~WithStmt();
+
+	virtual WithStmt * clone() const override { return new WithStmt( *this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
+	virtual Declaration * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
+	virtual void printShort( std::ostream & os, Indenter indent = {} ) const override { print(os, indent); }
 };
 
@@ -363,5 +389,6 @@
 
 	virtual AsmDecl *clone() const override { return new AsmDecl( *this ); }
-	virtual void accept( Visitor &v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual AsmDecl *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
 	virtual void print( std::ostream &os, Indenter indent = {} ) const override;
@@ -379,5 +406,6 @@
 
 	virtual StaticAssertDecl * clone() const override { return new StaticAssertDecl( *this ); }
-	virtual void accept( Visitor &v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual StaticAssertDecl * acceptMutator( Mutator &m )  override { return m.mutate( this ); }
 	virtual void print( std::ostream &os, Indenter indent = {} ) const override;
Index: src/SynTree/Expression.cc
===================================================================
--- src/SynTree/Expression.cc	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/SynTree/Expression.cc	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -724,5 +724,5 @@
 }
 
-DeletedExpr::DeletedExpr( Expression * expr, BaseSyntaxNode * deleteStmt ) : expr( expr ), deleteStmt( deleteStmt ) {
+DeletedExpr::DeletedExpr( Expression * expr, Declaration * deleteStmt ) : expr( expr ), deleteStmt( deleteStmt ) {
 	assert( expr->result );
 	result = expr->result->clone();
Index: src/SynTree/Expression.h
===================================================================
--- src/SynTree/Expression.h	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/SynTree/Expression.h	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -82,4 +82,5 @@
 	virtual Expression * clone() const override = 0;
 	virtual void accept( Visitor & v ) override = 0;
+	virtual void accept( Visitor & v ) const override = 0;
 	virtual Expression * acceptMutator( Mutator & m ) override = 0;
 	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
@@ -101,8 +102,9 @@
 	std::list<Expression *>& get_args() { return args; }
 
-	virtual ApplicationExpr * clone() const { return new ApplicationExpr( * this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, Indenter indent = {} ) const;
+	virtual ApplicationExpr * clone() const override { return new ApplicationExpr( * this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
+	virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
@@ -129,8 +131,9 @@
 	static UntypedExpr * createAssign( Expression * arg1, Expression * arg2 );
 
-	virtual UntypedExpr * clone() const { return new UntypedExpr( * this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, Indenter indent = {} ) const;
+	virtual UntypedExpr * clone() const override { return new UntypedExpr( * this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
+	virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
@@ -147,8 +150,9 @@
 	void set_name( std::string newValue ) { name = newValue; }
 
-	virtual NameExpr * clone() const { return new NameExpr( * this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, Indenter indent = {} ) const;
+	virtual NameExpr * clone() const override { return new NameExpr( * this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
+	virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
@@ -168,8 +172,9 @@
 	void set_arg(Expression * newValue ) { arg = newValue; }
 
-	virtual AddressExpr * clone() const { return new AddressExpr( * this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, Indenter indent = {} ) const;
+	virtual AddressExpr * clone() const override { return new AddressExpr( * this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
+	virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
@@ -184,8 +189,9 @@
 	virtual ~LabelAddressExpr();
 
-	virtual LabelAddressExpr * clone() const { return new LabelAddressExpr( * this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, Indenter indent = {} ) const;
+	virtual LabelAddressExpr * clone() const override { return new LabelAddressExpr( * this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
+	virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
@@ -205,8 +211,9 @@
 	void set_arg( Expression * newValue ) { arg = newValue; }
 
-	virtual CastExpr * clone() const { return new CastExpr( * this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, Indenter indent = {} ) const;
+	virtual CastExpr * clone() const override { return new CastExpr( * this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
+	virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
@@ -225,8 +232,9 @@
 	const std::string & targetString() const;
 
-	virtual KeywordCastExpr * clone() const { return new KeywordCastExpr( * this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, Indenter indent = {} ) const;
+	virtual KeywordCastExpr * clone() const override { return new KeywordCastExpr( * this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
+	virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
@@ -243,8 +251,9 @@
 	void set_arg( Expression * newValue ) { arg = newValue; }
 
-	virtual VirtualCastExpr * clone() const { return new VirtualCastExpr( * this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, Indenter indent = {} ) const;
+	virtual VirtualCastExpr * clone() const override { return new VirtualCastExpr( * this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
+	virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
@@ -264,8 +273,9 @@
 	void set_aggregate( Expression * newValue ) { aggregate = newValue; }
 
-	virtual UntypedMemberExpr * clone() const { return new UntypedMemberExpr( * this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, Indenter indent = {} ) const;
+	virtual UntypedMemberExpr * clone() const override { return new UntypedMemberExpr( * this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
+	virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
@@ -286,8 +296,9 @@
 	void set_aggregate( Expression * newValue ) { aggregate = newValue; }
 
-	virtual MemberExpr * clone() const { return new MemberExpr( * this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, Indenter indent = {} ) const;
+	virtual MemberExpr * clone() const override { return new MemberExpr( * this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
+	virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
@@ -308,8 +319,9 @@
 	static VariableExpr * functionPointer( FunctionDecl * decl );
 
-	virtual VariableExpr * clone() const { return new VariableExpr( * this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, Indenter indent = {} ) const;
+	virtual VariableExpr * clone() const override { return new VariableExpr( * this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
+	virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
@@ -329,8 +341,9 @@
 	long long int intValue() const;
 
-	virtual ConstantExpr * clone() const { return new ConstantExpr( * this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, Indenter indent = {} ) const;
+	virtual ConstantExpr * clone() const override { return new ConstantExpr( * this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
+	virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
@@ -354,8 +367,9 @@
 	void set_isType( bool newValue ) { isType = newValue; }
 
-	virtual SizeofExpr * clone() const { return new SizeofExpr( * this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, Indenter indent = {} ) const;
+	virtual SizeofExpr * clone() const override { return new SizeofExpr( * this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
+	virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
@@ -379,8 +393,9 @@
 	void set_isType( bool newValue ) { isType = newValue; }
 
-	virtual AlignofExpr * clone() const { return new AlignofExpr( * this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, Indenter indent = {} ) const;
+	virtual AlignofExpr * clone() const override { return new AlignofExpr( * this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
+	virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
@@ -400,8 +415,9 @@
 	void set_type( Type * newValue ) { type = newValue; }
 
-	virtual UntypedOffsetofExpr * clone() const { return new UntypedOffsetofExpr( * this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, Indenter indent = {} ) const;
+	virtual UntypedOffsetofExpr * clone() const override { return new UntypedOffsetofExpr( * this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
+	virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
@@ -421,8 +437,9 @@
 	void set_member( DeclarationWithType * newValue ) { member = newValue; }
 
-	virtual OffsetofExpr * clone() const { return new OffsetofExpr( * this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, Indenter indent = {} ) const;
+	virtual OffsetofExpr * clone() const override { return new OffsetofExpr( * this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
+	virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
@@ -439,8 +456,9 @@
 	void set_type( StructInstType * newValue ) { type = newValue; }
 
-	virtual OffsetPackExpr * clone() const { return new OffsetPackExpr( * this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, Indenter indent = {} ) const;
+	virtual OffsetPackExpr * clone() const override { return new OffsetPackExpr( * this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
+	virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
@@ -467,8 +485,9 @@
 	void set_isType( bool newValue ) { isType = newValue; }
 
-	virtual AttrExpr * clone() const { return new AttrExpr( * this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, Indenter indent = {} ) const;
+	virtual AttrExpr * clone() const override { return new AttrExpr( * this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
+	virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
@@ -489,8 +508,9 @@
 	void set_arg2( Expression * newValue ) { arg2 = newValue; }
 
-	virtual LogicalExpr * clone() const { return new LogicalExpr( * this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, Indenter indent = {} ) const;
+	virtual LogicalExpr * clone() const override { return new LogicalExpr( * this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
+	virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 
   private:
@@ -516,8 +536,9 @@
 	void set_arg3( Expression * newValue ) { arg3 = newValue; }
 
-	virtual ConditionalExpr * clone() const { return new ConditionalExpr( * this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, Indenter indent = {} ) const;
+	virtual ConditionalExpr * clone() const override { return new ConditionalExpr( * this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
+	virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
@@ -537,8 +558,9 @@
 	void set_arg2( Expression * newValue ) { arg2 = newValue; }
 
-	virtual CommaExpr * clone() const { return new CommaExpr( * this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, Indenter indent = {} ) const;
+	virtual CommaExpr * clone() const override { return new CommaExpr( * this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
+	virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
@@ -555,8 +577,9 @@
 	void set_type( Type * newValue ) { type = newValue; }
 
-	virtual TypeExpr * clone() const { return new TypeExpr( * this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, Indenter indent = {} ) const;
+	virtual TypeExpr * clone() const override { return new TypeExpr( * this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
+	virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
@@ -581,8 +604,9 @@
 	void set_operand( Expression * newValue ) { operand = newValue; }
 
-	virtual AsmExpr * clone() const { return new AsmExpr( * this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, Indenter indent = {} ) const;
+	virtual AsmExpr * clone() const override { return new AsmExpr( * this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
+	virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 
 	// https://gcc.gnu.org/onlinedocs/gcc-4.7.1/gcc/Machine-Constraints.html#Machine-Constraints
@@ -599,8 +623,9 @@
 	virtual ~ImplicitCopyCtorExpr();
 
-	virtual ImplicitCopyCtorExpr * clone() const { return new ImplicitCopyCtorExpr( * this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, Indenter indent = {} ) const;
+	virtual ImplicitCopyCtorExpr * clone() const override { return new ImplicitCopyCtorExpr( * this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
+	virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
@@ -617,8 +642,9 @@
 	void set_callExpr( Expression * newValue ) { callExpr = newValue; }
 
-	virtual ConstructorExpr * clone() const { return new ConstructorExpr( * this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, Indenter indent = {} ) const;
+	virtual ConstructorExpr * clone() const override { return new ConstructorExpr( * this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
+	virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
@@ -635,8 +661,9 @@
 	void set_initializer( Initializer * i ) { initializer = i; }
 
-	virtual CompoundLiteralExpr * clone() const { return new CompoundLiteralExpr( * this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, Indenter indent = {} ) const;
+	virtual CompoundLiteralExpr * clone() const override { return new CompoundLiteralExpr( * this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
+	virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
@@ -654,8 +681,9 @@
 	RangeExpr * set_high( Expression * high ) { RangeExpr::high = high; return this; }
 
-	virtual RangeExpr * clone() const { return new RangeExpr( * this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, Indenter indent = {} ) const;
+	virtual RangeExpr * clone() const override { return new RangeExpr( * this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
+	virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
@@ -671,8 +699,9 @@
 	std::list<Expression*>& get_exprs() { return exprs; }
 
-	virtual UntypedTupleExpr * clone() const { return new UntypedTupleExpr( * this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, Indenter indent = {} ) const;
+	virtual UntypedTupleExpr * clone() const override { return new UntypedTupleExpr( * this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
+	virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
@@ -688,8 +717,9 @@
 	std::list<Expression*>& get_exprs() { return exprs; }
 
-	virtual TupleExpr * clone() const { return new TupleExpr( * this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, Indenter indent = {} ) const;
+	virtual TupleExpr * clone() const override { return new TupleExpr( * this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
+	virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
@@ -709,8 +739,9 @@
 	TupleIndexExpr * set_index( unsigned int newValue ) { index = newValue; return this; }
 
-	virtual TupleIndexExpr * clone() const { return new TupleIndexExpr( * this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, Indenter indent = {} ) const;
+	virtual TupleIndexExpr * clone() const override { return new TupleIndexExpr( * this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
+	virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
@@ -727,8 +758,9 @@
 	StmtExpr * get_stmtExpr() const { return stmtExpr; }
 
-	virtual TupleAssignExpr * clone() const { return new TupleAssignExpr( * this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, Indenter indent = {} ) const;
+	virtual TupleAssignExpr * clone() const override { return new TupleAssignExpr( * this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
+	virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 
 	friend class ConverterNewToOld;
@@ -760,8 +792,9 @@
 	std::list< Expression * > & get_dtors() { return dtors; }
 
-	virtual StmtExpr * clone() const { return new StmtExpr( * this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, Indenter indent = {} ) const;
+	virtual StmtExpr * clone() const override { return new StmtExpr( * this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
+	virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
@@ -787,8 +820,9 @@
 	int get_id() const { return id; }
 
-	virtual UniqueExpr * clone() const { return new UniqueExpr( * this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, Indenter indent = {} ) const;
+	virtual UniqueExpr * clone() const override { return new UniqueExpr( * this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
+	virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 
 private:
@@ -821,8 +855,9 @@
 	std::list<InitAlternative> & get_initAlts() { return initAlts; }
 
-	virtual UntypedInitExpr * clone() const { return new UntypedInitExpr( * this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, Indenter indent = {} ) const;
+	virtual UntypedInitExpr * clone() const override { return new UntypedInitExpr( * this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
+	virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
@@ -842,8 +877,9 @@
 	InitExpr * set_designation( Designation * newValue ) { designation = newValue; return this; }
 
-	virtual InitExpr * clone() const { return new InitExpr( * this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, Indenter indent = {} ) const;
+	virtual InitExpr * clone() const override { return new InitExpr( * this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
+	virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
@@ -852,14 +888,15 @@
 public:
 	Expression * expr;
-	BaseSyntaxNode * deleteStmt;
-
-	DeletedExpr( Expression * expr, BaseSyntaxNode * deleteStmt );
+	Declaration * deleteStmt;
+
+	DeletedExpr( Expression * expr, Declaration * deleteStmt );
 	DeletedExpr( const DeletedExpr & other );
 	~DeletedExpr();
 
-	virtual DeletedExpr * clone() const { return new DeletedExpr( * this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, Indenter indent = {} ) const;
+	virtual DeletedExpr * clone() const override { return new DeletedExpr( * this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
+	virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
@@ -873,8 +910,9 @@
 	~DefaultArgExpr();
 
-	virtual DefaultArgExpr * clone() const { return new DefaultArgExpr( * this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, Indenter indent = {} ) const;
+	virtual DefaultArgExpr * clone() const override { return new DefaultArgExpr( * this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
+	virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
@@ -901,8 +939,9 @@
 	virtual ~GenericExpr();
 
-	virtual GenericExpr * clone() const { return new GenericExpr( * this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, Indenter indent = {} ) const;
+	virtual GenericExpr * clone() const override { return new GenericExpr( * this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
+	virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
Index: src/SynTree/Initializer.h
===================================================================
--- src/SynTree/Initializer.h	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/SynTree/Initializer.h	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -38,5 +38,6 @@
 
 	virtual Designation * clone() const override { return new Designation( *this ); };
-	virtual void accept( Visitor &v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual Designation * acceptMutator( Mutator &m ) override { return m.mutate( this ); }
 	virtual void print( std::ostream &os, Indenter indent = {} ) const override;
@@ -52,8 +53,9 @@
 	virtual ~Initializer();
 
-	bool get_maybeConstructed() { return maybeConstructed; }
+	bool get_maybeConstructed() const { return maybeConstructed; }
 
 	virtual Initializer *clone() const override = 0;
-	virtual void accept( Visitor &v ) override = 0;
+	virtual void accept( Visitor & v ) override = 0;
+	virtual void accept( Visitor & v ) const override = 0;
 	virtual Initializer *acceptMutator( Mutator &m ) override = 0;
 	virtual void print( std::ostream &os, Indenter indent = {} ) const override = 0;
@@ -76,5 +78,6 @@
 
 	virtual SingleInit *clone() const override { return new SingleInit( *this); }
-	virtual void accept( Visitor &v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual Initializer *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
 	virtual void print( std::ostream &os, Indenter indent = {} ) const override;
@@ -104,5 +107,6 @@
 
 	virtual ListInit *clone() const override { return new ListInit( *this ); }
-	virtual void accept( Visitor &v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual Initializer *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
 	virtual void print( std::ostream &os, Indenter indent = {} ) const override;
@@ -133,5 +137,6 @@
 
 	ConstructorInit *clone() const override { return new ConstructorInit( *this ); }
-	virtual void accept( Visitor &v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual Initializer *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
 	virtual void print( std::ostream &os, Indenter indent = {} ) const override;
Index: src/SynTree/Mutator.h
===================================================================
--- src/SynTree/Mutator.h	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/SynTree/Mutator.h	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -52,5 +52,5 @@
 	virtual Statement * mutate( FinallyStmt * catchStmt ) = 0;
 	virtual Statement * mutate( WaitForStmt * waitforStmt ) = 0;
-	virtual Statement * mutate( WithStmt * withStmt ) = 0;
+	virtual Declaration * mutate( WithStmt * withStmt ) = 0;
 	virtual NullStmt * mutate( NullStmt * nullStmt ) = 0;
 	virtual Statement * mutate( DeclStmt * declStmt ) = 0;
Index: src/SynTree/Statement.cc
===================================================================
--- src/SynTree/Statement.cc	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/SynTree/Statement.cc	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -493,6 +493,6 @@
 
 
-WithStmt::WithStmt( const std::list< Expression * > & exprs, Statement * stmt ) : Statement(), exprs( exprs ), stmt( stmt ) {}
-WithStmt::WithStmt( const WithStmt & other ) : Statement( other ), stmt( maybeClone( other.stmt ) ) {
+WithStmt::WithStmt( const std::list< Expression * > & exprs, Statement * stmt ) : Declaration("", noStorageClasses, LinkageSpec::Cforall), exprs( exprs ), stmt( stmt ) {}
+WithStmt::WithStmt( const WithStmt & other ) : Declaration( other ), stmt( maybeClone( other.stmt ) ) {
 	cloneAll( other.exprs, exprs );
 }
Index: src/SynTree/Statement.h
===================================================================
--- src/SynTree/Statement.h	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/SynTree/Statement.h	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -45,4 +45,5 @@
 	virtual Statement * clone() const override = 0;
 	virtual void accept( Visitor & v ) override = 0;
+	virtual void accept( Visitor & v ) const override = 0;
 	virtual Statement * acceptMutator( Mutator & m ) override = 0;
 	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
@@ -64,4 +65,5 @@
 	virtual CompoundStmt * clone() const override { return new CompoundStmt( *this ); }
 	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual CompoundStmt * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
 	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
@@ -74,4 +76,5 @@
 	virtual NullStmt * clone() const override { return new NullStmt( *this ); }
 	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual NullStmt * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
 	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
@@ -91,4 +94,5 @@
 	virtual ExprStmt * clone() const override { return new ExprStmt( *this ); }
 	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
 	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
@@ -120,8 +124,9 @@
 	void set_gotolabels( const std::list<Label> & newValue ) { gotolabels = newValue; }
 
-	virtual AsmStmt * clone() const { return new AsmStmt( *this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Statement * acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, Indenter indent = {} ) const;
+	virtual AsmStmt * clone() const override { return new AsmStmt( *this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
+	virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
@@ -133,8 +138,9 @@
 	virtual ~DirectiveStmt(){}
 
-	virtual DirectiveStmt * clone() const { return new DirectiveStmt( *this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Statement * acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, Indenter indent = {} ) const;
+	virtual DirectiveStmt * clone() const override { return new DirectiveStmt( *this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
+	virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
@@ -161,4 +167,5 @@
 	virtual IfStmt * clone() const override { return new IfStmt( *this ); }
 	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
 	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
@@ -180,4 +187,5 @@
 
 	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
 
@@ -208,4 +216,5 @@
 
 	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
 
@@ -236,4 +245,5 @@
 	virtual WhileStmt * clone() const override { return new WhileStmt( *this ); }
 	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
 	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
@@ -261,4 +271,5 @@
 	virtual ForStmt * clone() const override { return new ForStmt( *this ); }
 	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
 	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
@@ -290,4 +301,5 @@
 	virtual BranchStmt * clone() const override { return new BranchStmt( *this ); }
 	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
 	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
@@ -309,4 +321,5 @@
 	virtual ReturnStmt * clone() const override { return new ReturnStmt( *this ); }
 	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
 	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
@@ -333,4 +346,5 @@
 	virtual ThrowStmt * clone() const override { return new ThrowStmt( *this ); }
 	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
 	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
@@ -356,4 +370,5 @@
 	virtual TryStmt * clone() const override { return new TryStmt( *this ); }
 	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
 	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
@@ -384,4 +399,5 @@
 	virtual CatchStmt * clone() const override { return new CatchStmt( *this ); }
 	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
 	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
@@ -401,4 +417,5 @@
 	virtual FinallyStmt * clone() const override { return new FinallyStmt( *this ); }
 	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
 	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
@@ -438,23 +455,25 @@
 	virtual WaitForStmt * clone() const override { return new WaitForStmt( *this ); }
 	virtual void accept( Visitor & v ) override { v.visit( this ); }
-	virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
-	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
-
-};
-
-class WithStmt : public Statement {
-public:
-	std::list< Expression * > exprs;
-	Statement * stmt;
-
-	WithStmt( const std::list< Expression * > & exprs, Statement * stmt );
-	WithStmt( const WithStmt & other );
-	virtual ~WithStmt();
-
-	virtual WithStmt * clone() const override { return new WithStmt( *this ); }
-	virtual void accept( Visitor & v ) override { v.visit( this ); }
-	virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
-	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
-};
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
+	virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
+
+};
+
+// class WithStmt : public Statement {
+// public:
+// 	std::list< Expression * > exprs;
+// 	Statement * stmt;
+
+// 	WithStmt( const std::list< Expression * > & exprs, Statement * stmt );
+// 	WithStmt( const WithStmt & other );
+// 	virtual ~WithStmt();
+
+// 	virtual WithStmt * clone() const override { return new WithStmt( *this ); }
+// 	virtual void accept( Visitor & v ) override { v.visit( this ); }
+// 	virtual void accept( Visitor & v ) const override { v.visit( this ); }
+// 	virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
+// 	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
+// };
 
 
@@ -473,4 +492,5 @@
 	virtual DeclStmt * clone() const override { return new DeclStmt( *this ); }
 	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
 	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
@@ -494,4 +514,5 @@
 	virtual ImplicitCtorDtorStmt * clone() const override { return new ImplicitCtorDtorStmt( *this ); }
 	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
 	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
Index: src/SynTree/Type.h
===================================================================
--- src/SynTree/Type.h	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/SynTree/Type.h	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -144,10 +144,10 @@
 
 	Qualifiers & get_qualifiers() { return tq; }
-	bool get_const() { return tq.is_const; }
-	bool get_volatile() { return tq.is_volatile; }
-	bool get_restrict() { return tq.is_restrict; }
-	bool get_lvalue() { return tq.is_lvalue; }
-	bool get_mutex() { return tq.is_mutex; }
-	bool get_atomic() { return tq.is_atomic; }
+	bool get_const() const { return tq.is_const; }
+	bool get_volatile() const { return tq.is_volatile; }
+	bool get_restrict() const { return tq.is_restrict; }
+	bool get_lvalue() const { return tq.is_lvalue; }
+	bool get_mutex() const { return tq.is_mutex; }
+	bool get_atomic() const { return tq.is_atomic; }
 	void set_const( bool newValue ) { tq.is_const = newValue; }
 	void set_volatile( bool newValue ) { tq.is_volatile = newValue; }
@@ -184,4 +184,5 @@
 	virtual Type *clone() const = 0;
 	virtual void accept( Visitor & v ) = 0;
+	virtual void accept( Visitor & v ) const = 0;
 	virtual Type *acceptMutator( Mutator & m ) = 0;
 	virtual void print( std::ostream & os, Indenter indent = {} ) const;
@@ -201,4 +202,5 @@
 	virtual VoidType *clone() const override { return new VoidType( *this ); }
 	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
 	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
@@ -259,4 +261,5 @@
 	virtual BasicType *clone() const override { return new BasicType( *this ); }
 	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
 	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
@@ -294,4 +297,5 @@
 	virtual PointerType *clone() const override { return new PointerType( *this ); }
 	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
 	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
@@ -325,4 +329,5 @@
 	virtual ArrayType *clone() const override { return new ArrayType( *this ); }
 	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
 	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
@@ -340,4 +345,5 @@
 	virtual QualifiedType *clone() const override { return new QualifiedType( *this ); }
 	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
 	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
@@ -366,4 +372,5 @@
 	virtual ReferenceType *clone() const override { return new ReferenceType( *this ); }
 	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
 	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
@@ -395,4 +402,5 @@
 	virtual FunctionType *clone() const override { return new FunctionType( *this ); }
 	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
 	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
@@ -455,4 +463,5 @@
 	virtual StructInstType *clone() const override { return new StructInstType( *this ); }
 	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
 
@@ -492,4 +501,5 @@
 	virtual UnionInstType *clone() const override { return new UnionInstType( *this ); }
 	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
 
@@ -519,4 +529,5 @@
 	virtual EnumInstType *clone() const override { return new EnumInstType( *this ); }
 	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
 
@@ -542,4 +553,5 @@
 	virtual TraitInstType *clone() const override { return new TraitInstType( *this ); }
 	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
   private:
@@ -569,4 +581,5 @@
 	virtual TypeInstType *clone() const override { return new TypeInstType( *this ); }
 	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
 	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
@@ -606,4 +619,5 @@
 	virtual TupleType *clone() const override { return new TupleType( *this ); }
 	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
 	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
@@ -616,5 +630,5 @@
 
 	TypeofType( const Type::Qualifiers & tq, Expression *expr, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
-	TypeofType( const Type::Qualifiers & tq, Expression *expr, bool is_basetypeof, 
+	TypeofType( const Type::Qualifiers & tq, Expression *expr, bool is_basetypeof,
 		const std::list< Attribute * > & attributes = std::list< Attribute * >() );
 	TypeofType( const TypeofType& );
@@ -628,4 +642,5 @@
 	virtual TypeofType *clone() const override { return new TypeofType( *this ); }
 	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
 	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
@@ -657,4 +672,5 @@
 	virtual AttrType *clone() const override { return new AttrType( *this ); }
 	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
 	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
@@ -671,4 +687,5 @@
 	virtual VarArgsType *clone() const override { return new VarArgsType( *this ); }
 	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
 	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
@@ -683,4 +700,5 @@
 	virtual ZeroType *clone() const override { return new ZeroType( *this ); }
 	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
 	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
@@ -695,4 +713,5 @@
 	virtual OneType *clone() const override { return new OneType( *this ); }
 	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
 	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
@@ -705,4 +724,5 @@
 	virtual GlobalScopeType *clone() const override { return new GlobalScopeType( *this ); }
 	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
 	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
Index: src/SynTree/Visitor.h
===================================================================
--- src/SynTree/Visitor.h	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/SynTree/Visitor.h	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -27,107 +27,200 @@
 	// of the given syntax node, but performs no other action.
 
-	virtual void visit( ObjectDecl * objectDecl ) = 0;
-	virtual void visit( FunctionDecl * functionDecl ) = 0;
-	virtual void visit( StructDecl * aggregateDecl ) = 0;
-	virtual void visit( UnionDecl * aggregateDecl ) = 0;
-	virtual void visit( EnumDecl * aggregateDecl ) = 0;
-	virtual void visit( TraitDecl * aggregateDecl ) = 0;
-	virtual void visit( TypeDecl * typeDecl ) = 0;
-	virtual void visit( TypedefDecl * typeDecl ) = 0;
-	virtual void visit( AsmDecl * asmDecl ) = 0;
-	virtual void visit( StaticAssertDecl * assertDecl ) = 0;
-
-	virtual void visit( CompoundStmt * compoundStmt ) = 0;
-	virtual void visit( ExprStmt * exprStmt ) = 0;
-	virtual void visit( AsmStmt * asmStmt ) = 0;
-	virtual void visit( DirectiveStmt * directiveStmt ) = 0;
-	virtual void visit( IfStmt * ifStmt ) = 0;
-	virtual void visit( WhileStmt * whileStmt ) = 0;
-	virtual void visit( ForStmt * forStmt ) = 0;
-	virtual void visit( SwitchStmt * switchStmt ) = 0;
-	virtual void visit( CaseStmt * caseStmt ) = 0;
-	virtual void visit( BranchStmt * branchStmt ) = 0;
-	virtual void visit( ReturnStmt * returnStmt ) = 0;
-	virtual void visit( ThrowStmt * throwStmt ) = 0;
-	virtual void visit( TryStmt * tryStmt ) = 0;
-	virtual void visit( CatchStmt * catchStmt ) = 0;
-	virtual void visit( FinallyStmt * finallyStmt ) = 0;
-	virtual void visit( WaitForStmt * waitforStmt ) = 0;
-	virtual void visit( WithStmt * withStmt ) = 0;
-	virtual void visit( NullStmt * nullStmt ) = 0;
-	virtual void visit( DeclStmt * declStmt ) = 0;
-	virtual void visit( ImplicitCtorDtorStmt * impCtorDtorStmt ) = 0;
-
-	virtual void visit( ApplicationExpr * applicationExpr ) = 0;
-	virtual void visit( UntypedExpr * untypedExpr ) = 0;
-	virtual void visit( NameExpr * nameExpr ) = 0;
-	virtual void visit( CastExpr * castExpr ) = 0;
-	virtual void visit( KeywordCastExpr * castExpr ) = 0;
-	virtual void visit( VirtualCastExpr * castExpr ) = 0;
-	virtual void visit( AddressExpr * addressExpr ) = 0;
-	virtual void visit( LabelAddressExpr * labAddressExpr ) = 0;
-	virtual void visit( UntypedMemberExpr * memberExpr ) = 0;
-	virtual void visit( MemberExpr * memberExpr ) = 0;
-	virtual void visit( VariableExpr * variableExpr ) = 0;
-	virtual void visit( ConstantExpr * constantExpr ) = 0;
-	virtual void visit( SizeofExpr * sizeofExpr ) = 0;
-	virtual void visit( AlignofExpr * alignofExpr ) = 0;
-	virtual void visit( UntypedOffsetofExpr * offsetofExpr ) = 0;
-	virtual void visit( OffsetofExpr * offsetofExpr ) = 0;
-	virtual void visit( OffsetPackExpr * offsetPackExpr ) = 0;
-	virtual void visit( AttrExpr * attrExpr ) = 0;
-	virtual void visit( LogicalExpr * logicalExpr ) = 0;
-	virtual void visit( ConditionalExpr * conditionalExpr ) = 0;
-	virtual void visit( CommaExpr * commaExpr ) = 0;
-	virtual void visit( TypeExpr * typeExpr ) = 0;
-	virtual void visit( AsmExpr * asmExpr ) = 0;
-	virtual void visit( ImplicitCopyCtorExpr * impCpCtorExpr ) = 0;
-	virtual void visit( ConstructorExpr *  ctorExpr ) = 0;
-	virtual void visit( CompoundLiteralExpr * compLitExpr ) = 0;
-	virtual void visit( RangeExpr * rangeExpr ) = 0;
-	virtual void visit( UntypedTupleExpr * tupleExpr ) = 0;
-	virtual void visit( TupleExpr * tupleExpr ) = 0;
-	virtual void visit( TupleIndexExpr * tupleExpr ) = 0;
-	virtual void visit( TupleAssignExpr * assignExpr ) = 0;
-	virtual void visit( StmtExpr *  stmtExpr ) = 0;
-	virtual void visit( UniqueExpr *  uniqueExpr ) = 0;
-	virtual void visit( UntypedInitExpr *  initExpr ) = 0;
-	virtual void visit( InitExpr *  initExpr ) = 0;
-	virtual void visit( DeletedExpr * delExpr ) = 0;
-	virtual void visit( DefaultArgExpr * argExpr ) = 0;
-	virtual void visit( GenericExpr * genExpr ) = 0;
-
-	virtual void visit( VoidType * basicType ) = 0;
-	virtual void visit( BasicType * basicType ) = 0;
-	virtual void visit( PointerType * pointerType ) = 0;
-	virtual void visit( ArrayType * arrayType ) = 0;
-	virtual void visit( ReferenceType * refType ) = 0;
-	virtual void visit( QualifiedType * qualType ) = 0;
-	virtual void visit( FunctionType * functionType ) = 0;
-	virtual void visit( StructInstType * aggregateUseType ) = 0;
-	virtual void visit( UnionInstType * aggregateUseType ) = 0;
-	virtual void visit( EnumInstType * aggregateUseType ) = 0;
-	virtual void visit( TraitInstType * aggregateUseType ) = 0;
-	virtual void visit( TypeInstType * aggregateUseType ) = 0;
-	virtual void visit( TupleType * tupleType ) = 0;
-	virtual void visit( TypeofType * typeofType ) = 0;
-	virtual void visit( AttrType * attrType ) = 0;
-	virtual void visit( VarArgsType * varArgsType ) = 0;
-	virtual void visit( ZeroType * zeroType ) = 0;
-	virtual void visit( OneType * oneType ) = 0;
-	virtual void visit( GlobalScopeType * globalType ) = 0;
-
-	virtual void visit( Designation * designation ) = 0;
-	virtual void visit( SingleInit * singleInit ) = 0;
-	virtual void visit( ListInit * listInit ) = 0;
-	virtual void visit( ConstructorInit * ctorInit ) = 0;
-
-	virtual void visit( Constant * constant ) = 0;
-
-	virtual void visit( Attribute * attribute ) = 0;
+	virtual void visit( ObjectDecl * node ) { visit( const_cast<const ObjectDecl *>(node) ); }
+	virtual void visit( const ObjectDecl * objectDecl ) = 0;
+	virtual void visit( FunctionDecl * node ) { visit( const_cast<const FunctionDecl *>(node) ); }
+	virtual void visit( const FunctionDecl * functionDecl ) = 0;
+	virtual void visit( StructDecl * node ) { visit( const_cast<const StructDecl *>(node) ); }
+	virtual void visit( const StructDecl * aggregateDecl ) = 0;
+	virtual void visit( UnionDecl * node ) { visit( const_cast<const UnionDecl *>(node) ); }
+	virtual void visit( const UnionDecl * aggregateDecl ) = 0;
+	virtual void visit( EnumDecl * node ) { visit( const_cast<const EnumDecl *>(node) ); }
+	virtual void visit( const EnumDecl * aggregateDecl ) = 0;
+	virtual void visit( TraitDecl * node ) { visit( const_cast<const TraitDecl *>(node) ); }
+	virtual void visit( const TraitDecl * aggregateDecl ) = 0;
+	virtual void visit( TypeDecl * node ) { visit( const_cast<const TypeDecl *>(node) ); }
+	virtual void visit( const TypeDecl * typeDecl ) = 0;
+	virtual void visit( TypedefDecl * node ) { visit( const_cast<const TypedefDecl *>(node) ); }
+	virtual void visit( const TypedefDecl * typeDecl ) = 0;
+	virtual void visit( AsmDecl * node ) { visit( const_cast<const AsmDecl *>(node) ); }
+	virtual void visit( const AsmDecl * asmDecl ) = 0;
+	virtual void visit( StaticAssertDecl * node ) { visit( const_cast<const StaticAssertDecl *>(node) ); }
+	virtual void visit( const StaticAssertDecl * assertDecl ) = 0;
+
+	virtual void visit( CompoundStmt * node ) { visit( const_cast<const CompoundStmt *>(node) ); }
+	virtual void visit( const CompoundStmt * compoundStmt ) = 0;
+	virtual void visit( ExprStmt * node ) { visit( const_cast<const ExprStmt *>(node) ); }
+	virtual void visit( const ExprStmt * exprStmt ) = 0;
+	virtual void visit( AsmStmt * node ) { visit( const_cast<const AsmStmt *>(node) ); }
+	virtual void visit( const AsmStmt * asmStmt ) = 0;
+	virtual void visit( DirectiveStmt * node ) { visit( const_cast<const DirectiveStmt *>(node) ); }
+	virtual void visit( const DirectiveStmt * directiveStmt ) = 0;
+	virtual void visit( IfStmt * node ) { visit( const_cast<const IfStmt *>(node) ); }
+	virtual void visit( const IfStmt * ifStmt ) = 0;
+	virtual void visit( WhileStmt * node ) { visit( const_cast<const WhileStmt *>(node) ); }
+	virtual void visit( const WhileStmt * whileStmt ) = 0;
+	virtual void visit( ForStmt * node ) { visit( const_cast<const ForStmt *>(node) ); }
+	virtual void visit( const ForStmt * forStmt ) = 0;
+	virtual void visit( SwitchStmt * node ) { visit( const_cast<const SwitchStmt *>(node) ); }
+	virtual void visit( const SwitchStmt * switchStmt ) = 0;
+	virtual void visit( CaseStmt * node ) { visit( const_cast<const CaseStmt *>(node) ); }
+	virtual void visit( const CaseStmt * caseStmt ) = 0;
+	virtual void visit( BranchStmt * node ) { visit( const_cast<const BranchStmt *>(node) ); }
+	virtual void visit( const BranchStmt * branchStmt ) = 0;
+	virtual void visit( ReturnStmt * node ) { visit( const_cast<const ReturnStmt *>(node) ); }
+	virtual void visit( const ReturnStmt * returnStmt ) = 0;
+	virtual void visit( ThrowStmt * node ) { visit( const_cast<const ThrowStmt *>(node) ); }
+	virtual void visit( const ThrowStmt * throwStmt ) = 0;
+	virtual void visit( TryStmt * node ) { visit( const_cast<const TryStmt *>(node) ); }
+	virtual void visit( const TryStmt * tryStmt ) = 0;
+	virtual void visit( CatchStmt * node ) { visit( const_cast<const CatchStmt *>(node) ); }
+	virtual void visit( const CatchStmt * catchStmt ) = 0;
+	virtual void visit( FinallyStmt * node ) { visit( const_cast<const FinallyStmt *>(node) ); }
+	virtual void visit( const FinallyStmt * finallyStmt ) = 0;
+	virtual void visit( WaitForStmt * node ) { visit( const_cast<const WaitForStmt *>(node) ); }
+	virtual void visit( const WaitForStmt * waitforStmt ) = 0;
+	virtual void visit( WithStmt * node ) { visit( const_cast<const WithStmt *>(node) ); }
+	virtual void visit( const WithStmt * withStmt ) = 0;
+	virtual void visit( NullStmt * node ) { visit( const_cast<const NullStmt *>(node) ); }
+	virtual void visit( const NullStmt * nullStmt ) = 0;
+	virtual void visit( DeclStmt * node ) { visit( const_cast<const DeclStmt *>(node) ); }
+	virtual void visit( const DeclStmt * declStmt ) = 0;
+	virtual void visit( ImplicitCtorDtorStmt * node ) { visit( const_cast<const ImplicitCtorDtorStmt *>(node) ); }
+	virtual void visit( const ImplicitCtorDtorStmt * impCtorDtorStmt ) = 0;
+
+	virtual void visit( ApplicationExpr * node ) { visit( const_cast<const ApplicationExpr *>(node) ); }
+	virtual void visit( const ApplicationExpr * applicationExpr ) = 0;
+	virtual void visit( UntypedExpr * node ) { visit( const_cast<const UntypedExpr *>(node) ); }
+	virtual void visit( const UntypedExpr * untypedExpr ) = 0;
+	virtual void visit( NameExpr * node ) { visit( const_cast<const NameExpr *>(node) ); }
+	virtual void visit( const NameExpr * nameExpr ) = 0;
+	virtual void visit( CastExpr * node ) { visit( const_cast<const CastExpr *>(node) ); }
+	virtual void visit( const CastExpr * castExpr ) = 0;
+	virtual void visit( KeywordCastExpr * node ) { visit( const_cast<const KeywordCastExpr *>(node) ); }
+	virtual void visit( const KeywordCastExpr * castExpr ) = 0;
+	virtual void visit( VirtualCastExpr * node ) { visit( const_cast<const VirtualCastExpr *>(node) ); }
+	virtual void visit( const VirtualCastExpr * castExpr ) = 0;
+	virtual void visit( AddressExpr * node ) { visit( const_cast<const AddressExpr *>(node) ); }
+	virtual void visit( const AddressExpr * addressExpr ) = 0;
+	virtual void visit( LabelAddressExpr * node ) { visit( const_cast<const LabelAddressExpr *>(node) ); }
+	virtual void visit( const LabelAddressExpr * labAddressExpr ) = 0;
+	virtual void visit( UntypedMemberExpr * node ) { visit( const_cast<const UntypedMemberExpr *>(node) ); }
+	virtual void visit( const UntypedMemberExpr * memberExpr ) = 0;
+	virtual void visit( MemberExpr * node ) { visit( const_cast<const MemberExpr *>(node) ); }
+	virtual void visit( const MemberExpr * memberExpr ) = 0;
+	virtual void visit( VariableExpr * node ) { visit( const_cast<const VariableExpr *>(node) ); }
+	virtual void visit( const VariableExpr * variableExpr ) = 0;
+	virtual void visit( ConstantExpr * node ) { visit( const_cast<const ConstantExpr *>(node) ); }
+	virtual void visit( const ConstantExpr * constantExpr ) = 0;
+	virtual void visit( SizeofExpr * node ) { visit( const_cast<const SizeofExpr *>(node) ); }
+	virtual void visit( const SizeofExpr * sizeofExpr ) = 0;
+	virtual void visit( AlignofExpr * node ) { visit( const_cast<const AlignofExpr *>(node) ); }
+	virtual void visit( const AlignofExpr * alignofExpr ) = 0;
+	virtual void visit( UntypedOffsetofExpr * node ) { visit( const_cast<const UntypedOffsetofExpr *>(node) ); }
+	virtual void visit( const UntypedOffsetofExpr * offsetofExpr ) = 0;
+	virtual void visit( OffsetofExpr * node ) { visit( const_cast<const OffsetofExpr *>(node) ); }
+	virtual void visit( const OffsetofExpr * offsetofExpr ) = 0;
+	virtual void visit( OffsetPackExpr * node ) { visit( const_cast<const OffsetPackExpr *>(node) ); }
+	virtual void visit( const OffsetPackExpr * offsetPackExpr ) = 0;
+	virtual void visit( AttrExpr * node ) { visit( const_cast<const AttrExpr *>(node) ); }
+	virtual void visit( const AttrExpr * attrExpr ) = 0;
+	virtual void visit( LogicalExpr * node ) { visit( const_cast<const LogicalExpr *>(node) ); }
+	virtual void visit( const LogicalExpr * logicalExpr ) = 0;
+	virtual void visit( ConditionalExpr * node ) { visit( const_cast<const ConditionalExpr *>(node) ); }
+	virtual void visit( const ConditionalExpr * conditionalExpr ) = 0;
+	virtual void visit( CommaExpr * node ) { visit( const_cast<const CommaExpr *>(node) ); }
+	virtual void visit( const CommaExpr * commaExpr ) = 0;
+	virtual void visit( TypeExpr * node ) { visit( const_cast<const TypeExpr *>(node) ); }
+	virtual void visit( const TypeExpr * typeExpr ) = 0;
+	virtual void visit( AsmExpr * node ) { visit( const_cast<const AsmExpr *>(node) ); }
+	virtual void visit( const AsmExpr * asmExpr ) = 0;
+	virtual void visit( ImplicitCopyCtorExpr * node ) { visit( const_cast<const ImplicitCopyCtorExpr *>(node) ); }
+	virtual void visit( const ImplicitCopyCtorExpr * impCpCtorExpr ) = 0;
+	virtual void visit( ConstructorExpr * node ) { visit( const_cast<const ConstructorExpr *>(node) ); }
+	virtual void visit( const ConstructorExpr *  ctorExpr ) = 0;
+	virtual void visit( CompoundLiteralExpr * node ) { visit( const_cast<const CompoundLiteralExpr *>(node) ); }
+	virtual void visit( const CompoundLiteralExpr * compLitExpr ) = 0;
+	virtual void visit( RangeExpr * node ) { visit( const_cast<const RangeExpr *>(node) ); }
+	virtual void visit( const RangeExpr * rangeExpr ) = 0;
+	virtual void visit( UntypedTupleExpr * node ) { visit( const_cast<const UntypedTupleExpr *>(node) ); }
+	virtual void visit( const UntypedTupleExpr * tupleExpr ) = 0;
+	virtual void visit( TupleExpr * node ) { visit( const_cast<const TupleExpr *>(node) ); }
+	virtual void visit( const TupleExpr * tupleExpr ) = 0;
+	virtual void visit( TupleIndexExpr * node ) { visit( const_cast<const TupleIndexExpr *>(node) ); }
+	virtual void visit( const TupleIndexExpr * tupleExpr ) = 0;
+	virtual void visit( TupleAssignExpr * node ) { visit( const_cast<const TupleAssignExpr *>(node) ); }
+	virtual void visit( const TupleAssignExpr * assignExpr ) = 0;
+	virtual void visit( StmtExpr * node ) { visit( const_cast<const StmtExpr *>(node) ); }
+	virtual void visit( const StmtExpr *  stmtExpr ) = 0;
+	virtual void visit( UniqueExpr * node ) { visit( const_cast<const UniqueExpr *>(node) ); }
+	virtual void visit( const UniqueExpr *  uniqueExpr ) = 0;
+	virtual void visit( UntypedInitExpr * node ) { visit( const_cast<const UntypedInitExpr *>(node) ); }
+	virtual void visit( const UntypedInitExpr *  initExpr ) = 0;
+	virtual void visit( InitExpr * node ) { visit( const_cast<const InitExpr *>(node) ); }
+	virtual void visit( const InitExpr *  initExpr ) = 0;
+	virtual void visit( DeletedExpr * node ) { visit( const_cast<const DeletedExpr *>(node) ); }
+	virtual void visit( const DeletedExpr * delExpr ) = 0;
+	virtual void visit( DefaultArgExpr * node ) { visit( const_cast<const DefaultArgExpr *>(node) ); }
+	virtual void visit( const DefaultArgExpr * argExpr ) = 0;
+	virtual void visit( GenericExpr * node ) { visit( const_cast<const GenericExpr *>(node) ); }
+	virtual void visit( const GenericExpr * genExpr ) = 0;
+
+	virtual void visit( VoidType * node ) { visit( const_cast<const VoidType *>(node) ); }
+	virtual void visit( const VoidType * basicType ) = 0;
+	virtual void visit( BasicType * node ) { visit( const_cast<const BasicType *>(node) ); }
+	virtual void visit( const BasicType * basicType ) = 0;
+	virtual void visit( PointerType * node ) { visit( const_cast<const PointerType *>(node) ); }
+	virtual void visit( const PointerType * pointerType ) = 0;
+	virtual void visit( ArrayType * node ) { visit( const_cast<const ArrayType *>(node) ); }
+	virtual void visit( const ArrayType * arrayType ) = 0;
+	virtual void visit( ReferenceType * node ) { visit( const_cast<const ReferenceType *>(node) ); }
+	virtual void visit( const ReferenceType * refType ) = 0;
+	virtual void visit( QualifiedType * node ) { visit( const_cast<const QualifiedType *>(node) ); }
+	virtual void visit( const QualifiedType * qualType ) = 0;
+	virtual void visit( FunctionType * node ) { visit( const_cast<const FunctionType *>(node) ); }
+	virtual void visit( const FunctionType * functionType ) = 0;
+	virtual void visit( StructInstType * node ) { visit( const_cast<const StructInstType *>(node) ); }
+	virtual void visit( const StructInstType * aggregateUseType ) = 0;
+	virtual void visit( UnionInstType * node ) { visit( const_cast<const UnionInstType *>(node) ); }
+	virtual void visit( const UnionInstType * aggregateUseType ) = 0;
+	virtual void visit( EnumInstType * node ) { visit( const_cast<const EnumInstType *>(node) ); }
+	virtual void visit( const EnumInstType * aggregateUseType ) = 0;
+	virtual void visit( TraitInstType * node ) { visit( const_cast<const TraitInstType *>(node) ); }
+	virtual void visit( const TraitInstType * aggregateUseType ) = 0;
+	virtual void visit( TypeInstType * node ) { visit( const_cast<const TypeInstType *>(node) ); }
+	virtual void visit( const TypeInstType * aggregateUseType ) = 0;
+	virtual void visit( TupleType * node ) { visit( const_cast<const TupleType *>(node) ); }
+	virtual void visit( const TupleType * tupleType ) = 0;
+	virtual void visit( TypeofType * node ) { visit( const_cast<const TypeofType *>(node) ); }
+	virtual void visit( const TypeofType * typeofType ) = 0;
+	virtual void visit( AttrType * node ) { visit( const_cast<const AttrType *>(node) ); }
+	virtual void visit( const AttrType * attrType ) = 0;
+	virtual void visit( VarArgsType * node ) { visit( const_cast<const VarArgsType *>(node) ); }
+	virtual void visit( const VarArgsType * varArgsType ) = 0;
+	virtual void visit( ZeroType * node ) { visit( const_cast<const ZeroType *>(node) ); }
+	virtual void visit( const ZeroType * zeroType ) = 0;
+	virtual void visit( OneType * node ) { visit( const_cast<const OneType *>(node) ); }
+	virtual void visit( const OneType * oneType ) = 0;
+	virtual void visit( GlobalScopeType * node ) { visit( const_cast<const GlobalScopeType *>(node) ); }
+	virtual void visit( const GlobalScopeType * globalType ) = 0;
+
+	virtual void visit( Designation * node ) { visit( const_cast<const Designation *>(node) ); }
+	virtual void visit( const Designation * designation ) = 0;
+	virtual void visit( SingleInit * node ) { visit( const_cast<const SingleInit *>(node) ); }
+	virtual void visit( const SingleInit * singleInit ) = 0;
+	virtual void visit( ListInit * node ) { visit( const_cast<const ListInit *>(node) ); }
+	virtual void visit( const ListInit * listInit ) = 0;
+	virtual void visit( ConstructorInit * node ) { visit( const_cast<const ConstructorInit *>(node) ); }
+	virtual void visit( const ConstructorInit * ctorInit ) = 0;
+
+	virtual void visit( Constant * node ) { visit( const_cast<const Constant *>(node) ); }
+	virtual void visit( const Constant * constant ) = 0;
+
+	virtual void visit( Attribute * node ) { visit( const_cast<const Attribute *>(node) ); }
+	virtual void visit( const Attribute * attribute ) = 0;
 };
 
 template< typename TreeType, typename VisitorType >
-inline void maybeAccept( TreeType *tree, VisitorType &visitor ) {
+inline void maybeAccept( TreeType * tree, VisitorType & visitor ) {
 	if ( tree ) {
 		tree->accept( visitor );
@@ -135,11 +228,35 @@
 }
 
+template< typename TreeType, typename VisitorType >
+inline void maybeAccept( const TreeType * tree, VisitorType & visitor ) {
+	if ( tree ) {
+		tree->accept( visitor );
+	}
+}
+
 template< typename Container, typename VisitorType >
-inline void acceptAll( Container &container, VisitorType &visitor ) {
+inline void acceptAll( Container & container, VisitorType & visitor ) {
 	SemanticErrorException errors;
-	for ( typename Container::iterator i = container.begin(); i != container.end(); ++i ) {
+	for ( auto * i : container ) {
 		try {
-			if ( *i ) {
-				(*i)->accept( visitor );
+			if ( i ) {
+				i->accept( visitor );
+			}
+		} catch( SemanticErrorException & e ) {
+			errors.append( e );
+		}
+	}
+	if ( ! errors.isEmpty() ) {
+		throw errors;
+	}
+}
+
+template< typename Container, typename VisitorType >
+inline void acceptAll( const Container & container, VisitorType & visitor ) {
+	SemanticErrorException errors;
+	for ( const auto * i : container ) {
+		try {
+			if ( i ) {
+				i->accept( visitor );
 			}
 		} catch( SemanticErrorException &e ) {
Index: src/Tuples/Explode.h
===================================================================
--- src/Tuples/Explode.h	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/Tuples/Explode.h	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -51,5 +51,5 @@
 	template<typename OutputIterator>
 	void append( OutputIterator out, Expression* expr, const ResolvExpr::TypeEnvironment& env,
-			const ResolvExpr::OpenVarSet& openVars, const ResolvExpr::AssertionList& need, 
+			const ResolvExpr::OpenVarSet& openVars, const ResolvExpr::AssertionList& need,
 			const ResolvExpr::Cost& cost, const ResolvExpr::Cost& cvtCost ) {
 		*out++ = ResolvExpr::Alternative{ expr, env, openVars, need, cost, cvtCost };
@@ -58,5 +58,5 @@
 	/// Append alternative to an ExplodedActual
 	static inline void append( ResolvExpr::ExplodedActual& ea, Expression* expr,
-			const ResolvExpr::TypeEnvironment&, const ResolvExpr::OpenVarSet&, 
+			const ResolvExpr::TypeEnvironment&, const ResolvExpr::OpenVarSet&,
 			const ResolvExpr::AssertionList&, const ResolvExpr::Cost&, const ResolvExpr::Cost& ) {
 		ea.exprs.emplace_back( expr );
@@ -111,5 +111,5 @@
 		} else {
 			// atomic (non-tuple) type - output a clone of the expression in a new alternative
-			append( std::forward<Output>(out), expr->clone(), alt.env, alt.openVars, alt.need,  
+			append( std::forward<Output>(out), expr->clone(), alt.env, alt.openVars, alt.need,
 				alt.cost, alt.cvtCost );
 		}
@@ -174,6 +174,6 @@
 template< typename Output >
 void explodeRecursive(
-	const ast::CastExpr * expr, const ResolvExpr::Candidate & arg,
-	const ast::SymbolTable & symtab, Output && out
+	const ast::CastExpr *, const ResolvExpr::Candidate &,
+	const ast::SymbolTable &, Output &&
 ) {
 }
@@ -239,6 +239,6 @@
 /// explode list of candidates into flattened list of candidates
 template< typename Output >
-void explode( 
-	const ResolvExpr::CandidateList & cands, const ast::SymbolTable & symtab, Output && out, 
+void explode(
+	const ResolvExpr::CandidateList & cands, const ast::SymbolTable & symtab, Output && out,
 	bool isTupleAssign = false
 ) {
Index: src/Tuples/TupleAssignment.cc
===================================================================
--- src/Tuples/TupleAssignment.cc	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/Tuples/TupleAssignment.cc	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -67,8 +67,8 @@
 		struct Matcher {
 		  public:
-			Matcher( TupleAssignSpotter_old &spotter, const ResolvExpr::AltList& lhs, 
+			Matcher( TupleAssignSpotter_old &spotter, const ResolvExpr::AltList& lhs,
 				const ResolvExpr::AltList& rhs );
 			virtual ~Matcher() {}
-			
+
 			virtual void match( std::list< Expression * > &out ) = 0;
 			ObjectDecl * newObject( UniqueName & namer, Expression * expr );
@@ -83,5 +83,5 @@
 				for ( const ResolvExpr::Alternative& alt : alts ) { combineState( alt ); }
 			}
-			
+
 			ResolvExpr::AltList lhs, rhs;
 			TupleAssignSpotter_old &spotter;
@@ -264,5 +264,5 @@
 		}
 
-		// extract expressions from the assignment alternatives to produce a list of assignments 
+		// extract expressions from the assignment alternatives to produce a list of assignments
 		// that together form a single alternative
 		std::list< Expression *> solved_assigns;
@@ -271,10 +271,10 @@
 			matcher->combineState( alt );
 		}
-		
+
 		// xxx -- was push_front
 		currentFinder.get_alternatives().push_back( ResolvExpr::Alternative{
-			new TupleAssignExpr{ solved_assigns, matcher->tmpDecls }, matcher->compositeEnv, 
-			matcher->openVars, 
-			ResolvExpr::AssertionList( matcher->need.begin(), matcher->need.end() ), 
+			new TupleAssignExpr{ solved_assigns, matcher->tmpDecls }, matcher->compositeEnv,
+			matcher->openVars,
+			ResolvExpr::AssertionList( matcher->need.begin(), matcher->need.end() ),
 			ResolvExpr::sumCost( current ) + matcher->baseCost } );
 	}
@@ -284,5 +284,5 @@
 	: lhs(lhs), rhs(rhs), spotter(spotter),
 	  baseCost( ResolvExpr::sumCost( lhs ) + ResolvExpr::sumCost( rhs ) ) {
-		combineState( lhs ); 
+		combineState( lhs );
 		combineState( rhs );
 	}
@@ -390,5 +390,5 @@
 		return dynamic_cast< const ast::TupleType * >( expr->result->stripReferences() );
 	}
-	
+
 	/// true if `expr` is of tuple type or a reference to one
 	bool refToTuple( const ast::Expr * expr ) {
@@ -421,18 +421,19 @@
 			}
 
-			Matcher( 
+			Matcher(
 				TupleAssignSpotter_new & s, const CodeLocation & loc,
 				const ResolvExpr::CandidateList & l, const ResolvExpr::CandidateList & r )
-			: lhs( l ), rhs( r ), spotter( s ), location( loc ), 
-			  baseCost( ResolvExpr::sumCost( lhs ) + ResolvExpr::sumCost( rhs ) ), tmpDecls(), 
+			: lhs( l ), rhs( r ), spotter( s ), location( loc ),
+			  baseCost( ResolvExpr::sumCost( lhs ) + ResolvExpr::sumCost( rhs ) ), tmpDecls(),
 			  env(), open(), need() {
 				for ( auto & cand : lhs ) combineState( *cand );
 				for ( auto & cand : rhs ) combineState( *cand );
 			}
+			virtual ~Matcher() = default;
 
 			virtual std::vector< ast::ptr< ast::Expr > > match() = 0;
 
-			/// removes environments from subexpressions within statement expressions, which could 
-			/// throw off later passes like those in Box which rely on PolyMutator, and adds the 
+			/// removes environments from subexpressions within statement expressions, which could
+			/// throw off later passes like those in Box which rely on PolyMutator, and adds the
 			/// bindings to the env
 			struct EnvRemover {
@@ -455,13 +456,13 @@
 			ast::ObjectDecl * newObject( UniqueName & namer, const ast::Expr * expr ) {
 				assert( expr->result && ! expr->result->isVoid() );
-				
-				ast::ObjectDecl * ret = new ast::ObjectDecl{ 
-					location, namer.newName(), expr->result, new ast::SingleInit{ location, expr }, 
+
+				ast::ObjectDecl * ret = new ast::ObjectDecl{
+					location, namer.newName(), expr->result, new ast::SingleInit{ location, expr },
 					ast::Storage::Classes{}, ast::Linkage::Cforall };
-				
+
 				// if expression type is a reference, just need an initializer, otherwise construct
 				if ( ! expr->result.as< ast::ReferenceType >() ) {
 					// resolve ctor/dtor for the new object
-					ast::ptr< ast::Init > ctorInit = ResolvExpr::resolveCtorInit( 
+					ast::ptr< ast::Init > ctorInit = ResolvExpr::resolveCtorInit(
 							InitTweak::genCtorInit( location, ret ), spotter.crntFinder.localSyms );
 					// remove environments from subexpressions of stmtExpr
@@ -474,7 +475,7 @@
 			}
 
-			ast::UntypedExpr * createFunc( 
-				const std::string & fname, const ast::ObjectDecl * left, 
-				const ast::ObjectDecl * right 
+			ast::UntypedExpr * createFunc(
+				const std::string & fname, const ast::ObjectDecl * left,
+				const ast::ObjectDecl * right
 			) {
 				assert( left );
@@ -486,8 +487,8 @@
 					args.front() = new ast::AddressExpr{ location, args.front() };
 					if ( right ) { args.back() = new ast::AddressExpr{ location, args.back() }; }
-					return new ast::UntypedExpr{ 
+					return new ast::UntypedExpr{
 						location, new ast::NameExpr{ location, "?=?" }, std::move(args) };
 				} else {
-					return new ast::UntypedExpr{ 
+					return new ast::UntypedExpr{
 						location, new ast::NameExpr{ location, fname }, std::move(args) };
 				}
@@ -498,5 +499,5 @@
 		struct MassAssignMatcher final : public Matcher {
 			MassAssignMatcher(
-				TupleAssignSpotter_new & s, const CodeLocation & loc, 
+				TupleAssignSpotter_new & s, const CodeLocation & loc,
 				const ResolvExpr::CandidateList & l, const ResolvExpr::CandidateList & r )
 			: Matcher( s, loc, l, r ) {}
@@ -508,10 +509,10 @@
 				assert( lhs.empty() ? rhs.empty() : rhs.size() <= 1 );
 
-				ast::ptr< ast::ObjectDecl > rtmp = 
+				ast::ptr< ast::ObjectDecl > rtmp =
 					rhs.size() == 1 ? newObject( rhsNamer, rhs.front()->expr ) : nullptr;
 
 				std::vector< ast::ptr< ast::Expr > > out;
 				for ( ResolvExpr::CandidateRef & lhsCand : lhs ) {
-					// create a temporary object for each value in the LHS and create a call 
+					// create a temporary object for each value in the LHS and create a call
 					// involving the RHS
 					ast::ptr< ast::ObjectDecl > ltmp = newObject( lhsNamer, lhsCand->expr );
@@ -528,5 +529,5 @@
 		struct MultipleAssignMatcher final : public Matcher {
 			MultipleAssignMatcher(
-				TupleAssignSpotter_new & s, const CodeLocation & loc, 
+				TupleAssignSpotter_new & s, const CodeLocation & loc,
 				const ResolvExpr::CandidateList & l, const ResolvExpr::CandidateList & r )
 			: Matcher( s, loc, l, r ) {}
@@ -538,5 +539,5 @@
 				if ( lhs.size() != rhs.size() ) return {};
 
-				// produce a new temporary object for each value in the LHS and RHS and pairwise 
+				// produce a new temporary object for each value in the LHS and RHS and pairwise
 				// create the calls
 				std::vector< ast::ptr< ast::ObjectDecl > > ltmp, rtmp;
@@ -547,5 +548,5 @@
 					ResolvExpr::CandidateRef & rhsCand = rhs[i];
 
-					// convert RHS to LHS type minus one reference -- important for case where LHS 
+					// convert RHS to LHS type minus one reference -- important for case where LHS
 					// is && and RHS is lvalue
 					auto lhsType = lhsCand->expr->result.strict_as< ast::ReferenceType >();
@@ -557,5 +558,5 @@
 					rtmp.emplace_back( std::move( robj ) );
 
-					// resolve the cast expression so that rhsCand return type is bound by the cast 
+					// resolve the cast expression so that rhsCand return type is bound by the cast
 					// type as needed, and transfer the resulting environment
 					ResolvExpr::CandidateFinder finder{ spotter.crntFinder.localSyms, env };
@@ -564,8 +565,8 @@
 					env = std::move( finder.candidates.front()->env );
 				}
-				
+
 				splice( tmpDecls, ltmp );
 				splice( tmpDecls, rtmp );
-				
+
 				return out;
 			}
@@ -575,12 +576,12 @@
 		std::string fname;
 		std::unique_ptr< Matcher > matcher;
-	
+
 	public:
-		TupleAssignSpotter_new( ResolvExpr::CandidateFinder & f ) 
+		TupleAssignSpotter_new( ResolvExpr::CandidateFinder & f )
 		: crntFinder( f ), fname(), matcher() {}
 
 		// find left- and right-hand-sides for mass or multiple assignment
-		void spot( 
-			const ast::UntypedExpr * expr, std::vector< ResolvExpr::CandidateFinder > & args 
+		void spot(
+			const ast::UntypedExpr * expr, std::vector< ResolvExpr::CandidateFinder > & args
 		) {
 			if ( auto op = expr->func.as< ast::NameExpr >() ) {
@@ -599,8 +600,8 @@
 					if ( ! refToTuple( lhsCand->expr ) ) continue;
 
-					// explode is aware of casts - ensure every LHS is sent into explode with a 
+					// explode is aware of casts - ensure every LHS is sent into explode with a
 					// reference cast
 					if ( ! lhsCand->expr.as< ast::CastExpr >() ) {
-						lhsCand->expr = new ast::CastExpr{ 
+						lhsCand->expr = new ast::CastExpr{
 							lhsCand->expr, new ast::ReferenceType{ lhsCand->expr->result } };
 					}
@@ -610,5 +611,5 @@
 					explode( *lhsCand, crntFinder.localSyms, back_inserter(lhs), true );
 					for ( ResolvExpr::CandidateRef & cand : lhs ) {
-						// each LHS value must be a reference - some come in with a cast, if not 
+						// each LHS value must be a reference - some come in with a cast, if not
 						// just cast to reference here
 						if ( ! cand->expr->result.as< ast::ReferenceType >() ) {
@@ -629,10 +630,10 @@
 								// multiple assignment
 								explode( *rhsCand, crntFinder.localSyms, back_inserter(rhs), true );
-								matcher.reset( 
+								matcher.reset(
 									new MultipleAssignMatcher{ *this, expr->location, lhs, rhs } );
 							} else {
 								// mass assignment
 								rhs.emplace_back( rhsCand );
-								matcher.reset( 
+								matcher.reset(
 									new MassAssignMatcher{ *this, expr->location, lhs, rhs } );
 							}
@@ -642,5 +643,5 @@
 						// expand all possible RHS possibilities
 						std::vector< ResolvExpr::CandidateList > rhsCands;
-						combos( 
+						combos(
 							std::next( args.begin(), 1 ), args.end(), back_inserter( rhsCands ) );
 						for ( const ResolvExpr::CandidateList & rhsCand : rhsCands ) {
@@ -648,5 +649,5 @@
 							ResolvExpr::CandidateList rhs;
 							explode( rhsCand, crntFinder.localSyms, back_inserter(rhs), true );
-							matcher.reset( 
+							matcher.reset(
 								new MultipleAssignMatcher{ *this, expr->location, lhs, rhs } );
 							match();
@@ -663,6 +664,6 @@
 
 			if ( ! ( matcher->lhs.empty() && matcher->rhs.empty() ) ) {
-				// if both LHS and RHS are empty than this is the empty tuple case, wherein it's 
-				// okay for newAssigns to be empty. Otherwise, return early so that no new 
+				// if both LHS and RHS are empty than this is the empty tuple case, wherein it's
+				// okay for newAssigns to be empty. Otherwise, return early so that no new
 				// candidates are generated
 				if ( newAssigns.empty() ) return;
@@ -692,5 +693,5 @@
 			}
 
-			// extract expressions from the assignment candidates to produce a list of assignments 
+			// extract expressions from the assignment candidates to produce a list of assignments
 			// that together form a sigle candidate
 			std::vector< ast::ptr< ast::Expr > > solved;
@@ -701,7 +702,7 @@
 
 			crntFinder.candidates.emplace_back( std::make_shared< ResolvExpr::Candidate >(
-				new ast::TupleAssignExpr{ 
-					matcher->location, std::move( solved ), std::move( matcher->tmpDecls ) }, 
-				std::move( matcher->env ), std::move( matcher->open ), std::move( matcher->need ), 
+				new ast::TupleAssignExpr{
+					matcher->location, std::move( solved ), std::move( matcher->tmpDecls ) },
+				std::move( matcher->env ), std::move( matcher->open ), std::move( matcher->need ),
 				ResolvExpr::sumCost( crnt ) + matcher->baseCost ) );
 		}
@@ -709,6 +710,6 @@
 } // anonymous namespace
 
-void handleTupleAssignment( 
-	ResolvExpr::CandidateFinder & finder, const ast::UntypedExpr * assign, 
+void handleTupleAssignment(
+	ResolvExpr::CandidateFinder & finder, const ast::UntypedExpr * assign,
 	std::vector< ResolvExpr::CandidateFinder > & args
 ) {
Index: src/main.cc
===================================================================
--- src/main.cc	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/main.cc	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -460,23 +460,24 @@
 	const char * descript;
 } printopts[] = {
-	{ "altexpr", expraltp, true, "alternatives for expressions" },
-	{ "ascodegen", codegenp, true, "as codegen rather than AST" },
-	{ "ast", astp, true, "AST after parsing" },
-	{ "astdecl", validp, true, "AST after declaration validation pass" },
-	{ "asterr", errorp, true, "AST on error" },
-	{ "astexpr", exprp, true, "AST after expression analysis" },
-	{ "astgen", genericsp, true, "AST after instantiate generics" },
-	{ "box", bboxp, true, "before box step" },
-	{ "ctordtor", ctorinitp, true, "after ctor/dtor are replaced" },
-	{ "codegen", bcodegenp, true, "before code generation" },
+	{ "ascodegen", codegenp, true, "print AST as codegen rather than AST" },
+	{ "asterr", errorp, true, "print AST on error" },
 	{ "declstats", declstatsp, true, "code property statistics" },
 	{ "parse", yydebug, true, "yacc (parsing) debug information" },
 	{ "pretty", prettycodegenp, true, "prettyprint for ascodegen flag" },
-	{ "resolver", bresolvep, true, "before resolver step" },
 	{ "rproto", resolvprotop, true, "resolver-proto instance" },
-	{ "rsteps", resolvep, true, "resolver steps" },
-	{ "symevt", symtabp, true, "symbol table events" },
-	{ "tree", parsep, true, "parse tree" },
-	{ "tuple", tuplep, true, "after tuple expansion" },
+	{ "rsteps", resolvep, true, "print resolver steps" },
+	{ "tree", parsep, true, "print parse tree" },
+	// code dumps
+	{ "ast", astp, true, "print AST after parsing" },
+	{ "symevt", symtabp, true, "print AST after symbol table events" },
+	{ "altexpr", expraltp, true, "print alternatives for expressions" },
+	{ "astdecl", validp, true, "print AST after declaration validation pass" },
+	{ "resolver", bresolvep, true, "print AST before resolver step" },
+	{ "astexpr", exprp, true, "print AST after expression analysis" },
+	{ "ctordtor", ctorinitp, true, "print AST after ctor/dtor are replaced" },
+	{ "tuple", tuplep, true, "print AST after tuple expansion" },
+	{ "astgen", genericsp, true, "print AST after instantiate generics" },
+	{ "box", bboxp, true, "print AST before box step" },
+	{ "codegen", bcodegenp, true, "print AST before code generation" },
 };
 enum { printoptsSize = sizeof( printopts ) / sizeof( printopts[0] ) };
