Index: src/AST/Expr.hpp
===================================================================
--- src/AST/Expr.hpp	(revision f3cc5b6512f55846804a909de3b8735e14b2adef)
+++ src/AST/Expr.hpp	(revision 87701b607d65c7537ed3e6026229861ab1667c6b)
@@ -27,7 +27,4 @@
 #include "Visitor.hpp"
 
-// Must be included in *all* AST classes; should be #undef'd at the end of the file
-#define MUTATE_FRIEND template<typename node_t> friend auto mutate(const node_t * node);
-
 namespace ast {
 
@@ -130,8 +127,7 @@
 private:
 	Expr * clone() const override = 0;
-	MUTATE_FRIEND
-};
-
-/// The application of a function to a set of parameters. 
+};
+
+/// The application of a function to a set of parameters.
 /// Post-resolver form of `UntypedExpr`
 class ApplicationExpr final : public Expr {
@@ -145,5 +141,4 @@
 private:
 	ApplicationExpr * clone() const override { return new ApplicationExpr{ *this }; }
-	MUTATE_FRIEND
 };
 
@@ -165,5 +160,4 @@
 private:
 	UntypedExpr * clone() const override { return new UntypedExpr{ *this }; }
-	MUTATE_FRIEND
 };
 
@@ -179,5 +173,4 @@
 private:
 	NameExpr * clone() const override { return new NameExpr{ *this }; }
-	MUTATE_FRIEND
 };
 
@@ -192,5 +185,4 @@
 private:
 	AddressExpr * clone() const override { return new AddressExpr{ *this }; }
-	MUTATE_FRIEND
 };
 
@@ -206,5 +198,4 @@
 private:
 	LabelAddressExpr * clone() const override { return new LabelAddressExpr{ *this }; }
-	MUTATE_FRIEND
 };
 
@@ -218,5 +209,5 @@
 	GeneratedFlag isGenerated;
 
-	CastExpr( const CodeLocation & loc, const Expr * a, const Type * to, 
+	CastExpr( const CodeLocation & loc, const Expr * a, const Type * to,
 		GeneratedFlag g = GeneratedCast ) : Expr( loc, to ), arg( a ), isGenerated( g ) {}
 	/// Cast-to-void
@@ -226,5 +217,4 @@
 private:
 	CastExpr * clone() const override { return new CastExpr{ *this }; }
-	MUTATE_FRIEND
 };
 
@@ -244,5 +234,4 @@
 private:
 	KeywordCastExpr * clone() const override { return new KeywordCastExpr{ *this }; }
-	MUTATE_FRIEND
 };
 
@@ -258,5 +247,4 @@
 private:
 	VirtualCastExpr * clone() const override { return new VirtualCastExpr{ *this }; }
-	MUTATE_FRIEND
 };
 
@@ -273,5 +261,4 @@
 private:
 	UntypedMemberExpr * clone() const override { return new UntypedMemberExpr{ *this }; }
-	MUTATE_FRIEND
 };
 
@@ -287,5 +274,4 @@
 private:
 	MemberExpr * clone() const override { return new MemberExpr{ *this }; }
-	MUTATE_FRIEND
 };
 
@@ -303,5 +289,4 @@
 private:
 	VariableExpr * clone() const override { return new VariableExpr{ *this }; }
-	MUTATE_FRIEND
 };
 
@@ -311,5 +296,5 @@
 		unsigned long long ival;
 		double dval;
-		
+
 		Val( unsigned long long i ) : ival( i ) {}
 		Val( double d ) : dval( d ) {}
@@ -318,10 +303,10 @@
 	std::string rep;
 
-	ConstantExpr( 
+	ConstantExpr(
 		const CodeLocation & loc, const Type * ty, const std::string & r, unsigned long long v )
 	: Expr( loc, ty ), val( v ), rep( r ) {}
 	ConstantExpr( const CodeLocation & loc, const Type * ty, const std::string & r, double v )
 	: Expr( loc, ty ), val( v ), rep( r ) {}
-	
+
 	/// Gets the value of this constant as an integer
 	long long int intValue() const;
@@ -347,5 +332,4 @@
 private:
 	ConstantExpr * clone() const override { return new ConstantExpr{ *this }; }
-	MUTATE_FRIEND
 };
 
@@ -363,5 +347,4 @@
 private:
 	SizeofExpr * clone() const override { return new SizeofExpr{ *this }; }
-	MUTATE_FRIEND
 };
 
@@ -379,5 +362,4 @@
 private:
 	AlignofExpr * clone() const override { return new AlignofExpr{ *this }; }
-	MUTATE_FRIEND
 };
 
@@ -394,5 +376,4 @@
 private:
 	UntypedOffsetofExpr * clone() const override { return new UntypedOffsetofExpr{ *this }; }
-	MUTATE_FRIEND
 };
 
@@ -408,5 +389,4 @@
 private:
 	OffsetofExpr * clone() const override { return new OffsetofExpr{ *this }; }
-	MUTATE_FRIEND
 };
 
@@ -421,5 +401,4 @@
 private:
 	OffsetPackExpr * clone() const override { return new OffsetPackExpr{ *this }; }
-	MUTATE_FRIEND
 };
 
@@ -439,5 +418,4 @@
 private:
 	LogicalExpr * clone() const override { return new LogicalExpr{ *this }; }
-	MUTATE_FRIEND
 };
 
@@ -455,5 +433,4 @@
 private:
 	ConditionalExpr * clone() const override { return new ConditionalExpr{ *this }; }
-	MUTATE_FRIEND
 };
 
@@ -464,5 +441,5 @@
 	ptr<Expr> arg2;
 
-	CommaExpr( const CodeLocation & loc, const Expr * a1, const Expr * a2 ) 
+	CommaExpr( const CodeLocation & loc, const Expr * a1, const Expr * a2 )
 	: Expr( loc ), arg1( a1 ), arg2( a2 ) {}
 
@@ -470,5 +447,4 @@
 private:
 	CommaExpr * clone() const override { return new CommaExpr{ *this }; }
-	MUTATE_FRIEND
 };
 
@@ -483,5 +459,4 @@
 private:
 	TypeExpr * clone() const override { return new TypeExpr{ *this }; }
-	MUTATE_FRIEND
 };
 
@@ -491,93 +466,8 @@
 public:
 	ptr<Expr> inout;
-	ptr<Expr> constraint; 
-};
-
-//=================================================================================================
-/// This disgusting and giant piece of boiler-plate is here to solve a cyclic dependency
-/// remove only if there is a better solution
-/// The problem is that ast::ptr< ... > uses increment/decrement which won't work well with
-/// forward declarations
-inline void increment( const class Expr * node, Node::ref_type ref ) { node->increment(ref); }
-inline void decrement( const class Expr * node, Node::ref_type ref ) { node->decrement(ref); }
-inline void increment( const class ApplicationExpr * node, Node::ref_type ref ) { node->increment(ref); }
-inline void decrement( const class ApplicationExpr * node, Node::ref_type ref ) { node->decrement(ref); }
-inline void increment( const class UntypedExpr * node, Node::ref_type ref ) { node->increment(ref); }
-inline void decrement( const class UntypedExpr * node, Node::ref_type ref ) { node->decrement(ref); }
-inline void increment( const class NameExpr * node, Node::ref_type ref ) { node->increment(ref); }
-inline void decrement( const class NameExpr * node, Node::ref_type ref ) { node->decrement(ref); }
-inline void increment( const class AddressExpr * node, Node::ref_type ref ) { node->increment(ref); }
-inline void decrement( const class AddressExpr * node, Node::ref_type ref ) { node->decrement(ref); }
-inline void increment( const class LabelAddressExpr * node, Node::ref_type ref ) { node->increment(ref); }
-inline void decrement( const class LabelAddressExpr * node, Node::ref_type ref ) { node->decrement(ref); }
-inline void increment( const class CastExpr * node, Node::ref_type ref ) { node->increment(ref); }
-inline void decrement( const class CastExpr * node, Node::ref_type ref ) { node->decrement(ref); }
-inline void increment( const class KeywordCastExpr * node, Node::ref_type ref ) { node->increment(ref); }
-inline void decrement( const class KeywordCastExpr * node, Node::ref_type ref ) { node->decrement(ref); }
-inline void increment( const class VirtualCastExpr * node, Node::ref_type ref ) { node->increment(ref); }
-inline void decrement( const class VirtualCastExpr * node, Node::ref_type ref ) { node->decrement(ref); }
-inline void increment( const class MemberExpr * node, Node::ref_type ref ) { node->increment(ref); }
-inline void decrement( const class MemberExpr * node, Node::ref_type ref ) { node->decrement(ref); }
-inline void increment( const class UntypedMemberExpr * node, Node::ref_type ref ) { node->increment(ref); }
-inline void decrement( const class UntypedMemberExpr * node, Node::ref_type ref ) { node->decrement(ref); }
-inline void increment( const class VariableExpr * node, Node::ref_type ref ) { node->increment(ref); }
-inline void decrement( const class VariableExpr * node, Node::ref_type ref ) { node->decrement(ref); }
-inline void increment( const class ConstantExpr * node, Node::ref_type ref ) { node->increment(ref); }
-inline void decrement( const class ConstantExpr * node, Node::ref_type ref ) { node->decrement(ref); }
-inline void increment( const class SizeofExpr * node, Node::ref_type ref ) { node->increment(ref); }
-inline void decrement( const class SizeofExpr * node, Node::ref_type ref ) { node->decrement(ref); }
-inline void increment( const class AlignofExpr * node, Node::ref_type ref ) { node->increment(ref); }
-inline void decrement( const class AlignofExpr * node, Node::ref_type ref ) { node->decrement(ref); }
-inline void increment( const class UntypedOffsetofExpr * node, Node::ref_type ref ) { node->increment(ref); }
-inline void decrement( const class UntypedOffsetofExpr * node, Node::ref_type ref ) { node->decrement(ref); }
-inline void increment( const class OffsetofExpr * node, Node::ref_type ref ) { node->increment(ref); }
-inline void decrement( const class OffsetofExpr * node, Node::ref_type ref ) { node->decrement(ref); }
-inline void increment( const class OffsetPackExpr * node, Node::ref_type ref ) { node->increment(ref); }
-inline void decrement( const class OffsetPackExpr * node, Node::ref_type ref ) { node->decrement(ref); }
-inline void increment( const class LogicalExpr * node, Node::ref_type ref ) { node->increment(ref); }
-inline void decrement( const class LogicalExpr * node, Node::ref_type ref ) { node->decrement(ref); }
-inline void increment( const class ConditionalExpr * node, Node::ref_type ref ) { node->increment(ref); }
-inline void decrement( const class ConditionalExpr * node, Node::ref_type ref ) { node->decrement(ref); }
-inline void increment( const class CommaExpr * node, Node::ref_type ref ) { node->increment(ref); }
-inline void decrement( const class CommaExpr * node, Node::ref_type ref ) { node->decrement(ref); }
-inline void increment( const class TypeExpr * node, Node::ref_type ref ) { node->increment(ref); }
-inline void decrement( const class TypeExpr * node, Node::ref_type ref ) { node->decrement(ref); }
-inline void increment( const class AsmExpr * node, Node::ref_type ref ) { node->increment(ref); }
-inline void decrement( const class AsmExpr * node, Node::ref_type ref ) { node->decrement(ref); }
-// inline void increment( const class ImplicitCopyCtorExpr * node, Node::ref_type ref ) { node->increment(ref); }
-// inline void decrement( const class ImplicitCopyCtorExpr * node, Node::ref_type ref ) { node->decrement(ref); }
-// inline void increment( const class ConstructorExpr * node, Node::ref_type ref ) { node->increment(ref); }
-// inline void decrement( const class ConstructorExpr * node, Node::ref_type ref ) { node->decrement(ref); }
-// inline void increment( const class CompoundLiteralExpr * node, Node::ref_type ref ) { node->increment(ref); }
-// inline void decrement( const class CompoundLiteralExpr * node, Node::ref_type ref ) { node->decrement(ref); }
-// inline void increment( const class UntypedValofExpr * node, Node::ref_type ref ) { node->increment(ref); }
-// inline void decrement( const class UntypedValofExpr * node, Node::ref_type ref ) { node->decrement(ref); }
-// inline void increment( const class RangeExpr * node, Node::ref_type ref ) { node->increment(ref); }
-// inline void decrement( const class RangeExpr * node, Node::ref_type ref ) { node->decrement(ref); }
-// inline void increment( const class UntypedTupleExpr * node, Node::ref_type ref ) { node->increment(ref); }
-// inline void decrement( const class UntypedTupleExpr * node, Node::ref_type ref ) { node->decrement(ref); }
-// inline void increment( const class TupleExpr * node, Node::ref_type ref ) { node->increment(ref); }
-// inline void decrement( const class TupleExpr * node, Node::ref_type ref ) { node->decrement(ref); }
-// inline void increment( const class TupleIndexExpr * node, Node::ref_type ref ) { node->increment(ref); }
-// inline void decrement( const class TupleIndexExpr * node, Node::ref_type ref ) { node->decrement(ref); }
-// inline void increment( const class TupleAssignExpr * node, Node::ref_type ref ) { node->increment(ref); }
-// inline void decrement( const class TupleAssignExpr * node, Node::ref_type ref ) { node->decrement(ref); }
-// inline void increment( const class StmtExpr * node, Node::ref_type ref ) { node->increment(ref); }
-// inline void decrement( const class StmtExpr * node, Node::ref_type ref ) { node->decrement(ref); }
-// inline void increment( const class UniqueExpr * node, Node::ref_type ref ) { node->increment(ref); }
-// inline void decrement( const class UniqueExpr * node, Node::ref_type ref ) { node->decrement(ref); }
-// inline void increment( const class UntypedInitExpr * node, Node::ref_type ref ) { node->increment(ref); }
-// inline void decrement( const class UntypedInitExpr * node, Node::ref_type ref ) { node->decrement(ref); }
-// inline void increment( const class InitExpr * node, Node::ref_type ref ) { node->increment(ref); }
-// inline void decrement( const class InitExpr * node, Node::ref_type ref ) { node->decrement(ref); }
-// inline void increment( const class DeletedExpr * node, Node::ref_type ref ) { node->increment(ref); }
-// inline void decrement( const class DeletedExpr * node, Node::ref_type ref ) { node->decrement(ref); }
-// inline void increment( const class DefaultArgExpr * node, Node::ref_type ref ) { node->increment(ref); }
-// inline void decrement( const class DefaultArgExpr * node, Node::ref_type ref ) { node->decrement(ref); }
-// inline void increment( const class GenericExpr * node, Node::ref_type ref ) { node->increment(ref); }
-// inline void decrement( const class GenericExpr * node, Node::ref_type ref ) { node->decrement(ref); }
+	ptr<Expr> constraint;
+};
+
 }
-
-#undef MUTATE_FRIEND
 
 // Local Variables: //
