Index: src/AST/Convert.cpp
===================================================================
--- src/AST/Convert.cpp	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/AST/Convert.cpp	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -518,5 +518,5 @@
 	}
 
-	const ast::Stmt * visit( const ast::WithStmt * node ) override final {
+	const ast::Decl * visit( const ast::WithStmt * node ) override final {
 		if ( inCache( node ) ) return nullptr;
 		auto stmt = new WithStmt(
@@ -524,5 +524,6 @@
 			get<Statement>().accept1( node->stmt )
 		);
-		return stmtPostamble( stmt, node );
+		declPostamble( stmt, node );
+		return nullptr;
 	}
 
@@ -1050,6 +1051,6 @@
 				get<Expression>().accept1(node->expr),
 				inCache(node->deleteStmt) ?
-					this->node :
-					get<BaseSyntaxNode>().accept1(node->deleteStmt)
+					strict_dynamic_cast<Declaration*>(this->node) :
+					get<Declaration>().accept1(node->deleteStmt)
 			)
 		);
@@ -1366,5 +1367,5 @@
 	ast::Node * node = nullptr;
 	/// cache of nodes that might be referenced by readonly<> for de-duplication
-	std::unordered_map< BaseSyntaxNode *, ast::Node * > cache = {};
+	std::unordered_map< const BaseSyntaxNode *, ast::Node * > cache = {};
 
 	// Local Utilities:
@@ -1433,8 +1434,8 @@
 		to<std::vector>::from( make_labels( std::move( labels ) ) )
 
-	static ast::CV::Qualifiers cv( Type * ty ) { return { ty->get_qualifiers().val }; }
+	static ast::CV::Qualifiers cv( const Type * ty ) { return { ty->tq.val }; }
 
 	/// returns true and sets `node` if in cache
-	bool inCache( BaseSyntaxNode * old ) {
+	bool inCache( const BaseSyntaxNode * old ) {
 		auto it = cache.find( old );
 		if ( it == cache.end() ) return false;
@@ -1445,5 +1446,5 @@
 	// Now all the visit functions:
 
-	virtual void visit( ObjectDecl * old ) override final {
+	virtual void visit( const ObjectDecl * old ) override final {
 		auto&& type = GET_ACCEPT_1(type, Type);
 		auto&& init = GET_ACCEPT_1(init, Init);
@@ -1476,5 +1477,5 @@
 	}
 
-	virtual void visit( FunctionDecl * old ) override final {
+	virtual void visit( const FunctionDecl * old ) override final {
 		if ( inCache( old ) ) return;
 		auto decl = new ast::FunctionDecl{
@@ -1509,5 +1510,5 @@
 	}
 
-	virtual void visit( StructDecl * old ) override final {
+	virtual void visit( const StructDecl * old ) override final {
 		if ( inCache( old ) ) return;
 		auto decl = new ast::StructDecl(
@@ -1534,5 +1535,5 @@
 	}
 
-	virtual void visit( UnionDecl * old ) override final {
+	virtual void visit( const UnionDecl * old ) override final {
 		if ( inCache( old ) ) return;
 		auto decl = new ast::UnionDecl(
@@ -1554,5 +1555,5 @@
 	}
 
-	virtual void visit( EnumDecl * old ) override final {
+	virtual void visit( const EnumDecl * old ) override final {
 		if ( inCache( old ) ) return;
 		auto decl = new ast::EnumDecl(
@@ -1574,5 +1575,5 @@
 	}
 
-	virtual void visit( TraitDecl * old ) override final {
+	virtual void visit( const TraitDecl * old ) override final {
 		if ( inCache( old ) ) return;
 		auto decl = new ast::TraitDecl(
@@ -1594,5 +1595,5 @@
 	}
 
-	virtual void visit( TypeDecl * old ) override final {
+	virtual void visit( const TypeDecl * old ) override final {
 		if ( inCache( old ) ) return;
 		auto decl = new ast::TypeDecl{
@@ -1614,5 +1615,5 @@
 	}
 
-	virtual void visit( TypedefDecl * old ) override final {
+	virtual void visit( const TypedefDecl * old ) override final {
 		auto decl = new ast::TypedefDecl(
 			old->location,
@@ -1631,5 +1632,5 @@
 	}
 
-	virtual void visit( AsmDecl * old ) override final {
+	virtual void visit( const AsmDecl * old ) override final {
 		auto decl = new ast::AsmDecl{
 			old->location,
@@ -1643,5 +1644,5 @@
 	}
 
-	virtual void visit( StaticAssertDecl * old ) override final {
+	virtual void visit( const StaticAssertDecl * old ) override final {
 		auto decl = new ast::StaticAssertDecl{
 			old->location,
@@ -1656,5 +1657,5 @@
 	}
 
-	virtual void visit( CompoundStmt * old ) override final {
+	virtual void visit( const CompoundStmt * old ) override final {
 		if ( inCache( old ) ) return;
 		auto stmt = new ast::CompoundStmt(
@@ -1668,5 +1669,5 @@
 	}
 
-	virtual void visit( ExprStmt * old ) override final {
+	virtual void visit( const ExprStmt * old ) override final {
 		if ( inCache( old ) ) return;
 		this->node = new ast::ExprStmt(
@@ -1678,5 +1679,5 @@
 	}
 
-	virtual void visit( AsmStmt * old ) override final {
+	virtual void visit( const AsmStmt * old ) override final {
 		if ( inCache( old ) ) return;
 		this->node = new ast::AsmStmt(
@@ -1693,5 +1694,5 @@
 	}
 
-	virtual void visit( DirectiveStmt * old ) override final {
+	virtual void visit( const DirectiveStmt * old ) override final {
 		if ( inCache( old ) ) return;
 		this->node = new ast::DirectiveStmt(
@@ -1703,5 +1704,5 @@
 	}
 
-	virtual void visit( IfStmt * old ) override final {
+	virtual void visit( const IfStmt * old ) override final {
 		if ( inCache( old ) ) return;
 		this->node = new ast::IfStmt(
@@ -1716,5 +1717,5 @@
 	}
 
-	virtual void visit( SwitchStmt * old ) override final {
+	virtual void visit( const SwitchStmt * old ) override final {
 		if ( inCache( old ) ) return;
 		this->node = new ast::SwitchStmt(
@@ -1727,5 +1728,5 @@
 	}
 
-	virtual void visit( CaseStmt * old ) override final {
+	virtual void visit( const CaseStmt * old ) override final {
 		if ( inCache( old ) ) return;
 		this->node = new ast::CaseStmt(
@@ -1738,5 +1739,5 @@
 	}
 
-	virtual void visit( WhileStmt * old ) override final {
+	virtual void visit( const WhileStmt * old ) override final {
 		if ( inCache( old ) ) return;
 		this->node = new ast::WhileStmt(
@@ -1751,5 +1752,5 @@
 	}
 
-	virtual void visit( ForStmt * old ) override final {
+	virtual void visit( const ForStmt * old ) override final {
 		if ( inCache( old ) ) return;
 		this->node = new ast::ForStmt(
@@ -1764,5 +1765,5 @@
 	}
 
-	virtual void visit( BranchStmt * old ) override final {
+	virtual void visit( const BranchStmt * old ) override final {
 		if ( inCache( old ) ) return;
 		if (old->computedTarget) {
@@ -1801,5 +1802,5 @@
 	}
 
-	virtual void visit( ReturnStmt * old ) override final {
+	virtual void visit( const ReturnStmt * old ) override final {
 		if ( inCache( old ) ) return;
 		this->node = new ast::ReturnStmt(
@@ -1811,5 +1812,5 @@
 	}
 
-	virtual void visit( ThrowStmt * old ) override final {
+	virtual void visit( const ThrowStmt * old ) override final {
 		if ( inCache( old ) ) return;
 		ast::ExceptionKind kind;
@@ -1835,5 +1836,5 @@
 	}
 
-	virtual void visit( TryStmt * old ) override final {
+	virtual void visit( const TryStmt * old ) override final {
 		if ( inCache( old ) ) return;
 		this->node = new ast::TryStmt(
@@ -1847,5 +1848,5 @@
 	}
 
-	virtual void visit( CatchStmt * old ) override final {
+	virtual void visit( const CatchStmt * old ) override final {
 		if ( inCache( old ) ) return;
 		ast::ExceptionKind kind;
@@ -1872,5 +1873,5 @@
 	}
 
-	virtual void visit( FinallyStmt * old ) override final {
+	virtual void visit( const FinallyStmt * old ) override final {
 		if ( inCache( old ) ) return;
 		this->node = new ast::FinallyStmt(
@@ -1882,5 +1883,5 @@
 	}
 
-	virtual void visit( WaitForStmt * old ) override final {
+	virtual void visit( const WaitForStmt * old ) override final {
 		if ( inCache( old ) ) return;
 		ast::WaitForStmt * stmt = new ast::WaitForStmt(
@@ -1914,16 +1915,15 @@
 	}
 
-	virtual void visit( WithStmt * old ) override final {
+	virtual void visit( const WithStmt * old ) override final {
 		if ( inCache( old ) ) return;
 		this->node = new ast::WithStmt(
 			old->location,
 			GET_ACCEPT_V(exprs, Expr),
-			GET_ACCEPT_1(stmt, Stmt),
-			GET_LABELS_V(old->labels)
+			GET_ACCEPT_1(stmt, Stmt)
 		);
 		cache.emplace( old, this->node );
 	}
 
-	virtual void visit( NullStmt * old ) override final {
+	virtual void visit( const NullStmt * old ) override final {
 		if ( inCache( old ) ) return;
 		this->node = new ast::NullStmt(
@@ -1934,5 +1934,5 @@
 	}
 
-	virtual void visit( DeclStmt * old ) override final {
+	virtual void visit( const DeclStmt * old ) override final {
 		if ( inCache( old ) ) return;
 		this->node = new ast::DeclStmt(
@@ -1944,5 +1944,5 @@
 	}
 
-	virtual void visit( ImplicitCtorDtorStmt * old ) override final {
+	virtual void visit( const ImplicitCtorDtorStmt * old ) override final {
 		if ( inCache( old ) ) return;
 		auto stmt = new ast::ImplicitCtorDtorStmt(
@@ -2001,5 +2001,5 @@
 	}
 
-	ast::Expr * visitBaseExpr_SkipResultType(Expression * old, ast::Expr * nw) {
+	ast::Expr * visitBaseExpr_SkipResultType( const Expression * old, ast::Expr * nw) {
 
 		nw->env    = convertTypeSubstitution(old->env);
@@ -2011,5 +2011,5 @@
 	}
 
-	ast::Expr * visitBaseExpr(Expression * old, ast::Expr * nw) {
+	ast::Expr * visitBaseExpr( const Expression * old, ast::Expr * nw) {
 
 		nw->result = GET_ACCEPT_1(result, Type);
@@ -2017,5 +2017,5 @@
 	}
 
-	virtual void visit( ApplicationExpr * old ) override final {
+	virtual void visit( const ApplicationExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::ApplicationExpr(
@@ -2027,5 +2027,5 @@
 	}
 
-	virtual void visit( UntypedExpr * old ) override final {
+	virtual void visit( const UntypedExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::UntypedExpr(
@@ -2037,5 +2037,5 @@
 	}
 
-	virtual void visit( NameExpr * old ) override final {
+	virtual void visit( const NameExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::NameExpr(
@@ -2046,5 +2046,5 @@
 	}
 
-	virtual void visit( CastExpr * old ) override final {
+	virtual void visit( const CastExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::CastExpr(
@@ -2056,5 +2056,5 @@
 	}
 
-	virtual void visit( KeywordCastExpr * old) override final {
+	virtual void visit( const KeywordCastExpr * old) override final {
 		ast::KeywordCastExpr::Target castTarget = ast::KeywordCastExpr::NUMBER_OF_TARGETS;
 		switch (old->target) {
@@ -2081,5 +2081,5 @@
 	}
 
-	virtual void visit( VirtualCastExpr * old ) override final {
+	virtual void visit( const VirtualCastExpr * old ) override final {
 		this->node = visitBaseExpr_SkipResultType( old,
 			new ast::VirtualCastExpr(
@@ -2091,5 +2091,5 @@
 	}
 
-	virtual void visit( AddressExpr * old ) override final {
+	virtual void visit( const AddressExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::AddressExpr(
@@ -2100,5 +2100,5 @@
 	}
 
-	virtual void visit( LabelAddressExpr * old ) override final {
+	virtual void visit( const LabelAddressExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::LabelAddressExpr(
@@ -2109,5 +2109,5 @@
 	}
 
-	virtual void visit( UntypedMemberExpr * old ) override final {
+	virtual void visit( const UntypedMemberExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::UntypedMemberExpr(
@@ -2119,5 +2119,5 @@
 	}
 
-	virtual void visit( MemberExpr * old ) override final {
+	virtual void visit( const MemberExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::MemberExpr(
@@ -2129,5 +2129,5 @@
 	}
 
-	virtual void visit( VariableExpr * old ) override final {
+	virtual void visit( const VariableExpr * old ) override final {
 		auto expr = new ast::VariableExpr(
 			old->location
@@ -2140,16 +2140,16 @@
 	}
 
-	virtual void visit( ConstantExpr * old ) override final {
+	virtual void visit( const ConstantExpr * old ) override final {
 		ast::ConstantExpr *rslt = new ast::ConstantExpr(
 			old->location,
 			GET_ACCEPT_1(result, Type),
-			old->constant.get_value(),
+			old->constant.rep,
 			old->constant.ival
 		);
-		rslt->underlyer = getAccept1< ast::Type, Type* >( old->constant.get_type() );
+		rslt->underlyer = getAccept1< ast::Type, Type* >( old->constant.type );
 		this->node = visitBaseExpr( old, rslt );
 	}
 
-	virtual void visit( SizeofExpr * old ) override final {
+	virtual void visit( const SizeofExpr * old ) override final {
 		assert (old->expr || old->type);
 		assert (! (old->expr && old->type));
@@ -2172,5 +2172,5 @@
 	}
 
-	virtual void visit( AlignofExpr * old ) override final {
+	virtual void visit( const AlignofExpr * old ) override final {
 		assert (old->expr || old->type);
 		assert (! (old->expr && old->type));
@@ -2193,5 +2193,5 @@
 	}
 
-	virtual void visit( UntypedOffsetofExpr * old ) override final {
+	virtual void visit( const UntypedOffsetofExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::UntypedOffsetofExpr(
@@ -2203,5 +2203,5 @@
 	}
 
-	virtual void visit( OffsetofExpr * old ) override final {
+	virtual void visit( const OffsetofExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::OffsetofExpr(
@@ -2213,5 +2213,5 @@
 	}
 
-	virtual void visit( OffsetPackExpr * old ) override final {
+	virtual void visit( const OffsetPackExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::OffsetPackExpr(
@@ -2222,5 +2222,5 @@
 	}
 
-	virtual void visit( LogicalExpr * old ) override final {
+	virtual void visit( const LogicalExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::LogicalExpr(
@@ -2235,5 +2235,5 @@
 	}
 
-	virtual void visit( ConditionalExpr * old ) override final {
+	virtual void visit( const ConditionalExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::ConditionalExpr(
@@ -2246,5 +2246,5 @@
 	}
 
-	virtual void visit( CommaExpr * old ) override final {
+	virtual void visit( const CommaExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::CommaExpr(
@@ -2256,5 +2256,5 @@
 	}
 
-	virtual void visit( TypeExpr * old ) override final {
+	virtual void visit( const TypeExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::TypeExpr(
@@ -2265,5 +2265,5 @@
 	}
 
-	virtual void visit( AsmExpr * old ) override final {
+	virtual void visit( const AsmExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::AsmExpr(
@@ -2276,5 +2276,5 @@
 	}
 
-	virtual void visit( ImplicitCopyCtorExpr * old ) override final {
+	virtual void visit( const ImplicitCopyCtorExpr * old ) override final {
 		auto rslt = new ast::ImplicitCopyCtorExpr(
 			old->location,
@@ -2285,5 +2285,5 @@
 	}
 
-	virtual void visit( ConstructorExpr * old ) override final {
+	virtual void visit( const ConstructorExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::ConstructorExpr(
@@ -2294,5 +2294,5 @@
 	}
 
-	virtual void visit( CompoundLiteralExpr * old ) override final {
+	virtual void visit( const CompoundLiteralExpr * old ) override final {
 		this->node = visitBaseExpr_SkipResultType( old,
 			new ast::CompoundLiteralExpr(
@@ -2304,5 +2304,5 @@
 	}
 
-	virtual void visit( RangeExpr * old ) override final {
+	virtual void visit( const RangeExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::RangeExpr(
@@ -2314,5 +2314,5 @@
 	}
 
-	virtual void visit( UntypedTupleExpr * old ) override final {
+	virtual void visit( const UntypedTupleExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::UntypedTupleExpr(
@@ -2323,5 +2323,5 @@
 	}
 
-	virtual void visit( TupleExpr * old ) override final {
+	virtual void visit( const TupleExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::TupleExpr(
@@ -2332,5 +2332,5 @@
 	}
 
-	virtual void visit( TupleIndexExpr * old ) override final {
+	virtual void visit( const TupleIndexExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::TupleIndexExpr(
@@ -2342,5 +2342,5 @@
 	}
 
-	virtual void visit( TupleAssignExpr * old ) override final {
+	virtual void visit( const TupleAssignExpr * old ) override final {
 		this->node = visitBaseExpr_SkipResultType( old,
 			new ast::TupleAssignExpr(
@@ -2352,5 +2352,5 @@
 	}
 
-	virtual void visit( StmtExpr * old ) override final {
+	virtual void visit( const StmtExpr * old ) override final {
 		auto rslt = new ast::StmtExpr(
 			old->location,
@@ -2363,5 +2363,5 @@
 	}
 
-	virtual void visit( UniqueExpr * old ) override final {
+	virtual void visit( const UniqueExpr * old ) override final {
 		auto rslt = new ast::UniqueExpr(
 			old->location,
@@ -2375,5 +2375,5 @@
 	}
 
-	virtual void visit( UntypedInitExpr * old ) override final {
+	virtual void visit( const UntypedInitExpr * old ) override final {
 		std::deque<ast::InitAlternative> initAlts;
 		for (auto ia : old->initAlts) {
@@ -2392,5 +2392,5 @@
 	}
 
-	virtual void visit( InitExpr * old ) override final {
+	virtual void visit( const InitExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::InitExpr(
@@ -2402,5 +2402,5 @@
 	}
 
-	virtual void visit( DeletedExpr * old ) override final {
+	virtual void visit( const DeletedExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::DeletedExpr(
@@ -2408,11 +2408,11 @@
 				GET_ACCEPT_1(expr, Expr),
 				inCache(old->deleteStmt) ?
-					this->node :
-					GET_ACCEPT_1(deleteStmt, Node)
-			)
-		);
-	}
-
-	virtual void visit( DefaultArgExpr * old ) override final {
+					strict_dynamic_cast<ast::Decl*>(this->node) :
+					GET_ACCEPT_1(deleteStmt, Decl)
+			)
+		);
+	}
+
+	virtual void visit( const DefaultArgExpr * old ) override final {
 		this->node = visitBaseExpr( old,
 			new ast::DefaultArgExpr(
@@ -2423,5 +2423,5 @@
 	}
 
-	virtual void visit( GenericExpr * old ) override final {
+	virtual void visit( const GenericExpr * old ) override final {
 		std::vector<ast::GenericExpr::Association> associations;
 		for (auto association : old->associations) {
@@ -2440,5 +2440,5 @@
 	}
 
-	void visitType( Type * old, ast::Type * type ) {
+	void visitType( const Type * old, ast::Type * type ) {
 		// Some types do this in their constructor so add a check.
 		if ( !old->attributes.empty() && type->attributes.empty() ) {
@@ -2448,9 +2448,9 @@
 	}
 
-	virtual void visit( VoidType * old ) override final {
+	virtual void visit( const VoidType * old ) override final {
 		visitType( old, new ast::VoidType{ cv( old ) } );
 	}
 
-	virtual void visit( BasicType * old ) override final {
+	virtual void visit( const BasicType * old ) override final {
 		auto type = new ast::BasicType{ (ast::BasicType::Kind)(unsigned)old->kind, cv( old ) };
 		// I believe this should always be a BasicType.
@@ -2461,5 +2461,5 @@
 	}
 
-	virtual void visit( PointerType * old ) override final {
+	virtual void visit( const PointerType * old ) override final {
 		visitType( old, new ast::PointerType{
 			GET_ACCEPT_1( base, Type ),
@@ -2471,5 +2471,5 @@
 	}
 
-	virtual void visit( ArrayType * old ) override final {
+	virtual void visit( const ArrayType * old ) override final {
 		visitType( old, new ast::ArrayType{
 			GET_ACCEPT_1( base, Type ),
@@ -2481,5 +2481,5 @@
 	}
 
-	virtual void visit( ReferenceType * old ) override final {
+	virtual void visit( const ReferenceType * old ) override final {
 		visitType( old, new ast::ReferenceType{
 			GET_ACCEPT_1( base, Type ),
@@ -2488,5 +2488,5 @@
 	}
 
-	virtual void visit( QualifiedType * old ) override final {
+	virtual void visit( const QualifiedType * old ) override final {
 		visitType( old, new ast::QualifiedType{
 			GET_ACCEPT_1( parent, Type ),
@@ -2496,5 +2496,5 @@
 	}
 
-	virtual void visit( FunctionType * old ) override final {
+	virtual void visit( const FunctionType * old ) override final {
 		auto ty = new ast::FunctionType {
 			(ast::ArgumentFlag)old->isVarArgs,
@@ -2507,5 +2507,5 @@
 	}
 
-	void postvisit( ReferenceToType * old, ast::ReferenceToType * ty ) {
+	void postvisit( const ReferenceToType * old, ast::ReferenceToType * ty ) {
 		ty->forall = GET_ACCEPT_V( forall, TypeDecl );
 		ty->params = GET_ACCEPT_V( parameters, Expr );
@@ -2514,5 +2514,5 @@
 	}
 
-	virtual void visit( StructInstType * old ) override final {
+	virtual void visit( const StructInstType * old ) override final {
 		ast::StructInstType * ty;
 		if ( old->baseStruct ) {
@@ -2532,5 +2532,5 @@
 	}
 
-	virtual void visit( UnionInstType * old ) override final {
+	virtual void visit( const UnionInstType * old ) override final {
 		ast::UnionInstType * ty;
 		if ( old->baseUnion ) {
@@ -2550,5 +2550,5 @@
 	}
 
-	virtual void visit( EnumInstType * old ) override final {
+	virtual void visit( const EnumInstType * old ) override final {
 		ast::EnumInstType * ty;
 		if ( old->baseEnum ) {
@@ -2568,5 +2568,5 @@
 	}
 
-	virtual void visit( TraitInstType * old ) override final {
+	virtual void visit( const TraitInstType * old ) override final {
 		ast::TraitInstType * ty;
 		if ( old->baseTrait ) {
@@ -2586,5 +2586,5 @@
 	}
 
-	virtual void visit( TypeInstType * old ) override final {
+	virtual void visit( const TypeInstType * old ) override final {
 		ast::TypeInstType * ty;
 		if ( old->baseType ) {
@@ -2606,5 +2606,5 @@
 	}
 
-	virtual void visit( TupleType * old ) override final {
+	virtual void visit( const TupleType * old ) override final {
 		visitType( old, new ast::TupleType{
 			GET_ACCEPT_V( types, Type ),
@@ -2614,5 +2614,5 @@
 	}
 
-	virtual void visit( TypeofType * old ) override final {
+	virtual void visit( const TypeofType * old ) override final {
 		visitType( old, new ast::TypeofType{
 			GET_ACCEPT_1( expr, Expr ),
@@ -2622,25 +2622,25 @@
 	}
 
-	virtual void visit( AttrType * ) override final {
+	virtual void visit( const AttrType * ) override final {
 		assertf( false, "AttrType deprecated in new AST." );
 	}
 
-	virtual void visit( VarArgsType * old ) override final {
+	virtual void visit( const VarArgsType * old ) override final {
 		visitType( old, new ast::VarArgsType{ cv( old ) } );
 	}
 
-	virtual void visit( ZeroType * old ) override final {
+	virtual void visit( const ZeroType * old ) override final {
 		visitType( old, new ast::ZeroType{ cv( old ) } );
 	}
 
-	virtual void visit( OneType * old ) override final {
+	virtual void visit( const OneType * old ) override final {
 		visitType( old, new ast::OneType{ cv( old ) } );
 	}
 
-	virtual void visit( GlobalScopeType * old ) override final {
+	virtual void visit( const GlobalScopeType * old ) override final {
 		visitType( old, new ast::GlobalScopeType{} );
 	}
 
-	virtual void visit( Designation * old ) override final {
+	virtual void visit( const Designation * old ) override final {
 		this->node = new ast::Designation(
 			old->location,
@@ -2649,5 +2649,5 @@
 	}
 
-	virtual void visit( SingleInit * old ) override final {
+	virtual void visit( const SingleInit * old ) override final {
 		this->node = new ast::SingleInit(
 			old->location,
@@ -2657,5 +2657,5 @@
 	}
 
-	virtual void visit( ListInit * old ) override final {
+	virtual void visit( const ListInit * old ) override final {
 		this->node = new ast::ListInit(
 			old->location,
@@ -2666,5 +2666,5 @@
 	}
 
-	virtual void visit( ConstructorInit * old ) override final {
+	virtual void visit( const ConstructorInit * old ) override final {
 		this->node = new ast::ConstructorInit(
 			old->location,
@@ -2675,5 +2675,5 @@
 	}
 
-	virtual void visit( Constant * ) override final {
+	virtual void visit( const Constant * ) override final {
 		// Handled in visit( ConstantEpxr * ).
 		// In the new tree, Constant fields are inlined into containing ConstantExpression.
@@ -2681,5 +2681,5 @@
 	}
 
-	virtual void visit( Attribute * old ) override final {
+	virtual void visit( const Attribute * old ) override final {
 		this->node = new ast::Attribute(
 			old->name,
@@ -2688,5 +2688,5 @@
 	}
 
-	virtual void visit( AttrExpr * ) override final {
+	virtual void visit( const AttrExpr * ) override final {
 		assertf( false, "AttrExpr deprecated in new AST." );
 	}
Index: src/AST/Decl.hpp
===================================================================
--- src/AST/Decl.hpp	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/AST/Decl.hpp	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -104,7 +104,7 @@
 	ptr<Expr> bitfieldWidth;
 
-	ObjectDecl( const CodeLocation & loc, const std::string & name, const Type * type, 
-		const Init * init = nullptr, Storage::Classes storage = {}, 
-		Linkage::Spec linkage = Linkage::C, const Expr * bitWd = nullptr, 
+	ObjectDecl( const CodeLocation & loc, const std::string & name, const Type * type,
+		const Init * init = nullptr, Storage::Classes storage = {},
+		Linkage::Spec linkage = Linkage::C, const Expr * bitWd = nullptr,
 		std::vector< ptr<Attribute> > && attrs = {}, Function::Specs fs = {} )
 	: DeclWithType( loc, name, storage, linkage, std::move(attrs), fs ), type( type ),
@@ -325,4 +325,19 @@
 };
 
+/// With statement `with (...) ...`
+class WithStmt final : public Decl {
+public:
+	std::vector<ptr<Expr>> exprs;
+	ptr<Stmt> stmt;
+
+	WithStmt( const CodeLocation & loc, std::vector<ptr<Expr>> && exprs, const Stmt * stmt )
+	: Decl(loc, "", Storage::Auto, Linkage::Cforall), exprs(std::move(exprs)), stmt(stmt) {}
+
+	const Decl * accept( Visitor & v ) const override { return v.visit( this ); }
+private:
+	WithStmt * clone() const override { return new WithStmt{ *this }; }
+	MUTATE_FRIEND
+};
+
 class AsmDecl : public Decl {
 public:
Index: src/AST/Expr.hpp
===================================================================
--- src/AST/Expr.hpp	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/AST/Expr.hpp	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -50,6 +50,6 @@
 
 	ParamEntry() : decl( 0 ), declptr( nullptr ), actualType( nullptr ), formalType( nullptr ), expr( nullptr ) {}
-	ParamEntry( 
-		UniqueId id, const Decl * declptr, const Type * actual, const Type * formal, 
+	ParamEntry(
+		UniqueId id, const Decl * declptr, const Type * actual, const Type * formal,
 		const Expr * e )
 	: decl( id ), declptr( declptr ), actualType( actual ), formalType( formal ), expr( e ) {}
@@ -115,7 +115,7 @@
 			case Empty: new(&data.resnSlots) ResnSlots{}; mode = Slots; // fallthrough
 			case Slots: return data.resnSlots;
-			case Params: assert(!"Cannot return to resnSlots from Params");
+			case Params: assertf(false, "Cannot return to resnSlots from Params"); abort();
 			}
-			return *((ResnSlots*)nullptr);
+			assertf(false, "unreachable");
 		}
 
@@ -124,6 +124,6 @@
 				return data.resnSlots;
 			}
-			assert(!"Mode was not already resnSlots");
-			return *((ResnSlots*)nullptr);
+			assertf(false, "Mode was not already resnSlots");
+			abort();
 		}
 
@@ -134,6 +134,5 @@
 			case Params: return data.inferParams;
 			}
-			assert(!"unreachable");
-			return *((InferredParams*)nullptr);
+			assertf(false, "unreachable");
 		}
 
@@ -142,14 +141,14 @@
 				return data.inferParams;
 			}
-			assert(!"Mode was not already Params");
-			return *((InferredParams*)nullptr);
+			assertf(false, "Mode was not already Params");
+			abort();
 		}
 
 		void set_inferParams( InferredParams && ps ) {
 			switch(mode) {
-			case Slots: 
+			case Slots:
 				data.resnSlots.~ResnSlots();
 				// fallthrough
-			case Empty: 
+			case Empty:
 				new(&data.inferParams) InferredParams{ std::move( ps ) };
 				mode = Params;
@@ -175,5 +174,5 @@
 					data.inferParams[p.first] = std::move(p.second);
 				}
-			} else assert(!"invalid mode");
+			} else assertf(false, "invalid mode");
 		}
 	};
@@ -387,5 +386,5 @@
 
 	ConstantExpr(
-		const CodeLocation & loc, const Type * ty, const std::string & r, 
+		const CodeLocation & loc, const Type * ty, const std::string & r,
 			std::optional<unsigned long long> i )
 	: Expr( loc, ty ), rep( r ), ival( i ) {}
@@ -773,7 +772,7 @@
 public:
 	ptr<Expr> expr;
-	readonly<Node> deleteStmt;
-
-	DeletedExpr( const CodeLocation & loc, const Expr * e, const Node * del )
+	readonly<Decl> deleteStmt;
+
+	DeletedExpr( const CodeLocation & loc, const Expr * e, const Decl * del )
 	: Expr( loc, e->result ), expr( e ), deleteStmt( del ) { assert( expr->result ); }
 
Index: src/AST/Pass.hpp
===================================================================
--- src/AST/Pass.hpp	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/AST/Pass.hpp	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -115,5 +115,5 @@
 	const ast::Stmt *             visit( const ast::FinallyStmt          * ) override final;
 	const ast::Stmt *             visit( const ast::WaitForStmt          * ) override final;
-	const ast::Stmt *             visit( const ast::WithStmt             * ) override final;
+	const ast::Decl *             visit( const ast::WithStmt             * ) override final;
 	const ast::NullStmt *         visit( const ast::NullStmt             * ) override final;
 	const ast::Stmt *             visit( const ast::DeclStmt             * ) override final;
Index: src/AST/Pass.impl.hpp
===================================================================
--- src/AST/Pass.impl.hpp	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/AST/Pass.impl.hpp	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -909,5 +909,5 @@
 // WithStmt
 template< typename pass_t >
-const ast::Stmt * ast::Pass< pass_t >::visit( const ast::WithStmt * node ) {
+const ast::Decl * ast::Pass< pass_t >::visit( const ast::WithStmt * node ) {
 	VISIT_START( node );
 
Index: src/AST/Print.cpp
===================================================================
--- src/AST/Print.cpp	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/AST/Print.cpp	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -37,5 +37,5 @@
 }
 
-class Printer : public Visitor {
+class Printer final : public Visitor {
 public:
 	ostream & os;
@@ -272,5 +272,5 @@
 
 public:
-	virtual const ast::DeclWithType * visit( const ast::ObjectDecl * node ) {
+	virtual const ast::DeclWithType * visit( const ast::ObjectDecl * node ) override final {
 		if ( ! node->name.empty() ) os << node->name << ": ";
 
@@ -314,5 +314,5 @@
 	}
 
-	virtual const ast::DeclWithType * visit( const ast::FunctionDecl * node ) {
+	virtual const ast::DeclWithType * visit( const ast::FunctionDecl * node ) override final {
 		if ( !node->name.empty() ) os << node->name << ": ";
 
@@ -342,25 +342,25 @@
 	}
 
-	virtual const ast::Decl * visit( const ast::StructDecl * node ) {
+	virtual const ast::Decl * visit( const ast::StructDecl * node ) override final {
 		print(node);
 		return node;
 	}
 
-	virtual const ast::Decl * visit( const ast::UnionDecl * node ) {
+	virtual const ast::Decl * visit( const ast::UnionDecl * node ) override final {
 		print(node);
 		return node;
 	}
 
-	virtual const ast::Decl * visit( const ast::EnumDecl * node ) {
+	virtual const ast::Decl * visit( const ast::EnumDecl * node ) override final {
 		print(node);
 		return node;
 	}
 
-	virtual const ast::Decl * visit( const ast::TraitDecl * node ) {
+	virtual const ast::Decl * visit( const ast::TraitDecl * node ) override final {
 		print(node);
 		return node;
 	}
 
-	virtual const ast::Decl * visit( const ast::TypeDecl * node ) {
+	virtual const ast::Decl * visit( const ast::TypeDecl * node ) override final {
 		preprint( node );
 		if ( ! short_mode && node->init ) {
@@ -374,15 +374,15 @@
 	}
 
-	virtual const ast::Decl * visit( const ast::TypedefDecl * node ) {
-		preprint( node );
-		return node;
-	}
-
-	virtual const ast::AsmDecl * visit( const ast::AsmDecl * node ) {
+	virtual const ast::Decl * visit( const ast::TypedefDecl * node ) override final {
+		preprint( node );
+		return node;
+	}
+
+	virtual const ast::AsmDecl * visit( const ast::AsmDecl * node ) override final {
 		safe_print( node->stmt );
 		return node;
 	}
 
-	virtual const ast::StaticAssertDecl * visit( const ast::StaticAssertDecl * node ) {
+	virtual const ast::StaticAssertDecl * visit( const ast::StaticAssertDecl * node ) override final {
 		os << "Static Assert with condition: ";
 		++indent;
@@ -396,5 +396,5 @@
 	}
 
-	virtual const ast::CompoundStmt * visit( const ast::CompoundStmt * node ) {
+	virtual const ast::CompoundStmt * visit( const ast::CompoundStmt * node ) override final {
 		os << "Compound Statement:" << endl;
 		++indent;
@@ -404,5 +404,5 @@
 	}
 
-	virtual const ast::Stmt * visit( const ast::ExprStmt * node ) {
+	virtual const ast::Stmt * visit( const ast::ExprStmt * node ) override final {
 		++indent;
 		os << "Expression Statement:" << endl << indent;
@@ -412,5 +412,5 @@
 	}
 
-	virtual const ast::Stmt * visit( const ast::AsmStmt * node ) {
+	virtual const ast::Stmt * visit( const ast::AsmStmt * node ) override final {
 		os << "Assembler Statement:" << endl;
 		++indent;
@@ -433,10 +433,10 @@
 	}
 
-	virtual const ast::Stmt * visit( const ast::DirectiveStmt * node ) {
+	virtual const ast::Stmt * visit( const ast::DirectiveStmt * node ) override final {
 		os << "GCC Directive: " << node->directive << endl;
 		return node;
 	}
 
-	virtual const ast::Stmt * visit( const ast::IfStmt * node ) {
+	virtual const ast::Stmt * visit( const ast::IfStmt * node ) override final {
 		os << "If on condition:" << endl;
 		++indent;
@@ -473,5 +473,5 @@
 	}
 
-	virtual const ast::Stmt * visit( const ast::WhileStmt * node ) {
+	virtual const ast::Stmt * visit( const ast::WhileStmt * node ) override final {
 		if ( node->isDoWhile ) { os << "Do-"; }
 		os << "While on condition:" << endl;
@@ -490,5 +490,5 @@
 	}
 
-	virtual const ast::Stmt * visit( const ast::ForStmt * node ) {
+	virtual const ast::Stmt * visit( const ast::ForStmt * node ) override final {
 		os << "For Statement" << endl;
 
@@ -532,5 +532,5 @@
 	}
 
-	virtual const ast::Stmt * visit( const ast::SwitchStmt * node ) {
+	virtual const ast::Stmt * visit( const ast::SwitchStmt * node ) override final {
 		os << "Switch on condition: ";
 		safe_print( node->cond );
@@ -546,5 +546,5 @@
 	}
 
-	virtual const ast::Stmt * visit( const ast::CaseStmt * node ) {
+	virtual const ast::Stmt * visit( const ast::CaseStmt * node ) override final {
 		if ( node->isDefault() ) {
 			os << indent << "Default ";
@@ -565,5 +565,5 @@
 	}
 
-	virtual const ast::Stmt * visit( const ast::BranchStmt * node ) {
+	virtual const ast::Stmt * visit( const ast::BranchStmt * node ) override final {
 		os << "Branch (" << node->kindName() << ")" << endl;
 		++indent;
@@ -586,5 +586,5 @@
 	}
 
-	virtual const ast::Stmt * visit( const ast::ReturnStmt * node ) {
+	virtual const ast::Stmt * visit( const ast::ReturnStmt * node ) override final {
 		os << "Return Statement, returning";
 		if ( node->expr ) {
@@ -601,5 +601,5 @@
 	}
 
-	virtual const ast::Stmt * visit( const ast::ThrowStmt * node ) {
+	virtual const ast::Stmt * visit( const ast::ThrowStmt * node ) override final {
 		if ( node->target ) os << "Non-Local ";
 
@@ -621,5 +621,5 @@
 	}
 
-	virtual const ast::Stmt * visit( const ast::TryStmt * node ) {
+	virtual const ast::Stmt * visit( const ast::TryStmt * node ) override final {
 		++indent;
 		os << "Try Statement" << endl << indent-1
@@ -642,5 +642,5 @@
 	}
 
-	virtual const ast::Stmt * visit( const ast::CatchStmt * node ) {
+	virtual const ast::Stmt * visit( const ast::CatchStmt * node ) override final {
 		os << "Catch ";
 		switch ( node->kind ) {
@@ -667,5 +667,5 @@
 	}
 
-	virtual const ast::Stmt * visit( const ast::FinallyStmt * node ) {
+	virtual const ast::Stmt * visit( const ast::FinallyStmt * node ) override final {
 		os << "Finally Statement" << endl;
 		os << indent << "... with block:" << endl;
@@ -678,5 +678,5 @@
 	}
 
-	virtual const ast::Stmt * visit( const ast::WaitForStmt * node ) {
+	virtual const ast::Stmt * visit( const ast::WaitForStmt * node ) override final {
 		os << "Waitfor Statement" << endl;
 		indent += 2;
@@ -732,5 +732,5 @@
 	}
 
-	virtual const ast::Stmt * visit( const ast::WithStmt * node ) {
+	virtual const ast::Decl * visit( const ast::WithStmt * node ) override final {
 		os << "With statement" << endl;
 		os << indent << "... with expressions:" << endl;
@@ -744,5 +744,5 @@
 	}
 
-	virtual const ast::NullStmt * visit( const ast::NullStmt * node ) {
+	virtual const ast::NullStmt * visit( const ast::NullStmt * node ) override final {
 		os << "Null Statement" << endl;
 		print( node->labels );
@@ -751,5 +751,5 @@
 	}
 
-	virtual const ast::Stmt * visit( const ast::DeclStmt * node ) {
+	virtual const ast::Stmt * visit( const ast::DeclStmt * node ) override final {
 		os << "Declaration of ";
 		safe_print( node->decl );
@@ -758,5 +758,5 @@
 	}
 
-	virtual const ast::Stmt * visit( const ast::ImplicitCtorDtorStmt * node ) {
+	virtual const ast::Stmt * visit( const ast::ImplicitCtorDtorStmt * node ) override final {
 		os << "Implicit Ctor Dtor Statement" << endl;
 		os << indent << "... with Ctor/Dtor: ";
@@ -769,5 +769,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::ApplicationExpr * node ) {
+	virtual const ast::Expr * visit( const ast::ApplicationExpr * node ) override final {
 		++indent;
 		os << "Application of" << endl << indent;
@@ -784,5 +784,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::UntypedExpr * node ) {
+	virtual const ast::Expr * visit( const ast::UntypedExpr * node ) override final {
 		++indent;
 		os << "Applying untyped:" << endl;
@@ -797,5 +797,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::NameExpr * node ) {
+	virtual const ast::Expr * visit( const ast::NameExpr * node ) override final {
 		os << "Name: " << node->name;
 		postprint( node );
@@ -804,5 +804,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::AddressExpr * node ) {
+	virtual const ast::Expr * visit( const ast::AddressExpr * node ) override final {
 		os << "Address of:" << endl;
 		++indent;
@@ -815,5 +815,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::LabelAddressExpr * node ) {
+	virtual const ast::Expr * visit( const ast::LabelAddressExpr * node ) override final {
 		os << "Address of label:" << node->arg;
 
@@ -821,5 +821,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::CastExpr * node ) {
+	virtual const ast::Expr * visit( const ast::CastExpr * node ) override final {
 		++indent;
 		os << (node->isGenerated ? "Generated" : "Explicit") << " cast of:" << endl << indent;
@@ -841,5 +841,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::KeywordCastExpr * node ) {
+	virtual const ast::Expr * visit( const ast::KeywordCastExpr * node ) override final {
 		++indent;
 		os << "Keyword Cast of:" << endl << indent;
@@ -852,5 +852,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::VirtualCastExpr * node ) {
+	virtual const ast::Expr * visit( const ast::VirtualCastExpr * node ) override final {
 		++indent;
 		os << "Virtual Cast of:" << endl << indent;
@@ -869,5 +869,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::UntypedMemberExpr * node ) {
+	virtual const ast::Expr * visit( const ast::UntypedMemberExpr * node ) override final {
 		++indent;
 		os << "Untyped Member Expression, with field: " << endl << indent;
@@ -881,5 +881,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::MemberExpr * node ) {
+	virtual const ast::Expr * visit( const ast::MemberExpr * node ) override final {
 		++indent;
 		os << "Member Expression, with field:" << endl << indent;
@@ -893,5 +893,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::VariableExpr * node ) {
+	virtual const ast::Expr * visit( const ast::VariableExpr * node ) override final {
 		os << "Variable Expression: ";
 		short_print( node->var );
@@ -901,5 +901,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::ConstantExpr * node ) {
+	virtual const ast::Expr * visit( const ast::ConstantExpr * node ) override final {
 		os << "Constant Expression (" << node->rep;
 		if ( node->result ) {
@@ -913,5 +913,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::SizeofExpr * node ) {
+	virtual const ast::Expr * visit( const ast::SizeofExpr * node ) override final {
 		os << "Sizeof Expression on: ";
 		++indent;
@@ -924,5 +924,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::AlignofExpr * node ) {
+	virtual const ast::Expr * visit( const ast::AlignofExpr * node ) override final {
 		os << "Alignof Expression on: ";
 		++indent;
@@ -935,5 +935,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::UntypedOffsetofExpr * node ) {
+	virtual const ast::Expr * visit( const ast::UntypedOffsetofExpr * node ) override final {
 		os << "Untyped Offsetof Expression on member " << node->member << " of ";
 		++indent;
@@ -945,5 +945,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::OffsetofExpr * node ) {
+	virtual const ast::Expr * visit( const ast::OffsetofExpr * node ) override final {
 		os << "Offsetof Expression on member " << node->member->name << " of ";
 		++indent;
@@ -955,5 +955,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::OffsetPackExpr * node ) {
+	virtual const ast::Expr * visit( const ast::OffsetPackExpr * node ) override final {
 		os << "Offset Pack Expression on: ";
 		++indent;
@@ -965,5 +965,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::LogicalExpr * node ) {
+	virtual const ast::Expr * visit( const ast::LogicalExpr * node ) override final {
 		os << "Short-circuited operation (" << (node->isAnd ? "and" : "or") << ") on: ";
 		safe_print( node->arg1 );
@@ -975,5 +975,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::ConditionalExpr * node ) {
+	virtual const ast::Expr * visit( const ast::ConditionalExpr * node ) override final {
 		++indent;
 		os << "Conditional expression on:" << endl << indent;
@@ -989,5 +989,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::CommaExpr * node ) {
+	virtual const ast::Expr * visit( const ast::CommaExpr * node ) override final {
 		++indent;
 		os << "Comma Expression:" << endl << indent;
@@ -1001,5 +1001,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::TypeExpr * node ) {
+	virtual const ast::Expr * visit( const ast::TypeExpr * node ) override final {
 		safe_print( node->type );
 		postprint( node );
@@ -1008,5 +1008,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::AsmExpr * node ) {
+	virtual const ast::Expr * visit( const ast::AsmExpr * node ) override final {
 		os << "Asm Expression:" << endl;
 		++indent;
@@ -1019,5 +1019,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::ImplicitCopyCtorExpr * node ) {
+	virtual const ast::Expr * visit( const ast::ImplicitCopyCtorExpr * node ) override final {
 		++indent;
 		os << "Implicit Copy Constructor Expression:" << endl << indent;
@@ -1029,5 +1029,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::ConstructorExpr * node ) {
+	virtual const ast::Expr * visit( const ast::ConstructorExpr * node ) override final {
 		os <<  "Constructor Expression:" << endl << indent+1;
 		indent += 2;
@@ -1039,5 +1039,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::CompoundLiteralExpr * node ) {
+	virtual const ast::Expr * visit( const ast::CompoundLiteralExpr * node ) override final {
 		++indent;
 		os << "Compound Literal Expression: " << endl << indent;
@@ -1051,5 +1051,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::RangeExpr * node ) {
+	virtual const ast::Expr * visit( const ast::RangeExpr * node ) override final {
 		os << "Range Expression: ";
 		safe_print( node->low );
@@ -1061,5 +1061,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::UntypedTupleExpr * node ) {
+	virtual const ast::Expr * visit( const ast::UntypedTupleExpr * node ) override final {
 		os << "Untyped Tuple:" << endl;
 		++indent;
@@ -1071,5 +1071,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::TupleExpr * node ) {
+	virtual const ast::Expr * visit( const ast::TupleExpr * node ) override final {
 		os << "Tuple:" << endl;
 		++indent;
@@ -1081,5 +1081,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::TupleIndexExpr * node ) {
+	virtual const ast::Expr * visit( const ast::TupleIndexExpr * node ) override final {
 		os << "Tuple Index Expression, with tuple:" << endl;
 		++indent;
@@ -1093,5 +1093,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::TupleAssignExpr * node ) {
+	virtual const ast::Expr * visit( const ast::TupleAssignExpr * node ) override final {
 		os << "Tuple Assignment Expression, with stmt expr:" << endl;
 		++indent;
@@ -1104,5 +1104,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::StmtExpr * node ) {
+	virtual const ast::Expr * visit( const ast::StmtExpr * node ) override final {
 		++indent;
 		os << "Statement Expression:" << endl << indent;
@@ -1122,5 +1122,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::UniqueExpr * node ) {
+	virtual const ast::Expr * visit( const ast::UniqueExpr * node ) override final {
 		++indent;
 		os << "Unique Expression with id: " << node->id << endl << indent;
@@ -1136,5 +1136,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::UntypedInitExpr * node ) {
+	virtual const ast::Expr * visit( const ast::UntypedInitExpr * node ) override final {
 		++indent;
 		os << "Untyped Init Expression" << endl << indent;
@@ -1152,5 +1152,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::InitExpr * node ) {
+	virtual const ast::Expr * visit( const ast::InitExpr * node ) override final {
 		++indent;
 		os << "Init Expression" << endl << indent;
@@ -1163,5 +1163,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::DeletedExpr * node ) {
+	virtual const ast::Expr * visit( const ast::DeletedExpr * node ) override final {
 		++indent;
 		os << "Deleted Expression" << endl << indent;
@@ -1174,5 +1174,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::DefaultArgExpr * node ) {
+	virtual const ast::Expr * visit( const ast::DefaultArgExpr * node ) override final {
 		++indent;
 		os << "Default Argument Expression" << endl << indent;
@@ -1183,5 +1183,5 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::GenericExpr * node ) {
+	virtual const ast::Expr * visit( const ast::GenericExpr * node ) override final {
 		++indent;
 		os << "C11 _Generic Expression" << endl << indent;
@@ -1206,5 +1206,5 @@
 	}
 
-	virtual const ast::Type * visit( const ast::VoidType * node ) {
+	virtual const ast::Type * visit( const ast::VoidType * node ) override final {
 		preprint( node );
 		os << "void";
@@ -1212,5 +1212,5 @@
 	}
 
-	virtual const ast::Type * visit( const ast::BasicType * node ) {
+	virtual const ast::Type * visit( const ast::BasicType * node ) override final {
 		preprint( node );
 		os << ast::BasicType::typeNames[ node->kind ];
@@ -1218,5 +1218,5 @@
 	}
 
-	virtual const ast::Type * visit( const ast::PointerType * node ) {
+	virtual const ast::Type * visit( const ast::PointerType * node ) override final {
 		preprint( node );
 		if ( ! node->isArray() ) {
@@ -1241,5 +1241,5 @@
 	}
 
-	virtual const ast::Type * visit( const ast::ArrayType * node ) {
+	virtual const ast::Type * visit( const ast::ArrayType * node ) override final {
 		preprint( node );
 		if ( node->isStatic ) {
@@ -1265,5 +1265,5 @@
 	}
 
-	virtual const ast::Type * visit( const ast::ReferenceType * node ) {
+	virtual const ast::Type * visit( const ast::ReferenceType * node ) override final {
 		preprint( node );
 		os << "reference to ";
@@ -1273,5 +1273,5 @@
 	}
 
-	virtual const ast::Type * visit( const ast::QualifiedType * node ) {
+	virtual const ast::Type * visit( const ast::QualifiedType * node ) override final {
 		preprint( node );
 		++indent;
@@ -1286,5 +1286,5 @@
 	}
 
-	virtual const ast::Type * visit( const ast::FunctionType * node ) {
+	virtual const ast::Type * visit( const ast::FunctionType * node ) override final {
 		preprint( node );
 
@@ -1315,5 +1315,5 @@
 	}
 
-	virtual const ast::Type * visit( const ast::StructInstType * node ) {
+	virtual const ast::Type * visit( const ast::StructInstType * node ) override final {
 		preprint( node );
 		os << "instance of struct " << node->name;
@@ -1326,5 +1326,5 @@
 	}
 
-	virtual const ast::Type * visit( const ast::UnionInstType * node ) {
+	virtual const ast::Type * visit( const ast::UnionInstType * node ) override final {
 		preprint( node );
 		os << "instance of union " << node->name;
@@ -1337,5 +1337,5 @@
 	}
 
-	virtual const ast::Type * visit( const ast::EnumInstType * node ) {
+	virtual const ast::Type * visit( const ast::EnumInstType * node ) override final {
 		preprint( node );
 		os << "instance of enum " << node->name;
@@ -1348,5 +1348,5 @@
 	}
 
-	virtual const ast::Type * visit( const ast::TraitInstType * node ) {
+	virtual const ast::Type * visit( const ast::TraitInstType * node ) override final {
 		preprint( node );
 		os << "instance of trait " << node->name;
@@ -1356,5 +1356,5 @@
 	}
 
-	virtual const ast::Type * visit( const ast::TypeInstType * node ) {
+	virtual const ast::Type * visit( const ast::TypeInstType * node ) override final {
 		preprint( node );
 		os << "instance of type " << node->name
@@ -1365,5 +1365,5 @@
 	}
 
-	virtual const ast::Type * visit( const ast::TupleType * node ) {
+	virtual const ast::Type * visit( const ast::TupleType * node ) override final {
 		preprint( node );
 		os << "tuple of types" << endl;
@@ -1375,5 +1375,5 @@
 	}
 
-	virtual const ast::Type * visit( const ast::TypeofType * node ) {
+	virtual const ast::Type * visit( const ast::TypeofType * node ) override final {
 		preprint( node );
 		if ( node->kind == ast::TypeofType::Basetypeof ) { os << "base-"; }
@@ -1384,5 +1384,5 @@
 	}
 
-	virtual const ast::Type * visit( const ast::VarArgsType * node ) {
+	virtual const ast::Type * visit( const ast::VarArgsType * node ) override final {
 		preprint( node );
 		os << "builtin var args pack";
@@ -1390,5 +1390,5 @@
 	}
 
-	virtual const ast::Type * visit( const ast::ZeroType * node ) {
+	virtual const ast::Type * visit( const ast::ZeroType * node ) override final {
 		preprint( node );
 		os << "zero_t";
@@ -1396,5 +1396,5 @@
 	}
 
-	virtual const ast::Type * visit( const ast::OneType * node ) {
+	virtual const ast::Type * visit( const ast::OneType * node ) override final {
 		preprint( node );
 		os << "one_t";
@@ -1402,5 +1402,5 @@
 	}
 
-	virtual const ast::Type * visit( const ast::GlobalScopeType * node ) {
+	virtual const ast::Type * visit( const ast::GlobalScopeType * node ) override final {
 		preprint( node );
 		os << "Global Scope Type";
@@ -1408,5 +1408,5 @@
 	}
 
-	virtual const ast::Designation * visit( const ast::Designation * node ) {
+	virtual const ast::Designation * visit( const ast::Designation * node ) override final {
 		if ( node->designators.empty() ) return node;
 		os << "... designated by: " << endl;
@@ -1421,5 +1421,5 @@
 	}
 
-	virtual const ast::Init * visit( const ast::SingleInit * node ) {
+	virtual const ast::Init * visit( const ast::SingleInit * node ) override final {
 		os << "Simple Initializer: ";
 		safe_print( node->value );
@@ -1427,5 +1427,5 @@
 	}
 
-	virtual const ast::Init * visit( const ast::ListInit * node ) {
+	virtual const ast::Init * visit( const ast::ListInit * node ) override final {
 		os << "Compound initializer: " << endl;
 		++indent;
@@ -1445,5 +1445,5 @@
 	}
 
-	virtual const ast::Init * visit( const ast::ConstructorInit * node ) {
+	virtual const ast::Init * visit( const ast::ConstructorInit * node ) override final {
 		os << "Constructor initializer: " << endl;
 		if ( node->ctor ) {
@@ -1470,5 +1470,5 @@
 	}
 
-	virtual const ast::Attribute * visit( const ast::Attribute * node ) {
+	virtual const ast::Attribute * visit( const ast::Attribute * node ) override final {
 		if ( node->empty() ) return node;
 		os << "Attribute with name: " << node->name;
@@ -1481,5 +1481,5 @@
 	}
 
-	virtual const ast::TypeSubstitution * visit( const ast::TypeSubstitution * node ) {
+	virtual const ast::TypeSubstitution * visit( const ast::TypeSubstitution * node ) override final {
 		os << indent << "Types:" << endl;
 		for ( const auto& i : *node ) {
Index: src/AST/Stmt.hpp
===================================================================
--- src/AST/Stmt.hpp	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/AST/Stmt.hpp	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -382,20 +382,4 @@
 };
 
-/// With statement `with (...) ...`
-class WithStmt final : public Stmt {
-public:
-	std::vector<ptr<Expr>> exprs;
-	ptr<Stmt> stmt;
-
-	WithStmt( const CodeLocation & loc, std::vector<ptr<Expr>> && exprs, const Stmt * stmt,
-		std::vector<Label> && labels = {} )
-	: Stmt(loc, std::move(labels)), exprs(std::move(exprs)), stmt(stmt) {}
-
-	const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
-private:
-	WithStmt * clone() const override { return new WithStmt{ *this }; }
-	MUTATE_FRIEND
-};
-
 /// Any declaration in a (compound) statement.
 class DeclStmt final : public Stmt {
Index: src/AST/SymbolTable.cpp
===================================================================
--- src/AST/SymbolTable.cpp	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/AST/SymbolTable.cpp	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -73,5 +73,5 @@
 
 SymbolTable::SymbolTable()
-: idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable(), 
+: idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable(),
   prevScope(), scope( 0 ), repScope( 0 ) { ++*stats().count; }
 
@@ -171,5 +171,5 @@
 }
 
-void SymbolTable::addDeletedId( const DeclWithType * decl, const Node * deleter ) {
+void SymbolTable::addDeletedId( const DeclWithType * decl, const Decl * deleter ) {
 	// default handling of conflicts is to raise an error
 	addId( decl, OnConflict::error(), nullptr, deleter );
@@ -189,5 +189,5 @@
 			}
 		}
-		// does not need to be added to the table if both existing and added have a base that are 
+		// does not need to be added to the table if both existing and added have a base that are
 		// the same
 		return true;
@@ -209,14 +209,14 @@
 	const std::string &id = decl->name;
 
-	if ( ! typeTable ) { 
+	if ( ! typeTable ) {
 		typeTable = TypeTable::new_ptr();
 	} else {
 		++*stats().map_lookups;
 		auto existing = typeTable->find( id );
-		if ( existing != typeTable->end() 
-			&& existing->second.scope == scope 
+		if ( existing != typeTable->end()
+			&& existing->second.scope == scope
 			&& addedTypeConflicts( existing->second.decl, decl ) ) return;
 	}
-	
+
 	lazyInitScope();
 	++*stats().map_mutations;
@@ -237,6 +237,6 @@
 		++*stats().map_lookups;
 		auto existing = structTable->find( id );
-		if ( existing != structTable->end()  
-			&& existing->second.scope == scope 
+		if ( existing != structTable->end()
+			&& existing->second.scope == scope
 			&& addedDeclConflicts( existing->second.decl, decl ) ) return;
 	}
@@ -256,9 +256,9 @@
 		++*stats().map_lookups;
 		auto existing = enumTable->find( id );
-		if ( existing != enumTable->end()  
-			&& existing->second.scope == scope 
+		if ( existing != enumTable->end()
+			&& existing->second.scope == scope
 			&& addedDeclConflicts( existing->second.decl, decl ) ) return;
 	}
-	
+
 	lazyInitScope();
 	++*stats().map_mutations;
@@ -279,6 +279,6 @@
 		++*stats().map_lookups;
 		auto existing = unionTable->find( id );
-		if ( existing != unionTable->end() 
-			&& existing->second.scope == scope 
+		if ( existing != unionTable->end()
+			&& existing->second.scope == scope
 			&& addedDeclConflicts( existing->second.decl, decl ) ) return;
 	}
@@ -298,6 +298,6 @@
 		++*stats().map_lookups;
 		auto existing = traitTable->find( id );
-		if ( existing != traitTable->end() 
-			&& existing->second.scope == scope 
+		if ( existing != traitTable->end()
+			&& existing->second.scope == scope
 			&& addedDeclConflicts( existing->second.decl, decl ) ) return;
 	}
@@ -309,15 +309,15 @@
 
 
-void SymbolTable::addWith( const std::vector< ptr<Expr> > & withExprs, const Node * withStmt ) {
+void SymbolTable::addWith( const std::vector< ptr<Expr> > & withExprs, const Decl * withStmt ) {
 	for ( const Expr * expr : withExprs ) {
 		if ( ! expr->result ) continue;
 		const Type * resTy = expr->result->stripReferences();
 		auto aggrType = dynamic_cast< const ReferenceToType * >( resTy );
-		assertf( aggrType, "WithStmt expr has non-aggregate type: %s", 
+		assertf( aggrType, "WithStmt expr has non-aggregate type: %s",
 			toString( expr->result ).c_str() );
 		const AggregateDecl * aggr = aggrType->aggr();
-		assertf( aggr, "WithStmt has null aggregate from type: %s", 
+		assertf( aggr, "WithStmt has null aggregate from type: %s",
 			toString( expr->result ).c_str() );
-		
+
 		addMembers( aggr, expr, OnConflict::deleteWith( withStmt ) );
 	}
@@ -373,7 +373,7 @@
 	}
 
-	/// gets the declaration for the function acting on a type specified by otype key, 
+	/// gets the declaration for the function acting on a type specified by otype key,
 	/// nullptr if none such
-	const FunctionDecl * getFunctionForOtype( 
+	const FunctionDecl * getFunctionForOtype(
 			const DeclWithType * decl, const std::string & otypeKey ) {
 		auto func = dynamic_cast< const FunctionDecl * >( decl );
@@ -383,13 +383,13 @@
 }
 
-bool SymbolTable::removeSpecialOverrides( 
+bool SymbolTable::removeSpecialOverrides(
 		SymbolTable::IdData & data, SymbolTable::MangleTable::Ptr & mangleTable ) {
-	// if a type contains user defined ctor/dtor/assign, then special rules trigger, which 
-	// determine the set of ctor/dtor/assign that can be used  by the requester. In particular, 
-	// if the user defines a default ctor, then the generated default ctor is unavailable, 
-	// likewise for copy ctor and dtor. If the user defines any ctor/dtor, then no generated 
-	// field ctors are available. If the user defines any ctor then the generated default ctor 
-	// is unavailable (intrinsic default ctor must be overridden exactly). If the user defines 
-	// anything that looks like a copy constructor, then the generated copy constructor is 
+	// if a type contains user defined ctor/dtor/assign, then special rules trigger, which
+	// determine the set of ctor/dtor/assign that can be used  by the requester. In particular,
+	// if the user defines a default ctor, then the generated default ctor is unavailable,
+	// likewise for copy ctor and dtor. If the user defines any ctor/dtor, then no generated
+	// field ctors are available. If the user defines any ctor then the generated default ctor
+	// is unavailable (intrinsic default ctor must be overridden exactly). If the user defines
+	// anything that looks like a copy constructor, then the generated copy constructor is
 	// unavailable, and likewise for the assignment operator.
 
@@ -450,5 +450,5 @@
 		// if this is the first user-defined function, delete non-user-defined overloads
 		std::vector< MangleTable::value_type > deleted;
-		
+
 		for ( const auto& entry : *mangleTable ) {
 			// skip decls that aren't functions or are for the wrong type
@@ -489,5 +489,5 @@
 			if ( dataIsCopyFunc ) {
 				// remove current function if exists a user-defined copy function
-				// since the signatures for copy functions don't need to match exactly, using 
+				// since the signatures for copy functions don't need to match exactly, using
 				// a delete statement is the wrong approach
 				if ( InitTweak::isCopyFunction( decl ) ) return false;
@@ -499,5 +499,5 @@
 		}
 	}
-	
+
 	// nothing (more) to fix, return true
 	return true;
@@ -525,18 +525,18 @@
 
 bool SymbolTable::addedIdConflicts(
-		const SymbolTable::IdData & existing, const DeclWithType * added, 
-		SymbolTable::OnConflict handleConflicts, const Node * deleter ) {
-	// if we're giving the same name mangling to things of different types then there is something 
+		const SymbolTable::IdData & existing, const DeclWithType * added,
+		SymbolTable::OnConflict handleConflicts, const Decl * deleter ) {
+	// if we're giving the same name mangling to things of different types then there is something
 	// wrong
 	assert( (isObject( added ) && isObject( existing.id ) )
 		|| ( isFunction( added ) && isFunction( existing.id ) ) );
-	
+
 	if ( existing.id->linkage.is_overrideable ) {
 		// new definition shadows the autogenerated one, even at the same scope
 		return false;
-	} else if ( existing.id->linkage.is_mangled 
-			|| ResolvExpr::typesCompatible( 
+	} else if ( existing.id->linkage.is_mangled
+			|| ResolvExpr::typesCompatible(
 				added->get_type(), existing.id->get_type(), SymbolTable{} ) ) {
-		
+
 		// it is a conflict if one declaration is deleted and the other is not
 		if ( deleter && ! existing.deleter ) {
@@ -555,7 +555,7 @@
 		if ( isDefinition( added ) && isDefinition( existing.id ) ) {
 			if ( handleConflicts.mode == OnConflict::Error ) {
-				SemanticError( added, 
-					isFunction( added ) ? 
-						"duplicate function definition for " : 
+				SemanticError( added,
+					isFunction( added ) ?
+						"duplicate function definition for " :
 						"duplicate object definition for " );
 			}
@@ -572,7 +572,7 @@
 }
 
-void SymbolTable::addId( 
-		const DeclWithType * decl, SymbolTable::OnConflict handleConflicts, const Expr * baseExpr, 
-		const Node * deleter ) {
+void SymbolTable::addId(
+		const DeclWithType * decl, SymbolTable::OnConflict handleConflicts, const Expr * baseExpr,
+		const Decl * deleter ) {
 	++*stats().add_calls;
 	const std::string &name = decl->name;
@@ -581,5 +581,5 @@
 	std::string mangleName;
 	if ( decl->linkage.is_overrideable ) {
-		// mangle the name without including the appropriate suffix, so overridable routines 
+		// mangle the name without including the appropriate suffix, so overridable routines
 		// are placed into the same "bucket" as their user defined versions.
 		mangleName = Mangle::mangle( decl, Mangle::Mode{ Mangle::NoOverrideable } );
@@ -588,5 +588,5 @@
 	}
 
-	// this ensures that no two declarations with the same unmangled name at the same scope 
+	// this ensures that no two declarations with the same unmangled name at the same scope
 	// both have C linkage
 	if ( decl->linkage.is_mangled ) {
@@ -596,5 +596,5 @@
 		}
 	} else {
-		// NOTE: only correct if name mangling is completely isomorphic to C 
+		// NOTE: only correct if name mangling is completely isomorphic to C
 		// type-compatibility, which it may not be.
 		if ( hasIncompatibleCDecl( name, mangleName ) ) {
@@ -628,6 +628,6 @@
 						idTable = idTable->set(
 							name,
-							mangleTable->set( 
-								mangleName, 
+							mangleTable->set(
+								mangleName,
 								IdData{ existing->second, handleConflicts.deleter } ) );
 					}
@@ -647,5 +647,5 @@
 }
 
-void SymbolTable::addMembers( 
+void SymbolTable::addMembers(
 		const AggregateDecl * aggr, const Expr * expr, SymbolTable::OnConflict handleConflicts ) {
 	for ( const Decl * decl : aggr->members ) {
@@ -655,9 +655,9 @@
 				const Type * t = dwt->get_type()->stripReferences();
 				if ( auto rty = dynamic_cast<const ReferenceToType *>( t ) ) {
-					if ( ! dynamic_cast<const StructInstType *>(rty) 
+					if ( ! dynamic_cast<const StructInstType *>(rty)
 						&& ! dynamic_cast<const UnionInstType *>(rty) ) continue;
 					ResolvExpr::Cost cost = ResolvExpr::Cost::zero;
 					const Expr * base = ResolvExpr::referenceToRvalueConversion( expr, cost );
-					addMembers( 
+					addMembers(
 						rty->aggr(), new MemberExpr{ base->location, dwt, base }, handleConflicts );
 				}
@@ -680,5 +680,5 @@
 		if ( ! decl.second.id->linkage.is_mangled && decl.first == mangleName ) return true;
 	}
-	
+
 	return false;
 }
Index: src/AST/SymbolTable.hpp
===================================================================
--- src/AST/SymbolTable.hpp	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/AST/SymbolTable.hpp	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -37,13 +37,13 @@
 		readonly<DeclWithType> id = nullptr;  ///< Identifier of declaration
 		readonly<Expr> baseExpr = nullptr;    ///< Implied containing aggregate (from WithExpr)
-		readonly<Node> deleter = nullptr;     ///< Node deleting this declaration (if non-null)
+		readonly<Decl> deleter = nullptr;     ///< Node deleting this declaration (if non-null)
 		unsigned long scope = 0;              ///< Scope of identifier
 
 		IdData() = default;
-		IdData( const DeclWithType * i, const Expr * base, const Node * del, unsigned long s ) 
+		IdData( const DeclWithType * i, const Expr * base, const Decl * del, unsigned long s )
 		: id( i ), baseExpr( base ), deleter( del ), scope( s ) {}
-		
+
 		/// Modify an existing node with a new deleter
-		IdData( const IdData & o, const Node * del )
+		IdData( const IdData & o, const Decl * del )
 		: id( o.id ), baseExpr( o.baseExpr ), deleter( del ), scope( o.scope ) {}
 
@@ -58,5 +58,5 @@
 	struct scoped {
 		readonly<D> decl;     ///< wrapped declaration
-		unsigned long scope;  ///< scope of this declaration 
+		unsigned long scope;  ///< scope of this declaration
 
 		scoped(const D * d, unsigned long s) : decl(d), scope(s) {}
@@ -88,5 +88,5 @@
 	~SymbolTable();
 
-	// when using an indexer manually (e.g., within a mutator traversal), it is necessary to 
+	// when using an indexer manually (e.g., within a mutator traversal), it is necessary to
 	// tell the indexer explicitly when scopes begin and end
 	void enterScope();
@@ -118,5 +118,5 @@
 	void addId( const DeclWithType * decl, const Expr * baseExpr = nullptr );
 	/// Adds a deleted identifier declaration to the symbol table
-	void addDeletedId( const DeclWithType * decl, const Node * deleter );
+	void addDeletedId( const DeclWithType * decl, const Decl * deleter );
 
 	/// Adds a type to the symbol table
@@ -136,5 +136,5 @@
 
 	/// adds all of the IDs from WithStmt exprs
-	void addWith( const std::vector< ptr<Expr> > & withExprs, const Node * withStmt );
+	void addWith( const std::vector< ptr<Expr> > & withExprs, const Decl * withStmt );
 
 	/// convenience function for adding a list of Ids to the indexer
@@ -154,5 +154,5 @@
 	const SymbolTable * atScope( unsigned long i ) const;
 
-	/// Removes matching autogenerated constructors and destructors so that they will not be 
+	/// Removes matching autogenerated constructors and destructors so that they will not be
 	/// selected. If returns false, passed decl should not be added.
 	bool removeSpecialOverrides( IdData & decl, MangleTable::Ptr & mangleTable );
@@ -164,25 +164,25 @@
 			Delete  ///< Delete the earlier version with the delete statement
 		} mode;
-		const Node * deleter;  ///< Statement that deletes this expression
+		const Decl * deleter;  ///< Statement that deletes this expression
 
 	private:
 		OnConflict() : mode(Error), deleter(nullptr) {}
-		OnConflict( const Node * d ) : mode(Delete), deleter(d) {}
+		OnConflict( const Decl * d ) : mode(Delete), deleter(d) {}
 	public:
 		OnConflict( const OnConflict& ) = default;
 
 		static OnConflict error() { return {}; }
-		static OnConflict deleteWith( const Node * d ) { return { d }; }
+		static OnConflict deleteWith( const Decl * d ) { return { d }; }
 	};
 
 	/// true if the existing identifier conflicts with the added identifier
 	bool addedIdConflicts(
-		const IdData & existing, const DeclWithType * added, OnConflict handleConflicts, 
-		const Node * deleter );
+		const IdData & existing, const DeclWithType * added, OnConflict handleConflicts,
+		const Decl * deleter );
 
 	/// common code for addId, addDeletedId, etc.
-	void addId( 
-		const DeclWithType * decl, OnConflict handleConflicts, const Expr * baseExpr = nullptr, 
-		const Node * deleter = nullptr );
+	void addId(
+		const DeclWithType * decl, OnConflict handleConflicts, const Expr * baseExpr = nullptr,
+		const Decl * deleter = nullptr );
 
 	/// adds all of the members of the Aggregate (addWith helper)
Index: src/AST/Type.hpp
===================================================================
--- src/AST/Type.hpp	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/AST/Type.hpp	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -37,5 +37,6 @@
 
 template< typename T > class Pass;
-class ForallSubstitutor;
+
+struct ForallSubstitutor;
 
 class Type : public Node {
@@ -169,5 +170,5 @@
 	static const char *typeNames[];
 
-	BasicType( Kind k, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} ) 
+	BasicType( Kind k, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} )
 	: Type(q, std::move(as)), kind(k) {}
 
@@ -276,5 +277,5 @@
 public:
 	using ForallList = std::vector<ptr<TypeDecl>>;
-	
+
 	ForallList forall;
 
@@ -340,5 +341,5 @@
 	bool hoistType = false;
 
-	ReferenceToType( 
+	ReferenceToType(
 		const std::string& n, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} )
 	: ParameterizedType(q, std::move(as)), params(), name(n) {}
@@ -361,9 +362,9 @@
 	readonly<StructDecl> base;
 
-	StructInstType( 
+	StructInstType(
 		const std::string& n, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} )
 	: ReferenceToType( n, q, std::move(as) ), base() {}
 
-	StructInstType( 
+	StructInstType(
 		const StructDecl * b, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} );
 
@@ -383,9 +384,9 @@
 	readonly<UnionDecl> base;
 
-	UnionInstType( 
+	UnionInstType(
 		const std::string& n, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} )
 	: ReferenceToType( n, q, std::move(as) ), base() {}
 
-	UnionInstType( 
+	UnionInstType(
 		const UnionDecl * b, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} );
 
@@ -405,9 +406,9 @@
 	readonly<EnumDecl> base;
 
-	EnumInstType( 
+	EnumInstType(
 		const std::string& n, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} )
 	: ReferenceToType( n, q, std::move(as) ), base() {}
 
-	EnumInstType( 
+	EnumInstType(
 		const EnumDecl * b, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} );
 
@@ -427,9 +428,9 @@
 	readonly<TraitDecl> base;
 
-	TraitInstType( 
+	TraitInstType(
 		const std::string& n, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} )
 	: ReferenceToType( n, q, std::move(as) ), base() {}
-	
-	TraitInstType( 
+
+	TraitInstType(
 		const TraitDecl * b, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} );
 
@@ -451,10 +452,10 @@
 	TypeVar::Kind kind;
 
-	TypeInstType( 
+	TypeInstType(
 		const std::string& n, const TypeDecl * b, CV::Qualifiers q = {},
 		std::vector<ptr<Attribute>> && as = {} )
 	: ReferenceToType( n, q, std::move(as) ), base( b ), kind( b->kind ) {}
-	
-	TypeInstType( 
+
+	TypeInstType(
 		const std::string& n, TypeVar::Kind k, CV::Qualifiers q = {},
 		std::vector<ptr<Attribute>> && as = {} )
Index: src/AST/Visitor.hpp
===================================================================
--- src/AST/Visitor.hpp	(revision f6cc734e6e6ad8d8f1335041c851da7a591bb05a)
+++ src/AST/Visitor.hpp	(revision 4eb43fa21537c79c32be1ee375bd917f2a305475)
@@ -48,5 +48,5 @@
     virtual const ast::Stmt *             visit( const ast::FinallyStmt          * ) = 0;
     virtual const ast::Stmt *             visit( const ast::WaitForStmt          * ) = 0;
-    virtual const ast::Stmt *             visit( const ast::WithStmt             * ) = 0;
+    virtual const ast::Decl *             visit( const ast::WithStmt             * ) = 0;
     virtual const ast::NullStmt *         visit( const ast::NullStmt             * ) = 0;
     virtual const ast::Stmt *             visit( const ast::DeclStmt             * ) = 0;
