Index: src/AST/Convert.cpp
===================================================================
--- src/AST/Convert.cpp	(revision 302d84c22b87fe90c1971f7dec09ac9ec099da53)
+++ src/AST/Convert.cpp	(revision fce4e31b3ccbea074ba05609992ef025123ea16a)
@@ -1355,5 +1355,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:
@@ -1422,8 +1422,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;
@@ -1434,5 +1434,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);
@@ -1465,5 +1465,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{
@@ -1498,5 +1498,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(
@@ -1523,5 +1523,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(
@@ -1543,5 +1543,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(
@@ -1563,5 +1563,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(
@@ -1583,5 +1583,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{
@@ -1603,5 +1603,5 @@
 	}
 
-	virtual void visit( TypedefDecl * old ) override final {
+	virtual void visit( const TypedefDecl * old ) override final {
 		auto decl = new ast::TypedefDecl(
 			old->location,
@@ -1620,5 +1620,5 @@
 	}
 
-	virtual void visit( AsmDecl * old ) override final {
+	virtual void visit( const AsmDecl * old ) override final {
 		auto decl = new ast::AsmDecl{
 			old->location,
@@ -1632,5 +1632,5 @@
 	}
 
-	virtual void visit( StaticAssertDecl * old ) override final {
+	virtual void visit( const StaticAssertDecl * old ) override final {
 		auto decl = new ast::StaticAssertDecl{
 			old->location,
@@ -1645,5 +1645,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(
@@ -1657,5 +1657,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(
@@ -1667,5 +1667,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(
@@ -1682,5 +1682,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(
@@ -1692,5 +1692,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(
@@ -1705,5 +1705,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(
@@ -1716,5 +1716,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(
@@ -1727,5 +1727,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(
@@ -1740,5 +1740,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(
@@ -1753,5 +1753,5 @@
 	}
 
-	virtual void visit( BranchStmt * old ) override final {
+	virtual void visit( const BranchStmt * old ) override final {
 		if ( inCache( old ) ) return;
 		if (old->computedTarget) {
@@ -1790,5 +1790,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(
@@ -1800,5 +1800,5 @@
 	}
 
-	virtual void visit( ThrowStmt * old ) override final {
+	virtual void visit( const ThrowStmt * old ) override final {
 		if ( inCache( old ) ) return;
 		ast::ExceptionKind kind;
@@ -1824,5 +1824,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(
@@ -1836,5 +1836,5 @@
 	}
 
-	virtual void visit( CatchStmt * old ) override final {
+	virtual void visit( const CatchStmt * old ) override final {
 		if ( inCache( old ) ) return;
 		ast::ExceptionKind kind;
@@ -1861,5 +1861,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(
@@ -1871,5 +1871,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(
@@ -1903,5 +1903,5 @@
 	}
 
-	virtual void visit( WithStmt * old ) override final {
+	virtual void visit( const WithStmt * old ) override final {
 		if ( inCache( old ) ) return;
 		this->node = new ast::WithStmt(
@@ -1914,5 +1914,5 @@
 	}
 
-	virtual void visit( NullStmt * old ) override final {
+	virtual void visit( const NullStmt * old ) override final {
 		if ( inCache( old ) ) return;
 		this->node = new ast::NullStmt(
@@ -1923,5 +1923,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(
@@ -1933,5 +1933,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(
@@ -1990,5 +1990,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);
@@ -2000,5 +2000,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);
@@ -2006,5 +2006,5 @@
 	}
 
-	virtual void visit( ApplicationExpr * old ) override final {
+	virtual void visit( const ApplicationExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::ApplicationExpr(
@@ -2016,5 +2016,5 @@
 	}
 
-	virtual void visit( UntypedExpr * old ) override final {
+	virtual void visit( const UntypedExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::UntypedExpr(
@@ -2026,5 +2026,5 @@
 	}
 
-	virtual void visit( NameExpr * old ) override final {
+	virtual void visit( const NameExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::NameExpr(
@@ -2035,5 +2035,5 @@
 	}
 
-	virtual void visit( CastExpr * old ) override final {
+	virtual void visit( const CastExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::CastExpr(
@@ -2045,5 +2045,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) {
@@ -2070,5 +2070,5 @@
 	}
 
-	virtual void visit( VirtualCastExpr * old ) override final {
+	virtual void visit( const VirtualCastExpr * old ) override final {
 		this->node = visitBaseExpr_SkipResultType( old,
 			new ast::VirtualCastExpr(
@@ -2080,5 +2080,5 @@
 	}
 
-	virtual void visit( AddressExpr * old ) override final {
+	virtual void visit( const AddressExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::AddressExpr(
@@ -2089,5 +2089,5 @@
 	}
 
-	virtual void visit( LabelAddressExpr * old ) override final {
+	virtual void visit( const LabelAddressExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::LabelAddressExpr(
@@ -2098,5 +2098,5 @@
 	}
 
-	virtual void visit( UntypedMemberExpr * old ) override final {
+	virtual void visit( const UntypedMemberExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::UntypedMemberExpr(
@@ -2108,5 +2108,5 @@
 	}
 
-	virtual void visit( MemberExpr * old ) override final {
+	virtual void visit( const MemberExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::MemberExpr(
@@ -2118,5 +2118,5 @@
 	}
 
-	virtual void visit( VariableExpr * old ) override final {
+	virtual void visit( const VariableExpr * old ) override final {
 		auto expr = new ast::VariableExpr(
 			old->location
@@ -2129,16 +2129,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));
@@ -2161,5 +2161,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));
@@ -2182,5 +2182,5 @@
 	}
 
-	virtual void visit( UntypedOffsetofExpr * old ) override final {
+	virtual void visit( const UntypedOffsetofExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::UntypedOffsetofExpr(
@@ -2192,5 +2192,5 @@
 	}
 
-	virtual void visit( OffsetofExpr * old ) override final {
+	virtual void visit( const OffsetofExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::OffsetofExpr(
@@ -2202,5 +2202,5 @@
 	}
 
-	virtual void visit( OffsetPackExpr * old ) override final {
+	virtual void visit( const OffsetPackExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::OffsetPackExpr(
@@ -2211,5 +2211,5 @@
 	}
 
-	virtual void visit( LogicalExpr * old ) override final {
+	virtual void visit( const LogicalExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::LogicalExpr(
@@ -2224,5 +2224,5 @@
 	}
 
-	virtual void visit( ConditionalExpr * old ) override final {
+	virtual void visit( const ConditionalExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::ConditionalExpr(
@@ -2235,5 +2235,5 @@
 	}
 
-	virtual void visit( CommaExpr * old ) override final {
+	virtual void visit( const CommaExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::CommaExpr(
@@ -2245,5 +2245,5 @@
 	}
 
-	virtual void visit( TypeExpr * old ) override final {
+	virtual void visit( const TypeExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::TypeExpr(
@@ -2254,5 +2254,5 @@
 	}
 
-	virtual void visit( AsmExpr * old ) override final {
+	virtual void visit( const AsmExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::AsmExpr(
@@ -2265,5 +2265,5 @@
 	}
 
-	virtual void visit( ImplicitCopyCtorExpr * old ) override final {
+	virtual void visit( const ImplicitCopyCtorExpr * old ) override final {
 		auto rslt = new ast::ImplicitCopyCtorExpr(
 			old->location,
@@ -2274,5 +2274,5 @@
 	}
 
-	virtual void visit( ConstructorExpr * old ) override final {
+	virtual void visit( const ConstructorExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::ConstructorExpr(
@@ -2283,5 +2283,5 @@
 	}
 
-	virtual void visit( CompoundLiteralExpr * old ) override final {
+	virtual void visit( const CompoundLiteralExpr * old ) override final {
 		this->node = visitBaseExpr_SkipResultType( old,
 			new ast::CompoundLiteralExpr(
@@ -2293,5 +2293,5 @@
 	}
 
-	virtual void visit( RangeExpr * old ) override final {
+	virtual void visit( const RangeExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::RangeExpr(
@@ -2303,5 +2303,5 @@
 	}
 
-	virtual void visit( UntypedTupleExpr * old ) override final {
+	virtual void visit( const UntypedTupleExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::UntypedTupleExpr(
@@ -2312,5 +2312,5 @@
 	}
 
-	virtual void visit( TupleExpr * old ) override final {
+	virtual void visit( const TupleExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::TupleExpr(
@@ -2321,5 +2321,5 @@
 	}
 
-	virtual void visit( TupleIndexExpr * old ) override final {
+	virtual void visit( const TupleIndexExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::TupleIndexExpr(
@@ -2331,5 +2331,5 @@
 	}
 
-	virtual void visit( TupleAssignExpr * old ) override final {
+	virtual void visit( const TupleAssignExpr * old ) override final {
 		this->node = visitBaseExpr_SkipResultType( old,
 			new ast::TupleAssignExpr(
@@ -2341,5 +2341,5 @@
 	}
 
-	virtual void visit( StmtExpr * old ) override final {
+	virtual void visit( const StmtExpr * old ) override final {
 		auto rslt = new ast::StmtExpr(
 			old->location,
@@ -2352,5 +2352,5 @@
 	}
 
-	virtual void visit( UniqueExpr * old ) override final {
+	virtual void visit( const UniqueExpr * old ) override final {
 		auto rslt = new ast::UniqueExpr(
 			old->location,
@@ -2364,5 +2364,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) {
@@ -2381,5 +2381,5 @@
 	}
 
-	virtual void visit( InitExpr * old ) override final {
+	virtual void visit( const InitExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::InitExpr(
@@ -2391,5 +2391,5 @@
 	}
 
-	virtual void visit( DeletedExpr * old ) override final {
+	virtual void visit( const DeletedExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::DeletedExpr(
@@ -2403,5 +2403,5 @@
 	}
 
-	virtual void visit( DefaultArgExpr * old ) override final {
+	virtual void visit( const DefaultArgExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::DefaultArgExpr(
@@ -2412,5 +2412,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) {
@@ -2429,5 +2429,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() ) {
@@ -2437,9 +2437,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.
@@ -2450,5 +2450,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 ),
@@ -2460,5 +2460,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 ),
@@ -2470,5 +2470,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 ),
@@ -2477,5 +2477,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 ),
@@ -2485,5 +2485,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,
@@ -2496,5 +2496,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 );
@@ -2503,5 +2503,5 @@
 	}
 
-	virtual void visit( StructInstType * old ) override final {
+	virtual void visit( const StructInstType * old ) override final {
 		ast::StructInstType * ty;
 		if ( old->baseStruct ) {
@@ -2521,5 +2521,5 @@
 	}
 
-	virtual void visit( UnionInstType * old ) override final {
+	virtual void visit( const UnionInstType * old ) override final {
 		ast::UnionInstType * ty;
 		if ( old->baseUnion ) {
@@ -2539,5 +2539,5 @@
 	}
 
-	virtual void visit( EnumInstType * old ) override final {
+	virtual void visit( const EnumInstType * old ) override final {
 		ast::EnumInstType * ty;
 		if ( old->baseEnum ) {
@@ -2557,5 +2557,5 @@
 	}
 
-	virtual void visit( TraitInstType * old ) override final {
+	virtual void visit( const TraitInstType * old ) override final {
 		ast::TraitInstType * ty;
 		if ( old->baseTrait ) {
@@ -2575,5 +2575,5 @@
 	}
 
-	virtual void visit( TypeInstType * old ) override final {
+	virtual void visit( const TypeInstType * old ) override final {
 		ast::TypeInstType * ty;
 		if ( old->baseType ) {
@@ -2595,5 +2595,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 ),
@@ -2603,5 +2603,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 ),
@@ -2611,25 +2611,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,
@@ -2638,5 +2638,5 @@
 	}
 
-	virtual void visit( SingleInit * old ) override final {
+	virtual void visit( const SingleInit * old ) override final {
 		this->node = new ast::SingleInit(
 			old->location,
@@ -2646,5 +2646,5 @@
 	}
 
-	virtual void visit( ListInit * old ) override final {
+	virtual void visit( const ListInit * old ) override final {
 		this->node = new ast::ListInit(
 			old->location,
@@ -2655,5 +2655,5 @@
 	}
 
-	virtual void visit( ConstructorInit * old ) override final {
+	virtual void visit( const ConstructorInit * old ) override final {
 		this->node = new ast::ConstructorInit(
 			old->location,
@@ -2664,5 +2664,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.
@@ -2670,5 +2670,5 @@
 	}
 
-	virtual void visit( Attribute * old ) override final {
+	virtual void visit( const Attribute * old ) override final {
 		this->node = new ast::Attribute(
 			old->name,
@@ -2677,5 +2677,5 @@
 	}
 
-	virtual void visit( AttrExpr * ) override final {
+	virtual void visit( const AttrExpr * ) override final {
 		assertf( false, "AttrExpr deprecated in new AST." );
 	}
Index: src/AST/Expr.hpp
===================================================================
--- src/AST/Expr.hpp	(revision 302d84c22b87fe90c1971f7dec09ac9ec099da53)
+++ src/AST/Expr.hpp	(revision fce4e31b3ccbea074ba05609992ef025123ea16a)
@@ -47,6 +47,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 ) {}
@@ -112,7 +112,6 @@
 			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);
 		}
 
@@ -121,6 +120,6 @@
 				return data.resnSlots;
 			}
-			assert(!"Mode was not already resnSlots");
-			return *((ResnSlots*)nullptr);
+			assertf(false, "Mode was not already resnSlots");
+			abort();
 		}
 
@@ -131,6 +130,5 @@
 			case Params: return data.inferParams;
 			}
-			assert(!"unreachable");
-			return *((InferredParams*)nullptr);
+			assertf(false, "unreachable");
 		}
 
@@ -139,14 +137,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;
@@ -172,5 +170,5 @@
 					data.inferParams[p.first] = std::move(p.second);
 				}
-			} else assert(!"invalid mode");
+			} else assertf(false, "invalid mode");
 		}
 	};
@@ -384,5 +382,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 ) {}
Index: src/Common/PassVisitor.h
===================================================================
--- src/Common/PassVisitor.h	(revision 302d84c22b87fe90c1971f7dec09ac9ec099da53)
+++ src/Common/PassVisitor.h	(revision fce4e31b3ccbea074ba05609992ef025123ea16a)
@@ -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;
@@ -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 );
 
 
Index: src/Common/PassVisitor.impl.h
===================================================================
--- src/Common/PassVisitor.impl.h	(revision 302d84c22b87fe90c1971f7dec09ac9ec099da53)
+++ src/Common/PassVisitor.impl.h	(revision fce4e31b3ccbea074ba05609992ef025123ea16a)
@@ -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,28 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const FunctionDecl * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( node->withExprs, *this );
+	{
+		// 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
+		);
+		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,4 +625,14 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const StructDecl * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( node->parameters, *this );
+	maybeAccept_impl( node->members   , *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Declaration * PassVisitor< pass_type >::mutate( StructDecl * node ) {
 	MUTATE_START( node );
@@ -522,4 +673,13 @@
 	VISIT_END( node );
 }
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( const UnionDecl * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( node->parameters, *this );
+	maybeAccept_impl( node->members   , *this );
+
+	VISIT_END( node );
+}
 
 template< typename pass_type >
@@ -557,4 +717,15 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const EnumDecl * node ) {
+	VISIT_START( 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 );
@@ -587,4 +758,14 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const TraitDecl * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( node->parameters, *this );
+	maybeAccept_impl( node->members   , *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Declaration * PassVisitor< pass_type >::mutate( TraitDecl * node ) {
 	MUTATE_START( node );
@@ -625,4 +806,16 @@
 }
 
+
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( const TypeDecl * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( node->parameters, *this );
+	maybeAccept_impl( node->base      , *this );
+	maybeAccept_impl( node->assertions, *this );
+
+	VISIT_END( node );
+}
+
 template< typename pass_type >
 Declaration * PassVisitor< pass_type >::mutate( TypeDecl * node ) {
@@ -667,4 +860,15 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const TypedefDecl * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( node->parameters, *this );
+	maybeAccept_impl( node->base      , *this );
+	maybeAccept_impl( node->assertions, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Declaration * PassVisitor< pass_type >::mutate( TypedefDecl * node ) {
 	MUTATE_START( node );
@@ -695,4 +899,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 +923,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 +965,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 +1004,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 +1036,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 +1069,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 +1090,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,4 +1099,16 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const IfStmt * node ) {
+	VISIT_START( node );
+
+	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 );
@@ -839,5 +1116,5 @@
 		// if statements introduce a level of scope (for the initialization)
 		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeMutate_impl( node->get_initialization(), *this );
+		maybeMutate_impl( node->initialization, *this );
 		node->condition = mutateExpression( node->condition );
 		node->thenPart  = mutateStatement ( node->thenPart  );
@@ -860,4 +1137,15 @@
 		node->body = visitStatement( node->body );
 	}
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( const WhileStmt * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( node->initialization, *this );
+	visitExpression ( node->condition );
+	visitStatement( node->body );
 
 	VISIT_END( node );
@@ -897,4 +1185,16 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const ForStmt * node ) {
+	VISIT_START( node );
+
+	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 +1223,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 +1255,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 +1283,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 +1306,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 +1325,4 @@
 //--------------------------------------------------------------------------
 // ThrowStmt
-
 template< typename pass_type >
 void PassVisitor< pass_type >::visit( ThrowStmt * node ) {
@@ -1002,4 +1336,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 +1359,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 +1406,15 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const CatchStmt * node ) {
+	VISIT_START( node );
+
+	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 +1441,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 +1482,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 +1526,5 @@
 
 //--------------------------------------------------------------------------
-// NullStmt
+// WithStmt
 template< typename pass_type >
 void PassVisitor< pass_type >::visit( WithStmt * node ) {
@@ -1145,4 +1541,14 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const WithStmt * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( node->exprs, *this );
+	maybeAccept_impl( node->stmt, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Statement * PassVisitor< pass_type >::mutate( WithStmt * node ) {
 	MUTATE_START( node );
@@ -1166,4 +1572,10 @@
 
 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 );
@@ -1183,4 +1595,13 @@
 
 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 );
@@ -1195,4 +1616,13 @@
 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 );
 
@@ -1220,4 +1650,15 @@
 	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 );
+
+	maybeAccept_impl( node->result  , *this );
+	maybeAccept_impl( node->function, *this );
+	maybeAccept_impl( node->args    , *this );
 
 	VISIT_END( node );
@@ -1253,4 +1694,17 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const UntypedExpr * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( 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 +1732,13 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const NameExpr * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( node->result, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Expression * PassVisitor< pass_type >::mutate( NameExpr * node ) {
 	MUTATE_START( node );
@@ -1295,4 +1758,14 @@
 	indexerScopedAccept( node->result, *this );
 	maybeAccept_impl        ( node->arg   , *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( const CastExpr * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( node->result, *this );
+	maybeAccept_impl( node->arg   , *this );
 
 	VISIT_END( node );
@@ -1323,4 +1796,14 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const KeywordCastExpr * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( 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 );
@@ -1346,4 +1829,14 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const VirtualCastExpr * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( node->result, *this );
+	maybeAccept_impl( node->arg, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Expression * PassVisitor< pass_type >::mutate( VirtualCastExpr * node ) {
 	MUTATE_START( node );
@@ -1369,4 +1862,14 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const AddressExpr * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( 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 +1894,13 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const LabelAddressExpr * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( node->result, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Expression * PassVisitor< pass_type >::mutate( LabelAddressExpr * node ) {
 	MUTATE_START( node );
@@ -1409,4 +1921,15 @@
 	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 );
+
+	maybeAccept_impl( node->result   , *this );
+	maybeAccept_impl( node->aggregate, *this );
+	maybeAccept_impl( node->member   , *this );
 
 	VISIT_END( node );
@@ -1438,4 +1961,14 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const MemberExpr * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( 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 +1993,13 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const VariableExpr * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( node->result, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 Expression * PassVisitor< pass_type >::mutate( VariableExpr * node ) {
 	MUTATE_START( node );
@@ -1477,4 +2019,14 @@
 	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 );
+
+	maybeAccept_impl( node->result   , *this );
+	maybeAccept_impl( &node->constant, *this );
 
 	VISIT_END( node );
@@ -1501,4 +2053,18 @@
 
 	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 );
+
+	maybeAccept_impl( node->result, *this );
 	if ( node->get_isType() ) {
 		maybeAccept_impl( node->type, *this );
@@ -1542,4 +2108,18 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const AlignofExpr * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( 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 +2149,14 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const UntypedOffsetofExpr * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( 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 +2182,14 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const OffsetofExpr * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( 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 +2215,14 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const OffsetPackExpr * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( 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 );
@@ -1632,4 +2242,18 @@
 
 	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 );
+
+	maybeAccept_impl( node->result, *this );
 	if ( node->get_isType() ) {
 		maybeAccept_impl( node->type, *this );
@@ -1670,4 +2294,15 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const LogicalExpr * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( 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 +2326,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 );
+
+	maybeAccept_impl( node->result, *this );
+	maybeAccept_impl( node->arg1  , *this );
+	maybeAccept_impl( node->arg2  , *this );
+	maybeAccept_impl( node->arg3  , *this );
 
 	VISIT_END( node );
@@ -1722,4 +2369,15 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const CommaExpr * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( 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 +2404,14 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const TypeExpr * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( 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 );
@@ -1766,4 +2434,16 @@
 	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 );
+
+	maybeAccept_impl( node->result    , *this );
+	maybeAccept_impl( node->inout     , *this );
+	maybeAccept_impl( node->constraint, *this );
+	maybeAccept_impl( node->operand   , *this );
 
 	VISIT_END( node );
@@ -1796,4 +2476,14 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const ImplicitCopyCtorExpr * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( 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 +2509,14 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const ConstructorExpr * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( 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 +2542,14 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const CompoundLiteralExpr * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( 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 );
@@ -1861,4 +2571,15 @@
 	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 );
+
+	maybeAccept_impl( node->result, *this );
+	maybeAccept_impl( node->low   , *this );
+	maybeAccept_impl( node->high  , *this );
 
 	VISIT_END( node );
@@ -1890,4 +2611,14 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const UntypedTupleExpr * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( 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 +2644,14 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const TupleExpr * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( 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 +2677,14 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const TupleIndexExpr * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( 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 +2705,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 );
+
+	maybeAccept_impl( node->result  , *this );
+	maybeAccept_impl( node->stmtExpr, *this );
 
 	VISIT_END( node );
@@ -1989,4 +2750,16 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const StmtExpr * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( 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 );
@@ -2018,4 +2791,14 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const UniqueExpr * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( 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 );
@@ -2036,4 +2819,15 @@
 	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 );
+
+	maybeAccept_impl( 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.
 
@@ -2067,4 +2861,15 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const InitExpr * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( 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 );
@@ -2092,4 +2897,15 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const DeletedExpr * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( node->result, *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 >
 Expression * PassVisitor< pass_type >::mutate( DeletedExpr * node ) {
 	MUTATE_START( node );
@@ -2109,4 +2925,14 @@
 
 	indexerScopedAccept( node->result, *this );
+	maybeAccept_impl( node->expr, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( const DefaultArgExpr * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( node->result, *this );
 	maybeAccept_impl( node->expr, *this );
 
@@ -2135,4 +2961,18 @@
 	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 );
+
+	maybeAccept_impl( node->result, *this );
+	maybeAccept_impl( node->control, *this );
+	for ( const GenericExpr::Association & assoc : node->associations ) {
+		maybeAccept_impl( assoc.type, *this );
 		maybeAccept_impl( assoc.expr, *this );
 	}
@@ -2168,4 +3008,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 +3029,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 +3068,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 +3103,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 +3137,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 +3170,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 );
@@ -2294,4 +3195,15 @@
 template< typename pass_type >
 void PassVisitor< pass_type >::visit( 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 >
+void PassVisitor< pass_type >::visit( const FunctionType * node ) {
 	VISIT_START( node );
 
@@ -2332,4 +3244,14 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const StructInstType * 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( StructInstType * node ) {
 	MUTATE_START( node );
@@ -2364,4 +3286,14 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( const UnionInstType * 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( UnionInstType * node ) {
 	MUTATE_START( node );
@@ -2391,4 +3323,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 +3355,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 +3378,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 +3420,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 +3445,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 +3491,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 +3532,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 +3561,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 +3590,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 +3619,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 +3648,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 +3677,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 +3698,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 +3740,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 +3771,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 +3788,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 302d84c22b87fe90c1971f7dec09ac9ec099da53)
+++ src/Common/PassVisitor.proto.h	(revision fce4e31b3ccbea074ba05609992ef025123ea16a)
@@ -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,5 +225,4 @@
 	pass.indexer.func( arg1, arg2 );                                                                                                \
 }                                                                                                                              \
-                                                                                                                               \
 template<typename pass_type>                                                                                                   \
 static inline void indexer_impl_##func ( pass_type &, long, type1, type2 ) { }
@@ -233,5 +248,5 @@
 
 template<typename pass_type>
-static inline auto indexer_impl_addStructFwd( pass_type &, long, StructDecl * ) {}
+static inline auto indexer_impl_addStructFwd( pass_type &, long, const StructDecl * ) {}
 
 template<typename pass_type>
@@ -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/ResolvExpr/AdjustExprType.cc
===================================================================
--- src/ResolvExpr/AdjustExprType.cc	(revision 302d84c22b87fe90c1971f7dec09ac9ec099da53)
+++ src/ResolvExpr/AdjustExprType.cc	(revision fce4e31b3ccbea074ba05609992ef025123ea16a)
@@ -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;
 }
@@ -148,6 +148,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/CastCost.cc
===================================================================
--- src/ResolvExpr/CastCost.cc	(revision 302d84c22b87fe90c1971f7dec09ac9ec099da53)
+++ src/ResolvExpr/CastCost.cc	(revision fce4e31b3ccbea074ba05609992ef025123ea16a)
@@ -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 302d84c22b87fe90c1971f7dec09ac9ec099da53)
+++ src/ResolvExpr/CommonType.cc	(revision fce4e31b3ccbea074ba05609992ef025123ea16a)
@@ -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 = type1.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 302d84c22b87fe90c1971f7dec09ac9ec099da53)
+++ src/ResolvExpr/ConversionCost.cc	(revision fce4e31b3ccbea074ba05609992ef025123ea16a)
@@ -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 302d84c22b87fe90c1971f7dec09ac9ec099da53)
+++ src/ResolvExpr/ConversionCost.h	(revision fce4e31b3ccbea074ba05609992ef025123ea16a)
@@ -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 302d84c22b87fe90c1971f7dec09ac9ec099da53)
+++ src/ResolvExpr/PtrsAssignable.cc	(revision fce4e31b3ccbea074ba05609992ef025123ea16a)
@@ -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 302d84c22b87fe90c1971f7dec09ac9ec099da53)
+++ src/ResolvExpr/PtrsCastable.cc	(revision fce4e31b3ccbea074ba05609992ef025123ea16a)
@@ -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/Resolver.cc
===================================================================
--- src/ResolvExpr/Resolver.cc	(revision 302d84c22b87fe90c1971f7dec09ac9ec099da53)
+++ src/ResolvExpr/Resolver.cc	(revision fce4e31b3ccbea074ba05609992ef025123ea16a)
@@ -562,6 +562,5 @@
 		// TODO: Replace *exception type with &exception type.
 		if ( throwStmt->get_expr() ) {
-			StructDecl * exception_decl =
-				indexer.lookupStruct( "__cfaabi_ehm__base_exception_t" );
+			StructDecl * exception_decl = indexer.lookupMutableStruct( "__cfaabi_ehm__base_exception_t" );
 			assert( exception_decl );
 			Type * exceptType = new PointerType( noQualifiers, new StructInstType( noQualifiers, exception_decl ) );
@@ -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::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 302d84c22b87fe90c1971f7dec09ac9ec099da53)
+++ src/ResolvExpr/Unify.cc	(revision fce4e31b3ccbea074ba05609992ef025123ea16a)
@@ -97,7 +97,7 @@
 	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 );
 
@@ -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 302d84c22b87fe90c1971f7dec09ac9ec099da53)
+++ src/ResolvExpr/typeops.h	(revision fce4e31b3ccbea074ba05609992ef025123ea16a)
@@ -73,37 +73,37 @@
 
 	/// 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, 
+	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 );
+	bool typesCompatibleIgnoreQualifiers( const Type *, const Type *, const SymTab::Indexer &indexer, const TypeEnvironment &env );
 
 	inline bool typesCompatible( Type *t1, Type *t2, const SymTab::Indexer &indexer ) {
@@ -112,15 +112,15 @@
 	}
 
-	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 = {} );
 
@@ -133,10 +133,10 @@
 	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(
 		const ast::Type * type, const ast::SymbolTable & symtab, const ast::TypeEnvironment & env );
 
@@ -149,5 +149,5 @@
 	// new AST version in TypeEnvironment.cpp (only place it was used in old AST)
 
-	template<typename Iter> 
+	template<typename Iter>
 	bool occursIn( Type* ty, Iter begin, Iter end, const TypeEnvironment &env ) {
 		while ( begin != end ) {
@@ -176,8 +176,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 );
Index: src/SymTab/Indexer.cc
===================================================================
--- src/SymTab/Indexer.cc	(revision 302d84c22b87fe90c1971f7dec09ac9ec099da53)
+++ src/SymTab/Indexer.cc	(revision fce4e31b3ccbea074ba05609992ef025123ea16a)
@@ -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,53 @@
 	}
 
-	NamedTypeDecl *Indexer::lookupType( const std::string &id ) const {
-		++*stats().lookup_calls;
+	const NamedTypeDecl * Indexer::lookupType( const std::string & id ) const { return lookupMutableType(id); }
+	NamedTypeDecl * Indexer::lookupMutableType( 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 { return lookupMutableStruct(id); }
+	StructDecl * Indexer::lookupMutableStruct( 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 { return lookupMutableEnum(id); }
+	EnumDecl * Indexer::lookupMutableEnum( 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 { return lookupMutableUnion(id); }
+	UnionDecl * Indexer::lookupMutableUnion( 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 { return lookupMutableTrait(id); }
+	TraitDecl * Indexer::lookupMutableTrait( 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,17 +177,17 @@
 	}
 
-	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 );
 	}
@@ -207,9 +212,9 @@
 	}
 
-	
-	bool Indexer::addedIdConflicts( 
-			const Indexer::IdData & existing, DeclarationWithType *added, 
+
+	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 
+		// 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 +224,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 +243,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 +260,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 +275,13 @@
 			}
 		}
-		
+
 		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,14 +300,14 @@
 
 	/// gets the base type of the first parameter; decl must be a ctor/dtor/assignment function
-	std::string getOtypeKey( FunctionDecl* function ) {
+	std::string getOtypeKey( 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 ) {
@@ -312,13 +317,13 @@
 	}
 
-	bool Indexer::removeSpecialOverrides( 
+	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 
+		// 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.
 
@@ -340,6 +345,6 @@
 			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 );
@@ -368,9 +373,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,6 +384,6 @@
 			// 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 );
@@ -402,5 +407,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,5 +413,5 @@
 			// 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 );
@@ -418,5 +423,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 +433,19 @@
 			}
 		}
-		
+
 		// nothing (more) to fix, return true
 		return true;
 	}
 
-	void Indexer::addId( 
-			DeclarationWithType *decl, OnConflict handleConflicts, Expression * baseExpr, 
+	void Indexer::addId(
+			DeclarationWithType * decl, OnConflict handleConflicts, Expression * baseExpr,
 			BaseSyntaxNode * deleteStmt ) {
-		++*stats().add_calls;
+		++* 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 +454,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 +462,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 +475,5 @@
 			mangleTable = MangleTable::new_ptr();
 		} else {
-			++*stats().map_lookups;
+			++* stats().map_lookups;
 			auto decls = idTable->find( name );
 			if ( decls == idTable->end() ) {
@@ -477,5 +482,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 +491,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,5 +509,5 @@
 		// 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) ) );
 	}
@@ -518,5 +523,5 @@
 	}
 
-	bool addedTypeConflicts( NamedTypeDecl *existing, NamedTypeDecl *added ) {
+	bool addedTypeConflicts( NamedTypeDecl * existing, NamedTypeDecl * added ) {
 		if ( existing->base == nullptr ) {
 			return false;
@@ -530,29 +535,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( 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( AggregateDecl * existing, AggregateDecl * added ) {
 		if ( ! existing->body ) {
 			return false;
@@ -563,89 +568,89 @@
 	}
 
-	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( 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( 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( 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( 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, 
+	void Indexer::addMembers( AggregateDecl * aggr, Expression * expr,
 			OnConflict handleConflicts ) {
 		for ( Declaration * decl : aggr->members ) {
@@ -654,5 +659,5 @@
 				if ( dwt->name == "" ) {
 					Type * t = dwt->get_type()->stripReferences();
-					if ( dynamic_cast<StructInstType*>( t ) || dynamic_cast<UnionInstType*>( t ) ) {
+					if ( dynamic_cast<StructInstType *>( t ) || dynamic_cast<UnionInstType *>( t ) ) {
 						Expression * base = expr->clone();
 						ResolvExpr::Cost cost = ResolvExpr::Cost::zero; // xxx - carry this cost into the indexer as a base cost?
Index: src/SymTab/Indexer.h
===================================================================
--- src/SymTab/Indexer.h	(revision 302d84c22b87fe90c1971f7dec09ac9ec099da53)
+++ src/SymTab/Indexer.h	(revision fce4e31b3ccbea074ba05609992ef025123ea16a)
@@ -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();
@@ -50,7 +50,7 @@
 			// NOTE: shouldn't need either of these constructors, but gcc-4 does not properly support initializer lists with default members.
 			IdData() = default;
-			IdData( 
+			IdData(
 				DeclarationWithType * id, Expression * baseExpr, BaseSyntaxNode * deleteStmt,
-				unsigned long scope ) 
+				unsigned long scope )
 				: id( id ), baseExpr( baseExpr ), deleteStmt( deleteStmt ), scope( scope ) {}
 			IdData( const IdData& o, BaseSyntaxNode * deleteStmt )
@@ -61,35 +61,40 @@
 
 		/// 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;
+		NamedTypeDecl * lookupMutableType( 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;
+		StructDecl * lookupMutableStruct( 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;
+		EnumDecl * lookupMutableEnum( 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;
+		UnionDecl * lookupMutableUnion( 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;
+		TraitDecl * lookupMutableTrait( 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 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( 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 );
 
 		/// adds all of the IDs from WithStmt exprs
@@ -106,11 +111,11 @@
 
 	  private:
-	  	/// Wraps a Decl* with a scope
+	  	/// Wraps a Decl * with a scope
 	  	template<typename Decl>
 		struct Scoped {
-			Decl* decl;           ///< declaration
+			Decl * decl;           ///< declaration
 			unsigned long scope;  ///< scope of this declaration
 
-			Scoped(Decl* d, unsigned long s) : decl(d), scope(s) {}
+			Scoped(Decl * d, unsigned long s) : decl(d), scope(s) {}
 		};
 
@@ -140,7 +145,7 @@
 
 		/// 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 );
@@ -166,10 +171,10 @@
 		/// true if the existing identifier conflicts with the added identifier
 		bool addedIdConflicts(
-			const IdData& existing, DeclarationWithType * added, OnConflict handleConflicts, 
+			const IdData& existing, DeclarationWithType * added, OnConflict handleConflicts,
 			BaseSyntaxNode * deleteStmt );
 
 		/// common code for addId, addDeletedId, etc.
-		void addId( 
-			DeclarationWithType * decl, OnConflict handleConflicts, 
+		void addId(
+			DeclarationWithType * decl, OnConflict handleConflicts,
 			Expression * baseExpr = nullptr, BaseSyntaxNode * deleteStmt = nullptr );
 
@@ -178,7 +183,7 @@
 
 		/// 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/Validate.cc
===================================================================
--- src/SymTab/Validate.cc	(revision 302d84c22b87fe90c1971f7dec09ac9ec099da53)
+++ src/SymTab/Validate.cc	(revision fce4e31b3ccbea074ba05609992ef025123ea16a)
@@ -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,6 +641,6 @@
 	}
 
-	void LinkReferenceToTypes_old::postvisit( EnumInstType *enumInst ) {
-		EnumDecl *st = local_indexer->lookupEnum( enumInst->name );
+	void LinkReferenceToTypes_old::postvisit( EnumInstType * enumInst ) {
+		EnumDecl * st = local_indexer->lookupMutableEnum( enumInst->name );
 		// it's not a semantic error if the enum is not found, just an implicit forward declaration
 		if ( st ) {
@@ -661,6 +661,6 @@
 	}
 
-	void LinkReferenceToTypes_old::postvisit( StructInstType *structInst ) {
-		StructDecl *st = local_indexer->lookupStruct( structInst->name );
+	void LinkReferenceToTypes_old::postvisit( StructInstType * structInst ) {
+		StructDecl * st = local_indexer->lookupMutableStruct( structInst->name );
 		// it's not a semantic error if the struct is not found, just an implicit forward declaration
 		if ( st ) {
@@ -674,6 +674,6 @@
 	}
 
-	void LinkReferenceToTypes_old::postvisit( UnionInstType *unionInst ) {
-		UnionDecl *un = local_indexer->lookupUnion( unionInst->name );
+	void LinkReferenceToTypes_old::postvisit( UnionInstType * unionInst ) {
+		UnionDecl * un = local_indexer->lookupMutableUnion( unionInst->name );
 		// it's not a semantic error if the union is not found, just an implicit forward declaration
 		if ( un ) {
@@ -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 );
+		TraitDecl * traitDecl = local_indexer->lookupMutableTrait( traitInst->name );
 		if ( ! traitDecl ) {
 			SemanticError( traitInst->location, "use of undeclared trait " + traitInst->name );
@@ -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 302d84c22b87fe90c1971f7dec09ac9ec099da53)
+++ src/SymTab/Validate.h	(revision fce4e31b3ccbea074ba05609992ef025123ea16a)
@@ -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 302d84c22b87fe90c1971f7dec09ac9ec099da53)
+++ src/SynTree/Attribute.h	(revision fce4e31b3ccbea074ba05609992ef025123ea16a)
@@ -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 302d84c22b87fe90c1971f7dec09ac9ec099da53)
+++ src/SynTree/BaseSyntaxNode.h	(revision fce4e31b3ccbea074ba05609992ef025123ea16a)
@@ -32,9 +32,10 @@
 	BaseSyntaxNode( const BaseSyntaxNode & o ) : location(o.location) { ++*new_nodes; }
 	BaseSyntaxNode & operator=( const BaseSyntaxNode & ) = default;
-	
+
 	virtual ~BaseSyntaxNode() {}
 
 	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:
Index: src/SynTree/Constant.h
===================================================================
--- src/SynTree/Constant.h	(revision 302d84c22b87fe90c1971f7dec09ac9ec099da53)
+++ src/SynTree/Constant.h	(revision fce4e31b3ccbea074ba05609992ef025123ea16a)
@@ -33,5 +33,5 @@
 	virtual ~Constant();
 
-	virtual Constant * clone() const { return new Constant( *this ); }
+	virtual Constant * clone() const override { return new Constant( *this ); }
 
 	Type * get_type() { return type; }
@@ -51,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 302d84c22b87fe90c1971f7dec09ac9ec099da53)
+++ src/SynTree/Declaration.h	(revision fce4e31b3ccbea074ba05609992ef025123ea16a)
@@ -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,5 +353,6 @@
 
 	virtual TraitDecl *clone() const override { return new TraitDecl( *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:
@@ -363,5 +372,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 +389,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.h
===================================================================
--- src/SynTree/Expression.h	(revision 302d84c22b87fe90c1971f7dec09ac9ec099da53)
+++ src/SynTree/Expression.h	(revision fce4e31b3ccbea074ba05609992ef025123ea16a)
@@ -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;
 };
 
@@ -858,8 +894,9 @@
 	~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 302d84c22b87fe90c1971f7dec09ac9ec099da53)
+++ src/SynTree/Initializer.h	(revision fce4e31b3ccbea074ba05609992ef025123ea16a)
@@ -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/Statement.h
===================================================================
--- src/SynTree/Statement.h	(revision 302d84c22b87fe90c1971f7dec09ac9ec099da53)
+++ src/SynTree/Statement.h	(revision fce4e31b3ccbea074ba05609992ef025123ea16a)
@@ -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,4 +455,5 @@
 	virtual WaitForStmt * clone() const override { return new WaitForStmt( *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;
@@ -454,4 +472,5 @@
 	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 302d84c22b87fe90c1971f7dec09ac9ec099da53)
+++ src/SynTree/Type.h	(revision fce4e31b3ccbea074ba05609992ef025123ea16a)
@@ -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 302d84c22b87fe90c1971f7dec09ac9ec099da53)
+++ src/SynTree/Visitor.h	(revision fce4e31b3ccbea074ba05609992ef025123ea16a)
@@ -27,103 +27,196 @@
 	// 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;
 };
 
Index: src/Tuples/Explode.h
===================================================================
--- src/Tuples/Explode.h	(revision 302d84c22b87fe90c1971f7dec09ac9ec099da53)
+++ src/Tuples/Explode.h	(revision fce4e31b3ccbea074ba05609992ef025123ea16a)
@@ -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 &&
 ) {
 }
@@ -240,6 +240,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 302d84c22b87fe90c1971f7dec09ac9ec099da53)
+++ src/Tuples/TupleAssignment.cc	(revision fce4e31b3ccbea074ba05609992ef025123ea16a)
@@ -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.symtab );
 					// 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.symtab, 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.symtab, 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.symtab, 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.symtab, 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
 ) {
