Index: src/SynTree/AddressExpr.cc
===================================================================
--- src/SynTree/AddressExpr.cc	(revision 9bfc9da8135feec0d8796caf32105cd2b1957afc)
+++ src/SynTree/AddressExpr.cc	(revision 68f9c43ecf1873cbb5f06aee682704b56612ed16)
@@ -58,8 +58,4 @@
 }
 
-AddressExpr::~AddressExpr() {
-	delete arg;
-}
-
 void AddressExpr::print( std::ostream &os, Indenter indent ) const {
 	os << "Address of:" << std::endl;
@@ -75,5 +71,4 @@
 }
 LabelAddressExpr::LabelAddressExpr( const LabelAddressExpr & other ) : Expression( other ), arg( other.arg ) {}
-LabelAddressExpr::~LabelAddressExpr() {}
 
 void LabelAddressExpr::print( std::ostream & os, Indenter ) const {
Index: src/SynTree/AggregateDecl.cc
===================================================================
--- src/SynTree/AggregateDecl.cc	(revision 9bfc9da8135feec0d8796caf32105cd2b1957afc)
+++ src/SynTree/AggregateDecl.cc	(revision 68f9c43ecf1873cbb5f06aee682704b56612ed16)
@@ -33,10 +33,4 @@
 	cloneAll( other.attributes, attributes );
 	body = other.body;
-}
-
-AggregateDecl::~AggregateDecl() {
-	deleteAll( attributes );
-	deleteAll( parameters );
-	deleteAll( members );
 }
 
Index: src/SynTree/ApplicationExpr.cc
===================================================================
--- src/SynTree/ApplicationExpr.cc	(revision 9bfc9da8135feec0d8796caf32105cd2b1957afc)
+++ src/SynTree/ApplicationExpr.cc	(revision 68f9c43ecf1873cbb5f06aee682704b56612ed16)
@@ -43,10 +43,4 @@
 }
 
-ParamEntry::~ParamEntry() {
-	delete actualType;
-	delete formalType;
-	delete expr;
-}
-
 ApplicationExpr::ApplicationExpr( Expression *funcExpr, const std::list<Expression *> & args ) : function( funcExpr ), args( args ) {
 	PointerType *pointer = strict_dynamic_cast< PointerType* >( funcExpr->get_result() );
@@ -61,9 +55,4 @@
 		Expression( other ), function( maybeClone( other.function ) ) {
 	cloneAll( other.args, args );
-}
-
-ApplicationExpr::~ApplicationExpr() {
-	delete function;
-	deleteAll( args );
 }
 
Index: src/SynTree/ArrayType.cc
===================================================================
--- src/SynTree/ArrayType.cc	(revision 9bfc9da8135feec0d8796caf32105cd2b1957afc)
+++ src/SynTree/ArrayType.cc	(revision 68f9c43ecf1873cbb5f06aee682704b56612ed16)
@@ -34,9 +34,4 @@
 }
 
-ArrayType::~ArrayType() {
-	delete base;
-	delete dimension;
-}
-
 void ArrayType::print( std::ostream &os, Indenter indent ) const {
 	Type::print( os, indent );
Index: src/SynTree/AttrType.cc
===================================================================
--- src/SynTree/AttrType.cc	(revision 9bfc9da8135feec0d8796caf32105cd2b1957afc)
+++ src/SynTree/AttrType.cc	(revision 68f9c43ecf1873cbb5f06aee682704b56612ed16)
@@ -37,9 +37,4 @@
 }
 
-AttrType::~AttrType() {
-	delete expr;
-	delete type;
-}
-
 void AttrType::print( std::ostream &os, Indenter indent ) const {
 	Type::print( os, indent );
Index: src/SynTree/Attribute.cc
===================================================================
--- src/SynTree/Attribute.cc	(revision 9bfc9da8135feec0d8796caf32105cd2b1957afc)
+++ src/SynTree/Attribute.cc	(revision 68f9c43ecf1873cbb5f06aee682704b56612ed16)
@@ -23,8 +23,4 @@
 Attribute::Attribute( const Attribute &other ) : name( other.name ) {
 	cloneAll( other.parameters, parameters );
-}
-
-Attribute::~Attribute() {
-	deleteAll( parameters );
 }
 
Index: src/SynTree/Attribute.h
===================================================================
--- src/SynTree/Attribute.h	(revision 9bfc9da8135feec0d8796caf32105cd2b1957afc)
+++ src/SynTree/Attribute.h	(revision 68f9c43ecf1873cbb5f06aee682704b56612ed16)
@@ -36,5 +36,4 @@
 	Attribute( std::string name = "", const std::list< Expression * > & parameters = std::list< Expression * >() ) : name( name ), parameters( parameters ) {}
 	Attribute( const Attribute &other );
-	virtual ~Attribute();
 
 	std::string get_name() const { return name; }
Index: src/SynTree/BaseSyntaxNode.h
===================================================================
--- src/SynTree/BaseSyntaxNode.h	(revision 9bfc9da8135feec0d8796caf32105cd2b1957afc)
+++ src/SynTree/BaseSyntaxNode.h	(revision 68f9c43ecf1873cbb5f06aee682704b56612ed16)
@@ -17,13 +17,13 @@
 
 #include "Common/CodeLocation.h"
+#include "Common/GC.h"
 #include "Common/Indenter.h"
+
 class Visitor;
 class Mutator;
 
-class BaseSyntaxNode {
-  public:
+class BaseSyntaxNode : GC_Object {
+public:
 	CodeLocation location;
-
-	virtual ~BaseSyntaxNode() {}
 
 	virtual BaseSyntaxNode * clone() const = 0;
Index: src/SynTree/CommaExpr.cc
===================================================================
--- src/SynTree/CommaExpr.cc	(revision 9bfc9da8135feec0d8796caf32105cd2b1957afc)
+++ src/SynTree/CommaExpr.cc	(revision 68f9c43ecf1873cbb5f06aee682704b56612ed16)
@@ -34,9 +34,4 @@
 }
 
-CommaExpr::~CommaExpr() {
-	delete arg1;
-	delete arg2;
-}
-
 void CommaExpr::print( std::ostream &os, Indenter indent ) const {
 	os << "Comma Expression:" << std::endl;
Index: src/SynTree/CompoundStmt.cc
===================================================================
--- src/SynTree/CompoundStmt.cc	(revision 9bfc9da8135feec0d8796caf32105cd2b1957afc)
+++ src/SynTree/CompoundStmt.cc	(revision 68f9c43ecf1873cbb5f06aee682704b56612ed16)
@@ -68,8 +68,4 @@
 }
 
-CompoundStmt::~CompoundStmt() {
-	deleteAll( kids );
-}
-
 void CompoundStmt::print( std::ostream &os, Indenter indent ) const {
 	os << "CompoundStmt" << endl;
Index: src/SynTree/Constant.cc
===================================================================
--- src/SynTree/Constant.cc	(revision 9bfc9da8135feec0d8796caf32105cd2b1957afc)
+++ src/SynTree/Constant.cc	(revision 68f9c43ecf1873cbb5f06aee682704b56612ed16)
@@ -27,6 +27,4 @@
 	type = other.type->clone();
 }
-
-Constant::~Constant() { delete type; }
 
 Constant Constant::from_bool( bool b ) {
Index: src/SynTree/Constant.h
===================================================================
--- src/SynTree/Constant.h	(revision 9bfc9da8135feec0d8796caf32105cd2b1957afc)
+++ src/SynTree/Constant.h	(revision 68f9c43ecf1873cbb5f06aee682704b56612ed16)
@@ -30,6 +30,5 @@
 	Constant( Type * type, std::string rep, double val );
 	Constant( const Constant & other );
-	virtual ~Constant();
-
+	
 	virtual Constant * clone() const { return new Constant( *this ); }
 
Index: src/SynTree/DeclStmt.cc
===================================================================
--- src/SynTree/DeclStmt.cc	(revision 9bfc9da8135feec0d8796caf32105cd2b1957afc)
+++ src/SynTree/DeclStmt.cc	(revision 68f9c43ecf1873cbb5f06aee682704b56612ed16)
@@ -29,8 +29,4 @@
 }
 
-DeclStmt::~DeclStmt() {
-	delete decl;
-}
-
 void DeclStmt::print( std::ostream &os, Indenter indent ) const {
 	assert( decl != 0 );
Index: src/SynTree/Declaration.cc
===================================================================
--- src/SynTree/Declaration.cc	(revision 9bfc9da8135feec0d8796caf32105cd2b1957afc)
+++ src/SynTree/Declaration.cc	(revision 68f9c43ecf1873cbb5f06aee682704b56612ed16)
@@ -38,7 +38,4 @@
 }
 
-Declaration::~Declaration() {
-}
-
 void Declaration::fixUniqueId() {
 	// don't need to set unique ID twice
@@ -68,8 +65,4 @@
 }
 
-AsmDecl::~AsmDecl() {
-	delete stmt;
-}
-
 void AsmDecl::print( std::ostream &os, Indenter indent ) const {
 	stmt->print( os, indent );
Index: src/SynTree/Declaration.h
===================================================================
--- src/SynTree/Declaration.h	(revision 9bfc9da8135feec0d8796caf32105cd2b1957afc)
+++ src/SynTree/Declaration.h	(revision 68f9c43ecf1873cbb5f06aee682704b56612ed16)
@@ -45,5 +45,4 @@
 	Declaration( const std::string &name, Type::StorageClasses scs, LinkageSpec::Spec linkage );
 	Declaration( const Declaration &other );
-	virtual ~Declaration();
 
 	const std::string &get_name() const { return name; }
@@ -87,6 +86,5 @@
 	DeclarationWithType( const std::string &name, Type::StorageClasses scs, LinkageSpec::Spec linkage, const std::list< Attribute * > & attributes, Type::FuncSpecifiers fs );
 	DeclarationWithType( const DeclarationWithType &other );
-	virtual ~DeclarationWithType();
-
+	
 	std::string get_mangleName() const { return mangleName; }
 	DeclarationWithType * set_mangleName( std::string newValue ) { mangleName = newValue; return this; }
@@ -126,5 +124,4 @@
 				const std::list< Attribute * > attributes = std::list< Attribute * >(), Type::FuncSpecifiers fs = Type::FuncSpecifiers() );
 	ObjectDecl( const ObjectDecl &other );
-	virtual ~ObjectDecl();
 
 	virtual Type * get_type() const override { return type; }
@@ -156,5 +153,4 @@
 				  const std::list< Attribute * > attributes = std::list< Attribute * >(), Type::FuncSpecifiers fs = Type::FuncSpecifiers() );
 	FunctionDecl( const FunctionDecl &other );
-	virtual ~FunctionDecl();
 
 	virtual Type * get_type() const override { return type; }
@@ -184,5 +180,4 @@
 	NamedTypeDecl( const std::string &name, Type::StorageClasses scs, Type *type );
 	NamedTypeDecl( const NamedTypeDecl &other );
-	virtual ~NamedTypeDecl();
 
 	Type *get_base() const { return base; }
@@ -219,5 +214,4 @@
 	TypeDecl( const std::string &name, Type::StorageClasses scs, Type *type, Kind kind, bool sized, Type * init = nullptr );
 	TypeDecl( const TypeDecl &other );
-	virtual ~TypeDecl();
 
 	Kind get_kind() const { return kind; }
@@ -268,6 +262,5 @@
 	AggregateDecl( const std::string &name, const std::list< Attribute * > & attributes = std::list< class Attribute * >(), LinkageSpec::Spec linkage = LinkageSpec::Cforall );
 	AggregateDecl( const AggregateDecl &other );
-	virtual ~AggregateDecl();
-
+	
 	std::list<Declaration*>& get_members() { return members; }
 	std::list<TypeDecl*>& get_parameters() { return parameters; }
@@ -353,5 +346,4 @@
 	AsmDecl( AsmStmt *stmt );
 	AsmDecl( const AsmDecl &other );
-	virtual ~AsmDecl();
 
 	AsmStmt *get_stmt() { return stmt; }
Index: src/SynTree/DeclarationWithType.cc
===================================================================
--- src/SynTree/DeclarationWithType.cc	(revision 9bfc9da8135feec0d8796caf32105cd2b1957afc)
+++ src/SynTree/DeclarationWithType.cc	(revision 68f9c43ecf1873cbb5f06aee682704b56612ed16)
@@ -34,9 +34,4 @@
 }
 
-DeclarationWithType::~DeclarationWithType() {
-	deleteAll( attributes );
-	delete asmName;
-}
-
 // Local Variables: //
 // tab-width: 4 //
Index: src/SynTree/Expression.cc
===================================================================
--- src/SynTree/Expression.cc	(revision 9bfc9da8135feec0d8796caf32105cd2b1957afc)
+++ src/SynTree/Expression.cc	(revision 68f9c43ecf1873cbb5f06aee682704b56612ed16)
@@ -52,5 +52,4 @@
 Expression::~Expression() {
 	delete env;
-	delete result;
 }
 
@@ -74,6 +73,4 @@
 ConstantExpr::ConstantExpr( const ConstantExpr &other) : Expression( other ), constant( other.constant ) {
 }
-
-ConstantExpr::~ConstantExpr() {}
 
 void ConstantExpr::print( std::ostream &os, Indenter indent ) const {
@@ -120,8 +117,4 @@
 }
 
-VariableExpr::~VariableExpr() {
-	// don't delete the declaration, since it points somewhere else in the tree
-}
-
 VariableExpr * VariableExpr::functionPointer( FunctionDecl * func ) {
 	VariableExpr * funcExpr = new VariableExpr( func );
@@ -150,9 +143,4 @@
 }
 
-SizeofExpr::~SizeofExpr() {
-	delete expr;
-	delete type;
-}
-
 void SizeofExpr::print( std::ostream &os, Indenter indent) const {
 	os << "Sizeof Expression on: ";
@@ -176,9 +164,4 @@
 }
 
-AlignofExpr::~AlignofExpr() {
-	delete expr;
-	delete type;
-}
-
 void AlignofExpr::print( std::ostream &os, Indenter indent) const {
 	os << "Alignof Expression on: ";
@@ -196,8 +179,4 @@
 UntypedOffsetofExpr::UntypedOffsetofExpr( const UntypedOffsetofExpr &other ) :
 	Expression( other ), type( maybeClone( other.type ) ), member( other.member ) {}
-
-UntypedOffsetofExpr::~UntypedOffsetofExpr() {
-	delete type;
-}
 
 void UntypedOffsetofExpr::print( std::ostream &os, Indenter indent) const {
@@ -217,8 +196,4 @@
 	Expression( other ), type( maybeClone( other.type ) ), member( other.member ) {}
 
-OffsetofExpr::~OffsetofExpr() {
-	delete type;
-}
-
 void OffsetofExpr::print( std::ostream &os, Indenter indent) const {
 	os << "Offsetof Expression on member " << member->name << " of ";
@@ -234,6 +209,4 @@
 OffsetPackExpr::OffsetPackExpr( const OffsetPackExpr &other ) : Expression( other ), type( maybeClone( other.type ) ) {}
 
-OffsetPackExpr::~OffsetPackExpr() { delete type; }
-
 void OffsetPackExpr::print( std::ostream &os, Indenter indent ) const {
 	os << "Offset pack expression on ";
@@ -252,10 +225,4 @@
 AttrExpr::AttrExpr( const AttrExpr &other ) :
 		Expression( other ), attr( maybeClone( other.attr ) ), expr( maybeClone( other.expr ) ), type( maybeClone( other.type ) ), isType( other.isType ) {
-}
-
-AttrExpr::~AttrExpr() {
-	delete attr;
-	delete expr;
-	delete type;
 }
 
@@ -280,8 +247,4 @@
 
 CastExpr::CastExpr( const CastExpr &other ) : Expression( other ), arg( maybeClone( other.arg ) ) {
-}
-
-CastExpr::~CastExpr() {
-	delete arg;
 }
 
@@ -306,8 +269,4 @@
 }
 
-VirtualCastExpr::~VirtualCastExpr() {
-	delete arg;
-}
-
 void VirtualCastExpr::print( std::ostream &os, Indenter indent ) const {
 	os << "Virtual Cast of:" << std::endl << indent+1;
@@ -332,9 +291,4 @@
 }
 
-UntypedMemberExpr::~UntypedMemberExpr() {
-	delete aggregate;
-	delete member;
-}
-
 void UntypedMemberExpr::print( std::ostream &os, Indenter indent ) const {
 	os << "Untyped Member Expression, with field: " << std::endl << indent+1;
@@ -363,9 +317,4 @@
 }
 
-MemberExpr::~MemberExpr() {
-	// don't delete the member declaration, since it points somewhere else in the tree
-	delete aggregate;
-}
-
 void MemberExpr::print( std::ostream &os, Indenter indent ) const {
 	os << "Member Expression, with field: " << std::endl;
@@ -383,9 +332,4 @@
 		Expression( other ), function( maybeClone( other.function ) ) {
 	cloneAll( other.args, args );
-}
-
-UntypedExpr::~UntypedExpr() {
-	delete function;
-	deleteAll( args );
 }
 
@@ -436,6 +380,4 @@
 }
 
-NameExpr::~NameExpr() {}
-
 void NameExpr::print( std::ostream &os, Indenter indent ) const {
 	os << "Name: " << get_name();
@@ -450,9 +392,4 @@
 LogicalExpr::LogicalExpr( const LogicalExpr &other ) :
 		Expression( other ), arg1( maybeClone( other.arg1 ) ), arg2( maybeClone( other.arg2 ) ), isAnd( other.isAnd ) {
-}
-
-LogicalExpr::~LogicalExpr() {
-	delete arg1;
-	delete arg2;
 }
 
@@ -470,10 +407,4 @@
 ConditionalExpr::ConditionalExpr( const ConditionalExpr &other ) :
 		Expression( other ), arg1( maybeClone( other.arg1 ) ), arg2( maybeClone( other.arg2 ) ), arg3( maybeClone( other.arg3 ) ) {
-}
-
-ConditionalExpr::~ConditionalExpr() {
-	delete arg1;
-	delete arg2;
-	delete arg3;
 }
 
@@ -513,8 +444,4 @@
 ImplicitCopyCtorExpr::~ImplicitCopyCtorExpr() {
 	set_env( nullptr ); // ImplicitCopyCtorExpr does not take ownership of an environment
-	delete callExpr;
-	deleteAll( tempDecls );
-	deleteAll( returnDecls );
-	deleteAll( dtors );
 }
 
@@ -541,8 +468,4 @@
 }
 
-ConstructorExpr::~ConstructorExpr() {
-	delete callExpr;
-}
-
 void ConstructorExpr::print( std::ostream &os, Indenter indent ) const {
 	os <<  "Constructor Expression: " << std::endl << indent+1;
@@ -559,8 +482,4 @@
 
 CompoundLiteralExpr::CompoundLiteralExpr( const CompoundLiteralExpr &other ) : Expression( other ), initializer( other.initializer->clone() ) {}
-
-CompoundLiteralExpr::~CompoundLiteralExpr() {
-	delete initializer;
-}
 
 void CompoundLiteralExpr::print( std::ostream &os, Indenter indent ) const {
@@ -589,13 +508,7 @@
 	cloneAll( other.dtors, dtors );
 }
-StmtExpr::~StmtExpr() {
-	delete statements;
-	deleteAll( dtors );
-	deleteAll( returnDecls );
-}
 void StmtExpr::computeResult() {
 	assert( statements );
 	std::list< Statement * > & body = statements->kids;
-	delete result;
 	result = nullptr;
 	if ( ! returnDecls.empty() ) {
@@ -640,9 +553,5 @@
 UniqueExpr::UniqueExpr( const UniqueExpr &other ) : Expression( other ), expr( maybeClone( other.expr ) ), object( maybeClone( other.object ) ), var( maybeClone( other.var ) ), id( other.id ) {
 }
-UniqueExpr::~UniqueExpr() {
-	delete expr;
-	delete object;
-	delete var;
-}
+
 void UniqueExpr::print( std::ostream &os, Indenter indent ) const {
 	os << "Unique Expression with id:" << id << std::endl << indent+1;
@@ -657,14 +566,7 @@
 InitAlternative::InitAlternative( Type * type, Designation * designation ) : type( type ), designation( designation ) {}
 InitAlternative::InitAlternative( const InitAlternative & other ) : type( maybeClone( other.type ) ), designation( maybeClone( other.designation ) ) {}
-InitAlternative::~InitAlternative() {
-	delete type;
-	delete designation;
-}
 
 UntypedInitExpr::UntypedInitExpr( Expression * expr, const std::list<InitAlternative> & initAlts ) : expr( expr ), initAlts( initAlts ) {}
 UntypedInitExpr::UntypedInitExpr( const UntypedInitExpr & other ) : Expression( other ), expr( maybeClone( other.expr ) ), initAlts( other.initAlts ) {}
-UntypedInitExpr::~UntypedInitExpr() {
-	delete expr;
-}
 
 void UntypedInitExpr::print( std::ostream & os, Indenter indent ) const {
@@ -684,8 +586,4 @@
 }
 InitExpr::InitExpr( const InitExpr & other ) : Expression( other ), expr( maybeClone( other.expr ) ), designation( maybeClone( other.designation) ) {}
-InitExpr::~InitExpr() {
-	delete expr;
-	delete designation;
-}
 
 void InitExpr::print( std::ostream & os, Indenter indent ) const {
@@ -701,7 +599,4 @@
 }
 DeletedExpr::DeletedExpr( const DeletedExpr & other ) : Expression( other ), expr( maybeClone( other.expr ) ), deleteStmt( other.deleteStmt ) {}
-DeletedExpr::~DeletedExpr() {
-	delete expr;
-}
 
 void DeletedExpr::print( std::ostream & os, Indenter indent ) const {
Index: src/SynTree/Expression.h
===================================================================
--- src/SynTree/Expression.h	(revision 9bfc9da8135feec0d8796caf32105cd2b1957afc)
+++ src/SynTree/Expression.h	(revision 68f9c43ecf1873cbb5f06aee682704b56612ed16)
@@ -41,5 +41,4 @@
 	ParamEntry( UniqueId decl, Type * actualType, Type * formalType, Expression* expr ): decl( decl ), actualType( actualType ), formalType( formalType ), expr( expr ), inferParams( new InferredParams ) {}
 	ParamEntry( const ParamEntry & other );
-	~ParamEntry();
 	ParamEntry & operator=( const ParamEntry & other );
 
@@ -53,4 +52,7 @@
 /// Expression is the root type for all expressions
 class Expression : public BaseSyntaxNode {
+  protected:
+	virtual ~Expression();
+
   public:
 	Type * result;
@@ -61,5 +63,4 @@
 	Expression();
 	Expression( const Expression & other );
-	virtual ~Expression();
 
 	Type *& get_result() { return result; }
@@ -89,5 +90,4 @@
 	ApplicationExpr( Expression * function, const std::list<Expression *> & args = std::list< Expression * >() );
 	ApplicationExpr( const ApplicationExpr & other );
-	virtual ~ApplicationExpr();
 
 	Expression * get_function() const { return function; }
@@ -111,5 +111,4 @@
 	UntypedExpr( Expression * function, const std::list<Expression *> & args = std::list< Expression * >() );
 	UntypedExpr( const UntypedExpr & other );
-	virtual ~UntypedExpr();
 
 	Expression * get_function() const { return function; }
@@ -136,5 +135,4 @@
 	NameExpr( std::string name );
 	NameExpr( const NameExpr & other );
-	virtual ~NameExpr();
 
 	const std::string & get_name() const { return name; }
@@ -157,5 +155,4 @@
 	AddressExpr( Expression * arg );
 	AddressExpr( const AddressExpr & other );
-	virtual ~AddressExpr();
 
 	Expression * get_arg() const { return arg; }
@@ -176,5 +173,4 @@
 	LabelAddressExpr( const Label &arg );
 	LabelAddressExpr( const LabelAddressExpr & other );
-	virtual ~LabelAddressExpr();
 
 	virtual LabelAddressExpr * clone() const { return new LabelAddressExpr( * this ); }
@@ -192,5 +188,4 @@
 	CastExpr( Expression * arg, Type * toType );
 	CastExpr( const CastExpr & other );
-	virtual ~CastExpr();
 
 	Expression * get_arg() const { return arg; }
@@ -210,5 +205,4 @@
 	VirtualCastExpr( Expression * arg, Type * toType );
 	VirtualCastExpr( const VirtualCastExpr & other );
-	virtual ~VirtualCastExpr();
 
 	Expression * get_arg() const { return arg; }
@@ -229,5 +223,4 @@
 	UntypedMemberExpr( Expression * member, Expression * aggregate );
 	UntypedMemberExpr( const UntypedMemberExpr & other );
-	virtual ~UntypedMemberExpr();
 
 	Expression * get_member() const { return member; }
@@ -251,5 +244,4 @@
 	MemberExpr( DeclarationWithType * member, Expression * aggregate );
 	MemberExpr( const MemberExpr & other );
-	virtual ~MemberExpr();
 
 	DeclarationWithType * get_member() const { return member; }
@@ -272,5 +264,4 @@
 	VariableExpr( DeclarationWithType * var );
 	VariableExpr( const VariableExpr & other );
-	virtual ~VariableExpr();
 
 	DeclarationWithType * get_var() const { return var; }
@@ -292,5 +283,4 @@
 	ConstantExpr( Constant constant );
 	ConstantExpr( const ConstantExpr & other );
-	virtual ~ConstantExpr();
 
 	Constant * get_constant() { return & constant; }
@@ -316,5 +306,4 @@
 	SizeofExpr( const SizeofExpr & other );
 	SizeofExpr( Type * type );
-	virtual ~SizeofExpr();
 
 	Expression * get_expr() const { return expr; }
@@ -341,5 +330,4 @@
 	AlignofExpr( const AlignofExpr & other );
 	AlignofExpr( Type * type );
-	virtual ~AlignofExpr();
 
 	Expression * get_expr() const { return expr; }
@@ -364,5 +352,4 @@
 	UntypedOffsetofExpr( Type * type, const std::string & member );
 	UntypedOffsetofExpr( const UntypedOffsetofExpr & other );
-	virtual ~UntypedOffsetofExpr();
 
 	std::string get_member() const { return member; }
@@ -385,5 +372,4 @@
 	OffsetofExpr( Type * type, DeclarationWithType * member );
 	OffsetofExpr( const OffsetofExpr & other );
-	virtual ~OffsetofExpr();
 
 	Type * get_type() const { return type; }
@@ -405,5 +391,4 @@
 	OffsetPackExpr( StructInstType * type );
 	OffsetPackExpr( const OffsetPackExpr & other );
-	virtual ~OffsetPackExpr();
 
 	StructInstType * get_type() const { return type; }
@@ -427,5 +412,4 @@
 	AttrExpr( const AttrExpr & other );
 	AttrExpr( Expression * attr, Type * type );
-	virtual ~AttrExpr();
 
 	Expression * get_attr() const { return attr; }
@@ -452,5 +436,4 @@
 	LogicalExpr( Expression * arg1, Expression * arg2, bool andp = true );
 	LogicalExpr( const LogicalExpr & other );
-	virtual ~LogicalExpr();
 
 	bool get_isAnd() const { return isAnd; }
@@ -478,5 +461,4 @@
 	ConditionalExpr( Expression * arg1, Expression * arg2, Expression * arg3 );
 	ConditionalExpr( const ConditionalExpr & other );
-	virtual ~ConditionalExpr();
 
 	Expression * get_arg1() const { return arg1; }
@@ -501,5 +483,4 @@
 	CommaExpr( Expression * arg1, Expression * arg2 );
 	CommaExpr( const CommaExpr & other );
-	virtual ~CommaExpr();
 
 	Expression * get_arg1() const { return arg1; }
@@ -521,5 +502,4 @@
 	TypeExpr( Type * type );
 	TypeExpr( const TypeExpr & other );
-	virtual ~TypeExpr();
 
 	Type * get_type() const { return type; }
@@ -541,5 +521,4 @@
 	AsmExpr( Expression * inout, Expression * constraint, Expression * operand ) : inout( inout ), constraint( constraint ), operand( operand ) {}
 	AsmExpr( const AsmExpr & other );
-	virtual ~AsmExpr() { delete inout; delete constraint; delete operand; };
 
 	Expression * get_inout() const { return inout; }
@@ -563,4 +542,7 @@
 /// along with a set of copy constructor calls, one for each argument.
 class ImplicitCopyCtorExpr : public Expression {
+protected:
+	virtual ~ImplicitCopyCtorExpr();
+
 public:
 	ApplicationExpr * callExpr;
@@ -571,5 +553,4 @@
 	ImplicitCopyCtorExpr( ApplicationExpr * callExpr );
 	ImplicitCopyCtorExpr( const ImplicitCopyCtorExpr & other );
-	virtual ~ImplicitCopyCtorExpr();
 
 	ApplicationExpr * get_callExpr() const { return callExpr; }
@@ -593,5 +574,4 @@
 	ConstructorExpr( Expression * callExpr );
 	ConstructorExpr( const ConstructorExpr & other );
-	~ConstructorExpr();
 
 	Expression * get_callExpr() const { return callExpr; }
@@ -611,5 +591,4 @@
 	CompoundLiteralExpr( Type * type, Initializer * initializer );
 	CompoundLiteralExpr( const CompoundLiteralExpr & other );
-	virtual ~CompoundLiteralExpr();
 
 	Initializer * get_initializer() const { return initializer; }
@@ -648,5 +627,4 @@
 	UntypedTupleExpr( const std::list< Expression * > & exprs );
 	UntypedTupleExpr( const UntypedTupleExpr & other );
-	virtual ~UntypedTupleExpr();
 
 	std::list<Expression*>& get_exprs() { return exprs; }
@@ -665,5 +643,4 @@
 	TupleExpr( const std::list< Expression * > & exprs );
 	TupleExpr( const TupleExpr & other );
-	virtual ~TupleExpr();
 
 	std::list<Expression*>& get_exprs() { return exprs; }
@@ -683,5 +660,4 @@
 	TupleIndexExpr( Expression * tuple, unsigned int index );
 	TupleIndexExpr( const TupleIndexExpr & other );
-	virtual ~TupleIndexExpr();
 
 	Expression * get_tuple() const { return tuple; }
@@ -703,5 +679,4 @@
 	TupleAssignExpr( const std::list< Expression * > & assigns, const std::list< ObjectDecl * > & tempDecls );
 	TupleAssignExpr( const TupleAssignExpr & other );
-	virtual ~TupleAssignExpr();
 
 	TupleAssignExpr * set_stmtExpr( StmtExpr * newValue ) { stmtExpr = newValue; return this; }
@@ -723,5 +698,4 @@
 	StmtExpr( CompoundStmt * statements );
 	StmtExpr( const StmtExpr & other );
-	virtual ~StmtExpr();
 
 	CompoundStmt * get_statements() const { return statements; }
@@ -748,5 +722,4 @@
 	UniqueExpr( Expression * expr, long long idVal = -1 );
 	UniqueExpr( const UniqueExpr & other );
-	~UniqueExpr();
 
 	Expression * get_expr() const { return expr; }
@@ -778,5 +751,4 @@
 	InitAlternative( const InitAlternative & other );
 	InitAlternative & operator=( const Initializer & other ) = delete; // at the moment this isn't used, and I don't want to implement it
-	~InitAlternative();
 };
 
@@ -788,5 +760,4 @@
 	UntypedInitExpr( Expression * expr, const std::list<InitAlternative> & initAlts );
 	UntypedInitExpr( const UntypedInitExpr & other );
-	~UntypedInitExpr();
 
 	Expression * get_expr() const { return expr; }
@@ -808,5 +779,4 @@
 	InitExpr( Expression * expr, Designation * designation );
 	InitExpr( const InitExpr & other );
-	~InitExpr();
 
 	Expression * get_expr() const { return expr; }
@@ -830,5 +800,4 @@
 	DeletedExpr( Expression * expr, BaseSyntaxNode * deleteStmt );
 	DeletedExpr( const DeletedExpr & other );
-	~DeletedExpr();
 
 	virtual DeletedExpr * clone() const { return new DeletedExpr( * this ); }
Index: src/SynTree/FunctionDecl.cc
===================================================================
--- src/SynTree/FunctionDecl.cc	(revision 9bfc9da8135feec0d8796caf32105cd2b1957afc)
+++ src/SynTree/FunctionDecl.cc	(revision 68f9c43ecf1873cbb5f06aee682704b56612ed16)
@@ -52,10 +52,4 @@
 	}
 	cloneAll( other.withExprs, withExprs );
-}
-
-FunctionDecl::~FunctionDecl() {
-	delete type;
-	delete statements;
-	deleteAll( withExprs );
 }
 
Index: src/SynTree/FunctionType.cc
===================================================================
--- src/SynTree/FunctionType.cc	(revision 9bfc9da8135feec0d8796caf32105cd2b1957afc)
+++ src/SynTree/FunctionType.cc	(revision 68f9c43ecf1873cbb5f06aee682704b56612ed16)
@@ -31,9 +31,4 @@
 	cloneAll( other.returnVals, returnVals );
 	cloneAll( other.parameters, parameters );
-}
-
-FunctionType::~FunctionType() {
-	deleteAll( returnVals );
-	deleteAll( parameters );
 }
 
Index: src/SynTree/GcTracer.cc
===================================================================
--- src/SynTree/GcTracer.cc	(revision 68f9c43ecf1873cbb5f06aee682704b56612ed16)
+++ src/SynTree/GcTracer.cc	(revision 68f9c43ecf1873cbb5f06aee682704b56612ed16)
@@ -0,0 +1,29 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// GcTracer.cc --
+//
+// Author           : Aaron B. Moss
+// Created On       : Thu Mar 15 14:47:00 2018
+// Last Modified By : Aaron B. Moss
+// Last Modified On : Thu Mar 15 14:47:00 2018
+// Update Count     : 1
+//
+
+#include "GcTracer.h"
+
+#include "Expression.h"
+#include "TypeSubstitution.h"
+
+void GcTracer::postvisit( Expression * expr ) {
+
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/SynTree/GcTracer.h
===================================================================
--- src/SynTree/GcTracer.h	(revision 68f9c43ecf1873cbb5f06aee682704b56612ed16)
+++ src/SynTree/GcTracer.h	(revision 68f9c43ecf1873cbb5f06aee682704b56612ed16)
@@ -0,0 +1,62 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// GcTracer.h --
+//
+// Author           : Aaron B. Moss
+// Created On       : Thu Mar 15 14:47:00 2018
+// Last Modified By : Aaron B. Moss
+// Last Modified On : Thu Mar 15 14:47:00 2018
+// Update Count     : 1
+//
+
+#pragma once
+
+#include <list>
+
+#include "BaseSyntaxNode.h"
+#include "Expression.h"
+
+#include "Common/GC.h"
+#include "Common/PassVisitor.h"
+
+class Expression;
+
+/// Implements `trace` method for syntax nodes
+class GcTracer final : public WithShortCircuiting, public WithVisitorRef<GcTracer> {
+	const GC& gc;
+
+public:
+	GcTracer( const GC& gc ) : gc(gc) {}
+
+	void previsit( BaseSyntaxNode * node ) {
+		// skip tree if already seen
+		if ( node->mark == gc.mark ) {
+			visit_children = false;
+			return;
+		}
+
+		// mark node
+		node->mark = gc.mark;
+	}
+
+	void postvisit( Expression* expr ) {
+		maybeAccept( expr->env, *visitor );
+	}
+};
+
+/// Traces entire translation unit recursively
+static inline const GC& operator<< ( const GC& gc, const std::list<Declaration*>& translationUnit ) {
+	PassVisitor<GcTracer> tracer{ gc };
+	acceptAll( translationUnit, tracer );
+	return gc;
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/SynTree/Initializer.cc
===================================================================
--- src/SynTree/Initializer.cc	(revision 9bfc9da8135feec0d8796caf32105cd2b1957afc)
+++ src/SynTree/Initializer.cc	(revision 68f9c43ecf1873cbb5f06aee682704b56612ed16)
@@ -32,10 +32,4 @@
 }
 
-Designation::~Designation() {
-	// std::cerr << "destroying designation" << std::endl;
-	deleteAll( designators );
-	// std::cerr << "finished destroying designation" << std::endl;
-}
-
 void Designation::print( std::ostream &os, Indenter indent ) const {
 	if ( ! designators.empty() ) {
@@ -52,5 +46,4 @@
 Initializer::Initializer( const Initializer & other ) : BaseSyntaxNode( other ), maybeConstructed( other.maybeConstructed ) {
 }
-Initializer::~Initializer() {}
 
 SingleInit::SingleInit( Expression *v, bool maybeConstructed ) : Initializer( maybeConstructed ), value ( v ) {
@@ -58,8 +51,4 @@
 
 SingleInit::SingleInit( const SingleInit &other ) : Initializer(other), value ( maybeClone( other.value ) ) {
-}
-
-SingleInit::~SingleInit() {
-	delete value;
 }
 
@@ -87,9 +76,4 @@
 }
 
-ListInit::~ListInit() {
-	deleteAll( initializers );
-	deleteAll( designations );
-}
-
 void ListInit::print( std::ostream &os, Indenter indent ) const {
 	os << "Compound initializer: " << std::endl;
@@ -110,10 +94,4 @@
 ConstructorInit::ConstructorInit( Statement * ctor, Statement * dtor, Initializer * init ) : Initializer( true ), ctor( ctor ), dtor( dtor ), init( init ) {}
 ConstructorInit::ConstructorInit( const ConstructorInit &other ) : Initializer( other ), ctor( maybeClone( other.ctor ) ), dtor( maybeClone( other.dtor ) ), init( maybeClone( other.init ) ) {
-}
-
-ConstructorInit::~ConstructorInit() {
-	delete ctor;
-	delete dtor;
-	delete init;
 }
 
Index: src/SynTree/Initializer.h
===================================================================
--- src/SynTree/Initializer.h	(revision 9bfc9da8135feec0d8796caf32105cd2b1957afc)
+++ src/SynTree/Initializer.h	(revision 68f9c43ecf1873cbb5f06aee682704b56612ed16)
@@ -33,5 +33,4 @@
 	Designation( const std::list< Expression * > & designators );
 	Designation( const Designation & other );
-	virtual ~Designation();
 
 	std::list< Expression * > & get_designators() { return designators; }
@@ -50,5 +49,4 @@
 	Initializer( bool maybeConstructed );
 	Initializer( const Initializer & other );
-	virtual ~Initializer();
 
 	bool get_maybeConstructed() { return maybeConstructed; }
@@ -70,5 +68,4 @@
 	SingleInit( Expression *value, bool maybeConstructed = false );
 	SingleInit( const SingleInit &other );
-	virtual ~SingleInit();
 
 	Expression *get_value() { return value; }
@@ -91,5 +88,4 @@
 			  const std::list<Designation *> &designators = {}, bool maybeConstructed = false );
 	ListInit( const ListInit & other );
-	virtual ~ListInit();
 
 	std::list<Designation *> & get_designations() { return designations; }
@@ -123,5 +119,4 @@
 	ConstructorInit( Statement * ctor, Statement * dtor, Initializer * init );
 	ConstructorInit( const ConstructorInit &other );
-	virtual ~ConstructorInit();
 
 	void set_ctor( Statement * newValue ) { ctor = newValue; }
Index: src/SynTree/NamedTypeDecl.cc
===================================================================
--- src/SynTree/NamedTypeDecl.cc	(revision 9bfc9da8135feec0d8796caf32105cd2b1957afc)
+++ src/SynTree/NamedTypeDecl.cc	(revision 68f9c43ecf1873cbb5f06aee682704b56612ed16)
@@ -30,10 +30,4 @@
 	cloneAll( other.parameters, parameters );
 	cloneAll( other.assertions, assertions );
-}
-
-NamedTypeDecl::~NamedTypeDecl() {
-	delete base;
-	deleteAll( parameters );
-	deleteAll( assertions );
 }
 
Index: src/SynTree/ObjectDecl.cc
===================================================================
--- src/SynTree/ObjectDecl.cc	(revision 9bfc9da8135feec0d8796caf32105cd2b1957afc)
+++ src/SynTree/ObjectDecl.cc	(revision 68f9c43ecf1873cbb5f06aee682704b56612ed16)
@@ -32,10 +32,4 @@
 ObjectDecl::ObjectDecl( const ObjectDecl &other )
 	: Parent( other ), type( maybeClone( other.type ) ), init( maybeClone( other.init ) ), bitfieldWidth( maybeClone( other.bitfieldWidth ) ) {
-}
-
-ObjectDecl::~ObjectDecl() {
-	delete type;
-	delete init;
-	delete bitfieldWidth;
 }
 
Index: src/SynTree/PointerType.cc
===================================================================
--- src/SynTree/PointerType.cc	(revision 9bfc9da8135feec0d8796caf32105cd2b1957afc)
+++ src/SynTree/PointerType.cc	(revision 68f9c43ecf1873cbb5f06aee682704b56612ed16)
@@ -36,9 +36,4 @@
 }
 
-PointerType::~PointerType() {
-	delete base;
-	delete dimension;
-}
-
 void PointerType::print( std::ostream &os, Indenter indent ) const {
 	Type::print( os, indent );
Index: src/SynTree/ReferenceToType.cc
===================================================================
--- src/SynTree/ReferenceToType.cc	(revision 9bfc9da8135feec0d8796caf32105cd2b1957afc)
+++ src/SynTree/ReferenceToType.cc	(revision 68f9c43ecf1873cbb5f06aee682704b56612ed16)
@@ -32,8 +32,4 @@
 ReferenceToType::ReferenceToType( const ReferenceToType &other ) : Type( other ), name( other.name ), hoistType( other.hoistType ) {
 	cloneAll( other.parameters, parameters );
-}
-
-ReferenceToType::~ReferenceToType() {
-	deleteAll( parameters );
 }
 
@@ -170,7 +166,4 @@
 }
 
-TraitInstType::~TraitInstType() {
-}
-
 bool TraitInstType::isComplete() const { assert( false ); }
 
@@ -183,9 +176,4 @@
 
 TypeInstType::TypeInstType( const TypeInstType &other ) : Parent( other ), baseType( other.baseType ), isFtype( other.isFtype ) {
-}
-
-
-TypeInstType::~TypeInstType() {
-	// delete baseType; //This is shared and should not be deleted
 }
 
Index: src/SynTree/ReferenceType.cc
===================================================================
--- src/SynTree/ReferenceType.cc	(revision 9bfc9da8135feec0d8796caf32105cd2b1957afc)
+++ src/SynTree/ReferenceType.cc	(revision 68f9c43ecf1873cbb5f06aee682704b56612ed16)
@@ -28,8 +28,4 @@
 }
 
-ReferenceType::~ReferenceType() {
-	delete base;
-}
-
 int ReferenceType::referenceDepth() const {
 	return base->referenceDepth()+1;
Index: src/SynTree/Statement.cc
===================================================================
--- src/SynTree/Statement.cc	(revision 9bfc9da8135feec0d8796caf32105cd2b1957afc)
+++ src/SynTree/Statement.cc	(revision 68f9c43ecf1873cbb5f06aee682704b56612ed16)
@@ -44,13 +44,7 @@
 }
 
-Statement::~Statement() {}
-
 ExprStmt::ExprStmt( Expression *expr ) : Statement(), expr( expr ) {}
 
 ExprStmt::ExprStmt( const ExprStmt &other ) : Statement( other ), expr( maybeClone( other.expr ) ) {}
-
-ExprStmt::~ExprStmt() {
-	delete expr;
-}
 
 void ExprStmt::print( std::ostream &os, Indenter indent ) const {
@@ -66,11 +60,4 @@
   cloneAll( other.input, input );
   cloneAll( other.clobber, clobber );
-}
-
-AsmStmt::~AsmStmt() {
-	delete instruction;
-	deleteAll( output );
-	deleteAll( input );
-	deleteAll( clobber );
 }
 
@@ -122,8 +109,4 @@
 ReturnStmt::ReturnStmt( const ReturnStmt & other ) : Statement( other ), expr( maybeClone( other.expr ) ) {}
 
-ReturnStmt::~ReturnStmt() {
-	delete expr;
-}
-
 void ReturnStmt::print( std::ostream &os, Indenter indent ) const {
 	os << "Return Statement, returning: ";
@@ -141,11 +124,4 @@
 	Statement( other ), condition( maybeClone( other.condition ) ), thenPart( maybeClone( other.thenPart ) ), elsePart( maybeClone( other.elsePart ) ) {
 	cloneAll( other.initialization, initialization );
-}
-
-IfStmt::~IfStmt() {
-	deleteAll( initialization );
-	delete condition;
-	delete thenPart;
-	delete elsePart;
 }
 
@@ -185,10 +161,4 @@
 }
 
-SwitchStmt::~SwitchStmt() {
-	delete condition;
-	// destroy statements
-	deleteAll( statements );
-}
-
 void SwitchStmt::print( std::ostream &os, Indenter indent ) const {
 	os << "Switch on condition: ";
@@ -209,9 +179,4 @@
 	Statement( other ), condition( maybeClone(other.condition ) ), _isDefault( other._isDefault ) {
 	cloneAll( other.stmts, stmts );
-}
-
-CaseStmt::~CaseStmt() {
-	delete condition;
-	deleteAll( stmts );
 }
 
@@ -243,9 +208,4 @@
 }
 
-WhileStmt::~WhileStmt() {
-	delete body;
-	delete condition;
-}
-
 void WhileStmt::print( std::ostream &os, Indenter indent ) const {
 	os << "While on condition: " << endl ;
@@ -265,11 +225,4 @@
 		cloneAll( other.initialization, initialization );
 
-}
-
-ForStmt::~ForStmt() {
-	deleteAll( initialization );
-	delete condition;
-	delete increment;
-	delete body;
 }
 
@@ -311,9 +264,4 @@
 ThrowStmt::ThrowStmt( const ThrowStmt &other ) :
 	Statement ( other ), kind( other.kind ), expr( maybeClone( other.expr ) ), target( maybeClone( other.target ) ) {
-}
-
-ThrowStmt::~ThrowStmt() {
-	delete expr;
-	delete target;
 }
 
@@ -336,10 +284,4 @@
 }
 
-TryStmt::~TryStmt() {
-	delete block;
-	deleteAll( handlers );
-	delete finallyBlock;
-}
-
 void TryStmt::print( std::ostream &os, Indenter indent ) const {
 	os << "Try Statement" << endl;
@@ -370,9 +312,4 @@
 }
 
-CatchStmt::~CatchStmt() {
-	delete decl;
-	delete body;
-}
-
 void CatchStmt::print( std::ostream &os, Indenter indent ) const {
 	os << "Catch " << ((Terminate == kind) ? "Terminate" : "Resume") << " Statement" << endl;
@@ -397,8 +334,4 @@
 
 FinallyStmt::FinallyStmt( const FinallyStmt & other ) : Statement( other ), block( maybeClone( other.block ) ) {
-}
-
-FinallyStmt::~FinallyStmt() {
-	delete block;
 }
 
@@ -434,20 +367,4 @@
 }
 
-WaitForStmt::~WaitForStmt() {
-	for( auto & clause : clauses ) {
-		delete clause.target.function;
-		deleteAll( clause.target.arguments );
-		delete clause.statement;
-		delete clause.condition;
-	}
-
-	delete timeout.time;
-	delete timeout.statement;
-	delete timeout.condition;
-
-	delete orelse.statement;
-	delete orelse.condition;
-}
-
 void WaitForStmt::print( std::ostream &os, Indenter indent ) const {
 	os << "Waitfor Statement" << endl;
@@ -460,8 +377,4 @@
 WithStmt::WithStmt( const WithStmt & other ) : Statement( other ), stmt( maybeClone( other.stmt ) ) {
 	cloneAll( other.exprs, exprs );
-}
-WithStmt::~WithStmt() {
-	deleteAll( exprs );
-	delete stmt;
 }
 
@@ -489,8 +402,4 @@
 }
 
-ImplicitCtorDtorStmt::~ImplicitCtorDtorStmt() {
-	delete callStmt;
-}
-
 void ImplicitCtorDtorStmt::print( std::ostream &os, Indenter indent ) const {
 	os << "Implicit Ctor Dtor Statement" << endl;
Index: src/SynTree/Statement.h
===================================================================
--- src/SynTree/Statement.h	(revision 9bfc9da8135feec0d8796caf32105cd2b1957afc)
+++ src/SynTree/Statement.h	(revision 68f9c43ecf1873cbb5f06aee682704b56612ed16)
@@ -38,5 +38,4 @@
 
 	Statement( const std::list<Label> & labels = {} );
-	virtual ~Statement();
 
 	std::list<Label> & get_labels() { return labels; }
@@ -56,5 +55,4 @@
 	CompoundStmt( std::list<Statement *> stmts );
 	CompoundStmt( const CompoundStmt &other );
-	virtual ~CompoundStmt();
 
 	std::list<Statement*>& get_kids() { return kids; }
@@ -84,5 +82,4 @@
 	ExprStmt( Expression *expr );
 	ExprStmt( const ExprStmt &other );
-	virtual ~ExprStmt();
 
 	Expression *get_expr() { return expr; }
@@ -105,5 +102,4 @@
 	AsmStmt( bool voltile, Expression *instruction, std::list<Expression *> output, std::list<Expression *> input, std::list<ConstantExpr *> clobber, std::list<Label> gotolabels );
 	AsmStmt( const AsmStmt &other );
-	virtual ~AsmStmt();
 
 	bool get_voltile() { return voltile; }
@@ -136,5 +132,4 @@
 			std::list<Statement *> initialization = std::list<Statement *>() );
 	IfStmt( const IfStmt &other );
-	virtual ~IfStmt();
 
 	std::list<Statement *> &get_initialization() { return initialization; }
@@ -159,5 +154,4 @@
 	SwitchStmt( Expression *condition, const std::list<Statement *> &statements );
 	SwitchStmt( const SwitchStmt &other );
-	virtual ~SwitchStmt();
 
 	Expression *get_condition() { return condition; }
@@ -181,5 +175,4 @@
 	CaseStmt( Expression *conditions, const std::list<Statement *> &stmts, bool isdef = false ) throw (SemanticErrorException);
 	CaseStmt( const CaseStmt &other );
-	virtual ~CaseStmt();
 
 	static CaseStmt * makeDefault( const std::list<Label> & labels = {}, std::list<Statement *> stmts = std::list<Statement *>() );
@@ -212,5 +205,4 @@
 	       Statement *body, bool isDoWhile = false );
 	WhileStmt( const WhileStmt &other );
-	virtual ~WhileStmt();
 
 	Expression *get_condition() { return condition; }
@@ -237,5 +229,4 @@
 	     Expression *condition = 0, Expression *increment = 0, Statement *body = 0 );
 	ForStmt( const ForStmt &other );
-	virtual ~ForStmt();
 
 	std::list<Statement *> &get_initialization() { return initialization; }
@@ -290,5 +281,4 @@
 	ReturnStmt( Expression *expr );
 	ReturnStmt( const ReturnStmt &other );
-	virtual ~ReturnStmt();
 
 	Expression *get_expr() { return expr; }
@@ -311,5 +301,4 @@
 	ThrowStmt( Kind kind, Expression * expr, Expression * target = nullptr );
 	ThrowStmt( const ThrowStmt &other );
-	virtual ~ThrowStmt();
 
 	Kind get_kind() { return kind; }
@@ -333,5 +322,4 @@
 	TryStmt( CompoundStmt *tryBlock, std::list<CatchStmt *> &handlers, FinallyStmt *finallyBlock = 0 );
 	TryStmt( const TryStmt &other );
-	virtual ~TryStmt();
 
 	CompoundStmt *get_block() const { return block; }
@@ -360,5 +348,4 @@
 	           Expression *cond, Statement *body );
 	CatchStmt( const CatchStmt &other );
-	virtual ~CatchStmt();
 
 	Kind get_kind() { return kind; }
@@ -382,5 +369,4 @@
 	FinallyStmt( CompoundStmt *block );
 	FinallyStmt( const FinallyStmt &other );
-	virtual ~FinallyStmt();
 
 	CompoundStmt *get_block() const { return block; }
@@ -409,5 +395,4 @@
 	WaitForStmt();
 	WaitForStmt( const WaitForStmt & );
-	virtual ~WaitForStmt();
 
 	std::vector<Clause> clauses;
@@ -438,5 +423,4 @@
 	WithStmt( const std::list< Expression * > & exprs, Statement * stmt );
 	WithStmt( const WithStmt & other );
-	virtual ~WithStmt();
 
 	virtual WithStmt * clone() const override { return new WithStmt( *this ); }
@@ -454,5 +438,4 @@
 	DeclStmt( Declaration *decl );
 	DeclStmt( const DeclStmt &other );
-	virtual ~DeclStmt();
 
 	Declaration *get_decl() const { return decl; }
@@ -476,5 +459,4 @@
 	ImplicitCtorDtorStmt( Statement * callStmt );
 	ImplicitCtorDtorStmt( const ImplicitCtorDtorStmt & other );
-	virtual ~ImplicitCtorDtorStmt();
 
 	Statement *get_callStmt() const { return callStmt; }
Index: src/SynTree/TupleExpr.cc
===================================================================
--- src/SynTree/TupleExpr.cc	(revision 9bfc9da8135feec0d8796caf32105cd2b1957afc)
+++ src/SynTree/TupleExpr.cc	(revision 68f9c43ecf1873cbb5f06aee682704b56612ed16)
@@ -35,8 +35,4 @@
 }
 
-UntypedTupleExpr::~UntypedTupleExpr() {
-	deleteAll( exprs );
-}
-
 void UntypedTupleExpr::print( std::ostream &os, Indenter indent ) const {
 	os << "Untyped Tuple:" << std::endl;
@@ -51,8 +47,4 @@
 TupleExpr::TupleExpr( const TupleExpr &other ) : Expression( other ) {
 	cloneAll( other.exprs, exprs );
-}
-
-TupleExpr::~TupleExpr() {
-	deleteAll( exprs );
 }
 
@@ -72,8 +64,4 @@
 
 TupleIndexExpr::TupleIndexExpr( const TupleIndexExpr &other ) : Expression( other ), tuple( other.tuple->clone() ), index( other.index ) {
-}
-
-TupleIndexExpr::~TupleIndexExpr() {
-	delete tuple;
 }
 
@@ -105,8 +93,4 @@
 }
 
-TupleAssignExpr::~TupleAssignExpr() {
-	delete stmtExpr;
-}
-
 void TupleAssignExpr::print( std::ostream &os, Indenter indent ) const {
 	os << "Tuple Assignment Expression, with stmt expr:" << std::endl;
Index: src/SynTree/TupleType.cc
===================================================================
--- src/SynTree/TupleType.cc	(revision 9bfc9da8135feec0d8796caf32105cd2b1957afc)
+++ src/SynTree/TupleType.cc	(revision 68f9c43ecf1873cbb5f06aee682704b56612ed16)
@@ -43,9 +43,4 @@
 }
 
-TupleType::~TupleType() {
-	deleteAll( types );
-	deleteAll( members );
-}
-
 void TupleType::print( std::ostream &os, Indenter indent ) const {
 	Type::print( os, indent );
Index: src/SynTree/Type.cc
===================================================================
--- src/SynTree/Type.cc	(revision 9bfc9da8135feec0d8796caf32105cd2b1957afc)
+++ src/SynTree/Type.cc	(revision 68f9c43ecf1873cbb5f06aee682704b56612ed16)
@@ -57,9 +57,4 @@
 }
 
-Type::~Type() {
-	deleteAll( forall );
-	deleteAll( attributes );
-}
-
 // These must remain in the same order as the corresponding bit fields.
 const char * Type::FuncSpecifiersNames[] = { "inline", "fortran", "_Noreturn" };
Index: src/SynTree/Type.h
===================================================================
--- src/SynTree/Type.h	(revision 9bfc9da8135feec0d8796caf32105cd2b1957afc)
+++ src/SynTree/Type.h	(revision 68f9c43ecf1873cbb5f06aee682704b56612ed16)
@@ -141,5 +141,4 @@
 	Type( const Qualifiers & tq, const std::list< Attribute * > & attributes );
 	Type( const Type & other );
-	virtual ~Type();
 
 	Qualifiers & get_qualifiers() { return tq; }
@@ -261,5 +260,4 @@
 	PointerType( const Type::Qualifiers & tq, Type *base, Expression *dimension, bool isVarLen, bool isStatic, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
 	PointerType( const PointerType& );
-	virtual ~PointerType();
 
 	Type *get_base() { return base; }
@@ -291,5 +289,4 @@
 	ArrayType( const Type::Qualifiers & tq, Type *base, Expression *dimension, bool isVarLen, bool isStatic, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
 	ArrayType( const ArrayType& );
-	virtual ~ArrayType();
 
 	Type *get_base() { return base; }
@@ -319,5 +316,4 @@
 	ReferenceType( const Type::Qualifiers & tq, Type *base, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
 	ReferenceType( const ReferenceType & );
-	virtual ~ReferenceType();
 
 	Type *get_base() { return base; }
@@ -352,5 +348,4 @@
 	FunctionType( const Type::Qualifiers & tq, bool isVarArgs, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
 	FunctionType( const FunctionType& );
-	virtual ~FunctionType();
 
 	std::list<DeclarationWithType*> & get_returnVals() { return returnVals; }
@@ -376,5 +371,4 @@
 	ReferenceToType( const Type::Qualifiers & tq, const std::string & name, const std::list< Attribute * > & attributes );
 	ReferenceToType( const ReferenceToType & other );
-	virtual ~ReferenceToType();
 
 	const std::string & get_name() const { return name; }
@@ -503,5 +497,4 @@
 	TraitInstType( const Type::Qualifiers & tq, TraitDecl * baseTrait, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
 	TraitInstType( const TraitInstType & other );
-	~TraitInstType();
 
 	virtual bool isComplete() const override;
@@ -525,5 +518,4 @@
 	TypeInstType( const Type::Qualifiers & tq, const std::string & name, bool isFtype, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
 	TypeInstType( const TypeInstType & other );
-	~TypeInstType();
 
 	TypeDecl *get_baseType() const { return baseType; }
@@ -549,5 +541,4 @@
 	TupleType( const Type::Qualifiers & tq, const std::list< Type * > & types, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
 	TupleType( const TupleType& );
-	virtual ~TupleType();
 
 	typedef std::list<Type*> value_type;
@@ -583,5 +574,4 @@
 	TypeofType( const Type::Qualifiers & tq, Expression *expr, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
 	TypeofType( const TypeofType& );
-	virtual ~TypeofType();
 
 	Expression *get_expr() const { return expr; }
@@ -606,5 +596,4 @@
 	AttrType( const Type::Qualifiers & tq, const std::string & name, Type *type, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
 	AttrType( const AttrType& );
-	virtual ~AttrType();
 
 	const std::string & get_name() const { return name; }
Index: src/SynTree/TypeDecl.cc
===================================================================
--- src/SynTree/TypeDecl.cc	(revision 9bfc9da8135feec0d8796caf32105cd2b1957afc)
+++ src/SynTree/TypeDecl.cc	(revision 68f9c43ecf1873cbb5f06aee682704b56612ed16)
@@ -25,8 +25,4 @@
 
 TypeDecl::TypeDecl( const TypeDecl &other ) : Parent( other ), init( maybeClone( other.init ) ), sized( other.sized ), kind( other.kind ) {
-}
-
-TypeDecl::~TypeDecl() {
-  delete init;
 }
 
Index: src/SynTree/TypeExpr.cc
===================================================================
--- src/SynTree/TypeExpr.cc	(revision 9bfc9da8135feec0d8796caf32105cd2b1957afc)
+++ src/SynTree/TypeExpr.cc	(revision 68f9c43ecf1873cbb5f06aee682704b56612ed16)
@@ -26,8 +26,4 @@
 }
 
-TypeExpr::~TypeExpr() {
-	delete type;
-}
-
 void TypeExpr::print( std::ostream &os, Indenter indent ) const {
 	if ( type ) type->print( os, indent );
Index: src/SynTree/TypeSubstitution.cc
===================================================================
--- src/SynTree/TypeSubstitution.cc	(revision 9bfc9da8135feec0d8796caf32105cd2b1957afc)
+++ src/SynTree/TypeSubstitution.cc	(revision 68f9c43ecf1873cbb5f06aee682704b56612ed16)
@@ -26,13 +26,4 @@
 }
 
-TypeSubstitution::~TypeSubstitution() {
-	for ( TypeEnvType::iterator i = typeEnv.begin(); i != typeEnv.end(); ++i ) {
-		delete( i->second );
-	}
-	for ( VarEnvType::iterator i = varEnv.begin(); i != varEnv.end(); ++i ) {
-		delete( i->second );
-	}
-}
-
 TypeSubstitution &TypeSubstitution::operator=( const TypeSubstitution &other ) {
 	if ( this == &other ) return *this;
@@ -57,17 +48,9 @@
 
 void TypeSubstitution::add( std::string formalType, Type *actualType ) {
-	TypeEnvType::iterator i = typeEnv.find( formalType );
-	if ( i != typeEnv.end() ) {
-		delete i->second;
-	} // if
 	typeEnv[ formalType ] = actualType->clone();
 }
 
 void TypeSubstitution::remove( std::string formalType ) {
-	TypeEnvType::iterator i = typeEnv.find( formalType );
-	if ( i != typeEnv.end() ) {
-		delete i->second;
-		typeEnv.erase( formalType );
-	} // if
+	typeEnv.erase( formalType );
 }
 
@@ -155,5 +138,4 @@
 		Type * newtype = i->second->clone();
 		newtype->get_qualifiers() |= inst->get_qualifiers();
-		delete inst;
 		return newtype;
 	} // if
@@ -166,5 +148,4 @@
 	} else {
 		subCount++;
-		delete nameExpr;
 		return i->second->clone();
 	} // if
Index: src/SynTree/TypeSubstitution.h
===================================================================
--- src/SynTree/TypeSubstitution.h	(revision 9bfc9da8135feec0d8796caf32105cd2b1957afc)
+++ src/SynTree/TypeSubstitution.h	(revision 68f9c43ecf1873cbb5f06aee682704b56612ed16)
@@ -35,5 +35,4 @@
 	TypeSubstitution( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actualBegin );
 	TypeSubstitution( const TypeSubstitution &other );
-	virtual ~TypeSubstitution();
 
 	TypeSubstitution &operator=( const TypeSubstitution &other );
@@ -101,8 +100,4 @@
 			if ( TypeExpr *actual = dynamic_cast< TypeExpr* >( *actualIt ) ) {
 				if ( formal->get_name() != "" ) {
-					TypeEnvType::iterator i = typeEnv.find( formal->get_name() );
-					if ( i != typeEnv.end() ) {
-						delete i->second;
-					} // if
 					typeEnv[ formal->get_name() ] = actual->get_type()->clone();
 				} // if
Index: src/SynTree/TypeofType.cc
===================================================================
--- src/SynTree/TypeofType.cc	(revision 9bfc9da8135feec0d8796caf32105cd2b1957afc)
+++ src/SynTree/TypeofType.cc	(revision 68f9c43ecf1873cbb5f06aee682704b56612ed16)
@@ -29,8 +29,4 @@
 }
 
-TypeofType::~TypeofType() {
-	delete expr;
-}
-
 void TypeofType::print( std::ostream &os, Indenter indent ) const {
 	Type::print( os, indent );
Index: src/SynTree/module.mk
===================================================================
--- src/SynTree/module.mk	(revision 9bfc9da8135feec0d8796caf32105cd2b1957afc)
+++ src/SynTree/module.mk	(revision 68f9c43ecf1873cbb5f06aee682704b56612ed16)
@@ -48,4 +48,5 @@
        SynTree/TypeSubstitution.cc \
        SynTree/Attribute.cc \
+       SynTree/GcTracer.cc \
        SynTree/VarExprReplacer.cc
 
